]> git.ipfire.org Git - people/ms/ipfire-3.x.git/blame - pkgs/kernel/patches/grsecurity-2.2.2-2.6.38.1-201103262052.patch
kernel: Update to 2.6.38.1.
[people/ms/ipfire-3.x.git] / pkgs / kernel / patches / grsecurity-2.2.2-2.6.38.1-201103262052.patch
CommitLineData
16454cff
MT
1diff -urNp linux-2.6.38.1/arch/alpha/include/asm/dma-mapping.h linux-2.6.38.1/arch/alpha/include/asm/dma-mapping.h
2--- linux-2.6.38.1/arch/alpha/include/asm/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
3+++ linux-2.6.38.1/arch/alpha/include/asm/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
4@@ -3,9 +3,9 @@
5
6 #include <linux/dma-attrs.h>
7
8-extern struct dma_map_ops *dma_ops;
9+extern const struct dma_map_ops *dma_ops;
10
11-static inline struct dma_map_ops *get_dma_ops(struct device *dev)
12+static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
13 {
14 return dma_ops;
15 }
16454cff
MT
16diff -urNp linux-2.6.38.1/arch/alpha/include/asm/elf.h linux-2.6.38.1/arch/alpha/include/asm/elf.h
17--- linux-2.6.38.1/arch/alpha/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
18+++ linux-2.6.38.1/arch/alpha/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 19@@ -90,6 +90,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
58c5fc13
MT
20
21 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
22
23+#ifdef CONFIG_PAX_ASLR
24+#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
25+
26+#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
27+#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
28+#endif
29+
30 /* $0 is set by ld.so to a pointer to a function which might be
31 registered using atexit. This provides a mean for the dynamic
32 linker to call DT_FINI functions for shared libraries that have
16454cff
MT
33diff -urNp linux-2.6.38.1/arch/alpha/include/asm/pgtable.h linux-2.6.38.1/arch/alpha/include/asm/pgtable.h
34--- linux-2.6.38.1/arch/alpha/include/asm/pgtable.h 2011-03-14 21:20:32.000000000 -0400
35+++ linux-2.6.38.1/arch/alpha/include/asm/pgtable.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
36@@ -101,6 +101,17 @@ struct vm_area_struct;
37 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
38 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
39 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
40+
41+#ifdef CONFIG_PAX_PAGEEXEC
42+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
43+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
44+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
45+#else
46+# define PAGE_SHARED_NOEXEC PAGE_SHARED
47+# define PAGE_COPY_NOEXEC PAGE_COPY
48+# define PAGE_READONLY_NOEXEC PAGE_READONLY
49+#endif
50+
51 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
52
53 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
16454cff
MT
54diff -urNp linux-2.6.38.1/arch/alpha/kernel/module.c linux-2.6.38.1/arch/alpha/kernel/module.c
55--- linux-2.6.38.1/arch/alpha/kernel/module.c 2011-03-14 21:20:32.000000000 -0400
56+++ linux-2.6.38.1/arch/alpha/kernel/module.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
57@@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
58
59 /* The small sections were sorted to the end of the segment.
60 The following should definitely cover them. */
61- gp = (u64)me->module_core + me->core_size - 0x8000;
62+ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
63 got = sechdrs[me->arch.gotsecindex].sh_addr;
64
65 for (i = 0; i < n; i++) {
16454cff
MT
66diff -urNp linux-2.6.38.1/arch/alpha/kernel/osf_sys.c linux-2.6.38.1/arch/alpha/kernel/osf_sys.c
67--- linux-2.6.38.1/arch/alpha/kernel/osf_sys.c 2011-03-14 21:20:32.000000000 -0400
68+++ linux-2.6.38.1/arch/alpha/kernel/osf_sys.c 2011-03-21 18:31:35.000000000 -0400
69@@ -1162,7 +1162,7 @@ arch_get_unmapped_area_1(unsigned long a
57199397
MT
70 /* At this point: (!vma || addr < vma->vm_end). */
71 if (limit - len < addr)
72 return -ENOMEM;
73- if (!vma || addr + len <= vma->vm_start)
74+ if (check_heap_stack_gap(vma, addr, len))
75 return addr;
76 addr = vma->vm_end;
77 vma = vma->vm_next;
16454cff 78@@ -1198,6 +1198,10 @@ arch_get_unmapped_area(struct file *filp
58c5fc13
MT
79 merely specific addresses, but regions of memory -- perhaps
80 this feature should be incorporated into all ports? */
81
82+#ifdef CONFIG_PAX_RANDMMAP
83+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
84+#endif
85+
86 if (addr) {
87 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
88 if (addr != (unsigned long) -ENOMEM)
16454cff 89@@ -1205,8 +1209,8 @@ arch_get_unmapped_area(struct file *filp
58c5fc13
MT
90 }
91
92 /* Next, try allocating at TASK_UNMAPPED_BASE. */
93- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
94- len, limit);
95+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
96+
97 if (addr != (unsigned long) -ENOMEM)
98 return addr;
99
16454cff
MT
100diff -urNp linux-2.6.38.1/arch/alpha/kernel/pci_iommu.c linux-2.6.38.1/arch/alpha/kernel/pci_iommu.c
101--- linux-2.6.38.1/arch/alpha/kernel/pci_iommu.c 2011-03-14 21:20:32.000000000 -0400
102+++ linux-2.6.38.1/arch/alpha/kernel/pci_iommu.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
103@@ -950,7 +950,7 @@ static int alpha_pci_set_mask(struct dev
104 return 0;
105 }
106
107-struct dma_map_ops alpha_pci_ops = {
108+const struct dma_map_ops alpha_pci_ops = {
109 .alloc_coherent = alpha_pci_alloc_coherent,
110 .free_coherent = alpha_pci_free_coherent,
111 .map_page = alpha_pci_map_page,
112@@ -962,5 +962,5 @@ struct dma_map_ops alpha_pci_ops = {
113 .set_dma_mask = alpha_pci_set_mask,
114 };
115
116-struct dma_map_ops *dma_ops = &alpha_pci_ops;
117+const struct dma_map_ops *dma_ops = &alpha_pci_ops;
118 EXPORT_SYMBOL(dma_ops);
16454cff
MT
119diff -urNp linux-2.6.38.1/arch/alpha/kernel/pci-noop.c linux-2.6.38.1/arch/alpha/kernel/pci-noop.c
120--- linux-2.6.38.1/arch/alpha/kernel/pci-noop.c 2011-03-14 21:20:32.000000000 -0400
121+++ linux-2.6.38.1/arch/alpha/kernel/pci-noop.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
122@@ -173,7 +173,7 @@ static int alpha_noop_set_mask(struct de
123 return 0;
124 }
125
126-struct dma_map_ops alpha_noop_ops = {
127+const struct dma_map_ops alpha_noop_ops = {
128 .alloc_coherent = alpha_noop_alloc_coherent,
129 .free_coherent = alpha_noop_free_coherent,
130 .map_page = alpha_noop_map_page,
131@@ -183,7 +183,7 @@ struct dma_map_ops alpha_noop_ops = {
132 .set_dma_mask = alpha_noop_set_mask,
133 };
134
135-struct dma_map_ops *dma_ops = &alpha_noop_ops;
136+const struct dma_map_ops *dma_ops = &alpha_noop_ops;
137 EXPORT_SYMBOL(dma_ops);
138
139 void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
16454cff
MT
140diff -urNp linux-2.6.38.1/arch/alpha/mm/fault.c linux-2.6.38.1/arch/alpha/mm/fault.c
141--- linux-2.6.38.1/arch/alpha/mm/fault.c 2011-03-14 21:20:32.000000000 -0400
142+++ linux-2.6.38.1/arch/alpha/mm/fault.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
143@@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
144 __reload_thread(pcb);
145 }
146
147+#ifdef CONFIG_PAX_PAGEEXEC
148+/*
149+ * PaX: decide what to do with offenders (regs->pc = fault address)
150+ *
151+ * returns 1 when task should be killed
152+ * 2 when patched PLT trampoline was detected
153+ * 3 when unpatched PLT trampoline was detected
154+ */
155+static int pax_handle_fetch_fault(struct pt_regs *regs)
156+{
157+
158+#ifdef CONFIG_PAX_EMUPLT
159+ int err;
160+
161+ do { /* PaX: patched PLT emulation #1 */
162+ unsigned int ldah, ldq, jmp;
163+
164+ err = get_user(ldah, (unsigned int *)regs->pc);
165+ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
166+ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
167+
168+ if (err)
169+ break;
170+
171+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
172+ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
173+ jmp == 0x6BFB0000U)
174+ {
175+ unsigned long r27, addr;
176+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
177+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
178+
179+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
180+ err = get_user(r27, (unsigned long *)addr);
181+ if (err)
182+ break;
183+
184+ regs->r27 = r27;
185+ regs->pc = r27;
186+ return 2;
187+ }
188+ } while (0);
189+
190+ do { /* PaX: patched PLT emulation #2 */
191+ unsigned int ldah, lda, br;
192+
193+ err = get_user(ldah, (unsigned int *)regs->pc);
194+ err |= get_user(lda, (unsigned int *)(regs->pc+4));
195+ err |= get_user(br, (unsigned int *)(regs->pc+8));
196+
197+ if (err)
198+ break;
199+
200+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
201+ (lda & 0xFFFF0000U) == 0xA77B0000U &&
202+ (br & 0xFFE00000U) == 0xC3E00000U)
203+ {
204+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
205+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
206+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
207+
208+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
209+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
210+ return 2;
211+ }
212+ } while (0);
213+
214+ do { /* PaX: unpatched PLT emulation */
215+ unsigned int br;
216+
217+ err = get_user(br, (unsigned int *)regs->pc);
218+
219+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
220+ unsigned int br2, ldq, nop, jmp;
221+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
222+
223+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
224+ err = get_user(br2, (unsigned int *)addr);
225+ err |= get_user(ldq, (unsigned int *)(addr+4));
226+ err |= get_user(nop, (unsigned int *)(addr+8));
227+ err |= get_user(jmp, (unsigned int *)(addr+12));
228+ err |= get_user(resolver, (unsigned long *)(addr+16));
229+
230+ if (err)
231+ break;
232+
233+ if (br2 == 0xC3600000U &&
234+ ldq == 0xA77B000CU &&
235+ nop == 0x47FF041FU &&
236+ jmp == 0x6B7B0000U)
237+ {
238+ regs->r28 = regs->pc+4;
239+ regs->r27 = addr+16;
240+ regs->pc = resolver;
241+ return 3;
242+ }
243+ }
244+ } while (0);
245+#endif
246+
247+ return 1;
248+}
249+
250+void pax_report_insns(void *pc, void *sp)
251+{
252+ unsigned long i;
253+
254+ printk(KERN_ERR "PAX: bytes at PC: ");
255+ for (i = 0; i < 5; i++) {
256+ unsigned int c;
257+ if (get_user(c, (unsigned int *)pc+i))
258+ printk(KERN_CONT "???????? ");
259+ else
260+ printk(KERN_CONT "%08x ", c);
261+ }
262+ printk("\n");
263+}
264+#endif
265
266 /*
267 * This routine handles page faults. It determines the address,
268@@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
269 good_area:
270 si_code = SEGV_ACCERR;
271 if (cause < 0) {
272- if (!(vma->vm_flags & VM_EXEC))
273+ if (!(vma->vm_flags & VM_EXEC)) {
274+
275+#ifdef CONFIG_PAX_PAGEEXEC
276+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
277+ goto bad_area;
278+
279+ up_read(&mm->mmap_sem);
280+ switch (pax_handle_fetch_fault(regs)) {
281+
282+#ifdef CONFIG_PAX_EMUPLT
283+ case 2:
284+ case 3:
285+ return;
286+#endif
287+
288+ }
289+ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
290+ do_group_exit(SIGKILL);
291+#else
292 goto bad_area;
293+#endif
294+
295+ }
296 } else if (!cause) {
297 /* Allow reads even for write-only mappings */
298 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
16454cff
MT
299diff -urNp linux-2.6.38.1/arch/arm/include/asm/elf.h linux-2.6.38.1/arch/arm/include/asm/elf.h
300--- linux-2.6.38.1/arch/arm/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
301+++ linux-2.6.38.1/arch/arm/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
302@@ -115,7 +115,14 @@ int dump_task_regs(struct task_struct *t
58c5fc13
MT
303 the loader. We need to make sure that it is out of the way of the program
304 that it will "exec", and that there is sufficient room for the brk. */
305
306-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
307+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
308+
309+#ifdef CONFIG_PAX_ASLR
310+#define PAX_ELF_ET_DYN_BASE 0x00008000UL
311+
312+#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
313+#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
314+#endif
315
316 /* When the program starts, a1 contains a pointer to a function to be
317 registered with atexit, as per the SVR4 ABI. A value of 0 means we
16454cff 318@@ -125,10 +132,6 @@ int dump_task_regs(struct task_struct *t
bc901d79
MT
319 extern void elf_set_personality(const struct elf32_hdr *);
320 #define SET_PERSONALITY(ex) elf_set_personality(&(ex))
321
322-struct mm_struct;
323-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
324-#define arch_randomize_brk arch_randomize_brk
325-
326 extern int vectors_user_mapping(void);
327 #define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
328 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
16454cff
MT
329diff -urNp linux-2.6.38.1/arch/arm/include/asm/kmap_types.h linux-2.6.38.1/arch/arm/include/asm/kmap_types.h
330--- linux-2.6.38.1/arch/arm/include/asm/kmap_types.h 2011-03-14 21:20:32.000000000 -0400
331+++ linux-2.6.38.1/arch/arm/include/asm/kmap_types.h 2011-03-21 18:31:35.000000000 -0400
57199397 332@@ -21,6 +21,7 @@ enum km_type {
df50ba0c 333 KM_L1_CACHE,
58c5fc13 334 KM_L2_CACHE,
57199397 335 KM_KDB,
58c5fc13
MT
336+ KM_CLEARPAGE,
337 KM_TYPE_NR
338 };
339
16454cff
MT
340diff -urNp linux-2.6.38.1/arch/arm/include/asm/uaccess.h linux-2.6.38.1/arch/arm/include/asm/uaccess.h
341--- linux-2.6.38.1/arch/arm/include/asm/uaccess.h 2011-03-14 21:20:32.000000000 -0400
342+++ linux-2.6.38.1/arch/arm/include/asm/uaccess.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 343@@ -403,6 +403,9 @@ extern unsigned long __must_check __strn
58c5fc13
MT
344
345 static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
346 {
347+ if ((long)n < 0)
348+ return n;
349+
350 if (access_ok(VERIFY_READ, from, n))
351 n = __copy_from_user(to, from, n);
352 else /* security hole - plug it */
ae4e228f 353@@ -412,6 +415,9 @@ static inline unsigned long __must_check
58c5fc13
MT
354
355 static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
356 {
357+ if ((long)n < 0)
358+ return n;
359+
360 if (access_ok(VERIFY_WRITE, to, n))
361 n = __copy_to_user(to, from, n);
362 return n;
16454cff
MT
363diff -urNp linux-2.6.38.1/arch/arm/kernel/kgdb.c linux-2.6.38.1/arch/arm/kernel/kgdb.c
364--- linux-2.6.38.1/arch/arm/kernel/kgdb.c 2011-03-14 21:20:32.000000000 -0400
365+++ linux-2.6.38.1/arch/arm/kernel/kgdb.c 2011-03-21 18:31:35.000000000 -0400
6892158b 366@@ -246,7 +246,7 @@ void kgdb_arch_exit(void)
ae4e228f
MT
367 * and we handle the normal undef case within the do_undefinstr
368 * handler.
369 */
370-struct kgdb_arch arch_kgdb_ops = {
371+const struct kgdb_arch arch_kgdb_ops = {
372 #ifndef __ARMEB__
373 .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
374 #else /* ! __ARMEB__ */
16454cff
MT
375diff -urNp linux-2.6.38.1/arch/arm/kernel/process.c linux-2.6.38.1/arch/arm/kernel/process.c
376--- linux-2.6.38.1/arch/arm/kernel/process.c 2011-03-14 21:20:32.000000000 -0400
377+++ linux-2.6.38.1/arch/arm/kernel/process.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
378@@ -28,7 +28,6 @@
379 #include <linux/tick.h>
380 #include <linux/utsname.h>
381 #include <linux/uaccess.h>
382-#include <linux/random.h>
383 #include <linux/hw_breakpoint.h>
384
385 #include <asm/cacheflush.h>
386@@ -477,12 +476,6 @@ unsigned long get_wchan(struct task_stru
387 return 0;
388 }
389
390-unsigned long arch_randomize_brk(struct mm_struct *mm)
391-{
392- unsigned long range_end = mm->brk + 0x02000000;
393- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
394-}
395-
16454cff 396 #ifdef CONFIG_MMU
bc901d79
MT
397 /*
398 * The vectors page is always readable from user space for the
16454cff
MT
399diff -urNp linux-2.6.38.1/arch/arm/mach-msm/last_radio_log.c linux-2.6.38.1/arch/arm/mach-msm/last_radio_log.c
400--- linux-2.6.38.1/arch/arm/mach-msm/last_radio_log.c 2011-03-14 21:20:32.000000000 -0400
401+++ linux-2.6.38.1/arch/arm/mach-msm/last_radio_log.c 2011-03-21 18:31:35.000000000 -0400
402@@ -47,7 +47,7 @@ static ssize_t last_radio_log_read(struc
57199397
MT
403 return count;
404 }
405
16454cff
MT
406-static struct file_operations last_radio_log_fops = {
407+static struct file_operations last_radio_log_fops = { /* cannot be const, see msm_init_last_radio_log */
bc901d79
MT
408 .read = last_radio_log_read,
409 .llseek = default_llseek,
16454cff
MT
410 };
411diff -urNp linux-2.6.38.1/arch/arm/mach-ux500/mbox-db5500.c linux-2.6.38.1/arch/arm/mach-ux500/mbox-db5500.c
412--- linux-2.6.38.1/arch/arm/mach-ux500/mbox-db5500.c 2011-03-14 21:20:32.000000000 -0400
413+++ linux-2.6.38.1/arch/arm/mach-ux500/mbox-db5500.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
414@@ -168,7 +168,7 @@ static ssize_t mbox_read_fifo(struct dev
415 return sprintf(buf, "0x%X\n", mbox_value);
416 }
417
418-static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo);
419+static DEVICE_ATTR(fifo, S_IWUSR | S_IRUGO, mbox_read_fifo, mbox_write_fifo);
420
421 static int mbox_show(struct seq_file *s, void *data)
422 {
16454cff
MT
423diff -urNp linux-2.6.38.1/arch/arm/mm/fault.c linux-2.6.38.1/arch/arm/mm/fault.c
424--- linux-2.6.38.1/arch/arm/mm/fault.c 2011-03-14 21:20:32.000000000 -0400
425+++ linux-2.6.38.1/arch/arm/mm/fault.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 426@@ -167,6 +167,13 @@ __do_user_fault(struct task_struct *tsk,
ae4e228f
MT
427 }
428 #endif
429
430+#ifdef CONFIG_PAX_PAGEEXEC
431+ if (fsr & FSR_LNX_PF) {
432+ pax_report_fault(regs, (void *)regs->ARM_pc, (void *)regs->ARM_sp);
433+ do_group_exit(SIGKILL);
434+ }
435+#endif
436+
437 tsk->thread.address = addr;
438 tsk->thread.error_code = fsr;
439 tsk->thread.trap_no = 14;
df50ba0c 440@@ -364,6 +371,33 @@ do_page_fault(unsigned long addr, unsign
ae4e228f
MT
441 }
442 #endif /* CONFIG_MMU */
443
444+#ifdef CONFIG_PAX_PAGEEXEC
445+void pax_report_insns(void *pc, void *sp)
446+{
447+ long i;
448+
449+ printk(KERN_ERR "PAX: bytes at PC: ");
450+ for (i = 0; i < 20; i++) {
451+ unsigned char c;
452+ if (get_user(c, (__force unsigned char __user *)pc+i))
453+ printk(KERN_CONT "?? ");
454+ else
455+ printk(KERN_CONT "%02x ", c);
456+ }
457+ printk("\n");
458+
459+ printk(KERN_ERR "PAX: bytes at SP-4: ");
460+ for (i = -1; i < 20; i++) {
461+ unsigned long c;
462+ if (get_user(c, (__force unsigned long __user *)sp+i))
463+ printk(KERN_CONT "???????? ");
464+ else
465+ printk(KERN_CONT "%08lx ", c);
466+ }
467+ printk("\n");
468+}
469+#endif
470+
471 /*
472 * First Level Translation Fault Handler
473 *
16454cff
MT
474diff -urNp linux-2.6.38.1/arch/arm/mm/mmap.c linux-2.6.38.1/arch/arm/mm/mmap.c
475--- linux-2.6.38.1/arch/arm/mm/mmap.c 2011-03-14 21:20:32.000000000 -0400
476+++ linux-2.6.38.1/arch/arm/mm/mmap.c 2011-03-21 18:31:35.000000000 -0400
6892158b 477@@ -64,6 +64,10 @@ arch_get_unmapped_area(struct file *filp
58c5fc13
MT
478 if (len > TASK_SIZE)
479 return -ENOMEM;
480
481+#ifdef CONFIG_PAX_RANDMMAP
482+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
483+#endif
484+
485 if (addr) {
486 if (do_align)
487 addr = COLOUR_ALIGN(addr, pgoff);
6892158b 488@@ -71,15 +75,14 @@ arch_get_unmapped_area(struct file *filp
57199397
MT
489 addr = PAGE_ALIGN(addr);
490
491 vma = find_vma(mm, addr);
492- if (TASK_SIZE - len >= addr &&
493- (!vma || addr + len <= vma->vm_start))
494+ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
58c5fc13
MT
495 return addr;
496 }
497 if (len > mm->cached_hole_size) {
498- start_addr = addr = mm->free_area_cache;
499+ start_addr = addr = mm->free_area_cache;
500 } else {
501- start_addr = addr = TASK_UNMAPPED_BASE;
502- mm->cached_hole_size = 0;
503+ start_addr = addr = mm->mmap_base;
504+ mm->cached_hole_size = 0;
505 }
6892158b
MT
506 /* 8 bits of randomness in 20 address space bits */
507 if (current->flags & PF_RANDOMIZE)
508@@ -98,14 +101,14 @@ full_search:
58c5fc13
MT
509 * Start a new search - just in case we missed
510 * some holes.
511 */
512- if (start_addr != TASK_UNMAPPED_BASE) {
513- start_addr = addr = TASK_UNMAPPED_BASE;
514+ if (start_addr != mm->mmap_base) {
515+ start_addr = addr = mm->mmap_base;
516 mm->cached_hole_size = 0;
517 goto full_search;
518 }
57199397
MT
519 return -ENOMEM;
520 }
521- if (!vma || addr + len <= vma->vm_start) {
522+ if (check_heap_stack_gap(vma, addr, len)) {
523 /*
524 * Remember the place where we stopped the search:
525 */
16454cff
MT
526diff -urNp linux-2.6.38.1/arch/avr32/include/asm/elf.h linux-2.6.38.1/arch/avr32/include/asm/elf.h
527--- linux-2.6.38.1/arch/avr32/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
528+++ linux-2.6.38.1/arch/avr32/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 529@@ -84,8 +84,14 @@ typedef struct user_fpu_struct elf_fpreg
58c5fc13
MT
530 the loader. We need to make sure that it is out of the way of the program
531 that it will "exec", and that there is sufficient room for the brk. */
532
533-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
534+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
535
536+#ifdef CONFIG_PAX_ASLR
537+#define PAX_ELF_ET_DYN_BASE 0x00001000UL
538+
539+#define PAX_DELTA_MMAP_LEN 15
540+#define PAX_DELTA_STACK_LEN 15
541+#endif
542
543 /* This yields a mask that user programs can use to figure out what
544 instruction set this CPU supports. This could be done in user space,
16454cff
MT
545diff -urNp linux-2.6.38.1/arch/avr32/include/asm/kmap_types.h linux-2.6.38.1/arch/avr32/include/asm/kmap_types.h
546--- linux-2.6.38.1/arch/avr32/include/asm/kmap_types.h 2011-03-14 21:20:32.000000000 -0400
547+++ linux-2.6.38.1/arch/avr32/include/asm/kmap_types.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
548@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
549 D(11) KM_IRQ1,
550 D(12) KM_SOFTIRQ0,
551 D(13) KM_SOFTIRQ1,
552-D(14) KM_TYPE_NR
553+D(14) KM_CLEARPAGE,
554+D(15) KM_TYPE_NR
555 };
556
557 #undef D
16454cff
MT
558diff -urNp linux-2.6.38.1/arch/avr32/mm/fault.c linux-2.6.38.1/arch/avr32/mm/fault.c
559--- linux-2.6.38.1/arch/avr32/mm/fault.c 2011-03-14 21:20:32.000000000 -0400
560+++ linux-2.6.38.1/arch/avr32/mm/fault.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
561@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
562
563 int exception_trace = 1;
564
565+#ifdef CONFIG_PAX_PAGEEXEC
566+void pax_report_insns(void *pc, void *sp)
567+{
568+ unsigned long i;
569+
570+ printk(KERN_ERR "PAX: bytes at PC: ");
571+ for (i = 0; i < 20; i++) {
572+ unsigned char c;
573+ if (get_user(c, (unsigned char *)pc+i))
574+ printk(KERN_CONT "???????? ");
575+ else
576+ printk(KERN_CONT "%02x ", c);
577+ }
578+ printk("\n");
579+}
580+#endif
581+
582 /*
583 * This routine handles page faults. It determines the address and the
584 * problem, and then passes it off to one of the appropriate routines.
6892158b 585@@ -156,6 +173,16 @@ bad_area:
58c5fc13
MT
586 up_read(&mm->mmap_sem);
587
588 if (user_mode(regs)) {
589+
590+#ifdef CONFIG_PAX_PAGEEXEC
591+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
592+ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
593+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
594+ do_group_exit(SIGKILL);
595+ }
596+ }
597+#endif
598+
599 if (exception_trace && printk_ratelimit())
600 printk("%s%s[%d]: segfault at %08lx pc %08lx "
601 "sp %08lx ecr %lu\n",
16454cff
MT
602diff -urNp linux-2.6.38.1/arch/blackfin/kernel/kgdb.c linux-2.6.38.1/arch/blackfin/kernel/kgdb.c
603--- linux-2.6.38.1/arch/blackfin/kernel/kgdb.c 2011-03-14 21:20:32.000000000 -0400
604+++ linux-2.6.38.1/arch/blackfin/kernel/kgdb.c 2011-03-21 18:31:35.000000000 -0400
605@@ -420,7 +420,7 @@ int kgdb_arch_handle_exception(int vecto
ae4e228f 606 return -1; /* this means that we do not want to exit from the handler */
58c5fc13
MT
607 }
608
ae4e228f
MT
609-struct kgdb_arch arch_kgdb_ops = {
610+const struct kgdb_arch arch_kgdb_ops = {
611 .gdb_bpt_instr = {0xa1},
612 #ifdef CONFIG_SMP
613 .flags = KGDB_HW_BREAKPOINT|KGDB_THR_PROC_SWAP,
16454cff
MT
614diff -urNp linux-2.6.38.1/arch/blackfin/mm/maccess.c linux-2.6.38.1/arch/blackfin/mm/maccess.c
615--- linux-2.6.38.1/arch/blackfin/mm/maccess.c 2011-03-14 21:20:32.000000000 -0400
616+++ linux-2.6.38.1/arch/blackfin/mm/maccess.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
617@@ -16,7 +16,7 @@ static int validate_memory_access_addres
618 return bfin_mem_access_type(addr, size);
58c5fc13
MT
619 }
620
ae4e228f
MT
621-long probe_kernel_read(void *dst, void *src, size_t size)
622+long probe_kernel_read(void *dst, const void *src, size_t size)
58c5fc13 623 {
ae4e228f
MT
624 unsigned long lsrc = (unsigned long)src;
625 int mem_type;
626@@ -55,7 +55,7 @@ long probe_kernel_read(void *dst, void *
627 return -EFAULT;
58c5fc13
MT
628 }
629
ae4e228f
MT
630-long probe_kernel_write(void *dst, void *src, size_t size)
631+long probe_kernel_write(void *dst, const void *src, size_t size)
58c5fc13 632 {
ae4e228f
MT
633 unsigned long ldst = (unsigned long)dst;
634 int mem_type;
16454cff
MT
635diff -urNp linux-2.6.38.1/arch/frv/include/asm/kmap_types.h linux-2.6.38.1/arch/frv/include/asm/kmap_types.h
636--- linux-2.6.38.1/arch/frv/include/asm/kmap_types.h 2011-03-14 21:20:32.000000000 -0400
637+++ linux-2.6.38.1/arch/frv/include/asm/kmap_types.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
638@@ -23,6 +23,7 @@ enum km_type {
639 KM_IRQ1,
640 KM_SOFTIRQ0,
641 KM_SOFTIRQ1,
642+ KM_CLEARPAGE,
643 KM_TYPE_NR
644 };
645
16454cff
MT
646diff -urNp linux-2.6.38.1/arch/frv/mm/elf-fdpic.c linux-2.6.38.1/arch/frv/mm/elf-fdpic.c
647--- linux-2.6.38.1/arch/frv/mm/elf-fdpic.c 2011-03-14 21:20:32.000000000 -0400
648+++ linux-2.6.38.1/arch/frv/mm/elf-fdpic.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
649@@ -73,8 +73,7 @@ unsigned long arch_get_unmapped_area(str
650 if (addr) {
651 addr = PAGE_ALIGN(addr);
652 vma = find_vma(current->mm, addr);
653- if (TASK_SIZE - len >= addr &&
654- (!vma || addr + len <= vma->vm_start))
655+ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
656 goto success;
657 }
658
659@@ -89,7 +88,7 @@ unsigned long arch_get_unmapped_area(str
660 for (; vma; vma = vma->vm_next) {
661 if (addr > limit)
662 break;
663- if (addr + len <= vma->vm_start)
664+ if (check_heap_stack_gap(vma, addr, len))
665 goto success;
666 addr = vma->vm_end;
667 }
668@@ -104,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
669 for (; vma; vma = vma->vm_next) {
670 if (addr > limit)
671 break;
672- if (addr + len <= vma->vm_start)
673+ if (check_heap_stack_gap(vma, addr, len))
674 goto success;
675 addr = vma->vm_end;
676 }
16454cff
MT
677diff -urNp linux-2.6.38.1/arch/ia64/hp/common/hwsw_iommu.c linux-2.6.38.1/arch/ia64/hp/common/hwsw_iommu.c
678--- linux-2.6.38.1/arch/ia64/hp/common/hwsw_iommu.c 2011-03-14 21:20:32.000000000 -0400
679+++ linux-2.6.38.1/arch/ia64/hp/common/hwsw_iommu.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
680@@ -17,7 +17,7 @@
681 #include <linux/swiotlb.h>
682 #include <asm/machvec.h>
58c5fc13 683
ae4e228f
MT
684-extern struct dma_map_ops sba_dma_ops, swiotlb_dma_ops;
685+extern const struct dma_map_ops sba_dma_ops, swiotlb_dma_ops;
58c5fc13 686
ae4e228f
MT
687 /* swiotlb declarations & definitions: */
688 extern int swiotlb_late_init_with_default_size (size_t size);
689@@ -33,7 +33,7 @@ static inline int use_swiotlb(struct dev
690 !sba_dma_ops.dma_supported(dev, *dev->dma_mask);
58c5fc13
MT
691 }
692
ae4e228f
MT
693-struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
694+const struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
695 {
696 if (use_swiotlb(dev))
697 return &swiotlb_dma_ops;
16454cff
MT
698diff -urNp linux-2.6.38.1/arch/ia64/hp/common/sba_iommu.c linux-2.6.38.1/arch/ia64/hp/common/sba_iommu.c
699--- linux-2.6.38.1/arch/ia64/hp/common/sba_iommu.c 2011-03-14 21:20:32.000000000 -0400
700+++ linux-2.6.38.1/arch/ia64/hp/common/sba_iommu.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
701@@ -2097,7 +2097,7 @@ static struct acpi_driver acpi_sba_ioc_d
702 },
703 };
58c5fc13 704
ae4e228f
MT
705-extern struct dma_map_ops swiotlb_dma_ops;
706+extern const struct dma_map_ops swiotlb_dma_ops;
58c5fc13 707
ae4e228f
MT
708 static int __init
709 sba_init(void)
710@@ -2211,7 +2211,7 @@ sba_page_override(char *str)
58c5fc13 711
ae4e228f 712 __setup("sbapagesize=",sba_page_override);
58c5fc13 713
ae4e228f
MT
714-struct dma_map_ops sba_dma_ops = {
715+const struct dma_map_ops sba_dma_ops = {
716 .alloc_coherent = sba_alloc_coherent,
717 .free_coherent = sba_free_coherent,
718 .map_page = sba_map_page,
16454cff
MT
719diff -urNp linux-2.6.38.1/arch/ia64/include/asm/dma-mapping.h linux-2.6.38.1/arch/ia64/include/asm/dma-mapping.h
720--- linux-2.6.38.1/arch/ia64/include/asm/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
721+++ linux-2.6.38.1/arch/ia64/include/asm/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 722@@ -12,7 +12,7 @@
58c5fc13 723
ae4e228f
MT
724 #define ARCH_HAS_DMA_GET_REQUIRED_MASK
725
726-extern struct dma_map_ops *dma_ops;
727+extern const struct dma_map_ops *dma_ops;
728 extern struct ia64_machine_vector ia64_mv;
729 extern void set_iommu_machvec(void);
58c5fc13 730
ae4e228f
MT
731@@ -24,7 +24,7 @@ extern void machvec_dma_sync_sg(struct d
732 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
733 dma_addr_t *daddr, gfp_t gfp)
734 {
735- struct dma_map_ops *ops = platform_dma_get_ops(dev);
736+ const struct dma_map_ops *ops = platform_dma_get_ops(dev);
737 void *caddr;
738
739 caddr = ops->alloc_coherent(dev, size, daddr, gfp);
740@@ -35,7 +35,7 @@ static inline void *dma_alloc_coherent(s
741 static inline void dma_free_coherent(struct device *dev, size_t size,
742 void *caddr, dma_addr_t daddr)
743 {
744- struct dma_map_ops *ops = platform_dma_get_ops(dev);
745+ const struct dma_map_ops *ops = platform_dma_get_ops(dev);
746 debug_dma_free_coherent(dev, size, caddr, daddr);
747 ops->free_coherent(dev, size, caddr, daddr);
748 }
749@@ -49,13 +49,13 @@ static inline void dma_free_coherent(str
750
751 static inline int dma_mapping_error(struct device *dev, dma_addr_t daddr)
752 {
753- struct dma_map_ops *ops = platform_dma_get_ops(dev);
754+ const struct dma_map_ops *ops = platform_dma_get_ops(dev);
755 return ops->mapping_error(dev, daddr);
756 }
757
758 static inline int dma_supported(struct device *dev, u64 mask)
759 {
760- struct dma_map_ops *ops = platform_dma_get_ops(dev);
761+ const struct dma_map_ops *ops = platform_dma_get_ops(dev);
762 return ops->dma_supported(dev, mask);
763 }
764
16454cff
MT
765diff -urNp linux-2.6.38.1/arch/ia64/include/asm/elf.h linux-2.6.38.1/arch/ia64/include/asm/elf.h
766--- linux-2.6.38.1/arch/ia64/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
767+++ linux-2.6.38.1/arch/ia64/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 768@@ -42,6 +42,13 @@
58c5fc13
MT
769 */
770 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
771
772+#ifdef CONFIG_PAX_ASLR
773+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
774+
775+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
776+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
777+#endif
778+
779 #define PT_IA_64_UNWIND 0x70000001
780
781 /* IA-64 relocations: */
16454cff
MT
782diff -urNp linux-2.6.38.1/arch/ia64/include/asm/machvec.h linux-2.6.38.1/arch/ia64/include/asm/machvec.h
783--- linux-2.6.38.1/arch/ia64/include/asm/machvec.h 2011-03-14 21:20:32.000000000 -0400
784+++ linux-2.6.38.1/arch/ia64/include/asm/machvec.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
785@@ -45,7 +45,7 @@ typedef void ia64_mv_kernel_launch_event
786 /* DMA-mapping interface: */
787 typedef void ia64_mv_dma_init (void);
788 typedef u64 ia64_mv_dma_get_required_mask (struct device *);
789-typedef struct dma_map_ops *ia64_mv_dma_get_ops(struct device *);
790+typedef const struct dma_map_ops *ia64_mv_dma_get_ops(struct device *);
791
792 /*
793 * WARNING: The legacy I/O space is _architected_. Platforms are
794@@ -251,7 +251,7 @@ extern void machvec_init_from_cmdline(co
795 # endif /* CONFIG_IA64_GENERIC */
796
797 extern void swiotlb_dma_init(void);
798-extern struct dma_map_ops *dma_get_ops(struct device *);
799+extern const struct dma_map_ops *dma_get_ops(struct device *);
800
801 /*
802 * Define default versions so we can extend machvec for new platforms without having
16454cff
MT
803diff -urNp linux-2.6.38.1/arch/ia64/include/asm/pgtable.h linux-2.6.38.1/arch/ia64/include/asm/pgtable.h
804--- linux-2.6.38.1/arch/ia64/include/asm/pgtable.h 2011-03-14 21:20:32.000000000 -0400
805+++ linux-2.6.38.1/arch/ia64/include/asm/pgtable.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
806@@ -12,7 +12,7 @@
807 * David Mosberger-Tang <davidm@hpl.hp.com>
808 */
809
810-
811+#include <linux/const.h>
812 #include <asm/mman.h>
813 #include <asm/page.h>
814 #include <asm/processor.h>
58c5fc13
MT
815@@ -143,6 +143,17 @@
816 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
817 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
818 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
819+
820+#ifdef CONFIG_PAX_PAGEEXEC
821+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
822+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
823+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
824+#else
825+# define PAGE_SHARED_NOEXEC PAGE_SHARED
826+# define PAGE_READONLY_NOEXEC PAGE_READONLY
827+# define PAGE_COPY_NOEXEC PAGE_COPY
828+#endif
829+
830 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
831 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
832 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
16454cff
MT
833diff -urNp linux-2.6.38.1/arch/ia64/include/asm/spinlock.h linux-2.6.38.1/arch/ia64/include/asm/spinlock.h
834--- linux-2.6.38.1/arch/ia64/include/asm/spinlock.h 2011-03-14 21:20:32.000000000 -0400
835+++ linux-2.6.38.1/arch/ia64/include/asm/spinlock.h 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
836@@ -72,7 +72,7 @@ static __always_inline void __ticket_spi
837 unsigned short *p = (unsigned short *)&lock->lock + 1, tmp;
838
839 asm volatile ("ld2.bias %0=[%1]" : "=r"(tmp) : "r"(p));
840- ACCESS_ONCE(*p) = (tmp + 2) & ~1;
841+ ACCESS_ONCE_RW(*p) = (tmp + 2) & ~1;
842 }
843
844 static __always_inline void __ticket_spin_unlock_wait(arch_spinlock_t *lock)
16454cff
MT
845diff -urNp linux-2.6.38.1/arch/ia64/include/asm/uaccess.h linux-2.6.38.1/arch/ia64/include/asm/uaccess.h
846--- linux-2.6.38.1/arch/ia64/include/asm/uaccess.h 2011-03-14 21:20:32.000000000 -0400
847+++ linux-2.6.38.1/arch/ia64/include/asm/uaccess.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
848@@ -257,7 +257,7 @@ __copy_from_user (void *to, const void _
849 const void *__cu_from = (from); \
850 long __cu_len = (n); \
851 \
852- if (__access_ok(__cu_to, __cu_len, get_fs())) \
ae4e228f 853+ if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_to, __cu_len, get_fs())) \
58c5fc13
MT
854 __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
855 __cu_len; \
856 })
857@@ -269,7 +269,7 @@ __copy_from_user (void *to, const void _
858 long __cu_len = (n); \
859 \
860 __chk_user_ptr(__cu_from); \
861- if (__access_ok(__cu_from, __cu_len, get_fs())) \
ae4e228f 862+ if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_from, __cu_len, get_fs())) \
58c5fc13
MT
863 __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \
864 __cu_len; \
865 })
16454cff
MT
866diff -urNp linux-2.6.38.1/arch/ia64/kernel/dma-mapping.c linux-2.6.38.1/arch/ia64/kernel/dma-mapping.c
867--- linux-2.6.38.1/arch/ia64/kernel/dma-mapping.c 2011-03-14 21:20:32.000000000 -0400
868+++ linux-2.6.38.1/arch/ia64/kernel/dma-mapping.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
869@@ -3,7 +3,7 @@
870 /* Set this to 1 if there is a HW IOMMU in the system */
871 int iommu_detected __read_mostly;
872
873-struct dma_map_ops *dma_ops;
874+const struct dma_map_ops *dma_ops;
875 EXPORT_SYMBOL(dma_ops);
876
877 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
878@@ -16,7 +16,7 @@ static int __init dma_init(void)
879 }
880 fs_initcall(dma_init);
881
882-struct dma_map_ops *dma_get_ops(struct device *dev)
883+const struct dma_map_ops *dma_get_ops(struct device *dev)
884 {
885 return dma_ops;
886 }
16454cff
MT
887diff -urNp linux-2.6.38.1/arch/ia64/kernel/module.c linux-2.6.38.1/arch/ia64/kernel/module.c
888--- linux-2.6.38.1/arch/ia64/kernel/module.c 2011-03-14 21:20:32.000000000 -0400
889+++ linux-2.6.38.1/arch/ia64/kernel/module.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
890@@ -315,8 +315,7 @@ module_alloc (unsigned long size)
891 void
892 module_free (struct module *mod, void *module_region)
893 {
894- if (mod && mod->arch.init_unw_table &&
895- module_region == mod->module_init) {
896+ if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
897 unw_remove_unwind_table(mod->arch.init_unw_table);
898 mod->arch.init_unw_table = NULL;
899 }
900@@ -502,15 +501,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
901 }
902
903 static inline int
904+in_init_rx (const struct module *mod, uint64_t addr)
905+{
906+ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
907+}
908+
909+static inline int
910+in_init_rw (const struct module *mod, uint64_t addr)
911+{
912+ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
913+}
914+
915+static inline int
916 in_init (const struct module *mod, uint64_t addr)
917 {
918- return addr - (uint64_t) mod->module_init < mod->init_size;
919+ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
920+}
921+
922+static inline int
923+in_core_rx (const struct module *mod, uint64_t addr)
924+{
925+ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
926+}
927+
928+static inline int
929+in_core_rw (const struct module *mod, uint64_t addr)
930+{
931+ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
932 }
933
934 static inline int
935 in_core (const struct module *mod, uint64_t addr)
936 {
937- return addr - (uint64_t) mod->module_core < mod->core_size;
938+ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
939 }
940
941 static inline int
942@@ -693,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_
943 break;
944
945 case RV_BDREL:
946- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
947+ if (in_init_rx(mod, val))
948+ val -= (uint64_t) mod->module_init_rx;
949+ else if (in_init_rw(mod, val))
950+ val -= (uint64_t) mod->module_init_rw;
951+ else if (in_core_rx(mod, val))
952+ val -= (uint64_t) mod->module_core_rx;
953+ else if (in_core_rw(mod, val))
954+ val -= (uint64_t) mod->module_core_rw;
955 break;
956
957 case RV_LTV:
958@@ -828,15 +858,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
959 * addresses have been selected...
960 */
961 uint64_t gp;
962- if (mod->core_size > MAX_LTOFF)
963+ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
964 /*
965 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
966 * at the end of the module.
967 */
968- gp = mod->core_size - MAX_LTOFF / 2;
969+ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
970 else
971- gp = mod->core_size / 2;
972- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
973+ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
974+ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
975 mod->arch.gp = gp;
976 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
977 }
16454cff
MT
978diff -urNp linux-2.6.38.1/arch/ia64/kernel/pci-dma.c linux-2.6.38.1/arch/ia64/kernel/pci-dma.c
979--- linux-2.6.38.1/arch/ia64/kernel/pci-dma.c 2011-03-14 21:20:32.000000000 -0400
980+++ linux-2.6.38.1/arch/ia64/kernel/pci-dma.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
981@@ -43,7 +43,7 @@ struct device fallback_dev = {
982 .dma_mask = &fallback_dev.coherent_dma_mask,
983 };
984
985-extern struct dma_map_ops intel_dma_ops;
986+extern const struct dma_map_ops intel_dma_ops;
987
988 static int __init pci_iommu_init(void)
989 {
16454cff
MT
990diff -urNp linux-2.6.38.1/arch/ia64/kernel/pci-swiotlb.c linux-2.6.38.1/arch/ia64/kernel/pci-swiotlb.c
991--- linux-2.6.38.1/arch/ia64/kernel/pci-swiotlb.c 2011-03-14 21:20:32.000000000 -0400
992+++ linux-2.6.38.1/arch/ia64/kernel/pci-swiotlb.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 993@@ -22,7 +22,7 @@ static void *ia64_swiotlb_alloc_coherent
ae4e228f
MT
994 return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
995 }
996
997-struct dma_map_ops swiotlb_dma_ops = {
998+const struct dma_map_ops swiotlb_dma_ops = {
999 .alloc_coherent = ia64_swiotlb_alloc_coherent,
1000 .free_coherent = swiotlb_free_coherent,
1001 .map_page = swiotlb_map_page,
16454cff
MT
1002diff -urNp linux-2.6.38.1/arch/ia64/kernel/sys_ia64.c linux-2.6.38.1/arch/ia64/kernel/sys_ia64.c
1003--- linux-2.6.38.1/arch/ia64/kernel/sys_ia64.c 2011-03-14 21:20:32.000000000 -0400
1004+++ linux-2.6.38.1/arch/ia64/kernel/sys_ia64.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
1005@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
1006 if (REGION_NUMBER(addr) == RGN_HPAGE)
1007 addr = 0;
1008 #endif
1009+
1010+#ifdef CONFIG_PAX_RANDMMAP
1011+ if (mm->pax_flags & MF_PAX_RANDMMAP)
1012+ addr = mm->free_area_cache;
1013+ else
1014+#endif
1015+
1016 if (!addr)
1017 addr = mm->free_area_cache;
1018
57199397 1019@@ -61,14 +68,14 @@ arch_get_unmapped_area (struct file *fil
58c5fc13
MT
1020 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
1021 /* At this point: (!vma || addr < vma->vm_end). */
1022 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
1023- if (start_addr != TASK_UNMAPPED_BASE) {
1024+ if (start_addr != mm->mmap_base) {
1025 /* Start a new search --- just in case we missed some holes. */
1026- addr = TASK_UNMAPPED_BASE;
1027+ addr = mm->mmap_base;
1028 goto full_search;
1029 }
1030 return -ENOMEM;
57199397
MT
1031 }
1032- if (!vma || addr + len <= vma->vm_start) {
1033+ if (check_heap_stack_gap(vma, addr, len)) {
1034 /* Remember the address where we stopped this search: */
1035 mm->free_area_cache = addr + len;
1036 return addr;
16454cff
MT
1037diff -urNp linux-2.6.38.1/arch/ia64/kernel/vmlinux.lds.S linux-2.6.38.1/arch/ia64/kernel/vmlinux.lds.S
1038--- linux-2.6.38.1/arch/ia64/kernel/vmlinux.lds.S 2011-03-14 21:20:32.000000000 -0400
1039+++ linux-2.6.38.1/arch/ia64/kernel/vmlinux.lds.S 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
1040@@ -199,7 +199,7 @@ SECTIONS {
1041 /* Per-cpu data: */
1042 . = ALIGN(PERCPU_PAGE_SIZE);
1043 PERCPU_VADDR(PERCPU_ADDR, :percpu)
1044- __phys_per_cpu_start = __per_cpu_load;
1045+ __phys_per_cpu_start = per_cpu_load;
1046 /*
1047 * ensure percpu data fits
1048 * into percpu page size
16454cff
MT
1049diff -urNp linux-2.6.38.1/arch/ia64/mm/fault.c linux-2.6.38.1/arch/ia64/mm/fault.c
1050--- linux-2.6.38.1/arch/ia64/mm/fault.c 2011-03-14 21:20:32.000000000 -0400
1051+++ linux-2.6.38.1/arch/ia64/mm/fault.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
1052@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
1053 return pte_present(pte);
1054 }
1055
1056+#ifdef CONFIG_PAX_PAGEEXEC
1057+void pax_report_insns(void *pc, void *sp)
1058+{
1059+ unsigned long i;
1060+
1061+ printk(KERN_ERR "PAX: bytes at PC: ");
1062+ for (i = 0; i < 8; i++) {
1063+ unsigned int c;
1064+ if (get_user(c, (unsigned int *)pc+i))
1065+ printk(KERN_CONT "???????? ");
1066+ else
1067+ printk(KERN_CONT "%08x ", c);
1068+ }
1069+ printk("\n");
1070+}
1071+#endif
1072+
1073 void __kprobes
1074 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
1075 {
1076@@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
1077 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
1078 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
1079
1080- if ((vma->vm_flags & mask) != mask)
1081+ if ((vma->vm_flags & mask) != mask) {
1082+
1083+#ifdef CONFIG_PAX_PAGEEXEC
1084+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
1085+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
1086+ goto bad_area;
1087+
1088+ up_read(&mm->mmap_sem);
1089+ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
1090+ do_group_exit(SIGKILL);
1091+ }
1092+#endif
1093+
1094 goto bad_area;
1095
1096+ }
1097+
58c5fc13
MT
1098 /*
1099 * If for any reason at all we couldn't handle the fault, make
57199397 1100 * sure we exit gracefully rather than endlessly redo the
16454cff
MT
1101diff -urNp linux-2.6.38.1/arch/ia64/mm/hugetlbpage.c linux-2.6.38.1/arch/ia64/mm/hugetlbpage.c
1102--- linux-2.6.38.1/arch/ia64/mm/hugetlbpage.c 2011-03-14 21:20:32.000000000 -0400
1103+++ linux-2.6.38.1/arch/ia64/mm/hugetlbpage.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
1104@@ -171,7 +171,7 @@ unsigned long hugetlb_get_unmapped_area(
1105 /* At this point: (!vmm || addr < vmm->vm_end). */
1106 if (REGION_OFFSET(addr) + len > RGN_MAP_LIMIT)
1107 return -ENOMEM;
1108- if (!vmm || (addr + len) <= vmm->vm_start)
1109+ if (check_heap_stack_gap(vmm, addr, len))
1110 return addr;
1111 addr = ALIGN(vmm->vm_end, HPAGE_SIZE);
1112 }
16454cff
MT
1113diff -urNp linux-2.6.38.1/arch/ia64/mm/init.c linux-2.6.38.1/arch/ia64/mm/init.c
1114--- linux-2.6.38.1/arch/ia64/mm/init.c 2011-03-14 21:20:32.000000000 -0400
1115+++ linux-2.6.38.1/arch/ia64/mm/init.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
1116@@ -122,6 +122,19 @@ ia64_init_addr_space (void)
1117 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
1118 vma->vm_end = vma->vm_start + PAGE_SIZE;
1119 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
1120+
1121+#ifdef CONFIG_PAX_PAGEEXEC
1122+ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
1123+ vma->vm_flags &= ~VM_EXEC;
1124+
1125+#ifdef CONFIG_PAX_MPROTECT
1126+ if (current->mm->pax_flags & MF_PAX_MPROTECT)
1127+ vma->vm_flags &= ~VM_MAYEXEC;
1128+#endif
1129+
1130+ }
1131+#endif
1132+
1133 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1134 down_write(&current->mm->mmap_sem);
1135 if (insert_vm_struct(current->mm, vma)) {
16454cff
MT
1136diff -urNp linux-2.6.38.1/arch/ia64/sn/pci/pci_dma.c linux-2.6.38.1/arch/ia64/sn/pci/pci_dma.c
1137--- linux-2.6.38.1/arch/ia64/sn/pci/pci_dma.c 2011-03-14 21:20:32.000000000 -0400
1138+++ linux-2.6.38.1/arch/ia64/sn/pci/pci_dma.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 1139@@ -465,7 +465,7 @@ int sn_pci_legacy_write(struct pci_bus *
ae4e228f 1140 return ret;
58c5fc13
MT
1141 }
1142
ae4e228f
MT
1143-static struct dma_map_ops sn_dma_ops = {
1144+static const struct dma_map_ops sn_dma_ops = {
1145 .alloc_coherent = sn_dma_alloc_coherent,
1146 .free_coherent = sn_dma_free_coherent,
1147 .map_page = sn_dma_map_page,
16454cff
MT
1148diff -urNp linux-2.6.38.1/arch/m32r/lib/usercopy.c linux-2.6.38.1/arch/m32r/lib/usercopy.c
1149--- linux-2.6.38.1/arch/m32r/lib/usercopy.c 2011-03-14 21:20:32.000000000 -0400
1150+++ linux-2.6.38.1/arch/m32r/lib/usercopy.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
1151@@ -14,6 +14,9 @@
1152 unsigned long
1153 __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
1154 {
1155+ if ((long)n < 0)
1156+ return n;
1157+
1158 prefetch(from);
1159 if (access_ok(VERIFY_WRITE, to, n))
1160 __copy_user(to,from,n);
1161@@ -23,6 +26,9 @@ __generic_copy_to_user(void __user *to,
1162 unsigned long
1163 __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
1164 {
1165+ if ((long)n < 0)
1166+ return n;
1167+
1168 prefetchw(to);
1169 if (access_ok(VERIFY_READ, from, n))
1170 __copy_user_zeroing(to,from,n);
16454cff
MT
1171diff -urNp linux-2.6.38.1/arch/microblaze/include/asm/device.h linux-2.6.38.1/arch/microblaze/include/asm/device.h
1172--- linux-2.6.38.1/arch/microblaze/include/asm/device.h 2011-03-14 21:20:32.000000000 -0400
1173+++ linux-2.6.38.1/arch/microblaze/include/asm/device.h 2011-03-21 18:31:35.000000000 -0400
57199397 1174@@ -13,7 +13,7 @@ struct device_node;
df50ba0c 1175
57199397 1176 struct dev_archdata {
df50ba0c
MT
1177 /* DMA operations on that device */
1178- struct dma_map_ops *dma_ops;
1179+ const struct dma_map_ops *dma_ops;
1180 void *dma_data;
1181 };
1182
16454cff
MT
1183diff -urNp linux-2.6.38.1/arch/microblaze/include/asm/dma-mapping.h linux-2.6.38.1/arch/microblaze/include/asm/dma-mapping.h
1184--- linux-2.6.38.1/arch/microblaze/include/asm/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
1185+++ linux-2.6.38.1/arch/microblaze/include/asm/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
1186@@ -43,14 +43,14 @@ static inline unsigned long device_to_ma
1187 return 0xfffffffful;
1188 }
1189
1190-extern struct dma_map_ops *dma_ops;
1191+extern const struct dma_map_ops *dma_ops;
1192
1193 /*
1194 * Available generic sets of operations
1195 */
1196-extern struct dma_map_ops dma_direct_ops;
1197+extern const struct dma_map_ops dma_direct_ops;
1198
1199-static inline struct dma_map_ops *get_dma_ops(struct device *dev)
1200+static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
1201 {
1202 /* We don't handle the NULL dev case for ISA for now. We could
1203 * do it via an out of line call but it is not needed for now. The
1204@@ -63,14 +63,14 @@ static inline struct dma_map_ops *get_dm
1205 return dev->archdata.dma_ops;
1206 }
1207
1208-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
1209+static inline void set_dma_ops(struct device *dev, const struct dma_map_ops *ops)
1210 {
1211 dev->archdata.dma_ops = ops;
1212 }
1213
1214 static inline int dma_supported(struct device *dev, u64 mask)
1215 {
1216- struct dma_map_ops *ops = get_dma_ops(dev);
1217+ const struct dma_map_ops *ops = get_dma_ops(dev);
1218
1219 if (unlikely(!ops))
1220 return 0;
6892158b 1221@@ -81,7 +81,7 @@ static inline int dma_supported(struct d
df50ba0c
MT
1222
1223 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
1224 {
1225- struct dma_map_ops *ops = get_dma_ops(dev);
1226+ const struct dma_map_ops *ops = get_dma_ops(dev);
1227
1228 if (unlikely(ops == NULL))
1229 return -EIO;
6892158b 1230@@ -97,7 +97,7 @@ static inline int dma_set_mask(struct de
df50ba0c
MT
1231
1232 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
1233 {
1234- struct dma_map_ops *ops = get_dma_ops(dev);
1235+ const struct dma_map_ops *ops = get_dma_ops(dev);
1236 if (ops->mapping_error)
1237 return ops->mapping_error(dev, dma_addr);
1238
6892158b 1239@@ -110,7 +110,7 @@ static inline int dma_mapping_error(stru
df50ba0c
MT
1240 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
1241 dma_addr_t *dma_handle, gfp_t flag)
1242 {
1243- struct dma_map_ops *ops = get_dma_ops(dev);
1244+ const struct dma_map_ops *ops = get_dma_ops(dev);
1245 void *memory;
1246
1247 BUG_ON(!ops);
6892158b 1248@@ -124,7 +124,7 @@ static inline void *dma_alloc_coherent(s
df50ba0c
MT
1249 static inline void dma_free_coherent(struct device *dev, size_t size,
1250 void *cpu_addr, dma_addr_t dma_handle)
1251 {
1252- struct dma_map_ops *ops = get_dma_ops(dev);
1253+ const struct dma_map_ops *ops = get_dma_ops(dev);
1254
1255 BUG_ON(!ops);
1256 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
16454cff
MT
1257diff -urNp linux-2.6.38.1/arch/microblaze/include/asm/pci.h linux-2.6.38.1/arch/microblaze/include/asm/pci.h
1258--- linux-2.6.38.1/arch/microblaze/include/asm/pci.h 2011-03-14 21:20:32.000000000 -0400
1259+++ linux-2.6.38.1/arch/microblaze/include/asm/pci.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
1260@@ -54,8 +54,8 @@ static inline void pcibios_penalize_isa_
1261 }
1262
1263 #ifdef CONFIG_PCI
1264-extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
1265-extern struct dma_map_ops *get_pci_dma_ops(void);
1266+extern void set_pci_dma_ops(const struct dma_map_ops *dma_ops);
1267+extern const struct dma_map_ops *get_pci_dma_ops(void);
1268 #else /* CONFIG_PCI */
1269 #define set_pci_dma_ops(d)
1270 #define get_pci_dma_ops() NULL
16454cff
MT
1271diff -urNp linux-2.6.38.1/arch/microblaze/kernel/dma.c linux-2.6.38.1/arch/microblaze/kernel/dma.c
1272--- linux-2.6.38.1/arch/microblaze/kernel/dma.c 2011-03-14 21:20:32.000000000 -0400
1273+++ linux-2.6.38.1/arch/microblaze/kernel/dma.c 2011-03-21 18:31:35.000000000 -0400
57199397 1274@@ -133,7 +133,7 @@ static inline void dma_direct_unmap_page
df50ba0c
MT
1275 __dma_sync_page(dma_address, 0 , size, direction);
1276 }
1277
1278-struct dma_map_ops dma_direct_ops = {
1279+const struct dma_map_ops dma_direct_ops = {
1280 .alloc_coherent = dma_direct_alloc_coherent,
1281 .free_coherent = dma_direct_free_coherent,
1282 .map_sg = dma_direct_map_sg,
16454cff
MT
1283diff -urNp linux-2.6.38.1/arch/microblaze/kernel/kgdb.c linux-2.6.38.1/arch/microblaze/kernel/kgdb.c
1284--- linux-2.6.38.1/arch/microblaze/kernel/kgdb.c 2011-03-14 21:20:32.000000000 -0400
1285+++ linux-2.6.38.1/arch/microblaze/kernel/kgdb.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 1286@@ -141,10 +141,11 @@ void kgdb_arch_exit(void)
6892158b
MT
1287 /*
1288 * Global data
1289 */
1290-struct kgdb_arch arch_kgdb_ops = {
1291+const struct kgdb_arch arch_kgdb_ops = {
bc901d79
MT
1292 #ifdef __MICROBLAZEEL__
1293 .gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
1294 #else
1295+>>>>>>> master
6892158b 1296 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
bc901d79 1297 #endif
6892158b 1298 };
16454cff
MT
1299diff -urNp linux-2.6.38.1/arch/microblaze/pci/pci-common.c linux-2.6.38.1/arch/microblaze/pci/pci-common.c
1300--- linux-2.6.38.1/arch/microblaze/pci/pci-common.c 2011-03-14 21:20:32.000000000 -0400
1301+++ linux-2.6.38.1/arch/microblaze/pci/pci-common.c 2011-03-21 18:31:35.000000000 -0400
6892158b 1302@@ -47,14 +47,14 @@ resource_size_t isa_mem_base;
df50ba0c
MT
1303 /* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
1304 unsigned int pci_flags;
1305
1306-static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
1307+static const struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
1308
1309-void set_pci_dma_ops(struct dma_map_ops *dma_ops)
1310+void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
1311 {
1312 pci_dma_ops = dma_ops;
1313 }
1314
1315-struct dma_map_ops *get_pci_dma_ops(void)
1316+const struct dma_map_ops *get_pci_dma_ops(void)
1317 {
1318 return pci_dma_ops;
1319 }
16454cff
MT
1320diff -urNp linux-2.6.38.1/arch/mips/cavium-octeon/dma-octeon.c linux-2.6.38.1/arch/mips/cavium-octeon/dma-octeon.c
1321--- linux-2.6.38.1/arch/mips/cavium-octeon/dma-octeon.c 2011-03-14 21:20:32.000000000 -0400
1322+++ linux-2.6.38.1/arch/mips/cavium-octeon/dma-octeon.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
1323@@ -202,7 +202,7 @@ static phys_addr_t octeon_unity_dma_to_p
1324 }
1325
1326 struct octeon_dma_map_ops {
1327- struct dma_map_ops dma_map_ops;
1328+ const struct dma_map_ops dma_map_ops;
1329 dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr);
1330 phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr);
1331 };
1332@@ -324,7 +324,7 @@ static struct octeon_dma_map_ops _octeon
1333 },
1334 };
1335
1336-struct dma_map_ops *octeon_pci_dma_map_ops;
1337+const struct dma_map_ops *octeon_pci_dma_map_ops;
1338
1339 void __init octeon_pci_dma_init(void)
1340 {
16454cff
MT
1341diff -urNp linux-2.6.38.1/arch/mips/include/asm/device.h linux-2.6.38.1/arch/mips/include/asm/device.h
1342--- linux-2.6.38.1/arch/mips/include/asm/device.h 2011-03-14 21:20:32.000000000 -0400
1343+++ linux-2.6.38.1/arch/mips/include/asm/device.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
1344@@ -10,7 +10,7 @@ struct dma_map_ops;
1345
1346 struct dev_archdata {
1347 /* DMA operations on that device */
1348- struct dma_map_ops *dma_ops;
1349+ const struct dma_map_ops *dma_ops;
1350 };
1351
1352 struct pdev_archdata {
16454cff
MT
1353diff -urNp linux-2.6.38.1/arch/mips/include/asm/dma-mapping.h linux-2.6.38.1/arch/mips/include/asm/dma-mapping.h
1354--- linux-2.6.38.1/arch/mips/include/asm/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
1355+++ linux-2.6.38.1/arch/mips/include/asm/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
1356@@ -7,9 +7,9 @@
1357
1358 #include <dma-coherence.h>
1359
1360-extern struct dma_map_ops *mips_dma_map_ops;
1361+extern const struct dma_map_ops *mips_dma_map_ops;
1362
1363-static inline struct dma_map_ops *get_dma_ops(struct device *dev)
1364+static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
1365 {
1366 if (dev && dev->archdata.dma_ops)
1367 return dev->archdata.dma_ops;
1368@@ -31,13 +31,13 @@ static inline void dma_mark_clean(void *
1369
1370 static inline int dma_supported(struct device *dev, u64 mask)
1371 {
1372- struct dma_map_ops *ops = get_dma_ops(dev);
1373+ const struct dma_map_ops *ops = get_dma_ops(dev);
1374 return ops->dma_supported(dev, mask);
1375 }
1376
1377 static inline int dma_mapping_error(struct device *dev, u64 mask)
1378 {
1379- struct dma_map_ops *ops = get_dma_ops(dev);
1380+ const struct dma_map_ops *ops = get_dma_ops(dev);
1381 return ops->mapping_error(dev, mask);
1382 }
1383
1384@@ -59,7 +59,7 @@ static inline void *dma_alloc_coherent(s
1385 dma_addr_t *dma_handle, gfp_t gfp)
1386 {
1387 void *ret;
1388- struct dma_map_ops *ops = get_dma_ops(dev);
1389+ const struct dma_map_ops *ops = get_dma_ops(dev);
1390
1391 ret = ops->alloc_coherent(dev, size, dma_handle, gfp);
1392
1393@@ -71,7 +71,7 @@ static inline void *dma_alloc_coherent(s
1394 static inline void dma_free_coherent(struct device *dev, size_t size,
1395 void *vaddr, dma_addr_t dma_handle)
1396 {
1397- struct dma_map_ops *ops = get_dma_ops(dev);
1398+ const struct dma_map_ops *ops = get_dma_ops(dev);
1399
1400 ops->free_coherent(dev, size, vaddr, dma_handle);
1401
16454cff
MT
1402diff -urNp linux-2.6.38.1/arch/mips/include/asm/elf.h linux-2.6.38.1/arch/mips/include/asm/elf.h
1403--- linux-2.6.38.1/arch/mips/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
1404+++ linux-2.6.38.1/arch/mips/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 1405@@ -372,13 +372,16 @@ extern const char *__elf_platform;
58c5fc13
MT
1406 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
1407 #endif
1408
1409+#ifdef CONFIG_PAX_ASLR
1410+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1411+
1412+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1413+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1414+#endif
1415+
df50ba0c
MT
1416 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
1417 struct linux_binprm;
1418 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
bc901d79
MT
1419 int uses_interp);
1420
1421-struct mm_struct;
1422-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
1423-#define arch_randomize_brk arch_randomize_brk
1424-
1425 #endif /* _ASM_ELF_H */
16454cff
MT
1426diff -urNp linux-2.6.38.1/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h linux-2.6.38.1/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
1427--- linux-2.6.38.1/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h 2011-03-14 21:20:32.000000000 -0400
1428+++ linux-2.6.38.1/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
1429@@ -66,7 +66,7 @@ dma_addr_t phys_to_dma(struct device *de
1430 phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
1431
1432 struct dma_map_ops;
1433-extern struct dma_map_ops *octeon_pci_dma_map_ops;
1434+extern const struct dma_map_ops *octeon_pci_dma_map_ops;
1435 extern char *octeon_swiotlb;
1436
1437 #endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
16454cff
MT
1438diff -urNp linux-2.6.38.1/arch/mips/include/asm/page.h linux-2.6.38.1/arch/mips/include/asm/page.h
1439--- linux-2.6.38.1/arch/mips/include/asm/page.h 2011-03-14 21:20:32.000000000 -0400
1440+++ linux-2.6.38.1/arch/mips/include/asm/page.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 1441@@ -93,7 +93,7 @@ extern void copy_user_highpage(struct pa
58c5fc13
MT
1442 #ifdef CONFIG_CPU_MIPS32
1443 typedef struct { unsigned long pte_low, pte_high; } pte_t;
1444 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
1445- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
1446+ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
1447 #else
1448 typedef struct { unsigned long long pte; } pte_t;
1449 #define pte_val(x) ((x).pte)
16454cff
MT
1450diff -urNp linux-2.6.38.1/arch/mips/include/asm/system.h linux-2.6.38.1/arch/mips/include/asm/system.h
1451--- linux-2.6.38.1/arch/mips/include/asm/system.h 2011-03-14 21:20:32.000000000 -0400
1452+++ linux-2.6.38.1/arch/mips/include/asm/system.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
1453@@ -23,6 +23,7 @@
1454 #include <asm/dsp.h>
1455 #include <asm/watch.h>
1456 #include <asm/war.h>
1457+#include <asm/asm.h>
1458
1459
1460 /*
1461@@ -230,6 +231,6 @@ extern void per_cpu_trap_init(void);
58c5fc13
MT
1462 */
1463 #define __ARCH_WANT_UNLOCKED_CTXSW
1464
1465-extern unsigned long arch_align_stack(unsigned long sp);
1466+#define arch_align_stack(x) ((x) & ALMASK)
1467
1468 #endif /* _ASM_SYSTEM_H */
16454cff
MT
1469diff -urNp linux-2.6.38.1/arch/mips/kernel/binfmt_elfn32.c linux-2.6.38.1/arch/mips/kernel/binfmt_elfn32.c
1470--- linux-2.6.38.1/arch/mips/kernel/binfmt_elfn32.c 2011-03-14 21:20:32.000000000 -0400
1471+++ linux-2.6.38.1/arch/mips/kernel/binfmt_elfn32.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
1472@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
1473 #undef ELF_ET_DYN_BASE
1474 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1475
1476+#ifdef CONFIG_PAX_ASLR
1477+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1478+
1479+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1480+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1481+#endif
1482+
1483 #include <asm/processor.h>
1484 #include <linux/module.h>
1485 #include <linux/elfcore.h>
16454cff
MT
1486diff -urNp linux-2.6.38.1/arch/mips/kernel/binfmt_elfo32.c linux-2.6.38.1/arch/mips/kernel/binfmt_elfo32.c
1487--- linux-2.6.38.1/arch/mips/kernel/binfmt_elfo32.c 2011-03-14 21:20:32.000000000 -0400
1488+++ linux-2.6.38.1/arch/mips/kernel/binfmt_elfo32.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
1489@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
1490 #undef ELF_ET_DYN_BASE
1491 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1492
1493+#ifdef CONFIG_PAX_ASLR
1494+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1495+
1496+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1497+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1498+#endif
1499+
1500 #include <asm/processor.h>
1501
1502 /*
16454cff
MT
1503diff -urNp linux-2.6.38.1/arch/mips/kernel/kgdb.c linux-2.6.38.1/arch/mips/kernel/kgdb.c
1504--- linux-2.6.38.1/arch/mips/kernel/kgdb.c 2011-03-14 21:20:32.000000000 -0400
1505+++ linux-2.6.38.1/arch/mips/kernel/kgdb.c 2011-03-21 18:31:35.000000000 -0400
1506@@ -351,7 +351,7 @@ int kgdb_arch_handle_exception(int vecto
ae4e228f
MT
1507 return -1;
1508 }
1509
16454cff
MT
1510-struct kgdb_arch arch_kgdb_ops;
1511+struct kgdb_arch arch_kgdb_ops; /* cannot be const, see kgdb_arch_init */
ae4e228f
MT
1512
1513 /*
16454cff
MT
1514 * We use kgdb_early_setup so that functions we need to call now don't
1515diff -urNp linux-2.6.38.1/arch/mips/kernel/process.c linux-2.6.38.1/arch/mips/kernel/process.c
1516--- linux-2.6.38.1/arch/mips/kernel/process.c 2011-03-14 21:20:32.000000000 -0400
1517+++ linux-2.6.38.1/arch/mips/kernel/process.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 1518@@ -473,15 +473,3 @@ unsigned long get_wchan(struct task_stru
58c5fc13
MT
1519 out:
1520 return pc;
1521 }
1522-
1523-/*
1524- * Don't forget that the stack pointer must be aligned on a 8 bytes
1525- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
1526- */
1527-unsigned long arch_align_stack(unsigned long sp)
1528-{
1529- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
1530- sp -= get_random_int() & ~PAGE_MASK;
1531-
1532- return sp & ALMASK;
1533-}
16454cff
MT
1534diff -urNp linux-2.6.38.1/arch/mips/kernel/syscall.c linux-2.6.38.1/arch/mips/kernel/syscall.c
1535--- linux-2.6.38.1/arch/mips/kernel/syscall.c 2011-03-14 21:20:32.000000000 -0400
1536+++ linux-2.6.38.1/arch/mips/kernel/syscall.c 2011-03-21 18:31:35.000000000 -0400
6892158b 1537@@ -108,14 +108,18 @@ unsigned long arch_get_unmapped_area(str
58c5fc13
MT
1538 do_color_align = 0;
1539 if (filp || (flags & MAP_SHARED))
1540 do_color_align = 1;
1541+
1542+#ifdef CONFIG_PAX_RANDMMAP
1543+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
1544+#endif
1545+
1546 if (addr) {
1547 if (do_color_align)
1548 addr = COLOUR_ALIGN(addr, pgoff);
57199397
MT
1549 else
1550 addr = PAGE_ALIGN(addr);
1551 vmm = find_vma(current->mm, addr);
1552- if (task_size - len >= addr &&
1553- (!vmm || addr + len <= vmm->vm_start))
1554+ if (task_size - len >= addr && check_heap_stack_gap(vmm, addr, len))
58c5fc13
MT
1555 return addr;
1556 }
6892158b
MT
1557 addr = current->mm->mmap_base;
1558@@ -128,7 +132,7 @@ unsigned long arch_get_unmapped_area(str
57199397
MT
1559 /* At this point: (!vmm || addr < vmm->vm_end). */
1560 if (task_size - len < addr)
1561 return -ENOMEM;
1562- if (!vmm || addr + len <= vmm->vm_start)
1563+ if (check_heap_stack_gap(vmm, addr, len))
1564 return addr;
1565 addr = vmm->vm_end;
1566 if (do_color_align)
bc901d79
MT
1567@@ -168,19 +172,6 @@ static inline unsigned long brk_rnd(void
1568 return rnd;
1569 }
1570
1571-unsigned long arch_randomize_brk(struct mm_struct *mm)
1572-{
1573- unsigned long base = mm->brk;
1574- unsigned long ret;
1575-
1576- ret = PAGE_ALIGN(base + brk_rnd());
1577-
1578- if (ret < mm->brk)
1579- return mm->brk;
1580-
1581- return ret;
1582-}
1583-
1584 SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
1585 unsigned long, prot, unsigned long, flags, unsigned long,
1586 fd, off_t, offset)
16454cff
MT
1587diff -urNp linux-2.6.38.1/arch/mips/mm/dma-default.c linux-2.6.38.1/arch/mips/mm/dma-default.c
1588--- linux-2.6.38.1/arch/mips/mm/dma-default.c 2011-03-14 21:20:32.000000000 -0400
1589+++ linux-2.6.38.1/arch/mips/mm/dma-default.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
1590@@ -300,7 +300,7 @@ void dma_cache_sync(struct device *dev,
1591
1592 EXPORT_SYMBOL(dma_cache_sync);
1593
1594-static struct dma_map_ops mips_default_dma_map_ops = {
1595+static const struct dma_map_ops mips_default_dma_map_ops = {
1596 .alloc_coherent = mips_dma_alloc_coherent,
1597 .free_coherent = mips_dma_free_coherent,
1598 .map_page = mips_dma_map_page,
1599@@ -315,7 +315,7 @@ static struct dma_map_ops mips_default_d
1600 .dma_supported = mips_dma_supported
1601 };
1602
1603-struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
1604+const struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
1605 EXPORT_SYMBOL(mips_dma_map_ops);
1606
1607 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
16454cff
MT
1608diff -urNp linux-2.6.38.1/arch/mips/mm/fault.c linux-2.6.38.1/arch/mips/mm/fault.c
1609--- linux-2.6.38.1/arch/mips/mm/fault.c 2011-03-14 21:20:32.000000000 -0400
1610+++ linux-2.6.38.1/arch/mips/mm/fault.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 1611@@ -28,6 +28,23 @@
58c5fc13 1612 #include <asm/highmem.h> /* For VMALLOC_END */
6892158b 1613 #include <linux/kdebug.h>
58c5fc13
MT
1614
1615+#ifdef CONFIG_PAX_PAGEEXEC
6892158b 1616+void pax_report_insns(void *pc, void *sp)
58c5fc13
MT
1617+{
1618+ unsigned long i;
1619+
1620+ printk(KERN_ERR "PAX: bytes at PC: ");
1621+ for (i = 0; i < 5; i++) {
1622+ unsigned int c;
1623+ if (get_user(c, (unsigned int *)pc+i))
1624+ printk(KERN_CONT "???????? ");
1625+ else
1626+ printk(KERN_CONT "%08x ", c);
1627+ }
1628+ printk("\n");
1629+}
1630+#endif
1631+
1632 /*
1633 * This routine handles page faults. It determines the address,
1634 * and the problem, and then passes it off to one of the appropriate
16454cff
MT
1635diff -urNp linux-2.6.38.1/arch/parisc/include/asm/elf.h linux-2.6.38.1/arch/parisc/include/asm/elf.h
1636--- linux-2.6.38.1/arch/parisc/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
1637+++ linux-2.6.38.1/arch/parisc/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 1638@@ -342,6 +342,13 @@ struct pt_regs; /* forward declaration..
58c5fc13
MT
1639
1640 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
1641
1642+#ifdef CONFIG_PAX_ASLR
1643+#define PAX_ELF_ET_DYN_BASE 0x10000UL
1644+
1645+#define PAX_DELTA_MMAP_LEN 16
1646+#define PAX_DELTA_STACK_LEN 16
1647+#endif
1648+
1649 /* This yields a mask that user programs can use to figure out what
1650 instruction set this CPU supports. This could be done in user space,
1651 but it's not easy, and we've already done it here. */
16454cff
MT
1652diff -urNp linux-2.6.38.1/arch/parisc/include/asm/pgtable.h linux-2.6.38.1/arch/parisc/include/asm/pgtable.h
1653--- linux-2.6.38.1/arch/parisc/include/asm/pgtable.h 2011-03-14 21:20:32.000000000 -0400
1654+++ linux-2.6.38.1/arch/parisc/include/asm/pgtable.h 2011-03-21 18:31:35.000000000 -0400
1655@@ -209,6 +209,17 @@ struct vm_area_struct;
58c5fc13
MT
1656 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
1657 #define PAGE_COPY PAGE_EXECREAD
1658 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
1659+
1660+#ifdef CONFIG_PAX_PAGEEXEC
1661+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
1662+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
1663+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
1664+#else
1665+# define PAGE_SHARED_NOEXEC PAGE_SHARED
1666+# define PAGE_COPY_NOEXEC PAGE_COPY
1667+# define PAGE_READONLY_NOEXEC PAGE_READONLY
1668+#endif
1669+
1670 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
1671 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
1672 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
16454cff
MT
1673diff -urNp linux-2.6.38.1/arch/parisc/kernel/module.c linux-2.6.38.1/arch/parisc/kernel/module.c
1674--- linux-2.6.38.1/arch/parisc/kernel/module.c 2011-03-14 21:20:32.000000000 -0400
1675+++ linux-2.6.38.1/arch/parisc/kernel/module.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 1676@@ -96,16 +96,38 @@
58c5fc13
MT
1677
1678 /* three functions to determine where in the module core
1679 * or init pieces the location is */
1680+static inline int in_init_rx(struct module *me, void *loc)
1681+{
1682+ return (loc >= me->module_init_rx &&
1683+ loc < (me->module_init_rx + me->init_size_rx));
1684+}
1685+
1686+static inline int in_init_rw(struct module *me, void *loc)
1687+{
1688+ return (loc >= me->module_init_rw &&
1689+ loc < (me->module_init_rw + me->init_size_rw));
1690+}
1691+
1692 static inline int in_init(struct module *me, void *loc)
1693 {
1694- return (loc >= me->module_init &&
1695- loc <= (me->module_init + me->init_size));
1696+ return in_init_rx(me, loc) || in_init_rw(me, loc);
1697+}
1698+
1699+static inline int in_core_rx(struct module *me, void *loc)
1700+{
1701+ return (loc >= me->module_core_rx &&
1702+ loc < (me->module_core_rx + me->core_size_rx));
1703+}
1704+
1705+static inline int in_core_rw(struct module *me, void *loc)
1706+{
1707+ return (loc >= me->module_core_rw &&
1708+ loc < (me->module_core_rw + me->core_size_rw));
1709 }
1710
1711 static inline int in_core(struct module *me, void *loc)
1712 {
1713- return (loc >= me->module_core &&
1714- loc <= (me->module_core + me->core_size));
1715+ return in_core_rx(me, loc) || in_core_rw(me, loc);
1716 }
1717
1718 static inline int in_local(struct module *me, void *loc)
df50ba0c 1719@@ -365,13 +387,13 @@ int module_frob_arch_sections(CONST Elf_
58c5fc13
MT
1720 }
1721
1722 /* align things a bit */
1723- me->core_size = ALIGN(me->core_size, 16);
1724- me->arch.got_offset = me->core_size;
1725- me->core_size += gots * sizeof(struct got_entry);
1726-
1727- me->core_size = ALIGN(me->core_size, 16);
1728- me->arch.fdesc_offset = me->core_size;
1729- me->core_size += fdescs * sizeof(Elf_Fdesc);
1730+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
1731+ me->arch.got_offset = me->core_size_rw;
1732+ me->core_size_rw += gots * sizeof(struct got_entry);
1733+
1734+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
1735+ me->arch.fdesc_offset = me->core_size_rw;
1736+ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
1737
1738 me->arch.got_max = gots;
1739 me->arch.fdesc_max = fdescs;
df50ba0c 1740@@ -389,7 +411,7 @@ static Elf64_Word get_got(struct module
58c5fc13
MT
1741
1742 BUG_ON(value == 0);
1743
1744- got = me->module_core + me->arch.got_offset;
1745+ got = me->module_core_rw + me->arch.got_offset;
1746 for (i = 0; got[i].addr; i++)
1747 if (got[i].addr == value)
1748 goto out;
df50ba0c 1749@@ -407,7 +429,7 @@ static Elf64_Word get_got(struct module
58c5fc13
MT
1750 #ifdef CONFIG_64BIT
1751 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
1752 {
1753- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
1754+ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
1755
1756 if (!value) {
1757 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
df50ba0c 1758@@ -425,7 +447,7 @@ static Elf_Addr get_fdesc(struct module
58c5fc13
MT
1759
1760 /* Create new one */
1761 fdesc->addr = value;
1762- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1763+ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1764 return (Elf_Addr)fdesc;
1765 }
1766 #endif /* CONFIG_64BIT */
df50ba0c 1767@@ -849,7 +871,7 @@ register_unwind_table(struct module *me,
58c5fc13
MT
1768
1769 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
1770 end = table + sechdrs[me->arch.unwind_section].sh_size;
1771- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1772+ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1773
1774 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
1775 me->arch.unwind_section, table, end, gp);
16454cff
MT
1776diff -urNp linux-2.6.38.1/arch/parisc/kernel/sys_parisc.c linux-2.6.38.1/arch/parisc/kernel/sys_parisc.c
1777--- linux-2.6.38.1/arch/parisc/kernel/sys_parisc.c 2011-03-14 21:20:32.000000000 -0400
1778+++ linux-2.6.38.1/arch/parisc/kernel/sys_parisc.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
1779@@ -43,7 +43,7 @@ static unsigned long get_unshared_area(u
1780 /* At this point: (!vma || addr < vma->vm_end). */
1781 if (TASK_SIZE - len < addr)
1782 return -ENOMEM;
1783- if (!vma || addr + len <= vma->vm_start)
1784+ if (check_heap_stack_gap(vma, addr, len))
1785 return addr;
1786 addr = vma->vm_end;
1787 }
1788@@ -79,7 +79,7 @@ static unsigned long get_shared_area(str
1789 /* At this point: (!vma || addr < vma->vm_end). */
1790 if (TASK_SIZE - len < addr)
1791 return -ENOMEM;
1792- if (!vma || addr + len <= vma->vm_start)
1793+ if (check_heap_stack_gap(vma, addr, len))
1794 return addr;
1795 addr = DCACHE_ALIGN(vma->vm_end - offset) + offset;
1796 if (addr < vma->vm_end) /* handle wraparound */
58c5fc13
MT
1797@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
1798 if (flags & MAP_FIXED)
1799 return addr;
1800 if (!addr)
1801- addr = TASK_UNMAPPED_BASE;
1802+ addr = current->mm->mmap_base;
1803
1804 if (filp) {
1805 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
16454cff
MT
1806diff -urNp linux-2.6.38.1/arch/parisc/kernel/traps.c linux-2.6.38.1/arch/parisc/kernel/traps.c
1807--- linux-2.6.38.1/arch/parisc/kernel/traps.c 2011-03-14 21:20:32.000000000 -0400
1808+++ linux-2.6.38.1/arch/parisc/kernel/traps.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
1809@@ -733,9 +733,7 @@ void notrace handle_interruption(int cod
1810
1811 down_read(&current->mm->mmap_sem);
1812 vma = find_vma(current->mm,regs->iaoq[0]);
1813- if (vma && (regs->iaoq[0] >= vma->vm_start)
1814- && (vma->vm_flags & VM_EXEC)) {
1815-
1816+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
1817 fault_address = regs->iaoq[0];
1818 fault_space = regs->iasq[0];
1819
16454cff
MT
1820diff -urNp linux-2.6.38.1/arch/parisc/mm/fault.c linux-2.6.38.1/arch/parisc/mm/fault.c
1821--- linux-2.6.38.1/arch/parisc/mm/fault.c 2011-03-14 21:20:32.000000000 -0400
1822+++ linux-2.6.38.1/arch/parisc/mm/fault.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
1823@@ -15,6 +15,7 @@
1824 #include <linux/sched.h>
1825 #include <linux/interrupt.h>
1826 #include <linux/module.h>
1827+#include <linux/unistd.h>
1828
1829 #include <asm/uaccess.h>
1830 #include <asm/traps.h>
1831@@ -52,7 +53,7 @@ DEFINE_PER_CPU(struct exception_data, ex
1832 static unsigned long
1833 parisc_acctyp(unsigned long code, unsigned int inst)
1834 {
1835- if (code == 6 || code == 16)
1836+ if (code == 6 || code == 7 || code == 16)
1837 return VM_EXEC;
1838
1839 switch (inst & 0xf0000000) {
1840@@ -138,6 +139,116 @@ parisc_acctyp(unsigned long code, unsign
1841 }
1842 #endif
1843
1844+#ifdef CONFIG_PAX_PAGEEXEC
1845+/*
1846+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
1847+ *
1848+ * returns 1 when task should be killed
1849+ * 2 when rt_sigreturn trampoline was detected
1850+ * 3 when unpatched PLT trampoline was detected
1851+ */
1852+static int pax_handle_fetch_fault(struct pt_regs *regs)
1853+{
1854+
1855+#ifdef CONFIG_PAX_EMUPLT
1856+ int err;
1857+
1858+ do { /* PaX: unpatched PLT emulation */
1859+ unsigned int bl, depwi;
1860+
1861+ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
1862+ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
1863+
1864+ if (err)
1865+ break;
1866+
1867+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
1868+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
1869+
1870+ err = get_user(ldw, (unsigned int *)addr);
1871+ err |= get_user(bv, (unsigned int *)(addr+4));
1872+ err |= get_user(ldw2, (unsigned int *)(addr+8));
1873+
1874+ if (err)
1875+ break;
1876+
1877+ if (ldw == 0x0E801096U &&
1878+ bv == 0xEAC0C000U &&
1879+ ldw2 == 0x0E881095U)
1880+ {
1881+ unsigned int resolver, map;
1882+
1883+ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
1884+ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
1885+ if (err)
1886+ break;
1887+
1888+ regs->gr[20] = instruction_pointer(regs)+8;
1889+ regs->gr[21] = map;
1890+ regs->gr[22] = resolver;
1891+ regs->iaoq[0] = resolver | 3UL;
1892+ regs->iaoq[1] = regs->iaoq[0] + 4;
1893+ return 3;
1894+ }
1895+ }
1896+ } while (0);
1897+#endif
1898+
1899+#ifdef CONFIG_PAX_EMUTRAMP
1900+
1901+#ifndef CONFIG_PAX_EMUSIGRT
1902+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
1903+ return 1;
1904+#endif
1905+
1906+ do { /* PaX: rt_sigreturn emulation */
1907+ unsigned int ldi1, ldi2, bel, nop;
1908+
1909+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
1910+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
1911+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
1912+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
1913+
1914+ if (err)
1915+ break;
1916+
1917+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
1918+ ldi2 == 0x3414015AU &&
1919+ bel == 0xE4008200U &&
1920+ nop == 0x08000240U)
1921+ {
1922+ regs->gr[25] = (ldi1 & 2) >> 1;
1923+ regs->gr[20] = __NR_rt_sigreturn;
1924+ regs->gr[31] = regs->iaoq[1] + 16;
1925+ regs->sr[0] = regs->iasq[1];
1926+ regs->iaoq[0] = 0x100UL;
1927+ regs->iaoq[1] = regs->iaoq[0] + 4;
1928+ regs->iasq[0] = regs->sr[2];
1929+ regs->iasq[1] = regs->sr[2];
1930+ return 2;
1931+ }
1932+ } while (0);
1933+#endif
1934+
1935+ return 1;
1936+}
1937+
1938+void pax_report_insns(void *pc, void *sp)
1939+{
1940+ unsigned long i;
1941+
1942+ printk(KERN_ERR "PAX: bytes at PC: ");
1943+ for (i = 0; i < 5; i++) {
1944+ unsigned int c;
1945+ if (get_user(c, (unsigned int *)pc+i))
1946+ printk(KERN_CONT "???????? ");
1947+ else
1948+ printk(KERN_CONT "%08x ", c);
1949+ }
1950+ printk("\n");
1951+}
1952+#endif
1953+
1954 int fixup_exception(struct pt_regs *regs)
1955 {
1956 const struct exception_table_entry *fix;
1957@@ -192,8 +303,33 @@ good_area:
1958
1959 acc_type = parisc_acctyp(code,regs->iir);
1960
1961- if ((vma->vm_flags & acc_type) != acc_type)
1962+ if ((vma->vm_flags & acc_type) != acc_type) {
1963+
1964+#ifdef CONFIG_PAX_PAGEEXEC
1965+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
1966+ (address & ~3UL) == instruction_pointer(regs))
1967+ {
1968+ up_read(&mm->mmap_sem);
1969+ switch (pax_handle_fetch_fault(regs)) {
1970+
1971+#ifdef CONFIG_PAX_EMUPLT
1972+ case 3:
1973+ return;
1974+#endif
1975+
1976+#ifdef CONFIG_PAX_EMUTRAMP
1977+ case 2:
1978+ return;
1979+#endif
1980+
1981+ }
1982+ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1983+ do_group_exit(SIGKILL);
1984+ }
1985+#endif
1986+
1987 goto bad_area;
1988+ }
1989
1990 /*
1991 * If for any reason at all we couldn't handle the fault, make
16454cff
MT
1992diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/device.h linux-2.6.38.1/arch/powerpc/include/asm/device.h
1993--- linux-2.6.38.1/arch/powerpc/include/asm/device.h 2011-03-14 21:20:32.000000000 -0400
1994+++ linux-2.6.38.1/arch/powerpc/include/asm/device.h 2011-03-21 18:31:35.000000000 -0400
1995@@ -17,7 +17,7 @@ struct device_node;
1996 */
57199397 1997 struct dev_archdata {
ae4e228f
MT
1998 /* DMA operations on that device */
1999- struct dma_map_ops *dma_ops;
2000+ const struct dma_map_ops *dma_ops;
2001
2002 /*
2003 * When an iommu is in use, dma_data is used as a ptr to the base of the
16454cff
MT
2004diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/dma-mapping.h linux-2.6.38.1/arch/powerpc/include/asm/dma-mapping.h
2005--- linux-2.6.38.1/arch/powerpc/include/asm/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
2006+++ linux-2.6.38.1/arch/powerpc/include/asm/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
2007@@ -66,12 +66,13 @@ static inline unsigned long device_to_ma
2008 /*
df50ba0c
MT
2009 * Available generic sets of operations
2010 */
57199397 2011+/* cannot be const */
ae4e228f 2012 #ifdef CONFIG_PPC64
bc901d79
MT
2013-extern struct dma_map_ops dma_iommu_ops;
2014+extern const struct dma_map_ops dma_iommu_ops;
ae4e228f
MT
2015 #endif
2016-extern struct dma_map_ops dma_direct_ops;
2017+extern const struct dma_map_ops dma_direct_ops;
2018
2019-static inline struct dma_map_ops *get_dma_ops(struct device *dev)
2020+static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
58c5fc13 2021 {
ae4e228f
MT
2022 /* We don't handle the NULL dev case for ISA for now. We could
2023 * do it via an out of line call but it is not needed for now. The
57199397 2024@@ -84,7 +85,7 @@ static inline struct dma_map_ops *get_dm
ae4e228f 2025 return dev->archdata.dma_ops;
58c5fc13
MT
2026 }
2027
ae4e228f
MT
2028-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
2029+static inline void set_dma_ops(struct device *dev, const struct dma_map_ops *ops)
58c5fc13 2030 {
ae4e228f 2031 dev->archdata.dma_ops = ops;
58c5fc13 2032 }
57199397 2033@@ -118,7 +119,7 @@ static inline void set_dma_offset(struct
58c5fc13 2034
ae4e228f 2035 static inline int dma_supported(struct device *dev, u64 mask)
58c5fc13 2036 {
ae4e228f
MT
2037- struct dma_map_ops *dma_ops = get_dma_ops(dev);
2038+ const struct dma_map_ops *dma_ops = get_dma_ops(dev);
58c5fc13 2039
ae4e228f
MT
2040 if (unlikely(dma_ops == NULL))
2041 return 0;
bc901d79 2042@@ -132,7 +133,7 @@ extern int dma_set_mask(struct device *d
ae4e228f
MT
2043 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
2044 dma_addr_t *dma_handle, gfp_t flag)
2045 {
2046- struct dma_map_ops *dma_ops = get_dma_ops(dev);
2047+ const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2048 void *cpu_addr;
2049
2050 BUG_ON(!dma_ops);
bc901d79 2051@@ -147,7 +148,7 @@ static inline void *dma_alloc_coherent(s
ae4e228f
MT
2052 static inline void dma_free_coherent(struct device *dev, size_t size,
2053 void *cpu_addr, dma_addr_t dma_handle)
58c5fc13 2054 {
ae4e228f
MT
2055- struct dma_map_ops *dma_ops = get_dma_ops(dev);
2056+ const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2057
2058 BUG_ON(!dma_ops);
2059
bc901d79 2060@@ -158,7 +159,7 @@ static inline void dma_free_coherent(str
ae4e228f
MT
2061
2062 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
2063 {
2064- struct dma_map_ops *dma_ops = get_dma_ops(dev);
2065+ const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2066
2067 if (dma_ops->mapping_error)
2068 return dma_ops->mapping_error(dev, dma_addr);
16454cff
MT
2069diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/elf.h linux-2.6.38.1/arch/powerpc/include/asm/elf.h
2070--- linux-2.6.38.1/arch/powerpc/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
2071+++ linux-2.6.38.1/arch/powerpc/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 2072@@ -178,8 +178,19 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
58c5fc13
MT
2073 the loader. We need to make sure that it is out of the way of the program
2074 that it will "exec", and that there is sufficient room for the brk. */
2075
2076-extern unsigned long randomize_et_dyn(unsigned long base);
2077-#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000))
2078+#define ELF_ET_DYN_BASE (0x20000000)
2079+
2080+#ifdef CONFIG_PAX_ASLR
2081+#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
2082+
2083+#ifdef __powerpc64__
bc901d79
MT
2084+#define PAX_DELTA_MMAP_LEN (is_32bit_task() ? 16 : 28)
2085+#define PAX_DELTA_STACK_LEN (is_32bit_task() ? 16 : 28)
58c5fc13
MT
2086+#else
2087+#define PAX_DELTA_MMAP_LEN 15
2088+#define PAX_DELTA_STACK_LEN 15
2089+#endif
2090+#endif
2091
2092 /*
2093 * Our registers are always unsigned longs, whether we're a 32 bit
ae4e228f 2094@@ -274,9 +285,6 @@ extern int arch_setup_additional_pages(s
58c5fc13
MT
2095 (0x7ff >> (PAGE_SHIFT - 12)) : \
2096 (0x3ffff >> (PAGE_SHIFT - 12)))
2097
2098-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
2099-#define arch_randomize_brk arch_randomize_brk
2100-
2101 #endif /* __KERNEL__ */
2102
2103 /*
16454cff
MT
2104diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/iommu.h linux-2.6.38.1/arch/powerpc/include/asm/iommu.h
2105--- linux-2.6.38.1/arch/powerpc/include/asm/iommu.h 2011-03-14 21:20:32.000000000 -0400
2106+++ linux-2.6.38.1/arch/powerpc/include/asm/iommu.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
2107@@ -116,6 +116,9 @@ extern void iommu_init_early_iSeries(voi
2108 extern void iommu_init_early_dart(void);
2109 extern void iommu_init_early_pasemi(void);
2110
2111+/* dma-iommu.c */
2112+extern int dma_iommu_dma_supported(struct device *dev, u64 mask);
2113+
2114 #ifdef CONFIG_PCI
2115 extern void pci_iommu_init(void);
2116 extern void pci_direct_iommu_init(void);
16454cff
MT
2117diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/kmap_types.h linux-2.6.38.1/arch/powerpc/include/asm/kmap_types.h
2118--- linux-2.6.38.1/arch/powerpc/include/asm/kmap_types.h 2011-03-14 21:20:32.000000000 -0400
2119+++ linux-2.6.38.1/arch/powerpc/include/asm/kmap_types.h 2011-03-21 18:31:35.000000000 -0400
57199397 2120@@ -27,6 +27,7 @@ enum km_type {
58c5fc13
MT
2121 KM_PPC_SYNC_PAGE,
2122 KM_PPC_SYNC_ICACHE,
57199397 2123 KM_KDB,
58c5fc13
MT
2124+ KM_CLEARPAGE,
2125 KM_TYPE_NR
2126 };
2127
16454cff
MT
2128diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/page_64.h linux-2.6.38.1/arch/powerpc/include/asm/page_64.h
2129--- linux-2.6.38.1/arch/powerpc/include/asm/page_64.h 2011-03-14 21:20:32.000000000 -0400
2130+++ linux-2.6.38.1/arch/powerpc/include/asm/page_64.h 2011-03-21 18:31:35.000000000 -0400
57199397 2131@@ -172,15 +172,18 @@ do { \
efbe55a5
MT
2132 * stack by default, so in the absense of a PT_GNU_STACK program header
2133 * we turn execute permission off.
2134 */
2135-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
2136- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2137+#define VM_STACK_DEFAULT_FLAGS32 \
2138+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
2139+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2140
2141 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
2142 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2143
2144+#ifndef CONFIG_PAX_PAGEEXEC
2145 #define VM_STACK_DEFAULT_FLAGS \
bc901d79 2146 (is_32bit_task() ? \
efbe55a5
MT
2147 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
2148+#endif
2149
2150 #include <asm-generic/getorder.h>
2151
16454cff
MT
2152diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/page.h linux-2.6.38.1/arch/powerpc/include/asm/page.h
2153--- linux-2.6.38.1/arch/powerpc/include/asm/page.h 2011-03-14 21:20:32.000000000 -0400
2154+++ linux-2.6.38.1/arch/powerpc/include/asm/page.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
2155@@ -129,8 +129,9 @@ extern phys_addr_t kernstart_addr;
2156 * and needs to be executable. This means the whole heap ends
2157 * up being executable.
2158 */
2159-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
2160- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2161+#define VM_DATA_DEFAULT_FLAGS32 \
2162+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
2163+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2164
2165 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
2166 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2167@@ -158,6 +159,9 @@ extern phys_addr_t kernstart_addr;
2168 #define is_kernel_addr(x) ((x) >= PAGE_OFFSET)
2169 #endif
2170
2171+#define ktla_ktva(addr) (addr)
2172+#define ktva_ktla(addr) (addr)
2173+
2174 #ifndef __ASSEMBLY__
2175
2176 #undef STRICT_MM_TYPECHECKS
16454cff
MT
2177diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/pci.h linux-2.6.38.1/arch/powerpc/include/asm/pci.h
2178--- linux-2.6.38.1/arch/powerpc/include/asm/pci.h 2011-03-14 21:20:32.000000000 -0400
2179+++ linux-2.6.38.1/arch/powerpc/include/asm/pci.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
2180@@ -65,8 +65,8 @@ static inline int pci_get_legacy_ide_irq
2181 }
2182
2183 #ifdef CONFIG_PCI
2184-extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
2185-extern struct dma_map_ops *get_pci_dma_ops(void);
2186+extern void set_pci_dma_ops(const struct dma_map_ops *dma_ops);
2187+extern const struct dma_map_ops *get_pci_dma_ops(void);
2188 #else /* CONFIG_PCI */
2189 #define set_pci_dma_ops(d)
2190 #define get_pci_dma_ops() NULL
16454cff
MT
2191diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/pgtable.h linux-2.6.38.1/arch/powerpc/include/asm/pgtable.h
2192--- linux-2.6.38.1/arch/powerpc/include/asm/pgtable.h 2011-03-14 21:20:32.000000000 -0400
2193+++ linux-2.6.38.1/arch/powerpc/include/asm/pgtable.h 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
2194@@ -2,6 +2,7 @@
2195 #define _ASM_POWERPC_PGTABLE_H
2196 #ifdef __KERNEL__
2197
2198+#include <linux/const.h>
2199 #ifndef __ASSEMBLY__
2200 #include <asm/processor.h> /* For TASK_SIZE */
2201 #include <asm/mmu.h>
16454cff
MT
2202diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/pte-hash32.h linux-2.6.38.1/arch/powerpc/include/asm/pte-hash32.h
2203--- linux-2.6.38.1/arch/powerpc/include/asm/pte-hash32.h 2011-03-14 21:20:32.000000000 -0400
2204+++ linux-2.6.38.1/arch/powerpc/include/asm/pte-hash32.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
2205@@ -21,6 +21,7 @@
2206 #define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */
2207 #define _PAGE_USER 0x004 /* usermode access allowed */
2208 #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
ae4e228f 2209+#define _PAGE_EXEC _PAGE_GUARDED
58c5fc13
MT
2210 #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
2211 #define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
2212 #define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
16454cff
MT
2213diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/reg.h linux-2.6.38.1/arch/powerpc/include/asm/reg.h
2214--- linux-2.6.38.1/arch/powerpc/include/asm/reg.h 2011-03-23 17:20:06.000000000 -0400
2215+++ linux-2.6.38.1/arch/powerpc/include/asm/reg.h 2011-03-23 17:21:43.000000000 -0400
ae4e228f 2216@@ -191,6 +191,7 @@
58c5fc13
MT
2217 #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
2218 #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
2219 #define DSISR_NOHPTE 0x40000000 /* no translation found */
2220+#define DSISR_GUARDED 0x10000000 /* fetch from guarded storage */
2221 #define DSISR_PROTFAULT 0x08000000 /* protection fault */
2222 #define DSISR_ISSTORE 0x02000000 /* access was a store */
2223 #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
16454cff
MT
2224diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/swiotlb.h linux-2.6.38.1/arch/powerpc/include/asm/swiotlb.h
2225--- linux-2.6.38.1/arch/powerpc/include/asm/swiotlb.h 2011-03-14 21:20:32.000000000 -0400
2226+++ linux-2.6.38.1/arch/powerpc/include/asm/swiotlb.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
2227@@ -13,7 +13,7 @@
2228
2229 #include <linux/swiotlb.h>
2230
2231-extern struct dma_map_ops swiotlb_dma_ops;
2232+extern const struct dma_map_ops swiotlb_dma_ops;
2233
2234 static inline void dma_mark_clean(void *addr, size_t size) {}
2235
16454cff
MT
2236diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/system.h linux-2.6.38.1/arch/powerpc/include/asm/system.h
2237--- linux-2.6.38.1/arch/powerpc/include/asm/system.h 2011-03-14 21:20:32.000000000 -0400
2238+++ linux-2.6.38.1/arch/powerpc/include/asm/system.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
2239@@ -533,7 +533,7 @@ __cmpxchg_local(volatile void *ptr, unsi
2240 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
2241 #endif
2242
2243-extern unsigned long arch_align_stack(unsigned long sp);
2244+#define arch_align_stack(x) ((x) & ~0xfUL)
2245
2246 /* Used in very early kernel initialization. */
2247 extern unsigned long reloc_offset(void);
16454cff
MT
2248diff -urNp linux-2.6.38.1/arch/powerpc/include/asm/uaccess.h linux-2.6.38.1/arch/powerpc/include/asm/uaccess.h
2249--- linux-2.6.38.1/arch/powerpc/include/asm/uaccess.h 2011-03-14 21:20:32.000000000 -0400
2250+++ linux-2.6.38.1/arch/powerpc/include/asm/uaccess.h 2011-03-21 18:31:35.000000000 -0400
efbe55a5
MT
2251@@ -13,6 +13,8 @@
2252 #define VERIFY_READ 0
2253 #define VERIFY_WRITE 1
2254
2255+extern void check_object_size(const void *ptr, unsigned long n, bool to);
2256+
2257 /*
2258 * The fs value determines whether argument validity checking should be
2259 * performed or not. If get_fs() == USER_DS, checking is performed, with
2260@@ -327,52 +329,6 @@ do { \
58c5fc13
MT
2261 extern unsigned long __copy_tofrom_user(void __user *to,
2262 const void __user *from, unsigned long size);
2263
2264-#ifndef __powerpc64__
2265-
2266-static inline unsigned long copy_from_user(void *to,
2267- const void __user *from, unsigned long n)
2268-{
2269- unsigned long over;
2270-
2271- if (access_ok(VERIFY_READ, from, n))
2272- return __copy_tofrom_user((__force void __user *)to, from, n);
2273- if ((unsigned long)from < TASK_SIZE) {
2274- over = (unsigned long)from + n - TASK_SIZE;
2275- return __copy_tofrom_user((__force void __user *)to, from,
2276- n - over) + over;
2277- }
2278- return n;
2279-}
2280-
2281-static inline unsigned long copy_to_user(void __user *to,
2282- const void *from, unsigned long n)
2283-{
2284- unsigned long over;
2285-
2286- if (access_ok(VERIFY_WRITE, to, n))
2287- return __copy_tofrom_user(to, (__force void __user *)from, n);
2288- if ((unsigned long)to < TASK_SIZE) {
2289- over = (unsigned long)to + n - TASK_SIZE;
2290- return __copy_tofrom_user(to, (__force void __user *)from,
2291- n - over) + over;
2292- }
2293- return n;
2294-}
2295-
2296-#else /* __powerpc64__ */
2297-
2298-#define __copy_in_user(to, from, size) \
2299- __copy_tofrom_user((to), (from), (size))
2300-
2301-extern unsigned long copy_from_user(void *to, const void __user *from,
2302- unsigned long n);
2303-extern unsigned long copy_to_user(void __user *to, const void *from,
2304- unsigned long n);
2305-extern unsigned long copy_in_user(void __user *to, const void __user *from,
2306- unsigned long n);
2307-
2308-#endif /* __powerpc64__ */
2309-
2310 static inline unsigned long __copy_from_user_inatomic(void *to,
2311 const void __user *from, unsigned long n)
2312 {
efbe55a5 2313@@ -396,6 +352,10 @@ static inline unsigned long __copy_from_
58c5fc13
MT
2314 if (ret == 0)
2315 return 0;
2316 }
ae4e228f 2317+
58c5fc13
MT
2318+ if (!__builtin_constant_p(n))
2319+ check_object_size(to, n, false);
2320+
2321 return __copy_tofrom_user((__force void __user *)to, from, n);
2322 }
2323
efbe55a5 2324@@ -422,6 +382,10 @@ static inline unsigned long __copy_to_us
58c5fc13
MT
2325 if (ret == 0)
2326 return 0;
2327 }
ae4e228f 2328+
58c5fc13
MT
2329+ if (!__builtin_constant_p(n))
2330+ check_object_size(from, n, true);
2331+
2332 return __copy_tofrom_user(to, (__force const void __user *)from, n);
2333 }
2334
efbe55a5 2335@@ -439,6 +403,92 @@ static inline unsigned long __copy_to_us
58c5fc13
MT
2336 return __copy_to_user_inatomic(to, from, size);
2337 }
2338
2339+#ifndef __powerpc64__
2340+
2341+static inline unsigned long __must_check copy_from_user(void *to,
2342+ const void __user *from, unsigned long n)
2343+{
2344+ unsigned long over;
2345+
ae4e228f 2346+ if ((long)n < 0)
58c5fc13
MT
2347+ return n;
2348+
2349+ if (access_ok(VERIFY_READ, from, n)) {
2350+ if (!__builtin_constant_p(n))
2351+ check_object_size(to, n, false);
58c5fc13
MT
2352+ return __copy_tofrom_user((__force void __user *)to, from, n);
2353+ }
2354+ if ((unsigned long)from < TASK_SIZE) {
2355+ over = (unsigned long)from + n - TASK_SIZE;
2356+ if (!__builtin_constant_p(n - over))
2357+ check_object_size(to, n - over, false);
2358+ return __copy_tofrom_user((__force void __user *)to, from,
2359+ n - over) + over;
2360+ }
2361+ return n;
2362+}
2363+
2364+static inline unsigned long __must_check copy_to_user(void __user *to,
2365+ const void *from, unsigned long n)
2366+{
2367+ unsigned long over;
2368+
ae4e228f 2369+ if ((long)n < 0)
58c5fc13
MT
2370+ return n;
2371+
2372+ if (access_ok(VERIFY_WRITE, to, n)) {
2373+ if (!__builtin_constant_p(n))
2374+ check_object_size(from, n, true);
2375+ return __copy_tofrom_user(to, (__force void __user *)from, n);
2376+ }
2377+ if ((unsigned long)to < TASK_SIZE) {
2378+ over = (unsigned long)to + n - TASK_SIZE;
2379+ if (!__builtin_constant_p(n))
2380+ check_object_size(from, n - over, true);
2381+ return __copy_tofrom_user(to, (__force void __user *)from,
2382+ n - over) + over;
2383+ }
2384+ return n;
2385+}
2386+
2387+#else /* __powerpc64__ */
2388+
2389+#define __copy_in_user(to, from, size) \
2390+ __copy_tofrom_user((to), (from), (size))
2391+
ae4e228f 2392+static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
58c5fc13 2393+{
ae4e228f 2394+ if ((long)n < 0 || n > INT_MAX)
58c5fc13
MT
2395+ return n;
2396+
2397+ if (!__builtin_constant_p(n))
2398+ check_object_size(to, n, false);
2399+
2400+ if (likely(access_ok(VERIFY_READ, from, n)))
2401+ n = __copy_from_user(to, from, n);
2402+ else
2403+ memset(to, 0, n);
58c5fc13
MT
2404+ return n;
2405+}
2406+
ae4e228f 2407+static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
58c5fc13 2408+{
ae4e228f 2409+ if ((long)n < 0 || n > INT_MAX)
58c5fc13
MT
2410+ return n;
2411+
2412+ if (likely(access_ok(VERIFY_WRITE, to, n))) {
2413+ if (!__builtin_constant_p(n))
2414+ check_object_size(from, n, true);
2415+ n = __copy_to_user(to, from, n);
2416+ }
58c5fc13
MT
2417+ return n;
2418+}
2419+
2420+extern unsigned long copy_in_user(void __user *to, const void __user *from,
2421+ unsigned long n);
2422+
2423+#endif /* __powerpc64__ */
2424+
2425 extern unsigned long __clear_user(void __user *addr, unsigned long size);
2426
2427 static inline unsigned long clear_user(void __user *addr, unsigned long size)
16454cff
MT
2428diff -urNp linux-2.6.38.1/arch/powerpc/kernel/dma.c linux-2.6.38.1/arch/powerpc/kernel/dma.c
2429--- linux-2.6.38.1/arch/powerpc/kernel/dma.c 2011-03-14 21:20:32.000000000 -0400
2430+++ linux-2.6.38.1/arch/powerpc/kernel/dma.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 2431@@ -136,7 +136,7 @@ static inline void dma_direct_sync_singl
57199397
MT
2432 }
2433 #endif
2434
2435-struct dma_map_ops dma_direct_ops = {
2436+const struct dma_map_ops dma_direct_ops = {
2437 .alloc_coherent = dma_direct_alloc_coherent,
2438 .free_coherent = dma_direct_free_coherent,
2439 .map_sg = dma_direct_map_sg,
bc901d79
MT
2440@@ -157,7 +157,7 @@ EXPORT_SYMBOL(dma_direct_ops);
2441
2442 int dma_set_mask(struct device *dev, u64 dma_mask)
2443 {
2444- struct dma_map_ops *dma_ops = get_dma_ops(dev);
2445+ const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2446
2447 if (ppc_md.dma_set_mask)
2448 return ppc_md.dma_set_mask(dev, dma_mask);
16454cff
MT
2449diff -urNp linux-2.6.38.1/arch/powerpc/kernel/dma-iommu.c linux-2.6.38.1/arch/powerpc/kernel/dma-iommu.c
2450--- linux-2.6.38.1/arch/powerpc/kernel/dma-iommu.c 2011-03-14 21:20:32.000000000 -0400
2451+++ linux-2.6.38.1/arch/powerpc/kernel/dma-iommu.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
2452@@ -70,7 +70,7 @@ static void dma_iommu_unmap_sg(struct de
2453 }
2454
2455 /* We support DMA to/from any memory page via the iommu */
2456-static int dma_iommu_dma_supported(struct device *dev, u64 mask)
2457+int dma_iommu_dma_supported(struct device *dev, u64 mask)
2458 {
2459 struct iommu_table *tbl = get_iommu_table_base(dev);
2460
16454cff 2461@@ -90,7 +90,7 @@ static int dma_iommu_dma_supported(struc
6892158b
MT
2462 return 1;
2463 }
2464
16454cff
MT
2465-struct dma_map_ops dma_iommu_ops = {
2466+struct dma_map_ops dma_iommu_ops = { /* cannot be const, see arch/powerpc/platforms/cell/iommu.c */
6892158b
MT
2467 .alloc_coherent = dma_iommu_alloc_coherent,
2468 .free_coherent = dma_iommu_free_coherent,
16454cff
MT
2469 .map_sg = dma_iommu_map_sg,
2470diff -urNp linux-2.6.38.1/arch/powerpc/kernel/dma-swiotlb.c linux-2.6.38.1/arch/powerpc/kernel/dma-swiotlb.c
2471--- linux-2.6.38.1/arch/powerpc/kernel/dma-swiotlb.c 2011-03-14 21:20:32.000000000 -0400
2472+++ linux-2.6.38.1/arch/powerpc/kernel/dma-swiotlb.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 2473@@ -31,7 +31,7 @@ unsigned int ppc_swiotlb_enable;
ae4e228f
MT
2474 * map_page, and unmap_page on highmem, use normal dma_ops
2475 * for everything else.
2476 */
2477-struct dma_map_ops swiotlb_dma_ops = {
2478+const struct dma_map_ops swiotlb_dma_ops = {
2479 .alloc_coherent = dma_direct_alloc_coherent,
2480 .free_coherent = dma_direct_free_coherent,
2481 .map_sg = swiotlb_map_sg_attrs,
16454cff
MT
2482diff -urNp linux-2.6.38.1/arch/powerpc/kernel/exceptions-64e.S linux-2.6.38.1/arch/powerpc/kernel/exceptions-64e.S
2483--- linux-2.6.38.1/arch/powerpc/kernel/exceptions-64e.S 2011-03-14 21:20:32.000000000 -0400
2484+++ linux-2.6.38.1/arch/powerpc/kernel/exceptions-64e.S 2011-03-21 18:31:35.000000000 -0400
6892158b 2485@@ -495,6 +495,7 @@ storage_fault_common:
ae4e228f
MT
2486 std r14,_DAR(r1)
2487 std r15,_DSISR(r1)
2488 addi r3,r1,STACK_FRAME_OVERHEAD
2489+ bl .save_nvgprs
2490 mr r4,r14
2491 mr r5,r15
2492 ld r14,PACA_EXGEN+EX_R14(r13)
6892158b 2493@@ -504,8 +505,7 @@ storage_fault_common:
ae4e228f
MT
2494 cmpdi r3,0
2495 bne- 1f
2496 b .ret_from_except_lite
2497-1: bl .save_nvgprs
2498- mr r5,r3
2499+1: mr r5,r3
2500 addi r3,r1,STACK_FRAME_OVERHEAD
2501 ld r4,_DAR(r1)
2502 bl .bad_page_fault
16454cff
MT
2503diff -urNp linux-2.6.38.1/arch/powerpc/kernel/exceptions-64s.S linux-2.6.38.1/arch/powerpc/kernel/exceptions-64s.S
2504--- linux-2.6.38.1/arch/powerpc/kernel/exceptions-64s.S 2011-03-14 21:20:32.000000000 -0400
2505+++ linux-2.6.38.1/arch/powerpc/kernel/exceptions-64s.S 2011-03-21 18:31:35.000000000 -0400
2506@@ -848,10 +848,10 @@ handle_page_fault:
ae4e228f
MT
2507 11: ld r4,_DAR(r1)
2508 ld r5,_DSISR(r1)
2509 addi r3,r1,STACK_FRAME_OVERHEAD
2510+ bl .save_nvgprs
2511 bl .do_page_fault
2512 cmpdi r3,0
2513 beq+ 13f
2514- bl .save_nvgprs
2515 mr r5,r3
2516 addi r3,r1,STACK_FRAME_OVERHEAD
2517 lwz r4,_DAR(r1)
16454cff
MT
2518diff -urNp linux-2.6.38.1/arch/powerpc/kernel/ibmebus.c linux-2.6.38.1/arch/powerpc/kernel/ibmebus.c
2519--- linux-2.6.38.1/arch/powerpc/kernel/ibmebus.c 2011-03-14 21:20:32.000000000 -0400
2520+++ linux-2.6.38.1/arch/powerpc/kernel/ibmebus.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 2521@@ -128,7 +128,7 @@ static int ibmebus_dma_supported(struct
ae4e228f
MT
2522 return 1;
2523 }
2524
2525-static struct dma_map_ops ibmebus_dma_ops = {
2526+static const struct dma_map_ops ibmebus_dma_ops = {
2527 .alloc_coherent = ibmebus_alloc_coherent,
2528 .free_coherent = ibmebus_free_coherent,
2529 .map_sg = ibmebus_map_sg,
16454cff
MT
2530diff -urNp linux-2.6.38.1/arch/powerpc/kernel/kgdb.c linux-2.6.38.1/arch/powerpc/kernel/kgdb.c
2531--- linux-2.6.38.1/arch/powerpc/kernel/kgdb.c 2011-03-14 21:20:32.000000000 -0400
2532+++ linux-2.6.38.1/arch/powerpc/kernel/kgdb.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 2533@@ -422,7 +422,7 @@ int kgdb_arch_handle_exception(int vecto
ae4e228f
MT
2534 /*
2535 * Global data
2536 */
2537-struct kgdb_arch arch_kgdb_ops = {
2538+const struct kgdb_arch arch_kgdb_ops = {
2539 .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08},
2540 };
2541
16454cff
MT
2542diff -urNp linux-2.6.38.1/arch/powerpc/kernel/module_32.c linux-2.6.38.1/arch/powerpc/kernel/module_32.c
2543--- linux-2.6.38.1/arch/powerpc/kernel/module_32.c 2011-03-14 21:20:32.000000000 -0400
2544+++ linux-2.6.38.1/arch/powerpc/kernel/module_32.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
2545@@ -162,7 +162,7 @@ int module_frob_arch_sections(Elf32_Ehdr
2546 me->arch.core_plt_section = i;
2547 }
2548 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
2549- printk("Module doesn't contain .plt or .init.plt sections.\n");
2550+ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
2551 return -ENOEXEC;
2552 }
2553
2554@@ -203,11 +203,16 @@ static uint32_t do_plt_call(void *locati
2555
2556 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
2557 /* Init, or core PLT? */
2558- if (location >= mod->module_core
2559- && location < mod->module_core + mod->core_size)
2560+ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
2561+ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
2562 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
2563- else
2564+ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
2565+ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
2566 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
2567+ else {
2568+ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
2569+ return ~0UL;
2570+ }
2571
2572 /* Find this entry, or if that fails, the next avail. entry */
2573 while (entry->jump[0]) {
16454cff
MT
2574diff -urNp linux-2.6.38.1/arch/powerpc/kernel/module.c linux-2.6.38.1/arch/powerpc/kernel/module.c
2575--- linux-2.6.38.1/arch/powerpc/kernel/module.c 2011-03-14 21:20:32.000000000 -0400
2576+++ linux-2.6.38.1/arch/powerpc/kernel/module.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
2577@@ -31,11 +31,24 @@
2578
2579 LIST_HEAD(module_bug_list);
2580
2581+#ifdef CONFIG_PAX_KERNEXEC
2582 void *module_alloc(unsigned long size)
2583 {
2584 if (size == 0)
2585 return NULL;
2586
2587+ return vmalloc(size);
2588+}
2589+
2590+void *module_alloc_exec(unsigned long size)
2591+#else
2592+void *module_alloc(unsigned long size)
2593+#endif
2594+
2595+{
2596+ if (size == 0)
2597+ return NULL;
2598+
2599 return vmalloc_exec(size);
2600 }
2601
2602@@ -45,6 +58,13 @@ void module_free(struct module *mod, voi
2603 vfree(module_region);
2604 }
2605
2606+#ifdef CONFIG_PAX_KERNEXEC
2607+void module_free_exec(struct module *mod, void *module_region)
2608+{
2609+ module_free(mod, module_region);
2610+}
2611+#endif
2612+
2613 static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
2614 const Elf_Shdr *sechdrs,
2615 const char *name)
16454cff
MT
2616diff -urNp linux-2.6.38.1/arch/powerpc/kernel/pci-common.c linux-2.6.38.1/arch/powerpc/kernel/pci-common.c
2617--- linux-2.6.38.1/arch/powerpc/kernel/pci-common.c 2011-03-14 21:20:32.000000000 -0400
2618+++ linux-2.6.38.1/arch/powerpc/kernel/pci-common.c 2011-03-21 18:31:35.000000000 -0400
6892158b 2619@@ -52,14 +52,14 @@ resource_size_t isa_mem_base;
ae4e228f
MT
2620 unsigned int ppc_pci_flags = 0;
2621
2622
2623-static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
2624+static const struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
2625
2626-void set_pci_dma_ops(struct dma_map_ops *dma_ops)
2627+void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
2628 {
2629 pci_dma_ops = dma_ops;
2630 }
2631
2632-struct dma_map_ops *get_pci_dma_ops(void)
2633+const struct dma_map_ops *get_pci_dma_ops(void)
2634 {
2635 return pci_dma_ops;
2636 }
16454cff
MT
2637diff -urNp linux-2.6.38.1/arch/powerpc/kernel/process.c linux-2.6.38.1/arch/powerpc/kernel/process.c
2638--- linux-2.6.38.1/arch/powerpc/kernel/process.c 2011-03-14 21:20:32.000000000 -0400
2639+++ linux-2.6.38.1/arch/powerpc/kernel/process.c 2011-03-21 18:31:35.000000000 -0400
2640@@ -655,8 +655,8 @@ void show_regs(struct pt_regs * regs)
bc901d79
MT
2641 * Lookup NIP late so we have the best change of getting the
2642 * above info out without failing
2643 */
2644- printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip);
2645- printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link);
2646+ printk("NIP ["REG"] %pA\n", regs->nip, (void *)regs->nip);
2647+ printk("LR ["REG"] %pA\n", regs->link, (void *)regs->link);
2648 #endif
2649 show_stack(current, (unsigned long *) regs->gpr[1]);
2650 if (!user_mode(regs))
16454cff 2651@@ -1146,10 +1146,10 @@ void show_stack(struct task_struct *tsk,
bc901d79
MT
2652 newsp = stack[0];
2653 ip = stack[STACK_FRAME_LR_SAVE];
2654 if (!firstframe || ip != lr) {
2655- printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
2656+ printk("["REG"] ["REG"] %pA", sp, ip, (void *)ip);
2657 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
2658 if ((ip == rth || ip == mrth) && curr_frame >= 0) {
2659- printk(" (%pS)",
2660+ printk(" (%pA)",
2661 (void *)current->ret_stack[curr_frame].ret);
2662 curr_frame--;
2663 }
16454cff 2664@@ -1169,7 +1169,7 @@ void show_stack(struct task_struct *tsk,
bc901d79
MT
2665 struct pt_regs *regs = (struct pt_regs *)
2666 (sp + STACK_FRAME_OVERHEAD);
2667 lr = regs->link;
2668- printk("--- Exception: %lx at %pS\n LR = %pS\n",
2669+ printk("--- Exception: %lx at %pA\n LR = %pA\n",
2670 regs->trap, (void *)regs->nip, (void *)lr);
2671 firstframe = 1;
2672 }
16454cff 2673@@ -1244,58 +1244,3 @@ void thread_info_cache_init(void)
58c5fc13 2674 }
6892158b 2675
bc901d79
MT
2676 #endif /* THREAD_SHIFT < PAGE_SHIFT */
2677-
2678-unsigned long arch_align_stack(unsigned long sp)
2679-{
2680- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
2681- sp -= get_random_int() & ~PAGE_MASK;
2682- return sp & ~0xf;
2683-}
2684-
58c5fc13
MT
2685-static inline unsigned long brk_rnd(void)
2686-{
2687- unsigned long rnd = 0;
2688-
2689- /* 8MB for 32bit, 1GB for 64bit */
2690- if (is_32bit_task())
2691- rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
2692- else
2693- rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
2694-
2695- return rnd << PAGE_SHIFT;
2696-}
2697-
2698-unsigned long arch_randomize_brk(struct mm_struct *mm)
2699-{
ae4e228f
MT
2700- unsigned long base = mm->brk;
2701- unsigned long ret;
2702-
2703-#ifdef CONFIG_PPC_STD_MMU_64
2704- /*
2705- * If we are using 1TB segments and we are allowed to randomise
2706- * the heap, we can put it above 1TB so it is backed by a 1TB
2707- * segment. Otherwise the heap will be in the bottom 1TB
2708- * which always uses 256MB segments and this may result in a
2709- * performance penalty.
2710- */
2711- if (!is_32bit_task() && (mmu_highuser_ssize == MMU_SEGSIZE_1T))
2712- base = max_t(unsigned long, mm->brk, 1UL << SID_SHIFT_1T);
2713-#endif
2714-
2715- ret = PAGE_ALIGN(base + brk_rnd());
58c5fc13
MT
2716-
2717- if (ret < mm->brk)
2718- return mm->brk;
2719-
2720- return ret;
2721-}
2722-
2723-unsigned long randomize_et_dyn(unsigned long base)
2724-{
2725- unsigned long ret = PAGE_ALIGN(base + brk_rnd());
2726-
2727- if (ret < base)
2728- return base;
2729-
2730- return ret;
2731-}
16454cff
MT
2732diff -urNp linux-2.6.38.1/arch/powerpc/kernel/signal_32.c linux-2.6.38.1/arch/powerpc/kernel/signal_32.c
2733--- linux-2.6.38.1/arch/powerpc/kernel/signal_32.c 2011-03-14 21:20:32.000000000 -0400
2734+++ linux-2.6.38.1/arch/powerpc/kernel/signal_32.c 2011-03-21 18:31:35.000000000 -0400
6892158b 2735@@ -858,7 +858,7 @@ int handle_rt_signal32(unsigned long sig
58c5fc13
MT
2736 /* Save user registers on the stack */
2737 frame = &rt_sf->uc.uc_mcontext;
2738 addr = frame;
2739- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
2740+ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
2741 if (save_user_regs(regs, frame, 0, 1))
2742 goto badframe;
2743 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
16454cff
MT
2744diff -urNp linux-2.6.38.1/arch/powerpc/kernel/signal_64.c linux-2.6.38.1/arch/powerpc/kernel/signal_64.c
2745--- linux-2.6.38.1/arch/powerpc/kernel/signal_64.c 2011-03-14 21:20:32.000000000 -0400
2746+++ linux-2.6.38.1/arch/powerpc/kernel/signal_64.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
2747@@ -429,7 +429,7 @@ int handle_rt_signal64(int signr, struct
2748 current->thread.fpscr.val = 0;
2749
2750 /* Set up to return from userspace. */
2751- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
2752+ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
2753 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
2754 } else {
2755 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
16454cff
MT
2756diff -urNp linux-2.6.38.1/arch/powerpc/kernel/vdso.c linux-2.6.38.1/arch/powerpc/kernel/vdso.c
2757--- linux-2.6.38.1/arch/powerpc/kernel/vdso.c 2011-03-14 21:20:32.000000000 -0400
2758+++ linux-2.6.38.1/arch/powerpc/kernel/vdso.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 2759@@ -36,6 +36,7 @@
58c5fc13
MT
2760 #include <asm/firmware.h>
2761 #include <asm/vdso.h>
2762 #include <asm/vdso_datapage.h>
2763+#include <asm/mman.h>
2764
2765 #include "setup.h"
2766
ae4e228f 2767@@ -220,7 +221,7 @@ int arch_setup_additional_pages(struct l
58c5fc13
MT
2768 vdso_base = VDSO32_MBASE;
2769 #endif
2770
2771- current->mm->context.vdso_base = 0;
2772+ current->mm->context.vdso_base = ~0UL;
2773
2774 /* vDSO has a problem and was disabled, just don't "enable" it for the
2775 * process
ae4e228f 2776@@ -240,7 +241,7 @@ int arch_setup_additional_pages(struct l
58c5fc13 2777 vdso_base = get_unmapped_area(NULL, vdso_base,
ae4e228f
MT
2778 (vdso_pages << PAGE_SHIFT) +
2779 ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
2780- 0, 0);
2781+ 0, MAP_PRIVATE | MAP_EXECUTABLE);
58c5fc13
MT
2782 if (IS_ERR_VALUE(vdso_base)) {
2783 rc = vdso_base;
2784 goto fail_mmapsem;
16454cff
MT
2785diff -urNp linux-2.6.38.1/arch/powerpc/kernel/vio.c linux-2.6.38.1/arch/powerpc/kernel/vio.c
2786--- linux-2.6.38.1/arch/powerpc/kernel/vio.c 2011-03-14 21:20:32.000000000 -0400
2787+++ linux-2.6.38.1/arch/powerpc/kernel/vio.c 2011-03-21 18:31:35.000000000 -0400
2788@@ -605,11 +605,12 @@ static int vio_dma_iommu_dma_supported(s
2789 return dma_iommu_ops.dma_supported(dev, mask);
ae4e228f
MT
2790 }
2791
2792-struct dma_map_ops vio_dma_mapping_ops = {
16454cff 2793+const struct dma_map_ops vio_dma_mapping_ops = {
ae4e228f
MT
2794 .alloc_coherent = vio_dma_iommu_alloc_coherent,
2795 .free_coherent = vio_dma_iommu_free_coherent,
2796 .map_sg = vio_dma_iommu_map_sg,
2797 .unmap_sg = vio_dma_iommu_unmap_sg,
2798+ .dma_supported = dma_iommu_dma_supported,
2799 .map_page = vio_dma_iommu_map_page,
2800 .unmap_page = vio_dma_iommu_unmap_page,
16454cff
MT
2801 .dma_supported = vio_dma_iommu_dma_supported,
2802diff -urNp linux-2.6.38.1/arch/powerpc/lib/usercopy_64.c linux-2.6.38.1/arch/powerpc/lib/usercopy_64.c
2803--- linux-2.6.38.1/arch/powerpc/lib/usercopy_64.c 2011-03-14 21:20:32.000000000 -0400
2804+++ linux-2.6.38.1/arch/powerpc/lib/usercopy_64.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
2805@@ -9,22 +9,6 @@
2806 #include <linux/module.h>
2807 #include <asm/uaccess.h>
2808
2809-unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
2810-{
2811- if (likely(access_ok(VERIFY_READ, from, n)))
2812- n = __copy_from_user(to, from, n);
2813- else
2814- memset(to, 0, n);
2815- return n;
2816-}
2817-
2818-unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
2819-{
2820- if (likely(access_ok(VERIFY_WRITE, to, n)))
2821- n = __copy_to_user(to, from, n);
2822- return n;
2823-}
2824-
2825 unsigned long copy_in_user(void __user *to, const void __user *from,
2826 unsigned long n)
2827 {
2828@@ -35,7 +19,5 @@ unsigned long copy_in_user(void __user *
2829 return n;
2830 }
2831
2832-EXPORT_SYMBOL(copy_from_user);
2833-EXPORT_SYMBOL(copy_to_user);
2834 EXPORT_SYMBOL(copy_in_user);
2835
16454cff
MT
2836diff -urNp linux-2.6.38.1/arch/powerpc/mm/fault.c linux-2.6.38.1/arch/powerpc/mm/fault.c
2837--- linux-2.6.38.1/arch/powerpc/mm/fault.c 2011-03-14 21:20:32.000000000 -0400
2838+++ linux-2.6.38.1/arch/powerpc/mm/fault.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 2839@@ -31,6 +31,10 @@
58c5fc13 2840 #include <linux/kdebug.h>
ae4e228f 2841 #include <linux/perf_event.h>
bc901d79 2842 #include <linux/magic.h>
58c5fc13
MT
2843+#include <linux/slab.h>
2844+#include <linux/pagemap.h>
2845+#include <linux/compiler.h>
2846+#include <linux/unistd.h>
2847
2848 #include <asm/firmware.h>
2849 #include <asm/page.h>
bc901d79 2850@@ -42,6 +46,7 @@
58c5fc13
MT
2851 #include <asm/tlbflush.h>
2852 #include <asm/siginfo.h>
ae4e228f 2853 #include <mm/mmu_decl.h>
58c5fc13
MT
2854+#include <asm/ptrace.h>
2855
58c5fc13 2856 #ifdef CONFIG_KPROBES
ae4e228f 2857 static inline int notify_page_fault(struct pt_regs *regs)
bc901d79 2858@@ -65,6 +70,33 @@ static inline int notify_page_fault(stru
58c5fc13
MT
2859 }
2860 #endif
2861
2862+#ifdef CONFIG_PAX_PAGEEXEC
2863+/*
2864+ * PaX: decide what to do with offenders (regs->nip = fault address)
2865+ *
2866+ * returns 1 when task should be killed
2867+ */
2868+static int pax_handle_fetch_fault(struct pt_regs *regs)
2869+{
2870+ return 1;
2871+}
2872+
2873+void pax_report_insns(void *pc, void *sp)
2874+{
2875+ unsigned long i;
2876+
2877+ printk(KERN_ERR "PAX: bytes at PC: ");
2878+ for (i = 0; i < 5; i++) {
2879+ unsigned int c;
ae4e228f 2880+ if (get_user(c, (unsigned int __user *)pc+i))
58c5fc13
MT
2881+ printk(KERN_CONT "???????? ");
2882+ else
2883+ printk(KERN_CONT "%08x ", c);
2884+ }
2885+ printk("\n");
2886+}
2887+#endif
2888+
2889 /*
2890 * Check whether the instruction at regs->nip is a store using
2891 * an update addressing form which will update r1.
bc901d79 2892@@ -135,7 +167,7 @@ int __kprobes do_page_fault(struct pt_re
58c5fc13
MT
2893 * indicate errors in DSISR but can validly be set in SRR1.
2894 */
2895 if (trap == 0x400)
2896- error_code &= 0x48200000;
2897+ error_code &= 0x58200000;
2898 else
2899 is_write = error_code & DSISR_ISSTORE;
2900 #else
bc901d79 2901@@ -258,7 +290,7 @@ good_area:
58c5fc13
MT
2902 * "undefined". Of those that can be set, this is the only
2903 * one which seems bad.
2904 */
2905- if (error_code & 0x10000000)
2906+ if (error_code & DSISR_GUARDED)
2907 /* Guarded storage error. */
2908 goto bad_area;
2909 #endif /* CONFIG_8xx */
bc901d79 2910@@ -273,7 +305,7 @@ good_area:
58c5fc13
MT
2911 * processors use the same I/D cache coherency mechanism
2912 * as embedded.
2913 */
2914- if (error_code & DSISR_PROTFAULT)
2915+ if (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))
2916 goto bad_area;
2917 #endif /* CONFIG_PPC_STD_MMU */
2918
bc901d79 2919@@ -342,6 +374,23 @@ bad_area:
58c5fc13
MT
2920 bad_area_nosemaphore:
2921 /* User mode accesses cause a SIGSEGV */
2922 if (user_mode(regs)) {
2923+
2924+#ifdef CONFIG_PAX_PAGEEXEC
2925+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
2926+#ifdef CONFIG_PPC_STD_MMU
2927+ if (is_exec && (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))) {
2928+#else
2929+ if (is_exec && regs->nip == address) {
2930+#endif
2931+ switch (pax_handle_fetch_fault(regs)) {
2932+ }
2933+
2934+ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
2935+ do_group_exit(SIGKILL);
2936+ }
2937+ }
2938+#endif
2939+
2940 _exception(SIGSEGV, regs, code, address);
2941 return 0;
2942 }
16454cff
MT
2943diff -urNp linux-2.6.38.1/arch/powerpc/mm/mmap_64.c linux-2.6.38.1/arch/powerpc/mm/mmap_64.c
2944--- linux-2.6.38.1/arch/powerpc/mm/mmap_64.c 2011-03-14 21:20:32.000000000 -0400
2945+++ linux-2.6.38.1/arch/powerpc/mm/mmap_64.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
2946@@ -99,10 +99,22 @@ void arch_pick_mmap_layout(struct mm_str
2947 */
2948 if (mmap_is_legacy()) {
2949 mm->mmap_base = TASK_UNMAPPED_BASE;
2950+
2951+#ifdef CONFIG_PAX_RANDMMAP
2952+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2953+ mm->mmap_base += mm->delta_mmap;
2954+#endif
2955+
2956 mm->get_unmapped_area = arch_get_unmapped_area;
2957 mm->unmap_area = arch_unmap_area;
2958 } else {
2959 mm->mmap_base = mmap_base();
2960+
2961+#ifdef CONFIG_PAX_RANDMMAP
2962+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2963+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2964+#endif
2965+
2966 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2967 mm->unmap_area = arch_unmap_area_topdown;
2968 }
16454cff
MT
2969diff -urNp linux-2.6.38.1/arch/powerpc/mm/slice.c linux-2.6.38.1/arch/powerpc/mm/slice.c
2970--- linux-2.6.38.1/arch/powerpc/mm/slice.c 2011-03-14 21:20:32.000000000 -0400
2971+++ linux-2.6.38.1/arch/powerpc/mm/slice.c 2011-03-21 23:47:41.000000000 -0400
6892158b 2972@@ -98,7 +98,7 @@ static int slice_area_is_free(struct mm_
57199397
MT
2973 if ((mm->task_size - len) < addr)
2974 return 0;
2975 vma = find_vma(mm, addr);
2976- return (!vma || (addr + len) <= vma->vm_start);
2977+ return check_heap_stack_gap(vma, addr, len);
2978 }
2979
6892158b
MT
2980 static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice)
2981@@ -256,7 +256,7 @@ full_search:
57199397
MT
2982 addr = _ALIGN_UP(addr + 1, 1ul << SLICE_HIGH_SHIFT);
2983 continue;
2984 }
2985- if (!vma || addr + len <= vma->vm_start) {
2986+ if (check_heap_stack_gap(vma, addr, len)) {
2987 /*
2988 * Remember the place where we stopped the search:
2989 */
16454cff
MT
2990@@ -313,10 +313,14 @@ static unsigned long slice_find_area_top
2991 }
2992 }
2993
2994- addr = mm->mmap_base;
2995- while (addr > len) {
2996+ if (mm->mmap_base < len)
2997+ addr = -ENOMEM;
2998+ else
2999+ addr = mm->mmap_base - len;
3000+
3001+ while (!IS_ERR_VALUE(addr)) {
3002 /* Go down by chunk size */
3003- addr = _ALIGN_DOWN(addr - len, 1ul << pshift);
3004+ addr = _ALIGN_DOWN(addr, 1ul << pshift);
3005
3006 /* Check for hit with different page size */
3007 mask = slice_range_to_mask(addr, len);
3008@@ -336,7 +340,7 @@ static unsigned long slice_find_area_top
57199397
MT
3009 * return with success:
3010 */
3011 vma = find_vma(mm, addr);
3012- if (!vma || (addr + len) <= vma->vm_start) {
3013+ if (check_heap_stack_gap(vma, addr, len)) {
3014 /* remember the address as a hint for next time */
3015 if (use_cache)
3016 mm->free_area_cache = addr;
16454cff
MT
3017@@ -348,7 +352,7 @@ static unsigned long slice_find_area_top
3018 mm->cached_hole_size = vma->vm_start - addr;
3019
3020 /* try just below the current vma->vm_start */
3021- addr = vma->vm_start;
3022+ addr = skip_heap_stack_gap(vma, len);
3023 }
3024
3025 /*
3026@@ -426,6 +430,11 @@ unsigned long slice_get_unmapped_area(un
58c5fc13
MT
3027 if (fixed && addr > (mm->task_size - len))
3028 return -EINVAL;
3029
3030+#ifdef CONFIG_PAX_RANDMMAP
3031+ if (!fixed && (mm->pax_flags & MF_PAX_RANDMMAP))
3032+ addr = 0;
3033+#endif
3034+
3035 /* If hint, make sure it matches our alignment restrictions */
3036 if (!fixed && addr) {
3037 addr = _ALIGN_UP(addr, 1ul << pshift);
16454cff
MT
3038diff -urNp linux-2.6.38.1/arch/powerpc/platforms/cell/iommu.c linux-2.6.38.1/arch/powerpc/platforms/cell/iommu.c
3039--- linux-2.6.38.1/arch/powerpc/platforms/cell/iommu.c 2011-03-14 21:20:32.000000000 -0400
3040+++ linux-2.6.38.1/arch/powerpc/platforms/cell/iommu.c 2011-03-21 18:31:35.000000000 -0400
57199397 3041@@ -642,7 +642,7 @@ static int dma_fixed_dma_supported(struc
ae4e228f
MT
3042
3043 static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
3044
3045-struct dma_map_ops dma_iommu_fixed_ops = {
3046+const struct dma_map_ops dma_iommu_fixed_ops = {
3047 .alloc_coherent = dma_fixed_alloc_coherent,
3048 .free_coherent = dma_fixed_free_coherent,
3049 .map_sg = dma_fixed_map_sg,
16454cff
MT
3050diff -urNp linux-2.6.38.1/arch/powerpc/platforms/ps3/system-bus.c linux-2.6.38.1/arch/powerpc/platforms/ps3/system-bus.c
3051--- linux-2.6.38.1/arch/powerpc/platforms/ps3/system-bus.c 2011-03-14 21:20:32.000000000 -0400
3052+++ linux-2.6.38.1/arch/powerpc/platforms/ps3/system-bus.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 3053@@ -695,7 +695,7 @@ static int ps3_dma_supported(struct devi
ae4e228f
MT
3054 return mask >= DMA_BIT_MASK(32);
3055 }
3056
3057-static struct dma_map_ops ps3_sb_dma_ops = {
3058+static const struct dma_map_ops ps3_sb_dma_ops = {
3059 .alloc_coherent = ps3_alloc_coherent,
3060 .free_coherent = ps3_free_coherent,
3061 .map_sg = ps3_sb_map_sg,
df50ba0c 3062@@ -705,7 +705,7 @@ static struct dma_map_ops ps3_sb_dma_ops
ae4e228f 3063 .unmap_page = ps3_unmap_page,
58c5fc13
MT
3064 };
3065
ae4e228f
MT
3066-static struct dma_map_ops ps3_ioc0_dma_ops = {
3067+static const struct dma_map_ops ps3_ioc0_dma_ops = {
3068 .alloc_coherent = ps3_alloc_coherent,
3069 .free_coherent = ps3_free_coherent,
3070 .map_sg = ps3_ioc0_map_sg,
16454cff
MT
3071diff -urNp linux-2.6.38.1/arch/powerpc/sysdev/ppc4xx_cpm.c linux-2.6.38.1/arch/powerpc/sysdev/ppc4xx_cpm.c
3072--- linux-2.6.38.1/arch/powerpc/sysdev/ppc4xx_cpm.c 2011-03-14 21:20:32.000000000 -0400
3073+++ linux-2.6.38.1/arch/powerpc/sysdev/ppc4xx_cpm.c 2011-03-21 18:31:35.000000000 -0400
3074@@ -240,7 +240,7 @@ static int cpm_suspend_enter(suspend_sta
3075 return 0;
58c5fc13
MT
3076 }
3077
16454cff
MT
3078-static struct platform_suspend_ops cpm_suspend_ops = {
3079+static const struct platform_suspend_ops cpm_suspend_ops = {
3080 .valid = cpm_suspend_valid,
3081 .enter = cpm_suspend_enter,
58c5fc13 3082 };
16454cff
MT
3083diff -urNp linux-2.6.38.1/arch/s390/include/asm/elf.h linux-2.6.38.1/arch/s390/include/asm/elf.h
3084--- linux-2.6.38.1/arch/s390/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
3085+++ linux-2.6.38.1/arch/s390/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
3086@@ -162,8 +162,14 @@ extern unsigned int vdso_enabled;
3087 the loader. We need to make sure that it is out of the way of the program
ae4e228f 3088 that it will "exec", and that there is sufficient room for the brk. */
58c5fc13 3089
16454cff
MT
3090-extern unsigned long randomize_et_dyn(unsigned long base);
3091-#define ELF_ET_DYN_BASE (randomize_et_dyn(STACK_TOP / 3 * 2))
3092+#define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2)
3093+
ae4e228f
MT
3094+#ifdef CONFIG_PAX_ASLR
3095+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_31BIT) ? 0x10000UL : 0x80000000UL)
58c5fc13 3096+
ae4e228f
MT
3097+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_31BIT) ? 15 : 26 )
3098+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_31BIT) ? 15 : 26 )
3099+#endif
16454cff 3100
ae4e228f
MT
3101 /* This yields a mask that user programs can use to figure out what
3102 instruction set this CPU supports. */
16454cff
MT
3103@@ -222,7 +228,4 @@ struct linux_binprm;
3104 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
3105 int arch_setup_additional_pages(struct linux_binprm *, int);
3106
3107-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
3108-#define arch_randomize_brk arch_randomize_brk
3109-
3110 #endif
3111diff -urNp linux-2.6.38.1/arch/s390/include/asm/system.h linux-2.6.38.1/arch/s390/include/asm/system.h
3112--- linux-2.6.38.1/arch/s390/include/asm/system.h 2011-03-14 21:20:32.000000000 -0400
3113+++ linux-2.6.38.1/arch/s390/include/asm/system.h 2011-03-21 18:31:35.000000000 -0400
3114@@ -449,7 +449,7 @@ extern void (*_machine_restart)(char *co
3115 extern void (*_machine_halt)(void);
3116 extern void (*_machine_power_off)(void);
58c5fc13 3117
16454cff
MT
3118-extern unsigned long arch_align_stack(unsigned long sp);
3119+#define arch_align_stack(x) ((x) & ~0xfUL)
3120
3121 static inline int tprot(unsigned long addr)
3122 {
3123diff -urNp linux-2.6.38.1/arch/s390/include/asm/uaccess.h linux-2.6.38.1/arch/s390/include/asm/uaccess.h
3124--- linux-2.6.38.1/arch/s390/include/asm/uaccess.h 2011-03-14 21:20:32.000000000 -0400
3125+++ linux-2.6.38.1/arch/s390/include/asm/uaccess.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 3126@@ -234,6 +234,10 @@ static inline unsigned long __must_check
58c5fc13
MT
3127 copy_to_user(void __user *to, const void *from, unsigned long n)
3128 {
3129 might_fault();
3130+
3131+ if ((long)n < 0)
3132+ return n;
3133+
3134 if (access_ok(VERIFY_WRITE, to, n))
3135 n = __copy_to_user(to, from, n);
3136 return n;
ae4e228f 3137@@ -259,6 +263,9 @@ copy_to_user(void __user *to, const void
58c5fc13
MT
3138 static inline unsigned long __must_check
3139 __copy_from_user(void *to, const void __user *from, unsigned long n)
3140 {
3141+ if ((long)n < 0)
3142+ return n;
3143+
3144 if (__builtin_constant_p(n) && (n <= 256))
3145 return uaccess.copy_from_user_small(n, from, to);
3146 else
df50ba0c
MT
3147@@ -293,6 +300,10 @@ copy_from_user(void *to, const void __us
3148 unsigned int sz = __compiletime_object_size(to);
3149
58c5fc13
MT
3150 might_fault();
3151+
3152+ if ((long)n < 0)
3153+ return n;
3154+
df50ba0c
MT
3155 if (unlikely(sz != -1 && sz < n)) {
3156 copy_from_user_overflow();
3157 return n;
16454cff
MT
3158diff -urNp linux-2.6.38.1/arch/s390/Kconfig linux-2.6.38.1/arch/s390/Kconfig
3159--- linux-2.6.38.1/arch/s390/Kconfig 2011-03-14 21:20:32.000000000 -0400
3160+++ linux-2.6.38.1/arch/s390/Kconfig 2011-03-21 18:31:35.000000000 -0400
3161@@ -233,11 +233,9 @@ config S390_EXEC_PROTECT
3162 prompt "Data execute protection"
57199397
MT
3163 help
3164 This option allows to enable a buffer overflow protection for user
3165- space programs and it also selects the addressing mode option above.
3166- The kernel parameter noexec=on will enable this feature and also
3167- switch the addressing modes, default is disabled. Enabling this (via
bc901d79
MT
3168- kernel parameter) on machines earlier than IBM System z9 this will
3169- reduce system performance.
57199397 3170+ space programs.
bc901d79 3171+ Enabling this (via kernel parameter) on machines earlier than IBM
16454cff 3172+ System z9 this will reduce system performance.
57199397
MT
3173
3174 comment "Code generation options"
3175
16454cff
MT
3176diff -urNp linux-2.6.38.1/arch/s390/kernel/module.c linux-2.6.38.1/arch/s390/kernel/module.c
3177--- linux-2.6.38.1/arch/s390/kernel/module.c 2011-03-14 21:20:32.000000000 -0400
3178+++ linux-2.6.38.1/arch/s390/kernel/module.c 2011-03-21 18:31:35.000000000 -0400
57199397 3179@@ -168,11 +168,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
58c5fc13
MT
3180
3181 /* Increase core size by size of got & plt and set start
3182 offsets for got and plt. */
3183- me->core_size = ALIGN(me->core_size, 4);
3184- me->arch.got_offset = me->core_size;
3185- me->core_size += me->arch.got_size;
3186- me->arch.plt_offset = me->core_size;
3187- me->core_size += me->arch.plt_size;
3188+ me->core_size_rw = ALIGN(me->core_size_rw, 4);
3189+ me->arch.got_offset = me->core_size_rw;
3190+ me->core_size_rw += me->arch.got_size;
3191+ me->arch.plt_offset = me->core_size_rx;
3192+ me->core_size_rx += me->arch.plt_size;
3193 return 0;
3194 }
3195
57199397 3196@@ -258,7 +258,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
58c5fc13
MT
3197 if (info->got_initialized == 0) {
3198 Elf_Addr *gotent;
3199
3200- gotent = me->module_core + me->arch.got_offset +
3201+ gotent = me->module_core_rw + me->arch.got_offset +
3202 info->got_offset;
3203 *gotent = val;
3204 info->got_initialized = 1;
57199397 3205@@ -282,7 +282,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
58c5fc13
MT
3206 else if (r_type == R_390_GOTENT ||
3207 r_type == R_390_GOTPLTENT)
3208 *(unsigned int *) loc =
3209- (val + (Elf_Addr) me->module_core - loc) >> 1;
3210+ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
3211 else if (r_type == R_390_GOT64 ||
3212 r_type == R_390_GOTPLT64)
3213 *(unsigned long *) loc = val;
57199397 3214@@ -296,7 +296,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
58c5fc13
MT
3215 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
3216 if (info->plt_initialized == 0) {
3217 unsigned int *ip;
3218- ip = me->module_core + me->arch.plt_offset +
3219+ ip = me->module_core_rx + me->arch.plt_offset +
3220 info->plt_offset;
3221 #ifndef CONFIG_64BIT
3222 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
57199397 3223@@ -321,7 +321,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
58c5fc13
MT
3224 val - loc + 0xffffUL < 0x1ffffeUL) ||
3225 (r_type == R_390_PLT32DBL &&
3226 val - loc + 0xffffffffULL < 0x1fffffffeULL)))
3227- val = (Elf_Addr) me->module_core +
3228+ val = (Elf_Addr) me->module_core_rx +
3229 me->arch.plt_offset +
3230 info->plt_offset;
3231 val += rela->r_addend - loc;
57199397 3232@@ -343,7 +343,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
58c5fc13
MT
3233 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
3234 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
3235 val = val + rela->r_addend -
3236- ((Elf_Addr) me->module_core + me->arch.got_offset);
3237+ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
3238 if (r_type == R_390_GOTOFF16)
3239 *(unsigned short *) loc = val;
3240 else if (r_type == R_390_GOTOFF32)
57199397 3241@@ -353,7 +353,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
58c5fc13
MT
3242 break;
3243 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
3244 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
3245- val = (Elf_Addr) me->module_core + me->arch.got_offset +
3246+ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
3247 rela->r_addend - loc;
3248 if (r_type == R_390_GOTPC)
3249 *(unsigned int *) loc = val;
16454cff
MT
3250diff -urNp linux-2.6.38.1/arch/s390/kernel/process.c linux-2.6.38.1/arch/s390/kernel/process.c
3251--- linux-2.6.38.1/arch/s390/kernel/process.c 2011-03-14 21:20:32.000000000 -0400
3252+++ linux-2.6.38.1/arch/s390/kernel/process.c 2011-03-21 18:31:35.000000000 -0400
3253@@ -334,39 +334,3 @@ unsigned long get_wchan(struct task_stru
3254 }
3255 return 0;
3256 }
3257-
3258-unsigned long arch_align_stack(unsigned long sp)
3259-{
3260- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
3261- sp -= get_random_int() & ~PAGE_MASK;
3262- return sp & ~0xf;
3263-}
3264-
3265-static inline unsigned long brk_rnd(void)
3266-{
3267- /* 8MB for 32bit, 1GB for 64bit */
3268- if (is_32bit_task())
3269- return (get_random_int() & 0x7ffUL) << PAGE_SHIFT;
3270- else
3271- return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT;
3272-}
3273-
3274-unsigned long arch_randomize_brk(struct mm_struct *mm)
3275-{
3276- unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
3277-
3278- if (ret < mm->brk)
3279- return mm->brk;
3280- return ret;
3281-}
3282-
3283-unsigned long randomize_et_dyn(unsigned long base)
3284-{
3285- unsigned long ret = PAGE_ALIGN(base + brk_rnd());
3286-
3287- if (!(current->flags & PF_RANDOMIZE))
3288- return base;
3289- if (ret < base)
3290- return base;
3291- return ret;
3292-}
3293diff -urNp linux-2.6.38.1/arch/s390/kernel/setup.c linux-2.6.38.1/arch/s390/kernel/setup.c
3294--- linux-2.6.38.1/arch/s390/kernel/setup.c 2011-03-14 21:20:32.000000000 -0400
3295+++ linux-2.6.38.1/arch/s390/kernel/setup.c 2011-03-21 18:31:35.000000000 -0400
57199397 3296@@ -281,7 +281,7 @@ static int __init early_parse_mem(char *
ae4e228f
MT
3297 }
3298 early_param("mem", early_parse_mem);
58c5fc13 3299
ae4e228f
MT
3300-unsigned int user_mode = HOME_SPACE_MODE;
3301+unsigned int user_mode = SECONDARY_SPACE_MODE;
3302 EXPORT_SYMBOL_GPL(user_mode);
3303
3304 static int set_amode_and_uaccess(unsigned long user_amode,
57199397 3305@@ -310,17 +310,6 @@ static int set_amode_and_uaccess(unsigne
ae4e228f
MT
3306 }
3307 }
3308
3309-/*
3310- * Switch kernel/user addressing modes?
3311- */
3312-static int __init early_parse_switch_amode(char *p)
3313-{
3314- if (user_mode != SECONDARY_SPACE_MODE)
3315- user_mode = PRIMARY_SPACE_MODE;
3316- return 0;
3317-}
3318-early_param("switch_amode", early_parse_switch_amode);
3319-
3320 static int __init early_parse_user_mode(char *p)
3321 {
3322 if (p && strcmp(p, "primary") == 0)
57199397 3323@@ -337,20 +326,6 @@ static int __init early_parse_user_mode(
ae4e228f
MT
3324 }
3325 early_param("user_mode", early_parse_user_mode);
3326
3327-#ifdef CONFIG_S390_EXEC_PROTECT
3328-/*
3329- * Enable execute protection?
3330- */
3331-static int __init early_parse_noexec(char *p)
3332-{
3333- if (!strncmp(p, "off", 3))
3334- return 0;
3335- user_mode = SECONDARY_SPACE_MODE;
3336- return 0;
3337-}
3338-early_param("noexec", early_parse_noexec);
3339-#endif /* CONFIG_S390_EXEC_PROTECT */
3340-
3341 static void setup_addressing_mode(void)
3342 {
3343 if (user_mode == SECONDARY_SPACE_MODE) {
16454cff
MT
3344diff -urNp linux-2.6.38.1/arch/s390/mm/maccess.c linux-2.6.38.1/arch/s390/mm/maccess.c
3345--- linux-2.6.38.1/arch/s390/mm/maccess.c 2011-03-14 21:20:32.000000000 -0400
3346+++ linux-2.6.38.1/arch/s390/mm/maccess.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
3347@@ -45,7 +45,7 @@ static long probe_kernel_write_odd(void
3348 return rc ? rc : count;
3349 }
3350
3351-long probe_kernel_write(void *dst, void *src, size_t size)
3352+long probe_kernel_write(void *dst, const void *src, size_t size)
3353 {
3354 long copied = 0;
3355
16454cff
MT
3356diff -urNp linux-2.6.38.1/arch/s390/mm/mmap.c linux-2.6.38.1/arch/s390/mm/mmap.c
3357--- linux-2.6.38.1/arch/s390/mm/mmap.c 2011-03-14 21:20:32.000000000 -0400
3358+++ linux-2.6.38.1/arch/s390/mm/mmap.c 2011-03-21 18:31:35.000000000 -0400
3359@@ -91,10 +91,22 @@ void arch_pick_mmap_layout(struct mm_str
ae4e228f
MT
3360 */
3361 if (mmap_is_legacy()) {
3362 mm->mmap_base = TASK_UNMAPPED_BASE;
3363+
3364+#ifdef CONFIG_PAX_RANDMMAP
3365+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3366+ mm->mmap_base += mm->delta_mmap;
3367+#endif
3368+
3369 mm->get_unmapped_area = arch_get_unmapped_area;
3370 mm->unmap_area = arch_unmap_area;
3371 } else {
3372 mm->mmap_base = mmap_base();
3373+
3374+#ifdef CONFIG_PAX_RANDMMAP
3375+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3376+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3377+#endif
3378+
3379 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3380 mm->unmap_area = arch_unmap_area_topdown;
3381 }
16454cff 3382@@ -166,10 +178,22 @@ void arch_pick_mmap_layout(struct mm_str
ae4e228f
MT
3383 */
3384 if (mmap_is_legacy()) {
3385 mm->mmap_base = TASK_UNMAPPED_BASE;
3386+
3387+#ifdef CONFIG_PAX_RANDMMAP
3388+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3389+ mm->mmap_base += mm->delta_mmap;
3390+#endif
3391+
3392 mm->get_unmapped_area = s390_get_unmapped_area;
3393 mm->unmap_area = arch_unmap_area;
3394 } else {
3395 mm->mmap_base = mmap_base();
3396+
3397+#ifdef CONFIG_PAX_RANDMMAP
3398+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3399+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3400+#endif
3401+
3402 mm->get_unmapped_area = s390_get_unmapped_area_topdown;
3403 mm->unmap_area = arch_unmap_area_topdown;
3404 }
16454cff
MT
3405diff -urNp linux-2.6.38.1/arch/score/include/asm/system.h linux-2.6.38.1/arch/score/include/asm/system.h
3406--- linux-2.6.38.1/arch/score/include/asm/system.h 2011-03-14 21:20:32.000000000 -0400
3407+++ linux-2.6.38.1/arch/score/include/asm/system.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
3408@@ -17,7 +17,7 @@ do { \
3409 #define finish_arch_switch(prev) do {} while (0)
3410
3411 typedef void (*vi_handler_t)(void);
3412-extern unsigned long arch_align_stack(unsigned long sp);
3413+#define arch_align_stack(x) (x)
3414
3415 #define mb() barrier()
3416 #define rmb() barrier()
16454cff
MT
3417diff -urNp linux-2.6.38.1/arch/score/kernel/process.c linux-2.6.38.1/arch/score/kernel/process.c
3418--- linux-2.6.38.1/arch/score/kernel/process.c 2011-03-14 21:20:32.000000000 -0400
3419+++ linux-2.6.38.1/arch/score/kernel/process.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
3420@@ -161,8 +161,3 @@ unsigned long get_wchan(struct task_stru
3421
3422 return task_pt_regs(task)->cp0_epc;
3423 }
3424-
3425-unsigned long arch_align_stack(unsigned long sp)
3426-{
3427- return sp;
3428-}
16454cff
MT
3429diff -urNp linux-2.6.38.1/arch/sh/include/asm/dma-mapping.h linux-2.6.38.1/arch/sh/include/asm/dma-mapping.h
3430--- linux-2.6.38.1/arch/sh/include/asm/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
3431+++ linux-2.6.38.1/arch/sh/include/asm/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
3432@@ -1,10 +1,10 @@
3433 #ifndef __ASM_SH_DMA_MAPPING_H
3434 #define __ASM_SH_DMA_MAPPING_H
3435
3436-extern struct dma_map_ops *dma_ops;
3437+extern const struct dma_map_ops *dma_ops;
3438 extern void no_iommu_init(void);
3439
3440-static inline struct dma_map_ops *get_dma_ops(struct device *dev)
3441+static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
3442 {
3443 return dma_ops;
3444 }
3445@@ -14,7 +14,7 @@ static inline struct dma_map_ops *get_dm
3446
3447 static inline int dma_supported(struct device *dev, u64 mask)
3448 {
3449- struct dma_map_ops *ops = get_dma_ops(dev);
3450+ const struct dma_map_ops *ops = get_dma_ops(dev);
3451
3452 if (ops->dma_supported)
3453 return ops->dma_supported(dev, mask);
3454@@ -24,7 +24,7 @@ static inline int dma_supported(struct d
3455
3456 static inline int dma_set_mask(struct device *dev, u64 mask)
3457 {
3458- struct dma_map_ops *ops = get_dma_ops(dev);
3459+ const struct dma_map_ops *ops = get_dma_ops(dev);
3460
3461 if (!dev->dma_mask || !dma_supported(dev, mask))
3462 return -EIO;
6892158b 3463@@ -44,7 +44,7 @@ void dma_cache_sync(struct device *dev,
ae4e228f
MT
3464
3465 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
3466 {
3467- struct dma_map_ops *ops = get_dma_ops(dev);
3468+ const struct dma_map_ops *ops = get_dma_ops(dev);
3469
3470 if (ops->mapping_error)
3471 return ops->mapping_error(dev, dma_addr);
6892158b 3472@@ -55,7 +55,7 @@ static inline int dma_mapping_error(stru
ae4e228f
MT
3473 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
3474 dma_addr_t *dma_handle, gfp_t gfp)
3475 {
3476- struct dma_map_ops *ops = get_dma_ops(dev);
3477+ const struct dma_map_ops *ops = get_dma_ops(dev);
3478 void *memory;
3479
3480 if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
6892158b 3481@@ -72,7 +72,7 @@ static inline void *dma_alloc_coherent(s
ae4e228f
MT
3482 static inline void dma_free_coherent(struct device *dev, size_t size,
3483 void *vaddr, dma_addr_t dma_handle)
3484 {
3485- struct dma_map_ops *ops = get_dma_ops(dev);
3486+ const struct dma_map_ops *ops = get_dma_ops(dev);
3487
df50ba0c
MT
3488 if (dma_release_from_coherent(dev, get_order(size), vaddr))
3489 return;
16454cff
MT
3490diff -urNp linux-2.6.38.1/arch/sh/kernel/dma-nommu.c linux-2.6.38.1/arch/sh/kernel/dma-nommu.c
3491--- linux-2.6.38.1/arch/sh/kernel/dma-nommu.c 2011-03-14 21:20:32.000000000 -0400
3492+++ linux-2.6.38.1/arch/sh/kernel/dma-nommu.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
3493@@ -62,7 +62,7 @@ static void nommu_sync_sg(struct device
3494 }
3495 #endif
3496
3497-struct dma_map_ops nommu_dma_ops = {
3498+const struct dma_map_ops nommu_dma_ops = {
3499 .alloc_coherent = dma_generic_alloc_coherent,
3500 .free_coherent = dma_generic_free_coherent,
3501 .map_page = nommu_map_page,
16454cff
MT
3502diff -urNp linux-2.6.38.1/arch/sh/kernel/kgdb.c linux-2.6.38.1/arch/sh/kernel/kgdb.c
3503--- linux-2.6.38.1/arch/sh/kernel/kgdb.c 2011-03-14 21:20:32.000000000 -0400
3504+++ linux-2.6.38.1/arch/sh/kernel/kgdb.c 2011-03-21 18:31:35.000000000 -0400
57199397 3505@@ -319,7 +319,7 @@ void kgdb_arch_exit(void)
df50ba0c 3506 unregister_die_notifier(&kgdb_notifier);
ae4e228f
MT
3507 }
3508
3509-struct kgdb_arch arch_kgdb_ops = {
3510+const struct kgdb_arch arch_kgdb_ops = {
3511 /* Breakpoint instruction: trapa #0x3c */
3512 #ifdef CONFIG_CPU_LITTLE_ENDIAN
3513 .gdb_bpt_instr = { 0x3c, 0xc3 },
16454cff
MT
3514diff -urNp linux-2.6.38.1/arch/sh/mm/consistent.c linux-2.6.38.1/arch/sh/mm/consistent.c
3515--- linux-2.6.38.1/arch/sh/mm/consistent.c 2011-03-14 21:20:32.000000000 -0400
3516+++ linux-2.6.38.1/arch/sh/mm/consistent.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 3517@@ -22,7 +22,7 @@
ae4e228f
MT
3518
3519 #define PREALLOC_DMA_DEBUG_ENTRIES 4096
3520
3521-struct dma_map_ops *dma_ops;
3522+const struct dma_map_ops *dma_ops;
3523 EXPORT_SYMBOL(dma_ops);
3524
3525 static int __init dma_init(void)
16454cff
MT
3526diff -urNp linux-2.6.38.1/arch/sh/mm/mmap.c linux-2.6.38.1/arch/sh/mm/mmap.c
3527--- linux-2.6.38.1/arch/sh/mm/mmap.c 2011-03-14 21:20:32.000000000 -0400
3528+++ linux-2.6.38.1/arch/sh/mm/mmap.c 2011-03-21 23:47:41.000000000 -0400
57199397
MT
3529@@ -74,8 +74,7 @@ unsigned long arch_get_unmapped_area(str
3530 addr = PAGE_ALIGN(addr);
3531
3532 vma = find_vma(mm, addr);
3533- if (TASK_SIZE - len >= addr &&
3534- (!vma || addr + len <= vma->vm_start))
3535+ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
3536 return addr;
3537 }
efbe55a5 3538
57199397
MT
3539@@ -106,7 +105,7 @@ full_search:
3540 }
3541 return -ENOMEM;
3542 }
3543- if (likely(!vma || addr + len <= vma->vm_start)) {
3544+ if (likely(check_heap_stack_gap(vma, addr, len))) {
3545 /*
3546 * Remember the place where we stopped the search:
3547 */
3548@@ -157,8 +156,7 @@ arch_get_unmapped_area_topdown(struct fi
3549 addr = PAGE_ALIGN(addr);
3550
3551 vma = find_vma(mm, addr);
3552- if (TASK_SIZE - len >= addr &&
3553- (!vma || addr + len <= vma->vm_start))
3554+ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
3555 return addr;
3556 }
3557
3558@@ -179,7 +177,7 @@ arch_get_unmapped_area_topdown(struct fi
3559 /* make sure it can fit in the remaining address space */
3560 if (likely(addr > len)) {
3561 vma = find_vma(mm, addr-len);
3562- if (!vma || addr <= vma->vm_start) {
3563+ if (check_heap_stack_gap(vma, addr - len, len)) {
3564 /* remember the address as a hint for next time */
3565 return (mm->free_area_cache = addr-len);
3566 }
16454cff
MT
3567@@ -188,18 +186,18 @@ arch_get_unmapped_area_topdown(struct fi
3568 if (unlikely(mm->mmap_base < len))
3569 goto bottomup;
3570
3571- addr = mm->mmap_base-len;
3572- if (do_colour_align)
3573- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
3574+ addr = mm->mmap_base - len;
3575
3576 do {
3577+ if (do_colour_align)
3578+ addr = COLOUR_ALIGN_DOWN(addr, pgoff);
3579 /*
3580 * Lookup failure means no vma is above this address,
3581 * else if new region fits below vma->vm_start,
57199397
MT
3582 * return with success:
3583 */
3584 vma = find_vma(mm, addr);
3585- if (likely(!vma || addr+len <= vma->vm_start)) {
3586+ if (likely(check_heap_stack_gap(vma, addr, len))) {
3587 /* remember the address as a hint for next time */
3588 return (mm->free_area_cache = addr);
3589 }
16454cff
MT
3590@@ -209,10 +207,8 @@ arch_get_unmapped_area_topdown(struct fi
3591 mm->cached_hole_size = vma->vm_start - addr;
3592
3593 /* try just below the current vma->vm_start */
3594- addr = vma->vm_start-len;
3595- if (do_colour_align)
3596- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
3597- } while (likely(len < vma->vm_start));
3598+ addr = skip_heap_stack_gap(vma, len);
3599+ } while (!IS_ERR_VALUE(addr));
3600
3601 bottomup:
3602 /*
3603diff -urNp linux-2.6.38.1/arch/sparc/include/asm/atomic_64.h linux-2.6.38.1/arch/sparc/include/asm/atomic_64.h
3604--- linux-2.6.38.1/arch/sparc/include/asm/atomic_64.h 2011-03-14 21:20:32.000000000 -0400
3605+++ linux-2.6.38.1/arch/sparc/include/asm/atomic_64.h 2011-03-21 18:31:35.000000000 -0400
57199397 3606@@ -14,18 +14,40 @@
58c5fc13
MT
3607 #define ATOMIC64_INIT(i) { (i) }
3608
57199397 3609 #define atomic_read(v) (*(volatile int *)&(v)->counter)
ae4e228f
MT
3610+static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
3611+{
3612+ return v->counter;
3613+}
57199397 3614 #define atomic64_read(v) (*(volatile long *)&(v)->counter)
ae4e228f
MT
3615+static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
3616+{
3617+ return v->counter;
3618+}
58c5fc13
MT
3619
3620 #define atomic_set(v, i) (((v)->counter) = i)
ae4e228f
MT
3621+static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
3622+{
3623+ v->counter = i;
3624+}
58c5fc13 3625 #define atomic64_set(v, i) (((v)->counter) = i)
ae4e228f
MT
3626+static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
3627+{
3628+ v->counter = i;
3629+}
58c5fc13
MT
3630
3631 extern void atomic_add(int, atomic_t *);
3632+extern void atomic_add_unchecked(int, atomic_unchecked_t *);
57199397
MT
3633 extern void atomic64_add(long, atomic64_t *);
3634+extern void atomic64_add_unchecked(long, atomic64_unchecked_t *);
58c5fc13
MT
3635 extern void atomic_sub(int, atomic_t *);
3636+extern void atomic_sub_unchecked(int, atomic_unchecked_t *);
57199397
MT
3637 extern void atomic64_sub(long, atomic64_t *);
3638+extern void atomic64_sub_unchecked(long, atomic64_unchecked_t *);
58c5fc13
MT
3639
3640 extern int atomic_add_ret(int, atomic_t *);
57199397
MT
3641+extern int atomic_add_ret_unchecked(int, atomic_unchecked_t *);
3642 extern long atomic64_add_ret(long, atomic64_t *);
3643+extern long atomic64_add_ret_unchecked(long, atomic64_unchecked_t *);
ae4e228f 3644 extern int atomic_sub_ret(int, atomic_t *);
57199397 3645 extern long atomic64_sub_ret(long, atomic64_t *);
ae4e228f 3646
6892158b 3647@@ -33,12 +55,24 @@ extern long atomic64_sub_ret(long, atomi
57199397 3648 #define atomic64_dec_return(v) atomic64_sub_ret(1, v)
ae4e228f
MT
3649
3650 #define atomic_inc_return(v) atomic_add_ret(1, v)
57199397
MT
3651+static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
3652+{
3653+ return atomic_add_ret_unchecked(1, v);
3654+}
ae4e228f 3655 #define atomic64_inc_return(v) atomic64_add_ret(1, v)
57199397
MT
3656+static inline long atomic64_inc_return_unchecked(atomic64_unchecked_t *v)
3657+{
3658+ return atomic64_add_ret_unchecked(1, v);
3659+}
ae4e228f
MT
3660
3661 #define atomic_sub_return(i, v) atomic_sub_ret(i, v)
3662 #define atomic64_sub_return(i, v) atomic64_sub_ret(i, v)
6892158b
MT
3663
3664 #define atomic_add_return(i, v) atomic_add_ret(i, v)
3665+static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
3666+{
3667+ return atomic_add_ret_unchecked(i, v);
3668+}
3669 #define atomic64_add_return(i, v) atomic64_add_ret(i, v)
3670
3671 /*
3672@@ -59,10 +93,26 @@ extern long atomic64_sub_ret(long, atomi
58c5fc13
MT
3673 #define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0)
3674
3675 #define atomic_inc(v) atomic_add(1, v)
ae4e228f
MT
3676+static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
3677+{
3678+ atomic_add_unchecked(1, v);
3679+}
58c5fc13 3680 #define atomic64_inc(v) atomic64_add(1, v)
ae4e228f
MT
3681+static inline void atomic64_inc_unchecked(atomic64_unchecked_t *v)
3682+{
3683+ atomic64_add_unchecked(1, v);
3684+}
58c5fc13
MT
3685
3686 #define atomic_dec(v) atomic_sub(1, v)
df50ba0c
MT
3687+static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
3688+{
3689+ atomic_sub_unchecked(1, v);
3690+}
ae4e228f 3691 #define atomic64_dec(v) atomic64_sub(1, v)
df50ba0c
MT
3692+static inline void atomic64_dec_unchecked(atomic64_unchecked_t *v)
3693+{
3694+ atomic64_sub_unchecked(1, v);
3695+}
3696
3697 #define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
3698 #define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
6892158b 3699@@ -72,17 +122,28 @@ extern long atomic64_sub_ret(long, atomi
58c5fc13
MT
3700
3701 static inline int atomic_add_unless(atomic_t *v, int a, int u)
3702 {
3703- int c, old;
3704+ int c, old, new;
3705 c = atomic_read(v);
3706 for (;;) {
3707- if (unlikely(c == (u)))
3708+ if (unlikely(c == u))
3709 break;
3710- old = atomic_cmpxchg((v), c, c + (a));
3711+
3712+ asm volatile("addcc %2, %0, %0\n"
3713+
3714+#ifdef CONFIG_PAX_REFCOUNT
3715+ "tvs %%icc, 6\n"
3716+#endif
3717+
3718+ : "=r" (new)
3719+ : "0" (c), "ir" (a)
3720+ : "cc");
3721+
3722+ old = atomic_cmpxchg(v, c, new);
3723 if (likely(old == c))
3724 break;
3725 c = old;
3726 }
3727- return c != (u);
3728+ return c != u;
3729 }
3730
3731 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
6892158b 3732@@ -93,17 +154,28 @@ static inline int atomic_add_unless(atom
58c5fc13 3733
57199397 3734 static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
58c5fc13
MT
3735 {
3736- long c, old;
3737+ long c, old, new;
3738 c = atomic64_read(v);
3739 for (;;) {
3740- if (unlikely(c == (u)))
3741+ if (unlikely(c == u))
3742 break;
3743- old = atomic64_cmpxchg((v), c, c + (a));
3744+
3745+ asm volatile("addcc %2, %0, %0\n"
3746+
3747+#ifdef CONFIG_PAX_REFCOUNT
3748+ "tvs %%xcc, 6\n"
3749+#endif
3750+
3751+ : "=r" (new)
3752+ : "0" (c), "ir" (a)
3753+ : "cc");
3754+
3755+ old = atomic64_cmpxchg(v, c, new);
3756 if (likely(old == c))
3757 break;
3758 c = old;
3759 }
3760- return c != (u);
3761+ return c != u;
3762 }
3763
3764 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
16454cff
MT
3765diff -urNp linux-2.6.38.1/arch/sparc/include/asm/dma-mapping.h linux-2.6.38.1/arch/sparc/include/asm/dma-mapping.h
3766--- linux-2.6.38.1/arch/sparc/include/asm/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
3767+++ linux-2.6.38.1/arch/sparc/include/asm/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
3768@@ -12,10 +12,10 @@ extern int dma_supported(struct device *
3769 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
ae4e228f 3770 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
ae4e228f
MT
3771
3772-extern struct dma_map_ops *dma_ops, pci32_dma_ops;
df50ba0c 3773+extern const struct dma_map_ops *dma_ops, pci32_dma_ops;
ae4e228f
MT
3774 extern struct bus_type pci_bus_type;
3775
3776-static inline struct dma_map_ops *get_dma_ops(struct device *dev)
3777+static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
3778 {
3779 #if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
3780 if (dev->bus == &pci_bus_type)
6892158b 3781@@ -29,7 +29,7 @@ static inline struct dma_map_ops *get_dm
ae4e228f
MT
3782 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
3783 dma_addr_t *dma_handle, gfp_t flag)
3784 {
3785- struct dma_map_ops *ops = get_dma_ops(dev);
3786+ const struct dma_map_ops *ops = get_dma_ops(dev);
3787 void *cpu_addr;
3788
3789 cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag);
6892158b 3790@@ -40,7 +40,7 @@ static inline void *dma_alloc_coherent(s
ae4e228f
MT
3791 static inline void dma_free_coherent(struct device *dev, size_t size,
3792 void *cpu_addr, dma_addr_t dma_handle)
3793 {
3794- struct dma_map_ops *ops = get_dma_ops(dev);
3795+ const struct dma_map_ops *ops = get_dma_ops(dev);
3796
3797 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
3798 ops->free_coherent(dev, size, cpu_addr, dma_handle);
16454cff
MT
3799diff -urNp linux-2.6.38.1/arch/sparc/include/asm/elf_32.h linux-2.6.38.1/arch/sparc/include/asm/elf_32.h
3800--- linux-2.6.38.1/arch/sparc/include/asm/elf_32.h 2011-03-14 21:20:32.000000000 -0400
3801+++ linux-2.6.38.1/arch/sparc/include/asm/elf_32.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 3802@@ -114,6 +114,13 @@ typedef struct {
58c5fc13
MT
3803
3804 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
3805
3806+#ifdef CONFIG_PAX_ASLR
3807+#define PAX_ELF_ET_DYN_BASE 0x10000UL
3808+
3809+#define PAX_DELTA_MMAP_LEN 16
3810+#define PAX_DELTA_STACK_LEN 16
3811+#endif
3812+
3813 /* This yields a mask that user programs can use to figure out what
3814 instruction set this cpu supports. This can NOT be done in userspace
3815 on Sparc. */
16454cff
MT
3816diff -urNp linux-2.6.38.1/arch/sparc/include/asm/elf_64.h linux-2.6.38.1/arch/sparc/include/asm/elf_64.h
3817--- linux-2.6.38.1/arch/sparc/include/asm/elf_64.h 2011-03-14 21:20:32.000000000 -0400
3818+++ linux-2.6.38.1/arch/sparc/include/asm/elf_64.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 3819@@ -162,6 +162,12 @@ typedef struct {
58c5fc13
MT
3820 #define ELF_ET_DYN_BASE 0x0000010000000000UL
3821 #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
3822
3823+#ifdef CONFIG_PAX_ASLR
3824+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
3825+
ae4e228f
MT
3826+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28)
3827+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29)
58c5fc13
MT
3828+#endif
3829
3830 /* This yields a mask that user programs can use to figure out what
3831 instruction set this cpu supports. */
16454cff
MT
3832diff -urNp linux-2.6.38.1/arch/sparc/include/asm/pgtable_32.h linux-2.6.38.1/arch/sparc/include/asm/pgtable_32.h
3833--- linux-2.6.38.1/arch/sparc/include/asm/pgtable_32.h 2011-03-14 21:20:32.000000000 -0400
3834+++ linux-2.6.38.1/arch/sparc/include/asm/pgtable_32.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
3835@@ -43,6 +43,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
3836 BTFIXUPDEF_INT(page_none)
3837 BTFIXUPDEF_INT(page_copy)
3838 BTFIXUPDEF_INT(page_readonly)
3839+
3840+#ifdef CONFIG_PAX_PAGEEXEC
3841+BTFIXUPDEF_INT(page_shared_noexec)
3842+BTFIXUPDEF_INT(page_copy_noexec)
3843+BTFIXUPDEF_INT(page_readonly_noexec)
3844+#endif
3845+
3846 BTFIXUPDEF_INT(page_kernel)
3847
3848 #define PMD_SHIFT SUN4C_PMD_SHIFT
3849@@ -64,6 +71,16 @@ extern pgprot_t PAGE_SHARED;
3850 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
3851 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
3852
3853+#ifdef CONFIG_PAX_PAGEEXEC
3854+extern pgprot_t PAGE_SHARED_NOEXEC;
3855+# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
3856+# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
3857+#else
3858+# define PAGE_SHARED_NOEXEC PAGE_SHARED
3859+# define PAGE_COPY_NOEXEC PAGE_COPY
3860+# define PAGE_READONLY_NOEXEC PAGE_READONLY
3861+#endif
3862+
3863 extern unsigned long page_kernel;
3864
3865 #ifdef MODULE
16454cff
MT
3866diff -urNp linux-2.6.38.1/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.38.1/arch/sparc/include/asm/pgtsrmmu.h
3867--- linux-2.6.38.1/arch/sparc/include/asm/pgtsrmmu.h 2011-03-14 21:20:32.000000000 -0400
3868+++ linux-2.6.38.1/arch/sparc/include/asm/pgtsrmmu.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
3869@@ -115,6 +115,13 @@
3870 SRMMU_EXEC | SRMMU_REF)
3871 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
3872 SRMMU_EXEC | SRMMU_REF)
3873+
3874+#ifdef CONFIG_PAX_PAGEEXEC
3875+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
3876+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
3877+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
3878+#endif
3879+
3880 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
3881 SRMMU_DIRTY | SRMMU_REF)
3882
16454cff
MT
3883diff -urNp linux-2.6.38.1/arch/sparc/include/asm/spinlock_64.h linux-2.6.38.1/arch/sparc/include/asm/spinlock_64.h
3884--- linux-2.6.38.1/arch/sparc/include/asm/spinlock_64.h 2011-03-14 21:20:32.000000000 -0400
3885+++ linux-2.6.38.1/arch/sparc/include/asm/spinlock_64.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 3886@@ -99,7 +99,12 @@ static void inline arch_read_lock(arch_r
58c5fc13
MT
3887 __asm__ __volatile__ (
3888 "1: ldsw [%2], %0\n"
3889 " brlz,pn %0, 2f\n"
3890-"4: add %0, 1, %1\n"
3891+"4: addcc %0, 1, %1\n"
3892+
3893+#ifdef CONFIG_PAX_REFCOUNT
3894+" tvs %%icc, 6\n"
3895+#endif
3896+
3897 " cas [%2], %0, %1\n"
3898 " cmp %0, %1\n"
3899 " bne,pn %%icc, 1b\n"
ae4e228f 3900@@ -112,7 +117,7 @@ static void inline arch_read_lock(arch_r
58c5fc13
MT
3901 " .previous"
3902 : "=&r" (tmp1), "=&r" (tmp2)
3903 : "r" (lock)
3904- : "memory");
3905+ : "memory", "cc");
3906 }
3907
ae4e228f
MT
3908 static int inline arch_read_trylock(arch_rwlock_t *lock)
3909@@ -123,7 +128,12 @@ static int inline arch_read_trylock(arch
58c5fc13
MT
3910 "1: ldsw [%2], %0\n"
3911 " brlz,a,pn %0, 2f\n"
3912 " mov 0, %0\n"
3913-" add %0, 1, %1\n"
3914+" addcc %0, 1, %1\n"
3915+
3916+#ifdef CONFIG_PAX_REFCOUNT
3917+" tvs %%icc, 6\n"
3918+#endif
3919+
3920 " cas [%2], %0, %1\n"
3921 " cmp %0, %1\n"
3922 " bne,pn %%icc, 1b\n"
ae4e228f 3923@@ -142,7 +152,12 @@ static void inline arch_read_unlock(arch
58c5fc13
MT
3924
3925 __asm__ __volatile__(
3926 "1: lduw [%2], %0\n"
3927-" sub %0, 1, %1\n"
3928+" subcc %0, 1, %1\n"
3929+
3930+#ifdef CONFIG_PAX_REFCOUNT
ae4e228f 3931+" tvs %%icc, 6\n"
58c5fc13
MT
3932+#endif
3933+
3934 " cas [%2], %0, %1\n"
3935 " cmp %0, %1\n"
3936 " bne,pn %%xcc, 1b\n"
16454cff
MT
3937diff -urNp linux-2.6.38.1/arch/sparc/include/asm/uaccess_32.h linux-2.6.38.1/arch/sparc/include/asm/uaccess_32.h
3938--- linux-2.6.38.1/arch/sparc/include/asm/uaccess_32.h 2011-03-14 21:20:32.000000000 -0400
3939+++ linux-2.6.38.1/arch/sparc/include/asm/uaccess_32.h 2011-03-21 18:31:35.000000000 -0400
6892158b 3940@@ -249,27 +249,46 @@ extern unsigned long __copy_user(void __
58c5fc13
MT
3941
3942 static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
3943 {
3944- if (n && __access_ok((unsigned long) to, n))
3945+ if ((long)n < 0)
3946+ return n;
3947+
3948+ if (n && __access_ok((unsigned long) to, n)) {
3949+ if (!__builtin_constant_p(n))
3950+ check_object_size(from, n, true);
3951 return __copy_user(to, (__force void __user *) from, n);
3952- else
3953+ } else
3954 return n;
3955 }
3956
3957 static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
3958 {
3959+ if ((long)n < 0)
3960+ return n;
3961+
3962+ if (!__builtin_constant_p(n))
3963+ check_object_size(from, n, true);
3964+
3965 return __copy_user(to, (__force void __user *) from, n);
3966 }
3967
6892158b 3968 static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
58c5fc13 3969 {
6892158b 3970- if (n && __access_ok((unsigned long) from, n))
58c5fc13
MT
3971+ if ((long)n < 0)
3972+ return n;
3973+
3974+ if (n && __access_ok((unsigned long) from, n)) {
3975+ if (!__builtin_constant_p(n))
3976+ check_object_size(to, n, false);
3977 return __copy_user((__force void __user *) to, from, n);
3978- else
3979+ } else
3980 return n;
3981 }
3982
3983 static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
3984 {
3985+ if ((long)n < 0)
3986+ return n;
58c5fc13
MT
3987+
3988 return __copy_user((__force void __user *) to, from, n);
3989 }
3990
16454cff
MT
3991diff -urNp linux-2.6.38.1/arch/sparc/include/asm/uaccess_64.h linux-2.6.38.1/arch/sparc/include/asm/uaccess_64.h
3992--- linux-2.6.38.1/arch/sparc/include/asm/uaccess_64.h 2011-03-14 21:20:32.000000000 -0400
3993+++ linux-2.6.38.1/arch/sparc/include/asm/uaccess_64.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
3994@@ -10,6 +10,7 @@
3995 #include <linux/compiler.h>
3996 #include <linux/string.h>
3997 #include <linux/thread_info.h>
3998+#include <linux/kernel.h>
3999 #include <asm/asi.h>
4000 #include <asm/system.h>
4001 #include <asm/spitfire.h>
6892158b
MT
4002@@ -213,8 +214,15 @@ extern unsigned long copy_from_user_fixu
4003 static inline unsigned long __must_check
4004 copy_from_user(void *to, const void __user *from, unsigned long size)
4005 {
4006- unsigned long ret = ___copy_from_user(to, from, size);
4007+ unsigned long ret;
ae4e228f
MT
4008
4009+ if ((long)size < 0 || size > INT_MAX)
58c5fc13
MT
4010+ return size;
4011+
4012+ if (!__builtin_constant_p(size))
4013+ check_object_size(to, size, false);
4014+
6892158b
MT
4015+ ret = ___copy_from_user(to, from, size);
4016 if (unlikely(ret))
4017 ret = copy_from_user_fixup(to, from, size);
4018
4019@@ -230,8 +238,15 @@ extern unsigned long copy_to_user_fixup(
58c5fc13
MT
4020 static inline unsigned long __must_check
4021 copy_to_user(void __user *to, const void *from, unsigned long size)
4022 {
4023- unsigned long ret = ___copy_to_user(to, from, size);
4024+ unsigned long ret;
4025+
ae4e228f 4026+ if ((long)size < 0 || size > INT_MAX)
58c5fc13
MT
4027+ return size;
4028+
4029+ if (!__builtin_constant_p(size))
4030+ check_object_size(from, size, true);
58c5fc13 4031
ae4e228f 4032+ ret = ___copy_to_user(to, from, size);
58c5fc13
MT
4033 if (unlikely(ret))
4034 ret = copy_to_user_fixup(to, from, size);
ae4e228f 4035 return ret;
16454cff
MT
4036diff -urNp linux-2.6.38.1/arch/sparc/include/asm/uaccess.h linux-2.6.38.1/arch/sparc/include/asm/uaccess.h
4037--- linux-2.6.38.1/arch/sparc/include/asm/uaccess.h 2011-03-14 21:20:32.000000000 -0400
4038+++ linux-2.6.38.1/arch/sparc/include/asm/uaccess.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
4039@@ -1,5 +1,13 @@
4040 #ifndef ___ASM_SPARC_UACCESS_H
4041 #define ___ASM_SPARC_UACCESS_H
4042+
4043+#ifdef __KERNEL__
4044+#ifndef __ASSEMBLY__
4045+#include <linux/types.h>
4046+extern void check_object_size(const void *ptr, unsigned long n, bool to);
4047+#endif
4048+#endif
4049+
4050 #if defined(__sparc__) && defined(__arch64__)
4051 #include <asm/uaccess_64.h>
4052 #else
16454cff
MT
4053diff -urNp linux-2.6.38.1/arch/sparc/kernel/iommu.c linux-2.6.38.1/arch/sparc/kernel/iommu.c
4054--- linux-2.6.38.1/arch/sparc/kernel/iommu.c 2011-03-14 21:20:32.000000000 -0400
4055+++ linux-2.6.38.1/arch/sparc/kernel/iommu.c 2011-03-21 18:31:35.000000000 -0400
4056@@ -827,7 +827,7 @@ static void dma_4u_sync_sg_for_cpu(struc
ae4e228f
MT
4057 spin_unlock_irqrestore(&iommu->lock, flags);
4058 }
4059
4060-static struct dma_map_ops sun4u_dma_ops = {
4061+static const struct dma_map_ops sun4u_dma_ops = {
4062 .alloc_coherent = dma_4u_alloc_coherent,
4063 .free_coherent = dma_4u_free_coherent,
4064 .map_page = dma_4u_map_page,
16454cff 4065@@ -838,7 +838,7 @@ static struct dma_map_ops sun4u_dma_ops
ae4e228f
MT
4066 .sync_sg_for_cpu = dma_4u_sync_sg_for_cpu,
4067 };
4068
4069-struct dma_map_ops *dma_ops = &sun4u_dma_ops;
4070+const struct dma_map_ops *dma_ops = &sun4u_dma_ops;
4071 EXPORT_SYMBOL(dma_ops);
4072
4073 extern int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask);
16454cff
MT
4074diff -urNp linux-2.6.38.1/arch/sparc/kernel/ioport.c linux-2.6.38.1/arch/sparc/kernel/ioport.c
4075--- linux-2.6.38.1/arch/sparc/kernel/ioport.c 2011-03-14 21:20:32.000000000 -0400
4076+++ linux-2.6.38.1/arch/sparc/kernel/ioport.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
4077@@ -397,7 +397,7 @@ static void sbus_sync_sg_for_device(stru
4078 BUG();
4079 }
4080
4081-struct dma_map_ops sbus_dma_ops = {
4082+const struct dma_map_ops sbus_dma_ops = {
4083 .alloc_coherent = sbus_alloc_coherent,
4084 .free_coherent = sbus_free_coherent,
4085 .map_page = sbus_map_page,
4086@@ -408,7 +408,7 @@ struct dma_map_ops sbus_dma_ops = {
4087 .sync_sg_for_device = sbus_sync_sg_for_device,
4088 };
4089
4090-struct dma_map_ops *dma_ops = &sbus_dma_ops;
4091+const struct dma_map_ops *dma_ops = &sbus_dma_ops;
4092 EXPORT_SYMBOL(dma_ops);
4093
4094 static int __init sparc_register_ioport(void)
4095@@ -645,7 +645,7 @@ static void pci32_sync_sg_for_device(str
4096 }
4097 }
4098
4099-struct dma_map_ops pci32_dma_ops = {
4100+const struct dma_map_ops pci32_dma_ops = {
4101 .alloc_coherent = pci32_alloc_coherent,
4102 .free_coherent = pci32_free_coherent,
4103 .map_page = pci32_map_page,
16454cff
MT
4104diff -urNp linux-2.6.38.1/arch/sparc/kernel/kgdb_32.c linux-2.6.38.1/arch/sparc/kernel/kgdb_32.c
4105--- linux-2.6.38.1/arch/sparc/kernel/kgdb_32.c 2011-03-14 21:20:32.000000000 -0400
4106+++ linux-2.6.38.1/arch/sparc/kernel/kgdb_32.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
4107@@ -164,7 +164,7 @@ void kgdb_arch_set_pc(struct pt_regs *re
4108 regs->npc = regs->pc + 4;
ae4e228f
MT
4109 }
4110
4111-struct kgdb_arch arch_kgdb_ops = {
4112+const struct kgdb_arch arch_kgdb_ops = {
4113 /* Breakpoint instruction: ta 0x7d */
4114 .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x7d },
4115 };
16454cff
MT
4116diff -urNp linux-2.6.38.1/arch/sparc/kernel/kgdb_64.c linux-2.6.38.1/arch/sparc/kernel/kgdb_64.c
4117--- linux-2.6.38.1/arch/sparc/kernel/kgdb_64.c 2011-03-14 21:20:32.000000000 -0400
4118+++ linux-2.6.38.1/arch/sparc/kernel/kgdb_64.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
4119@@ -187,7 +187,7 @@ void kgdb_arch_set_pc(struct pt_regs *re
4120 regs->tnpc = regs->tpc + 4;
ae4e228f
MT
4121 }
4122
4123-struct kgdb_arch arch_kgdb_ops = {
4124+const struct kgdb_arch arch_kgdb_ops = {
4125 /* Breakpoint instruction: ta 0x72 */
4126 .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x72 },
4127 };
16454cff
MT
4128diff -urNp linux-2.6.38.1/arch/sparc/kernel/Makefile linux-2.6.38.1/arch/sparc/kernel/Makefile
4129--- linux-2.6.38.1/arch/sparc/kernel/Makefile 2011-03-14 21:20:32.000000000 -0400
4130+++ linux-2.6.38.1/arch/sparc/kernel/Makefile 2011-03-21 18:31:35.000000000 -0400
57199397
MT
4131@@ -3,7 +3,7 @@
4132 #
4133
4134 asflags-y := -ansi
4135-ccflags-y := -Werror
4136+#ccflags-y := -Werror
4137
4138 extra-y := head_$(BITS).o
4139 extra-y += init_task.o
16454cff
MT
4140diff -urNp linux-2.6.38.1/arch/sparc/kernel/pci_sun4v.c linux-2.6.38.1/arch/sparc/kernel/pci_sun4v.c
4141--- linux-2.6.38.1/arch/sparc/kernel/pci_sun4v.c 2011-03-14 21:20:32.000000000 -0400
4142+++ linux-2.6.38.1/arch/sparc/kernel/pci_sun4v.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
4143@@ -525,7 +525,7 @@ static void dma_4v_unmap_sg(struct devic
4144 spin_unlock_irqrestore(&iommu->lock, flags);
4145 }
4146
4147-static struct dma_map_ops sun4v_dma_ops = {
4148+static const struct dma_map_ops sun4v_dma_ops = {
4149 .alloc_coherent = dma_4v_alloc_coherent,
4150 .free_coherent = dma_4v_free_coherent,
4151 .map_page = dma_4v_map_page,
16454cff
MT
4152diff -urNp linux-2.6.38.1/arch/sparc/kernel/process_32.c linux-2.6.38.1/arch/sparc/kernel/process_32.c
4153--- linux-2.6.38.1/arch/sparc/kernel/process_32.c 2011-03-14 21:20:32.000000000 -0400
4154+++ linux-2.6.38.1/arch/sparc/kernel/process_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
4155@@ -196,7 +196,7 @@ void __show_backtrace(unsigned long fp)
4156 rw->ins[4], rw->ins[5],
4157 rw->ins[6],
4158 rw->ins[7]);
4159- printk("%pS\n", (void *) rw->ins[7]);
4160+ printk("%pA\n", (void *) rw->ins[7]);
4161 rw = (struct reg_window32 *) rw->ins[6];
4162 }
4163 spin_unlock_irqrestore(&sparc_backtrace_lock, flags);
4164@@ -263,14 +263,14 @@ void show_regs(struct pt_regs *r)
4165
4166 printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx %s\n",
4167 r->psr, r->pc, r->npc, r->y, print_tainted());
4168- printk("PC: <%pS>\n", (void *) r->pc);
4169+ printk("PC: <%pA>\n", (void *) r->pc);
4170 printk("%%G: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
4171 r->u_regs[0], r->u_regs[1], r->u_regs[2], r->u_regs[3],
4172 r->u_regs[4], r->u_regs[5], r->u_regs[6], r->u_regs[7]);
4173 printk("%%O: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
4174 r->u_regs[8], r->u_regs[9], r->u_regs[10], r->u_regs[11],
4175 r->u_regs[12], r->u_regs[13], r->u_regs[14], r->u_regs[15]);
4176- printk("RPC: <%pS>\n", (void *) r->u_regs[15]);
4177+ printk("RPC: <%pA>\n", (void *) r->u_regs[15]);
4178
4179 printk("%%L: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
4180 rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3],
4181@@ -305,7 +305,7 @@ void show_stack(struct task_struct *tsk,
4182 rw = (struct reg_window32 *) fp;
4183 pc = rw->ins[7];
4184 printk("[%08lx : ", pc);
4185- printk("%pS ] ", (void *) pc);
4186+ printk("%pA ] ", (void *) pc);
4187 fp = rw->ins[6];
4188 } while (++count < 16);
4189 printk("\n");
16454cff
MT
4190diff -urNp linux-2.6.38.1/arch/sparc/kernel/process_64.c linux-2.6.38.1/arch/sparc/kernel/process_64.c
4191--- linux-2.6.38.1/arch/sparc/kernel/process_64.c 2011-03-14 21:20:32.000000000 -0400
4192+++ linux-2.6.38.1/arch/sparc/kernel/process_64.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
4193@@ -180,14 +180,14 @@ static void show_regwindow(struct pt_reg
4194 printk("i4: %016lx i5: %016lx i6: %016lx i7: %016lx\n",
4195 rwk->ins[4], rwk->ins[5], rwk->ins[6], rwk->ins[7]);
4196 if (regs->tstate & TSTATE_PRIV)
4197- printk("I7: <%pS>\n", (void *) rwk->ins[7]);
4198+ printk("I7: <%pA>\n", (void *) rwk->ins[7]);
4199 }
4200
4201 void show_regs(struct pt_regs *regs)
4202 {
4203 printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x %s\n", regs->tstate,
4204 regs->tpc, regs->tnpc, regs->y, print_tainted());
4205- printk("TPC: <%pS>\n", (void *) regs->tpc);
4206+ printk("TPC: <%pA>\n", (void *) regs->tpc);
4207 printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
4208 regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
4209 regs->u_regs[3]);
4210@@ -200,7 +200,7 @@ void show_regs(struct pt_regs *regs)
4211 printk("o4: %016lx o5: %016lx sp: %016lx ret_pc: %016lx\n",
4212 regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
4213 regs->u_regs[15]);
4214- printk("RPC: <%pS>\n", (void *) regs->u_regs[15]);
4215+ printk("RPC: <%pA>\n", (void *) regs->u_regs[15]);
4216 show_regwindow(regs);
4217 show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]);
4218 }
4219@@ -285,7 +285,7 @@ void arch_trigger_all_cpu_backtrace(void
4220 ((tp && tp->task) ? tp->task->pid : -1));
4221
4222 if (gp->tstate & TSTATE_PRIV) {
4223- printk(" TPC[%pS] O7[%pS] I7[%pS] RPC[%pS]\n",
4224+ printk(" TPC[%pA] O7[%pA] I7[%pA] RPC[%pA]\n",
4225 (void *) gp->tpc,
4226 (void *) gp->o7,
4227 (void *) gp->i7,
16454cff
MT
4228diff -urNp linux-2.6.38.1/arch/sparc/kernel/sys_sparc_32.c linux-2.6.38.1/arch/sparc/kernel/sys_sparc_32.c
4229--- linux-2.6.38.1/arch/sparc/kernel/sys_sparc_32.c 2011-03-14 21:20:32.000000000 -0400
4230+++ linux-2.6.38.1/arch/sparc/kernel/sys_sparc_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 4231@@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
58c5fc13
MT
4232 if (ARCH_SUN4C && len > 0x20000000)
4233 return -ENOMEM;
4234 if (!addr)
4235- addr = TASK_UNMAPPED_BASE;
4236+ addr = current->mm->mmap_base;
4237
4238 if (flags & MAP_SHARED)
4239 addr = COLOUR_ALIGN(addr);
bc901d79 4240@@ -71,7 +71,7 @@ unsigned long arch_get_unmapped_area(str
57199397
MT
4241 }
4242 if (TASK_SIZE - PAGE_SIZE - len < addr)
4243 return -ENOMEM;
4244- if (!vmm || addr + len <= vmm->vm_start)
4245+ if (check_heap_stack_gap(vmm, addr, len))
4246 return addr;
4247 addr = vmm->vm_end;
4248 if (flags & MAP_SHARED)
16454cff
MT
4249diff -urNp linux-2.6.38.1/arch/sparc/kernel/sys_sparc_64.c linux-2.6.38.1/arch/sparc/kernel/sys_sparc_64.c
4250--- linux-2.6.38.1/arch/sparc/kernel/sys_sparc_64.c 2011-03-14 21:20:32.000000000 -0400
4251+++ linux-2.6.38.1/arch/sparc/kernel/sys_sparc_64.c 2011-03-21 23:47:41.000000000 -0400
df50ba0c 4252@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
58c5fc13
MT
4253 /* We do not accept a shared mapping if it would violate
4254 * cache aliasing constraints.
4255 */
4256- if ((flags & MAP_SHARED) &&
4257+ if ((filp || (flags & MAP_SHARED)) &&
4258 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
4259 return -EINVAL;
4260 return addr;
df50ba0c 4261@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
58c5fc13
MT
4262 if (filp || (flags & MAP_SHARED))
4263 do_color_align = 1;
4264
4265+#ifdef CONFIG_PAX_RANDMMAP
4266+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
4267+#endif
4268+
4269 if (addr) {
4270 if (do_color_align)
4271 addr = COLOUR_ALIGN(addr, pgoff);
57199397
MT
4272@@ -146,15 +150,14 @@ unsigned long arch_get_unmapped_area(str
4273 addr = PAGE_ALIGN(addr);
4274
4275 vma = find_vma(mm, addr);
4276- if (task_size - len >= addr &&
4277- (!vma || addr + len <= vma->vm_start))
4278+ if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
4279 return addr;
58c5fc13
MT
4280 }
4281
4282 if (len > mm->cached_hole_size) {
4283- start_addr = addr = mm->free_area_cache;
4284+ start_addr = addr = mm->free_area_cache;
4285 } else {
4286- start_addr = addr = TASK_UNMAPPED_BASE;
4287+ start_addr = addr = mm->mmap_base;
4288 mm->cached_hole_size = 0;
4289 }
4290
57199397 4291@@ -174,14 +177,14 @@ full_search:
58c5fc13
MT
4292 vma = find_vma(mm, VA_EXCLUDE_END);
4293 }
4294 if (unlikely(task_size < addr)) {
4295- if (start_addr != TASK_UNMAPPED_BASE) {
4296- start_addr = addr = TASK_UNMAPPED_BASE;
4297+ if (start_addr != mm->mmap_base) {
4298+ start_addr = addr = mm->mmap_base;
4299 mm->cached_hole_size = 0;
4300 goto full_search;
4301 }
57199397
MT
4302 return -ENOMEM;
4303 }
4304- if (likely(!vma || addr + len <= vma->vm_start)) {
4305+ if (likely(check_heap_stack_gap(vma, addr, len))) {
4306 /*
4307 * Remember the place where we stopped the search:
4308 */
4309@@ -215,7 +218,7 @@ arch_get_unmapped_area_topdown(struct fi
58c5fc13
MT
4310 /* We do not accept a shared mapping if it would violate
4311 * cache aliasing constraints.
4312 */
4313- if ((flags & MAP_SHARED) &&
4314+ if ((filp || (flags & MAP_SHARED)) &&
4315 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
4316 return -EINVAL;
4317 return addr;
57199397
MT
4318@@ -236,8 +239,7 @@ arch_get_unmapped_area_topdown(struct fi
4319 addr = PAGE_ALIGN(addr);
4320
4321 vma = find_vma(mm, addr);
4322- if (task_size - len >= addr &&
4323- (!vma || addr + len <= vma->vm_start))
4324+ if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
4325 return addr;
4326 }
4327
4328@@ -258,7 +260,7 @@ arch_get_unmapped_area_topdown(struct fi
4329 /* make sure it can fit in the remaining address space */
4330 if (likely(addr > len)) {
4331 vma = find_vma(mm, addr-len);
4332- if (!vma || addr <= vma->vm_start) {
4333+ if (check_heap_stack_gap(vma, addr - len, len)) {
4334 /* remember the address as a hint for next time */
4335 return (mm->free_area_cache = addr-len);
4336 }
16454cff
MT
4337@@ -267,18 +269,18 @@ arch_get_unmapped_area_topdown(struct fi
4338 if (unlikely(mm->mmap_base < len))
4339 goto bottomup;
4340
4341- addr = mm->mmap_base-len;
4342- if (do_color_align)
4343- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
4344+ addr = mm->mmap_base - len;
4345
4346 do {
4347+ if (do_color_align)
4348+ addr = COLOUR_ALIGN_DOWN(addr, pgoff);
4349 /*
4350 * Lookup failure means no vma is above this address,
4351 * else if new region fits below vma->vm_start,
57199397
MT
4352 * return with success:
4353 */
4354 vma = find_vma(mm, addr);
4355- if (likely(!vma || addr+len <= vma->vm_start)) {
4356+ if (likely(check_heap_stack_gap(vma, addr, len))) {
4357 /* remember the address as a hint for next time */
4358 return (mm->free_area_cache = addr);
4359 }
16454cff
MT
4360@@ -288,10 +290,8 @@ arch_get_unmapped_area_topdown(struct fi
4361 mm->cached_hole_size = vma->vm_start - addr;
4362
4363 /* try just below the current vma->vm_start */
4364- addr = vma->vm_start-len;
4365- if (do_color_align)
4366- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
4367- } while (likely(len < vma->vm_start));
4368+ addr = skip_heap_stack_gap(vma, len);
4369+ } while (!IS_ERR_VALUE(addr));
4370
4371 bottomup:
4372 /*
4373@@ -385,6 +385,12 @@ void arch_pick_mmap_layout(struct mm_str
ae4e228f 4374 gap == RLIM_INFINITY ||
58c5fc13
MT
4375 sysctl_legacy_va_layout) {
4376 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
4377+
4378+#ifdef CONFIG_PAX_RANDMMAP
4379+ if (mm->pax_flags & MF_PAX_RANDMMAP)
4380+ mm->mmap_base += mm->delta_mmap;
4381+#endif
4382+
4383 mm->get_unmapped_area = arch_get_unmapped_area;
4384 mm->unmap_area = arch_unmap_area;
4385 } else {
16454cff 4386@@ -397,6 +403,12 @@ void arch_pick_mmap_layout(struct mm_str
58c5fc13
MT
4387 gap = (task_size / 6 * 5);
4388
4389 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
4390+
4391+#ifdef CONFIG_PAX_RANDMMAP
4392+ if (mm->pax_flags & MF_PAX_RANDMMAP)
4393+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
4394+#endif
4395+
4396 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4397 mm->unmap_area = arch_unmap_area_topdown;
4398 }
16454cff
MT
4399diff -urNp linux-2.6.38.1/arch/sparc/kernel/traps_32.c linux-2.6.38.1/arch/sparc/kernel/traps_32.c
4400--- linux-2.6.38.1/arch/sparc/kernel/traps_32.c 2011-03-14 21:20:32.000000000 -0400
4401+++ linux-2.6.38.1/arch/sparc/kernel/traps_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
4402@@ -76,7 +76,7 @@ void die_if_kernel(char *str, struct pt_
4403 count++ < 30 &&
4404 (((unsigned long) rw) >= PAGE_OFFSET) &&
4405 !(((unsigned long) rw) & 0x7)) {
4406- printk("Caller[%08lx]: %pS\n", rw->ins[7],
4407+ printk("Caller[%08lx]: %pA\n", rw->ins[7],
4408 (void *) rw->ins[7]);
4409 rw = (struct reg_window32 *)rw->ins[6];
4410 }
16454cff
MT
4411diff -urNp linux-2.6.38.1/arch/sparc/kernel/traps_64.c linux-2.6.38.1/arch/sparc/kernel/traps_64.c
4412--- linux-2.6.38.1/arch/sparc/kernel/traps_64.c 2011-03-14 21:20:32.000000000 -0400
4413+++ linux-2.6.38.1/arch/sparc/kernel/traps_64.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
4414@@ -75,7 +75,7 @@ static void dump_tl1_traplog(struct tl1_
4415 i + 1,
4416 p->trapstack[i].tstate, p->trapstack[i].tpc,
4417 p->trapstack[i].tnpc, p->trapstack[i].tt);
4418- printk("TRAPLOG: TPC<%pS>\n", (void *) p->trapstack[i].tpc);
4419+ printk("TRAPLOG: TPC<%pA>\n", (void *) p->trapstack[i].tpc);
4420 }
4421 }
4422
57199397 4423@@ -95,6 +95,12 @@ void bad_trap(struct pt_regs *regs, long
58c5fc13
MT
4424
4425 lvl -= 0x100;
4426 if (regs->tstate & TSTATE_PRIV) {
4427+
4428+#ifdef CONFIG_PAX_REFCOUNT
4429+ if (lvl == 6)
4430+ pax_report_refcount_overflow(regs);
4431+#endif
4432+
4433 sprintf(buffer, "Kernel bad sw trap %lx", lvl);
4434 die_if_kernel(buffer, regs);
4435 }
57199397 4436@@ -113,11 +119,16 @@ void bad_trap(struct pt_regs *regs, long
58c5fc13
MT
4437 void bad_trap_tl1(struct pt_regs *regs, long lvl)
4438 {
4439 char buffer[32];
4440-
4441+
4442 if (notify_die(DIE_TRAP_TL1, "bad trap tl1", regs,
4443 0, lvl, SIGTRAP) == NOTIFY_STOP)
4444 return;
4445
4446+#ifdef CONFIG_PAX_REFCOUNT
4447+ if (lvl == 6)
4448+ pax_report_refcount_overflow(regs);
4449+#endif
4450+
4451 dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
4452
4453 sprintf (buffer, "Bad trap %lx at tl>0", lvl);
bc901d79
MT
4454@@ -1141,7 +1152,7 @@ static void cheetah_log_errors(struct pt
4455 regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate);
4456 printk("%s" "ERROR(%d): ",
4457 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id());
4458- printk("TPC<%pS>\n", (void *) regs->tpc);
4459+ printk("TPC<%pA>\n", (void *) regs->tpc);
4460 printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n",
4461 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
4462 (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT,
4463@@ -1748,7 +1759,7 @@ void cheetah_plus_parity_error(int type,
4464 smp_processor_id(),
4465 (type & 0x1) ? 'I' : 'D',
4466 regs->tpc);
4467- printk(KERN_EMERG "TPC<%pS>\n", (void *) regs->tpc);
4468+ printk(KERN_EMERG "TPC<%pA>\n", (void *) regs->tpc);
4469 panic("Irrecoverable Cheetah+ parity error.");
4470 }
4471
4472@@ -1756,7 +1767,7 @@ void cheetah_plus_parity_error(int type,
4473 smp_processor_id(),
4474 (type & 0x1) ? 'I' : 'D',
4475 regs->tpc);
4476- printk(KERN_WARNING "TPC<%pS>\n", (void *) regs->tpc);
4477+ printk(KERN_WARNING "TPC<%pA>\n", (void *) regs->tpc);
4478 }
4479
4480 struct sun4v_error_entry {
4481@@ -1963,9 +1974,9 @@ void sun4v_itlb_error_report(struct pt_r
4482
4483 printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n",
4484 regs->tpc, tl);
4485- printk(KERN_EMERG "SUN4V-ITLB: TPC<%pS>\n", (void *) regs->tpc);
4486+ printk(KERN_EMERG "SUN4V-ITLB: TPC<%pA>\n", (void *) regs->tpc);
4487 printk(KERN_EMERG "SUN4V-ITLB: O7[%lx]\n", regs->u_regs[UREG_I7]);
4488- printk(KERN_EMERG "SUN4V-ITLB: O7<%pS>\n",
4489+ printk(KERN_EMERG "SUN4V-ITLB: O7<%pA>\n",
4490 (void *) regs->u_regs[UREG_I7]);
4491 printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] "
4492 "pte[%lx] error[%lx]\n",
4493@@ -1987,9 +1998,9 @@ void sun4v_dtlb_error_report(struct pt_r
4494
4495 printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n",
4496 regs->tpc, tl);
4497- printk(KERN_EMERG "SUN4V-DTLB: TPC<%pS>\n", (void *) regs->tpc);
4498+ printk(KERN_EMERG "SUN4V-DTLB: TPC<%pA>\n", (void *) regs->tpc);
4499 printk(KERN_EMERG "SUN4V-DTLB: O7[%lx]\n", regs->u_regs[UREG_I7]);
4500- printk(KERN_EMERG "SUN4V-DTLB: O7<%pS>\n",
4501+ printk(KERN_EMERG "SUN4V-DTLB: O7<%pA>\n",
4502 (void *) regs->u_regs[UREG_I7]);
4503 printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] "
4504 "pte[%lx] error[%lx]\n",
4505@@ -2196,13 +2207,13 @@ void show_stack(struct task_struct *tsk,
4506 fp = (unsigned long)sf->fp + STACK_BIAS;
4507 }
4508
4509- printk(" [%016lx] %pS\n", pc, (void *) pc);
4510+ printk(" [%016lx] %pA\n", pc, (void *) pc);
4511 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
4512 if ((pc + 8UL) == (unsigned long) &return_to_handler) {
4513 int index = tsk->curr_ret_stack;
4514 if (tsk->ret_stack && index >= graph) {
4515 pc = tsk->ret_stack[index - graph].ret;
4516- printk(" [%016lx] %pS\n", pc, (void *) pc);
4517+ printk(" [%016lx] %pA\n", pc, (void *) pc);
4518 graph++;
4519 }
4520 }
4521@@ -2255,7 +2266,7 @@ void die_if_kernel(char *str, struct pt_
4522 while (rw &&
4523 count++ < 30 &&
4524 kstack_valid(tp, (unsigned long) rw)) {
4525- printk("Caller[%016lx]: %pS\n", rw->ins[7],
4526+ printk("Caller[%016lx]: %pA\n", rw->ins[7],
4527 (void *) rw->ins[7]);
4528
4529 rw = kernel_stack_up(rw);
16454cff
MT
4530diff -urNp linux-2.6.38.1/arch/sparc/kernel/unaligned_64.c linux-2.6.38.1/arch/sparc/kernel/unaligned_64.c
4531--- linux-2.6.38.1/arch/sparc/kernel/unaligned_64.c 2011-03-14 21:20:32.000000000 -0400
4532+++ linux-2.6.38.1/arch/sparc/kernel/unaligned_64.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
4533@@ -278,7 +278,7 @@ static void log_unaligned(struct pt_regs
4534 static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
4535
4536 if (__ratelimit(&ratelimit)) {
4537- printk("Kernel unaligned access at TPC[%lx] %pS\n",
4538+ printk("Kernel unaligned access at TPC[%lx] %pA\n",
4539 regs->tpc, (void *) regs->tpc);
4540 }
4541 }
16454cff
MT
4542diff -urNp linux-2.6.38.1/arch/sparc/lib/atomic_64.S linux-2.6.38.1/arch/sparc/lib/atomic_64.S
4543--- linux-2.6.38.1/arch/sparc/lib/atomic_64.S 2011-03-14 21:20:32.000000000 -0400
4544+++ linux-2.6.38.1/arch/sparc/lib/atomic_64.S 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
4545@@ -18,7 +18,12 @@
4546 atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
4547 BACKOFF_SETUP(%o2)
4548 1: lduw [%o1], %g1
4549- add %g1, %o0, %g7
4550+ addcc %g1, %o0, %g7
4551+
4552+#ifdef CONFIG_PAX_REFCOUNT
4553+ tvs %icc, 6
4554+#endif
4555+
4556 cas [%o1], %g1, %g7
4557 cmp %g1, %g7
6892158b 4558 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
58c5fc13
MT
4559@@ -28,12 +33,32 @@ atomic_add: /* %o0 = increment, %o1 = at
4560 2: BACKOFF_SPIN(%o2, %o3, 1b)
4561 .size atomic_add, .-atomic_add
4562
4563+ .globl atomic_add_unchecked
4564+ .type atomic_add_unchecked,#function
4565+atomic_add_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
4566+ BACKOFF_SETUP(%o2)
4567+1: lduw [%o1], %g1
4568+ add %g1, %o0, %g7
4569+ cas [%o1], %g1, %g7
4570+ cmp %g1, %g7
4571+ bne,pn %icc, 2f
4572+ nop
4573+ retl
4574+ nop
4575+2: BACKOFF_SPIN(%o2, %o3, 1b)
4576+ .size atomic_add_unchecked, .-atomic_add_unchecked
4577+
4578 .globl atomic_sub
4579 .type atomic_sub,#function
4580 atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
4581 BACKOFF_SETUP(%o2)
4582 1: lduw [%o1], %g1
4583- sub %g1, %o0, %g7
4584+ subcc %g1, %o0, %g7
4585+
4586+#ifdef CONFIG_PAX_REFCOUNT
4587+ tvs %icc, 6
4588+#endif
4589+
4590 cas [%o1], %g1, %g7
4591 cmp %g1, %g7
6892158b 4592 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
58c5fc13
MT
4593@@ -43,12 +68,32 @@ atomic_sub: /* %o0 = decrement, %o1 = at
4594 2: BACKOFF_SPIN(%o2, %o3, 1b)
4595 .size atomic_sub, .-atomic_sub
4596
4597+ .globl atomic_sub_unchecked
4598+ .type atomic_sub_unchecked,#function
4599+atomic_sub_unchecked: /* %o0 = decrement, %o1 = atomic_ptr */
4600+ BACKOFF_SETUP(%o2)
4601+1: lduw [%o1], %g1
4602+ sub %g1, %o0, %g7
4603+ cas [%o1], %g1, %g7
4604+ cmp %g1, %g7
4605+ bne,pn %icc, 2f
4606+ nop
4607+ retl
4608+ nop
4609+2: BACKOFF_SPIN(%o2, %o3, 1b)
4610+ .size atomic_sub_unchecked, .-atomic_sub_unchecked
4611+
4612 .globl atomic_add_ret
4613 .type atomic_add_ret,#function
4614 atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
4615 BACKOFF_SETUP(%o2)
4616 1: lduw [%o1], %g1
4617- add %g1, %o0, %g7
4618+ addcc %g1, %o0, %g7
4619+
4620+#ifdef CONFIG_PAX_REFCOUNT
4621+ tvs %icc, 6
4622+#endif
4623+
4624 cas [%o1], %g1, %g7
4625 cmp %g1, %g7
6892158b
MT
4626 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
4627@@ -58,12 +103,33 @@ atomic_add_ret: /* %o0 = increment, %o1
57199397
MT
4628 2: BACKOFF_SPIN(%o2, %o3, 1b)
4629 .size atomic_add_ret, .-atomic_add_ret
4630
4631+ .globl atomic_add_ret_unchecked
4632+ .type atomic_add_ret_unchecked,#function
4633+atomic_add_ret_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
4634+ BACKOFF_SETUP(%o2)
4635+1: lduw [%o1], %g1
4636+ addcc %g1, %o0, %g7
4637+ cas [%o1], %g1, %g7
4638+ cmp %g1, %g7
4639+ bne,pn %icc, 2f
4640+ add %g7, %o0, %g7
4641+ sra %g7, 0, %o0
4642+ retl
4643+ nop
4644+2: BACKOFF_SPIN(%o2, %o3, 1b)
4645+ .size atomic_add_ret_unchecked, .-atomic_add_ret_unchecked
4646+
4647 .globl atomic_sub_ret
4648 .type atomic_sub_ret,#function
58c5fc13
MT
4649 atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
4650 BACKOFF_SETUP(%o2)
4651 1: lduw [%o1], %g1
4652- sub %g1, %o0, %g7
4653+ subcc %g1, %o0, %g7
4654+
4655+#ifdef CONFIG_PAX_REFCOUNT
4656+ tvs %icc, 6
4657+#endif
4658+
4659 cas [%o1], %g1, %g7
4660 cmp %g1, %g7
6892158b
MT
4661 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
4662@@ -78,7 +144,12 @@ atomic_sub_ret: /* %o0 = decrement, %o1
58c5fc13
MT
4663 atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
4664 BACKOFF_SETUP(%o2)
4665 1: ldx [%o1], %g1
4666- add %g1, %o0, %g7
4667+ addcc %g1, %o0, %g7
4668+
4669+#ifdef CONFIG_PAX_REFCOUNT
4670+ tvs %xcc, 6
4671+#endif
4672+
4673 casx [%o1], %g1, %g7
4674 cmp %g1, %g7
6892158b
MT
4675 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
4676@@ -88,12 +159,32 @@ atomic64_add: /* %o0 = increment, %o1 =
ae4e228f
MT
4677 2: BACKOFF_SPIN(%o2, %o3, 1b)
4678 .size atomic64_add, .-atomic64_add
4679
4680+ .globl atomic64_add_unchecked
4681+ .type atomic64_add_unchecked,#function
4682+atomic64_add_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
4683+ BACKOFF_SETUP(%o2)
4684+1: ldx [%o1], %g1
4685+ addcc %g1, %o0, %g7
4686+ casx [%o1], %g1, %g7
4687+ cmp %g1, %g7
4688+ bne,pn %xcc, 2f
4689+ nop
4690+ retl
4691+ nop
4692+2: BACKOFF_SPIN(%o2, %o3, 1b)
4693+ .size atomic64_add_unchecked, .-atomic64_add_unchecked
4694+
4695 .globl atomic64_sub
4696 .type atomic64_sub,#function
58c5fc13
MT
4697 atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
4698 BACKOFF_SETUP(%o2)
4699 1: ldx [%o1], %g1
4700- sub %g1, %o0, %g7
4701+ subcc %g1, %o0, %g7
4702+
4703+#ifdef CONFIG_PAX_REFCOUNT
4704+ tvs %xcc, 6
4705+#endif
4706+
4707 casx [%o1], %g1, %g7
4708 cmp %g1, %g7
6892158b
MT
4709 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
4710@@ -103,12 +194,32 @@ atomic64_sub: /* %o0 = decrement, %o1 =
df50ba0c
MT
4711 2: BACKOFF_SPIN(%o2, %o3, 1b)
4712 .size atomic64_sub, .-atomic64_sub
4713
4714+ .globl atomic64_sub_unchecked
4715+ .type atomic64_sub_unchecked,#function
4716+atomic64_sub_unchecked: /* %o0 = decrement, %o1 = atomic_ptr */
4717+ BACKOFF_SETUP(%o2)
4718+1: ldx [%o1], %g1
4719+ subcc %g1, %o0, %g7
4720+ casx [%o1], %g1, %g7
4721+ cmp %g1, %g7
4722+ bne,pn %xcc, 2f
4723+ nop
4724+ retl
4725+ nop
4726+2: BACKOFF_SPIN(%o2, %o3, 1b)
4727+ .size atomic64_sub_unchecked, .-atomic64_sub_unchecked
4728+
4729 .globl atomic64_add_ret
4730 .type atomic64_add_ret,#function
58c5fc13
MT
4731 atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
4732 BACKOFF_SETUP(%o2)
4733 1: ldx [%o1], %g1
4734- add %g1, %o0, %g7
4735+ addcc %g1, %o0, %g7
4736+
4737+#ifdef CONFIG_PAX_REFCOUNT
4738+ tvs %xcc, 6
4739+#endif
4740+
4741 casx [%o1], %g1, %g7
4742 cmp %g1, %g7
6892158b
MT
4743 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
4744@@ -118,12 +229,33 @@ atomic64_add_ret: /* %o0 = increment, %o
ae4e228f
MT
4745 2: BACKOFF_SPIN(%o2, %o3, 1b)
4746 .size atomic64_add_ret, .-atomic64_add_ret
4747
4748+ .globl atomic64_add_ret_unchecked
4749+ .type atomic64_add_ret_unchecked,#function
4750+atomic64_add_ret_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
4751+ BACKOFF_SETUP(%o2)
4752+1: ldx [%o1], %g1
4753+ addcc %g1, %o0, %g7
4754+ casx [%o1], %g1, %g7
4755+ cmp %g1, %g7
4756+ bne,pn %xcc, 2f
4757+ add %g7, %o0, %g7
4758+ mov %g7, %o0
4759+ retl
4760+ nop
4761+2: BACKOFF_SPIN(%o2, %o3, 1b)
4762+ .size atomic64_add_ret_unchecked, .-atomic64_add_ret_unchecked
4763+
4764 .globl atomic64_sub_ret
4765 .type atomic64_sub_ret,#function
58c5fc13
MT
4766 atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
4767 BACKOFF_SETUP(%o2)
4768 1: ldx [%o1], %g1
4769- sub %g1, %o0, %g7
4770+ subcc %g1, %o0, %g7
4771+
4772+#ifdef CONFIG_PAX_REFCOUNT
4773+ tvs %xcc, 6
4774+#endif
4775+
4776 casx [%o1], %g1, %g7
4777 cmp %g1, %g7
6892158b 4778 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
16454cff
MT
4779diff -urNp linux-2.6.38.1/arch/sparc/lib/ksyms.c linux-2.6.38.1/arch/sparc/lib/ksyms.c
4780--- linux-2.6.38.1/arch/sparc/lib/ksyms.c 2011-03-14 21:20:32.000000000 -0400
4781+++ linux-2.6.38.1/arch/sparc/lib/ksyms.c 2011-03-21 18:31:35.000000000 -0400
57199397 4782@@ -142,12 +142,17 @@ EXPORT_SYMBOL(__downgrade_write);
58c5fc13
MT
4783
4784 /* Atomic counter implementation. */
4785 EXPORT_SYMBOL(atomic_add);
4786+EXPORT_SYMBOL(atomic_add_unchecked);
4787 EXPORT_SYMBOL(atomic_add_ret);
4788 EXPORT_SYMBOL(atomic_sub);
4789+EXPORT_SYMBOL(atomic_sub_unchecked);
4790 EXPORT_SYMBOL(atomic_sub_ret);
4791 EXPORT_SYMBOL(atomic64_add);
57199397 4792+EXPORT_SYMBOL(atomic64_add_unchecked);
58c5fc13 4793 EXPORT_SYMBOL(atomic64_add_ret);
57199397 4794+EXPORT_SYMBOL(atomic64_add_ret_unchecked);
df50ba0c
MT
4795 EXPORT_SYMBOL(atomic64_sub);
4796+EXPORT_SYMBOL(atomic64_sub_unchecked);
4797 EXPORT_SYMBOL(atomic64_sub_ret);
4798
4799 /* Atomic bit operations. */
16454cff
MT
4800diff -urNp linux-2.6.38.1/arch/sparc/Makefile linux-2.6.38.1/arch/sparc/Makefile
4801--- linux-2.6.38.1/arch/sparc/Makefile 2011-03-14 21:20:32.000000000 -0400
4802+++ linux-2.6.38.1/arch/sparc/Makefile 2011-03-21 18:31:35.000000000 -0400
57199397
MT
4803@@ -75,7 +75,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
4804 # Export what is needed by arch/sparc/boot/Makefile
4805 export VMLINUX_INIT VMLINUX_MAIN
4806 VMLINUX_INIT := $(head-y) $(init-y)
4807-VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/
4808+VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
4809 VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
4810 VMLINUX_MAIN += $(drivers-y) $(net-y)
efbe55a5 4811
16454cff
MT
4812diff -urNp linux-2.6.38.1/arch/sparc/mm/fault_32.c linux-2.6.38.1/arch/sparc/mm/fault_32.c
4813--- linux-2.6.38.1/arch/sparc/mm/fault_32.c 2011-03-14 21:20:32.000000000 -0400
4814+++ linux-2.6.38.1/arch/sparc/mm/fault_32.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 4815@@ -22,6 +22,9 @@
58c5fc13
MT
4816 #include <linux/interrupt.h>
4817 #include <linux/module.h>
4818 #include <linux/kdebug.h>
4819+#include <linux/slab.h>
4820+#include <linux/pagemap.h>
4821+#include <linux/compiler.h>
4822
4823 #include <asm/system.h>
4824 #include <asm/page.h>
df50ba0c 4825@@ -209,6 +212,268 @@ static unsigned long compute_si_addr(str
58c5fc13
MT
4826 return safe_compute_effective_address(regs, insn);
4827 }
4828
4829+#ifdef CONFIG_PAX_PAGEEXEC
4830+#ifdef CONFIG_PAX_DLRESOLVE
ae4e228f 4831+static void pax_emuplt_close(struct vm_area_struct *vma)
58c5fc13
MT
4832+{
4833+ vma->vm_mm->call_dl_resolve = 0UL;
4834+}
4835+
4836+static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
4837+{
4838+ unsigned int *kaddr;
4839+
4840+ vmf->page = alloc_page(GFP_HIGHUSER);
4841+ if (!vmf->page)
4842+ return VM_FAULT_OOM;
4843+
4844+ kaddr = kmap(vmf->page);
4845+ memset(kaddr, 0, PAGE_SIZE);
4846+ kaddr[0] = 0x9DE3BFA8U; /* save */
4847+ flush_dcache_page(vmf->page);
4848+ kunmap(vmf->page);
4849+ return VM_FAULT_MAJOR;
4850+}
4851+
4852+static const struct vm_operations_struct pax_vm_ops = {
4853+ .close = pax_emuplt_close,
4854+ .fault = pax_emuplt_fault
4855+};
4856+
4857+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4858+{
4859+ int ret;
4860+
df50ba0c 4861+ INIT_LIST_HEAD(&vma->anon_vma_chain);
58c5fc13
MT
4862+ vma->vm_mm = current->mm;
4863+ vma->vm_start = addr;
4864+ vma->vm_end = addr + PAGE_SIZE;
4865+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4866+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
4867+ vma->vm_ops = &pax_vm_ops;
4868+
4869+ ret = insert_vm_struct(current->mm, vma);
4870+ if (ret)
4871+ return ret;
4872+
4873+ ++current->mm->total_vm;
4874+ return 0;
4875+}
4876+#endif
4877+
4878+/*
4879+ * PaX: decide what to do with offenders (regs->pc = fault address)
4880+ *
4881+ * returns 1 when task should be killed
4882+ * 2 when patched PLT trampoline was detected
4883+ * 3 when unpatched PLT trampoline was detected
4884+ */
4885+static int pax_handle_fetch_fault(struct pt_regs *regs)
4886+{
4887+
4888+#ifdef CONFIG_PAX_EMUPLT
4889+ int err;
4890+
4891+ do { /* PaX: patched PLT emulation #1 */
4892+ unsigned int sethi1, sethi2, jmpl;
4893+
4894+ err = get_user(sethi1, (unsigned int *)regs->pc);
4895+ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
4896+ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
4897+
4898+ if (err)
4899+ break;
4900+
4901+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4902+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
4903+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
4904+ {
4905+ unsigned int addr;
4906+
4907+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4908+ addr = regs->u_regs[UREG_G1];
4909+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4910+ regs->pc = addr;
4911+ regs->npc = addr+4;
4912+ return 2;
4913+ }
4914+ } while (0);
4915+
4916+ { /* PaX: patched PLT emulation #2 */
4917+ unsigned int ba;
4918+
4919+ err = get_user(ba, (unsigned int *)regs->pc);
4920+
4921+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4922+ unsigned int addr;
4923+
4924+ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4925+ regs->pc = addr;
4926+ regs->npc = addr+4;
4927+ return 2;
4928+ }
4929+ }
4930+
4931+ do { /* PaX: patched PLT emulation #3 */
4932+ unsigned int sethi, jmpl, nop;
4933+
4934+ err = get_user(sethi, (unsigned int *)regs->pc);
4935+ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
4936+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
4937+
4938+ if (err)
4939+ break;
4940+
4941+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4942+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4943+ nop == 0x01000000U)
4944+ {
4945+ unsigned int addr;
4946+
4947+ addr = (sethi & 0x003FFFFFU) << 10;
4948+ regs->u_regs[UREG_G1] = addr;
4949+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4950+ regs->pc = addr;
4951+ regs->npc = addr+4;
4952+ return 2;
4953+ }
4954+ } while (0);
4955+
4956+ do { /* PaX: unpatched PLT emulation step 1 */
4957+ unsigned int sethi, ba, nop;
4958+
4959+ err = get_user(sethi, (unsigned int *)regs->pc);
4960+ err |= get_user(ba, (unsigned int *)(regs->pc+4));
4961+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
4962+
4963+ if (err)
4964+ break;
4965+
4966+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4967+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4968+ nop == 0x01000000U)
4969+ {
4970+ unsigned int addr, save, call;
4971+
4972+ if ((ba & 0xFFC00000U) == 0x30800000U)
4973+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4974+ else
4975+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
4976+
4977+ err = get_user(save, (unsigned int *)addr);
4978+ err |= get_user(call, (unsigned int *)(addr+4));
4979+ err |= get_user(nop, (unsigned int *)(addr+8));
4980+ if (err)
4981+ break;
4982+
4983+#ifdef CONFIG_PAX_DLRESOLVE
4984+ if (save == 0x9DE3BFA8U &&
4985+ (call & 0xC0000000U) == 0x40000000U &&
4986+ nop == 0x01000000U)
4987+ {
4988+ struct vm_area_struct *vma;
4989+ unsigned long call_dl_resolve;
4990+
4991+ down_read(&current->mm->mmap_sem);
4992+ call_dl_resolve = current->mm->call_dl_resolve;
4993+ up_read(&current->mm->mmap_sem);
4994+ if (likely(call_dl_resolve))
4995+ goto emulate;
4996+
4997+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4998+
4999+ down_write(&current->mm->mmap_sem);
5000+ if (current->mm->call_dl_resolve) {
5001+ call_dl_resolve = current->mm->call_dl_resolve;
5002+ up_write(&current->mm->mmap_sem);
5003+ if (vma)
5004+ kmem_cache_free(vm_area_cachep, vma);
5005+ goto emulate;
5006+ }
5007+
5008+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5009+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
5010+ up_write(&current->mm->mmap_sem);
5011+ if (vma)
5012+ kmem_cache_free(vm_area_cachep, vma);
5013+ return 1;
5014+ }
5015+
5016+ if (pax_insert_vma(vma, call_dl_resolve)) {
5017+ up_write(&current->mm->mmap_sem);
5018+ kmem_cache_free(vm_area_cachep, vma);
5019+ return 1;
5020+ }
5021+
5022+ current->mm->call_dl_resolve = call_dl_resolve;
5023+ up_write(&current->mm->mmap_sem);
5024+
5025+emulate:
5026+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5027+ regs->pc = call_dl_resolve;
5028+ regs->npc = addr+4;
5029+ return 3;
5030+ }
5031+#endif
5032+
5033+ /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */
5034+ if ((save & 0xFFC00000U) == 0x05000000U &&
5035+ (call & 0xFFFFE000U) == 0x85C0A000U &&
5036+ nop == 0x01000000U)
5037+ {
5038+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5039+ regs->u_regs[UREG_G2] = addr + 4;
5040+ addr = (save & 0x003FFFFFU) << 10;
5041+ addr += (((call | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
5042+ regs->pc = addr;
5043+ regs->npc = addr+4;
5044+ return 3;
5045+ }
5046+ }
5047+ } while (0);
5048+
5049+ do { /* PaX: unpatched PLT emulation step 2 */
5050+ unsigned int save, call, nop;
5051+
5052+ err = get_user(save, (unsigned int *)(regs->pc-4));
5053+ err |= get_user(call, (unsigned int *)regs->pc);
5054+ err |= get_user(nop, (unsigned int *)(regs->pc+4));
5055+ if (err)
5056+ break;
5057+
5058+ if (save == 0x9DE3BFA8U &&
5059+ (call & 0xC0000000U) == 0x40000000U &&
5060+ nop == 0x01000000U)
5061+ {
5062+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
5063+
5064+ regs->u_regs[UREG_RETPC] = regs->pc;
5065+ regs->pc = dl_resolve;
5066+ regs->npc = dl_resolve+4;
5067+ return 3;
5068+ }
5069+ } while (0);
5070+#endif
5071+
5072+ return 1;
5073+}
5074+
5075+void pax_report_insns(void *pc, void *sp)
5076+{
5077+ unsigned long i;
5078+
5079+ printk(KERN_ERR "PAX: bytes at PC: ");
ae4e228f 5080+ for (i = 0; i < 8; i++) {
58c5fc13
MT
5081+ unsigned int c;
5082+ if (get_user(c, (unsigned int *)pc+i))
5083+ printk(KERN_CONT "???????? ");
5084+ else
5085+ printk(KERN_CONT "%08x ", c);
5086+ }
5087+ printk("\n");
5088+}
5089+#endif
5090+
df50ba0c
MT
5091 static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
5092 int text_fault)
58c5fc13 5093 {
df50ba0c 5094@@ -282,6 +547,24 @@ good_area:
58c5fc13
MT
5095 if(!(vma->vm_flags & VM_WRITE))
5096 goto bad_area;
5097 } else {
5098+
5099+#ifdef CONFIG_PAX_PAGEEXEC
5100+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
5101+ up_read(&mm->mmap_sem);
5102+ switch (pax_handle_fetch_fault(regs)) {
5103+
5104+#ifdef CONFIG_PAX_EMUPLT
5105+ case 2:
5106+ case 3:
5107+ return;
5108+#endif
5109+
5110+ }
5111+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
5112+ do_group_exit(SIGKILL);
5113+ }
5114+#endif
5115+
5116 /* Allow reads even for write-only mappings */
5117 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
5118 goto bad_area;
16454cff
MT
5119diff -urNp linux-2.6.38.1/arch/sparc/mm/fault_64.c linux-2.6.38.1/arch/sparc/mm/fault_64.c
5120--- linux-2.6.38.1/arch/sparc/mm/fault_64.c 2011-03-14 21:20:32.000000000 -0400
5121+++ linux-2.6.38.1/arch/sparc/mm/fault_64.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 5122@@ -21,6 +21,9 @@
58c5fc13
MT
5123 #include <linux/kprobes.h>
5124 #include <linux/kdebug.h>
5125 #include <linux/percpu.h>
5126+#include <linux/slab.h>
5127+#include <linux/pagemap.h>
5128+#include <linux/compiler.h>
5129
5130 #include <asm/page.h>
5131 #include <asm/pgtable.h>
bc901d79
MT
5132@@ -74,7 +77,7 @@ static void __kprobes bad_kernel_pc(stru
5133 printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
5134 regs->tpc);
5135 printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]);
5136- printk("OOPS: RPC <%pS>\n", (void *) regs->u_regs[15]);
5137+ printk("OOPS: RPC <%pA>\n", (void *) regs->u_regs[15]);
5138 printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr);
5139 dump_stack();
5140 unhandled_fault(regs->tpc, current, regs);
df50ba0c 5141@@ -272,6 +275,457 @@ static void noinline __kprobes bogus_32b
58c5fc13
MT
5142 show_regs(regs);
5143 }
5144
5145+#ifdef CONFIG_PAX_PAGEEXEC
5146+#ifdef CONFIG_PAX_DLRESOLVE
5147+static void pax_emuplt_close(struct vm_area_struct *vma)
5148+{
5149+ vma->vm_mm->call_dl_resolve = 0UL;
5150+}
5151+
5152+static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
5153+{
5154+ unsigned int *kaddr;
5155+
5156+ vmf->page = alloc_page(GFP_HIGHUSER);
5157+ if (!vmf->page)
5158+ return VM_FAULT_OOM;
5159+
5160+ kaddr = kmap(vmf->page);
5161+ memset(kaddr, 0, PAGE_SIZE);
5162+ kaddr[0] = 0x9DE3BFA8U; /* save */
5163+ flush_dcache_page(vmf->page);
5164+ kunmap(vmf->page);
5165+ return VM_FAULT_MAJOR;
5166+}
5167+
5168+static const struct vm_operations_struct pax_vm_ops = {
5169+ .close = pax_emuplt_close,
5170+ .fault = pax_emuplt_fault
5171+};
5172+
5173+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
5174+{
5175+ int ret;
5176+
df50ba0c 5177+ INIT_LIST_HEAD(&vma->anon_vma_chain);
58c5fc13
MT
5178+ vma->vm_mm = current->mm;
5179+ vma->vm_start = addr;
5180+ vma->vm_end = addr + PAGE_SIZE;
5181+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
5182+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
5183+ vma->vm_ops = &pax_vm_ops;
5184+
5185+ ret = insert_vm_struct(current->mm, vma);
5186+ if (ret)
5187+ return ret;
5188+
5189+ ++current->mm->total_vm;
5190+ return 0;
5191+}
5192+#endif
5193+
5194+/*
5195+ * PaX: decide what to do with offenders (regs->tpc = fault address)
5196+ *
5197+ * returns 1 when task should be killed
5198+ * 2 when patched PLT trampoline was detected
5199+ * 3 when unpatched PLT trampoline was detected
5200+ */
5201+static int pax_handle_fetch_fault(struct pt_regs *regs)
5202+{
5203+
5204+#ifdef CONFIG_PAX_EMUPLT
5205+ int err;
5206+
5207+ do { /* PaX: patched PLT emulation #1 */
5208+ unsigned int sethi1, sethi2, jmpl;
5209+
5210+ err = get_user(sethi1, (unsigned int *)regs->tpc);
5211+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
5212+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
5213+
5214+ if (err)
5215+ break;
5216+
5217+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5218+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
5219+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
5220+ {
5221+ unsigned long addr;
5222+
5223+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
5224+ addr = regs->u_regs[UREG_G1];
5225+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
5226+
5227+ if (test_thread_flag(TIF_32BIT))
5228+ addr &= 0xFFFFFFFFUL;
5229+
5230+ regs->tpc = addr;
5231+ regs->tnpc = addr+4;
5232+ return 2;
5233+ }
5234+ } while (0);
5235+
5236+ { /* PaX: patched PLT emulation #2 */
5237+ unsigned int ba;
5238+
5239+ err = get_user(ba, (unsigned int *)regs->tpc);
5240+
5241+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
5242+ unsigned long addr;
5243+
5244+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
5245+
5246+ if (test_thread_flag(TIF_32BIT))
5247+ addr &= 0xFFFFFFFFUL;
5248+
5249+ regs->tpc = addr;
5250+ regs->tnpc = addr+4;
5251+ return 2;
5252+ }
5253+ }
5254+
5255+ do { /* PaX: patched PLT emulation #3 */
5256+ unsigned int sethi, jmpl, nop;
5257+
5258+ err = get_user(sethi, (unsigned int *)regs->tpc);
5259+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
5260+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
5261+
5262+ if (err)
5263+ break;
5264+
5265+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
5266+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
5267+ nop == 0x01000000U)
5268+ {
5269+ unsigned long addr;
5270+
5271+ addr = (sethi & 0x003FFFFFU) << 10;
5272+ regs->u_regs[UREG_G1] = addr;
5273+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
5274+
5275+ if (test_thread_flag(TIF_32BIT))
5276+ addr &= 0xFFFFFFFFUL;
5277+
5278+ regs->tpc = addr;
5279+ regs->tnpc = addr+4;
5280+ return 2;
5281+ }
5282+ } while (0);
5283+
5284+ do { /* PaX: patched PLT emulation #4 */
ae4e228f 5285+ unsigned int sethi, mov1, call, mov2;
58c5fc13 5286+
ae4e228f
MT
5287+ err = get_user(sethi, (unsigned int *)regs->tpc);
5288+ err |= get_user(mov1, (unsigned int *)(regs->tpc+4));
5289+ err |= get_user(call, (unsigned int *)(regs->tpc+8));
5290+ err |= get_user(mov2, (unsigned int *)(regs->tpc+12));
58c5fc13
MT
5291+
5292+ if (err)
5293+ break;
5294+
ae4e228f
MT
5295+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
5296+ mov1 == 0x8210000FU &&
58c5fc13
MT
5297+ (call & 0xC0000000U) == 0x40000000U &&
5298+ mov2 == 0x9E100001U)
5299+ {
5300+ unsigned long addr;
5301+
5302+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
5303+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5304+
5305+ if (test_thread_flag(TIF_32BIT))
5306+ addr &= 0xFFFFFFFFUL;
5307+
5308+ regs->tpc = addr;
5309+ regs->tnpc = addr+4;
5310+ return 2;
5311+ }
5312+ } while (0);
5313+
5314+ do { /* PaX: patched PLT emulation #5 */
ae4e228f 5315+ unsigned int sethi, sethi1, sethi2, or1, or2, sllx, jmpl, nop;
58c5fc13 5316+
ae4e228f
MT
5317+ err = get_user(sethi, (unsigned int *)regs->tpc);
5318+ err |= get_user(sethi1, (unsigned int *)(regs->tpc+4));
5319+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+8));
5320+ err |= get_user(or1, (unsigned int *)(regs->tpc+12));
5321+ err |= get_user(or2, (unsigned int *)(regs->tpc+16));
5322+ err |= get_user(sllx, (unsigned int *)(regs->tpc+20));
5323+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+24));
5324+ err |= get_user(nop, (unsigned int *)(regs->tpc+28));
58c5fc13
MT
5325+
5326+ if (err)
5327+ break;
5328+
ae4e228f
MT
5329+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
5330+ (sethi1 & 0xFFC00000U) == 0x03000000U &&
58c5fc13
MT
5331+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
5332+ (or1 & 0xFFFFE000U) == 0x82106000U &&
5333+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
ae4e228f 5334+ sllx == 0x83287020U &&
58c5fc13
MT
5335+ jmpl == 0x81C04005U &&
5336+ nop == 0x01000000U)
5337+ {
5338+ unsigned long addr;
5339+
5340+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
5341+ regs->u_regs[UREG_G1] <<= 32;
5342+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
5343+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
5344+ regs->tpc = addr;
5345+ regs->tnpc = addr+4;
5346+ return 2;
5347+ }
5348+ } while (0);
5349+
5350+ do { /* PaX: patched PLT emulation #6 */
ae4e228f 5351+ unsigned int sethi, sethi1, sethi2, sllx, or, jmpl, nop;
58c5fc13 5352+
ae4e228f
MT
5353+ err = get_user(sethi, (unsigned int *)regs->tpc);
5354+ err |= get_user(sethi1, (unsigned int *)(regs->tpc+4));
5355+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+8));
5356+ err |= get_user(sllx, (unsigned int *)(regs->tpc+12));
5357+ err |= get_user(or, (unsigned int *)(regs->tpc+16));
5358+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
5359+ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
58c5fc13
MT
5360+
5361+ if (err)
5362+ break;
5363+
ae4e228f
MT
5364+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
5365+ (sethi1 & 0xFFC00000U) == 0x03000000U &&
58c5fc13 5366+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
ae4e228f 5367+ sllx == 0x83287020U &&
58c5fc13
MT
5368+ (or & 0xFFFFE000U) == 0x8A116000U &&
5369+ jmpl == 0x81C04005U &&
5370+ nop == 0x01000000U)
5371+ {
5372+ unsigned long addr;
5373+
5374+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
5375+ regs->u_regs[UREG_G1] <<= 32;
5376+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
5377+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
5378+ regs->tpc = addr;
5379+ regs->tnpc = addr+4;
5380+ return 2;
5381+ }
5382+ } while (0);
5383+
5384+ do { /* PaX: unpatched PLT emulation step 1 */
5385+ unsigned int sethi, ba, nop;
5386+
5387+ err = get_user(sethi, (unsigned int *)regs->tpc);
5388+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
5389+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
5390+
5391+ if (err)
5392+ break;
5393+
5394+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
5395+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
5396+ nop == 0x01000000U)
5397+ {
5398+ unsigned long addr;
5399+ unsigned int save, call;
ae4e228f 5400+ unsigned int sethi1, sethi2, or1, or2, sllx, add, jmpl;
58c5fc13
MT
5401+
5402+ if ((ba & 0xFFC00000U) == 0x30800000U)
5403+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
5404+ else
5405+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
5406+
5407+ if (test_thread_flag(TIF_32BIT))
5408+ addr &= 0xFFFFFFFFUL;
5409+
5410+ err = get_user(save, (unsigned int *)addr);
5411+ err |= get_user(call, (unsigned int *)(addr+4));
5412+ err |= get_user(nop, (unsigned int *)(addr+8));
5413+ if (err)
5414+ break;
5415+
5416+#ifdef CONFIG_PAX_DLRESOLVE
5417+ if (save == 0x9DE3BFA8U &&
5418+ (call & 0xC0000000U) == 0x40000000U &&
5419+ nop == 0x01000000U)
5420+ {
5421+ struct vm_area_struct *vma;
5422+ unsigned long call_dl_resolve;
5423+
5424+ down_read(&current->mm->mmap_sem);
5425+ call_dl_resolve = current->mm->call_dl_resolve;
5426+ up_read(&current->mm->mmap_sem);
5427+ if (likely(call_dl_resolve))
5428+ goto emulate;
5429+
5430+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
5431+
5432+ down_write(&current->mm->mmap_sem);
5433+ if (current->mm->call_dl_resolve) {
5434+ call_dl_resolve = current->mm->call_dl_resolve;
5435+ up_write(&current->mm->mmap_sem);
5436+ if (vma)
5437+ kmem_cache_free(vm_area_cachep, vma);
5438+ goto emulate;
5439+ }
5440+
5441+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5442+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
5443+ up_write(&current->mm->mmap_sem);
5444+ if (vma)
5445+ kmem_cache_free(vm_area_cachep, vma);
5446+ return 1;
5447+ }
5448+
5449+ if (pax_insert_vma(vma, call_dl_resolve)) {
5450+ up_write(&current->mm->mmap_sem);
5451+ kmem_cache_free(vm_area_cachep, vma);
5452+ return 1;
5453+ }
5454+
5455+ current->mm->call_dl_resolve = call_dl_resolve;
5456+ up_write(&current->mm->mmap_sem);
5457+
5458+emulate:
5459+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5460+ regs->tpc = call_dl_resolve;
5461+ regs->tnpc = addr+4;
5462+ return 3;
5463+ }
5464+#endif
5465+
5466+ /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */
5467+ if ((save & 0xFFC00000U) == 0x05000000U &&
5468+ (call & 0xFFFFE000U) == 0x85C0A000U &&
5469+ nop == 0x01000000U)
5470+ {
5471+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5472+ regs->u_regs[UREG_G2] = addr + 4;
5473+ addr = (save & 0x003FFFFFU) << 10;
5474+ addr += (((call | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
5475+
5476+ if (test_thread_flag(TIF_32BIT))
5477+ addr &= 0xFFFFFFFFUL;
5478+
5479+ regs->tpc = addr;
5480+ regs->tnpc = addr+4;
5481+ return 3;
5482+ }
ae4e228f
MT
5483+
5484+ /* PaX: 64-bit PLT stub */
5485+ err = get_user(sethi1, (unsigned int *)addr);
5486+ err |= get_user(sethi2, (unsigned int *)(addr+4));
5487+ err |= get_user(or1, (unsigned int *)(addr+8));
5488+ err |= get_user(or2, (unsigned int *)(addr+12));
5489+ err |= get_user(sllx, (unsigned int *)(addr+16));
5490+ err |= get_user(add, (unsigned int *)(addr+20));
5491+ err |= get_user(jmpl, (unsigned int *)(addr+24));
5492+ err |= get_user(nop, (unsigned int *)(addr+28));
5493+ if (err)
5494+ break;
5495+
5496+ if ((sethi1 & 0xFFC00000U) == 0x09000000U &&
5497+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
5498+ (or1 & 0xFFFFE000U) == 0x88112000U &&
5499+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
5500+ sllx == 0x89293020U &&
5501+ add == 0x8A010005U &&
5502+ jmpl == 0x89C14000U &&
5503+ nop == 0x01000000U)
5504+ {
5505+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5506+ regs->u_regs[UREG_G4] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
5507+ regs->u_regs[UREG_G4] <<= 32;
5508+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
5509+ regs->u_regs[UREG_G5] += regs->u_regs[UREG_G4];
5510+ regs->u_regs[UREG_G4] = addr + 24;
5511+ addr = regs->u_regs[UREG_G5];
5512+ regs->tpc = addr;
5513+ regs->tnpc = addr+4;
5514+ return 3;
5515+ }
58c5fc13
MT
5516+ }
5517+ } while (0);
5518+
5519+#ifdef CONFIG_PAX_DLRESOLVE
5520+ do { /* PaX: unpatched PLT emulation step 2 */
5521+ unsigned int save, call, nop;
5522+
5523+ err = get_user(save, (unsigned int *)(regs->tpc-4));
5524+ err |= get_user(call, (unsigned int *)regs->tpc);
5525+ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
5526+ if (err)
5527+ break;
5528+
5529+ if (save == 0x9DE3BFA8U &&
5530+ (call & 0xC0000000U) == 0x40000000U &&
5531+ nop == 0x01000000U)
5532+ {
5533+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5534+
5535+ if (test_thread_flag(TIF_32BIT))
5536+ dl_resolve &= 0xFFFFFFFFUL;
5537+
5538+ regs->u_regs[UREG_RETPC] = regs->tpc;
5539+ regs->tpc = dl_resolve;
5540+ regs->tnpc = dl_resolve+4;
5541+ return 3;
5542+ }
5543+ } while (0);
5544+#endif
5545+
5546+ do { /* PaX: patched PLT emulation #7, must be AFTER the unpatched PLT emulation */
5547+ unsigned int sethi, ba, nop;
5548+
5549+ err = get_user(sethi, (unsigned int *)regs->tpc);
5550+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
5551+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
5552+
5553+ if (err)
5554+ break;
5555+
5556+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
5557+ (ba & 0xFFF00000U) == 0x30600000U &&
5558+ nop == 0x01000000U)
5559+ {
5560+ unsigned long addr;
5561+
5562+ addr = (sethi & 0x003FFFFFU) << 10;
5563+ regs->u_regs[UREG_G1] = addr;
5564+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
5565+
5566+ if (test_thread_flag(TIF_32BIT))
5567+ addr &= 0xFFFFFFFFUL;
5568+
5569+ regs->tpc = addr;
5570+ regs->tnpc = addr+4;
5571+ return 2;
5572+ }
5573+ } while (0);
5574+
5575+#endif
5576+
5577+ return 1;
5578+}
5579+
5580+void pax_report_insns(void *pc, void *sp)
5581+{
5582+ unsigned long i;
5583+
5584+ printk(KERN_ERR "PAX: bytes at PC: ");
ae4e228f 5585+ for (i = 0; i < 8; i++) {
58c5fc13
MT
5586+ unsigned int c;
5587+ if (get_user(c, (unsigned int *)pc+i))
5588+ printk(KERN_CONT "???????? ");
5589+ else
5590+ printk(KERN_CONT "%08x ", c);
5591+ }
5592+ printk("\n");
5593+}
5594+#endif
5595+
5596 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
5597 {
5598 struct mm_struct *mm = current->mm;
df50ba0c 5599@@ -340,6 +794,29 @@ asmlinkage void __kprobes do_sparc64_fau
58c5fc13
MT
5600 if (!vma)
5601 goto bad_area;
5602
5603+#ifdef CONFIG_PAX_PAGEEXEC
5604+ /* PaX: detect ITLB misses on non-exec pages */
5605+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
5606+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
5607+ {
5608+ if (address != regs->tpc)
5609+ goto good_area;
5610+
5611+ up_read(&mm->mmap_sem);
5612+ switch (pax_handle_fetch_fault(regs)) {
5613+
5614+#ifdef CONFIG_PAX_EMUPLT
5615+ case 2:
5616+ case 3:
5617+ return;
5618+#endif
5619+
5620+ }
5621+ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
5622+ do_group_exit(SIGKILL);
5623+ }
5624+#endif
5625+
5626 /* Pure DTLB misses do not tell us whether the fault causing
5627 * load/store/atomic was a write or not, it only says that there
5628 * was no match. So in such a case we (carefully) read the
16454cff
MT
5629diff -urNp linux-2.6.38.1/arch/sparc/mm/hugetlbpage.c linux-2.6.38.1/arch/sparc/mm/hugetlbpage.c
5630--- linux-2.6.38.1/arch/sparc/mm/hugetlbpage.c 2011-03-14 21:20:32.000000000 -0400
5631+++ linux-2.6.38.1/arch/sparc/mm/hugetlbpage.c 2011-03-21 23:47:41.000000000 -0400
57199397
MT
5632@@ -68,7 +68,7 @@ full_search:
5633 }
5634 return -ENOMEM;
5635 }
5636- if (likely(!vma || addr + len <= vma->vm_start)) {
5637+ if (likely(check_heap_stack_gap(vma, addr, len))) {
5638 /*
5639 * Remember the place where we stopped the search:
5640 */
5641@@ -107,7 +107,7 @@ hugetlb_get_unmapped_area_topdown(struct
5642 /* make sure it can fit in the remaining address space */
5643 if (likely(addr > len)) {
5644 vma = find_vma(mm, addr-len);
5645- if (!vma || addr <= vma->vm_start) {
5646+ if (check_heap_stack_gap(vma, addr - len, len)) {
5647 /* remember the address as a hint for next time */
5648 return (mm->free_area_cache = addr-len);
5649 }
16454cff
MT
5650@@ -116,16 +116,17 @@ hugetlb_get_unmapped_area_topdown(struct
5651 if (unlikely(mm->mmap_base < len))
5652 goto bottomup;
5653
5654- addr = (mm->mmap_base-len) & HPAGE_MASK;
5655+ addr = mm->mmap_base - len;
5656
5657 do {
5658+ addr &= HPAGE_MASK;
5659 /*
5660 * Lookup failure means no vma is above this address,
5661 * else if new region fits below vma->vm_start,
57199397
MT
5662 * return with success:
5663 */
5664 vma = find_vma(mm, addr);
5665- if (likely(!vma || addr+len <= vma->vm_start)) {
5666+ if (likely(check_heap_stack_gap(vma, addr, len))) {
5667 /* remember the address as a hint for next time */
5668 return (mm->free_area_cache = addr);
5669 }
16454cff
MT
5670@@ -135,8 +136,8 @@ hugetlb_get_unmapped_area_topdown(struct
5671 mm->cached_hole_size = vma->vm_start - addr;
5672
5673 /* try just below the current vma->vm_start */
5674- addr = (vma->vm_start-len) & HPAGE_MASK;
5675- } while (likely(len < vma->vm_start));
5676+ addr = skip_heap_stack_gap(vma, len);
5677+ } while (!IS_ERR_VALUE(addr));
5678
5679 bottomup:
5680 /*
5681@@ -182,8 +183,7 @@ hugetlb_get_unmapped_area(struct file *f
57199397
MT
5682 if (addr) {
5683 addr = ALIGN(addr, HPAGE_SIZE);
5684 vma = find_vma(mm, addr);
5685- if (task_size - len >= addr &&
5686- (!vma || addr + len <= vma->vm_start))
5687+ if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
5688 return addr;
5689 }
5690 if (mm->get_unmapped_area == arch_get_unmapped_area)
16454cff
MT
5691diff -urNp linux-2.6.38.1/arch/sparc/mm/init_32.c linux-2.6.38.1/arch/sparc/mm/init_32.c
5692--- linux-2.6.38.1/arch/sparc/mm/init_32.c 2011-03-14 21:20:32.000000000 -0400
5693+++ linux-2.6.38.1/arch/sparc/mm/init_32.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 5694@@ -318,6 +318,9 @@ extern void device_scan(void);
58c5fc13
MT
5695 pgprot_t PAGE_SHARED __read_mostly;
5696 EXPORT_SYMBOL(PAGE_SHARED);
5697
5698+pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
5699+EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
5700+
5701 void __init paging_init(void)
5702 {
5703 switch(sparc_cpu_model) {
df50ba0c 5704@@ -346,17 +349,17 @@ void __init paging_init(void)
58c5fc13
MT
5705
5706 /* Initialize the protection map with non-constant, MMU dependent values. */
5707 protection_map[0] = PAGE_NONE;
5708- protection_map[1] = PAGE_READONLY;
5709- protection_map[2] = PAGE_COPY;
5710- protection_map[3] = PAGE_COPY;
5711+ protection_map[1] = PAGE_READONLY_NOEXEC;
5712+ protection_map[2] = PAGE_COPY_NOEXEC;
5713+ protection_map[3] = PAGE_COPY_NOEXEC;
5714 protection_map[4] = PAGE_READONLY;
5715 protection_map[5] = PAGE_READONLY;
5716 protection_map[6] = PAGE_COPY;
5717 protection_map[7] = PAGE_COPY;
5718 protection_map[8] = PAGE_NONE;
5719- protection_map[9] = PAGE_READONLY;
5720- protection_map[10] = PAGE_SHARED;
5721- protection_map[11] = PAGE_SHARED;
5722+ protection_map[9] = PAGE_READONLY_NOEXEC;
5723+ protection_map[10] = PAGE_SHARED_NOEXEC;
5724+ protection_map[11] = PAGE_SHARED_NOEXEC;
5725 protection_map[12] = PAGE_READONLY;
5726 protection_map[13] = PAGE_READONLY;
5727 protection_map[14] = PAGE_SHARED;
16454cff
MT
5728diff -urNp linux-2.6.38.1/arch/sparc/mm/Makefile linux-2.6.38.1/arch/sparc/mm/Makefile
5729--- linux-2.6.38.1/arch/sparc/mm/Makefile 2011-03-14 21:20:32.000000000 -0400
5730+++ linux-2.6.38.1/arch/sparc/mm/Makefile 2011-03-21 18:31:35.000000000 -0400
57199397
MT
5731@@ -2,7 +2,7 @@
5732 #
5733
5734 asflags-y := -ansi
5735-ccflags-y := -Werror
5736+#ccflags-y := -Werror
5737
5738 obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o
5739 obj-y += fault_$(BITS).o
16454cff
MT
5740diff -urNp linux-2.6.38.1/arch/sparc/mm/srmmu.c linux-2.6.38.1/arch/sparc/mm/srmmu.c
5741--- linux-2.6.38.1/arch/sparc/mm/srmmu.c 2011-03-14 21:20:32.000000000 -0400
5742+++ linux-2.6.38.1/arch/sparc/mm/srmmu.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 5743@@ -2200,6 +2200,13 @@ void __init ld_mmu_srmmu(void)
58c5fc13
MT
5744 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
5745 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
5746 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
5747+
5748+#ifdef CONFIG_PAX_PAGEEXEC
5749+ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
5750+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
5751+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
5752+#endif
5753+
5754 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
5755 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
5756
16454cff
MT
5757diff -urNp linux-2.6.38.1/arch/um/include/asm/kmap_types.h linux-2.6.38.1/arch/um/include/asm/kmap_types.h
5758--- linux-2.6.38.1/arch/um/include/asm/kmap_types.h 2011-03-14 21:20:32.000000000 -0400
5759+++ linux-2.6.38.1/arch/um/include/asm/kmap_types.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
5760@@ -23,6 +23,7 @@ enum km_type {
5761 KM_IRQ1,
5762 KM_SOFTIRQ0,
5763 KM_SOFTIRQ1,
5764+ KM_CLEARPAGE,
5765 KM_TYPE_NR
5766 };
5767
16454cff
MT
5768diff -urNp linux-2.6.38.1/arch/um/include/asm/page.h linux-2.6.38.1/arch/um/include/asm/page.h
5769--- linux-2.6.38.1/arch/um/include/asm/page.h 2011-03-14 21:20:32.000000000 -0400
5770+++ linux-2.6.38.1/arch/um/include/asm/page.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
5771@@ -14,6 +14,9 @@
5772 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
5773 #define PAGE_MASK (~(PAGE_SIZE-1))
5774
5775+#define ktla_ktva(addr) (addr)
5776+#define ktva_ktla(addr) (addr)
5777+
5778 #ifndef __ASSEMBLY__
5779
5780 struct page;
16454cff
MT
5781diff -urNp linux-2.6.38.1/arch/um/kernel/process.c linux-2.6.38.1/arch/um/kernel/process.c
5782--- linux-2.6.38.1/arch/um/kernel/process.c 2011-03-14 21:20:32.000000000 -0400
5783+++ linux-2.6.38.1/arch/um/kernel/process.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
5784@@ -404,22 +404,6 @@ int singlestepping(void * t)
5785 return 2;
5786 }
5787
5788-/*
5789- * Only x86 and x86_64 have an arch_align_stack().
5790- * All other arches have "#define arch_align_stack(x) (x)"
5791- * in their asm/system.h
5792- * As this is included in UML from asm-um/system-generic.h,
5793- * we can use it to behave as the subarch does.
5794- */
5795-#ifndef arch_align_stack
5796-unsigned long arch_align_stack(unsigned long sp)
5797-{
5798- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
5799- sp -= get_random_int() % 8192;
5800- return sp & ~0xf;
5801-}
5802-#endif
5803-
5804 unsigned long get_wchan(struct task_struct *p)
5805 {
5806 unsigned long stack_page, sp, ip;
16454cff
MT
5807diff -urNp linux-2.6.38.1/arch/um/sys-i386/syscalls.c linux-2.6.38.1/arch/um/sys-i386/syscalls.c
5808--- linux-2.6.38.1/arch/um/sys-i386/syscalls.c 2011-03-14 21:20:32.000000000 -0400
5809+++ linux-2.6.38.1/arch/um/sys-i386/syscalls.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
5810@@ -11,6 +11,21 @@
5811 #include "asm/uaccess.h"
5812 #include "asm/unistd.h"
5813
5814+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
5815+{
5816+ unsigned long pax_task_size = TASK_SIZE;
5817+
5818+#ifdef CONFIG_PAX_SEGMEXEC
5819+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
5820+ pax_task_size = SEGMEXEC_TASK_SIZE;
5821+#endif
5822+
5823+ if (len > pax_task_size || addr > pax_task_size - len)
5824+ return -EINVAL;
5825+
5826+ return 0;
5827+}
5828+
5829 /*
df50ba0c
MT
5830 * The prototype on i386 is:
5831 *
16454cff
MT
5832diff -urNp linux-2.6.38.1/arch/x86/boot/bitops.h linux-2.6.38.1/arch/x86/boot/bitops.h
5833--- linux-2.6.38.1/arch/x86/boot/bitops.h 2011-03-14 21:20:32.000000000 -0400
5834+++ linux-2.6.38.1/arch/x86/boot/bitops.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
5835@@ -26,7 +26,7 @@ static inline int variable_test_bit(int
5836 u8 v;
5837 const u32 *p = (const u32 *)addr;
5838
5839- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
5840+ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
5841 return v;
5842 }
5843
5844@@ -37,7 +37,7 @@ static inline int variable_test_bit(int
5845
5846 static inline void set_bit(int nr, void *addr)
5847 {
5848- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
5849+ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
5850 }
5851
5852 #endif /* BOOT_BITOPS_H */
16454cff
MT
5853diff -urNp linux-2.6.38.1/arch/x86/boot/boot.h linux-2.6.38.1/arch/x86/boot/boot.h
5854--- linux-2.6.38.1/arch/x86/boot/boot.h 2011-03-14 21:20:32.000000000 -0400
5855+++ linux-2.6.38.1/arch/x86/boot/boot.h 2011-03-21 18:31:35.000000000 -0400
6892158b 5856@@ -85,7 +85,7 @@ static inline void io_delay(void)
58c5fc13
MT
5857 static inline u16 ds(void)
5858 {
5859 u16 seg;
5860- asm("movw %%ds,%0" : "=rm" (seg));
5861+ asm volatile("movw %%ds,%0" : "=rm" (seg));
5862 return seg;
5863 }
5864
6892158b 5865@@ -181,7 +181,7 @@ static inline void wrgs32(u32 v, addr_t
58c5fc13
MT
5866 static inline int memcmp(const void *s1, const void *s2, size_t len)
5867 {
5868 u8 diff;
5869- asm("repe; cmpsb; setnz %0"
5870+ asm volatile("repe; cmpsb; setnz %0"
5871 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
5872 return diff;
5873 }
16454cff
MT
5874diff -urNp linux-2.6.38.1/arch/x86/boot/compressed/head_32.S linux-2.6.38.1/arch/x86/boot/compressed/head_32.S
5875--- linux-2.6.38.1/arch/x86/boot/compressed/head_32.S 2011-03-14 21:20:32.000000000 -0400
5876+++ linux-2.6.38.1/arch/x86/boot/compressed/head_32.S 2011-03-21 18:31:35.000000000 -0400
ae4e228f 5877@@ -76,7 +76,7 @@ ENTRY(startup_32)
58c5fc13
MT
5878 notl %eax
5879 andl %eax, %ebx
5880 #else
5881- movl $LOAD_PHYSICAL_ADDR, %ebx
5882+ movl $____LOAD_PHYSICAL_ADDR, %ebx
5883 #endif
5884
5885 /* Target address to relocate to for decompression */
6892158b 5886@@ -162,7 +162,7 @@ relocated:
58c5fc13
MT
5887 * and where it was actually loaded.
5888 */
5889 movl %ebp, %ebx
5890- subl $LOAD_PHYSICAL_ADDR, %ebx
5891+ subl $____LOAD_PHYSICAL_ADDR, %ebx
5892 jz 2f /* Nothing to be done if loaded at compiled addr. */
5893 /*
5894 * Process relocations.
6892158b 5895@@ -170,8 +170,7 @@ relocated:
58c5fc13
MT
5896
5897 1: subl $4, %edi
5898 movl (%edi), %ecx
5899- testl %ecx, %ecx
5900- jz 2f
5901+ jecxz 2f
5902 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
5903 jmp 1b
5904 2:
16454cff
MT
5905diff -urNp linux-2.6.38.1/arch/x86/boot/compressed/head_64.S linux-2.6.38.1/arch/x86/boot/compressed/head_64.S
5906--- linux-2.6.38.1/arch/x86/boot/compressed/head_64.S 2011-03-14 21:20:32.000000000 -0400
5907+++ linux-2.6.38.1/arch/x86/boot/compressed/head_64.S 2011-03-21 18:31:35.000000000 -0400
ae4e228f 5908@@ -91,7 +91,7 @@ ENTRY(startup_32)
58c5fc13
MT
5909 notl %eax
5910 andl %eax, %ebx
5911 #else
5912- movl $LOAD_PHYSICAL_ADDR, %ebx
5913+ movl $____LOAD_PHYSICAL_ADDR, %ebx
5914 #endif
5915
5916 /* Target address to relocate to for decompression */
5917@@ -233,7 +233,7 @@ ENTRY(startup_64)
5918 notq %rax
5919 andq %rax, %rbp
5920 #else
5921- movq $LOAD_PHYSICAL_ADDR, %rbp
5922+ movq $____LOAD_PHYSICAL_ADDR, %rbp
5923 #endif
5924
5925 /* Target address to relocate to for decompression */
16454cff
MT
5926diff -urNp linux-2.6.38.1/arch/x86/boot/compressed/misc.c linux-2.6.38.1/arch/x86/boot/compressed/misc.c
5927--- linux-2.6.38.1/arch/x86/boot/compressed/misc.c 2011-03-14 21:20:32.000000000 -0400
5928+++ linux-2.6.38.1/arch/x86/boot/compressed/misc.c 2011-03-21 18:31:35.000000000 -0400
5929@@ -310,7 +310,7 @@ static void parse_elf(void *output)
58c5fc13
MT
5930 case PT_LOAD:
5931 #ifdef CONFIG_RELOCATABLE
5932 dest = output;
5933- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
5934+ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
5935 #else
5936 dest = (void *)(phdr->p_paddr);
5937 #endif
16454cff 5938@@ -363,7 +363,7 @@ asmlinkage void decompress_kernel(void *
58c5fc13
MT
5939 error("Destination address too large");
5940 #endif
5941 #ifndef CONFIG_RELOCATABLE
5942- if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
5943+ if ((unsigned long)output != ____LOAD_PHYSICAL_ADDR)
5944 error("Wrong destination address");
5945 #endif
5946
16454cff
MT
5947diff -urNp linux-2.6.38.1/arch/x86/boot/compressed/relocs.c linux-2.6.38.1/arch/x86/boot/compressed/relocs.c
5948--- linux-2.6.38.1/arch/x86/boot/compressed/relocs.c 2011-03-14 21:20:32.000000000 -0400
5949+++ linux-2.6.38.1/arch/x86/boot/compressed/relocs.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 5950@@ -13,8 +13,11 @@
58c5fc13 5951
ae4e228f
MT
5952 static void die(char *fmt, ...);
5953
5954+#include "../../../../include/generated/autoconf.h"
58c5fc13
MT
5955+
5956 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
5957 static Elf32_Ehdr ehdr;
5958+static Elf32_Phdr *phdr;
5959 static unsigned long reloc_count, reloc_idx;
5960 static unsigned long *relocs;
5961
ae4e228f 5962@@ -270,9 +273,39 @@ static void read_ehdr(FILE *fp)
58c5fc13
MT
5963 }
5964 }
5965
5966+static void read_phdrs(FILE *fp)
5967+{
5968+ unsigned int i;
5969+
5970+ phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
5971+ if (!phdr) {
5972+ die("Unable to allocate %d program headers\n",
5973+ ehdr.e_phnum);
5974+ }
5975+ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
5976+ die("Seek to %d failed: %s\n",
5977+ ehdr.e_phoff, strerror(errno));
5978+ }
5979+ if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
5980+ die("Cannot read ELF program headers: %s\n",
5981+ strerror(errno));
5982+ }
5983+ for(i = 0; i < ehdr.e_phnum; i++) {
5984+ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
5985+ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
5986+ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
5987+ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
5988+ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
5989+ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
5990+ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
5991+ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
5992+ }
5993+
5994+}
5995+
5996 static void read_shdrs(FILE *fp)
5997 {
5998- int i;
5999+ unsigned int i;
6000 Elf32_Shdr shdr;
6001
6002 secs = calloc(ehdr.e_shnum, sizeof(struct section));
ae4e228f 6003@@ -307,7 +340,7 @@ static void read_shdrs(FILE *fp)
58c5fc13
MT
6004
6005 static void read_strtabs(FILE *fp)
6006 {
6007- int i;
6008+ unsigned int i;
6009 for (i = 0; i < ehdr.e_shnum; i++) {
6010 struct section *sec = &secs[i];
6011 if (sec->shdr.sh_type != SHT_STRTAB) {
ae4e228f 6012@@ -332,7 +365,7 @@ static void read_strtabs(FILE *fp)
58c5fc13
MT
6013
6014 static void read_symtabs(FILE *fp)
6015 {
6016- int i,j;
6017+ unsigned int i,j;
6018 for (i = 0; i < ehdr.e_shnum; i++) {
6019 struct section *sec = &secs[i];
6020 if (sec->shdr.sh_type != SHT_SYMTAB) {
ae4e228f 6021@@ -365,7 +398,9 @@ static void read_symtabs(FILE *fp)
58c5fc13
MT
6022
6023 static void read_relocs(FILE *fp)
6024 {
6025- int i,j;
6026+ unsigned int i,j;
6027+ uint32_t base;
6028+
6029 for (i = 0; i < ehdr.e_shnum; i++) {
6030 struct section *sec = &secs[i];
6031 if (sec->shdr.sh_type != SHT_REL) {
ae4e228f 6032@@ -385,9 +420,18 @@ static void read_relocs(FILE *fp)
58c5fc13
MT
6033 die("Cannot read symbol table: %s\n",
6034 strerror(errno));
6035 }
6036+ base = 0;
6037+ for (j = 0; j < ehdr.e_phnum; j++) {
6038+ if (phdr[j].p_type != PT_LOAD )
6039+ continue;
6040+ 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)
6041+ continue;
6042+ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
6043+ break;
6044+ }
6045 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
6046 Elf32_Rel *rel = &sec->reltab[j];
6047- rel->r_offset = elf32_to_cpu(rel->r_offset);
6048+ rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
6049 rel->r_info = elf32_to_cpu(rel->r_info);
6050 }
6051 }
ae4e228f 6052@@ -396,14 +440,14 @@ static void read_relocs(FILE *fp)
58c5fc13
MT
6053
6054 static void print_absolute_symbols(void)
6055 {
6056- int i;
6057+ unsigned int i;
6058 printf("Absolute symbols\n");
6059 printf(" Num: Value Size Type Bind Visibility Name\n");
6060 for (i = 0; i < ehdr.e_shnum; i++) {
6061 struct section *sec = &secs[i];
6062 char *sym_strtab;
6063 Elf32_Sym *sh_symtab;
6064- int j;
6065+ unsigned int j;
6066
6067 if (sec->shdr.sh_type != SHT_SYMTAB) {
6068 continue;
ae4e228f 6069@@ -431,14 +475,14 @@ static void print_absolute_symbols(void)
58c5fc13
MT
6070
6071 static void print_absolute_relocs(void)
6072 {
6073- int i, printed = 0;
6074+ unsigned int i, printed = 0;
6075
6076 for (i = 0; i < ehdr.e_shnum; i++) {
6077 struct section *sec = &secs[i];
6078 struct section *sec_applies, *sec_symtab;
6079 char *sym_strtab;
6080 Elf32_Sym *sh_symtab;
6081- int j;
6082+ unsigned int j;
6083 if (sec->shdr.sh_type != SHT_REL) {
6084 continue;
6085 }
ae4e228f 6086@@ -499,13 +543,13 @@ static void print_absolute_relocs(void)
58c5fc13
MT
6087
6088 static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
6089 {
6090- int i;
6091+ unsigned int i;
6092 /* Walk through the relocations */
6093 for (i = 0; i < ehdr.e_shnum; i++) {
6094 char *sym_strtab;
6095 Elf32_Sym *sh_symtab;
6096 struct section *sec_applies, *sec_symtab;
6097- int j;
6098+ unsigned int j;
6099 struct section *sec = &secs[i];
6100
6101 if (sec->shdr.sh_type != SHT_REL) {
ae4e228f
MT
6102@@ -530,6 +574,22 @@ static void walk_relocs(void (*visit)(El
6103 !is_rel_reloc(sym_name(sym_strtab, sym))) {
58c5fc13
MT
6104 continue;
6105 }
6106+ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
57199397 6107+ if (!strcmp(sec_name(sym->st_shndx), ".data..percpu") && strcmp(sym_name(sym_strtab, sym), "__per_cpu_load"))
58c5fc13
MT
6108+ continue;
6109+
6110+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
6111+ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
57199397 6112+ if (!strcmp(sec_name(sym->st_shndx), ".module.text") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
ae4e228f 6113+ continue;
58c5fc13
MT
6114+ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
6115+ continue;
6116+ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
6117+ continue;
6118+ if (!strcmp(sec_name(sym->st_shndx), ".text") && strcmp(sym_name(sym_strtab, sym), "__LOAD_PHYSICAL_ADDR"))
6119+ continue;
6120+#endif
ae4e228f
MT
6121+
6122 switch (r_type) {
6123 case R_386_NONE:
6124 case R_386_PC32:
6125@@ -571,7 +631,7 @@ static int cmp_relocs(const void *va, co
58c5fc13
MT
6126
6127 static void emit_relocs(int as_text)
6128 {
6129- int i;
6130+ unsigned int i;
6131 /* Count how many relocations I have and allocate space for them. */
6132 reloc_count = 0;
6133 walk_relocs(count_reloc);
ae4e228f 6134@@ -665,6 +725,7 @@ int main(int argc, char **argv)
58c5fc13
MT
6135 fname, strerror(errno));
6136 }
6137 read_ehdr(fp);
6138+ read_phdrs(fp);
6139 read_shdrs(fp);
6140 read_strtabs(fp);
6141 read_symtabs(fp);
16454cff
MT
6142diff -urNp linux-2.6.38.1/arch/x86/boot/cpucheck.c linux-2.6.38.1/arch/x86/boot/cpucheck.c
6143--- linux-2.6.38.1/arch/x86/boot/cpucheck.c 2011-03-14 21:20:32.000000000 -0400
6144+++ linux-2.6.38.1/arch/x86/boot/cpucheck.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
6145@@ -74,7 +74,7 @@ static int has_fpu(void)
6146 u16 fcw = -1, fsw = -1;
6147 u32 cr0;
6148
6149- asm("movl %%cr0,%0" : "=r" (cr0));
6150+ asm volatile("movl %%cr0,%0" : "=r" (cr0));
6151 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
6152 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
6153 asm volatile("movl %0,%%cr0" : : "r" (cr0));
6154@@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
6155 {
6156 u32 f0, f1;
6157
6158- asm("pushfl ; "
6159+ asm volatile("pushfl ; "
6160 "pushfl ; "
6161 "popl %0 ; "
6162 "movl %0,%1 ; "
6163@@ -115,7 +115,7 @@ static void get_flags(void)
6164 set_bit(X86_FEATURE_FPU, cpu.flags);
6165
6166 if (has_eflag(X86_EFLAGS_ID)) {
6167- asm("cpuid"
6168+ asm volatile("cpuid"
6169 : "=a" (max_intel_level),
6170 "=b" (cpu_vendor[0]),
6171 "=d" (cpu_vendor[1]),
6172@@ -124,7 +124,7 @@ static void get_flags(void)
6173
6174 if (max_intel_level >= 0x00000001 &&
6175 max_intel_level <= 0x0000ffff) {
6176- asm("cpuid"
6177+ asm volatile("cpuid"
6178 : "=a" (tfms),
6179 "=c" (cpu.flags[4]),
6180 "=d" (cpu.flags[0])
6181@@ -136,7 +136,7 @@ static void get_flags(void)
6182 cpu.model += ((tfms >> 16) & 0xf) << 4;
6183 }
6184
6185- asm("cpuid"
6186+ asm volatile("cpuid"
6187 : "=a" (max_amd_level)
6188 : "a" (0x80000000)
6189 : "ebx", "ecx", "edx");
6190@@ -144,7 +144,7 @@ static void get_flags(void)
6191 if (max_amd_level >= 0x80000001 &&
6192 max_amd_level <= 0x8000ffff) {
6193 u32 eax = 0x80000001;
6194- asm("cpuid"
6195+ asm volatile("cpuid"
6196 : "+a" (eax),
6197 "=c" (cpu.flags[6]),
6198 "=d" (cpu.flags[1])
6199@@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
6200 u32 ecx = MSR_K7_HWCR;
6201 u32 eax, edx;
6202
6203- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6204+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6205 eax &= ~(1 << 15);
6206- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6207+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6208
6209 get_flags(); /* Make sure it really did something */
6210 err = check_flags();
6211@@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
6212 u32 ecx = MSR_VIA_FCR;
6213 u32 eax, edx;
6214
6215- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6216+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6217 eax |= (1<<1)|(1<<7);
6218- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6219+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6220
6221 set_bit(X86_FEATURE_CX8, cpu.flags);
6222 err = check_flags();
6223@@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
6224 u32 eax, edx;
6225 u32 level = 1;
6226
6227- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6228- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
6229- asm("cpuid"
6230+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6231+ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
6232+ asm volatile("cpuid"
6233 : "+a" (level), "=d" (cpu.flags[0])
6234 : : "ecx", "ebx");
6235- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6236+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6237
6238 err = check_flags();
6239 }
16454cff
MT
6240diff -urNp linux-2.6.38.1/arch/x86/boot/header.S linux-2.6.38.1/arch/x86/boot/header.S
6241--- linux-2.6.38.1/arch/x86/boot/header.S 2011-03-14 21:20:32.000000000 -0400
6242+++ linux-2.6.38.1/arch/x86/boot/header.S 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
6243@@ -224,7 +224,7 @@ setup_data: .quad 0 # 64-bit physical
6244 # single linked list of
6245 # struct setup_data
6246
6247-pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
6248+pref_address: .quad ____LOAD_PHYSICAL_ADDR # preferred load addr
6249
6250 #define ZO_INIT_SIZE (ZO__end - ZO_startup_32 + ZO_z_extract_offset)
6251 #define VO_INIT_SIZE (VO__end - VO__text)
16454cff
MT
6252diff -urNp linux-2.6.38.1/arch/x86/boot/memory.c linux-2.6.38.1/arch/x86/boot/memory.c
6253--- linux-2.6.38.1/arch/x86/boot/memory.c 2011-03-14 21:20:32.000000000 -0400
6254+++ linux-2.6.38.1/arch/x86/boot/memory.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
6255@@ -19,7 +19,7 @@
6256
6257 static int detect_memory_e820(void)
6258 {
6259- int count = 0;
6260+ unsigned int count = 0;
6261 struct biosregs ireg, oreg;
6262 struct e820entry *desc = boot_params.e820_map;
6263 static struct e820entry buf; /* static so it is zeroed */
16454cff
MT
6264diff -urNp linux-2.6.38.1/arch/x86/boot/video.c linux-2.6.38.1/arch/x86/boot/video.c
6265--- linux-2.6.38.1/arch/x86/boot/video.c 2011-03-14 21:20:32.000000000 -0400
6266+++ linux-2.6.38.1/arch/x86/boot/video.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
6267@@ -96,7 +96,7 @@ static void store_mode_params(void)
6268 static unsigned int get_entry(void)
6269 {
6270 char entry_buf[4];
6271- int i, len = 0;
6272+ unsigned int i, len = 0;
6273 int key;
6274 unsigned int v;
6275
16454cff
MT
6276diff -urNp linux-2.6.38.1/arch/x86/boot/video-vesa.c linux-2.6.38.1/arch/x86/boot/video-vesa.c
6277--- linux-2.6.38.1/arch/x86/boot/video-vesa.c 2011-03-14 21:20:32.000000000 -0400
6278+++ linux-2.6.38.1/arch/x86/boot/video-vesa.c 2011-03-21 18:31:35.000000000 -0400
57199397 6279@@ -200,6 +200,7 @@ static void vesa_store_pm_info(void)
58c5fc13 6280
57199397
MT
6281 boot_params.screen_info.vesapm_seg = oreg.es;
6282 boot_params.screen_info.vesapm_off = oreg.di;
6283+ boot_params.screen_info.vesapm_size = oreg.cx;
6284 }
efbe55a5 6285
57199397 6286 /*
16454cff
MT
6287diff -urNp linux-2.6.38.1/arch/x86/ia32/ia32_aout.c linux-2.6.38.1/arch/x86/ia32/ia32_aout.c
6288--- linux-2.6.38.1/arch/x86/ia32/ia32_aout.c 2011-03-14 21:20:32.000000000 -0400
6289+++ linux-2.6.38.1/arch/x86/ia32/ia32_aout.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
6290@@ -162,6 +162,8 @@ static int aout_core_dump(long signr, st
6291 unsigned long dump_start, dump_size;
6292 struct user32 dump;
6293
6294+ memset(&dump, 0, sizeof(dump));
6295+
6296 fs = get_fs();
6297 set_fs(KERNEL_DS);
6298 has_dumped = 1;
16454cff
MT
6299diff -urNp linux-2.6.38.1/arch/x86/ia32/ia32entry.S linux-2.6.38.1/arch/x86/ia32/ia32entry.S
6300--- linux-2.6.38.1/arch/x86/ia32/ia32entry.S 2011-03-14 21:20:32.000000000 -0400
6301+++ linux-2.6.38.1/arch/x86/ia32/ia32entry.S 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
6302@@ -13,6 +13,7 @@
6303 #include <asm/thread_info.h>
6304 #include <asm/segment.h>
6305 #include <asm/irqflags.h>
6306+#include <asm/pgtable.h>
6307 #include <linux/linkage.h>
6308
6309 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
317566c1
MT
6310@@ -93,6 +94,18 @@ ENTRY(native_irq_enable_sysexit)
6311 ENDPROC(native_irq_enable_sysexit)
6312 #endif
6313
6314+ .macro pax_enter_kernel_user
df50ba0c
MT
6315+#ifdef CONFIG_PAX_MEMORY_UDEREF
6316+ call pax_enter_kernel_user
6317+#endif
317566c1
MT
6318+ .endm
6319+
6320+ .macro pax_exit_kernel_user
6321+#ifdef CONFIG_PAX_MEMORY_UDEREF
6322+ call pax_exit_kernel_user
6323+#endif
6324+ .endm
df50ba0c 6325+
317566c1
MT
6326 /*
6327 * 32bit SYSENTER instruction entry.
6328 *
6329@@ -120,6 +133,7 @@ ENTRY(ia32_sysenter_target)
6330 SWAPGS_UNSAFE_STACK
6331 movq PER_CPU_VAR(kernel_stack), %rsp
6332 addq $(KERNEL_STACK_OFFSET),%rsp
6333+ pax_enter_kernel_user
df50ba0c
MT
6334 /*
6335 * No need to follow this irqs on/off section: the syscall
6336 * disabled irqs, here we enable it straight after entry:
317566c1 6337@@ -150,6 +164,12 @@ ENTRY(ia32_sysenter_target)
df50ba0c
MT
6338 SAVE_ARGS 0,0,1
6339 /* no need to do an access_ok check here because rbp has been
6340 32bit zero extended */
6341+
6342+#ifdef CONFIG_PAX_MEMORY_UDEREF
6343+ mov $PAX_USER_SHADOW_BASE,%r10
6344+ add %r10,%rbp
6345+#endif
6346+
6347 1: movl (%rbp),%ebp
6348 .section __ex_table,"a"
6349 .quad 1b,ia32_badarg
317566c1 6350@@ -172,6 +192,7 @@ sysenter_dispatch:
df50ba0c
MT
6351 testl $_TIF_ALLWORK_MASK,TI_flags(%r10)
6352 jnz sysexit_audit
6353 sysexit_from_sys_call:
317566c1 6354+ pax_exit_kernel_user
df50ba0c
MT
6355 andl $~TS_COMPAT,TI_status(%r10)
6356 /* clear IF, that popfq doesn't enable interrupts early */
6357 andl $~0x200,EFLAGS-R11(%rsp)
317566c1 6358@@ -290,6 +311,11 @@ ENTRY(ia32_cstar_target)
df50ba0c
MT
6359 movl %esp,%r8d
6360 CFI_REGISTER rsp,r8
6361 movq PER_CPU_VAR(kernel_stack),%rsp
6362+
6363+#ifdef CONFIG_PAX_MEMORY_UDEREF
317566c1 6364+ pax_enter_kernel_user
df50ba0c
MT
6365+#endif
6366+
6367 /*
6368 * No need to follow this irqs on/off section: the syscall
6369 * disabled irqs and here we enable it straight after entry:
317566c1 6370@@ -311,6 +337,12 @@ ENTRY(ia32_cstar_target)
df50ba0c
MT
6371 /* no need to do an access_ok check here because r8 has been
6372 32bit zero extended */
6373 /* hardware stack frame is complete now */
6374+
6375+#ifdef CONFIG_PAX_MEMORY_UDEREF
6376+ mov $PAX_USER_SHADOW_BASE,%r10
6377+ add %r10,%r8
6378+#endif
6379+
6380 1: movl (%r8),%r9d
6381 .section __ex_table,"a"
6382 .quad 1b,ia32_badarg
317566c1 6383@@ -333,6 +365,7 @@ cstar_dispatch:
df50ba0c
MT
6384 testl $_TIF_ALLWORK_MASK,TI_flags(%r10)
6385 jnz sysretl_audit
6386 sysretl_from_sys_call:
317566c1 6387+ pax_exit_kernel_user
df50ba0c
MT
6388 andl $~TS_COMPAT,TI_status(%r10)
6389 RESTORE_ARGS 1,-ARG_SKIP,1,1,1
6390 movl RIP-ARGOFFSET(%rsp),%ecx
317566c1 6391@@ -415,6 +448,7 @@ ENTRY(ia32_syscall)
df50ba0c
MT
6392 CFI_REL_OFFSET rip,RIP-RIP
6393 PARAVIRT_ADJUST_EXCEPTION_FRAME
6394 SWAPGS
317566c1 6395+ pax_enter_kernel_user
df50ba0c
MT
6396 /*
6397 * No need to follow this irqs on/off section: the syscall
6398 * disabled irqs and here we enable it straight after entry:
16454cff
MT
6399diff -urNp linux-2.6.38.1/arch/x86/ia32/ia32_signal.c linux-2.6.38.1/arch/x86/ia32/ia32_signal.c
6400--- linux-2.6.38.1/arch/x86/ia32/ia32_signal.c 2011-03-14 21:20:32.000000000 -0400
6401+++ linux-2.6.38.1/arch/x86/ia32/ia32_signal.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
6402@@ -403,7 +403,7 @@ static void __user *get_sigframe(struct
6403 sp -= frame_size;
6404 /* Align the stack pointer according to the i386 ABI,
6405 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
6406- sp = ((sp + 4) & -16ul) - 4;
6407+ sp = ((sp - 12) & -16ul) - 4;
6408 return (void __user *) sp;
6409 }
6410
bc901d79
MT
6411@@ -461,7 +461,7 @@ int ia32_setup_frame(int sig, struct k_s
6412 * These are actually not used anymore, but left because some
6413 * gdb versions depend on them as a marker.
6414 */
6415- put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
6416+ put_user_ex(*((const u64 *)&code), (u64 *)frame->retcode);
6417 } put_user_catch(err);
6418
6419 if (err)
57199397
MT
6420@@ -503,7 +503,7 @@ int ia32_setup_rt_frame(int sig, struct
6421 0xb8,
6422 __NR_ia32_rt_sigreturn,
6423 0x80cd,
6424- 0,
6425+ 0
6426 };
6427
6428 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
bc901d79 6429@@ -533,16 +533,18 @@ int ia32_setup_rt_frame(int sig, struct
6892158b
MT
6430
6431 if (ka->sa.sa_flags & SA_RESTORER)
6432 restorer = ka->sa.sa_restorer;
6433+ else if (current->mm->context.vdso)
6434+ /* Return stub is in 32bit vsyscall page */
6435+ restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6436 else
6437- restorer = VDSO32_SYMBOL(current->mm->context.vdso,
6438- rt_sigreturn);
6439+ restorer = &frame->retcode;
6440 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
6441
6442 /*
bc901d79
MT
6443 * Not actually used anymore, but left because some gdb
6444 * versions need it.
6445 */
6446- put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
6447+ put_user_ex(*((const u64 *)&code), (u64 *)frame->retcode);
6448 } put_user_catch(err);
6449
6450 if (err)
16454cff
MT
6451diff -urNp linux-2.6.38.1/arch/x86/include/asm/alternative.h linux-2.6.38.1/arch/x86/include/asm/alternative.h
6452--- linux-2.6.38.1/arch/x86/include/asm/alternative.h 2011-03-14 21:20:32.000000000 -0400
6453+++ linux-2.6.38.1/arch/x86/include/asm/alternative.h 2011-03-21 18:31:35.000000000 -0400
6454@@ -94,7 +94,7 @@ static inline int alternatives_text_rese
6892158b 6455 ".section .discard,\"aw\",@progbits\n" \
ae4e228f 6456 " .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */ \
58c5fc13
MT
6457 ".previous\n" \
6458- ".section .altinstr_replacement, \"ax\"\n" \
6459+ ".section .altinstr_replacement, \"a\"\n" \
6460 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
6461 ".previous"
6462
16454cff
MT
6463diff -urNp linux-2.6.38.1/arch/x86/include/asm/apm.h linux-2.6.38.1/arch/x86/include/asm/apm.h
6464--- linux-2.6.38.1/arch/x86/include/asm/apm.h 2011-03-14 21:20:32.000000000 -0400
6465+++ linux-2.6.38.1/arch/x86/include/asm/apm.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
6466@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
6467 __asm__ __volatile__(APM_DO_ZERO_SEGS
6468 "pushl %%edi\n\t"
6469 "pushl %%ebp\n\t"
6470- "lcall *%%cs:apm_bios_entry\n\t"
6471+ "lcall *%%ss:apm_bios_entry\n\t"
6472 "setc %%al\n\t"
6473 "popl %%ebp\n\t"
6474 "popl %%edi\n\t"
6475@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
6476 __asm__ __volatile__(APM_DO_ZERO_SEGS
6477 "pushl %%edi\n\t"
6478 "pushl %%ebp\n\t"
6479- "lcall *%%cs:apm_bios_entry\n\t"
6480+ "lcall *%%ss:apm_bios_entry\n\t"
6481 "setc %%bl\n\t"
6482 "popl %%ebp\n\t"
6483 "popl %%edi\n\t"
16454cff
MT
6484diff -urNp linux-2.6.38.1/arch/x86/include/asm/atomic64_32.h linux-2.6.38.1/arch/x86/include/asm/atomic64_32.h
6485--- linux-2.6.38.1/arch/x86/include/asm/atomic64_32.h 2011-03-14 21:20:32.000000000 -0400
6486+++ linux-2.6.38.1/arch/x86/include/asm/atomic64_32.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c 6487@@ -12,6 +12,14 @@ typedef struct {
ae4e228f
MT
6488 u64 __aligned(8) counter;
6489 } atomic64_t;
6490
6491+#ifdef CONFIG_PAX_REFCOUNT
6492+typedef struct {
6493+ u64 __aligned(8) counter;
6494+} atomic64_unchecked_t;
6495+#else
6496+typedef atomic64_t atomic64_unchecked_t;
6497+#endif
6498+
6499 #define ATOMIC64_INIT(val) { (val) }
6500
57199397 6501 #ifdef CONFIG_X86_CMPXCHG64
16454cff
MT
6502diff -urNp linux-2.6.38.1/arch/x86/include/asm/atomic64_64.h linux-2.6.38.1/arch/x86/include/asm/atomic64_64.h
6503--- linux-2.6.38.1/arch/x86/include/asm/atomic64_64.h 2011-03-14 21:20:32.000000000 -0400
6504+++ linux-2.6.38.1/arch/x86/include/asm/atomic64_64.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
6505@@ -18,7 +18,19 @@
6506 */
6507 static inline long atomic64_read(const atomic64_t *v)
6508 {
6509- return (*(volatile long *)&(v)->counter);
6510+ return (*(volatile const long *)&(v)->counter);
6511+}
6512+
6513+/**
ae4e228f
MT
6514+ * atomic64_read_unchecked - read atomic64 variable
6515+ * @v: pointer of type atomic64_unchecked_t
6516+ *
6517+ * Atomically reads the value of @v.
6518+ * Doesn't imply a read memory barrier.
6519+ */
6520+static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
6521+{
bc901d79
MT
6522+ return (*(volatile const long *)&(v)->counter);
6523 }
6524
6525 /**
df50ba0c 6526@@ -34,6 +46,18 @@ static inline void atomic64_set(atomic64
ae4e228f
MT
6527 }
6528
6529 /**
6530+ * atomic64_set_unchecked - set atomic64 variable
6531+ * @v: pointer to type atomic64_unchecked_t
6532+ * @i: required value
6533+ *
6534+ * Atomically sets the value of @v to @i.
6535+ */
6536+static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
6537+{
6538+ v->counter = i;
6539+}
6540+
6541+/**
6542 * atomic64_add - add integer to atomic64 variable
6543 * @i: integer value to add
6544 * @v: pointer to type atomic64_t
df50ba0c 6545@@ -42,6 +66,28 @@ static inline void atomic64_set(atomic64
58c5fc13
MT
6546 */
6547 static inline void atomic64_add(long i, atomic64_t *v)
6548 {
58c5fc13
MT
6549+ asm volatile(LOCK_PREFIX "addq %1,%0\n"
6550+
6551+#ifdef CONFIG_PAX_REFCOUNT
6552+ "jno 0f\n"
6553+ LOCK_PREFIX "subq %1,%0\n"
6554+ "int $4\n0:\n"
6555+ _ASM_EXTABLE(0b, 0b)
6556+#endif
6557+
ae4e228f
MT
6558+ : "=m" (v->counter)
6559+ : "er" (i), "m" (v->counter));
6560+}
6561+
6562+/**
6563+ * atomic64_add_unchecked - add integer to atomic64 variable
6564+ * @i: integer value to add
6565+ * @v: pointer to type atomic64_unchecked_t
6566+ *
6567+ * Atomically adds @i to @v.
6568+ */
6569+static inline void atomic64_add_unchecked(long i, atomic64_unchecked_t *v)
6570+{
6571 asm volatile(LOCK_PREFIX "addq %1,%0"
58c5fc13
MT
6572 : "=m" (v->counter)
6573 : "er" (i), "m" (v->counter));
6892158b 6574@@ -56,7 +102,29 @@ static inline void atomic64_add(long i,
58c5fc13
MT
6575 */
6576 static inline void atomic64_sub(long i, atomic64_t *v)
6577 {
6578- asm volatile(LOCK_PREFIX "subq %1,%0"
6579+ asm volatile(LOCK_PREFIX "subq %1,%0\n"
6580+
6581+#ifdef CONFIG_PAX_REFCOUNT
6582+ "jno 0f\n"
6583+ LOCK_PREFIX "addq %1,%0\n"
6584+ "int $4\n0:\n"
6585+ _ASM_EXTABLE(0b, 0b)
6586+#endif
6587+
6892158b
MT
6588+ : "=m" (v->counter)
6589+ : "er" (i), "m" (v->counter));
6590+}
6591+
6592+/**
6593+ * atomic64_sub_unchecked - subtract the atomic64 variable
6594+ * @i: integer value to subtract
6595+ * @v: pointer to type atomic64_unchecked_t
6596+ *
6597+ * Atomically subtracts @i from @v.
6598+ */
6599+static inline void atomic64_sub_unchecked(long i, atomic64_unchecked_t *v)
6600+{
6601+ asm volatile(LOCK_PREFIX "subq %1,%0\n"
58c5fc13
MT
6602 : "=m" (v->counter)
6603 : "er" (i), "m" (v->counter));
6604 }
6892158b 6605@@ -74,7 +142,16 @@ static inline int atomic64_sub_and_test(
58c5fc13
MT
6606 {
6607 unsigned char c;
6608
6609- asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
6610+ asm volatile(LOCK_PREFIX "subq %2,%0\n"
6611+
6612+#ifdef CONFIG_PAX_REFCOUNT
6613+ "jno 0f\n"
6614+ LOCK_PREFIX "addq %2,%0\n"
6615+ "int $4\n0:\n"
6616+ _ASM_EXTABLE(0b, 0b)
6617+#endif
6618+
6619+ "sete %1\n"
6620 : "=m" (v->counter), "=qm" (c)
6621 : "er" (i), "m" (v->counter) : "memory");
6622 return c;
6892158b 6623@@ -88,6 +165,27 @@ static inline int atomic64_sub_and_test(
58c5fc13
MT
6624 */
6625 static inline void atomic64_inc(atomic64_t *v)
6626 {
58c5fc13
MT
6627+ asm volatile(LOCK_PREFIX "incq %0\n"
6628+
6629+#ifdef CONFIG_PAX_REFCOUNT
6630+ "jno 0f\n"
58c5fc13 6631+ LOCK_PREFIX "decq %0\n"
6892158b
MT
6632+ "int $4\n0:\n"
6633+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
6634+#endif
6635+
ae4e228f
MT
6636+ : "=m" (v->counter)
6637+ : "m" (v->counter));
6638+}
6639+
6640+/**
6641+ * atomic64_inc_unchecked - increment atomic64 variable
6642+ * @v: pointer to type atomic64_unchecked_t
6643+ *
6644+ * Atomically increments @v by 1.
6645+ */
6646+static inline void atomic64_inc_unchecked(atomic64_unchecked_t *v)
6647+{
6648 asm volatile(LOCK_PREFIX "incq %0"
58c5fc13
MT
6649 : "=m" (v->counter)
6650 : "m" (v->counter));
6892158b 6651@@ -101,7 +199,28 @@ static inline void atomic64_inc(atomic64
58c5fc13
MT
6652 */
6653 static inline void atomic64_dec(atomic64_t *v)
6654 {
6655- asm volatile(LOCK_PREFIX "decq %0"
6656+ asm volatile(LOCK_PREFIX "decq %0\n"
6657+
6658+#ifdef CONFIG_PAX_REFCOUNT
6659+ "jno 0f\n"
58c5fc13 6660+ LOCK_PREFIX "incq %0\n"
6892158b
MT
6661+ "int $4\n0:\n"
6662+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
6663+#endif
6664+
df50ba0c
MT
6665+ : "=m" (v->counter)
6666+ : "m" (v->counter));
6667+}
6668+
6669+/**
6670+ * atomic64_dec_unchecked - decrement atomic64 variable
6671+ * @v: pointer to type atomic64_t
6672+ *
6673+ * Atomically decrements @v by 1.
6674+ */
6675+static inline void atomic64_dec_unchecked(atomic64_unchecked_t *v)
6676+{
6677+ asm volatile(LOCK_PREFIX "decq %0\n"
58c5fc13
MT
6678 : "=m" (v->counter)
6679 : "m" (v->counter));
6680 }
6892158b 6681@@ -118,7 +237,16 @@ static inline int atomic64_dec_and_test(
58c5fc13
MT
6682 {
6683 unsigned char c;
6684
6685- asm volatile(LOCK_PREFIX "decq %0; sete %1"
6686+ asm volatile(LOCK_PREFIX "decq %0\n"
6687+
6688+#ifdef CONFIG_PAX_REFCOUNT
6689+ "jno 0f\n"
58c5fc13 6690+ LOCK_PREFIX "incq %0\n"
6892158b
MT
6691+ "int $4\n0:\n"
6692+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
6693+#endif
6694+
6695+ "sete %1\n"
6696 : "=m" (v->counter), "=qm" (c)
6697 : "m" (v->counter) : "memory");
6698 return c != 0;
6892158b 6699@@ -136,7 +264,16 @@ static inline int atomic64_inc_and_test(
58c5fc13
MT
6700 {
6701 unsigned char c;
6702
6703- asm volatile(LOCK_PREFIX "incq %0; sete %1"
6704+ asm volatile(LOCK_PREFIX "incq %0\n"
6705+
6706+#ifdef CONFIG_PAX_REFCOUNT
6707+ "jno 0f\n"
58c5fc13 6708+ LOCK_PREFIX "decq %0\n"
6892158b
MT
6709+ "int $4\n0:\n"
6710+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
6711+#endif
6712+
6713+ "sete %1\n"
6714 : "=m" (v->counter), "=qm" (c)
6715 : "m" (v->counter) : "memory");
6716 return c != 0;
6892158b 6717@@ -155,7 +292,16 @@ static inline int atomic64_add_negative(
58c5fc13
MT
6718 {
6719 unsigned char c;
6720
6721- asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
6722+ asm volatile(LOCK_PREFIX "addq %2,%0\n"
6723+
6724+#ifdef CONFIG_PAX_REFCOUNT
6725+ "jno 0f\n"
6726+ LOCK_PREFIX "subq %2,%0\n"
6727+ "int $4\n0:\n"
6728+ _ASM_EXTABLE(0b, 0b)
6729+#endif
6730+
6731+ "sets %1\n"
6732 : "=m" (v->counter), "=qm" (c)
6733 : "er" (i), "m" (v->counter) : "memory");
6734 return c;
6892158b 6735@@ -171,7 +317,31 @@ static inline int atomic64_add_negative(
58c5fc13
MT
6736 static inline long atomic64_add_return(long i, atomic64_t *v)
6737 {
6738 long __i = i;
6739- asm volatile(LOCK_PREFIX "xaddq %0, %1;"
6740+ asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
6741+
6742+#ifdef CONFIG_PAX_REFCOUNT
6743+ "jno 0f\n"
6744+ "movq %0, %1\n"
6745+ "int $4\n0:\n"
6746+ _ASM_EXTABLE(0b, 0b)
6747+#endif
6748+
ae4e228f
MT
6749+ : "+r" (i), "+m" (v->counter)
6750+ : : "memory");
6751+ return i + __i;
6752+}
6753+
6754+/**
6755+ * atomic64_add_return_unchecked - add and return
6756+ * @i: integer value to add
6757+ * @v: pointer to type atomic64_unchecked_t
6758+ *
6759+ * Atomically adds @i to @v and returns @i + @v
6760+ */
6761+static inline long atomic64_add_return_unchecked(long i, atomic64_unchecked_t *v)
6762+{
6763+ long __i = i;
6764+ asm volatile(LOCK_PREFIX "xaddq %0, %1"
58c5fc13
MT
6765 : "+r" (i), "+m" (v->counter)
6766 : : "memory");
6767 return i + __i;
6892158b 6768@@ -183,6 +353,10 @@ static inline long atomic64_sub_return(l
ae4e228f
MT
6769 }
6770
6771 #define atomic64_inc_return(v) (atomic64_add_return(1, (v)))
57199397
MT
6772+static inline long atomic64_inc_return_unchecked(atomic64_unchecked_t *v)
6773+{
6774+ return atomic64_add_return_unchecked(1, v);
6775+}
ae4e228f
MT
6776 #define atomic64_dec_return(v) (atomic64_sub_return(1, (v)))
6777
6778 static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
6892158b 6779@@ -206,17 +380,30 @@ static inline long atomic64_xchg(atomic6
58c5fc13 6780 */
df50ba0c 6781 static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
58c5fc13 6782 {
df50ba0c
MT
6783- long c, old;
6784+ long c, old, new;
6785 c = atomic64_read(v);
58c5fc13
MT
6786 for (;;) {
6787- if (unlikely(c == (u)))
6788+ if (unlikely(c == u))
6789 break;
df50ba0c 6790- old = atomic64_cmpxchg((v), c, c + (a));
58c5fc13 6791+
df50ba0c 6792+ asm volatile("add %2,%0\n"
58c5fc13
MT
6793+
6794+#ifdef CONFIG_PAX_REFCOUNT
6795+ "jno 0f\n"
6892158b 6796+ "sub %2,%0\n"
58c5fc13
MT
6797+ "int $4\n0:\n"
6798+ _ASM_EXTABLE(0b, 0b)
6799+#endif
6800+
6801+ : "=r" (new)
6802+ : "0" (c), "ir" (a));
6803+
df50ba0c 6804+ old = atomic64_cmpxchg(v, c, new);
58c5fc13
MT
6805 if (likely(old == c))
6806 break;
6807 c = old;
6808 }
6809- return c != (u);
6810+ return c != u;
6811 }
6812
df50ba0c 6813 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
16454cff
MT
6814diff -urNp linux-2.6.38.1/arch/x86/include/asm/atomic.h linux-2.6.38.1/arch/x86/include/asm/atomic.h
6815--- linux-2.6.38.1/arch/x86/include/asm/atomic.h 2011-03-14 21:20:32.000000000 -0400
6816+++ linux-2.6.38.1/arch/x86/include/asm/atomic.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
6817@@ -22,7 +22,18 @@
6818 */
6819 static inline int atomic_read(const atomic_t *v)
6820 {
6821- return (*(volatile int *)&(v)->counter);
6822+ return (*(volatile const int *)&(v)->counter);
6823+}
6824+
6825+/**
57199397
MT
6826+ * atomic_read_unchecked - read atomic variable
6827+ * @v: pointer of type atomic_unchecked_t
6828+ *
6829+ * Atomically reads the value of @v.
6830+ */
6831+static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
6832+{
bc901d79
MT
6833+ return (*(volatile const int *)&(v)->counter);
6834 }
6835
6836 /**
57199397
MT
6837@@ -38,6 +49,18 @@ static inline void atomic_set(atomic_t *
6838 }
6839
6840 /**
6841+ * atomic_set_unchecked - set atomic variable
6842+ * @v: pointer of type atomic_unchecked_t
6843+ * @i: required value
6844+ *
6845+ * Atomically sets the value of @v to @i.
6846+ */
6847+static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
6848+{
6849+ v->counter = i;
6850+}
6851+
6852+/**
6853 * atomic_add - add integer to atomic variable
6854 * @i: integer value to add
6855 * @v: pointer of type atomic_t
6856@@ -46,7 +69,29 @@ static inline void atomic_set(atomic_t *
6857 */
6858 static inline void atomic_add(int i, atomic_t *v)
6859 {
6860- asm volatile(LOCK_PREFIX "addl %1,%0"
6861+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
6862+
6863+#ifdef CONFIG_PAX_REFCOUNT
6864+ "jno 0f\n"
6865+ LOCK_PREFIX "subl %1,%0\n"
bc901d79 6866+ "int $4\n0:\n"
57199397
MT
6867+ _ASM_EXTABLE(0b, 0b)
6868+#endif
6869+
6870+ : "+m" (v->counter)
6871+ : "ir" (i));
6872+}
6873+
6874+/**
6875+ * atomic_add_unchecked - add integer to atomic variable
6876+ * @i: integer value to add
6877+ * @v: pointer of type atomic_unchecked_t
6878+ *
6879+ * Atomically adds @i to @v.
6880+ */
6881+static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
6882+{
6883+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
6884 : "+m" (v->counter)
6885 : "ir" (i));
6886 }
6887@@ -60,7 +105,29 @@ static inline void atomic_add(int i, ato
6888 */
6889 static inline void atomic_sub(int i, atomic_t *v)
6890 {
6891- asm volatile(LOCK_PREFIX "subl %1,%0"
6892+ asm volatile(LOCK_PREFIX "subl %1,%0\n"
6893+
6894+#ifdef CONFIG_PAX_REFCOUNT
6895+ "jno 0f\n"
6896+ LOCK_PREFIX "addl %1,%0\n"
bc901d79 6897+ "int $4\n0:\n"
57199397
MT
6898+ _ASM_EXTABLE(0b, 0b)
6899+#endif
6900+
6901+ : "+m" (v->counter)
6902+ : "ir" (i));
6903+}
6904+
6905+/**
6906+ * atomic_sub_unchecked - subtract integer from atomic variable
6907+ * @i: integer value to subtract
6908+ * @v: pointer of type atomic_t
6909+ *
6910+ * Atomically subtracts @i from @v.
6911+ */
6912+static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
6913+{
6914+ asm volatile(LOCK_PREFIX "subl %1,%0\n"
6915 : "+m" (v->counter)
6916 : "ir" (i));
6917 }
6918@@ -78,7 +145,16 @@ static inline int atomic_sub_and_test(in
6919 {
6920 unsigned char c;
6921
6922- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
6923+ asm volatile(LOCK_PREFIX "subl %2,%0\n"
6924+
6925+#ifdef CONFIG_PAX_REFCOUNT
6926+ "jno 0f\n"
6927+ LOCK_PREFIX "addl %2,%0\n"
bc901d79 6928+ "int $4\n0:\n"
57199397
MT
6929+ _ASM_EXTABLE(0b, 0b)
6930+#endif
6931+
6932+ "sete %1\n"
6933 : "+m" (v->counter), "=qm" (c)
6934 : "ir" (i) : "memory");
6935 return c;
6936@@ -92,7 +168,27 @@ static inline int atomic_sub_and_test(in
6937 */
6938 static inline void atomic_inc(atomic_t *v)
6939 {
6940- asm volatile(LOCK_PREFIX "incl %0"
6941+ asm volatile(LOCK_PREFIX "incl %0\n"
6942+
6943+#ifdef CONFIG_PAX_REFCOUNT
6944+ "jno 0f\n"
6945+ LOCK_PREFIX "decl %0\n"
bc901d79 6946+ "int $4\n0:\n"
57199397
MT
6947+ _ASM_EXTABLE(0b, 0b)
6948+#endif
6949+
6950+ : "+m" (v->counter));
6951+}
6952+
6953+/**
6954+ * atomic_inc_unchecked - increment atomic variable
6955+ * @v: pointer of type atomic_unchecked_t
6956+ *
6957+ * Atomically increments @v by 1.
6958+ */
6959+static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
6960+{
6961+ asm volatile(LOCK_PREFIX "incl %0\n"
6962 : "+m" (v->counter));
6963 }
6964
6965@@ -104,7 +200,27 @@ static inline void atomic_inc(atomic_t *
6966 */
6967 static inline void atomic_dec(atomic_t *v)
6968 {
6969- asm volatile(LOCK_PREFIX "decl %0"
6970+ asm volatile(LOCK_PREFIX "decl %0\n"
6971+
6972+#ifdef CONFIG_PAX_REFCOUNT
6973+ "jno 0f\n"
6974+ LOCK_PREFIX "incl %0\n"
bc901d79 6975+ "int $4\n0:\n"
57199397
MT
6976+ _ASM_EXTABLE(0b, 0b)
6977+#endif
6978+
6979+ : "+m" (v->counter));
6980+}
6981+
6982+/**
6983+ * atomic_dec_unchecked - decrement atomic variable
6984+ * @v: pointer of type atomic_t
6985+ *
6986+ * Atomically decrements @v by 1.
6987+ */
6988+static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
6989+{
6990+ asm volatile(LOCK_PREFIX "decl %0\n"
6991 : "+m" (v->counter));
6992 }
6993
6994@@ -120,7 +236,16 @@ static inline int atomic_dec_and_test(at
6995 {
6996 unsigned char c;
6997
6998- asm volatile(LOCK_PREFIX "decl %0; sete %1"
6999+ asm volatile(LOCK_PREFIX "decl %0\n"
7000+
7001+#ifdef CONFIG_PAX_REFCOUNT
7002+ "jno 0f\n"
7003+ LOCK_PREFIX "incl %0\n"
bc901d79 7004+ "int $4\n0:\n"
57199397
MT
7005+ _ASM_EXTABLE(0b, 0b)
7006+#endif
7007+
7008+ "sete %1\n"
7009 : "+m" (v->counter), "=qm" (c)
7010 : : "memory");
7011 return c != 0;
7012@@ -138,7 +263,16 @@ static inline int atomic_inc_and_test(at
7013 {
7014 unsigned char c;
7015
7016- asm volatile(LOCK_PREFIX "incl %0; sete %1"
7017+ asm volatile(LOCK_PREFIX "incl %0\n"
7018+
7019+#ifdef CONFIG_PAX_REFCOUNT
7020+ "jno 0f\n"
7021+ LOCK_PREFIX "decl %0\n"
bc901d79 7022+ "int $4\n0:\n"
57199397
MT
7023+ _ASM_EXTABLE(0b, 0b)
7024+#endif
7025+
7026+ "sete %1\n"
7027 : "+m" (v->counter), "=qm" (c)
7028 : : "memory");
7029 return c != 0;
7030@@ -157,7 +291,16 @@ static inline int atomic_add_negative(in
7031 {
7032 unsigned char c;
7033
7034- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
7035+ asm volatile(LOCK_PREFIX "addl %2,%0\n"
7036+
7037+#ifdef CONFIG_PAX_REFCOUNT
7038+ "jno 0f\n"
7039+ LOCK_PREFIX "subl %2,%0\n"
bc901d79 7040+ "int $4\n0:\n"
57199397
MT
7041+ _ASM_EXTABLE(0b, 0b)
7042+#endif
7043+
7044+ "sets %1\n"
7045 : "+m" (v->counter), "=qm" (c)
7046 : "ir" (i) : "memory");
7047 return c;
7048@@ -180,6 +323,46 @@ static inline int atomic_add_return(int
7049 #endif
7050 /* Modern 486+ processor */
7051 __i = i;
7052+ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
7053+
7054+#ifdef CONFIG_PAX_REFCOUNT
7055+ "jno 0f\n"
7056+ "movl %0, %1\n"
bc901d79 7057+ "int $4\n0:\n"
57199397
MT
7058+ _ASM_EXTABLE(0b, 0b)
7059+#endif
7060+
7061+ : "+r" (i), "+m" (v->counter)
7062+ : : "memory");
7063+ return i + __i;
7064+
7065+#ifdef CONFIG_M386
7066+no_xadd: /* Legacy 386 processor */
7067+ local_irq_save(flags);
7068+ __i = atomic_read(v);
7069+ atomic_set(v, i + __i);
7070+ local_irq_restore(flags);
7071+ return i + __i;
7072+#endif
7073+}
7074+
7075+/**
7076+ * atomic_add_return_unchecked - add integer and return
7077+ * @v: pointer of type atomic_unchecked_t
7078+ * @i: integer value to add
7079+ *
7080+ * Atomically adds @i to @v and returns @i + @v
7081+ */
7082+static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
7083+{
7084+ int __i;
7085+#ifdef CONFIG_M386
7086+ unsigned long flags;
7087+ if (unlikely(boot_cpu_data.x86 <= 3))
7088+ goto no_xadd;
7089+#endif
7090+ /* Modern 486+ processor */
7091+ __i = i;
7092 asm volatile(LOCK_PREFIX "xaddl %0, %1"
7093 : "+r" (i), "+m" (v->counter)
7094 : : "memory");
7095@@ -208,6 +391,10 @@ static inline int atomic_sub_return(int
7096 }
7097
7098 #define atomic_inc_return(v) (atomic_add_return(1, v))
7099+static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
7100+{
7101+ return atomic_add_return_unchecked(1, v);
7102+}
7103 #define atomic_dec_return(v) (atomic_sub_return(1, v))
7104
7105 static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
317566c1 7106@@ -231,21 +418,77 @@ static inline int atomic_xchg(atomic_t *
57199397
MT
7107 */
7108 static inline int atomic_add_unless(atomic_t *v, int a, int u)
7109 {
7110- int c, old;
7111+ int c, old, new;
7112 c = atomic_read(v);
7113 for (;;) {
7114- if (unlikely(c == (u)))
7115+ if (unlikely(c == u))
7116 break;
7117- old = atomic_cmpxchg((v), c, c + (a));
7118+
7119+ asm volatile("addl %2,%0\n"
7120+
7121+#ifdef CONFIG_PAX_REFCOUNT
7122+ "jno 0f\n"
6892158b 7123+ "subl %2,%0\n"
bc901d79 7124+ "int $4\n0:\n"
57199397
MT
7125+ _ASM_EXTABLE(0b, 0b)
7126+#endif
7127+
7128+ : "=r" (new)
7129+ : "0" (c), "ir" (a));
7130+
7131+ old = atomic_cmpxchg(v, c, new);
7132 if (likely(old == c))
7133 break;
7134 c = old;
7135 }
7136- return c != (u);
7137+ return c != u;
7138 }
7139
7140 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
317566c1
MT
7141
7142+/**
7143+ * atomic_inc_not_zero_hint - increment if not null
7144+ * @v: pointer of type atomic_t
7145+ * @hint: probable value of the atomic before the increment
7146+ *
7147+ * This version of atomic_inc_not_zero() gives a hint of probable
7148+ * value of the atomic. This helps processor to not read the memory
7149+ * before doing the atomic read/modify/write cycle, lowering
7150+ * number of bus transactions on some arches.
7151+ *
7152+ * Returns: 0 if increment was not done, 1 otherwise.
7153+ */
7154+#define atomic_inc_not_zero_hint atomic_inc_not_zero_hint
7155+static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint)
7156+{
7157+ int val, c = hint, new;
7158+
7159+ /* sanity test, should be removed by compiler if hint is a constant */
7160+ if (!hint)
7161+ return atomic_inc_not_zero(v);
7162+
7163+ do {
7164+ asm volatile("incl %0\n"
7165+
7166+#ifdef CONFIG_PAX_REFCOUNT
7167+ "jno 0f\n"
7168+ "decl %0\n"
7169+ "int $4\n0:\n"
7170+ _ASM_EXTABLE(0b, 0b)
7171+#endif
7172+
7173+ : "=r" (new)
7174+ : "0" (c));
7175+
7176+ val = atomic_cmpxchg(v, c, new);
7177+ if (val == c)
7178+ return 1;
7179+ c = val;
7180+ } while (c);
7181+
7182+ return 0;
7183+}
7184+
7185 /*
7186 * atomic_dec_if_positive - decrement by 1 if old value positive
7187 * @v: pointer of type atomic_t
16454cff
MT
7188diff -urNp linux-2.6.38.1/arch/x86/include/asm/bitops.h linux-2.6.38.1/arch/x86/include/asm/bitops.h
7189--- linux-2.6.38.1/arch/x86/include/asm/bitops.h 2011-03-14 21:20:32.000000000 -0400
7190+++ linux-2.6.38.1/arch/x86/include/asm/bitops.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
7191@@ -38,7 +38,7 @@
7192 * a mask operation on a byte.
7193 */
7194 #define IS_IMMEDIATE(nr) (__builtin_constant_p(nr))
7195-#define CONST_MASK_ADDR(nr, addr) BITOP_ADDR((void *)(addr) + ((nr)>>3))
7196+#define CONST_MASK_ADDR(nr, addr) BITOP_ADDR((volatile void *)(addr) + ((nr)>>3))
7197 #define CONST_MASK(nr) (1 << ((nr) & 7))
7198
7199 /**
16454cff
MT
7200diff -urNp linux-2.6.38.1/arch/x86/include/asm/boot.h linux-2.6.38.1/arch/x86/include/asm/boot.h
7201--- linux-2.6.38.1/arch/x86/include/asm/boot.h 2011-03-14 21:20:32.000000000 -0400
7202+++ linux-2.6.38.1/arch/x86/include/asm/boot.h 2011-03-21 18:31:35.000000000 -0400
efbe55a5
MT
7203@@ -11,10 +11,15 @@
7204 #include <asm/pgtable_types.h>
df50ba0c 7205
efbe55a5
MT
7206 /* Physical address where kernel should be loaded. */
7207-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
7208+#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
7209 + (CONFIG_PHYSICAL_ALIGN - 1)) \
7210 & ~(CONFIG_PHYSICAL_ALIGN - 1))
df50ba0c 7211
efbe55a5
MT
7212+#ifndef __ASSEMBLY__
7213+extern unsigned char __LOAD_PHYSICAL_ADDR[];
7214+#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
df50ba0c
MT
7215+#endif
7216+
efbe55a5
MT
7217 /* Minimum kernel alignment, as a power of two */
7218 #ifdef CONFIG_X86_64
7219 #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT
16454cff
MT
7220diff -urNp linux-2.6.38.1/arch/x86/include/asm/cacheflush.h linux-2.6.38.1/arch/x86/include/asm/cacheflush.h
7221--- linux-2.6.38.1/arch/x86/include/asm/cacheflush.h 2011-03-14 21:20:32.000000000 -0400
7222+++ linux-2.6.38.1/arch/x86/include/asm/cacheflush.h 2011-03-21 18:31:35.000000000 -0400
7223@@ -26,7 +26,7 @@ static inline unsigned long get_page_mem
57199397
MT
7224 unsigned long pg_flags = pg->flags & _PGMT_MASK;
7225
7226 if (pg_flags == _PGMT_DEFAULT)
7227- return -1;
7228+ return ~0UL;
7229 else if (pg_flags == _PGMT_WC)
7230 return _PAGE_CACHE_WC;
7231 else if (pg_flags == _PGMT_UC_MINUS)
16454cff
MT
7232diff -urNp linux-2.6.38.1/arch/x86/include/asm/cache.h linux-2.6.38.1/arch/x86/include/asm/cache.h
7233--- linux-2.6.38.1/arch/x86/include/asm/cache.h 2011-03-14 21:20:32.000000000 -0400
7234+++ linux-2.6.38.1/arch/x86/include/asm/cache.h 2011-03-21 18:31:35.000000000 -0400
efbe55a5
MT
7235@@ -8,6 +8,7 @@
7236 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
7237
57199397
MT
7238 #define __read_mostly __attribute__((__section__(".data..read_mostly")))
7239+#define __read_only __attribute__((__section__(".data..read_only")))
efbe55a5
MT
7240
7241 #define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT
7242 #define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
16454cff
MT
7243diff -urNp linux-2.6.38.1/arch/x86/include/asm/checksum_32.h linux-2.6.38.1/arch/x86/include/asm/checksum_32.h
7244--- linux-2.6.38.1/arch/x86/include/asm/checksum_32.h 2011-03-14 21:20:32.000000000 -0400
7245+++ linux-2.6.38.1/arch/x86/include/asm/checksum_32.h 2011-03-21 18:31:35.000000000 -0400
efbe55a5
MT
7246@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
7247 int len, __wsum sum,
7248 int *src_err_ptr, int *dst_err_ptr);
df50ba0c 7249
efbe55a5
MT
7250+asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
7251+ int len, __wsum sum,
7252+ int *src_err_ptr, int *dst_err_ptr);
df50ba0c 7253+
efbe55a5
MT
7254+asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
7255+ int len, __wsum sum,
7256+ int *src_err_ptr, int *dst_err_ptr);
df50ba0c 7257+
efbe55a5
MT
7258 /*
7259 * Note: when you get a NULL pointer exception here this means someone
7260 * passed in an incorrect kernel address to one of these functions.
7261@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
7262 int *err_ptr)
df50ba0c 7263 {
efbe55a5
MT
7264 might_sleep();
7265- return csum_partial_copy_generic((__force void *)src, dst,
7266+ return csum_partial_copy_generic_from_user((__force void *)src, dst,
7267 len, sum, err_ptr, NULL);
58c5fc13
MT
7268 }
7269
ae4e228f 7270@@ -178,7 +186,7 @@ static inline __wsum csum_and_copy_to_us
58c5fc13
MT
7271 {
7272 might_sleep();
7273 if (access_ok(VERIFY_WRITE, dst, len))
7274- return csum_partial_copy_generic(src, (__force void *)dst,
7275+ return csum_partial_copy_generic_to_user(src, (__force void *)dst,
7276 len, sum, NULL, err_ptr);
7277
7278 if (len)
16454cff
MT
7279diff -urNp linux-2.6.38.1/arch/x86/include/asm/cpufeature.h linux-2.6.38.1/arch/x86/include/asm/cpufeature.h
7280--- linux-2.6.38.1/arch/x86/include/asm/cpufeature.h 2011-03-14 21:20:32.000000000 -0400
7281+++ linux-2.6.38.1/arch/x86/include/asm/cpufeature.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 7282@@ -349,7 +349,7 @@ static __always_inline __pure bool __sta
6892158b
MT
7283 ".section .discard,\"aw\",@progbits\n"
7284 " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
57199397
MT
7285 ".previous\n"
7286- ".section .altinstr_replacement,\"ax\"\n"
7287+ ".section .altinstr_replacement,\"a\"\n"
7288 "3: movb $1,%0\n"
7289 "4:\n"
7290 ".previous\n"
16454cff
MT
7291diff -urNp linux-2.6.38.1/arch/x86/include/asm/desc_defs.h linux-2.6.38.1/arch/x86/include/asm/desc_defs.h
7292--- linux-2.6.38.1/arch/x86/include/asm/desc_defs.h 2011-03-14 21:20:32.000000000 -0400
7293+++ linux-2.6.38.1/arch/x86/include/asm/desc_defs.h 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
7294@@ -31,6 +31,12 @@ struct desc_struct {
7295 unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
7296 unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
7297 };
7298+ struct {
7299+ u16 offset_low;
7300+ u16 seg;
7301+ unsigned reserved: 8, type: 4, s: 1, dpl: 2, p: 1;
7302+ unsigned offset_high: 16;
16454cff 7303+ } gate;
317566c1
MT
7304 };
7305 } __attribute__((packed));
7306
16454cff
MT
7307diff -urNp linux-2.6.38.1/arch/x86/include/asm/desc.h linux-2.6.38.1/arch/x86/include/asm/desc.h
7308--- linux-2.6.38.1/arch/x86/include/asm/desc.h 2011-03-14 21:20:32.000000000 -0400
7309+++ linux-2.6.38.1/arch/x86/include/asm/desc.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
7310@@ -4,6 +4,7 @@
7311 #include <asm/desc_defs.h>
7312 #include <asm/ldt.h>
7313 #include <asm/mmu.h>
7314+#include <asm/pgtable.h>
7315 #include <linux/smp.h>
7316
7317 static inline void fill_ldt(struct desc_struct *desc,
7318@@ -15,6 +16,7 @@ static inline void fill_ldt(struct desc_
58c5fc13
MT
7319 desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
7320 desc->type = (info->read_exec_only ^ 1) << 1;
7321 desc->type |= info->contents << 2;
7322+ desc->type |= info->seg_not_present ^ 1;
7323 desc->s = 1;
7324 desc->dpl = 0x3;
7325 desc->p = info->seg_not_present ^ 1;
ae4e228f 7326@@ -31,16 +33,12 @@ static inline void fill_ldt(struct desc_
58c5fc13
MT
7327 }
7328
7329 extern struct desc_ptr idt_descr;
7330-extern gate_desc idt_table[];
7331-
7332-struct gdt_page {
7333- struct desc_struct gdt[GDT_ENTRIES];
7334-} __attribute__((aligned(PAGE_SIZE)));
7335-DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
7336+extern gate_desc idt_table[256];
7337
7338+extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
7339 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
7340 {
7341- return per_cpu(gdt_page, cpu).gdt;
7342+ return cpu_gdt_table[cpu];
7343 }
7344
7345 #ifdef CONFIG_X86_64
317566c1
MT
7346@@ -65,9 +63,14 @@ static inline void pack_gate(gate_desc *
7347 unsigned long base, unsigned dpl, unsigned flags,
7348 unsigned short seg)
7349 {
7350- gate->a = (seg << 16) | (base & 0xffff);
7351- gate->b = (base & 0xffff0000) |
7352- (((0x80 | type | (dpl << 5)) & 0xff) << 8);
16454cff
MT
7353+ gate->gate.offset_low = base;
7354+ gate->gate.seg = seg;
7355+ gate->gate.reserved = 0;
7356+ gate->gate.type = type;
7357+ gate->gate.s = 0;
7358+ gate->gate.dpl = dpl;
7359+ gate->gate.p = 1;
7360+ gate->gate.offset_high = base >> 16;
317566c1
MT
7361 }
7362
7363 #endif
7364@@ -115,19 +118,24 @@ static inline void paravirt_free_ldt(str
58c5fc13
MT
7365 static inline void native_write_idt_entry(gate_desc *idt, int entry,
7366 const gate_desc *gate)
7367 {
ae4e228f 7368+ pax_open_kernel();
58c5fc13 7369 memcpy(&idt[entry], gate, sizeof(*gate));
ae4e228f 7370+ pax_close_kernel();
58c5fc13
MT
7371 }
7372
7373 static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
7374 const void *desc)
7375 {
ae4e228f 7376+ pax_open_kernel();
58c5fc13 7377 memcpy(&ldt[entry], desc, 8);
ae4e228f 7378+ pax_close_kernel();
58c5fc13
MT
7379 }
7380
7381 static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
7382 const void *desc, int type)
7383 {
7384 unsigned int size;
58c5fc13
MT
7385+
7386 switch (type) {
7387 case DESC_TSS:
7388 size = sizeof(tss_desc);
317566c1 7389@@ -139,7 +147,10 @@ static inline void native_write_gdt_entr
58c5fc13
MT
7390 size = sizeof(struct desc_struct);
7391 break;
7392 }
7393+
ae4e228f 7394+ pax_open_kernel();
58c5fc13 7395 memcpy(&gdt[entry], desc, size);
ae4e228f 7396+ pax_close_kernel();
58c5fc13
MT
7397 }
7398
7399 static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
317566c1 7400@@ -211,7 +222,9 @@ static inline void native_set_ldt(const
58c5fc13
MT
7401
7402 static inline void native_load_tr_desc(void)
7403 {
ae4e228f 7404+ pax_open_kernel();
58c5fc13 7405 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
ae4e228f 7406+ pax_close_kernel();
58c5fc13
MT
7407 }
7408
7409 static inline void native_load_gdt(const struct desc_ptr *dtr)
317566c1 7410@@ -246,8 +259,10 @@ static inline void native_load_tls(struc
58c5fc13
MT
7411 unsigned int i;
7412 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
7413
ae4e228f 7414+ pax_open_kernel();
58c5fc13
MT
7415 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
7416 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
ae4e228f 7417+ pax_close_kernel();
58c5fc13
MT
7418 }
7419
7420 #define _LDT_empty(info) \
317566c1 7421@@ -309,7 +324,7 @@ static inline void set_desc_limit(struct
df50ba0c
MT
7422 desc->limit = (limit >> 16) & 0xf;
7423 }
7424
7425-static inline void _set_gate(int gate, unsigned type, void *addr,
7426+static inline void _set_gate(int gate, unsigned type, const void *addr,
7427 unsigned dpl, unsigned ist, unsigned seg)
7428 {
7429 gate_desc s;
317566c1 7430@@ -327,7 +342,7 @@ static inline void _set_gate(int gate, u
df50ba0c
MT
7431 * Pentium F0 0F bugfix can have resulted in the mapped
7432 * IDT being write-protected.
7433 */
7434-static inline void set_intr_gate(unsigned int n, void *addr)
7435+static inline void set_intr_gate(unsigned int n, const void *addr)
7436 {
7437 BUG_ON((unsigned)n > 0xFF);
7438 _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
317566c1 7439@@ -356,19 +371,19 @@ static inline void alloc_intr_gate(unsig
df50ba0c
MT
7440 /*
7441 * This routine sets up an interrupt gate at directory privilege level 3.
7442 */
7443-static inline void set_system_intr_gate(unsigned int n, void *addr)
7444+static inline void set_system_intr_gate(unsigned int n, const void *addr)
7445 {
7446 BUG_ON((unsigned)n > 0xFF);
7447 _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
7448 }
7449
7450-static inline void set_system_trap_gate(unsigned int n, void *addr)
7451+static inline void set_system_trap_gate(unsigned int n, const void *addr)
7452 {
7453 BUG_ON((unsigned)n > 0xFF);
7454 _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS);
7455 }
7456
7457-static inline void set_trap_gate(unsigned int n, void *addr)
7458+static inline void set_trap_gate(unsigned int n, const void *addr)
7459 {
7460 BUG_ON((unsigned)n > 0xFF);
7461 _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS);
317566c1 7462@@ -377,19 +392,31 @@ static inline void set_trap_gate(unsigne
df50ba0c
MT
7463 static inline void set_task_gate(unsigned int n, unsigned int gdt_entry)
7464 {
7465 BUG_ON((unsigned)n > 0xFF);
7466- _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3));
7467+ _set_gate(n, GATE_TASK, (const void *)0, 0, 0, (gdt_entry<<3));
7468 }
7469
7470-static inline void set_intr_gate_ist(int n, void *addr, unsigned ist)
7471+static inline void set_intr_gate_ist(int n, const void *addr, unsigned ist)
7472 {
7473 BUG_ON((unsigned)n > 0xFF);
7474 _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS);
7475 }
7476
7477-static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist)
7478+static inline void set_system_intr_gate_ist(int n, const void *addr, unsigned ist)
7479 {
7480 BUG_ON((unsigned)n > 0xFF);
58c5fc13
MT
7481 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
7482 }
7483
7484+#ifdef CONFIG_X86_32
7485+static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
7486+{
7487+ struct desc_struct d;
7488+
7489+ if (likely(limit))
7490+ limit = (limit - 1UL) >> PAGE_SHIFT;
7491+ pack_descriptor(&d, base, limit, 0xFB, 0xC);
7492+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
7493+}
7494+#endif
7495+
7496 #endif /* _ASM_X86_DESC_H */
16454cff
MT
7497diff -urNp linux-2.6.38.1/arch/x86/include/asm/device.h linux-2.6.38.1/arch/x86/include/asm/device.h
7498--- linux-2.6.38.1/arch/x86/include/asm/device.h 2011-03-14 21:20:32.000000000 -0400
7499+++ linux-2.6.38.1/arch/x86/include/asm/device.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
7500@@ -6,7 +6,7 @@ struct dev_archdata {
7501 void *acpi_handle;
7502 #endif
7503 #ifdef CONFIG_X86_64
7504-struct dma_map_ops *dma_ops;
7505+ const struct dma_map_ops *dma_ops;
7506 #endif
7507 #if defined(CONFIG_DMAR) || defined(CONFIG_AMD_IOMMU)
7508 void *iommu; /* hook for IOMMU specific extension */
16454cff
MT
7509diff -urNp linux-2.6.38.1/arch/x86/include/asm/dma-mapping.h linux-2.6.38.1/arch/x86/include/asm/dma-mapping.h
7510--- linux-2.6.38.1/arch/x86/include/asm/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
7511+++ linux-2.6.38.1/arch/x86/include/asm/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
7512@@ -26,9 +26,9 @@ extern int iommu_merge;
7513 extern struct device x86_dma_fallback_dev;
7514 extern int panic_on_overflow;
7515
7516-extern struct dma_map_ops *dma_ops;
7517+extern const struct dma_map_ops *dma_ops;
7518
7519-static inline struct dma_map_ops *get_dma_ops(struct device *dev)
7520+static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
7521 {
7522 #ifdef CONFIG_X86_32
7523 return dma_ops;
7524@@ -45,7 +45,7 @@ static inline struct dma_map_ops *get_dm
7525 /* Make sure we keep the same behaviour */
7526 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
7527 {
7528- struct dma_map_ops *ops = get_dma_ops(dev);
7529+ const struct dma_map_ops *ops = get_dma_ops(dev);
7530 if (ops->mapping_error)
7531 return ops->mapping_error(dev, dma_addr);
7532
6892158b 7533@@ -115,7 +115,7 @@ static inline void *
ae4e228f
MT
7534 dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
7535 gfp_t gfp)
7536 {
7537- struct dma_map_ops *ops = get_dma_ops(dev);
7538+ const struct dma_map_ops *ops = get_dma_ops(dev);
7539 void *memory;
7540
7541 gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
6892158b 7542@@ -142,7 +142,7 @@ dma_alloc_coherent(struct device *dev, s
ae4e228f
MT
7543 static inline void dma_free_coherent(struct device *dev, size_t size,
7544 void *vaddr, dma_addr_t bus)
7545 {
7546- struct dma_map_ops *ops = get_dma_ops(dev);
7547+ const struct dma_map_ops *ops = get_dma_ops(dev);
7548
7549 WARN_ON(irqs_disabled()); /* for portability */
7550
16454cff
MT
7551diff -urNp linux-2.6.38.1/arch/x86/include/asm/e820.h linux-2.6.38.1/arch/x86/include/asm/e820.h
7552--- linux-2.6.38.1/arch/x86/include/asm/e820.h 2011-03-14 21:20:32.000000000 -0400
7553+++ linux-2.6.38.1/arch/x86/include/asm/e820.h 2011-03-21 18:31:35.000000000 -0400
57199397 7554@@ -69,7 +69,7 @@ struct e820map {
ae4e228f 7555 #define ISA_START_ADDRESS 0xa0000
58c5fc13 7556 #define ISA_END_ADDRESS 0x100000
58c5fc13
MT
7557
7558-#define BIOS_BEGIN 0x000a0000
7559+#define BIOS_BEGIN 0x000c0000
7560 #define BIOS_END 0x00100000
7561
bc901d79 7562 #define BIOS_ROM_BASE 0xffe00000
16454cff
MT
7563diff -urNp linux-2.6.38.1/arch/x86/include/asm/elf.h linux-2.6.38.1/arch/x86/include/asm/elf.h
7564--- linux-2.6.38.1/arch/x86/include/asm/elf.h 2011-03-14 21:20:32.000000000 -0400
7565+++ linux-2.6.38.1/arch/x86/include/asm/elf.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 7566@@ -237,7 +237,25 @@ extern int force_personality32;
58c5fc13
MT
7567 the loader. We need to make sure that it is out of the way of the program
7568 that it will "exec", and that there is sufficient room for the brk. */
7569
7570+#ifdef CONFIG_PAX_SEGMEXEC
7571+#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
7572+#else
7573 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
7574+#endif
7575+
7576+#ifdef CONFIG_PAX_ASLR
7577+#ifdef CONFIG_X86_32
7578+#define PAX_ELF_ET_DYN_BASE 0x10000000UL
7579+
7580+#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
7581+#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
7582+#else
7583+#define PAX_ELF_ET_DYN_BASE 0x400000UL
7584+
df50ba0c
MT
7585+#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : TASK_SIZE_MAX_SHIFT - PAGE_SHIFT - 3)
7586+#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : TASK_SIZE_MAX_SHIFT - PAGE_SHIFT - 3)
58c5fc13
MT
7587+#endif
7588+#endif
7589
7590 /* This yields a mask that user programs can use to figure out what
7591 instruction set this CPU supports. This could be done in user space,
ae4e228f 7592@@ -291,8 +309,7 @@ do { \
58c5fc13
MT
7593 #define ARCH_DLINFO \
7594 do { \
7595 if (vdso_enabled) \
7596- NEW_AUX_ENT(AT_SYSINFO_EHDR, \
7597- (unsigned long)current->mm->context.vdso); \
7598+ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
7599 } while (0)
7600
7601 #define AT_SYSINFO 32
ae4e228f 7602@@ -303,7 +320,7 @@ do { \
58c5fc13
MT
7603
7604 #endif /* !CONFIG_X86_32 */
7605
7606-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
7607+#define VDSO_CURRENT_BASE (current->mm->context.vdso)
7608
7609 #define VDSO_ENTRY \
7610 ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
ae4e228f 7611@@ -317,7 +334,4 @@ extern int arch_setup_additional_pages(s
58c5fc13
MT
7612 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
7613 #define compat_arch_setup_additional_pages syscall32_setup_pages
7614
7615-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
7616-#define arch_randomize_brk arch_randomize_brk
7617-
7618 #endif /* _ASM_X86_ELF_H */
16454cff
MT
7619diff -urNp linux-2.6.38.1/arch/x86/include/asm/futex.h linux-2.6.38.1/arch/x86/include/asm/futex.h
7620--- linux-2.6.38.1/arch/x86/include/asm/futex.h 2011-03-14 21:20:32.000000000 -0400
7621+++ linux-2.6.38.1/arch/x86/include/asm/futex.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 7622@@ -12,16 +12,18 @@
58c5fc13
MT
7623 #include <asm/system.h>
7624
df50ba0c 7625 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
df50ba0c 7626+ typecheck(u32 *, uaddr); \
58c5fc13
MT
7627 asm volatile("1:\t" insn "\n" \
7628 "2:\t.section .fixup,\"ax\"\n" \
df50ba0c
MT
7629 "3:\tmov\t%3, %1\n" \
7630 "\tjmp\t2b\n" \
7631 "\t.previous\n" \
7632 _ASM_EXTABLE(1b, 3b) \
7633- : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
c52201e0 7634+ : "=r" (oldval), "=r" (ret), "+m" (*(u32 *)____m(uaddr))\
df50ba0c
MT
7635 : "i" (-EFAULT), "0" (oparg), "1" (0))
7636
7637 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
7638+ typecheck(u32 *, uaddr); \
7639 asm volatile("1:\tmovl %2, %0\n" \
7640 "\tmovl\t%0, %3\n" \
7641 "\t" insn "\n" \
bc901d79 7642@@ -34,10 +36,10 @@
df50ba0c
MT
7643 _ASM_EXTABLE(1b, 4b) \
7644 _ASM_EXTABLE(2b, 4b) \
58c5fc13 7645 : "=&a" (oldval), "=&r" (ret), \
df50ba0c 7646- "+m" (*uaddr), "=&r" (tem) \
c52201e0 7647+ "+m" (*(u32 *)____m(uaddr)), "=&r" (tem) \
58c5fc13 7648 : "r" (oparg), "i" (-EFAULT), "1" (0))
58c5fc13
MT
7649
7650-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
7651+static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
7652 {
7653 int op = (encoded_op >> 28) & 7;
7654 int cmp = (encoded_op >> 24) & 15;
bc901d79 7655@@ -61,10 +63,10 @@ static inline int futex_atomic_op_inuser
58c5fc13
MT
7656
7657 switch (op) {
7658 case FUTEX_OP_SET:
bc901d79 7659- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
16454cff 7660+ __futex_atomic_op1(__copyuser_seg"xchgl %0, %2", ret, oldval, uaddr, oparg);
58c5fc13
MT
7661 break;
7662 case FUTEX_OP_ADD:
bc901d79 7663- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
16454cff 7664+ __futex_atomic_op1(LOCK_PREFIX __copyuser_seg"xaddl %0, %2", ret, oldval,
58c5fc13 7665 uaddr, oparg);
58c5fc13
MT
7666 break;
7667 case FUTEX_OP_OR:
bc901d79 7668@@ -109,7 +111,7 @@ static inline int futex_atomic_op_inuser
58c5fc13
MT
7669 return ret;
7670 }
7671
7672-static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
7673+static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
7674 int newval)
7675 {
7676
bc901d79 7677@@ -119,16 +121,16 @@ static inline int futex_atomic_cmpxchg_i
df50ba0c
MT
7678 return -ENOSYS;
7679 #endif
7680
7681- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
7682+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
58c5fc13
MT
7683 return -EFAULT;
7684
7685- asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
16454cff 7686+ asm volatile("1:\t" LOCK_PREFIX __copyuser_seg"cmpxchgl %3, %1\n"
bc901d79 7687 "2:\t.section .fixup, \"ax\"\n"
58c5fc13
MT
7688 "3:\tmov %2, %0\n"
7689 "\tjmp 2b\n"
7690 "\t.previous\n"
7691 _ASM_EXTABLE(1b, 3b)
bc901d79 7692- : "=a" (oldval), "+m" (*uaddr)
c52201e0 7693+ : "=a" (oldval), "+m" (*(u32 *)____m(uaddr))
58c5fc13 7694 : "i" (-EFAULT), "r" (newval), "0" (oldval)
58c5fc13
MT
7695 : "memory"
7696 );
16454cff
MT
7697diff -urNp linux-2.6.38.1/arch/x86/include/asm/i387.h linux-2.6.38.1/arch/x86/include/asm/i387.h
7698--- linux-2.6.38.1/arch/x86/include/asm/i387.h 2011-03-14 21:20:32.000000000 -0400
7699+++ linux-2.6.38.1/arch/x86/include/asm/i387.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 7700@@ -92,6 +92,11 @@ static inline int fxrstor_checking(struc
df50ba0c
MT
7701 {
7702 int err;
7703
7704+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
7705+ if ((unsigned long)fx < PAX_USER_SHADOW_BASE)
7706+ fx = (struct i387_fxsave_struct *)((void *)fx + PAX_USER_SHADOW_BASE);
7707+#endif
7708+
bc901d79 7709 /* See comment in fxsave() below. */
16454cff
MT
7710 #ifdef CONFIG_AS_FXSAVEQ
7711 asm volatile("1: fxrstorq %[fx]\n\t"
7712@@ -121,6 +126,11 @@ static inline int fxsave_user(struct i38
df50ba0c
MT
7713 {
7714 int err;
7715
7716+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
7717+ if ((unsigned long)fx < PAX_USER_SHADOW_BASE)
7718+ fx = (struct i387_fxsave_struct __user *)((void __user *)fx + PAX_USER_SHADOW_BASE);
7719+#endif
7720+
6892158b
MT
7721 /*
7722 * Clear the bytes not touched by the fxsave and reserved
7723 * for the SW usage.
16454cff 7724@@ -213,13 +223,8 @@ static inline void fpu_fxsave(struct fpu
bc901d79 7725 #endif /* CONFIG_X86_64 */
58c5fc13
MT
7726
7727 /* We need a safe address that is cheap to find and that is already
7728- in L1 during context switch. The best choices are unfortunately
7729- different for UP and SMP */
7730-#ifdef CONFIG_SMP
7731-#define safe_address (__per_cpu_offset[0])
7732-#else
7733-#define safe_address (kstat_cpu(0).cpustat.user)
7734-#endif
7735+ in L1 during context switch. */
7736+#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
7737
7738 /*
7739 * These must be called with preempt disabled
16454cff
MT
7740diff -urNp linux-2.6.38.1/arch/x86/include/asm/io.h linux-2.6.38.1/arch/x86/include/asm/io.h
7741--- linux-2.6.38.1/arch/x86/include/asm/io.h 2011-03-14 21:20:32.000000000 -0400
7742+++ linux-2.6.38.1/arch/x86/include/asm/io.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 7743@@ -216,6 +216,17 @@ extern void set_iounmap_nonlazy(void);
58c5fc13
MT
7744
7745 #include <linux/vmalloc.h>
7746
7747+#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
ae4e228f 7748+static inline int valid_phys_addr_range(unsigned long addr, size_t count)
58c5fc13 7749+{
c52201e0 7750+ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1ULL << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
58c5fc13
MT
7751+}
7752+
ae4e228f 7753+static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t count)
58c5fc13 7754+{
c52201e0 7755+ return (pfn + (count >> PAGE_SHIFT)) < (1ULL << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
58c5fc13
MT
7756+}
7757+
df50ba0c
MT
7758 /*
7759 * Convert a virtual cached pointer to an uncached pointer
7760 */
16454cff
MT
7761diff -urNp linux-2.6.38.1/arch/x86/include/asm/iommu.h linux-2.6.38.1/arch/x86/include/asm/iommu.h
7762--- linux-2.6.38.1/arch/x86/include/asm/iommu.h 2011-03-14 21:20:32.000000000 -0400
7763+++ linux-2.6.38.1/arch/x86/include/asm/iommu.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
7764@@ -1,7 +1,7 @@
7765 #ifndef _ASM_X86_IOMMU_H
7766 #define _ASM_X86_IOMMU_H
7767
7768-extern struct dma_map_ops nommu_dma_ops;
7769+extern const struct dma_map_ops nommu_dma_ops;
7770 extern int force_iommu, no_iommu;
7771 extern int iommu_detected;
7772 extern int iommu_pass_through;
16454cff
MT
7773diff -urNp linux-2.6.38.1/arch/x86/include/asm/irqflags.h linux-2.6.38.1/arch/x86/include/asm/irqflags.h
7774--- linux-2.6.38.1/arch/x86/include/asm/irqflags.h 2011-03-14 21:20:32.000000000 -0400
7775+++ linux-2.6.38.1/arch/x86/include/asm/irqflags.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 7776@@ -140,6 +140,11 @@ static inline unsigned long arch_local_i
ae4e228f
MT
7777 sti; \
7778 sysexit
7779
df50ba0c
MT
7780+#define GET_CR0_INTO_RDI mov %cr0, %rdi
7781+#define SET_RDI_INTO_CR0 mov %rdi, %cr0
7782+#define GET_CR3_INTO_RDI mov %cr3, %rdi
7783+#define SET_RDI_INTO_CR3 mov %rdi, %cr3
ae4e228f
MT
7784+
7785 #else
58c5fc13
MT
7786 #define INTERRUPT_RETURN iret
7787 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
16454cff
MT
7788diff -urNp linux-2.6.38.1/arch/x86/include/asm/kvm_host.h linux-2.6.38.1/arch/x86/include/asm/kvm_host.h
7789--- linux-2.6.38.1/arch/x86/include/asm/kvm_host.h 2011-03-14 21:20:32.000000000 -0400
7790+++ linux-2.6.38.1/arch/x86/include/asm/kvm_host.h 2011-03-21 18:31:35.000000000 -0400
7791@@ -603,7 +603,7 @@ struct kvm_arch_async_pf {
7792 bool direct_map;
58c5fc13
MT
7793 };
7794
7795-extern struct kvm_x86_ops *kvm_x86_ops;
7796+extern const struct kvm_x86_ops *kvm_x86_ops;
7797
7798 int kvm_mmu_module_init(void);
7799 void kvm_mmu_module_exit(void);
16454cff
MT
7800diff -urNp linux-2.6.38.1/arch/x86/include/asm/local.h linux-2.6.38.1/arch/x86/include/asm/local.h
7801--- linux-2.6.38.1/arch/x86/include/asm/local.h 2011-03-14 21:20:32.000000000 -0400
7802+++ linux-2.6.38.1/arch/x86/include/asm/local.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 7803@@ -18,26 +18,58 @@ typedef struct {
58c5fc13
MT
7804
7805 static inline void local_inc(local_t *l)
7806 {
7807- asm volatile(_ASM_INC "%0"
7808+ asm volatile(_ASM_INC "%0\n"
7809+
7810+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7811+ "jno 0f\n"
58c5fc13 7812+ _ASM_DEC "%0\n"
bc901d79
MT
7813+ "int $4\n0:\n"
7814+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7815+#endif
7816+
7817 : "+m" (l->a.counter));
7818 }
7819
7820 static inline void local_dec(local_t *l)
7821 {
7822- asm volatile(_ASM_DEC "%0"
7823+ asm volatile(_ASM_DEC "%0\n"
7824+
7825+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7826+ "jno 0f\n"
58c5fc13 7827+ _ASM_INC "%0\n"
bc901d79
MT
7828+ "int $4\n0:\n"
7829+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7830+#endif
7831+
7832 : "+m" (l->a.counter));
7833 }
7834
7835 static inline void local_add(long i, local_t *l)
7836 {
7837- asm volatile(_ASM_ADD "%1,%0"
7838+ asm volatile(_ASM_ADD "%1,%0\n"
7839+
7840+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7841+ "jno 0f\n"
58c5fc13 7842+ _ASM_SUB "%1,%0\n"
bc901d79
MT
7843+ "int $4\n0:\n"
7844+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7845+#endif
7846+
7847 : "+m" (l->a.counter)
7848 : "ir" (i));
7849 }
7850
7851 static inline void local_sub(long i, local_t *l)
7852 {
7853- asm volatile(_ASM_SUB "%1,%0"
7854+ asm volatile(_ASM_SUB "%1,%0\n"
7855+
7856+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7857+ "jno 0f\n"
58c5fc13 7858+ _ASM_ADD "%1,%0\n"
bc901d79
MT
7859+ "int $4\n0:\n"
7860+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7861+#endif
7862+
7863 : "+m" (l->a.counter)
7864 : "ir" (i));
7865 }
bc901d79 7866@@ -55,7 +87,16 @@ static inline int local_sub_and_test(lon
58c5fc13
MT
7867 {
7868 unsigned char c;
7869
7870- asm volatile(_ASM_SUB "%2,%0; sete %1"
7871+ asm volatile(_ASM_SUB "%2,%0\n"
7872+
7873+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7874+ "jno 0f\n"
58c5fc13 7875+ _ASM_ADD "%2,%0\n"
bc901d79
MT
7876+ "int $4\n0:\n"
7877+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7878+#endif
7879+
7880+ "sete %1\n"
7881 : "+m" (l->a.counter), "=qm" (c)
7882 : "ir" (i) : "memory");
7883 return c;
bc901d79 7884@@ -73,7 +114,16 @@ static inline int local_dec_and_test(loc
58c5fc13
MT
7885 {
7886 unsigned char c;
7887
7888- asm volatile(_ASM_DEC "%0; sete %1"
7889+ asm volatile(_ASM_DEC "%0\n"
7890+
7891+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7892+ "jno 0f\n"
58c5fc13 7893+ _ASM_INC "%0\n"
bc901d79
MT
7894+ "int $4\n0:\n"
7895+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7896+#endif
7897+
7898+ "sete %1\n"
7899 : "+m" (l->a.counter), "=qm" (c)
7900 : : "memory");
7901 return c != 0;
bc901d79 7902@@ -91,7 +141,16 @@ static inline int local_inc_and_test(loc
58c5fc13
MT
7903 {
7904 unsigned char c;
7905
7906- asm volatile(_ASM_INC "%0; sete %1"
7907+ asm volatile(_ASM_INC "%0\n"
7908+
7909+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7910+ "jno 0f\n"
58c5fc13 7911+ _ASM_DEC "%0\n"
bc901d79
MT
7912+ "int $4\n0:\n"
7913+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7914+#endif
7915+
7916+ "sete %1\n"
7917 : "+m" (l->a.counter), "=qm" (c)
7918 : : "memory");
7919 return c != 0;
bc901d79 7920@@ -110,7 +169,16 @@ static inline int local_add_negative(lon
58c5fc13
MT
7921 {
7922 unsigned char c;
7923
7924- asm volatile(_ASM_ADD "%2,%0; sets %1"
7925+ asm volatile(_ASM_ADD "%2,%0\n"
7926+
7927+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7928+ "jno 0f\n"
58c5fc13 7929+ _ASM_SUB "%2,%0\n"
bc901d79
MT
7930+ "int $4\n0:\n"
7931+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7932+#endif
7933+
7934+ "sets %1\n"
7935 : "+m" (l->a.counter), "=qm" (c)
7936 : "ir" (i) : "memory");
7937 return c;
bc901d79 7938@@ -133,7 +201,15 @@ static inline long local_add_return(long
58c5fc13
MT
7939 #endif
7940 /* Modern 486+ processor */
7941 __i = i;
7942- asm volatile(_ASM_XADD "%0, %1;"
7943+ asm volatile(_ASM_XADD "%0, %1\n"
7944+
7945+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 7946+ "jno 0f\n"
58c5fc13 7947+ _ASM_MOV "%0,%1\n"
bc901d79
MT
7948+ "int $4\n0:\n"
7949+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
7950+#endif
7951+
7952 : "+r" (i), "+m" (l->a.counter)
7953 : : "memory");
7954 return i + __i;
16454cff
MT
7955diff -urNp linux-2.6.38.1/arch/x86/include/asm/mc146818rtc.h linux-2.6.38.1/arch/x86/include/asm/mc146818rtc.h
7956--- linux-2.6.38.1/arch/x86/include/asm/mc146818rtc.h 2011-03-14 21:20:32.000000000 -0400
7957+++ linux-2.6.38.1/arch/x86/include/asm/mc146818rtc.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
7958@@ -81,8 +81,8 @@ static inline unsigned char current_lock
7959 #else
7960 #define lock_cmos_prefix(reg) do {} while (0)
7961 #define lock_cmos_suffix(reg) do {} while (0)
7962-#define lock_cmos(reg)
7963-#define unlock_cmos()
7964+#define lock_cmos(reg) do {} while (0)
7965+#define unlock_cmos() do {} while (0)
7966 #define do_i_have_lock_cmos() 0
7967 #define current_lock_cmos_reg() 0
7968 #endif
16454cff
MT
7969diff -urNp linux-2.6.38.1/arch/x86/include/asm/mce.h linux-2.6.38.1/arch/x86/include/asm/mce.h
7970--- linux-2.6.38.1/arch/x86/include/asm/mce.h 2011-03-14 21:20:32.000000000 -0400
7971+++ linux-2.6.38.1/arch/x86/include/asm/mce.h 2011-03-21 18:31:35.000000000 -0400
7972@@ -198,7 +198,7 @@ int mce_notify_irq(void);
7973 void mce_notify_process(void);
7974
7975 DECLARE_PER_CPU(struct mce, injectm);
7976-extern struct file_operations mce_chrdev_ops;
7977+extern struct file_operations mce_chrdev_ops; /* cannot be const, see arch/x86/kernel/cpu/mcheck/mce. */
7978
7979 /*
7980 * Exception handler
7981diff -urNp linux-2.6.38.1/arch/x86/include/asm/microcode.h linux-2.6.38.1/arch/x86/include/asm/microcode.h
7982--- linux-2.6.38.1/arch/x86/include/asm/microcode.h 2011-03-14 21:20:32.000000000 -0400
7983+++ linux-2.6.38.1/arch/x86/include/asm/microcode.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
7984@@ -12,13 +12,13 @@ struct device;
7985 enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND };
7986
7987 struct microcode_ops {
7988- enum ucode_state (*request_microcode_user) (int cpu,
7989+ enum ucode_state (* const request_microcode_user) (int cpu,
7990 const void __user *buf, size_t size);
7991
7992- enum ucode_state (*request_microcode_fw) (int cpu,
7993+ enum ucode_state (* const request_microcode_fw) (int cpu,
7994 struct device *device);
7995
7996- void (*microcode_fini_cpu) (int cpu);
7997+ void (* const microcode_fini_cpu) (int cpu);
7998
7999 /*
8000 * The generic 'microcode_core' part guarantees that
16454cff 8001@@ -38,16 +38,16 @@ struct ucode_cpu_info {
ae4e228f
MT
8002 extern struct ucode_cpu_info ucode_cpu_info[];
8003
8004 #ifdef CONFIG_MICROCODE_INTEL
8005-extern struct microcode_ops * __init init_intel_microcode(void);
8006+extern const struct microcode_ops * __init init_intel_microcode(void);
8007 #else
8008-static inline struct microcode_ops * __init init_intel_microcode(void)
8009+static inline const struct microcode_ops * __init init_intel_microcode(void)
8010 {
8011 return NULL;
8012 }
8013 #endif /* CONFIG_MICROCODE_INTEL */
8014
8015 #ifdef CONFIG_MICROCODE_AMD
8016-extern struct microcode_ops * __init init_amd_microcode(void);
8017+extern const struct microcode_ops * __init init_amd_microcode(void);
16454cff
MT
8018
8019 static inline void get_ucode_data(void *to, const u8 *from, size_t n)
8020 {
8021@@ -55,7 +55,7 @@ static inline void get_ucode_data(void *
8022 }
8023
ae4e228f
MT
8024 #else
8025-static inline struct microcode_ops * __init init_amd_microcode(void)
8026+static inline const struct microcode_ops * __init init_amd_microcode(void)
8027 {
8028 return NULL;
8029 }
16454cff
MT
8030diff -urNp linux-2.6.38.1/arch/x86/include/asm/mman.h linux-2.6.38.1/arch/x86/include/asm/mman.h
8031--- linux-2.6.38.1/arch/x86/include/asm/mman.h 2011-03-14 21:20:32.000000000 -0400
8032+++ linux-2.6.38.1/arch/x86/include/asm/mman.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
8033@@ -5,4 +5,14 @@
8034
8035 #include <asm-generic/mman.h>
58c5fc13
MT
8036
8037+#ifdef __KERNEL__
8038+#ifndef __ASSEMBLY__
8039+#ifdef CONFIG_X86_32
8040+#define arch_mmap_check i386_mmap_check
8041+int i386_mmap_check(unsigned long addr, unsigned long len,
8042+ unsigned long flags);
8043+#endif
8044+#endif
8045+#endif
8046+
8047 #endif /* _ASM_X86_MMAN_H */
16454cff
MT
8048diff -urNp linux-2.6.38.1/arch/x86/include/asm/mmu_context.h linux-2.6.38.1/arch/x86/include/asm/mmu_context.h
8049--- linux-2.6.38.1/arch/x86/include/asm/mmu_context.h 2011-03-14 21:20:32.000000000 -0400
8050+++ linux-2.6.38.1/arch/x86/include/asm/mmu_context.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
8051@@ -24,6 +24,21 @@ void destroy_context(struct mm_struct *m
8052
8053 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
8054 {
8055+
8056+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
8057+ unsigned int i;
8058+ pgd_t *pgd;
8059+
8060+ pax_open_kernel();
8061+ pgd = get_cpu_pgd(smp_processor_id());
8062+ for (i = USER_PGD_PTRS; i < 2 * USER_PGD_PTRS; ++i)
8063+ if (paravirt_enabled())
8064+ set_pgd(pgd+i, native_make_pgd(0));
8065+ else
8066+ pgd[i] = native_make_pgd(0);
8067+ pax_close_kernel();
8068+#endif
8069+
8070 #ifdef CONFIG_SMP
8071 if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
8072 percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
c52201e0 8073@@ -34,17 +49,30 @@ static inline void switch_mm(struct mm_s
58c5fc13
MT
8074 struct task_struct *tsk)
8075 {
8076 unsigned cpu = smp_processor_id();
8077+#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
8078+ int tlbstate = TLBSTATE_OK;
8079+#endif
8080
8081 if (likely(prev != next)) {
58c5fc13
MT
8082 #ifdef CONFIG_SMP
8083+#ifdef CONFIG_X86_32
8084+ tlbstate = percpu_read(cpu_tlbstate.state);
8085+#endif
8086 percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
8087 percpu_write(cpu_tlbstate.active_mm, next);
8088 #endif
df50ba0c
MT
8089 cpumask_set_cpu(cpu, mm_cpumask(next));
8090
8091 /* Re-load page tables */
8092+#ifdef CONFIG_PAX_PER_CPU_PGD
8093+ pax_open_kernel();
8094+ __clone_user_pgds(get_cpu_pgd(cpu), next->pgd, USER_PGD_PTRS);
8095+ __shadow_user_pgds(get_cpu_pgd(cpu) + USER_PGD_PTRS, next->pgd, USER_PGD_PTRS);
8096+ pax_close_kernel();
8097+ load_cr3(get_cpu_pgd(cpu));
8098+#else
8099 load_cr3(next->pgd);
c52201e0 8100-
df50ba0c 8101+#endif
c52201e0
MT
8102 /* stop flush ipis for the previous mm */
8103 cpumask_clear_cpu(cpu, mm_cpumask(prev));
df50ba0c 8104
c52201e0 8105@@ -53,9 +81,38 @@ static inline void switch_mm(struct mm_s
58c5fc13
MT
8106 */
8107 if (unlikely(prev->context.ldt != next->context.ldt))
8108 load_LDT_nolock(&next->context);
df50ba0c 8109- }
58c5fc13
MT
8110+
8111+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
ae4e228f 8112+ if (!(__supported_pte_mask & _PAGE_NX)) {
58c5fc13
MT
8113+ smp_mb__before_clear_bit();
8114+ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
8115+ smp_mb__after_clear_bit();
8116+ cpu_set(cpu, next->context.cpu_user_cs_mask);
8117+ }
8118+#endif
8119+
8120+#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC))
8121+ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
ae4e228f
MT
8122+ prev->context.user_cs_limit != next->context.user_cs_limit))
8123+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
df50ba0c 8124 #ifdef CONFIG_SMP
ae4e228f 8125+ else if (unlikely(tlbstate != TLBSTATE_OK))
58c5fc13
MT
8126+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
8127+#endif
ae4e228f 8128+#endif
58c5fc13 8129+
df50ba0c 8130+ }
58c5fc13 8131 else {
df50ba0c
MT
8132+
8133+#ifdef CONFIG_PAX_PER_CPU_PGD
8134+ pax_open_kernel();
8135+ __clone_user_pgds(get_cpu_pgd(cpu), next->pgd, USER_PGD_PTRS);
8136+ __shadow_user_pgds(get_cpu_pgd(cpu) + USER_PGD_PTRS, next->pgd, USER_PGD_PTRS);
8137+ pax_close_kernel();
8138+ load_cr3(get_cpu_pgd(cpu));
8139+#endif
8140+
8141+#ifdef CONFIG_SMP
8142 percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
8143 BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next);
8144
c52201e0 8145@@ -64,11 +121,28 @@ static inline void switch_mm(struct mm_s
df50ba0c
MT
8146 * tlb flush IPI delivery. We must reload CR3
8147 * to make sure to use no freed page tables.
58c5fc13 8148 */
df50ba0c
MT
8149+
8150+#ifndef CONFIG_PAX_PER_CPU_PGD
58c5fc13 8151 load_cr3(next->pgd);
df50ba0c
MT
8152+#endif
8153+
58c5fc13
MT
8154 load_LDT_nolock(&next->context);
8155+
8156+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
ae4e228f 8157+ if (!(__supported_pte_mask & _PAGE_NX))
58c5fc13
MT
8158+ cpu_set(cpu, next->context.cpu_user_cs_mask);
8159+#endif
8160+
8161+#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC))
8162+#ifdef CONFIG_PAX_PAGEEXEC
ae4e228f 8163+ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && (__supported_pte_mask & _PAGE_NX)))
58c5fc13
MT
8164+#endif
8165+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
8166+#endif
8167+
8168 }
df50ba0c 8169- }
58c5fc13 8170 #endif
df50ba0c
MT
8171+ }
8172 }
8173
8174 #define activate_mm(prev, next) \
16454cff
MT
8175diff -urNp linux-2.6.38.1/arch/x86/include/asm/mmu.h linux-2.6.38.1/arch/x86/include/asm/mmu.h
8176--- linux-2.6.38.1/arch/x86/include/asm/mmu.h 2011-03-14 21:20:32.000000000 -0400
8177+++ linux-2.6.38.1/arch/x86/include/asm/mmu.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
8178@@ -9,10 +9,23 @@
8179 * we put the segment information here.
8180 */
8181 typedef struct {
8182- void *ldt;
8183+ struct desc_struct *ldt;
8184 int size;
8185 struct mutex lock;
8186- void *vdso;
8187+ unsigned long vdso;
8188+
8189+#ifdef CONFIG_X86_32
8190+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8191+ unsigned long user_cs_base;
8192+ unsigned long user_cs_limit;
8193+
8194+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
8195+ cpumask_t cpu_user_cs_mask;
8196+#endif
8197+
8198+#endif
8199+#endif
8200+
8201 } mm_context_t;
8202
8203 #ifdef CONFIG_SMP
16454cff
MT
8204diff -urNp linux-2.6.38.1/arch/x86/include/asm/module.h linux-2.6.38.1/arch/x86/include/asm/module.h
8205--- linux-2.6.38.1/arch/x86/include/asm/module.h 2011-03-14 21:20:32.000000000 -0400
8206+++ linux-2.6.38.1/arch/x86/include/asm/module.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 8207@@ -59,8 +59,26 @@
df50ba0c
MT
8208 #error unknown processor family
8209 #endif
8210
8211+#ifdef CONFIG_PAX_MEMORY_UDEREF
8212+#define MODULE_PAX_UDEREF "UDEREF "
8213+#else
8214+#define MODULE_PAX_UDEREF ""
8215+#endif
8216+
8217 #ifdef CONFIG_X86_32
bc901d79 8218-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
df50ba0c
MT
8219+# ifdef CONFIG_PAX_KERNEXEC
8220+# define MODULE_PAX_KERNEXEC "KERNEXEC "
8221+# else
8222+# define MODULE_PAX_KERNEXEC ""
8223+# endif
58c5fc13
MT
8224+# ifdef CONFIG_GRKERNSEC
8225+# define MODULE_GRSEC "GRSECURITY "
8226+# else
8227+# define MODULE_GRSEC ""
8228+# endif
bc901d79 8229+# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_GRSEC MODULE_PAX_KERNEXEC MODULE_PAX_UDEREF
df50ba0c
MT
8230+#else
8231+# define MODULE_ARCH_VERMAGIC MODULE_PAX_UDEREF
58c5fc13
MT
8232 #endif
8233
8234 #endif /* _ASM_X86_MODULE_H */
16454cff
MT
8235diff -urNp linux-2.6.38.1/arch/x86/include/asm/page_64_types.h linux-2.6.38.1/arch/x86/include/asm/page_64_types.h
8236--- linux-2.6.38.1/arch/x86/include/asm/page_64_types.h 2011-03-14 21:20:32.000000000 -0400
8237+++ linux-2.6.38.1/arch/x86/include/asm/page_64_types.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
8238@@ -56,7 +56,7 @@ void copy_page(void *to, void *from);
8239
8240 /* duplicated to the one in bootmem.h */
8241 extern unsigned long max_pfn;
8242-extern unsigned long phys_base;
8243+extern const unsigned long phys_base;
8244
8245 extern unsigned long __phys_addr(unsigned long);
8246 #define __phys_reloc_hide(x) (x)
16454cff
MT
8247diff -urNp linux-2.6.38.1/arch/x86/include/asm/paravirt.h linux-2.6.38.1/arch/x86/include/asm/paravirt.h
8248--- linux-2.6.38.1/arch/x86/include/asm/paravirt.h 2011-03-14 21:20:32.000000000 -0400
8249+++ linux-2.6.38.1/arch/x86/include/asm/paravirt.h 2011-03-21 18:31:35.000000000 -0400
8250@@ -739,6 +739,21 @@ static inline void __set_fixmap(unsigned
ae4e228f
MT
8251 pv_mmu_ops.set_fixmap(idx, phys, flags);
8252 }
8253
8254+#ifdef CONFIG_PAX_KERNEXEC
8255+static inline unsigned long pax_open_kernel(void)
8256+{
efbe55a5 8257+ return PVOP_CALL0(unsigned long, pv_mmu_ops.pax_open_kernel);
ae4e228f
MT
8258+}
8259+
8260+static inline unsigned long pax_close_kernel(void)
8261+{
efbe55a5 8262+ return PVOP_CALL0(unsigned long, pv_mmu_ops.pax_close_kernel);
ae4e228f
MT
8263+}
8264+#else
8265+static inline unsigned long pax_open_kernel(void) { return 0; }
8266+static inline unsigned long pax_close_kernel(void) { return 0; }
8267+#endif
8268+
8269 #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
8270
8271 static inline int arch_spin_is_locked(struct arch_spinlock *lock)
16454cff 8272@@ -955,7 +970,7 @@ extern void default_banner(void);
58c5fc13
MT
8273
8274 #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
8275 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
8276-#define PARA_INDIRECT(addr) *%cs:addr
8277+#define PARA_INDIRECT(addr) *%ss:addr
8278 #endif
8279
8280 #define INTERRUPT_RETURN \
16454cff 8281@@ -1032,6 +1047,21 @@ extern void default_banner(void);
df50ba0c 8282 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \
ae4e228f
MT
8283 CLBR_NONE, \
8284 jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit))
58c5fc13 8285+
df50ba0c 8286+#define GET_CR0_INTO_RDI \
ae4e228f 8287+ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \
df50ba0c 8288+ mov %rax,%rdi
ae4e228f 8289+
df50ba0c
MT
8290+#define SET_RDI_INTO_CR0 \
8291+ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0)
ae4e228f 8292+
df50ba0c
MT
8293+#define GET_CR3_INTO_RDI \
8294+ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr3); \
8295+ mov %rax,%rdi
8296+
8297+#define SET_RDI_INTO_CR3 \
8298+ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_write_cr3)
ae4e228f
MT
8299+
8300 #endif /* CONFIG_X86_32 */
8301
8302 #endif /* __ASSEMBLY__ */
16454cff
MT
8303diff -urNp linux-2.6.38.1/arch/x86/include/asm/paravirt_types.h linux-2.6.38.1/arch/x86/include/asm/paravirt_types.h
8304--- linux-2.6.38.1/arch/x86/include/asm/paravirt_types.h 2011-03-14 21:20:32.000000000 -0400
8305+++ linux-2.6.38.1/arch/x86/include/asm/paravirt_types.h 2011-03-21 18:31:35.000000000 -0400
8306@@ -317,6 +317,12 @@ struct pv_mmu_ops {
ae4e228f
MT
8307 an mfn. We can tell which is which from the index. */
8308 void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
8309 phys_addr_t phys, pgprot_t flags);
8310+
8311+#ifdef CONFIG_PAX_KERNEXEC
8312+ unsigned long (*pax_open_kernel)(void);
8313+ unsigned long (*pax_close_kernel)(void);
8314+#endif
8315+
8316 };
8317
8318 struct arch_spinlock;
16454cff
MT
8319diff -urNp linux-2.6.38.1/arch/x86/include/asm/pci_x86.h linux-2.6.38.1/arch/x86/include/asm/pci_x86.h
8320--- linux-2.6.38.1/arch/x86/include/asm/pci_x86.h 2011-03-14 21:20:32.000000000 -0400
8321+++ linux-2.6.38.1/arch/x86/include/asm/pci_x86.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 8322@@ -93,16 +93,16 @@ extern int (*pcibios_enable_irq)(struct
ae4e228f
MT
8323 extern void (*pcibios_disable_irq)(struct pci_dev *dev);
8324
8325 struct pci_raw_ops {
8326- int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
8327+ int (* const read)(unsigned int domain, unsigned int bus, unsigned int devfn,
8328 int reg, int len, u32 *val);
8329- int (*write)(unsigned int domain, unsigned int bus, unsigned int devfn,
8330+ int (* const write)(unsigned int domain, unsigned int bus, unsigned int devfn,
8331 int reg, int len, u32 val);
8332 };
8333
8334-extern struct pci_raw_ops *raw_pci_ops;
8335-extern struct pci_raw_ops *raw_pci_ext_ops;
8336+extern const struct pci_raw_ops *raw_pci_ops;
8337+extern const struct pci_raw_ops *raw_pci_ext_ops;
8338
8339-extern struct pci_raw_ops pci_direct_conf1;
8340+extern const struct pci_raw_ops pci_direct_conf1;
8341 extern bool port_cf9_safe;
8342
8343 /* arch_initcall level */
16454cff
MT
8344diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgalloc.h linux-2.6.38.1/arch/x86/include/asm/pgalloc.h
8345--- linux-2.6.38.1/arch/x86/include/asm/pgalloc.h 2011-03-14 21:20:32.000000000 -0400
8346+++ linux-2.6.38.1/arch/x86/include/asm/pgalloc.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 8347@@ -63,6 +63,13 @@ static inline void pmd_populate_kernel(s
58c5fc13
MT
8348 pmd_t *pmd, pte_t *pte)
8349 {
8350 paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
8351+ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
8352+}
8353+
8354+static inline void pmd_populate_user(struct mm_struct *mm,
8355+ pmd_t *pmd, pte_t *pte)
8356+{
8357+ paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
8358 set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
8359 }
8360
16454cff
MT
8361diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgtable-2level.h linux-2.6.38.1/arch/x86/include/asm/pgtable-2level.h
8362--- linux-2.6.38.1/arch/x86/include/asm/pgtable-2level.h 2011-03-14 21:20:32.000000000 -0400
8363+++ linux-2.6.38.1/arch/x86/include/asm/pgtable-2level.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 8364@@ -18,7 +18,9 @@ static inline void native_set_pte(pte_t
58c5fc13
MT
8365
8366 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
8367 {
ae4e228f 8368+ pax_open_kernel();
58c5fc13 8369 *pmdp = pmd;
ae4e228f 8370+ pax_close_kernel();
58c5fc13
MT
8371 }
8372
8373 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
16454cff
MT
8374diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgtable_32.h linux-2.6.38.1/arch/x86/include/asm/pgtable_32.h
8375--- linux-2.6.38.1/arch/x86/include/asm/pgtable_32.h 2011-03-14 21:20:32.000000000 -0400
8376+++ linux-2.6.38.1/arch/x86/include/asm/pgtable_32.h 2011-03-21 18:31:35.000000000 -0400
6892158b 8377@@ -25,9 +25,6 @@
57199397
MT
8378 struct mm_struct;
8379 struct vm_area_struct;
8380
8381-extern pgd_t swapper_pg_dir[1024];
bc901d79 8382-extern pgd_t initial_page_table[1024];
57199397
MT
8383-
8384 static inline void pgtable_cache_init(void) { }
8385 static inline void check_pgt_cache(void) { }
8386 void paging_init(void);
6892158b 8387@@ -48,6 +45,12 @@ extern void set_pmd_pfn(unsigned long, u
57199397
MT
8388 # include <asm/pgtable-2level.h>
8389 #endif
8390
8391+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
bc901d79 8392+extern pgd_t initial_page_table[PTRS_PER_PGD];
57199397
MT
8393+#ifdef CONFIG_X86_PAE
8394+extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
8395+#endif
8396+
8397 #if defined(CONFIG_HIGHPTE)
bc901d79
MT
8398 #define pte_offset_map(dir, address) \
8399 ((pte_t *)kmap_atomic(pmd_page(*(dir))) + \
8400@@ -62,7 +65,9 @@ extern void set_pmd_pfn(unsigned long, u
57199397
MT
8401 /* Clear a kernel PTE and flush it from the TLB */
8402 #define kpte_clear_flush(ptep, vaddr) \
8403 do { \
8404+ pax_open_kernel(); \
8405 pte_clear(&init_mm, (vaddr), (ptep)); \
8406+ pax_close_kernel(); \
8407 __flush_tlb_one((vaddr)); \
8408 } while (0)
8409
bc901d79 8410@@ -74,6 +79,9 @@ do { \
57199397
MT
8411
8412 #endif /* !__ASSEMBLY__ */
8413
8414+#define HAVE_ARCH_UNMAPPED_AREA
8415+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
8416+
8417 /*
8418 * kern_addr_valid() is (1) for FLATMEM and (0) for
8419 * SPARSEMEM and DISCONTIGMEM
16454cff
MT
8420diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgtable_32_types.h linux-2.6.38.1/arch/x86/include/asm/pgtable_32_types.h
8421--- linux-2.6.38.1/arch/x86/include/asm/pgtable_32_types.h 2011-03-14 21:20:32.000000000 -0400
8422+++ linux-2.6.38.1/arch/x86/include/asm/pgtable_32_types.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
8423@@ -8,7 +8,7 @@
8424 */
8425 #ifdef CONFIG_X86_PAE
8426 # include <asm/pgtable-3level_types.h>
8427-# define PMD_SIZE (1UL << PMD_SHIFT)
8428+# define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
8429 # define PMD_MASK (~(PMD_SIZE - 1))
8430 #else
8431 # include <asm/pgtable-2level_types.h>
8432@@ -46,6 +46,19 @@ extern bool __vmalloc_start_set; /* set
8433 # define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE)
8434 #endif
8435
8436+#ifdef CONFIG_PAX_KERNEXEC
8437+#ifndef __ASSEMBLY__
8438+extern unsigned char MODULES_EXEC_VADDR[];
8439+extern unsigned char MODULES_EXEC_END[];
8440+#endif
8441+#include <asm/boot.h>
8442+#define ktla_ktva(addr) (addr + LOAD_PHYSICAL_ADDR + PAGE_OFFSET)
8443+#define ktva_ktla(addr) (addr - LOAD_PHYSICAL_ADDR - PAGE_OFFSET)
8444+#else
8445+#define ktla_ktva(addr) (addr)
8446+#define ktva_ktla(addr) (addr)
8447+#endif
8448+
8449 #define MODULES_VADDR VMALLOC_START
8450 #define MODULES_END VMALLOC_END
8451 #define MODULES_LEN (MODULES_VADDR - MODULES_END)
16454cff
MT
8452diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgtable-3level.h linux-2.6.38.1/arch/x86/include/asm/pgtable-3level.h
8453--- linux-2.6.38.1/arch/x86/include/asm/pgtable-3level.h 2011-03-23 17:20:06.000000000 -0400
8454+++ linux-2.6.38.1/arch/x86/include/asm/pgtable-3level.h 2011-03-23 17:21:43.000000000 -0400
ae4e228f 8455@@ -38,12 +38,16 @@ static inline void native_set_pte_atomic
58c5fc13
MT
8456
8457 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
8458 {
ae4e228f 8459+ pax_open_kernel();
58c5fc13 8460 set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
ae4e228f 8461+ pax_close_kernel();
58c5fc13
MT
8462 }
8463
8464 static inline void native_set_pud(pud_t *pudp, pud_t pud)
8465 {
ae4e228f 8466+ pax_open_kernel();
58c5fc13 8467 set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
ae4e228f 8468+ pax_close_kernel();
58c5fc13
MT
8469 }
8470
8471 /*
16454cff
MT
8472diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgtable_64.h linux-2.6.38.1/arch/x86/include/asm/pgtable_64.h
8473--- linux-2.6.38.1/arch/x86/include/asm/pgtable_64.h 2011-03-14 21:20:32.000000000 -0400
8474+++ linux-2.6.38.1/arch/x86/include/asm/pgtable_64.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
8475@@ -16,10 +16,13 @@
8476
8477 extern pud_t level3_kernel_pgt[512];
8478 extern pud_t level3_ident_pgt[512];
8479+extern pud_t level3_vmalloc_pgt[512];
8480+extern pud_t level3_vmemmap_pgt[512];
8481+extern pud_t level2_vmemmap_pgt[512];
8482 extern pmd_t level2_kernel_pgt[512];
8483 extern pmd_t level2_fixmap_pgt[512];
8484-extern pmd_t level2_ident_pgt[512];
8485-extern pgd_t init_level4_pgt[];
8486+extern pmd_t level2_ident_pgt[512*2];
8487+extern pgd_t init_level4_pgt[512];
8488
8489 #define swapper_pg_dir init_level4_pgt
8490
16454cff 8491@@ -61,7 +64,9 @@ static inline void native_set_pte_atomic
57199397
MT
8492
8493 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
8494 {
8495+ pax_open_kernel();
8496 *pmdp = pmd;
8497+ pax_close_kernel();
8498 }
8499
8500 static inline void native_pmd_clear(pmd_t *pmd)
16454cff 8501@@ -107,7 +112,9 @@ static inline void native_pud_clear(pud_
57199397
MT
8502
8503 static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd)
8504 {
8505+ pax_open_kernel();
8506 *pgdp = pgd;
8507+ pax_close_kernel();
8508 }
8509
8510 static inline void native_pgd_clear(pgd_t *pgd)
16454cff
MT
8511diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgtable_64_types.h linux-2.6.38.1/arch/x86/include/asm/pgtable_64_types.h
8512--- linux-2.6.38.1/arch/x86/include/asm/pgtable_64_types.h 2011-03-14 21:20:32.000000000 -0400
8513+++ linux-2.6.38.1/arch/x86/include/asm/pgtable_64_types.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
8514@@ -59,5 +59,10 @@ typedef struct { pteval_t pte; } pte_t;
8515 #define MODULES_VADDR _AC(0xffffffffa0000000, UL)
8516 #define MODULES_END _AC(0xffffffffff000000, UL)
8517 #define MODULES_LEN (MODULES_END - MODULES_VADDR)
8518+#define MODULES_EXEC_VADDR MODULES_VADDR
8519+#define MODULES_EXEC_END MODULES_END
8520+
8521+#define ktla_ktva(addr) (addr)
8522+#define ktva_ktla(addr) (addr)
8523
8524 #endif /* _ASM_X86_PGTABLE_64_DEFS_H */
16454cff
MT
8525diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgtable.h linux-2.6.38.1/arch/x86/include/asm/pgtable.h
8526--- linux-2.6.38.1/arch/x86/include/asm/pgtable.h 2011-03-14 21:20:32.000000000 -0400
8527+++ linux-2.6.38.1/arch/x86/include/asm/pgtable.h 2011-03-21 18:31:35.000000000 -0400
8528@@ -81,12 +81,51 @@ extern struct mm_struct *pgd_page_get_mm
ae4e228f
MT
8529
8530 #define arch_end_context_switch(prev) do {} while(0)
8531
8532+#define pax_open_kernel() native_pax_open_kernel()
8533+#define pax_close_kernel() native_pax_close_kernel()
8534 #endif /* CONFIG_PARAVIRT */
8535
8536+#define __HAVE_ARCH_PAX_OPEN_KERNEL
8537+#define __HAVE_ARCH_PAX_CLOSE_KERNEL
58c5fc13
MT
8538+
8539+#ifdef CONFIG_PAX_KERNEXEC
ae4e228f
MT
8540+static inline unsigned long native_pax_open_kernel(void)
8541+{
58c5fc13
MT
8542+ unsigned long cr0;
8543+
ae4e228f
MT
8544+ preempt_disable();
8545+ barrier();
8546+ cr0 = read_cr0() ^ X86_CR0_WP;
8547+ BUG_ON(unlikely(cr0 & X86_CR0_WP));
8548+ write_cr0(cr0);
8549+ return cr0 ^ X86_CR0_WP;
8550+}
58c5fc13 8551+
ae4e228f
MT
8552+static inline unsigned long native_pax_close_kernel(void)
8553+{
8554+ unsigned long cr0;
58c5fc13 8555+
ae4e228f
MT
8556+ cr0 = read_cr0() ^ X86_CR0_WP;
8557+ BUG_ON(unlikely(!(cr0 & X86_CR0_WP)));
8558+ write_cr0(cr0);
8559+ barrier();
8560+ preempt_enable_no_resched();
8561+ return cr0 ^ X86_CR0_WP;
8562+}
8563+#else
8564+static inline unsigned long native_pax_open_kernel(void) { return 0; }
8565+static inline unsigned long native_pax_close_kernel(void) { return 0; }
58c5fc13
MT
8566+#endif
8567+
ae4e228f 8568 /*
58c5fc13
MT
8569 * The following only work if pte_present() is true.
8570 * Undefined behaviour if not..
8571 */
8572+static inline int pte_user(pte_t pte)
8573+{
8574+ return pte_val(pte) & _PAGE_USER;
8575+}
8576+
8577 static inline int pte_dirty(pte_t pte)
8578 {
8579 return pte_flags(pte) & _PAGE_DIRTY;
16454cff 8580@@ -196,9 +235,29 @@ static inline pte_t pte_wrprotect(pte_t
58c5fc13
MT
8581 return pte_clear_flags(pte, _PAGE_RW);
8582 }
8583
8584+static inline pte_t pte_mkread(pte_t pte)
8585+{
8586+ return __pte(pte_val(pte) | _PAGE_USER);
8587+}
8588+
8589 static inline pte_t pte_mkexec(pte_t pte)
8590 {
8591- return pte_clear_flags(pte, _PAGE_NX);
8592+#ifdef CONFIG_X86_PAE
8593+ if (__supported_pte_mask & _PAGE_NX)
8594+ return pte_clear_flags(pte, _PAGE_NX);
8595+ else
8596+#endif
8597+ return pte_set_flags(pte, _PAGE_USER);
8598+}
8599+
8600+static inline pte_t pte_exprotect(pte_t pte)
8601+{
8602+#ifdef CONFIG_X86_PAE
8603+ if (__supported_pte_mask & _PAGE_NX)
8604+ return pte_set_flags(pte, _PAGE_NX);
8605+ else
8606+#endif
8607+ return pte_clear_flags(pte, _PAGE_USER);
8608 }
8609
8610 static inline pte_t pte_mkdirty(pte_t pte)
16454cff 8611@@ -390,6 +449,15 @@ pte_t *populate_extra_pte(unsigned long
df50ba0c
MT
8612 #endif
8613
8614 #ifndef __ASSEMBLY__
8615+
8616+#ifdef CONFIG_PAX_PER_CPU_PGD
8617+extern pgd_t cpu_pgd[NR_CPUS][PTRS_PER_PGD];
8618+static inline pgd_t *get_cpu_pgd(unsigned int cpu)
8619+{
8620+ return cpu_pgd[cpu];
8621+}
8622+#endif
8623+
8624 #include <linux/mm_types.h>
8625
8626 static inline int pte_none(pte_t pte)
16454cff 8627@@ -560,7 +628,7 @@ static inline pud_t *pud_offset(pgd_t *p
58c5fc13
MT
8628
8629 static inline int pgd_bad(pgd_t pgd)
8630 {
8631- return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
8632+ return (pgd_flags(pgd) & ~(_PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
8633 }
8634
8635 static inline int pgd_none(pgd_t pgd)
16454cff 8636@@ -583,7 +651,12 @@ static inline int pgd_none(pgd_t pgd)
df50ba0c
MT
8637 * pgd_offset() returns a (pgd_t *)
8638 * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
8639 */
8640-#define pgd_offset(mm, address) ((mm)->pgd + pgd_index((address)))
8641+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
8642+
8643+#ifdef CONFIG_PAX_PER_CPU_PGD
8644+#define pgd_offset_cpu(cpu, address) (get_cpu_pgd(cpu) + pgd_index(address))
8645+#endif
8646+
8647 /*
8648 * a shortcut which implies the use of the kernel's pgd, instead
8649 * of a process's
16454cff 8650@@ -594,6 +667,20 @@ static inline int pgd_none(pgd_t pgd)
df50ba0c
MT
8651 #define KERNEL_PGD_BOUNDARY pgd_index(PAGE_OFFSET)
8652 #define KERNEL_PGD_PTRS (PTRS_PER_PGD - KERNEL_PGD_BOUNDARY)
8653
8654+#ifdef CONFIG_X86_32
8655+#define USER_PGD_PTRS KERNEL_PGD_BOUNDARY
8656+#else
8657+#define TASK_SIZE_MAX_SHIFT CONFIG_TASK_SIZE_MAX_SHIFT
8658+#define USER_PGD_PTRS (_AC(1,UL) << (TASK_SIZE_MAX_SHIFT - PGDIR_SHIFT))
8659+
8660+#ifdef CONFIG_PAX_MEMORY_UDEREF
8661+#define PAX_USER_SHADOW_BASE (_AC(1,UL) << TASK_SIZE_MAX_SHIFT)
8662+#else
8663+#define PAX_USER_SHADOW_BASE (_AC(0,UL))
8664+#endif
8665+
8666+#endif
8667+
8668 #ifndef __ASSEMBLY__
8669
8670 extern int direct_gbpages;
16454cff 8671@@ -758,11 +845,23 @@ static inline void pmdp_set_wrprotect(st
ae4e228f
MT
8672 * dst and src can be on the same page, but the range must not overlap,
8673 * and must not cross a page boundary.
58c5fc13 8674 */
ae4e228f
MT
8675-static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
8676+static inline void clone_pgd_range(pgd_t *dst, const pgd_t *src, int count)
58c5fc13
MT
8677 {
8678- memcpy(dst, src, count * sizeof(pgd_t));
ae4e228f
MT
8679+ pax_open_kernel();
8680+ while (count--)
8681+ *dst++ = *src++;
8682+ pax_close_kernel();
58c5fc13
MT
8683 }
8684
df50ba0c
MT
8685+#ifdef CONFIG_PAX_PER_CPU_PGD
8686+extern void __clone_user_pgds(pgd_t *dst, const pgd_t *src, int count);
8687+#endif
8688+
8689+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
8690+extern void __shadow_user_pgds(pgd_t *dst, const pgd_t *src, int count);
8691+#else
8692+static inline void __shadow_user_pgds(pgd_t *dst, const pgd_t *src, int count) {}
8693+#endif
58c5fc13 8694
df50ba0c
MT
8695 #include <asm-generic/pgtable.h>
8696 #endif /* __ASSEMBLY__ */
16454cff
MT
8697diff -urNp linux-2.6.38.1/arch/x86/include/asm/pgtable_types.h linux-2.6.38.1/arch/x86/include/asm/pgtable_types.h
8698--- linux-2.6.38.1/arch/x86/include/asm/pgtable_types.h 2011-03-14 21:20:32.000000000 -0400
8699+++ linux-2.6.38.1/arch/x86/include/asm/pgtable_types.h 2011-03-21 18:31:35.000000000 -0400
8700@@ -16,13 +16,12 @@
58c5fc13
MT
8701 #define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
8702 #define _PAGE_BIT_PAT 7 /* on 4KB pages */
8703 #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
8704-#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
8705+#define _PAGE_BIT_SPECIAL 9 /* special mappings, no associated struct page */
8706 #define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
8707 #define _PAGE_BIT_HIDDEN 11 /* hidden by kmemcheck */
8708 #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
8709-#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
8710-#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1
16454cff 8711-#define _PAGE_BIT_SPLITTING _PAGE_BIT_UNUSED1 /* only valid on a PSE pmd */
58c5fc13 8712+#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SPECIAL
16454cff 8713+#define _PAGE_BIT_SPLITTING _PAGE_BIT_SPECIAL /* only valid on a PSE pmd */
58c5fc13
MT
8714 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
8715
8716 /* If _PAGE_BIT_PRESENT is clear, we use these: */
16454cff 8717@@ -40,7 +39,6 @@
58c5fc13
MT
8718 #define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
8719 #define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
8720 #define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
8721-#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
8722 #define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
8723 #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
8724 #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
16454cff 8725@@ -57,8 +55,10 @@
58c5fc13
MT
8726
8727 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
8728 #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
8729-#else
8730+#elif defined(CONFIG_KMEMCHECK)
8731 #define _PAGE_NX (_AT(pteval_t, 0))
8732+#else
8733+#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN)
8734 #endif
8735
8736 #define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE)
16454cff 8737@@ -96,6 +96,9 @@
58c5fc13
MT
8738 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
8739 _PAGE_ACCESSED)
8740
8741+#define PAGE_READONLY_NOEXEC PAGE_READONLY
8742+#define PAGE_SHARED_NOEXEC PAGE_SHARED
8743+
8744 #define __PAGE_KERNEL_EXEC \
8745 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
8746 #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
16454cff 8747@@ -106,8 +109,8 @@
58c5fc13
MT
8748 #define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC)
8749 #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
8750 #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
8751-#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
8752-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
8753+#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RO | _PAGE_USER)
8754+#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
8755 #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
8756 #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
8757 #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
16454cff 8758@@ -166,8 +169,8 @@
58c5fc13
MT
8759 * bits are combined, this will alow user to access the high address mapped
8760 * VDSO in the presence of CONFIG_COMPAT_VDSO
8761 */
8762-#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
8763-#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
8764+#define PTE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
8765+#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
8766 #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
8767 #endif
8768
16454cff 8769@@ -205,7 +208,17 @@ static inline pgdval_t pgd_flags(pgd_t p
57199397
MT
8770 {
8771 return native_pgd_val(pgd) & PTE_FLAGS_MASK;
8772 }
8773+#endif
8774
8775+#if PAGETABLE_LEVELS == 3
8776+#include <asm-generic/pgtable-nopud.h>
8777+#endif
8778+
8779+#if PAGETABLE_LEVELS == 2
8780+#include <asm-generic/pgtable-nopmd.h>
8781+#endif
8782+
8783+#ifndef __ASSEMBLY__
8784 #if PAGETABLE_LEVELS > 3
8785 typedef struct { pudval_t pud; } pud_t;
8786
16454cff 8787@@ -219,8 +232,6 @@ static inline pudval_t native_pud_val(pu
57199397
MT
8788 return pud.pud;
8789 }
8790 #else
8791-#include <asm-generic/pgtable-nopud.h>
8792-
8793 static inline pudval_t native_pud_val(pud_t pud)
8794 {
8795 return native_pgd_val(pud.pgd);
16454cff 8796@@ -240,8 +251,6 @@ static inline pmdval_t native_pmd_val(pm
57199397
MT
8797 return pmd.pmd;
8798 }
8799 #else
8800-#include <asm-generic/pgtable-nopmd.h>
8801-
8802 static inline pmdval_t native_pmd_val(pmd_t pmd)
8803 {
8804 return native_pgd_val(pmd.pud.pgd);
16454cff 8805@@ -281,7 +290,6 @@ typedef struct page *pgtable_t;
58c5fc13
MT
8806
8807 extern pteval_t __supported_pte_mask;
ae4e228f
MT
8808 extern void set_nx(void);
8809-extern int nx_enabled;
58c5fc13
MT
8810
8811 #define pgprot_writecombine pgprot_writecombine
8812 extern pgprot_t pgprot_writecombine(pgprot_t prot);
16454cff
MT
8813diff -urNp linux-2.6.38.1/arch/x86/include/asm/processor.h linux-2.6.38.1/arch/x86/include/asm/processor.h
8814--- linux-2.6.38.1/arch/x86/include/asm/processor.h 2011-03-14 21:20:32.000000000 -0400
8815+++ linux-2.6.38.1/arch/x86/include/asm/processor.h 2011-03-21 18:31:35.000000000 -0400
8816@@ -270,7 +270,7 @@ struct tss_struct {
58c5fc13
MT
8817
8818 } ____cacheline_aligned;
8819
8820-DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);
8821+extern struct tss_struct init_tss[NR_CPUS];
8822
8823 /*
8824 * Save the original ist values for checking stack pointers during debugging
bc901d79 8825@@ -864,8 +864,15 @@ static inline void spin_lock_prefetch(co
58c5fc13
MT
8826 */
8827 #define TASK_SIZE PAGE_OFFSET
8828 #define TASK_SIZE_MAX TASK_SIZE
8829+
8830+#ifdef CONFIG_PAX_SEGMEXEC
8831+#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
58c5fc13
MT
8832+#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
8833+#else
8834 #define STACK_TOP TASK_SIZE
8835-#define STACK_TOP_MAX STACK_TOP
8836+#endif
ae4e228f 8837+
58c5fc13
MT
8838+#define STACK_TOP_MAX TASK_SIZE
8839
8840 #define INIT_THREAD { \
8841 .sp0 = sizeof(init_stack) + (long)&init_stack, \
bc901d79 8842@@ -882,7 +889,7 @@ static inline void spin_lock_prefetch(co
58c5fc13
MT
8843 */
8844 #define INIT_TSS { \
8845 .x86_tss = { \
8846- .sp0 = sizeof(init_stack) + (long)&init_stack, \
8847+ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
8848 .ss0 = __KERNEL_DS, \
8849 .ss1 = __KERNEL_CS, \
8850 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
bc901d79 8851@@ -893,11 +900,7 @@ static inline void spin_lock_prefetch(co
58c5fc13
MT
8852 extern unsigned long thread_saved_pc(struct task_struct *tsk);
8853
8854 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
8855-#define KSTK_TOP(info) \
8856-({ \
8857- unsigned long *__ptr = (unsigned long *)(info); \
8858- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
8859-})
8860+#define KSTK_TOP(info) ((info)->task.thread.sp0)
8861
8862 /*
8863 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
bc901d79 8864@@ -912,7 +915,7 @@ extern unsigned long thread_saved_pc(str
58c5fc13
MT
8865 #define task_pt_regs(task) \
8866 ({ \
8867 struct pt_regs *__regs__; \
8868- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
8869+ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
8870 __regs__ - 1; \
8871 })
8872
bc901d79 8873@@ -922,13 +925,13 @@ extern unsigned long thread_saved_pc(str
df50ba0c
MT
8874 /*
8875 * User space process size. 47bits minus one guard page.
8876 */
8877-#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
8878+#define TASK_SIZE_MAX ((1UL << TASK_SIZE_MAX_SHIFT) - PAGE_SIZE)
8879
8880 /* This decides where the kernel will search for a free chunk of vm
58c5fc13
MT
8881 * space during mmap's.
8882 */
8883 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
8884- 0xc0000000 : 0xFFFFe000)
8885+ 0xc0000000 : 0xFFFFf000)
8886
8887 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
8888 IA32_PAGE_OFFSET : TASK_SIZE_MAX)
bc901d79 8889@@ -965,6 +968,10 @@ extern void start_thread(struct pt_regs
58c5fc13
MT
8890 */
8891 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
8892
8893+#ifdef CONFIG_PAX_SEGMEXEC
8894+#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
8895+#endif
8896+
8897 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
8898
8899 /* Get/set a process' ability to use the timestamp counter instruction */
16454cff
MT
8900diff -urNp linux-2.6.38.1/arch/x86/include/asm/ptrace.h linux-2.6.38.1/arch/x86/include/asm/ptrace.h
8901--- linux-2.6.38.1/arch/x86/include/asm/ptrace.h 2011-03-14 21:20:32.000000000 -0400
8902+++ linux-2.6.38.1/arch/x86/include/asm/ptrace.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 8903@@ -152,28 +152,29 @@ static inline unsigned long regs_return_
58c5fc13
MT
8904 }
8905
8906 /*
8907- * user_mode_vm(regs) determines whether a register set came from user mode.
8908+ * user_mode(regs) determines whether a register set came from user mode.
8909 * This is true if V8086 mode was enabled OR if the register set was from
8910 * protected mode with RPL-3 CS value. This tricky test checks that with
8911 * one comparison. Many places in the kernel can bypass this full check
8912- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
8913+ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
8914+ * be used.
8915 */
8916-static inline int user_mode(struct pt_regs *regs)
8917+static inline int user_mode_novm(struct pt_regs *regs)
8918 {
8919 #ifdef CONFIG_X86_32
8920 return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
8921 #else
8922- return !!(regs->cs & 3);
8923+ return !!(regs->cs & SEGMENT_RPL_MASK);
8924 #endif
8925 }
8926
8927-static inline int user_mode_vm(struct pt_regs *regs)
8928+static inline int user_mode(struct pt_regs *regs)
8929 {
8930 #ifdef CONFIG_X86_32
8931 return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
8932 USER_RPL;
8933 #else
8934- return user_mode(regs);
8935+ return user_mode_novm(regs);
8936 #endif
8937 }
8938
16454cff
MT
8939diff -urNp linux-2.6.38.1/arch/x86/include/asm/reboot.h linux-2.6.38.1/arch/x86/include/asm/reboot.h
8940--- linux-2.6.38.1/arch/x86/include/asm/reboot.h 2011-03-14 21:20:32.000000000 -0400
8941+++ linux-2.6.38.1/arch/x86/include/asm/reboot.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
8942@@ -18,7 +18,7 @@ extern struct machine_ops machine_ops;
8943
8944 void native_machine_crash_shutdown(struct pt_regs *regs);
8945 void native_machine_shutdown(void);
8946-void machine_real_restart(const unsigned char *code, int length);
8947+void machine_real_restart(const unsigned char *code, unsigned int length);
8948
8949 typedef void (*nmi_shootdown_cb)(int, struct die_args*);
8950 void nmi_shootdown_cpus(nmi_shootdown_cb callback);
16454cff
MT
8951diff -urNp linux-2.6.38.1/arch/x86/include/asm/rwsem.h linux-2.6.38.1/arch/x86/include/asm/rwsem.h
8952--- linux-2.6.38.1/arch/x86/include/asm/rwsem.h 2011-03-14 21:20:32.000000000 -0400
8953+++ linux-2.6.38.1/arch/x86/include/asm/rwsem.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 8954@@ -118,6 +118,14 @@ static inline void __down_read(struct rw
58c5fc13
MT
8955 {
8956 asm volatile("# beginning down_read\n\t"
df50ba0c 8957 LOCK_PREFIX _ASM_INC "(%1)\n\t"
58c5fc13
MT
8958+
8959+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 8960+ "jno 0f\n"
df50ba0c 8961+ LOCK_PREFIX _ASM_DEC "(%1)\n"
bc901d79
MT
8962+ "int $4\n0:\n"
8963+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
8964+#endif
8965+
6892158b 8966 /* adds 0x00000001 */
bc901d79 8967 " jns 1f\n"
58c5fc13 8968 " call call_rwsem_down_read_failed\n"
bc901d79
MT
8969@@ -139,6 +147,14 @@ static inline int __down_read_trylock(st
8970 "1:\n\t"
df50ba0c
MT
8971 " mov %1,%2\n\t"
8972 " add %3,%2\n\t"
58c5fc13
MT
8973+
8974+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 8975+ "jno 0f\n"
df50ba0c 8976+ "sub %3,%2\n"
bc901d79
MT
8977+ "int $4\n0:\n"
8978+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
8979+#endif
8980+
bc901d79 8981 " jle 2f\n\t"
df50ba0c 8982 LOCK_PREFIX " cmpxchg %2,%0\n\t"
bc901d79
MT
8983 " jnz 1b\n\t"
8984@@ -158,6 +174,14 @@ static inline void __down_write_nested(s
6892158b 8985 rwsem_count_t tmp;
58c5fc13 8986 asm volatile("# beginning down_write\n\t"
df50ba0c 8987 LOCK_PREFIX " xadd %1,(%2)\n\t"
58c5fc13
MT
8988+
8989+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 8990+ "jno 0f\n"
df50ba0c 8991+ "mov %1,(%2)\n"
bc901d79
MT
8992+ "int $4\n0:\n"
8993+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
8994+#endif
8995+
6892158b 8996 /* adds 0xffff0001, returns the old value */
df50ba0c 8997 " test %1,%1\n\t"
58c5fc13 8998 /* was the count 0 before? */
bc901d79 8999@@ -196,6 +220,14 @@ static inline void __up_read(struct rw_s
6892158b 9000 rwsem_count_t tmp;
58c5fc13 9001 asm volatile("# beginning __up_read\n\t"
df50ba0c 9002 LOCK_PREFIX " xadd %1,(%2)\n\t"
58c5fc13
MT
9003+
9004+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9005+ "jno 0f\n"
df50ba0c 9006+ "mov %1,(%2)\n"
bc901d79
MT
9007+ "int $4\n0:\n"
9008+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9009+#endif
9010+
9011 /* subtracts 1, returns the old value */
bc901d79 9012 " jns 1f\n\t"
6892158b 9013 " call call_rwsem_wake\n" /* expects old value in %edx */
bc901d79 9014@@ -214,6 +246,14 @@ static inline void __up_write(struct rw_
df50ba0c 9015 rwsem_count_t tmp;
58c5fc13 9016 asm volatile("# beginning __up_write\n\t"
df50ba0c 9017 LOCK_PREFIX " xadd %1,(%2)\n\t"
58c5fc13
MT
9018+
9019+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9020+ "jno 0f\n"
df50ba0c 9021+ "mov %1,(%2)\n"
bc901d79
MT
9022+ "int $4\n0:\n"
9023+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9024+#endif
9025+
6892158b 9026 /* subtracts 0xffff0001, returns the old value */
bc901d79 9027 " jns 1f\n\t"
6892158b 9028 " call call_rwsem_wake\n" /* expects old value in %edx */
bc901d79 9029@@ -231,6 +271,14 @@ static inline void __downgrade_write(str
58c5fc13
MT
9030 {
9031 asm volatile("# beginning __downgrade_write\n\t"
df50ba0c 9032 LOCK_PREFIX _ASM_ADD "%2,(%1)\n\t"
58c5fc13
MT
9033+
9034+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9035+ "jno 0f\n"
df50ba0c 9036+ LOCK_PREFIX _ASM_SUB "%2,(%1)\n"
bc901d79
MT
9037+ "int $4\n0:\n"
9038+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9039+#endif
9040+
df50ba0c
MT
9041 /*
9042 * transitions 0xZZZZ0001 -> 0xYYYY0001 (i386)
9043 * 0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 (x86_64)
bc901d79 9044@@ -250,7 +298,15 @@ static inline void __downgrade_write(str
df50ba0c
MT
9045 static inline void rwsem_atomic_add(rwsem_count_t delta,
9046 struct rw_semaphore *sem)
58c5fc13 9047 {
df50ba0c
MT
9048- asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0"
9049+ asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0\n"
58c5fc13
MT
9050+
9051+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9052+ "jno 0f\n"
df50ba0c 9053+ LOCK_PREFIX _ASM_SUB "%1,%0\n"
bc901d79
MT
9054+ "int $4\n0:\n"
9055+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9056+#endif
9057+
9058 : "+m" (sem->count)
df50ba0c 9059 : "er" (delta));
58c5fc13 9060 }
bc901d79 9061@@ -263,7 +319,15 @@ static inline rwsem_count_t rwsem_atomic
58c5fc13 9062 {
df50ba0c 9063 rwsem_count_t tmp = delta;
58c5fc13
MT
9064
9065- asm volatile(LOCK_PREFIX "xadd %0,%1"
9066+ asm volatile(LOCK_PREFIX "xadd %0,%1\n"
9067+
9068+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9069+ "jno 0f\n"
df50ba0c 9070+ "mov %0,%1\n"
bc901d79
MT
9071+ "int $4\n0:\n"
9072+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9073+#endif
9074+
9075 : "+r" (tmp), "+m" (sem->count)
9076 : : "memory");
9077
16454cff
MT
9078diff -urNp linux-2.6.38.1/arch/x86/include/asm/segment.h linux-2.6.38.1/arch/x86/include/asm/segment.h
9079--- linux-2.6.38.1/arch/x86/include/asm/segment.h 2011-03-14 21:20:32.000000000 -0400
9080+++ linux-2.6.38.1/arch/x86/include/asm/segment.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
9081@@ -62,8 +62,8 @@
9082 * 26 - ESPFIX small SS
9083 * 27 - per-cpu [ offset to per-cpu data area ]
9084 * 28 - stack_canary-20 [ for stack protector ]
9085- * 29 - unused
9086- * 30 - unused
9087+ * 29 - PCI BIOS CS
9088+ * 30 - PCI BIOS DS
9089 * 31 - TSS for double fault handler
9090 */
9091 #define GDT_ENTRY_TLS_MIN 6
9092@@ -77,6 +77,8 @@
9093
bc901d79 9094 #define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE+0)
ae4e228f
MT
9095
9096+#define GDT_ENTRY_KERNEXEC_KERNEL_CS (4)
9097+
bc901d79 9098 #define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE+1)
58c5fc13 9099
bc901d79 9100 #define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE+4)
ae4e228f 9101@@ -102,6 +104,12 @@
58c5fc13
MT
9102 #define __KERNEL_STACK_CANARY 0
9103 #endif
9104
bc901d79 9105+#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE+17)
58c5fc13
MT
9106+#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
9107+
bc901d79 9108+#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE+18)
58c5fc13
MT
9109+#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
9110+
9111 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
9112
9113 /*
ae4e228f 9114@@ -139,7 +147,7 @@
58c5fc13
MT
9115 */
9116
9117 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
9118-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
9119+#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
9120
9121
9122 #else
ae4e228f
MT
9123@@ -163,6 +171,8 @@
9124 #define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS * 8 + 3)
9125 #define __USER32_DS __USER_DS
9126
9127+#define GDT_ENTRY_KERNEXEC_KERNEL_CS 7
9128+
9129 #define GDT_ENTRY_TSS 8 /* needs two entries */
9130 #define GDT_ENTRY_LDT 10 /* needs two entries */
9131 #define GDT_ENTRY_TLS_MIN 12
9132@@ -183,6 +193,7 @@
9133 #endif
9134
bc901d79
MT
9135 #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
9136+#define __KERNEXEC_KERNEL_CS (GDT_ENTRY_KERNEXEC_KERNEL_CS*8)
9137 #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
9138 #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3)
9139 #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3)
16454cff
MT
9140diff -urNp linux-2.6.38.1/arch/x86/include/asm/smp.h linux-2.6.38.1/arch/x86/include/asm/smp.h
9141--- linux-2.6.38.1/arch/x86/include/asm/smp.h 2011-03-14 21:20:32.000000000 -0400
9142+++ linux-2.6.38.1/arch/x86/include/asm/smp.h 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
9143@@ -24,7 +24,7 @@ extern unsigned int num_processors;
9144 DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
9145 DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
9146 DECLARE_PER_CPU(u16, cpu_llc_id);
9147-DECLARE_PER_CPU(int, cpu_number);
9148+DECLARE_PER_CPU(unsigned int, cpu_number);
9149
9150 static inline struct cpumask *cpu_sibling_mask(int cpu)
9151 {
16454cff
MT
9152diff -urNp linux-2.6.38.1/arch/x86/include/asm/spinlock.h linux-2.6.38.1/arch/x86/include/asm/spinlock.h
9153--- linux-2.6.38.1/arch/x86/include/asm/spinlock.h 2011-03-14 21:20:32.000000000 -0400
9154+++ linux-2.6.38.1/arch/x86/include/asm/spinlock.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 9155@@ -249,6 +249,14 @@ static inline int arch_write_can_lock(ar
ae4e228f 9156 static inline void arch_read_lock(arch_rwlock_t *rw)
58c5fc13
MT
9157 {
9158 asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
58c5fc13
MT
9159+
9160+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9161+ "jno 0f\n"
58c5fc13 9162+ LOCK_PREFIX " addl $1,(%0)\n"
bc901d79
MT
9163+ "int $4\n0:\n"
9164+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9165+#endif
9166+
bc901d79
MT
9167 "jns 1f\n"
9168 "call __read_lock_failed\n\t"
9169 "1:\n"
9170@@ -258,6 +266,14 @@ static inline void arch_read_lock(arch_r
ae4e228f 9171 static inline void arch_write_lock(arch_rwlock_t *rw)
58c5fc13
MT
9172 {
9173 asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
58c5fc13
MT
9174+
9175+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9176+ "jno 0f\n"
58c5fc13 9177+ LOCK_PREFIX " addl %1,(%0)\n"
bc901d79
MT
9178+ "int $4\n0:\n"
9179+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9180+#endif
9181+
bc901d79
MT
9182 "jz 1f\n"
9183 "call __write_lock_failed\n\t"
9184 "1:\n"
9185@@ -286,12 +302,29 @@ static inline int arch_write_trylock(arc
58c5fc13 9186
ae4e228f 9187 static inline void arch_read_unlock(arch_rwlock_t *rw)
58c5fc13
MT
9188 {
9189- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
9190+ asm volatile(LOCK_PREFIX "incl %0\n"
9191+
9192+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9193+ "jno 0f\n"
58c5fc13 9194+ LOCK_PREFIX "decl %0\n"
bc901d79
MT
9195+ "int $4\n0:\n"
9196+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9197+#endif
9198+
9199+ :"+m" (rw->lock) : : "memory");
9200 }
9201
ae4e228f 9202 static inline void arch_write_unlock(arch_rwlock_t *rw)
58c5fc13
MT
9203 {
9204- asm volatile(LOCK_PREFIX "addl %1, %0"
9205+ asm volatile(LOCK_PREFIX "addl %1, %0\n"
9206+
9207+#ifdef CONFIG_PAX_REFCOUNT
58c5fc13 9208+ "jno 0f\n"
bc901d79 9209+ LOCK_PREFIX "subl %1, %0\n"
58c5fc13 9210+ "int $4\n0:\n"
bc901d79 9211+ _ASM_EXTABLE(0b, 0b)
58c5fc13
MT
9212+#endif
9213+
9214 : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
9215 }
9216
16454cff
MT
9217diff -urNp linux-2.6.38.1/arch/x86/include/asm/stackprotector.h linux-2.6.38.1/arch/x86/include/asm/stackprotector.h
9218--- linux-2.6.38.1/arch/x86/include/asm/stackprotector.h 2011-03-14 21:20:32.000000000 -0400
9219+++ linux-2.6.38.1/arch/x86/include/asm/stackprotector.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
9220@@ -113,7 +113,7 @@ static inline void setup_stack_canary_se
9221
9222 static inline void load_stack_canary_segment(void)
9223 {
9224-#ifdef CONFIG_X86_32
9225+#if defined(CONFIG_X86_32) && !defined(CONFIG_PAX_MEMORY_UDEREF)
9226 asm volatile ("mov %0, %%gs" : : "r" (0));
9227 #endif
9228 }
16454cff
MT
9229diff -urNp linux-2.6.38.1/arch/x86/include/asm/system.h linux-2.6.38.1/arch/x86/include/asm/system.h
9230--- linux-2.6.38.1/arch/x86/include/asm/system.h 2011-03-14 21:20:32.000000000 -0400
9231+++ linux-2.6.38.1/arch/x86/include/asm/system.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 9232@@ -202,7 +202,7 @@ static inline unsigned long get_limit(un
58c5fc13
MT
9233 {
9234 unsigned long __limit;
9235 asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
9236- return __limit + 1;
9237+ return __limit;
9238 }
9239
9240 static inline void native_clts(void)
ae4e228f 9241@@ -342,7 +342,7 @@ void enable_hlt(void);
58c5fc13
MT
9242
9243 void cpu_idle_wait(void);
9244
9245-extern unsigned long arch_align_stack(unsigned long sp);
9246+#define arch_align_stack(x) ((x) & ~0xfUL)
9247 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
9248
9249 void default_idle(void);
16454cff
MT
9250diff -urNp linux-2.6.38.1/arch/x86/include/asm/uaccess_32.h linux-2.6.38.1/arch/x86/include/asm/uaccess_32.h
9251--- linux-2.6.38.1/arch/x86/include/asm/uaccess_32.h 2011-03-14 21:20:32.000000000 -0400
9252+++ linux-2.6.38.1/arch/x86/include/asm/uaccess_32.h 2011-03-21 18:31:35.000000000 -0400
efbe55a5 9253@@ -44,6 +44,9 @@ unsigned long __must_check __copy_from_u
58c5fc13
MT
9254 static __always_inline unsigned long __must_check
9255 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
9256 {
9257+ if ((long)n < 0)
9258+ return n;
9259+
9260 if (__builtin_constant_p(n)) {
9261 unsigned long ret;
9262
efbe55a5 9263@@ -62,6 +65,8 @@ __copy_to_user_inatomic(void __user *to,
58c5fc13
MT
9264 return ret;
9265 }
9266 }
9267+ if (!__builtin_constant_p(n))
9268+ check_object_size(from, n, true);
9269 return __copy_to_user_ll(to, from, n);
9270 }
9271
efbe55a5 9272@@ -89,6 +94,9 @@ __copy_to_user(void __user *to, const vo
58c5fc13
MT
9273 static __always_inline unsigned long
9274 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
9275 {
9276+ if ((long)n < 0)
9277+ return n;
9278+
9279 /* Avoid zeroing the tail if the copy fails..
9280 * If 'n' is constant and 1, 2, or 4, we do still zero on a failure,
9281 * but as the zeroing behaviour is only significant when n is not
efbe55a5 9282@@ -138,6 +146,10 @@ static __always_inline unsigned long
58c5fc13
MT
9283 __copy_from_user(void *to, const void __user *from, unsigned long n)
9284 {
9285 might_fault();
9286+
9287+ if ((long)n < 0)
9288+ return n;
9289+
9290 if (__builtin_constant_p(n)) {
9291 unsigned long ret;
9292
efbe55a5 9293@@ -153,6 +165,8 @@ __copy_from_user(void *to, const void __
58c5fc13
MT
9294 return ret;
9295 }
9296 }
9297+ if (!__builtin_constant_p(n))
9298+ check_object_size(to, n, false);
9299 return __copy_from_user_ll(to, from, n);
9300 }
9301
efbe55a5 9302@@ -160,6 +174,10 @@ static __always_inline unsigned long __c
58c5fc13
MT
9303 const void __user *from, unsigned long n)
9304 {
9305 might_fault();
9306+
9307+ if ((long)n < 0)
9308+ return n;
9309+
9310 if (__builtin_constant_p(n)) {
9311 unsigned long ret;
9312
efbe55a5 9313@@ -182,15 +200,19 @@ static __always_inline unsigned long
58c5fc13
MT
9314 __copy_from_user_inatomic_nocache(void *to, const void __user *from,
9315 unsigned long n)
9316 {
9317- return __copy_from_user_ll_nocache_nozero(to, from, n);
ae4e228f 9318-}
58c5fc13
MT
9319+ if ((long)n < 0)
9320+ return n;
ae4e228f
MT
9321
9322-unsigned long __must_check copy_to_user(void __user *to,
9323- const void *from, unsigned long n);
9324-unsigned long __must_check _copy_from_user(void *to,
9325- const void __user *from,
9326- unsigned long n);
58c5fc13
MT
9327+ return __copy_from_user_ll_nocache_nozero(to, from, n);
9328+}
ae4e228f
MT
9329
9330+extern void copy_to_user_overflow(void)
9331+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
9332+ __compiletime_error("copy_to_user() buffer size is not provably correct")
9333+#else
9334+ __compiletime_warning("copy_to_user() buffer size is not provably correct")
9335+#endif
9336+;
9337
9338 extern void copy_from_user_overflow(void)
9339 #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
efbe55a5 9340@@ -200,17 +222,61 @@ extern void copy_from_user_overflow(void
ae4e228f
MT
9341 #endif
9342 ;
9343
9344-static inline unsigned long __must_check copy_from_user(void *to,
9345- const void __user *from,
9346- unsigned long n)
58c5fc13
MT
9347+/**
9348+ * copy_to_user: - Copy a block of data into user space.
9349+ * @to: Destination address, in user space.
9350+ * @from: Source address, in kernel space.
9351+ * @n: Number of bytes to copy.
9352+ *
9353+ * Context: User context only. This function may sleep.
9354+ *
9355+ * Copy data from kernel space to user space.
9356+ *
9357+ * Returns number of bytes that could not be copied.
9358+ * On success, this will be zero.
9359+ */
ae4e228f 9360+static inline unsigned long __must_check
58c5fc13
MT
9361+copy_to_user(void __user *to, const void *from, unsigned long n)
9362+{
ae4e228f
MT
9363+ int sz = __compiletime_object_size(from);
9364+
9365+ if (unlikely(sz != -1 && sz < n))
9366+ copy_to_user_overflow();
9367+ else if (access_ok(VERIFY_WRITE, to, n))
58c5fc13
MT
9368+ n = __copy_to_user(to, from, n);
9369+ return n;
9370+}
9371+
9372+/**
9373+ * copy_from_user: - Copy a block of data from user space.
9374+ * @to: Destination address, in kernel space.
9375+ * @from: Source address, in user space.
9376+ * @n: Number of bytes to copy.
9377+ *
9378+ * Context: User context only. This function may sleep.
9379+ *
9380+ * Copy data from user space to kernel space.
9381+ *
9382+ * Returns number of bytes that could not be copied.
9383+ * On success, this will be zero.
9384+ *
9385+ * If some data could not be copied, this function will pad the copied
9386+ * data to the requested size using zero bytes.
9387+ */
ae4e228f 9388+static inline unsigned long __must_check
58c5fc13 9389+copy_from_user(void *to, const void __user *from, unsigned long n)
ae4e228f
MT
9390 {
9391 int sz = __compiletime_object_size(to);
9392
9393- if (likely(sz == -1 || sz >= n))
9394- n = _copy_from_user(to, from, n);
9395- else
9396+ if (unlikely(sz != -1 && sz < n))
9397 copy_from_user_overflow();
9398-
9399+ else if (access_ok(VERIFY_READ, from, n))
58c5fc13
MT
9400+ n = __copy_from_user(to, from, n);
9401+ else if ((long)n > 0) {
9402+ if (!__builtin_constant_p(n))
9403+ check_object_size(to, n, false);
9404+ memset(to, 0, n);
9405+ }
ae4e228f 9406 return n;
58c5fc13
MT
9407 }
9408
16454cff
MT
9409diff -urNp linux-2.6.38.1/arch/x86/include/asm/uaccess_64.h linux-2.6.38.1/arch/x86/include/asm/uaccess_64.h
9410--- linux-2.6.38.1/arch/x86/include/asm/uaccess_64.h 2011-03-14 21:20:32.000000000 -0400
9411+++ linux-2.6.38.1/arch/x86/include/asm/uaccess_64.h 2011-03-21 18:31:35.000000000 -0400
6892158b 9412@@ -11,6 +11,9 @@
df50ba0c
MT
9413 #include <asm/alternative.h>
9414 #include <asm/cpufeature.h>
58c5fc13 9415 #include <asm/page.h>
df50ba0c
MT
9416+#include <asm/pgtable.h>
9417+
58c5fc13 9418+#define set_fs(x) (current_thread_info()->addr_limit = (x))
df50ba0c 9419
58c5fc13
MT
9420 /*
9421 * Copy To/From Userspace
6892158b 9422@@ -37,26 +40,26 @@ copy_user_generic(void *to, const void *
df50ba0c
MT
9423 return ret;
9424 }
9425
58c5fc13 9426-__must_check unsigned long
ae4e228f 9427-_copy_to_user(void __user *to, const void *from, unsigned len);
58c5fc13 9428-__must_check unsigned long
ae4e228f
MT
9429-_copy_from_user(void *to, const void __user *from, unsigned len);
9430+static __always_inline __must_check unsigned long
9431+__copy_to_user(void __user *to, const void *from, unsigned len);
9432+static __always_inline __must_check unsigned long
9433+__copy_from_user(void *to, const void __user *from, unsigned len);
9434 __must_check unsigned long
58c5fc13
MT
9435 copy_in_user(void __user *to, const void __user *from, unsigned len);
9436
ae4e228f
MT
9437 static inline unsigned long __must_check copy_from_user(void *to,
9438 const void __user *from,
9439- unsigned long n)
9440+ unsigned n)
9441 {
9442- int sz = __compiletime_object_size(to);
9443-
9444 might_fault();
9445- if (likely(sz == -1 || sz >= n))
9446- n = _copy_from_user(to, from, n);
9447-#ifdef CONFIG_DEBUG_VM
9448- else
9449- WARN(1, "Buffer overflow detected!\n");
9450-#endif
9451+
9452+ if (access_ok(VERIFY_READ, from, n))
9453+ n = __copy_from_user(to, from, n);
9454+ else if ((int)n > 0) {
9455+ if (!__builtin_constant_p(n))
9456+ check_object_size(to, n, false);
9457+ memset(to, 0, n);
9458+ }
9459 return n;
9460 }
9461
bc901d79 9462@@ -65,110 +68,174 @@ int copy_to_user(void __user *dst, const
ae4e228f
MT
9463 {
9464 might_fault();
9465
9466- return _copy_to_user(dst, src, size);
9467+ if (access_ok(VERIFY_WRITE, dst, size))
9468+ size = __copy_to_user(dst, src, size);
9469+ return size;
9470 }
9471
58c5fc13
MT
9472 static __always_inline __must_check
9473-int __copy_from_user(void *dst, const void __user *src, unsigned size)
9474+unsigned long __copy_from_user(void *dst, const void __user *src, unsigned size)
9475 {
9476- int ret = 0;
ae4e228f 9477+ int sz = __compiletime_object_size(dst);
58c5fc13
MT
9478+ unsigned ret = 0;
9479
9480 might_fault();
9481- if (!__builtin_constant_p(size))
bc901d79 9482- return copy_user_generic(dst, (__force void *)src, size);
58c5fc13
MT
9483+
9484+ if ((int)size < 0)
9485+ return size;
9486+
bc901d79
MT
9487+#ifdef CONFIG_PAX_MEMORY_UDEREF
9488+ if (!__access_ok(VERIFY_READ, src, size))
9489+ return size;
9490+#endif
9491+
ae4e228f
MT
9492+ if (unlikely(sz != -1 && sz < size)) {
9493+#ifdef CONFIG_DEBUG_VM
9494+ WARN(1, "Buffer overflow detected!\n");
9495+#endif
9496+ return size;
9497+ }
9498+
58c5fc13
MT
9499+ if (!__builtin_constant_p(size)) {
9500+ check_object_size(dst, size, false);
df50ba0c
MT
9501+ if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9502+ src += PAX_USER_SHADOW_BASE;
bc901d79 9503+ return copy_user_generic(dst, (__force const void *)src, size);
58c5fc13
MT
9504+ }
9505 switch (size) {
bc901d79
MT
9506- case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
9507+ case 1:__get_user_asm(*(u8 *)dst, (const u8 __user *)src,
58c5fc13 9508 ret, "b", "b", "=q", 1);
bc901d79
MT
9509 return ret;
9510- case 2:__get_user_asm(*(u16 *)dst, (u16 __user *)src,
9511+ case 2:__get_user_asm(*(u16 *)dst, (const u16 __user *)src,
9512 ret, "w", "w", "=r", 2);
9513 return ret;
9514- case 4:__get_user_asm(*(u32 *)dst, (u32 __user *)src,
9515+ case 4:__get_user_asm(*(u32 *)dst, (const u32 __user *)src,
9516 ret, "l", "k", "=r", 4);
9517 return ret;
9518- case 8:__get_user_asm(*(u64 *)dst, (u64 __user *)src,
9519+ case 8:__get_user_asm(*(u64 *)dst, (const u64 __user *)src,
9520 ret, "q", "", "=r", 8);
9521 return ret;
9522 case 10:
9523- __get_user_asm(*(u64 *)dst, (u64 __user *)src,
9524+ __get_user_asm(*(u64 *)dst, (const u64 __user *)src,
9525 ret, "q", "", "=r", 10);
9526 if (unlikely(ret))
9527 return ret;
9528 __get_user_asm(*(u16 *)(8 + (char *)dst),
9529- (u16 __user *)(8 + (char __user *)src),
9530+ (const u16 __user *)(8 + (const char __user *)src),
9531 ret, "w", "w", "=r", 2);
9532 return ret;
9533 case 16:
9534- __get_user_asm(*(u64 *)dst, (u64 __user *)src,
9535+ __get_user_asm(*(u64 *)dst, (const u64 __user *)src,
9536 ret, "q", "", "=r", 16);
9537 if (unlikely(ret))
9538 return ret;
9539 __get_user_asm(*(u64 *)(8 + (char *)dst),
9540- (u64 __user *)(8 + (char __user *)src),
9541+ (const u64 __user *)(8 + (const char __user *)src),
df50ba0c
MT
9542 ret, "q", "", "=r", 8);
9543 return ret;
9544 default:
bc901d79 9545- return copy_user_generic(dst, (__force void *)src, size);
df50ba0c
MT
9546+ if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9547+ src += PAX_USER_SHADOW_BASE;
bc901d79 9548+ return copy_user_generic(dst, (__force const void *)src, size);
df50ba0c 9549 }
58c5fc13
MT
9550 }
9551
9552 static __always_inline __must_check
9553-int __copy_to_user(void __user *dst, const void *src, unsigned size)
9554+unsigned long __copy_to_user(void __user *dst, const void *src, unsigned size)
9555 {
9556- int ret = 0;
ae4e228f 9557+ int sz = __compiletime_object_size(src);
58c5fc13
MT
9558+ unsigned ret = 0;
9559
9560 might_fault();
9561- if (!__builtin_constant_p(size))
9562+
9563+ if ((int)size < 0)
9564+ return size;
9565+
bc901d79
MT
9566+#ifdef CONFIG_PAX_MEMORY_UDEREF
9567+ if (!__access_ok(VERIFY_WRITE, dst, size))
9568+ return size;
9569+#endif
9570+
ae4e228f
MT
9571+ if (unlikely(sz != -1 && sz < size)) {
9572+#ifdef CONFIG_DEBUG_VM
9573+ WARN(1, "Buffer overflow detected!\n");
9574+#endif
9575+ return size;
9576+ }
9577+
58c5fc13
MT
9578+ if (!__builtin_constant_p(size)) {
9579+ check_object_size(src, size, true);
df50ba0c
MT
9580+ if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9581+ dst += PAX_USER_SHADOW_BASE;
58c5fc13
MT
9582 return copy_user_generic((__force void *)dst, src, size);
9583+ }
9584 switch (size) {
bc901d79
MT
9585- case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
9586+ case 1:__put_user_asm(*(const u8 *)src, (u8 __user *)dst,
58c5fc13 9587 ret, "b", "b", "iq", 1);
bc901d79
MT
9588 return ret;
9589- case 2:__put_user_asm(*(u16 *)src, (u16 __user *)dst,
9590+ case 2:__put_user_asm(*(const u16 *)src, (u16 __user *)dst,
9591 ret, "w", "w", "ir", 2);
9592 return ret;
9593- case 4:__put_user_asm(*(u32 *)src, (u32 __user *)dst,
9594+ case 4:__put_user_asm(*(const u32 *)src, (u32 __user *)dst,
9595 ret, "l", "k", "ir", 4);
9596 return ret;
9597- case 8:__put_user_asm(*(u64 *)src, (u64 __user *)dst,
9598+ case 8:__put_user_asm(*(const u64 *)src, (u64 __user *)dst,
9599 ret, "q", "", "er", 8);
9600 return ret;
9601 case 10:
9602- __put_user_asm(*(u64 *)src, (u64 __user *)dst,
9603+ __put_user_asm(*(const u64 *)src, (u64 __user *)dst,
9604 ret, "q", "", "er", 10);
9605 if (unlikely(ret))
9606 return ret;
9607 asm("":::"memory");
9608- __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
9609+ __put_user_asm(4[(const u16 *)src], 4 + (u16 __user *)dst,
9610 ret, "w", "w", "ir", 2);
9611 return ret;
9612 case 16:
9613- __put_user_asm(*(u64 *)src, (u64 __user *)dst,
9614+ __put_user_asm(*(const u64 *)src, (u64 __user *)dst,
9615 ret, "q", "", "er", 16);
9616 if (unlikely(ret))
9617 return ret;
9618 asm("":::"memory");
9619- __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
9620+ __put_user_asm(1[(const u64 *)src], 1 + (u64 __user *)dst,
df50ba0c
MT
9621 ret, "q", "", "er", 8);
9622 return ret;
9623 default:
9624+ if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9625+ dst += PAX_USER_SHADOW_BASE;
9626 return copy_user_generic((__force void *)dst, src, size);
9627 }
58c5fc13
MT
9628 }
9629
9630 static __always_inline __must_check
9631-int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
ae4e228f 9632+unsigned long __copy_in_user(void __user *dst, const void __user *src, unsigned size)
58c5fc13
MT
9633 {
9634- int ret = 0;
58c5fc13
MT
9635+ unsigned ret = 0;
9636
9637 might_fault();
df50ba0c 9638- if (!__builtin_constant_p(size))
58c5fc13
MT
9639+
9640+ if ((int)size < 0)
9641+ return size;
9642+
bc901d79
MT
9643+#ifdef CONFIG_PAX_MEMORY_UDEREF
9644+ if (!__access_ok(VERIFY_READ, src, size))
9645+ return size;
9646+ if (!__access_ok(VERIFY_WRITE, dst, size))
9647+ return size;
9648+#endif
9649+
df50ba0c
MT
9650+ if (!__builtin_constant_p(size)) {
9651+ if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9652+ src += PAX_USER_SHADOW_BASE;
9653+ if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9654+ dst += PAX_USER_SHADOW_BASE;
58c5fc13 9655 return copy_user_generic((__force void *)dst,
bc901d79
MT
9656- (__force void *)src, size);
9657+ (__force const void *)src, size);
df50ba0c
MT
9658+ }
9659 switch (size) {
9660 case 1: {
9661 u8 tmp;
bc901d79
MT
9662- __get_user_asm(tmp, (u8 __user *)src,
9663+ __get_user_asm(tmp, (const u8 __user *)src,
9664 ret, "b", "b", "=q", 1);
9665 if (likely(!ret))
9666 __put_user_asm(tmp, (u8 __user *)dst,
9667@@ -177,7 +244,7 @@ int __copy_in_user(void __user *dst, con
9668 }
9669 case 2: {
9670 u16 tmp;
9671- __get_user_asm(tmp, (u16 __user *)src,
9672+ __get_user_asm(tmp, (const u16 __user *)src,
9673 ret, "w", "w", "=r", 2);
9674 if (likely(!ret))
9675 __put_user_asm(tmp, (u16 __user *)dst,
9676@@ -187,7 +254,7 @@ int __copy_in_user(void __user *dst, con
9677
9678 case 4: {
9679 u32 tmp;
9680- __get_user_asm(tmp, (u32 __user *)src,
9681+ __get_user_asm(tmp, (const u32 __user *)src,
9682 ret, "l", "k", "=r", 4);
9683 if (likely(!ret))
9684 __put_user_asm(tmp, (u32 __user *)dst,
9685@@ -196,7 +263,7 @@ int __copy_in_user(void __user *dst, con
9686 }
9687 case 8: {
9688 u64 tmp;
9689- __get_user_asm(tmp, (u64 __user *)src,
9690+ __get_user_asm(tmp, (const u64 __user *)src,
9691 ret, "q", "", "=r", 8);
9692 if (likely(!ret))
9693 __put_user_asm(tmp, (u64 __user *)dst,
9694@@ -204,8 +271,12 @@ int __copy_in_user(void __user *dst, con
df50ba0c
MT
9695 return ret;
9696 }
9697 default:
9698+ if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9699+ src += PAX_USER_SHADOW_BASE;
9700+ if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9701+ dst += PAX_USER_SHADOW_BASE;
9702 return copy_user_generic((__force void *)dst,
bc901d79
MT
9703- (__force void *)src, size);
9704+ (__force const void *)src, size);
df50ba0c 9705 }
bc901d79
MT
9706 }
9707
9708@@ -222,33 +293,68 @@ __must_check unsigned long __clear_user(
df50ba0c
MT
9709 static __must_check __always_inline int
9710 __copy_from_user_inatomic(void *dst, const void __user *src, unsigned size)
9711 {
bc901d79
MT
9712+ if ((int)size < 0)
9713+ return size;
9714+
9715+#ifdef CONFIG_PAX_MEMORY_UDEREF
9716+ if (!__access_ok(VERIFY_READ, src, size))
9717+ return size;
9718+#endif
9719+
df50ba0c
MT
9720+ if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9721+ src += PAX_USER_SHADOW_BASE;
ae4e228f
MT
9722 return copy_user_generic(dst, (__force const void *)src, size);
9723 }
58c5fc13
MT
9724
9725-static __must_check __always_inline int
9726+static __must_check __always_inline unsigned long
9727 __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
9728 {
9729+ if ((int)size < 0)
9730+ return size;
9731+
bc901d79
MT
9732+#ifdef CONFIG_PAX_MEMORY_UDEREF
9733+ if (!__access_ok(VERIFY_WRITE, dst, size))
9734+ return size;
9735+#endif
9736+
df50ba0c
MT
9737+ if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9738+ dst += PAX_USER_SHADOW_BASE;
58c5fc13
MT
9739 return copy_user_generic((__force void *)dst, src, size);
9740 }
9741
9742-extern long __copy_user_nocache(void *dst, const void __user *src,
9743+extern unsigned long __copy_user_nocache(void *dst, const void __user *src,
9744 unsigned size, int zerorest);
9745
9746-static inline int
9747-__copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
9748+static inline unsigned long __copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
9749 {
9750 might_sleep();
9751+
9752+ if ((int)size < 0)
9753+ return size;
bc901d79
MT
9754+
9755+#ifdef CONFIG_PAX_MEMORY_UDEREF
9756+ if (!__access_ok(VERIFY_READ, src, size))
9757+ return size;
9758+#endif
58c5fc13
MT
9759+
9760 return __copy_user_nocache(dst, src, size, 1);
9761 }
9762
9763-static inline int
9764-__copy_from_user_inatomic_nocache(void *dst, const void __user *src,
9765+static inline unsigned long __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
9766 unsigned size)
9767 {
9768+ if ((int)size < 0)
9769+ return size;
bc901d79
MT
9770+
9771+#ifdef CONFIG_PAX_MEMORY_UDEREF
9772+ if (!__access_ok(VERIFY_READ, src, size))
9773+ return size;
9774+#endif
58c5fc13
MT
9775+
9776 return __copy_user_nocache(dst, src, size, 0);
9777 }
9778
9779-unsigned long
9780+extern unsigned long
9781 copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest);
9782
9783 #endif /* _ASM_X86_UACCESS_64_H */
16454cff
MT
9784diff -urNp linux-2.6.38.1/arch/x86/include/asm/uaccess.h linux-2.6.38.1/arch/x86/include/asm/uaccess.h
9785--- linux-2.6.38.1/arch/x86/include/asm/uaccess.h 2011-03-14 21:20:32.000000000 -0400
9786+++ linux-2.6.38.1/arch/x86/include/asm/uaccess.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
9787@@ -8,12 +8,15 @@
9788 #include <linux/thread_info.h>
9789 #include <linux/prefetch.h>
9790 #include <linux/string.h>
9791+#include <linux/sched.h>
9792 #include <asm/asm.h>
9793 #include <asm/page.h>
9794
9795 #define VERIFY_READ 0
9796 #define VERIFY_WRITE 1
9797
9798+extern void check_object_size(const void *ptr, unsigned long n, bool to);
9799+
9800 /*
9801 * The fs value determines whether argument validity checking should be
9802 * performed or not. If get_fs() == USER_DS, checking is performed, with
9803@@ -29,7 +32,12 @@
9804
9805 #define get_ds() (KERNEL_DS)
9806 #define get_fs() (current_thread_info()->addr_limit)
bc901d79
MT
9807+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
9808+void __set_fs(mm_segment_t x);
57199397
MT
9809+void set_fs(mm_segment_t x);
9810+#else
9811 #define set_fs(x) (current_thread_info()->addr_limit = (x))
9812+#endif
9813
9814 #define segment_eq(a, b) ((a).seg == (b).seg)
9815
9816@@ -77,7 +85,33 @@
9817 * checks that the pointer is in the user space range - after calling
9818 * this function, memory access functions may still return -EFAULT.
9819 */
9820-#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0))
9821+#define __access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0))
9822+#define access_ok(type, addr, size) \
9823+({ \
9824+ long __size = size; \
9825+ unsigned long __addr = (unsigned long)addr; \
9826+ unsigned long __addr_ao = __addr & PAGE_MASK; \
9827+ unsigned long __end_ao = __addr + __size - 1; \
9828+ bool __ret_ao = __range_not_ok(__addr, __size) == 0; \
9829+ if (__ret_ao && unlikely((__end_ao ^ __addr_ao) & PAGE_MASK)) { \
9830+ while(__addr_ao <= __end_ao) { \
9831+ char __c_ao; \
9832+ __addr_ao += PAGE_SIZE; \
9833+ if (__size > PAGE_SIZE) \
9834+ cond_resched(); \
9835+ if (__get_user(__c_ao, (char __user *)__addr)) \
9836+ break; \
9837+ if (type != VERIFY_WRITE) { \
9838+ __addr = __addr_ao; \
9839+ continue; \
9840+ } \
9841+ if (__put_user(__c_ao, (char __user *)__addr)) \
9842+ break; \
9843+ __addr = __addr_ao; \
9844+ } \
9845+ } \
9846+ __ret_ao; \
9847+})
9848
9849 /*
9850 * The exception table consists of pairs of addresses: the first is the
bc901d79 9851@@ -183,12 +217,20 @@ extern int __get_user_bad(void);
57199397
MT
9852 asm volatile("call __put_user_" #size : "=a" (__ret_pu) \
9853 : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
9854
9855-
bc901d79 9856+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16454cff 9857+#define __copyuser_seg "gs;"
bc901d79
MT
9858+#define __COPYUSER_SET_ES "pushl %%gs; popl %%es\n"
9859+#define __COPYUSER_RESTORE_ES "pushl %%ss; popl %%es\n"
57199397 9860+#else
bc901d79
MT
9861+#define __copyuser_seg
9862+#define __COPYUSER_SET_ES
9863+#define __COPYUSER_RESTORE_ES
57199397
MT
9864+#endif
9865
9866 #ifdef CONFIG_X86_32
9867 #define __put_user_asm_u64(x, addr, err, errret) \
9868- asm volatile("1: movl %%eax,0(%2)\n" \
9869- "2: movl %%edx,4(%2)\n" \
16454cff
MT
9870+ asm volatile("1: "__copyuser_seg"movl %%eax,0(%2)\n" \
9871+ "2: "__copyuser_seg"movl %%edx,4(%2)\n" \
57199397 9872 "3:\n" \
57199397
MT
9873 ".section .fixup,\"ax\"\n" \
9874 "4: movl %3,%0\n" \
bc901d79
MT
9875@@ -200,8 +242,8 @@ extern int __get_user_bad(void);
9876 : "A" (x), "r" (addr), "i" (errret), "0" (err))
57199397
MT
9877
9878 #define __put_user_asm_ex_u64(x, addr) \
9879- asm volatile("1: movl %%eax,0(%1)\n" \
9880- "2: movl %%edx,4(%1)\n" \
16454cff
MT
9881+ asm volatile("1: "__copyuser_seg"movl %%eax,0(%1)\n" \
9882+ "2: "__copyuser_seg"movl %%edx,4(%1)\n" \
57199397 9883 "3:\n" \
57199397
MT
9884 _ASM_EXTABLE(1b, 2b - 1b) \
9885 _ASM_EXTABLE(2b, 3b - 2b) \
bc901d79 9886@@ -374,7 +416,7 @@ do { \
57199397
MT
9887 } while (0)
9888
9889 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
9890- asm volatile("1: mov"itype" %2,%"rtype"1\n" \
16454cff 9891+ asm volatile("1: "__copyuser_seg"mov"itype" %2,%"rtype"1\n"\
57199397 9892 "2:\n" \
57199397
MT
9893 ".section .fixup,\"ax\"\n" \
9894 "3: mov %3,%0\n" \
bc901d79 9895@@ -382,7 +424,7 @@ do { \
57199397
MT
9896 " jmp 2b\n" \
9897 ".previous\n" \
9898 _ASM_EXTABLE(1b, 3b) \
9899- : "=r" (err), ltype(x) \
57199397 9900+ : "=r" (err), ltype (x) \
bc901d79 9901 : "m" (__m(addr)), "i" (errret), "0" (err))
57199397
MT
9902
9903 #define __get_user_size_ex(x, ptr, size) \
bc901d79 9904@@ -407,7 +449,7 @@ do { \
57199397
MT
9905 } while (0)
9906
9907 #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
9908- asm volatile("1: mov"itype" %1,%"rtype"0\n" \
16454cff 9909+ asm volatile("1: "__copyuser_seg"mov"itype" %1,%"rtype"0\n"\
57199397 9910 "2:\n" \
57199397 9911 _ASM_EXTABLE(1b, 2b - 1b) \
bc901d79
MT
9912 : ltype(x) : "m" (__m(addr)))
9913@@ -424,13 +466,24 @@ do { \
57199397
MT
9914 int __gu_err; \
9915 unsigned long __gu_val; \
9916 __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
9917- (x) = (__force __typeof__(*(ptr)))__gu_val; \
9918+ (x) = (__typeof__(*(ptr)))__gu_val; \
9919 __gu_err; \
9920 })
9921
9922 /* FIXME: this hack is definitely wrong -AK */
9923 struct __large_struct { unsigned long buf[100]; };
9924-#define __m(x) (*(struct __large_struct __user *)(x))
9925+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
9926+#define ____m(x) \
9927+({ \
9928+ unsigned long ____x = (unsigned long)(x); \
9929+ if (____x < PAX_USER_SHADOW_BASE) \
9930+ ____x += PAX_USER_SHADOW_BASE; \
9931+ (void __user *)____x; \
9932+})
9933+#else
9934+#define ____m(x) (x)
9935+#endif
9936+#define __m(x) (*(struct __large_struct __user *)____m(x))
9937
9938 /*
9939 * Tell gcc we read from memory instead of writing: this is because
bc901d79 9940@@ -438,7 +491,7 @@ struct __large_struct { unsigned long bu
57199397
MT
9941 * aliasing issues.
9942 */
9943 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
9944- asm volatile("1: mov"itype" %"rtype"1,%2\n" \
16454cff 9945+ asm volatile("1: "__copyuser_seg"mov"itype" %"rtype"1,%2\n"\
57199397 9946 "2:\n" \
57199397
MT
9947 ".section .fixup,\"ax\"\n" \
9948 "3: mov %3,%0\n" \
bc901d79 9949@@ -446,10 +499,10 @@ struct __large_struct { unsigned long bu
57199397
MT
9950 ".previous\n" \
9951 _ASM_EXTABLE(1b, 3b) \
9952 : "=r"(err) \
9953- : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
bc901d79 9954+ : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err))
57199397
MT
9955
9956 #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
9957- asm volatile("1: mov"itype" %"rtype"0,%1\n" \
16454cff 9958+ asm volatile("1: "__copyuser_seg"mov"itype" %"rtype"0,%1\n"\
57199397 9959 "2:\n" \
57199397 9960 _ASM_EXTABLE(1b, 2b - 1b) \
bc901d79
MT
9961 : : ltype(x), "m" (__m(addr)))
9962@@ -488,8 +541,12 @@ struct __large_struct { unsigned long bu
9963 * On error, the variable @x is set to zero.
9964 */
57199397 9965
bc901d79
MT
9966+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
9967+#define __get_user(x, ptr) get_user((x), (ptr))
9968+#else
9969 #define __get_user(x, ptr) \
9970 __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
9971+#endif
9972
9973 /**
9974 * __put_user: - Write a simple value into user space, with less checking.
9975@@ -511,8 +568,12 @@ struct __large_struct { unsigned long bu
9976 * Returns zero on success, or -EFAULT on error.
9977 */
9978
9979+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
9980+#define __put_user(x, ptr) put_user((x), (ptr))
9981+#else
9982 #define __put_user(x, ptr) \
9983 __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
9984+#endif
9985
9986 #define __get_user_unaligned __get_user
9987 #define __put_user_unaligned __put_user
9988@@ -530,7 +591,7 @@ struct __large_struct { unsigned long bu
57199397
MT
9989 #define get_user_ex(x, ptr) do { \
9990 unsigned long __gue_val; \
9991 __get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr)))); \
9992- (x) = (__force __typeof__(*(ptr)))__gue_val; \
9993+ (x) = (__typeof__(*(ptr)))__gue_val; \
9994 } while (0)
9995
9996 #ifdef CONFIG_X86_WP_WORKS_OK
bc901d79 9997@@ -567,6 +628,7 @@ extern struct movsl_mask {
57199397
MT
9998
9999 #define ARCH_HAS_NOCACHE_UACCESS 1
10000
10001+#define ARCH_HAS_SORT_EXTABLE
10002 #ifdef CONFIG_X86_32
10003 # include "uaccess_32.h"
10004 #else
16454cff
MT
10005diff -urNp linux-2.6.38.1/arch/x86/include/asm/vgtod.h linux-2.6.38.1/arch/x86/include/asm/vgtod.h
10006--- linux-2.6.38.1/arch/x86/include/asm/vgtod.h 2011-03-14 21:20:32.000000000 -0400
10007+++ linux-2.6.38.1/arch/x86/include/asm/vgtod.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
10008@@ -14,6 +14,7 @@ struct vsyscall_gtod_data {
10009 int sysctl_enabled;
10010 struct timezone sys_tz;
10011 struct { /* extract of a clocksource struct */
10012+ char name[8];
10013 cycle_t (*vread)(void);
10014 cycle_t cycle_last;
10015 cycle_t mask;
16454cff
MT
10016diff -urNp linux-2.6.38.1/arch/x86/include/asm/vsyscall.h linux-2.6.38.1/arch/x86/include/asm/vsyscall.h
10017--- linux-2.6.38.1/arch/x86/include/asm/vsyscall.h 2011-03-14 21:20:32.000000000 -0400
10018+++ linux-2.6.38.1/arch/x86/include/asm/vsyscall.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
10019@@ -15,9 +15,10 @@ enum vsyscall_num {
10020
10021 #ifdef __KERNEL__
10022 #include <linux/seqlock.h>
10023+#include <linux/getcpu.h>
10024+#include <linux/time.h>
10025
10026 #define __section_vgetcpu_mode __attribute__ ((unused, __section__ (".vgetcpu_mode"), aligned(16)))
10027-#define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16)))
10028
10029 /* Definitions for CONFIG_GENERIC_TIME definitions */
10030 #define __section_vsyscall_gtod_data __attribute__ \
10031@@ -31,7 +32,6 @@ enum vsyscall_num {
10032 #define VGETCPU_LSL 2
10033
10034 extern int __vgetcpu_mode;
10035-extern volatile unsigned long __jiffies;
10036
10037 /* kernel space (writeable) */
10038 extern int vgetcpu_mode;
10039@@ -39,6 +39,9 @@ extern struct timezone sys_tz;
10040
10041 extern void map_vsyscall(void);
10042
10043+extern int vgettimeofday(struct timeval * tv, struct timezone * tz);
10044+extern time_t vtime(time_t *t);
10045+extern long vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache);
10046 #endif /* __KERNEL__ */
10047
10048 #endif /* _ASM_X86_VSYSCALL_H */
16454cff
MT
10049diff -urNp linux-2.6.38.1/arch/x86/include/asm/xsave.h linux-2.6.38.1/arch/x86/include/asm/xsave.h
10050--- linux-2.6.38.1/arch/x86/include/asm/xsave.h 2011-03-14 21:20:32.000000000 -0400
10051+++ linux-2.6.38.1/arch/x86/include/asm/xsave.h 2011-03-21 18:31:35.000000000 -0400
6892158b 10052@@ -65,6 +65,11 @@ static inline int xsave_user(struct xsav
df50ba0c
MT
10053 {
10054 int err;
6892158b 10055
df50ba0c
MT
10056+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
10057+ if ((unsigned long)buf < PAX_USER_SHADOW_BASE)
10058+ buf = (struct xsave_struct __user *)((void __user*)buf + PAX_USER_SHADOW_BASE);
10059+#endif
10060+
6892158b
MT
10061 /*
10062 * Clear the xsave header first, so that reserved fields are
10063 * initialized to zero.
10064@@ -100,6 +105,11 @@ static inline int xrestore_user(struct x
df50ba0c
MT
10065 u32 lmask = mask;
10066 u32 hmask = mask >> 32;
10067
10068+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
10069+ if ((unsigned long)xstate < PAX_USER_SHADOW_BASE)
10070+ xstate = (struct xsave_struct *)((void *)xstate + PAX_USER_SHADOW_BASE);
10071+#endif
10072+
10073 __asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n"
10074 "2:\n"
10075 ".section .fixup,\"ax\"\n"
16454cff
MT
10076diff -urNp linux-2.6.38.1/arch/x86/Kconfig linux-2.6.38.1/arch/x86/Kconfig
10077--- linux-2.6.38.1/arch/x86/Kconfig 2011-03-14 21:20:32.000000000 -0400
10078+++ linux-2.6.38.1/arch/x86/Kconfig 2011-03-21 18:31:35.000000000 -0400
10079@@ -223,7 +223,7 @@ config X86_TRAMPOLINE
bc901d79
MT
10080
10081 config X86_32_LAZY_GS
10082 def_bool y
10083- depends on X86_32 && !CC_STACKPROTECTOR
10084+ depends on X86_32 && !CC_STACKPROTECTOR && !PAX_MEMORY_UDEREF
10085
10086 config ARCH_HWEIGHT_CFLAGS
10087 string
16454cff 10088@@ -1019,7 +1019,7 @@ choice
57199397
MT
10089
10090 config NOHIGHMEM
10091 bool "off"
10092- depends on !X86_NUMAQ
10093+ depends on !X86_NUMAQ && !(PAX_PAGEEXEC && PAX_ENABLE_PAE)
10094 ---help---
10095 Linux can use up to 64 Gigabytes of physical memory on x86 systems.
10096 However, the address space of 32-bit x86 processors is only 4
16454cff 10097@@ -1056,7 +1056,7 @@ config NOHIGHMEM
57199397
MT
10098
10099 config HIGHMEM4G
10100 bool "4GB"
10101- depends on !X86_NUMAQ
10102+ depends on !X86_NUMAQ && !(PAX_PAGEEXEC && PAX_ENABLE_PAE)
10103 ---help---
10104 Select this if you have a 32-bit processor and between 1 and 4
10105 gigabytes of physical RAM.
16454cff 10106@@ -1110,7 +1110,7 @@ config PAGE_OFFSET
57199397
MT
10107 hex
10108 default 0xB0000000 if VMSPLIT_3G_OPT
10109 default 0x80000000 if VMSPLIT_2G
10110- default 0x78000000 if VMSPLIT_2G_OPT
10111+ default 0x70000000 if VMSPLIT_2G_OPT
10112 default 0x40000000 if VMSPLIT_1G
10113 default 0xC0000000
10114 depends on X86_32
16454cff 10115@@ -1454,7 +1454,7 @@ config ARCH_USES_PG_UNCACHED
57199397
MT
10116
10117 config EFI
10118 bool "EFI runtime service support"
10119- depends on ACPI
10120+ depends on ACPI && !PAX_KERNEXEC
10121 ---help---
10122 This enables the kernel to use EFI runtime services that are
10123 available (such as the EFI variable services).
16454cff 10124@@ -1484,6 +1484,7 @@ config SECCOMP
bc901d79
MT
10125
10126 config CC_STACKPROTECTOR
10127 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
10128+ depends on X86_64 || !PAX_MEMORY_UDEREF
10129 ---help---
10130 This option turns on the -fstack-protector GCC feature. This
10131 feature puts, at the beginning of functions, a canary value on
16454cff 10132@@ -1541,6 +1542,7 @@ config KEXEC_JUMP
57199397 10133 config PHYSICAL_START
16454cff 10134 hex "Physical address where the kernel is loaded" if (EXPERT || CRASH_DUMP)
57199397
MT
10135 default "0x1000000"
10136+ range 0x400000 0x40000000
10137 ---help---
10138 This gives the physical address where the kernel is loaded.
10139
16454cff 10140@@ -1604,6 +1606,7 @@ config X86_NEED_RELOCS
57199397
MT
10141 config PHYSICAL_ALIGN
10142 hex "Alignment value to which kernel should be aligned" if X86_32
10143 default "0x1000000"
10144+ range 0x400000 0x1000000 if PAX_KERNEXEC
10145 range 0x2000 0x1000000
10146 ---help---
10147 This value puts the alignment restrictions on physical address
16454cff 10148@@ -1635,9 +1638,10 @@ config HOTPLUG_CPU
57199397
MT
10149 Say N if you want to disable CPU hotplug.
10150
10151 config COMPAT_VDSO
10152- def_bool y
10153+ def_bool n
10154 prompt "Compat VDSO support"
10155 depends on X86_32 || IA32_EMULATION
10156+ depends on !PAX_NOEXEC && !PAX_MEMORY_UDEREF
10157 ---help---
10158 Map the 32-bit VDSO to the predictable old-style address too.
10159
16454cff
MT
10160diff -urNp linux-2.6.38.1/arch/x86/Kconfig.cpu linux-2.6.38.1/arch/x86/Kconfig.cpu
10161--- linux-2.6.38.1/arch/x86/Kconfig.cpu 2011-03-14 21:20:32.000000000 -0400
10162+++ linux-2.6.38.1/arch/x86/Kconfig.cpu 2011-03-21 18:31:35.000000000 -0400
10163@@ -339,7 +339,7 @@ config X86_PPRO_FENCE
57199397
MT
10164
10165 config X86_F00F_BUG
10166 def_bool y
10167- depends on M586MMX || M586TSC || M586 || M486 || M386
10168+ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
10169
10170 config X86_INVD_BUG
10171 def_bool y
16454cff 10172@@ -363,7 +363,7 @@ config X86_POPAD_OK
57199397
MT
10173
10174 config X86_ALIGNMENT_16
10175 def_bool y
10176- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
10177+ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
10178
10179 config X86_INTEL_USERCOPY
10180 def_bool y
16454cff 10181@@ -409,7 +409,7 @@ config X86_CMPXCHG64
57199397
MT
10182 # generates cmov.
10183 config X86_CMOV
10184 def_bool y
10185- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
10186+ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
10187
10188 config X86_MINIMUM_CPU_FAMILY
10189 int
16454cff
MT
10190diff -urNp linux-2.6.38.1/arch/x86/Kconfig.debug linux-2.6.38.1/arch/x86/Kconfig.debug
10191--- linux-2.6.38.1/arch/x86/Kconfig.debug 2011-03-14 21:20:32.000000000 -0400
10192+++ linux-2.6.38.1/arch/x86/Kconfig.debug 2011-03-21 18:31:35.000000000 -0400
bc901d79 10193@@ -101,7 +101,7 @@ config X86_PTDUMP
57199397
MT
10194 config DEBUG_RODATA
10195 bool "Write protect kernel read-only data structures"
10196 default y
10197- depends on DEBUG_KERNEL
10198+ depends on DEBUG_KERNEL && BROKEN
10199 ---help---
10200 Mark the kernel read-only data as write-protected in the pagetables,
10201 in order to catch accidental (and incorrect) writes to such const
16454cff
MT
10202@@ -119,7 +119,7 @@ config DEBUG_RODATA_TEST
10203
10204 config DEBUG_SET_MODULE_RONX
10205 bool "Set loadable kernel module data as NX and text as RO"
10206- depends on MODULES
10207+ depends on MODULES && BROKEN
10208 ---help---
10209 This option helps catch unintended modifications to loadable
10210 kernel module's text and read-only data. It also prevents execution
10211diff -urNp linux-2.6.38.1/arch/x86/kernel/acpi/boot.c linux-2.6.38.1/arch/x86/kernel/acpi/boot.c
10212--- linux-2.6.38.1/arch/x86/kernel/acpi/boot.c 2011-03-14 21:20:32.000000000 -0400
10213+++ linux-2.6.38.1/arch/x86/kernel/acpi/boot.c 2011-03-21 18:31:35.000000000 -0400
10214@@ -1472,7 +1472,7 @@ static struct dmi_system_id __initdata a
58c5fc13
MT
10215 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
10216 },
10217 },
10218- {}
10219+ { NULL, NULL, {{0, {0}}}, NULL}
10220 };
10221
10222 /*
16454cff
MT
10223diff -urNp linux-2.6.38.1/arch/x86/kernel/acpi/sleep.c linux-2.6.38.1/arch/x86/kernel/acpi/sleep.c
10224--- linux-2.6.38.1/arch/x86/kernel/acpi/sleep.c 2011-03-14 21:20:32.000000000 -0400
10225+++ linux-2.6.38.1/arch/x86/kernel/acpi/sleep.c 2011-03-21 18:31:35.000000000 -0400
10226@@ -18,7 +18,7 @@
58c5fc13
MT
10227 #include "realmode/wakeup.h"
10228 #include "sleep.h"
10229
10230-unsigned long acpi_wakeup_address;
10231+unsigned long acpi_wakeup_address = 0x2000;
10232 unsigned long acpi_realmode_flags;
10233
10234 /* address in low memory of the wakeup routine. */
16454cff 10235@@ -99,8 +99,12 @@ int acpi_save_state_mem(void)
58c5fc13
MT
10236 header->trampoline_segment = setup_trampoline() >> 4;
10237 #ifdef CONFIG_SMP
16454cff 10238 stack_start = (unsigned long)temp_stack + sizeof(temp_stack);
58c5fc13 10239+
ae4e228f 10240+ pax_open_kernel();
58c5fc13
MT
10241 early_gdt_descr.address =
10242 (unsigned long)get_cpu_gdt_table(smp_processor_id());
ae4e228f 10243+ pax_close_kernel();
58c5fc13
MT
10244+
10245 initial_gs = per_cpu_offset(smp_processor_id());
10246 #endif
10247 initial_code = (unsigned long)wakeup_long64;
16454cff
MT
10248diff -urNp linux-2.6.38.1/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.38.1/arch/x86/kernel/acpi/wakeup_32.S
10249--- linux-2.6.38.1/arch/x86/kernel/acpi/wakeup_32.S 2011-03-14 21:20:32.000000000 -0400
10250+++ linux-2.6.38.1/arch/x86/kernel/acpi/wakeup_32.S 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
10251@@ -30,13 +30,11 @@ wakeup_pmode_return:
10252 # and restore the stack ... but you need gdt for this to work
10253 movl saved_context_esp, %esp
10254
10255- movl %cs:saved_magic, %eax
10256- cmpl $0x12345678, %eax
10257+ cmpl $0x12345678, saved_magic
10258 jne bogus_magic
10259
10260 # jump to place where we left off
10261- movl saved_eip, %eax
10262- jmp *%eax
10263+ jmp *(saved_eip)
10264
10265 bogus_magic:
10266 jmp bogus_magic
16454cff
MT
10267diff -urNp linux-2.6.38.1/arch/x86/kernel/alternative.c linux-2.6.38.1/arch/x86/kernel/alternative.c
10268--- linux-2.6.38.1/arch/x86/kernel/alternative.c 2011-03-23 17:20:06.000000000 -0400
10269+++ linux-2.6.38.1/arch/x86/kernel/alternative.c 2011-03-26 20:47:42.000000000 -0400
6892158b 10270@@ -248,7 +248,7 @@ static void alternatives_smp_lock(const
57199397
MT
10271 if (!*poff || ptr < text || ptr >= text_end)
10272 continue;
10273 /* turn DS segment override prefix into lock prefix */
10274- if (*ptr == 0x3e)
10275+ if (*ktla_ktva(ptr) == 0x3e)
10276 text_poke(ptr, ((unsigned char []){0xf0}), 1);
10277 };
10278 mutex_unlock(&text_mutex);
6892158b 10279@@ -269,7 +269,7 @@ static void alternatives_smp_unlock(cons
57199397
MT
10280 if (!*poff || ptr < text || ptr >= text_end)
10281 continue;
10282 /* turn lock prefix into DS segment override prefix */
10283- if (*ptr == 0xf0)
10284+ if (*ktla_ktva(ptr) == 0xf0)
10285 text_poke(ptr, ((unsigned char []){0x3E}), 1);
10286 };
10287 mutex_unlock(&text_mutex);
16454cff 10288@@ -438,7 +438,7 @@ void __init_or_module apply_paravirt(str
58c5fc13
MT
10289
10290 BUG_ON(p->len > MAX_PATCH_LEN);
10291 /* prep the buffer with the original instructions */
10292- memcpy(insnbuf, p->instr, p->len);
10293+ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
10294 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
10295 (unsigned long)p->instr, p->len);
10296
16454cff 10297@@ -506,7 +506,7 @@ void __init alternative_instructions(voi
df50ba0c
MT
10298 if (smp_alt_once)
10299 free_init_pages("SMP alternatives",
10300 (unsigned long)__smp_locks,
10301- (unsigned long)__smp_locks_end);
10302+ PAGE_ALIGN((unsigned long)__smp_locks_end));
10303
10304 restart_nmi();
10305 }
16454cff 10306@@ -523,13 +523,17 @@ void __init alternative_instructions(voi
58c5fc13
MT
10307 * instructions. And on the local CPU you need to be protected again NMI or MCE
10308 * handlers seeing an inconsistent instruction while you patch.
10309 */
bc901d79
MT
10310-void *__init_or_module text_poke_early(void *addr, const void *opcode,
10311+void *__kprobes text_poke_early(void *addr, const void *opcode,
ae4e228f 10312 size_t len)
58c5fc13
MT
10313 {
10314 unsigned long flags;
58c5fc13
MT
10315 local_irq_save(flags);
10316- memcpy(addr, opcode, len);
10317+
ae4e228f 10318+ pax_open_kernel();
58c5fc13 10319+ memcpy(ktla_ktva(addr), opcode, len);
57199397 10320 sync_core();
ae4e228f 10321+ pax_close_kernel();
58c5fc13 10322+
ae4e228f 10323 local_irq_restore(flags);
58c5fc13 10324 /* Could also do a CLFLUSH here to speed up CPU recovery; but
57199397 10325 that causes hangs on some VIA CPUs. */
16454cff 10326@@ -551,36 +555,22 @@ void *__init_or_module text_poke_early(v
58c5fc13
MT
10327 */
10328 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
10329 {
10330- unsigned long flags;
10331- char *vaddr;
10332+ unsigned char *vaddr = ktla_ktva(addr);
10333 struct page *pages[2];
10334- int i;
10335+ size_t i;
58c5fc13 10336
ae4e228f 10337 if (!core_kernel_text((unsigned long)addr)) {
58c5fc13
MT
10338- pages[0] = vmalloc_to_page(addr);
10339- pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
58c5fc13
MT
10340+ pages[0] = vmalloc_to_page(vaddr);
10341+ pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
10342 } else {
10343- pages[0] = virt_to_page(addr);
10344+ pages[0] = virt_to_page(vaddr);
10345 WARN_ON(!PageReserved(pages[0]));
10346- pages[1] = virt_to_page(addr + PAGE_SIZE);
10347+ pages[1] = virt_to_page(vaddr + PAGE_SIZE);
10348 }
10349 BUG_ON(!pages[0]);
10350- local_irq_save(flags);
10351- set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0]));
10352- if (pages[1])
10353- set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1]));
10354- vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0);
10355- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
10356- clear_fixmap(FIX_TEXT_POKE0);
10357- if (pages[1])
10358- clear_fixmap(FIX_TEXT_POKE1);
10359- local_flush_tlb();
10360- sync_core();
10361- /* Could also do a CLFLUSH here to speed up CPU recovery; but
10362- that causes hangs on some VIA CPUs. */
10363+ text_poke_early(addr, opcode, len);
10364 for (i = 0; i < len; i++)
10365- BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
10366- local_irq_restore(flags);
bc901d79 10367+ BUG_ON((vaddr)[i] != ((const unsigned char *)opcode)[i]);
58c5fc13
MT
10368 return addr;
10369 }
df50ba0c 10370
16454cff
MT
10371@@ -620,12 +610,7 @@ static int __kprobes stop_machine_text_p
10372 flush_icache_range((unsigned long)p->addr,
10373 (unsigned long)p->addr + p->len);
10374 }
10375- /*
10376- * Intel Archiecture Software Developer's Manual section 7.1.3 specifies
10377- * that a core serializing instruction such as "cpuid" should be
10378- * executed on _each_ core before the new instruction is made visible.
10379- */
10380- sync_core();
10381+
10382 return 0;
10383 }
10384
10385@@ -682,9 +667,9 @@ void __kprobes text_poke_smp_batch(struc
bc901d79
MT
10386 #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL)
10387
10388 #ifdef CONFIG_X86_64
10389-unsigned char ideal_nop5[5] = { 0x66, 0x66, 0x66, 0x66, 0x90 };
10390+unsigned char ideal_nop5[5] __read_only = { 0x66, 0x66, 0x66, 0x66, 0x90 };
10391 #else
10392-unsigned char ideal_nop5[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 };
10393+unsigned char ideal_nop5[5] __read_only = { 0x3e, 0x8d, 0x74, 0x26, 0x00 };
10394 #endif
10395
10396 void __init arch_init_ideal_nop5(void)
16454cff
MT
10397diff -urNp linux-2.6.38.1/arch/x86/kernel/amd_iommu.c linux-2.6.38.1/arch/x86/kernel/amd_iommu.c
10398--- linux-2.6.38.1/arch/x86/kernel/amd_iommu.c 2011-03-14 21:20:32.000000000 -0400
10399+++ linux-2.6.38.1/arch/x86/kernel/amd_iommu.c 2011-03-21 18:31:35.000000000 -0400
6892158b 10400@@ -2286,7 +2286,7 @@ static void prealloc_protection_domains(
ae4e228f
MT
10401 }
10402 }
10403
10404-static struct dma_map_ops amd_iommu_dma_ops = {
10405+static const struct dma_map_ops amd_iommu_dma_ops = {
10406 .alloc_coherent = alloc_coherent,
10407 .free_coherent = free_coherent,
10408 .map_page = map_page,
16454cff
MT
10409diff -urNp linux-2.6.38.1/arch/x86/kernel/apic/io_apic.c linux-2.6.38.1/arch/x86/kernel/apic/io_apic.c
10410--- linux-2.6.38.1/arch/x86/kernel/apic/io_apic.c 2011-03-14 21:20:32.000000000 -0400
10411+++ linux-2.6.38.1/arch/x86/kernel/apic/io_apic.c 2011-03-21 18:31:35.000000000 -0400
10412@@ -617,7 +617,7 @@ struct IO_APIC_route_entry **alloc_ioapi
ae4e228f 10413 ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
bc901d79 10414 GFP_KERNEL);
ae4e228f
MT
10415 if (!ioapic_entries)
10416- return 0;
10417+ return NULL;
58c5fc13 10418
ae4e228f
MT
10419 for (apic = 0; apic < nr_ioapics; apic++) {
10420 ioapic_entries[apic] =
16454cff 10421@@ -634,7 +634,7 @@ nomem:
ae4e228f
MT
10422 kfree(ioapic_entries[apic]);
10423 kfree(ioapic_entries);
58c5fc13 10424
ae4e228f
MT
10425- return 0;
10426+ return NULL;
10427 }
58c5fc13 10428
ae4e228f 10429 /*
16454cff 10430@@ -1044,7 +1044,7 @@ int IO_APIC_get_PCI_irq_vector(int bus,
ae4e228f
MT
10431 }
10432 EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
10433
10434-void lock_vector_lock(void)
10435+void lock_vector_lock(void) __acquires(vector_lock)
10436 {
10437 /* Used to the online set of cpus does not change
10438 * during assign_irq_vector.
16454cff 10439@@ -1052,7 +1052,7 @@ void lock_vector_lock(void)
df50ba0c 10440 raw_spin_lock(&vector_lock);
ae4e228f
MT
10441 }
10442
10443-void unlock_vector_lock(void)
10444+void unlock_vector_lock(void) __releases(vector_lock)
10445 {
df50ba0c 10446 raw_spin_unlock(&vector_lock);
ae4e228f 10447 }
16454cff
MT
10448diff -urNp linux-2.6.38.1/arch/x86/kernel/apm_32.c linux-2.6.38.1/arch/x86/kernel/apm_32.c
10449--- linux-2.6.38.1/arch/x86/kernel/apm_32.c 2011-03-14 21:20:32.000000000 -0400
10450+++ linux-2.6.38.1/arch/x86/kernel/apm_32.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
10451@@ -410,7 +410,7 @@ static DEFINE_MUTEX(apm_mutex);
10452 * This is for buggy BIOS's that refer to (real mode) segment 0x40
10453 * even though they are called in protected mode.
10454 */
10455-static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
10456+static const struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4093,
10457 (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
10458
10459 static const char driver_version[] = "1.16ac"; /* no spaces */
10460@@ -588,7 +588,10 @@ static long __apm_bios_call(void *_call)
58c5fc13
MT
10461 BUG_ON(cpu != 0);
10462 gdt = get_cpu_gdt_table(cpu);
10463 save_desc_40 = gdt[0x40 / 8];
10464+
ae4e228f 10465+ pax_open_kernel();
58c5fc13 10466 gdt[0x40 / 8] = bad_bios_desc;
ae4e228f 10467+ pax_close_kernel();
58c5fc13 10468
58c5fc13
MT
10469 apm_irq_save(flags);
10470 APM_DO_SAVE_SEGS;
ae4e228f 10471@@ -597,7 +600,11 @@ static long __apm_bios_call(void *_call)
58c5fc13
MT
10472 &call->esi);
10473 APM_DO_RESTORE_SEGS;
10474 apm_irq_restore(flags);
10475+
ae4e228f 10476+ pax_open_kernel();
58c5fc13 10477 gdt[0x40 / 8] = save_desc_40;
ae4e228f 10478+ pax_close_kernel();
58c5fc13
MT
10479+
10480 put_cpu();
10481
10482 return call->eax & 0xff;
ae4e228f 10483@@ -664,7 +671,10 @@ static long __apm_bios_call_simple(void
58c5fc13
MT
10484 BUG_ON(cpu != 0);
10485 gdt = get_cpu_gdt_table(cpu);
10486 save_desc_40 = gdt[0x40 / 8];
10487+
ae4e228f 10488+ pax_open_kernel();
58c5fc13 10489 gdt[0x40 / 8] = bad_bios_desc;
ae4e228f 10490+ pax_close_kernel();
58c5fc13 10491
58c5fc13
MT
10492 apm_irq_save(flags);
10493 APM_DO_SAVE_SEGS;
ae4e228f 10494@@ -672,7 +682,11 @@ static long __apm_bios_call_simple(void
58c5fc13
MT
10495 &call->eax);
10496 APM_DO_RESTORE_SEGS;
10497 apm_irq_restore(flags);
10498+
ae4e228f 10499+ pax_open_kernel();
58c5fc13 10500 gdt[0x40 / 8] = save_desc_40;
ae4e228f 10501+ pax_close_kernel();
58c5fc13
MT
10502+
10503 put_cpu();
10504 return error;
10505 }
ae4e228f 10506@@ -975,7 +989,7 @@ recalc:
58c5fc13
MT
10507
10508 static void apm_power_off(void)
10509 {
10510- unsigned char po_bios_call[] = {
10511+ const unsigned char po_bios_call[] = {
10512 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
10513 0x8e, 0xd0, /* movw ax,ss */
10514 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
bc901d79 10515@@ -1932,7 +1946,10 @@ static const struct file_operations apm_
58c5fc13
MT
10516 static struct miscdevice apm_device = {
10517 APM_MINOR_DEV,
10518 "apm_bios",
10519- &apm_bios_fops
10520+ &apm_bios_fops,
10521+ {NULL, NULL},
10522+ NULL,
10523+ NULL
10524 };
10525
10526
bc901d79 10527@@ -2253,7 +2270,7 @@ static struct dmi_system_id __initdata a
58c5fc13
MT
10528 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
10529 },
10530
10531- { }
10532+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
10533 };
10534
10535 /*
bc901d79 10536@@ -2356,12 +2373,15 @@ static int __init apm_init(void)
58c5fc13
MT
10537 * code to that CPU.
10538 */
10539 gdt = get_cpu_gdt_table(0);
10540+
ae4e228f
MT
10541+ pax_open_kernel();
10542 set_desc_base(&gdt[APM_CS >> 3],
10543 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
10544 set_desc_base(&gdt[APM_CS_16 >> 3],
10545 (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
10546 set_desc_base(&gdt[APM_DS >> 3],
10547 (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
10548+ pax_close_kernel();
58c5fc13 10549
58c5fc13
MT
10550 proc_create("apm", 0, NULL, &apm_file_ops);
10551
16454cff
MT
10552diff -urNp linux-2.6.38.1/arch/x86/kernel/asm-offsets_32.c linux-2.6.38.1/arch/x86/kernel/asm-offsets_32.c
10553--- linux-2.6.38.1/arch/x86/kernel/asm-offsets_32.c 2011-03-14 21:20:32.000000000 -0400
10554+++ linux-2.6.38.1/arch/x86/kernel/asm-offsets_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 10555@@ -113,6 +113,11 @@ void foo(void)
58c5fc13
MT
10556 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
10557 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
10558 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
ae4e228f
MT
10559+
10560+#ifdef CONFIG_PAX_KERNEXEC
58c5fc13 10561+ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
ae4e228f
MT
10562+#endif
10563+
58c5fc13
MT
10564 #endif
10565
10566 #ifdef CONFIG_XEN
16454cff
MT
10567diff -urNp linux-2.6.38.1/arch/x86/kernel/asm-offsets_64.c linux-2.6.38.1/arch/x86/kernel/asm-offsets_64.c
10568--- linux-2.6.38.1/arch/x86/kernel/asm-offsets_64.c 2011-03-14 21:20:32.000000000 -0400
10569+++ linux-2.6.38.1/arch/x86/kernel/asm-offsets_64.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 10570@@ -63,6 +63,18 @@ int main(void)
ae4e228f
MT
10571 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
10572 OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs);
10573 OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
10574+
10575+#ifdef CONFIG_PAX_KERNEXEC
10576+ OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
10577+ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
10578+#endif
df50ba0c
MT
10579+
10580+#ifdef CONFIG_PAX_MEMORY_UDEREF
10581+ OFFSET(PV_MMU_read_cr3, pv_mmu_ops, read_cr3);
10582+ OFFSET(PV_MMU_write_cr3, pv_mmu_ops, write_cr3);
10583+ OFFSET(PV_MMU_set_pgd, pv_mmu_ops, set_pgd);
10584+#endif
ae4e228f
MT
10585+
10586 #endif
10587
10588
df50ba0c 10589@@ -115,6 +127,7 @@ int main(void)
58c5fc13
MT
10590 ENTRY(cr8);
10591 BLANK();
10592 #undef ENTRY
10593+ DEFINE(TSS_size, sizeof(struct tss_struct));
10594 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
10595 BLANK();
10596 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
16454cff
MT
10597diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/common.c linux-2.6.38.1/arch/x86/kernel/cpu/common.c
10598--- linux-2.6.38.1/arch/x86/kernel/cpu/common.c 2011-03-14 21:20:32.000000000 -0400
10599+++ linux-2.6.38.1/arch/x86/kernel/cpu/common.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 10600@@ -83,60 +83,6 @@ static const struct cpu_dev __cpuinitcon
58c5fc13
MT
10601
10602 static const struct cpu_dev *this_cpu __cpuinitdata = &default_cpu;
10603
10604-DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
10605-#ifdef CONFIG_X86_64
10606- /*
10607- * We need valid kernel segments for data and code in long mode too
10608- * IRET will check the segment types kkeil 2000/10/28
10609- * Also sysret mandates a special GDT layout
10610- *
10611- * TLS descriptors are currently at a different place compared to i386.
10612- * Hopefully nobody expects them at a fixed place (Wine?)
10613- */
ae4e228f
MT
10614- [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
10615- [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
10616- [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
10617- [GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),
10618- [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
10619- [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
58c5fc13 10620-#else
ae4e228f
MT
10621- [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff),
10622- [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
10623- [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff),
10624- [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff),
58c5fc13
MT
10625- /*
10626- * Segments used for calling PnP BIOS have byte granularity.
10627- * They code segments and data segments have fixed 64k limits,
10628- * the transfer segment sizes are set at run time.
10629- */
10630- /* 32-bit code */
ae4e228f 10631- [GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
58c5fc13 10632- /* 16-bit code */
ae4e228f 10633- [GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
58c5fc13 10634- /* 16-bit data */
ae4e228f 10635- [GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff),
58c5fc13 10636- /* 16-bit data */
ae4e228f 10637- [GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0),
58c5fc13 10638- /* 16-bit data */
ae4e228f 10639- [GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0),
58c5fc13
MT
10640- /*
10641- * The APM segments have byte granularity and their bases
10642- * are set at run time. All have 64k limits.
10643- */
10644- /* 32-bit code */
ae4e228f 10645- [GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
58c5fc13 10646- /* 16-bit code */
ae4e228f 10647- [GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
58c5fc13 10648- /* data */
ae4e228f 10649- [GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff),
58c5fc13 10650-
ae4e228f
MT
10651- [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
10652- [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
58c5fc13
MT
10653- GDT_STACK_CANARY_INIT
10654-#endif
10655-} };
10656-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
10657-
10658 static int __init x86_xsave_setup(char *s)
10659 {
10660 setup_clear_cpu_cap(X86_FEATURE_XSAVE);
6892158b 10661@@ -352,7 +298,7 @@ void switch_to_new_gdt(int cpu)
58c5fc13
MT
10662 {
10663 struct desc_ptr gdt_descr;
10664
10665- gdt_descr.address = (long)get_cpu_gdt_table(cpu);
10666+ gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
10667 gdt_descr.size = GDT_SIZE - 1;
10668 load_gdt(&gdt_descr);
10669 /* Reload the per-cpu base */
bc901d79 10670@@ -825,6 +771,10 @@ static void __cpuinit identify_cpu(struc
58c5fc13
MT
10671 /* Filter out anything that depends on CPUID levels we don't have */
10672 filter_cpuid_features(c, true);
10673
ae4e228f 10674+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || (defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32))
58c5fc13
MT
10675+ setup_clear_cpu_cap(X86_FEATURE_SEP);
10676+#endif
10677+
10678 /* If the model name is still unset, do table lookup. */
10679 if (!c->x86_model_id[0]) {
10680 const char *p;
16454cff 10681@@ -1084,7 +1034,7 @@ struct pt_regs * __cpuinit idle_regs(str
bc901d79
MT
10682 {
10683 memset(regs, 0, sizeof(struct pt_regs));
10684 regs->fs = __KERNEL_PERCPU;
10685- regs->gs = __KERNEL_STACK_CANARY;
10686+ savesegment(gs, regs->gs);
10687
10688 return regs;
10689 }
16454cff 10690@@ -1139,7 +1089,7 @@ void __cpuinit cpu_init(void)
58c5fc13
MT
10691 int i;
10692
10693 cpu = stack_smp_processor_id();
10694- t = &per_cpu(init_tss, cpu);
10695+ t = init_tss + cpu;
ae4e228f 10696 oist = &per_cpu(orig_ist, cpu);
58c5fc13
MT
10697
10698 #ifdef CONFIG_NUMA
16454cff 10699@@ -1165,7 +1115,7 @@ void __cpuinit cpu_init(void)
df50ba0c
MT
10700 switch_to_new_gdt(cpu);
10701 loadsegment(fs, 0);
10702
10703- load_idt((const struct desc_ptr *)&idt_descr);
10704+ load_idt(&idt_descr);
10705
10706 memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
10707 syscall_init();
16454cff 10708@@ -1174,7 +1124,6 @@ void __cpuinit cpu_init(void)
bc901d79
MT
10709 wrmsrl(MSR_KERNEL_GS_BASE, 0);
10710 barrier();
10711
10712- x86_configure_nx();
10713 if (cpu != 0)
10714 enable_x2apic();
10715
16454cff 10716@@ -1228,7 +1177,7 @@ void __cpuinit cpu_init(void)
58c5fc13
MT
10717 {
10718 int cpu = smp_processor_id();
10719 struct task_struct *curr = current;
10720- struct tss_struct *t = &per_cpu(init_tss, cpu);
10721+ struct tss_struct *t = init_tss + cpu;
10722 struct thread_struct *thread = &curr->thread;
10723
10724 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
16454cff
MT
10725diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.38.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
10726--- linux-2.6.38.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2011-03-14 21:20:32.000000000 -0400
10727+++ linux-2.6.38.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2011-03-21 18:31:35.000000000 -0400
6892158b 10728@@ -481,7 +481,7 @@ static const struct dmi_system_id sw_any
58c5fc13
MT
10729 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
10730 },
10731 },
10732- { }
10733+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
10734 };
58c5fc13 10735
ae4e228f 10736 static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
16454cff
MT
10737diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.38.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
10738--- linux-2.6.38.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2011-03-14 21:20:32.000000000 -0400
10739+++ linux-2.6.38.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 10740@@ -226,7 +226,7 @@ static struct cpu_model models[] =
58c5fc13
MT
10741 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
10742 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
10743
10744- { NULL, }
10745+ { NULL, NULL, 0, NULL}
10746 };
10747 #undef _BANIAS
10748 #undef BANIAS
16454cff
MT
10749diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/intel.c linux-2.6.38.1/arch/x86/kernel/cpu/intel.c
10750--- linux-2.6.38.1/arch/x86/kernel/cpu/intel.c 2011-03-14 21:20:32.000000000 -0400
10751+++ linux-2.6.38.1/arch/x86/kernel/cpu/intel.c 2011-03-21 18:31:35.000000000 -0400
6892158b 10752@@ -161,7 +161,7 @@ static void __cpuinit trap_init_f00f_bug
58c5fc13
MT
10753 * Update the IDT descriptor and reload the IDT so that
10754 * it uses the read-only mapped virtual address.
10755 */
10756- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
10757+ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
10758 load_idt(&idt_descr);
10759 }
10760 #endif
16454cff
MT
10761diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/Makefile linux-2.6.38.1/arch/x86/kernel/cpu/Makefile
10762--- linux-2.6.38.1/arch/x86/kernel/cpu/Makefile 2011-03-14 21:20:32.000000000 -0400
10763+++ linux-2.6.38.1/arch/x86/kernel/cpu/Makefile 2011-03-21 18:31:35.000000000 -0400
57199397
MT
10764@@ -8,10 +8,6 @@ CFLAGS_REMOVE_common.o = -pg
10765 CFLAGS_REMOVE_perf_event.o = -pg
10766 endif
10767
10768-# Make sure load_percpu_segment has no stackprotector
10769-nostackp := $(call cc-option, -fno-stack-protector)
10770-CFLAGS_common.o := $(nostackp)
10771-
6892158b 10772 obj-y := intel_cacheinfo.o scattered.o topology.o
57199397
MT
10773 obj-y += proc.o capflags.o powerflags.o common.o
10774 obj-y += vmware.o hypervisor.o sched.o mshyperv.o
16454cff
MT
10775diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/mcheck/mce.c linux-2.6.38.1/arch/x86/kernel/cpu/mcheck/mce.c
10776--- linux-2.6.38.1/arch/x86/kernel/cpu/mcheck/mce.c 2011-03-14 21:20:32.000000000 -0400
10777+++ linux-2.6.38.1/arch/x86/kernel/cpu/mcheck/mce.c 2011-03-21 18:31:35.000000000 -0400
c52201e0
MT
10778@@ -45,6 +45,7 @@
10779 #include <asm/ipi.h>
10780 #include <asm/mce.h>
10781 #include <asm/msr.h>
10782+#include <asm/local.h>
10783
10784 #include "mce-internal.h"
10785
10786@@ -219,7 +220,7 @@ static void print_mce(struct mce *m)
ae4e228f
MT
10787 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
10788 m->cs, m->ip);
10789
10790- if (m->cs == __KERNEL_CS)
10791+ if (m->cs == __KERNEL_CS || m->cs == __KERNEXEC_KERNEL_CS)
10792 print_symbol("{%s}", m->ip);
10793 pr_cont("\n");
10794 }
c52201e0 10795@@ -1460,14 +1461,14 @@ void __cpuinit mcheck_cpu_init(struct cp
58c5fc13
MT
10796 */
10797
10798 static DEFINE_SPINLOCK(mce_state_lock);
10799-static int open_count; /* #times opened */
c52201e0 10800+static local_t open_count; /* #times opened */
58c5fc13
MT
10801 static int open_exclu; /* already open exclusive? */
10802
10803 static int mce_open(struct inode *inode, struct file *file)
10804 {
10805 spin_lock(&mce_state_lock);
10806
10807- if (open_exclu || (open_count && (file->f_flags & O_EXCL))) {
c52201e0 10808+ if (open_exclu || (local_read(&open_count) && (file->f_flags & O_EXCL))) {
58c5fc13
MT
10809 spin_unlock(&mce_state_lock);
10810
10811 return -EBUSY;
c52201e0 10812@@ -1475,7 +1476,7 @@ static int mce_open(struct inode *inode,
58c5fc13
MT
10813
10814 if (file->f_flags & O_EXCL)
10815 open_exclu = 1;
10816- open_count++;
c52201e0 10817+ local_inc(&open_count);
58c5fc13
MT
10818
10819 spin_unlock(&mce_state_lock);
10820
c52201e0 10821@@ -1486,7 +1487,7 @@ static int mce_release(struct inode *ino
58c5fc13
MT
10822 {
10823 spin_lock(&mce_state_lock);
10824
10825- open_count--;
c52201e0 10826+ local_dec(&open_count);
58c5fc13
MT
10827 open_exclu = 0;
10828
10829 spin_unlock(&mce_state_lock);
16454cff
MT
10830@@ -1658,8 +1659,7 @@ static long mce_ioctl(struct file *f, un
10831 }
10832 }
10833
10834-/* Modified in mce-inject.c, so not static or const */
10835-struct file_operations mce_chrdev_ops = {
10836+struct file_operations mce_chrdev_ops = { /* Modified in mce-inject.c, so not static or const */
10837 .open = mce_open,
10838 .release = mce_release,
10839 .read = mce_read,
10840@@ -1673,6 +1673,7 @@ static struct miscdevice mce_log_device
58c5fc13
MT
10841 MISC_MCELOG_MINOR,
10842 "mcelog",
10843 &mce_chrdev_ops,
10844+ {NULL, NULL}, NULL, NULL
10845 };
10846
10847 /*
16454cff
MT
10848diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/generic.c
10849--- linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/generic.c 2011-03-14 21:20:32.000000000 -0400
10850+++ linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/generic.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 10851@@ -28,7 +28,7 @@ static struct fixed_range_block fixed_ra
ae4e228f
MT
10852 { MSR_MTRRfix64K_00000, 1 }, /* one 64k MTRR */
10853 { MSR_MTRRfix16K_80000, 2 }, /* two 16k MTRRs */
10854 { MSR_MTRRfix4K_C0000, 8 }, /* eight 4k MTRRs */
58c5fc13
MT
10855- {}
10856+ { 0, 0 }
10857 };
10858
10859 static unsigned long smp_changes_mask;
16454cff
MT
10860diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/main.c linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/main.c
10861--- linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/main.c 2011-03-14 21:20:32.000000000 -0400
10862+++ linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/main.c 2011-03-21 18:31:35.000000000 -0400
57199397 10863@@ -61,7 +61,7 @@ static DEFINE_MUTEX(mtrr_mutex);
ae4e228f
MT
10864 u64 size_or_mask, size_and_mask;
10865 static bool mtrr_aps_delayed_init;
10866
df50ba0c 10867-static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
ae4e228f
MT
10868+static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM] __read_only;
10869
df50ba0c 10870 const struct mtrr_ops *mtrr_if;
ae4e228f 10871
16454cff
MT
10872diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/mtrr.h linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/mtrr.h
10873--- linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/mtrr.h 2011-03-14 21:20:32.000000000 -0400
10874+++ linux-2.6.38.1/arch/x86/kernel/cpu/mtrr/mtrr.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
10875@@ -12,19 +12,19 @@
10876 extern unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
10877
10878 struct mtrr_ops {
10879- u32 vendor;
10880- u32 use_intel_if;
10881- void (*set)(unsigned int reg, unsigned long base,
10882+ const u32 vendor;
10883+ const u32 use_intel_if;
10884+ void (* const set)(unsigned int reg, unsigned long base,
10885 unsigned long size, mtrr_type type);
10886- void (*set_all)(void);
10887+ void (* const set_all)(void);
10888
10889- void (*get)(unsigned int reg, unsigned long *base,
10890+ void (* const get)(unsigned int reg, unsigned long *base,
10891 unsigned long *size, mtrr_type *type);
10892- int (*get_free_region)(unsigned long base, unsigned long size,
10893+ int (* const get_free_region)(unsigned long base, unsigned long size,
10894 int replace_reg);
10895- int (*validate_add_page)(unsigned long base, unsigned long size,
10896+ int (* const validate_add_page)(unsigned long base, unsigned long size,
10897 unsigned int type);
10898- int (*have_wrcomb)(void);
10899+ int (* const have_wrcomb)(void);
10900 };
10901
10902 extern int generic_get_free_region(unsigned long base, unsigned long size,
16454cff
MT
10903diff -urNp linux-2.6.38.1/arch/x86/kernel/cpu/perf_event.c linux-2.6.38.1/arch/x86/kernel/cpu/perf_event.c
10904--- linux-2.6.38.1/arch/x86/kernel/cpu/perf_event.c 2011-03-14 21:20:32.000000000 -0400
10905+++ linux-2.6.38.1/arch/x86/kernel/cpu/perf_event.c 2011-03-21 18:31:35.000000000 -0400
10906@@ -1781,7 +1781,7 @@ perf_callchain_user(struct perf_callchai
57199397
MT
10907 break;
10908
bc901d79 10909 perf_callchain_store(entry, frame.return_address);
57199397
MT
10910- fp = frame.next_frame;
10911+ fp = (__force const void __user *)frame.next_frame;
10912 }
10913 }
10914
16454cff
MT
10915diff -urNp linux-2.6.38.1/arch/x86/kernel/crash.c linux-2.6.38.1/arch/x86/kernel/crash.c
10916--- linux-2.6.38.1/arch/x86/kernel/crash.c 2011-03-14 21:20:32.000000000 -0400
10917+++ linux-2.6.38.1/arch/x86/kernel/crash.c 2011-03-21 18:31:35.000000000 -0400
6892158b 10918@@ -42,7 +42,7 @@ static void kdump_nmi_callback(int cpu,
58c5fc13
MT
10919 regs = args->regs;
10920
10921 #ifdef CONFIG_X86_32
10922- if (!user_mode_vm(regs)) {
10923+ if (!user_mode(regs)) {
10924 crash_fixup_ss_esp(&fixed_regs, regs);
10925 regs = &fixed_regs;
10926 }
16454cff
MT
10927diff -urNp linux-2.6.38.1/arch/x86/kernel/doublefault_32.c linux-2.6.38.1/arch/x86/kernel/doublefault_32.c
10928--- linux-2.6.38.1/arch/x86/kernel/doublefault_32.c 2011-03-14 21:20:32.000000000 -0400
10929+++ linux-2.6.38.1/arch/x86/kernel/doublefault_32.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
10930@@ -11,7 +11,7 @@
10931
10932 #define DOUBLEFAULT_STACKSIZE (1024)
10933 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
10934-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
10935+#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
10936
10937 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
10938
10939@@ -21,7 +21,7 @@ static void doublefault_fn(void)
10940 unsigned long gdt, tss;
10941
10942 store_gdt(&gdt_desc);
10943- gdt = gdt_desc.address;
10944+ gdt = (unsigned long)gdt_desc.address;
10945
10946 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
10947
ae4e228f 10948@@ -58,10 +58,10 @@ struct tss_struct doublefault_tss __cach
58c5fc13
MT
10949 /* 0x2 bit is always set */
10950 .flags = X86_EFLAGS_SF | 0x2,
10951 .sp = STACK_START,
10952- .es = __USER_DS,
10953+ .es = __KERNEL_DS,
10954 .cs = __KERNEL_CS,
10955 .ss = __KERNEL_DS,
10956- .ds = __USER_DS,
10957+ .ds = __KERNEL_DS,
10958 .fs = __KERNEL_PERCPU,
10959
10960 .__cr3 = __pa_nodebug(swapper_pg_dir),
16454cff
MT
10961diff -urNp linux-2.6.38.1/arch/x86/kernel/dumpstack_32.c linux-2.6.38.1/arch/x86/kernel/dumpstack_32.c
10962--- linux-2.6.38.1/arch/x86/kernel/dumpstack_32.c 2011-03-14 21:20:32.000000000 -0400
10963+++ linux-2.6.38.1/arch/x86/kernel/dumpstack_32.c 2011-03-21 18:31:35.000000000 -0400
10964@@ -95,21 +95,22 @@ void show_registers(struct pt_regs *regs
58c5fc13
MT
10965 * When in-kernel, we also print out the stack and code at the
10966 * time of the fault..
10967 */
10968- if (!user_mode_vm(regs)) {
10969+ if (!user_mode(regs)) {
10970 unsigned int code_prologue = code_bytes * 43 / 64;
10971 unsigned int code_len = code_bytes;
10972 unsigned char c;
10973 u8 *ip;
10974+ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
10975
10976 printk(KERN_EMERG "Stack:\n");
16454cff 10977 show_stack_log_lvl(NULL, regs, &regs->sp, KERN_EMERG);
58c5fc13
MT
10978
10979 printk(KERN_EMERG "Code: ");
10980
10981- ip = (u8 *)regs->ip - code_prologue;
10982+ ip = (u8 *)regs->ip - code_prologue + cs_base;
10983 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
10984 /* try starting at IP */
10985- ip = (u8 *)regs->ip;
10986+ ip = (u8 *)regs->ip + cs_base;
10987 code_len = code_len - code_prologue + 1;
10988 }
10989 for (i = 0; i < code_len; i++, ip++) {
16454cff 10990@@ -118,7 +119,7 @@ void show_registers(struct pt_regs *regs
58c5fc13
MT
10991 printk(" Bad EIP value.");
10992 break;
10993 }
10994- if (ip == (u8 *)regs->ip)
10995+ if (ip == (u8 *)regs->ip + cs_base)
10996 printk("<%02x> ", c);
10997 else
10998 printk("%02x ", c);
16454cff 10999@@ -131,6 +132,7 @@ int is_valid_bugaddr(unsigned long ip)
58c5fc13
MT
11000 {
11001 unsigned short ud2;
11002
11003+ ip = ktla_ktva(ip);
11004 if (ip < PAGE_OFFSET)
11005 return 0;
11006 if (probe_kernel_address((unsigned short *)ip, ud2))
16454cff
MT
11007diff -urNp linux-2.6.38.1/arch/x86/kernel/dumpstack.c linux-2.6.38.1/arch/x86/kernel/dumpstack.c
11008--- linux-2.6.38.1/arch/x86/kernel/dumpstack.c 2011-03-14 21:20:32.000000000 -0400
11009+++ linux-2.6.38.1/arch/x86/kernel/dumpstack.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
11010@@ -2,6 +2,9 @@
11011 * Copyright (C) 1991, 1992 Linus Torvalds
11012 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
11013 */
11014+#ifdef CONFIG_GRKERNSEC_HIDESYM
11015+#define __INCLUDED_BY_HIDESYM 1
11016+#endif
11017 #include <linux/kallsyms.h>
11018 #include <linux/kprobes.h>
11019 #include <linux/uaccess.h>
11020@@ -27,7 +30,7 @@ static int die_counter;
11021
11022 void printk_address(unsigned long address, int reliable)
11023 {
11024- printk(" [<%p>] %s%pS\n", (void *) address,
11025+ printk(" [<%p>] %s%pA\n", (void *) address,
11026 reliable ? "" : "? ", (void *) address);
11027 }
11028
16454cff
MT
11029@@ -200,7 +203,7 @@ void dump_stack(void)
11030 unsigned long stack;
57199397
MT
11031
11032 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
11033- current->pid, current->comm, print_tainted(),
11034+ task_pid_nr(current), current->comm, print_tainted(),
11035 init_utsname()->release,
11036 (int)strcspn(init_utsname()->version, " "),
11037 init_utsname()->version);
16454cff 11038@@ -257,7 +260,7 @@ void __kprobes oops_end(unsigned long fl
57199397
MT
11039 panic("Fatal exception in interrupt");
11040 if (panic_on_oops)
11041 panic("Fatal exception");
11042- do_exit(signr);
11043+ do_group_exit(signr);
11044 }
11045
11046 int __kprobes __die(const char *str, struct pt_regs *regs, long err)
16454cff 11047@@ -284,7 +287,7 @@ int __kprobes __die(const char *str, str
57199397
MT
11048
11049 show_registers(regs);
11050 #ifdef CONFIG_X86_32
11051- if (user_mode_vm(regs)) {
11052+ if (user_mode(regs)) {
11053 sp = regs->sp;
11054 ss = regs->ss & 0xffff;
11055 } else {
16454cff 11056@@ -312,7 +315,7 @@ void die(const char *str, struct pt_regs
57199397
MT
11057 unsigned long flags = oops_begin();
11058 int sig = SIGSEGV;
11059
11060- if (!user_mode_vm(regs))
11061+ if (!user_mode(regs))
11062 report_bug(regs->ip, regs);
11063
11064 if (__die(str, regs, err))
16454cff
MT
11065diff -urNp linux-2.6.38.1/arch/x86/kernel/entry_32.S linux-2.6.38.1/arch/x86/kernel/entry_32.S
11066--- linux-2.6.38.1/arch/x86/kernel/entry_32.S 2011-03-14 21:20:32.000000000 -0400
11067+++ linux-2.6.38.1/arch/x86/kernel/entry_32.S 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
11068@@ -183,13 +183,81 @@
11069 /*CFI_REL_OFFSET gs, PT_GS*/
11070 .endm
11071 .macro SET_KERNEL_GS reg
58c5fc13 11072+
bc901d79
MT
11073+#ifdef CONFIG_CC_STACKPROTECTOR
11074 movl $(__KERNEL_STACK_CANARY), \reg
11075+#elif defined(CONFIG_PAX_MEMORY_UDEREF)
11076+ movl $(__USER_DS), \reg
11077+#else
11078+ xorl \reg, \reg
11079+#endif
11080+
11081 movl \reg, %gs
11082 .endm
58c5fc13
MT
11083
11084 #endif /* CONFIG_X86_32_LAZY_GS */
11085
11086-.macro SAVE_ALL
df50ba0c
MT
11087+.macro PAX_EXIT_KERNEL
11088+#ifdef CONFIG_PAX_KERNEXEC
11089+#ifdef CONFIG_PARAVIRT
bc901d79 11090+ push %eax; push %ecx
df50ba0c
MT
11091+#endif
11092+ mov %cs, %esi
11093+ cmp $__KERNEXEC_KERNEL_CS, %esi
11094+ jnz 2f
11095+#ifdef CONFIG_PARAVIRT
11096+ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0);
11097+ mov %eax, %esi
11098+#else
11099+ mov %cr0, %esi
11100+#endif
11101+ btr $16, %esi
11102+ ljmp $__KERNEL_CS, $1f
11103+1:
11104+#ifdef CONFIG_PARAVIRT
11105+ mov %esi, %eax
11106+ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0);
11107+#else
11108+ mov %esi, %cr0
11109+#endif
11110+2:
11111+#ifdef CONFIG_PARAVIRT
11112+ pop %ecx; pop %eax
11113+#endif
11114+#endif
11115+.endm
11116+
11117+.macro PAX_ENTER_KERNEL
11118+#ifdef CONFIG_PAX_KERNEXEC
11119+#ifdef CONFIG_PARAVIRT
bc901d79 11120+ push %eax; push %ecx
df50ba0c
MT
11121+ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0)
11122+ mov %eax, %esi
11123+#else
11124+ mov %cr0, %esi
11125+#endif
11126+ bts $16, %esi
11127+ jnc 1f
11128+ mov %cs, %esi
11129+ cmp $__KERNEL_CS, %esi
11130+ jz 3f
11131+ ljmp $__KERNEL_CS, $3f
11132+1: ljmp $__KERNEXEC_KERNEL_CS, $2f
11133+2:
11134+#ifdef CONFIG_PARAVIRT
11135+ mov %esi, %eax
11136+ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0)
11137+#else
11138+ mov %esi, %cr0
11139+#endif
11140+3:
11141+#ifdef CONFIG_PARAVIRT
11142+ pop %ecx; pop %eax
11143+#endif
11144+#endif
11145+.endm
11146+
58c5fc13
MT
11147+.macro __SAVE_ALL _DS
11148 cld
11149 PUSH_GS
bc901d79
MT
11150 pushl_cfi %fs
11151@@ -212,7 +280,7 @@
11152 CFI_REL_OFFSET ecx, 0
11153 pushl_cfi %ebx
58c5fc13
MT
11154 CFI_REL_OFFSET ebx, 0
11155- movl $(__USER_DS), %edx
11156+ movl $\_DS, %edx
11157 movl %edx, %ds
11158 movl %edx, %es
11159 movl $(__KERNEL_PERCPU), %edx
bc901d79 11160@@ -220,6 +288,15 @@
58c5fc13
MT
11161 SET_KERNEL_GS %edx
11162 .endm
11163
11164+.macro SAVE_ALL
ae4e228f 11165+#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
58c5fc13 11166+ __SAVE_ALL __KERNEL_DS
ae4e228f 11167+ PAX_ENTER_KERNEL
58c5fc13
MT
11168+#else
11169+ __SAVE_ALL __USER_DS
11170+#endif
11171+.endm
11172+
11173 .macro RESTORE_INT_REGS
bc901d79
MT
11174 popl_cfi %ebx
11175 CFI_RESTORE ebx
11176@@ -330,7 +407,15 @@ check_userspace:
58c5fc13
MT
11177 movb PT_CS(%esp), %al
11178 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
11179 cmpl $USER_RPL, %eax
11180+
11181+#ifdef CONFIG_PAX_KERNEXEC
11182+ jae resume_userspace
ae4e228f
MT
11183+
11184+ PAX_EXIT_KERNEL
58c5fc13
MT
11185+ jmp resume_kernel
11186+#else
11187 jb resume_kernel # not returning to v8086 or userspace
11188+#endif
11189
11190 ENTRY(resume_userspace)
11191 LOCKDEP_SYS_EXIT
bc901d79 11192@@ -392,10 +477,9 @@ sysenter_past_esp:
58c5fc13
MT
11193 /*CFI_REL_OFFSET cs, 0*/
11194 /*
11195 * Push current_thread_info()->sysenter_return to the stack.
11196- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
11197- * pushed above; +8 corresponds to copy_thread's esp0 setting.
11198 */
bc901d79 11199- pushl_cfi ((TI_sysenter_return)-THREAD_SIZE_asm+8+4*4)(%esp)
58c5fc13 11200+ GET_THREAD_INFO(%ebp)
bc901d79 11201+ pushl_cfi TI_sysenter_return(%ebp)
58c5fc13
MT
11202 CFI_REL_OFFSET eip, 0
11203
bc901d79
MT
11204 pushl_cfi %eax
11205@@ -406,9 +490,19 @@ sysenter_past_esp:
58c5fc13
MT
11206 * Load the potential sixth argument from user stack.
11207 * Careful about security.
11208 */
11209+ movl PT_OLDESP(%esp),%ebp
11210+
11211+#ifdef CONFIG_PAX_MEMORY_UDEREF
11212+ mov PT_OLDSS(%esp),%ds
11213+1: movl %ds:(%ebp),%ebp
11214+ push %ss
11215+ pop %ds
11216+#else
11217 cmpl $__PAGE_OFFSET-3,%ebp
11218 jae syscall_fault
11219 1: movl (%ebp),%ebp
11220+#endif
11221+
11222 movl %ebp,PT_EBP(%esp)
11223 .section __ex_table,"a"
11224 .align 4
bc901d79 11225@@ -431,12 +525,23 @@ sysenter_do_call:
58c5fc13
MT
11226 testl $_TIF_ALLWORK_MASK, %ecx
11227 jne sysexit_audit
11228 sysenter_exit:
11229+
11230+#ifdef CONFIG_PAX_RANDKSTACK
11231+ pushl %eax
11232+ CFI_ADJUST_CFA_OFFSET 4
11233+ call pax_randomize_kstack
11234+ popl %eax
11235+ CFI_ADJUST_CFA_OFFSET -4
11236+#endif
11237+
11238 /* if something modifies registers it must also disable sysexit */
11239 movl PT_EIP(%esp), %edx
11240 movl PT_OLDESP(%esp), %ecx
11241 xorl %ebp,%ebp
11242 TRACE_IRQS_ON
11243 1: mov PT_FS(%esp), %fs
11244+2: mov PT_DS(%esp), %ds
11245+3: mov PT_ES(%esp), %es
11246 PTGS_TO_GS
11247 ENABLE_INTERRUPTS_SYSEXIT
11248
bc901d79 11249@@ -479,11 +584,17 @@ sysexit_audit:
58c5fc13
MT
11250
11251 CFI_ENDPROC
11252 .pushsection .fixup,"ax"
11253-2: movl $0,PT_FS(%esp)
11254+4: movl $0,PT_FS(%esp)
11255+ jmp 1b
11256+5: movl $0,PT_DS(%esp)
11257+ jmp 1b
11258+6: movl $0,PT_ES(%esp)
11259 jmp 1b
11260 .section __ex_table,"a"
11261 .align 4
11262- .long 1b,2b
11263+ .long 1b,4b
11264+ .long 2b,5b
11265+ .long 3b,6b
11266 .popsection
11267 PTGS_TO_GS_EX
11268 ENDPROC(ia32_sysenter_target)
bc901d79 11269@@ -516,6 +627,10 @@ syscall_exit:
58c5fc13
MT
11270 testl $_TIF_ALLWORK_MASK, %ecx # current->work
11271 jne syscall_exit_work
11272
11273+#ifdef CONFIG_PAX_RANDKSTACK
11274+ call pax_randomize_kstack
11275+#endif
11276+
11277 restore_all:
11278 TRACE_IRQS_IRET
11279 restore_all_notrace:
bc901d79 11280@@ -575,14 +690,21 @@ ldt_ss:
6892158b
MT
11281 * compensating for the offset by changing to the ESPFIX segment with
11282 * a base address that matches for the difference.
11283 */
11284-#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
11285+#define GDT_ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)(%ebx)
11286 mov %esp, %edx /* load kernel esp */
58c5fc13
MT
11287 mov PT_OLDESP(%esp), %eax /* load userspace esp */
11288 mov %dx, %ax /* eax: new kernel esp */
11289 sub %eax, %edx /* offset (low word is 0) */
58c5fc13
MT
11290+#ifdef CONFIG_SMP
11291+ movl PER_CPU_VAR(cpu_number), %ebx
11292+ shll $PAGE_SHIFT_asm, %ebx
11293+ addl $cpu_gdt_table, %ebx
11294+#else
11295+ movl $cpu_gdt_table, %ebx
11296+#endif
11297 shr $16, %edx
6892158b
MT
11298- mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
11299- mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
11300+ mov %dl, 4 + GDT_ESPFIX_SS /* bits 16..23 */
11301+ mov %dh, 7 + GDT_ESPFIX_SS /* bits 24..31 */
bc901d79
MT
11302 pushl_cfi $__ESPFIX_SS
11303 pushl_cfi %eax /* new kernel esp */
11304 /* Disable interrupts, but do not irqtrace this section: we
11305@@ -617,23 +739,17 @@ work_resched:
58c5fc13
MT
11306
11307 work_notifysig: # deal with pending signals and
11308 # notify-resume requests
11309+ movl %esp, %eax
11310 #ifdef CONFIG_VM86
11311 testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
11312- movl %esp, %eax
11313- jne work_notifysig_v86 # returning to kernel-space or
11314+ jz 1f # returning to kernel-space or
11315 # vm86-space
11316- xorl %edx, %edx
11317- call do_notify_resume
11318- jmp resume_userspace_sig
11319
11320- ALIGN
11321-work_notifysig_v86:
bc901d79 11322 pushl_cfi %ecx # save ti_flags for do_notify_resume
58c5fc13 11323 call save_v86_state # %eax contains pt_regs pointer
bc901d79 11324 popl_cfi %ecx
58c5fc13
MT
11325 movl %eax, %esp
11326-#else
11327- movl %esp, %eax
11328+1:
11329 #endif
11330 xorl %edx, %edx
11331 call do_notify_resume
bc901d79 11332@@ -668,6 +784,10 @@ END(syscall_exit_work)
58c5fc13
MT
11333
11334 RING0_INT_FRAME # can't unwind into user space anyway
11335 syscall_fault:
11336+#ifdef CONFIG_PAX_MEMORY_UDEREF
11337+ push %ss
11338+ pop %ds
11339+#endif
11340 GET_THREAD_INFO(%ebp)
11341 movl $-EFAULT,PT_EAX(%esp)
11342 jmp resume_userspace
bc901d79
MT
11343@@ -750,6 +870,36 @@ ptregs_clone:
11344 CFI_ENDPROC
11345 ENDPROC(ptregs_clone)
11346
11347+ ALIGN;
11348+ENTRY(kernel_execve)
11349+ CFI_STARTPROC
11350+ pushl_cfi %ebp
11351+ sub $PT_OLDSS+4,%esp
11352+ pushl_cfi %edi
11353+ pushl_cfi %ecx
11354+ pushl_cfi %eax
11355+ lea 3*4(%esp),%edi
11356+ mov $PT_OLDSS/4+1,%ecx
11357+ xorl %eax,%eax
11358+ rep stosl
11359+ popl_cfi %eax
11360+ popl_cfi %ecx
11361+ popl_cfi %edi
11362+ movl $X86_EFLAGS_IF,PT_EFLAGS(%esp)
11363+ pushl_cfi %esp
11364+ call sys_execve
11365+ add $4,%esp
11366+ CFI_ADJUST_CFA_OFFSET -4
11367+ GET_THREAD_INFO(%ebp)
11368+ test %eax,%eax
11369+ jz syscall_exit
11370+ add $PT_OLDSS+4,%esp
11371+ CFI_ADJUST_CFA_OFFSET -PT_OLDSS-4
11372+ popl_cfi %ebp
11373+ ret
11374+ CFI_ENDPROC
11375+ENDPROC(kernel_execve)
11376+
11377 .macro FIXUP_ESPFIX_STACK
11378 /*
11379 * Switch back for ESPFIX stack to the normal zerobased stack
11380@@ -759,8 +909,15 @@ ENDPROC(ptregs_clone)
58c5fc13
MT
11381 * normal stack and adjusts ESP with the matching offset.
11382 */
11383 /* fixup the stack */
6892158b
MT
11384- mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
11385- mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
58c5fc13
MT
11386+#ifdef CONFIG_SMP
11387+ movl PER_CPU_VAR(cpu_number), %ebx
11388+ shll $PAGE_SHIFT_asm, %ebx
11389+ addl $cpu_gdt_table, %ebx
11390+#else
11391+ movl $cpu_gdt_table, %ebx
11392+#endif
6892158b
MT
11393+ mov 4 + GDT_ESPFIX_SS, %al /* bits 16..23 */
11394+ mov 7 + GDT_ESPFIX_SS, %ah /* bits 24..31 */
58c5fc13 11395 shl $16, %eax
6892158b 11396 addl %esp, %eax /* the adjusted stack pointer */
bc901d79
MT
11397 pushl_cfi $__KERNEL_DS
11398@@ -1211,7 +1368,6 @@ return_to_handler:
ae4e228f 11399 jmp *%ecx
58c5fc13
MT
11400 #endif
11401
11402-.section .rodata,"a"
11403 #include "syscall_table_32.S"
11404
11405 syscall_table_size=(.-sys_call_table)
bc901d79 11406@@ -1257,9 +1413,12 @@ error_code:
58c5fc13
MT
11407 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
11408 REG_TO_PTGS %ecx
11409 SET_KERNEL_GS %ecx
11410- movl $(__USER_DS), %ecx
11411+ movl $(__KERNEL_DS), %ecx
11412 movl %ecx, %ds
11413 movl %ecx, %es
df50ba0c
MT
11414+
11415+ PAX_ENTER_KERNEL
11416+
58c5fc13 11417 TRACE_IRQS_OFF
df50ba0c
MT
11418 movl %esp,%eax # pt_regs pointer
11419 call *%edi
bc901d79 11420@@ -1344,6 +1503,9 @@ nmi_stack_correct:
58c5fc13
MT
11421 xorl %edx,%edx # zero error code
11422 movl %esp,%eax # pt_regs pointer
11423 call do_nmi
11424+
ae4e228f 11425+ PAX_EXIT_KERNEL
58c5fc13
MT
11426+
11427 jmp restore_all_notrace
11428 CFI_ENDPROC
11429
bc901d79 11430@@ -1380,6 +1542,9 @@ nmi_espfix_stack:
58c5fc13
MT
11431 FIXUP_ESPFIX_STACK # %eax == %esp
11432 xorl %edx,%edx # zero error code
11433 call do_nmi
11434+
ae4e228f 11435+ PAX_EXIT_KERNEL
58c5fc13
MT
11436+
11437 RESTORE_REGS
11438 lss 12+4(%esp), %esp # back to espfix stack
11439 CFI_ADJUST_CFA_OFFSET -24
16454cff
MT
11440diff -urNp linux-2.6.38.1/arch/x86/kernel/entry_64.S linux-2.6.38.1/arch/x86/kernel/entry_64.S
11441--- linux-2.6.38.1/arch/x86/kernel/entry_64.S 2011-03-23 17:20:06.000000000 -0400
11442+++ linux-2.6.38.1/arch/x86/kernel/entry_64.S 2011-03-23 17:21:49.000000000 -0400
ae4e228f
MT
11443@@ -53,6 +53,7 @@
11444 #include <asm/paravirt.h>
11445 #include <asm/ftrace.h>
11446 #include <asm/percpu.h>
11447+#include <asm/pgtable.h>
11448
11449 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
11450 #include <linux/elf-em.h>
317566c1 11451@@ -174,6 +175,201 @@ ENTRY(native_usergs_sysret64)
df50ba0c
MT
11452 ENDPROC(native_usergs_sysret64)
11453 #endif /* CONFIG_PARAVIRT */
11454
11455+ .macro ljmpq sel, off
11456+#if defined(CONFIG_MCORE2) || defined (CONFIG_MATOM)
11457+ .byte 0x48; ljmp *1234f(%rip)
11458+ .pushsection .rodata
11459+ .align 16
11460+ 1234: .quad \off; .word \sel
11461+ .popsection
11462+#else
11463+ push $\sel
11464+ push $\off
11465+ lretq
11466+#endif
11467+ .endm
11468+
317566c1
MT
11469+ .macro pax_enter_kernel
11470+#ifdef CONFIG_PAX_KERNEXEC
11471+ call pax_enter_kernel
11472+#endif
11473+ .endm
11474+
11475+ .macro pax_exit_kernel
11476+#ifdef CONFIG_PAX_KERNEXEC
11477+ call pax_exit_kernel
11478+#endif
11479+ .endm
df50ba0c
MT
11480+
11481+#ifdef CONFIG_PAX_KERNEXEC
317566c1 11482+ENTRY(pax_enter_kernel)
df50ba0c
MT
11483+ push %rdi
11484+
11485+#ifdef CONFIG_PARAVIRT
11486+ PV_SAVE_REGS(CLBR_RDI)
11487+#endif
11488+
11489+ GET_CR0_INTO_RDI
11490+ bts $16,%rdi
11491+ jnc 1f
11492+ mov %cs,%edi
11493+ cmp $__KERNEL_CS,%edi
11494+ jz 3f
11495+ ljmpq __KERNEL_CS,3f
11496+1: ljmpq __KERNEXEC_KERNEL_CS,2f
11497+2: SET_RDI_INTO_CR0
11498+3:
11499+
11500+#ifdef CONFIG_PARAVIRT
11501+ PV_RESTORE_REGS(CLBR_RDI)
11502+#endif
11503+
11504+ pop %rdi
df50ba0c
MT
11505+ retq
11506+ENDPROC(pax_enter_kernel)
11507+
11508+ENTRY(pax_exit_kernel)
df50ba0c
MT
11509+ push %rdi
11510+
11511+#ifdef CONFIG_PARAVIRT
11512+ PV_SAVE_REGS(CLBR_RDI)
11513+#endif
11514+
11515+ mov %cs,%rdi
11516+ cmp $__KERNEXEC_KERNEL_CS,%edi
11517+ jnz 2f
11518+ GET_CR0_INTO_RDI
11519+ btr $16,%rdi
11520+ ljmpq __KERNEL_CS,1f
11521+1: SET_RDI_INTO_CR0
11522+2:
11523+
11524+#ifdef CONFIG_PARAVIRT
11525+ PV_RESTORE_REGS(CLBR_RDI);
11526+#endif
11527+
11528+ pop %rdi
df50ba0c
MT
11529+ retq
11530+ENDPROC(pax_exit_kernel)
317566c1 11531+#endif
df50ba0c 11532+
317566c1
MT
11533+ .macro pax_enter_kernel_user
11534+#ifdef CONFIG_PAX_MEMORY_UDEREF
11535+ call pax_enter_kernel_user
11536+#endif
11537+ .endm
df50ba0c 11538+
317566c1 11539+ .macro pax_exit_kernel_user
df50ba0c 11540+#ifdef CONFIG_PAX_MEMORY_UDEREF
317566c1
MT
11541+ call pax_exit_kernel_user
11542+#endif
11543+ .endm
11544+
11545+#ifdef CONFIG_PAX_MEMORY_UDEREF
11546+ENTRY(pax_enter_kernel_user)
df50ba0c
MT
11547+ push %rdi
11548+ push %rbx
11549+
11550+#ifdef CONFIG_PARAVIRT
11551+ PV_SAVE_REGS(CLBR_RDI)
11552+#endif
11553+
11554+ GET_CR3_INTO_RDI
11555+ mov %rdi,%rbx
11556+ add $__START_KERNEL_map,%rbx
11557+ sub phys_base(%rip),%rbx
11558+
11559+#ifdef CONFIG_PARAVIRT
11560+ push %rdi
11561+ cmpl $0, pv_info+PARAVIRT_enabled
11562+ jz 1f
11563+ i = 0
11564+ .rept USER_PGD_PTRS
11565+ mov i*8(%rbx),%rsi
11566+ mov $0,%sil
11567+ lea i*8(%rbx),%rdi
11568+ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_set_pgd)
11569+ i = i + 1
11570+ .endr
11571+ jmp 2f
11572+1:
11573+#endif
11574+
11575+ i = 0
11576+ .rept USER_PGD_PTRS
11577+ movb $0,i*8(%rbx)
11578+ i = i + 1
11579+ .endr
11580+
11581+#ifdef CONFIG_PARAVIRT
11582+2: pop %rdi
11583+#endif
11584+ SET_RDI_INTO_CR3
11585+
11586+#ifdef CONFIG_PAX_KERNEXEC
11587+ GET_CR0_INTO_RDI
11588+ bts $16,%rdi
11589+ SET_RDI_INTO_CR0
11590+#endif
11591+
11592+#ifdef CONFIG_PARAVIRT
11593+ PV_RESTORE_REGS(CLBR_RDI)
11594+#endif
11595+
11596+ pop %rbx
11597+ pop %rdi
df50ba0c
MT
11598+ retq
11599+ENDPROC(pax_enter_kernel_user)
11600+
11601+ENTRY(pax_exit_kernel_user)
df50ba0c
MT
11602+ push %rdi
11603+
11604+#ifdef CONFIG_PARAVIRT
11605+ push %rbx
11606+ PV_SAVE_REGS(CLBR_RDI)
11607+#endif
11608+
11609+#ifdef CONFIG_PAX_KERNEXEC
11610+ GET_CR0_INTO_RDI
11611+ btr $16,%rdi
11612+ SET_RDI_INTO_CR0
11613+#endif
11614+
11615+ GET_CR3_INTO_RDI
11616+ add $__START_KERNEL_map,%rdi
11617+ sub phys_base(%rip),%rdi
11618+
11619+#ifdef CONFIG_PARAVIRT
11620+ cmpl $0, pv_info+PARAVIRT_enabled
11621+ jz 1f
11622+ mov %rdi,%rbx
11623+ i = 0
11624+ .rept USER_PGD_PTRS
11625+ mov i*8(%rbx),%rsi
11626+ mov $0x67,%sil
11627+ lea i*8(%rbx),%rdi
11628+ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_set_pgd)
11629+ i = i + 1
11630+ .endr
11631+ jmp 2f
11632+1:
11633+#endif
11634+
11635+ i = 0
11636+ .rept USER_PGD_PTRS
11637+ movb $0x67,i*8(%rdi)
11638+ i = i + 1
11639+ .endr
11640+
11641+#ifdef CONFIG_PARAVIRT
11642+2: PV_RESTORE_REGS(CLBR_RDI)
11643+ pop %rbx
11644+#endif
11645+
11646+ pop %rdi
df50ba0c
MT
11647+ retq
11648+ENDPROC(pax_exit_kernel_user)
317566c1 11649+#endif
df50ba0c
MT
11650
11651 .macro TRACE_IRQS_IRETQ offset=ARGOFFSET
11652 #ifdef CONFIG_TRACE_IRQFLAGS
16454cff
MT
11653@@ -316,7 +512,7 @@ ENTRY(save_args)
11654 leaq -RBP+8(%rsp),%rdi /* arg1 for handler */
df50ba0c
MT
11655 movq_cfi rbp, 8 /* push %rbp */
11656 leaq 8(%rsp), %rbp /* mov %rsp, %ebp */
11657- testl $3, CS(%rdi)
11658+ testb $3, CS(%rdi)
11659 je 1f
11660 SWAPGS
11661 /*
16454cff 11662@@ -407,7 +603,7 @@ ENTRY(ret_from_fork)
df50ba0c
MT
11663
11664 RESTORE_REST
11665
11666- testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread?
11667+ testb $3, CS-ARGOFFSET(%rsp) # from kernel_thread?
11668 je int_ret_from_sys_call
11669
11670 testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET
16454cff 11671@@ -466,6 +662,7 @@ ENTRY(system_call_after_swapgs)
df50ba0c
MT
11672
11673 movq %rsp,PER_CPU_VAR(old_rsp)
11674 movq PER_CPU_VAR(kernel_stack),%rsp
317566c1 11675+ pax_enter_kernel_user
df50ba0c
MT
11676 /*
11677 * No need to follow this irqs off/on section - it's straight
11678 * and short:
16454cff 11679@@ -500,6 +697,7 @@ sysret_check:
df50ba0c
MT
11680 andl %edi,%edx
11681 jnz sysret_careful
11682 CFI_REMEMBER_STATE
317566c1 11683+ pax_exit_kernel_user
df50ba0c
MT
11684 /*
11685 * sysretq will re-enable interrupts:
11686 */
16454cff 11687@@ -609,7 +807,7 @@ tracesys:
df50ba0c
MT
11688 GLOBAL(int_ret_from_sys_call)
11689 DISABLE_INTERRUPTS(CLBR_NONE)
11690 TRACE_IRQS_OFF
11691- testl $3,CS-ARGOFFSET(%rsp)
11692+ testb $3,CS-ARGOFFSET(%rsp)
11693 je retint_restore_args
11694 movl $_TIF_ALLWORK_MASK,%edi
11695 /* edi: mask to check */
16454cff
MT
11696@@ -791,6 +989,16 @@ END(interrupt)
11697 CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP
ae4e228f
MT
11698 call save_args
11699 PARTIAL_FRAME 0
df50ba0c
MT
11700+#ifdef CONFIG_PAX_MEMORY_UDEREF
11701+ testb $3, CS(%rdi)
11702+ jnz 1f
317566c1 11703+ pax_enter_kernel
df50ba0c 11704+ jmp 2f
317566c1 11705+1: pax_enter_kernel_user
df50ba0c
MT
11706+2:
11707+#else
317566c1 11708+ pax_enter_kernel
df50ba0c 11709+#endif
ae4e228f
MT
11710 call \func
11711 .endm
11712
16454cff 11713@@ -823,7 +1031,7 @@ ret_from_intr:
ae4e228f
MT
11714 CFI_ADJUST_CFA_OFFSET -8
11715 exit_intr:
ae4e228f 11716 GET_THREAD_INFO(%rcx)
df50ba0c
MT
11717- testl $3,CS-ARGOFFSET(%rsp)
11718+ testb $3,CS-ARGOFFSET(%rsp)
ae4e228f 11719 je retint_kernel
df50ba0c
MT
11720
11721 /* Interrupt came from user space */
16454cff 11722@@ -845,12 +1053,14 @@ retint_swapgs: /* return to user-space
df50ba0c
MT
11723 * The iretq could re-enable interrupts:
11724 */
11725 DISABLE_INTERRUPTS(CLBR_ANY)
317566c1 11726+ pax_exit_kernel_user
df50ba0c
MT
11727 TRACE_IRQS_IRETQ
11728 SWAPGS
11729 jmp restore_args
11730
11731 retint_restore_args: /* return to kernel space */
11732 DISABLE_INTERRUPTS(CLBR_ANY)
317566c1 11733+ pax_exit_kernel
df50ba0c
MT
11734 /*
11735 * The iretq could re-enable interrupts:
11736 */
16454cff 11737@@ -1022,6 +1232,16 @@ ENTRY(\sym)
bc901d79 11738 CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
ae4e228f
MT
11739 call error_entry
11740 DEFAULT_FRAME 0
df50ba0c
MT
11741+#ifdef CONFIG_PAX_MEMORY_UDEREF
11742+ testb $3, CS(%rsp)
11743+ jnz 1f
317566c1 11744+ pax_enter_kernel
df50ba0c 11745+ jmp 2f
317566c1 11746+1: pax_enter_kernel_user
df50ba0c
MT
11747+2:
11748+#else
317566c1 11749+ pax_enter_kernel
df50ba0c 11750+#endif
ae4e228f
MT
11751 movq %rsp,%rdi /* pt_regs pointer */
11752 xorl %esi,%esi /* no error code */
11753 call \do_sym
16454cff 11754@@ -1039,6 +1259,16 @@ ENTRY(\sym)
bc901d79 11755 CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
ae4e228f
MT
11756 call save_paranoid
11757 TRACE_IRQS_OFF
df50ba0c
MT
11758+#ifdef CONFIG_PAX_MEMORY_UDEREF
11759+ testb $3, CS(%rsp)
11760+ jnz 1f
317566c1 11761+ pax_enter_kernel
df50ba0c 11762+ jmp 2f
317566c1 11763+1: pax_enter_kernel_user
df50ba0c
MT
11764+2:
11765+#else
317566c1 11766+ pax_enter_kernel
df50ba0c 11767+#endif
ae4e228f
MT
11768 movq %rsp,%rdi /* pt_regs pointer */
11769 xorl %esi,%esi /* no error code */
11770 call \do_sym
16454cff 11771@@ -1047,7 +1277,7 @@ ENTRY(\sym)
6892158b
MT
11772 END(\sym)
11773 .endm
11774
11775-#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
11776+#define INIT_TSS_IST(x) (TSS_ist + ((x) - 1) * 8)(%r12)
11777 .macro paranoidzeroentry_ist sym do_sym ist
11778 ENTRY(\sym)
11779 INTR_FRAME
16454cff 11780@@ -1057,8 +1287,24 @@ ENTRY(\sym)
bc901d79 11781 CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
ae4e228f 11782 call save_paranoid
58c5fc13 11783 TRACE_IRQS_OFF
df50ba0c
MT
11784+#ifdef CONFIG_PAX_MEMORY_UDEREF
11785+ testb $3, CS(%rsp)
11786+ jnz 1f
317566c1 11787+ pax_enter_kernel
df50ba0c 11788+ jmp 2f
317566c1 11789+1: pax_enter_kernel_user
df50ba0c
MT
11790+2:
11791+#else
317566c1 11792+ pax_enter_kernel
df50ba0c 11793+#endif
58c5fc13
MT
11794 movq %rsp,%rdi /* pt_regs pointer */
11795 xorl %esi,%esi /* no error code */
58c5fc13 11796+#ifdef CONFIG_SMP
ae4e228f
MT
11797+ imul $TSS_size, PER_CPU_VAR(cpu_number), %r12d
11798+ lea init_tss(%r12), %r12
58c5fc13 11799+#else
ae4e228f 11800+ lea init_tss(%rip), %r12
58c5fc13 11801+#endif
6892158b 11802 subq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
58c5fc13 11803 call \do_sym
6892158b 11804 addq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
16454cff 11805@@ -1075,6 +1321,16 @@ ENTRY(\sym)
bc901d79 11806 CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
ae4e228f
MT
11807 call error_entry
11808 DEFAULT_FRAME 0
df50ba0c
MT
11809+#ifdef CONFIG_PAX_MEMORY_UDEREF
11810+ testb $3, CS(%rsp)
11811+ jnz 1f
317566c1 11812+ pax_enter_kernel
df50ba0c 11813+ jmp 2f
317566c1 11814+1: pax_enter_kernel_user
df50ba0c
MT
11815+2:
11816+#else
317566c1 11817+ pax_enter_kernel
df50ba0c 11818+#endif
ae4e228f
MT
11819 movq %rsp,%rdi /* pt_regs pointer */
11820 movq ORIG_RAX(%rsp),%rsi /* get error code */
11821 movq $-1,ORIG_RAX(%rsp) /* no syscall to restart */
16454cff 11822@@ -1094,6 +1350,16 @@ ENTRY(\sym)
ae4e228f
MT
11823 call save_paranoid
11824 DEFAULT_FRAME 0
11825 TRACE_IRQS_OFF
df50ba0c
MT
11826+#ifdef CONFIG_PAX_MEMORY_UDEREF
11827+ testb $3, CS(%rsp)
11828+ jnz 1f
317566c1 11829+ pax_enter_kernel
df50ba0c 11830+ jmp 2f
317566c1 11831+1: pax_enter_kernel_user
df50ba0c
MT
11832+2:
11833+#else
317566c1 11834+ pax_enter_kernel
df50ba0c 11835+#endif
ae4e228f
MT
11836 movq %rsp,%rdi /* pt_regs pointer */
11837 movq ORIG_RAX(%rsp),%rsi /* get error code */
11838 movq $-1,ORIG_RAX(%rsp) /* no syscall to restart */
16454cff 11839@@ -1356,14 +1622,27 @@ ENTRY(paranoid_exit)
df50ba0c
MT
11840 TRACE_IRQS_OFF
11841 testl %ebx,%ebx /* swapgs needed? */
11842 jnz paranoid_restore
11843- testl $3,CS(%rsp)
11844+ testb $3,CS(%rsp)
ae4e228f 11845 jnz paranoid_userspace
df50ba0c 11846+#ifdef CONFIG_PAX_MEMORY_UDEREF
317566c1 11847+ pax_exit_kernel
df50ba0c
MT
11848+ TRACE_IRQS_IRETQ 0
11849+ SWAPGS_UNSAFE_STACK
11850+ RESTORE_ALL 8
11851+ jmp irq_return
11852+#endif
ae4e228f 11853 paranoid_swapgs:
df50ba0c 11854+#ifdef CONFIG_PAX_MEMORY_UDEREF
317566c1 11855+ pax_exit_kernel_user
df50ba0c 11856+#else
317566c1 11857+ pax_exit_kernel
df50ba0c 11858+#endif
ae4e228f
MT
11859 TRACE_IRQS_IRETQ 0
11860 SWAPGS_UNSAFE_STACK
11861 RESTORE_ALL 8
11862 jmp irq_return
11863 paranoid_restore:
317566c1 11864+ pax_exit_kernel
ae4e228f
MT
11865 TRACE_IRQS_IRETQ 0
11866 RESTORE_ALL 8
11867 jmp irq_return
16454cff 11868@@ -1421,7 +1700,7 @@ ENTRY(error_entry)
df50ba0c
MT
11869 movq_cfi r14, R14+8
11870 movq_cfi r15, R15+8
11871 xorl %ebx,%ebx
11872- testl $3,CS+8(%rsp)
11873+ testb $3,CS+8(%rsp)
11874 je error_kernelspace
11875 error_swapgs:
11876 SWAPGS
16454cff 11877@@ -1485,6 +1764,16 @@ ENTRY(nmi)
bc901d79 11878 CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
ae4e228f
MT
11879 call save_paranoid
11880 DEFAULT_FRAME 0
df50ba0c
MT
11881+#ifdef CONFIG_PAX_MEMORY_UDEREF
11882+ testb $3, CS(%rsp)
11883+ jnz 1f
317566c1 11884+ pax_enter_kernel
df50ba0c 11885+ jmp 2f
317566c1 11886+1: pax_enter_kernel_user
df50ba0c
MT
11887+2:
11888+#else
317566c1 11889+ pax_enter_kernel
df50ba0c 11890+#endif
ae4e228f
MT
11891 /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
11892 movq %rsp,%rdi
11893 movq $-1,%rsi
16454cff 11894@@ -1495,11 +1784,25 @@ ENTRY(nmi)
df50ba0c
MT
11895 DISABLE_INTERRUPTS(CLBR_NONE)
11896 testl %ebx,%ebx /* swapgs needed? */
11897 jnz nmi_restore
11898- testl $3,CS(%rsp)
11899+ testb $3,CS(%rsp)
11900 jnz nmi_userspace
317566c1
MT
11901+#ifdef CONFIG_PAX_MEMORY_UDEREF
11902+ pax_exit_kernel
11903+ SWAPGS_UNSAFE_STACK
11904+ RESTORE_ALL 8
11905+ jmp irq_return
11906+#endif
ae4e228f 11907 nmi_swapgs:
317566c1
MT
11908+#ifdef CONFIG_PAX_MEMORY_UDEREF
11909+ pax_exit_kernel_user
11910+#else
11911+ pax_exit_kernel
11912+#endif
ae4e228f 11913 SWAPGS_UNSAFE_STACK
317566c1
MT
11914+ RESTORE_ALL 8
11915+ jmp irq_return
ae4e228f 11916 nmi_restore:
317566c1 11917+ pax_exit_kernel
ae4e228f
MT
11918 RESTORE_ALL 8
11919 jmp irq_return
11920 nmi_userspace:
16454cff
MT
11921diff -urNp linux-2.6.38.1/arch/x86/kernel/ftrace.c linux-2.6.38.1/arch/x86/kernel/ftrace.c
11922--- linux-2.6.38.1/arch/x86/kernel/ftrace.c 2011-03-14 21:20:32.000000000 -0400
11923+++ linux-2.6.38.1/arch/x86/kernel/ftrace.c 2011-03-21 18:31:35.000000000 -0400
11924@@ -177,7 +177,9 @@ void ftrace_nmi_enter(void)
df50ba0c 11925
ae4e228f
MT
11926 if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
11927 smp_rmb();
11928+ pax_open_kernel();
11929 ftrace_mod_code();
11930+ pax_close_kernel();
11931 atomic_inc(&nmi_update_count);
11932 }
11933 /* Must have previous changes seen before executions */
16454cff 11934@@ -271,6 +273,8 @@ ftrace_modify_code(unsigned long ip, uns
ae4e228f
MT
11935 {
11936 unsigned char replaced[MCOUNT_INSN_SIZE];
11937
11938+ ip = ktla_ktva(ip);
11939+
11940 /*
11941 * Note: Due to modules and __init, code can
11942 * disappear and change, we need to protect against faulting
16454cff 11943@@ -327,7 +331,7 @@ int ftrace_update_ftrace_func(ftrace_fun
58c5fc13
MT
11944 unsigned char old[MCOUNT_INSN_SIZE], *new;
11945 int ret;
11946
11947- memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
11948+ memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
11949 new = ftrace_call_replace(ip, (unsigned long)func);
ae4e228f
MT
11950 ret = ftrace_modify_code(ip, old, new);
11951
16454cff 11952@@ -353,6 +357,8 @@ static int ftrace_mod_jmp(unsigned long
ae4e228f
MT
11953 {
11954 unsigned char code[MCOUNT_INSN_SIZE];
11955
11956+ ip = ktla_ktva(ip);
11957+
11958 if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
11959 return -EFAULT;
11960
16454cff
MT
11961diff -urNp linux-2.6.38.1/arch/x86/kernel/head32.c linux-2.6.38.1/arch/x86/kernel/head32.c
11962--- linux-2.6.38.1/arch/x86/kernel/head32.c 2011-03-14 21:20:32.000000000 -0400
11963+++ linux-2.6.38.1/arch/x86/kernel/head32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 11964@@ -19,6 +19,7 @@
ae4e228f 11965 #include <asm/io_apic.h>
58c5fc13 11966 #include <asm/bios_ebda.h>
bc901d79 11967 #include <asm/tlbflush.h>
58c5fc13
MT
11968+#include <asm/boot.h>
11969
ae4e228f 11970 static void __init i386_default_early_setup(void)
58c5fc13 11971 {
bc901d79
MT
11972@@ -43,7 +44,7 @@ void __init i386_start_kernel(void)
11973 memblock_x86_reserve_range(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE");
df50ba0c 11974 #endif
58c5fc13 11975
bc901d79
MT
11976- memblock_x86_reserve_range(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
11977+ memblock_x86_reserve_range(LOAD_PHYSICAL_ADDR, __pa_symbol(&__bss_stop), "TEXT DATA BSS");
58c5fc13
MT
11978
11979 #ifdef CONFIG_BLK_DEV_INITRD
11980 /* Reserve INITRD */
16454cff
MT
11981diff -urNp linux-2.6.38.1/arch/x86/kernel/head_32.S linux-2.6.38.1/arch/x86/kernel/head_32.S
11982--- linux-2.6.38.1/arch/x86/kernel/head_32.S 2011-03-14 21:20:32.000000000 -0400
11983+++ linux-2.6.38.1/arch/x86/kernel/head_32.S 2011-03-21 18:31:35.000000000 -0400
df50ba0c 11984@@ -25,6 +25,12 @@
58c5fc13
MT
11985 /* Physical address */
11986 #define pa(X) ((X) - __PAGE_OFFSET)
ae4e228f
MT
11987
11988+#ifdef CONFIG_PAX_KERNEXEC
11989+#define ta(X) (X)
11990+#else
11991+#define ta(X) ((X) - __PAGE_OFFSET)
11992+#endif
11993+
11994 /*
11995 * References to members of the new_cpu_data structure.
11996 */
df50ba0c 11997@@ -54,11 +60,7 @@
58c5fc13
MT
11998 * and small than max_low_pfn, otherwise will waste some page table entries
11999 */
12000
12001-#if PTRS_PER_PMD > 1
12002-#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
12003-#else
12004-#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
12005-#endif
12006+#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PTE)
12007
bc901d79
MT
12008 /* Number of possible pages in the lowmem region */
12009 LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT)
12010@@ -77,6 +79,12 @@ INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_P
58c5fc13
MT
12011 RESERVE_BRK(pagetables, INIT_MAP_SIZE)
12012
12013 /*
12014+ * Real beginning of normal "text" segment
12015+ */
12016+ENTRY(stext)
12017+ENTRY(_stext)
12018+
12019+/*
12020 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
12021 * %esi points to the real-mode code as a 32-bit pointer.
12022 * CS and DS must be 4 GB flat segments, but we don't depend on
bc901d79 12023@@ -84,6 +92,13 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE)
58c5fc13
MT
12024 * can.
12025 */
ae4e228f 12026 __HEAD
58c5fc13
MT
12027+
12028+#ifdef CONFIG_PAX_KERNEXEC
12029+ jmp startup_32
12030+/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
12031+.fill PAGE_SIZE-5,1,0xcc
12032+#endif
12033+
12034 ENTRY(startup_32)
16454cff
MT
12035 movl pa(stack_start),%ecx
12036
12037@@ -105,6 +120,57 @@ ENTRY(startup_32)
58c5fc13 12038 2:
16454cff 12039 leal -__PAGE_OFFSET(%ecx),%esp
58c5fc13
MT
12040
12041+#ifdef CONFIG_SMP
12042+ movl $pa(cpu_gdt_table),%edi
12043+ movl $__per_cpu_load,%eax
12044+ movw %ax,__KERNEL_PERCPU + 2(%edi)
12045+ rorl $16,%eax
12046+ movb %al,__KERNEL_PERCPU + 4(%edi)
12047+ movb %ah,__KERNEL_PERCPU + 7(%edi)
12048+ movl $__per_cpu_end - 1,%eax
ae4e228f 12049+ subl $__per_cpu_start,%eax
58c5fc13
MT
12050+ movw %ax,__KERNEL_PERCPU + 0(%edi)
12051+#endif
12052+
12053+#ifdef CONFIG_PAX_MEMORY_UDEREF
12054+ movl $NR_CPUS,%ecx
12055+ movl $pa(cpu_gdt_table),%edi
12056+1:
12057+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
bc901d79
MT
12058+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0fb00),GDT_ENTRY_DEFAULT_USER_CS * 8 + 4(%edi)
12059+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0f300),GDT_ENTRY_DEFAULT_USER_DS * 8 + 4(%edi)
58c5fc13
MT
12060+ addl $PAGE_SIZE_asm,%edi
12061+ loop 1b
12062+#endif
12063+
12064+#ifdef CONFIG_PAX_KERNEXEC
12065+ movl $pa(boot_gdt),%edi
ae4e228f 12066+ movl $__LOAD_PHYSICAL_ADDR,%eax
58c5fc13
MT
12067+ movw %ax,__BOOT_CS + 2(%edi)
12068+ rorl $16,%eax
12069+ movb %al,__BOOT_CS + 4(%edi)
12070+ movb %ah,__BOOT_CS + 7(%edi)
12071+ rorl $16,%eax
12072+
ae4e228f
MT
12073+ ljmp $(__BOOT_CS),$1f
12074+1:
12075+
58c5fc13
MT
12076+ movl $NR_CPUS,%ecx
12077+ movl $pa(cpu_gdt_table),%edi
ae4e228f 12078+ addl $__PAGE_OFFSET,%eax
58c5fc13
MT
12079+1:
12080+ movw %ax,__KERNEL_CS + 2(%edi)
ae4e228f 12081+ movw %ax,__KERNEXEC_KERNEL_CS + 2(%edi)
58c5fc13
MT
12082+ rorl $16,%eax
12083+ movb %al,__KERNEL_CS + 4(%edi)
ae4e228f 12084+ movb %al,__KERNEXEC_KERNEL_CS + 4(%edi)
58c5fc13 12085+ movb %ah,__KERNEL_CS + 7(%edi)
ae4e228f 12086+ movb %ah,__KERNEXEC_KERNEL_CS + 7(%edi)
58c5fc13
MT
12087+ rorl $16,%eax
12088+ addl $PAGE_SIZE_asm,%edi
12089+ loop 1b
12090+#endif
12091+
12092 /*
12093 * Clear BSS first so that there are no surprises...
12094 */
16454cff 12095@@ -195,8 +261,11 @@ ENTRY(startup_32)
58c5fc13
MT
12096 movl %eax, pa(max_pfn_mapped)
12097
12098 /* Do early initialization of the fixmap area */
bc901d79
MT
12099- movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
12100- movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
58c5fc13 12101+#ifdef CONFIG_COMPAT_VDSO
bc901d79 12102+ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(initial_pg_pmd+0x1000*KPMDS-8)
58c5fc13 12103+#else
bc901d79 12104+ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,pa(initial_pg_pmd+0x1000*KPMDS-8)
58c5fc13
MT
12105+#endif
12106 #else /* Not PAE */
12107
12108 page_pde_offset = (__PAGE_OFFSET >> 20);
16454cff 12109@@ -226,8 +295,11 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
58c5fc13
MT
12110 movl %eax, pa(max_pfn_mapped)
12111
12112 /* Do early initialization of the fixmap area */
bc901d79
MT
12113- movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
12114- movl %eax,pa(initial_page_table+0xffc)
58c5fc13 12115+#ifdef CONFIG_COMPAT_VDSO
bc901d79 12116+ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(initial_page_table+0xffc)
58c5fc13 12117+#else
bc901d79 12118+ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,pa(initial_page_table+0xffc)
58c5fc13
MT
12119+#endif
12120 #endif
16454cff
MT
12121
12122 #ifdef CONFIG_PARAVIRT
12123@@ -241,9 +313,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
12124 cmpl $num_subarch_entries, %eax
12125 jae bad_subarch
12126
12127- movl pa(subarch_entries)(,%eax,4), %eax
12128- subl $__PAGE_OFFSET, %eax
12129- jmp *%eax
12130+ jmp *pa(subarch_entries)(,%eax,4)
12131
12132 bad_subarch:
12133 WEAK(lguest_entry)
12134@@ -255,10 +325,10 @@ WEAK(xen_entry)
12135 __INITDATA
12136
12137 subarch_entries:
12138- .long default_entry /* normal x86/PC */
12139- .long lguest_entry /* lguest hypervisor */
12140- .long xen_entry /* Xen hypervisor */
12141- .long default_entry /* Moorestown MID */
12142+ .long pa(default_entry) /* normal x86/PC */
12143+ .long pa(lguest_entry) /* lguest hypervisor */
12144+ .long pa(xen_entry) /* Xen hypervisor */
12145+ .long pa(default_entry) /* Moorestown MID */
12146 num_subarch_entries = (. - subarch_entries) / 4
12147 .previous
12148 #else
12149@@ -312,6 +382,7 @@ default_entry:
58c5fc13
MT
12150 orl %edx,%eax
12151 movl %eax,%cr4
12152
12153+#ifdef CONFIG_X86_PAE
ae4e228f
MT
12154 testb $X86_CR4_PAE, %al # check if PAE is enabled
12155 jz 6f
58c5fc13 12156
16454cff 12157@@ -340,6 +411,9 @@ default_entry:
58c5fc13
MT
12158 /* Make changes effective */
12159 wrmsr
12160
12161+ btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4)
58c5fc13 12162+#endif
ae4e228f 12163+
58c5fc13
MT
12164 6:
12165
12166 /*
16454cff 12167@@ -443,7 +517,7 @@ is386: movl $2,%ecx # set MP
58c5fc13
MT
12168 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
12169 movl %eax,%ss # after changing gdt.
12170
12171- movl $(__USER_DS),%eax # DS/ES contains default USER segment
12172+# movl $(__KERNEL_DS),%eax # DS/ES contains default KERNEL segment
12173 movl %eax,%ds
12174 movl %eax,%es
12175
16454cff 12176@@ -457,15 +531,22 @@ is386: movl $2,%ecx # set MP
58c5fc13
MT
12177 */
12178 cmpb $0,ready
12179 jne 1f
df50ba0c 12180- movl $gdt_page,%eax
58c5fc13 12181+ movl $cpu_gdt_table,%eax
df50ba0c 12182 movl $stack_canary,%ecx
58c5fc13
MT
12183+#ifdef CONFIG_SMP
12184+ addl $__per_cpu_load,%ecx
12185+#endif
12186 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
12187 shrl $16, %ecx
12188 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
bc901d79
MT
12189 movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
12190 1:
12191-#endif
12192 movl $(__KERNEL_STACK_CANARY),%eax
12193+#elif defined(CONFIG_PAX_MEMORY_UDEREF)
12194+ movl $(__USER_DS),%eax
12195+#else
12196+ xorl %eax,%eax
12197+#endif
12198 movl %eax,%gs
12199
12200 xorl %eax,%eax # Clear LDT
16454cff 12201@@ -558,22 +639,22 @@ early_page_fault:
58c5fc13
MT
12202 jmp early_fault
12203
12204 early_fault:
12205- cld
12206 #ifdef CONFIG_PRINTK
12207+ cmpl $1,%ss:early_recursion_flag
12208+ je hlt_loop
12209+ incl %ss:early_recursion_flag
12210+ cld
12211 pusha
12212 movl $(__KERNEL_DS),%eax
12213 movl %eax,%ds
12214 movl %eax,%es
12215- cmpl $2,early_recursion_flag
12216- je hlt_loop
12217- incl early_recursion_flag
12218 movl %cr2,%eax
12219 pushl %eax
12220 pushl %edx /* trapno */
12221 pushl $fault_msg
12222 call printk
12223+; call dump_stack
12224 #endif
12225- call dump_stack
12226 hlt_loop:
12227 hlt
12228 jmp hlt_loop
16454cff 12229@@ -581,8 +662,11 @@ hlt_loop:
58c5fc13
MT
12230 /* This is the default interrupt "handler" :-) */
12231 ALIGN
12232 ignore_int:
12233- cld
12234 #ifdef CONFIG_PRINTK
12235+ cmpl $2,%ss:early_recursion_flag
12236+ je hlt_loop
12237+ incl %ss:early_recursion_flag
12238+ cld
12239 pushl %eax
12240 pushl %ecx
12241 pushl %edx
16454cff 12242@@ -591,9 +675,6 @@ ignore_int:
58c5fc13
MT
12243 movl $(__KERNEL_DS),%eax
12244 movl %eax,%ds
12245 movl %eax,%es
12246- cmpl $2,early_recursion_flag
12247- je hlt_loop
12248- incl early_recursion_flag
12249 pushl 16(%esp)
12250 pushl 24(%esp)
12251 pushl 32(%esp)
16454cff 12252@@ -622,29 +703,43 @@ ENTRY(initial_code)
58c5fc13
MT
12253 /*
12254 * BSS section
12255 */
ae4e228f 12256-__PAGE_ALIGNED_BSS
58c5fc13
MT
12257- .align PAGE_SIZE_asm
12258 #ifdef CONFIG_X86_PAE
bc901d79 12259+.section .initial_pg_pmd,"a",@progbits
16454cff 12260 initial_pg_pmd:
58c5fc13
MT
12261 .fill 1024*KPMDS,4,0
12262 #else
c52201e0 12263+.section .initial_page_table,"a",@progbits
bc901d79 12264 ENTRY(initial_page_table)
58c5fc13
MT
12265 .fill 1024,4,0
12266 #endif
bc901d79 12267+.section .initial_pg_fixmap,"a",@progbits
16454cff 12268 initial_pg_fixmap:
58c5fc13 12269 .fill 1024,4,0
bc901d79
MT
12270+.section .empty_zero_page,"a",@progbits
12271 ENTRY(empty_zero_page)
12272 .fill 4096,1,0
12273+.section .swapper_pg_dir,"a",@progbits
12274 ENTRY(swapper_pg_dir)
6892158b
MT
12275+#ifdef CONFIG_X86_PAE
12276+ .fill 4,8,0
12277+#else
12278 .fill 1024,4,0
6892158b 12279+#endif
58c5fc13 12280+
bc901d79 12281+/*
58c5fc13
MT
12282+ * The IDT has to be page-aligned to simplify the Pentium
12283+ * F0 0F bug workaround.. We have a special link segment
12284+ * for this.
12285+ */
12286+.section .idt,"a",@progbits
12287+ENTRY(idt_table)
12288+ .fill 256,8,0
bc901d79
MT
12289
12290 /*
58c5fc13
MT
12291 * This starts the data section.
12292 */
12293 #ifdef CONFIG_X86_PAE
ae4e228f 12294-__PAGE_ALIGNED_DATA
58c5fc13
MT
12295- /* Page-aligned for the benefit of paravirt? */
12296- .align PAGE_SIZE_asm
bc901d79
MT
12297+.section .initial_page_table,"a",@progbits
12298 ENTRY(initial_page_table)
12299 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
58c5fc13 12300 # if KPMDS == 3
16454cff 12301@@ -663,13 +758,22 @@ ENTRY(initial_page_table)
df50ba0c
MT
12302 # error "Kernel PMDs should be 1, 2 or 3"
12303 # endif
12304 .align PAGE_SIZE_asm /* needs to be page-sized too */
12305+
12306+#ifdef CONFIG_PAX_PER_CPU_PGD
12307+ENTRY(cpu_pgd)
12308+ .rept NR_CPUS
12309+ .fill 4,8,0
12310+ .endr
12311+#endif
12312+
12313 #endif
58c5fc13
MT
12314
12315 .data
16454cff 12316 .balign 4
58c5fc13
MT
12317 ENTRY(stack_start)
12318- .long init_thread_union+THREAD_SIZE
12319+ .long init_thread_union+THREAD_SIZE-8
58c5fc13
MT
12320
12321+.section .rodata,"a",@progbits
12322 early_recursion_flag:
12323 .long 0
12324
16454cff 12325@@ -707,7 +811,7 @@ fault_msg:
58c5fc13
MT
12326 .word 0 # 32 bit align gdt_desc.address
12327 boot_gdt_descr:
12328 .word __BOOT_DS+7
12329- .long boot_gdt - __PAGE_OFFSET
12330+ .long pa(boot_gdt)
12331
12332 .word 0 # 32-bit align idt_desc.address
12333 idt_descr:
16454cff 12334@@ -718,7 +822,7 @@ idt_descr:
58c5fc13
MT
12335 .word 0 # 32 bit align gdt_desc.address
12336 ENTRY(early_gdt_descr)
12337 .word GDT_ENTRIES*8-1
df50ba0c 12338- .long gdt_page /* Overwritten for secondary CPUs */
58c5fc13
MT
12339+ .long cpu_gdt_table /* Overwritten for secondary CPUs */
12340
12341 /*
12342 * The boot_gdt must mirror the equivalent in setup.S and is
16454cff 12343@@ -727,5 +831,65 @@ ENTRY(early_gdt_descr)
58c5fc13
MT
12344 .align L1_CACHE_BYTES
12345 ENTRY(boot_gdt)
12346 .fill GDT_ENTRY_BOOT_CS,8,0
12347- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
12348- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
12349+ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
12350+ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
12351+
12352+ .align PAGE_SIZE_asm
12353+ENTRY(cpu_gdt_table)
12354+ .rept NR_CPUS
12355+ .quad 0x0000000000000000 /* NULL descriptor */
12356+ .quad 0x0000000000000000 /* 0x0b reserved */
12357+ .quad 0x0000000000000000 /* 0x13 reserved */
12358+ .quad 0x0000000000000000 /* 0x1b reserved */
ae4e228f
MT
12359+
12360+#ifdef CONFIG_PAX_KERNEXEC
12361+ .quad 0x00cf9b000000ffff /* 0x20 alternate kernel 4GB code at 0x00000000 */
12362+#else
58c5fc13 12363+ .quad 0x0000000000000000 /* 0x20 unused */
ae4e228f
MT
12364+#endif
12365+
58c5fc13
MT
12366+ .quad 0x0000000000000000 /* 0x28 unused */
12367+ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
12368+ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
12369+ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
12370+ .quad 0x0000000000000000 /* 0x4b reserved */
12371+ .quad 0x0000000000000000 /* 0x53 reserved */
12372+ .quad 0x0000000000000000 /* 0x5b reserved */
12373+
12374+ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
12375+ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
12376+ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
12377+ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
12378+
12379+ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
12380+ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
12381+
12382+ /*
12383+ * Segments used for calling PnP BIOS have byte granularity.
12384+ * The code segments and data segments have fixed 64k limits,
12385+ * the transfer segment sizes are set at run time.
12386+ */
12387+ .quad 0x00409b000000ffff /* 0x90 32-bit code */
12388+ .quad 0x00009b000000ffff /* 0x98 16-bit code */
12389+ .quad 0x000093000000ffff /* 0xa0 16-bit data */
12390+ .quad 0x0000930000000000 /* 0xa8 16-bit data */
12391+ .quad 0x0000930000000000 /* 0xb0 16-bit data */
12392+
12393+ /*
12394+ * The APM segments have byte granularity and their bases
12395+ * are set at run time. All have 64k limits.
12396+ */
12397+ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
12398+ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
12399+ .quad 0x004093000000ffff /* 0xc8 APM DS data */
12400+
12401+ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
12402+ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
ae4e228f 12403+ .quad 0x0040910000000018 /* 0xe0 - STACK_CANARY */
58c5fc13
MT
12404+ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_CS */
12405+ .quad 0x0000000000000000 /* 0xf0 - PCIBIOS_DS */
12406+ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
12407+
12408+ /* Be sure this is zeroed to avoid false validations in Xen */
12409+ .fill PAGE_SIZE_asm - GDT_SIZE,1,0
12410+ .endr
16454cff
MT
12411diff -urNp linux-2.6.38.1/arch/x86/kernel/head_64.S linux-2.6.38.1/arch/x86/kernel/head_64.S
12412--- linux-2.6.38.1/arch/x86/kernel/head_64.S 2011-03-14 21:20:32.000000000 -0400
12413+++ linux-2.6.38.1/arch/x86/kernel/head_64.S 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
12414@@ -19,6 +19,7 @@
12415 #include <asm/cache.h>
12416 #include <asm/processor-flags.h>
12417 #include <asm/percpu.h>
12418+#include <asm/cpufeature.h>
12419
12420 #ifdef CONFIG_PARAVIRT
12421 #include <asm/asm-offsets.h>
12422@@ -38,6 +39,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
58c5fc13
MT
12423 L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
12424 L4_START_KERNEL = pgd_index(__START_KERNEL_map)
12425 L3_START_KERNEL = pud_index(__START_KERNEL_map)
12426+L4_VMALLOC_START = pgd_index(VMALLOC_START)
12427+L3_VMALLOC_START = pud_index(VMALLOC_START)
12428+L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
12429+L3_VMEMMAP_START = pud_index(VMEMMAP_START)
12430
12431 .text
ae4e228f
MT
12432 __HEAD
12433@@ -85,35 +90,22 @@ startup_64:
58c5fc13
MT
12434 */
12435 addq %rbp, init_level4_pgt + 0(%rip)
12436 addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
12437+ addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
12438+ addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
12439 addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
12440
12441 addq %rbp, level3_ident_pgt + 0(%rip)
ae4e228f 12442+#ifndef CONFIG_XEN
58c5fc13 12443+ addq %rbp, level3_ident_pgt + 8(%rip)
ae4e228f 12444+#endif
58c5fc13
MT
12445
12446- addq %rbp, level3_kernel_pgt + (510*8)(%rip)
12447- addq %rbp, level3_kernel_pgt + (511*8)(%rip)
12448+ addq %rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip)
12449
12450- addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
12451+ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
12452+ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
12453
12454- /* Add an Identity mapping if I am above 1G */
12455- leaq _text(%rip), %rdi
12456- andq $PMD_PAGE_MASK, %rdi
12457-
12458- movq %rdi, %rax
12459- shrq $PUD_SHIFT, %rax
12460- andq $(PTRS_PER_PUD - 1), %rax
12461- jz ident_complete
12462-
12463- leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
12464- leaq level3_ident_pgt(%rip), %rbx
12465- movq %rdx, 0(%rbx, %rax, 8)
12466-
12467- movq %rdi, %rax
12468- shrq $PMD_SHIFT, %rax
12469- andq $(PTRS_PER_PMD - 1), %rax
12470- leaq __PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx
12471- leaq level2_spare_pgt(%rip), %rbx
12472- movq %rdx, 0(%rbx, %rax, 8)
12473-ident_complete:
12474+ addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
12475+ addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
12476
12477 /*
12478 * Fixup the kernel text+data virtual addresses. Note that
df50ba0c
MT
12479@@ -161,8 +153,8 @@ ENTRY(secondary_startup_64)
12480 * after the boot processor executes this code.
12481 */
12482
12483- /* Enable PAE mode and PGE */
12484- movl $(X86_CR4_PAE | X86_CR4_PGE), %eax
12485+ /* Enable PAE mode and PSE/PGE */
12486+ movl $(X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE), %eax
12487 movq %rax, %cr4
12488
12489 /* Setup early boot stage 4 level pagetables. */
ae4e228f
MT
12490@@ -184,9 +176,14 @@ ENTRY(secondary_startup_64)
12491 movl $MSR_EFER, %ecx
12492 rdmsr
12493 btsl $_EFER_SCE, %eax /* Enable System Call */
12494- btl $20,%edi /* No Execute supported? */
12495+ btl $(X86_FEATURE_NX & 31),%edi /* No Execute supported? */
58c5fc13
MT
12496 jnc 1f
12497 btsl $_EFER_NX, %eax
12498+ leaq init_level4_pgt(%rip), %rdi
12499+ btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
12500+ btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
12501+ btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
ae4e228f 12502+ btsq $_PAGE_BIT_NX, __supported_pte_mask(%rip)
58c5fc13
MT
12503 1: wrmsr /* Make changes effective */
12504
12505 /* Setup cr0 */
6892158b 12506@@ -270,7 +267,7 @@ ENTRY(secondary_startup_64)
58c5fc13
MT
12507 bad_address:
12508 jmp bad_address
12509
12510- .section ".init.text","ax"
12511+ __INIT
12512 #ifdef CONFIG_EARLY_PRINTK
12513 .globl early_idt_handlers
12514 early_idt_handlers:
6892158b 12515@@ -315,18 +312,23 @@ ENTRY(early_idt_handler)
58c5fc13
MT
12516 #endif /* EARLY_PRINTK */
12517 1: hlt
12518 jmp 1b
12519+ .previous
12520
12521 #ifdef CONFIG_EARLY_PRINTK
12522+ __INITDATA
12523 early_recursion_flag:
12524 .long 0
12525+ .previous
12526
12527+ .section .rodata,"a",@progbits
12528 early_idt_msg:
12529 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
12530 early_idt_ripmsg:
12531 .asciz "RIP %s\n"
12532-#endif /* CONFIG_EARLY_PRINTK */
12533 .previous
12534+#endif /* CONFIG_EARLY_PRINTK */
12535
12536+ .section .rodata,"a",@progbits
12537 #define NEXT_PAGE(name) \
12538 .balign PAGE_SIZE; \
12539 ENTRY(name)
bc901d79
MT
12540@@ -339,7 +341,6 @@ ENTRY(name)
12541 i = i + 1 ; \
12542 .endr
12543
12544- .data
12545 /*
12546 * This default setting generates an ident mapping at address 0x100000
12547 * and a mapping for the kernel that precisely maps virtual address
12548@@ -350,13 +351,36 @@ NEXT_PAGE(init_level4_pgt)
58c5fc13
MT
12549 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
12550 .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
12551 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
12552+ .org init_level4_pgt + L4_VMALLOC_START*8, 0
12553+ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
12554+ .org init_level4_pgt + L4_VMEMMAP_START*8, 0
12555+ .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
12556 .org init_level4_pgt + L4_START_KERNEL*8, 0
12557 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
12558 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
12559
df50ba0c
MT
12560+#ifdef CONFIG_PAX_PER_CPU_PGD
12561+NEXT_PAGE(cpu_pgd)
12562+ .rept NR_CPUS
12563+ .fill 512,8,0
12564+ .endr
12565+#endif
12566+
58c5fc13
MT
12567 NEXT_PAGE(level3_ident_pgt)
12568 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
12569+#ifdef CONFIG_XEN
12570 .fill 511,8,0
12571+#else
12572+ .quad level2_ident_pgt + PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
ae4e228f 12573+ .fill 510,8,0
58c5fc13
MT
12574+#endif
12575+
12576+NEXT_PAGE(level3_vmalloc_pgt)
12577+ .fill 512,8,0
12578+
12579+NEXT_PAGE(level3_vmemmap_pgt)
12580+ .fill L3_VMEMMAP_START,8,0
12581+ .quad level2_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
12582
12583 NEXT_PAGE(level3_kernel_pgt)
12584 .fill L3_START_KERNEL,8,0
bc901d79 12585@@ -364,20 +388,23 @@ NEXT_PAGE(level3_kernel_pgt)
58c5fc13
MT
12586 .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
12587 .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
12588
12589+NEXT_PAGE(level2_vmemmap_pgt)
12590+ .fill 512,8,0
12591+
12592 NEXT_PAGE(level2_fixmap_pgt)
12593- .fill 506,8,0
12594- .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
12595- /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
12596- .fill 5,8,0
12597+ .fill 507,8,0
12598+ .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
12599+ /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
12600+ .fill 4,8,0
12601
12602-NEXT_PAGE(level1_fixmap_pgt)
12603+NEXT_PAGE(level1_vsyscall_pgt)
12604 .fill 512,8,0
12605
12606-NEXT_PAGE(level2_ident_pgt)
12607- /* Since I easily can, map the first 1G.
ae4e228f 12608+ /* Since I easily can, map the first 2G.
58c5fc13
MT
12609 * Don't set NX because code runs from these pages.
12610 */
12611- PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
12612+NEXT_PAGE(level2_ident_pgt)
ae4e228f 12613+ PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 2*PTRS_PER_PMD)
58c5fc13
MT
12614
12615 NEXT_PAGE(level2_kernel_pgt)
12616 /*
bc901d79 12617@@ -390,33 +417,55 @@ NEXT_PAGE(level2_kernel_pgt)
58c5fc13
MT
12618 * If you want to increase this then increase MODULES_VADDR
12619 * too.)
12620 */
12621- PMDS(0, __PAGE_KERNEL_LARGE_EXEC,
12622- KERNEL_IMAGE_SIZE/PMD_SIZE)
12623-
12624-NEXT_PAGE(level2_spare_pgt)
12625- .fill 512, 8, 0
12626+ PMDS(0, __PAGE_KERNEL_LARGE_EXEC, KERNEL_IMAGE_SIZE/PMD_SIZE)
12627
12628 #undef PMDS
12629 #undef NEXT_PAGE
12630
12631- .data
12632+ .align PAGE_SIZE
12633+ENTRY(cpu_gdt_table)
12634+ .rept NR_CPUS
12635+ .quad 0x0000000000000000 /* NULL descriptor */
12636+ .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
12637+ .quad 0x00af9b000000ffff /* __KERNEL_CS */
12638+ .quad 0x00cf93000000ffff /* __KERNEL_DS */
12639+ .quad 0x00cffb000000ffff /* __USER32_CS */
12640+ .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
12641+ .quad 0x00affb000000ffff /* __USER_CS */
ae4e228f
MT
12642+
12643+#ifdef CONFIG_PAX_KERNEXEC
12644+ .quad 0x00af9b000000ffff /* __KERNEXEC_KERNEL_CS */
12645+#else
58c5fc13 12646+ .quad 0x0 /* unused */
ae4e228f
MT
12647+#endif
12648+
58c5fc13
MT
12649+ .quad 0,0 /* TSS */
12650+ .quad 0,0 /* LDT */
12651+ .quad 0,0,0 /* three TLS descriptors */
12652+ .quad 0x0000f40000000000 /* node/CPU stored in limit */
12653+ /* asm/segment.h:GDT_ENTRIES must match this */
12654+
12655+ /* zero the remaining page */
12656+ .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
12657+ .endr
12658+
12659 .align 16
12660 .globl early_gdt_descr
12661 early_gdt_descr:
12662 .word GDT_ENTRIES*8-1
12663 early_gdt_descr_base:
12664- .quad INIT_PER_CPU_VAR(gdt_page)
12665+ .quad cpu_gdt_table
12666
12667 ENTRY(phys_base)
12668 /* This must match the first entry in level2_kernel_pgt */
12669 .quad 0x0000000000000000
12670
12671 #include "../../x86/xen/xen-head.S"
12672-
12673- .section .bss, "aw", @nobits
12674+
12675+ .section .rodata,"a",@progbits
12676 .align L1_CACHE_BYTES
12677 ENTRY(idt_table)
12678- .skip IDT_ENTRIES * 16
12679+ .fill 512,8,0
12680
ae4e228f 12681 __PAGE_ALIGNED_BSS
58c5fc13 12682 .align PAGE_SIZE
16454cff
MT
12683diff -urNp linux-2.6.38.1/arch/x86/kernel/i386_ksyms_32.c linux-2.6.38.1/arch/x86/kernel/i386_ksyms_32.c
12684--- linux-2.6.38.1/arch/x86/kernel/i386_ksyms_32.c 2011-03-14 21:20:32.000000000 -0400
12685+++ linux-2.6.38.1/arch/x86/kernel/i386_ksyms_32.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
12686@@ -20,8 +20,12 @@ extern void cmpxchg8b_emu(void);
12687 EXPORT_SYMBOL(cmpxchg8b_emu);
58c5fc13
MT
12688 #endif
12689
12690+EXPORT_SYMBOL_GPL(cpu_gdt_table);
12691+
12692 /* Networking helper routines. */
12693 EXPORT_SYMBOL(csum_partial_copy_generic);
12694+EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
12695+EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
12696
12697 EXPORT_SYMBOL(__get_user_1);
12698 EXPORT_SYMBOL(__get_user_2);
ae4e228f 12699@@ -36,3 +40,7 @@ EXPORT_SYMBOL(strstr);
58c5fc13
MT
12700
12701 EXPORT_SYMBOL(csum_partial);
12702 EXPORT_SYMBOL(empty_zero_page);
12703+
12704+#ifdef CONFIG_PAX_KERNEXEC
12705+EXPORT_SYMBOL(__LOAD_PHYSICAL_ADDR);
12706+#endif
16454cff
MT
12707diff -urNp linux-2.6.38.1/arch/x86/kernel/init_task.c linux-2.6.38.1/arch/x86/kernel/init_task.c
12708--- linux-2.6.38.1/arch/x86/kernel/init_task.c 2011-03-14 21:20:32.000000000 -0400
12709+++ linux-2.6.38.1/arch/x86/kernel/init_task.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 12710@@ -38,5 +38,5 @@ EXPORT_SYMBOL(init_task);
58c5fc13
MT
12711 * section. Since TSS's are completely CPU-local, we want them
12712 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
12713 */
12714-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
12715-
12716+struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
12717+EXPORT_SYMBOL(init_tss);
16454cff
MT
12718diff -urNp linux-2.6.38.1/arch/x86/kernel/ioport.c linux-2.6.38.1/arch/x86/kernel/ioport.c
12719--- linux-2.6.38.1/arch/x86/kernel/ioport.c 2011-03-14 21:20:32.000000000 -0400
12720+++ linux-2.6.38.1/arch/x86/kernel/ioport.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
12721@@ -6,6 +6,7 @@
12722 #include <linux/sched.h>
12723 #include <linux/kernel.h>
12724 #include <linux/capability.h>
12725+#include <linux/security.h>
12726 #include <linux/errno.h>
12727 #include <linux/types.h>
12728 #include <linux/ioport.h>
12729@@ -41,6 +42,12 @@ asmlinkage long sys_ioperm(unsigned long
12730
12731 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
12732 return -EINVAL;
12733+#ifdef CONFIG_GRKERNSEC_IO
df50ba0c 12734+ if (turn_on && grsec_disable_privio) {
58c5fc13
MT
12735+ gr_handle_ioperm();
12736+ return -EPERM;
12737+ }
12738+#endif
12739 if (turn_on && !capable(CAP_SYS_RAWIO))
12740 return -EPERM;
12741
12742@@ -67,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long
12743 * because the ->io_bitmap_max value must match the bitmap
12744 * contents:
12745 */
12746- tss = &per_cpu(init_tss, get_cpu());
12747+ tss = init_tss + get_cpu();
12748
12749 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
12750
df50ba0c 12751@@ -112,6 +119,12 @@ long sys_iopl(unsigned int level, struct
58c5fc13
MT
12752 return -EINVAL;
12753 /* Trying to gain more privileges? */
12754 if (level > old) {
12755+#ifdef CONFIG_GRKERNSEC_IO
df50ba0c
MT
12756+ if (grsec_disable_privio) {
12757+ gr_handle_iopl();
12758+ return -EPERM;
12759+ }
12760+#endif
58c5fc13
MT
12761 if (!capable(CAP_SYS_RAWIO))
12762 return -EPERM;
58c5fc13 12763 }
16454cff
MT
12764diff -urNp linux-2.6.38.1/arch/x86/kernel/irq_32.c linux-2.6.38.1/arch/x86/kernel/irq_32.c
12765--- linux-2.6.38.1/arch/x86/kernel/irq_32.c 2011-03-14 21:20:32.000000000 -0400
12766+++ linux-2.6.38.1/arch/x86/kernel/irq_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 12767@@ -91,7 +91,7 @@ execute_on_irq_stack(int overflow, struc
58c5fc13
MT
12768 return 0;
12769
12770 /* build the stack frame on the IRQ stack */
12771- isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
12772+ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
12773 irqctx->tinfo.task = curctx->tinfo.task;
12774 irqctx->tinfo.previous_esp = current_stack_pointer;
12775
bc901d79
MT
12776@@ -103,6 +103,10 @@ execute_on_irq_stack(int overflow, struc
12777 (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) |
12778 (curctx->tinfo.preempt_count & SOFTIRQ_MASK);
12779
12780+#ifdef CONFIG_PAX_MEMORY_UDEREF
12781+ __set_fs(irqctx->tinfo.addr_limit);
12782+#endif
12783+
12784 if (unlikely(overflow))
12785 call_on_stack(print_stack_overflow, isp);
12786
12787@@ -113,6 +117,11 @@ execute_on_irq_stack(int overflow, struc
12788 : "0" (irq), "1" (desc), "2" (isp),
12789 "D" (desc->handle_irq)
12790 : "memory", "cc", "ecx");
12791+
12792+#ifdef CONFIG_PAX_MEMORY_UDEREF
12793+ __set_fs(curctx->tinfo.addr_limit);
12794+#endif
12795+
12796 return 1;
12797 }
12798
317566c1 12799@@ -168,9 +177,18 @@ asmlinkage void do_softirq(void)
58c5fc13
MT
12800 irqctx->tinfo.previous_esp = current_stack_pointer;
12801
12802 /* build the stack frame on the softirq stack */
12803- isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
12804+ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
bc901d79
MT
12805+
12806+#ifdef CONFIG_PAX_MEMORY_UDEREF
12807+ __set_fs(irqctx->tinfo.addr_limit);
12808+#endif
58c5fc13
MT
12809
12810 call_on_stack(__do_softirq, isp);
bc901d79
MT
12811+
12812+#ifdef CONFIG_PAX_MEMORY_UDEREF
12813+ __set_fs(curctx->addr_limit);
12814+#endif
12815+
58c5fc13 12816 /*
bc901d79
MT
12817 * Shouldnt happen, we returned above if in_interrupt():
12818 */
16454cff
MT
12819diff -urNp linux-2.6.38.1/arch/x86/kernel/kgdb.c linux-2.6.38.1/arch/x86/kernel/kgdb.c
12820--- linux-2.6.38.1/arch/x86/kernel/kgdb.c 2011-03-14 21:20:32.000000000 -0400
12821+++ linux-2.6.38.1/arch/x86/kernel/kgdb.c 2011-03-21 18:31:35.000000000 -0400
12822@@ -124,11 +124,11 @@ char *dbg_get_reg(int regno, void *mem,
6892158b
MT
12823 switch (regno) {
12824 #ifdef CONFIG_X86_32
12825 case GDB_SS:
12826- if (!user_mode_vm(regs))
12827+ if (!user_mode(regs))
12828 *(unsigned long *)mem = __KERNEL_DS;
12829 break;
12830 case GDB_SP:
12831- if (!user_mode_vm(regs))
12832+ if (!user_mode(regs))
12833 *(unsigned long *)mem = kernel_stack_pointer(regs);
12834 break;
12835 case GDB_GS:
16454cff 12836@@ -719,7 +719,7 @@ void kgdb_arch_set_pc(struct pt_regs *re
57199397 12837 regs->ip = ip;
ae4e228f
MT
12838 }
12839
12840-struct kgdb_arch arch_kgdb_ops = {
12841+const struct kgdb_arch arch_kgdb_ops = {
12842 /* Breakpoint instruction: */
12843 .gdb_bpt_instr = { 0xcc },
12844 .flags = KGDB_HW_BREAKPOINT,
16454cff
MT
12845diff -urNp linux-2.6.38.1/arch/x86/kernel/kprobes.c linux-2.6.38.1/arch/x86/kernel/kprobes.c
12846--- linux-2.6.38.1/arch/x86/kernel/kprobes.c 2011-03-14 21:20:32.000000000 -0400
12847+++ linux-2.6.38.1/arch/x86/kernel/kprobes.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 12848@@ -115,8 +115,11 @@ static void __kprobes __synthesize_relat
df50ba0c
MT
12849 } __attribute__((packed)) *insn;
12850
bc901d79 12851 insn = (struct __arch_relative_insn *)from;
58c5fc13 12852+
ae4e228f 12853+ pax_open_kernel();
df50ba0c
MT
12854 insn->raddr = (s32)((long)(to) - ((long)(from) + 5));
12855 insn->op = op;
ae4e228f 12856+ pax_close_kernel();
58c5fc13
MT
12857 }
12858
df50ba0c 12859 /* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
bc901d79
MT
12860@@ -153,7 +156,7 @@ static int __kprobes can_boost(kprobe_op
12861 kprobe_opcode_t opcode;
12862 kprobe_opcode_t *orig_opcodes = opcodes;
12863
12864- if (search_exception_tables((unsigned long)opcodes))
12865+ if (search_exception_tables(ktva_ktla((unsigned long)opcodes)))
12866 return 0; /* Page fault may occur on this address. */
12867
12868 retry:
12869@@ -314,7 +317,9 @@ static int __kprobes __copy_instruction(
df50ba0c
MT
12870 }
12871 }
12872 insn_get_length(&insn);
ae4e228f 12873+ pax_open_kernel();
df50ba0c 12874 memcpy(dest, insn.kaddr, insn.length);
ae4e228f 12875+ pax_close_kernel();
58c5fc13 12876
df50ba0c
MT
12877 #ifdef CONFIG_X86_64
12878 if (insn_rip_relative(&insn)) {
bc901d79 12879@@ -338,7 +343,9 @@ static int __kprobes __copy_instruction(
df50ba0c
MT
12880 (u8 *) dest;
12881 BUG_ON((s64) (s32) newdisp != newdisp); /* Sanity check. */
12882 disp = (u8 *) dest + insn_offset_displacement(&insn);
12883+ pax_open_kernel();
12884 *(s32 *) disp = (s32) newdisp;
12885+ pax_close_kernel();
12886 }
12887 #endif
12888 return insn.length;
bc901d79 12889@@ -352,12 +359,12 @@ static void __kprobes arch_copy_kprobe(s
df50ba0c
MT
12890 */
12891 __copy_instruction(p->ainsn.insn, p->addr, 0);
58c5fc13
MT
12892
12893- if (can_boost(p->addr))
12894+ if (can_boost(ktla_ktva(p->addr)))
12895 p->ainsn.boostable = 0;
12896 else
12897 p->ainsn.boostable = -1;
12898
12899- p->opcode = *p->addr;
12900+ p->opcode = *(ktla_ktva(p->addr));
12901 }
12902
12903 int __kprobes arch_prepare_kprobe(struct kprobe *p)
bc901d79 12904@@ -474,7 +481,7 @@ static void __kprobes setup_singlestep(s
df50ba0c
MT
12905 * nor set current_kprobe, because it doesn't use single
12906 * stepping.
12907 */
12908- regs->ip = (unsigned long)p->ainsn.insn;
12909+ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
12910 preempt_enable_no_resched();
12911 return;
12912 }
bc901d79 12913@@ -493,7 +500,7 @@ static void __kprobes setup_singlestep(s
58c5fc13
MT
12914 if (p->opcode == BREAKPOINT_INSTRUCTION)
12915 regs->ip = (unsigned long)p->addr;
12916 else
12917- regs->ip = (unsigned long)p->ainsn.insn;
12918+ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
12919 }
12920
df50ba0c 12921 /*
bc901d79 12922@@ -572,7 +579,7 @@ static int __kprobes kprobe_handler(stru
df50ba0c
MT
12923 setup_singlestep(p, regs, kcb, 0);
12924 return 1;
12925 }
12926- } else if (*addr != BREAKPOINT_INSTRUCTION) {
12927+ } else if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
58c5fc13
MT
12928 /*
12929 * The breakpoint instruction was removed right
12930 * after we hit it. Another cpu has removed
bc901d79 12931@@ -817,7 +824,7 @@ static void __kprobes resume_execution(s
58c5fc13
MT
12932 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
12933 {
12934 unsigned long *tos = stack_addr(regs);
12935- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
12936+ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
12937 unsigned long orig_ip = (unsigned long)p->addr;
12938 kprobe_opcode_t *insn = p->ainsn.insn;
12939
bc901d79 12940@@ -999,7 +1006,7 @@ int __kprobes kprobe_exceptions_notify(s
58c5fc13
MT
12941 struct die_args *args = data;
12942 int ret = NOTIFY_DONE;
12943
12944- if (args->regs && user_mode_vm(args->regs))
12945+ if (args->regs && user_mode(args->regs))
12946 return ret;
12947
12948 switch (val) {
16454cff 12949@@ -1372,7 +1379,7 @@ int __kprobes arch_prepare_optimized_kpr
bc901d79
MT
12950 * Verify if the address gap is in 2GB range, because this uses
12951 * a relative jump.
12952 */
12953- rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
12954+ rel = (long)op->optinsn.insn - ktla_ktva((long)op->kp.addr) + RELATIVEJUMP_SIZE;
12955 if (abs(rel) > 0x7fffffff)
12956 return -ERANGE;
12957
16454cff 12958@@ -1393,11 +1400,11 @@ int __kprobes arch_prepare_optimized_kpr
bc901d79
MT
12959 synthesize_set_arg1(buf + TMPL_MOVE_IDX, (unsigned long)op);
12960
12961 /* Set probe function call */
12962- synthesize_relcall(buf + TMPL_CALL_IDX, optimized_callback);
12963+ synthesize_relcall(buf + TMPL_CALL_IDX, ktla_ktva(optimized_callback));
12964
12965 /* Set returning jmp instruction at the tail of out-of-line buffer */
12966 synthesize_reljump(buf + TMPL_END_IDX + op->optinsn.size,
12967- (u8 *)op->kp.addr + op->optinsn.size);
12968+ (u8 *)ktla_ktva(op->kp.addr) + op->optinsn.size);
12969
12970 flush_icache_range((unsigned long) buf,
12971 (unsigned long) buf + TMPL_END_IDX +
16454cff 12972@@ -1419,7 +1426,7 @@ static void __kprobes setup_optimize_kpr
bc901d79
MT
12973 ((long)op->kp.addr + RELATIVEJUMP_SIZE));
12974
12975 /* Backup instructions which will be replaced by jump address */
12976- memcpy(op->optinsn.copied_insn, op->kp.addr + INT3_SIZE,
12977+ memcpy(op->optinsn.copied_insn, ktla_ktva(op->kp.addr) + INT3_SIZE,
12978 RELATIVE_ADDR_SIZE);
12979
16454cff
MT
12980 insn_buf[0] = RELATIVEJUMP_OPCODE;
12981diff -urNp linux-2.6.38.1/arch/x86/kernel/ldt.c linux-2.6.38.1/arch/x86/kernel/ldt.c
12982--- linux-2.6.38.1/arch/x86/kernel/ldt.c 2011-03-14 21:20:32.000000000 -0400
12983+++ linux-2.6.38.1/arch/x86/kernel/ldt.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 12984@@ -67,13 +67,13 @@ static int alloc_ldt(mm_context_t *pc, i
58c5fc13
MT
12985 if (reload) {
12986 #ifdef CONFIG_SMP
12987 preempt_disable();
12988- load_LDT(pc);
12989+ load_LDT_nolock(pc);
ae4e228f
MT
12990 if (!cpumask_equal(mm_cpumask(current->mm),
12991 cpumask_of(smp_processor_id())))
58c5fc13
MT
12992 smp_call_function(flush_ldt, current->mm, 1);
12993 preempt_enable();
12994 #else
12995- load_LDT(pc);
12996+ load_LDT_nolock(pc);
12997 #endif
12998 }
12999 if (oldsize) {
df50ba0c 13000@@ -95,7 +95,7 @@ static inline int copy_ldt(mm_context_t
58c5fc13
MT
13001 return err;
13002
13003 for (i = 0; i < old->size; i++)
13004- write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
13005+ write_ldt_entry(new->ldt, i, old->ldt + i);
13006 return 0;
13007 }
13008
df50ba0c 13009@@ -116,6 +116,24 @@ int init_new_context(struct task_struct
58c5fc13
MT
13010 retval = copy_ldt(&mm->context, &old_mm->context);
13011 mutex_unlock(&old_mm->context.lock);
13012 }
13013+
13014+ if (tsk == current) {
6892158b 13015+ mm->context.vdso = 0;
58c5fc13
MT
13016+
13017+#ifdef CONFIG_X86_32
13018+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13019+ mm->context.user_cs_base = 0UL;
13020+ mm->context.user_cs_limit = ~0UL;
13021+
13022+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
13023+ cpus_clear(mm->context.cpu_user_cs_mask);
13024+#endif
13025+
13026+#endif
13027+#endif
13028+
13029+ }
13030+
13031 return retval;
13032 }
13033
df50ba0c 13034@@ -230,6 +248,13 @@ static int write_ldt(void __user *ptr, u
58c5fc13
MT
13035 }
13036 }
13037
13038+#ifdef CONFIG_PAX_SEGMEXEC
13039+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
13040+ error = -EINVAL;
13041+ goto out_unlock;
13042+ }
13043+#endif
13044+
13045 fill_ldt(&ldt, &ldt_info);
13046 if (oldmode)
13047 ldt.avl = 0;
16454cff
MT
13048diff -urNp linux-2.6.38.1/arch/x86/kernel/machine_kexec_32.c linux-2.6.38.1/arch/x86/kernel/machine_kexec_32.c
13049--- linux-2.6.38.1/arch/x86/kernel/machine_kexec_32.c 2011-03-14 21:20:32.000000000 -0400
13050+++ linux-2.6.38.1/arch/x86/kernel/machine_kexec_32.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 13051@@ -27,7 +27,7 @@
58c5fc13 13052 #include <asm/cacheflush.h>
ae4e228f 13053 #include <asm/debugreg.h>
58c5fc13
MT
13054
13055-static void set_idt(void *newidt, __u16 limit)
13056+static void set_idt(struct desc_struct *newidt, __u16 limit)
13057 {
13058 struct desc_ptr curidt;
13059
ae4e228f 13060@@ -39,7 +39,7 @@ static void set_idt(void *newidt, __u16
58c5fc13
MT
13061 }
13062
13063
13064-static void set_gdt(void *newgdt, __u16 limit)
13065+static void set_gdt(struct desc_struct *newgdt, __u16 limit)
13066 {
13067 struct desc_ptr curgdt;
13068
13069@@ -217,7 +217,7 @@ void machine_kexec(struct kimage *image)
13070 }
13071
13072 control_page = page_address(image->control_code_page);
13073- memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
13074+ memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
13075
13076 relocate_kernel_ptr = control_page;
13077 page_list[PA_CONTROL_PAGE] = __pa(control_page);
16454cff
MT
13078diff -urNp linux-2.6.38.1/arch/x86/kernel/microcode_amd.c linux-2.6.38.1/arch/x86/kernel/microcode_amd.c
13079--- linux-2.6.38.1/arch/x86/kernel/microcode_amd.c 2011-03-14 21:20:32.000000000 -0400
13080+++ linux-2.6.38.1/arch/x86/kernel/microcode_amd.c 2011-03-21 18:31:35.000000000 -0400
13081@@ -317,7 +317,7 @@ static void microcode_fini_cpu_amd(int c
ae4e228f
MT
13082 uci->mc = NULL;
13083 }
13084
13085-static struct microcode_ops microcode_amd_ops = {
13086+static const struct microcode_ops microcode_amd_ops = {
13087 .request_microcode_user = request_microcode_user,
13088 .request_microcode_fw = request_microcode_fw,
13089 .collect_cpu_info = collect_cpu_info_amd,
16454cff 13090@@ -325,7 +325,7 @@ static struct microcode_ops microcode_am
ae4e228f
MT
13091 .microcode_fini_cpu = microcode_fini_cpu_amd,
13092 };
58c5fc13 13093
ae4e228f
MT
13094-struct microcode_ops * __init init_amd_microcode(void)
13095+const struct microcode_ops * __init init_amd_microcode(void)
13096 {
13097 return &microcode_amd_ops;
13098 }
16454cff
MT
13099diff -urNp linux-2.6.38.1/arch/x86/kernel/microcode_core.c linux-2.6.38.1/arch/x86/kernel/microcode_core.c
13100--- linux-2.6.38.1/arch/x86/kernel/microcode_core.c 2011-03-14 21:20:32.000000000 -0400
13101+++ linux-2.6.38.1/arch/x86/kernel/microcode_core.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
13102@@ -92,7 +92,7 @@ MODULE_LICENSE("GPL");
13103
13104 #define MICROCODE_VERSION "2.00"
13105
13106-static struct microcode_ops *microcode_ops;
13107+static const struct microcode_ops *microcode_ops;
13108
13109 /*
13110 * Synchronization.
16454cff
MT
13111diff -urNp linux-2.6.38.1/arch/x86/kernel/microcode_intel.c linux-2.6.38.1/arch/x86/kernel/microcode_intel.c
13112--- linux-2.6.38.1/arch/x86/kernel/microcode_intel.c 2011-03-14 21:20:32.000000000 -0400
13113+++ linux-2.6.38.1/arch/x86/kernel/microcode_intel.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 13114@@ -440,13 +440,13 @@ static enum ucode_state request_microcod
ae4e228f
MT
13115
13116 static int get_ucode_user(void *to, const void *from, size_t n)
13117 {
13118- return copy_from_user(to, from, n);
13119+ return copy_from_user(to, (__force const void __user *)from, n);
13120 }
13121
13122 static enum ucode_state
13123 request_microcode_user(int cpu, const void __user *buf, size_t size)
13124 {
13125- return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
13126+ return generic_load_microcode(cpu, (__force void *)buf, size, &get_ucode_user);
13127 }
13128
13129 static void microcode_fini_cpu(int cpu)
bc901d79 13130@@ -457,7 +457,7 @@ static void microcode_fini_cpu(int cpu)
ae4e228f
MT
13131 uci->mc = NULL;
13132 }
13133
13134-static struct microcode_ops microcode_intel_ops = {
13135+static const struct microcode_ops microcode_intel_ops = {
13136 .request_microcode_user = request_microcode_user,
13137 .request_microcode_fw = request_microcode_fw,
13138 .collect_cpu_info = collect_cpu_info,
bc901d79 13139@@ -465,7 +465,7 @@ static struct microcode_ops microcode_in
ae4e228f
MT
13140 .microcode_fini_cpu = microcode_fini_cpu,
13141 };
13142
13143-struct microcode_ops * __init init_intel_microcode(void)
13144+const struct microcode_ops * __init init_intel_microcode(void)
13145 {
13146 return &microcode_intel_ops;
13147 }
16454cff
MT
13148diff -urNp linux-2.6.38.1/arch/x86/kernel/module.c linux-2.6.38.1/arch/x86/kernel/module.c
13149--- linux-2.6.38.1/arch/x86/kernel/module.c 2011-03-14 21:20:32.000000000 -0400
13150+++ linux-2.6.38.1/arch/x86/kernel/module.c 2011-03-21 18:31:35.000000000 -0400
13151@@ -35,21 +35,66 @@
58c5fc13
MT
13152 #define DEBUGP(fmt...)
13153 #endif
13154
13155-void *module_alloc(unsigned long size)
16454cff 13156+static inline void *__module_alloc(unsigned long size, pgprot_t prot)
58c5fc13 13157 {
16454cff 13158 if (PAGE_ALIGN(size) > MODULES_LEN)
58c5fc13 13159 return NULL;
16454cff
MT
13160 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
13161- GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
13162+ GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, prot,
13163 -1, __builtin_return_address(0));
13164 }
58c5fc13 13165
58c5fc13
MT
13166+void *module_alloc(unsigned long size)
13167+{
ae4e228f
MT
13168+
13169+#ifdef CONFIG_PAX_KERNEXEC
58c5fc13 13170+ return __module_alloc(size, PAGE_KERNEL);
ae4e228f
MT
13171+#else
13172+ return __module_alloc(size, PAGE_KERNEL_EXEC);
13173+#endif
13174+
16454cff
MT
13175+}
13176+
ae4e228f 13177 /* Free memory returned from module_alloc */
16454cff
MT
13178 void module_free(struct module *mod, void *module_region)
13179 {
ae4e228f
MT
13180 vfree(module_region);
13181 }
13182
13183+#ifdef CONFIG_PAX_KERNEXEC
13184+#ifdef CONFIG_X86_32
58c5fc13
MT
13185+void *module_alloc_exec(unsigned long size)
13186+{
13187+ struct vm_struct *area;
13188+
13189+ if (size == 0)
13190+ return NULL;
13191+
13192+ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_EXEC_VADDR, (unsigned long)&MODULES_EXEC_END);
ae4e228f 13193+ return area ? area->addr : NULL;
58c5fc13
MT
13194+}
13195+EXPORT_SYMBOL(module_alloc_exec);
13196+
13197+void module_free_exec(struct module *mod, void *module_region)
13198+{
ae4e228f 13199+ vunmap(module_region);
58c5fc13
MT
13200+}
13201+EXPORT_SYMBOL(module_free_exec);
13202+#else
58c5fc13
MT
13203+void module_free_exec(struct module *mod, void *module_region)
13204+{
13205+ module_free(mod, module_region);
13206+}
13207+EXPORT_SYMBOL(module_free_exec);
13208+
13209+void *module_alloc_exec(unsigned long size)
13210+{
13211+ return __module_alloc(size, PAGE_KERNEL_RX);
13212+}
13213+EXPORT_SYMBOL(module_alloc_exec);
13214+#endif
58c5fc13 13215+#endif
ae4e228f
MT
13216+
13217 /* We don't need anything special. */
13218 int module_frob_arch_sections(Elf_Ehdr *hdr,
13219 Elf_Shdr *sechdrs,
16454cff 13220@@ -69,14 +114,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
58c5fc13
MT
13221 unsigned int i;
13222 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
13223 Elf32_Sym *sym;
13224- uint32_t *location;
13225+ uint32_t *plocation, location;
58c5fc13
MT
13226
13227 DEBUGP("Applying relocate section %u to %u\n", relsec,
13228 sechdrs[relsec].sh_info);
13229 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
13230 /* This is where to make the change */
13231- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
13232- + rel[i].r_offset;
13233+ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
13234+ location = (uint32_t)plocation;
13235+ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
13236+ plocation = ktla_ktva((void *)plocation);
13237 /* This is the symbol it is referring to. Note that all
13238 undefined symbols have been resolved. */
13239 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
16454cff 13240@@ -85,11 +132,15 @@ int apply_relocate(Elf32_Shdr *sechdrs,
58c5fc13
MT
13241 switch (ELF32_R_TYPE(rel[i].r_info)) {
13242 case R_386_32:
13243 /* We add the value into the location given */
13244- *location += sym->st_value;
ae4e228f 13245+ pax_open_kernel();
58c5fc13 13246+ *plocation += sym->st_value;
ae4e228f 13247+ pax_close_kernel();
58c5fc13
MT
13248 break;
13249 case R_386_PC32:
13250 /* Add the value, subtract its postition */
13251- *location += sym->st_value - (uint32_t)location;
ae4e228f 13252+ pax_open_kernel();
58c5fc13 13253+ *plocation += sym->st_value - location;
ae4e228f 13254+ pax_close_kernel();
58c5fc13
MT
13255 break;
13256 default:
13257 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
16454cff 13258@@ -145,21 +196,30 @@ int apply_relocate_add(Elf64_Shdr *sechd
58c5fc13
MT
13259 case R_X86_64_NONE:
13260 break;
13261 case R_X86_64_64:
ae4e228f 13262+ pax_open_kernel();
58c5fc13 13263 *(u64 *)loc = val;
ae4e228f 13264+ pax_close_kernel();
58c5fc13
MT
13265 break;
13266 case R_X86_64_32:
ae4e228f 13267+ pax_open_kernel();
58c5fc13 13268 *(u32 *)loc = val;
ae4e228f 13269+ pax_close_kernel();
58c5fc13
MT
13270 if (val != *(u32 *)loc)
13271 goto overflow;
13272 break;
13273 case R_X86_64_32S:
ae4e228f 13274+ pax_open_kernel();
58c5fc13 13275 *(s32 *)loc = val;
ae4e228f 13276+ pax_close_kernel();
58c5fc13
MT
13277 if ((s64)val != *(s32 *)loc)
13278 goto overflow;
13279 break;
13280 case R_X86_64_PC32:
13281 val -= (u64)loc;
ae4e228f 13282+ pax_open_kernel();
58c5fc13 13283 *(u32 *)loc = val;
ae4e228f 13284+ pax_close_kernel();
58c5fc13
MT
13285+
13286 #if 0
13287 if ((s64)val != *(s32 *)loc)
13288 goto overflow;
16454cff
MT
13289diff -urNp linux-2.6.38.1/arch/x86/kernel/paravirt.c linux-2.6.38.1/arch/x86/kernel/paravirt.c
13290--- linux-2.6.38.1/arch/x86/kernel/paravirt.c 2011-03-14 21:20:32.000000000 -0400
13291+++ linux-2.6.38.1/arch/x86/kernel/paravirt.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 13292@@ -122,7 +122,7 @@ unsigned paravirt_patch_jmp(void *insnbu
58c5fc13 13293 * corresponding structure. */
df50ba0c 13294 static void *get_call_destination(u8 type)
58c5fc13
MT
13295 {
13296- struct paravirt_patch_template tmpl = {
13297+ const struct paravirt_patch_template tmpl = {
13298 .pv_init_ops = pv_init_ops,
13299 .pv_time_ops = pv_time_ops,
13300 .pv_cpu_ops = pv_cpu_ops,
df50ba0c 13301@@ -145,14 +145,14 @@ unsigned paravirt_patch_default(u8 type,
58c5fc13 13302 if (opfunc == NULL)
df50ba0c
MT
13303 /* If there's no function, patch it with a ud2a (BUG) */
13304 ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a));
13305- else if (opfunc == _paravirt_nop)
13306+ else if (opfunc == (void *)_paravirt_nop)
13307 /* If the operation is a nop, then nop the callsite */
13308 ret = paravirt_patch_nop();
13309
13310 /* identity functions just return their single argument */
13311- else if (opfunc == _paravirt_ident_32)
13312+ else if (opfunc == (void *)_paravirt_ident_32)
13313 ret = paravirt_patch_ident_32(insnbuf, len);
13314- else if (opfunc == _paravirt_ident_64)
13315+ else if (opfunc == (void *)_paravirt_ident_64)
13316 ret = paravirt_patch_ident_64(insnbuf, len);
13317
13318 else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
ae4e228f 13319@@ -178,7 +178,7 @@ unsigned paravirt_patch_insns(void *insn
58c5fc13
MT
13320 if (insn_len > len || start == NULL)
13321 insn_len = len;
13322 else
13323- memcpy(insnbuf, start, insn_len);
13324+ memcpy(insnbuf, ktla_ktva(start), insn_len);
13325
13326 return insn_len;
13327 }
ae4e228f 13328@@ -294,22 +294,22 @@ void arch_flush_lazy_mmu_mode(void)
58c5fc13
MT
13329 preempt_enable();
13330 }
13331
13332-struct pv_info pv_info = {
13333+struct pv_info pv_info __read_only = {
13334 .name = "bare hardware",
13335 .paravirt_enabled = 0,
13336 .kernel_rpl = 0,
13337 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
13338 };
13339
13340-struct pv_init_ops pv_init_ops = {
13341+struct pv_init_ops pv_init_ops __read_only = {
13342 .patch = native_patch,
58c5fc13
MT
13343 };
13344
13345-struct pv_time_ops pv_time_ops = {
13346+struct pv_time_ops pv_time_ops __read_only = {
ae4e228f 13347 .sched_clock = native_sched_clock,
58c5fc13
MT
13348 };
13349
13350-struct pv_irq_ops pv_irq_ops = {
13351+struct pv_irq_ops pv_irq_ops __read_only = {
58c5fc13
MT
13352 .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
13353 .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
ae4e228f
MT
13354 .irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable),
13355@@ -321,7 +321,7 @@ struct pv_irq_ops pv_irq_ops = {
58c5fc13
MT
13356 #endif
13357 };
13358
13359-struct pv_cpu_ops pv_cpu_ops = {
13360+struct pv_cpu_ops pv_cpu_ops __read_only = {
13361 .cpuid = native_cpuid,
13362 .get_debugreg = native_get_debugreg,
13363 .set_debugreg = native_set_debugreg,
ae4e228f 13364@@ -382,7 +382,7 @@ struct pv_cpu_ops pv_cpu_ops = {
58c5fc13
MT
13365 .end_context_switch = paravirt_nop,
13366 };
13367
13368-struct pv_apic_ops pv_apic_ops = {
13369+struct pv_apic_ops pv_apic_ops __read_only = {
13370 #ifdef CONFIG_X86_LOCAL_APIC
ae4e228f
MT
13371 .startup_ipi_hook = paravirt_nop,
13372 #endif
13373@@ -396,7 +396,7 @@ struct pv_apic_ops pv_apic_ops = {
58c5fc13
MT
13374 #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64)
13375 #endif
13376
13377-struct pv_mmu_ops pv_mmu_ops = {
13378+struct pv_mmu_ops pv_mmu_ops __read_only = {
ae4e228f
MT
13379
13380 .read_cr2 = native_read_cr2,
13381 .write_cr2 = native_write_cr2,
16454cff 13382@@ -465,6 +465,12 @@ struct pv_mmu_ops pv_mmu_ops = {
ae4e228f
MT
13383 },
13384
13385 .set_fixmap = native_set_fixmap,
13386+
13387+#ifdef CONFIG_PAX_KERNEXEC
13388+ .pax_open_kernel = native_pax_open_kernel,
13389+ .pax_close_kernel = native_pax_close_kernel,
13390+#endif
13391+
13392 };
13393
13394 EXPORT_SYMBOL_GPL(pv_time_ops);
16454cff
MT
13395diff -urNp linux-2.6.38.1/arch/x86/kernel/paravirt-spinlocks.c linux-2.6.38.1/arch/x86/kernel/paravirt-spinlocks.c
13396--- linux-2.6.38.1/arch/x86/kernel/paravirt-spinlocks.c 2011-03-14 21:20:32.000000000 -0400
13397+++ linux-2.6.38.1/arch/x86/kernel/paravirt-spinlocks.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
13398@@ -13,7 +13,7 @@ default_spin_lock_flags(arch_spinlock_t
13399 arch_spin_lock(lock);
13400 }
13401
13402-struct pv_lock_ops pv_lock_ops = {
13403+struct pv_lock_ops pv_lock_ops __read_only = {
13404 #ifdef CONFIG_SMP
13405 .spin_is_locked = __ticket_spin_is_locked,
13406 .spin_is_contended = __ticket_spin_is_contended,
16454cff
MT
13407diff -urNp linux-2.6.38.1/arch/x86/kernel/pci-calgary_64.c linux-2.6.38.1/arch/x86/kernel/pci-calgary_64.c
13408--- linux-2.6.38.1/arch/x86/kernel/pci-calgary_64.c 2011-03-14 21:20:32.000000000 -0400
13409+++ linux-2.6.38.1/arch/x86/kernel/pci-calgary_64.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 13410@@ -476,7 +476,7 @@ static void calgary_free_coherent(struct
ae4e228f
MT
13411 free_pages((unsigned long)vaddr, get_order(size));
13412 }
13413
13414-static struct dma_map_ops calgary_dma_ops = {
13415+static const struct dma_map_ops calgary_dma_ops = {
13416 .alloc_coherent = calgary_alloc_coherent,
13417 .free_coherent = calgary_free_coherent,
13418 .map_sg = calgary_map_sg,
16454cff
MT
13419diff -urNp linux-2.6.38.1/arch/x86/kernel/pci-dma.c linux-2.6.38.1/arch/x86/kernel/pci-dma.c
13420--- linux-2.6.38.1/arch/x86/kernel/pci-dma.c 2011-03-14 21:20:32.000000000 -0400
13421+++ linux-2.6.38.1/arch/x86/kernel/pci-dma.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 13422@@ -16,7 +16,7 @@
ae4e228f
MT
13423
13424 static int forbid_dac __read_mostly;
13425
13426-struct dma_map_ops *dma_ops = &nommu_dma_ops;
13427+const struct dma_map_ops *dma_ops = &nommu_dma_ops;
13428 EXPORT_SYMBOL(dma_ops);
13429
13430 static int iommu_sac_force __read_mostly;
bc901d79 13431@@ -250,7 +250,7 @@ early_param("iommu", iommu_setup);
ae4e228f
MT
13432
13433 int dma_supported(struct device *dev, u64 mask)
13434 {
13435- struct dma_map_ops *ops = get_dma_ops(dev);
13436+ const struct dma_map_ops *ops = get_dma_ops(dev);
13437
13438 #ifdef CONFIG_PCI
13439 if (mask > 0xffffffff && forbid_dac > 0) {
16454cff
MT
13440diff -urNp linux-2.6.38.1/arch/x86/kernel/pci-gart_64.c linux-2.6.38.1/arch/x86/kernel/pci-gart_64.c
13441--- linux-2.6.38.1/arch/x86/kernel/pci-gart_64.c 2011-03-14 21:20:32.000000000 -0400
13442+++ linux-2.6.38.1/arch/x86/kernel/pci-gart_64.c 2011-03-21 18:31:35.000000000 -0400
13443@@ -706,7 +706,7 @@ static __init int init_amd_gatt(struct a
ae4e228f
MT
13444 return -1;
13445 }
13446
13447-static struct dma_map_ops gart_dma_ops = {
13448+static const struct dma_map_ops gart_dma_ops = {
13449 .map_sg = gart_map_sg,
13450 .unmap_sg = gart_unmap_sg,
13451 .map_page = gart_map_page,
16454cff
MT
13452diff -urNp linux-2.6.38.1/arch/x86/kernel/pci-nommu.c linux-2.6.38.1/arch/x86/kernel/pci-nommu.c
13453--- linux-2.6.38.1/arch/x86/kernel/pci-nommu.c 2011-03-14 21:20:32.000000000 -0400
13454+++ linux-2.6.38.1/arch/x86/kernel/pci-nommu.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 13455@@ -95,7 +95,7 @@ static void nommu_sync_sg_for_device(str
ae4e228f
MT
13456 flush_write_buffers();
13457 }
13458
13459-struct dma_map_ops nommu_dma_ops = {
13460+const struct dma_map_ops nommu_dma_ops = {
13461 .alloc_coherent = dma_generic_alloc_coherent,
13462 .free_coherent = nommu_free_coherent,
13463 .map_sg = nommu_map_sg,
16454cff
MT
13464diff -urNp linux-2.6.38.1/arch/x86/kernel/pci-swiotlb.c linux-2.6.38.1/arch/x86/kernel/pci-swiotlb.c
13465--- linux-2.6.38.1/arch/x86/kernel/pci-swiotlb.c 2011-03-14 21:20:32.000000000 -0400
13466+++ linux-2.6.38.1/arch/x86/kernel/pci-swiotlb.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 13467@@ -26,7 +26,7 @@ static void *x86_swiotlb_alloc_coherent(
ae4e228f
MT
13468 return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
13469 }
13470
13471-static struct dma_map_ops swiotlb_dma_ops = {
13472+static const struct dma_map_ops swiotlb_dma_ops = {
13473 .mapping_error = swiotlb_dma_mapping_error,
13474 .alloc_coherent = x86_swiotlb_alloc_coherent,
13475 .free_coherent = swiotlb_free_coherent,
16454cff
MT
13476diff -urNp linux-2.6.38.1/arch/x86/kernel/process_32.c linux-2.6.38.1/arch/x86/kernel/process_32.c
13477--- linux-2.6.38.1/arch/x86/kernel/process_32.c 2011-03-14 21:20:32.000000000 -0400
13478+++ linux-2.6.38.1/arch/x86/kernel/process_32.c 2011-03-21 18:31:35.000000000 -0400
13479@@ -65,6 +65,7 @@ asmlinkage void ret_from_fork(void) __as
57199397
MT
13480 unsigned long thread_saved_pc(struct task_struct *tsk)
13481 {
13482 return ((unsigned long *)tsk->thread.sp)[3];
13483+//XXX return tsk->thread.eip;
13484 }
13485
13486 #ifndef CONFIG_SMP
16454cff 13487@@ -126,15 +127,14 @@ void __show_regs(struct pt_regs *regs, i
57199397
MT
13488 unsigned long sp;
13489 unsigned short ss, gs;
13490
13491- if (user_mode_vm(regs)) {
13492+ if (user_mode(regs)) {
13493 sp = regs->sp;
13494 ss = regs->ss & 0xffff;
bc901d79
MT
13495- gs = get_user_gs(regs);
13496 } else {
13497 sp = kernel_stack_pointer(regs);
13498 savesegment(ss, ss);
13499- savesegment(gs, gs);
13500 }
13501+ gs = get_user_gs(regs);
13502
13503 show_regs_common();
13504
16454cff 13505@@ -196,7 +196,7 @@ int copy_thread(unsigned long clone_flag
57199397
MT
13506 struct task_struct *tsk;
13507 int err;
13508
13509- childregs = task_pt_regs(p);
13510+ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
13511 *childregs = *regs;
13512 childregs->ax = 0;
13513 childregs->sp = sp;
16454cff 13514@@ -293,7 +293,7 @@ __switch_to(struct task_struct *prev_p,
57199397
MT
13515 struct thread_struct *prev = &prev_p->thread,
13516 *next = &next_p->thread;
13517 int cpu = smp_processor_id();
13518- struct tss_struct *tss = &per_cpu(init_tss, cpu);
13519+ struct tss_struct *tss = init_tss + cpu;
13520 bool preload_fpu;
13521
13522 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
16454cff 13523@@ -328,6 +328,10 @@ __switch_to(struct task_struct *prev_p,
57199397
MT
13524 */
13525 lazy_save_gs(prev->gs);
13526
13527+#ifdef CONFIG_PAX_MEMORY_UDEREF
bc901d79 13528+ __set_fs(task_thread_info(next_p)->addr_limit);
57199397
MT
13529+#endif
13530+
13531 /*
13532 * Load the per-thread Thread-Local Storage descriptor.
13533 */
16454cff 13534@@ -404,3 +408,27 @@ unsigned long get_wchan(struct task_stru
57199397
MT
13535 return 0;
13536 }
13537
13538+#ifdef CONFIG_PAX_RANDKSTACK
13539+asmlinkage void pax_randomize_kstack(void)
13540+{
13541+ struct thread_struct *thread = &current->thread;
13542+ unsigned long time;
13543+
13544+ if (!randomize_va_space)
13545+ return;
13546+
13547+ rdtscl(time);
13548+
13549+ /* P4 seems to return a 0 LSB, ignore it */
13550+#ifdef CONFIG_MPENTIUM4
13551+ time &= 0x1EUL;
13552+ time <<= 2;
13553+#else
13554+ time &= 0xFUL;
13555+ time <<= 3;
13556+#endif
13557+
13558+ thread->sp0 ^= time;
13559+ load_sp0(init_tss + smp_processor_id(), thread);
13560+}
13561+#endif
16454cff
MT
13562diff -urNp linux-2.6.38.1/arch/x86/kernel/process_64.c linux-2.6.38.1/arch/x86/kernel/process_64.c
13563--- linux-2.6.38.1/arch/x86/kernel/process_64.c 2011-03-14 21:20:32.000000000 -0400
13564+++ linux-2.6.38.1/arch/x86/kernel/process_64.c 2011-03-21 18:31:35.000000000 -0400
13565@@ -87,7 +87,7 @@ static void __exit_idle(void)
57199397
MT
13566 void exit_idle(void)
13567 {
13568 /* idle loop has pid 0 */
13569- if (current->pid)
13570+ if (task_pid_nr(current))
13571 return;
13572 __exit_idle();
13573 }
16454cff 13574@@ -376,7 +376,7 @@ __switch_to(struct task_struct *prev_p,
57199397
MT
13575 struct thread_struct *prev = &prev_p->thread;
13576 struct thread_struct *next = &next_p->thread;
13577 int cpu = smp_processor_id();
13578- struct tss_struct *tss = &per_cpu(init_tss, cpu);
13579+ struct tss_struct *tss = init_tss + cpu;
13580 unsigned fsindex, gsindex;
13581 bool preload_fpu;
13582
16454cff 13583@@ -529,12 +529,11 @@ unsigned long get_wchan(struct task_stru
57199397
MT
13584 if (!p || p == current || p->state == TASK_RUNNING)
13585 return 0;
13586 stack = (unsigned long)task_stack_page(p);
13587- if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
13588+ if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
13589 return 0;
13590 fp = *(u64 *)(p->thread.sp);
13591 do {
13592- if (fp < (unsigned long)stack ||
13593- fp >= (unsigned long)stack+THREAD_SIZE)
13594+ if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
13595 return 0;
13596 ip = *(u64 *)(fp+8);
13597 if (!in_sched_functions(ip))
16454cff
MT
13598diff -urNp linux-2.6.38.1/arch/x86/kernel/process.c linux-2.6.38.1/arch/x86/kernel/process.c
13599--- linux-2.6.38.1/arch/x86/kernel/process.c 2011-03-14 21:20:32.000000000 -0400
13600+++ linux-2.6.38.1/arch/x86/kernel/process.c 2011-03-21 18:31:35.000000000 -0400
13601@@ -70,7 +70,7 @@ void exit_thread(void)
efbe55a5
MT
13602 unsigned long *bp = t->io_bitmap_ptr;
13603
13604 if (bp) {
13605- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
13606+ struct tss_struct *tss = init_tss + get_cpu();
13607
13608 t->io_bitmap_ptr = NULL;
13609 clear_thread_flag(TIF_IO_BITMAP);
16454cff 13610@@ -97,6 +97,7 @@ void show_regs_common(void)
c52201e0
MT
13611 vendor = dmi_get_system_info(DMI_SYS_VENDOR);
13612 if (!vendor)
13613 vendor = "";
13614+
13615 product = dmi_get_system_info(DMI_PRODUCT_NAME);
13616 if (!product)
13617 product = "";
16454cff 13618@@ -105,8 +106,8 @@ void show_regs_common(void)
c52201e0 13619 board = dmi_get_system_info(DMI_BOARD_NAME);
efbe55a5
MT
13620
13621 printk(KERN_CONT "\n");
c52201e0 13622- printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s",
efbe55a5 13623- current->pid, current->comm, print_tainted(),
c52201e0 13624+ printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s\n",
efbe55a5
MT
13625+ task_pid_nr(current), current->comm, print_tainted(),
13626 init_utsname()->release,
13627 (int)strcspn(init_utsname()->version, " "),
c52201e0 13628 init_utsname()->version);
16454cff 13629@@ -123,6 +124,9 @@ void flush_thread(void)
efbe55a5
MT
13630 {
13631 struct task_struct *tsk = current;
13632
bc901d79 13633+#if defined(CONFIG_X86_32) && !defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_PAX_MEMORY_UDEREF)
efbe55a5
MT
13634+ loadsegment(gs, 0);
13635+#endif
13636 flush_ptrace_hw_breakpoint(tsk);
13637 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
13638 /*
16454cff 13639@@ -285,10 +289,10 @@ int kernel_thread(int (*fn)(void *), voi
efbe55a5
MT
13640 regs.di = (unsigned long) arg;
13641
13642 #ifdef CONFIG_X86_32
13643- regs.ds = __USER_DS;
13644- regs.es = __USER_DS;
13645+ regs.ds = __KERNEL_DS;
13646+ regs.es = __KERNEL_DS;
13647 regs.fs = __KERNEL_PERCPU;
bc901d79
MT
13648- regs.gs = __KERNEL_STACK_CANARY;
13649+ savesegment(gs, regs.gs);
efbe55a5 13650 #else
bc901d79
MT
13651 regs.ss = __KERNEL_DS;
13652 #endif
16454cff 13653@@ -667,17 +671,3 @@ static int __init idle_setup(char *str)
efbe55a5
MT
13654 return 0;
13655 }
13656 early_param("idle", idle_setup);
13657-
13658-unsigned long arch_align_stack(unsigned long sp)
13659-{
13660- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
13661- sp -= get_random_int() % 8192;
13662- return sp & ~0xf;
13663-}
13664-
13665-unsigned long arch_randomize_brk(struct mm_struct *mm)
13666-{
13667- unsigned long range_end = mm->brk + 0x02000000;
13668- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
13669-}
13670-
16454cff
MT
13671diff -urNp linux-2.6.38.1/arch/x86/kernel/ptrace.c linux-2.6.38.1/arch/x86/kernel/ptrace.c
13672--- linux-2.6.38.1/arch/x86/kernel/ptrace.c 2011-03-14 21:20:32.000000000 -0400
13673+++ linux-2.6.38.1/arch/x86/kernel/ptrace.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
13674@@ -805,7 +805,7 @@ long arch_ptrace(struct task_struct *chi
13675 unsigned long addr, unsigned long data)
ae4e228f
MT
13676 {
13677 int ret;
13678- unsigned long __user *datap = (unsigned long __user *)data;
13679+ unsigned long __user *datap = (__force unsigned long __user *)data;
13680
13681 switch (request) {
13682 /* read the word at location addr in the USER area. */
bc901d79
MT
13683@@ -890,14 +890,14 @@ long arch_ptrace(struct task_struct *chi
13684 if ((int) addr < 0)
ae4e228f
MT
13685 return -EIO;
13686 ret = do_get_thread_area(child, addr,
bc901d79
MT
13687- (struct user_desc __user *)data);
13688+ (__force struct user_desc __user *) data);
ae4e228f
MT
13689 break;
13690
13691 case PTRACE_SET_THREAD_AREA:
bc901d79 13692 if ((int) addr < 0)
ae4e228f
MT
13693 return -EIO;
13694 ret = do_set_thread_area(child, addr,
bc901d79
MT
13695- (struct user_desc __user *)data, 0);
13696+ (__force struct user_desc __user *) data, 0);
ae4e228f
MT
13697 break;
13698 #endif
13699
bc901d79 13700@@ -1314,7 +1314,7 @@ static void fill_sigtrap_info(struct tas
ae4e228f
MT
13701 memset(info, 0, sizeof(*info));
13702 info->si_signo = SIGTRAP;
13703 info->si_code = si_code;
13704- info->si_addr = user_mode_vm(regs) ? (void __user *)regs->ip : NULL;
13705+ info->si_addr = user_mode(regs) ? (__force void __user *)regs->ip : NULL;
13706 }
13707
13708 void user_single_step_siginfo(struct task_struct *tsk,
16454cff
MT
13709@@ -1347,7 +1347,7 @@ void send_sigtrap(struct task_struct *ts
13710 * We must return the syscall number to actually look up in the table.
13711 * This can be -1L to skip running any syscall at all.
13712 */
13713-asmregparm long syscall_trace_enter(struct pt_regs *regs)
13714+long syscall_trace_enter(struct pt_regs *regs)
13715 {
13716 long ret = 0;
13717
13718@@ -1392,7 +1392,7 @@ asmregparm long syscall_trace_enter(stru
13719 return ret ?: regs->orig_ax;
13720 }
13721
13722-asmregparm void syscall_trace_leave(struct pt_regs *regs)
13723+void syscall_trace_leave(struct pt_regs *regs)
13724 {
13725 bool step;
13726
13727diff -urNp linux-2.6.38.1/arch/x86/kernel/reboot.c linux-2.6.38.1/arch/x86/kernel/reboot.c
13728--- linux-2.6.38.1/arch/x86/kernel/reboot.c 2011-03-14 21:20:32.000000000 -0400
13729+++ linux-2.6.38.1/arch/x86/kernel/reboot.c 2011-03-21 18:31:35.000000000 -0400
13730@@ -34,7 +34,7 @@ void (*pm_power_off)(void);
58c5fc13
MT
13731 EXPORT_SYMBOL(pm_power_off);
13732
13733 static const struct desc_ptr no_idt = {};
13734-static int reboot_mode;
13735+static unsigned short reboot_mode;
13736 enum reboot_type reboot_type = BOOT_KBD;
13737 int reboot_force;
13738
16454cff
MT
13739@@ -293,7 +293,7 @@ static struct dmi_system_id __initdata r
13740 DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
58c5fc13
MT
13741 },
13742 },
13743- { }
13744+ { NULL, NULL, {{0, {0}}}, NULL}
13745 };
13746
13747 static int __init reboot_init(void)
16454cff 13748@@ -309,12 +309,12 @@ core_initcall(reboot_init);
58c5fc13
MT
13749 controller to pulse the CPU reset line, which is more thorough, but
13750 doesn't work with at least one type of 486 motherboard. It is easy
13751 to stop this code working; hence the copious comments. */
13752-static const unsigned long long
13753-real_mode_gdt_entries [3] =
13754+static struct desc_struct
13755+real_mode_gdt_entries [3] __read_only =
13756 {
13757- 0x0000000000000000ULL, /* Null descriptor */
13758- 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
13759- 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
ae4e228f
MT
13760+ GDT_ENTRY_INIT(0, 0, 0), /* Null descriptor */
13761+ GDT_ENTRY_INIT(0x9b, 0, 0xffff), /* 16-bit real-mode 64k code at 0x00000000 */
13762+ GDT_ENTRY_INIT(0x93, 0x100, 0xffff) /* 16-bit real-mode 64k data at 0x00000100 */
58c5fc13
MT
13763 };
13764
13765 static const struct desc_ptr
16454cff 13766@@ -363,7 +363,7 @@ static const unsigned char jump_to_bios
58c5fc13
MT
13767 * specified by the code and length parameters.
13768 * We assume that length will aways be less that 100!
13769 */
13770-void machine_real_restart(const unsigned char *code, int length)
13771+void machine_real_restart(const unsigned char *code, unsigned int length)
13772 {
13773 local_irq_disable();
13774
16454cff 13775@@ -390,16 +390,15 @@ void machine_real_restart(const unsigned
58c5fc13
MT
13776 boot)". This seems like a fairly standard thing that gets set by
13777 REBOOT.COM programs, and the previous reset routine did this
13778 too. */
13779- *((unsigned short *)0x472) = reboot_mode;
13780+ *(unsigned short *)(__va(0x472)) = reboot_mode;
13781
13782 /* For the switch to real mode, copy some code to low memory. It has
13783 to be in the first 64k because it is running in 16-bit mode, and it
13784 has to have the same physical and virtual address, because it turns
13785 off paging. Copy it near the end of the first page, out of the way
13786 of BIOS variables. */
13787- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
13788- real_mode_switch, sizeof (real_mode_switch));
13789- memcpy((void *)(0x1000 - 100), code, length);
13790+ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
13791+ memcpy(__va(0x1000 - 100), code, length);
13792
13793 /* Set up the IDT for real mode. */
13794 load_idt(&real_mode_idt);
16454cff
MT
13795diff -urNp linux-2.6.38.1/arch/x86/kernel/setup.c linux-2.6.38.1/arch/x86/kernel/setup.c
13796--- linux-2.6.38.1/arch/x86/kernel/setup.c 2011-03-14 21:20:32.000000000 -0400
13797+++ linux-2.6.38.1/arch/x86/kernel/setup.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 13798@@ -654,7 +654,7 @@ static void __init trim_bios_range(void)
efbe55a5
MT
13799 * area (640->1Mb) as ram even though it is not.
13800 * take them out.
13801 */
13802- e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1);
13803+ e820_remove_range(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_RAM, 1);
13804 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
13805 }
13806
bc901d79 13807@@ -790,14 +790,14 @@ void __init setup_arch(char **cmdline_p)
58c5fc13
MT
13808
13809 if (!boot_params.hdr.root_flags)
13810 root_mountflags &= ~MS_RDONLY;
13811- init_mm.start_code = (unsigned long) _text;
13812- init_mm.end_code = (unsigned long) _etext;
13813+ init_mm.start_code = ktla_ktva((unsigned long) _text);
13814+ init_mm.end_code = ktla_ktva((unsigned long) _etext);
13815 init_mm.end_data = (unsigned long) _edata;
13816 init_mm.brk = _brk_end;
13817
13818- code_resource.start = virt_to_phys(_text);
13819- code_resource.end = virt_to_phys(_etext)-1;
13820- data_resource.start = virt_to_phys(_etext);
13821+ code_resource.start = virt_to_phys(ktla_ktva(_text));
13822+ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
13823+ data_resource.start = virt_to_phys(_sdata);
13824 data_resource.end = virt_to_phys(_edata)-1;
13825 bss_resource.start = virt_to_phys(&__bss_start);
13826 bss_resource.end = virt_to_phys(&__bss_stop)-1;
16454cff
MT
13827diff -urNp linux-2.6.38.1/arch/x86/kernel/setup_percpu.c linux-2.6.38.1/arch/x86/kernel/setup_percpu.c
13828--- linux-2.6.38.1/arch/x86/kernel/setup_percpu.c 2011-03-14 21:20:32.000000000 -0400
13829+++ linux-2.6.38.1/arch/x86/kernel/setup_percpu.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
13830@@ -21,19 +21,17 @@
13831 #include <asm/cpu.h>
13832 #include <asm/stackprotector.h>
58c5fc13 13833
6892158b 13834-DEFINE_PER_CPU(int, cpu_number);
58c5fc13 13835+#ifdef CONFIG_SMP
6892158b 13836+DEFINE_PER_CPU(unsigned int, cpu_number);
58c5fc13
MT
13837 EXPORT_PER_CPU_SYMBOL(cpu_number);
13838+#endif
13839
13840-#ifdef CONFIG_X86_64
13841 #define BOOT_PERCPU_OFFSET ((unsigned long)__per_cpu_load)
13842-#else
13843-#define BOOT_PERCPU_OFFSET 0
13844-#endif
13845
13846 DEFINE_PER_CPU(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;
13847 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
13848
13849-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
13850+unsigned long __per_cpu_offset[NR_CPUS] __read_only = {
13851 [0 ... NR_CPUS-1] = BOOT_PERCPU_OFFSET,
13852 };
13853 EXPORT_SYMBOL(__per_cpu_offset);
bc901d79 13854@@ -155,10 +153,10 @@ static inline void setup_percpu_segment(
58c5fc13
MT
13855 {
13856 #ifdef CONFIG_X86_32
ae4e228f
MT
13857 struct desc_struct gdt;
13858+ unsigned long base = per_cpu_offset(cpu);
13859
58c5fc13
MT
13860- pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
13861- 0x2 | DESCTYPE_S, 0x8);
13862- gdt.s = 1;
ae4e228f
MT
13863+ pack_descriptor(&gdt, base, (VMALLOC_END - base - 1) >> PAGE_SHIFT,
13864+ 0x83 | DESCTYPE_S, 0xC);
13865 write_gdt_entry(get_cpu_gdt_table(cpu),
13866 GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
58c5fc13 13867 #endif
bc901d79 13868@@ -207,6 +205,11 @@ void __init setup_per_cpu_areas(void)
58c5fc13
MT
13869 /* alrighty, percpu areas up and running */
13870 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
13871 for_each_possible_cpu(cpu) {
13872+#ifdef CONFIG_CC_STACKPROTECTOR
13873+#ifdef CONFIG_x86_32
13874+ unsigned long canary = per_cpu(stack_canary, cpu);
13875+#endif
13876+#endif
ae4e228f 13877 per_cpu_offset(cpu) = delta + pcpu_unit_offsets[cpu];
58c5fc13
MT
13878 per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
13879 per_cpu(cpu_number, cpu) = cpu;
bc901d79 13880@@ -243,6 +246,12 @@ void __init setup_per_cpu_areas(void)
57199397 13881 set_cpu_numa_node(cpu, early_cpu_to_node(cpu));
58c5fc13
MT
13882 #endif
13883 #endif
13884+#ifdef CONFIG_CC_STACKPROTECTOR
13885+#ifdef CONFIG_x86_32
13886+ if (cpu == boot_cpu_id)
13887+ per_cpu(stack_canary, cpu) = canary;
13888+#endif
13889+#endif
13890 /*
57199397 13891 * Up to this point, the boot CPU has been using .init.data
58c5fc13 13892 * area. Reload any changed state for the boot CPU.
16454cff
MT
13893diff -urNp linux-2.6.38.1/arch/x86/kernel/signal.c linux-2.6.38.1/arch/x86/kernel/signal.c
13894--- linux-2.6.38.1/arch/x86/kernel/signal.c 2011-03-14 21:20:32.000000000 -0400
13895+++ linux-2.6.38.1/arch/x86/kernel/signal.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 13896@@ -198,7 +198,7 @@ static unsigned long align_sigframe(unsi
58c5fc13
MT
13897 * Align the stack pointer according to the i386 ABI,
13898 * i.e. so that on function entry ((sp + 4) & 15) == 0.
13899 */
13900- sp = ((sp + 4) & -16ul) - 4;
13901+ sp = ((sp - 12) & -16ul) - 4;
13902 #else /* !CONFIG_X86_32 */
13903 sp = round_down(sp, 16) - 8;
13904 #endif
ae4e228f
MT
13905@@ -249,11 +249,11 @@ get_sigframe(struct k_sigaction *ka, str
13906 * Return an always-bogus address instead so we will die with SIGSEGV.
13907 */
13908 if (onsigstack && !likely(on_sig_stack(sp)))
13909- return (void __user *)-1L;
13910+ return (__force void __user *)-1L;
13911
13912 /* save i387 state */
13913 if (used_math() && save_i387_xstate(*fpstate) < 0)
13914- return (void __user *)-1L;
13915+ return (__force void __user *)-1L;
13916
13917 return (void __user *)sp;
13918 }
13919@@ -308,9 +308,9 @@ __setup_frame(int sig, struct k_sigactio
58c5fc13
MT
13920 }
13921
13922 if (current->mm->context.vdso)
13923- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
ae4e228f 13924+ restorer = (__force void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
58c5fc13
MT
13925 else
13926- restorer = &frame->retcode;
13927+ restorer = (void __user *)&frame->retcode;
13928 if (ka->sa.sa_flags & SA_RESTORER)
13929 restorer = ka->sa.sa_restorer;
13930
ae4e228f
MT
13931@@ -324,7 +324,7 @@ __setup_frame(int sig, struct k_sigactio
13932 * reasons and because gdb uses it as a signature to notice
13933 * signal handler stack frames.
13934 */
13935- err |= __put_user(*((u64 *)&retcode), (u64 *)frame->retcode);
13936+ err |= __put_user(*((u64 *)&retcode), (u64 __user *)frame->retcode);
13937
13938 if (err)
13939 return -EFAULT;
6892158b 13940@@ -378,7 +378,10 @@ static int __setup_rt_frame(int sig, str
58c5fc13
MT
13941 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
13942
13943 /* Set up to return from userspace. */
13944- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6892158b
MT
13945+ if (current->mm->context.vdso)
13946+ restorer = (__force void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
13947+ else
13948+ restorer = (void __user *)&frame->retcode;
58c5fc13
MT
13949 if (ka->sa.sa_flags & SA_RESTORER)
13950 restorer = ka->sa.sa_restorer;
13951 put_user_ex(restorer, &frame->pretcode);
6892158b 13952@@ -390,7 +393,7 @@ static int __setup_rt_frame(int sig, str
ae4e228f
MT
13953 * reasons and because gdb uses it as a signature to notice
13954 * signal handler stack frames.
13955 */
13956- put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
13957+ put_user_ex(*((u64 *)&rt_retcode), (u64 __user *)frame->retcode);
13958 } put_user_catch(err);
13959
13960 if (err)
6892158b 13961@@ -780,7 +783,7 @@ static void do_signal(struct pt_regs *re
58c5fc13
MT
13962 * X86_32: vm86 regs switched out by assembly code before reaching
13963 * here, so testing against kernel CS suffices.
13964 */
13965- if (!user_mode(regs))
13966+ if (!user_mode_novm(regs))
13967 return;
13968
13969 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
16454cff
MT
13970diff -urNp linux-2.6.38.1/arch/x86/kernel/smpboot.c linux-2.6.38.1/arch/x86/kernel/smpboot.c
13971--- linux-2.6.38.1/arch/x86/kernel/smpboot.c 2011-03-14 21:20:32.000000000 -0400
13972+++ linux-2.6.38.1/arch/x86/kernel/smpboot.c 2011-03-21 18:31:35.000000000 -0400
13973@@ -783,7 +783,11 @@ do_rest:
58c5fc13
MT
13974 (unsigned long)task_stack_page(c_idle.idle) -
13975 KERNEL_STACK_OFFSET + THREAD_SIZE;
13976 #endif
13977+
ae4e228f 13978+ pax_open_kernel();
58c5fc13 13979 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
ae4e228f 13980+ pax_close_kernel();
58c5fc13
MT
13981+
13982 initial_code = (unsigned long)start_secondary;
16454cff 13983 stack_start = c_idle.idle->thread.sp;
58c5fc13 13984
16454cff 13985@@ -923,6 +927,12 @@ int __cpuinit native_cpu_up(unsigned int
df50ba0c
MT
13986
13987 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
13988
13989+#ifdef CONFIG_PAX_PER_CPU_PGD
13990+ clone_pgd_range(get_cpu_pgd(cpu) + KERNEL_PGD_BOUNDARY,
13991+ swapper_pg_dir + KERNEL_PGD_BOUNDARY,
13992+ KERNEL_PGD_PTRS);
13993+#endif
13994+
6892158b 13995 err = do_boot_cpu(apicid, cpu);
6892158b 13996 if (err) {
bc901d79 13997 pr_debug("do_boot_cpu failed %d\n", err);
16454cff
MT
13998diff -urNp linux-2.6.38.1/arch/x86/kernel/step.c linux-2.6.38.1/arch/x86/kernel/step.c
13999--- linux-2.6.38.1/arch/x86/kernel/step.c 2011-03-14 21:20:32.000000000 -0400
14000+++ linux-2.6.38.1/arch/x86/kernel/step.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
14001@@ -27,10 +27,10 @@ unsigned long convert_ip_to_linear(struc
14002 struct desc_struct *desc;
58c5fc13
MT
14003 unsigned long base;
14004
14005- seg &= ~7UL;
14006+ seg >>= 3;
14007
14008 mutex_lock(&child->mm->context.lock);
14009- if (unlikely((seg >> 3) >= child->mm->context.size))
58c5fc13 14010+ if (unlikely(seg >= child->mm->context.size))
ae4e228f 14011 addr = -1L; /* bogus selector, access would fault */
58c5fc13 14012 else {
ae4e228f 14013 desc = child->mm->context.ldt + seg;
bc901d79
MT
14014@@ -42,7 +42,8 @@ unsigned long convert_ip_to_linear(struc
14015 addr += base;
14016 }
14017 mutex_unlock(&child->mm->context.lock);
14018- }
14019+ } else if (seg == __KERNEL_CS || seg == __KERNEXEC_KERNEL_CS)
14020+ addr = ktla_ktva(addr);
14021
14022 return addr;
14023 }
14024@@ -53,6 +54,9 @@ static int is_setting_trap_flag(struct t
58c5fc13
MT
14025 unsigned char opcode[15];
14026 unsigned long addr = convert_ip_to_linear(child, regs);
14027
14028+ if (addr == -EINVAL)
14029+ return 0;
14030+
14031 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
14032 for (i = 0; i < copied; i++) {
14033 switch (opcode[i]) {
bc901d79 14034@@ -74,7 +78,7 @@ static int is_setting_trap_flag(struct t
58c5fc13
MT
14035
14036 #ifdef CONFIG_X86_64
14037 case 0x40 ... 0x4f:
14038- if (regs->cs != __USER_CS)
14039+ if ((regs->cs & 0xffff) != __USER_CS)
14040 /* 32-bit mode: register increment */
14041 return 0;
14042 /* 64-bit mode: REX prefix */
16454cff
MT
14043diff -urNp linux-2.6.38.1/arch/x86/kernel/syscall_table_32.S linux-2.6.38.1/arch/x86/kernel/syscall_table_32.S
14044--- linux-2.6.38.1/arch/x86/kernel/syscall_table_32.S 2011-03-14 21:20:32.000000000 -0400
14045+++ linux-2.6.38.1/arch/x86/kernel/syscall_table_32.S 2011-03-21 18:31:35.000000000 -0400
57199397
MT
14046@@ -1,3 +1,4 @@
14047+.section .rodata,"a",@progbits
14048 ENTRY(sys_call_table)
14049 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
14050 .long sys_exit
16454cff
MT
14051diff -urNp linux-2.6.38.1/arch/x86/kernel/sys_i386_32.c linux-2.6.38.1/arch/x86/kernel/sys_i386_32.c
14052--- linux-2.6.38.1/arch/x86/kernel/sys_i386_32.c 2011-03-14 21:20:32.000000000 -0400
14053+++ linux-2.6.38.1/arch/x86/kernel/sys_i386_32.c 2011-03-21 23:47:41.000000000 -0400
bc901d79 14054@@ -24,17 +24,224 @@
58c5fc13
MT
14055
14056 #include <asm/syscalls.h>
14057
bc901d79
MT
14058-/*
14059- * Do a system call from kernel instead of calling sys_execve so we
14060- * end up with proper pt_regs.
14061- */
14062-int kernel_execve(const char *filename,
14063- const char *const argv[],
14064- const char *const envp[])
58c5fc13 14065+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
bc901d79
MT
14066 {
14067- long __res;
14068- asm volatile ("int $0x80"
14069- : "=a" (__res)
14070- : "0" (__NR_execve), "b" (filename), "c" (argv), "d" (envp) : "memory");
14071- return __res;
58c5fc13
MT
14072+ unsigned long pax_task_size = TASK_SIZE;
14073+
14074+#ifdef CONFIG_PAX_SEGMEXEC
14075+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
14076+ pax_task_size = SEGMEXEC_TASK_SIZE;
14077+#endif
14078+
14079+ if (len > pax_task_size || addr > pax_task_size - len)
14080+ return -EINVAL;
14081+
14082+ return 0;
14083+}
14084+
58c5fc13
MT
14085+unsigned long
14086+arch_get_unmapped_area(struct file *filp, unsigned long addr,
14087+ unsigned long len, unsigned long pgoff, unsigned long flags)
14088+{
14089+ struct mm_struct *mm = current->mm;
14090+ struct vm_area_struct *vma;
14091+ unsigned long start_addr, pax_task_size = TASK_SIZE;
14092+
14093+#ifdef CONFIG_PAX_SEGMEXEC
14094+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
14095+ pax_task_size = SEGMEXEC_TASK_SIZE;
14096+#endif
14097+
6892158b
MT
14098+ pax_task_size -= PAGE_SIZE;
14099+
58c5fc13
MT
14100+ if (len > pax_task_size)
14101+ return -ENOMEM;
14102+
14103+ if (flags & MAP_FIXED)
14104+ return addr;
14105+
14106+#ifdef CONFIG_PAX_RANDMMAP
14107+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
14108+#endif
14109+
14110+ if (addr) {
14111+ addr = PAGE_ALIGN(addr);
57199397
MT
14112+ if (pax_task_size - len >= addr) {
14113+ vma = find_vma(mm, addr);
14114+ if (check_heap_stack_gap(vma, addr, len))
14115+ return addr;
14116+ }
58c5fc13
MT
14117+ }
14118+ if (len > mm->cached_hole_size) {
14119+ start_addr = addr = mm->free_area_cache;
14120+ } else {
14121+ start_addr = addr = mm->mmap_base;
14122+ mm->cached_hole_size = 0;
14123+ }
14124+
14125+#ifdef CONFIG_PAX_PAGEEXEC
ae4e228f 14126+ if (!(__supported_pte_mask & _PAGE_NX) && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
58c5fc13
MT
14127+ start_addr = 0x00110000UL;
14128+
14129+#ifdef CONFIG_PAX_RANDMMAP
14130+ if (mm->pax_flags & MF_PAX_RANDMMAP)
14131+ start_addr += mm->delta_mmap & 0x03FFF000UL;
14132+#endif
14133+
14134+ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
14135+ start_addr = addr = mm->mmap_base;
14136+ else
14137+ addr = start_addr;
14138+ }
14139+#endif
14140+
14141+full_search:
14142+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
14143+ /* At this point: (!vma || addr < vma->vm_end). */
14144+ if (pax_task_size - len < addr) {
14145+ /*
14146+ * Start a new search - just in case we missed
14147+ * some holes.
14148+ */
14149+ if (start_addr != mm->mmap_base) {
14150+ start_addr = addr = mm->mmap_base;
14151+ mm->cached_hole_size = 0;
14152+ goto full_search;
14153+ }
14154+ return -ENOMEM;
14155+ }
57199397
MT
14156+ if (check_heap_stack_gap(vma, addr, len))
14157+ break;
58c5fc13
MT
14158+ if (addr + mm->cached_hole_size < vma->vm_start)
14159+ mm->cached_hole_size = vma->vm_start - addr;
14160+ addr = vma->vm_end;
14161+ if (mm->start_brk <= addr && addr < mm->mmap_base) {
14162+ start_addr = addr = mm->mmap_base;
14163+ mm->cached_hole_size = 0;
14164+ goto full_search;
14165+ }
14166+ }
57199397
MT
14167+
14168+ /*
14169+ * Remember the place where we stopped the search:
14170+ */
14171+ mm->free_area_cache = addr + len;
14172+ return addr;
58c5fc13
MT
14173+}
14174+
14175+unsigned long
14176+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
14177+ const unsigned long len, const unsigned long pgoff,
14178+ const unsigned long flags)
14179+{
14180+ struct vm_area_struct *vma;
14181+ struct mm_struct *mm = current->mm;
14182+ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
14183+
14184+#ifdef CONFIG_PAX_SEGMEXEC
14185+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
14186+ pax_task_size = SEGMEXEC_TASK_SIZE;
14187+#endif
14188+
6892158b
MT
14189+ pax_task_size -= PAGE_SIZE;
14190+
58c5fc13
MT
14191+ /* requested length too big for entire address space */
14192+ if (len > pax_task_size)
14193+ return -ENOMEM;
14194+
14195+ if (flags & MAP_FIXED)
14196+ return addr;
14197+
14198+#ifdef CONFIG_PAX_PAGEEXEC
ae4e228f 14199+ if (!(__supported_pte_mask & _PAGE_NX) && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
58c5fc13
MT
14200+ goto bottomup;
14201+#endif
14202+
14203+#ifdef CONFIG_PAX_RANDMMAP
14204+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
14205+#endif
14206+
14207+ /* requesting a specific address */
14208+ if (addr) {
14209+ addr = PAGE_ALIGN(addr);
57199397
MT
14210+ if (pax_task_size - len >= addr) {
14211+ vma = find_vma(mm, addr);
14212+ if (check_heap_stack_gap(vma, addr, len))
14213+ return addr;
14214+ }
58c5fc13
MT
14215+ }
14216+
14217+ /* check if free_area_cache is useful for us */
14218+ if (len <= mm->cached_hole_size) {
14219+ mm->cached_hole_size = 0;
14220+ mm->free_area_cache = mm->mmap_base;
14221+ }
14222+
14223+ /* either no address requested or can't fit in requested address hole */
14224+ addr = mm->free_area_cache;
14225+
14226+ /* make sure it can fit in the remaining address space */
14227+ if (addr > len) {
14228+ vma = find_vma(mm, addr-len);
57199397 14229+ if (check_heap_stack_gap(vma, addr - len, len))
58c5fc13
MT
14230+ /* remember the address as a hint for next time */
14231+ return (mm->free_area_cache = addr-len);
14232+ }
14233+
14234+ if (mm->mmap_base < len)
14235+ goto bottomup;
14236+
14237+ addr = mm->mmap_base-len;
14238+
14239+ do {
14240+ /*
14241+ * Lookup failure means no vma is above this address,
14242+ * else if new region fits below vma->vm_start,
14243+ * return with success:
14244+ */
14245+ vma = find_vma(mm, addr);
57199397 14246+ if (check_heap_stack_gap(vma, addr, len))
58c5fc13
MT
14247+ /* remember the address as a hint for next time */
14248+ return (mm->free_area_cache = addr);
14249+
14250+ /* remember the largest hole we saw so far */
14251+ if (addr + mm->cached_hole_size < vma->vm_start)
14252+ mm->cached_hole_size = vma->vm_start - addr;
14253+
14254+ /* try just below the current vma->vm_start */
16454cff
MT
14255+ addr = skip_heap_stack_gap(vma, len);
14256+ } while (!IS_ERR_VALUE(addr));
58c5fc13
MT
14257+
14258+bottomup:
14259+ /*
14260+ * A failed mmap() very likely causes application failure,
14261+ * so fall back to the bottom-up function here. This scenario
14262+ * can happen with large stack limits and large mmap()
14263+ * allocations.
14264+ */
14265+
14266+#ifdef CONFIG_PAX_SEGMEXEC
14267+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
14268+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
14269+ else
14270+#endif
14271+
14272+ mm->mmap_base = TASK_UNMAPPED_BASE;
14273+
14274+#ifdef CONFIG_PAX_RANDMMAP
14275+ if (mm->pax_flags & MF_PAX_RANDMMAP)
14276+ mm->mmap_base += mm->delta_mmap;
14277+#endif
14278+
14279+ mm->free_area_cache = mm->mmap_base;
14280+ mm->cached_hole_size = ~0UL;
14281+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
14282+ /*
14283+ * Restore the topdown base:
14284+ */
14285+ mm->mmap_base = base;
14286+ mm->free_area_cache = base;
14287+ mm->cached_hole_size = ~0UL;
14288+
14289+ return addr;
bc901d79 14290 }
16454cff
MT
14291diff -urNp linux-2.6.38.1/arch/x86/kernel/sys_x86_64.c linux-2.6.38.1/arch/x86/kernel/sys_x86_64.c
14292--- linux-2.6.38.1/arch/x86/kernel/sys_x86_64.c 2011-03-14 21:20:32.000000000 -0400
14293+++ linux-2.6.38.1/arch/x86/kernel/sys_x86_64.c 2011-03-21 23:47:41.000000000 -0400
ae4e228f 14294@@ -32,8 +32,8 @@ out:
58c5fc13
MT
14295 return error;
14296 }
14297
14298-static void find_start_end(unsigned long flags, unsigned long *begin,
14299- unsigned long *end)
14300+static void find_start_end(struct mm_struct *mm, unsigned long flags,
14301+ unsigned long *begin, unsigned long *end)
14302 {
14303 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
14304 unsigned long new_begin;
ae4e228f 14305@@ -52,7 +52,7 @@ static void find_start_end(unsigned long
58c5fc13
MT
14306 *begin = new_begin;
14307 }
14308 } else {
14309- *begin = TASK_UNMAPPED_BASE;
14310+ *begin = mm->mmap_base;
14311 *end = TASK_SIZE;
14312 }
14313 }
57199397 14314@@ -69,16 +69,19 @@ arch_get_unmapped_area(struct file *filp
58c5fc13
MT
14315 if (flags & MAP_FIXED)
14316 return addr;
14317
14318- find_start_end(flags, &begin, &end);
14319+ find_start_end(mm, flags, &begin, &end);
14320
14321 if (len > end)
14322 return -ENOMEM;
14323
14324+#ifdef CONFIG_PAX_RANDMMAP
14325+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
14326+#endif
14327+
14328 if (addr) {
14329 addr = PAGE_ALIGN(addr);
14330 vma = find_vma(mm, addr);
57199397
MT
14331- if (end - len >= addr &&
14332- (!vma || addr + len <= vma->vm_start))
14333+ if (end - len >= addr && check_heap_stack_gap(vma, addr, len))
14334 return addr;
14335 }
14336 if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
14337@@ -106,7 +109,7 @@ full_search:
14338 }
14339 return -ENOMEM;
14340 }
14341- if (!vma || addr + len <= vma->vm_start) {
14342+ if (check_heap_stack_gap(vma, addr, len)) {
14343 /*
14344 * Remember the place where we stopped the search:
14345 */
14346@@ -128,7 +131,7 @@ arch_get_unmapped_area_topdown(struct fi
58c5fc13
MT
14347 {
14348 struct vm_area_struct *vma;
14349 struct mm_struct *mm = current->mm;
14350- unsigned long addr = addr0;
14351+ unsigned long base = mm->mmap_base, addr = addr0;
14352
14353 /* requested length too big for entire address space */
14354 if (len > TASK_SIZE)
16454cff 14355@@ -141,13 +144,18 @@ arch_get_unmapped_area_topdown(struct fi
58c5fc13
MT
14356 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
14357 goto bottomup;
14358
14359+#ifdef CONFIG_PAX_RANDMMAP
14360+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
14361+#endif
14362+
14363 /* requesting a specific address */
14364 if (addr) {
14365 addr = PAGE_ALIGN(addr);
16454cff 14366- vma = find_vma(mm, addr);
57199397
MT
14367- if (TASK_SIZE - len >= addr &&
14368- (!vma || addr + len <= vma->vm_start))
16454cff
MT
14369- return addr;
14370+ if (TASK_SIZE - len >= addr) {
14371+ vma = find_vma(mm, addr);
14372+ if (check_heap_stack_gap(vma, addr, len))
14373+ return addr;
14374+ }
57199397
MT
14375 }
14376
16454cff
MT
14377 /* check if free_area_cache is useful for us */
14378@@ -162,7 +170,7 @@ arch_get_unmapped_area_topdown(struct fi
57199397
MT
14379 /* make sure it can fit in the remaining address space */
14380 if (addr > len) {
14381 vma = find_vma(mm, addr-len);
14382- if (!vma || addr <= vma->vm_start)
14383+ if (check_heap_stack_gap(vma, addr - len, len))
14384 /* remember the address as a hint for next time */
14385 return mm->free_area_cache = addr-len;
14386 }
16454cff 14387@@ -179,7 +187,7 @@ arch_get_unmapped_area_topdown(struct fi
57199397
MT
14388 * return with success:
14389 */
14390 vma = find_vma(mm, addr);
14391- if (!vma || addr+len <= vma->vm_start)
14392+ if (check_heap_stack_gap(vma, addr, len))
14393 /* remember the address as a hint for next time */
14394 return mm->free_area_cache = addr;
14395
16454cff
MT
14396@@ -188,8 +196,8 @@ arch_get_unmapped_area_topdown(struct fi
14397 mm->cached_hole_size = vma->vm_start - addr;
14398
14399 /* try just below the current vma->vm_start */
14400- addr = vma->vm_start-len;
14401- } while (len < vma->vm_start);
14402+ addr = skip_heap_stack_gap(vma, len);
14403+ } while (!IS_ERR_VALUE(addr));
14404
14405 bottomup:
14406 /*
14407@@ -198,13 +206,21 @@ bottomup:
58c5fc13
MT
14408 * can happen with large stack limits and large mmap()
14409 * allocations.
14410 */
14411+ mm->mmap_base = TASK_UNMAPPED_BASE;
14412+
14413+#ifdef CONFIG_PAX_RANDMMAP
14414+ if (mm->pax_flags & MF_PAX_RANDMMAP)
14415+ mm->mmap_base += mm->delta_mmap;
14416+#endif
14417+
14418+ mm->free_area_cache = mm->mmap_base;
14419 mm->cached_hole_size = ~0UL;
14420- mm->free_area_cache = TASK_UNMAPPED_BASE;
14421 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
14422 /*
14423 * Restore the topdown base:
14424 */
14425- mm->free_area_cache = mm->mmap_base;
14426+ mm->mmap_base = base;
14427+ mm->free_area_cache = base;
14428 mm->cached_hole_size = ~0UL;
14429
14430 return addr;
16454cff
MT
14431diff -urNp linux-2.6.38.1/arch/x86/kernel/time.c linux-2.6.38.1/arch/x86/kernel/time.c
14432--- linux-2.6.38.1/arch/x86/kernel/time.c 2011-03-14 21:20:32.000000000 -0400
14433+++ linux-2.6.38.1/arch/x86/kernel/time.c 2011-03-21 18:31:35.000000000 -0400
14434@@ -22,17 +22,13 @@
14435 #include <asm/hpet.h>
14436 #include <asm/time.h>
ae4e228f
MT
14437
14438-#ifdef CONFIG_X86_64
14439-volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
14440-#endif
14441-
14442 unsigned long profile_pc(struct pt_regs *regs)
14443 {
58c5fc13
MT
14444 unsigned long pc = instruction_pointer(regs);
14445
58c5fc13
MT
14446- if (!user_mode_vm(regs) && in_lock_functions(pc)) {
14447+ if (!user_mode(regs) && in_lock_functions(pc)) {
14448 #ifdef CONFIG_FRAME_POINTER
14449- return *(unsigned long *)(regs->bp + sizeof(long));
14450+ return ktla_ktva(*(unsigned long *)(regs->bp + sizeof(long)));
14451 #else
ae4e228f
MT
14452 unsigned long *sp =
14453 (unsigned long *)kernel_stack_pointer(regs);
16454cff 14454@@ -41,11 +37,17 @@ unsigned long profile_pc(struct pt_regs
ae4e228f
MT
14455 * or above a saved flags. Eflags has bits 22-31 zero,
14456 * kernel addresses don't.
14457 */
58c5fc13
MT
14458+
14459+#ifdef CONFIG_PAX_KERNEXEC
14460+ return ktla_ktva(sp[0]);
14461+#else
14462 if (sp[0] >> 22)
14463 return sp[0];
14464 if (sp[1] >> 22)
14465 return sp[1];
14466 #endif
14467+
14468+#endif
14469 }
58c5fc13
MT
14470 return pc;
14471 }
16454cff
MT
14472diff -urNp linux-2.6.38.1/arch/x86/kernel/tls.c linux-2.6.38.1/arch/x86/kernel/tls.c
14473--- linux-2.6.38.1/arch/x86/kernel/tls.c 2011-03-14 21:20:32.000000000 -0400
14474+++ linux-2.6.38.1/arch/x86/kernel/tls.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
14475@@ -85,6 +85,11 @@ int do_set_thread_area(struct task_struc
14476 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
14477 return -EINVAL;
14478
14479+#ifdef CONFIG_PAX_SEGMEXEC
14480+ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
14481+ return -EINVAL;
14482+#endif
14483+
14484 set_tls_desc(p, idx, &info, 1);
14485
14486 return 0;
16454cff
MT
14487diff -urNp linux-2.6.38.1/arch/x86/kernel/trampoline_32.S linux-2.6.38.1/arch/x86/kernel/trampoline_32.S
14488--- linux-2.6.38.1/arch/x86/kernel/trampoline_32.S 2011-03-14 21:20:32.000000000 -0400
14489+++ linux-2.6.38.1/arch/x86/kernel/trampoline_32.S 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
14490@@ -32,6 +32,12 @@
14491 #include <asm/segment.h>
14492 #include <asm/page_types.h>
14493
14494+#ifdef CONFIG_PAX_KERNEXEC
14495+#define ta(X) (X)
14496+#else
14497+#define ta(X) ((X) - __PAGE_OFFSET)
14498+#endif
14499+
14500 /* We can free up trampoline after bootup if cpu hotplug is not supported. */
14501 __CPUINITRODATA
14502 .code16
14503@@ -60,7 +66,7 @@ r_base = .
14504 inc %ax # protected mode (PE) bit
14505 lmsw %ax # into protected mode
14506 # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S
14507- ljmpl $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET)
14508+ ljmpl $__BOOT_CS, $ta(startup_32_smp)
14509
14510 # These need to be in the same 64K segment as the above;
14511 # hence we don't use the boot_gdt_descr defined in head.S
16454cff
MT
14512diff -urNp linux-2.6.38.1/arch/x86/kernel/trampoline_64.S linux-2.6.38.1/arch/x86/kernel/trampoline_64.S
14513--- linux-2.6.38.1/arch/x86/kernel/trampoline_64.S 2011-03-14 21:20:32.000000000 -0400
14514+++ linux-2.6.38.1/arch/x86/kernel/trampoline_64.S 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
14515@@ -91,7 +91,7 @@ startup_32:
14516 movl $__KERNEL_DS, %eax # Initialize the %ds segment register
14517 movl %eax, %ds
14518
14519- movl $X86_CR4_PAE, %eax
14520+ movl $(X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE), %eax
14521 movl %eax, %cr4 # Enable PAE mode
14522
14523 # Setup trampoline 4 level pagetables
14524@@ -138,7 +138,7 @@ tidt:
14525 # so the kernel can live anywhere
14526 .balign 4
14527 tgdt:
14528- .short tgdt_end - tgdt # gdt limit
14529+ .short tgdt_end - tgdt - 1 # gdt limit
14530 .long tgdt - r_base
14531 .short 0
14532 .quad 0x00cf9b000000ffff # __KERNEL32_CS
16454cff
MT
14533diff -urNp linux-2.6.38.1/arch/x86/kernel/traps.c linux-2.6.38.1/arch/x86/kernel/traps.c
14534--- linux-2.6.38.1/arch/x86/kernel/traps.c 2011-03-14 21:20:32.000000000 -0400
14535+++ linux-2.6.38.1/arch/x86/kernel/traps.c 2011-03-21 18:31:35.000000000 -0400
57199397 14536@@ -70,12 +70,6 @@ asmlinkage int system_call(void);
58c5fc13
MT
14537
14538 /* Do we ignore FPU interrupts ? */
14539 char ignore_fpu_irq;
14540-
14541-/*
14542- * The IDT has to be page-aligned to simplify the Pentium
ae4e228f 14543- * F0 0F bug workaround.
58c5fc13 14544- */
ae4e228f 14545-gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, };
58c5fc13
MT
14546 #endif
14547
14548 DECLARE_BITMAP(used_vectors, NR_VECTORS);
16454cff 14549@@ -117,13 +111,13 @@ static inline void preempt_conditional_c
58c5fc13 14550 }
ae4e228f
MT
14551
14552 static void __kprobes
14553-do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
14554+do_trap(int trapnr, int signr, const char *str, struct pt_regs *regs,
14555 long error_code, siginfo_t *info)
14556 {
58c5fc13
MT
14557 struct task_struct *tsk = current;
14558
14559 #ifdef CONFIG_X86_32
14560- if (regs->flags & X86_VM_MASK) {
14561+ if (v8086_mode(regs)) {
14562 /*
14563 * traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
14564 * On nmi (interrupt 2), do_trap should not be called.
16454cff 14565@@ -134,7 +128,7 @@ do_trap(int trapnr, int signr, char *str
58c5fc13
MT
14566 }
14567 #endif
14568
14569- if (!user_mode(regs))
14570+ if (!user_mode_novm(regs))
14571 goto kernel_trap;
14572
14573 #ifdef CONFIG_X86_32
16454cff 14574@@ -157,7 +151,7 @@ trap_signal:
58c5fc13
MT
14575 printk_ratelimit()) {
14576 printk(KERN_INFO
14577 "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
14578- tsk->comm, tsk->pid, str,
14579+ tsk->comm, task_pid_nr(tsk), str,
14580 regs->ip, regs->sp, error_code);
14581 print_vma_addr(" in ", regs->ip);
14582 printk("\n");
16454cff 14583@@ -174,8 +168,20 @@ kernel_trap:
ae4e228f
MT
14584 if (!fixup_exception(regs)) {
14585 tsk->thread.error_code = error_code;
58c5fc13 14586 tsk->thread.trap_no = trapnr;
ae4e228f
MT
14587+
14588+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
14589+ if (trapnr == 12 && ((regs->cs & 0xFFFF) == __KERNEL_CS || (regs->cs & 0xFFFF) == __KERNEXEC_KERNEL_CS))
14590+ str = "PAX: suspicious stack segment fault";
14591+#endif
14592+
58c5fc13
MT
14593 die(str, regs, error_code);
14594 }
14595+
14596+#ifdef CONFIG_PAX_REFCOUNT
14597+ if (trapnr == 4)
14598+ pax_report_refcount_overflow(regs);
14599+#endif
14600+
14601 return;
14602
14603 #ifdef CONFIG_X86_32
16454cff 14604@@ -264,14 +270,30 @@ do_general_protection(struct pt_regs *re
58c5fc13
MT
14605 conditional_sti(regs);
14606
14607 #ifdef CONFIG_X86_32
14608- if (regs->flags & X86_VM_MASK)
14609+ if (v8086_mode(regs))
14610 goto gp_in_vm86;
14611 #endif
14612
14613 tsk = current;
14614- if (!user_mode(regs))
14615+ if (!user_mode_novm(regs))
14616 goto gp_in_kernel;
14617
14618+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
ae4e228f 14619+ if (!(__supported_pte_mask & _PAGE_NX) && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
58c5fc13
MT
14620+ struct mm_struct *mm = tsk->mm;
14621+ unsigned long limit;
14622+
14623+ down_write(&mm->mmap_sem);
14624+ limit = mm->context.user_cs_limit;
14625+ if (limit < TASK_SIZE) {
14626+ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
14627+ up_write(&mm->mmap_sem);
14628+ return;
14629+ }
14630+ up_write(&mm->mmap_sem);
14631+ }
14632+#endif
14633+
14634 tsk->thread.error_code = error_code;
14635 tsk->thread.trap_no = 13;
14636
16454cff 14637@@ -304,6 +326,13 @@ gp_in_kernel:
58c5fc13
MT
14638 if (notify_die(DIE_GPF, "general protection fault", regs,
14639 error_code, 13, SIGSEGV) == NOTIFY_STOP)
14640 return;
14641+
14642+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
ae4e228f 14643+ if ((regs->cs & 0xFFFF) == __KERNEL_CS || (regs->cs & 0xFFFF) == __KERNEXEC_KERNEL_CS)
58c5fc13
MT
14644+ die("PAX: suspicious general protection fault", regs, error_code);
14645+ else
14646+#endif
14647+
14648 die("general protection fault", regs, error_code);
14649 }
14650
16454cff 14651@@ -569,7 +598,7 @@ dotraplinkage void __kprobes do_debug(st
ae4e228f
MT
14652 /* It's safe to allow irq's after DR6 has been saved */
14653 preempt_conditional_sti(regs);
58c5fc13 14654
ae4e228f
MT
14655- if (regs->flags & X86_VM_MASK) {
14656+ if (v8086_mode(regs)) {
14657 handle_vm86_trap((struct kernel_vm86_regs *) regs,
14658 error_code, 1);
bc901d79 14659 preempt_conditional_cli(regs);
16454cff 14660@@ -583,7 +612,7 @@ dotraplinkage void __kprobes do_debug(st
ae4e228f
MT
14661 * We already checked v86 mode above, so we can check for kernel mode
14662 * by just checking the CPL of CS.
58c5fc13 14663 */
ae4e228f
MT
14664- if ((dr6 & DR_STEP) && !user_mode(regs)) {
14665+ if ((dr6 & DR_STEP) && !user_mode_novm(regs)) {
14666 tsk->thread.debugreg6 &= ~DR_STEP;
14667 set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
14668 regs->flags &= ~X86_EFLAGS_TF;
16454cff 14669@@ -612,7 +641,7 @@ void math_error(struct pt_regs *regs, in
58c5fc13 14670 return;
57199397
MT
14671 conditional_sti(regs);
14672
14673- if (!user_mode_vm(regs))
14674+ if (!user_mode(regs))
14675 {
14676 if (!fixup_exception(regs)) {
14677 task->thread.error_code = error_code;
16454cff
MT
14678diff -urNp linux-2.6.38.1/arch/x86/kernel/tsc.c linux-2.6.38.1/arch/x86/kernel/tsc.c
14679--- linux-2.6.38.1/arch/x86/kernel/tsc.c 2011-03-14 21:20:32.000000000 -0400
14680+++ linux-2.6.38.1/arch/x86/kernel/tsc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 14681@@ -837,7 +837,7 @@ static struct dmi_system_id __initdata b
58c5fc13
MT
14682 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
14683 },
14684 },
14685- {}
14686+ { NULL, NULL, {{0, {0}}}, NULL}
14687 };
14688
14689 static void __init check_system_tsc_reliable(void)
16454cff
MT
14690diff -urNp linux-2.6.38.1/arch/x86/kernel/vm86_32.c linux-2.6.38.1/arch/x86/kernel/vm86_32.c
14691--- linux-2.6.38.1/arch/x86/kernel/vm86_32.c 2011-03-14 21:20:32.000000000 -0400
14692+++ linux-2.6.38.1/arch/x86/kernel/vm86_32.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
14693@@ -41,6 +41,7 @@
14694 #include <linux/ptrace.h>
14695 #include <linux/audit.h>
14696 #include <linux/stddef.h>
14697+#include <linux/grsecurity.h>
14698
14699 #include <asm/uaccess.h>
14700 #include <asm/io.h>
14701@@ -148,7 +149,7 @@ struct pt_regs *save_v86_state(struct ke
58c5fc13
MT
14702 do_exit(SIGSEGV);
14703 }
14704
14705- tss = &per_cpu(init_tss, get_cpu());
14706+ tss = init_tss + get_cpu();
14707 current->thread.sp0 = current->thread.saved_sp0;
14708 current->thread.sysenter_cs = __KERNEL_CS;
14709 load_sp0(tss, &current->thread);
16454cff 14710@@ -208,6 +209,13 @@ int sys_vm86old(struct vm86_struct __use
ae4e228f
MT
14711 struct task_struct *tsk;
14712 int tmp, ret = -EPERM;
14713
14714+#ifdef CONFIG_GRKERNSEC_VM86
14715+ if (!capable(CAP_SYS_RAWIO)) {
14716+ gr_handle_vm86();
14717+ goto out;
14718+ }
14719+#endif
14720+
14721 tsk = current;
14722 if (tsk->thread.saved_sp0)
14723 goto out;
16454cff 14724@@ -238,6 +246,14 @@ int sys_vm86(unsigned long cmd, unsigned
ae4e228f
MT
14725 int tmp, ret;
14726 struct vm86plus_struct __user *v86;
14727
14728+#ifdef CONFIG_GRKERNSEC_VM86
14729+ if (!capable(CAP_SYS_RAWIO)) {
14730+ gr_handle_vm86();
14731+ ret = -EPERM;
14732+ goto out;
14733+ }
14734+#endif
14735+
14736 tsk = current;
14737 switch (cmd) {
14738 case VM86_REQUEST_IRQ:
16454cff 14739@@ -324,7 +340,7 @@ static void do_sys_vm86(struct kernel_vm
58c5fc13
MT
14740 tsk->thread.saved_fs = info->regs32->fs;
14741 tsk->thread.saved_gs = get_user_gs(info->regs32);
14742
14743- tss = &per_cpu(init_tss, get_cpu());
14744+ tss = init_tss + get_cpu();
14745 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
14746 if (cpu_has_sep)
14747 tsk->thread.sysenter_cs = 0;
16454cff 14748@@ -529,7 +545,7 @@ static void do_int(struct kernel_vm86_re
ae4e228f
MT
14749 goto cannot_handle;
14750 if (i == 0x21 && is_revectored(AH(regs), &KVM86->int21_revectored))
14751 goto cannot_handle;
14752- intr_ptr = (unsigned long __user *) (i << 2);
14753+ intr_ptr = (__force unsigned long __user *) (i << 2);
14754 if (get_user(segoffs, intr_ptr))
14755 goto cannot_handle;
14756 if ((segoffs >> 16) == BIOSSEG)
16454cff
MT
14757diff -urNp linux-2.6.38.1/arch/x86/kernel/vmlinux.lds.S linux-2.6.38.1/arch/x86/kernel/vmlinux.lds.S
14758--- linux-2.6.38.1/arch/x86/kernel/vmlinux.lds.S 2011-03-14 21:20:32.000000000 -0400
14759+++ linux-2.6.38.1/arch/x86/kernel/vmlinux.lds.S 2011-03-21 18:31:35.000000000 -0400
57199397 14760@@ -26,6 +26,13 @@
58c5fc13
MT
14761 #include <asm/page_types.h>
14762 #include <asm/cache.h>
14763 #include <asm/boot.h>
14764+#include <asm/segment.h>
14765+
58c5fc13
MT
14766+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
14767+#define __KERNEL_TEXT_OFFSET (LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR)
14768+#else
14769+#define __KERNEL_TEXT_OFFSET 0
14770+#endif
14771
14772 #undef i386 /* in case the preprocessor is a 32bit one */
14773
bc901d79 14774@@ -34,11 +41,9 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONF
58c5fc13
MT
14775 #ifdef CONFIG_X86_32
14776 OUTPUT_ARCH(i386)
14777 ENTRY(phys_startup_32)
14778-jiffies = jiffies_64;
14779 #else
14780 OUTPUT_ARCH(i386:x86-64)
14781 ENTRY(phys_startup_64)
14782-jiffies_64 = jiffies;
14783 #endif
14784
ae4e228f 14785 #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
bc901d79 14786@@ -69,31 +74,46 @@ jiffies_64 = jiffies;
ae4e228f 14787
58c5fc13
MT
14788 PHDRS {
14789 text PT_LOAD FLAGS(5); /* R_E */
57199397
MT
14790+#ifdef CONFIG_X86_32
14791+ module PT_LOAD FLAGS(5); /* R_E */
14792+#endif
ae4e228f
MT
14793+#ifdef CONFIG_XEN
14794+ rodata PT_LOAD FLAGS(5); /* R_E */
14795+#else
58c5fc13 14796+ rodata PT_LOAD FLAGS(4); /* R__ */
ae4e228f 14797+#endif
16454cff 14798 data PT_LOAD FLAGS(6); /* RW_ */
58c5fc13 14799 #ifdef CONFIG_X86_64
ae4e228f 14800 user PT_LOAD FLAGS(5); /* R_E */
58c5fc13
MT
14801+#endif
14802+ init.begin PT_LOAD FLAGS(6); /* RW_ */
14803 #ifdef CONFIG_SMP
ae4e228f 14804 percpu PT_LOAD FLAGS(6); /* RW_ */
58c5fc13
MT
14805 #endif
14806+ text.init PT_LOAD FLAGS(5); /* R_E */
14807+ text.exit PT_LOAD FLAGS(5); /* R_E */
14808 init PT_LOAD FLAGS(7); /* RWE */
14809-#endif
14810 note PT_NOTE FLAGS(0); /* ___ */
14811 }
14812
14813 SECTIONS
14814 {
14815 #ifdef CONFIG_X86_32
14816- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
14817- phys_startup_32 = startup_32 - LOAD_OFFSET;
14818+ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
14819 #else
14820- . = __START_KERNEL;
14821- phys_startup_64 = startup_64 - LOAD_OFFSET;
14822+ . = __START_KERNEL;
14823 #endif
14824
14825 /* Text and read-only data */
ae4e228f
MT
14826- .text : AT(ADDR(.text) - LOAD_OFFSET) {
14827- _text = .;
58c5fc13 14828+ .text (. - __KERNEL_TEXT_OFFSET): AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
ae4e228f 14829 /* bootstrapping code */
58c5fc13
MT
14830+#ifdef CONFIG_X86_32
14831+ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
14832+#else
14833+ phys_startup_64 = startup_64 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
14834+#endif
14835+ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
ae4e228f
MT
14836+ _text = .;
14837 HEAD_TEXT
58c5fc13 14838 #ifdef CONFIG_X86_32
58c5fc13 14839 . = ALIGN(PAGE_SIZE);
bc901d79 14840@@ -108,13 +128,47 @@ SECTIONS
ae4e228f
MT
14841 IRQENTRY_TEXT
14842 *(.fixup)
14843 *(.gnu.warning)
14844- /* End of text section */
14845- _etext = .;
58c5fc13
MT
14846 } :text = 0x9090
14847
14848- NOTES :text :note
14849+ . += __KERNEL_TEXT_OFFSET;
df50ba0c 14850+
58c5fc13
MT
14851+#ifdef CONFIG_X86_32
14852+ . = ALIGN(PAGE_SIZE);
58c5fc13 14853+ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
ae4e228f
MT
14854+
14855+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
58c5fc13
MT
14856+ MODULES_EXEC_VADDR = .;
14857+ BYTE(0)
ae4e228f 14858+ . += (CONFIG_PAX_KERNEXEC_MODULE_TEXT * 1024 * 1024);
57199397 14859+ . = ALIGN(HPAGE_SIZE);
58c5fc13 14860+ MODULES_EXEC_END = . - 1;
58c5fc13 14861+#endif
ae4e228f
MT
14862+
14863+ } :module
58c5fc13
MT
14864+#endif
14865+
57199397 14866+ .text.end : AT(ADDR(.text.end) - LOAD_OFFSET) {
ae4e228f
MT
14867+ /* End of text section */
14868+ _etext = . - __KERNEL_TEXT_OFFSET;
57199397 14869+ }
bc901d79
MT
14870
14871- EXCEPTION_TABLE(16) :text = 0x9090
57199397
MT
14872+#ifdef CONFIG_X86_32
14873+ . = ALIGN(PAGE_SIZE);
14874+ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
14875+ *(.idt)
14876+ . = ALIGN(PAGE_SIZE);
14877+ *(.empty_zero_page)
bc901d79
MT
14878+ *(.initial_pg_fixmap)
14879+ *(.initial_pg_pmd)
14880+ *(.initial_page_table)
57199397
MT
14881+ *(.swapper_pg_dir)
14882+ } :rodata
14883+#endif
14884+
14885+ . = ALIGN(PAGE_SIZE);
14886+ NOTES :rodata :note
bc901d79 14887+
57199397
MT
14888+ EXCEPTION_TABLE(16) :rodata
14889
16454cff
MT
14890 #if defined(CONFIG_DEBUG_RODATA)
14891 /* .text should occupy whole number of pages */
14892@@ -126,16 +180,20 @@ SECTIONS
57199397
MT
14893
14894 /* Data */
14895 .data : AT(ADDR(.data) - LOAD_OFFSET) {
58c5fc13
MT
14896+
14897+#ifdef CONFIG_PAX_KERNEXEC
bc901d79 14898+ . = ALIGN(HPAGE_SIZE);
58c5fc13 14899+#else
bc901d79 14900+ . = ALIGN(PAGE_SIZE);
58c5fc13
MT
14901+#endif
14902+
14903 /* Start of data section */
14904 _sdata = .;
14905
14906 /* init_task */
14907 INIT_TASK_DATA(THREAD_SIZE)
14908
14909-#ifdef CONFIG_X86_32
14910- /* 32 bit has nosave before _edata */
14911 NOSAVE_DATA
14912-#endif
14913
14914 PAGE_ALIGNED_DATA(PAGE_SIZE)
ae4e228f 14915
16454cff 14916@@ -144,6 +202,8 @@ SECTIONS
bc901d79
MT
14917 DATA_DATA
14918 CONSTRUCTORS
14919
14920+ jiffies = jiffies_64;
14921+
14922 /* rarely changed data like cpu maps */
14923 READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES)
14924
16454cff 14925@@ -198,12 +258,6 @@ SECTIONS
58c5fc13
MT
14926 }
14927 vgetcpu_mode = VVIRT(.vgetcpu_mode);
14928
ae4e228f 14929- . = ALIGN(L1_CACHE_BYTES);
58c5fc13
MT
14930- .jiffies : AT(VLOAD(.jiffies)) {
14931- *(.jiffies)
14932- }
14933- jiffies = VVIRT(.jiffies);
14934-
14935 .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
14936 *(.vsyscall_3)
14937 }
16454cff 14938@@ -219,12 +273,19 @@ SECTIONS
58c5fc13
MT
14939 #endif /* CONFIG_X86_64 */
14940
14941 /* Init code and data - will be freed after init */
14942- . = ALIGN(PAGE_SIZE);
14943 .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
14944+ BYTE(0)
14945+
14946+#ifdef CONFIG_PAX_KERNEXEC
57199397 14947+ . = ALIGN(HPAGE_SIZE);
58c5fc13
MT
14948+#else
14949+ . = ALIGN(PAGE_SIZE);
14950+#endif
14951+
14952 __init_begin = .; /* paired with __init_end */
14953- }
14954+ } :init.begin
14955
14956-#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
14957+#ifdef CONFIG_SMP
14958 /*
14959 * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
14960 * output PHDR, so the next output section - .init.text - should
16454cff 14961@@ -233,12 +294,27 @@ SECTIONS
58c5fc13
MT
14962 PERCPU_VADDR(0, :percpu)
14963 #endif
14964
ae4e228f 14965- INIT_TEXT_SECTION(PAGE_SIZE)
58c5fc13
MT
14966-#ifdef CONFIG_X86_64
14967- :init
14968-#endif
ae4e228f
MT
14969+ . = ALIGN(PAGE_SIZE);
14970+ init_begin = .;
14971+ .init.text (. - __KERNEL_TEXT_OFFSET): AT(init_begin - LOAD_OFFSET) {
14972+ VMLINUX_SYMBOL(_sinittext) = .;
14973+ INIT_TEXT
14974+ VMLINUX_SYMBOL(_einittext) = .;
14975+ . = ALIGN(PAGE_SIZE);
58c5fc13 14976+ } :text.init
bc901d79
MT
14977
14978- INIT_DATA_SECTION(16)
58c5fc13
MT
14979+ /*
14980+ * .exit.text is discard at runtime, not link time, to deal with
14981+ * references from .altinstructions and .eh_frame
14982+ */
57199397 14983+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
58c5fc13
MT
14984+ EXIT_TEXT
14985+ . = ALIGN(16);
14986+ } :text.exit
14987+ . = init_begin + SIZEOF(.init.text) + SIZEOF(.exit.text);
bc901d79 14988+
ae4e228f
MT
14989+ . = ALIGN(PAGE_SIZE);
14990+ INIT_DATA_SECTION(16) :init
58c5fc13 14991
ae4e228f
MT
14992 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
14993 __x86_cpu_dev_start = .;
16454cff 14994@@ -292,19 +368,12 @@ SECTIONS
bc901d79 14995 __iommu_table_end = .;
58c5fc13 14996 }
bc901d79 14997 . = ALIGN(8);
58c5fc13
MT
14998- /*
14999- * .exit.text is discard at runtime, not link time, to deal with
15000- * references from .altinstructions and .eh_frame
15001- */
15002- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
15003- EXIT_TEXT
15004- }
bc901d79 15005
58c5fc13
MT
15006 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
15007 EXIT_DATA
15008 }
58c5fc13
MT
15009
15010-#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
15011+#ifndef CONFIG_SMP
bc901d79 15012 PERCPU(THREAD_SIZE)
58c5fc13
MT
15013 #endif
15014
16454cff 15015@@ -323,16 +392,10 @@ SECTIONS
df50ba0c
MT
15016 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
15017 __smp_locks = .;
15018 *(.smp_locks)
15019- . = ALIGN(PAGE_SIZE);
15020 __smp_locks_end = .;
15021+ . = ALIGN(PAGE_SIZE);
58c5fc13
MT
15022 }
15023
15024-#ifdef CONFIG_X86_64
15025- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
15026- NOSAVE_DATA
15027- }
15028-#endif
15029-
15030 /* BSS */
15031 . = ALIGN(PAGE_SIZE);
15032 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
16454cff 15033@@ -348,6 +411,7 @@ SECTIONS
58c5fc13
MT
15034 __brk_base = .;
15035 . += 64 * 1024; /* 64k alignment slop space */
15036 *(.brk_reservation) /* areas brk users have reserved */
57199397 15037+ . = ALIGN(HPAGE_SIZE);
58c5fc13
MT
15038 __brk_limit = .;
15039 }
15040
16454cff 15041@@ -374,13 +438,12 @@ SECTIONS
58c5fc13
MT
15042 * for the boot processor.
15043 */
df50ba0c 15044 #define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load
58c5fc13
MT
15045-INIT_PER_CPU(gdt_page);
15046 INIT_PER_CPU(irq_stack_union);
15047
15048 /*
15049 * Build-time check on the image size:
15050 */
15051-. = ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
15052+. = ASSERT((_end - _text - __KERNEL_TEXT_OFFSET <= KERNEL_IMAGE_SIZE),
15053 "kernel image bigger than KERNEL_IMAGE_SIZE");
15054
15055 #ifdef CONFIG_SMP
16454cff
MT
15056diff -urNp linux-2.6.38.1/arch/x86/kernel/vsyscall_64.c linux-2.6.38.1/arch/x86/kernel/vsyscall_64.c
15057--- linux-2.6.38.1/arch/x86/kernel/vsyscall_64.c 2011-03-14 21:20:32.000000000 -0400
15058+++ linux-2.6.38.1/arch/x86/kernel/vsyscall_64.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 15059@@ -80,6 +80,7 @@ void update_vsyscall(struct timespec *wa
58c5fc13
MT
15060
15061 write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags);
15062 /* copy vsyscall data */
15063+ strlcpy(vsyscall_gtod_data.clock.name, clock->name, sizeof vsyscall_gtod_data.clock.name);
15064 vsyscall_gtod_data.clock.vread = clock->vread;
15065 vsyscall_gtod_data.clock.cycle_last = clock->cycle_last;
15066 vsyscall_gtod_data.clock.mask = clock->mask;
6892158b 15067@@ -208,7 +209,7 @@ vgetcpu(unsigned *cpu, unsigned *node, s
58c5fc13
MT
15068 We do this here because otherwise user space would do it on
15069 its own in a likely inferior way (no access to jiffies).
15070 If you don't like it pass NULL. */
15071- if (tcache && tcache->blob[0] == (j = __jiffies)) {
15072+ if (tcache && tcache->blob[0] == (j = jiffies)) {
15073 p = tcache->blob[1];
15074 } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
15075 /* Load per CPU data from RDTSCP */
16454cff
MT
15076diff -urNp linux-2.6.38.1/arch/x86/kernel/x8664_ksyms_64.c linux-2.6.38.1/arch/x86/kernel/x8664_ksyms_64.c
15077--- linux-2.6.38.1/arch/x86/kernel/x8664_ksyms_64.c 2011-03-14 21:20:32.000000000 -0400
15078+++ linux-2.6.38.1/arch/x86/kernel/x8664_ksyms_64.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
15079@@ -29,8 +29,6 @@ EXPORT_SYMBOL(__put_user_8);
15080 EXPORT_SYMBOL(copy_user_generic_string);
15081 EXPORT_SYMBOL(copy_user_generic_unrolled);
58c5fc13 15082 EXPORT_SYMBOL(__copy_user_nocache);
ae4e228f
MT
15083-EXPORT_SYMBOL(_copy_from_user);
15084-EXPORT_SYMBOL(_copy_to_user);
58c5fc13
MT
15085
15086 EXPORT_SYMBOL(copy_page);
ae4e228f 15087 EXPORT_SYMBOL(clear_page);
16454cff
MT
15088diff -urNp linux-2.6.38.1/arch/x86/kernel/xsave.c linux-2.6.38.1/arch/x86/kernel/xsave.c
15089--- linux-2.6.38.1/arch/x86/kernel/xsave.c 2011-03-14 21:20:32.000000000 -0400
15090+++ linux-2.6.38.1/arch/x86/kernel/xsave.c 2011-03-21 18:31:35.000000000 -0400
6892158b 15091@@ -130,7 +130,7 @@ int check_for_xstate(struct i387_fxsave_
ae4e228f 15092 fx_sw_user->xstate_size > fx_sw_user->extended_size)
6892158b 15093 return -EINVAL;
ae4e228f
MT
15094
15095- err = __get_user(magic2, (__u32 *) (((void *)fpstate) +
15096+ err = __get_user(magic2, (__u32 __user *) (((void __user *)fpstate) +
15097 fx_sw_user->extended_size -
15098 FP_XSTATE_MAGIC2_SIZE));
6892158b
MT
15099 if (err)
15100@@ -267,7 +267,7 @@ fx_only:
ae4e228f
MT
15101 * the other extended state.
15102 */
15103 xrstor_state(init_xstate_buf, pcntxt_mask & ~XSTATE_FPSSE);
15104- return fxrstor_checking((__force struct i387_fxsave_struct *)buf);
15105+ return fxrstor_checking((struct i387_fxsave_struct __user *)buf);
15106 }
15107
15108 /*
6892158b 15109@@ -299,7 +299,7 @@ int restore_i387_xstate(void __user *buf
57199397 15110 if (use_xsave())
ae4e228f
MT
15111 err = restore_user_xstate(buf);
15112 else
15113- err = fxrstor_checking((__force struct i387_fxsave_struct *)
15114+ err = fxrstor_checking((struct i387_fxsave_struct __user *)
15115 buf);
15116 if (unlikely(err)) {
15117 /*
16454cff
MT
15118diff -urNp linux-2.6.38.1/arch/x86/kvm/emulate.c linux-2.6.38.1/arch/x86/kvm/emulate.c
15119--- linux-2.6.38.1/arch/x86/kvm/emulate.c 2011-03-14 21:20:32.000000000 -0400
15120+++ linux-2.6.38.1/arch/x86/kvm/emulate.c 2011-03-21 18:31:35.000000000 -0400
15121@@ -88,7 +88,7 @@
df50ba0c
MT
15122 #define Src2ImmByte (2<<29)
15123 #define Src2One (3<<29)
bc901d79 15124 #define Src2Imm (4<<29)
57199397 15125-#define Src2Mask (7<<29)
df50ba0c
MT
15126+#define Src2Mask (7U<<29)
15127
bc901d79
MT
15128 #define X2(x...) x, x
15129 #define X3(x...) X2(x), x
16454cff 15130@@ -189,6 +189,7 @@ struct group_dual {
ae4e228f 15131
bc901d79 15132 #define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix, _dsttype) \
ae4e228f
MT
15133 do { \
15134+ unsigned long _tmp; \
15135 __asm__ __volatile__ ( \
15136 _PRE_EFLAGS("0", "4", "2") \
15137 _op _suffix " %"_x"3,%1; " \
16454cff 15138@@ -202,8 +203,6 @@ struct group_dual {
ae4e228f
MT
15139 /* Raw emulation: instruction has two explicit operands. */
15140 #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
15141 do { \
15142- unsigned long _tmp; \
15143- \
15144 switch ((_dst).bytes) { \
15145 case 2: \
bc901d79 15146 ____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w",u16);\
16454cff 15147@@ -219,7 +218,6 @@ struct group_dual {
ae4e228f
MT
15148
15149 #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \
15150 do { \
15151- unsigned long _tmp; \
15152 switch ((_dst).bytes) { \
15153 case 1: \
bc901d79 15154 ____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b",u8); \
16454cff
MT
15155diff -urNp linux-2.6.38.1/arch/x86/kvm/lapic.c linux-2.6.38.1/arch/x86/kvm/lapic.c
15156--- linux-2.6.38.1/arch/x86/kvm/lapic.c 2011-03-14 21:20:32.000000000 -0400
15157+++ linux-2.6.38.1/arch/x86/kvm/lapic.c 2011-03-21 18:31:35.000000000 -0400
6892158b 15158@@ -53,7 +53,7 @@
df50ba0c
MT
15159 #define APIC_BUS_CYCLE_NS 1
15160
15161 /* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
15162-#define apic_debug(fmt, arg...)
15163+#define apic_debug(fmt, arg...) do {} while (0)
15164
15165 #define APIC_LVT_NUM 6
15166 /* 14 is the version for Xeon and Pentium 8.4.8*/
16454cff
MT
15167diff -urNp linux-2.6.38.1/arch/x86/kvm/svm.c linux-2.6.38.1/arch/x86/kvm/svm.c
15168--- linux-2.6.38.1/arch/x86/kvm/svm.c 2011-03-14 21:20:32.000000000 -0400
15169+++ linux-2.6.38.1/arch/x86/kvm/svm.c 2011-03-21 18:31:35.000000000 -0400
15170@@ -3273,7 +3273,11 @@ static void reload_tss(struct kvm_vcpu *
58c5fc13
MT
15171 int cpu = raw_smp_processor_id();
15172
ae4e228f 15173 struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
58c5fc13 15174+
ae4e228f
MT
15175+ pax_open_kernel();
15176 sd->tss_desc->type = 9; /* available 32/64-bit TSS */
15177+ pax_close_kernel();
58c5fc13
MT
15178+
15179 load_TR_desc();
15180 }
15181
16454cff 15182@@ -3850,7 +3854,7 @@ static void svm_fpu_deactivate(struct kv
57199397 15183 update_cr0_intercept(svm);
58c5fc13
MT
15184 }
15185
15186-static struct kvm_x86_ops svm_x86_ops = {
15187+static const struct kvm_x86_ops svm_x86_ops = {
15188 .cpu_has_kvm_support = has_svm,
15189 .disabled_by_bios = is_disabled,
15190 .hardware_setup = svm_hardware_setup,
16454cff
MT
15191diff -urNp linux-2.6.38.1/arch/x86/kvm/vmx.c linux-2.6.38.1/arch/x86/kvm/vmx.c
15192--- linux-2.6.38.1/arch/x86/kvm/vmx.c 2011-03-14 21:20:32.000000000 -0400
15193+++ linux-2.6.38.1/arch/x86/kvm/vmx.c 2011-03-21 18:31:35.000000000 -0400
15194@@ -725,7 +725,11 @@ static void reload_tss(void)
bc901d79 15195 struct desc_struct *descs;
58c5fc13 15196
bc901d79 15197 descs = (void *)gdt->address;
58c5fc13 15198+
ae4e228f 15199+ pax_open_kernel();
58c5fc13 15200 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
ae4e228f 15201+ pax_close_kernel();
58c5fc13
MT
15202+
15203 load_TR_desc();
15204 }
15205
16454cff 15206@@ -1642,8 +1646,11 @@ static __init int hardware_setup(void)
58c5fc13
MT
15207 if (!cpu_has_vmx_flexpriority())
15208 flexpriority_enabled = 0;
15209
15210- if (!cpu_has_vmx_tpr_shadow())
15211- kvm_x86_ops->update_cr8_intercept = NULL;
15212+ if (!cpu_has_vmx_tpr_shadow()) {
ae4e228f 15213+ pax_open_kernel();
58c5fc13 15214+ *(void **)&kvm_x86_ops->update_cr8_intercept = NULL;
ae4e228f 15215+ pax_close_kernel();
58c5fc13
MT
15216+ }
15217
ae4e228f
MT
15218 if (enable_ept && !cpu_has_vmx_ept_2m_page())
15219 kvm_disable_largepages();
16454cff 15220@@ -2640,7 +2647,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
57199397 15221 vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */
58c5fc13
MT
15222
15223 asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return));
15224- vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */
15225+ vmcs_writel(HOST_RIP, ktla_ktva(kvm_vmx_return)); /* 22.2.5 */
15226 vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0);
15227 vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0);
57199397 15228 vmcs_write64(VM_EXIT_MSR_LOAD_ADDR, __pa(vmx->msr_autoload.host));
16454cff 15229@@ -4031,6 +4038,12 @@ static void vmx_vcpu_run(struct kvm_vcpu
58c5fc13
MT
15230 "jmp .Lkvm_vmx_return \n\t"
15231 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
15232 ".Lkvm_vmx_return: "
15233+
15234+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
15235+ "ljmp %[cs],$.Lkvm_vmx_return2\n\t"
15236+ ".Lkvm_vmx_return2: "
15237+#endif
15238+
15239 /* Save guest registers, load host registers, keep flags */
15240 "xchg %0, (%%"R"sp) \n\t"
15241 "mov %%"R"ax, %c[rax](%0) \n\t"
16454cff 15242@@ -4077,6 +4090,11 @@ static void vmx_vcpu_run(struct kvm_vcpu
58c5fc13
MT
15243 [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
15244 #endif
15245 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
15246+
15247+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
15248+ ,[cs]"i"(__KERNEL_CS)
15249+#endif
15250+
15251 : "cc", "memory"
bc901d79 15252 , R"ax", R"bx", R"di", R"si"
58c5fc13 15253 #ifdef CONFIG_X86_64
16454cff 15254@@ -4091,7 +4109,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
bc901d79
MT
15255
15256 vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
58c5fc13
MT
15257
15258- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
6892158b 15259+ asm("mov %0, %%ds; mov %0, %%es; mov %0, %%ss" : : "r"(__KERNEL_DS));
58c5fc13
MT
15260 vmx->launched = 1;
15261
bc901d79 15262 vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
16454cff 15263@@ -4326,7 +4344,7 @@ static void vmx_set_supported_cpuid(u32
efbe55a5 15264 {
58c5fc13
MT
15265 }
15266
15267-static struct kvm_x86_ops vmx_x86_ops = {
15268+static const struct kvm_x86_ops vmx_x86_ops = {
15269 .cpu_has_kvm_support = cpu_has_kvm_support,
15270 .disabled_by_bios = vmx_disabled_by_bios,
15271 .hardware_setup = hardware_setup,
16454cff
MT
15272diff -urNp linux-2.6.38.1/arch/x86/kvm/x86.c linux-2.6.38.1/arch/x86/kvm/x86.c
15273--- linux-2.6.38.1/arch/x86/kvm/x86.c 2011-03-14 21:20:32.000000000 -0400
15274+++ linux-2.6.38.1/arch/x86/kvm/x86.c 2011-03-21 18:31:35.000000000 -0400
15275@@ -93,7 +93,7 @@ static void update_cr8_intercept(struct
ae4e228f
MT
15276 static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
15277 struct kvm_cpuid_entry2 __user *entries);
58c5fc13
MT
15278
15279-struct kvm_x86_ops *kvm_x86_ops;
15280+const struct kvm_x86_ops *kvm_x86_ops;
15281 EXPORT_SYMBOL_GPL(kvm_x86_ops);
15282
ae4e228f 15283 int ignore_msrs = 0;
16454cff 15284@@ -119,38 +119,38 @@ static struct kvm_shared_msrs_global __r
ae4e228f
MT
15285 static DEFINE_PER_CPU(struct kvm_shared_msrs, shared_msrs);
15286
58c5fc13
MT
15287 struct kvm_stats_debugfs_item debugfs_entries[] = {
15288- { "pf_fixed", VCPU_STAT(pf_fixed) },
15289- { "pf_guest", VCPU_STAT(pf_guest) },
15290- { "tlb_flush", VCPU_STAT(tlb_flush) },
15291- { "invlpg", VCPU_STAT(invlpg) },
15292- { "exits", VCPU_STAT(exits) },
15293- { "io_exits", VCPU_STAT(io_exits) },
15294- { "mmio_exits", VCPU_STAT(mmio_exits) },
15295- { "signal_exits", VCPU_STAT(signal_exits) },
15296- { "irq_window", VCPU_STAT(irq_window_exits) },
15297- { "nmi_window", VCPU_STAT(nmi_window_exits) },
15298- { "halt_exits", VCPU_STAT(halt_exits) },
15299- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
15300- { "hypercalls", VCPU_STAT(hypercalls) },
15301- { "request_irq", VCPU_STAT(request_irq_exits) },
15302- { "irq_exits", VCPU_STAT(irq_exits) },
15303- { "host_state_reload", VCPU_STAT(host_state_reload) },
15304- { "efer_reload", VCPU_STAT(efer_reload) },
15305- { "fpu_reload", VCPU_STAT(fpu_reload) },
15306- { "insn_emulation", VCPU_STAT(insn_emulation) },
15307- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
15308- { "irq_injections", VCPU_STAT(irq_injections) },
15309- { "nmi_injections", VCPU_STAT(nmi_injections) },
15310- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
15311- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
15312- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
15313- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
15314- { "mmu_flooded", VM_STAT(mmu_flooded) },
15315- { "mmu_recycled", VM_STAT(mmu_recycled) },
15316- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
15317- { "mmu_unsync", VM_STAT(mmu_unsync) },
15318- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
15319- { "largepages", VM_STAT(lpages) },
15320+ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
15321+ { "pf_guest", VCPU_STAT(pf_guest), NULL },
15322+ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
15323+ { "invlpg", VCPU_STAT(invlpg), NULL },
15324+ { "exits", VCPU_STAT(exits), NULL },
15325+ { "io_exits", VCPU_STAT(io_exits), NULL },
15326+ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
15327+ { "signal_exits", VCPU_STAT(signal_exits), NULL },
15328+ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
15329+ { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
15330+ { "halt_exits", VCPU_STAT(halt_exits), NULL },
15331+ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
15332+ { "hypercalls", VCPU_STAT(hypercalls), NULL },
15333+ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
15334+ { "irq_exits", VCPU_STAT(irq_exits), NULL },
15335+ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
15336+ { "efer_reload", VCPU_STAT(efer_reload), NULL },
15337+ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
15338+ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
15339+ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
15340+ { "irq_injections", VCPU_STAT(irq_injections), NULL },
15341+ { "nmi_injections", VCPU_STAT(nmi_injections), NULL },
15342+ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
15343+ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
15344+ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
15345+ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
15346+ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
15347+ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
15348+ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
15349+ { "mmu_unsync", VM_STAT(mmu_unsync), NULL },
15350+ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
15351+ { "largepages", VM_STAT(lpages), NULL },
15352 { NULL }
15353 };
15354
16454cff 15355@@ -2023,6 +2023,8 @@ long kvm_arch_dev_ioctl(struct file *fil
ae4e228f
MT
15356 if (n < msr_list.nmsrs)
15357 goto out;
15358 r = -EFAULT;
15359+ if (num_msrs_to_save > ARRAY_SIZE(msrs_to_save))
15360+ goto out;
15361 if (copy_to_user(user_msr_list->indices, &msrs_to_save,
15362 num_msrs_to_save * sizeof(u32)))
15363 goto out;
16454cff 15364@@ -2499,7 +2501,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
58c5fc13
MT
15365 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
15366 struct kvm_interrupt *irq)
15367 {
15368- if (irq->irq < 0 || irq->irq >= 256)
15369+ if (irq->irq >= 256)
15370 return -EINVAL;
15371 if (irqchip_in_kernel(vcpu->kvm))
15372 return -ENXIO;
16454cff 15373@@ -4687,10 +4689,10 @@ void kvm_after_handle_nmi(struct kvm_vcp
ae4e228f 15374 }
57199397 15375 EXPORT_SYMBOL_GPL(kvm_after_handle_nmi);
58c5fc13
MT
15376
15377-int kvm_arch_init(void *opaque)
15378+int kvm_arch_init(const void *opaque)
15379 {
ae4e228f 15380 int r;
58c5fc13
MT
15381- struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
15382+ const struct kvm_x86_ops *ops = (const struct kvm_x86_ops *)opaque;
15383
15384 if (kvm_x86_ops) {
15385 printk(KERN_ERR "kvm: already loaded the other module\n");
16454cff
MT
15386diff -urNp linux-2.6.38.1/arch/x86/lib/atomic64_cx8_32.S linux-2.6.38.1/arch/x86/lib/atomic64_cx8_32.S
15387--- linux-2.6.38.1/arch/x86/lib/atomic64_cx8_32.S 2011-03-14 21:20:32.000000000 -0400
15388+++ linux-2.6.38.1/arch/x86/lib/atomic64_cx8_32.S 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
15389@@ -86,13 +86,23 @@ ENTRY(atomic64_\func\()_return_cx8)
15390 movl %edx, %ecx
15391 \ins\()l %esi, %ebx
15392 \insc\()l %edi, %ecx
15393+
15394+#ifdef CONFIG_PAX_REFCOUNT
15395+ into
15396+2:
15397+ _ASM_EXTABLE(2b, 3f)
15398+#endif
15399+
15400 LOCK_PREFIX
15401 cmpxchg8b (%ebp)
15402 jne 1b
15403-
15404-10:
15405 movl %ebx, %eax
15406 movl %ecx, %edx
15407+
15408+#ifdef CONFIG_PAX_REFCOUNT
15409+3:
15410+#endif
15411+
15412 RESTORE edi
15413 RESTORE esi
15414 RESTORE ebx
15415@@ -116,13 +126,24 @@ ENTRY(atomic64_\func\()_return_cx8)
15416 movl %edx, %ecx
15417 \ins\()l $1, %ebx
15418 \insc\()l $0, %ecx
15419+
15420+#ifdef CONFIG_PAX_REFCOUNT
15421+ into
15422+2:
15423+ _ASM_EXTABLE(2b, 3f)
15424+#endif
15425+
15426 LOCK_PREFIX
15427 cmpxchg8b (%esi)
15428 jne 1b
15429
15430-10:
15431 movl %ebx, %eax
15432 movl %ecx, %edx
15433+
15434+#ifdef CONFIG_PAX_REFCOUNT
15435+3:
15436+#endif
15437+
15438 RESTORE ebx
15439 ret
15440 CFI_ENDPROC
15441@@ -176,6 +197,13 @@ ENTRY(atomic64_add_unless_cx8)
15442 movl %edx, %ecx
15443 addl %esi, %ebx
15444 adcl %edi, %ecx
15445+
15446+#ifdef CONFIG_PAX_REFCOUNT
15447+ into
15448+1234:
15449+ _ASM_EXTABLE(1234b, 1234b)
15450+#endif
15451+
15452 LOCK_PREFIX
15453 cmpxchg8b (%ebp)
15454 jne 1b
15455@@ -208,6 +236,13 @@ ENTRY(atomic64_inc_not_zero_cx8)
15456 movl %edx, %ecx
15457 addl $1, %ebx
15458 adcl $0, %ecx
15459+
15460+#ifdef CONFIG_PAX_REFCOUNT
15461+ into
15462+1234:
15463+ _ASM_EXTABLE(1234b, 1234b)
15464+#endif
15465+
15466 LOCK_PREFIX
15467 cmpxchg8b (%esi)
15468 jne 1b
16454cff
MT
15469diff -urNp linux-2.6.38.1/arch/x86/lib/checksum_32.S linux-2.6.38.1/arch/x86/lib/checksum_32.S
15470--- linux-2.6.38.1/arch/x86/lib/checksum_32.S 2011-03-14 21:20:32.000000000 -0400
15471+++ linux-2.6.38.1/arch/x86/lib/checksum_32.S 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
15472@@ -28,7 +28,8 @@
15473 #include <linux/linkage.h>
15474 #include <asm/dwarf2.h>
15475 #include <asm/errno.h>
15476-
15477+#include <asm/segment.h>
15478+
15479 /*
15480 * computes a partial checksum, e.g. for TCP/UDP fragments
15481 */
bc901d79 15482@@ -304,9 +305,28 @@ unsigned int csum_partial_copy_generic (
58c5fc13
MT
15483
15484 #define ARGBASE 16
15485 #define FP 12
15486-
15487-ENTRY(csum_partial_copy_generic)
15488+
15489+ENTRY(csum_partial_copy_generic_to_user)
15490 CFI_STARTPROC
bc901d79
MT
15491+
15492+#ifdef CONFIG_PAX_MEMORY_UDEREF
15493+ pushl %gs
58c5fc13
MT
15494+ CFI_ADJUST_CFA_OFFSET 4
15495+ popl %es
15496+ CFI_ADJUST_CFA_OFFSET -4
15497+ jmp csum_partial_copy_generic
bc901d79 15498+#endif
58c5fc13
MT
15499+
15500+ENTRY(csum_partial_copy_generic_from_user)
bc901d79
MT
15501+
15502+#ifdef CONFIG_PAX_MEMORY_UDEREF
15503+ pushl %gs
58c5fc13
MT
15504+ CFI_ADJUST_CFA_OFFSET 4
15505+ popl %ds
15506+ CFI_ADJUST_CFA_OFFSET -4
bc901d79 15507+#endif
58c5fc13
MT
15508+
15509+ENTRY(csum_partial_copy_generic)
15510 subl $4,%esp
15511 CFI_ADJUST_CFA_OFFSET 4
15512 pushl %edi
bc901d79 15513@@ -331,7 +351,7 @@ ENTRY(csum_partial_copy_generic)
58c5fc13
MT
15514 jmp 4f
15515 SRC(1: movw (%esi), %bx )
15516 addl $2, %esi
15517-DST( movw %bx, (%edi) )
15518+DST( movw %bx, %es:(%edi) )
15519 addl $2, %edi
15520 addw %bx, %ax
15521 adcl $0, %eax
bc901d79 15522@@ -343,30 +363,30 @@ DST( movw %bx, (%edi) )
58c5fc13
MT
15523 SRC(1: movl (%esi), %ebx )
15524 SRC( movl 4(%esi), %edx )
15525 adcl %ebx, %eax
15526-DST( movl %ebx, (%edi) )
15527+DST( movl %ebx, %es:(%edi) )
15528 adcl %edx, %eax
15529-DST( movl %edx, 4(%edi) )
15530+DST( movl %edx, %es:4(%edi) )
15531
15532 SRC( movl 8(%esi), %ebx )
15533 SRC( movl 12(%esi), %edx )
15534 adcl %ebx, %eax
15535-DST( movl %ebx, 8(%edi) )
15536+DST( movl %ebx, %es:8(%edi) )
15537 adcl %edx, %eax
15538-DST( movl %edx, 12(%edi) )
15539+DST( movl %edx, %es:12(%edi) )
15540
15541 SRC( movl 16(%esi), %ebx )
15542 SRC( movl 20(%esi), %edx )
15543 adcl %ebx, %eax
15544-DST( movl %ebx, 16(%edi) )
15545+DST( movl %ebx, %es:16(%edi) )
15546 adcl %edx, %eax
15547-DST( movl %edx, 20(%edi) )
15548+DST( movl %edx, %es:20(%edi) )
15549
15550 SRC( movl 24(%esi), %ebx )
15551 SRC( movl 28(%esi), %edx )
15552 adcl %ebx, %eax
15553-DST( movl %ebx, 24(%edi) )
15554+DST( movl %ebx, %es:24(%edi) )
15555 adcl %edx, %eax
15556-DST( movl %edx, 28(%edi) )
15557+DST( movl %edx, %es:28(%edi) )
15558
15559 lea 32(%esi), %esi
15560 lea 32(%edi), %edi
bc901d79 15561@@ -380,7 +400,7 @@ DST( movl %edx, 28(%edi) )
58c5fc13
MT
15562 shrl $2, %edx # This clears CF
15563 SRC(3: movl (%esi), %ebx )
15564 adcl %ebx, %eax
15565-DST( movl %ebx, (%edi) )
15566+DST( movl %ebx, %es:(%edi) )
15567 lea 4(%esi), %esi
15568 lea 4(%edi), %edi
15569 dec %edx
bc901d79 15570@@ -392,12 +412,12 @@ DST( movl %ebx, (%edi) )
58c5fc13
MT
15571 jb 5f
15572 SRC( movw (%esi), %cx )
15573 leal 2(%esi), %esi
15574-DST( movw %cx, (%edi) )
15575+DST( movw %cx, %es:(%edi) )
15576 leal 2(%edi), %edi
15577 je 6f
15578 shll $16,%ecx
15579 SRC(5: movb (%esi), %cl )
15580-DST( movb %cl, (%edi) )
15581+DST( movb %cl, %es:(%edi) )
15582 6: addl %ecx, %eax
15583 adcl $0, %eax
15584 7:
bc901d79 15585@@ -408,7 +428,7 @@ DST( movb %cl, (%edi) )
58c5fc13
MT
15586
15587 6001:
15588 movl ARGBASE+20(%esp), %ebx # src_err_ptr
15589- movl $-EFAULT, (%ebx)
15590+ movl $-EFAULT, %ss:(%ebx)
15591
15592 # zero the complete destination - computing the rest
15593 # is too much work
bc901d79 15594@@ -421,11 +441,19 @@ DST( movb %cl, (%edi) )
58c5fc13
MT
15595
15596 6002:
15597 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
15598- movl $-EFAULT,(%ebx)
15599+ movl $-EFAULT,%ss:(%ebx)
15600 jmp 5000b
15601
15602 .previous
15603
15604+ pushl %ss
15605+ CFI_ADJUST_CFA_OFFSET 4
15606+ popl %ds
15607+ CFI_ADJUST_CFA_OFFSET -4
15608+ pushl %ss
15609+ CFI_ADJUST_CFA_OFFSET 4
15610+ popl %es
15611+ CFI_ADJUST_CFA_OFFSET -4
15612 popl %ebx
15613 CFI_ADJUST_CFA_OFFSET -4
15614 CFI_RESTORE ebx
bc901d79 15615@@ -439,26 +467,47 @@ DST( movb %cl, (%edi) )
58c5fc13
MT
15616 CFI_ADJUST_CFA_OFFSET -4
15617 ret
15618 CFI_ENDPROC
15619-ENDPROC(csum_partial_copy_generic)
15620+ENDPROC(csum_partial_copy_generic_to_user)
15621
15622 #else
15623
15624 /* Version for PentiumII/PPro */
15625
15626 #define ROUND1(x) \
15627+ nop; nop; nop; \
15628 SRC(movl x(%esi), %ebx ) ; \
15629 addl %ebx, %eax ; \
15630- DST(movl %ebx, x(%edi) ) ;
15631+ DST(movl %ebx, %es:x(%edi)) ;
15632
15633 #define ROUND(x) \
15634+ nop; nop; nop; \
15635 SRC(movl x(%esi), %ebx ) ; \
15636 adcl %ebx, %eax ; \
15637- DST(movl %ebx, x(%edi) ) ;
15638+ DST(movl %ebx, %es:x(%edi)) ;
15639
15640 #define ARGBASE 12
15641-
15642-ENTRY(csum_partial_copy_generic)
15643+
15644+ENTRY(csum_partial_copy_generic_to_user)
15645 CFI_STARTPROC
bc901d79
MT
15646+
15647+#ifdef CONFIG_PAX_MEMORY_UDEREF
15648+ pushl %gs
58c5fc13
MT
15649+ CFI_ADJUST_CFA_OFFSET 4
15650+ popl %es
15651+ CFI_ADJUST_CFA_OFFSET -4
15652+ jmp csum_partial_copy_generic
bc901d79 15653+#endif
58c5fc13
MT
15654+
15655+ENTRY(csum_partial_copy_generic_from_user)
bc901d79
MT
15656+
15657+#ifdef CONFIG_PAX_MEMORY_UDEREF
15658+ pushl %gs
58c5fc13
MT
15659+ CFI_ADJUST_CFA_OFFSET 4
15660+ popl %ds
15661+ CFI_ADJUST_CFA_OFFSET -4
bc901d79 15662+#endif
58c5fc13
MT
15663+
15664+ENTRY(csum_partial_copy_generic)
15665 pushl %ebx
15666 CFI_ADJUST_CFA_OFFSET 4
15667 CFI_REL_OFFSET ebx, 0
bc901d79 15668@@ -482,7 +531,7 @@ ENTRY(csum_partial_copy_generic)
58c5fc13
MT
15669 subl %ebx, %edi
15670 lea -1(%esi),%edx
15671 andl $-32,%edx
15672- lea 3f(%ebx,%ebx), %ebx
15673+ lea 3f(%ebx,%ebx,2), %ebx
15674 testl %esi, %esi
15675 jmp *%ebx
15676 1: addl $64,%esi
bc901d79 15677@@ -503,19 +552,19 @@ ENTRY(csum_partial_copy_generic)
58c5fc13
MT
15678 jb 5f
15679 SRC( movw (%esi), %dx )
15680 leal 2(%esi), %esi
15681-DST( movw %dx, (%edi) )
15682+DST( movw %dx, %es:(%edi) )
15683 leal 2(%edi), %edi
15684 je 6f
15685 shll $16,%edx
15686 5:
15687 SRC( movb (%esi), %dl )
15688-DST( movb %dl, (%edi) )
15689+DST( movb %dl, %es:(%edi) )
15690 6: addl %edx, %eax
15691 adcl $0, %eax
15692 7:
15693 .section .fixup, "ax"
15694 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
15695- movl $-EFAULT, (%ebx)
15696+ movl $-EFAULT, %ss:(%ebx)
15697 # zero the complete destination (computing the rest is too much work)
15698 movl ARGBASE+8(%esp),%edi # dst
15699 movl ARGBASE+12(%esp),%ecx # len
bc901d79 15700@@ -523,10 +572,21 @@ DST( movb %dl, (%edi) )
58c5fc13
MT
15701 rep; stosb
15702 jmp 7b
15703 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
15704- movl $-EFAULT, (%ebx)
15705+ movl $-EFAULT, %ss:(%ebx)
15706 jmp 7b
15707 .previous
15708
bc901d79 15709+#ifdef CONFIG_PAX_MEMORY_UDEREF
58c5fc13
MT
15710+ pushl %ss
15711+ CFI_ADJUST_CFA_OFFSET 4
15712+ popl %ds
15713+ CFI_ADJUST_CFA_OFFSET -4
15714+ pushl %ss
15715+ CFI_ADJUST_CFA_OFFSET 4
15716+ popl %es
15717+ CFI_ADJUST_CFA_OFFSET -4
bc901d79
MT
15718+#endif
15719+
58c5fc13
MT
15720 popl %esi
15721 CFI_ADJUST_CFA_OFFSET -4
15722 CFI_RESTORE esi
bc901d79 15723@@ -538,7 +598,7 @@ DST( movb %dl, (%edi) )
58c5fc13
MT
15724 CFI_RESTORE ebx
15725 ret
15726 CFI_ENDPROC
15727-ENDPROC(csum_partial_copy_generic)
15728+ENDPROC(csum_partial_copy_generic_to_user)
15729
15730 #undef ROUND
15731 #undef ROUND1
16454cff
MT
15732diff -urNp linux-2.6.38.1/arch/x86/lib/clear_page_64.S linux-2.6.38.1/arch/x86/lib/clear_page_64.S
15733--- linux-2.6.38.1/arch/x86/lib/clear_page_64.S 2011-03-14 21:20:32.000000000 -0400
15734+++ linux-2.6.38.1/arch/x86/lib/clear_page_64.S 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
15735@@ -43,7 +43,7 @@ ENDPROC(clear_page)
15736
15737 #include <asm/cpufeature.h>
15738
15739- .section .altinstr_replacement,"ax"
15740+ .section .altinstr_replacement,"a"
15741 1: .byte 0xeb /* jmp <disp8> */
15742 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
15743 2:
16454cff
MT
15744diff -urNp linux-2.6.38.1/arch/x86/lib/copy_page_64.S linux-2.6.38.1/arch/x86/lib/copy_page_64.S
15745--- linux-2.6.38.1/arch/x86/lib/copy_page_64.S 2011-03-14 21:20:32.000000000 -0400
15746+++ linux-2.6.38.1/arch/x86/lib/copy_page_64.S 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
15747@@ -104,7 +104,7 @@ ENDPROC(copy_page)
15748
15749 #include <asm/cpufeature.h>
15750
15751- .section .altinstr_replacement,"ax"
15752+ .section .altinstr_replacement,"a"
15753 1: .byte 0xeb /* jmp <disp8> */
15754 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
15755 2:
16454cff
MT
15756diff -urNp linux-2.6.38.1/arch/x86/lib/copy_user_64.S linux-2.6.38.1/arch/x86/lib/copy_user_64.S
15757--- linux-2.6.38.1/arch/x86/lib/copy_user_64.S 2011-03-14 21:20:32.000000000 -0400
15758+++ linux-2.6.38.1/arch/x86/lib/copy_user_64.S 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
15759@@ -15,13 +15,14 @@
15760 #include <asm/asm-offsets.h>
15761 #include <asm/thread_info.h>
15762 #include <asm/cpufeature.h>
15763+#include <asm/pgtable.h>
15764
15765 .macro ALTERNATIVE_JUMP feature,orig,alt
15766 0:
58c5fc13
MT
15767 .byte 0xe9 /* 32bit jump */
15768 .long \orig-1f /* by default jump to orig */
15769 1:
15770- .section .altinstr_replacement,"ax"
15771+ .section .altinstr_replacement,"a"
15772 2: .byte 0xe9 /* near jump with 32bit immediate */
15773 .long \alt-1b /* offset */ /* or alternatively to alt */
15774 .previous
df50ba0c 15775@@ -64,37 +65,13 @@
58c5fc13
MT
15776 #endif
15777 .endm
15778
15779-/* Standard copy_to_user with segment limit checking */
ae4e228f 15780-ENTRY(_copy_to_user)
58c5fc13
MT
15781- CFI_STARTPROC
15782- GET_THREAD_INFO(%rax)
15783- movq %rdi,%rcx
15784- addq %rdx,%rcx
15785- jc bad_to_user
15786- cmpq TI_addr_limit(%rax),%rcx
15787- jae bad_to_user
15788- ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
15789- CFI_ENDPROC
ae4e228f 15790-ENDPROC(_copy_to_user)
58c5fc13
MT
15791-
15792-/* Standard copy_from_user with segment limit checking */
ae4e228f 15793-ENTRY(_copy_from_user)
58c5fc13
MT
15794- CFI_STARTPROC
15795- GET_THREAD_INFO(%rax)
15796- movq %rsi,%rcx
15797- addq %rdx,%rcx
15798- jc bad_from_user
15799- cmpq TI_addr_limit(%rax),%rcx
15800- jae bad_from_user
15801- ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
15802- CFI_ENDPROC
ae4e228f 15803-ENDPROC(_copy_from_user)
58c5fc13 15804-
df50ba0c
MT
15805 .section .fixup,"ax"
15806 /* must zero dest */
58c5fc13
MT
15807 ENTRY(bad_from_user)
15808 bad_from_user:
15809 CFI_STARTPROC
15810+ testl %edx,%edx
15811+ js bad_to_user
15812 movl %edx,%ecx
15813 xorl %eax,%eax
15814 rep
16454cff
MT
15815diff -urNp linux-2.6.38.1/arch/x86/lib/copy_user_nocache_64.S linux-2.6.38.1/arch/x86/lib/copy_user_nocache_64.S
15816--- linux-2.6.38.1/arch/x86/lib/copy_user_nocache_64.S 2011-03-14 21:20:32.000000000 -0400
15817+++ linux-2.6.38.1/arch/x86/lib/copy_user_nocache_64.S 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
15818@@ -14,6 +14,7 @@
15819 #include <asm/current.h>
15820 #include <asm/asm-offsets.h>
15821 #include <asm/thread_info.h>
15822+#include <asm/pgtable.h>
15823
15824 .macro ALIGN_DESTINATION
15825 #ifdef FIX_ALIGNMENT
15826@@ -50,6 +51,15 @@
15827 */
15828 ENTRY(__copy_user_nocache)
15829 CFI_STARTPROC
15830+
15831+#ifdef CONFIG_PAX_MEMORY_UDEREF
15832+ mov $PAX_USER_SHADOW_BASE,%rcx
15833+ cmp %rcx,%rsi
15834+ jae 1f
15835+ add %rcx,%rsi
15836+1:
15837+#endif
15838+
15839 cmpl $8,%edx
15840 jb 20f /* less then 8 bytes, go to byte copy loop */
15841 ALIGN_DESTINATION
16454cff
MT
15842diff -urNp linux-2.6.38.1/arch/x86/lib/csum-wrappers_64.c linux-2.6.38.1/arch/x86/lib/csum-wrappers_64.c
15843--- linux-2.6.38.1/arch/x86/lib/csum-wrappers_64.c 2011-03-14 21:20:32.000000000 -0400
15844+++ linux-2.6.38.1/arch/x86/lib/csum-wrappers_64.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
15845@@ -52,6 +52,8 @@ csum_partial_copy_from_user(const void _
15846 len -= 2;
15847 }
15848 }
15849+ if ((unsigned long)src < PAX_USER_SHADOW_BASE)
15850+ src += PAX_USER_SHADOW_BASE;
15851 isum = csum_partial_copy_generic((__force const void *)src,
15852 dst, len, isum, errp, NULL);
15853 if (unlikely(*errp))
15854@@ -105,6 +107,8 @@ csum_partial_copy_to_user(const void *sr
15855 }
15856
15857 *errp = 0;
15858+ if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
15859+ dst += PAX_USER_SHADOW_BASE;
15860 return csum_partial_copy_generic(src, (void __force *)dst,
15861 len, isum, NULL, errp);
15862 }
16454cff
MT
15863diff -urNp linux-2.6.38.1/arch/x86/lib/getuser.S linux-2.6.38.1/arch/x86/lib/getuser.S
15864--- linux-2.6.38.1/arch/x86/lib/getuser.S 2011-03-14 21:20:32.000000000 -0400
15865+++ linux-2.6.38.1/arch/x86/lib/getuser.S 2011-03-21 18:31:35.000000000 -0400
bc901d79 15866@@ -33,14 +33,35 @@
58c5fc13
MT
15867 #include <asm/asm-offsets.h>
15868 #include <asm/thread_info.h>
15869 #include <asm/asm.h>
15870+#include <asm/segment.h>
df50ba0c 15871+#include <asm/pgtable.h>
bc901d79
MT
15872+
15873+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16454cff 15874+#define __copyuser_seg gs;
bc901d79
MT
15875+#else
15876+#define __copyuser_seg
15877+#endif
58c5fc13
MT
15878
15879 .text
15880 ENTRY(__get_user_1)
ae4e228f 15881 CFI_STARTPROC
58c5fc13 15882+
bc901d79 15883+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
ae4e228f
MT
15884 GET_THREAD_INFO(%_ASM_DX)
15885 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
15886 jae bad_get_user
bc901d79 15887-1: movzb (%_ASM_AX),%edx
df50ba0c
MT
15888+
15889+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
15890+ mov $PAX_USER_SHADOW_BASE,%_ASM_DX
15891+ cmp %_ASM_DX,%_ASM_AX
15892+ jae 1234f
15893+ add %_ASM_DX,%_ASM_AX
15894+1234:
15895+#endif
15896+
58c5fc13
MT
15897+#endif
15898+
16454cff 15899+1: __copyuser_seg movzb (%_ASM_AX),%edx
58c5fc13
MT
15900 xor %eax,%eax
15901 ret
15902 CFI_ENDPROC
bc901d79 15903@@ -49,11 +70,24 @@ ENDPROC(__get_user_1)
ae4e228f
MT
15904 ENTRY(__get_user_2)
15905 CFI_STARTPROC
15906 add $1,%_ASM_AX
58c5fc13 15907+
bc901d79 15908+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
ae4e228f
MT
15909 jc bad_get_user
15910 GET_THREAD_INFO(%_ASM_DX)
15911 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
15912 jae bad_get_user
bc901d79 15913-2: movzwl -1(%_ASM_AX),%edx
df50ba0c
MT
15914+
15915+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
15916+ mov $PAX_USER_SHADOW_BASE,%_ASM_DX
15917+ cmp %_ASM_DX,%_ASM_AX
15918+ jae 1234f
15919+ add %_ASM_DX,%_ASM_AX
15920+1234:
15921+#endif
15922+
58c5fc13
MT
15923+#endif
15924+
16454cff 15925+2: __copyuser_seg movzwl -1(%_ASM_AX),%edx
58c5fc13
MT
15926 xor %eax,%eax
15927 ret
15928 CFI_ENDPROC
bc901d79 15929@@ -62,11 +96,24 @@ ENDPROC(__get_user_2)
ae4e228f
MT
15930 ENTRY(__get_user_4)
15931 CFI_STARTPROC
15932 add $3,%_ASM_AX
58c5fc13 15933+
bc901d79 15934+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
ae4e228f
MT
15935 jc bad_get_user
15936 GET_THREAD_INFO(%_ASM_DX)
15937 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
15938 jae bad_get_user
bc901d79 15939-3: mov -3(%_ASM_AX),%edx
df50ba0c
MT
15940+
15941+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
15942+ mov $PAX_USER_SHADOW_BASE,%_ASM_DX
15943+ cmp %_ASM_DX,%_ASM_AX
15944+ jae 1234f
15945+ add %_ASM_DX,%_ASM_AX
15946+1234:
15947+#endif
15948+
58c5fc13
MT
15949+#endif
15950+
16454cff 15951+3: __copyuser_seg mov -3(%_ASM_AX),%edx
58c5fc13
MT
15952 xor %eax,%eax
15953 ret
15954 CFI_ENDPROC
bc901d79 15955@@ -80,6 +127,15 @@ ENTRY(__get_user_8)
df50ba0c
MT
15956 GET_THREAD_INFO(%_ASM_DX)
15957 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
15958 jae bad_get_user
15959+
15960+#ifdef CONFIG_PAX_MEMORY_UDEREF
15961+ mov $PAX_USER_SHADOW_BASE,%_ASM_DX
15962+ cmp %_ASM_DX,%_ASM_AX
15963+ jae 1234f
15964+ add %_ASM_DX,%_ASM_AX
15965+1234:
15966+#endif
15967+
15968 4: movq -7(%_ASM_AX),%_ASM_DX
15969 xor %eax,%eax
15970 ret
16454cff
MT
15971diff -urNp linux-2.6.38.1/arch/x86/lib/insn.c linux-2.6.38.1/arch/x86/lib/insn.c
15972--- linux-2.6.38.1/arch/x86/lib/insn.c 2011-03-14 21:20:32.000000000 -0400
15973+++ linux-2.6.38.1/arch/x86/lib/insn.c 2011-03-21 18:31:35.000000000 -0400
c52201e0 15974@@ -21,6 +21,11 @@
57199397
MT
15975 #include <linux/string.h>
15976 #include <asm/inat.h>
15977 #include <asm/insn.h>
c52201e0 15978+#ifdef __KERNEL__
57199397 15979+#include <asm/pgtable_types.h>
c52201e0
MT
15980+#else
15981+#define ktla_ktva(addr) addr
15982+#endif
57199397
MT
15983
15984 #define get_next(t, insn) \
15985 ({t r; r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
c52201e0 15986@@ -40,8 +45,8 @@
57199397
MT
15987 void insn_init(struct insn *insn, const void *kaddr, int x86_64)
15988 {
15989 memset(insn, 0, sizeof(*insn));
15990- insn->kaddr = kaddr;
15991- insn->next_byte = kaddr;
15992+ insn->kaddr = ktla_ktva(kaddr);
15993+ insn->next_byte = ktla_ktva(kaddr);
15994 insn->x86_64 = x86_64 ? 1 : 0;
15995 insn->opnd_bytes = 4;
15996 if (x86_64)
16454cff
MT
15997diff -urNp linux-2.6.38.1/arch/x86/lib/mmx_32.c linux-2.6.38.1/arch/x86/lib/mmx_32.c
15998--- linux-2.6.38.1/arch/x86/lib/mmx_32.c 2011-03-14 21:20:32.000000000 -0400
15999+++ linux-2.6.38.1/arch/x86/lib/mmx_32.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
16000@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
16001 {
16002 void *p;
16003 int i;
16004+ unsigned long cr0;
16005
16006 if (unlikely(in_interrupt()))
16007 return __memcpy(to, from, len);
16008@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
16009 kernel_fpu_begin();
16010
16011 __asm__ __volatile__ (
16012- "1: prefetch (%0)\n" /* This set is 28 bytes */
16013- " prefetch 64(%0)\n"
16014- " prefetch 128(%0)\n"
16015- " prefetch 192(%0)\n"
16016- " prefetch 256(%0)\n"
16017+ "1: prefetch (%1)\n" /* This set is 28 bytes */
16018+ " prefetch 64(%1)\n"
16019+ " prefetch 128(%1)\n"
16020+ " prefetch 192(%1)\n"
16021+ " prefetch 256(%1)\n"
16022 "2: \n"
16023 ".section .fixup, \"ax\"\n"
16024- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
16025+ "3: \n"
16026+
16027+#ifdef CONFIG_PAX_KERNEXEC
16028+ " movl %%cr0, %0\n"
16029+ " movl %0, %%eax\n"
16030+ " andl $0xFFFEFFFF, %%eax\n"
16031+ " movl %%eax, %%cr0\n"
16032+#endif
16033+
16034+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
16035+
16036+#ifdef CONFIG_PAX_KERNEXEC
16037+ " movl %0, %%cr0\n"
16038+#endif
16039+
16040 " jmp 2b\n"
16041 ".previous\n"
16042 _ASM_EXTABLE(1b, 3b)
16043- : : "r" (from));
16044+ : "=&r" (cr0) : "r" (from) : "ax");
16045
16046 for ( ; i > 5; i--) {
16047 __asm__ __volatile__ (
16048- "1: prefetch 320(%0)\n"
16049- "2: movq (%0), %%mm0\n"
16050- " movq 8(%0), %%mm1\n"
16051- " movq 16(%0), %%mm2\n"
16052- " movq 24(%0), %%mm3\n"
16053- " movq %%mm0, (%1)\n"
16054- " movq %%mm1, 8(%1)\n"
16055- " movq %%mm2, 16(%1)\n"
16056- " movq %%mm3, 24(%1)\n"
16057- " movq 32(%0), %%mm0\n"
16058- " movq 40(%0), %%mm1\n"
16059- " movq 48(%0), %%mm2\n"
16060- " movq 56(%0), %%mm3\n"
16061- " movq %%mm0, 32(%1)\n"
16062- " movq %%mm1, 40(%1)\n"
16063- " movq %%mm2, 48(%1)\n"
16064- " movq %%mm3, 56(%1)\n"
16065+ "1: prefetch 320(%1)\n"
16066+ "2: movq (%1), %%mm0\n"
16067+ " movq 8(%1), %%mm1\n"
16068+ " movq 16(%1), %%mm2\n"
16069+ " movq 24(%1), %%mm3\n"
16070+ " movq %%mm0, (%2)\n"
16071+ " movq %%mm1, 8(%2)\n"
16072+ " movq %%mm2, 16(%2)\n"
16073+ " movq %%mm3, 24(%2)\n"
16074+ " movq 32(%1), %%mm0\n"
16075+ " movq 40(%1), %%mm1\n"
16076+ " movq 48(%1), %%mm2\n"
16077+ " movq 56(%1), %%mm3\n"
16078+ " movq %%mm0, 32(%2)\n"
16079+ " movq %%mm1, 40(%2)\n"
16080+ " movq %%mm2, 48(%2)\n"
16081+ " movq %%mm3, 56(%2)\n"
16082 ".section .fixup, \"ax\"\n"
16083- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16084+ "3:\n"
16085+
16086+#ifdef CONFIG_PAX_KERNEXEC
16087+ " movl %%cr0, %0\n"
16088+ " movl %0, %%eax\n"
16089+ " andl $0xFFFEFFFF, %%eax\n"
16090+ " movl %%eax, %%cr0\n"
16091+#endif
16092+
16093+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16094+
16095+#ifdef CONFIG_PAX_KERNEXEC
16096+ " movl %0, %%cr0\n"
16097+#endif
16098+
16099 " jmp 2b\n"
16100 ".previous\n"
16101 _ASM_EXTABLE(1b, 3b)
16102- : : "r" (from), "r" (to) : "memory");
16103+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
16104
16105 from += 64;
16106 to += 64;
16107@@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
16108 static void fast_copy_page(void *to, void *from)
16109 {
16110 int i;
16111+ unsigned long cr0;
16112
16113 kernel_fpu_begin();
16114
16115@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
16116 * but that is for later. -AV
16117 */
16118 __asm__ __volatile__(
16119- "1: prefetch (%0)\n"
16120- " prefetch 64(%0)\n"
16121- " prefetch 128(%0)\n"
16122- " prefetch 192(%0)\n"
16123- " prefetch 256(%0)\n"
16124+ "1: prefetch (%1)\n"
16125+ " prefetch 64(%1)\n"
16126+ " prefetch 128(%1)\n"
16127+ " prefetch 192(%1)\n"
16128+ " prefetch 256(%1)\n"
16129 "2: \n"
16130 ".section .fixup, \"ax\"\n"
16131- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
16132+ "3: \n"
16133+
16134+#ifdef CONFIG_PAX_KERNEXEC
16135+ " movl %%cr0, %0\n"
16136+ " movl %0, %%eax\n"
16137+ " andl $0xFFFEFFFF, %%eax\n"
16138+ " movl %%eax, %%cr0\n"
16139+#endif
16140+
16141+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
16142+
16143+#ifdef CONFIG_PAX_KERNEXEC
16144+ " movl %0, %%cr0\n"
16145+#endif
16146+
16147 " jmp 2b\n"
16148 ".previous\n"
16149- _ASM_EXTABLE(1b, 3b) : : "r" (from));
16150+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
16151
16152 for (i = 0; i < (4096-320)/64; i++) {
16153 __asm__ __volatile__ (
16154- "1: prefetch 320(%0)\n"
16155- "2: movq (%0), %%mm0\n"
16156- " movntq %%mm0, (%1)\n"
16157- " movq 8(%0), %%mm1\n"
16158- " movntq %%mm1, 8(%1)\n"
16159- " movq 16(%0), %%mm2\n"
16160- " movntq %%mm2, 16(%1)\n"
16161- " movq 24(%0), %%mm3\n"
16162- " movntq %%mm3, 24(%1)\n"
16163- " movq 32(%0), %%mm4\n"
16164- " movntq %%mm4, 32(%1)\n"
16165- " movq 40(%0), %%mm5\n"
16166- " movntq %%mm5, 40(%1)\n"
16167- " movq 48(%0), %%mm6\n"
16168- " movntq %%mm6, 48(%1)\n"
16169- " movq 56(%0), %%mm7\n"
16170- " movntq %%mm7, 56(%1)\n"
16171+ "1: prefetch 320(%1)\n"
16172+ "2: movq (%1), %%mm0\n"
16173+ " movntq %%mm0, (%2)\n"
16174+ " movq 8(%1), %%mm1\n"
16175+ " movntq %%mm1, 8(%2)\n"
16176+ " movq 16(%1), %%mm2\n"
16177+ " movntq %%mm2, 16(%2)\n"
16178+ " movq 24(%1), %%mm3\n"
16179+ " movntq %%mm3, 24(%2)\n"
16180+ " movq 32(%1), %%mm4\n"
16181+ " movntq %%mm4, 32(%2)\n"
16182+ " movq 40(%1), %%mm5\n"
16183+ " movntq %%mm5, 40(%2)\n"
16184+ " movq 48(%1), %%mm6\n"
16185+ " movntq %%mm6, 48(%2)\n"
16186+ " movq 56(%1), %%mm7\n"
16187+ " movntq %%mm7, 56(%2)\n"
16188 ".section .fixup, \"ax\"\n"
16189- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16190+ "3:\n"
16191+
16192+#ifdef CONFIG_PAX_KERNEXEC
16193+ " movl %%cr0, %0\n"
16194+ " movl %0, %%eax\n"
16195+ " andl $0xFFFEFFFF, %%eax\n"
16196+ " movl %%eax, %%cr0\n"
16197+#endif
16198+
16199+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16200+
16201+#ifdef CONFIG_PAX_KERNEXEC
16202+ " movl %0, %%cr0\n"
16203+#endif
16204+
16205 " jmp 2b\n"
16206 ".previous\n"
16207- _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
16208+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
16209
16210 from += 64;
16211 to += 64;
16212@@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
16213 static void fast_copy_page(void *to, void *from)
16214 {
16215 int i;
16216+ unsigned long cr0;
16217
16218 kernel_fpu_begin();
16219
16220 __asm__ __volatile__ (
16221- "1: prefetch (%0)\n"
16222- " prefetch 64(%0)\n"
16223- " prefetch 128(%0)\n"
16224- " prefetch 192(%0)\n"
16225- " prefetch 256(%0)\n"
16226+ "1: prefetch (%1)\n"
16227+ " prefetch 64(%1)\n"
16228+ " prefetch 128(%1)\n"
16229+ " prefetch 192(%1)\n"
16230+ " prefetch 256(%1)\n"
16231 "2: \n"
16232 ".section .fixup, \"ax\"\n"
16233- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
16234+ "3: \n"
16235+
16236+#ifdef CONFIG_PAX_KERNEXEC
16237+ " movl %%cr0, %0\n"
16238+ " movl %0, %%eax\n"
16239+ " andl $0xFFFEFFFF, %%eax\n"
16240+ " movl %%eax, %%cr0\n"
16241+#endif
16242+
16243+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
16244+
16245+#ifdef CONFIG_PAX_KERNEXEC
16246+ " movl %0, %%cr0\n"
16247+#endif
16248+
16249 " jmp 2b\n"
16250 ".previous\n"
16251- _ASM_EXTABLE(1b, 3b) : : "r" (from));
16252+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
16253
16254 for (i = 0; i < 4096/64; i++) {
16255 __asm__ __volatile__ (
16256- "1: prefetch 320(%0)\n"
16257- "2: movq (%0), %%mm0\n"
16258- " movq 8(%0), %%mm1\n"
16259- " movq 16(%0), %%mm2\n"
16260- " movq 24(%0), %%mm3\n"
16261- " movq %%mm0, (%1)\n"
16262- " movq %%mm1, 8(%1)\n"
16263- " movq %%mm2, 16(%1)\n"
16264- " movq %%mm3, 24(%1)\n"
16265- " movq 32(%0), %%mm0\n"
16266- " movq 40(%0), %%mm1\n"
16267- " movq 48(%0), %%mm2\n"
16268- " movq 56(%0), %%mm3\n"
16269- " movq %%mm0, 32(%1)\n"
16270- " movq %%mm1, 40(%1)\n"
16271- " movq %%mm2, 48(%1)\n"
16272- " movq %%mm3, 56(%1)\n"
16273+ "1: prefetch 320(%1)\n"
16274+ "2: movq (%1), %%mm0\n"
16275+ " movq 8(%1), %%mm1\n"
16276+ " movq 16(%1), %%mm2\n"
16277+ " movq 24(%1), %%mm3\n"
16278+ " movq %%mm0, (%2)\n"
16279+ " movq %%mm1, 8(%2)\n"
16280+ " movq %%mm2, 16(%2)\n"
16281+ " movq %%mm3, 24(%2)\n"
16282+ " movq 32(%1), %%mm0\n"
16283+ " movq 40(%1), %%mm1\n"
16284+ " movq 48(%1), %%mm2\n"
16285+ " movq 56(%1), %%mm3\n"
16286+ " movq %%mm0, 32(%2)\n"
16287+ " movq %%mm1, 40(%2)\n"
16288+ " movq %%mm2, 48(%2)\n"
16289+ " movq %%mm3, 56(%2)\n"
16290 ".section .fixup, \"ax\"\n"
16291- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16292+ "3:\n"
16293+
16294+#ifdef CONFIG_PAX_KERNEXEC
16295+ " movl %%cr0, %0\n"
16296+ " movl %0, %%eax\n"
16297+ " andl $0xFFFEFFFF, %%eax\n"
16298+ " movl %%eax, %%cr0\n"
16299+#endif
16300+
16301+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16302+
16303+#ifdef CONFIG_PAX_KERNEXEC
16304+ " movl %0, %%cr0\n"
16305+#endif
16306+
16307 " jmp 2b\n"
16308 ".previous\n"
16309 _ASM_EXTABLE(1b, 3b)
16310- : : "r" (from), "r" (to) : "memory");
16311+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
16312
16313 from += 64;
16314 to += 64;
16454cff
MT
16315diff -urNp linux-2.6.38.1/arch/x86/lib/putuser.S linux-2.6.38.1/arch/x86/lib/putuser.S
16316--- linux-2.6.38.1/arch/x86/lib/putuser.S 2011-03-14 21:20:32.000000000 -0400
16317+++ linux-2.6.38.1/arch/x86/lib/putuser.S 2011-03-21 18:31:35.000000000 -0400
df50ba0c 16318@@ -15,7 +15,8 @@
58c5fc13
MT
16319 #include <asm/thread_info.h>
16320 #include <asm/errno.h>
16321 #include <asm/asm.h>
df50ba0c 16322-
58c5fc13 16323+#include <asm/segment.h>
df50ba0c 16324+#include <asm/pgtable.h>
58c5fc13
MT
16325
16326 /*
df50ba0c 16327 * __put_user_X
bc901d79 16328@@ -29,52 +30,119 @@
ae4e228f
MT
16329 * as they get called from within inline assembly.
16330 */
16331
16332-#define ENTER CFI_STARTPROC ; \
16333- GET_THREAD_INFO(%_ASM_BX)
16334+#define ENTER CFI_STARTPROC
16335 #define EXIT ret ; \
16336 CFI_ENDPROC
16337
57199397
MT
16338+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16339+#define _DEST %_ASM_CX,%_ASM_BX
16340+#else
16341+#define _DEST %_ASM_CX
16342+#endif
bc901d79
MT
16343+
16344+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16454cff 16345+#define __copyuser_seg gs;
bc901d79
MT
16346+#else
16347+#define __copyuser_seg
16348+#endif
57199397 16349+
ae4e228f
MT
16350 .text
16351 ENTRY(__put_user_1)
58c5fc13 16352 ENTER
58c5fc13 16353+
bc901d79 16354+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
ae4e228f
MT
16355+ GET_THREAD_INFO(%_ASM_BX)
16356 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
16357 jae bad_put_user
57199397 16358-1: movb %al,(%_ASM_CX)
df50ba0c
MT
16359+
16360+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16361+ mov $PAX_USER_SHADOW_BASE,%_ASM_BX
16362+ cmp %_ASM_BX,%_ASM_CX
57199397
MT
16363+ jb 1234f
16364+ xor %ebx,%ebx
df50ba0c
MT
16365+1234:
16366+#endif
16367+
58c5fc13
MT
16368+#endif
16369+
16454cff 16370+1: __copyuser_seg movb %al,(_DEST)
58c5fc13
MT
16371 xor %eax,%eax
16372 EXIT
16373 ENDPROC(__put_user_1)
ae4e228f
MT
16374
16375 ENTRY(__put_user_2)
16376 ENTER
58c5fc13 16377+
bc901d79 16378+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
ae4e228f
MT
16379+ GET_THREAD_INFO(%_ASM_BX)
16380 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
16381 sub $1,%_ASM_BX
16382 cmp %_ASM_BX,%_ASM_CX
16383 jae bad_put_user
57199397 16384-2: movw %ax,(%_ASM_CX)
df50ba0c
MT
16385+
16386+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16387+ mov $PAX_USER_SHADOW_BASE,%_ASM_BX
16388+ cmp %_ASM_BX,%_ASM_CX
57199397
MT
16389+ jb 1234f
16390+ xor %ebx,%ebx
df50ba0c
MT
16391+1234:
16392+#endif
16393+
58c5fc13
MT
16394+#endif
16395+
16454cff 16396+2: __copyuser_seg movw %ax,(_DEST)
58c5fc13
MT
16397 xor %eax,%eax
16398 EXIT
16399 ENDPROC(__put_user_2)
ae4e228f
MT
16400
16401 ENTRY(__put_user_4)
16402 ENTER
58c5fc13 16403+
bc901d79 16404+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
ae4e228f
MT
16405+ GET_THREAD_INFO(%_ASM_BX)
16406 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
16407 sub $3,%_ASM_BX
16408 cmp %_ASM_BX,%_ASM_CX
16409 jae bad_put_user
57199397 16410-3: movl %eax,(%_ASM_CX)
df50ba0c
MT
16411+
16412+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16413+ mov $PAX_USER_SHADOW_BASE,%_ASM_BX
16414+ cmp %_ASM_BX,%_ASM_CX
57199397
MT
16415+ jb 1234f
16416+ xor %ebx,%ebx
df50ba0c
MT
16417+1234:
16418+#endif
16419+
58c5fc13
MT
16420+#endif
16421+
16454cff 16422+3: __copyuser_seg movl %eax,(_DEST)
58c5fc13
MT
16423 xor %eax,%eax
16424 EXIT
16425 ENDPROC(__put_user_4)
ae4e228f
MT
16426
16427 ENTRY(__put_user_8)
16428 ENTER
58c5fc13 16429+
bc901d79 16430+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
ae4e228f
MT
16431+ GET_THREAD_INFO(%_ASM_BX)
16432 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
16433 sub $7,%_ASM_BX
16434 cmp %_ASM_BX,%_ASM_CX
16435 jae bad_put_user
57199397 16436-4: mov %_ASM_AX,(%_ASM_CX)
df50ba0c
MT
16437+
16438+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16439+ mov $PAX_USER_SHADOW_BASE,%_ASM_BX
16440+ cmp %_ASM_BX,%_ASM_CX
57199397
MT
16441+ jb 1234f
16442+ xor %ebx,%ebx
df50ba0c
MT
16443+1234:
16444+#endif
16445+
58c5fc13
MT
16446+#endif
16447+
16454cff 16448+4: __copyuser_seg mov %_ASM_AX,(_DEST)
58c5fc13 16449 #ifdef CONFIG_X86_32
57199397 16450-5: movl %edx,4(%_ASM_CX)
16454cff 16451+5: __copyuser_seg movl %edx,4(_DEST)
58c5fc13 16452 #endif
58c5fc13
MT
16453 xor %eax,%eax
16454 EXIT
16454cff
MT
16455diff -urNp linux-2.6.38.1/arch/x86/lib/usercopy_32.c linux-2.6.38.1/arch/x86/lib/usercopy_32.c
16456--- linux-2.6.38.1/arch/x86/lib/usercopy_32.c 2011-03-14 21:20:32.000000000 -0400
16457+++ linux-2.6.38.1/arch/x86/lib/usercopy_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
16458@@ -43,7 +43,7 @@ do { \
16459 __asm__ __volatile__( \
16460 " testl %1,%1\n" \
16461 " jz 2f\n" \
58c5fc13 16462- "0: lodsb\n" \
16454cff 16463+ "0: "__copyuser_seg"lodsb\n" \
bc901d79
MT
16464 " stosb\n" \
16465 " testb %%al,%%al\n" \
16466 " jz 1f\n" \
16467@@ -128,10 +128,12 @@ do { \
16468 int __d0; \
16469 might_fault(); \
16470 __asm__ __volatile__( \
16471+ __COPYUSER_SET_ES \
16472 "0: rep; stosl\n" \
16473 " movl %2,%0\n" \
16474 "1: rep; stosb\n" \
16475 "2:\n" \
16476+ __COPYUSER_RESTORE_ES \
16477 ".section .fixup,\"ax\"\n" \
16478 "3: lea 0(%2,%0,4),%0\n" \
16479 " jmp 2b\n" \
16480@@ -200,6 +202,7 @@ long strnlen_user(const char __user *s,
58c5fc13
MT
16481 might_fault();
16482
16483 __asm__ __volatile__(
bc901d79 16484+ __COPYUSER_SET_ES
58c5fc13
MT
16485 " testl %0, %0\n"
16486 " jz 3f\n"
bc901d79
MT
16487 " andl %0,%%ecx\n"
16488@@ -208,6 +211,7 @@ long strnlen_user(const char __user *s,
58c5fc13
MT
16489 " subl %%ecx,%0\n"
16490 " addl %0,%%eax\n"
16491 "1:\n"
bc901d79 16492+ __COPYUSER_RESTORE_ES
58c5fc13
MT
16493 ".section .fixup,\"ax\"\n"
16494 "2: xorl %%eax,%%eax\n"
16495 " jmp 1b\n"
bc901d79 16496@@ -227,7 +231,7 @@ EXPORT_SYMBOL(strnlen_user);
58c5fc13
MT
16497
16498 #ifdef CONFIG_X86_INTEL_USERCOPY
16499 static unsigned long
16500-__copy_user_intel(void __user *to, const void *from, unsigned long size)
16501+__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
bc901d79
MT
16502 {
16503 int d0, d1;
16504 __asm__ __volatile__(
16505@@ -239,36 +243,36 @@ __copy_user_intel(void __user *to, const
16506 " .align 2,0x90\n"
16507 "3: movl 0(%4), %%eax\n"
16508 "4: movl 4(%4), %%edx\n"
16509- "5: movl %%eax, 0(%3)\n"
16510- "6: movl %%edx, 4(%3)\n"
16454cff
MT
16511+ "5: "__copyuser_seg" movl %%eax, 0(%3)\n"
16512+ "6: "__copyuser_seg" movl %%edx, 4(%3)\n"
bc901d79
MT
16513 "7: movl 8(%4), %%eax\n"
16514 "8: movl 12(%4),%%edx\n"
16515- "9: movl %%eax, 8(%3)\n"
16516- "10: movl %%edx, 12(%3)\n"
16454cff
MT
16517+ "9: "__copyuser_seg" movl %%eax, 8(%3)\n"
16518+ "10: "__copyuser_seg" movl %%edx, 12(%3)\n"
bc901d79
MT
16519 "11: movl 16(%4), %%eax\n"
16520 "12: movl 20(%4), %%edx\n"
16521- "13: movl %%eax, 16(%3)\n"
16522- "14: movl %%edx, 20(%3)\n"
16454cff
MT
16523+ "13: "__copyuser_seg" movl %%eax, 16(%3)\n"
16524+ "14: "__copyuser_seg" movl %%edx, 20(%3)\n"
bc901d79
MT
16525 "15: movl 24(%4), %%eax\n"
16526 "16: movl 28(%4), %%edx\n"
16527- "17: movl %%eax, 24(%3)\n"
16528- "18: movl %%edx, 28(%3)\n"
16454cff
MT
16529+ "17: "__copyuser_seg" movl %%eax, 24(%3)\n"
16530+ "18: "__copyuser_seg" movl %%edx, 28(%3)\n"
bc901d79
MT
16531 "19: movl 32(%4), %%eax\n"
16532 "20: movl 36(%4), %%edx\n"
16533- "21: movl %%eax, 32(%3)\n"
16534- "22: movl %%edx, 36(%3)\n"
16454cff
MT
16535+ "21: "__copyuser_seg" movl %%eax, 32(%3)\n"
16536+ "22: "__copyuser_seg" movl %%edx, 36(%3)\n"
bc901d79
MT
16537 "23: movl 40(%4), %%eax\n"
16538 "24: movl 44(%4), %%edx\n"
16539- "25: movl %%eax, 40(%3)\n"
16540- "26: movl %%edx, 44(%3)\n"
16454cff
MT
16541+ "25: "__copyuser_seg" movl %%eax, 40(%3)\n"
16542+ "26: "__copyuser_seg" movl %%edx, 44(%3)\n"
bc901d79
MT
16543 "27: movl 48(%4), %%eax\n"
16544 "28: movl 52(%4), %%edx\n"
16545- "29: movl %%eax, 48(%3)\n"
16546- "30: movl %%edx, 52(%3)\n"
16454cff
MT
16547+ "29: "__copyuser_seg" movl %%eax, 48(%3)\n"
16548+ "30: "__copyuser_seg" movl %%edx, 52(%3)\n"
bc901d79
MT
16549 "31: movl 56(%4), %%eax\n"
16550 "32: movl 60(%4), %%edx\n"
16551- "33: movl %%eax, 56(%3)\n"
16552- "34: movl %%edx, 60(%3)\n"
16454cff
MT
16553+ "33: "__copyuser_seg" movl %%eax, 56(%3)\n"
16554+ "34: "__copyuser_seg" movl %%edx, 60(%3)\n"
bc901d79
MT
16555 " addl $-64, %0\n"
16556 " addl $64, %4\n"
16557 " addl $64, %3\n"
16558@@ -278,10 +282,119 @@ __copy_user_intel(void __user *to, const
16559 " shrl $2, %0\n"
16560 " andl $3, %%eax\n"
16561 " cld\n"
16562+ __COPYUSER_SET_ES
16563 "99: rep; movsl\n"
16564 "36: movl %%eax, %0\n"
16565 "37: rep; movsb\n"
16566 "100:\n"
16567+ __COPYUSER_RESTORE_ES
58c5fc13
MT
16568+ ".section .fixup,\"ax\"\n"
16569+ "101: lea 0(%%eax,%0,4),%0\n"
16570+ " jmp 100b\n"
16571+ ".previous\n"
16572+ ".section __ex_table,\"a\"\n"
16573+ " .align 4\n"
16574+ " .long 1b,100b\n"
16575+ " .long 2b,100b\n"
16576+ " .long 3b,100b\n"
16577+ " .long 4b,100b\n"
16578+ " .long 5b,100b\n"
16579+ " .long 6b,100b\n"
16580+ " .long 7b,100b\n"
16581+ " .long 8b,100b\n"
16582+ " .long 9b,100b\n"
16583+ " .long 10b,100b\n"
16584+ " .long 11b,100b\n"
16585+ " .long 12b,100b\n"
16586+ " .long 13b,100b\n"
16587+ " .long 14b,100b\n"
16588+ " .long 15b,100b\n"
16589+ " .long 16b,100b\n"
16590+ " .long 17b,100b\n"
16591+ " .long 18b,100b\n"
16592+ " .long 19b,100b\n"
16593+ " .long 20b,100b\n"
16594+ " .long 21b,100b\n"
16595+ " .long 22b,100b\n"
16596+ " .long 23b,100b\n"
16597+ " .long 24b,100b\n"
16598+ " .long 25b,100b\n"
16599+ " .long 26b,100b\n"
16600+ " .long 27b,100b\n"
16601+ " .long 28b,100b\n"
16602+ " .long 29b,100b\n"
16603+ " .long 30b,100b\n"
16604+ " .long 31b,100b\n"
16605+ " .long 32b,100b\n"
16606+ " .long 33b,100b\n"
16607+ " .long 34b,100b\n"
16608+ " .long 35b,100b\n"
16609+ " .long 36b,100b\n"
16610+ " .long 37b,100b\n"
16611+ " .long 99b,101b\n"
16612+ ".previous"
16613+ : "=&c"(size), "=&D" (d0), "=&S" (d1)
bc901d79 16614+ : "1"(to), "2"(from), "0"(size)
58c5fc13
MT
16615+ : "eax", "edx", "memory");
16616+ return size;
16617+}
16618+
16619+static unsigned long
16620+__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
bc901d79
MT
16621+{
16622+ int d0, d1;
16623+ __asm__ __volatile__(
16624+ " .align 2,0x90\n"
16454cff 16625+ "1: "__copyuser_seg" movl 32(%4), %%eax\n"
bc901d79
MT
16626+ " cmpl $67, %0\n"
16627+ " jbe 3f\n"
16454cff 16628+ "2: "__copyuser_seg" movl 64(%4), %%eax\n"
bc901d79 16629+ " .align 2,0x90\n"
16454cff
MT
16630+ "3: "__copyuser_seg" movl 0(%4), %%eax\n"
16631+ "4: "__copyuser_seg" movl 4(%4), %%edx\n"
bc901d79
MT
16632+ "5: movl %%eax, 0(%3)\n"
16633+ "6: movl %%edx, 4(%3)\n"
16454cff
MT
16634+ "7: "__copyuser_seg" movl 8(%4), %%eax\n"
16635+ "8: "__copyuser_seg" movl 12(%4),%%edx\n"
bc901d79
MT
16636+ "9: movl %%eax, 8(%3)\n"
16637+ "10: movl %%edx, 12(%3)\n"
16454cff
MT
16638+ "11: "__copyuser_seg" movl 16(%4), %%eax\n"
16639+ "12: "__copyuser_seg" movl 20(%4), %%edx\n"
bc901d79
MT
16640+ "13: movl %%eax, 16(%3)\n"
16641+ "14: movl %%edx, 20(%3)\n"
16454cff
MT
16642+ "15: "__copyuser_seg" movl 24(%4), %%eax\n"
16643+ "16: "__copyuser_seg" movl 28(%4), %%edx\n"
bc901d79
MT
16644+ "17: movl %%eax, 24(%3)\n"
16645+ "18: movl %%edx, 28(%3)\n"
16454cff
MT
16646+ "19: "__copyuser_seg" movl 32(%4), %%eax\n"
16647+ "20: "__copyuser_seg" movl 36(%4), %%edx\n"
bc901d79
MT
16648+ "21: movl %%eax, 32(%3)\n"
16649+ "22: movl %%edx, 36(%3)\n"
16454cff
MT
16650+ "23: "__copyuser_seg" movl 40(%4), %%eax\n"
16651+ "24: "__copyuser_seg" movl 44(%4), %%edx\n"
bc901d79
MT
16652+ "25: movl %%eax, 40(%3)\n"
16653+ "26: movl %%edx, 44(%3)\n"
16454cff
MT
16654+ "27: "__copyuser_seg" movl 48(%4), %%eax\n"
16655+ "28: "__copyuser_seg" movl 52(%4), %%edx\n"
bc901d79
MT
16656+ "29: movl %%eax, 48(%3)\n"
16657+ "30: movl %%edx, 52(%3)\n"
16454cff
MT
16658+ "31: "__copyuser_seg" movl 56(%4), %%eax\n"
16659+ "32: "__copyuser_seg" movl 60(%4), %%edx\n"
bc901d79
MT
16660+ "33: movl %%eax, 56(%3)\n"
16661+ "34: movl %%edx, 60(%3)\n"
16662+ " addl $-64, %0\n"
16663+ " addl $64, %4\n"
16664+ " addl $64, %3\n"
16665+ " cmpl $63, %0\n"
16666+ " ja 1b\n"
16667+ "35: movl %0, %%eax\n"
16668+ " shrl $2, %0\n"
16669+ " andl $3, %%eax\n"
16670+ " cld\n"
16454cff 16671+ "99: rep; "__copyuser_seg" movsl\n"
bc901d79 16672+ "36: movl %%eax, %0\n"
16454cff 16673+ "37: rep; "__copyuser_seg" movsb\n"
bc901d79 16674+ "100:\n"
58c5fc13
MT
16675 ".section .fixup,\"ax\"\n"
16676 "101: lea 0(%%eax,%0,4),%0\n"
16677 " jmp 100b\n"
bc901d79 16678@@ -339,41 +452,41 @@ __copy_user_zeroing_intel(void *to, cons
58c5fc13
MT
16679 int d0, d1;
16680 __asm__ __volatile__(
58c5fc13 16681 " .align 2,0x90\n"
bc901d79 16682- "0: movl 32(%4), %%eax\n"
16454cff 16683+ "0: "__copyuser_seg" movl 32(%4), %%eax\n"
58c5fc13 16684 " cmpl $67, %0\n"
bc901d79
MT
16685 " jbe 2f\n"
16686- "1: movl 64(%4), %%eax\n"
16454cff 16687+ "1: "__copyuser_seg" movl 64(%4), %%eax\n"
58c5fc13 16688 " .align 2,0x90\n"
bc901d79
MT
16689- "2: movl 0(%4), %%eax\n"
16690- "21: movl 4(%4), %%edx\n"
16454cff
MT
16691+ "2: "__copyuser_seg" movl 0(%4), %%eax\n"
16692+ "21: "__copyuser_seg" movl 4(%4), %%edx\n"
bc901d79
MT
16693 " movl %%eax, 0(%3)\n"
16694 " movl %%edx, 4(%3)\n"
16695- "3: movl 8(%4), %%eax\n"
16696- "31: movl 12(%4),%%edx\n"
16454cff
MT
16697+ "3: "__copyuser_seg" movl 8(%4), %%eax\n"
16698+ "31: "__copyuser_seg" movl 12(%4),%%edx\n"
bc901d79
MT
16699 " movl %%eax, 8(%3)\n"
16700 " movl %%edx, 12(%3)\n"
16701- "4: movl 16(%4), %%eax\n"
16702- "41: movl 20(%4), %%edx\n"
16454cff
MT
16703+ "4: "__copyuser_seg" movl 16(%4), %%eax\n"
16704+ "41: "__copyuser_seg" movl 20(%4), %%edx\n"
bc901d79
MT
16705 " movl %%eax, 16(%3)\n"
16706 " movl %%edx, 20(%3)\n"
16707- "10: movl 24(%4), %%eax\n"
16708- "51: movl 28(%4), %%edx\n"
16454cff
MT
16709+ "10: "__copyuser_seg" movl 24(%4), %%eax\n"
16710+ "51: "__copyuser_seg" movl 28(%4), %%edx\n"
bc901d79
MT
16711 " movl %%eax, 24(%3)\n"
16712 " movl %%edx, 28(%3)\n"
16713- "11: movl 32(%4), %%eax\n"
16714- "61: movl 36(%4), %%edx\n"
16454cff
MT
16715+ "11: "__copyuser_seg" movl 32(%4), %%eax\n"
16716+ "61: "__copyuser_seg" movl 36(%4), %%edx\n"
bc901d79
MT
16717 " movl %%eax, 32(%3)\n"
16718 " movl %%edx, 36(%3)\n"
16719- "12: movl 40(%4), %%eax\n"
16720- "71: movl 44(%4), %%edx\n"
16454cff
MT
16721+ "12: "__copyuser_seg" movl 40(%4), %%eax\n"
16722+ "71: "__copyuser_seg" movl 44(%4), %%edx\n"
bc901d79
MT
16723 " movl %%eax, 40(%3)\n"
16724 " movl %%edx, 44(%3)\n"
16725- "13: movl 48(%4), %%eax\n"
16726- "81: movl 52(%4), %%edx\n"
16454cff
MT
16727+ "13: "__copyuser_seg" movl 48(%4), %%eax\n"
16728+ "81: "__copyuser_seg" movl 52(%4), %%edx\n"
bc901d79
MT
16729 " movl %%eax, 48(%3)\n"
16730 " movl %%edx, 52(%3)\n"
16731- "14: movl 56(%4), %%eax\n"
16732- "91: movl 60(%4), %%edx\n"
16454cff
MT
16733+ "14: "__copyuser_seg" movl 56(%4), %%eax\n"
16734+ "91: "__copyuser_seg" movl 60(%4), %%edx\n"
bc901d79
MT
16735 " movl %%eax, 56(%3)\n"
16736 " movl %%edx, 60(%3)\n"
58c5fc13 16737 " addl $-64, %0\n"
bc901d79
MT
16738@@ -385,9 +498,9 @@ __copy_user_zeroing_intel(void *to, cons
16739 " shrl $2, %0\n"
16740 " andl $3, %%eax\n"
16741 " cld\n"
16742- "6: rep; movsl\n"
16454cff 16743+ "6: rep; "__copyuser_seg" movsl\n"
58c5fc13 16744 " movl %%eax,%0\n"
bc901d79 16745- "7: rep; movsb\n"
16454cff 16746+ "7: rep; "__copyuser_seg" movsb\n"
58c5fc13 16747 "8:\n"
58c5fc13
MT
16748 ".section .fixup,\"ax\"\n"
16749 "9: lea 0(%%eax,%0,4),%0\n"
bc901d79 16750@@ -440,41 +553,41 @@ static unsigned long __copy_user_zeroing
58c5fc13
MT
16751
16752 __asm__ __volatile__(
58c5fc13 16753 " .align 2,0x90\n"
bc901d79 16754- "0: movl 32(%4), %%eax\n"
16454cff 16755+ "0: "__copyuser_seg" movl 32(%4), %%eax\n"
58c5fc13 16756 " cmpl $67, %0\n"
bc901d79
MT
16757 " jbe 2f\n"
16758- "1: movl 64(%4), %%eax\n"
16454cff 16759+ "1: "__copyuser_seg" movl 64(%4), %%eax\n"
58c5fc13 16760 " .align 2,0x90\n"
bc901d79
MT
16761- "2: movl 0(%4), %%eax\n"
16762- "21: movl 4(%4), %%edx\n"
16454cff
MT
16763+ "2: "__copyuser_seg" movl 0(%4), %%eax\n"
16764+ "21: "__copyuser_seg" movl 4(%4), %%edx\n"
bc901d79
MT
16765 " movnti %%eax, 0(%3)\n"
16766 " movnti %%edx, 4(%3)\n"
16767- "3: movl 8(%4), %%eax\n"
16768- "31: movl 12(%4),%%edx\n"
16454cff
MT
16769+ "3: "__copyuser_seg" movl 8(%4), %%eax\n"
16770+ "31: "__copyuser_seg" movl 12(%4),%%edx\n"
bc901d79
MT
16771 " movnti %%eax, 8(%3)\n"
16772 " movnti %%edx, 12(%3)\n"
16773- "4: movl 16(%4), %%eax\n"
16774- "41: movl 20(%4), %%edx\n"
16454cff
MT
16775+ "4: "__copyuser_seg" movl 16(%4), %%eax\n"
16776+ "41: "__copyuser_seg" movl 20(%4), %%edx\n"
bc901d79
MT
16777 " movnti %%eax, 16(%3)\n"
16778 " movnti %%edx, 20(%3)\n"
16779- "10: movl 24(%4), %%eax\n"
16780- "51: movl 28(%4), %%edx\n"
16454cff
MT
16781+ "10: "__copyuser_seg" movl 24(%4), %%eax\n"
16782+ "51: "__copyuser_seg" movl 28(%4), %%edx\n"
bc901d79
MT
16783 " movnti %%eax, 24(%3)\n"
16784 " movnti %%edx, 28(%3)\n"
16785- "11: movl 32(%4), %%eax\n"
16786- "61: movl 36(%4), %%edx\n"
16454cff
MT
16787+ "11: "__copyuser_seg" movl 32(%4), %%eax\n"
16788+ "61: "__copyuser_seg" movl 36(%4), %%edx\n"
bc901d79
MT
16789 " movnti %%eax, 32(%3)\n"
16790 " movnti %%edx, 36(%3)\n"
16791- "12: movl 40(%4), %%eax\n"
16792- "71: movl 44(%4), %%edx\n"
16454cff
MT
16793+ "12: "__copyuser_seg" movl 40(%4), %%eax\n"
16794+ "71: "__copyuser_seg" movl 44(%4), %%edx\n"
bc901d79
MT
16795 " movnti %%eax, 40(%3)\n"
16796 " movnti %%edx, 44(%3)\n"
16797- "13: movl 48(%4), %%eax\n"
16798- "81: movl 52(%4), %%edx\n"
16454cff
MT
16799+ "13: "__copyuser_seg" movl 48(%4), %%eax\n"
16800+ "81: "__copyuser_seg" movl 52(%4), %%edx\n"
bc901d79
MT
16801 " movnti %%eax, 48(%3)\n"
16802 " movnti %%edx, 52(%3)\n"
16803- "14: movl 56(%4), %%eax\n"
16804- "91: movl 60(%4), %%edx\n"
16454cff
MT
16805+ "14: "__copyuser_seg" movl 56(%4), %%eax\n"
16806+ "91: "__copyuser_seg" movl 60(%4), %%edx\n"
bc901d79
MT
16807 " movnti %%eax, 56(%3)\n"
16808 " movnti %%edx, 60(%3)\n"
58c5fc13 16809 " addl $-64, %0\n"
bc901d79
MT
16810@@ -487,9 +600,9 @@ static unsigned long __copy_user_zeroing
16811 " shrl $2, %0\n"
16812 " andl $3, %%eax\n"
16813 " cld\n"
16814- "6: rep; movsl\n"
16454cff 16815+ "6: rep; "__copyuser_seg" movsl\n"
58c5fc13 16816 " movl %%eax,%0\n"
bc901d79 16817- "7: rep; movsb\n"
16454cff 16818+ "7: rep; "__copyuser_seg" movsb\n"
58c5fc13 16819 "8:\n"
58c5fc13
MT
16820 ".section .fixup,\"ax\"\n"
16821 "9: lea 0(%%eax,%0,4),%0\n"
bc901d79 16822@@ -537,41 +650,41 @@ static unsigned long __copy_user_intel_n
58c5fc13
MT
16823
16824 __asm__ __volatile__(
58c5fc13 16825 " .align 2,0x90\n"
bc901d79 16826- "0: movl 32(%4), %%eax\n"
16454cff 16827+ "0: "__copyuser_seg" movl 32(%4), %%eax\n"
58c5fc13 16828 " cmpl $67, %0\n"
bc901d79
MT
16829 " jbe 2f\n"
16830- "1: movl 64(%4), %%eax\n"
16454cff 16831+ "1: "__copyuser_seg" movl 64(%4), %%eax\n"
58c5fc13 16832 " .align 2,0x90\n"
bc901d79
MT
16833- "2: movl 0(%4), %%eax\n"
16834- "21: movl 4(%4), %%edx\n"
16454cff
MT
16835+ "2: "__copyuser_seg" movl 0(%4), %%eax\n"
16836+ "21: "__copyuser_seg" movl 4(%4), %%edx\n"
bc901d79
MT
16837 " movnti %%eax, 0(%3)\n"
16838 " movnti %%edx, 4(%3)\n"
16839- "3: movl 8(%4), %%eax\n"
16840- "31: movl 12(%4),%%edx\n"
16454cff
MT
16841+ "3: "__copyuser_seg" movl 8(%4), %%eax\n"
16842+ "31: "__copyuser_seg" movl 12(%4),%%edx\n"
bc901d79
MT
16843 " movnti %%eax, 8(%3)\n"
16844 " movnti %%edx, 12(%3)\n"
16845- "4: movl 16(%4), %%eax\n"
16846- "41: movl 20(%4), %%edx\n"
16454cff
MT
16847+ "4: "__copyuser_seg" movl 16(%4), %%eax\n"
16848+ "41: "__copyuser_seg" movl 20(%4), %%edx\n"
bc901d79
MT
16849 " movnti %%eax, 16(%3)\n"
16850 " movnti %%edx, 20(%3)\n"
16851- "10: movl 24(%4), %%eax\n"
16852- "51: movl 28(%4), %%edx\n"
16454cff
MT
16853+ "10: "__copyuser_seg" movl 24(%4), %%eax\n"
16854+ "51: "__copyuser_seg" movl 28(%4), %%edx\n"
bc901d79
MT
16855 " movnti %%eax, 24(%3)\n"
16856 " movnti %%edx, 28(%3)\n"
16857- "11: movl 32(%4), %%eax\n"
16858- "61: movl 36(%4), %%edx\n"
16454cff
MT
16859+ "11: "__copyuser_seg" movl 32(%4), %%eax\n"
16860+ "61: "__copyuser_seg" movl 36(%4), %%edx\n"
bc901d79
MT
16861 " movnti %%eax, 32(%3)\n"
16862 " movnti %%edx, 36(%3)\n"
16863- "12: movl 40(%4), %%eax\n"
16864- "71: movl 44(%4), %%edx\n"
16454cff
MT
16865+ "12: "__copyuser_seg" movl 40(%4), %%eax\n"
16866+ "71: "__copyuser_seg" movl 44(%4), %%edx\n"
bc901d79
MT
16867 " movnti %%eax, 40(%3)\n"
16868 " movnti %%edx, 44(%3)\n"
16869- "13: movl 48(%4), %%eax\n"
16870- "81: movl 52(%4), %%edx\n"
16454cff
MT
16871+ "13: "__copyuser_seg" movl 48(%4), %%eax\n"
16872+ "81: "__copyuser_seg" movl 52(%4), %%edx\n"
bc901d79
MT
16873 " movnti %%eax, 48(%3)\n"
16874 " movnti %%edx, 52(%3)\n"
16875- "14: movl 56(%4), %%eax\n"
16876- "91: movl 60(%4), %%edx\n"
16454cff
MT
16877+ "14: "__copyuser_seg" movl 56(%4), %%eax\n"
16878+ "91: "__copyuser_seg" movl 60(%4), %%edx\n"
bc901d79
MT
16879 " movnti %%eax, 56(%3)\n"
16880 " movnti %%edx, 60(%3)\n"
58c5fc13 16881 " addl $-64, %0\n"
bc901d79
MT
16882@@ -584,9 +697,9 @@ static unsigned long __copy_user_intel_n
16883 " shrl $2, %0\n"
16884 " andl $3, %%eax\n"
16885 " cld\n"
16886- "6: rep; movsl\n"
16454cff 16887+ "6: rep; "__copyuser_seg" movsl\n"
58c5fc13 16888 " movl %%eax,%0\n"
bc901d79 16889- "7: rep; movsb\n"
16454cff 16890+ "7: rep; "__copyuser_seg" movsb\n"
58c5fc13 16891 "8:\n"
58c5fc13
MT
16892 ".section .fixup,\"ax\"\n"
16893 "9: lea 0(%%eax,%0,4),%0\n"
bc901d79 16894@@ -629,32 +742,36 @@ static unsigned long __copy_user_intel_n
58c5fc13
MT
16895 */
16896 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
16897 unsigned long size);
16898-unsigned long __copy_user_intel(void __user *to, const void *from,
16899+unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
16900+ unsigned long size);
16901+unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
16902 unsigned long size);
16903 unsigned long __copy_user_zeroing_intel_nocache(void *to,
16904 const void __user *from, unsigned long size);
16905 #endif /* CONFIG_X86_INTEL_USERCOPY */
16906
16907 /* Generic arbitrary sized copy. */
16908-#define __copy_user(to, from, size) \
bc901d79
MT
16909+#define __copy_user(to, from, size, prefix, set, restore) \
16910 do { \
16911 int __d0, __d1, __d2; \
16912 __asm__ __volatile__( \
16913+ set \
16914 " cmp $7,%0\n" \
16915 " jbe 1f\n" \
16916 " movl %1,%0\n" \
16917 " negl %0\n" \
16918 " andl $7,%0\n" \
16919 " subl %0,%3\n" \
58c5fc13 16920- "4: rep; movsb\n" \
16454cff 16921+ "4: rep; "prefix"movsb\n" \
bc901d79
MT
16922 " movl %3,%0\n" \
16923 " shrl $2,%0\n" \
16924 " andl $3,%3\n" \
16925 " .align 2,0x90\n" \
58c5fc13 16926- "0: rep; movsl\n" \
16454cff 16927+ "0: rep; "prefix"movsl\n" \
bc901d79 16928 " movl %3,%0\n" \
58c5fc13 16929- "1: rep; movsb\n" \
16454cff 16930+ "1: rep; "prefix"movsb\n" \
bc901d79
MT
16931 "2:\n" \
16932+ restore \
16933 ".section .fixup,\"ax\"\n" \
16934 "5: addl %3,%0\n" \
16935 " jmp 2b\n" \
16936@@ -682,14 +799,14 @@ do { \
16937 " negl %0\n" \
16938 " andl $7,%0\n" \
16939 " subl %0,%3\n" \
58c5fc13 16940- "4: rep; movsb\n" \
16454cff 16941+ "4: rep; "__copyuser_seg"movsb\n" \
bc901d79
MT
16942 " movl %3,%0\n" \
16943 " shrl $2,%0\n" \
16944 " andl $3,%3\n" \
16945 " .align 2,0x90\n" \
58c5fc13 16946- "0: rep; movsl\n" \
16454cff 16947+ "0: rep; "__copyuser_seg"movsl\n" \
bc901d79 16948 " movl %3,%0\n" \
58c5fc13 16949- "1: rep; movsb\n" \
16454cff 16950+ "1: rep; "__copyuser_seg"movsb\n" \
bc901d79
MT
16951 "2:\n" \
16952 ".section .fixup,\"ax\"\n" \
16953 "5: addl %3,%0\n" \
16954@@ -775,9 +892,9 @@ survive:
58c5fc13
MT
16955 }
16956 #endif
16957 if (movsl_is_ok(to, from, n))
16958- __copy_user(to, from, n);
bc901d79 16959+ __copy_user(to, from, n, "", __COPYUSER_SET_ES, __COPYUSER_RESTORE_ES);
58c5fc13
MT
16960 else
16961- n = __copy_user_intel(to, from, n);
16962+ n = __generic_copy_to_user_intel(to, from, n);
16963 return n;
16964 }
16965 EXPORT_SYMBOL(__copy_to_user_ll);
bc901d79 16966@@ -797,10 +914,9 @@ unsigned long __copy_from_user_ll_nozero
58c5fc13
MT
16967 unsigned long n)
16968 {
16969 if (movsl_is_ok(to, from, n))
16970- __copy_user(to, from, n);
bc901d79 16971+ __copy_user(to, from, n, __copyuser_seg, "", "");
58c5fc13
MT
16972 else
16973- n = __copy_user_intel((void __user *)to,
16974- (const void *)from, n);
16975+ n = __generic_copy_from_user_intel(to, from, n);
16976 return n;
16977 }
16978 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
bc901d79 16979@@ -827,65 +943,49 @@ unsigned long __copy_from_user_ll_nocach
58c5fc13
MT
16980 if (n > 64 && cpu_has_xmm2)
16981 n = __copy_user_intel_nocache(to, from, n);
16982 else
16983- __copy_user(to, from, n);
bc901d79 16984+ __copy_user(to, from, n, __copyuser_seg, "", "");
58c5fc13
MT
16985 #else
16986- __copy_user(to, from, n);
bc901d79 16987+ __copy_user(to, from, n, __copyuser_seg, "", "");
58c5fc13
MT
16988 #endif
16989 return n;
16990 }
16991 EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero);
16992
16993-/**
16994- * copy_to_user: - Copy a block of data into user space.
16995- * @to: Destination address, in user space.
16996- * @from: Source address, in kernel space.
16997- * @n: Number of bytes to copy.
16998- *
16999- * Context: User context only. This function may sleep.
17000- *
17001- * Copy data from kernel space to user space.
17002- *
17003- * Returns number of bytes that could not be copied.
17004- * On success, this will be zero.
17005- */
17006-unsigned long
17007-copy_to_user(void __user *to, const void *from, unsigned long n)
ae4e228f 17008+void copy_from_user_overflow(void)
58c5fc13
MT
17009 {
17010- if (access_ok(VERIFY_WRITE, to, n))
17011- n = __copy_to_user(to, from, n);
17012- return n;
ae4e228f 17013+ WARN(1, "Buffer overflow detected!\n");
58c5fc13
MT
17014 }
17015-EXPORT_SYMBOL(copy_to_user);
ae4e228f 17016+EXPORT_SYMBOL(copy_from_user_overflow);
58c5fc13
MT
17017
17018-/**
17019- * copy_from_user: - Copy a block of data from user space.
17020- * @to: Destination address, in kernel space.
17021- * @from: Source address, in user space.
17022- * @n: Number of bytes to copy.
17023- *
17024- * Context: User context only. This function may sleep.
17025- *
17026- * Copy data from user space to kernel space.
17027- *
17028- * Returns number of bytes that could not be copied.
17029- * On success, this will be zero.
17030- *
17031- * If some data could not be copied, this function will pad the copied
17032- * data to the requested size using zero bytes.
17033- */
17034-unsigned long
ae4e228f
MT
17035-_copy_from_user(void *to, const void __user *from, unsigned long n)
17036+void copy_to_user_overflow(void)
58c5fc13
MT
17037 {
17038- if (access_ok(VERIFY_READ, from, n))
17039- n = __copy_from_user(to, from, n);
17040- else
17041- memset(to, 0, n);
17042- return n;
ae4e228f
MT
17043+ WARN(1, "Buffer overflow detected!\n");
17044 }
17045-EXPORT_SYMBOL(_copy_from_user);
17046+EXPORT_SYMBOL(copy_to_user_overflow);
17047
17048-void copy_from_user_overflow(void)
17049+#ifdef CONFIG_PAX_MEMORY_UDEREF
bc901d79 17050+void __set_fs(mm_segment_t x)
ae4e228f
MT
17051 {
17052- WARN(1, "Buffer overflow detected!\n");
bc901d79
MT
17053+ switch (x.seg) {
17054+ case 0:
17055+ loadsegment(gs, 0);
17056+ break;
17057+ case TASK_SIZE_MAX:
17058+ loadsegment(gs, __USER_DS);
17059+ break;
17060+ case -1UL:
17061+ loadsegment(gs, __KERNEL_DS);
17062+ break;
17063+ default:
17064+ BUG();
17065+ }
17066+ return;
ae4e228f
MT
17067 }
17068-EXPORT_SYMBOL(copy_from_user_overflow);
17069+
17070+void set_fs(mm_segment_t x)
17071+{
58c5fc13 17072+ current_thread_info()->addr_limit = x;
bc901d79 17073+ __set_fs(x);
58c5fc13 17074+}
58c5fc13 17075+EXPORT_SYMBOL(set_fs);
bc901d79 17076+#endif
16454cff
MT
17077diff -urNp linux-2.6.38.1/arch/x86/lib/usercopy_64.c linux-2.6.38.1/arch/x86/lib/usercopy_64.c
17078--- linux-2.6.38.1/arch/x86/lib/usercopy_64.c 2011-03-14 21:20:32.000000000 -0400
17079+++ linux-2.6.38.1/arch/x86/lib/usercopy_64.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
17080@@ -42,6 +42,8 @@ long
17081 __strncpy_from_user(char *dst, const char __user *src, long count)
17082 {
17083 long res;
17084+ if ((unsigned long)src < PAX_USER_SHADOW_BASE)
17085+ src += PAX_USER_SHADOW_BASE;
17086 __do_strncpy_from_user(dst, src, count, res);
17087 return res;
17088 }
17089@@ -65,6 +67,8 @@ unsigned long __clear_user(void __user *
17090 {
17091 long __d0;
17092 might_fault();
17093+ if ((unsigned long)addr < PAX_USER_SHADOW_BASE)
17094+ addr += PAX_USER_SHADOW_BASE;
17095 /* no memory constraint because it doesn't change any memory gcc knows
17096 about */
17097 asm volatile(
17098@@ -151,10 +155,14 @@ EXPORT_SYMBOL(strlen_user);
17099
17100 unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
17101 {
17102- if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {
17103+ if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {
17104+ if ((unsigned long)to < PAX_USER_SHADOW_BASE)
17105+ to += PAX_USER_SHADOW_BASE;
17106+ if ((unsigned long)from < PAX_USER_SHADOW_BASE)
17107+ from += PAX_USER_SHADOW_BASE;
17108 return copy_user_generic((__force void *)to, (__force void *)from, len);
17109- }
17110- return len;
17111+ }
17112+ return len;
17113 }
17114 EXPORT_SYMBOL(copy_in_user);
17115
16454cff
MT
17116diff -urNp linux-2.6.38.1/arch/x86/Makefile linux-2.6.38.1/arch/x86/Makefile
17117--- linux-2.6.38.1/arch/x86/Makefile 2011-03-14 21:20:32.000000000 -0400
17118+++ linux-2.6.38.1/arch/x86/Makefile 2011-03-21 18:31:35.000000000 -0400
bc901d79 17119@@ -195,3 +195,12 @@ define archhelp
57199397
MT
17120 echo ' FDARGS="..." arguments for the booted kernel'
17121 echo ' FDINITRD=file initrd for the booted kernel'
17122 endef
17123+
17124+define OLD_LD
17125+
17126+*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
17127+*** Please upgrade your binutils to 2.18 or newer
17128+endef
17129+
17130+archprepare:
17131+ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
16454cff
MT
17132diff -urNp linux-2.6.38.1/arch/x86/mm/extable.c linux-2.6.38.1/arch/x86/mm/extable.c
17133--- linux-2.6.38.1/arch/x86/mm/extable.c 2011-03-14 21:20:32.000000000 -0400
17134+++ linux-2.6.38.1/arch/x86/mm/extable.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 17135@@ -1,14 +1,71 @@
58c5fc13
MT
17136 #include <linux/module.h>
17137 #include <linux/spinlock.h>
17138+#include <linux/sort.h>
17139 #include <asm/uaccess.h>
ae4e228f 17140+#include <asm/pgtable.h>
58c5fc13
MT
17141
17142+/*
17143+ * The exception table needs to be sorted so that the binary
17144+ * search that we use to find entries in it works properly.
17145+ * This is used both for the kernel exception table and for
17146+ * the exception tables of modules that get loaded.
17147+ */
17148+static int cmp_ex(const void *a, const void *b)
17149+{
17150+ const struct exception_table_entry *x = a, *y = b;
17151+
17152+ /* avoid overflow */
17153+ if (x->insn > y->insn)
17154+ return 1;
17155+ if (x->insn < y->insn)
17156+ return -1;
17157+ return 0;
17158+}
17159+
17160+static void swap_ex(void *a, void *b, int size)
17161+{
17162+ struct exception_table_entry t, *x = a, *y = b;
17163+
58c5fc13
MT
17164+ t = *x;
17165+
ae4e228f 17166+ pax_open_kernel();
58c5fc13
MT
17167+ *x = *y;
17168+ *y = t;
ae4e228f 17169+ pax_close_kernel();
58c5fc13
MT
17170+}
17171+
17172+void sort_extable(struct exception_table_entry *start,
17173+ struct exception_table_entry *finish)
17174+{
17175+ sort(start, finish - start, sizeof(struct exception_table_entry),
17176+ cmp_ex, swap_ex);
17177+}
17178+
17179+#ifdef CONFIG_MODULES
17180+/*
17181+ * If the exception table is sorted, any referring to the module init
17182+ * will be at the beginning or the end.
17183+ */
17184+void trim_init_extable(struct module *m)
17185+{
17186+ /*trim the beginning*/
17187+ while (m->num_exentries && within_module_init(m->extable[0].insn, m)) {
17188+ m->extable++;
17189+ m->num_exentries--;
17190+ }
17191+ /*trim the end*/
17192+ while (m->num_exentries &&
17193+ within_module_init(m->extable[m->num_exentries-1].insn, m))
17194+ m->num_exentries--;
17195+}
17196+#endif /* CONFIG_MODULES */
17197
17198 int fixup_exception(struct pt_regs *regs)
17199 {
17200 const struct exception_table_entry *fixup;
17201
17202 #ifdef CONFIG_PNPBIOS
17203- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
17204+ if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
17205 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
17206 extern u32 pnp_bios_is_utter_crap;
17207 pnp_bios_is_utter_crap = 1;
16454cff
MT
17208diff -urNp linux-2.6.38.1/arch/x86/mm/fault.c linux-2.6.38.1/arch/x86/mm/fault.c
17209--- linux-2.6.38.1/arch/x86/mm/fault.c 2011-03-14 21:20:32.000000000 -0400
17210+++ linux-2.6.38.1/arch/x86/mm/fault.c 2011-03-21 23:48:53.000000000 -0400
bc901d79 17211@@ -12,10 +12,18 @@
58c5fc13 17212 #include <linux/mmiotrace.h> /* kmmio_handler, ... */
ae4e228f 17213 #include <linux/perf_event.h> /* perf_sw_event */
bc901d79 17214 #include <linux/hugetlb.h> /* hstate_index_to_shift */
58c5fc13
MT
17215+#include <linux/unistd.h>
17216+#include <linux/compiler.h>
17217
17218 #include <asm/traps.h> /* dotraplinkage, ... */
17219 #include <asm/pgalloc.h> /* pgd_*(), ... */
17220 #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
17221+#include <asm/vsyscall.h>
17222+#include <asm/tlbflush.h>
df50ba0c
MT
17223+
17224+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
17225+#include <asm/stacktrace.h>
df50ba0c 17226+#endif
58c5fc13
MT
17227
17228 /*
17229 * Page fault error code bits:
bc901d79 17230@@ -53,7 +61,7 @@ static inline int __kprobes notify_page_
58c5fc13
MT
17231 int ret = 0;
17232
17233 /* kprobe_running() needs smp_processor_id() */
17234- if (kprobes_built_in() && !user_mode_vm(regs)) {
17235+ if (kprobes_built_in() && !user_mode(regs)) {
17236 preempt_disable();
17237 if (kprobe_running() && kprobe_fault_handler(regs, 14))
17238 ret = 1;
bc901d79
MT
17239@@ -114,7 +122,10 @@ check_prefetch_opcode(struct pt_regs *re
17240 return !instr_lo || (instr_lo>>1) == 1;
17241 case 0x00:
17242 /* Prefetch instruction is 0x0F0D or 0x0F18 */
17243- if (probe_kernel_address(instr, opcode))
17244+ if (user_mode(regs)) {
17245+ if (__copy_from_user_inatomic(&opcode, (__force unsigned char __user *)(instr), 1))
17246+ return 0;
17247+ } else if (probe_kernel_address(instr, opcode))
17248 return 0;
17249
17250 *prefetch = (instr_lo == 0xF) &&
17251@@ -148,7 +159,10 @@ is_prefetch(struct pt_regs *regs, unsign
17252 while (instr < max_instr) {
17253 unsigned char opcode;
17254
17255- if (probe_kernel_address(instr, opcode))
17256+ if (user_mode(regs)) {
17257+ if (__copy_from_user_inatomic(&opcode, (__force unsigned char __user *)(instr), 1))
17258+ break;
17259+ } else if (probe_kernel_address(instr, opcode))
17260 break;
17261
17262 instr++;
17263@@ -179,6 +193,30 @@ force_sig_info_fault(int si_signo, int s
58c5fc13
MT
17264 force_sig_info(si_signo, &info, tsk);
17265 }
17266
17267+#ifdef CONFIG_PAX_EMUTRAMP
17268+static int pax_handle_fetch_fault(struct pt_regs *regs);
17269+#endif
17270+
17271+#ifdef CONFIG_PAX_PAGEEXEC
17272+static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
17273+{
17274+ pgd_t *pgd;
17275+ pud_t *pud;
17276+ pmd_t *pmd;
17277+
17278+ pgd = pgd_offset(mm, address);
17279+ if (!pgd_present(*pgd))
17280+ return NULL;
17281+ pud = pud_offset(pgd, address);
17282+ if (!pud_present(*pud))
17283+ return NULL;
17284+ pmd = pmd_offset(pud, address);
17285+ if (!pmd_present(*pmd))
17286+ return NULL;
17287+ return pmd;
17288+}
17289+#endif
17290+
17291 DEFINE_SPINLOCK(pgd_lock);
17292 LIST_HEAD(pgd_list);
17293
16454cff
MT
17294@@ -229,10 +267,22 @@ void vmalloc_sync_all(void)
17295 for (address = VMALLOC_START & PMD_MASK;
17296 address >= TASK_SIZE && address < FIXADDR_TOP;
df50ba0c 17297 address += PMD_SIZE) {
df50ba0c
MT
17298+
17299+#ifdef CONFIG_PAX_PER_CPU_PGD
17300+ unsigned long cpu;
17301+#else
17302 struct page *page;
17303+#endif
17304
16454cff 17305 spin_lock(&pgd_lock);
df50ba0c
MT
17306+
17307+#ifdef CONFIG_PAX_PER_CPU_PGD
17308+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
17309+ pgd_t *pgd = get_cpu_pgd(cpu);
bc901d79 17310+ pmd_t *ret;
df50ba0c
MT
17311+#else
17312 list_for_each_entry(page, &pgd_list, lru) {
df50ba0c 17313+ pgd_t *pgd = page_address(page);
bc901d79
MT
17314 spinlock_t *pgt_lock;
17315 pmd_t *ret;
17316
16454cff 17317@@ -240,8 +290,13 @@ void vmalloc_sync_all(void)
bc901d79
MT
17318 pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
17319
17320 spin_lock(pgt_lock);
17321- ret = vmalloc_sync_one(page_address(page), address);
df50ba0c
MT
17322+#endif
17323+
bc901d79
MT
17324+ ret = vmalloc_sync_one(pgd, address);
17325+
17326+#ifndef CONFIG_PAX_PER_CPU_PGD
17327 spin_unlock(pgt_lock);
17328+#endif
17329
17330 if (!ret)
df50ba0c 17331 break;
16454cff 17332@@ -275,6 +330,11 @@ static noinline __kprobes int vmalloc_fa
df50ba0c
MT
17333 * an interrupt in the middle of a task switch..
17334 */
17335 pgd_paddr = read_cr3();
17336+
17337+#ifdef CONFIG_PAX_PER_CPU_PGD
17338+ BUG_ON(__pa(get_cpu_pgd(smp_processor_id())) != (pgd_paddr & PHYSICAL_PAGE_MASK));
17339+#endif
17340+
17341 pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
17342 if (!pmd_k)
17343 return -1;
16454cff 17344@@ -370,7 +430,14 @@ static noinline __kprobes int vmalloc_fa
df50ba0c
MT
17345 * happen within a race in page table update. In the later
17346 * case just flush:
17347 */
17348+
17349+#ifdef CONFIG_PAX_PER_CPU_PGD
17350+ BUG_ON(__pa(get_cpu_pgd(smp_processor_id())) != (read_cr3() & PHYSICAL_PAGE_MASK));
17351+ pgd = pgd_offset_cpu(smp_processor_id(), address);
17352+#else
17353 pgd = pgd_offset(current->active_mm, address);
17354+#endif
17355+
17356 pgd_ref = pgd_offset_k(address);
17357 if (pgd_none(*pgd_ref))
17358 return -1;
16454cff 17359@@ -532,7 +599,7 @@ static int is_errata93(struct pt_regs *r
58c5fc13
MT
17360 static int is_errata100(struct pt_regs *regs, unsigned long address)
17361 {
17362 #ifdef CONFIG_X86_64
17363- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32))
17364+ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) && (address >> 32))
17365 return 1;
17366 #endif
17367 return 0;
16454cff 17368@@ -559,7 +626,7 @@ static int is_f00f_bug(struct pt_regs *r
58c5fc13
MT
17369 }
17370
17371 static const char nx_warning[] = KERN_CRIT
17372-"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n";
17373+"kernel tried to execute NX-protected page - exploit attempt? (uid: %d, task: %s, pid: %d)\n";
17374
17375 static void
17376 show_fault_oops(struct pt_regs *regs, unsigned long error_code,
16454cff 17377@@ -568,15 +635,26 @@ show_fault_oops(struct pt_regs *regs, un
58c5fc13
MT
17378 if (!oops_may_print())
17379 return;
17380
17381- if (error_code & PF_INSTR) {
ae4e228f 17382+ if ((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR)) {
58c5fc13
MT
17383 unsigned int level;
17384
17385 pte_t *pte = lookup_address(address, &level);
17386
17387 if (pte && pte_present(*pte) && !pte_exec(*pte))
17388- printk(nx_warning, current_uid());
17389+ printk(nx_warning, current_uid(), current->comm, task_pid_nr(current));
17390 }
17391
17392+#ifdef CONFIG_PAX_KERNEXEC
ae4e228f 17393+ if (init_mm.start_code <= address && address < init_mm.end_code) {
58c5fc13 17394+ if (current->signal->curr_ip)
ae4e228f
MT
17395+ printk(KERN_ERR "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
17396+ &current->signal->curr_ip, current->comm, task_pid_nr(current), current_uid(), current_euid());
58c5fc13
MT
17397+ else
17398+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
17399+ current->comm, task_pid_nr(current), current_uid(), current_euid());
17400+ }
17401+#endif
17402+
17403 printk(KERN_ALERT "BUG: unable to handle kernel ");
17404 if (address < PAGE_SIZE)
17405 printk(KERN_CONT "NULL pointer dereference");
16454cff 17406@@ -701,6 +779,68 @@ __bad_area_nosemaphore(struct pt_regs *r
58c5fc13
MT
17407 unsigned long address, int si_code)
17408 {
17409 struct task_struct *tsk = current;
17410+ struct mm_struct *mm = tsk->mm;
17411+
17412+#ifdef CONFIG_X86_64
6892158b 17413+ if (mm && (error_code & PF_INSTR) && mm->context.vdso) {
58c5fc13
MT
17414+ if (regs->ip == (unsigned long)vgettimeofday) {
17415+ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_gettimeofday);
17416+ return;
17417+ } else if (regs->ip == (unsigned long)vtime) {
17418+ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_time);
17419+ return;
17420+ } else if (regs->ip == (unsigned long)vgetcpu) {
17421+ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, getcpu);
17422+ return;
17423+ }
17424+ }
17425+#endif
17426+
17427+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17428+ if (mm && (error_code & PF_USER)) {
17429+ unsigned long ip = regs->ip;
17430+
17431+ if (v8086_mode(regs))
6892158b 17432+ ip = ((regs->cs & 0xffff) << 4) + (ip & 0xffff);
58c5fc13
MT
17433+
17434+ /*
17435+ * It's possible to have interrupts off here:
17436+ */
17437+ local_irq_enable();
17438+
17439+#ifdef CONFIG_PAX_PAGEEXEC
17440+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
6892158b 17441+ (((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && ip == address))) {
58c5fc13
MT
17442+
17443+#ifdef CONFIG_PAX_EMUTRAMP
17444+ switch (pax_handle_fetch_fault(regs)) {
17445+ case 2:
17446+ return;
17447+ }
17448+#endif
17449+
6892158b 17450+ pax_report_fault(regs, (void *)ip, (void *)regs->sp);
58c5fc13
MT
17451+ do_group_exit(SIGKILL);
17452+ }
17453+#endif
17454+
17455+#ifdef CONFIG_PAX_SEGMEXEC
6892158b 17456+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (ip + SEGMEXEC_TASK_SIZE == address)) {
58c5fc13
MT
17457+
17458+#ifdef CONFIG_PAX_EMUTRAMP
17459+ switch (pax_handle_fetch_fault(regs)) {
17460+ case 2:
17461+ return;
17462+ }
17463+#endif
17464+
6892158b 17465+ pax_report_fault(regs, (void *)ip, (void *)regs->sp);
58c5fc13
MT
17466+ do_group_exit(SIGKILL);
17467+ }
17468+#endif
17469+
17470+ }
17471+#endif
17472
17473 /* User mode accesses just cause a SIGSEGV */
17474 if (error_code & PF_USER) {
16454cff 17475@@ -855,6 +995,99 @@ static int spurious_fault_check(unsigned
58c5fc13
MT
17476 return 1;
17477 }
17478
17479+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
17480+static int pax_handle_pageexec_fault(struct pt_regs *regs, struct mm_struct *mm, unsigned long address, unsigned long error_code)
17481+{
17482+ pte_t *pte;
17483+ pmd_t *pmd;
17484+ spinlock_t *ptl;
17485+ unsigned char pte_mask;
17486+
ae4e228f 17487+ if ((__supported_pte_mask & _PAGE_NX) || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
58c5fc13
MT
17488+ !(mm->pax_flags & MF_PAX_PAGEEXEC))
17489+ return 0;
17490+
17491+ /* PaX: it's our fault, let's handle it if we can */
17492+
17493+ /* PaX: take a look at read faults before acquiring any locks */
17494+ if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
17495+ /* instruction fetch attempt from a protected page in user mode */
17496+ up_read(&mm->mmap_sem);
17497+
17498+#ifdef CONFIG_PAX_EMUTRAMP
17499+ switch (pax_handle_fetch_fault(regs)) {
17500+ case 2:
17501+ return 1;
17502+ }
17503+#endif
17504+
17505+ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
17506+ do_group_exit(SIGKILL);
17507+ }
17508+
17509+ pmd = pax_get_pmd(mm, address);
17510+ if (unlikely(!pmd))
17511+ return 0;
17512+
17513+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
17514+ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
17515+ pte_unmap_unlock(pte, ptl);
17516+ return 0;
17517+ }
17518+
17519+ if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
17520+ /* write attempt to a protected page in user mode */
17521+ pte_unmap_unlock(pte, ptl);
17522+ return 0;
17523+ }
17524+
17525+#ifdef CONFIG_SMP
17526+ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
17527+#else
17528+ if (likely(address > get_limit(regs->cs)))
17529+#endif
17530+ {
17531+ set_pte(pte, pte_mkread(*pte));
17532+ __flush_tlb_one(address);
17533+ pte_unmap_unlock(pte, ptl);
17534+ up_read(&mm->mmap_sem);
17535+ return 1;
17536+ }
17537+
17538+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
17539+
17540+ /*
17541+ * PaX: fill DTLB with user rights and retry
17542+ */
17543+ __asm__ __volatile__ (
58c5fc13
MT
17544+ "orb %2,(%1)\n"
17545+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
17546+/*
17547+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
17548+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
17549+ * page fault when examined during a TLB load attempt. this is true not only
17550+ * for PTEs holding a non-present entry but also present entries that will
17551+ * raise a page fault (such as those set up by PaX, or the copy-on-write
17552+ * mechanism). in effect it means that we do *not* need to flush the TLBs
17553+ * for our target pages since their PTEs are simply not in the TLBs at all.
17554+
17555+ * the best thing in omitting it is that we gain around 15-20% speed in the
17556+ * fast path of the page fault handler and can get rid of tracing since we
17557+ * can no longer flush unintended entries.
17558+ */
17559+ "invlpg (%0)\n"
17560+#endif
16454cff 17561+ __copyuser_seg"testb $0,(%0)\n"
58c5fc13 17562+ "xorb %3,(%1)\n"
58c5fc13 17563+ :
bc901d79 17564+ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER)
58c5fc13
MT
17565+ : "memory", "cc");
17566+ pte_unmap_unlock(pte, ptl);
17567+ up_read(&mm->mmap_sem);
17568+ return 1;
17569+}
17570+#endif
17571+
17572 /*
17573 * Handle a spurious fault caused by a stale TLB entry.
17574 *
16454cff 17575@@ -927,6 +1160,9 @@ int show_unhandled_signals = 1;
58c5fc13 17576 static inline int
bc901d79 17577 access_error(unsigned long error_code, struct vm_area_struct *vma)
58c5fc13 17578 {
ae4e228f 17579+ if ((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
58c5fc13
MT
17580+ return 1;
17581+
bc901d79 17582 if (error_code & PF_WRITE) {
58c5fc13
MT
17583 /* write, present and write, not present: */
17584 if (unlikely(!(vma->vm_flags & VM_WRITE)))
16454cff 17585@@ -960,19 +1196,33 @@ do_page_fault(struct pt_regs *regs, unsi
58c5fc13
MT
17586 {
17587 struct vm_area_struct *vma;
17588 struct task_struct *tsk;
17589- unsigned long address;
17590 struct mm_struct *mm;
58c5fc13 17591 int fault;
bc901d79
MT
17592 int write = error_code & PF_WRITE;
17593 unsigned int flags = FAULT_FLAG_ALLOW_RETRY |
17594 (write ? FAULT_FLAG_WRITE : 0);
58c5fc13
MT
17595
17596+ /* Get the faulting address: */
df50ba0c
MT
17597+ unsigned long address = read_cr2();
17598+
17599+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
17600+ if (!user_mode(regs) && address < 2 * PAX_USER_SHADOW_BASE) {
17601+ if (!search_exception_tables(regs->ip)) {
17602+ bad_area_nosemaphore(regs, error_code, address);
17603+ return;
17604+ }
17605+ if (address < PAX_USER_SHADOW_BASE) {
17606+ printk(KERN_ERR "PAX: please report this to pageexec@freemail.hu\n");
bc901d79 17607+ printk(KERN_ERR "PAX: faulting IP: %pA\n", (void *)regs->ip);
16454cff 17608+ show_trace_log_lvl(NULL, NULL, (void *)regs->sp, KERN_ERR);
df50ba0c
MT
17609+ } else
17610+ address -= PAX_USER_SHADOW_BASE;
17611+ }
17612+#endif
58c5fc13
MT
17613+
17614 tsk = current;
17615 mm = tsk->mm;
17616
17617- /* Get the faulting address: */
17618- address = read_cr2();
17619-
17620 /*
17621 * Detect and handle instructions that would cause a page fault for
17622 * both a tracked kernel page and a userspace page.
16454cff 17623@@ -1032,7 +1282,7 @@ do_page_fault(struct pt_regs *regs, unsi
58c5fc13
MT
17624 * User-mode registers count as a user access even for any
17625 * potential system fault or CPU buglet:
17626 */
17627- if (user_mode_vm(regs)) {
17628+ if (user_mode(regs)) {
17629 local_irq_enable();
17630 error_code |= PF_USER;
17631 } else {
16454cff 17632@@ -1087,6 +1337,11 @@ retry:
58c5fc13
MT
17633 might_sleep();
17634 }
17635
17636+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
17637+ if (pax_handle_pageexec_fault(regs, mm, address, error_code))
17638+ return;
17639+#endif
17640+
17641 vma = find_vma(mm, address);
17642 if (unlikely(!vma)) {
17643 bad_area(regs, error_code, address);
16454cff 17644@@ -1098,18 +1353,24 @@ retry:
58c5fc13
MT
17645 bad_area(regs, error_code, address);
17646 return;
17647 }
17648- if (error_code & PF_USER) {
17649- /*
17650- * Accessing the stack below %sp is always a bug.
17651- * The large cushion allows instructions like enter
17652- * and pusha to work. ("enter $65535, $31" pushes
17653- * 32 pointers and then decrements %sp by 65535.)
17654- */
17655- if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
17656- bad_area(regs, error_code, address);
17657- return;
17658- }
17659+ /*
17660+ * Accessing the stack below %sp is always a bug.
17661+ * The large cushion allows instructions like enter
17662+ * and pusha to work. ("enter $65535, $31" pushes
17663+ * 32 pointers and then decrements %sp by 65535.)
17664+ */
17665+ if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < task_pt_regs(tsk)->sp)) {
17666+ bad_area(regs, error_code, address);
17667+ return;
df50ba0c 17668 }
58c5fc13
MT
17669+
17670+#ifdef CONFIG_PAX_SEGMEXEC
17671+ if (unlikely((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)) {
17672+ bad_area(regs, error_code, address);
17673+ return;
df50ba0c 17674+ }
58c5fc13
MT
17675+#endif
17676+
17677 if (unlikely(expand_stack(vma, address))) {
17678 bad_area(regs, error_code, address);
17679 return;
16454cff 17680@@ -1164,3 +1425,199 @@ good_area:
58c5fc13
MT
17681
17682 up_read(&mm->mmap_sem);
17683 }
17684+
17685+#ifdef CONFIG_PAX_EMUTRAMP
17686+static int pax_handle_fetch_fault_32(struct pt_regs *regs)
17687+{
17688+ int err;
17689+
17690+ do { /* PaX: gcc trampoline emulation #1 */
17691+ unsigned char mov1, mov2;
17692+ unsigned short jmp;
17693+ unsigned int addr1, addr2;
17694+
17695+#ifdef CONFIG_X86_64
17696+ if ((regs->ip + 11) >> 32)
17697+ break;
17698+#endif
17699+
17700+ err = get_user(mov1, (unsigned char __user *)regs->ip);
17701+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
17702+ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
17703+ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
17704+ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
17705+
17706+ if (err)
17707+ break;
17708+
17709+ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
17710+ regs->cx = addr1;
17711+ regs->ax = addr2;
17712+ regs->ip = addr2;
17713+ return 2;
17714+ }
17715+ } while (0);
17716+
17717+ do { /* PaX: gcc trampoline emulation #2 */
17718+ unsigned char mov, jmp;
17719+ unsigned int addr1, addr2;
17720+
17721+#ifdef CONFIG_X86_64
17722+ if ((regs->ip + 9) >> 32)
17723+ break;
17724+#endif
17725+
17726+ err = get_user(mov, (unsigned char __user *)regs->ip);
17727+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
17728+ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
17729+ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
17730+
17731+ if (err)
17732+ break;
17733+
17734+ if (mov == 0xB9 && jmp == 0xE9) {
17735+ regs->cx = addr1;
17736+ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
17737+ return 2;
17738+ }
17739+ } while (0);
17740+
17741+ return 1; /* PaX in action */
17742+}
17743+
17744+#ifdef CONFIG_X86_64
17745+static int pax_handle_fetch_fault_64(struct pt_regs *regs)
17746+{
17747+ int err;
17748+
17749+ do { /* PaX: gcc trampoline emulation #1 */
17750+ unsigned short mov1, mov2, jmp1;
17751+ unsigned char jmp2;
17752+ unsigned int addr1;
17753+ unsigned long addr2;
17754+
17755+ err = get_user(mov1, (unsigned short __user *)regs->ip);
17756+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
17757+ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
17758+ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
17759+ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
17760+ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
17761+
17762+ if (err)
17763+ break;
17764+
17765+ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
17766+ regs->r11 = addr1;
17767+ regs->r10 = addr2;
17768+ regs->ip = addr1;
17769+ return 2;
17770+ }
17771+ } while (0);
17772+
17773+ do { /* PaX: gcc trampoline emulation #2 */
17774+ unsigned short mov1, mov2, jmp1;
17775+ unsigned char jmp2;
17776+ unsigned long addr1, addr2;
17777+
17778+ err = get_user(mov1, (unsigned short __user *)regs->ip);
17779+ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
17780+ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
17781+ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
17782+ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
17783+ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
17784+
17785+ if (err)
17786+ break;
17787+
17788+ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
17789+ regs->r11 = addr1;
17790+ regs->r10 = addr2;
17791+ regs->ip = addr1;
17792+ return 2;
17793+ }
17794+ } while (0);
17795+
17796+ return 1; /* PaX in action */
17797+}
17798+#endif
17799+
17800+/*
17801+ * PaX: decide what to do with offenders (regs->ip = fault address)
17802+ *
17803+ * returns 1 when task should be killed
17804+ * 2 when gcc trampoline was detected
17805+ */
17806+static int pax_handle_fetch_fault(struct pt_regs *regs)
17807+{
17808+ if (v8086_mode(regs))
17809+ return 1;
17810+
17811+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
17812+ return 1;
17813+
17814+#ifdef CONFIG_X86_32
17815+ return pax_handle_fetch_fault_32(regs);
17816+#else
17817+ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
17818+ return pax_handle_fetch_fault_32(regs);
17819+ else
17820+ return pax_handle_fetch_fault_64(regs);
17821+#endif
17822+}
17823+#endif
17824+
17825+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17826+void pax_report_insns(void *pc, void *sp)
17827+{
17828+ long i;
17829+
17830+ printk(KERN_ERR "PAX: bytes at PC: ");
17831+ for (i = 0; i < 20; i++) {
17832+ unsigned char c;
ae4e228f 17833+ if (get_user(c, (__force unsigned char __user *)pc+i))
58c5fc13
MT
17834+ printk(KERN_CONT "?? ");
17835+ else
17836+ printk(KERN_CONT "%02x ", c);
17837+ }
17838+ printk("\n");
17839+
17840+ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
ae4e228f 17841+ for (i = -1; i < 80 / (long)sizeof(long); i++) {
58c5fc13 17842+ unsigned long c;
ae4e228f 17843+ if (get_user(c, (__force unsigned long __user *)sp+i))
58c5fc13
MT
17844+#ifdef CONFIG_X86_32
17845+ printk(KERN_CONT "???????? ");
17846+#else
17847+ printk(KERN_CONT "???????????????? ");
17848+#endif
17849+ else
17850+ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
17851+ }
17852+ printk("\n");
17853+}
17854+#endif
58c5fc13 17855+
ae4e228f
MT
17856+/**
17857+ * probe_kernel_write(): safely attempt to write to a location
17858+ * @dst: address to write to
17859+ * @src: pointer to the data that shall be written
17860+ * @size: size of the data chunk
17861+ *
17862+ * Safely write to address @dst from the buffer at @src. If a kernel fault
17863+ * happens, handle that and return -EFAULT.
17864+ */
17865+long notrace probe_kernel_write(void *dst, const void *src, size_t size)
17866+{
17867+ long ret;
17868+ mm_segment_t old_fs = get_fs();
17869+
17870+ set_fs(KERNEL_DS);
17871+ pagefault_disable();
17872+ pax_open_kernel();
17873+ ret = __copy_to_user_inatomic((__force void __user *)dst, src, size);
17874+ pax_close_kernel();
17875+ pagefault_enable();
17876+ set_fs(old_fs);
17877+
17878+ return ret ? -EFAULT : 0;
17879+}
16454cff
MT
17880diff -urNp linux-2.6.38.1/arch/x86/mm/gup.c linux-2.6.38.1/arch/x86/mm/gup.c
17881--- linux-2.6.38.1/arch/x86/mm/gup.c 2011-03-14 21:20:32.000000000 -0400
17882+++ linux-2.6.38.1/arch/x86/mm/gup.c 2011-03-21 18:31:35.000000000 -0400
17883@@ -263,7 +263,7 @@ int __get_user_pages_fast(unsigned long
ae4e228f
MT
17884 addr = start;
17885 len = (unsigned long) nr_pages << PAGE_SHIFT;
17886 end = start + len;
17887- if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
17888+ if (unlikely(!__access_ok(write ? VERIFY_WRITE : VERIFY_READ,
17889 (void __user *)start, len)))
17890 return 0;
58c5fc13 17891
16454cff
MT
17892diff -urNp linux-2.6.38.1/arch/x86/mm/highmem_32.c linux-2.6.38.1/arch/x86/mm/highmem_32.c
17893--- linux-2.6.38.1/arch/x86/mm/highmem_32.c 2011-03-14 21:20:32.000000000 -0400
17894+++ linux-2.6.38.1/arch/x86/mm/highmem_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 17895@@ -44,7 +44,10 @@ void *kmap_atomic_prot(struct page *page
58c5fc13
MT
17896 idx = type + KM_TYPE_NR*smp_processor_id();
17897 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
17898 BUG_ON(!pte_none(*(kmap_pte-idx)));
17899+
ae4e228f 17900+ pax_open_kernel();
58c5fc13 17901 set_pte(kmap_pte-idx, mk_pte(page, prot));
ae4e228f 17902+ pax_close_kernel();
58c5fc13 17903
58c5fc13
MT
17904 return (void *)vaddr;
17905 }
16454cff
MT
17906diff -urNp linux-2.6.38.1/arch/x86/mm/hugetlbpage.c linux-2.6.38.1/arch/x86/mm/hugetlbpage.c
17907--- linux-2.6.38.1/arch/x86/mm/hugetlbpage.c 2011-03-14 21:20:32.000000000 -0400
17908+++ linux-2.6.38.1/arch/x86/mm/hugetlbpage.c 2011-03-21 23:47:41.000000000 -0400
6892158b 17909@@ -266,13 +266,20 @@ static unsigned long hugetlb_get_unmappe
58c5fc13
MT
17910 struct hstate *h = hstate_file(file);
17911 struct mm_struct *mm = current->mm;
17912 struct vm_area_struct *vma;
17913- unsigned long start_addr;
17914+ unsigned long start_addr, pax_task_size = TASK_SIZE;
17915+
17916+#ifdef CONFIG_PAX_SEGMEXEC
17917+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
17918+ pax_task_size = SEGMEXEC_TASK_SIZE;
17919+#endif
6892158b
MT
17920+
17921+ pax_task_size -= PAGE_SIZE;
58c5fc13
MT
17922
17923 if (len > mm->cached_hole_size) {
17924- start_addr = mm->free_area_cache;
17925+ start_addr = mm->free_area_cache;
17926 } else {
17927- start_addr = TASK_UNMAPPED_BASE;
17928- mm->cached_hole_size = 0;
17929+ start_addr = mm->mmap_base;
17930+ mm->cached_hole_size = 0;
17931 }
17932
17933 full_search:
6892158b 17934@@ -280,26 +287,27 @@ full_search:
58c5fc13
MT
17935
17936 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
17937 /* At this point: (!vma || addr < vma->vm_end). */
17938- if (TASK_SIZE - len < addr) {
17939+ if (pax_task_size - len < addr) {
17940 /*
17941 * Start a new search - just in case we missed
17942 * some holes.
17943 */
17944- if (start_addr != TASK_UNMAPPED_BASE) {
17945- start_addr = TASK_UNMAPPED_BASE;
17946+ if (start_addr != mm->mmap_base) {
17947+ start_addr = mm->mmap_base;
17948 mm->cached_hole_size = 0;
17949 goto full_search;
17950 }
57199397
MT
17951 return -ENOMEM;
17952 }
17953- if (!vma || addr + len <= vma->vm_start) {
17954- mm->free_area_cache = addr + len;
17955- return addr;
17956- }
17957+ if (check_heap_stack_gap(vma, addr, len))
17958+ break;
17959 if (addr + mm->cached_hole_size < vma->vm_start)
17960 mm->cached_hole_size = vma->vm_start - addr;
17961 addr = ALIGN(vma->vm_end, huge_page_size(h));
17962 }
17963+
17964+ mm->free_area_cache = addr + len;
17965+ return addr;
17966 }
17967
17968 static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
6892158b 17969@@ -308,10 +316,9 @@ static unsigned long hugetlb_get_unmappe
57199397 17970 {
58c5fc13
MT
17971 struct hstate *h = hstate_file(file);
17972 struct mm_struct *mm = current->mm;
57199397 17973- struct vm_area_struct *vma, *prev_vma;
58c5fc13 17974- unsigned long base = mm->mmap_base, addr = addr0;
57199397 17975+ struct vm_area_struct *vma;
58c5fc13
MT
17976+ unsigned long base = mm->mmap_base, addr;
17977 unsigned long largest_hole = mm->cached_hole_size;
17978- int first_time = 1;
17979
17980 /* don't allow allocations above current base */
17981 if (mm->free_area_cache > base)
16454cff 17982@@ -321,64 +328,63 @@ static unsigned long hugetlb_get_unmappe
58c5fc13
MT
17983 largest_hole = 0;
17984 mm->free_area_cache = base;
17985 }
17986-try_again:
17987+
17988 /* make sure it can fit in the remaining address space */
17989 if (mm->free_area_cache < len)
17990 goto fail;
16454cff 17991
57199397 17992 /* either no address requested or cant fit in requested address hole */
16454cff
MT
17993- addr = (mm->free_area_cache - len) & huge_page_mask(h);
17994+ addr = (mm->free_area_cache - len);
57199397 17995 do {
16454cff 17996+ addr &= huge_page_mask(h);
57199397
MT
17997+ vma = find_vma(mm, addr);
17998 /*
17999 * Lookup failure means no vma is above this address,
18000 * i.e. return with success:
18001- */
18002- if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
18003- return addr;
18004-
18005- /*
18006 * new region fits between prev_vma->vm_end and
18007 * vma->vm_start, use it:
18008 */
18009- if (addr + len <= vma->vm_start &&
18010- (!prev_vma || (addr >= prev_vma->vm_end))) {
18011+ if (check_heap_stack_gap(vma, addr, len)) {
18012 /* remember the address as a hint for next time */
18013- mm->cached_hole_size = largest_hole;
18014- return (mm->free_area_cache = addr);
18015- } else {
18016- /* pull free_area_cache down to the first hole */
18017- if (mm->free_area_cache == vma->vm_end) {
18018- mm->free_area_cache = vma->vm_start;
18019- mm->cached_hole_size = largest_hole;
18020- }
18021+ mm->cached_hole_size = largest_hole;
18022+ return (mm->free_area_cache = addr);
18023+ }
18024+ /* pull free_area_cache down to the first hole */
18025+ if (mm->free_area_cache == vma->vm_end) {
18026+ mm->free_area_cache = vma->vm_start;
18027+ mm->cached_hole_size = largest_hole;
18028 }
18029
18030 /* remember the largest hole we saw so far */
18031 if (addr + largest_hole < vma->vm_start)
18032- largest_hole = vma->vm_start - addr;
18033+ largest_hole = vma->vm_start - addr;
18034
18035 /* try just below the current vma->vm_start */
16454cff
MT
18036- addr = (vma->vm_start - len) & huge_page_mask(h);
18037- } while (len <= vma->vm_start);
18038+ addr = skip_heap_stack_gap(vma, len);
18039+ } while (!IS_ERR_VALUE(addr));
58c5fc13
MT
18040
18041 fail:
18042 /*
18043- * if hint left us with no space for the requested
18044- * mapping then try again:
18045- */
18046- if (first_time) {
18047- mm->free_area_cache = base;
18048- largest_hole = 0;
18049- first_time = 0;
18050- goto try_again;
18051- }
18052- /*
18053 * A failed mmap() very likely causes application failure,
18054 * so fall back to the bottom-up function here. This scenario
18055 * can happen with large stack limits and large mmap()
18056 * allocations.
18057 */
18058- mm->free_area_cache = TASK_UNMAPPED_BASE;
18059+
18060+#ifdef CONFIG_PAX_SEGMEXEC
18061+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
18062+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
18063+ else
18064+#endif
18065+
18066+ mm->mmap_base = TASK_UNMAPPED_BASE;
18067+
18068+#ifdef CONFIG_PAX_RANDMMAP
18069+ if (mm->pax_flags & MF_PAX_RANDMMAP)
18070+ mm->mmap_base += mm->delta_mmap;
18071+#endif
18072+
18073+ mm->free_area_cache = mm->mmap_base;
18074 mm->cached_hole_size = ~0UL;
18075 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
18076 len, pgoff, flags);
16454cff 18077@@ -386,6 +392,7 @@ fail:
58c5fc13
MT
18078 /*
18079 * Restore the topdown base:
18080 */
18081+ mm->mmap_base = base;
18082 mm->free_area_cache = base;
18083 mm->cached_hole_size = ~0UL;
18084
16454cff 18085@@ -399,10 +406,19 @@ hugetlb_get_unmapped_area(struct file *f
58c5fc13
MT
18086 struct hstate *h = hstate_file(file);
18087 struct mm_struct *mm = current->mm;
18088 struct vm_area_struct *vma;
18089+ unsigned long pax_task_size = TASK_SIZE;
18090
18091 if (len & ~huge_page_mask(h))
18092 return -EINVAL;
18093- if (len > TASK_SIZE)
18094+
18095+#ifdef CONFIG_PAX_SEGMEXEC
18096+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
18097+ pax_task_size = SEGMEXEC_TASK_SIZE;
18098+#endif
18099+
6892158b
MT
18100+ pax_task_size -= PAGE_SIZE;
18101+
58c5fc13
MT
18102+ if (len > pax_task_size)
18103 return -ENOMEM;
18104
18105 if (flags & MAP_FIXED) {
16454cff 18106@@ -414,8 +430,7 @@ hugetlb_get_unmapped_area(struct file *f
58c5fc13
MT
18107 if (addr) {
18108 addr = ALIGN(addr, huge_page_size(h));
18109 vma = find_vma(mm, addr);
18110- if (TASK_SIZE - len >= addr &&
57199397
MT
18111- (!vma || addr + len <= vma->vm_start))
18112+ if (pax_task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
58c5fc13
MT
18113 return addr;
18114 }
57199397 18115 if (mm->get_unmapped_area == arch_get_unmapped_area)
16454cff
MT
18116diff -urNp linux-2.6.38.1/arch/x86/mm/init_32.c linux-2.6.38.1/arch/x86/mm/init_32.c
18117--- linux-2.6.38.1/arch/x86/mm/init_32.c 2011-03-14 21:20:32.000000000 -0400
18118+++ linux-2.6.38.1/arch/x86/mm/init_32.c 2011-03-21 18:31:35.000000000 -0400
18119@@ -74,36 +74,6 @@ static __init void *alloc_low_page(void)
58c5fc13
MT
18120 }
18121
18122 /*
18123- * Creates a middle page table and puts a pointer to it in the
18124- * given global directory entry. This only returns the gd entry
18125- * in non-PAE compilation mode, since the middle layer is folded.
18126- */
18127-static pmd_t * __init one_md_table_init(pgd_t *pgd)
18128-{
18129- pud_t *pud;
18130- pmd_t *pmd_table;
18131-
18132-#ifdef CONFIG_X86_PAE
18133- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
18134- if (after_bootmem)
ae4e228f 18135- pmd_table = (pmd_t *)alloc_bootmem_pages(PAGE_SIZE);
58c5fc13
MT
18136- else
18137- pmd_table = (pmd_t *)alloc_low_page();
18138- paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
18139- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
18140- pud = pud_offset(pgd, 0);
18141- BUG_ON(pmd_table != pmd_offset(pud, 0));
18142-
18143- return pmd_table;
18144- }
18145-#endif
18146- pud = pud_offset(pgd, 0);
18147- pmd_table = pmd_offset(pud, 0);
18148-
18149- return pmd_table;
18150-}
18151-
18152-/*
18153 * Create a page table and place a pointer to it in a middle page
18154 * directory entry:
18155 */
16454cff 18156@@ -123,13 +93,28 @@ static pte_t * __init one_page_table_ini
58c5fc13
MT
18157 page_table = (pte_t *)alloc_low_page();
18158
18159 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
18160+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18161+ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
18162+#else
18163 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
18164+#endif
18165 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
18166 }
18167
18168 return pte_offset_kernel(pmd, 0);
18169 }
18170
18171+static pmd_t * __init one_md_table_init(pgd_t *pgd)
18172+{
18173+ pud_t *pud;
18174+ pmd_t *pmd_table;
18175+
18176+ pud = pud_offset(pgd, 0);
18177+ pmd_table = pmd_offset(pud, 0);
18178+
18179+ return pmd_table;
18180+}
18181+
18182 pmd_t * __init populate_extra_pmd(unsigned long vaddr)
18183 {
18184 int pgd_idx = pgd_index(vaddr);
16454cff 18185@@ -203,6 +188,7 @@ page_table_range_init(unsigned long star
58c5fc13
MT
18186 int pgd_idx, pmd_idx;
18187 unsigned long vaddr;
18188 pgd_t *pgd;
18189+ pud_t *pud;
18190 pmd_t *pmd;
18191 pte_t *pte = NULL;
18192
16454cff 18193@@ -212,8 +198,13 @@ page_table_range_init(unsigned long star
58c5fc13
MT
18194 pgd = pgd_base + pgd_idx;
18195
18196 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
18197- pmd = one_md_table_init(pgd);
18198- pmd = pmd + pmd_index(vaddr);
18199+ pud = pud_offset(pgd, vaddr);
18200+ pmd = pmd_offset(pud, vaddr);
18201+
18202+#ifdef CONFIG_X86_PAE
18203+ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
18204+#endif
18205+
18206 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
18207 pmd++, pmd_idx++) {
18208 pte = page_table_kmap_check(one_page_table_init(pmd),
16454cff 18209@@ -225,11 +216,20 @@ page_table_range_init(unsigned long star
58c5fc13
MT
18210 }
18211 }
18212
18213-static inline int is_kernel_text(unsigned long addr)
18214+static inline int is_kernel_text(unsigned long start, unsigned long end)
18215 {
16454cff 18216- if (addr >= (unsigned long)_text && addr <= (unsigned long)__init_end)
58c5fc13
MT
18217- return 1;
18218- return 0;
ae4e228f 18219+ if ((start > ktla_ktva((unsigned long)_etext) ||
58c5fc13
MT
18220+ end <= ktla_ktva((unsigned long)_stext)) &&
18221+ (start > ktla_ktva((unsigned long)_einittext) ||
18222+ end <= ktla_ktva((unsigned long)_sinittext)) &&
ae4e228f
MT
18223+
18224+#ifdef CONFIG_ACPI_SLEEP
18225+ (start > (unsigned long)__va(acpi_wakeup_address) + 0x4000 || end <= (unsigned long)__va(acpi_wakeup_address)) &&
18226+#endif
18227+
58c5fc13
MT
18228+ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
18229+ return 0;
18230+ return 1;
18231 }
18232
18233 /*
16454cff 18234@@ -246,9 +246,10 @@ kernel_physical_mapping_init(unsigned lo
df50ba0c 18235 unsigned long last_map_addr = end;
58c5fc13
MT
18236 unsigned long start_pfn, end_pfn;
18237 pgd_t *pgd_base = swapper_pg_dir;
18238- int pgd_idx, pmd_idx, pte_ofs;
18239+ unsigned int pgd_idx, pmd_idx, pte_ofs;
18240 unsigned long pfn;
18241 pgd_t *pgd;
18242+ pud_t *pud;
18243 pmd_t *pmd;
18244 pte_t *pte;
18245 unsigned pages_2m, pages_4k;
16454cff 18246@@ -281,8 +282,13 @@ repeat:
58c5fc13
MT
18247 pfn = start_pfn;
18248 pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
18249 pgd = pgd_base + pgd_idx;
18250- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
18251- pmd = one_md_table_init(pgd);
18252+ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
18253+ pud = pud_offset(pgd, 0);
18254+ pmd = pmd_offset(pud, 0);
18255+
18256+#ifdef CONFIG_X86_PAE
18257+ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
18258+#endif
18259
18260 if (pfn >= end_pfn)
18261 continue;
16454cff 18262@@ -294,14 +300,13 @@ repeat:
58c5fc13
MT
18263 #endif
18264 for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
18265 pmd++, pmd_idx++) {
18266- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
18267+ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
18268
18269 /*
18270 * Map with big pages if possible, otherwise
18271 * create normal page tables:
18272 */
18273 if (use_pse) {
18274- unsigned int addr2;
18275 pgprot_t prot = PAGE_KERNEL_LARGE;
18276 /*
18277 * first pass will use the same initial
16454cff 18278@@ -311,11 +316,7 @@ repeat:
58c5fc13
MT
18279 __pgprot(PTE_IDENT_ATTR |
18280 _PAGE_PSE);
18281
18282- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
18283- PAGE_OFFSET + PAGE_SIZE-1;
18284-
18285- if (is_kernel_text(addr) ||
18286- is_kernel_text(addr2))
18287+ if (is_kernel_text(address, address + PMD_SIZE))
18288 prot = PAGE_KERNEL_LARGE_EXEC;
18289
18290 pages_2m++;
16454cff 18291@@ -332,7 +333,7 @@ repeat:
58c5fc13
MT
18292 pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
18293 pte += pte_ofs;
18294 for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
18295- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
18296+ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
18297 pgprot_t prot = PAGE_KERNEL;
18298 /*
18299 * first pass will use the same initial
16454cff 18300@@ -340,7 +341,7 @@ repeat:
58c5fc13
MT
18301 */
18302 pgprot_t init_prot = __pgprot(PTE_IDENT_ATTR);
18303
18304- if (is_kernel_text(addr))
18305+ if (is_kernel_text(address, address + PAGE_SIZE))
18306 prot = PAGE_KERNEL_EXEC;
18307
18308 pages_4k++;
16454cff 18309@@ -472,7 +473,7 @@ void __init native_pagetable_setup_start
58c5fc13
MT
18310
18311 pud = pud_offset(pgd, va);
18312 pmd = pmd_offset(pud, va);
18313- if (!pmd_present(*pmd))
18314+ if (!pmd_present(*pmd) || pmd_huge(*pmd))
18315 break;
18316
18317 pte = pte_offset_kernel(pmd, va);
16454cff 18318@@ -524,12 +525,10 @@ void __init early_ioremap_page_table_ran
58c5fc13
MT
18319
18320 static void __init pagetable_init(void)
18321 {
18322- pgd_t *pgd_base = swapper_pg_dir;
18323-
18324- permanent_kmaps_init(pgd_base);
18325+ permanent_kmaps_init(swapper_pg_dir);
18326 }
18327
58c5fc13
MT
18328-pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
18329+pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
18330 EXPORT_SYMBOL_GPL(__supported_pte_mask);
18331
18332 /* user-defined highmem size */
16454cff 18333@@ -755,6 +754,12 @@ void __init mem_init(void)
df50ba0c
MT
18334
18335 pci_iommu_alloc();
18336
18337+#ifdef CONFIG_PAX_PER_CPU_PGD
18338+ clone_pgd_range(get_cpu_pgd(0) + KERNEL_PGD_BOUNDARY,
18339+ swapper_pg_dir + KERNEL_PGD_BOUNDARY,
18340+ KERNEL_PGD_PTRS);
18341+#endif
18342+
18343 #ifdef CONFIG_FLATMEM
18344 BUG_ON(!mem_map);
18345 #endif
16454cff 18346@@ -772,7 +777,7 @@ void __init mem_init(void)
58c5fc13
MT
18347 set_highmem_pages_init();
18348
18349 codesize = (unsigned long) &_etext - (unsigned long) &_text;
18350- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
18351+ datasize = (unsigned long) &_edata - (unsigned long) &_sdata;
18352 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
18353
ae4e228f 18354 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
16454cff 18355@@ -813,10 +818,10 @@ void __init mem_init(void)
58c5fc13
MT
18356 ((unsigned long)&__init_end -
18357 (unsigned long)&__init_begin) >> 10,
18358
18359- (unsigned long)&_etext, (unsigned long)&_edata,
18360- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
18361+ (unsigned long)&_sdata, (unsigned long)&_edata,
18362+ ((unsigned long)&_edata - (unsigned long)&_sdata) >> 10,
18363
18364- (unsigned long)&_text, (unsigned long)&_etext,
18365+ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
18366 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
18367
18368 /*
16454cff 18369@@ -894,6 +899,7 @@ void set_kernel_text_rw(void)
ae4e228f
MT
18370 if (!kernel_set_to_readonly)
18371 return;
58c5fc13 18372
ae4e228f
MT
18373+ start = ktla_ktva(start);
18374 pr_debug("Set kernel text: %lx - %lx for read write\n",
18375 start, start+size);
18376
16454cff 18377@@ -908,6 +914,7 @@ void set_kernel_text_ro(void)
ae4e228f
MT
18378 if (!kernel_set_to_readonly)
18379 return;
18380
18381+ start = ktla_ktva(start);
18382 pr_debug("Set kernel text: %lx - %lx for read only\n",
18383 start, start+size);
18384
16454cff 18385@@ -936,6 +943,7 @@ void mark_rodata_ro(void)
ae4e228f
MT
18386 unsigned long start = PFN_ALIGN(_text);
18387 unsigned long size = PFN_ALIGN(_etext) - start;
18388
18389+ start = ktla_ktva(start);
18390 set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
18391 printk(KERN_INFO "Write protecting the kernel text: %luk\n",
18392 size >> 10);
16454cff
MT
18393diff -urNp linux-2.6.38.1/arch/x86/mm/init_64.c linux-2.6.38.1/arch/x86/mm/init_64.c
18394--- linux-2.6.38.1/arch/x86/mm/init_64.c 2011-03-14 21:20:32.000000000 -0400
18395+++ linux-2.6.38.1/arch/x86/mm/init_64.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 18396@@ -72,7 +72,7 @@ early_param("gbpages", parse_direct_gbpa
ae4e228f
MT
18397 * around without checking the pgd every time.
18398 */
18399
18400-pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
18401+pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_IOMAP);
18402 EXPORT_SYMBOL_GPL(__supported_pte_mask);
18403
18404 int force_personality32;
16454cff
MT
18405@@ -105,12 +105,22 @@ void sync_global_pgds(unsigned long star
18406
bc901d79
MT
18407 for (address = start; address <= end; address += PGDIR_SIZE) {
18408 const pgd_t *pgd_ref = pgd_offset_k(address);
bc901d79
MT
18409+
18410+#ifdef CONFIG_PAX_PER_CPU_PGD
18411+ unsigned long cpu;
18412+#else
18413 struct page *page;
18414+#endif
18415
18416 if (pgd_none(*pgd_ref))
18417 continue;
18418
16454cff 18419 spin_lock(&pgd_lock);
bc901d79
MT
18420+
18421+#ifdef CONFIG_PAX_PER_CPU_PGD
18422+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
18423+ pgd_t *pgd = pgd_offset_cpu(cpu, address);
18424+#else
18425 list_for_each_entry(page, &pgd_list, lru) {
18426 pgd_t *pgd;
18427 spinlock_t *pgt_lock;
18428@@ -119,6 +129,7 @@ void sync_global_pgds(unsigned long star
16454cff 18429 /* the pgt_lock only for Xen */
bc901d79
MT
18430 pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
18431 spin_lock(pgt_lock);
18432+#endif
18433
18434 if (pgd_none(*pgd))
18435 set_pgd(pgd, *pgd_ref);
18436@@ -126,7 +137,10 @@ void sync_global_pgds(unsigned long star
18437 BUG_ON(pgd_page_vaddr(*pgd)
18438 != pgd_page_vaddr(*pgd_ref));
18439
18440+#ifndef CONFIG_PAX_PER_CPU_PGD
18441 spin_unlock(pgt_lock);
18442+#endif
18443+
18444 }
16454cff 18445 spin_unlock(&pgd_lock);
bc901d79
MT
18446 }
18447@@ -200,7 +214,9 @@ void set_pte_vaddr_pud(pud_t *pud_page,
58c5fc13
MT
18448 pmd = fill_pmd(pud, vaddr);
18449 pte = fill_pte(pmd, vaddr);
18450
ae4e228f 18451+ pax_open_kernel();
58c5fc13 18452 set_pte(pte, new_pte);
ae4e228f 18453+ pax_close_kernel();
58c5fc13 18454
58c5fc13
MT
18455 /*
18456 * It's enough to flush this one mapping.
bc901d79 18457@@ -259,14 +275,12 @@ static void __init __init_extra_mapping(
58c5fc13
MT
18458 pgd = pgd_offset_k((unsigned long)__va(phys));
18459 if (pgd_none(*pgd)) {
18460 pud = (pud_t *) spp_getpage();
18461- set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
18462- _PAGE_USER));
18463+ set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
18464 }
18465 pud = pud_offset(pgd, (unsigned long)__va(phys));
18466 if (pud_none(*pud)) {
18467 pmd = (pmd_t *) spp_getpage();
18468- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
18469- _PAGE_USER));
18470+ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
18471 }
18472 pmd = pmd_offset(pud, phys);
18473 BUG_ON(!pmd_none(*pmd));
bc901d79 18474@@ -706,6 +720,12 @@ void __init mem_init(void)
df50ba0c
MT
18475
18476 pci_iommu_alloc();
18477
18478+#ifdef CONFIG_PAX_PER_CPU_PGD
18479+ clone_pgd_range(get_cpu_pgd(0) + KERNEL_PGD_BOUNDARY,
18480+ swapper_pg_dir + KERNEL_PGD_BOUNDARY,
18481+ KERNEL_PGD_PTRS);
18482+#endif
18483+
18484 /* clear_bss() already clear the empty_zero_page */
18485
18486 reservedpages = 0;
bc901d79 18487@@ -866,8 +886,8 @@ int kern_addr_valid(unsigned long addr)
58c5fc13
MT
18488 static struct vm_area_struct gate_vma = {
18489 .vm_start = VSYSCALL_START,
18490 .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
18491- .vm_page_prot = PAGE_READONLY_EXEC,
18492- .vm_flags = VM_READ | VM_EXEC
18493+ .vm_page_prot = PAGE_READONLY,
18494+ .vm_flags = VM_READ
18495 };
18496
18497 struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
bc901d79 18498@@ -901,7 +921,7 @@ int in_gate_area_no_task(unsigned long a
58c5fc13
MT
18499
18500 const char *arch_vma_name(struct vm_area_struct *vma)
18501 {
18502- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
18503+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
18504 return "[vdso]";
18505 if (vma == &gate_vma)
18506 return "[vsyscall]";
16454cff
MT
18507diff -urNp linux-2.6.38.1/arch/x86/mm/init.c linux-2.6.38.1/arch/x86/mm/init.c
18508--- linux-2.6.38.1/arch/x86/mm/init.c 2011-03-14 21:20:32.000000000 -0400
18509+++ linux-2.6.38.1/arch/x86/mm/init.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 18510@@ -72,11 +72,7 @@ static void __init find_early_table_spac
57199397
MT
18511 * cause a hotspot and fill up ZONE_DMA. The page tables
18512 * need roughly 0.5KB per GB.
18513 */
18514-#ifdef CONFIG_X86_32
18515- start = 0x7000;
18516-#else
18517- start = 0x8000;
18518-#endif
18519+ start = 0x100000;
bc901d79 18520 base = memblock_find_in_range(start, max_pfn_mapped<<PAGE_SHIFT,
57199397 18521 tables, PAGE_SIZE);
bc901d79
MT
18522 if (base == MEMBLOCK_ERROR)
18523@@ -323,7 +319,13 @@ unsigned long __init_refok init_memory_m
57199397
MT
18524 */
18525 int devmem_is_allowed(unsigned long pagenr)
18526 {
18527- if (pagenr <= 256)
18528+ if (!pagenr)
18529+ return 1;
18530+#ifdef CONFIG_VM86
18531+ if (pagenr < (ISA_START_ADDRESS >> PAGE_SHIFT))
18532+ return 1;
18533+#endif
18534+ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
18535 return 1;
18536 if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
18537 return 0;
16454cff 18538@@ -383,6 +385,86 @@ void free_init_pages(char *what, unsigne
57199397
MT
18539
18540 void free_initmem(void)
18541 {
18542+
18543+#ifdef CONFIG_PAX_KERNEXEC
18544+#ifdef CONFIG_X86_32
18545+ /* PaX: limit KERNEL_CS to actual size */
18546+ unsigned long addr, limit;
18547+ struct desc_struct d;
18548+ int cpu;
18549+
18550+ limit = paravirt_enabled() ? ktva_ktla(0xffffffff) : (unsigned long)&_etext;
18551+ limit = (limit - 1UL) >> PAGE_SHIFT;
18552+
18553+ memset(__LOAD_PHYSICAL_ADDR + PAGE_OFFSET, POISON_FREE_INITMEM, PAGE_SIZE);
18554+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
18555+ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
18556+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
18557+ }
18558+
18559+ /* PaX: make KERNEL_CS read-only */
18560+ addr = PFN_ALIGN(ktla_ktva((unsigned long)&_text));
18561+ if (!paravirt_enabled())
18562+ set_memory_ro(addr, (PFN_ALIGN(_sdata) - addr) >> PAGE_SHIFT);
18563+/*
18564+ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_sdata; addr += PMD_SIZE) {
18565+ pgd = pgd_offset_k(addr);
18566+ pud = pud_offset(pgd, addr);
18567+ pmd = pmd_offset(pud, addr);
18568+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
18569+ }
18570+*/
18571+#ifdef CONFIG_X86_PAE
18572+ set_memory_nx(PFN_ALIGN(__init_begin), (PFN_ALIGN(__init_end) - PFN_ALIGN(__init_begin)) >> PAGE_SHIFT);
18573+/*
18574+ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
18575+ pgd = pgd_offset_k(addr);
18576+ pud = pud_offset(pgd, addr);
18577+ pmd = pmd_offset(pud, addr);
18578+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
18579+ }
18580+*/
18581+#endif
18582+
18583+#ifdef CONFIG_MODULES
18584+ set_memory_4k((unsigned long)MODULES_EXEC_VADDR, (MODULES_EXEC_END - MODULES_EXEC_VADDR) >> PAGE_SHIFT);
18585+#endif
18586+
18587+#else
18588+ pgd_t *pgd;
18589+ pud_t *pud;
18590+ pmd_t *pmd;
18591+ unsigned long addr, end;
18592+
18593+ /* PaX: make kernel code/rodata read-only, rest non-executable */
18594+ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
18595+ pgd = pgd_offset_k(addr);
18596+ pud = pud_offset(pgd, addr);
18597+ pmd = pmd_offset(pud, addr);
18598+ if (!pmd_present(*pmd))
18599+ continue;
18600+ if ((unsigned long)_text <= addr && addr < (unsigned long)_sdata)
18601+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
18602+ else
18603+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
18604+ }
18605+
18606+ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
18607+ end = addr + KERNEL_IMAGE_SIZE;
18608+ for (; addr < end; addr += PMD_SIZE) {
18609+ pgd = pgd_offset_k(addr);
18610+ pud = pud_offset(pgd, addr);
18611+ pmd = pmd_offset(pud, addr);
18612+ if (!pmd_present(*pmd))
18613+ continue;
18614+ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_sdata)))
18615+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
57199397
MT
18616+ }
18617+#endif
18618+
18619+ flush_tlb_all();
18620+#endif
18621+
18622 free_init_pages("unused kernel memory",
18623 (unsigned long)(&__init_begin),
18624 (unsigned long)(&__init_end));
16454cff
MT
18625diff -urNp linux-2.6.38.1/arch/x86/mm/iomap_32.c linux-2.6.38.1/arch/x86/mm/iomap_32.c
18626--- linux-2.6.38.1/arch/x86/mm/iomap_32.c 2011-03-14 21:20:32.000000000 -0400
18627+++ linux-2.6.38.1/arch/x86/mm/iomap_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
18628@@ -64,7 +64,11 @@ void *kmap_atomic_prot_pfn(unsigned long
18629 type = kmap_atomic_idx_push();
58c5fc13
MT
18630 idx = type + KM_TYPE_NR * smp_processor_id();
18631 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
18632+
ae4e228f 18633+ pax_open_kernel();
58c5fc13 18634 set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
ae4e228f 18635+ pax_close_kernel();
58c5fc13
MT
18636+
18637 arch_flush_lazy_mmu_mode();
18638
18639 return (void *)vaddr;
16454cff
MT
18640diff -urNp linux-2.6.38.1/arch/x86/mm/ioremap.c linux-2.6.38.1/arch/x86/mm/ioremap.c
18641--- linux-2.6.38.1/arch/x86/mm/ioremap.c 2011-03-14 21:20:32.000000000 -0400
18642+++ linux-2.6.38.1/arch/x86/mm/ioremap.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
18643@@ -104,7 +104,7 @@ static void __iomem *__ioremap_caller(re
18644 for (pfn = phys_addr >> PAGE_SHIFT; pfn <= last_pfn; pfn++) {
58c5fc13
MT
18645 int is_ram = page_is_ram(pfn);
18646
ae4e228f
MT
18647- if (is_ram && pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
18648+ if (is_ram && pfn_valid(pfn) && (pfn >= 0x100 || !PageReserved(pfn_to_page(pfn))))
18649 return NULL;
18650 WARN_ON_ONCE(is_ram);
58c5fc13 18651 }
6892158b 18652@@ -344,7 +344,7 @@ static int __init early_ioremap_debug_se
58c5fc13
MT
18653 early_param("early_ioremap_debug", early_ioremap_debug_setup);
18654
18655 static __initdata int after_paging_init;
18656-static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
18657+static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __read_only __aligned(PAGE_SIZE);
18658
18659 static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
18660 {
bc901d79 18661@@ -381,8 +381,7 @@ void __init early_ioremap_init(void)
58c5fc13
MT
18662 slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
18663
18664 pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
18665- memset(bm_pte, 0, sizeof(bm_pte));
18666- pmd_populate_kernel(&init_mm, pmd, bm_pte);
18667+ pmd_populate_user(&init_mm, pmd, bm_pte);
18668
18669 /*
18670 * The boot-ioremap range spans multiple pmds, for which
16454cff
MT
18671diff -urNp linux-2.6.38.1/arch/x86/mm/kmemcheck/kmemcheck.c linux-2.6.38.1/arch/x86/mm/kmemcheck/kmemcheck.c
18672--- linux-2.6.38.1/arch/x86/mm/kmemcheck/kmemcheck.c 2011-03-14 21:20:32.000000000 -0400
18673+++ linux-2.6.38.1/arch/x86/mm/kmemcheck/kmemcheck.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
18674@@ -622,9 +622,9 @@ bool kmemcheck_fault(struct pt_regs *reg
18675 * memory (e.g. tracked pages)? For now, we need this to avoid
18676 * invoking kmemcheck for PnP BIOS calls.
18677 */
18678- if (regs->flags & X86_VM_MASK)
18679+ if (v8086_mode(regs))
18680 return false;
18681- if (regs->cs != __KERNEL_CS)
18682+ if (regs->cs != __KERNEL_CS && regs->cs != __KERNEXEC_KERNEL_CS)
18683 return false;
18684
18685 pte = kmemcheck_pte_lookup(address);
16454cff
MT
18686diff -urNp linux-2.6.38.1/arch/x86/mm/mmap.c linux-2.6.38.1/arch/x86/mm/mmap.c
18687--- linux-2.6.38.1/arch/x86/mm/mmap.c 2011-03-14 21:20:32.000000000 -0400
18688+++ linux-2.6.38.1/arch/x86/mm/mmap.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
18689@@ -49,7 +49,7 @@ static unsigned int stack_maxrandom_size
18690 * Leave an at least ~128 MB hole with possible stack randomization.
58c5fc13 18691 */
ae4e228f 18692 #define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())
58c5fc13
MT
18693-#define MAX_GAP (TASK_SIZE/6*5)
18694+#define MAX_GAP (pax_task_size/6*5)
18695
18696 /*
18697 * True on X86_32 or when emulating IA32 on X86_64
ae4e228f 18698@@ -94,27 +94,40 @@ static unsigned long mmap_rnd(void)
58c5fc13
MT
18699 return rnd << PAGE_SHIFT;
18700 }
18701
18702-static unsigned long mmap_base(void)
18703+static unsigned long mmap_base(struct mm_struct *mm)
18704 {
df50ba0c 18705 unsigned long gap = rlimit(RLIMIT_STACK);
58c5fc13
MT
18706+ unsigned long pax_task_size = TASK_SIZE;
18707+
18708+#ifdef CONFIG_PAX_SEGMEXEC
18709+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
18710+ pax_task_size = SEGMEXEC_TASK_SIZE;
18711+#endif
18712
18713 if (gap < MIN_GAP)
18714 gap = MIN_GAP;
18715 else if (gap > MAX_GAP)
18716 gap = MAX_GAP;
18717
18718- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
18719+ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
18720 }
18721
18722 /*
18723 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
18724 * does, but not when emulating X86_32
18725 */
18726-static unsigned long mmap_legacy_base(void)
18727+static unsigned long mmap_legacy_base(struct mm_struct *mm)
18728 {
18729- if (mmap_is_ia32())
18730+ if (mmap_is_ia32()) {
18731+
18732+#ifdef CONFIG_PAX_SEGMEXEC
18733+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
18734+ return SEGMEXEC_TASK_UNMAPPED_BASE;
18735+ else
18736+#endif
18737+
18738 return TASK_UNMAPPED_BASE;
18739- else
18740+ } else
18741 return TASK_UNMAPPED_BASE + mmap_rnd();
18742 }
18743
ae4e228f 18744@@ -125,11 +138,23 @@ static unsigned long mmap_legacy_base(vo
58c5fc13
MT
18745 void arch_pick_mmap_layout(struct mm_struct *mm)
18746 {
18747 if (mmap_is_legacy()) {
18748- mm->mmap_base = mmap_legacy_base();
18749+ mm->mmap_base = mmap_legacy_base(mm);
18750+
18751+#ifdef CONFIG_PAX_RANDMMAP
18752+ if (mm->pax_flags & MF_PAX_RANDMMAP)
18753+ mm->mmap_base += mm->delta_mmap;
18754+#endif
18755+
18756 mm->get_unmapped_area = arch_get_unmapped_area;
18757 mm->unmap_area = arch_unmap_area;
18758 } else {
18759- mm->mmap_base = mmap_base();
18760+ mm->mmap_base = mmap_base(mm);
18761+
18762+#ifdef CONFIG_PAX_RANDMMAP
18763+ if (mm->pax_flags & MF_PAX_RANDMMAP)
18764+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
18765+#endif
18766+
18767 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
18768 mm->unmap_area = arch_unmap_area_topdown;
18769 }
16454cff
MT
18770diff -urNp linux-2.6.38.1/arch/x86/mm/numa_32.c linux-2.6.38.1/arch/x86/mm/numa_32.c
18771--- linux-2.6.38.1/arch/x86/mm/numa_32.c 2011-03-14 21:20:32.000000000 -0400
18772+++ linux-2.6.38.1/arch/x86/mm/numa_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 18773@@ -99,7 +99,6 @@ unsigned long node_memmap_size_bytes(int
58c5fc13
MT
18774 }
18775 #endif
18776
18777-extern unsigned long find_max_low_pfn(void);
18778 extern unsigned long highend_pfn, highstart_pfn;
18779
18780 #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
16454cff
MT
18781diff -urNp linux-2.6.38.1/arch/x86/mm/pageattr.c linux-2.6.38.1/arch/x86/mm/pageattr.c
18782--- linux-2.6.38.1/arch/x86/mm/pageattr.c 2011-03-14 21:20:32.000000000 -0400
18783+++ linux-2.6.38.1/arch/x86/mm/pageattr.c 2011-03-21 18:31:35.000000000 -0400
18784@@ -261,7 +261,7 @@ static inline pgprot_t static_protection
df50ba0c 18785 */
16454cff
MT
18786 #ifdef CONFIG_PCI_BIOS
18787 if (pcibios_enabled && within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT))
df50ba0c
MT
18788- pgprot_val(forbidden) |= _PAGE_NX;
18789+ pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
16454cff 18790 #endif
df50ba0c
MT
18791
18792 /*
16454cff 18793@@ -269,9 +269,10 @@ static inline pgprot_t static_protection
58c5fc13
MT
18794 * Does not cover __inittext since that is gone later on. On
18795 * 64bit we do not enforce !NX on the low mapping
18796 */
18797- if (within(address, (unsigned long)_text, (unsigned long)_etext))
df50ba0c 18798- pgprot_val(forbidden) |= _PAGE_NX;
58c5fc13 18799+ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
df50ba0c 18800+ pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
58c5fc13
MT
18801
18802+#ifdef CONFIG_DEBUG_RODATA
18803 /*
18804 * The .rodata section needs to be read-only. Using the pfn
18805 * catches all aliases.
16454cff 18806@@ -279,6 +280,7 @@ static inline pgprot_t static_protection
58c5fc13
MT
18807 if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
18808 __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
18809 pgprot_val(forbidden) |= _PAGE_RW;
18810+#endif
18811
ae4e228f
MT
18812 #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
18813 /*
16454cff 18814@@ -317,6 +319,13 @@ static inline pgprot_t static_protection
df50ba0c
MT
18815 }
18816 #endif
18817
18818+#ifdef CONFIG_PAX_KERNEXEC
18819+ if (within(pfn, __pa((unsigned long)&_text), __pa((unsigned long)&_sdata))) {
18820+ pgprot_val(forbidden) |= _PAGE_RW;
18821+ pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
18822+ }
18823+#endif
18824+
18825 prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
18826
18827 return prot;
16454cff 18828@@ -369,23 +378,37 @@ EXPORT_SYMBOL_GPL(lookup_address);
58c5fc13
MT
18829 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
18830 {
58c5fc13 18831 /* change init_mm */
ae4e228f 18832+ pax_open_kernel();
58c5fc13 18833 set_pte_atomic(kpte, pte);
58c5fc13
MT
18834+
18835 #ifdef CONFIG_X86_32
18836 if (!SHARED_KERNEL_PMD) {
df50ba0c
MT
18837+
18838+#ifdef CONFIG_PAX_PER_CPU_PGD
18839+ unsigned long cpu;
18840+#else
58c5fc13 18841 struct page *page;
df50ba0c
MT
18842+#endif
18843
18844+#ifdef CONFIG_PAX_PER_CPU_PGD
18845+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
18846+ pgd_t *pgd = get_cpu_pgd(cpu);
18847+#else
18848 list_for_each_entry(page, &pgd_list, lru) {
18849- pgd_t *pgd;
18850+ pgd_t *pgd = (pgd_t *)page_address(page);
18851+#endif
18852+
18853 pud_t *pud;
18854 pmd_t *pmd;
18855
18856- pgd = (pgd_t *)page_address(page) + pgd_index(address);
18857+ pgd += pgd_index(address);
18858 pud = pud_offset(pgd, address);
18859 pmd = pmd_offset(pud, address);
18860 set_pte_atomic((pte_t *)pmd, pte);
18861 }
18862 }
18863 #endif
18864+ pax_close_kernel();
18865 }
18866
18867 static int
16454cff
MT
18868diff -urNp linux-2.6.38.1/arch/x86/mm/pageattr-test.c linux-2.6.38.1/arch/x86/mm/pageattr-test.c
18869--- linux-2.6.38.1/arch/x86/mm/pageattr-test.c 2011-03-14 21:20:32.000000000 -0400
18870+++ linux-2.6.38.1/arch/x86/mm/pageattr-test.c 2011-03-21 18:31:35.000000000 -0400
57199397 18871@@ -36,7 +36,7 @@ enum {
58c5fc13 18872
57199397
MT
18873 static int pte_testbit(pte_t pte)
18874 {
18875- return pte_flags(pte) & _PAGE_UNUSED1;
18876+ return pte_flags(pte) & _PAGE_CPA_TEST;
58c5fc13 18877 }
58c5fc13 18878
57199397 18879 struct split_state {
16454cff
MT
18880diff -urNp linux-2.6.38.1/arch/x86/mm/pat.c linux-2.6.38.1/arch/x86/mm/pat.c
18881--- linux-2.6.38.1/arch/x86/mm/pat.c 2011-03-14 21:20:32.000000000 -0400
18882+++ linux-2.6.38.1/arch/x86/mm/pat.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
18883@@ -361,7 +361,7 @@ int free_memtype(u64 start, u64 end)
18884
18885 if (!entry) {
58c5fc13
MT
18886 printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n",
18887- current->comm, current->pid, start, end);
18888+ current->comm, task_pid_nr(current), start, end);
57199397 18889 return -EINVAL;
58c5fc13
MT
18890 }
18891
57199397
MT
18892@@ -492,8 +492,8 @@ static inline int range_is_allowed(unsig
18893 while (cursor < to) {
18894 if (!devmem_is_allowed(pfn)) {
18895 printk(KERN_INFO
18896- "Program %s tried to access /dev/mem between %Lx->%Lx.\n",
18897- current->comm, from, to);
18898+ "Program %s tried to access /dev/mem between %Lx->%Lx (%Lx).\n",
18899+ current->comm, from, to, cursor);
18900 return 0;
18901 }
18902 cursor += PAGE_SIZE;
18903@@ -557,7 +557,7 @@ int kernel_map_sync_memtype(u64 base, un
58c5fc13
MT
18904 printk(KERN_INFO
18905 "%s:%d ioremap_change_attr failed %s "
18906 "for %Lx-%Lx\n",
18907- current->comm, current->pid,
18908+ current->comm, task_pid_nr(current),
18909 cattr_name(flags),
18910 base, (unsigned long long)(base + size));
18911 return -EINVAL;
57199397
MT
18912@@ -593,7 +593,7 @@ static int reserve_pfn_range(u64 paddr,
18913 if (want_flags != flags) {
18914 printk(KERN_WARNING
18915 "%s:%d map pfn RAM range req %s for %Lx-%Lx, got %s\n",
18916- current->comm, current->pid,
18917+ current->comm, task_pid_nr(current),
18918 cattr_name(want_flags),
18919 (unsigned long long)paddr,
18920 (unsigned long long)(paddr + size),
18921@@ -615,7 +615,7 @@ static int reserve_pfn_range(u64 paddr,
58c5fc13
MT
18922 free_memtype(paddr, paddr + size);
18923 printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
18924 " for %Lx-%Lx, got %s\n",
18925- current->comm, current->pid,
18926+ current->comm, task_pid_nr(current),
18927 cattr_name(want_flags),
18928 (unsigned long long)paddr,
18929 (unsigned long long)(paddr + size),
16454cff
MT
18930diff -urNp linux-2.6.38.1/arch/x86/mm/pgtable_32.c linux-2.6.38.1/arch/x86/mm/pgtable_32.c
18931--- linux-2.6.38.1/arch/x86/mm/pgtable_32.c 2011-03-14 21:20:32.000000000 -0400
18932+++ linux-2.6.38.1/arch/x86/mm/pgtable_32.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
18933@@ -48,10 +48,13 @@ void set_pte_vaddr(unsigned long vaddr,
18934 return;
18935 }
18936 pte = pte_offset_kernel(pmd, vaddr);
18937+
18938+ pax_open_kernel();
18939 if (pte_val(pteval))
18940 set_pte_at(&init_mm, vaddr, pte, pteval);
18941 else
18942 pte_clear(&init_mm, vaddr, pte);
18943+ pax_close_kernel();
18944
18945 /*
18946 * It's enough to flush this one mapping.
16454cff
MT
18947diff -urNp linux-2.6.38.1/arch/x86/mm/pgtable.c linux-2.6.38.1/arch/x86/mm/pgtable.c
18948--- linux-2.6.38.1/arch/x86/mm/pgtable.c 2011-03-23 17:20:06.000000000 -0400
18949+++ linux-2.6.38.1/arch/x86/mm/pgtable.c 2011-03-24 23:22:14.000000000 -0400
bc901d79 18950@@ -84,9 +84,58 @@ static inline void pgd_list_del(pgd_t *p
df50ba0c
MT
18951 list_del(&page->lru);
18952 }
18953
18954-#define UNSHARED_PTRS_PER_PGD \
18955- (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
18956+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
18957+pgdval_t clone_pgd_mask __read_only = ~_PAGE_PRESENT;
bc901d79 18958
df50ba0c
MT
18959+void __shadow_user_pgds(pgd_t *dst, const pgd_t *src, int count)
18960+{
18961+ while (count--)
bc901d79 18962+ *dst++ = __pgd((pgd_val(*src++) | (_PAGE_NX & __supported_pte_mask)) & ~_PAGE_USER);
df50ba0c
MT
18963+}
18964+#endif
18965+
18966+#ifdef CONFIG_PAX_PER_CPU_PGD
18967+void __clone_user_pgds(pgd_t *dst, const pgd_t *src, int count)
18968+{
18969+ while (count--)
18970+
18971+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
18972+ *dst++ = __pgd(pgd_val(*src++) & clone_pgd_mask);
18973+#else
18974+ *dst++ = *src++;
18975+#endif
18976+
18977+}
18978+#endif
18979+
18980+#ifdef CONFIG_PAX_PER_CPU_PGD
bc901d79 18981+static inline void pgd_ctor(struct mm_struct *mm, pgd_t *pgd) {}
df50ba0c
MT
18982+static inline void pgd_dtor(pgd_t *pgd) {}
18983+#ifdef CONFIG_X86_64
18984+#define pxd_t pud_t
18985+#define pyd_t pgd_t
18986+#define paravirt_release_pxd(pfn) paravirt_release_pud(pfn)
18987+#define pxd_free(mm, pud) pud_free((mm), (pud))
18988+#define pyd_populate(mm, pgd, pud) pgd_populate((mm), (pgd), (pud))
18989+#define pyd_offset(mm ,address) pgd_offset((mm), (address))
18990+#define PYD_SIZE PGDIR_SIZE
18991+#else
18992+#define pxd_t pmd_t
18993+#define pyd_t pud_t
18994+#define paravirt_release_pxd(pfn) paravirt_release_pmd(pfn)
18995+#define pxd_free(mm, pud) pmd_free((mm), (pud))
18996+#define pyd_populate(mm, pgd, pud) pud_populate((mm), (pgd), (pud))
18997+#define pyd_offset(mm ,address) pud_offset((mm), (address))
18998+#define PYD_SIZE PUD_SIZE
18999+#endif
19000+#else
19001+#define pxd_t pmd_t
19002+#define pyd_t pud_t
19003+#define paravirt_release_pxd(pfn) paravirt_release_pmd(pfn)
19004+#define pxd_free(mm, pmd) pmd_free((mm), (pmd))
19005+#define pyd_populate(mm, pud, pmd) pud_populate((mm), (pud), (pmd))
19006+#define pyd_offset(mm ,address) pud_offset((mm), (address))
19007+#define PYD_SIZE PUD_SIZE
19008
bc901d79 19009 static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm)
df50ba0c 19010 {
16454cff 19011@@ -128,6 +177,7 @@ static void pgd_dtor(pgd_t *pgd)
df50ba0c 19012 pgd_list_del(pgd);
16454cff 19013 spin_unlock(&pgd_lock);
df50ba0c
MT
19014 }
19015+#endif
19016
19017 /*
19018 * List of all pgd's needed for non-PAE so it can invalidate entries
16454cff 19019@@ -140,7 +190,7 @@ static void pgd_dtor(pgd_t *pgd)
df50ba0c
MT
19020 * -- wli
19021 */
19022
19023-#ifdef CONFIG_X86_PAE
19024+#if defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
19025 /*
19026 * In PAE mode, we need to do a cr3 reload (=tlb flush) when
19027 * updating the top-level pagetable entries to guarantee the
16454cff 19028@@ -152,7 +202,7 @@ static void pgd_dtor(pgd_t *pgd)
df50ba0c
MT
19029 * not shared between pagetables (!SHARED_KERNEL_PMDS), we allocate
19030 * and initialize the kernel pmds here.
19031 */
19032-#define PREALLOCATED_PMDS UNSHARED_PTRS_PER_PGD
19033+#define PREALLOCATED_PXDS (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
19034
19035 void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
19036 {
16454cff
MT
19037@@ -170,36 +220,38 @@ void pud_populate(struct mm_struct *mm,
19038 */
19039 flush_tlb_mm(mm);
df50ba0c
MT
19040 }
19041+#elif defined(CONFIG_X86_64) && defined(CONFIG_PAX_PER_CPU_PGD)
19042+#define PREALLOCATED_PXDS USER_PGD_PTRS
19043 #else /* !CONFIG_X86_PAE */
19044
19045 /* No need to prepopulate any pagetable entries in non-PAE modes. */
19046-#define PREALLOCATED_PMDS 0
19047+#define PREALLOCATED_PXDS 0
19048
19049 #endif /* CONFIG_X86_PAE */
19050
19051-static void free_pmds(pmd_t *pmds[])
19052+static void free_pxds(pxd_t *pxds[])
19053 {
19054 int i;
19055
19056- for(i = 0; i < PREALLOCATED_PMDS; i++)
19057- if (pmds[i])
19058- free_page((unsigned long)pmds[i]);
19059+ for(i = 0; i < PREALLOCATED_PXDS; i++)
19060+ if (pxds[i])
19061+ free_page((unsigned long)pxds[i]);
19062 }
19063
19064-static int preallocate_pmds(pmd_t *pmds[])
19065+static int preallocate_pxds(pxd_t *pxds[])
19066 {
19067 int i;
19068 bool failed = false;
19069
19070- for(i = 0; i < PREALLOCATED_PMDS; i++) {
19071- pmd_t *pmd = (pmd_t *)__get_free_page(PGALLOC_GFP);
19072- if (pmd == NULL)
19073+ for(i = 0; i < PREALLOCATED_PXDS; i++) {
19074+ pxd_t *pxd = (pxd_t *)__get_free_page(PGALLOC_GFP);
19075+ if (pxd == NULL)
19076 failed = true;
19077- pmds[i] = pmd;
19078+ pxds[i] = pxd;
19079 }
19080
19081 if (failed) {
19082- free_pmds(pmds);
19083+ free_pxds(pxds);
19084 return -ENOMEM;
19085 }
19086
16454cff 19087@@ -212,51 +264,55 @@ static int preallocate_pmds(pmd_t *pmds[
df50ba0c
MT
19088 * preallocate which never got a corresponding vma will need to be
19089 * freed manually.
19090 */
19091-static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
19092+static void pgd_mop_up_pxds(struct mm_struct *mm, pgd_t *pgdp)
19093 {
19094 int i;
19095
19096- for(i = 0; i < PREALLOCATED_PMDS; i++) {
19097+ for(i = 0; i < PREALLOCATED_PXDS; i++) {
19098 pgd_t pgd = pgdp[i];
19099
19100 if (pgd_val(pgd) != 0) {
19101- pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
19102+ pxd_t *pxd = (pxd_t *)pgd_page_vaddr(pgd);
19103
19104- pgdp[i] = native_make_pgd(0);
19105+ set_pgd(pgdp + i, native_make_pgd(0));
19106
19107- paravirt_release_pmd(pgd_val(pgd) >> PAGE_SHIFT);
19108- pmd_free(mm, pmd);
19109+ paravirt_release_pxd(pgd_val(pgd) >> PAGE_SHIFT);
19110+ pxd_free(mm, pxd);
19111 }
19112 }
19113 }
19114
19115-static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
19116+static void pgd_prepopulate_pxd(struct mm_struct *mm, pgd_t *pgd, pxd_t *pxds[])
19117 {
19118- pud_t *pud;
19119+ pyd_t *pyd;
19120 unsigned long addr;
19121 int i;
19122
19123- if (PREALLOCATED_PMDS == 0) /* Work around gcc-3.4.x bug */
19124+ if (PREALLOCATED_PXDS == 0) /* Work around gcc-3.4.x bug */
19125 return;
19126
19127- pud = pud_offset(pgd, 0);
19128+#ifdef CONFIG_X86_64
19129+ pyd = pyd_offset(mm, 0L);
19130+#else
19131+ pyd = pyd_offset(pgd, 0L);
19132+#endif
19133
19134- for (addr = i = 0; i < PREALLOCATED_PMDS;
19135- i++, pud++, addr += PUD_SIZE) {
19136- pmd_t *pmd = pmds[i];
19137+ for (addr = i = 0; i < PREALLOCATED_PXDS;
19138+ i++, pyd++, addr += PYD_SIZE) {
19139+ pxd_t *pxd = pxds[i];
19140
19141 if (i >= KERNEL_PGD_BOUNDARY)
19142- memcpy(pmd, (pmd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
19143- sizeof(pmd_t) * PTRS_PER_PMD);
19144+ memcpy(pxd, (pxd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
19145+ sizeof(pxd_t) * PTRS_PER_PMD);
19146
19147- pud_populate(mm, pud, pmd);
19148+ pyd_populate(mm, pyd, pxd);
19149 }
19150 }
19151
19152 pgd_t *pgd_alloc(struct mm_struct *mm)
19153 {
19154 pgd_t *pgd;
19155- pmd_t *pmds[PREALLOCATED_PMDS];
19156+ pxd_t *pxds[PREALLOCATED_PXDS];
df50ba0c
MT
19157
19158 pgd = (pgd_t *)__get_free_page(PGALLOC_GFP);
16454cff
MT
19159
19160@@ -265,11 +321,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
df50ba0c
MT
19161
19162 mm->pgd = pgd;
19163
19164- if (preallocate_pmds(pmds) != 0)
19165+ if (preallocate_pxds(pxds) != 0)
19166 goto out_free_pgd;
19167
19168 if (paravirt_pgd_alloc(mm) != 0)
19169- goto out_free_pmds;
19170+ goto out_free_pxds;
19171
19172 /*
19173 * Make sure that pre-populating the pmds is atomic with
16454cff
MT
19174@@ -279,14 +335,14 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
19175 spin_lock(&pgd_lock);
df50ba0c 19176
bc901d79 19177 pgd_ctor(mm, pgd);
df50ba0c
MT
19178- pgd_prepopulate_pmd(mm, pgd, pmds);
19179+ pgd_prepopulate_pxd(mm, pgd, pxds);
19180
16454cff 19181 spin_unlock(&pgd_lock);
df50ba0c
MT
19182
19183 return pgd;
19184
19185-out_free_pmds:
19186- free_pmds(pmds);
19187+out_free_pxds:
19188+ free_pxds(pxds);
19189 out_free_pgd:
19190 free_page((unsigned long)pgd);
19191 out:
16454cff 19192@@ -295,7 +351,7 @@ out:
df50ba0c
MT
19193
19194 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
19195 {
19196- pgd_mop_up_pmds(mm, pgd);
19197+ pgd_mop_up_pxds(mm, pgd);
19198 pgd_dtor(pgd);
19199 paravirt_pgd_free(mm, pgd);
19200 free_page((unsigned long)pgd);
16454cff
MT
19201diff -urNp linux-2.6.38.1/arch/x86/mm/setup_nx.c linux-2.6.38.1/arch/x86/mm/setup_nx.c
19202--- linux-2.6.38.1/arch/x86/mm/setup_nx.c 2011-03-14 21:20:32.000000000 -0400
19203+++ linux-2.6.38.1/arch/x86/mm/setup_nx.c 2011-03-21 18:31:35.000000000 -0400
efbe55a5 19204@@ -5,8 +5,10 @@
df50ba0c
MT
19205 #include <asm/pgtable.h>
19206 #include <asm/proto.h>
19207
19208+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
19209 static int disable_nx __cpuinitdata;
df50ba0c 19210
efbe55a5 19211+#ifndef CONFIG_PAX_PAGEEXEC
df50ba0c
MT
19212 /*
19213 * noexec = on|off
19214 *
efbe55a5 19215@@ -28,12 +30,17 @@ static int __init noexec_setup(char *str
df50ba0c
MT
19216 return 0;
19217 }
19218 early_param("noexec", noexec_setup);
efbe55a5
MT
19219+#endif
19220+
df50ba0c
MT
19221+#endif
19222
19223 void __cpuinit x86_configure_nx(void)
19224 {
19225+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
19226 if (cpu_has_nx && !disable_nx)
19227 __supported_pte_mask |= _PAGE_NX;
19228 else
19229+#endif
19230 __supported_pte_mask &= ~_PAGE_NX;
19231 }
19232
16454cff
MT
19233diff -urNp linux-2.6.38.1/arch/x86/mm/tlb.c linux-2.6.38.1/arch/x86/mm/tlb.c
19234--- linux-2.6.38.1/arch/x86/mm/tlb.c 2011-03-14 21:20:32.000000000 -0400
19235+++ linux-2.6.38.1/arch/x86/mm/tlb.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 19236@@ -14,7 +14,7 @@
58c5fc13
MT
19237 #include <asm/uv/uv.h>
19238
19239 DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
19240- = { &init_mm, 0, };
19241+ = { &init_mm, 0 };
19242
19243 /*
19244 * Smarter SMP flushing macros.
bc901d79 19245@@ -65,7 +65,11 @@ void leave_mm(int cpu)
df50ba0c
MT
19246 BUG();
19247 cpumask_clear_cpu(cpu,
19248 mm_cpumask(percpu_read(cpu_tlbstate.active_mm)));
19249+
19250+#ifndef CONFIG_PAX_PER_CPU_PGD
19251 load_cr3(swapper_pg_dir);
19252+#endif
19253+
19254 }
19255 EXPORT_SYMBOL_GPL(leave_mm);
19256
16454cff
MT
19257diff -urNp linux-2.6.38.1/arch/x86/oprofile/backtrace.c linux-2.6.38.1/arch/x86/oprofile/backtrace.c
19258--- linux-2.6.38.1/arch/x86/oprofile/backtrace.c 2011-03-14 21:20:32.000000000 -0400
19259+++ linux-2.6.38.1/arch/x86/oprofile/backtrace.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
19260@@ -57,7 +57,7 @@ dump_user_backtrace_32(struct stack_fram
19261 struct stack_frame_ia32 *fp;
ae4e228f
MT
19262
19263 /* Also check accessibility of one struct frame_head beyond */
19264- if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
19265+ if (!__access_ok(VERIFY_READ, head, sizeof(bufhead)))
19266 return NULL;
19267 if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
19268 return NULL;
bc901d79 19269@@ -123,7 +123,7 @@ x86_backtrace(struct pt_regs * const reg
58c5fc13 19270 {
bc901d79 19271 struct stack_frame *head = (struct stack_frame *)frame_pointer(regs);
58c5fc13
MT
19272
19273- if (!user_mode_vm(regs)) {
19274+ if (!user_mode(regs)) {
19275 unsigned long stack = kernel_stack_pointer(regs);
19276 if (depth)
16454cff
MT
19277 dump_trace(NULL, regs, (unsigned long *)stack,
19278diff -urNp linux-2.6.38.1/arch/x86/oprofile/op_model_p4.c linux-2.6.38.1/arch/x86/oprofile/op_model_p4.c
19279--- linux-2.6.38.1/arch/x86/oprofile/op_model_p4.c 2011-03-14 21:20:32.000000000 -0400
19280+++ linux-2.6.38.1/arch/x86/oprofile/op_model_p4.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 19281@@ -50,7 +50,7 @@ static inline void setup_num_counters(vo
58c5fc13
MT
19282 #endif
19283 }
19284
19285-static int inline addr_increment(void)
19286+static inline int addr_increment(void)
19287 {
19288 #ifdef CONFIG_SMP
19289 return smp_num_siblings == 2 ? 2 : 1;
16454cff
MT
19290diff -urNp linux-2.6.38.1/arch/x86/pci/ce4100.c linux-2.6.38.1/arch/x86/pci/ce4100.c
19291--- linux-2.6.38.1/arch/x86/pci/ce4100.c 2011-03-14 21:20:32.000000000 -0400
19292+++ linux-2.6.38.1/arch/x86/pci/ce4100.c 2011-03-21 18:31:35.000000000 -0400
19293@@ -302,7 +302,7 @@ static int ce4100_conf_write(unsigned in
19294 return pci_direct_conf1.write(seg, bus, devfn, reg, len, value);
19295 }
19296
19297-struct pci_raw_ops ce4100_pci_conf = {
19298+const struct pci_raw_ops ce4100_pci_conf = {
19299 .read = ce4100_conf_read,
19300 .write = ce4100_conf_write,
19301 };
19302diff -urNp linux-2.6.38.1/arch/x86/pci/common.c linux-2.6.38.1/arch/x86/pci/common.c
19303--- linux-2.6.38.1/arch/x86/pci/common.c 2011-03-14 21:20:32.000000000 -0400
19304+++ linux-2.6.38.1/arch/x86/pci/common.c 2011-03-21 18:31:35.000000000 -0400
19305@@ -33,8 +33,8 @@ int noioapicreroute = 1;
ae4e228f
MT
19306 int pcibios_last_bus = -1;
19307 unsigned long pirq_table_addr;
19308 struct pci_bus *pci_root_bus;
19309-struct pci_raw_ops *raw_pci_ops;
19310-struct pci_raw_ops *raw_pci_ext_ops;
19311+const struct pci_raw_ops *raw_pci_ops;
19312+const struct pci_raw_ops *raw_pci_ext_ops;
19313
19314 int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
19315 int reg, int len, u32 *val)
16454cff 19316@@ -423,7 +423,7 @@ static const struct dmi_system_id __devi
58c5fc13
MT
19317 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
19318 },
19319 },
19320- {}
19321+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
19322 };
19323
19324 void __init dmi_check_pciprobe(void)
16454cff
MT
19325diff -urNp linux-2.6.38.1/arch/x86/pci/direct.c linux-2.6.38.1/arch/x86/pci/direct.c
19326--- linux-2.6.38.1/arch/x86/pci/direct.c 2011-03-14 21:20:32.000000000 -0400
19327+++ linux-2.6.38.1/arch/x86/pci/direct.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
19328@@ -79,7 +79,7 @@ static int pci_conf1_write(unsigned int
19329
19330 #undef PCI_CONF1_ADDRESS
19331
19332-struct pci_raw_ops pci_direct_conf1 = {
19333+const struct pci_raw_ops pci_direct_conf1 = {
19334 .read = pci_conf1_read,
19335 .write = pci_conf1_write,
19336 };
19337@@ -173,7 +173,7 @@ static int pci_conf2_write(unsigned int
19338
19339 #undef PCI_CONF2_ADDRESS
19340
19341-struct pci_raw_ops pci_direct_conf2 = {
19342+const struct pci_raw_ops pci_direct_conf2 = {
19343 .read = pci_conf2_read,
19344 .write = pci_conf2_write,
19345 };
19346@@ -189,7 +189,7 @@ struct pci_raw_ops pci_direct_conf2 = {
19347 * This should be close to trivial, but it isn't, because there are buggy
19348 * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
19349 */
19350-static int __init pci_sanity_check(struct pci_raw_ops *o)
19351+static int __init pci_sanity_check(const struct pci_raw_ops *o)
19352 {
19353 u32 x = 0;
19354 int year, devfn;
16454cff
MT
19355diff -urNp linux-2.6.38.1/arch/x86/pci/fixup.c linux-2.6.38.1/arch/x86/pci/fixup.c
19356--- linux-2.6.38.1/arch/x86/pci/fixup.c 2011-03-14 21:20:32.000000000 -0400
19357+++ linux-2.6.38.1/arch/x86/pci/fixup.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
19358@@ -364,7 +364,7 @@ static const struct dmi_system_id __devi
19359 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
19360 },
19361 },
19362- {}
19363+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19364 };
19365
19366 /*
19367@@ -435,7 +435,7 @@ static const struct dmi_system_id __devi
19368 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
19369 },
19370 },
19371- { }
19372+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19373 };
19374
19375 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
16454cff
MT
19376diff -urNp linux-2.6.38.1/arch/x86/pci/irq.c linux-2.6.38.1/arch/x86/pci/irq.c
19377--- linux-2.6.38.1/arch/x86/pci/irq.c 2011-03-14 21:20:32.000000000 -0400
19378+++ linux-2.6.38.1/arch/x86/pci/irq.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 19379@@ -542,7 +542,7 @@ static __init int intel_router_probe(str
58c5fc13
MT
19380 static struct pci_device_id __initdata pirq_440gx[] = {
19381 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
19382 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
19383- { },
19384+ { PCI_DEVICE(0, 0) }
19385 };
19386
19387 /* 440GX has a proprietary PIRQ router -- don't use it */
16454cff 19388@@ -1115,7 +1115,7 @@ static struct dmi_system_id __initdata p
58c5fc13
MT
19389 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
19390 },
19391 },
19392- { }
19393+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19394 };
19395
df50ba0c 19396 void __init pcibios_irq_init(void)
16454cff
MT
19397diff -urNp linux-2.6.38.1/arch/x86/pci/mmconfig_32.c linux-2.6.38.1/arch/x86/pci/mmconfig_32.c
19398--- linux-2.6.38.1/arch/x86/pci/mmconfig_32.c 2011-03-14 21:20:32.000000000 -0400
19399+++ linux-2.6.38.1/arch/x86/pci/mmconfig_32.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
19400@@ -117,7 +117,7 @@ static int pci_mmcfg_write(unsigned int
19401 return 0;
19402 }
19403
19404-static struct pci_raw_ops pci_mmcfg = {
19405+static const struct pci_raw_ops pci_mmcfg = {
19406 .read = pci_mmcfg_read,
19407 .write = pci_mmcfg_write,
19408 };
16454cff
MT
19409diff -urNp linux-2.6.38.1/arch/x86/pci/mmconfig_64.c linux-2.6.38.1/arch/x86/pci/mmconfig_64.c
19410--- linux-2.6.38.1/arch/x86/pci/mmconfig_64.c 2011-03-14 21:20:32.000000000 -0400
19411+++ linux-2.6.38.1/arch/x86/pci/mmconfig_64.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
19412@@ -81,7 +81,7 @@ static int pci_mmcfg_write(unsigned int
19413 return 0;
19414 }
19415
19416-static struct pci_raw_ops pci_mmcfg = {
19417+static const struct pci_raw_ops pci_mmcfg = {
19418 .read = pci_mmcfg_read,
19419 .write = pci_mmcfg_write,
19420 };
16454cff
MT
19421diff -urNp linux-2.6.38.1/arch/x86/pci/numaq_32.c linux-2.6.38.1/arch/x86/pci/numaq_32.c
19422--- linux-2.6.38.1/arch/x86/pci/numaq_32.c 2011-03-14 21:20:32.000000000 -0400
19423+++ linux-2.6.38.1/arch/x86/pci/numaq_32.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 19424@@ -108,7 +108,7 @@ static int pci_conf1_mq_write(unsigned i
ae4e228f
MT
19425
19426 #undef PCI_CONF1_MQ_ADDRESS
19427
19428-static struct pci_raw_ops pci_direct_conf1_mq = {
19429+static const struct pci_raw_ops pci_direct_conf1_mq = {
19430 .read = pci_conf1_mq_read,
19431 .write = pci_conf1_mq_write
19432 };
16454cff
MT
19433diff -urNp linux-2.6.38.1/arch/x86/pci/olpc.c linux-2.6.38.1/arch/x86/pci/olpc.c
19434--- linux-2.6.38.1/arch/x86/pci/olpc.c 2011-03-14 21:20:32.000000000 -0400
19435+++ linux-2.6.38.1/arch/x86/pci/olpc.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
19436@@ -297,7 +297,7 @@ static int pci_olpc_write(unsigned int s
19437 return 0;
19438 }
19439
19440-static struct pci_raw_ops pci_olpc_conf = {
19441+static const struct pci_raw_ops pci_olpc_conf = {
19442 .read = pci_olpc_read,
19443 .write = pci_olpc_write,
19444 };
16454cff
MT
19445diff -urNp linux-2.6.38.1/arch/x86/pci/pcbios.c linux-2.6.38.1/arch/x86/pci/pcbios.c
19446--- linux-2.6.38.1/arch/x86/pci/pcbios.c 2011-03-14 21:20:32.000000000 -0400
19447+++ linux-2.6.38.1/arch/x86/pci/pcbios.c 2011-03-21 18:31:35.000000000 -0400
19448@@ -79,50 +79,93 @@ union bios32 {
58c5fc13
MT
19449 static struct {
19450 unsigned long address;
19451 unsigned short segment;
19452-} bios32_indirect = { 0, __KERNEL_CS };
19453+} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
19454
19455 /*
19456 * Returns the entry point for the given service, NULL on error
19457 */
19458
19459-static unsigned long bios32_service(unsigned long service)
19460+static unsigned long __devinit bios32_service(unsigned long service)
19461 {
19462 unsigned char return_code; /* %al */
19463 unsigned long address; /* %ebx */
19464 unsigned long length; /* %ecx */
19465 unsigned long entry; /* %edx */
19466 unsigned long flags;
19467+ struct desc_struct d, *gdt;
58c5fc13
MT
19468
19469 local_irq_save(flags);
19470- __asm__("lcall *(%%edi); cld"
19471+
19472+ gdt = get_cpu_gdt_table(smp_processor_id());
19473+
58c5fc13
MT
19474+ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
19475+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
19476+ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
19477+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
19478+
58c5fc13
MT
19479+ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
19480 : "=a" (return_code),
19481 "=b" (address),
19482 "=c" (length),
19483 "=d" (entry)
19484 : "0" (service),
19485 "1" (0),
19486- "D" (&bios32_indirect));
19487+ "D" (&bios32_indirect),
19488+ "r"(__PCIBIOS_DS)
19489+ : "memory");
19490+
ae4e228f 19491+ pax_open_kernel();
58c5fc13
MT
19492+ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
19493+ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
19494+ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
19495+ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
ae4e228f 19496+ pax_close_kernel();
58c5fc13
MT
19497+
19498 local_irq_restore(flags);
19499
19500 switch (return_code) {
19501- case 0:
19502- return address + entry;
19503- case 0x80: /* Not present */
19504- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
19505- return 0;
19506- default: /* Shouldn't happen */
19507- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
19508- service, return_code);
19509+ case 0: {
19510+ int cpu;
19511+ unsigned char flags;
19512+
19513+ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
19514+ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
19515+ printk(KERN_WARNING "bios32_service: not valid\n");
19516 return 0;
19517+ }
19518+ address = address + PAGE_OFFSET;
19519+ length += 16UL; /* some BIOSs underreport this... */
19520+ flags = 4;
19521+ if (length >= 64*1024*1024) {
19522+ length >>= PAGE_SHIFT;
19523+ flags |= 8;
19524+ }
19525+
58c5fc13
MT
19526+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
19527+ gdt = get_cpu_gdt_table(cpu);
19528+ pack_descriptor(&d, address, length, 0x9b, flags);
19529+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
19530+ pack_descriptor(&d, address, length, 0x93, flags);
19531+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
19532+ }
58c5fc13
MT
19533+ return entry;
19534+ }
19535+ case 0x80: /* Not present */
19536+ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
19537+ return 0;
19538+ default: /* Shouldn't happen */
19539+ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
19540+ service, return_code);
19541+ return 0;
19542 }
19543 }
19544
19545 static struct {
19546 unsigned long address;
19547 unsigned short segment;
19548-} pci_indirect = { 0, __KERNEL_CS };
19549+} pci_indirect __read_only = { 0, __PCIBIOS_CS };
19550
19551-static int pci_bios_present;
19552+static int pci_bios_present __read_only;
19553
19554 static int __devinit check_pcibios(void)
19555 {
16454cff 19556@@ -131,11 +174,13 @@ static int __devinit check_pcibios(void)
58c5fc13
MT
19557 unsigned long flags, pcibios_entry;
19558
19559 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
19560- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
19561+ pci_indirect.address = pcibios_entry;
19562
19563 local_irq_save(flags);
19564- __asm__(
19565- "lcall *(%%edi); cld\n\t"
19566+ __asm__("movw %w6, %%ds\n\t"
19567+ "lcall *%%ss:(%%edi); cld\n\t"
19568+ "push %%ss\n\t"
19569+ "pop %%ds\n\t"
19570 "jc 1f\n\t"
19571 "xor %%ah, %%ah\n"
19572 "1:"
16454cff 19573@@ -144,7 +189,8 @@ static int __devinit check_pcibios(void)
58c5fc13
MT
19574 "=b" (ebx),
19575 "=c" (ecx)
19576 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
19577- "D" (&pci_indirect)
19578+ "D" (&pci_indirect),
19579+ "r" (__PCIBIOS_DS)
19580 : "memory");
19581 local_irq_restore(flags);
19582
16454cff 19583@@ -188,7 +234,10 @@ static int pci_bios_read(unsigned int se
58c5fc13
MT
19584
19585 switch (len) {
19586 case 1:
19587- __asm__("lcall *(%%esi); cld\n\t"
19588+ __asm__("movw %w6, %%ds\n\t"
19589+ "lcall *%%ss:(%%esi); cld\n\t"
19590+ "push %%ss\n\t"
19591+ "pop %%ds\n\t"
19592 "jc 1f\n\t"
19593 "xor %%ah, %%ah\n"
19594 "1:"
16454cff 19595@@ -197,7 +246,8 @@ static int pci_bios_read(unsigned int se
58c5fc13
MT
19596 : "1" (PCIBIOS_READ_CONFIG_BYTE),
19597 "b" (bx),
19598 "D" ((long)reg),
19599- "S" (&pci_indirect));
19600+ "S" (&pci_indirect),
19601+ "r" (__PCIBIOS_DS));
19602 /*
19603 * Zero-extend the result beyond 8 bits, do not trust the
19604 * BIOS having done it:
16454cff 19605@@ -205,7 +255,10 @@ static int pci_bios_read(unsigned int se
58c5fc13
MT
19606 *value &= 0xff;
19607 break;
19608 case 2:
19609- __asm__("lcall *(%%esi); cld\n\t"
19610+ __asm__("movw %w6, %%ds\n\t"
19611+ "lcall *%%ss:(%%esi); cld\n\t"
19612+ "push %%ss\n\t"
19613+ "pop %%ds\n\t"
19614 "jc 1f\n\t"
19615 "xor %%ah, %%ah\n"
19616 "1:"
16454cff 19617@@ -214,7 +267,8 @@ static int pci_bios_read(unsigned int se
58c5fc13
MT
19618 : "1" (PCIBIOS_READ_CONFIG_WORD),
19619 "b" (bx),
19620 "D" ((long)reg),
19621- "S" (&pci_indirect));
19622+ "S" (&pci_indirect),
19623+ "r" (__PCIBIOS_DS));
19624 /*
19625 * Zero-extend the result beyond 16 bits, do not trust the
19626 * BIOS having done it:
16454cff 19627@@ -222,7 +276,10 @@ static int pci_bios_read(unsigned int se
58c5fc13
MT
19628 *value &= 0xffff;
19629 break;
19630 case 4:
19631- __asm__("lcall *(%%esi); cld\n\t"
19632+ __asm__("movw %w6, %%ds\n\t"
19633+ "lcall *%%ss:(%%esi); cld\n\t"
19634+ "push %%ss\n\t"
19635+ "pop %%ds\n\t"
19636 "jc 1f\n\t"
19637 "xor %%ah, %%ah\n"
19638 "1:"
16454cff 19639@@ -231,7 +288,8 @@ static int pci_bios_read(unsigned int se
58c5fc13
MT
19640 : "1" (PCIBIOS_READ_CONFIG_DWORD),
19641 "b" (bx),
19642 "D" ((long)reg),
19643- "S" (&pci_indirect));
19644+ "S" (&pci_indirect),
19645+ "r" (__PCIBIOS_DS));
19646 break;
19647 }
19648
16454cff 19649@@ -254,7 +312,10 @@ static int pci_bios_write(unsigned int s
58c5fc13
MT
19650
19651 switch (len) {
19652 case 1:
19653- __asm__("lcall *(%%esi); cld\n\t"
19654+ __asm__("movw %w6, %%ds\n\t"
19655+ "lcall *%%ss:(%%esi); cld\n\t"
19656+ "push %%ss\n\t"
19657+ "pop %%ds\n\t"
19658 "jc 1f\n\t"
19659 "xor %%ah, %%ah\n"
19660 "1:"
16454cff 19661@@ -263,10 +324,14 @@ static int pci_bios_write(unsigned int s
58c5fc13
MT
19662 "c" (value),
19663 "b" (bx),
19664 "D" ((long)reg),
19665- "S" (&pci_indirect));
19666+ "S" (&pci_indirect),
19667+ "r" (__PCIBIOS_DS));
19668 break;
19669 case 2:
19670- __asm__("lcall *(%%esi); cld\n\t"
19671+ __asm__("movw %w6, %%ds\n\t"
19672+ "lcall *%%ss:(%%esi); cld\n\t"
19673+ "push %%ss\n\t"
19674+ "pop %%ds\n\t"
19675 "jc 1f\n\t"
19676 "xor %%ah, %%ah\n"
19677 "1:"
16454cff 19678@@ -275,10 +340,14 @@ static int pci_bios_write(unsigned int s
58c5fc13
MT
19679 "c" (value),
19680 "b" (bx),
19681 "D" ((long)reg),
19682- "S" (&pci_indirect));
19683+ "S" (&pci_indirect),
19684+ "r" (__PCIBIOS_DS));
19685 break;
19686 case 4:
19687- __asm__("lcall *(%%esi); cld\n\t"
19688+ __asm__("movw %w6, %%ds\n\t"
19689+ "lcall *%%ss:(%%esi); cld\n\t"
19690+ "push %%ss\n\t"
19691+ "pop %%ds\n\t"
19692 "jc 1f\n\t"
19693 "xor %%ah, %%ah\n"
19694 "1:"
16454cff 19695@@ -287,7 +356,8 @@ static int pci_bios_write(unsigned int s
58c5fc13
MT
19696 "c" (value),
19697 "b" (bx),
19698 "D" ((long)reg),
19699- "S" (&pci_indirect));
19700+ "S" (&pci_indirect),
19701+ "r" (__PCIBIOS_DS));
19702 break;
19703 }
19704
16454cff 19705@@ -301,7 +371,7 @@ static int pci_bios_write(unsigned int s
ae4e228f
MT
19706 * Function table for BIOS32 access
19707 */
19708
19709-static struct pci_raw_ops pci_bios_access = {
19710+static const struct pci_raw_ops pci_bios_access = {
19711 .read = pci_bios_read,
19712 .write = pci_bios_write
19713 };
16454cff 19714@@ -310,7 +380,7 @@ static struct pci_raw_ops pci_bios_acces
ae4e228f
MT
19715 * Try to find PCI BIOS.
19716 */
19717
19718-static struct pci_raw_ops * __devinit pci_find_bios(void)
19719+static const struct pci_raw_ops * __devinit pci_find_bios(void)
19720 {
19721 union bios32 *check;
19722 unsigned char sum;
16454cff 19723@@ -392,10 +462,13 @@ struct irq_routing_table * pcibios_get_i
58c5fc13
MT
19724
19725 DBG("PCI: Fetching IRQ routing table... ");
19726 __asm__("push %%es\n\t"
19727+ "movw %w8, %%ds\n\t"
19728 "push %%ds\n\t"
19729 "pop %%es\n\t"
19730- "lcall *(%%esi); cld\n\t"
19731+ "lcall *%%ss:(%%esi); cld\n\t"
19732 "pop %%es\n\t"
19733+ "push %%ss\n\t"
19734+ "pop %%ds\n"
19735 "jc 1f\n\t"
19736 "xor %%ah, %%ah\n"
19737 "1:"
16454cff 19738@@ -406,7 +479,8 @@ struct irq_routing_table * pcibios_get_i
58c5fc13
MT
19739 "1" (0),
19740 "D" ((long) &opt),
19741 "S" (&pci_indirect),
19742- "m" (opt)
19743+ "m" (opt),
19744+ "r" (__PCIBIOS_DS)
19745 : "memory");
19746 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
19747 if (ret & 0xff00)
16454cff 19748@@ -430,7 +504,10 @@ int pcibios_set_irq_routing(struct pci_d
58c5fc13
MT
19749 {
19750 int ret;
19751
19752- __asm__("lcall *(%%esi); cld\n\t"
19753+ __asm__("movw %w5, %%ds\n\t"
19754+ "lcall *%%ss:(%%esi); cld\n\t"
19755+ "push %%ss\n\t"
19756+ "pop %%ds\n"
19757 "jc 1f\n\t"
19758 "xor %%ah, %%ah\n"
19759 "1:"
16454cff 19760@@ -438,7 +515,8 @@ int pcibios_set_irq_routing(struct pci_d
58c5fc13
MT
19761 : "0" (PCIBIOS_SET_PCI_HW_INT),
19762 "b" ((dev->bus->number << 8) | dev->devfn),
19763 "c" ((irq << 8) | (pin + 10)),
19764- "S" (&pci_indirect));
19765+ "S" (&pci_indirect),
19766+ "r" (__PCIBIOS_DS));
19767 return !(ret & 0xff00);
19768 }
19769 EXPORT_SYMBOL(pcibios_set_irq_routing);
16454cff
MT
19770diff -urNp linux-2.6.38.1/arch/x86/platform/efi/efi_32.c linux-2.6.38.1/arch/x86/platform/efi/efi_32.c
19771--- linux-2.6.38.1/arch/x86/platform/efi/efi_32.c 2011-03-14 21:20:32.000000000 -0400
19772+++ linux-2.6.38.1/arch/x86/platform/efi/efi_32.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
19773@@ -38,70 +38,37 @@
19774 */
19775
19776 static unsigned long efi_rt_eflags;
19777-static pgd_t efi_bak_pg_dir_pointer[2];
19778+static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
19779
19780-void efi_call_phys_prelog(void)
19781+void __init efi_call_phys_prelog(void)
19782 {
19783- unsigned long cr4;
19784- unsigned long temp;
19785 struct desc_ptr gdt_descr;
19786
19787 local_irq_save(efi_rt_eflags);
19788
19789- /*
19790- * If I don't have PAE, I should just duplicate two entries in page
19791- * directory. If I have PAE, I just need to duplicate one entry in
19792- * page directory.
19793- */
19794- cr4 = read_cr4_safe();
19795-
19796- if (cr4 & X86_CR4_PAE) {
19797- efi_bak_pg_dir_pointer[0].pgd =
19798- swapper_pg_dir[pgd_index(0)].pgd;
19799- swapper_pg_dir[0].pgd =
19800- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
19801- } else {
19802- efi_bak_pg_dir_pointer[0].pgd =
19803- swapper_pg_dir[pgd_index(0)].pgd;
19804- efi_bak_pg_dir_pointer[1].pgd =
19805- swapper_pg_dir[pgd_index(0x400000)].pgd;
19806- swapper_pg_dir[pgd_index(0)].pgd =
19807- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
19808- temp = PAGE_OFFSET + 0x400000;
19809- swapper_pg_dir[pgd_index(0x400000)].pgd =
19810- swapper_pg_dir[pgd_index(temp)].pgd;
19811- }
19812+ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
19813+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
19814+ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
19815
19816 /*
19817 * After the lock is released, the original page table is restored.
19818 */
19819 __flush_tlb_all();
19820
19821- gdt_descr.address = __pa(get_cpu_gdt_table(0));
19822+ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
19823 gdt_descr.size = GDT_SIZE - 1;
19824 load_gdt(&gdt_descr);
19825 }
19826
19827-void efi_call_phys_epilog(void)
19828+void __init efi_call_phys_epilog(void)
19829 {
19830- unsigned long cr4;
19831 struct desc_ptr gdt_descr;
19832
19833- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
19834+ gdt_descr.address = get_cpu_gdt_table(0);
19835 gdt_descr.size = GDT_SIZE - 1;
19836 load_gdt(&gdt_descr);
19837
19838- cr4 = read_cr4_safe();
19839-
19840- if (cr4 & X86_CR4_PAE) {
19841- swapper_pg_dir[pgd_index(0)].pgd =
19842- efi_bak_pg_dir_pointer[0].pgd;
19843- } else {
19844- swapper_pg_dir[pgd_index(0)].pgd =
19845- efi_bak_pg_dir_pointer[0].pgd;
19846- swapper_pg_dir[pgd_index(0x400000)].pgd =
19847- efi_bak_pg_dir_pointer[1].pgd;
19848- }
19849+ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
19850
19851 /*
19852 * After the lock is released, the original page table is restored.
16454cff
MT
19853diff -urNp linux-2.6.38.1/arch/x86/platform/efi/efi_stub_32.S linux-2.6.38.1/arch/x86/platform/efi/efi_stub_32.S
19854--- linux-2.6.38.1/arch/x86/platform/efi/efi_stub_32.S 2011-03-14 21:20:32.000000000 -0400
19855+++ linux-2.6.38.1/arch/x86/platform/efi/efi_stub_32.S 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
19856@@ -6,6 +6,7 @@
19857 */
19858
19859 #include <linux/linkage.h>
19860+#include <linux/init.h>
19861 #include <asm/page_types.h>
19862
19863 /*
19864@@ -20,7 +21,7 @@
19865 * service functions will comply with gcc calling convention, too.
19866 */
19867
19868-.text
19869+__INIT
19870 ENTRY(efi_call_phys)
19871 /*
19872 * 0. The function can only be called in Linux kernel. So CS has been
19873@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
19874 * The mapping of lower virtual memory has been created in prelog and
19875 * epilog.
19876 */
19877- movl $1f, %edx
19878- subl $__PAGE_OFFSET, %edx
19879- jmp *%edx
19880+ jmp 1f-__PAGE_OFFSET
19881 1:
19882
19883 /*
19884@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
19885 * parameter 2, ..., param n. To make things easy, we save the return
19886 * address of efi_call_phys in a global variable.
19887 */
19888- popl %edx
19889- movl %edx, saved_return_addr
19890- /* get the function pointer into ECX*/
19891- popl %ecx
19892- movl %ecx, efi_rt_function_ptr
19893- movl $2f, %edx
19894- subl $__PAGE_OFFSET, %edx
19895- pushl %edx
19896+ popl (saved_return_addr)
19897+ popl (efi_rt_function_ptr)
19898
19899 /*
19900 * 3. Clear PG bit in %CR0.
19901@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
19902 /*
19903 * 5. Call the physical function.
19904 */
19905- jmp *%ecx
19906+ call *(efi_rt_function_ptr-__PAGE_OFFSET)
19907
19908-2:
19909 /*
19910 * 6. After EFI runtime service returns, control will return to
19911 * following instruction. We'd better readjust stack pointer first.
19912@@ -88,35 +80,28 @@ ENTRY(efi_call_phys)
19913 movl %cr0, %edx
19914 orl $0x80000000, %edx
19915 movl %edx, %cr0
19916- jmp 1f
19917-1:
19918+
19919 /*
19920 * 8. Now restore the virtual mode from flat mode by
19921 * adding EIP with PAGE_OFFSET.
19922 */
19923- movl $1f, %edx
19924- jmp *%edx
19925+ jmp 1f+__PAGE_OFFSET
19926 1:
19927
19928 /*
19929 * 9. Balance the stack. And because EAX contain the return value,
19930 * we'd better not clobber it.
19931 */
19932- leal efi_rt_function_ptr, %edx
19933- movl (%edx), %ecx
19934- pushl %ecx
19935+ pushl (efi_rt_function_ptr)
19936
19937 /*
19938- * 10. Push the saved return address onto the stack and return.
19939+ * 10. Return to the saved return address.
19940 */
19941- leal saved_return_addr, %edx
19942- movl (%edx), %ecx
19943- pushl %ecx
19944- ret
19945+ jmpl *(saved_return_addr)
19946 ENDPROC(efi_call_phys)
19947 .previous
19948
19949-.data
19950+__INITDATA
19951 saved_return_addr:
19952 .long 0
19953 efi_rt_function_ptr:
16454cff
MT
19954diff -urNp linux-2.6.38.1/arch/x86/power/cpu.c linux-2.6.38.1/arch/x86/power/cpu.c
19955--- linux-2.6.38.1/arch/x86/power/cpu.c 2011-03-14 21:20:32.000000000 -0400
19956+++ linux-2.6.38.1/arch/x86/power/cpu.c 2011-03-21 18:31:35.000000000 -0400
6892158b 19957@@ -130,7 +130,7 @@ static void do_fpu_end(void)
58c5fc13
MT
19958 static void fix_processor_context(void)
19959 {
19960 int cpu = smp_processor_id();
19961- struct tss_struct *t = &per_cpu(init_tss, cpu);
19962+ struct tss_struct *t = init_tss + cpu;
58c5fc13
MT
19963
19964 set_tss_desc(cpu, t); /*
19965 * This just modifies memory; should not be
6892158b 19966@@ -140,7 +140,9 @@ static void fix_processor_context(void)
58c5fc13
MT
19967 */
19968
19969 #ifdef CONFIG_X86_64
ae4e228f 19970+ pax_open_kernel();
58c5fc13 19971 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
ae4e228f 19972+ pax_close_kernel();
58c5fc13 19973
58c5fc13
MT
19974 syscall_init(); /* This sets MSR_*STAR and related */
19975 #endif
16454cff
MT
19976diff -urNp linux-2.6.38.1/arch/x86/vdso/Makefile linux-2.6.38.1/arch/x86/vdso/Makefile
19977--- linux-2.6.38.1/arch/x86/vdso/Makefile 2011-03-14 21:20:32.000000000 -0400
19978+++ linux-2.6.38.1/arch/x86/vdso/Makefile 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
19979@@ -123,7 +123,7 @@ quiet_cmd_vdso = VDSO $@
19980 -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
19981 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
58c5fc13 19982
ae4e228f
MT
19983-VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
19984+VDSO_LDFLAGS = -fPIC -shared --no-undefined $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
58c5fc13
MT
19985 GCOV_PROFILE := n
19986
19987 #
16454cff
MT
19988diff -urNp linux-2.6.38.1/arch/x86/vdso/vclock_gettime.c linux-2.6.38.1/arch/x86/vdso/vclock_gettime.c
19989--- linux-2.6.38.1/arch/x86/vdso/vclock_gettime.c 2011-03-14 21:20:32.000000000 -0400
19990+++ linux-2.6.38.1/arch/x86/vdso/vclock_gettime.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
19991@@ -22,24 +22,48 @@
19992 #include <asm/hpet.h>
19993 #include <asm/unistd.h>
19994 #include <asm/io.h>
19995+#include <asm/fixmap.h>
19996 #include "vextern.h"
19997
19998 #define gtod vdso_vsyscall_gtod_data
19999
20000+notrace noinline long __vdso_fallback_time(long *t)
20001+{
20002+ long secs;
20003+ asm volatile("syscall"
20004+ : "=a" (secs)
20005+ : "0" (__NR_time),"D" (t) : "r11", "cx", "memory");
20006+ return secs;
20007+}
20008+
20009 notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
20010 {
20011 long ret;
20012 asm("syscall" : "=a" (ret) :
20013- "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "memory");
20014+ "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "r11", "cx", "memory");
20015 return ret;
20016 }
20017
20018+notrace static inline cycle_t __vdso_vread_hpet(void)
20019+{
20020+ return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0);
20021+}
20022+
20023+notrace static inline cycle_t __vdso_vread_tsc(void)
20024+{
20025+ cycle_t ret = (cycle_t)vget_cycles();
20026+
20027+ return ret >= gtod->clock.cycle_last ? ret : gtod->clock.cycle_last;
20028+}
20029+
20030 notrace static inline long vgetns(void)
20031 {
20032 long v;
20033- cycles_t (*vread)(void);
20034- vread = gtod->clock.vread;
20035- v = (vread() - gtod->clock.cycle_last) & gtod->clock.mask;
20036+ if (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3])
20037+ v = __vdso_vread_tsc();
20038+ else
20039+ v = __vdso_vread_hpet();
20040+ v = (v - gtod->clock.cycle_last) & gtod->clock.mask;
20041 return (v * gtod->clock.mult) >> gtod->clock.shift;
20042 }
20043
ae4e228f 20044@@ -113,7 +137,9 @@ notrace static noinline int do_monotonic
58c5fc13
MT
20045
20046 notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
20047 {
ae4e228f 20048- if (likely(gtod->sysctl_enabled))
58c5fc13
MT
20049+ if (likely(gtod->sysctl_enabled &&
20050+ ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) ||
20051+ (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]))))
20052 switch (clock) {
20053 case CLOCK_REALTIME:
ae4e228f
MT
20054 if (likely(gtod->clock.vread))
20055@@ -133,10 +159,20 @@ notrace int __vdso_clock_gettime(clockid
58c5fc13
MT
20056 int clock_gettime(clockid_t, struct timespec *)
20057 __attribute__((weak, alias("__vdso_clock_gettime")));
20058
20059-notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
20060+notrace noinline int __vdso_fallback_gettimeofday(struct timeval *tv, struct timezone *tz)
20061 {
20062 long ret;
20063- if (likely(gtod->sysctl_enabled && gtod->clock.vread)) {
20064+ asm("syscall" : "=a" (ret) :
20065+ "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "r11", "cx", "memory");
20066+ return ret;
20067+}
20068+
20069+notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
20070+{
20071+ if (likely(gtod->sysctl_enabled &&
20072+ ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) ||
20073+ (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]))))
20074+ {
20075 if (likely(tv != NULL)) {
20076 BUILD_BUG_ON(offsetof(struct timeval, tv_usec) !=
20077 offsetof(struct timespec, tv_nsec) ||
ae4e228f 20078@@ -151,9 +187,7 @@ notrace int __vdso_gettimeofday(struct t
58c5fc13
MT
20079 }
20080 return 0;
20081 }
20082- asm("syscall" : "=a" (ret) :
20083- "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
20084- return ret;
20085+ return __vdso_fallback_gettimeofday(tv, tz);
20086 }
20087 int gettimeofday(struct timeval *, struct timezone *)
20088 __attribute__((weak, alias("__vdso_gettimeofday")));
16454cff
MT
20089diff -urNp linux-2.6.38.1/arch/x86/vdso/vdso32-setup.c linux-2.6.38.1/arch/x86/vdso/vdso32-setup.c
20090--- linux-2.6.38.1/arch/x86/vdso/vdso32-setup.c 2011-03-14 21:20:32.000000000 -0400
20091+++ linux-2.6.38.1/arch/x86/vdso/vdso32-setup.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
20092@@ -25,6 +25,7 @@
20093 #include <asm/tlbflush.h>
20094 #include <asm/vdso.h>
20095 #include <asm/proto.h>
20096+#include <asm/mman.h>
20097
20098 enum {
20099 VDSO_DISABLED = 0,
20100@@ -226,7 +227,7 @@ static inline void map_compat_vdso(int m
20101 void enable_sep_cpu(void)
20102 {
20103 int cpu = get_cpu();
20104- struct tss_struct *tss = &per_cpu(init_tss, cpu);
20105+ struct tss_struct *tss = init_tss + cpu;
20106
20107 if (!boot_cpu_has(X86_FEATURE_SEP)) {
20108 put_cpu();
20109@@ -249,7 +250,7 @@ static int __init gate_vma_init(void)
20110 gate_vma.vm_start = FIXADDR_USER_START;
20111 gate_vma.vm_end = FIXADDR_USER_END;
20112 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
20113- gate_vma.vm_page_prot = __P101;
20114+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
20115 /*
20116 * Make sure the vDSO gets into every core dump.
20117 * Dumping its contents makes post-mortem fully interpretable later
20118@@ -331,14 +332,14 @@ int arch_setup_additional_pages(struct l
20119 if (compat)
20120 addr = VDSO_HIGH_BASE;
20121 else {
20122- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
20123+ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
20124 if (IS_ERR_VALUE(addr)) {
20125 ret = addr;
20126 goto up_fail;
20127 }
20128 }
20129
20130- current->mm->context.vdso = (void *)addr;
20131+ current->mm->context.vdso = addr;
20132
20133 if (compat_uses_vma || !compat) {
20134 /*
ae4e228f
MT
20135@@ -361,11 +362,11 @@ int arch_setup_additional_pages(struct l
20136 }
20137
20138 current_thread_info()->sysenter_return =
20139- VDSO32_SYMBOL(addr, SYSENTER_RETURN);
20140+ (__force void __user *)VDSO32_SYMBOL(addr, SYSENTER_RETURN);
58c5fc13
MT
20141
20142 up_fail:
20143 if (ret)
20144- current->mm->context.vdso = NULL;
20145+ current->mm->context.vdso = 0;
20146
20147 up_write(&mm->mmap_sem);
20148
ae4e228f 20149@@ -412,8 +413,14 @@ __initcall(ia32_binfmt_init);
58c5fc13
MT
20150
20151 const char *arch_vma_name(struct vm_area_struct *vma)
20152 {
20153- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
20154+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
20155 return "[vdso]";
20156+
20157+#ifdef CONFIG_PAX_SEGMEXEC
20158+ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
20159+ return "[vdso]";
20160+#endif
20161+
20162 return NULL;
20163 }
20164
ae4e228f 20165@@ -422,7 +429,7 @@ struct vm_area_struct *get_gate_vma(stru
58c5fc13
MT
20166 struct mm_struct *mm = tsk->mm;
20167
20168 /* Check to see if this task was created in compat vdso mode */
20169- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
20170+ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
20171 return &gate_vma;
20172 return NULL;
20173 }
16454cff
MT
20174diff -urNp linux-2.6.38.1/arch/x86/vdso/vdso.lds.S linux-2.6.38.1/arch/x86/vdso/vdso.lds.S
20175--- linux-2.6.38.1/arch/x86/vdso/vdso.lds.S 2011-03-14 21:20:32.000000000 -0400
20176+++ linux-2.6.38.1/arch/x86/vdso/vdso.lds.S 2011-03-21 18:31:35.000000000 -0400
57199397
MT
20177@@ -35,3 +35,9 @@ VDSO64_PRELINK = VDSO_PRELINK;
20178 #define VEXTERN(x) VDSO64_ ## x = vdso_ ## x;
20179 #include "vextern.h"
20180 #undef VEXTERN
20181+
20182+#define VEXTERN(x) VDSO64_ ## x = __vdso_ ## x;
20183+VEXTERN(fallback_gettimeofday)
20184+VEXTERN(fallback_time)
20185+VEXTERN(getcpu)
20186+#undef VEXTERN
16454cff
MT
20187diff -urNp linux-2.6.38.1/arch/x86/vdso/vextern.h linux-2.6.38.1/arch/x86/vdso/vextern.h
20188--- linux-2.6.38.1/arch/x86/vdso/vextern.h 2011-03-14 21:20:32.000000000 -0400
20189+++ linux-2.6.38.1/arch/x86/vdso/vextern.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
20190@@ -11,6 +11,5 @@
20191 put into vextern.h and be referenced as a pointer with vdso prefix.
20192 The main kernel later fills in the values. */
20193
20194-VEXTERN(jiffies)
20195 VEXTERN(vgetcpu_mode)
20196 VEXTERN(vsyscall_gtod_data)
16454cff
MT
20197diff -urNp linux-2.6.38.1/arch/x86/vdso/vma.c linux-2.6.38.1/arch/x86/vdso/vma.c
20198--- linux-2.6.38.1/arch/x86/vdso/vma.c 2011-03-14 21:20:32.000000000 -0400
20199+++ linux-2.6.38.1/arch/x86/vdso/vma.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 20200@@ -58,7 +58,7 @@ static int __init init_vdso_vars(void)
58c5fc13
MT
20201 if (!vbase)
20202 goto oom;
20203
20204- if (memcmp(vbase, "\177ELF", 4)) {
20205+ if (memcmp(vbase, ELFMAG, SELFMAG)) {
20206 printk("VDSO: I'm broken; not ELF\n");
20207 vdso_enabled = 0;
20208 }
6892158b 20209@@ -118,7 +118,7 @@ int arch_setup_additional_pages(struct l
58c5fc13
MT
20210 goto up_fail;
20211 }
20212
20213- current->mm->context.vdso = (void *)addr;
20214+ current->mm->context.vdso = addr;
20215
20216 ret = install_special_mapping(mm, addr, vdso_size,
20217 VM_READ|VM_EXEC|
6892158b 20218@@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l
58c5fc13
MT
20219 VM_ALWAYSDUMP,
20220 vdso_pages);
20221 if (ret) {
20222- current->mm->context.vdso = NULL;
20223+ current->mm->context.vdso = 0;
20224 goto up_fail;
20225 }
20226
6892158b 20227@@ -134,10 +134,3 @@ up_fail:
58c5fc13
MT
20228 up_write(&mm->mmap_sem);
20229 return ret;
20230 }
20231-
20232-static __init int vdso_setup(char *s)
20233-{
20234- vdso_enabled = simple_strtoul(s, NULL, 0);
20235- return 0;
20236-}
20237-__setup("vdso=", vdso_setup);
16454cff
MT
20238diff -urNp linux-2.6.38.1/arch/x86/xen/enlighten.c linux-2.6.38.1/arch/x86/xen/enlighten.c
20239--- linux-2.6.38.1/arch/x86/xen/enlighten.c 2011-03-14 21:20:32.000000000 -0400
20240+++ linux-2.6.38.1/arch/x86/xen/enlighten.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 20241@@ -85,8 +85,6 @@ EXPORT_SYMBOL_GPL(xen_start_info);
58c5fc13
MT
20242
20243 struct shared_info xen_dummy_shared_info;
20244
20245-void *xen_initial_gdt;
20246-
6892158b
MT
20247 RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
20248 __read_mostly int xen_have_vector_callback;
20249 EXPORT_SYMBOL_GPL(xen_have_vector_callback);
bc901d79 20250@@ -1134,7 +1132,17 @@ asmlinkage void __init xen_start_kernel(
df50ba0c
MT
20251 __userpte_alloc_gfp &= ~__GFP_HIGHMEM;
20252
20253 /* Work out if we support NX */
20254- x86_configure_nx();
20255+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
20256+ if ((cpuid_eax(0x80000000) & 0xffff0000) == 0x80000000 &&
57199397 20257+ (cpuid_edx(0x80000001) & (1U << (X86_FEATURE_NX & 31)))) {
df50ba0c
MT
20258+ unsigned l, h;
20259+
20260+ __supported_pte_mask |= _PAGE_NX;
20261+ rdmsr(MSR_EFER, l, h);
20262+ l |= EFER_NX;
20263+ wrmsr(MSR_EFER, l, h);
20264+ }
20265+#endif
20266
20267 xen_setup_features();
20268
bc901d79 20269@@ -1165,13 +1173,6 @@ asmlinkage void __init xen_start_kernel(
58c5fc13
MT
20270
20271 machine_ops = xen_machine_ops;
20272
20273- /*
20274- * The only reliable way to retain the initial address of the
20275- * percpu gdt_page is to remember it here, so we can go and
20276- * mark it RW later, when the initial percpu area is freed.
20277- */
20278- xen_initial_gdt = &per_cpu(gdt_page, 0);
20279-
20280 xen_smp_init();
20281
16454cff
MT
20282 #ifdef CONFIG_ACPI_NUMA
20283diff -urNp linux-2.6.38.1/arch/x86/xen/mmu.c linux-2.6.38.1/arch/x86/xen/mmu.c
20284--- linux-2.6.38.1/arch/x86/xen/mmu.c 2011-03-14 21:20:32.000000000 -0400
20285+++ linux-2.6.38.1/arch/x86/xen/mmu.c 2011-03-21 18:31:35.000000000 -0400
20286@@ -1718,6 +1718,8 @@ __init pgd_t *xen_setup_kernel_pagetable
58c5fc13
MT
20287 convert_pfn_mfn(init_level4_pgt);
20288 convert_pfn_mfn(level3_ident_pgt);
20289 convert_pfn_mfn(level3_kernel_pgt);
20290+ convert_pfn_mfn(level3_vmalloc_pgt);
20291+ convert_pfn_mfn(level3_vmemmap_pgt);
20292
20293 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
20294 l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
16454cff 20295@@ -1736,7 +1738,10 @@ __init pgd_t *xen_setup_kernel_pagetable
58c5fc13
MT
20296 set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
20297 set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
20298 set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
20299+ set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
20300+ set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
20301 set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
20302+ set_page_prot(level2_vmemmap_pgt, PAGE_KERNEL_RO);
20303 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
20304 set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
20305
16454cff
MT
20306diff -urNp linux-2.6.38.1/arch/x86/xen/pci-swiotlb-xen.c linux-2.6.38.1/arch/x86/xen/pci-swiotlb-xen.c
20307--- linux-2.6.38.1/arch/x86/xen/pci-swiotlb-xen.c 2011-03-14 21:20:32.000000000 -0400
20308+++ linux-2.6.38.1/arch/x86/xen/pci-swiotlb-xen.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 20309@@ -10,7 +10,7 @@
6892158b
MT
20310
20311 int xen_swiotlb __read_mostly;
20312
20313-static struct dma_map_ops xen_swiotlb_dma_ops = {
20314+static const struct dma_map_ops xen_swiotlb_dma_ops = {
20315 .mapping_error = xen_swiotlb_dma_mapping_error,
20316 .alloc_coherent = xen_swiotlb_alloc_coherent,
20317 .free_coherent = xen_swiotlb_free_coherent,
16454cff
MT
20318diff -urNp linux-2.6.38.1/arch/x86/xen/smp.c linux-2.6.38.1/arch/x86/xen/smp.c
20319--- linux-2.6.38.1/arch/x86/xen/smp.c 2011-03-14 21:20:32.000000000 -0400
20320+++ linux-2.6.38.1/arch/x86/xen/smp.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 20321@@ -194,11 +194,6 @@ static void __init xen_smp_prepare_boot_
58c5fc13
MT
20322 {
20323 BUG_ON(smp_processor_id() != 0);
20324 native_smp_prepare_boot_cpu();
20325-
20326- /* We've switched to the "real" per-cpu gdt, so make sure the
20327- old memory can be recycled */
20328- make_lowmem_page_readwrite(xen_initial_gdt);
20329-
bc901d79 20330 xen_filter_cpu_maps();
58c5fc13
MT
20331 xen_setup_vcpu_info_placement();
20332 }
bc901d79 20333@@ -259,12 +254,12 @@ cpu_initialize_context(unsigned int cpu,
58c5fc13
MT
20334 gdt = get_cpu_gdt_table(cpu);
20335
20336 ctxt->flags = VGCF_IN_KERNEL;
20337- ctxt->user_regs.ds = __USER_DS;
20338- ctxt->user_regs.es = __USER_DS;
20339+ ctxt->user_regs.ds = __KERNEL_DS;
20340+ ctxt->user_regs.es = __KERNEL_DS;
20341 ctxt->user_regs.ss = __KERNEL_DS;
20342 #ifdef CONFIG_X86_32
20343 ctxt->user_regs.fs = __KERNEL_PERCPU;
bc901d79
MT
20344- ctxt->user_regs.gs = __KERNEL_STACK_CANARY;
20345+ savesegment(gs, ctxt->user_regs.gs);
20346 #else
20347 ctxt->gs_base_kernel = per_cpu_offset(cpu);
20348 #endif
16454cff
MT
20349diff -urNp linux-2.6.38.1/arch/x86/xen/xen-head.S linux-2.6.38.1/arch/x86/xen/xen-head.S
20350--- linux-2.6.38.1/arch/x86/xen/xen-head.S 2011-03-14 21:20:32.000000000 -0400
20351+++ linux-2.6.38.1/arch/x86/xen/xen-head.S 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
20352@@ -19,6 +19,17 @@ ENTRY(startup_xen)
20353 #ifdef CONFIG_X86_32
20354 mov %esi,xen_start_info
20355 mov $init_thread_union+THREAD_SIZE,%esp
20356+#ifdef CONFIG_SMP
20357+ movl $cpu_gdt_table,%edi
20358+ movl $__per_cpu_load,%eax
20359+ movw %ax,__KERNEL_PERCPU + 2(%edi)
20360+ rorl $16,%eax
20361+ movb %al,__KERNEL_PERCPU + 4(%edi)
20362+ movb %ah,__KERNEL_PERCPU + 7(%edi)
20363+ movl $__per_cpu_end - 1,%eax
20364+ subl $__per_cpu_start,%eax
20365+ movw %ax,__KERNEL_PERCPU + 0(%edi)
20366+#endif
20367 #else
20368 mov %rsi,xen_start_info
20369 mov $init_thread_union+THREAD_SIZE,%rsp
16454cff
MT
20370diff -urNp linux-2.6.38.1/arch/x86/xen/xen-ops.h linux-2.6.38.1/arch/x86/xen/xen-ops.h
20371--- linux-2.6.38.1/arch/x86/xen/xen-ops.h 2011-03-14 21:20:32.000000000 -0400
20372+++ linux-2.6.38.1/arch/x86/xen/xen-ops.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
20373@@ -10,8 +10,6 @@
20374 extern const char xen_hypervisor_callback[];
20375 extern const char xen_failsafe_callback[];
20376
20377-extern void *xen_initial_gdt;
20378-
20379 struct trap_info;
20380 void xen_copy_trap_info(struct trap_info *traps);
20381
16454cff
MT
20382diff -urNp linux-2.6.38.1/block/blk-iopoll.c linux-2.6.38.1/block/blk-iopoll.c
20383--- linux-2.6.38.1/block/blk-iopoll.c 2011-03-14 21:20:32.000000000 -0400
20384+++ linux-2.6.38.1/block/blk-iopoll.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
20385@@ -77,7 +77,7 @@ void blk_iopoll_complete(struct blk_iopo
20386 }
20387 EXPORT_SYMBOL(blk_iopoll_complete);
20388
20389-static void blk_iopoll_softirq(struct softirq_action *h)
20390+static void blk_iopoll_softirq(void)
20391 {
20392 struct list_head *list = &__get_cpu_var(blk_cpu_iopoll);
20393 int rearm = 0, budget = blk_iopoll_budget;
16454cff
MT
20394diff -urNp linux-2.6.38.1/block/blk-map.c linux-2.6.38.1/block/blk-map.c
20395--- linux-2.6.38.1/block/blk-map.c 2011-03-14 21:20:32.000000000 -0400
20396+++ linux-2.6.38.1/block/blk-map.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 20397@@ -301,7 +301,7 @@ int blk_rq_map_kern(struct request_queue
ae4e228f
MT
20398 if (!len || !kbuf)
20399 return -EINVAL;
58c5fc13 20400
bc901d79
MT
20401- do_copy = !blk_rq_aligned(q, addr, len) || object_is_on_stack(kbuf);
20402+ do_copy = !blk_rq_aligned(q, addr, len) || object_starts_on_stack(kbuf);
ae4e228f
MT
20403 if (do_copy)
20404 bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading);
20405 else
16454cff
MT
20406diff -urNp linux-2.6.38.1/block/blk-softirq.c linux-2.6.38.1/block/blk-softirq.c
20407--- linux-2.6.38.1/block/blk-softirq.c 2011-03-14 21:20:32.000000000 -0400
20408+++ linux-2.6.38.1/block/blk-softirq.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
20409@@ -17,7 +17,7 @@ static DEFINE_PER_CPU(struct list_head,
20410 * Softirq action handler - move entries to local list and loop over them
20411 * while passing them to the queue registered handler.
20412 */
20413-static void blk_done_softirq(struct softirq_action *h)
20414+static void blk_done_softirq(void)
20415 {
20416 struct list_head *cpu_list, local_list;
58c5fc13 20417
16454cff
MT
20418diff -urNp linux-2.6.38.1/crypto/lrw.c linux-2.6.38.1/crypto/lrw.c
20419--- linux-2.6.38.1/crypto/lrw.c 2011-03-14 21:20:32.000000000 -0400
20420+++ linux-2.6.38.1/crypto/lrw.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
20421@@ -60,7 +60,7 @@ static int setkey(struct crypto_tfm *par
20422 struct priv *ctx = crypto_tfm_ctx(parent);
20423 struct crypto_cipher *child = ctx->child;
20424 int err, i;
20425- be128 tmp = { 0 };
20426+ be128 tmp = { 0, 0 };
20427 int bsize = crypto_cipher_blocksize(child);
20428
20429 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
16454cff
MT
20430diff -urNp linux-2.6.38.1/Documentation/dontdiff linux-2.6.38.1/Documentation/dontdiff
20431--- linux-2.6.38.1/Documentation/dontdiff 2011-03-14 21:20:32.000000000 -0400
20432+++ linux-2.6.38.1/Documentation/dontdiff 2011-03-21 18:31:35.000000000 -0400
57199397
MT
20433@@ -3,6 +3,7 @@
20434 *.bin
20435 *.cpio
20436 *.csp
20437+*.dbg
20438 *.dsp
20439 *.dvi
20440 *.elf
20441@@ -38,8 +39,10 @@
20442 *.tab.h
20443 *.tex
20444 *.ver
20445+*.vim
20446 *.xml
20447 *_MODULES
20448+*_reg_safe.h
20449 *_vga16.c
20450 *~
20451 *.9
20452@@ -49,11 +52,16 @@
20453 53c700_d.h
20454 CVS
20455 ChangeSet
20456+GPATH
20457+GRTAGS
20458+GSYMS
20459+GTAGS
20460 Image
20461 Kerntypes
20462 Module.markers
20463 Module.symvers
20464 PENDING
20465+PERF*
20466 SCCS
20467 System.map*
20468 TAGS
16454cff 20469@@ -82,6 +90,8 @@ bvmlinux
57199397 20470 bzImage*
16454cff 20471 capflags.c
57199397
MT
20472 classlist.h*
20473+clut_vga16.c
20474+common-cmds.h
20475 comp*.log
20476 compile.h*
20477 conf
16454cff 20478@@ -106,16 +116,19 @@ fore200e_mkfirm
57199397
MT
20479 fore200e_pca_fw.c*
20480 gconf
20481 gen-devlist
20482+gen-kdb_cmds.c
20483 gen_crc32table
20484 gen_init_cpio
20485 generated
20486 genheaders
20487 genksyms
20488 *_gray256.c
20489+hash
20490 ihex2fw
20491 ikconfig.h*
16454cff 20492 inat-tables.c
57199397
MT
20493 initramfs_data.cpio
20494+initramfs_data.cpio.bz2
20495 initramfs_data.cpio.gz
20496 initramfs_list
16454cff
MT
20497 int16.c
20498@@ -125,7 +138,6 @@ int32.c
20499 int4.c
20500 int8.c
57199397
MT
20501 kallsyms
20502-kconfig
20503 keywords.c
20504 ksym.c*
20505 ksym.h*
16454cff 20506@@ -149,7 +161,9 @@ mkboot
57199397
MT
20507 mkbugboot
20508 mkcpustr
20509 mkdep
20510+mkpiggy
20511 mkprep
20512+mkregtable
20513 mktables
20514 mktree
20515 modpost
16454cff 20516@@ -165,6 +179,7 @@ parse.h
57199397
MT
20517 patches*
20518 pca200e.bin
20519 pca200e_ecd.bin2
20520+perf-archive
20521 piggy.gz
57199397 20522 piggyback
16454cff
MT
20523 piggy.S
20524@@ -180,6 +195,7 @@ r600_reg_safe.h
57199397
MT
20525 raid6altivec*.c
20526 raid6int*.c
20527 raid6tables.c
20528+regdb.c
20529 relocs
16454cff
MT
20530 rn50_reg_safe.h
20531 rs600_reg_safe.h
20532@@ -189,6 +205,7 @@ setup
57199397
MT
20533 setup.bin
20534 setup.elf
20535 sImage
20536+slabinfo
20537 sm_tbl*
20538 split-include
20539 syscalltab.h
16454cff 20540@@ -213,13 +230,17 @@ version.h*
57199397
MT
20541 vmlinux
20542 vmlinux-*
20543 vmlinux.aout
20544+vmlinux.bin.all
20545+vmlinux.bin.bz2
20546 vmlinux.lds
20547+vmlinux.relocs
16454cff 20548 voffset.h
57199397
MT
20549 vsyscall.lds
20550 vsyscall_32.lds
20551 wanxlfw.inc
20552 uImage
20553 unifdef
20554+utsrelease.h
20555 wakeup.bin
20556 wakeup.elf
20557 wakeup.lds
16454cff
MT
20558diff -urNp linux-2.6.38.1/Documentation/filesystems/sysfs.txt linux-2.6.38.1/Documentation/filesystems/sysfs.txt
20559--- linux-2.6.38.1/Documentation/filesystems/sysfs.txt 2011-03-14 21:20:32.000000000 -0400
20560+++ linux-2.6.38.1/Documentation/filesystems/sysfs.txt 2011-03-21 18:31:35.000000000 -0400
57199397
MT
20561@@ -123,8 +123,8 @@ set of sysfs operations for forwarding r
20562 show and store methods of the attribute owners.
20563
20564 struct sysfs_ops {
20565- ssize_t (*show)(struct kobject *, struct attribute *, char *);
6892158b 20566- ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
57199397 20567+ ssize_t (* const show)(struct kobject *, struct attribute *, char *);
6892158b 20568+ ssize_t (* const store)(struct kobject *, struct attribute *, const char *, size_t);
57199397
MT
20569 };
20570
20571 [ Subsystems should have already defined a struct kobj_type as a
16454cff
MT
20572diff -urNp linux-2.6.38.1/Documentation/kernel-parameters.txt linux-2.6.38.1/Documentation/kernel-parameters.txt
20573--- linux-2.6.38.1/Documentation/kernel-parameters.txt 2011-03-14 21:20:32.000000000 -0400
20574+++ linux-2.6.38.1/Documentation/kernel-parameters.txt 2011-03-21 18:31:35.000000000 -0400
20575@@ -1853,6 +1853,13 @@ bytes respectively. Such letter suffixes
57199397
MT
20576 the specified number of seconds. This is to be used if
20577 your oopses keep scrolling off the screen.
20578
bc901d79 20579+ pax_nouderef [X86] disables UDEREF. Most likely needed under certain
57199397 20580+ virtualization environments that don't cope well with the
bc901d79
MT
20581+ expand down segment used by UDEREF on X86-32 or the frequent
20582+ page table updates on X86-64.
57199397 20583+
16454cff 20584+ pax_softmode= 0/1 to disable/enable PaX softmode on boot already.
57199397
MT
20585+
20586 pcbit= [HW,ISDN]
20587
20588 pcd. [PARIDE]
16454cff
MT
20589diff -urNp linux-2.6.38.1/drivers/acpi/battery.c linux-2.6.38.1/drivers/acpi/battery.c
20590--- linux-2.6.38.1/drivers/acpi/battery.c 2011-03-14 21:20:32.000000000 -0400
20591+++ linux-2.6.38.1/drivers/acpi/battery.c 2011-03-21 18:31:35.000000000 -0400
20592@@ -862,7 +862,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
ae4e228f
MT
20593 }
20594
20595 static struct battery_file {
20596- struct file_operations ops;
20597+ const struct file_operations ops;
20598 mode_t mode;
20599 const char *name;
20600 } acpi_battery_file[] = {
16454cff
MT
20601diff -urNp linux-2.6.38.1/drivers/acpi/blacklist.c linux-2.6.38.1/drivers/acpi/blacklist.c
20602--- linux-2.6.38.1/drivers/acpi/blacklist.c 2011-03-14 21:20:32.000000000 -0400
20603+++ linux-2.6.38.1/drivers/acpi/blacklist.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 20604@@ -73,7 +73,7 @@ static struct acpi_blacklist_item acpi_b
58c5fc13
MT
20605 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
20606 "Incorrect _ADR", 1},
20607
20608- {""}
ae4e228f 20609+ {"", "", 0, NULL, all_versions, NULL, 0}
58c5fc13
MT
20610 };
20611
20612 #if CONFIG_ACPI_BLACKLIST_YEAR
16454cff
MT
20613diff -urNp linux-2.6.38.1/drivers/acpi/dock.c linux-2.6.38.1/drivers/acpi/dock.c
20614--- linux-2.6.38.1/drivers/acpi/dock.c 2011-03-14 21:20:32.000000000 -0400
20615+++ linux-2.6.38.1/drivers/acpi/dock.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 20616@@ -77,7 +77,7 @@ struct dock_dependent_device {
ae4e228f
MT
20617 struct list_head list;
20618 struct list_head hotplug_list;
20619 acpi_handle handle;
20620- struct acpi_dock_ops *ops;
20621+ const struct acpi_dock_ops *ops;
20622 void *context;
20623 };
20624
df50ba0c 20625@@ -589,7 +589,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifi
ae4e228f
MT
20626 * the dock driver after _DCK is executed.
20627 */
20628 int
20629-register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
20630+register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops,
20631 void *context)
20632 {
20633 struct dock_dependent_device *dd;
16454cff
MT
20634diff -urNp linux-2.6.38.1/drivers/acpi/ec_sys.c linux-2.6.38.1/drivers/acpi/ec_sys.c
20635--- linux-2.6.38.1/drivers/acpi/ec_sys.c 2011-03-14 21:20:32.000000000 -0400
20636+++ linux-2.6.38.1/drivers/acpi/ec_sys.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
20637@@ -96,7 +96,7 @@ static ssize_t acpi_ec_write_io(struct f
20638 return count;
20639 }
58c5fc13 20640
bc901d79
MT
20641-static struct file_operations acpi_ec_io_ops = {
20642+static const struct file_operations acpi_ec_io_ops = {
20643 .owner = THIS_MODULE,
20644 .open = acpi_ec_open_io,
20645 .read = acpi_ec_read_io,
16454cff
MT
20646diff -urNp linux-2.6.38.1/drivers/acpi/power_meter.c linux-2.6.38.1/drivers/acpi/power_meter.c
20647--- linux-2.6.38.1/drivers/acpi/power_meter.c 2011-03-14 21:20:32.000000000 -0400
20648+++ linux-2.6.38.1/drivers/acpi/power_meter.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
20649@@ -316,8 +316,6 @@ static ssize_t set_trip(struct device *d
20650 return res;
20651
20652 temp /= 1000;
20653- if (temp < 0)
20654- return -EINVAL;
20655
20656 mutex_lock(&resource->lock);
20657 resource->trip[attr->index - 7] = temp;
16454cff
MT
20658diff -urNp linux-2.6.38.1/drivers/acpi/proc.c linux-2.6.38.1/drivers/acpi/proc.c
20659--- linux-2.6.38.1/drivers/acpi/proc.c 2011-03-14 21:20:32.000000000 -0400
20660+++ linux-2.6.38.1/drivers/acpi/proc.c 2011-03-21 18:31:35.000000000 -0400
20661@@ -342,19 +342,13 @@ acpi_system_write_wakeup_device(struct f
df50ba0c
MT
20662 size_t count, loff_t * ppos)
20663 {
20664 struct list_head *node, *next;
20665- char strbuf[5];
20666- char str[5] = "";
20667- unsigned int len = count;
16454cff 20668-
df50ba0c
MT
20669- if (len > 4)
20670- len = 4;
20671- if (len < 0)
20672- return -EFAULT;
16454cff 20673+ char strbuf[5] = {0};
df50ba0c
MT
20674
20675- if (copy_from_user(strbuf, buffer, len))
16454cff
MT
20676+ if (count > 4)
20677+ count = 4;
df50ba0c
MT
20678+ if (copy_from_user(strbuf, buffer, count))
20679 return -EFAULT;
20680- strbuf[len] = '\0';
20681- sscanf(strbuf, "%s", str);
20682+ strbuf[count] = '\0';
20683
20684 mutex_lock(&acpi_device_lock);
20685 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
16454cff 20686@@ -363,7 +357,7 @@ acpi_system_write_wakeup_device(struct f
df50ba0c
MT
20687 if (!dev->wakeup.flags.valid)
20688 continue;
20689
20690- if (!strncmp(dev->pnp.bus_id, str, 4)) {
20691+ if (!strncmp(dev->pnp.bus_id, strbuf, 4)) {
16454cff
MT
20692 if (device_can_wakeup(&dev->dev)) {
20693 bool enable = !device_may_wakeup(&dev->dev);
20694 device_set_wakeup_enable(&dev->dev, enable);
20695diff -urNp linux-2.6.38.1/drivers/acpi/processor_driver.c linux-2.6.38.1/drivers/acpi/processor_driver.c
20696--- linux-2.6.38.1/drivers/acpi/processor_driver.c 2011-03-14 21:20:32.000000000 -0400
20697+++ linux-2.6.38.1/drivers/acpi/processor_driver.c 2011-03-21 18:31:35.000000000 -0400
20698@@ -473,7 +473,7 @@ static int __cpuinit acpi_processor_add(
58c5fc13 20699 return 0;
57199397 20700 #endif
58c5fc13
MT
20701
20702- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
20703+ BUG_ON(pr->id >= nr_cpu_ids);
20704
20705 /*
20706 * Buggy BIOS check
16454cff
MT
20707diff -urNp linux-2.6.38.1/drivers/acpi/processor_idle.c linux-2.6.38.1/drivers/acpi/processor_idle.c
20708--- linux-2.6.38.1/drivers/acpi/processor_idle.c 2011-03-14 21:20:32.000000000 -0400
20709+++ linux-2.6.38.1/drivers/acpi/processor_idle.c 2011-03-21 18:31:35.000000000 -0400
20710@@ -121,7 +121,7 @@ static struct dmi_system_id __cpuinitdat
ae4e228f
MT
20711 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
20712 DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
20713 (void *)1},
58c5fc13
MT
20714- {},
20715+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL},
20716 };
20717
20718
16454cff
MT
20719diff -urNp linux-2.6.38.1/drivers/ata/acard-ahci.c linux-2.6.38.1/drivers/ata/acard-ahci.c
20720--- linux-2.6.38.1/drivers/ata/acard-ahci.c 2011-03-14 21:20:32.000000000 -0400
20721+++ linux-2.6.38.1/drivers/ata/acard-ahci.c 2011-03-21 18:31:35.000000000 -0400
20722@@ -87,7 +87,7 @@ static struct scsi_host_template acard_a
20723 AHCI_SHT("acard-ahci"),
20724 };
ae4e228f 20725
16454cff
MT
20726-static struct ata_port_operations acard_ops = {
20727+static const struct ata_port_operations acard_ops = {
20728 .inherits = &ahci_ops,
20729 .qc_prep = acard_ahci_qc_prep,
20730 .qc_fill_rtf = acard_ahci_qc_fill_rtf,
20731diff -urNp linux-2.6.38.1/drivers/ata/ahci.c linux-2.6.38.1/drivers/ata/ahci.c
20732--- linux-2.6.38.1/drivers/ata/ahci.c 2011-03-23 17:20:06.000000000 -0400
20733+++ linux-2.6.38.1/drivers/ata/ahci.c 2011-03-23 17:21:49.000000000 -0400
6892158b
MT
20734@@ -94,17 +94,17 @@ static struct scsi_host_template ahci_sh
20735 AHCI_SHT("ahci"),
20736 };
ae4e228f
MT
20737
20738-static struct ata_port_operations ahci_vt8251_ops = {
20739+static const struct ata_port_operations ahci_vt8251_ops = {
20740 .inherits = &ahci_ops,
20741 .hardreset = ahci_vt8251_hardreset,
20742 };
20743
20744-static struct ata_port_operations ahci_p5wdh_ops = {
20745+static const struct ata_port_operations ahci_p5wdh_ops = {
20746 .inherits = &ahci_ops,
20747 .hardreset = ahci_p5wdh_hardreset,
20748 };
20749
20750-static struct ata_port_operations ahci_sb600_ops = {
20751+static const struct ata_port_operations ahci_sb600_ops = {
20752 .inherits = &ahci_ops,
20753 .softreset = ahci_sb600_softreset,
20754 .pmp_softreset = ahci_sb600_softreset,
16454cff 20755@@ -394,7 +394,7 @@ static const struct pci_device_id ahci_p
58c5fc13
MT
20756 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
20757 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
20758
20759- { } /* terminate list */
20760+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
20761 };
20762
20763
16454cff
MT
20764diff -urNp linux-2.6.38.1/drivers/ata/ahci.h linux-2.6.38.1/drivers/ata/ahci.h
20765--- linux-2.6.38.1/drivers/ata/ahci.h 2011-03-14 21:20:32.000000000 -0400
20766+++ linux-2.6.38.1/drivers/ata/ahci.h 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
20767@@ -309,7 +309,7 @@ extern struct device_attribute *ahci_sde
20768 .shost_attrs = ahci_shost_attrs, \
20769 .sdev_attrs = ahci_sdev_attrs
57199397 20770
57199397
MT
20771-extern struct ata_port_operations ahci_ops;
20772+extern const struct ata_port_operations ahci_ops;
20773
16454cff
MT
20774 void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
20775 u32 opts);
20776diff -urNp linux-2.6.38.1/drivers/ata/ata_generic.c linux-2.6.38.1/drivers/ata/ata_generic.c
20777--- linux-2.6.38.1/drivers/ata/ata_generic.c 2011-03-14 21:20:32.000000000 -0400
20778+++ linux-2.6.38.1/drivers/ata/ata_generic.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 20779@@ -101,7 +101,7 @@ static struct scsi_host_template generic
ae4e228f
MT
20780 ATA_BMDMA_SHT(DRV_NAME),
20781 };
20782
20783-static struct ata_port_operations generic_port_ops = {
20784+static const struct ata_port_operations generic_port_ops = {
20785 .inherits = &ata_bmdma_port_ops,
20786 .cable_detect = ata_cable_unknown,
20787 .set_mode = generic_set_mode,
16454cff
MT
20788diff -urNp linux-2.6.38.1/drivers/ata/ata_piix.c linux-2.6.38.1/drivers/ata/ata_piix.c
20789--- linux-2.6.38.1/drivers/ata/ata_piix.c 2011-03-14 21:20:32.000000000 -0400
20790+++ linux-2.6.38.1/drivers/ata/ata_piix.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 20791@@ -309,7 +309,7 @@ static const struct pci_device_id piix_p
6892158b
MT
20792 { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
20793 /* SATA Controller IDE (PBG) */
20794 { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
58c5fc13
MT
20795- { } /* terminate list */
20796+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
20797 };
20798
20799 static struct pci_driver piix_pci_driver = {
bc901d79 20800@@ -327,12 +327,12 @@ static struct scsi_host_template piix_sh
ae4e228f
MT
20801 ATA_BMDMA_SHT(DRV_NAME),
20802 };
20803
df50ba0c
MT
20804-static struct ata_port_operations piix_sata_ops = {
20805+static const struct ata_port_operations piix_sata_ops = {
20806 .inherits = &ata_bmdma32_port_ops,
20807 .sff_irq_check = piix_irq_check,
20808 };
20809
ae4e228f
MT
20810-static struct ata_port_operations piix_pata_ops = {
20811+static const struct ata_port_operations piix_pata_ops = {
df50ba0c 20812 .inherits = &piix_sata_ops,
ae4e228f
MT
20813 .cable_detect = ata_cable_40wire,
20814 .set_piomode = piix_set_piomode,
bc901d79 20815@@ -340,12 +340,12 @@ static struct ata_port_operations piix_p
ae4e228f
MT
20816 .prereset = piix_pata_prereset,
20817 };
20818
20819-static struct ata_port_operations piix_vmw_ops = {
20820+static const struct ata_port_operations piix_vmw_ops = {
20821 .inherits = &piix_pata_ops,
20822 .bmdma_status = piix_vmw_bmdma_status,
20823 };
20824
20825-static struct ata_port_operations ich_pata_ops = {
20826+static const struct ata_port_operations ich_pata_ops = {
20827 .inherits = &piix_pata_ops,
20828 .cable_detect = ich_pata_cable_detect,
20829 .set_dmamode = ich_set_dmamode,
bc901d79
MT
20830@@ -361,7 +361,7 @@ static struct scsi_host_template piix_si
20831 .shost_attrs = piix_sidpr_shost_attrs,
ae4e228f
MT
20832 };
20833
ae4e228f
MT
20834-static struct ata_port_operations piix_sidpr_sata_ops = {
20835+static const struct ata_port_operations piix_sidpr_sata_ops = {
20836 .inherits = &piix_sata_ops,
20837 .hardreset = sata_std_hardreset,
20838 .scr_read = piix_sidpr_scr_read,
bc901d79 20839@@ -638,7 +638,7 @@ static const struct ich_laptop ich_lapto
58c5fc13
MT
20840 { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
20841 { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */
20842 /* end marker */
20843- { 0, }
20844+ { 0, 0, 0 }
20845 };
20846
20847 /**
bc901d79 20848@@ -1130,7 +1130,7 @@ static int piix_broken_suspend(void)
58c5fc13
MT
20849 },
20850 },
20851
20852- { } /* terminate list */
20853+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } /* terminate list */
20854 };
20855 static const char *oemstrs[] = {
20856 "Tecra M3,",
16454cff
MT
20857diff -urNp linux-2.6.38.1/drivers/ata/libahci.c linux-2.6.38.1/drivers/ata/libahci.c
20858--- linux-2.6.38.1/drivers/ata/libahci.c 2011-03-14 21:20:32.000000000 -0400
20859+++ linux-2.6.38.1/drivers/ata/libahci.c 2011-03-21 18:31:35.000000000 -0400
20860@@ -137,7 +137,7 @@ struct device_attribute *ahci_sdev_attrs
57199397 20861 };
6892158b 20862 EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
57199397
MT
20863
20864-struct ata_port_operations ahci_ops = {
20865+const struct ata_port_operations ahci_ops = {
20866 .inherits = &sata_pmp_port_ops,
20867
20868 .qc_defer = ahci_pmp_qc_defer,
16454cff
MT
20869diff -urNp linux-2.6.38.1/drivers/ata/libata-acpi.c linux-2.6.38.1/drivers/ata/libata-acpi.c
20870--- linux-2.6.38.1/drivers/ata/libata-acpi.c 2011-03-14 21:20:32.000000000 -0400
20871+++ linux-2.6.38.1/drivers/ata/libata-acpi.c 2011-03-21 18:31:35.000000000 -0400
6892158b 20872@@ -218,12 +218,12 @@ static void ata_acpi_dev_uevent(acpi_han
ae4e228f
MT
20873 ata_acpi_uevent(dev->link->ap, dev, event);
20874 }
20875
20876-static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
20877+static const struct acpi_dock_ops ata_acpi_dev_dock_ops = {
20878 .handler = ata_acpi_dev_notify_dock,
20879 .uevent = ata_acpi_dev_uevent,
20880 };
20881
20882-static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
20883+static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
20884 .handler = ata_acpi_ap_notify_dock,
20885 .uevent = ata_acpi_ap_uevent,
20886 };
16454cff
MT
20887diff -urNp linux-2.6.38.1/drivers/ata/libata-core.c linux-2.6.38.1/drivers/ata/libata-core.c
20888--- linux-2.6.38.1/drivers/ata/libata-core.c 2011-03-14 21:20:32.000000000 -0400
20889+++ linux-2.6.38.1/drivers/ata/libata-core.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 20890@@ -897,7 +897,7 @@ static const struct ata_xfer_ent {
58c5fc13
MT
20891 { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
20892 { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
20893 { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
20894- { -1, },
20895+ { -1, 0, 0 }
20896 };
20897
20898 /**
bc901d79 20899@@ -2885,7 +2885,7 @@ static const struct ata_timing ata_timin
58c5fc13
MT
20900 { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 },
20901 { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 },
20902
20903- { 0xFF }
20904+ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
20905 };
20906
20907 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
16454cff
MT
20908@@ -4141,7 +4141,7 @@ static const struct ata_blacklist_entry
20909 { "PIONEER DVD-RW DVR-212D", "1.28", ATA_HORKAGE_NOSETXFER },
58c5fc13
MT
20910
20911 /* End Marker */
20912- { }
20913+ { NULL, NULL, 0 }
20914 };
20915
6892158b 20916 /**
16454cff 20917@@ -4746,7 +4746,7 @@ void ata_qc_free(struct ata_queued_cmd *
6892158b
MT
20918 struct ata_port *ap;
20919 unsigned int tag;
20920
20921- WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
20922+ BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
20923 ap = qc->ap;
20924
20925 qc->flags = 0;
16454cff 20926@@ -4762,7 +4762,7 @@ void __ata_qc_complete(struct ata_queued
6892158b
MT
20927 struct ata_port *ap;
20928 struct ata_link *link;
20929
20930- WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
20931+ BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
20932 WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE));
20933 ap = qc->ap;
20934 link = qc->dev->link;
16454cff 20935@@ -5755,7 +5755,7 @@ static void ata_host_stop(struct device
ae4e228f
MT
20936 * LOCKING:
20937 * None.
20938 */
20939-static void ata_finalize_port_ops(struct ata_port_operations *ops)
20940+static void ata_finalize_port_ops(const struct ata_port_operations *ops)
20941 {
20942 static DEFINE_SPINLOCK(lock);
20943 const struct ata_port_operations *cur;
16454cff 20944@@ -5767,6 +5767,7 @@ static void ata_finalize_port_ops(struct
ae4e228f
MT
20945 return;
20946
20947 spin_lock(&lock);
20948+ pax_open_kernel();
20949
20950 for (cur = ops->inherits; cur; cur = cur->inherits) {
20951 void **inherit = (void **)cur;
16454cff 20952@@ -5780,8 +5781,9 @@ static void ata_finalize_port_ops(struct
ae4e228f
MT
20953 if (IS_ERR(*pp))
20954 *pp = NULL;
20955
20956- ops->inherits = NULL;
20957+ ((struct ata_port_operations *)ops)->inherits = NULL;
20958
20959+ pax_close_kernel();
20960 spin_unlock(&lock);
20961 }
20962
16454cff 20963@@ -5878,7 +5880,7 @@ int ata_host_start(struct ata_host *host
ae4e228f
MT
20964 */
20965 /* KILLME - the only user left is ipr */
20966 void ata_host_init(struct ata_host *host, struct device *dev,
20967- unsigned long flags, struct ata_port_operations *ops)
20968+ unsigned long flags, const struct ata_port_operations *ops)
20969 {
20970 spin_lock_init(&host->lock);
bc901d79 20971 mutex_init(&host->eh_mutex);
16454cff 20972@@ -6584,7 +6586,7 @@ static void ata_dummy_error_handler(stru
ae4e228f
MT
20973 /* truly dummy */
20974 }
20975
20976-struct ata_port_operations ata_dummy_port_ops = {
20977+const struct ata_port_operations ata_dummy_port_ops = {
20978 .qc_prep = ata_noop_qc_prep,
20979 .qc_issue = ata_dummy_qc_issue,
20980 .error_handler = ata_dummy_error_handler,
16454cff
MT
20981diff -urNp linux-2.6.38.1/drivers/ata/libata-eh.c linux-2.6.38.1/drivers/ata/libata-eh.c
20982--- linux-2.6.38.1/drivers/ata/libata-eh.c 2011-03-23 17:20:06.000000000 -0400
20983+++ linux-2.6.38.1/drivers/ata/libata-eh.c 2011-03-23 17:21:49.000000000 -0400
bc901d79 20984@@ -3880,7 +3880,7 @@ void ata_do_eh(struct ata_port *ap, ata_
ae4e228f
MT
20985 */
20986 void ata_std_error_handler(struct ata_port *ap)
20987 {
20988- struct ata_port_operations *ops = ap->ops;
20989+ const struct ata_port_operations *ops = ap->ops;
20990 ata_reset_fn_t hardreset = ops->hardreset;
20991
20992 /* ignore built-in hardreset if SCR access is not available */
16454cff
MT
20993diff -urNp linux-2.6.38.1/drivers/ata/libata-pmp.c linux-2.6.38.1/drivers/ata/libata-pmp.c
20994--- linux-2.6.38.1/drivers/ata/libata-pmp.c 2011-03-14 21:20:32.000000000 -0400
20995+++ linux-2.6.38.1/drivers/ata/libata-pmp.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 20996@@ -912,7 +912,7 @@ static int sata_pmp_handle_link_fail(str
ae4e228f
MT
20997 */
20998 static int sata_pmp_eh_recover(struct ata_port *ap)
20999 {
21000- struct ata_port_operations *ops = ap->ops;
21001+ const struct ata_port_operations *ops = ap->ops;
21002 int pmp_tries, link_tries[SATA_PMP_MAX_PORTS];
21003 struct ata_link *pmp_link = &ap->link;
21004 struct ata_device *pmp_dev = pmp_link->device;
16454cff
MT
21005diff -urNp linux-2.6.38.1/drivers/ata/pata_acpi.c linux-2.6.38.1/drivers/ata/pata_acpi.c
21006--- linux-2.6.38.1/drivers/ata/pata_acpi.c 2011-03-14 21:20:32.000000000 -0400
21007+++ linux-2.6.38.1/drivers/ata/pata_acpi.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21008@@ -216,7 +216,7 @@ static struct scsi_host_template pacpi_s
ae4e228f
MT
21009 ATA_BMDMA_SHT(DRV_NAME),
21010 };
21011
21012-static struct ata_port_operations pacpi_ops = {
21013+static const struct ata_port_operations pacpi_ops = {
21014 .inherits = &ata_bmdma_port_ops,
21015 .qc_issue = pacpi_qc_issue,
21016 .cable_detect = pacpi_cable_detect,
16454cff
MT
21017diff -urNp linux-2.6.38.1/drivers/ata/pata_ali.c linux-2.6.38.1/drivers/ata/pata_ali.c
21018--- linux-2.6.38.1/drivers/ata/pata_ali.c 2011-03-14 21:20:32.000000000 -0400
21019+++ linux-2.6.38.1/drivers/ata/pata_ali.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21020@@ -363,7 +363,7 @@ static struct scsi_host_template ali_sht
ae4e228f
MT
21021 * Port operations for PIO only ALi
21022 */
21023
21024-static struct ata_port_operations ali_early_port_ops = {
21025+static const struct ata_port_operations ali_early_port_ops = {
21026 .inherits = &ata_sff_port_ops,
21027 .cable_detect = ata_cable_40wire,
21028 .set_piomode = ali_set_piomode,
df50ba0c 21029@@ -380,7 +380,7 @@ static const struct ata_port_operations
ae4e228f
MT
21030 * Port operations for DMA capable ALi without cable
21031 * detect
21032 */
21033-static struct ata_port_operations ali_20_port_ops = {
21034+static const struct ata_port_operations ali_20_port_ops = {
21035 .inherits = &ali_dma_base_ops,
21036 .cable_detect = ata_cable_40wire,
21037 .mode_filter = ali_20_filter,
df50ba0c 21038@@ -391,7 +391,7 @@ static struct ata_port_operations ali_20
ae4e228f
MT
21039 /*
21040 * Port operations for DMA capable ALi with cable detect
21041 */
21042-static struct ata_port_operations ali_c2_port_ops = {
21043+static const struct ata_port_operations ali_c2_port_ops = {
21044 .inherits = &ali_dma_base_ops,
21045 .check_atapi_dma = ali_check_atapi_dma,
21046 .cable_detect = ali_c2_cable_detect,
df50ba0c 21047@@ -402,7 +402,7 @@ static struct ata_port_operations ali_c2
ae4e228f
MT
21048 /*
21049 * Port operations for DMA capable ALi with cable detect
21050 */
21051-static struct ata_port_operations ali_c4_port_ops = {
21052+static const struct ata_port_operations ali_c4_port_ops = {
21053 .inherits = &ali_dma_base_ops,
21054 .check_atapi_dma = ali_check_atapi_dma,
21055 .cable_detect = ali_c2_cable_detect,
df50ba0c 21056@@ -412,7 +412,7 @@ static struct ata_port_operations ali_c4
ae4e228f
MT
21057 /*
21058 * Port operations for DMA capable ALi with cable detect and LBA48
21059 */
21060-static struct ata_port_operations ali_c5_port_ops = {
21061+static const struct ata_port_operations ali_c5_port_ops = {
21062 .inherits = &ali_dma_base_ops,
21063 .check_atapi_dma = ali_check_atapi_dma,
21064 .dev_config = ali_warn_atapi_dma,
16454cff
MT
21065diff -urNp linux-2.6.38.1/drivers/ata/pata_amd.c linux-2.6.38.1/drivers/ata/pata_amd.c
21066--- linux-2.6.38.1/drivers/ata/pata_amd.c 2011-03-14 21:20:32.000000000 -0400
21067+++ linux-2.6.38.1/drivers/ata/pata_amd.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21068@@ -397,28 +397,28 @@ static const struct ata_port_operations
21069 .prereset = amd_pre_reset,
21070 };
21071
21072-static struct ata_port_operations amd33_port_ops = {
21073+static const struct ata_port_operations amd33_port_ops = {
21074 .inherits = &amd_base_port_ops,
21075 .cable_detect = ata_cable_40wire,
21076 .set_piomode = amd33_set_piomode,
21077 .set_dmamode = amd33_set_dmamode,
21078 };
21079
21080-static struct ata_port_operations amd66_port_ops = {
21081+static const struct ata_port_operations amd66_port_ops = {
21082 .inherits = &amd_base_port_ops,
21083 .cable_detect = ata_cable_unknown,
21084 .set_piomode = amd66_set_piomode,
21085 .set_dmamode = amd66_set_dmamode,
21086 };
21087
21088-static struct ata_port_operations amd100_port_ops = {
21089+static const struct ata_port_operations amd100_port_ops = {
21090 .inherits = &amd_base_port_ops,
21091 .cable_detect = ata_cable_unknown,
21092 .set_piomode = amd100_set_piomode,
21093 .set_dmamode = amd100_set_dmamode,
21094 };
21095
21096-static struct ata_port_operations amd133_port_ops = {
21097+static const struct ata_port_operations amd133_port_ops = {
21098 .inherits = &amd_base_port_ops,
21099 .cable_detect = amd_cable_detect,
21100 .set_piomode = amd133_set_piomode,
21101@@ -433,13 +433,13 @@ static const struct ata_port_operations
21102 .host_stop = nv_host_stop,
21103 };
21104
21105-static struct ata_port_operations nv100_port_ops = {
21106+static const struct ata_port_operations nv100_port_ops = {
21107 .inherits = &nv_base_port_ops,
21108 .set_piomode = nv100_set_piomode,
21109 .set_dmamode = nv100_set_dmamode,
21110 };
21111
21112-static struct ata_port_operations nv133_port_ops = {
21113+static const struct ata_port_operations nv133_port_ops = {
21114 .inherits = &nv_base_port_ops,
21115 .set_piomode = nv133_set_piomode,
21116 .set_dmamode = nv133_set_dmamode,
16454cff
MT
21117diff -urNp linux-2.6.38.1/drivers/ata/pata_artop.c linux-2.6.38.1/drivers/ata/pata_artop.c
21118--- linux-2.6.38.1/drivers/ata/pata_artop.c 2011-03-14 21:20:32.000000000 -0400
21119+++ linux-2.6.38.1/drivers/ata/pata_artop.c 2011-03-21 18:31:35.000000000 -0400
6892158b 21120@@ -312,7 +312,7 @@ static struct scsi_host_template artop_s
ae4e228f
MT
21121 ATA_BMDMA_SHT(DRV_NAME),
21122 };
21123
21124-static struct ata_port_operations artop6210_ops = {
21125+static const struct ata_port_operations artop6210_ops = {
21126 .inherits = &ata_bmdma_port_ops,
21127 .cable_detect = ata_cable_40wire,
21128 .set_piomode = artop6210_set_piomode,
6892158b 21129@@ -321,7 +321,7 @@ static struct ata_port_operations artop6
ae4e228f
MT
21130 .qc_defer = artop6210_qc_defer,
21131 };
21132
21133-static struct ata_port_operations artop6260_ops = {
21134+static const struct ata_port_operations artop6260_ops = {
21135 .inherits = &ata_bmdma_port_ops,
21136 .cable_detect = artop6260_cable_detect,
21137 .set_piomode = artop6260_set_piomode,
16454cff
MT
21138diff -urNp linux-2.6.38.1/drivers/ata/pata_at32.c linux-2.6.38.1/drivers/ata/pata_at32.c
21139--- linux-2.6.38.1/drivers/ata/pata_at32.c 2011-03-14 21:20:32.000000000 -0400
21140+++ linux-2.6.38.1/drivers/ata/pata_at32.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21141@@ -173,7 +173,7 @@ static struct scsi_host_template at32_sh
ae4e228f
MT
21142 ATA_PIO_SHT(DRV_NAME),
21143 };
21144
21145-static struct ata_port_operations at32_port_ops = {
21146+static const struct ata_port_operations at32_port_ops = {
21147 .inherits = &ata_sff_port_ops,
21148 .cable_detect = ata_cable_40wire,
21149 .set_piomode = pata_at32_set_piomode,
16454cff
MT
21150diff -urNp linux-2.6.38.1/drivers/ata/pata_at91.c linux-2.6.38.1/drivers/ata/pata_at91.c
21151--- linux-2.6.38.1/drivers/ata/pata_at91.c 2011-03-14 21:20:32.000000000 -0400
21152+++ linux-2.6.38.1/drivers/ata/pata_at91.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21153@@ -196,7 +196,7 @@ static struct scsi_host_template pata_at
ae4e228f
MT
21154 ATA_PIO_SHT(DRV_NAME),
21155 };
21156
21157-static struct ata_port_operations pata_at91_port_ops = {
21158+static const struct ata_port_operations pata_at91_port_ops = {
21159 .inherits = &ata_sff_port_ops,
21160
21161 .sff_data_xfer = pata_at91_data_xfer_noirq,
16454cff
MT
21162diff -urNp linux-2.6.38.1/drivers/ata/pata_atiixp.c linux-2.6.38.1/drivers/ata/pata_atiixp.c
21163--- linux-2.6.38.1/drivers/ata/pata_atiixp.c 2011-03-14 21:20:32.000000000 -0400
21164+++ linux-2.6.38.1/drivers/ata/pata_atiixp.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21165@@ -214,7 +214,7 @@ static struct scsi_host_template atiixp_
ae4e228f
MT
21166 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
21167 };
21168
21169-static struct ata_port_operations atiixp_port_ops = {
21170+static const struct ata_port_operations atiixp_port_ops = {
21171 .inherits = &ata_bmdma_port_ops,
21172
57199397 21173 .qc_prep = ata_bmdma_dumb_qc_prep,
16454cff
MT
21174diff -urNp linux-2.6.38.1/drivers/ata/pata_atp867x.c linux-2.6.38.1/drivers/ata/pata_atp867x.c
21175--- linux-2.6.38.1/drivers/ata/pata_atp867x.c 2011-03-14 21:20:32.000000000 -0400
21176+++ linux-2.6.38.1/drivers/ata/pata_atp867x.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21177@@ -275,7 +275,7 @@ static struct scsi_host_template atp867x
ae4e228f
MT
21178 ATA_BMDMA_SHT(DRV_NAME),
21179 };
21180
21181-static struct ata_port_operations atp867x_ops = {
21182+static const struct ata_port_operations atp867x_ops = {
21183 .inherits = &ata_bmdma_port_ops,
21184 .cable_detect = atp867x_cable_detect,
21185 .set_piomode = atp867x_set_piomode,
16454cff
MT
21186diff -urNp linux-2.6.38.1/drivers/ata/pata_bf54x.c linux-2.6.38.1/drivers/ata/pata_bf54x.c
21187--- linux-2.6.38.1/drivers/ata/pata_bf54x.c 2011-03-14 21:20:32.000000000 -0400
21188+++ linux-2.6.38.1/drivers/ata/pata_bf54x.c 2011-03-21 18:31:35.000000000 -0400
57199397 21189@@ -1420,7 +1420,7 @@ static struct scsi_host_template bfin_sh
ae4e228f
MT
21190 .dma_boundary = ATA_DMA_BOUNDARY,
21191 };
21192
21193-static struct ata_port_operations bfin_pata_ops = {
21194+static const struct ata_port_operations bfin_pata_ops = {
57199397 21195 .inherits = &ata_bmdma_port_ops,
ae4e228f
MT
21196
21197 .set_piomode = bfin_set_piomode,
16454cff
MT
21198diff -urNp linux-2.6.38.1/drivers/ata/pata_cmd640.c linux-2.6.38.1/drivers/ata/pata_cmd640.c
21199--- linux-2.6.38.1/drivers/ata/pata_cmd640.c 2011-03-14 21:20:32.000000000 -0400
21200+++ linux-2.6.38.1/drivers/ata/pata_cmd640.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 21201@@ -176,7 +176,7 @@ static struct scsi_host_template cmd640_
57199397 21202 ATA_PIO_SHT(DRV_NAME),
ae4e228f
MT
21203 };
21204
21205-static struct ata_port_operations cmd640_port_ops = {
21206+static const struct ata_port_operations cmd640_port_ops = {
57199397 21207 .inherits = &ata_sff_port_ops,
ae4e228f
MT
21208 /* In theory xfer_noirq is not needed once we kill the prefetcher */
21209 .sff_data_xfer = ata_sff_data_xfer_noirq,
16454cff
MT
21210diff -urNp linux-2.6.38.1/drivers/ata/pata_cmd64x.c linux-2.6.38.1/drivers/ata/pata_cmd64x.c
21211--- linux-2.6.38.1/drivers/ata/pata_cmd64x.c 2011-03-14 21:20:32.000000000 -0400
21212+++ linux-2.6.38.1/drivers/ata/pata_cmd64x.c 2011-03-21 18:31:35.000000000 -0400
6892158b 21213@@ -268,18 +268,18 @@ static const struct ata_port_operations
ae4e228f
MT
21214 .set_dmamode = cmd64x_set_dmamode,
21215 };
21216
21217-static struct ata_port_operations cmd64x_port_ops = {
21218+static const struct ata_port_operations cmd64x_port_ops = {
21219 .inherits = &cmd64x_base_ops,
21220 .cable_detect = ata_cable_40wire,
21221 };
21222
21223-static struct ata_port_operations cmd646r1_port_ops = {
21224+static const struct ata_port_operations cmd646r1_port_ops = {
21225 .inherits = &cmd64x_base_ops,
21226 .bmdma_stop = cmd646r1_bmdma_stop,
21227 .cable_detect = ata_cable_40wire,
21228 };
21229
21230-static struct ata_port_operations cmd648_port_ops = {
21231+static const struct ata_port_operations cmd648_port_ops = {
21232 .inherits = &cmd64x_base_ops,
21233 .bmdma_stop = cmd648_bmdma_stop,
21234 .cable_detect = cmd648_cable_detect,
16454cff
MT
21235diff -urNp linux-2.6.38.1/drivers/ata/pata_cs5520.c linux-2.6.38.1/drivers/ata/pata_cs5520.c
21236--- linux-2.6.38.1/drivers/ata/pata_cs5520.c 2011-03-14 21:20:32.000000000 -0400
21237+++ linux-2.6.38.1/drivers/ata/pata_cs5520.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21238@@ -108,7 +108,7 @@ static struct scsi_host_template cs5520_
21239 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
21240 };
21241
21242-static struct ata_port_operations cs5520_port_ops = {
21243+static const struct ata_port_operations cs5520_port_ops = {
21244 .inherits = &ata_bmdma_port_ops,
57199397 21245 .qc_prep = ata_bmdma_dumb_qc_prep,
ae4e228f 21246 .cable_detect = ata_cable_40wire,
16454cff
MT
21247diff -urNp linux-2.6.38.1/drivers/ata/pata_cs5530.c linux-2.6.38.1/drivers/ata/pata_cs5530.c
21248--- linux-2.6.38.1/drivers/ata/pata_cs5530.c 2011-03-14 21:20:32.000000000 -0400
21249+++ linux-2.6.38.1/drivers/ata/pata_cs5530.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21250@@ -164,7 +164,7 @@ static struct scsi_host_template cs5530_
21251 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
21252 };
21253
21254-static struct ata_port_operations cs5530_port_ops = {
21255+static const struct ata_port_operations cs5530_port_ops = {
21256 .inherits = &ata_bmdma_port_ops,
21257
57199397 21258 .qc_prep = ata_bmdma_dumb_qc_prep,
16454cff
MT
21259diff -urNp linux-2.6.38.1/drivers/ata/pata_cs5535.c linux-2.6.38.1/drivers/ata/pata_cs5535.c
21260--- linux-2.6.38.1/drivers/ata/pata_cs5535.c 2011-03-14 21:20:32.000000000 -0400
21261+++ linux-2.6.38.1/drivers/ata/pata_cs5535.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21262@@ -160,7 +160,7 @@ static struct scsi_host_template cs5535_
21263 ATA_BMDMA_SHT(DRV_NAME),
21264 };
21265
21266-static struct ata_port_operations cs5535_port_ops = {
21267+static const struct ata_port_operations cs5535_port_ops = {
21268 .inherits = &ata_bmdma_port_ops,
21269 .cable_detect = cs5535_cable_detect,
21270 .set_piomode = cs5535_set_piomode,
16454cff
MT
21271diff -urNp linux-2.6.38.1/drivers/ata/pata_cs5536.c linux-2.6.38.1/drivers/ata/pata_cs5536.c
21272--- linux-2.6.38.1/drivers/ata/pata_cs5536.c 2011-03-14 21:20:32.000000000 -0400
21273+++ linux-2.6.38.1/drivers/ata/pata_cs5536.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 21274@@ -233,7 +233,7 @@ static struct scsi_host_template cs5536_
ae4e228f
MT
21275 ATA_BMDMA_SHT(DRV_NAME),
21276 };
21277
21278-static struct ata_port_operations cs5536_port_ops = {
21279+static const struct ata_port_operations cs5536_port_ops = {
21280 .inherits = &ata_bmdma32_port_ops,
21281 .cable_detect = cs5536_cable_detect,
21282 .set_piomode = cs5536_set_piomode,
16454cff
MT
21283diff -urNp linux-2.6.38.1/drivers/ata/pata_cypress.c linux-2.6.38.1/drivers/ata/pata_cypress.c
21284--- linux-2.6.38.1/drivers/ata/pata_cypress.c 2011-03-14 21:20:32.000000000 -0400
21285+++ linux-2.6.38.1/drivers/ata/pata_cypress.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21286@@ -115,7 +115,7 @@ static struct scsi_host_template cy82c69
ae4e228f
MT
21287 ATA_BMDMA_SHT(DRV_NAME),
21288 };
21289
21290-static struct ata_port_operations cy82c693_port_ops = {
21291+static const struct ata_port_operations cy82c693_port_ops = {
21292 .inherits = &ata_bmdma_port_ops,
21293 .cable_detect = ata_cable_40wire,
21294 .set_piomode = cy82c693_set_piomode,
16454cff
MT
21295diff -urNp linux-2.6.38.1/drivers/ata/pata_efar.c linux-2.6.38.1/drivers/ata/pata_efar.c
21296--- linux-2.6.38.1/drivers/ata/pata_efar.c 2011-03-14 21:20:32.000000000 -0400
21297+++ linux-2.6.38.1/drivers/ata/pata_efar.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21298@@ -238,7 +238,7 @@ static struct scsi_host_template efar_sh
ae4e228f
MT
21299 ATA_BMDMA_SHT(DRV_NAME),
21300 };
21301
21302-static struct ata_port_operations efar_ops = {
21303+static const struct ata_port_operations efar_ops = {
21304 .inherits = &ata_bmdma_port_ops,
21305 .cable_detect = efar_cable_detect,
21306 .set_piomode = efar_set_piomode,
16454cff
MT
21307diff -urNp linux-2.6.38.1/drivers/ata/pata_hpt366.c linux-2.6.38.1/drivers/ata/pata_hpt366.c
21308--- linux-2.6.38.1/drivers/ata/pata_hpt366.c 2011-03-14 21:20:32.000000000 -0400
21309+++ linux-2.6.38.1/drivers/ata/pata_hpt366.c 2011-03-21 18:31:35.000000000 -0400
21310@@ -275,7 +275,7 @@ static struct scsi_host_template hpt36x_
ae4e228f
MT
21311 * Configuration for HPT366/68
21312 */
21313
21314-static struct ata_port_operations hpt366_port_ops = {
21315+static const struct ata_port_operations hpt366_port_ops = {
21316 .inherits = &ata_bmdma_port_ops,
21317 .cable_detect = hpt36x_cable_detect,
21318 .mode_filter = hpt366_filter,
16454cff
MT
21319diff -urNp linux-2.6.38.1/drivers/ata/pata_hpt37x.c linux-2.6.38.1/drivers/ata/pata_hpt37x.c
21320--- linux-2.6.38.1/drivers/ata/pata_hpt37x.c 2011-03-14 21:20:32.000000000 -0400
21321+++ linux-2.6.38.1/drivers/ata/pata_hpt37x.c 2011-03-21 18:31:35.000000000 -0400
21322@@ -587,7 +587,7 @@ static struct scsi_host_template hpt37x_
ae4e228f
MT
21323 * Configuration for HPT370
21324 */
21325
21326-static struct ata_port_operations hpt370_port_ops = {
21327+static const struct ata_port_operations hpt370_port_ops = {
21328 .inherits = &ata_bmdma_port_ops,
21329
21330 .bmdma_stop = hpt370_bmdma_stop,
16454cff 21331@@ -603,7 +603,7 @@ static struct ata_port_operations hpt370
ae4e228f
MT
21332 * Configuration for HPT370A. Close to 370 but less filters
21333 */
21334
21335-static struct ata_port_operations hpt370a_port_ops = {
21336+static const struct ata_port_operations hpt370a_port_ops = {
21337 .inherits = &hpt370_port_ops,
21338 .mode_filter = hpt370a_filter,
21339 };
16454cff
MT
21340@@ -613,7 +613,7 @@ static struct ata_port_operations hpt370
21341 * mode setting functionality.
ae4e228f
MT
21342 */
21343
16454cff
MT
21344-static struct ata_port_operations hpt302_port_ops = {
21345+static const struct ata_port_operations hpt302_port_ops = {
ae4e228f
MT
21346 .inherits = &ata_bmdma_port_ops,
21347
21348 .bmdma_stop = hpt37x_bmdma_stop,
16454cff
MT
21349@@ -629,7 +629,7 @@ static struct ata_port_operations hpt302
21350 * but we have a mode filter.
21351 */
21352
21353-static struct ata_port_operations hpt372_port_ops = {
21354+static const struct ata_port_operations hpt372_port_ops = {
21355 .inherits = &hpt302_port_ops,
21356 .mode_filter = hpt372_filter,
21357 };
21358@@ -639,7 +639,7 @@ static struct ata_port_operations hpt372
ae4e228f
MT
21359 * but we have a different cable detection procedure for function 1.
21360 */
21361
21362-static struct ata_port_operations hpt374_fn1_port_ops = {
21363+static const struct ata_port_operations hpt374_fn1_port_ops = {
21364 .inherits = &hpt372_port_ops,
21365 .cable_detect = hpt374_fn1_cable_detect,
16454cff
MT
21366 };
21367diff -urNp linux-2.6.38.1/drivers/ata/pata_hpt3x2n.c linux-2.6.38.1/drivers/ata/pata_hpt3x2n.c
21368--- linux-2.6.38.1/drivers/ata/pata_hpt3x2n.c 2011-03-14 21:20:32.000000000 -0400
21369+++ linux-2.6.38.1/drivers/ata/pata_hpt3x2n.c 2011-03-21 18:31:35.000000000 -0400
21370@@ -348,7 +348,7 @@ static struct scsi_host_template hpt3x2n
21371 * Configuration for HPT302N/371N.
ae4e228f
MT
21372 */
21373
16454cff
MT
21374-static struct ata_port_operations hpt3xxn_port_ops = {
21375+static const struct ata_port_operations hpt3xxn_port_ops = {
ae4e228f
MT
21376 .inherits = &ata_bmdma_port_ops,
21377
21378 .bmdma_stop = hpt3x2n_bmdma_stop,
16454cff
MT
21379@@ -366,7 +366,7 @@ static struct ata_port_operations hpt3xx
21380 * Configuration for HPT372N. Same as 302N/371N but we have a mode filter.
21381 */
21382
21383-static struct ata_port_operations hpt372n_port_ops = {
21384+static const struct ata_port_operations hpt372n_port_ops = {
21385 .inherits = &hpt3xxn_port_ops,
21386 .mode_filter = &hpt372n_filter,
21387 };
21388diff -urNp linux-2.6.38.1/drivers/ata/pata_hpt3x3.c linux-2.6.38.1/drivers/ata/pata_hpt3x3.c
21389--- linux-2.6.38.1/drivers/ata/pata_hpt3x3.c 2011-03-14 21:20:32.000000000 -0400
21390+++ linux-2.6.38.1/drivers/ata/pata_hpt3x3.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21391@@ -141,7 +141,7 @@ static struct scsi_host_template hpt3x3_
21392 ATA_BMDMA_SHT(DRV_NAME),
21393 };
21394
21395-static struct ata_port_operations hpt3x3_port_ops = {
21396+static const struct ata_port_operations hpt3x3_port_ops = {
21397 .inherits = &ata_bmdma_port_ops,
21398 .cable_detect = ata_cable_40wire,
21399 .set_piomode = hpt3x3_set_piomode,
16454cff
MT
21400diff -urNp linux-2.6.38.1/drivers/ata/pata_icside.c linux-2.6.38.1/drivers/ata/pata_icside.c
21401--- linux-2.6.38.1/drivers/ata/pata_icside.c 2011-03-14 21:20:32.000000000 -0400
21402+++ linux-2.6.38.1/drivers/ata/pata_icside.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21403@@ -320,7 +320,7 @@ static void pata_icside_postreset(struct
ae4e228f
MT
21404 }
21405 }
21406
21407-static struct ata_port_operations pata_icside_port_ops = {
21408+static const struct ata_port_operations pata_icside_port_ops = {
57199397 21409 .inherits = &ata_bmdma_port_ops,
ae4e228f
MT
21410 /* no need to build any PRD tables for DMA */
21411 .qc_prep = ata_noop_qc_prep,
16454cff
MT
21412diff -urNp linux-2.6.38.1/drivers/ata/pata_isapnp.c linux-2.6.38.1/drivers/ata/pata_isapnp.c
21413--- linux-2.6.38.1/drivers/ata/pata_isapnp.c 2011-03-14 21:20:32.000000000 -0400
21414+++ linux-2.6.38.1/drivers/ata/pata_isapnp.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21415@@ -23,12 +23,12 @@ static struct scsi_host_template isapnp_
21416 ATA_PIO_SHT(DRV_NAME),
21417 };
21418
21419-static struct ata_port_operations isapnp_port_ops = {
21420+static const struct ata_port_operations isapnp_port_ops = {
21421 .inherits = &ata_sff_port_ops,
21422 .cable_detect = ata_cable_40wire,
21423 };
21424
21425-static struct ata_port_operations isapnp_noalt_port_ops = {
21426+static const struct ata_port_operations isapnp_noalt_port_ops = {
21427 .inherits = &ata_sff_port_ops,
21428 .cable_detect = ata_cable_40wire,
21429 /* No altstatus so we don't want to use the lost interrupt poll */
16454cff
MT
21430diff -urNp linux-2.6.38.1/drivers/ata/pata_it8213.c linux-2.6.38.1/drivers/ata/pata_it8213.c
21431--- linux-2.6.38.1/drivers/ata/pata_it8213.c 2011-03-14 21:20:32.000000000 -0400
21432+++ linux-2.6.38.1/drivers/ata/pata_it8213.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21433@@ -233,7 +233,7 @@ static struct scsi_host_template it8213_
21434 };
21435
21436
21437-static struct ata_port_operations it8213_ops = {
21438+static const struct ata_port_operations it8213_ops = {
21439 .inherits = &ata_bmdma_port_ops,
21440 .cable_detect = it8213_cable_detect,
21441 .set_piomode = it8213_set_piomode,
16454cff
MT
21442diff -urNp linux-2.6.38.1/drivers/ata/pata_it821x.c linux-2.6.38.1/drivers/ata/pata_it821x.c
21443--- linux-2.6.38.1/drivers/ata/pata_it821x.c 2011-03-14 21:20:32.000000000 -0400
21444+++ linux-2.6.38.1/drivers/ata/pata_it821x.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21445@@ -801,7 +801,7 @@ static struct scsi_host_template it821x_
ae4e228f
MT
21446 ATA_BMDMA_SHT(DRV_NAME),
21447 };
21448
21449-static struct ata_port_operations it821x_smart_port_ops = {
21450+static const struct ata_port_operations it821x_smart_port_ops = {
21451 .inherits = &ata_bmdma_port_ops,
21452
21453 .check_atapi_dma= it821x_check_atapi_dma,
df50ba0c 21454@@ -815,7 +815,7 @@ static struct ata_port_operations it821x
ae4e228f
MT
21455 .port_start = it821x_port_start,
21456 };
21457
21458-static struct ata_port_operations it821x_passthru_port_ops = {
21459+static const struct ata_port_operations it821x_passthru_port_ops = {
21460 .inherits = &ata_bmdma_port_ops,
21461
21462 .check_atapi_dma= it821x_check_atapi_dma,
df50ba0c 21463@@ -831,7 +831,7 @@ static struct ata_port_operations it821x
ae4e228f
MT
21464 .port_start = it821x_port_start,
21465 };
21466
21467-static struct ata_port_operations it821x_rdc_port_ops = {
21468+static const struct ata_port_operations it821x_rdc_port_ops = {
21469 .inherits = &ata_bmdma_port_ops,
21470
21471 .check_atapi_dma= it821x_check_atapi_dma,
16454cff
MT
21472diff -urNp linux-2.6.38.1/drivers/ata/pata_ixp4xx_cf.c linux-2.6.38.1/drivers/ata/pata_ixp4xx_cf.c
21473--- linux-2.6.38.1/drivers/ata/pata_ixp4xx_cf.c 2011-03-14 21:20:32.000000000 -0400
21474+++ linux-2.6.38.1/drivers/ata/pata_ixp4xx_cf.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21475@@ -89,7 +89,7 @@ static struct scsi_host_template ixp4xx_
21476 ATA_PIO_SHT(DRV_NAME),
21477 };
21478
21479-static struct ata_port_operations ixp4xx_port_ops = {
21480+static const struct ata_port_operations ixp4xx_port_ops = {
21481 .inherits = &ata_sff_port_ops,
21482 .sff_data_xfer = ixp4xx_mmio_data_xfer,
21483 .cable_detect = ata_cable_40wire,
16454cff
MT
21484diff -urNp linux-2.6.38.1/drivers/ata/pata_jmicron.c linux-2.6.38.1/drivers/ata/pata_jmicron.c
21485--- linux-2.6.38.1/drivers/ata/pata_jmicron.c 2011-03-14 21:20:32.000000000 -0400
21486+++ linux-2.6.38.1/drivers/ata/pata_jmicron.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21487@@ -111,7 +111,7 @@ static struct scsi_host_template jmicron
21488 ATA_BMDMA_SHT(DRV_NAME),
21489 };
21490
21491-static struct ata_port_operations jmicron_ops = {
21492+static const struct ata_port_operations jmicron_ops = {
21493 .inherits = &ata_bmdma_port_ops,
21494 .prereset = jmicron_pre_reset,
21495 };
16454cff
MT
21496diff -urNp linux-2.6.38.1/drivers/ata/pata_legacy.c linux-2.6.38.1/drivers/ata/pata_legacy.c
21497--- linux-2.6.38.1/drivers/ata/pata_legacy.c 2011-03-14 21:20:32.000000000 -0400
21498+++ linux-2.6.38.1/drivers/ata/pata_legacy.c 2011-03-21 18:31:35.000000000 -0400
6892158b 21499@@ -116,7 +116,7 @@ struct legacy_probe {
ae4e228f
MT
21500
21501 struct legacy_controller {
21502 const char *name;
21503- struct ata_port_operations *ops;
21504+ const struct ata_port_operations *ops;
21505 unsigned int pio_mask;
21506 unsigned int flags;
21507 unsigned int pflags;
6892158b 21508@@ -239,12 +239,12 @@ static const struct ata_port_operations
ae4e228f
MT
21509 * pio_mask as well.
21510 */
21511
21512-static struct ata_port_operations simple_port_ops = {
21513+static const struct ata_port_operations simple_port_ops = {
21514 .inherits = &legacy_base_port_ops,
21515 .sff_data_xfer = ata_sff_data_xfer_noirq,
21516 };
21517
21518-static struct ata_port_operations legacy_port_ops = {
21519+static const struct ata_port_operations legacy_port_ops = {
21520 .inherits = &legacy_base_port_ops,
21521 .sff_data_xfer = ata_sff_data_xfer_noirq,
21522 .set_mode = legacy_set_mode,
6892158b 21523@@ -340,7 +340,7 @@ static unsigned int pdc_data_xfer_vlb(st
ae4e228f
MT
21524 return buflen;
21525 }
21526
21527-static struct ata_port_operations pdc20230_port_ops = {
21528+static const struct ata_port_operations pdc20230_port_ops = {
21529 .inherits = &legacy_base_port_ops,
21530 .set_piomode = pdc20230_set_piomode,
21531 .sff_data_xfer = pdc_data_xfer_vlb,
6892158b 21532@@ -373,7 +373,7 @@ static void ht6560a_set_piomode(struct a
ae4e228f
MT
21533 ioread8(ap->ioaddr.status_addr);
21534 }
21535
21536-static struct ata_port_operations ht6560a_port_ops = {
21537+static const struct ata_port_operations ht6560a_port_ops = {
21538 .inherits = &legacy_base_port_ops,
21539 .set_piomode = ht6560a_set_piomode,
21540 };
6892158b 21541@@ -416,7 +416,7 @@ static void ht6560b_set_piomode(struct a
ae4e228f
MT
21542 ioread8(ap->ioaddr.status_addr);
21543 }
21544
21545-static struct ata_port_operations ht6560b_port_ops = {
21546+static const struct ata_port_operations ht6560b_port_ops = {
21547 .inherits = &legacy_base_port_ops,
21548 .set_piomode = ht6560b_set_piomode,
21549 };
6892158b 21550@@ -515,7 +515,7 @@ static void opti82c611a_set_piomode(stru
ae4e228f
MT
21551 }
21552
21553
21554-static struct ata_port_operations opti82c611a_port_ops = {
21555+static const struct ata_port_operations opti82c611a_port_ops = {
21556 .inherits = &legacy_base_port_ops,
21557 .set_piomode = opti82c611a_set_piomode,
21558 };
6892158b 21559@@ -625,7 +625,7 @@ static unsigned int opti82c46x_qc_issue(
ae4e228f
MT
21560 return ata_sff_qc_issue(qc);
21561 }
21562
21563-static struct ata_port_operations opti82c46x_port_ops = {
21564+static const struct ata_port_operations opti82c46x_port_ops = {
21565 .inherits = &legacy_base_port_ops,
21566 .set_piomode = opti82c46x_set_piomode,
21567 .qc_issue = opti82c46x_qc_issue,
6892158b 21568@@ -787,20 +787,20 @@ static int qdi_port(struct platform_devi
ae4e228f
MT
21569 return 0;
21570 }
21571
21572-static struct ata_port_operations qdi6500_port_ops = {
21573+static const struct ata_port_operations qdi6500_port_ops = {
21574 .inherits = &legacy_base_port_ops,
21575 .set_piomode = qdi6500_set_piomode,
21576 .qc_issue = qdi_qc_issue,
21577 .sff_data_xfer = vlb32_data_xfer,
21578 };
21579
21580-static struct ata_port_operations qdi6580_port_ops = {
21581+static const struct ata_port_operations qdi6580_port_ops = {
21582 .inherits = &legacy_base_port_ops,
21583 .set_piomode = qdi6580_set_piomode,
21584 .sff_data_xfer = vlb32_data_xfer,
21585 };
21586
21587-static struct ata_port_operations qdi6580dp_port_ops = {
21588+static const struct ata_port_operations qdi6580dp_port_ops = {
21589 .inherits = &legacy_base_port_ops,
21590 .set_piomode = qdi6580dp_set_piomode,
21591 .qc_issue = qdi_qc_issue,
6892158b 21592@@ -872,7 +872,7 @@ static int winbond_port(struct platform_
ae4e228f
MT
21593 return 0;
21594 }
21595
21596-static struct ata_port_operations winbond_port_ops = {
21597+static const struct ata_port_operations winbond_port_ops = {
21598 .inherits = &legacy_base_port_ops,
21599 .set_piomode = winbond_set_piomode,
21600 .sff_data_xfer = vlb32_data_xfer,
6892158b 21601@@ -995,7 +995,7 @@ static __init int legacy_init_one(struct
ae4e228f
MT
21602 int pio_modes = controller->pio_mask;
21603 unsigned long io = probe->port;
21604 u32 mask = (1 << probe->slot);
21605- struct ata_port_operations *ops = controller->ops;
21606+ const struct ata_port_operations *ops = controller->ops;
21607 struct legacy_data *ld = &legacy_data[probe->slot];
21608 struct ata_host *host = NULL;
21609 struct ata_port *ap;
16454cff
MT
21610diff -urNp linux-2.6.38.1/drivers/ata/pata_macio.c linux-2.6.38.1/drivers/ata/pata_macio.c
21611--- linux-2.6.38.1/drivers/ata/pata_macio.c 2011-03-14 21:20:32.000000000 -0400
21612+++ linux-2.6.38.1/drivers/ata/pata_macio.c 2011-03-21 18:31:35.000000000 -0400
57199397 21613@@ -918,9 +918,8 @@ static struct scsi_host_template pata_ma
ae4e228f
MT
21614 .slave_configure = pata_macio_slave_config,
21615 };
21616
21617-static struct ata_port_operations pata_macio_ops = {
21618+static const struct ata_port_operations pata_macio_ops = {
57199397
MT
21619 .inherits = &ata_bmdma_port_ops,
21620-
ae4e228f 21621 .freeze = pata_macio_freeze,
57199397
MT
21622 .set_piomode = pata_macio_set_timings,
21623 .set_dmamode = pata_macio_set_timings,
16454cff
MT
21624diff -urNp linux-2.6.38.1/drivers/ata/pata_marvell.c linux-2.6.38.1/drivers/ata/pata_marvell.c
21625--- linux-2.6.38.1/drivers/ata/pata_marvell.c 2011-03-14 21:20:32.000000000 -0400
21626+++ linux-2.6.38.1/drivers/ata/pata_marvell.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21627@@ -100,7 +100,7 @@ static struct scsi_host_template marvell
21628 ATA_BMDMA_SHT(DRV_NAME),
21629 };
21630
21631-static struct ata_port_operations marvell_ops = {
21632+static const struct ata_port_operations marvell_ops = {
21633 .inherits = &ata_bmdma_port_ops,
21634 .cable_detect = marvell_cable_detect,
21635 .prereset = marvell_pre_reset,
16454cff
MT
21636diff -urNp linux-2.6.38.1/drivers/ata/pata_mpc52xx.c linux-2.6.38.1/drivers/ata/pata_mpc52xx.c
21637--- linux-2.6.38.1/drivers/ata/pata_mpc52xx.c 2011-03-14 21:20:32.000000000 -0400
21638+++ linux-2.6.38.1/drivers/ata/pata_mpc52xx.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21639@@ -609,7 +609,7 @@ static struct scsi_host_template mpc52xx
21640 ATA_PIO_SHT(DRV_NAME),
21641 };
21642
21643-static struct ata_port_operations mpc52xx_ata_port_ops = {
21644+static const struct ata_port_operations mpc52xx_ata_port_ops = {
c52201e0 21645 .inherits = &ata_bmdma_port_ops,
ae4e228f
MT
21646 .sff_dev_select = mpc52xx_ata_dev_select,
21647 .set_piomode = mpc52xx_ata_set_piomode,
16454cff
MT
21648diff -urNp linux-2.6.38.1/drivers/ata/pata_mpiix.c linux-2.6.38.1/drivers/ata/pata_mpiix.c
21649--- linux-2.6.38.1/drivers/ata/pata_mpiix.c 2011-03-14 21:20:32.000000000 -0400
21650+++ linux-2.6.38.1/drivers/ata/pata_mpiix.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21651@@ -140,7 +140,7 @@ static struct scsi_host_template mpiix_s
21652 ATA_PIO_SHT(DRV_NAME),
21653 };
21654
21655-static struct ata_port_operations mpiix_port_ops = {
21656+static const struct ata_port_operations mpiix_port_ops = {
21657 .inherits = &ata_sff_port_ops,
21658 .qc_issue = mpiix_qc_issue,
21659 .cable_detect = ata_cable_40wire,
16454cff
MT
21660diff -urNp linux-2.6.38.1/drivers/ata/pata_netcell.c linux-2.6.38.1/drivers/ata/pata_netcell.c
21661--- linux-2.6.38.1/drivers/ata/pata_netcell.c 2011-03-14 21:20:32.000000000 -0400
21662+++ linux-2.6.38.1/drivers/ata/pata_netcell.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21663@@ -34,7 +34,7 @@ static struct scsi_host_template netcell
21664 ATA_BMDMA_SHT(DRV_NAME),
21665 };
21666
21667-static struct ata_port_operations netcell_ops = {
21668+static const struct ata_port_operations netcell_ops = {
21669 .inherits = &ata_bmdma_port_ops,
21670 .cable_detect = ata_cable_80wire,
21671 .read_id = netcell_read_id,
16454cff
MT
21672diff -urNp linux-2.6.38.1/drivers/ata/pata_ninja32.c linux-2.6.38.1/drivers/ata/pata_ninja32.c
21673--- linux-2.6.38.1/drivers/ata/pata_ninja32.c 2011-03-14 21:20:32.000000000 -0400
21674+++ linux-2.6.38.1/drivers/ata/pata_ninja32.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21675@@ -81,7 +81,7 @@ static struct scsi_host_template ninja32
21676 ATA_BMDMA_SHT(DRV_NAME),
21677 };
21678
21679-static struct ata_port_operations ninja32_port_ops = {
21680+static const struct ata_port_operations ninja32_port_ops = {
21681 .inherits = &ata_bmdma_port_ops,
21682 .sff_dev_select = ninja32_dev_select,
21683 .cable_detect = ata_cable_40wire,
16454cff
MT
21684diff -urNp linux-2.6.38.1/drivers/ata/pata_ns87410.c linux-2.6.38.1/drivers/ata/pata_ns87410.c
21685--- linux-2.6.38.1/drivers/ata/pata_ns87410.c 2011-03-14 21:20:32.000000000 -0400
21686+++ linux-2.6.38.1/drivers/ata/pata_ns87410.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21687@@ -132,7 +132,7 @@ static struct scsi_host_template ns87410
21688 ATA_PIO_SHT(DRV_NAME),
21689 };
21690
21691-static struct ata_port_operations ns87410_port_ops = {
21692+static const struct ata_port_operations ns87410_port_ops = {
21693 .inherits = &ata_sff_port_ops,
21694 .qc_issue = ns87410_qc_issue,
21695 .cable_detect = ata_cable_40wire,
16454cff
MT
21696diff -urNp linux-2.6.38.1/drivers/ata/pata_ns87415.c linux-2.6.38.1/drivers/ata/pata_ns87415.c
21697--- linux-2.6.38.1/drivers/ata/pata_ns87415.c 2011-03-14 21:20:32.000000000 -0400
21698+++ linux-2.6.38.1/drivers/ata/pata_ns87415.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21699@@ -299,7 +299,7 @@ static u8 ns87560_bmdma_status(struct at
21700 }
21701 #endif /* 87560 SuperIO Support */
21702
21703-static struct ata_port_operations ns87415_pata_ops = {
21704+static const struct ata_port_operations ns87415_pata_ops = {
21705 .inherits = &ata_bmdma_port_ops,
21706
21707 .check_atapi_dma = ns87415_check_atapi_dma,
21708@@ -313,7 +313,7 @@ static struct ata_port_operations ns8741
21709 };
21710
21711 #if defined(CONFIG_SUPERIO)
21712-static struct ata_port_operations ns87560_pata_ops = {
21713+static const struct ata_port_operations ns87560_pata_ops = {
21714 .inherits = &ns87415_pata_ops,
21715 .sff_tf_read = ns87560_tf_read,
21716 .sff_check_status = ns87560_check_status,
16454cff
MT
21717diff -urNp linux-2.6.38.1/drivers/ata/pata_octeon_cf.c linux-2.6.38.1/drivers/ata/pata_octeon_cf.c
21718--- linux-2.6.38.1/drivers/ata/pata_octeon_cf.c 2011-03-14 21:20:32.000000000 -0400
21719+++ linux-2.6.38.1/drivers/ata/pata_octeon_cf.c 2011-03-21 18:31:35.000000000 -0400
21720@@ -780,7 +780,7 @@ static unsigned int octeon_cf_qc_issue(s
ae4e228f
MT
21721 return 0;
21722 }
21723
16454cff
MT
21724-static struct ata_port_operations octeon_cf_ops = {
21725+static struct ata_port_operations octeon_cf_ops = { /* cannot be const */
ae4e228f
MT
21726 .inherits = &ata_sff_port_ops,
21727 .check_atapi_dma = octeon_cf_check_atapi_dma,
16454cff
MT
21728 .qc_prep = ata_noop_qc_prep,
21729diff -urNp linux-2.6.38.1/drivers/ata/pata_oldpiix.c linux-2.6.38.1/drivers/ata/pata_oldpiix.c
21730--- linux-2.6.38.1/drivers/ata/pata_oldpiix.c 2011-03-14 21:20:32.000000000 -0400
21731+++ linux-2.6.38.1/drivers/ata/pata_oldpiix.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21732@@ -208,7 +208,7 @@ static struct scsi_host_template oldpiix
21733 ATA_BMDMA_SHT(DRV_NAME),
21734 };
21735
21736-static struct ata_port_operations oldpiix_pata_ops = {
21737+static const struct ata_port_operations oldpiix_pata_ops = {
21738 .inherits = &ata_bmdma_port_ops,
21739 .qc_issue = oldpiix_qc_issue,
21740 .cable_detect = ata_cable_40wire,
16454cff
MT
21741diff -urNp linux-2.6.38.1/drivers/ata/pata_opti.c linux-2.6.38.1/drivers/ata/pata_opti.c
21742--- linux-2.6.38.1/drivers/ata/pata_opti.c 2011-03-14 21:20:32.000000000 -0400
21743+++ linux-2.6.38.1/drivers/ata/pata_opti.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21744@@ -152,7 +152,7 @@ static struct scsi_host_template opti_sh
21745 ATA_PIO_SHT(DRV_NAME),
21746 };
21747
21748-static struct ata_port_operations opti_port_ops = {
21749+static const struct ata_port_operations opti_port_ops = {
21750 .inherits = &ata_sff_port_ops,
21751 .cable_detect = ata_cable_40wire,
21752 .set_piomode = opti_set_piomode,
16454cff
MT
21753diff -urNp linux-2.6.38.1/drivers/ata/pata_optidma.c linux-2.6.38.1/drivers/ata/pata_optidma.c
21754--- linux-2.6.38.1/drivers/ata/pata_optidma.c 2011-03-14 21:20:32.000000000 -0400
21755+++ linux-2.6.38.1/drivers/ata/pata_optidma.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21756@@ -337,7 +337,7 @@ static struct scsi_host_template optidma
21757 ATA_BMDMA_SHT(DRV_NAME),
21758 };
21759
21760-static struct ata_port_operations optidma_port_ops = {
21761+static const struct ata_port_operations optidma_port_ops = {
21762 .inherits = &ata_bmdma_port_ops,
21763 .cable_detect = ata_cable_40wire,
21764 .set_piomode = optidma_set_pio_mode,
21765@@ -346,7 +346,7 @@ static struct ata_port_operations optidm
21766 .prereset = optidma_pre_reset,
21767 };
21768
21769-static struct ata_port_operations optiplus_port_ops = {
21770+static const struct ata_port_operations optiplus_port_ops = {
21771 .inherits = &optidma_port_ops,
21772 .set_piomode = optiplus_set_pio_mode,
21773 .set_dmamode = optiplus_set_dma_mode,
16454cff
MT
21774diff -urNp linux-2.6.38.1/drivers/ata/pata_palmld.c linux-2.6.38.1/drivers/ata/pata_palmld.c
21775--- linux-2.6.38.1/drivers/ata/pata_palmld.c 2011-03-14 21:20:32.000000000 -0400
21776+++ linux-2.6.38.1/drivers/ata/pata_palmld.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21777@@ -37,7 +37,7 @@ static struct scsi_host_template palmld_
21778 ATA_PIO_SHT(DRV_NAME),
21779 };
21780
21781-static struct ata_port_operations palmld_port_ops = {
21782+static const struct ata_port_operations palmld_port_ops = {
21783 .inherits = &ata_sff_port_ops,
21784 .sff_data_xfer = ata_sff_data_xfer_noirq,
21785 .cable_detect = ata_cable_40wire,
16454cff
MT
21786diff -urNp linux-2.6.38.1/drivers/ata/pata_pcmcia.c linux-2.6.38.1/drivers/ata/pata_pcmcia.c
21787--- linux-2.6.38.1/drivers/ata/pata_pcmcia.c 2011-03-14 21:20:32.000000000 -0400
21788+++ linux-2.6.38.1/drivers/ata/pata_pcmcia.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 21789@@ -151,14 +151,14 @@ static struct scsi_host_template pcmcia_
ae4e228f
MT
21790 ATA_PIO_SHT(DRV_NAME),
21791 };
21792
21793-static struct ata_port_operations pcmcia_port_ops = {
21794+static const struct ata_port_operations pcmcia_port_ops = {
21795 .inherits = &ata_sff_port_ops,
21796 .sff_data_xfer = ata_sff_data_xfer_noirq,
21797 .cable_detect = ata_cable_40wire,
21798 .set_mode = pcmcia_set_mode,
21799 };
21800
21801-static struct ata_port_operations pcmcia_8bit_port_ops = {
21802+static const struct ata_port_operations pcmcia_8bit_port_ops = {
21803 .inherits = &ata_sff_port_ops,
21804 .sff_data_xfer = ata_data_xfer_8bit,
21805 .cable_detect = ata_cable_40wire,
bc901d79 21806@@ -205,7 +205,7 @@ static int pcmcia_init_one(struct pcmcia
ae4e228f
MT
21807 unsigned long io_base, ctl_base;
21808 void __iomem *io_addr, *ctl_addr;
21809 int n_ports = 1;
21810- struct ata_port_operations *ops = &pcmcia_port_ops;
21811+ const struct ata_port_operations *ops = &pcmcia_port_ops;
21812
57199397 21813 /* Set up attributes in order to probe card and get resources */
bc901d79 21814 pdev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
16454cff
MT
21815diff -urNp linux-2.6.38.1/drivers/ata/pata_pdc2027x.c linux-2.6.38.1/drivers/ata/pata_pdc2027x.c
21816--- linux-2.6.38.1/drivers/ata/pata_pdc2027x.c 2011-03-14 21:20:32.000000000 -0400
21817+++ linux-2.6.38.1/drivers/ata/pata_pdc2027x.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21818@@ -132,14 +132,14 @@ static struct scsi_host_template pdc2027
21819 ATA_BMDMA_SHT(DRV_NAME),
21820 };
21821
21822-static struct ata_port_operations pdc2027x_pata100_ops = {
21823+static const struct ata_port_operations pdc2027x_pata100_ops = {
21824 .inherits = &ata_bmdma_port_ops,
21825 .check_atapi_dma = pdc2027x_check_atapi_dma,
21826 .cable_detect = pdc2027x_cable_detect,
21827 .prereset = pdc2027x_prereset,
21828 };
21829
21830-static struct ata_port_operations pdc2027x_pata133_ops = {
21831+static const struct ata_port_operations pdc2027x_pata133_ops = {
21832 .inherits = &pdc2027x_pata100_ops,
21833 .mode_filter = pdc2027x_mode_filter,
21834 .set_piomode = pdc2027x_set_piomode,
16454cff
MT
21835diff -urNp linux-2.6.38.1/drivers/ata/pata_pdc202xx_old.c linux-2.6.38.1/drivers/ata/pata_pdc202xx_old.c
21836--- linux-2.6.38.1/drivers/ata/pata_pdc202xx_old.c 2011-03-14 21:20:32.000000000 -0400
21837+++ linux-2.6.38.1/drivers/ata/pata_pdc202xx_old.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 21838@@ -295,7 +295,7 @@ static struct scsi_host_template pdc202x
ae4e228f
MT
21839 ATA_BMDMA_SHT(DRV_NAME),
21840 };
21841
21842-static struct ata_port_operations pdc2024x_port_ops = {
21843+static const struct ata_port_operations pdc2024x_port_ops = {
21844 .inherits = &ata_bmdma_port_ops,
21845
21846 .cable_detect = ata_cable_40wire,
bc901d79
MT
21847@@ -306,7 +306,7 @@ static struct ata_port_operations pdc202
21848 .sff_irq_check = pdc202xx_irq_check,
ae4e228f
MT
21849 };
21850
21851-static struct ata_port_operations pdc2026x_port_ops = {
21852+static const struct ata_port_operations pdc2026x_port_ops = {
21853 .inherits = &pdc2024x_port_ops,
21854
21855 .check_atapi_dma = pdc2026x_check_atapi_dma,
16454cff
MT
21856diff -urNp linux-2.6.38.1/drivers/ata/pata_piccolo.c linux-2.6.38.1/drivers/ata/pata_piccolo.c
21857--- linux-2.6.38.1/drivers/ata/pata_piccolo.c 2011-03-14 21:20:32.000000000 -0400
21858+++ linux-2.6.38.1/drivers/ata/pata_piccolo.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21859@@ -67,7 +67,7 @@ static struct scsi_host_template tosh_sh
21860 ATA_BMDMA_SHT(DRV_NAME),
21861 };
21862
21863-static struct ata_port_operations tosh_port_ops = {
21864+static const struct ata_port_operations tosh_port_ops = {
21865 .inherits = &ata_bmdma_port_ops,
21866 .cable_detect = ata_cable_unknown,
21867 .set_piomode = tosh_set_piomode,
16454cff
MT
21868diff -urNp linux-2.6.38.1/drivers/ata/pata_platform.c linux-2.6.38.1/drivers/ata/pata_platform.c
21869--- linux-2.6.38.1/drivers/ata/pata_platform.c 2011-03-14 21:20:32.000000000 -0400
21870+++ linux-2.6.38.1/drivers/ata/pata_platform.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21871@@ -48,7 +48,7 @@ static struct scsi_host_template pata_pl
21872 ATA_PIO_SHT(DRV_NAME),
21873 };
21874
21875-static struct ata_port_operations pata_platform_port_ops = {
21876+static const struct ata_port_operations pata_platform_port_ops = {
21877 .inherits = &ata_sff_port_ops,
21878 .sff_data_xfer = ata_sff_data_xfer_noirq,
21879 .cable_detect = ata_cable_unknown,
16454cff
MT
21880diff -urNp linux-2.6.38.1/drivers/ata/pata_pxa.c linux-2.6.38.1/drivers/ata/pata_pxa.c
21881--- linux-2.6.38.1/drivers/ata/pata_pxa.c 2011-03-14 21:20:32.000000000 -0400
21882+++ linux-2.6.38.1/drivers/ata/pata_pxa.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
21883@@ -198,7 +198,7 @@ static struct scsi_host_template pxa_ata
21884 ATA_BMDMA_SHT(DRV_NAME),
21885 };
21886
21887-static struct ata_port_operations pxa_ata_port_ops = {
21888+static const struct ata_port_operations pxa_ata_port_ops = {
21889 .inherits = &ata_bmdma_port_ops,
21890 .cable_detect = ata_cable_40wire,
21891
16454cff
MT
21892diff -urNp linux-2.6.38.1/drivers/ata/pata_qdi.c linux-2.6.38.1/drivers/ata/pata_qdi.c
21893--- linux-2.6.38.1/drivers/ata/pata_qdi.c 2011-03-14 21:20:32.000000000 -0400
21894+++ linux-2.6.38.1/drivers/ata/pata_qdi.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21895@@ -157,7 +157,7 @@ static struct scsi_host_template qdi_sht
21896 ATA_PIO_SHT(DRV_NAME),
21897 };
21898
21899-static struct ata_port_operations qdi6500_port_ops = {
21900+static const struct ata_port_operations qdi6500_port_ops = {
21901 .inherits = &ata_sff_port_ops,
21902 .qc_issue = qdi_qc_issue,
21903 .sff_data_xfer = qdi_data_xfer,
21904@@ -165,7 +165,7 @@ static struct ata_port_operations qdi650
21905 .set_piomode = qdi6500_set_piomode,
21906 };
21907
21908-static struct ata_port_operations qdi6580_port_ops = {
21909+static const struct ata_port_operations qdi6580_port_ops = {
21910 .inherits = &qdi6500_port_ops,
21911 .set_piomode = qdi6580_set_piomode,
21912 };
16454cff
MT
21913diff -urNp linux-2.6.38.1/drivers/ata/pata_radisys.c linux-2.6.38.1/drivers/ata/pata_radisys.c
21914--- linux-2.6.38.1/drivers/ata/pata_radisys.c 2011-03-14 21:20:32.000000000 -0400
21915+++ linux-2.6.38.1/drivers/ata/pata_radisys.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21916@@ -187,7 +187,7 @@ static struct scsi_host_template radisys
21917 ATA_BMDMA_SHT(DRV_NAME),
21918 };
21919
21920-static struct ata_port_operations radisys_pata_ops = {
21921+static const struct ata_port_operations radisys_pata_ops = {
21922 .inherits = &ata_bmdma_port_ops,
21923 .qc_issue = radisys_qc_issue,
21924 .cable_detect = ata_cable_unknown,
16454cff
MT
21925diff -urNp linux-2.6.38.1/drivers/ata/pata_rb532_cf.c linux-2.6.38.1/drivers/ata/pata_rb532_cf.c
21926--- linux-2.6.38.1/drivers/ata/pata_rb532_cf.c 2011-03-14 21:20:32.000000000 -0400
21927+++ linux-2.6.38.1/drivers/ata/pata_rb532_cf.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21928@@ -69,7 +69,7 @@ static irqreturn_t rb532_pata_irq_handle
ae4e228f
MT
21929 return IRQ_HANDLED;
21930 }
21931
21932-static struct ata_port_operations rb532_pata_port_ops = {
21933+static const struct ata_port_operations rb532_pata_port_ops = {
21934 .inherits = &ata_sff_port_ops,
21935 .sff_data_xfer = ata_sff_data_xfer32,
21936 };
16454cff
MT
21937diff -urNp linux-2.6.38.1/drivers/ata/pata_rdc.c linux-2.6.38.1/drivers/ata/pata_rdc.c
21938--- linux-2.6.38.1/drivers/ata/pata_rdc.c 2011-03-14 21:20:32.000000000 -0400
21939+++ linux-2.6.38.1/drivers/ata/pata_rdc.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 21940@@ -273,7 +273,7 @@ static void rdc_set_dmamode(struct ata_p
ae4e228f
MT
21941 pci_write_config_byte(dev, 0x48, udma_enable);
21942 }
21943
21944-static struct ata_port_operations rdc_pata_ops = {
21945+static const struct ata_port_operations rdc_pata_ops = {
21946 .inherits = &ata_bmdma32_port_ops,
21947 .cable_detect = rdc_pata_cable_detect,
21948 .set_piomode = rdc_set_piomode,
16454cff
MT
21949diff -urNp linux-2.6.38.1/drivers/ata/pata_rz1000.c linux-2.6.38.1/drivers/ata/pata_rz1000.c
21950--- linux-2.6.38.1/drivers/ata/pata_rz1000.c 2011-03-14 21:20:32.000000000 -0400
21951+++ linux-2.6.38.1/drivers/ata/pata_rz1000.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21952@@ -54,7 +54,7 @@ static struct scsi_host_template rz1000_
21953 ATA_PIO_SHT(DRV_NAME),
21954 };
21955
21956-static struct ata_port_operations rz1000_port_ops = {
21957+static const struct ata_port_operations rz1000_port_ops = {
21958 .inherits = &ata_sff_port_ops,
21959 .cable_detect = ata_cable_40wire,
21960 .set_mode = rz1000_set_mode,
16454cff
MT
21961diff -urNp linux-2.6.38.1/drivers/ata/pata_samsung_cf.c linux-2.6.38.1/drivers/ata/pata_samsung_cf.c
21962--- linux-2.6.38.1/drivers/ata/pata_samsung_cf.c 2011-03-14 21:20:32.000000000 -0400
21963+++ linux-2.6.38.1/drivers/ata/pata_samsung_cf.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
21964@@ -399,7 +399,7 @@ static struct scsi_host_template pata_s3
21965 ATA_PIO_SHT(DRV_NAME),
21966 };
21967
21968-static struct ata_port_operations pata_s3c_port_ops = {
21969+static const struct ata_port_operations pata_s3c_port_ops = {
21970 .inherits = &ata_sff_port_ops,
21971 .sff_check_status = pata_s3c_check_status,
21972 .sff_check_altstatus = pata_s3c_check_altstatus,
21973@@ -413,7 +413,7 @@ static struct ata_port_operations pata_s
21974 .set_piomode = pata_s3c_set_piomode,
21975 };
21976
21977-static struct ata_port_operations pata_s5p_port_ops = {
21978+static const struct ata_port_operations pata_s5p_port_ops = {
21979 .inherits = &ata_sff_port_ops,
21980 .set_piomode = pata_s3c_set_piomode,
21981 };
16454cff
MT
21982diff -urNp linux-2.6.38.1/drivers/ata/pata_sc1200.c linux-2.6.38.1/drivers/ata/pata_sc1200.c
21983--- linux-2.6.38.1/drivers/ata/pata_sc1200.c 2011-03-14 21:20:32.000000000 -0400
21984+++ linux-2.6.38.1/drivers/ata/pata_sc1200.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
21985@@ -207,7 +207,7 @@ static struct scsi_host_template sc1200_
21986 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
21987 };
21988
21989-static struct ata_port_operations sc1200_port_ops = {
21990+static const struct ata_port_operations sc1200_port_ops = {
21991 .inherits = &ata_bmdma_port_ops,
57199397 21992 .qc_prep = ata_bmdma_dumb_qc_prep,
ae4e228f 21993 .qc_issue = sc1200_qc_issue,
16454cff
MT
21994diff -urNp linux-2.6.38.1/drivers/ata/pata_scc.c linux-2.6.38.1/drivers/ata/pata_scc.c
21995--- linux-2.6.38.1/drivers/ata/pata_scc.c 2011-03-14 21:20:32.000000000 -0400
21996+++ linux-2.6.38.1/drivers/ata/pata_scc.c 2011-03-21 18:31:35.000000000 -0400
6892158b 21997@@ -926,7 +926,7 @@ static struct scsi_host_template scc_sht
ae4e228f
MT
21998 ATA_BMDMA_SHT(DRV_NAME),
21999 };
22000
22001-static struct ata_port_operations scc_pata_ops = {
22002+static const struct ata_port_operations scc_pata_ops = {
22003 .inherits = &ata_bmdma_port_ops,
22004
22005 .set_piomode = scc_set_piomode,
16454cff
MT
22006diff -urNp linux-2.6.38.1/drivers/ata/pata_sch.c linux-2.6.38.1/drivers/ata/pata_sch.c
22007--- linux-2.6.38.1/drivers/ata/pata_sch.c 2011-03-14 21:20:32.000000000 -0400
22008+++ linux-2.6.38.1/drivers/ata/pata_sch.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
22009@@ -75,7 +75,7 @@ static struct scsi_host_template sch_sht
22010 ATA_BMDMA_SHT(DRV_NAME),
22011 };
22012
22013-static struct ata_port_operations sch_pata_ops = {
22014+static const struct ata_port_operations sch_pata_ops = {
22015 .inherits = &ata_bmdma_port_ops,
22016 .cable_detect = ata_cable_unknown,
22017 .set_piomode = sch_set_piomode,
16454cff
MT
22018diff -urNp linux-2.6.38.1/drivers/ata/pata_serverworks.c linux-2.6.38.1/drivers/ata/pata_serverworks.c
22019--- linux-2.6.38.1/drivers/ata/pata_serverworks.c 2011-03-14 21:20:32.000000000 -0400
22020+++ linux-2.6.38.1/drivers/ata/pata_serverworks.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22021@@ -300,7 +300,7 @@ static struct scsi_host_template serverw
ae4e228f
MT
22022 ATA_BMDMA_SHT(DRV_NAME),
22023 };
22024
22025-static struct ata_port_operations serverworks_osb4_port_ops = {
22026+static const struct ata_port_operations serverworks_osb4_port_ops = {
22027 .inherits = &ata_bmdma_port_ops,
22028 .cable_detect = serverworks_cable_detect,
22029 .mode_filter = serverworks_osb4_filter,
df50ba0c 22030@@ -308,7 +308,7 @@ static struct ata_port_operations server
ae4e228f
MT
22031 .set_dmamode = serverworks_set_dmamode,
22032 };
22033
22034-static struct ata_port_operations serverworks_csb_port_ops = {
22035+static const struct ata_port_operations serverworks_csb_port_ops = {
22036 .inherits = &serverworks_osb4_port_ops,
22037 .mode_filter = serverworks_csb_filter,
22038 };
16454cff
MT
22039diff -urNp linux-2.6.38.1/drivers/ata/pata_sil680.c linux-2.6.38.1/drivers/ata/pata_sil680.c
22040--- linux-2.6.38.1/drivers/ata/pata_sil680.c 2011-03-14 21:20:32.000000000 -0400
22041+++ linux-2.6.38.1/drivers/ata/pata_sil680.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 22042@@ -225,8 +225,7 @@ static struct scsi_host_template sil680_
ae4e228f
MT
22043 ATA_BMDMA_SHT(DRV_NAME),
22044 };
22045
57199397 22046-
ae4e228f
MT
22047-static struct ata_port_operations sil680_port_ops = {
22048+static const struct ata_port_operations sil680_port_ops = {
57199397
MT
22049 .inherits = &ata_bmdma32_port_ops,
22050 .sff_exec_command = sil680_sff_exec_command,
bc901d79 22051 .sff_irq_check = sil680_sff_irq_check,
16454cff
MT
22052diff -urNp linux-2.6.38.1/drivers/ata/pata_sis.c linux-2.6.38.1/drivers/ata/pata_sis.c
22053--- linux-2.6.38.1/drivers/ata/pata_sis.c 2011-03-14 21:20:32.000000000 -0400
22054+++ linux-2.6.38.1/drivers/ata/pata_sis.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
22055@@ -503,47 +503,47 @@ static struct scsi_host_template sis_sht
22056 ATA_BMDMA_SHT(DRV_NAME),
22057 };
22058
22059-static struct ata_port_operations sis_133_for_sata_ops = {
22060+static const struct ata_port_operations sis_133_for_sata_ops = {
22061 .inherits = &ata_bmdma_port_ops,
22062 .set_piomode = sis_133_set_piomode,
22063 .set_dmamode = sis_133_set_dmamode,
22064 .cable_detect = sis_133_cable_detect,
22065 };
22066
22067-static struct ata_port_operations sis_base_ops = {
22068+static const struct ata_port_operations sis_base_ops = {
22069 .inherits = &ata_bmdma_port_ops,
22070 .prereset = sis_pre_reset,
22071 };
22072
22073-static struct ata_port_operations sis_133_ops = {
22074+static const struct ata_port_operations sis_133_ops = {
22075 .inherits = &sis_base_ops,
22076 .set_piomode = sis_133_set_piomode,
22077 .set_dmamode = sis_133_set_dmamode,
22078 .cable_detect = sis_133_cable_detect,
22079 };
22080
22081-static struct ata_port_operations sis_133_early_ops = {
22082+static const struct ata_port_operations sis_133_early_ops = {
22083 .inherits = &sis_base_ops,
22084 .set_piomode = sis_100_set_piomode,
22085 .set_dmamode = sis_133_early_set_dmamode,
22086 .cable_detect = sis_66_cable_detect,
22087 };
22088
22089-static struct ata_port_operations sis_100_ops = {
22090+static const struct ata_port_operations sis_100_ops = {
22091 .inherits = &sis_base_ops,
22092 .set_piomode = sis_100_set_piomode,
22093 .set_dmamode = sis_100_set_dmamode,
22094 .cable_detect = sis_66_cable_detect,
22095 };
22096
22097-static struct ata_port_operations sis_66_ops = {
22098+static const struct ata_port_operations sis_66_ops = {
22099 .inherits = &sis_base_ops,
22100 .set_piomode = sis_old_set_piomode,
22101 .set_dmamode = sis_66_set_dmamode,
22102 .cable_detect = sis_66_cable_detect,
22103 };
22104
22105-static struct ata_port_operations sis_old_ops = {
22106+static const struct ata_port_operations sis_old_ops = {
22107 .inherits = &sis_base_ops,
22108 .set_piomode = sis_old_set_piomode,
22109 .set_dmamode = sis_old_set_dmamode,
16454cff
MT
22110diff -urNp linux-2.6.38.1/drivers/ata/pata_sl82c105.c linux-2.6.38.1/drivers/ata/pata_sl82c105.c
22111--- linux-2.6.38.1/drivers/ata/pata_sl82c105.c 2011-03-14 21:20:32.000000000 -0400
22112+++ linux-2.6.38.1/drivers/ata/pata_sl82c105.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 22113@@ -241,7 +241,7 @@ static struct scsi_host_template sl82c10
ae4e228f
MT
22114 ATA_BMDMA_SHT(DRV_NAME),
22115 };
22116
22117-static struct ata_port_operations sl82c105_port_ops = {
22118+static const struct ata_port_operations sl82c105_port_ops = {
22119 .inherits = &ata_bmdma_port_ops,
22120 .qc_defer = sl82c105_qc_defer,
22121 .bmdma_start = sl82c105_bmdma_start,
16454cff
MT
22122diff -urNp linux-2.6.38.1/drivers/ata/pata_triflex.c linux-2.6.38.1/drivers/ata/pata_triflex.c
22123--- linux-2.6.38.1/drivers/ata/pata_triflex.c 2011-03-14 21:20:32.000000000 -0400
22124+++ linux-2.6.38.1/drivers/ata/pata_triflex.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
22125@@ -178,7 +178,7 @@ static struct scsi_host_template triflex
22126 ATA_BMDMA_SHT(DRV_NAME),
22127 };
22128
22129-static struct ata_port_operations triflex_port_ops = {
22130+static const struct ata_port_operations triflex_port_ops = {
22131 .inherits = &ata_bmdma_port_ops,
22132 .bmdma_start = triflex_bmdma_start,
22133 .bmdma_stop = triflex_bmdma_stop,
16454cff
MT
22134diff -urNp linux-2.6.38.1/drivers/ata/pata_via.c linux-2.6.38.1/drivers/ata/pata_via.c
22135--- linux-2.6.38.1/drivers/ata/pata_via.c 2011-03-14 21:20:32.000000000 -0400
22136+++ linux-2.6.38.1/drivers/ata/pata_via.c 2011-03-21 18:31:35.000000000 -0400
6892158b 22137@@ -441,7 +441,7 @@ static struct scsi_host_template via_sht
ae4e228f
MT
22138 ATA_BMDMA_SHT(DRV_NAME),
22139 };
22140
22141-static struct ata_port_operations via_port_ops = {
22142+static const struct ata_port_operations via_port_ops = {
22143 .inherits = &ata_bmdma_port_ops,
22144 .cable_detect = via_cable_detect,
22145 .set_piomode = via_set_piomode,
6892158b 22146@@ -452,7 +452,7 @@ static struct ata_port_operations via_po
ae4e228f
MT
22147 .mode_filter = via_mode_filter,
22148 };
22149
22150-static struct ata_port_operations via_port_ops_noirq = {
22151+static const struct ata_port_operations via_port_ops_noirq = {
22152 .inherits = &via_port_ops,
22153 .sff_data_xfer = ata_sff_data_xfer_noirq,
22154 };
16454cff
MT
22155diff -urNp linux-2.6.38.1/drivers/ata/pdc_adma.c linux-2.6.38.1/drivers/ata/pdc_adma.c
22156--- linux-2.6.38.1/drivers/ata/pdc_adma.c 2011-03-14 21:20:32.000000000 -0400
22157+++ linux-2.6.38.1/drivers/ata/pdc_adma.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22158@@ -146,7 +146,7 @@ static struct scsi_host_template adma_at
ae4e228f
MT
22159 .dma_boundary = ADMA_DMA_BOUNDARY,
22160 };
22161
22162-static struct ata_port_operations adma_ata_ops = {
22163+static const struct ata_port_operations adma_ata_ops = {
22164 .inherits = &ata_sff_port_ops,
22165
22166 .lost_interrupt = ATA_OP_NULL,
16454cff
MT
22167diff -urNp linux-2.6.38.1/drivers/ata/sata_dwc_460ex.c linux-2.6.38.1/drivers/ata/sata_dwc_460ex.c
22168--- linux-2.6.38.1/drivers/ata/sata_dwc_460ex.c 2011-03-14 21:20:32.000000000 -0400
22169+++ linux-2.6.38.1/drivers/ata/sata_dwc_460ex.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
22170@@ -1560,7 +1560,7 @@ static struct scsi_host_template sata_dw
22171 .dma_boundary = ATA_DMA_BOUNDARY,
22172 };
22173
22174-static struct ata_port_operations sata_dwc_ops = {
22175+static const struct ata_port_operations sata_dwc_ops = {
22176 .inherits = &ata_sff_port_ops,
22177
22178 .error_handler = sata_dwc_error_handler,
16454cff
MT
22179diff -urNp linux-2.6.38.1/drivers/ata/sata_fsl.c linux-2.6.38.1/drivers/ata/sata_fsl.c
22180--- linux-2.6.38.1/drivers/ata/sata_fsl.c 2011-03-14 21:20:32.000000000 -0400
22181+++ linux-2.6.38.1/drivers/ata/sata_fsl.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 22182@@ -1258,7 +1258,7 @@ static struct scsi_host_template sata_fs
ae4e228f
MT
22183 .dma_boundary = ATA_DMA_BOUNDARY,
22184 };
22185
22186-static struct ata_port_operations sata_fsl_ops = {
22187+static const struct ata_port_operations sata_fsl_ops = {
22188 .inherits = &sata_pmp_port_ops,
22189
22190 .qc_defer = ata_std_qc_defer,
16454cff
MT
22191diff -urNp linux-2.6.38.1/drivers/ata/sata_inic162x.c linux-2.6.38.1/drivers/ata/sata_inic162x.c
22192--- linux-2.6.38.1/drivers/ata/sata_inic162x.c 2011-03-14 21:20:32.000000000 -0400
22193+++ linux-2.6.38.1/drivers/ata/sata_inic162x.c 2011-03-21 18:31:35.000000000 -0400
57199397 22194@@ -705,7 +705,7 @@ static int inic_port_start(struct ata_po
ae4e228f
MT
22195 return 0;
22196 }
22197
22198-static struct ata_port_operations inic_port_ops = {
22199+static const struct ata_port_operations inic_port_ops = {
22200 .inherits = &sata_port_ops,
22201
22202 .check_atapi_dma = inic_check_atapi_dma,
16454cff
MT
22203diff -urNp linux-2.6.38.1/drivers/ata/sata_mv.c linux-2.6.38.1/drivers/ata/sata_mv.c
22204--- linux-2.6.38.1/drivers/ata/sata_mv.c 2011-03-14 21:20:32.000000000 -0400
22205+++ linux-2.6.38.1/drivers/ata/sata_mv.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22206@@ -663,7 +663,7 @@ static struct scsi_host_template mv6_sht
ae4e228f
MT
22207 .dma_boundary = MV_DMA_BOUNDARY,
22208 };
22209
22210-static struct ata_port_operations mv5_ops = {
22211+static const struct ata_port_operations mv5_ops = {
22212 .inherits = &ata_sff_port_ops,
22213
22214 .lost_interrupt = ATA_OP_NULL,
57199397 22215@@ -683,7 +683,7 @@ static struct ata_port_operations mv5_op
ae4e228f
MT
22216 .port_stop = mv_port_stop,
22217 };
22218
22219-static struct ata_port_operations mv6_ops = {
22220+static const struct ata_port_operations mv6_ops = {
57199397
MT
22221 .inherits = &ata_bmdma_port_ops,
22222
22223 .lost_interrupt = ATA_OP_NULL,
22224@@ -717,7 +717,7 @@ static struct ata_port_operations mv6_op
22225 .port_stop = mv_port_stop,
ae4e228f
MT
22226 };
22227
22228-static struct ata_port_operations mv_iie_ops = {
22229+static const struct ata_port_operations mv_iie_ops = {
22230 .inherits = &mv6_ops,
22231 .dev_config = ATA_OP_NULL,
22232 .qc_prep = mv_qc_prep_iie,
16454cff
MT
22233diff -urNp linux-2.6.38.1/drivers/ata/sata_nv.c linux-2.6.38.1/drivers/ata/sata_nv.c
22234--- linux-2.6.38.1/drivers/ata/sata_nv.c 2011-03-14 21:20:32.000000000 -0400
22235+++ linux-2.6.38.1/drivers/ata/sata_nv.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22236@@ -465,7 +465,7 @@ static struct scsi_host_template nv_swnc
ae4e228f
MT
22237 * cases. Define nv_hardreset() which only kicks in for post-boot
22238 * probing and use it for all variants.
22239 */
22240-static struct ata_port_operations nv_generic_ops = {
22241+static const struct ata_port_operations nv_generic_ops = {
22242 .inherits = &ata_bmdma_port_ops,
22243 .lost_interrupt = ATA_OP_NULL,
22244 .scr_read = nv_scr_read,
df50ba0c 22245@@ -473,20 +473,20 @@ static struct ata_port_operations nv_gen
ae4e228f
MT
22246 .hardreset = nv_hardreset,
22247 };
22248
22249-static struct ata_port_operations nv_nf2_ops = {
22250+static const struct ata_port_operations nv_nf2_ops = {
22251 .inherits = &nv_generic_ops,
22252 .freeze = nv_nf2_freeze,
22253 .thaw = nv_nf2_thaw,
22254 };
22255
22256-static struct ata_port_operations nv_ck804_ops = {
22257+static const struct ata_port_operations nv_ck804_ops = {
22258 .inherits = &nv_generic_ops,
22259 .freeze = nv_ck804_freeze,
22260 .thaw = nv_ck804_thaw,
22261 .host_stop = nv_ck804_host_stop,
22262 };
22263
22264-static struct ata_port_operations nv_adma_ops = {
22265+static const struct ata_port_operations nv_adma_ops = {
22266 .inherits = &nv_ck804_ops,
22267
22268 .check_atapi_dma = nv_adma_check_atapi_dma,
df50ba0c 22269@@ -510,7 +510,7 @@ static struct ata_port_operations nv_adm
ae4e228f
MT
22270 .host_stop = nv_adma_host_stop,
22271 };
22272
22273-static struct ata_port_operations nv_swncq_ops = {
22274+static const struct ata_port_operations nv_swncq_ops = {
22275 .inherits = &nv_generic_ops,
22276
22277 .qc_defer = ata_std_qc_defer,
16454cff
MT
22278diff -urNp linux-2.6.38.1/drivers/ata/sata_promise.c linux-2.6.38.1/drivers/ata/sata_promise.c
22279--- linux-2.6.38.1/drivers/ata/sata_promise.c 2011-03-14 21:20:32.000000000 -0400
22280+++ linux-2.6.38.1/drivers/ata/sata_promise.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22281@@ -196,7 +196,7 @@ static const struct ata_port_operations
ae4e228f
MT
22282 .error_handler = pdc_error_handler,
22283 };
22284
22285-static struct ata_port_operations pdc_sata_ops = {
22286+static const struct ata_port_operations pdc_sata_ops = {
22287 .inherits = &pdc_common_ops,
22288 .cable_detect = pdc_sata_cable_detect,
22289 .freeze = pdc_sata_freeze,
df50ba0c 22290@@ -209,14 +209,14 @@ static struct ata_port_operations pdc_sa
ae4e228f
MT
22291
22292 /* First-generation chips need a more restrictive ->check_atapi_dma op,
22293 and ->freeze/thaw that ignore the hotplug controls. */
22294-static struct ata_port_operations pdc_old_sata_ops = {
22295+static const struct ata_port_operations pdc_old_sata_ops = {
22296 .inherits = &pdc_sata_ops,
22297 .freeze = pdc_freeze,
22298 .thaw = pdc_thaw,
22299 .check_atapi_dma = pdc_old_sata_check_atapi_dma,
22300 };
22301
22302-static struct ata_port_operations pdc_pata_ops = {
22303+static const struct ata_port_operations pdc_pata_ops = {
22304 .inherits = &pdc_common_ops,
22305 .cable_detect = pdc_pata_cable_detect,
22306 .freeze = pdc_freeze,
16454cff
MT
22307diff -urNp linux-2.6.38.1/drivers/ata/sata_qstor.c linux-2.6.38.1/drivers/ata/sata_qstor.c
22308--- linux-2.6.38.1/drivers/ata/sata_qstor.c 2011-03-14 21:20:32.000000000 -0400
22309+++ linux-2.6.38.1/drivers/ata/sata_qstor.c 2011-03-21 18:31:35.000000000 -0400
57199397 22310@@ -131,7 +131,7 @@ static struct scsi_host_template qs_ata_
ae4e228f
MT
22311 .dma_boundary = QS_DMA_BOUNDARY,
22312 };
22313
22314-static struct ata_port_operations qs_ata_ops = {
22315+static const struct ata_port_operations qs_ata_ops = {
22316 .inherits = &ata_sff_port_ops,
22317
22318 .check_atapi_dma = qs_check_atapi_dma,
16454cff
MT
22319diff -urNp linux-2.6.38.1/drivers/ata/sata_sil24.c linux-2.6.38.1/drivers/ata/sata_sil24.c
22320--- linux-2.6.38.1/drivers/ata/sata_sil24.c 2011-03-14 21:20:32.000000000 -0400
22321+++ linux-2.6.38.1/drivers/ata/sata_sil24.c 2011-03-21 18:31:35.000000000 -0400
efbe55a5
MT
22322@@ -389,7 +389,7 @@ static struct scsi_host_template sil24_s
22323 .dma_boundary = ATA_DMA_BOUNDARY,
22324 };
22325
22326-static struct ata_port_operations sil24_ops = {
22327+static const struct ata_port_operations sil24_ops = {
22328 .inherits = &sata_pmp_port_ops,
22329
22330 .qc_defer = sil24_qc_defer,
16454cff
MT
22331diff -urNp linux-2.6.38.1/drivers/ata/sata_sil.c linux-2.6.38.1/drivers/ata/sata_sil.c
22332--- linux-2.6.38.1/drivers/ata/sata_sil.c 2011-03-14 21:20:32.000000000 -0400
22333+++ linux-2.6.38.1/drivers/ata/sata_sil.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
22334@@ -182,7 +182,7 @@ static struct scsi_host_template sil_sht
22335 .sg_tablesize = ATA_MAX_PRD
22336 };
22337
22338-static struct ata_port_operations sil_ops = {
22339+static const struct ata_port_operations sil_ops = {
22340 .inherits = &ata_bmdma32_port_ops,
22341 .dev_config = sil_dev_config,
22342 .set_mode = sil_set_mode,
16454cff
MT
22343diff -urNp linux-2.6.38.1/drivers/ata/sata_sis.c linux-2.6.38.1/drivers/ata/sata_sis.c
22344--- linux-2.6.38.1/drivers/ata/sata_sis.c 2011-03-14 21:20:32.000000000 -0400
22345+++ linux-2.6.38.1/drivers/ata/sata_sis.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
22346@@ -89,7 +89,7 @@ static struct scsi_host_template sis_sht
22347 ATA_BMDMA_SHT(DRV_NAME),
22348 };
22349
22350-static struct ata_port_operations sis_ops = {
22351+static const struct ata_port_operations sis_ops = {
22352 .inherits = &ata_bmdma_port_ops,
22353 .scr_read = sis_scr_read,
22354 .scr_write = sis_scr_write,
16454cff
MT
22355diff -urNp linux-2.6.38.1/drivers/ata/sata_svw.c linux-2.6.38.1/drivers/ata/sata_svw.c
22356--- linux-2.6.38.1/drivers/ata/sata_svw.c 2011-03-14 21:20:32.000000000 -0400
22357+++ linux-2.6.38.1/drivers/ata/sata_svw.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
22358@@ -344,7 +344,7 @@ static struct scsi_host_template k2_sata
22359 };
22360
22361
22362-static struct ata_port_operations k2_sata_ops = {
22363+static const struct ata_port_operations k2_sata_ops = {
22364 .inherits = &ata_bmdma_port_ops,
22365 .sff_tf_load = k2_sata_tf_load,
22366 .sff_tf_read = k2_sata_tf_read,
16454cff
MT
22367diff -urNp linux-2.6.38.1/drivers/ata/sata_sx4.c linux-2.6.38.1/drivers/ata/sata_sx4.c
22368--- linux-2.6.38.1/drivers/ata/sata_sx4.c 2011-03-14 21:20:32.000000000 -0400
22369+++ linux-2.6.38.1/drivers/ata/sata_sx4.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22370@@ -249,7 +249,7 @@ static struct scsi_host_template pdc_sat
ae4e228f
MT
22371 };
22372
22373 /* TODO: inherit from base port_ops after converting to new EH */
22374-static struct ata_port_operations pdc_20621_ops = {
22375+static const struct ata_port_operations pdc_20621_ops = {
22376 .inherits = &ata_sff_port_ops,
22377
22378 .check_atapi_dma = pdc_check_atapi_dma,
16454cff
MT
22379diff -urNp linux-2.6.38.1/drivers/ata/sata_uli.c linux-2.6.38.1/drivers/ata/sata_uli.c
22380--- linux-2.6.38.1/drivers/ata/sata_uli.c 2011-03-14 21:20:32.000000000 -0400
22381+++ linux-2.6.38.1/drivers/ata/sata_uli.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22382@@ -80,7 +80,7 @@ static struct scsi_host_template uli_sht
ae4e228f
MT
22383 ATA_BMDMA_SHT(DRV_NAME),
22384 };
22385
22386-static struct ata_port_operations uli_ops = {
22387+static const struct ata_port_operations uli_ops = {
22388 .inherits = &ata_bmdma_port_ops,
22389 .scr_read = uli_scr_read,
22390 .scr_write = uli_scr_write,
16454cff
MT
22391diff -urNp linux-2.6.38.1/drivers/ata/sata_via.c linux-2.6.38.1/drivers/ata/sata_via.c
22392--- linux-2.6.38.1/drivers/ata/sata_via.c 2011-03-14 21:20:32.000000000 -0400
22393+++ linux-2.6.38.1/drivers/ata/sata_via.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22394@@ -115,32 +115,32 @@ static struct scsi_host_template svia_sh
ae4e228f
MT
22395 ATA_BMDMA_SHT(DRV_NAME),
22396 };
22397
22398-static struct ata_port_operations svia_base_ops = {
22399+static const struct ata_port_operations svia_base_ops = {
22400 .inherits = &ata_bmdma_port_ops,
22401 .sff_tf_load = svia_tf_load,
22402 };
22403
22404-static struct ata_port_operations vt6420_sata_ops = {
22405+static const struct ata_port_operations vt6420_sata_ops = {
22406 .inherits = &svia_base_ops,
22407 .freeze = svia_noop_freeze,
22408 .prereset = vt6420_prereset,
df50ba0c 22409 .bmdma_start = vt6420_bmdma_start,
ae4e228f
MT
22410 };
22411
22412-static struct ata_port_operations vt6421_pata_ops = {
22413+static const struct ata_port_operations vt6421_pata_ops = {
22414 .inherits = &svia_base_ops,
22415 .cable_detect = vt6421_pata_cable_detect,
22416 .set_piomode = vt6421_set_pio_mode,
22417 .set_dmamode = vt6421_set_dma_mode,
22418 };
22419
22420-static struct ata_port_operations vt6421_sata_ops = {
22421+static const struct ata_port_operations vt6421_sata_ops = {
22422 .inherits = &svia_base_ops,
22423 .scr_read = svia_scr_read,
22424 .scr_write = svia_scr_write,
22425 };
22426
22427-static struct ata_port_operations vt8251_ops = {
22428+static const struct ata_port_operations vt8251_ops = {
22429 .inherits = &svia_base_ops,
22430 .hardreset = sata_std_hardreset,
22431 .scr_read = vt8251_scr_read,
16454cff
MT
22432diff -urNp linux-2.6.38.1/drivers/ata/sata_vsc.c linux-2.6.38.1/drivers/ata/sata_vsc.c
22433--- linux-2.6.38.1/drivers/ata/sata_vsc.c 2011-03-14 21:20:32.000000000 -0400
22434+++ linux-2.6.38.1/drivers/ata/sata_vsc.c 2011-03-21 18:31:35.000000000 -0400
57199397 22435@@ -300,7 +300,7 @@ static struct scsi_host_template vsc_sat
ae4e228f
MT
22436 };
22437
22438
22439-static struct ata_port_operations vsc_sata_ops = {
22440+static const struct ata_port_operations vsc_sata_ops = {
22441 .inherits = &ata_bmdma_port_ops,
22442 /* The IRQ handling is not quite standard SFF behaviour so we
22443 cannot use the default lost interrupt handler */
16454cff
MT
22444diff -urNp linux-2.6.38.1/drivers/atm/adummy.c linux-2.6.38.1/drivers/atm/adummy.c
22445--- linux-2.6.38.1/drivers/atm/adummy.c 2011-03-14 21:20:32.000000000 -0400
22446+++ linux-2.6.38.1/drivers/atm/adummy.c 2011-03-21 18:31:35.000000000 -0400
6892158b 22447@@ -114,7 +114,7 @@ adummy_send(struct atm_vcc *vcc, struct
58c5fc13
MT
22448 vcc->pop(vcc, skb);
22449 else
22450 dev_kfree_skb_any(skb);
22451- atomic_inc(&vcc->stats->tx);
22452+ atomic_inc_unchecked(&vcc->stats->tx);
22453
22454 return 0;
22455 }
16454cff
MT
22456diff -urNp linux-2.6.38.1/drivers/atm/ambassador.c linux-2.6.38.1/drivers/atm/ambassador.c
22457--- linux-2.6.38.1/drivers/atm/ambassador.c 2011-03-14 21:20:32.000000000 -0400
22458+++ linux-2.6.38.1/drivers/atm/ambassador.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22459@@ -454,7 +454,7 @@ static void tx_complete (amb_dev * dev,
58c5fc13
MT
22460 PRINTD (DBG_FLOW|DBG_TX, "tx_complete %p %p", dev, tx);
22461
22462 // VC layer stats
22463- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
22464+ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
22465
22466 // free the descriptor
22467 kfree (tx_descr);
df50ba0c 22468@@ -495,7 +495,7 @@ static void rx_complete (amb_dev * dev,
58c5fc13
MT
22469 dump_skb ("<<<", vc, skb);
22470
22471 // VC layer stats
22472- atomic_inc(&atm_vcc->stats->rx);
22473+ atomic_inc_unchecked(&atm_vcc->stats->rx);
22474 __net_timestamp(skb);
22475 // end of our responsability
22476 atm_vcc->push (atm_vcc, skb);
df50ba0c 22477@@ -510,7 +510,7 @@ static void rx_complete (amb_dev * dev,
58c5fc13
MT
22478 } else {
22479 PRINTK (KERN_INFO, "dropped over-size frame");
22480 // should we count this?
22481- atomic_inc(&atm_vcc->stats->rx_drop);
22482+ atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
22483 }
22484
22485 } else {
df50ba0c 22486@@ -1342,7 +1342,7 @@ static int amb_send (struct atm_vcc * at
58c5fc13
MT
22487 }
22488
22489 if (check_area (skb->data, skb->len)) {
22490- atomic_inc(&atm_vcc->stats->tx_err);
22491+ atomic_inc_unchecked(&atm_vcc->stats->tx_err);
22492 return -ENOMEM; // ?
22493 }
22494
16454cff
MT
22495diff -urNp linux-2.6.38.1/drivers/atm/atmtcp.c linux-2.6.38.1/drivers/atm/atmtcp.c
22496--- linux-2.6.38.1/drivers/atm/atmtcp.c 2011-03-14 21:20:32.000000000 -0400
22497+++ linux-2.6.38.1/drivers/atm/atmtcp.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22498@@ -207,7 +207,7 @@ static int atmtcp_v_send(struct atm_vcc
58c5fc13
MT
22499 if (vcc->pop) vcc->pop(vcc,skb);
22500 else dev_kfree_skb(skb);
22501 if (dev_data) return 0;
22502- atomic_inc(&vcc->stats->tx_err);
22503+ atomic_inc_unchecked(&vcc->stats->tx_err);
22504 return -ENOLINK;
22505 }
22506 size = skb->len+sizeof(struct atmtcp_hdr);
df50ba0c 22507@@ -215,7 +215,7 @@ static int atmtcp_v_send(struct atm_vcc
58c5fc13
MT
22508 if (!new_skb) {
22509 if (vcc->pop) vcc->pop(vcc,skb);
22510 else dev_kfree_skb(skb);
22511- atomic_inc(&vcc->stats->tx_err);
22512+ atomic_inc_unchecked(&vcc->stats->tx_err);
22513 return -ENOBUFS;
22514 }
22515 hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
df50ba0c 22516@@ -226,8 +226,8 @@ static int atmtcp_v_send(struct atm_vcc
58c5fc13
MT
22517 if (vcc->pop) vcc->pop(vcc,skb);
22518 else dev_kfree_skb(skb);
22519 out_vcc->push(out_vcc,new_skb);
22520- atomic_inc(&vcc->stats->tx);
22521- atomic_inc(&out_vcc->stats->rx);
22522+ atomic_inc_unchecked(&vcc->stats->tx);
22523+ atomic_inc_unchecked(&out_vcc->stats->rx);
22524 return 0;
22525 }
22526
df50ba0c 22527@@ -301,7 +301,7 @@ static int atmtcp_c_send(struct atm_vcc
58c5fc13
MT
22528 out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
22529 read_unlock(&vcc_sklist_lock);
22530 if (!out_vcc) {
22531- atomic_inc(&vcc->stats->tx_err);
22532+ atomic_inc_unchecked(&vcc->stats->tx_err);
22533 goto done;
22534 }
22535 skb_pull(skb,sizeof(struct atmtcp_hdr));
df50ba0c 22536@@ -313,8 +313,8 @@ static int atmtcp_c_send(struct atm_vcc
58c5fc13
MT
22537 __net_timestamp(new_skb);
22538 skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
22539 out_vcc->push(out_vcc,new_skb);
22540- atomic_inc(&vcc->stats->tx);
22541- atomic_inc(&out_vcc->stats->rx);
22542+ atomic_inc_unchecked(&vcc->stats->tx);
22543+ atomic_inc_unchecked(&out_vcc->stats->rx);
22544 done:
22545 if (vcc->pop) vcc->pop(vcc,skb);
22546 else dev_kfree_skb(skb);
16454cff
MT
22547diff -urNp linux-2.6.38.1/drivers/atm/eni.c linux-2.6.38.1/drivers/atm/eni.c
22548--- linux-2.6.38.1/drivers/atm/eni.c 2011-03-14 21:20:32.000000000 -0400
22549+++ linux-2.6.38.1/drivers/atm/eni.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22550@@ -526,7 +526,7 @@ static int rx_aal0(struct atm_vcc *vcc)
58c5fc13
MT
22551 DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
22552 vcc->dev->number);
22553 length = 0;
22554- atomic_inc(&vcc->stats->rx_err);
22555+ atomic_inc_unchecked(&vcc->stats->rx_err);
22556 }
22557 else {
22558 length = ATM_CELL_SIZE-1; /* no HEC */
df50ba0c 22559@@ -581,7 +581,7 @@ static int rx_aal5(struct atm_vcc *vcc)
58c5fc13
MT
22560 size);
22561 }
22562 eff = length = 0;
22563- atomic_inc(&vcc->stats->rx_err);
22564+ atomic_inc_unchecked(&vcc->stats->rx_err);
22565 }
22566 else {
22567 size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
df50ba0c 22568@@ -598,7 +598,7 @@ static int rx_aal5(struct atm_vcc *vcc)
58c5fc13
MT
22569 "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n",
22570 vcc->dev->number,vcc->vci,length,size << 2,descr);
22571 length = eff = 0;
22572- atomic_inc(&vcc->stats->rx_err);
22573+ atomic_inc_unchecked(&vcc->stats->rx_err);
22574 }
22575 }
22576 skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL;
df50ba0c 22577@@ -771,7 +771,7 @@ rx_dequeued++;
58c5fc13
MT
22578 vcc->push(vcc,skb);
22579 pushed++;
22580 }
22581- atomic_inc(&vcc->stats->rx);
22582+ atomic_inc_unchecked(&vcc->stats->rx);
22583 }
22584 wake_up(&eni_dev->rx_wait);
22585 }
df50ba0c 22586@@ -1228,7 +1228,7 @@ static void dequeue_tx(struct atm_dev *d
58c5fc13
MT
22587 PCI_DMA_TODEVICE);
22588 if (vcc->pop) vcc->pop(vcc,skb);
22589 else dev_kfree_skb_irq(skb);
22590- atomic_inc(&vcc->stats->tx);
22591+ atomic_inc_unchecked(&vcc->stats->tx);
22592 wake_up(&eni_dev->tx_wait);
22593 dma_complete++;
22594 }
16454cff
MT
22595diff -urNp linux-2.6.38.1/drivers/atm/firestream.c linux-2.6.38.1/drivers/atm/firestream.c
22596--- linux-2.6.38.1/drivers/atm/firestream.c 2011-03-14 21:20:32.000000000 -0400
22597+++ linux-2.6.38.1/drivers/atm/firestream.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22598@@ -749,7 +749,7 @@ static void process_txdone_queue (struct
58c5fc13
MT
22599 }
22600 }
22601
22602- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
22603+ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
22604
22605 fs_dprintk (FS_DEBUG_TXMEM, "i");
22606 fs_dprintk (FS_DEBUG_ALLOC, "Free t-skb: %p\n", skb);
df50ba0c 22607@@ -816,7 +816,7 @@ static void process_incoming (struct fs_
58c5fc13
MT
22608 #endif
22609 skb_put (skb, qe->p1 & 0xffff);
22610 ATM_SKB(skb)->vcc = atm_vcc;
22611- atomic_inc(&atm_vcc->stats->rx);
22612+ atomic_inc_unchecked(&atm_vcc->stats->rx);
22613 __net_timestamp(skb);
22614 fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
22615 atm_vcc->push (atm_vcc, skb);
df50ba0c 22616@@ -837,12 +837,12 @@ static void process_incoming (struct fs_
58c5fc13
MT
22617 kfree (pe);
22618 }
22619 if (atm_vcc)
22620- atomic_inc(&atm_vcc->stats->rx_drop);
22621+ atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
22622 break;
22623 case 0x1f: /* Reassembly abort: no buffers. */
22624 /* Silently increment error counter. */
22625 if (atm_vcc)
22626- atomic_inc(&atm_vcc->stats->rx_drop);
22627+ atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
22628 break;
22629 default: /* Hmm. Haven't written the code to handle the others yet... -- REW */
22630 printk (KERN_WARNING "Don't know what to do with RX status %x: %s.\n",
16454cff
MT
22631diff -urNp linux-2.6.38.1/drivers/atm/fore200e.c linux-2.6.38.1/drivers/atm/fore200e.c
22632--- linux-2.6.38.1/drivers/atm/fore200e.c 2011-03-14 21:20:32.000000000 -0400
22633+++ linux-2.6.38.1/drivers/atm/fore200e.c 2011-03-21 18:31:35.000000000 -0400
57199397 22634@@ -933,9 +933,9 @@ fore200e_tx_irq(struct fore200e* fore200
58c5fc13
MT
22635 #endif
22636 /* check error condition */
22637 if (*entry->status & STATUS_ERROR)
22638- atomic_inc(&vcc->stats->tx_err);
22639+ atomic_inc_unchecked(&vcc->stats->tx_err);
22640 else
22641- atomic_inc(&vcc->stats->tx);
22642+ atomic_inc_unchecked(&vcc->stats->tx);
22643 }
22644 }
22645
57199397 22646@@ -1084,7 +1084,7 @@ fore200e_push_rpd(struct fore200e* fore2
58c5fc13
MT
22647 if (skb == NULL) {
22648 DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
22649
22650- atomic_inc(&vcc->stats->rx_drop);
22651+ atomic_inc_unchecked(&vcc->stats->rx_drop);
22652 return -ENOMEM;
22653 }
22654
57199397 22655@@ -1127,14 +1127,14 @@ fore200e_push_rpd(struct fore200e* fore2
58c5fc13
MT
22656
22657 dev_kfree_skb_any(skb);
22658
22659- atomic_inc(&vcc->stats->rx_drop);
22660+ atomic_inc_unchecked(&vcc->stats->rx_drop);
22661 return -ENOMEM;
22662 }
22663
22664 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
22665
22666 vcc->push(vcc, skb);
22667- atomic_inc(&vcc->stats->rx);
22668+ atomic_inc_unchecked(&vcc->stats->rx);
22669
22670 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
22671
57199397 22672@@ -1212,7 +1212,7 @@ fore200e_rx_irq(struct fore200e* fore200
58c5fc13
MT
22673 DPRINTK(2, "damaged PDU on %d.%d.%d\n",
22674 fore200e->atm_dev->number,
22675 entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
22676- atomic_inc(&vcc->stats->rx_err);
22677+ atomic_inc_unchecked(&vcc->stats->rx_err);
22678 }
22679 }
22680
57199397 22681@@ -1657,7 +1657,7 @@ fore200e_send(struct atm_vcc *vcc, struc
58c5fc13
MT
22682 goto retry_here;
22683 }
22684
22685- atomic_inc(&vcc->stats->tx_err);
22686+ atomic_inc_unchecked(&vcc->stats->tx_err);
22687
22688 fore200e->tx_sat++;
22689 DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
16454cff
MT
22690diff -urNp linux-2.6.38.1/drivers/atm/he.c linux-2.6.38.1/drivers/atm/he.c
22691--- linux-2.6.38.1/drivers/atm/he.c 2011-03-14 21:20:32.000000000 -0400
22692+++ linux-2.6.38.1/drivers/atm/he.c 2011-03-21 18:31:35.000000000 -0400
6892158b 22693@@ -1709,7 +1709,7 @@ he_service_rbrq(struct he_dev *he_dev, i
58c5fc13
MT
22694
22695 if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
22696 hprintk("HBUF_ERR! (cid 0x%x)\n", cid);
22697- atomic_inc(&vcc->stats->rx_drop);
22698+ atomic_inc_unchecked(&vcc->stats->rx_drop);
22699 goto return_host_buffers;
22700 }
22701
6892158b 22702@@ -1736,7 +1736,7 @@ he_service_rbrq(struct he_dev *he_dev, i
58c5fc13
MT
22703 RBRQ_LEN_ERR(he_dev->rbrq_head)
22704 ? "LEN_ERR" : "",
22705 vcc->vpi, vcc->vci);
22706- atomic_inc(&vcc->stats->rx_err);
22707+ atomic_inc_unchecked(&vcc->stats->rx_err);
22708 goto return_host_buffers;
22709 }
22710
6892158b 22711@@ -1788,7 +1788,7 @@ he_service_rbrq(struct he_dev *he_dev, i
58c5fc13
MT
22712 vcc->push(vcc, skb);
22713 spin_lock(&he_dev->global_lock);
22714
22715- atomic_inc(&vcc->stats->rx);
22716+ atomic_inc_unchecked(&vcc->stats->rx);
22717
22718 return_host_buffers:
22719 ++pdus_assembled;
6892158b 22720@@ -2114,7 +2114,7 @@ __enqueue_tpd(struct he_dev *he_dev, str
58c5fc13
MT
22721 tpd->vcc->pop(tpd->vcc, tpd->skb);
22722 else
22723 dev_kfree_skb_any(tpd->skb);
22724- atomic_inc(&tpd->vcc->stats->tx_err);
22725+ atomic_inc_unchecked(&tpd->vcc->stats->tx_err);
22726 }
22727 pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
22728 return;
6892158b 22729@@ -2526,7 +2526,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
58c5fc13
MT
22730 vcc->pop(vcc, skb);
22731 else
22732 dev_kfree_skb_any(skb);
22733- atomic_inc(&vcc->stats->tx_err);
22734+ atomic_inc_unchecked(&vcc->stats->tx_err);
22735 return -EINVAL;
22736 }
22737
6892158b 22738@@ -2537,7 +2537,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
58c5fc13
MT
22739 vcc->pop(vcc, skb);
22740 else
22741 dev_kfree_skb_any(skb);
22742- atomic_inc(&vcc->stats->tx_err);
22743+ atomic_inc_unchecked(&vcc->stats->tx_err);
22744 return -EINVAL;
22745 }
22746 #endif
6892158b 22747@@ -2549,7 +2549,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
58c5fc13
MT
22748 vcc->pop(vcc, skb);
22749 else
22750 dev_kfree_skb_any(skb);
22751- atomic_inc(&vcc->stats->tx_err);
22752+ atomic_inc_unchecked(&vcc->stats->tx_err);
22753 spin_unlock_irqrestore(&he_dev->global_lock, flags);
22754 return -ENOMEM;
22755 }
6892158b 22756@@ -2591,7 +2591,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
58c5fc13
MT
22757 vcc->pop(vcc, skb);
22758 else
22759 dev_kfree_skb_any(skb);
22760- atomic_inc(&vcc->stats->tx_err);
22761+ atomic_inc_unchecked(&vcc->stats->tx_err);
22762 spin_unlock_irqrestore(&he_dev->global_lock, flags);
22763 return -ENOMEM;
22764 }
6892158b 22765@@ -2622,7 +2622,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
58c5fc13
MT
22766 __enqueue_tpd(he_dev, tpd, cid);
22767 spin_unlock_irqrestore(&he_dev->global_lock, flags);
22768
22769- atomic_inc(&vcc->stats->tx);
22770+ atomic_inc_unchecked(&vcc->stats->tx);
22771
22772 return 0;
22773 }
16454cff
MT
22774diff -urNp linux-2.6.38.1/drivers/atm/horizon.c linux-2.6.38.1/drivers/atm/horizon.c
22775--- linux-2.6.38.1/drivers/atm/horizon.c 2011-03-14 21:20:32.000000000 -0400
22776+++ linux-2.6.38.1/drivers/atm/horizon.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22777@@ -1034,7 +1034,7 @@ static void rx_schedule (hrz_dev * dev,
58c5fc13
MT
22778 {
22779 struct atm_vcc * vcc = ATM_SKB(skb)->vcc;
22780 // VC layer stats
22781- atomic_inc(&vcc->stats->rx);
22782+ atomic_inc_unchecked(&vcc->stats->rx);
22783 __net_timestamp(skb);
22784 // end of our responsability
22785 vcc->push (vcc, skb);
df50ba0c 22786@@ -1186,7 +1186,7 @@ static void tx_schedule (hrz_dev * const
58c5fc13
MT
22787 dev->tx_iovec = NULL;
22788
22789 // VC layer stats
22790- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
22791+ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
22792
22793 // free the skb
22794 hrz_kfree_skb (skb);
16454cff
MT
22795diff -urNp linux-2.6.38.1/drivers/atm/idt77252.c linux-2.6.38.1/drivers/atm/idt77252.c
22796--- linux-2.6.38.1/drivers/atm/idt77252.c 2011-03-14 21:20:32.000000000 -0400
22797+++ linux-2.6.38.1/drivers/atm/idt77252.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22798@@ -811,7 +811,7 @@ drain_scq(struct idt77252_dev *card, str
58c5fc13
MT
22799 else
22800 dev_kfree_skb(skb);
22801
22802- atomic_inc(&vcc->stats->tx);
22803+ atomic_inc_unchecked(&vcc->stats->tx);
22804 }
22805
22806 atomic_dec(&scq->used);
df50ba0c 22807@@ -1074,13 +1074,13 @@ dequeue_rx(struct idt77252_dev *card, st
58c5fc13
MT
22808 if ((sb = dev_alloc_skb(64)) == NULL) {
22809 printk("%s: Can't allocate buffers for aal0.\n",
22810 card->name);
22811- atomic_add(i, &vcc->stats->rx_drop);
22812+ atomic_add_unchecked(i, &vcc->stats->rx_drop);
22813 break;
22814 }
22815 if (!atm_charge(vcc, sb->truesize)) {
22816 RXPRINTK("%s: atm_charge() dropped aal0 packets.\n",
22817 card->name);
22818- atomic_add(i - 1, &vcc->stats->rx_drop);
22819+ atomic_add_unchecked(i - 1, &vcc->stats->rx_drop);
22820 dev_kfree_skb(sb);
22821 break;
22822 }
df50ba0c 22823@@ -1097,7 +1097,7 @@ dequeue_rx(struct idt77252_dev *card, st
58c5fc13
MT
22824 ATM_SKB(sb)->vcc = vcc;
22825 __net_timestamp(sb);
22826 vcc->push(vcc, sb);
22827- atomic_inc(&vcc->stats->rx);
22828+ atomic_inc_unchecked(&vcc->stats->rx);
22829
22830 cell += ATM_CELL_PAYLOAD;
22831 }
df50ba0c 22832@@ -1134,13 +1134,13 @@ dequeue_rx(struct idt77252_dev *card, st
58c5fc13
MT
22833 "(CDC: %08x)\n",
22834 card->name, len, rpp->len, readl(SAR_REG_CDC));
22835 recycle_rx_pool_skb(card, rpp);
22836- atomic_inc(&vcc->stats->rx_err);
22837+ atomic_inc_unchecked(&vcc->stats->rx_err);
22838 return;
22839 }
22840 if (stat & SAR_RSQE_CRC) {
22841 RXPRINTK("%s: AAL5 CRC error.\n", card->name);
22842 recycle_rx_pool_skb(card, rpp);
22843- atomic_inc(&vcc->stats->rx_err);
22844+ atomic_inc_unchecked(&vcc->stats->rx_err);
22845 return;
22846 }
22847 if (skb_queue_len(&rpp->queue) > 1) {
df50ba0c 22848@@ -1151,7 +1151,7 @@ dequeue_rx(struct idt77252_dev *card, st
58c5fc13
MT
22849 RXPRINTK("%s: Can't alloc RX skb.\n",
22850 card->name);
22851 recycle_rx_pool_skb(card, rpp);
22852- atomic_inc(&vcc->stats->rx_err);
22853+ atomic_inc_unchecked(&vcc->stats->rx_err);
22854 return;
22855 }
22856 if (!atm_charge(vcc, skb->truesize)) {
df50ba0c 22857@@ -1170,7 +1170,7 @@ dequeue_rx(struct idt77252_dev *card, st
58c5fc13
MT
22858 __net_timestamp(skb);
22859
22860 vcc->push(vcc, skb);
22861- atomic_inc(&vcc->stats->rx);
22862+ atomic_inc_unchecked(&vcc->stats->rx);
22863
22864 return;
22865 }
df50ba0c 22866@@ -1192,7 +1192,7 @@ dequeue_rx(struct idt77252_dev *card, st
58c5fc13
MT
22867 __net_timestamp(skb);
22868
22869 vcc->push(vcc, skb);
22870- atomic_inc(&vcc->stats->rx);
22871+ atomic_inc_unchecked(&vcc->stats->rx);
22872
22873 if (skb->truesize > SAR_FB_SIZE_3)
22874 add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
df50ba0c 22875@@ -1304,14 +1304,14 @@ idt77252_rx_raw(struct idt77252_dev *car
58c5fc13
MT
22876 if (vcc->qos.aal != ATM_AAL0) {
22877 RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n",
22878 card->name, vpi, vci);
22879- atomic_inc(&vcc->stats->rx_drop);
22880+ atomic_inc_unchecked(&vcc->stats->rx_drop);
22881 goto drop;
22882 }
22883
22884 if ((sb = dev_alloc_skb(64)) == NULL) {
22885 printk("%s: Can't allocate buffers for AAL0.\n",
22886 card->name);
22887- atomic_inc(&vcc->stats->rx_err);
22888+ atomic_inc_unchecked(&vcc->stats->rx_err);
22889 goto drop;
22890 }
22891
df50ba0c 22892@@ -1330,7 +1330,7 @@ idt77252_rx_raw(struct idt77252_dev *car
58c5fc13
MT
22893 ATM_SKB(sb)->vcc = vcc;
22894 __net_timestamp(sb);
22895 vcc->push(vcc, sb);
22896- atomic_inc(&vcc->stats->rx);
22897+ atomic_inc_unchecked(&vcc->stats->rx);
22898
22899 drop:
22900 skb_pull(queue, 64);
df50ba0c 22901@@ -1955,13 +1955,13 @@ idt77252_send_skb(struct atm_vcc *vcc, s
58c5fc13
MT
22902
22903 if (vc == NULL) {
22904 printk("%s: NULL connection in send().\n", card->name);
22905- atomic_inc(&vcc->stats->tx_err);
22906+ atomic_inc_unchecked(&vcc->stats->tx_err);
22907 dev_kfree_skb(skb);
22908 return -EINVAL;
22909 }
22910 if (!test_bit(VCF_TX, &vc->flags)) {
22911 printk("%s: Trying to transmit on a non-tx VC.\n", card->name);
22912- atomic_inc(&vcc->stats->tx_err);
22913+ atomic_inc_unchecked(&vcc->stats->tx_err);
22914 dev_kfree_skb(skb);
22915 return -EINVAL;
22916 }
df50ba0c 22917@@ -1973,14 +1973,14 @@ idt77252_send_skb(struct atm_vcc *vcc, s
58c5fc13
MT
22918 break;
22919 default:
22920 printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
22921- atomic_inc(&vcc->stats->tx_err);
22922+ atomic_inc_unchecked(&vcc->stats->tx_err);
22923 dev_kfree_skb(skb);
22924 return -EINVAL;
22925 }
22926
22927 if (skb_shinfo(skb)->nr_frags != 0) {
22928 printk("%s: No scatter-gather yet.\n", card->name);
22929- atomic_inc(&vcc->stats->tx_err);
22930+ atomic_inc_unchecked(&vcc->stats->tx_err);
22931 dev_kfree_skb(skb);
22932 return -EINVAL;
22933 }
df50ba0c 22934@@ -1988,7 +1988,7 @@ idt77252_send_skb(struct atm_vcc *vcc, s
58c5fc13
MT
22935
22936 err = queue_skb(card, vc, skb, oam);
22937 if (err) {
22938- atomic_inc(&vcc->stats->tx_err);
22939+ atomic_inc_unchecked(&vcc->stats->tx_err);
22940 dev_kfree_skb(skb);
22941 return err;
22942 }
df50ba0c 22943@@ -2011,7 +2011,7 @@ idt77252_send_oam(struct atm_vcc *vcc, v
58c5fc13
MT
22944 skb = dev_alloc_skb(64);
22945 if (!skb) {
22946 printk("%s: Out of memory in send_oam().\n", card->name);
22947- atomic_inc(&vcc->stats->tx_err);
22948+ atomic_inc_unchecked(&vcc->stats->tx_err);
22949 return -ENOMEM;
22950 }
22951 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
16454cff
MT
22952diff -urNp linux-2.6.38.1/drivers/atm/iphase.c linux-2.6.38.1/drivers/atm/iphase.c
22953--- linux-2.6.38.1/drivers/atm/iphase.c 2011-03-14 21:20:32.000000000 -0400
22954+++ linux-2.6.38.1/drivers/atm/iphase.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 22955@@ -1124,7 +1124,7 @@ static int rx_pkt(struct atm_dev *dev)
58c5fc13
MT
22956 status = (u_short) (buf_desc_ptr->desc_mode);
22957 if (status & (RX_CER | RX_PTE | RX_OFL))
22958 {
22959- atomic_inc(&vcc->stats->rx_err);
22960+ atomic_inc_unchecked(&vcc->stats->rx_err);
22961 IF_ERR(printk("IA: bad packet, dropping it");)
22962 if (status & RX_CER) {
22963 IF_ERR(printk(" cause: packet CRC error\n");)
df50ba0c 22964@@ -1147,7 +1147,7 @@ static int rx_pkt(struct atm_dev *dev)
58c5fc13
MT
22965 len = dma_addr - buf_addr;
22966 if (len > iadev->rx_buf_sz) {
22967 printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz);
22968- atomic_inc(&vcc->stats->rx_err);
22969+ atomic_inc_unchecked(&vcc->stats->rx_err);
22970 goto out_free_desc;
22971 }
22972
df50ba0c 22973@@ -1297,7 +1297,7 @@ static void rx_dle_intr(struct atm_dev *
58c5fc13
MT
22974 ia_vcc = INPH_IA_VCC(vcc);
22975 if (ia_vcc == NULL)
22976 {
22977- atomic_inc(&vcc->stats->rx_err);
22978+ atomic_inc_unchecked(&vcc->stats->rx_err);
22979 dev_kfree_skb_any(skb);
22980 atm_return(vcc, atm_guess_pdu2truesize(len));
22981 goto INCR_DLE;
df50ba0c 22982@@ -1309,7 +1309,7 @@ static void rx_dle_intr(struct atm_dev *
58c5fc13
MT
22983 if ((length > iadev->rx_buf_sz) || (length >
22984 (skb->len - sizeof(struct cpcs_trailer))))
22985 {
22986- atomic_inc(&vcc->stats->rx_err);
22987+ atomic_inc_unchecked(&vcc->stats->rx_err);
22988 IF_ERR(printk("rx_dle_intr: Bad AAL5 trailer %d (skb len %d)",
22989 length, skb->len);)
22990 dev_kfree_skb_any(skb);
df50ba0c 22991@@ -1325,7 +1325,7 @@ static void rx_dle_intr(struct atm_dev *
58c5fc13
MT
22992
22993 IF_RX(printk("rx_dle_intr: skb push");)
22994 vcc->push(vcc,skb);
22995- atomic_inc(&vcc->stats->rx);
22996+ atomic_inc_unchecked(&vcc->stats->rx);
22997 iadev->rx_pkt_cnt++;
22998 }
22999 INCR_DLE:
df50ba0c 23000@@ -2807,15 +2807,15 @@ static int ia_ioctl(struct atm_dev *dev,
58c5fc13
MT
23001 {
23002 struct k_sonet_stats *stats;
23003 stats = &PRIV(_ia_dev[board])->sonet_stats;
23004- printk("section_bip: %d\n", atomic_read(&stats->section_bip));
23005- printk("line_bip : %d\n", atomic_read(&stats->line_bip));
23006- printk("path_bip : %d\n", atomic_read(&stats->path_bip));
23007- printk("line_febe : %d\n", atomic_read(&stats->line_febe));
23008- printk("path_febe : %d\n", atomic_read(&stats->path_febe));
23009- printk("corr_hcs : %d\n", atomic_read(&stats->corr_hcs));
23010- printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs));
23011- printk("tx_cells : %d\n", atomic_read(&stats->tx_cells));
23012- printk("rx_cells : %d\n", atomic_read(&stats->rx_cells));
23013+ printk("section_bip: %d\n", atomic_read_unchecked(&stats->section_bip));
23014+ printk("line_bip : %d\n", atomic_read_unchecked(&stats->line_bip));
23015+ printk("path_bip : %d\n", atomic_read_unchecked(&stats->path_bip));
23016+ printk("line_febe : %d\n", atomic_read_unchecked(&stats->line_febe));
23017+ printk("path_febe : %d\n", atomic_read_unchecked(&stats->path_febe));
23018+ printk("corr_hcs : %d\n", atomic_read_unchecked(&stats->corr_hcs));
23019+ printk("uncorr_hcs : %d\n", atomic_read_unchecked(&stats->uncorr_hcs));
23020+ printk("tx_cells : %d\n", atomic_read_unchecked(&stats->tx_cells));
23021+ printk("rx_cells : %d\n", atomic_read_unchecked(&stats->rx_cells));
23022 }
23023 ia_cmds.status = 0;
23024 break;
df50ba0c 23025@@ -2920,7 +2920,7 @@ static int ia_pkt_tx (struct atm_vcc *vc
58c5fc13
MT
23026 if ((desc == 0) || (desc > iadev->num_tx_desc))
23027 {
23028 IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);)
23029- atomic_inc(&vcc->stats->tx);
23030+ atomic_inc_unchecked(&vcc->stats->tx);
23031 if (vcc->pop)
23032 vcc->pop(vcc, skb);
23033 else
df50ba0c 23034@@ -3025,14 +3025,14 @@ static int ia_pkt_tx (struct atm_vcc *vc
58c5fc13
MT
23035 ATM_DESC(skb) = vcc->vci;
23036 skb_queue_tail(&iadev->tx_dma_q, skb);
23037
23038- atomic_inc(&vcc->stats->tx);
23039+ atomic_inc_unchecked(&vcc->stats->tx);
23040 iadev->tx_pkt_cnt++;
23041 /* Increment transaction counter */
23042 writel(2, iadev->dma+IPHASE5575_TX_COUNTER);
23043
23044 #if 0
23045 /* add flow control logic */
23046- if (atomic_read(&vcc->stats->tx) % 20 == 0) {
23047+ if (atomic_read_unchecked(&vcc->stats->tx) % 20 == 0) {
23048 if (iavcc->vc_desc_cnt > 10) {
23049 vcc->tx_quota = vcc->tx_quota * 3 / 4;
23050 printk("Tx1: vcc->tx_quota = %d \n", (u32)vcc->tx_quota );
16454cff
MT
23051diff -urNp linux-2.6.38.1/drivers/atm/lanai.c linux-2.6.38.1/drivers/atm/lanai.c
23052--- linux-2.6.38.1/drivers/atm/lanai.c 2011-03-14 21:20:32.000000000 -0400
23053+++ linux-2.6.38.1/drivers/atm/lanai.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 23054@@ -1303,7 +1303,7 @@ static void lanai_send_one_aal5(struct l
58c5fc13
MT
23055 vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
23056 lanai_endtx(lanai, lvcc);
23057 lanai_free_skb(lvcc->tx.atmvcc, skb);
23058- atomic_inc(&lvcc->tx.atmvcc->stats->tx);
23059+ atomic_inc_unchecked(&lvcc->tx.atmvcc->stats->tx);
23060 }
23061
23062 /* Try to fill the buffer - don't call unless there is backlog */
df50ba0c 23063@@ -1426,7 +1426,7 @@ static void vcc_rx_aal5(struct lanai_vcc
58c5fc13
MT
23064 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
23065 __net_timestamp(skb);
23066 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
23067- atomic_inc(&lvcc->rx.atmvcc->stats->rx);
23068+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx);
23069 out:
23070 lvcc->rx.buf.ptr = end;
23071 cardvcc_write(lvcc, endptr, vcc_rxreadptr);
df50ba0c 23072@@ -1668,7 +1668,7 @@ static int handle_service(struct lanai_d
58c5fc13
MT
23073 DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
23074 "vcc %d\n", lanai->number, (unsigned int) s, vci);
23075 lanai->stats.service_rxnotaal5++;
23076- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
23077+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
23078 return 0;
23079 }
23080 if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {
df50ba0c 23081@@ -1680,7 +1680,7 @@ static int handle_service(struct lanai_d
58c5fc13
MT
23082 int bytes;
23083 read_unlock(&vcc_sklist_lock);
23084 DPRINTK("got trashed rx pdu on vci %d\n", vci);
23085- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
23086+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
23087 lvcc->stats.x.aal5.service_trash++;
23088 bytes = (SERVICE_GET_END(s) * 16) -
23089 (((unsigned long) lvcc->rx.buf.ptr) -
df50ba0c 23090@@ -1692,7 +1692,7 @@ static int handle_service(struct lanai_d
58c5fc13
MT
23091 }
23092 if (s & SERVICE_STREAM) {
23093 read_unlock(&vcc_sklist_lock);
23094- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
23095+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
23096 lvcc->stats.x.aal5.service_stream++;
23097 printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
23098 "PDU on VCI %d!\n", lanai->number, vci);
df50ba0c 23099@@ -1700,7 +1700,7 @@ static int handle_service(struct lanai_d
58c5fc13
MT
23100 return 0;
23101 }
23102 DPRINTK("got rx crc error on vci %d\n", vci);
23103- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
23104+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
23105 lvcc->stats.x.aal5.service_rxcrc++;
23106 lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
23107 cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
16454cff
MT
23108diff -urNp linux-2.6.38.1/drivers/atm/nicstar.c linux-2.6.38.1/drivers/atm/nicstar.c
23109--- linux-2.6.38.1/drivers/atm/nicstar.c 2011-03-14 21:20:32.000000000 -0400
23110+++ linux-2.6.38.1/drivers/atm/nicstar.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 23111@@ -1654,7 +1654,7 @@ static int ns_send(struct atm_vcc *vcc,
6892158b
MT
23112 if ((vc = (vc_map *) vcc->dev_data) == NULL) {
23113 printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n",
23114 card->index);
23115- atomic_inc(&vcc->stats->tx_err);
23116+ atomic_inc_unchecked(&vcc->stats->tx_err);
23117 dev_kfree_skb_any(skb);
23118 return -EINVAL;
23119 }
bc901d79 23120@@ -1662,7 +1662,7 @@ static int ns_send(struct atm_vcc *vcc,
6892158b
MT
23121 if (!vc->tx) {
23122 printk("nicstar%d: Trying to transmit on a non-tx VC.\n",
23123 card->index);
23124- atomic_inc(&vcc->stats->tx_err);
23125+ atomic_inc_unchecked(&vcc->stats->tx_err);
23126 dev_kfree_skb_any(skb);
23127 return -EINVAL;
23128 }
bc901d79 23129@@ -1670,14 +1670,14 @@ static int ns_send(struct atm_vcc *vcc,
6892158b
MT
23130 if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {
23131 printk("nicstar%d: Only AAL0 and AAL5 are supported.\n",
23132 card->index);
23133- atomic_inc(&vcc->stats->tx_err);
23134+ atomic_inc_unchecked(&vcc->stats->tx_err);
23135 dev_kfree_skb_any(skb);
23136 return -EINVAL;
23137 }
58c5fc13 23138
6892158b
MT
23139 if (skb_shinfo(skb)->nr_frags != 0) {
23140 printk("nicstar%d: No scatter-gather yet.\n", card->index);
23141- atomic_inc(&vcc->stats->tx_err);
23142+ atomic_inc_unchecked(&vcc->stats->tx_err);
23143 dev_kfree_skb_any(skb);
23144 return -EINVAL;
23145 }
bc901d79 23146@@ -1725,11 +1725,11 @@ static int ns_send(struct atm_vcc *vcc,
6892158b
MT
23147 }
23148
23149 if (push_scqe(card, vc, scq, &scqe, skb) != 0) {
23150- atomic_inc(&vcc->stats->tx_err);
23151+ atomic_inc_unchecked(&vcc->stats->tx_err);
23152 dev_kfree_skb_any(skb);
23153 return -EIO;
23154 }
23155- atomic_inc(&vcc->stats->tx);
23156+ atomic_inc_unchecked(&vcc->stats->tx);
23157
23158 return 0;
23159 }
bc901d79 23160@@ -2046,14 +2046,14 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23161 printk
23162 ("nicstar%d: Can't allocate buffers for aal0.\n",
23163 card->index);
23164- atomic_add(i, &vcc->stats->rx_drop);
23165+ atomic_add_unchecked(i, &vcc->stats->rx_drop);
23166 break;
23167 }
23168 if (!atm_charge(vcc, sb->truesize)) {
23169 RXPRINTK
23170 ("nicstar%d: atm_charge() dropped aal0 packets.\n",
23171 card->index);
23172- atomic_add(i - 1, &vcc->stats->rx_drop); /* already increased by 1 */
23173+ atomic_add_unchecked(i - 1, &vcc->stats->rx_drop); /* already increased by 1 */
23174 dev_kfree_skb_any(sb);
23175 break;
23176 }
bc901d79 23177@@ -2068,7 +2068,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23178 ATM_SKB(sb)->vcc = vcc;
23179 __net_timestamp(sb);
23180 vcc->push(vcc, sb);
23181- atomic_inc(&vcc->stats->rx);
23182+ atomic_inc_unchecked(&vcc->stats->rx);
23183 cell += ATM_CELL_PAYLOAD;
23184 }
23185
bc901d79 23186@@ -2085,7 +2085,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23187 if (iovb == NULL) {
23188 printk("nicstar%d: Out of iovec buffers.\n",
23189 card->index);
23190- atomic_inc(&vcc->stats->rx_drop);
23191+ atomic_inc_unchecked(&vcc->stats->rx_drop);
23192 recycle_rx_buf(card, skb);
23193 return;
23194 }
bc901d79 23195@@ -2109,7 +2109,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23196 small or large buffer itself. */
23197 } else if (NS_PRV_IOVCNT(iovb) >= NS_MAX_IOVECS) {
23198 printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
23199- atomic_inc(&vcc->stats->rx_err);
23200+ atomic_inc_unchecked(&vcc->stats->rx_err);
23201 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
23202 NS_MAX_IOVECS);
23203 NS_PRV_IOVCNT(iovb) = 0;
bc901d79 23204@@ -2129,7 +2129,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23205 ("nicstar%d: Expected a small buffer, and this is not one.\n",
23206 card->index);
23207 which_list(card, skb);
23208- atomic_inc(&vcc->stats->rx_err);
23209+ atomic_inc_unchecked(&vcc->stats->rx_err);
23210 recycle_rx_buf(card, skb);
23211 vc->rx_iov = NULL;
23212 recycle_iov_buf(card, iovb);
bc901d79 23213@@ -2142,7 +2142,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23214 ("nicstar%d: Expected a large buffer, and this is not one.\n",
23215 card->index);
23216 which_list(card, skb);
23217- atomic_inc(&vcc->stats->rx_err);
23218+ atomic_inc_unchecked(&vcc->stats->rx_err);
23219 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
23220 NS_PRV_IOVCNT(iovb));
23221 vc->rx_iov = NULL;
bc901d79 23222@@ -2165,7 +2165,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23223 printk(" - PDU size mismatch.\n");
23224 else
23225 printk(".\n");
23226- atomic_inc(&vcc->stats->rx_err);
23227+ atomic_inc_unchecked(&vcc->stats->rx_err);
23228 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
23229 NS_PRV_IOVCNT(iovb));
23230 vc->rx_iov = NULL;
bc901d79 23231@@ -2179,7 +2179,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23232 /* skb points to a small buffer */
23233 if (!atm_charge(vcc, skb->truesize)) {
23234 push_rxbufs(card, skb);
23235- atomic_inc(&vcc->stats->rx_drop);
23236+ atomic_inc_unchecked(&vcc->stats->rx_drop);
23237 } else {
23238 skb_put(skb, len);
23239 dequeue_sm_buf(card, skb);
bc901d79 23240@@ -2189,7 +2189,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23241 ATM_SKB(skb)->vcc = vcc;
23242 __net_timestamp(skb);
23243 vcc->push(vcc, skb);
23244- atomic_inc(&vcc->stats->rx);
23245+ atomic_inc_unchecked(&vcc->stats->rx);
23246 }
23247 } else if (NS_PRV_IOVCNT(iovb) == 2) { /* One small plus one large buffer */
23248 struct sk_buff *sb;
bc901d79 23249@@ -2200,7 +2200,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23250 if (len <= NS_SMBUFSIZE) {
23251 if (!atm_charge(vcc, sb->truesize)) {
23252 push_rxbufs(card, sb);
23253- atomic_inc(&vcc->stats->rx_drop);
23254+ atomic_inc_unchecked(&vcc->stats->rx_drop);
23255 } else {
23256 skb_put(sb, len);
23257 dequeue_sm_buf(card, sb);
bc901d79 23258@@ -2210,7 +2210,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23259 ATM_SKB(sb)->vcc = vcc;
23260 __net_timestamp(sb);
23261 vcc->push(vcc, sb);
23262- atomic_inc(&vcc->stats->rx);
23263+ atomic_inc_unchecked(&vcc->stats->rx);
23264 }
23265
23266 push_rxbufs(card, skb);
bc901d79 23267@@ -2219,7 +2219,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23268
23269 if (!atm_charge(vcc, skb->truesize)) {
23270 push_rxbufs(card, skb);
23271- atomic_inc(&vcc->stats->rx_drop);
23272+ atomic_inc_unchecked(&vcc->stats->rx_drop);
23273 } else {
23274 dequeue_lg_buf(card, skb);
23275 #ifdef NS_USE_DESTRUCTORS
bc901d79 23276@@ -2232,7 +2232,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23277 ATM_SKB(skb)->vcc = vcc;
23278 __net_timestamp(skb);
23279 vcc->push(vcc, skb);
23280- atomic_inc(&vcc->stats->rx);
23281+ atomic_inc_unchecked(&vcc->stats->rx);
23282 }
23283
23284 push_rxbufs(card, sb);
bc901d79 23285@@ -2253,7 +2253,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23286 printk
23287 ("nicstar%d: Out of huge buffers.\n",
23288 card->index);
23289- atomic_inc(&vcc->stats->rx_drop);
23290+ atomic_inc_unchecked(&vcc->stats->rx_drop);
23291 recycle_iovec_rx_bufs(card,
23292 (struct iovec *)
23293 iovb->data,
bc901d79 23294@@ -2304,7 +2304,7 @@ static void dequeue_rx(ns_dev * card, ns
6892158b
MT
23295 card->hbpool.count++;
23296 } else
23297 dev_kfree_skb_any(hb);
23298- atomic_inc(&vcc->stats->rx_drop);
23299+ atomic_inc_unchecked(&vcc->stats->rx_drop);
23300 } else {
23301 /* Copy the small buffer to the huge buffer */
23302 sb = (struct sk_buff *)iov->iov_base;
bc901d79 23303@@ -2341,7 +2341,7 @@ static void dequeue_rx(ns_dev * card, ns
58c5fc13 23304 #endif /* NS_USE_DESTRUCTORS */
6892158b
MT
23305 __net_timestamp(hb);
23306 vcc->push(vcc, hb);
23307- atomic_inc(&vcc->stats->rx);
23308+ atomic_inc_unchecked(&vcc->stats->rx);
23309 }
23310 }
58c5fc13 23311
16454cff
MT
23312diff -urNp linux-2.6.38.1/drivers/atm/solos-pci.c linux-2.6.38.1/drivers/atm/solos-pci.c
23313--- linux-2.6.38.1/drivers/atm/solos-pci.c 2011-03-14 21:20:32.000000000 -0400
23314+++ linux-2.6.38.1/drivers/atm/solos-pci.c 2011-03-21 18:31:35.000000000 -0400
6892158b 23315@@ -717,7 +717,7 @@ void solos_bh(unsigned long card_arg)
58c5fc13
MT
23316 }
23317 atm_charge(vcc, skb->truesize);
23318 vcc->push(vcc, skb);
23319- atomic_inc(&vcc->stats->rx);
23320+ atomic_inc_unchecked(&vcc->stats->rx);
23321 break;
23322
23323 case PKT_STATUS:
16454cff 23324@@ -1026,7 +1026,7 @@ static uint32_t fpga_tx(struct solos_car
58c5fc13
MT
23325 vcc = SKB_CB(oldskb)->vcc;
23326
23327 if (vcc) {
23328- atomic_inc(&vcc->stats->tx);
23329+ atomic_inc_unchecked(&vcc->stats->tx);
23330 solos_pop(vcc, oldskb);
23331 } else
23332 dev_kfree_skb_irq(oldskb);
16454cff
MT
23333diff -urNp linux-2.6.38.1/drivers/atm/suni.c linux-2.6.38.1/drivers/atm/suni.c
23334--- linux-2.6.38.1/drivers/atm/suni.c 2011-03-14 21:20:32.000000000 -0400
23335+++ linux-2.6.38.1/drivers/atm/suni.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 23336@@ -50,8 +50,8 @@ static DEFINE_SPINLOCK(sunis_lock);
58c5fc13
MT
23337
23338
23339 #define ADD_LIMITED(s,v) \
23340- atomic_add((v),&stats->s); \
23341- if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX);
23342+ atomic_add_unchecked((v),&stats->s); \
23343+ if (atomic_read_unchecked(&stats->s) < 0) atomic_set_unchecked(&stats->s,INT_MAX);
23344
23345
23346 static void suni_hz(unsigned long from_timer)
16454cff
MT
23347diff -urNp linux-2.6.38.1/drivers/atm/uPD98402.c linux-2.6.38.1/drivers/atm/uPD98402.c
23348--- linux-2.6.38.1/drivers/atm/uPD98402.c 2011-03-14 21:20:32.000000000 -0400
23349+++ linux-2.6.38.1/drivers/atm/uPD98402.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 23350@@ -42,7 +42,7 @@ static int fetch_stats(struct atm_dev *d
58c5fc13
MT
23351 struct sonet_stats tmp;
23352 int error = 0;
23353
23354- atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
23355+ atomic_add_unchecked(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
23356 sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
23357 if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
23358 if (zero && !error) {
df50ba0c 23359@@ -161,9 +161,9 @@ static int uPD98402_ioctl(struct atm_dev
58c5fc13
MT
23360
23361
23362 #define ADD_LIMITED(s,v) \
23363- { atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \
23364- if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \
23365- atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); }
23366+ { atomic_add_unchecked(GET(v),&PRIV(dev)->sonet_stats.s); \
23367+ if (atomic_read_unchecked(&PRIV(dev)->sonet_stats.s) < 0) \
23368+ atomic_set_unchecked(&PRIV(dev)->sonet_stats.s,INT_MAX); }
23369
23370
23371 static void stat_event(struct atm_dev *dev)
df50ba0c 23372@@ -194,7 +194,7 @@ static void uPD98402_int(struct atm_dev
58c5fc13
MT
23373 if (reason & uPD98402_INT_PFM) stat_event(dev);
23374 if (reason & uPD98402_INT_PCO) {
23375 (void) GET(PCOCR); /* clear interrupt cause */
23376- atomic_add(GET(HECCT),
23377+ atomic_add_unchecked(GET(HECCT),
23378 &PRIV(dev)->sonet_stats.uncorr_hcs);
23379 }
23380 if ((reason & uPD98402_INT_RFO) &&
df50ba0c 23381@@ -222,9 +222,9 @@ static int uPD98402_start(struct atm_dev
58c5fc13
MT
23382 PUT(~(uPD98402_INT_PFM | uPD98402_INT_ALM | uPD98402_INT_RFO |
23383 uPD98402_INT_LOS),PIMR); /* enable them */
23384 (void) fetch_stats(dev,NULL,1); /* clear kernel counters */
23385- atomic_set(&PRIV(dev)->sonet_stats.corr_hcs,-1);
23386- atomic_set(&PRIV(dev)->sonet_stats.tx_cells,-1);
23387- atomic_set(&PRIV(dev)->sonet_stats.rx_cells,-1);
23388+ atomic_set_unchecked(&PRIV(dev)->sonet_stats.corr_hcs,-1);
23389+ atomic_set_unchecked(&PRIV(dev)->sonet_stats.tx_cells,-1);
23390+ atomic_set_unchecked(&PRIV(dev)->sonet_stats.rx_cells,-1);
23391 return 0;
23392 }
23393
16454cff
MT
23394diff -urNp linux-2.6.38.1/drivers/atm/zatm.c linux-2.6.38.1/drivers/atm/zatm.c
23395--- linux-2.6.38.1/drivers/atm/zatm.c 2011-03-14 21:20:32.000000000 -0400
23396+++ linux-2.6.38.1/drivers/atm/zatm.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 23397@@ -459,7 +459,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
58c5fc13
MT
23398 }
23399 if (!size) {
23400 dev_kfree_skb_irq(skb);
23401- if (vcc) atomic_inc(&vcc->stats->rx_err);
23402+ if (vcc) atomic_inc_unchecked(&vcc->stats->rx_err);
23403 continue;
23404 }
23405 if (!atm_charge(vcc,skb->truesize)) {
df50ba0c 23406@@ -469,7 +469,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
58c5fc13
MT
23407 skb->len = size;
23408 ATM_SKB(skb)->vcc = vcc;
23409 vcc->push(vcc,skb);
23410- atomic_inc(&vcc->stats->rx);
23411+ atomic_inc_unchecked(&vcc->stats->rx);
23412 }
23413 zout(pos & 0xffff,MTA(mbx));
23414 #if 0 /* probably a stupid idea */
df50ba0c 23415@@ -733,7 +733,7 @@ if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD
58c5fc13
MT
23416 skb_queue_head(&zatm_vcc->backlog,skb);
23417 break;
23418 }
23419- atomic_inc(&vcc->stats->tx);
23420+ atomic_inc_unchecked(&vcc->stats->tx);
23421 wake_up(&zatm_vcc->tx_wait);
23422 }
23423
16454cff
MT
23424diff -urNp linux-2.6.38.1/drivers/block/cciss.c linux-2.6.38.1/drivers/block/cciss.c
23425--- linux-2.6.38.1/drivers/block/cciss.c 2011-03-14 21:20:32.000000000 -0400
23426+++ linux-2.6.38.1/drivers/block/cciss.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
23427@@ -1112,6 +1112,8 @@ static int cciss_ioctl32_passthru(struct
23428 int err;
23429 u32 cp;
23430
23431+ memset(&arg64, 0, sizeof(arg64));
23432+
23433 err = 0;
23434 err |=
23435 copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
16454cff
MT
23436diff -urNp linux-2.6.38.1/drivers/char/agp/frontend.c linux-2.6.38.1/drivers/char/agp/frontend.c
23437--- linux-2.6.38.1/drivers/char/agp/frontend.c 2011-03-14 21:20:32.000000000 -0400
23438+++ linux-2.6.38.1/drivers/char/agp/frontend.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 23439@@ -817,7 +817,7 @@ static int agpioc_reserve_wrap(struct ag
58c5fc13
MT
23440 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
23441 return -EFAULT;
23442
23443- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
23444+ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
23445 return -EFAULT;
23446
23447 client = agp_find_client_by_pid(reserve.pid);
16454cff
MT
23448diff -urNp linux-2.6.38.1/drivers/char/agp/intel-agp.c linux-2.6.38.1/drivers/char/agp/intel-agp.c
23449--- linux-2.6.38.1/drivers/char/agp/intel-agp.c 2011-03-14 21:20:32.000000000 -0400
23450+++ linux-2.6.38.1/drivers/char/agp/intel-agp.c 2011-03-21 18:31:35.000000000 -0400
23451@@ -903,7 +903,7 @@ static struct pci_device_id agp_intel_pc
df50ba0c
MT
23452 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
23453 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
6892158b 23454 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
58c5fc13
MT
23455- { }
23456+ { 0, 0, 0, 0, 0, 0, 0 }
23457 };
23458
23459 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
16454cff
MT
23460diff -urNp linux-2.6.38.1/drivers/char/hpet.c linux-2.6.38.1/drivers/char/hpet.c
23461--- linux-2.6.38.1/drivers/char/hpet.c 2011-03-14 21:20:32.000000000 -0400
23462+++ linux-2.6.38.1/drivers/char/hpet.c 2011-03-21 18:31:35.000000000 -0400
57199397 23463@@ -553,7 +553,7 @@ static inline unsigned long hpet_time_di
ae4e228f
MT
23464 }
23465
df50ba0c 23466 static int
bc901d79
MT
23467-hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg,
23468+hpet_ioctl_common(struct hpet_dev *devp, unsigned int cmd, unsigned long arg,
23469 struct hpet_info *info)
ae4e228f 23470 {
df50ba0c 23471 struct hpet_timer __iomem *timer;
bc901d79 23472@@ -1043,7 +1043,7 @@ static struct acpi_driver hpet_acpi_driv
df50ba0c 23473 },
ae4e228f
MT
23474 };
23475
df50ba0c
MT
23476-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
23477+static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
ae4e228f 23478
df50ba0c
MT
23479 static int __init hpet_init(void)
23480 {
16454cff
MT
23481diff -urNp linux-2.6.38.1/drivers/char/ipmi/ipmi_msghandler.c linux-2.6.38.1/drivers/char/ipmi/ipmi_msghandler.c
23482--- linux-2.6.38.1/drivers/char/ipmi/ipmi_msghandler.c 2011-03-14 21:20:32.000000000 -0400
23483+++ linux-2.6.38.1/drivers/char/ipmi/ipmi_msghandler.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 23484@@ -414,7 +414,7 @@ struct ipmi_smi {
58c5fc13
MT
23485 struct proc_dir_entry *proc_dir;
23486 char proc_dir_name[10];
23487
23488- atomic_t stats[IPMI_NUM_STATS];
23489+ atomic_unchecked_t stats[IPMI_NUM_STATS];
23490
23491 /*
23492 * run_to_completion duplicate of smb_info, smi_info
ae4e228f 23493@@ -447,9 +447,9 @@ static DEFINE_MUTEX(smi_watchers_mutex);
58c5fc13
MT
23494
23495
23496 #define ipmi_inc_stat(intf, stat) \
23497- atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
23498+ atomic_inc_unchecked(&(intf)->stats[IPMI_STAT_ ## stat])
23499 #define ipmi_get_stat(intf, stat) \
23500- ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
23501+ ((unsigned int) atomic_read_unchecked(&(intf)->stats[IPMI_STAT_ ## stat]))
23502
23503 static int is_lan_addr(struct ipmi_addr *addr)
23504 {
16454cff 23505@@ -2844,7 +2844,7 @@ int ipmi_register_smi(struct ipmi_smi_ha
58c5fc13
MT
23506 INIT_LIST_HEAD(&intf->cmd_rcvrs);
23507 init_waitqueue_head(&intf->waitq);
23508 for (i = 0; i < IPMI_NUM_STATS; i++)
23509- atomic_set(&intf->stats[i], 0);
23510+ atomic_set_unchecked(&intf->stats[i], 0);
23511
23512 intf->proc_dir = NULL;
23513
16454cff
MT
23514diff -urNp linux-2.6.38.1/drivers/char/ipmi/ipmi_si_intf.c linux-2.6.38.1/drivers/char/ipmi/ipmi_si_intf.c
23515--- linux-2.6.38.1/drivers/char/ipmi/ipmi_si_intf.c 2011-03-14 21:20:32.000000000 -0400
23516+++ linux-2.6.38.1/drivers/char/ipmi/ipmi_si_intf.c 2011-03-21 18:31:35.000000000 -0400
23517@@ -285,7 +285,7 @@ struct smi_info {
58c5fc13
MT
23518 unsigned char slave_addr;
23519
23520 /* Counters and things for the proc filesystem. */
23521- atomic_t stats[SI_NUM_STATS];
23522+ atomic_unchecked_t stats[SI_NUM_STATS];
23523
23524 struct task_struct *thread;
23525
57199397 23526@@ -294,9 +294,9 @@ struct smi_info {
58c5fc13
MT
23527 };
23528
23529 #define smi_inc_stat(smi, stat) \
23530- atomic_inc(&(smi)->stats[SI_STAT_ ## stat])
23531+ atomic_inc_unchecked(&(smi)->stats[SI_STAT_ ## stat])
23532 #define smi_get_stat(smi, stat) \
23533- ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat]))
23534+ ((unsigned int) atomic_read_unchecked(&(smi)->stats[SI_STAT_ ## stat]))
23535
23536 #define SI_MAX_PARMS 4
23537
16454cff 23538@@ -3202,7 +3202,7 @@ static int try_smi_init(struct smi_info
58c5fc13
MT
23539 atomic_set(&new_smi->req_events, 0);
23540 new_smi->run_to_completion = 0;
23541 for (i = 0; i < SI_NUM_STATS; i++)
23542- atomic_set(&new_smi->stats[i], 0);
23543+ atomic_set_unchecked(&new_smi->stats[i], 0);
23544
57199397 23545 new_smi->interrupt_disabled = 1;
58c5fc13 23546 atomic_set(&new_smi->stop_operation, 0);
16454cff
MT
23547diff -urNp linux-2.6.38.1/drivers/char/mem.c linux-2.6.38.1/drivers/char/mem.c
23548--- linux-2.6.38.1/drivers/char/mem.c 2011-03-14 21:20:32.000000000 -0400
23549+++ linux-2.6.38.1/drivers/char/mem.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
23550@@ -18,6 +18,7 @@
23551 #include <linux/raw.h>
23552 #include <linux/tty.h>
23553 #include <linux/capability.h>
23554+#include <linux/security.h>
23555 #include <linux/ptrace.h>
23556 #include <linux/device.h>
23557 #include <linux/highmem.h>
ae4e228f 23558@@ -34,6 +35,10 @@
58c5fc13
MT
23559 # include <linux/efi.h>
23560 #endif
23561
23562+#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
23563+extern struct file_operations grsec_fops;
23564+#endif
23565+
ae4e228f
MT
23566 static inline unsigned long size_inside_page(unsigned long start,
23567 unsigned long size)
23568 {
57199397
MT
23569@@ -120,6 +125,7 @@ static ssize_t read_mem(struct file *fil
23570
23571 while (count > 0) {
23572 unsigned long remaining;
23573+ char *temp;
23574
23575 sz = size_inside_page(p, count);
23576
23577@@ -135,7 +141,23 @@ static ssize_t read_mem(struct file *fil
23578 if (!ptr)
23579 return -EFAULT;
23580
23581- remaining = copy_to_user(buf, ptr, sz);
23582+#ifdef CONFIG_PAX_USERCOPY
23583+ temp = kmalloc(sz, GFP_KERNEL);
23584+ if (!temp) {
23585+ unxlate_dev_mem_ptr(p, ptr);
23586+ return -ENOMEM;
23587+ }
23588+ memcpy(temp, ptr, sz);
23589+#else
23590+ temp = ptr;
23591+#endif
23592+
23593+ remaining = copy_to_user(buf, temp, sz);
23594+
23595+#ifdef CONFIG_PAX_USERCOPY
23596+ kfree(temp);
23597+#endif
23598+
23599 unxlate_dev_mem_ptr(p, ptr);
23600 if (remaining)
23601 return -EFAULT;
23602@@ -161,6 +183,11 @@ static ssize_t write_mem(struct file *fi
58c5fc13
MT
23603 if (!valid_phys_addr_range(p, count))
23604 return -EFAULT;
23605
23606+#ifdef CONFIG_GRKERNSEC_KMEM
23607+ gr_handle_mem_write();
23608+ return -EPERM;
23609+#endif
23610+
23611 written = 0;
23612
23613 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
57199397 23614@@ -316,6 +343,11 @@ static int mmap_mem(struct file *file, s
58c5fc13
MT
23615 &vma->vm_page_prot))
23616 return -EINVAL;
23617
23618+#ifdef CONFIG_GRKERNSEC_KMEM
23619+ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
23620+ return -EPERM;
23621+#endif
23622+
23623 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
23624 size,
23625 vma->vm_page_prot);
57199397
MT
23626@@ -398,9 +430,8 @@ static ssize_t read_kmem(struct file *fi
23627 size_t count, loff_t *ppos)
23628 {
23629 unsigned long p = *ppos;
23630- ssize_t low_count, read, sz;
23631+ ssize_t low_count, read, sz, err = 0;
23632 char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
23633- int err = 0;
23634
23635 read = 0;
23636 if (p < (unsigned long) high_memory) {
23637@@ -422,6 +453,8 @@ static ssize_t read_kmem(struct file *fi
23638 }
23639 #endif
23640 while (low_count > 0) {
23641+ char *temp;
23642+
23643 sz = size_inside_page(p, low_count);
23644
23645 /*
23646@@ -431,7 +464,22 @@ static ssize_t read_kmem(struct file *fi
23647 */
23648 kbuf = xlate_dev_kmem_ptr((char *)p);
23649
23650- if (copy_to_user(buf, kbuf, sz))
23651+#ifdef CONFIG_PAX_USERCOPY
23652+ temp = kmalloc(sz, GFP_KERNEL);
23653+ if (!temp)
23654+ return -ENOMEM;
23655+ memcpy(temp, kbuf, sz);
23656+#else
23657+ temp = kbuf;
23658+#endif
23659+
23660+ err = copy_to_user(buf, temp, sz);
23661+
23662+#ifdef CONFIG_PAX_USERCOPY
23663+ kfree(temp);
23664+#endif
23665+
23666+ if (err)
23667 return -EFAULT;
23668 buf += sz;
23669 p += sz;
23670@@ -530,6 +578,11 @@ static ssize_t write_kmem(struct file *f
58c5fc13 23671 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
ae4e228f 23672 int err = 0;
58c5fc13
MT
23673
23674+#ifdef CONFIG_GRKERNSEC_KMEM
23675+ gr_handle_kmem_write();
23676+ return -EPERM;
23677+#endif
23678+
23679 if (p < (unsigned long) high_memory) {
ae4e228f
MT
23680 unsigned long to_write = min_t(unsigned long, count,
23681 (unsigned long)high_memory - p);
57199397 23682@@ -731,6 +784,16 @@ static loff_t memory_lseek(struct file *
58c5fc13
MT
23683
23684 static int open_port(struct inode * inode, struct file * filp)
23685 {
23686+#ifdef CONFIG_GRKERNSEC_KMEM
23687+ gr_handle_open_port();
23688+ return -EPERM;
23689+#endif
23690+
23691+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
23692+}
23693+
23694+static int open_mem(struct inode * inode, struct file * filp)
23695+{
23696 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
23697 }
23698
57199397 23699@@ -738,7 +801,6 @@ static int open_port(struct inode * inod
58c5fc13
MT
23700 #define full_lseek null_lseek
23701 #define write_zero write_null
23702 #define read_full read_zero
23703-#define open_mem open_port
23704 #define open_kmem open_mem
23705 #define open_oldmem open_mem
23706
bc901d79 23707@@ -857,6 +919,9 @@ static const struct memdev {
58c5fc13 23708 #ifdef CONFIG_CRASH_DUMP
ae4e228f 23709 [12] = { "oldmem", 0, &oldmem_fops, NULL },
58c5fc13
MT
23710 #endif
23711+#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
ae4e228f 23712+ [13] = { "grsec",S_IRUSR | S_IWUGO, &grsec_fops, NULL },
58c5fc13
MT
23713+#endif
23714 };
23715
23716 static int memory_open(struct inode *inode, struct file *filp)
16454cff
MT
23717diff -urNp linux-2.6.38.1/drivers/char/nvram.c linux-2.6.38.1/drivers/char/nvram.c
23718--- linux-2.6.38.1/drivers/char/nvram.c 2011-03-14 21:20:32.000000000 -0400
23719+++ linux-2.6.38.1/drivers/char/nvram.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 23720@@ -246,7 +246,7 @@ static ssize_t nvram_read(struct file *f
ae4e228f
MT
23721
23722 spin_unlock_irq(&rtc_lock);
58c5fc13 23723
ae4e228f
MT
23724- if (copy_to_user(buf, contents, tmp - contents))
23725+ if (tmp - contents > sizeof(contents) || copy_to_user(buf, contents, tmp - contents))
23726 return -EFAULT;
23727
23728 *ppos = i;
bc901d79 23729@@ -435,7 +435,10 @@ static const struct file_operations nvra
58c5fc13
MT
23730 static struct miscdevice nvram_dev = {
23731 NVRAM_MINOR,
23732 "nvram",
23733- &nvram_fops
23734+ &nvram_fops,
23735+ {NULL, NULL},
23736+ NULL,
23737+ NULL
23738 };
23739
23740 static int __init nvram_init(void)
16454cff
MT
23741diff -urNp linux-2.6.38.1/drivers/char/pcmcia/ipwireless/tty.c linux-2.6.38.1/drivers/char/pcmcia/ipwireless/tty.c
23742--- linux-2.6.38.1/drivers/char/pcmcia/ipwireless/tty.c 2011-03-14 21:20:32.000000000 -0400
23743+++ linux-2.6.38.1/drivers/char/pcmcia/ipwireless/tty.c 2011-03-21 18:31:35.000000000 -0400
c52201e0
MT
23744@@ -29,6 +29,7 @@
23745 #include <linux/tty_driver.h>
23746 #include <linux/tty_flip.h>
23747 #include <linux/uaccess.h>
23748+#include <asm/local.h>
23749
23750 #include "tty.h"
23751 #include "network.h"
23752@@ -51,7 +52,7 @@ struct ipw_tty {
58c5fc13
MT
23753 int tty_type;
23754 struct ipw_network *network;
23755 struct tty_struct *linux_tty;
23756- int open_count;
c52201e0 23757+ local_t open_count;
58c5fc13
MT
23758 unsigned int control_lines;
23759 struct mutex ipw_tty_mutex;
23760 int tx_bytes_queued;
c52201e0 23761@@ -127,10 +128,10 @@ static int ipw_open(struct tty_struct *l
58c5fc13
MT
23762 mutex_unlock(&tty->ipw_tty_mutex);
23763 return -ENODEV;
23764 }
23765- if (tty->open_count == 0)
c52201e0 23766+ if (local_read(&tty->open_count) == 0)
58c5fc13
MT
23767 tty->tx_bytes_queued = 0;
23768
23769- tty->open_count++;
c52201e0 23770+ local_inc(&tty->open_count);
58c5fc13
MT
23771
23772 tty->linux_tty = linux_tty;
23773 linux_tty->driver_data = tty;
c52201e0 23774@@ -146,9 +147,7 @@ static int ipw_open(struct tty_struct *l
58c5fc13
MT
23775
23776 static void do_ipw_close(struct ipw_tty *tty)
23777 {
23778- tty->open_count--;
23779-
23780- if (tty->open_count == 0) {
c52201e0 23781+ if (local_dec_return(&tty->open_count) == 0) {
58c5fc13
MT
23782 struct tty_struct *linux_tty = tty->linux_tty;
23783
23784 if (linux_tty != NULL) {
c52201e0 23785@@ -169,7 +168,7 @@ static void ipw_hangup(struct tty_struct
58c5fc13
MT
23786 return;
23787
23788 mutex_lock(&tty->ipw_tty_mutex);
23789- if (tty->open_count == 0) {
c52201e0 23790+ if (local_read(&tty->open_count) == 0) {
58c5fc13
MT
23791 mutex_unlock(&tty->ipw_tty_mutex);
23792 return;
23793 }
c52201e0 23794@@ -198,7 +197,7 @@ void ipwireless_tty_received(struct ipw_
58c5fc13
MT
23795 return;
23796 }
23797
23798- if (!tty->open_count) {
c52201e0 23799+ if (!local_read(&tty->open_count)) {
58c5fc13
MT
23800 mutex_unlock(&tty->ipw_tty_mutex);
23801 return;
23802 }
c52201e0 23803@@ -240,7 +239,7 @@ static int ipw_write(struct tty_struct *
58c5fc13
MT
23804 return -ENODEV;
23805
23806 mutex_lock(&tty->ipw_tty_mutex);
23807- if (!tty->open_count) {
c52201e0 23808+ if (!local_read(&tty->open_count)) {
58c5fc13
MT
23809 mutex_unlock(&tty->ipw_tty_mutex);
23810 return -EINVAL;
23811 }
c52201e0 23812@@ -280,7 +279,7 @@ static int ipw_write_room(struct tty_str
58c5fc13
MT
23813 if (!tty)
23814 return -ENODEV;
23815
23816- if (!tty->open_count)
c52201e0 23817+ if (!local_read(&tty->open_count))
58c5fc13
MT
23818 return -EINVAL;
23819
23820 room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
c52201e0 23821@@ -322,7 +321,7 @@ static int ipw_chars_in_buffer(struct tt
58c5fc13
MT
23822 if (!tty)
23823 return 0;
23824
23825- if (!tty->open_count)
c52201e0 23826+ if (!local_read(&tty->open_count))
58c5fc13
MT
23827 return 0;
23828
23829 return tty->tx_bytes_queued;
c52201e0 23830@@ -403,7 +402,7 @@ static int ipw_tiocmget(struct tty_struc
58c5fc13
MT
23831 if (!tty)
23832 return -ENODEV;
23833
23834- if (!tty->open_count)
c52201e0 23835+ if (!local_read(&tty->open_count))
58c5fc13
MT
23836 return -EINVAL;
23837
23838 return get_control_lines(tty);
c52201e0 23839@@ -419,7 +418,7 @@ ipw_tiocmset(struct tty_struct *linux_tt
58c5fc13
MT
23840 if (!tty)
23841 return -ENODEV;
23842
23843- if (!tty->open_count)
c52201e0 23844+ if (!local_read(&tty->open_count))
58c5fc13
MT
23845 return -EINVAL;
23846
23847 return set_control_lines(tty, set, clear);
c52201e0 23848@@ -433,7 +432,7 @@ static int ipw_ioctl(struct tty_struct *
58c5fc13
MT
23849 if (!tty)
23850 return -ENODEV;
23851
23852- if (!tty->open_count)
c52201e0 23853+ if (!local_read(&tty->open_count))
58c5fc13
MT
23854 return -EINVAL;
23855
23856 /* FIXME: Exactly how is the tty object locked here .. */
c52201e0 23857@@ -582,7 +581,7 @@ void ipwireless_tty_free(struct ipw_tty
58c5fc13
MT
23858 against a parallel ioctl etc */
23859 mutex_lock(&ttyj->ipw_tty_mutex);
23860 }
23861- while (ttyj->open_count)
c52201e0 23862+ while (local_read(&ttyj->open_count))
58c5fc13
MT
23863 do_ipw_close(ttyj);
23864 ipwireless_disassociate_network_ttys(network,
23865 ttyj->channel_idx);
16454cff
MT
23866diff -urNp linux-2.6.38.1/drivers/char/random.c linux-2.6.38.1/drivers/char/random.c
23867--- linux-2.6.38.1/drivers/char/random.c 2011-03-14 21:20:32.000000000 -0400
23868+++ linux-2.6.38.1/drivers/char/random.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 23869@@ -254,8 +254,13 @@
58c5fc13
MT
23870 /*
23871 * Configuration information
23872 */
23873+#ifdef CONFIG_GRKERNSEC_RANDNET
23874+#define INPUT_POOL_WORDS 512
23875+#define OUTPUT_POOL_WORDS 128
23876+#else
23877 #define INPUT_POOL_WORDS 128
23878 #define OUTPUT_POOL_WORDS 32
23879+#endif
23880 #define SEC_XFER_SIZE 512
57199397 23881 #define EXTRACT_SIZE 10
58c5fc13 23882
57199397 23883@@ -293,10 +298,17 @@ static struct poolinfo {
58c5fc13
MT
23884 int poolwords;
23885 int tap1, tap2, tap3, tap4, tap5;
23886 } poolinfo_table[] = {
23887+#ifdef CONFIG_GRKERNSEC_RANDNET
23888+ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
23889+ { 512, 411, 308, 208, 104, 1 },
23890+ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
23891+ { 128, 103, 76, 51, 25, 1 },
23892+#else
23893 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
23894 { 128, 103, 76, 51, 25, 1 },
23895 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
23896 { 32, 26, 20, 14, 7, 1 },
23897+#endif
23898 #if 0
23899 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
23900 { 2048, 1638, 1231, 819, 411, 1 },
57199397 23901@@ -902,7 +914,7 @@ static ssize_t extract_entropy_user(stru
ae4e228f
MT
23902
23903 extract_buf(r, tmp);
23904 i = min_t(int, nbytes, EXTRACT_SIZE);
23905- if (copy_to_user(buf, tmp, i)) {
23906+ if (i > sizeof(tmp) || copy_to_user(buf, tmp, i)) {
23907 ret = -EFAULT;
23908 break;
23909 }
bc901d79 23910@@ -1207,7 +1219,7 @@ EXPORT_SYMBOL(generate_random_uuid);
58c5fc13
MT
23911 #include <linux/sysctl.h>
23912
23913 static int min_read_thresh = 8, min_write_thresh;
23914-static int max_read_thresh = INPUT_POOL_WORDS * 32;
23915+static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
23916 static int max_write_thresh = INPUT_POOL_WORDS * 32;
23917 static char sysctl_bootid[16];
23918
16454cff
MT
23919diff -urNp linux-2.6.38.1/drivers/char/sonypi.c linux-2.6.38.1/drivers/char/sonypi.c
23920--- linux-2.6.38.1/drivers/char/sonypi.c 2011-03-14 21:20:32.000000000 -0400
23921+++ linux-2.6.38.1/drivers/char/sonypi.c 2011-03-21 18:31:35.000000000 -0400
c52201e0
MT
23922@@ -55,6 +55,7 @@
23923 #include <asm/uaccess.h>
23924 #include <asm/io.h>
23925 #include <asm/system.h>
23926+#include <asm/local.h>
23927
23928 #include <linux/sonypi.h>
23929
23930@@ -491,7 +492,7 @@ static struct sonypi_device {
58c5fc13
MT
23931 spinlock_t fifo_lock;
23932 wait_queue_head_t fifo_proc_list;
23933 struct fasync_struct *fifo_async;
23934- int open_count;
c52201e0 23935+ local_t open_count;
58c5fc13
MT
23936 int model;
23937 struct input_dev *input_jog_dev;
23938 struct input_dev *input_key_dev;
c52201e0 23939@@ -898,7 +899,7 @@ static int sonypi_misc_fasync(int fd, st
58c5fc13
MT
23940 static int sonypi_misc_release(struct inode *inode, struct file *file)
23941 {
23942 mutex_lock(&sonypi_device.lock);
23943- sonypi_device.open_count--;
c52201e0 23944+ local_dec(&sonypi_device.open_count);
58c5fc13
MT
23945 mutex_unlock(&sonypi_device.lock);
23946 return 0;
23947 }
c52201e0 23948@@ -907,9 +908,9 @@ static int sonypi_misc_open(struct inode
ae4e228f 23949 {
58c5fc13
MT
23950 mutex_lock(&sonypi_device.lock);
23951 /* Flush input queue on first open */
23952- if (!sonypi_device.open_count)
c52201e0 23953+ if (!local_read(&sonypi_device.open_count))
ae4e228f 23954 kfifo_reset(&sonypi_device.fifo);
58c5fc13 23955- sonypi_device.open_count++;
c52201e0 23956+ local_inc(&sonypi_device.open_count);
58c5fc13 23957 mutex_unlock(&sonypi_device.lock);
ae4e228f 23958
58c5fc13 23959 return 0;
16454cff
MT
23960diff -urNp linux-2.6.38.1/drivers/char/tpm/tpm_bios.c linux-2.6.38.1/drivers/char/tpm/tpm_bios.c
23961--- linux-2.6.38.1/drivers/char/tpm/tpm_bios.c 2011-03-14 21:20:32.000000000 -0400
23962+++ linux-2.6.38.1/drivers/char/tpm/tpm_bios.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 23963@@ -173,7 +173,7 @@ static void *tpm_bios_measurements_start
ae4e228f
MT
23964 event = addr;
23965
23966 if ((event->event_type == 0 && event->event_size == 0) ||
23967- ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
23968+ (event->event_size >= limit - addr - sizeof(struct tcpa_event)))
23969 return NULL;
23970
23971 return addr;
df50ba0c 23972@@ -198,7 +198,7 @@ static void *tpm_bios_measurements_next(
ae4e228f
MT
23973 return NULL;
23974
23975 if ((event->event_type == 0 && event->event_size == 0) ||
23976- ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
23977+ (event->event_size >= limit - v - sizeof(struct tcpa_event)))
23978 return NULL;
23979
23980 (*pos)++;
df50ba0c 23981@@ -291,7 +291,8 @@ static int tpm_binary_bios_measurements_
ae4e228f
MT
23982 int i;
23983
23984 for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
23985- seq_putc(m, data[i]);
23986+ if (!seq_putc(m, data[i]))
23987+ return -EFAULT;
23988
58c5fc13
MT
23989 return 0;
23990 }
df50ba0c 23991@@ -410,6 +411,11 @@ static int read_log(struct tpm_bios_log
ae4e228f 23992 log->bios_event_log_end = log->bios_event_log + len;
58c5fc13 23993
ae4e228f
MT
23994 virt = acpi_os_map_memory(start, len);
23995+ if (!virt) {
23996+ kfree(log->bios_event_log);
23997+ log->bios_event_log = NULL;
23998+ return -EFAULT;
23999+ }
24000
24001 memcpy(log->bios_event_log, virt, len);
24002
16454cff
MT
24003diff -urNp linux-2.6.38.1/drivers/char/tpm/tpm.c linux-2.6.38.1/drivers/char/tpm/tpm.c
24004--- linux-2.6.38.1/drivers/char/tpm/tpm.c 2011-03-14 21:20:32.000000000 -0400
24005+++ linux-2.6.38.1/drivers/char/tpm/tpm.c 2011-03-21 18:31:35.000000000 -0400
24006@@ -411,7 +411,7 @@ static ssize_t tpm_transmit(struct tpm_c
24007 chip->vendor.req_complete_val)
24008 goto out_recv;
24009
24010- if ((status == chip->vendor.req_canceled)) {
24011+ if (status == chip->vendor.req_canceled) {
24012 dev_err(chip->dev, "Operation Canceled\n");
24013 rc = -ECANCELED;
24014 goto out;
24015diff -urNp linux-2.6.38.1/drivers/cpuidle/sysfs.c linux-2.6.38.1/drivers/cpuidle/sysfs.c
24016--- linux-2.6.38.1/drivers/cpuidle/sysfs.c 2011-03-14 21:20:32.000000000 -0400
24017+++ linux-2.6.38.1/drivers/cpuidle/sysfs.c 2011-03-21 18:31:35.000000000 -0400
57199397 24018@@ -300,7 +300,7 @@ static struct kobj_type ktype_state_cpui
df50ba0c 24019 .release = cpuidle_state_sysfs_release,
ae4e228f
MT
24020 };
24021
df50ba0c
MT
24022-static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
24023+static inline void cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
24024 {
24025 kobject_put(&device->kobjs[i]->kobj);
24026 wait_for_completion(&device->kobjs[i]->kobj_unregister);
16454cff
MT
24027diff -urNp linux-2.6.38.1/drivers/edac/edac_core.h linux-2.6.38.1/drivers/edac/edac_core.h
24028--- linux-2.6.38.1/drivers/edac/edac_core.h 2011-03-14 21:20:32.000000000 -0400
24029+++ linux-2.6.38.1/drivers/edac/edac_core.h 2011-03-21 18:31:35.000000000 -0400
24030@@ -88,11 +88,11 @@ extern int edac_debug_level;
58c5fc13
MT
24031
24032 #else /* !CONFIG_EDAC_DEBUG */
24033
24034-#define debugf0( ... )
24035-#define debugf1( ... )
24036-#define debugf2( ... )
24037-#define debugf3( ... )
24038-#define debugf4( ... )
24039+#define debugf0( ... ) do {} while (0)
24040+#define debugf1( ... ) do {} while (0)
24041+#define debugf2( ... ) do {} while (0)
24042+#define debugf3( ... ) do {} while (0)
24043+#define debugf4( ... ) do {} while (0)
24044
24045 #endif /* !CONFIG_EDAC_DEBUG */
24046
16454cff
MT
24047diff -urNp linux-2.6.38.1/drivers/edac/edac_mc_sysfs.c linux-2.6.38.1/drivers/edac/edac_mc_sysfs.c
24048--- linux-2.6.38.1/drivers/edac/edac_mc_sysfs.c 2011-03-14 21:20:32.000000000 -0400
24049+++ linux-2.6.38.1/drivers/edac/edac_mc_sysfs.c 2011-03-21 18:31:35.000000000 -0400
24050@@ -761,7 +761,7 @@ static void edac_inst_grp_release(struct
57199397
MT
24051 }
24052
24053 /* Intermediate show/store table */
24054-static struct sysfs_ops inst_grp_ops = {
24055+static const struct sysfs_ops inst_grp_ops = {
24056 .show = inst_grp_show,
24057 .store = inst_grp_store
24058 };
16454cff
MT
24059diff -urNp linux-2.6.38.1/drivers/firewire/core-cdev.c linux-2.6.38.1/drivers/firewire/core-cdev.c
24060--- linux-2.6.38.1/drivers/firewire/core-cdev.c 2011-03-14 21:20:32.000000000 -0400
24061+++ linux-2.6.38.1/drivers/firewire/core-cdev.c 2011-03-21 18:31:35.000000000 -0400
6892158b 24062@@ -1329,8 +1329,7 @@ static int init_iso_resource(struct clie
df50ba0c 24063 int ret;
ae4e228f 24064
df50ba0c
MT
24065 if ((request->channels == 0 && request->bandwidth == 0) ||
24066- request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL ||
24067- request->bandwidth < 0)
24068+ request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL)
24069 return -EINVAL;
ae4e228f 24070
df50ba0c 24071 r = kmalloc(sizeof(*r), GFP_KERNEL);
16454cff
MT
24072diff -urNp linux-2.6.38.1/drivers/firmware/dmi_scan.c linux-2.6.38.1/drivers/firmware/dmi_scan.c
24073--- linux-2.6.38.1/drivers/firmware/dmi_scan.c 2011-03-14 21:20:32.000000000 -0400
24074+++ linux-2.6.38.1/drivers/firmware/dmi_scan.c 2011-03-21 18:31:35.000000000 -0400
c52201e0 24075@@ -449,11 +449,6 @@ void __init dmi_scan_machine(void)
58c5fc13
MT
24076 }
24077 }
24078 else {
24079- /*
24080- * no iounmap() for that ioremap(); it would be a no-op, but
24081- * it's so early in setup that sucker gets confused into doing
24082- * what it shouldn't if we actually call it.
24083- */
24084 p = dmi_ioremap(0xF0000, 0x10000);
24085 if (p == NULL)
24086 goto error;
16454cff
MT
24087diff -urNp linux-2.6.38.1/drivers/gpu/drm/drm_crtc_helper.c linux-2.6.38.1/drivers/gpu/drm/drm_crtc_helper.c
24088--- linux-2.6.38.1/drivers/gpu/drm/drm_crtc_helper.c 2011-03-14 21:20:32.000000000 -0400
24089+++ linux-2.6.38.1/drivers/gpu/drm/drm_crtc_helper.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
24090@@ -276,7 +276,7 @@ static bool drm_encoder_crtc_ok(struct d
24091 struct drm_crtc *tmp;
24092 int crtc_mask = 1;
24093
bc901d79 24094- WARN(!crtc, "checking null crtc?\n");
6892158b
MT
24095+ BUG_ON(!crtc);
24096
24097 dev = crtc->dev;
24098
16454cff
MT
24099diff -urNp linux-2.6.38.1/drivers/gpu/drm/drm_drv.c linux-2.6.38.1/drivers/gpu/drm/drm_drv.c
24100--- linux-2.6.38.1/drivers/gpu/drm/drm_drv.c 2011-03-14 21:20:32.000000000 -0400
24101+++ linux-2.6.38.1/drivers/gpu/drm/drm_drv.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24102@@ -425,7 +425,7 @@ long drm_ioctl(struct file *filp,
ae4e228f
MT
24103
24104 dev = file_priv->minor->dev;
58c5fc13
MT
24105 atomic_inc(&dev->ioctl_count);
24106- atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
24107+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_IOCTLS]);
24108 ++file_priv->ioctl_count;
24109
24110 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
16454cff
MT
24111diff -urNp linux-2.6.38.1/drivers/gpu/drm/drm_fops.c linux-2.6.38.1/drivers/gpu/drm/drm_fops.c
24112--- linux-2.6.38.1/drivers/gpu/drm/drm_fops.c 2011-03-14 21:20:32.000000000 -0400
24113+++ linux-2.6.38.1/drivers/gpu/drm/drm_fops.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24114@@ -70,7 +70,7 @@ static int drm_setup(struct drm_device *
58c5fc13
MT
24115 }
24116
24117 for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
24118- atomic_set(&dev->counts[i], 0);
24119+ atomic_set_unchecked(&dev->counts[i], 0);
24120
24121 dev->sigdata.lock = NULL;
24122
bc901d79 24123@@ -134,8 +134,8 @@ int drm_open(struct inode *inode, struct
58c5fc13
MT
24124
24125 retcode = drm_open_helper(inode, filp, dev);
24126 if (!retcode) {
24127- atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
6892158b 24128- if (!dev->open_count++)
58c5fc13 24129+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]);
c52201e0 24130+ if (local_inc_return(&dev->open_count) == 1)
58c5fc13 24131 retcode = drm_setup(dev);
6892158b
MT
24132 }
24133 if (!retcode) {
16454cff 24134@@ -472,7 +472,7 @@ int drm_release(struct inode *inode, str
58c5fc13 24135
6892158b 24136 mutex_lock(&drm_global_mutex);
58c5fc13
MT
24137
24138- DRM_DEBUG("open_count = %d\n", dev->open_count);
c52201e0 24139+ DRM_DEBUG("open_count = %d\n", local_read(&dev->open_count));
58c5fc13
MT
24140
24141 if (dev->driver->preclose)
24142 dev->driver->preclose(dev, file_priv);
16454cff 24143@@ -484,7 +484,7 @@ int drm_release(struct inode *inode, str
58c5fc13
MT
24144 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
24145 task_pid_nr(current),
24146 (long)old_encode_dev(file_priv->minor->device),
24147- dev->open_count);
c52201e0 24148+ local_read(&dev->open_count));
58c5fc13
MT
24149
24150 /* if the master has gone away we can't do anything with the lock */
24151 if (file_priv->minor->master)
16454cff 24152@@ -565,8 +565,8 @@ int drm_release(struct inode *inode, str
58c5fc13
MT
24153 * End inline drm_release
24154 */
24155
24156- atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
58c5fc13 24157- if (!--dev->open_count) {
6892158b 24158+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_CLOSES]);
c52201e0 24159+ if (local_dec_and_test(&dev->open_count)) {
58c5fc13
MT
24160 if (atomic_read(&dev->ioctl_count)) {
24161 DRM_ERROR("Device busy: %d\n",
24162 atomic_read(&dev->ioctl_count));
16454cff
MT
24163diff -urNp linux-2.6.38.1/drivers/gpu/drm/drm_global.c linux-2.6.38.1/drivers/gpu/drm/drm_global.c
24164--- linux-2.6.38.1/drivers/gpu/drm/drm_global.c 2011-03-14 21:20:32.000000000 -0400
24165+++ linux-2.6.38.1/drivers/gpu/drm/drm_global.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
24166@@ -36,7 +36,7 @@
24167 struct drm_global_item {
24168 struct mutex mutex;
24169 void *object;
24170- int refcount;
24171+ atomic_t refcount;
24172 };
24173
24174 static struct drm_global_item glob[DRM_GLOBAL_NUM];
24175@@ -49,7 +49,7 @@ void drm_global_init(void)
24176 struct drm_global_item *item = &glob[i];
24177 mutex_init(&item->mutex);
24178 item->object = NULL;
24179- item->refcount = 0;
24180+ atomic_set(&item->refcount, 0);
24181 }
24182 }
24183
24184@@ -59,7 +59,7 @@ void drm_global_release(void)
24185 for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
24186 struct drm_global_item *item = &glob[i];
24187 BUG_ON(item->object != NULL);
24188- BUG_ON(item->refcount != 0);
24189+ BUG_ON(atomic_read(&item->refcount) != 0);
24190 }
24191 }
24192
24193@@ -70,7 +70,7 @@ int drm_global_item_ref(struct drm_globa
24194 void *object;
24195
24196 mutex_lock(&item->mutex);
24197- if (item->refcount == 0) {
24198+ if (atomic_read(&item->refcount) == 0) {
24199 item->object = kzalloc(ref->size, GFP_KERNEL);
24200 if (unlikely(item->object == NULL)) {
24201 ret = -ENOMEM;
24202@@ -83,7 +83,7 @@ int drm_global_item_ref(struct drm_globa
24203 goto out_err;
24204
24205 }
24206- ++item->refcount;
24207+ atomic_inc(&item->refcount);
24208 ref->object = item->object;
24209 object = item->object;
24210 mutex_unlock(&item->mutex);
24211@@ -100,9 +100,9 @@ void drm_global_item_unref(struct drm_gl
24212 struct drm_global_item *item = &glob[ref->global_type];
24213
24214 mutex_lock(&item->mutex);
24215- BUG_ON(item->refcount == 0);
24216+ BUG_ON(atomic_read(&item->refcount) == 0);
24217 BUG_ON(ref->object != item->object);
24218- if (--item->refcount == 0) {
24219+ if (atomic_dec_and_test(&item->refcount)) {
24220 ref->release(ref);
24221 item->object = NULL;
24222 }
16454cff
MT
24223diff -urNp linux-2.6.38.1/drivers/gpu/drm/drm_info.c linux-2.6.38.1/drivers/gpu/drm/drm_info.c
24224--- linux-2.6.38.1/drivers/gpu/drm/drm_info.c 2011-03-14 21:20:32.000000000 -0400
24225+++ linux-2.6.38.1/drivers/gpu/drm/drm_info.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
24226@@ -86,10 +86,14 @@ int drm_vm_info(struct seq_file *m, void
24227 struct drm_local_map *map;
24228 struct drm_map_list *r_list;
24229
24230- /* Hardcoded from _DRM_FRAME_BUFFER,
24231- _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
24232- _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
24233- const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
24234+ static const char * const types[] = {
24235+ [_DRM_FRAME_BUFFER] = "FB",
24236+ [_DRM_REGISTERS] = "REG",
24237+ [_DRM_SHM] = "SHM",
24238+ [_DRM_AGP] = "AGP",
24239+ [_DRM_SCATTER_GATHER] = "SG",
24240+ [_DRM_CONSISTENT] = "PCI",
24241+ [_DRM_GEM] = "GEM" };
24242 const char *type;
24243 int i;
24244
24245@@ -100,7 +104,7 @@ int drm_vm_info(struct seq_file *m, void
24246 map = r_list->map;
24247 if (!map)
24248 continue;
24249- if (map->type < 0 || map->type > 5)
24250+ if (map->type >= ARRAY_SIZE(types))
24251 type = "??";
24252 else
24253 type = types[map->type];
16454cff
MT
24254@@ -301,7 +305,11 @@ int drm_vma_info(struct seq_file *m, voi
24255 vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
24256 vma->vm_flags & VM_LOCKED ? 'l' : '-',
24257 vma->vm_flags & VM_IO ? 'i' : '-',
24258+#ifdef CONFIG_GRKERNSEC_HIDESYM
24259+ 0);
24260+#else
24261 vma->vm_pgoff);
24262+#endif
24263
24264 #if defined(__i386__)
24265 pgprot = pgprot_val(vma->vm_page_prot);
24266diff -urNp linux-2.6.38.1/drivers/gpu/drm/drm_ioctl.c linux-2.6.38.1/drivers/gpu/drm/drm_ioctl.c
24267--- linux-2.6.38.1/drivers/gpu/drm/drm_ioctl.c 2011-03-14 21:20:32.000000000 -0400
24268+++ linux-2.6.38.1/drivers/gpu/drm/drm_ioctl.c 2011-03-21 18:31:35.000000000 -0400
6892158b 24269@@ -353,7 +353,7 @@ int drm_getstats(struct drm_device *dev,
58c5fc13
MT
24270 stats->data[i].value =
24271 (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0);
24272 else
24273- stats->data[i].value = atomic_read(&dev->counts[i]);
24274+ stats->data[i].value = atomic_read_unchecked(&dev->counts[i]);
24275 stats->data[i].type = dev->types[i];
24276 }
24277
16454cff
MT
24278diff -urNp linux-2.6.38.1/drivers/gpu/drm/drm_lock.c linux-2.6.38.1/drivers/gpu/drm/drm_lock.c
24279--- linux-2.6.38.1/drivers/gpu/drm/drm_lock.c 2011-03-14 21:20:32.000000000 -0400
24280+++ linux-2.6.38.1/drivers/gpu/drm/drm_lock.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24281@@ -89,7 +89,7 @@ int drm_lock(struct drm_device *dev, voi
58c5fc13
MT
24282 if (drm_lock_take(&master->lock, lock->context)) {
24283 master->lock.file_priv = file_priv;
24284 master->lock.lock_time = jiffies;
24285- atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
24286+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_LOCKS]);
24287 break; /* Got lock */
24288 }
24289
bc901d79 24290@@ -160,7 +160,7 @@ int drm_unlock(struct drm_device *dev, v
58c5fc13
MT
24291 return -EINVAL;
24292 }
24293
24294- atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
24295+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_UNLOCKS]);
24296
bc901d79
MT
24297 if (drm_lock_free(&master->lock, lock->context)) {
24298 /* FIXME: Should really bail out here. */
16454cff
MT
24299diff -urNp linux-2.6.38.1/drivers/gpu/drm/i810/i810_dma.c linux-2.6.38.1/drivers/gpu/drm/i810/i810_dma.c
24300--- linux-2.6.38.1/drivers/gpu/drm/i810/i810_dma.c 2011-03-14 21:20:32.000000000 -0400
24301+++ linux-2.6.38.1/drivers/gpu/drm/i810/i810_dma.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24302@@ -953,8 +953,8 @@ static int i810_dma_vertex(struct drm_de
58c5fc13
MT
24303 dma->buflist[vertex->idx],
24304 vertex->discard, vertex->used);
24305
24306- atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
24307- atomic_inc(&dev->counts[_DRM_STAT_DMA]);
24308+ atomic_add_unchecked(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
24309+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
24310 sarea_priv->last_enqueue = dev_priv->counter - 1;
24311 sarea_priv->last_dispatch = (int)hw_status[5];
24312
bc901d79 24313@@ -1114,8 +1114,8 @@ static int i810_dma_mc(struct drm_device
58c5fc13
MT
24314 i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used,
24315 mc->last_render);
24316
24317- atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
24318- atomic_inc(&dev->counts[_DRM_STAT_DMA]);
24319+ atomic_add_unchecked(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
24320+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
24321 sarea_priv->last_enqueue = dev_priv->counter - 1;
24322 sarea_priv->last_dispatch = (int)hw_status[5];
24323
16454cff
MT
24324diff -urNp linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ch7017.c linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ch7017.c
24325--- linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ch7017.c 2011-03-14 21:20:32.000000000 -0400
24326+++ linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ch7017.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24327@@ -390,7 +390,7 @@ static void ch7017_destroy(struct intel_
57199397
MT
24328 }
24329 }
24330
24331-struct intel_dvo_dev_ops ch7017_ops = {
24332+const struct intel_dvo_dev_ops ch7017_ops = {
24333 .init = ch7017_init,
24334 .detect = ch7017_detect,
24335 .mode_valid = ch7017_mode_valid,
16454cff
MT
24336diff -urNp linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ch7xxx.c linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ch7xxx.c
24337--- linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ch7xxx.c 2011-03-14 21:20:32.000000000 -0400
24338+++ linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ch7xxx.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24339@@ -320,7 +320,7 @@ static void ch7xxx_destroy(struct intel_
57199397
MT
24340 }
24341 }
24342
24343-struct intel_dvo_dev_ops ch7xxx_ops = {
24344+const struct intel_dvo_dev_ops ch7xxx_ops = {
24345 .init = ch7xxx_init,
24346 .detect = ch7xxx_detect,
24347 .mode_valid = ch7xxx_mode_valid,
16454cff
MT
24348diff -urNp linux-2.6.38.1/drivers/gpu/drm/i915/dvo.h linux-2.6.38.1/drivers/gpu/drm/i915/dvo.h
24349--- linux-2.6.38.1/drivers/gpu/drm/i915/dvo.h 2011-03-14 21:20:32.000000000 -0400
24350+++ linux-2.6.38.1/drivers/gpu/drm/i915/dvo.h 2011-03-21 18:31:35.000000000 -0400
6892158b 24351@@ -122,23 +122,23 @@ struct intel_dvo_dev_ops {
ae4e228f
MT
24352 *
24353 * \return singly-linked list of modes or NULL if no modes found.
24354 */
24355- struct drm_display_mode *(*get_modes)(struct intel_dvo_device *dvo);
24356+ struct drm_display_mode *(* const get_modes)(struct intel_dvo_device *dvo);
24357
24358 /**
24359 * Clean up driver-specific bits of the output
24360 */
24361- void (*destroy) (struct intel_dvo_device *dvo);
24362+ void (* const destroy) (struct intel_dvo_device *dvo);
24363
24364 /**
24365 * Debugging hook to dump device registers to log file
24366 */
24367- void (*dump_regs)(struct intel_dvo_device *dvo);
24368+ void (* const dump_regs)(struct intel_dvo_device *dvo);
24369 };
24370
24371-extern struct intel_dvo_dev_ops sil164_ops;
24372-extern struct intel_dvo_dev_ops ch7xxx_ops;
24373-extern struct intel_dvo_dev_ops ivch_ops;
24374-extern struct intel_dvo_dev_ops tfp410_ops;
24375-extern struct intel_dvo_dev_ops ch7017_ops;
24376+extern const struct intel_dvo_dev_ops sil164_ops;
24377+extern const struct intel_dvo_dev_ops ch7xxx_ops;
24378+extern const struct intel_dvo_dev_ops ivch_ops;
24379+extern const struct intel_dvo_dev_ops tfp410_ops;
24380+extern const struct intel_dvo_dev_ops ch7017_ops;
24381
24382 #endif /* _INTEL_DVO_H */
16454cff
MT
24383diff -urNp linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ivch.c linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ivch.c
24384--- linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ivch.c 2011-03-14 21:20:32.000000000 -0400
24385+++ linux-2.6.38.1/drivers/gpu/drm/i915/dvo_ivch.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24386@@ -410,7 +410,7 @@ static void ivch_destroy(struct intel_dv
ae4e228f
MT
24387 }
24388 }
24389
24390-struct intel_dvo_dev_ops ivch_ops= {
24391+const struct intel_dvo_dev_ops ivch_ops= {
24392 .init = ivch_init,
24393 .dpms = ivch_dpms,
57199397 24394 .mode_valid = ivch_mode_valid,
16454cff
MT
24395diff -urNp linux-2.6.38.1/drivers/gpu/drm/i915/dvo_sil164.c linux-2.6.38.1/drivers/gpu/drm/i915/dvo_sil164.c
24396--- linux-2.6.38.1/drivers/gpu/drm/i915/dvo_sil164.c 2011-03-14 21:20:32.000000000 -0400
24397+++ linux-2.6.38.1/drivers/gpu/drm/i915/dvo_sil164.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24398@@ -252,7 +252,7 @@ static void sil164_destroy(struct intel_
ae4e228f
MT
24399 }
24400 }
24401
24402-struct intel_dvo_dev_ops sil164_ops = {
24403+const struct intel_dvo_dev_ops sil164_ops = {
24404 .init = sil164_init,
24405 .detect = sil164_detect,
24406 .mode_valid = sil164_mode_valid,
16454cff
MT
24407diff -urNp linux-2.6.38.1/drivers/gpu/drm/i915/dvo_tfp410.c linux-2.6.38.1/drivers/gpu/drm/i915/dvo_tfp410.c
24408--- linux-2.6.38.1/drivers/gpu/drm/i915/dvo_tfp410.c 2011-03-14 21:20:32.000000000 -0400
24409+++ linux-2.6.38.1/drivers/gpu/drm/i915/dvo_tfp410.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24410@@ -293,7 +293,7 @@ static void tfp410_destroy(struct intel_
ae4e228f
MT
24411 }
24412 }
24413
24414-struct intel_dvo_dev_ops tfp410_ops = {
24415+const struct intel_dvo_dev_ops tfp410_ops = {
24416 .init = tfp410_init,
24417 .detect = tfp410_detect,
24418 .mode_valid = tfp410_mode_valid,
16454cff
MT
24419diff -urNp linux-2.6.38.1/drivers/gpu/drm/i915/i915_dma.c linux-2.6.38.1/drivers/gpu/drm/i915/i915_dma.c
24420--- linux-2.6.38.1/drivers/gpu/drm/i915/i915_dma.c 2011-03-14 21:20:32.000000000 -0400
24421+++ linux-2.6.38.1/drivers/gpu/drm/i915/i915_dma.c 2011-03-21 18:31:35.000000000 -0400
24422@@ -1159,7 +1159,7 @@ static bool i915_switcheroo_can_switch(s
efbe55a5
MT
24423 bool can_switch;
24424
24425 spin_lock(&dev->count_lock);
24426- can_switch = (dev->open_count == 0);
c52201e0 24427+ can_switch = (local_read(&dev->open_count) == 0);
efbe55a5
MT
24428 spin_unlock(&dev->count_lock);
24429 return can_switch;
24430 }
16454cff
MT
24431diff -urNp linux-2.6.38.1/drivers/gpu/drm/i915/i915_drv.c linux-2.6.38.1/drivers/gpu/drm/i915/i915_drv.c
24432--- linux-2.6.38.1/drivers/gpu/drm/i915/i915_drv.c 2011-03-14 21:20:32.000000000 -0400
24433+++ linux-2.6.38.1/drivers/gpu/drm/i915/i915_drv.c 2011-03-21 18:31:35.000000000 -0400
24434@@ -673,7 +673,7 @@ static const struct dev_pm_ops i915_pm_o
ae4e228f
MT
24435 .restore = i915_pm_resume,
24436 };
24437
58c5fc13
MT
24438-static struct vm_operations_struct i915_gem_vm_ops = {
24439+static const struct vm_operations_struct i915_gem_vm_ops = {
24440 .fault = i915_gem_fault,
24441 .open = drm_gem_vm_open,
24442 .close = drm_gem_vm_close,
16454cff
MT
24443diff -urNp linux-2.6.38.1/drivers/gpu/drm/nouveau/nouveau_state.c linux-2.6.38.1/drivers/gpu/drm/nouveau/nouveau_state.c
24444--- linux-2.6.38.1/drivers/gpu/drm/nouveau/nouveau_state.c 2011-03-14 21:20:32.000000000 -0400
24445+++ linux-2.6.38.1/drivers/gpu/drm/nouveau/nouveau_state.c 2011-03-21 18:31:35.000000000 -0400
24446@@ -621,7 +621,7 @@ static bool nouveau_switcheroo_can_switc
efbe55a5
MT
24447 bool can_switch;
24448
24449 spin_lock(&dev->count_lock);
24450- can_switch = (dev->open_count == 0);
c52201e0 24451+ can_switch = (local_read(&dev->open_count) == 0);
efbe55a5
MT
24452 spin_unlock(&dev->count_lock);
24453 return can_switch;
24454 }
16454cff
MT
24455diff -urNp linux-2.6.38.1/drivers/gpu/drm/radeon/mkregtable.c linux-2.6.38.1/drivers/gpu/drm/radeon/mkregtable.c
24456--- linux-2.6.38.1/drivers/gpu/drm/radeon/mkregtable.c 2011-03-14 21:20:32.000000000 -0400
24457+++ linux-2.6.38.1/drivers/gpu/drm/radeon/mkregtable.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
24458@@ -637,14 +637,14 @@ static int parser_auth(struct table *t,
24459 regex_t mask_rex;
24460 regmatch_t match[4];
24461 char buf[1024];
24462- size_t end;
24463+ long end;
24464 int len;
24465 int done = 0;
24466 int r;
24467 unsigned o;
24468 struct offset *offset;
24469 char last_reg_s[10];
24470- int last_reg;
24471+ unsigned long last_reg;
24472
24473 if (regcomp
24474 (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
16454cff
MT
24475diff -urNp linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_device.c linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_device.c
24476--- linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_device.c 2011-03-14 21:20:32.000000000 -0400
24477+++ linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_device.c 2011-03-21 18:31:35.000000000 -0400
24478@@ -673,7 +673,7 @@ static bool radeon_switcheroo_can_switch
df50ba0c 24479 bool can_switch;
58c5fc13 24480
df50ba0c
MT
24481 spin_lock(&dev->count_lock);
24482- can_switch = (dev->open_count == 0);
c52201e0 24483+ can_switch = (local_read(&dev->open_count) == 0);
df50ba0c
MT
24484 spin_unlock(&dev->count_lock);
24485 return can_switch;
24486 }
16454cff
MT
24487diff -urNp linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_state.c linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_state.c
24488--- linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_state.c 2011-03-14 21:20:32.000000000 -0400
24489+++ linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_state.c 2011-03-21 18:31:35.000000000 -0400
efbe55a5 24490@@ -2168,7 +2168,7 @@ static int radeon_cp_clear(struct drm_de
ae4e228f
MT
24491 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
24492 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
24493
24494- if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes,
24495+ if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS || DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes,
24496 sarea_priv->nbox * sizeof(depth_boxes[0])))
24497 return -EFAULT;
24498
efbe55a5 24499@@ -3031,7 +3031,7 @@ static int radeon_cp_getparam(struct drm
58c5fc13
MT
24500 {
24501 drm_radeon_private_t *dev_priv = dev->dev_private;
24502 drm_radeon_getparam_t *param = data;
24503- int value;
24504+ int value = 0;
24505
24506 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
24507
16454cff
MT
24508diff -urNp linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_ttm.c linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_ttm.c
24509--- linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_ttm.c 2011-03-14 21:20:32.000000000 -0400
24510+++ linux-2.6.38.1/drivers/gpu/drm/radeon/radeon_ttm.c 2011-03-21 18:31:35.000000000 -0400
24511@@ -603,8 +603,9 @@ void radeon_ttm_set_active_vram_size(str
24512 man->size = size >> PAGE_SHIFT;
58c5fc13
MT
24513 }
24514
24515-static struct vm_operations_struct radeon_ttm_vm_ops;
ae4e228f 24516-static const struct vm_operations_struct *ttm_vm_ops = NULL;
57199397
MT
24517+extern int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
24518+extern void ttm_bo_vm_open(struct vm_area_struct *vma);
24519+extern void ttm_bo_vm_close(struct vm_area_struct *vma);
24520
24521 static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
24522 {
16454cff 24523@@ -612,17 +613,22 @@ static int radeon_ttm_fault(struct vm_ar
57199397
MT
24524 struct radeon_device *rdev;
24525 int r;
24526
24527- bo = (struct ttm_buffer_object *)vma->vm_private_data;
58c5fc13 24528- if (bo == NULL) {
57199397
MT
24529+ bo = (struct ttm_buffer_object *)vma->vm_private_data;
24530+ if (!bo)
24531 return VM_FAULT_NOPAGE;
58c5fc13 24532- }
57199397
MT
24533 rdev = radeon_get_rdev(bo->bdev);
24534 mutex_lock(&rdev->vram_mutex);
58c5fc13 24535- r = ttm_vm_ops->fault(vma, vmf);
57199397
MT
24536+ r = ttm_bo_vm_fault(vma, vmf);
24537 mutex_unlock(&rdev->vram_mutex);
24538 return r;
24539 }
24540
24541+static const struct vm_operations_struct radeon_ttm_vm_ops = {
24542+ .fault = radeon_ttm_fault,
24543+ .open = ttm_bo_vm_open,
24544+ .close = ttm_bo_vm_close
24545+};
24546+
58c5fc13
MT
24547 int radeon_mmap(struct file *filp, struct vm_area_struct *vma)
24548 {
24549 struct drm_file *file_priv;
16454cff 24550@@ -635,18 +641,11 @@ int radeon_mmap(struct file *filp, struc
58c5fc13 24551
bc901d79 24552 file_priv = filp->private_data;
58c5fc13
MT
24553 rdev = file_priv->minor->dev->dev_private;
24554- if (rdev == NULL) {
24555+ if (!rdev)
24556 return -EINVAL;
24557- }
57199397 24558 r = ttm_bo_mmap(filp, vma, &rdev->mman.bdev);
58c5fc13 24559- if (unlikely(r != 0)) {
57199397
MT
24560+ if (r)
24561 return r;
58c5fc13
MT
24562- }
24563- if (unlikely(ttm_vm_ops == NULL)) {
24564- ttm_vm_ops = vma->vm_ops;
24565- radeon_ttm_vm_ops = *ttm_vm_ops;
24566- radeon_ttm_vm_ops.fault = &radeon_ttm_fault;
24567- }
57199397
MT
24568 vma->vm_ops = &radeon_ttm_vm_ops;
24569 return 0;
58c5fc13 24570 }
16454cff
MT
24571diff -urNp linux-2.6.38.1/drivers/gpu/drm/ttm/ttm_bo.c linux-2.6.38.1/drivers/gpu/drm/ttm/ttm_bo.c
24572--- linux-2.6.38.1/drivers/gpu/drm/ttm/ttm_bo.c 2011-03-14 21:20:32.000000000 -0400
24573+++ linux-2.6.38.1/drivers/gpu/drm/ttm/ttm_bo.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
24574@@ -40,7 +40,7 @@
24575 #include <asm/atomic.h>
ae4e228f 24576
df50ba0c
MT
24577 #define TTM_ASSERT_LOCKED(param)
24578-#define TTM_DEBUG(fmt, arg...)
24579+#define TTM_DEBUG(fmt, arg...) do {} while (0)
24580 #define TTM_BO_HASH_ORDER 13
ae4e228f 24581
df50ba0c 24582 static int ttm_bo_setup_vm(struct ttm_buffer_object *bo);
16454cff
MT
24583diff -urNp linux-2.6.38.1/drivers/gpu/drm/ttm/ttm_bo_vm.c linux-2.6.38.1/drivers/gpu/drm/ttm/ttm_bo_vm.c
24584--- linux-2.6.38.1/drivers/gpu/drm/ttm/ttm_bo_vm.c 2011-03-14 21:20:32.000000000 -0400
24585+++ linux-2.6.38.1/drivers/gpu/drm/ttm/ttm_bo_vm.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
24586@@ -69,11 +69,11 @@ static struct ttm_buffer_object *ttm_bo_
24587 return best_bo;
24588 }
24589
24590-static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
24591+int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
58c5fc13
MT
24592 {
24593 struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
24594 vma->vm_private_data;
24595- struct ttm_bo_device *bdev = bo->bdev;
24596+ struct ttm_bo_device *bdev;
57199397
MT
24597 unsigned long page_offset;
24598 unsigned long page_last;
24599 unsigned long pfn;
16454cff
MT
24600@@ -83,8 +83,12 @@ static int ttm_bo_vm_fault(struct vm_are
24601 int i;
58c5fc13
MT
24602 unsigned long address = (unsigned long)vmf->virtual_address;
24603 int retval = VM_FAULT_NOPAGE;
16454cff
MT
24604- struct ttm_mem_type_manager *man =
24605- &bdev->man[bo->mem.mem_type];
24606+ struct ttm_mem_type_manager *man;
24607+
58c5fc13
MT
24608+ if (!bo)
24609+ return VM_FAULT_NOPAGE;
24610+ bdev = bo->bdev;
16454cff
MT
24611+ man = &bdev->man[bo->mem.mem_type];
24612
58c5fc13
MT
24613 /*
24614 * Work around locking order reversal in fault / nopfn
16454cff 24615@@ -219,22 +223,25 @@ out_unlock:
6892158b 24616 ttm_bo_unreserve(bo);
57199397
MT
24617 return retval;
24618 }
6892158b 24619+EXPORT_SYMBOL(ttm_bo_vm_fault);
57199397
MT
24620
24621-static void ttm_bo_vm_open(struct vm_area_struct *vma)
24622+void ttm_bo_vm_open(struct vm_area_struct *vma)
24623 {
24624 struct ttm_buffer_object *bo =
24625 (struct ttm_buffer_object *)vma->vm_private_data;
6892158b 24626
57199397
MT
24627 (void)ttm_bo_reference(bo);
24628 }
6892158b 24629+EXPORT_SYMBOL(ttm_bo_vm_open);
57199397
MT
24630
24631-static void ttm_bo_vm_close(struct vm_area_struct *vma)
24632+void ttm_bo_vm_close(struct vm_area_struct *vma)
24633 {
24634 struct ttm_buffer_object *bo = (struct ttm_buffer_object *)vma->vm_private_data;
24635
6892158b
MT
24636 ttm_bo_unref(&bo);
24637 vma->vm_private_data = NULL;
ae4e228f 24638 }
6892158b 24639+EXPORT_SYMBOL(ttm_bo_vm_close);
ae4e228f 24640
6892158b
MT
24641 static const struct vm_operations_struct ttm_bo_vm_ops = {
24642 .fault = ttm_bo_vm_fault,
16454cff
MT
24643diff -urNp linux-2.6.38.1/drivers/hid/usbhid/hiddev.c linux-2.6.38.1/drivers/hid/usbhid/hiddev.c
24644--- linux-2.6.38.1/drivers/hid/usbhid/hiddev.c 2011-03-14 21:20:32.000000000 -0400
24645+++ linux-2.6.38.1/drivers/hid/usbhid/hiddev.c 2011-03-21 18:31:35.000000000 -0400
24646@@ -613,7 +613,7 @@ static long hiddev_ioctl(struct file *fi
24647 break;
ae4e228f 24648
df50ba0c
MT
24649 case HIDIOCAPPLICATION:
24650- if (arg < 0 || arg >= hid->maxapplication)
24651+ if (arg >= hid->maxapplication)
16454cff 24652 break;
df50ba0c
MT
24653
24654 for (i = 0; i < hid->maxcollection; i++)
16454cff
MT
24655diff -urNp linux-2.6.38.1/drivers/hwmon/k8temp.c linux-2.6.38.1/drivers/hwmon/k8temp.c
24656--- linux-2.6.38.1/drivers/hwmon/k8temp.c 2011-03-14 21:20:32.000000000 -0400
24657+++ linux-2.6.38.1/drivers/hwmon/k8temp.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
24658@@ -138,7 +138,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
24659
ae4e228f 24660 static const struct pci_device_id k8temp_ids[] = {
58c5fc13
MT
24661 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
24662- { 0 },
24663+ { 0, 0, 0, 0, 0, 0, 0 },
24664 };
24665
24666 MODULE_DEVICE_TABLE(pci, k8temp_ids);
16454cff
MT
24667diff -urNp linux-2.6.38.1/drivers/hwmon/sis5595.c linux-2.6.38.1/drivers/hwmon/sis5595.c
24668--- linux-2.6.38.1/drivers/hwmon/sis5595.c 2011-03-14 21:20:32.000000000 -0400
24669+++ linux-2.6.38.1/drivers/hwmon/sis5595.c 2011-03-21 18:31:35.000000000 -0400
24670@@ -701,7 +701,7 @@ static struct sis5595_data *sis5595_upda
58c5fc13 24671
ae4e228f 24672 static const struct pci_device_id sis5595_pci_ids[] = {
58c5fc13
MT
24673 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
24674- { 0, }
24675+ { 0, 0, 0, 0, 0, 0, 0 }
24676 };
24677
24678 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
16454cff
MT
24679diff -urNp linux-2.6.38.1/drivers/hwmon/via686a.c linux-2.6.38.1/drivers/hwmon/via686a.c
24680--- linux-2.6.38.1/drivers/hwmon/via686a.c 2011-03-14 21:20:32.000000000 -0400
24681+++ linux-2.6.38.1/drivers/hwmon/via686a.c 2011-03-21 18:31:35.000000000 -0400
24682@@ -779,7 +779,7 @@ static struct via686a_data *via686a_upda
58c5fc13 24683
ae4e228f 24684 static const struct pci_device_id via686a_pci_ids[] = {
58c5fc13
MT
24685 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
24686- { 0, }
24687+ { 0, 0, 0, 0, 0, 0, 0 }
24688 };
24689
24690 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
16454cff
MT
24691diff -urNp linux-2.6.38.1/drivers/hwmon/vt8231.c linux-2.6.38.1/drivers/hwmon/vt8231.c
24692--- linux-2.6.38.1/drivers/hwmon/vt8231.c 2011-03-14 21:20:32.000000000 -0400
24693+++ linux-2.6.38.1/drivers/hwmon/vt8231.c 2011-03-21 18:31:35.000000000 -0400
24694@@ -701,7 +701,7 @@ static struct platform_driver vt8231_dri
58c5fc13 24695
ae4e228f 24696 static const struct pci_device_id vt8231_pci_ids[] = {
58c5fc13
MT
24697 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
24698- { 0, }
24699+ { 0, 0, 0, 0, 0, 0, 0 }
24700 };
24701
24702 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
16454cff
MT
24703diff -urNp linux-2.6.38.1/drivers/hwmon/w83791d.c linux-2.6.38.1/drivers/hwmon/w83791d.c
24704--- linux-2.6.38.1/drivers/hwmon/w83791d.c 2011-03-14 21:20:32.000000000 -0400
24705+++ linux-2.6.38.1/drivers/hwmon/w83791d.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 24706@@ -329,8 +329,8 @@ static int w83791d_detect(struct i2c_cli
58c5fc13
MT
24707 struct i2c_board_info *info);
24708 static int w83791d_remove(struct i2c_client *client);
24709
24710-static int w83791d_read(struct i2c_client *client, u8 register);
24711-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
24712+static int w83791d_read(struct i2c_client *client, u8 reg);
24713+static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
24714 static struct w83791d_data *w83791d_update_device(struct device *dev);
24715
24716 #ifdef DEBUG
16454cff
MT
24717diff -urNp linux-2.6.38.1/drivers/i2c/busses/i2c-i801.c linux-2.6.38.1/drivers/i2c/busses/i2c-i801.c
24718--- linux-2.6.38.1/drivers/i2c/busses/i2c-i801.c 2011-03-14 21:20:32.000000000 -0400
24719+++ linux-2.6.38.1/drivers/i2c/busses/i2c-i801.c 2011-03-21 18:31:35.000000000 -0400
24720@@ -621,7 +621,7 @@ static const struct pci_device_id i801_i
bc901d79
MT
24721 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) },
24722 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) },
24723 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) },
58c5fc13
MT
24724- { 0, }
24725+ { 0, 0, 0, 0, 0, 0, 0 }
24726 };
24727
57199397 24728 MODULE_DEVICE_TABLE(pci, i801_ids);
16454cff
MT
24729diff -urNp linux-2.6.38.1/drivers/i2c/busses/i2c-piix4.c linux-2.6.38.1/drivers/i2c/busses/i2c-piix4.c
24730--- linux-2.6.38.1/drivers/i2c/busses/i2c-piix4.c 2011-03-14 21:20:32.000000000 -0400
24731+++ linux-2.6.38.1/drivers/i2c/busses/i2c-piix4.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 24732@@ -124,7 +124,7 @@ static struct dmi_system_id __devinitdat
58c5fc13
MT
24733 .ident = "IBM",
24734 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
24735 },
24736- { },
ae4e228f 24737+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
58c5fc13
MT
24738 };
24739
24740 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
df50ba0c 24741@@ -491,7 +491,7 @@ static const struct pci_device_id piix4_
58c5fc13
MT
24742 PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
24743 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
24744 PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
24745- { 0, }
24746+ { 0, 0, 0, 0, 0, 0, 0 }
24747 };
24748
24749 MODULE_DEVICE_TABLE (pci, piix4_ids);
16454cff
MT
24750diff -urNp linux-2.6.38.1/drivers/i2c/busses/i2c-sis630.c linux-2.6.38.1/drivers/i2c/busses/i2c-sis630.c
24751--- linux-2.6.38.1/drivers/i2c/busses/i2c-sis630.c 2011-03-14 21:20:32.000000000 -0400
24752+++ linux-2.6.38.1/drivers/i2c/busses/i2c-sis630.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13 24753@@ -471,7 +471,7 @@ static struct i2c_adapter sis630_adapter
df50ba0c 24754 static const struct pci_device_id sis630_ids[] __devinitconst = {
58c5fc13
MT
24755 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
24756 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
24757- { 0, }
24758+ { 0, 0, 0, 0, 0, 0, 0 }
24759 };
24760
24761 MODULE_DEVICE_TABLE (pci, sis630_ids);
16454cff
MT
24762diff -urNp linux-2.6.38.1/drivers/i2c/busses/i2c-sis96x.c linux-2.6.38.1/drivers/i2c/busses/i2c-sis96x.c
24763--- linux-2.6.38.1/drivers/i2c/busses/i2c-sis96x.c 2011-03-14 21:20:32.000000000 -0400
24764+++ linux-2.6.38.1/drivers/i2c/busses/i2c-sis96x.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
24765@@ -247,7 +247,7 @@ static struct i2c_adapter sis96x_adapter
24766
df50ba0c 24767 static const struct pci_device_id sis96x_ids[] = {
58c5fc13
MT
24768 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
24769- { 0, }
24770+ { 0, 0, 0, 0, 0, 0, 0 }
24771 };
24772
24773 MODULE_DEVICE_TABLE (pci, sis96x_ids);
16454cff
MT
24774diff -urNp linux-2.6.38.1/drivers/ide/ide-cd.c linux-2.6.38.1/drivers/ide/ide-cd.c
24775--- linux-2.6.38.1/drivers/ide/ide-cd.c 2011-03-14 21:20:32.000000000 -0400
24776+++ linux-2.6.38.1/drivers/ide/ide-cd.c 2011-03-21 18:31:35.000000000 -0400
6892158b 24777@@ -776,7 +776,7 @@ static void cdrom_do_block_pc(ide_drive_
ae4e228f
MT
24778 alignment = queue_dma_alignment(q) | q->dma_pad_mask;
24779 if ((unsigned long)buf & alignment
24780 || blk_rq_bytes(rq) & q->dma_pad_mask
24781- || object_is_on_stack(buf))
24782+ || object_starts_on_stack(buf))
24783 drive->dma = 0;
24784 }
24785 }
16454cff
MT
24786diff -urNp linux-2.6.38.1/drivers/infiniband/core/cm.c linux-2.6.38.1/drivers/infiniband/core/cm.c
24787--- linux-2.6.38.1/drivers/infiniband/core/cm.c 2011-03-23 17:20:07.000000000 -0400
24788+++ linux-2.6.38.1/drivers/infiniband/core/cm.c 2011-03-23 17:21:50.000000000 -0400
df50ba0c 24789@@ -113,7 +113,7 @@ static char const counter_group_names[CM
ae4e228f
MT
24790
24791 struct cm_counter_group {
24792 struct kobject obj;
24793- atomic_long_t counter[CM_ATTR_COUNT];
24794+ atomic_long_unchecked_t counter[CM_ATTR_COUNT];
24795 };
24796
24797 struct cm_counter_attribute {
df50ba0c 24798@@ -1387,7 +1387,7 @@ static void cm_dup_req_handler(struct cm
ae4e228f
MT
24799 struct ib_mad_send_buf *msg = NULL;
24800 int ret;
24801
24802- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24803+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24804 counter[CM_REQ_COUNTER]);
24805
24806 /* Quick state check to discard duplicate REQs. */
df50ba0c 24807@@ -1765,7 +1765,7 @@ static void cm_dup_rep_handler(struct cm
ae4e228f
MT
24808 if (!cm_id_priv)
24809 return;
58c5fc13 24810
ae4e228f
MT
24811- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24812+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24813 counter[CM_REP_COUNTER]);
24814 ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg);
24815 if (ret)
df50ba0c 24816@@ -1932,7 +1932,7 @@ static int cm_rtu_handler(struct cm_work
ae4e228f
MT
24817 if (cm_id_priv->id.state != IB_CM_REP_SENT &&
24818 cm_id_priv->id.state != IB_CM_MRA_REP_RCVD) {
24819 spin_unlock_irq(&cm_id_priv->lock);
24820- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24821+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24822 counter[CM_RTU_COUNTER]);
24823 goto out;
24824 }
df50ba0c 24825@@ -2111,7 +2111,7 @@ static int cm_dreq_handler(struct cm_wor
ae4e228f
MT
24826 cm_id_priv = cm_acquire_id(dreq_msg->remote_comm_id,
24827 dreq_msg->local_comm_id);
24828 if (!cm_id_priv) {
24829- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24830+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24831 counter[CM_DREQ_COUNTER]);
24832 cm_issue_drep(work->port, work->mad_recv_wc);
24833 return -EINVAL;
df50ba0c 24834@@ -2132,7 +2132,7 @@ static int cm_dreq_handler(struct cm_wor
ae4e228f
MT
24835 case IB_CM_MRA_REP_RCVD:
24836 break;
24837 case IB_CM_TIMEWAIT:
24838- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24839+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24840 counter[CM_DREQ_COUNTER]);
24841 if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))
24842 goto unlock;
df50ba0c 24843@@ -2146,7 +2146,7 @@ static int cm_dreq_handler(struct cm_wor
ae4e228f
MT
24844 cm_free_msg(msg);
24845 goto deref;
24846 case IB_CM_DREQ_RCVD:
24847- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24848+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24849 counter[CM_DREQ_COUNTER]);
24850 goto unlock;
24851 default:
6892158b 24852@@ -2504,7 +2504,7 @@ static int cm_mra_handler(struct cm_work
ae4e228f
MT
24853 ib_modify_mad(cm_id_priv->av.port->mad_agent,
24854 cm_id_priv->msg, timeout)) {
24855 if (cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD)
24856- atomic_long_inc(&work->port->
24857+ atomic_long_inc_unchecked(&work->port->
24858 counter_group[CM_RECV_DUPLICATES].
24859 counter[CM_MRA_COUNTER]);
24860 goto out;
6892158b 24861@@ -2513,7 +2513,7 @@ static int cm_mra_handler(struct cm_work
ae4e228f
MT
24862 break;
24863 case IB_CM_MRA_REQ_RCVD:
24864 case IB_CM_MRA_REP_RCVD:
24865- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24866+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24867 counter[CM_MRA_COUNTER]);
24868 /* fall through */
24869 default:
6892158b 24870@@ -2675,7 +2675,7 @@ static int cm_lap_handler(struct cm_work
ae4e228f
MT
24871 case IB_CM_LAP_IDLE:
24872 break;
24873 case IB_CM_MRA_LAP_SENT:
24874- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24875+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24876 counter[CM_LAP_COUNTER]);
24877 if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))
24878 goto unlock;
6892158b 24879@@ -2691,7 +2691,7 @@ static int cm_lap_handler(struct cm_work
ae4e228f
MT
24880 cm_free_msg(msg);
24881 goto deref;
24882 case IB_CM_LAP_RCVD:
24883- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24884+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24885 counter[CM_LAP_COUNTER]);
24886 goto unlock;
24887 default:
6892158b 24888@@ -2975,7 +2975,7 @@ static int cm_sidr_req_handler(struct cm
ae4e228f
MT
24889 cur_cm_id_priv = cm_insert_remote_sidr(cm_id_priv);
24890 if (cur_cm_id_priv) {
24891 spin_unlock_irq(&cm.lock);
24892- atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
24893+ atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
24894 counter[CM_SIDR_REQ_COUNTER]);
24895 goto out; /* Duplicate message. */
24896 }
16454cff 24897@@ -3187,10 +3187,10 @@ static void cm_send_handler(struct ib_ma
ae4e228f
MT
24898 if (!msg->context[0] && (attr_index != CM_REJ_COUNTER))
24899 msg->retries = 1;
24900
24901- atomic_long_add(1 + msg->retries,
24902+ atomic_long_add_unchecked(1 + msg->retries,
24903 &port->counter_group[CM_XMIT].counter[attr_index]);
24904 if (msg->retries)
24905- atomic_long_add(msg->retries,
24906+ atomic_long_add_unchecked(msg->retries,
24907 &port->counter_group[CM_XMIT_RETRIES].
24908 counter[attr_index]);
24909
16454cff 24910@@ -3400,7 +3400,7 @@ static void cm_recv_handler(struct ib_ma
ae4e228f
MT
24911 }
24912
24913 attr_id = be16_to_cpu(mad_recv_wc->recv_buf.mad->mad_hdr.attr_id);
24914- atomic_long_inc(&port->counter_group[CM_RECV].
24915+ atomic_long_inc_unchecked(&port->counter_group[CM_RECV].
24916 counter[attr_id - CM_ATTR_ID_OFFSET]);
24917
24918 work = kmalloc(sizeof *work + sizeof(struct ib_sa_path_rec) * paths,
16454cff 24919@@ -3598,7 +3598,7 @@ static ssize_t cm_show_counter(struct ko
ae4e228f
MT
24920 cm_attr = container_of(attr, struct cm_counter_attribute, attr);
24921
24922 return sprintf(buf, "%ld\n",
24923- atomic_long_read(&group->counter[cm_attr->index]));
24924+ atomic_long_read_unchecked(&group->counter[cm_attr->index]));
24925 }
24926
df50ba0c 24927 static const struct sysfs_ops cm_counter_ops = {
16454cff
MT
24928diff -urNp linux-2.6.38.1/drivers/infiniband/hw/qib/qib.h linux-2.6.38.1/drivers/infiniband/hw/qib/qib.h
24929--- linux-2.6.38.1/drivers/infiniband/hw/qib/qib.h 2011-03-14 21:20:32.000000000 -0400
24930+++ linux-2.6.38.1/drivers/infiniband/hw/qib/qib.h 2011-03-21 18:31:35.000000000 -0400
6892158b 24931@@ -51,6 +51,7 @@
57199397
MT
24932 #include <linux/completion.h>
24933 #include <linux/kref.h>
24934 #include <linux/sched.h>
24935+#include <linux/slab.h>
24936
24937 #include "qib_common.h"
24938 #include "qib_verbs.h"
16454cff
MT
24939diff -urNp linux-2.6.38.1/drivers/input/keyboard/atkbd.c linux-2.6.38.1/drivers/input/keyboard/atkbd.c
24940--- linux-2.6.38.1/drivers/input/keyboard/atkbd.c 2011-03-14 21:20:32.000000000 -0400
24941+++ linux-2.6.38.1/drivers/input/keyboard/atkbd.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 24942@@ -1250,7 +1250,7 @@ static struct serio_device_id atkbd_seri
58c5fc13
MT
24943 .id = SERIO_ANY,
24944 .extra = SERIO_ANY,
24945 },
24946- { 0 }
24947+ { 0, 0, 0, 0 }
24948 };
24949
24950 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
16454cff
MT
24951diff -urNp linux-2.6.38.1/drivers/input/mouse/lifebook.c linux-2.6.38.1/drivers/input/mouse/lifebook.c
24952--- linux-2.6.38.1/drivers/input/mouse/lifebook.c 2011-03-14 21:20:32.000000000 -0400
24953+++ linux-2.6.38.1/drivers/input/mouse/lifebook.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 24954@@ -123,7 +123,7 @@ static const struct dmi_system_id __init
58c5fc13
MT
24955 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
24956 },
24957 },
24958- { }
24959+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
24960 };
24961
ae4e228f 24962 void __init lifebook_module_init(void)
16454cff
MT
24963diff -urNp linux-2.6.38.1/drivers/input/mouse/psmouse-base.c linux-2.6.38.1/drivers/input/mouse/psmouse-base.c
24964--- linux-2.6.38.1/drivers/input/mouse/psmouse-base.c 2011-03-14 21:20:32.000000000 -0400
24965+++ linux-2.6.38.1/drivers/input/mouse/psmouse-base.c 2011-03-21 18:31:35.000000000 -0400
6892158b 24966@@ -1462,7 +1462,7 @@ static struct serio_device_id psmouse_se
58c5fc13
MT
24967 .id = SERIO_ANY,
24968 .extra = SERIO_ANY,
24969 },
24970- { 0 }
24971+ { 0, 0, 0, 0 }
24972 };
24973
24974 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
16454cff
MT
24975diff -urNp linux-2.6.38.1/drivers/input/mouse/synaptics.c linux-2.6.38.1/drivers/input/mouse/synaptics.c
24976--- linux-2.6.38.1/drivers/input/mouse/synaptics.c 2011-03-14 21:20:32.000000000 -0400
24977+++ linux-2.6.38.1/drivers/input/mouse/synaptics.c 2011-03-21 18:31:35.000000000 -0400
24978@@ -559,7 +559,7 @@ static void synaptics_process_packet(str
58c5fc13
MT
24979 break;
24980 case 2:
24981 if (SYN_MODEL_PEN(priv->model_id))
24982- ; /* Nothing, treat a pen as a single finger */
24983+ break; /* Nothing, treat a pen as a single finger */
24984 break;
24985 case 4 ... 15:
24986 if (SYN_CAP_PALMDETECT(priv->capabilities))
16454cff 24987@@ -825,7 +825,6 @@ static const struct dmi_system_id __init
ae4e228f 24988 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
58c5fc13
MT
24989 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
24990 },
ae4e228f
MT
24991-
24992 },
24993 {
24994 /* Toshiba Portege M300 */
16454cff 24995@@ -834,9 +833,8 @@ static const struct dmi_system_id __init
ae4e228f
MT
24996 DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
24997 DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
24998 },
24999-
58c5fc13
MT
25000 },
25001- { }
25002+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
58c5fc13 25003 #endif
ae4e228f 25004 };
58c5fc13 25005
16454cff
MT
25006diff -urNp linux-2.6.38.1/drivers/input/mousedev.c linux-2.6.38.1/drivers/input/mousedev.c
25007--- linux-2.6.38.1/drivers/input/mousedev.c 2011-03-14 21:20:32.000000000 -0400
25008+++ linux-2.6.38.1/drivers/input/mousedev.c 2011-03-21 18:31:35.000000000 -0400
25009@@ -764,7 +764,7 @@ static ssize_t mousedev_read(struct file
ae4e228f
MT
25010
25011 spin_unlock_irq(&client->packet_lock);
25012
25013- if (copy_to_user(buffer, data, count))
25014+ if (count > sizeof(data) || copy_to_user(buffer, data, count))
25015 return -EFAULT;
25016
25017 return count;
16454cff 25018@@ -1067,7 +1067,7 @@ static struct input_handler mousedev_han
58c5fc13
MT
25019
25020 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
25021 static struct miscdevice psaux_mouse = {
25022- PSMOUSE_MINOR, "psaux", &mousedev_fops
25023+ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
25024 };
25025 static int psaux_registered;
25026 #endif
16454cff
MT
25027diff -urNp linux-2.6.38.1/drivers/input/serio/i8042-x86ia64io.h linux-2.6.38.1/drivers/input/serio/i8042-x86ia64io.h
25028--- linux-2.6.38.1/drivers/input/serio/i8042-x86ia64io.h 2011-03-14 21:20:32.000000000 -0400
25029+++ linux-2.6.38.1/drivers/input/serio/i8042-x86ia64io.h 2011-03-21 18:31:35.000000000 -0400
57199397 25030@@ -183,7 +183,7 @@ static const struct dmi_system_id __init
58c5fc13
MT
25031 DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
25032 },
25033 },
25034- { }
25035+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25036 };
25037
25038 /*
c52201e0
MT
25039@@ -431,7 +431,7 @@ static const struct dmi_system_id __init
25040 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
58c5fc13
MT
25041 },
25042 },
25043- { }
25044+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25045 };
25046
ae4e228f 25047 static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
c52201e0 25048@@ -505,7 +505,7 @@ static const struct dmi_system_id __init
ae4e228f 25049 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
58c5fc13
MT
25050 },
25051 },
25052- { }
25053+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25054 };
25055
25056 #ifdef CONFIG_PNP
c52201e0 25057@@ -524,7 +524,7 @@ static const struct dmi_system_id __init
58c5fc13
MT
25058 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
25059 },
25060 },
25061- { }
ae4e228f
MT
25062+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25063 };
25064
25065 static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
c52201e0 25066@@ -548,7 +548,7 @@ static const struct dmi_system_id __init
ae4e228f
MT
25067 DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
25068 },
25069 },
25070- { }
58c5fc13
MT
25071+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25072 };
25073 #endif
25074
16454cff 25075@@ -640,7 +640,7 @@ static const struct dmi_system_id __init
58c5fc13
MT
25076 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
25077 },
25078 },
25079- { }
25080+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25081 };
25082
25083 #endif /* CONFIG_X86 */
16454cff
MT
25084diff -urNp linux-2.6.38.1/drivers/input/serio/serio_raw.c linux-2.6.38.1/drivers/input/serio/serio_raw.c
25085--- linux-2.6.38.1/drivers/input/serio/serio_raw.c 2011-03-14 21:20:32.000000000 -0400
25086+++ linux-2.6.38.1/drivers/input/serio/serio_raw.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 25087@@ -376,7 +376,7 @@ static struct serio_device_id serio_raw_
58c5fc13
MT
25088 .id = SERIO_ANY,
25089 .extra = SERIO_ANY,
25090 },
25091- { 0 }
25092+ { 0, 0, 0, 0 }
25093 };
25094
25095 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
16454cff
MT
25096diff -urNp linux-2.6.38.1/drivers/isdn/gigaset/common.c linux-2.6.38.1/drivers/isdn/gigaset/common.c
25097--- linux-2.6.38.1/drivers/isdn/gigaset/common.c 2011-03-14 21:20:32.000000000 -0400
25098+++ linux-2.6.38.1/drivers/isdn/gigaset/common.c 2011-03-21 18:31:35.000000000 -0400
57199397 25099@@ -723,7 +723,7 @@ struct cardstate *gigaset_initcs(struct
58c5fc13
MT
25100 cs->commands_pending = 0;
25101 cs->cur_at_seq = 0;
25102 cs->gotfwver = -1;
25103- cs->open_count = 0;
c52201e0 25104+ local_set(&cs->open_count, 0);
58c5fc13
MT
25105 cs->dev = NULL;
25106 cs->tty = NULL;
25107 cs->tty_dev = NULL;
16454cff
MT
25108diff -urNp linux-2.6.38.1/drivers/isdn/gigaset/gigaset.h linux-2.6.38.1/drivers/isdn/gigaset/gigaset.h
25109--- linux-2.6.38.1/drivers/isdn/gigaset/gigaset.h 2011-03-14 21:20:32.000000000 -0400
25110+++ linux-2.6.38.1/drivers/isdn/gigaset/gigaset.h 2011-03-21 18:31:35.000000000 -0400
c52201e0
MT
25111@@ -35,6 +35,7 @@
25112 #include <linux/tty_driver.h>
25113 #include <linux/list.h>
25114 #include <asm/atomic.h>
25115+#include <asm/local.h>
25116
25117 #define GIG_VERSION {0, 5, 0, 0}
25118 #define GIG_COMPAT {0, 4, 0, 0}
25119@@ -433,7 +434,7 @@ struct cardstate {
58c5fc13
MT
25120 spinlock_t cmdlock;
25121 unsigned curlen, cmdbytes;
25122
25123- unsigned open_count;
c52201e0 25124+ local_t open_count;
58c5fc13
MT
25125 struct tty_struct *tty;
25126 struct tasklet_struct if_wake_tasklet;
25127 unsigned control_state;
16454cff
MT
25128diff -urNp linux-2.6.38.1/drivers/isdn/gigaset/interface.c linux-2.6.38.1/drivers/isdn/gigaset/interface.c
25129--- linux-2.6.38.1/drivers/isdn/gigaset/interface.c 2011-03-14 21:20:32.000000000 -0400
25130+++ linux-2.6.38.1/drivers/isdn/gigaset/interface.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 25131@@ -160,9 +160,7 @@ static int if_open(struct tty_struct *tt
ae4e228f 25132 return -ERESTARTSYS;
58c5fc13
MT
25133 tty->driver_data = cs;
25134
25135- ++cs->open_count;
25136-
25137- if (cs->open_count == 1) {
c52201e0 25138+ if (local_inc_return(&cs->open_count) == 1) {
58c5fc13
MT
25139 spin_lock_irqsave(&cs->lock, flags);
25140 cs->tty = tty;
25141 spin_unlock_irqrestore(&cs->lock, flags);
df50ba0c 25142@@ -190,10 +188,10 @@ static void if_close(struct tty_struct *
58c5fc13
MT
25143
25144 if (!cs->connected)
25145 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
25146- else if (!cs->open_count)
c52201e0 25147+ else if (!local_read(&cs->open_count))
58c5fc13
MT
25148 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25149 else {
25150- if (!--cs->open_count) {
c52201e0 25151+ if (!local_dec_return(&cs->open_count)) {
58c5fc13
MT
25152 spin_lock_irqsave(&cs->lock, flags);
25153 cs->tty = NULL;
25154 spin_unlock_irqrestore(&cs->lock, flags);
df50ba0c 25155@@ -228,7 +226,7 @@ static int if_ioctl(struct tty_struct *t
58c5fc13
MT
25156 if (!cs->connected) {
25157 gig_dbg(DEBUG_IF, "not connected");
25158 retval = -ENODEV;
25159- } else if (!cs->open_count)
c52201e0 25160+ } else if (!local_read(&cs->open_count))
58c5fc13
MT
25161 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25162 else {
25163 retval = 0;
6892158b 25164@@ -358,7 +356,7 @@ static int if_write(struct tty_struct *t
58c5fc13 25165 retval = -ENODEV;
6892158b
MT
25166 goto done;
25167 }
25168- if (!cs->open_count) {
c52201e0 25169+ if (!local_read(&cs->open_count)) {
58c5fc13 25170 dev_warn(cs->dev, "%s: device not opened\n", __func__);
6892158b
MT
25171 retval = -ENODEV;
25172 goto done;
25173@@ -411,7 +409,7 @@ static int if_write_room(struct tty_stru
58c5fc13
MT
25174 if (!cs->connected) {
25175 gig_dbg(DEBUG_IF, "not connected");
25176 retval = -ENODEV;
25177- } else if (!cs->open_count)
c52201e0 25178+ } else if (!local_read(&cs->open_count))
58c5fc13
MT
25179 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25180 else if (cs->mstate != MS_LOCKED) {
25181 dev_warn(cs->dev, "can't write to unlocked device\n");
6892158b 25182@@ -441,7 +439,7 @@ static int if_chars_in_buffer(struct tty
ae4e228f
MT
25183
25184 if (!cs->connected)
58c5fc13 25185 gig_dbg(DEBUG_IF, "not connected");
ae4e228f 25186- else if (!cs->open_count)
c52201e0 25187+ else if (!local_read(&cs->open_count))
58c5fc13 25188 dev_warn(cs->dev, "%s: device not opened\n", __func__);
ae4e228f 25189 else if (cs->mstate != MS_LOCKED)
58c5fc13 25190 dev_warn(cs->dev, "can't write to unlocked device\n");
6892158b 25191@@ -469,7 +467,7 @@ static void if_throttle(struct tty_struc
58c5fc13
MT
25192
25193 if (!cs->connected)
25194 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
25195- else if (!cs->open_count)
c52201e0 25196+ else if (!local_read(&cs->open_count))
58c5fc13 25197 dev_warn(cs->dev, "%s: device not opened\n", __func__);
ae4e228f 25198 else
df50ba0c 25199 gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
6892158b 25200@@ -493,7 +491,7 @@ static void if_unthrottle(struct tty_str
58c5fc13
MT
25201
25202 if (!cs->connected)
25203 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
25204- else if (!cs->open_count)
c52201e0 25205+ else if (!local_read(&cs->open_count))
58c5fc13 25206 dev_warn(cs->dev, "%s: device not opened\n", __func__);
ae4e228f 25207 else
df50ba0c 25208 gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
6892158b 25209@@ -524,7 +522,7 @@ static void if_set_termios(struct tty_st
58c5fc13
MT
25210 goto out;
25211 }
25212
25213- if (!cs->open_count) {
c52201e0 25214+ if (!local_read(&cs->open_count)) {
58c5fc13
MT
25215 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25216 goto out;
25217 }
16454cff
MT
25218diff -urNp linux-2.6.38.1/drivers/isdn/hardware/avm/b1.c linux-2.6.38.1/drivers/isdn/hardware/avm/b1.c
25219--- linux-2.6.38.1/drivers/isdn/hardware/avm/b1.c 2011-03-14 21:20:32.000000000 -0400
25220+++ linux-2.6.38.1/drivers/isdn/hardware/avm/b1.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 25221@@ -176,7 +176,7 @@ int b1_load_t4file(avmcard *card, capilo
ae4e228f
MT
25222 }
25223 if (left) {
25224 if (t4file->user) {
25225- if (copy_from_user(buf, dp, left))
bc901d79 25226+ if (left > sizeof buf || copy_from_user(buf, dp, left))
ae4e228f
MT
25227 return -EFAULT;
25228 } else {
25229 memcpy(buf, dp, left);
df50ba0c 25230@@ -224,7 +224,7 @@ int b1_load_config(avmcard *card, capilo
ae4e228f
MT
25231 }
25232 if (left) {
25233 if (config->user) {
25234- if (copy_from_user(buf, dp, left))
bc901d79 25235+ if (left > sizeof buf || copy_from_user(buf, dp, left))
ae4e228f
MT
25236 return -EFAULT;
25237 } else {
25238 memcpy(buf, dp, left);
16454cff
MT
25239diff -urNp linux-2.6.38.1/drivers/isdn/icn/icn.c linux-2.6.38.1/drivers/isdn/icn/icn.c
25240--- linux-2.6.38.1/drivers/isdn/icn/icn.c 2011-03-14 21:20:32.000000000 -0400
25241+++ linux-2.6.38.1/drivers/isdn/icn/icn.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 25242@@ -1045,7 +1045,7 @@ icn_writecmd(const u_char * buf, int len
ae4e228f
MT
25243 if (count > len)
25244 count = len;
25245 if (user) {
25246- if (copy_from_user(msg, buf, count))
bc901d79 25247+ if (count > sizeof msg || copy_from_user(msg, buf, count))
ae4e228f
MT
25248 return -EFAULT;
25249 } else
25250 memcpy(msg, buf, count);
16454cff
MT
25251diff -urNp linux-2.6.38.1/drivers/leds/leds-lp5521.c linux-2.6.38.1/drivers/leds/leds-lp5521.c
25252--- linux-2.6.38.1/drivers/leds/leds-lp5521.c 2011-03-14 21:20:32.000000000 -0400
25253+++ linux-2.6.38.1/drivers/leds/leds-lp5521.c 2011-03-21 18:31:35.000000000 -0400
25254@@ -534,7 +534,7 @@ static ssize_t lp5521_selftest(struct de
317566c1
MT
25255 }
25256
25257 /* led class device attributes */
25258-static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current);
25259+static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
25260 static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
25261
25262 static struct attribute *lp5521_led_attributes[] = {
16454cff 25263@@ -548,15 +548,15 @@ static struct attribute_group lp5521_led
317566c1
MT
25264 };
25265
25266 /* device attributes */
25267-static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO,
25268+static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUSR,
25269 show_engine1_mode, store_engine1_mode);
25270-static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO,
25271+static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUSR,
25272 show_engine2_mode, store_engine2_mode);
25273-static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO,
25274+static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUSR,
25275 show_engine3_mode, store_engine3_mode);
25276-static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load);
25277-static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load);
25278-static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load);
25279+static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
25280+static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
25281+static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
25282 static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
25283
25284 static struct attribute *lp5521_attributes[] = {
16454cff
MT
25285diff -urNp linux-2.6.38.1/drivers/leds/leds-lp5523.c linux-2.6.38.1/drivers/leds/leds-lp5523.c
25286--- linux-2.6.38.1/drivers/leds/leds-lp5523.c 2011-03-14 21:20:32.000000000 -0400
25287+++ linux-2.6.38.1/drivers/leds/leds-lp5523.c 2011-03-21 18:31:35.000000000 -0400
25288@@ -713,7 +713,7 @@ static ssize_t store_current(struct devi
317566c1
MT
25289 }
25290
25291 /* led class device attributes */
25292-static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current);
25293+static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
25294 static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
25295
25296 static struct attribute *lp5523_led_attributes[] = {
16454cff 25297@@ -727,21 +727,21 @@ static struct attribute_group lp5523_led
317566c1
MT
25298 };
25299
25300 /* device attributes */
25301-static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO,
25302+static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUSR,
25303 show_engine1_mode, store_engine1_mode);
25304-static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO,
25305+static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUSR,
25306 show_engine2_mode, store_engine2_mode);
25307-static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO,
25308+static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUSR,
25309 show_engine3_mode, store_engine3_mode);
25310-static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUGO,
25311+static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUSR,
25312 show_engine1_leds, store_engine1_leds);
25313-static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUGO,
25314+static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUSR,
25315 show_engine2_leds, store_engine2_leds);
25316-static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUGO,
25317+static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUSR,
25318 show_engine3_leds, store_engine3_leds);
25319-static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load);
25320-static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load);
25321-static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load);
25322+static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
25323+static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
25324+static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
25325 static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL);
25326
25327 static struct attribute *lp5523_attributes[] = {
16454cff
MT
25328diff -urNp linux-2.6.38.1/drivers/lguest/core.c linux-2.6.38.1/drivers/lguest/core.c
25329--- linux-2.6.38.1/drivers/lguest/core.c 2011-03-14 21:20:32.000000000 -0400
25330+++ linux-2.6.38.1/drivers/lguest/core.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 25331@@ -92,9 +92,17 @@ static __init int map_switcher(void)
58c5fc13
MT
25332 * it's worked so far. The end address needs +1 because __get_vm_area
25333 * allocates an extra guard page, so we need space for that.
25334 */
25335+
25336+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
25337+ switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
25338+ VM_ALLOC | VM_KERNEXEC, SWITCHER_ADDR, SWITCHER_ADDR
25339+ + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
25340+#else
25341 switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
25342 VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR
25343 + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
25344+#endif
25345+
25346 if (!switcher_vma) {
25347 err = -ENOMEM;
25348 printk("lguest: could not map switcher pages high\n");
bc901d79
MT
25349@@ -119,7 +127,7 @@ static __init int map_switcher(void)
25350 * Now the Switcher is mapped at the right address, we can't fail!
25351 * Copy in the compiled-in Switcher code (from <arch>_switcher.S).
25352 */
25353- memcpy(switcher_vma->addr, start_switcher_text,
25354+ memcpy(switcher_vma->addr, ktla_ktva(start_switcher_text),
25355 end_switcher_text - start_switcher_text);
25356
25357 printk(KERN_INFO "lguest: mapped switcher at %p\n",
16454cff
MT
25358diff -urNp linux-2.6.38.1/drivers/lguest/x86/core.c linux-2.6.38.1/drivers/lguest/x86/core.c
25359--- linux-2.6.38.1/drivers/lguest/x86/core.c 2011-03-14 21:20:32.000000000 -0400
25360+++ linux-2.6.38.1/drivers/lguest/x86/core.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
25361@@ -59,7 +59,7 @@ static struct {
25362 /* Offset from where switcher.S was compiled to where we've copied it */
25363 static unsigned long switcher_offset(void)
25364 {
25365- return SWITCHER_ADDR - (unsigned long)start_switcher_text;
25366+ return SWITCHER_ADDR - (unsigned long)ktla_ktva(start_switcher_text);
25367 }
25368
25369 /* This cpu's struct lguest_pages. */
25370@@ -100,7 +100,13 @@ static void copy_in_guest_info(struct lg
25371 * These copies are pretty cheap, so we do them unconditionally: */
25372 /* Save the current Host top-level page directory.
25373 */
25374+
25375+#ifdef CONFIG_PAX_PER_CPU_PGD
25376+ pages->state.host_cr3 = read_cr3();
25377+#else
25378 pages->state.host_cr3 = __pa(current->mm->pgd);
25379+#endif
25380+
25381 /*
25382 * Set up the Guest's page tables to see this CPU's pages (and no
25383 * other CPU's pages).
25384@@ -547,7 +553,7 @@ void __init lguest_arch_host_init(void)
25385 * compiled-in switcher code and the high-mapped copy we just made.
25386 */
25387 for (i = 0; i < IDT_ENTRIES; i++)
25388- default_idt_entries[i] += switcher_offset();
25389+ default_idt_entries[i] = ktla_ktva(default_idt_entries[i]) + switcher_offset();
25390
25391 /*
25392 * Set up the Switcher's per-cpu areas.
25393@@ -630,7 +636,7 @@ void __init lguest_arch_host_init(void)
25394 * it will be undisturbed when we switch. To change %cs and jump we
25395 * need this structure to feed to Intel's "lcall" instruction.
25396 */
25397- lguest_entry.offset = (long)switch_to_guest + switcher_offset();
25398+ lguest_entry.offset = (long)ktla_ktva(switch_to_guest) + switcher_offset();
25399 lguest_entry.segment = LGUEST_CS;
25400
25401 /*
16454cff
MT
25402diff -urNp linux-2.6.38.1/drivers/lguest/x86/switcher_32.S linux-2.6.38.1/drivers/lguest/x86/switcher_32.S
25403--- linux-2.6.38.1/drivers/lguest/x86/switcher_32.S 2011-03-14 21:20:32.000000000 -0400
25404+++ linux-2.6.38.1/drivers/lguest/x86/switcher_32.S 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
25405@@ -87,6 +87,7 @@
25406 #include <asm/page.h>
25407 #include <asm/segment.h>
25408 #include <asm/lguest.h>
25409+#include <asm/processor-flags.h>
25410
25411 // We mark the start of the code to copy
25412 // It's placed in .text tho it's never run here
25413@@ -149,6 +150,13 @@ ENTRY(switch_to_guest)
25414 // Changes type when we load it: damn Intel!
25415 // For after we switch over our page tables
25416 // That entry will be read-only: we'd crash.
25417+
25418+#ifdef CONFIG_PAX_KERNEXEC
25419+ mov %cr0, %edx
25420+ xor $X86_CR0_WP, %edx
25421+ mov %edx, %cr0
25422+#endif
25423+
25424 movl $(GDT_ENTRY_TSS*8), %edx
25425 ltr %dx
25426
25427@@ -157,9 +165,15 @@ ENTRY(switch_to_guest)
25428 // Let's clear it again for our return.
25429 // The GDT descriptor of the Host
25430 // Points to the table after two "size" bytes
25431- movl (LGUEST_PAGES_host_gdt_desc+2)(%eax), %edx
25432+ movl (LGUEST_PAGES_host_gdt_desc+2)(%eax), %eax
25433 // Clear "used" from type field (byte 5, bit 2)
25434- andb $0xFD, (GDT_ENTRY_TSS*8 + 5)(%edx)
25435+ andb $0xFD, (GDT_ENTRY_TSS*8 + 5)(%eax)
25436+
25437+#ifdef CONFIG_PAX_KERNEXEC
25438+ mov %cr0, %eax
25439+ xor $X86_CR0_WP, %eax
25440+ mov %eax, %cr0
25441+#endif
25442
25443 // Once our page table's switched, the Guest is live!
25444 // The Host fades as we run this final step.
25445@@ -295,13 +309,12 @@ deliver_to_host:
25446 // I consulted gcc, and it gave
25447 // These instructions, which I gladly credit:
25448 leal (%edx,%ebx,8), %eax
25449- movzwl (%eax),%edx
25450- movl 4(%eax), %eax
25451- xorw %ax, %ax
25452- orl %eax, %edx
25453+ movl 4(%eax), %edx
25454+ movw (%eax), %dx
25455 // Now the address of the handler's in %edx
25456 // We call it now: its "iret" drops us home.
25457- jmp *%edx
25458+ ljmp $__KERNEL_CS, $1f
25459+1: jmp *%edx
25460
25461 // Every interrupt can come to us here
25462 // But we must truly tell each apart.
16454cff
MT
25463diff -urNp linux-2.6.38.1/drivers/md/bitmap.c linux-2.6.38.1/drivers/md/bitmap.c
25464--- linux-2.6.38.1/drivers/md/bitmap.c 2011-03-14 21:20:32.000000000 -0400
25465+++ linux-2.6.38.1/drivers/md/bitmap.c 2011-03-21 18:31:35.000000000 -0400
6892158b 25466@@ -55,7 +55,7 @@
58c5fc13
MT
25467 # if DEBUG > 0
25468 # define PRINTK(x...) printk(KERN_DEBUG x)
25469 # else
25470-# define PRINTK(x...)
25471+# define PRINTK(x...) do {} while (0)
25472 # endif
25473 #endif
25474
16454cff
MT
25475diff -urNp linux-2.6.38.1/drivers/md/dm-ioctl.c linux-2.6.38.1/drivers/md/dm-ioctl.c
25476--- linux-2.6.38.1/drivers/md/dm-ioctl.c 2011-03-14 21:20:32.000000000 -0400
25477+++ linux-2.6.38.1/drivers/md/dm-ioctl.c 2011-03-21 18:31:35.000000000 -0400
25478@@ -1541,7 +1541,7 @@ static int validate_params(uint cmd, str
25479 cmd == DM_LIST_VERSIONS_CMD)
25480 return 0;
25481
25482- if ((cmd == DM_DEV_CREATE_CMD)) {
25483+ if (cmd == DM_DEV_CREATE_CMD) {
25484 if (!*param->name) {
25485 DMWARN("name not supplied when creating device");
25486 return -EINVAL;
25487diff -urNp linux-2.6.38.1/drivers/md/dm-table.c linux-2.6.38.1/drivers/md/dm-table.c
25488--- linux-2.6.38.1/drivers/md/dm-table.c 2011-03-14 21:20:32.000000000 -0400
25489+++ linux-2.6.38.1/drivers/md/dm-table.c 2011-03-21 18:31:35.000000000 -0400
25490@@ -372,7 +372,7 @@ static int device_area_is_invalid(struct
58c5fc13
MT
25491 if (!dev_size)
25492 return 0;
25493
25494- if ((start >= dev_size) || (start + len > dev_size)) {
25495+ if ((start >= dev_size) || (len > dev_size - start)) {
25496 DMWARN("%s: %s too small for target: "
25497 "start=%llu, len=%llu, dev_size=%llu",
25498 dm_device_name(ti->table->md), bdevname(bdev, b),
16454cff
MT
25499diff -urNp linux-2.6.38.1/drivers/md/md.c linux-2.6.38.1/drivers/md/md.c
25500--- linux-2.6.38.1/drivers/md/md.c 2011-03-14 21:20:32.000000000 -0400
25501+++ linux-2.6.38.1/drivers/md/md.c 2011-03-21 18:31:35.000000000 -0400
25502@@ -1889,7 +1889,7 @@ static int bind_rdev_to_array(mdk_rdev_t
bc901d79
MT
25503
25504 ko = &part_to_dev(rdev->bdev->bd_part)->kobj;
25505 if (sysfs_create_link(&rdev->kobj, ko, "block"))
25506- /* failure here is OK */;
25507+ /* failure here is OK */{}
25508 rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state");
25509
25510 list_add_rcu(&rdev->same_set, &mddev->disks);
16454cff 25511@@ -2499,7 +2499,7 @@ slot_store(mdk_rdev_t *rdev, const char
bc901d79
MT
25512 sysfs_notify_dirent_safe(rdev->sysfs_state);
25513 sprintf(nm, "rd%d", rdev->raid_disk);
25514 if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm))
25515- /* failure here is OK */;
25516+ /* failure here is OK */{}
25517 /* don't wakeup anyone, leave that to userspace. */
25518 } else {
16454cff
MT
25519 if (slot >= rdev->mddev->raid_disks &&
25520@@ -4594,7 +4594,7 @@ int md_run(mddev_t *mddev)
bc901d79
MT
25521 char nm[20];
25522 sprintf(nm, "rd%d", rdev->raid_disk);
25523 if (sysfs_create_link(&mddev->kobj, &rdev->kobj, nm))
25524- /* failure here is OK */;
25525+ /* failure here is OK */{}
25526 }
25527
25528 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
16454cff 25529@@ -6462,7 +6462,7 @@ static int md_seq_show(struct seq_file *
58c5fc13
MT
25530 chunk_kb ? "KB" : "B");
25531 if (bitmap->file) {
25532 seq_printf(seq, ", file: ");
25533- seq_path(seq, &bitmap->file->f_path, " \t\n");
25534+ seq_path(seq, &bitmap->file->f_path, " \t\n\\");
25535 }
25536
25537 seq_printf(seq, "\n");
16454cff 25538@@ -6556,7 +6556,7 @@ static int is_mddev_idle(mddev_t *mddev,
58c5fc13
MT
25539 struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
25540 curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
25541 (int)part_stat_read(&disk->part0, sectors[1]) -
25542- atomic_read(&disk->sync_io);
25543+ atomic_read_unchecked(&disk->sync_io);
25544 /* sync IO will cause sync_io to increase before the disk_stats
25545 * as sync_io is counted when a request starts, and
25546 * disk_stats is counted when it completes.
16454cff 25547@@ -7070,7 +7070,7 @@ static int remove_and_add_spares(mddev_t
bc901d79
MT
25548 sprintf(nm, "rd%d", rdev->raid_disk);
25549 if (sysfs_create_link(&mddev->kobj,
25550 &rdev->kobj, nm))
25551- /* failure here is OK */;
25552+ /* failure here is OK */{}
25553 spares++;
25554 md_new_event(mddev);
25555 set_bit(MD_CHANGE_DEVS, &mddev->flags);
16454cff
MT
25556diff -urNp linux-2.6.38.1/drivers/md/md.h linux-2.6.38.1/drivers/md/md.h
25557--- linux-2.6.38.1/drivers/md/md.h 2011-03-14 21:20:32.000000000 -0400
25558+++ linux-2.6.38.1/drivers/md/md.h 2011-03-21 18:31:35.000000000 -0400
25559@@ -360,7 +360,7 @@ static inline void rdev_dec_pending(mdk_
58c5fc13
MT
25560
25561 static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
25562 {
25563- atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
25564+ atomic_add_unchecked(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
25565 }
25566
25567 struct mdk_personality
16454cff
MT
25568diff -urNp linux-2.6.38.1/drivers/media/dvb/dvb-core/dvbdev.c linux-2.6.38.1/drivers/media/dvb/dvb-core/dvbdev.c
25569--- linux-2.6.38.1/drivers/media/dvb/dvb-core/dvbdev.c 2011-03-14 21:20:32.000000000 -0400
25570+++ linux-2.6.38.1/drivers/media/dvb/dvb-core/dvbdev.c 2011-03-21 18:31:35.000000000 -0400
25571@@ -192,7 +192,7 @@ int dvb_register_device(struct dvb_adapt
ae4e228f
MT
25572 const struct dvb_device *template, void *priv, int type)
25573 {
25574 struct dvb_device *dvbdev;
16454cff
MT
25575- struct file_operations *dvbdevfops;
25576+ struct file_operations *dvbdevfops; /* cannot be const, see this function */
ae4e228f
MT
25577 struct device *clsdev;
25578 int minor;
16454cff
MT
25579 int id;
25580diff -urNp linux-2.6.38.1/drivers/media/radio/radio-cadet.c linux-2.6.38.1/drivers/media/radio/radio-cadet.c
25581--- linux-2.6.38.1/drivers/media/radio/radio-cadet.c 2011-03-14 21:20:32.000000000 -0400
25582+++ linux-2.6.38.1/drivers/media/radio/radio-cadet.c 2011-03-21 18:31:35.000000000 -0400
25583@@ -349,7 +349,7 @@ static ssize_t cadet_read(struct file *f
25584 readbuf[i++] = dev->rdsbuf[dev->rdsout++];
25585 mutex_unlock(&dev->lock);
25586
25587- if (copy_to_user(data, readbuf, i))
25588+ if (i > sizeof readbuf || copy_to_user(data, readbuf, i))
25589 return -EFAULT;
25590 return i;
25591 }
25592diff -urNp linux-2.6.38.1/drivers/media/rc/ir-lirc-codec.c linux-2.6.38.1/drivers/media/rc/ir-lirc-codec.c
25593--- linux-2.6.38.1/drivers/media/rc/ir-lirc-codec.c 2011-03-14 21:20:32.000000000 -0400
25594+++ linux-2.6.38.1/drivers/media/rc/ir-lirc-codec.c 2011-03-21 18:31:35.000000000 -0400
25595@@ -277,7 +277,7 @@ static void ir_lirc_close(void *data)
bc901d79
MT
25596 return;
25597 }
25598
25599-static struct file_operations lirc_fops = {
25600+static const struct file_operations lirc_fops = {
25601 .owner = THIS_MODULE,
25602 .write = ir_lirc_transmit_ir,
25603 .unlocked_ioctl = ir_lirc_ioctl,
16454cff
MT
25604diff -urNp linux-2.6.38.1/drivers/media/rc/lirc_dev.c linux-2.6.38.1/drivers/media/rc/lirc_dev.c
25605--- linux-2.6.38.1/drivers/media/rc/lirc_dev.c 2011-03-14 21:20:32.000000000 -0400
25606+++ linux-2.6.38.1/drivers/media/rc/lirc_dev.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 25607@@ -151,7 +151,7 @@ static int lirc_thread(void *irctl)
6892158b
MT
25608 }
25609
25610
bc901d79
MT
25611-static struct file_operations lirc_dev_fops = {
25612+static const struct file_operations lirc_dev_fops = {
6892158b
MT
25613 .owner = THIS_MODULE,
25614 .read = lirc_dev_fop_read,
25615 .write = lirc_dev_fop_write,
16454cff
MT
25616diff -urNp linux-2.6.38.1/drivers/media/video/sn9c102/sn9c102_core.c linux-2.6.38.1/drivers/media/video/sn9c102/sn9c102_core.c
25617--- linux-2.6.38.1/drivers/media/video/sn9c102/sn9c102_core.c 2011-03-14 21:20:32.000000000 -0400
25618+++ linux-2.6.38.1/drivers/media/video/sn9c102/sn9c102_core.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
25619@@ -1430,9 +1430,9 @@ static DEVICE_ATTR(i2c_reg, S_IRUGO | S_
25620 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
25621 static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
25622 sn9c102_show_i2c_val, sn9c102_store_i2c_val);
25623-static DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
25624-static DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
25625-static DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
25626+static DEVICE_ATTR(green, S_IWUSR, NULL, sn9c102_store_green);
25627+static DEVICE_ATTR(blue, S_IWUSR, NULL, sn9c102_store_blue);
25628+static DEVICE_ATTR(red, S_IWUSR, NULL, sn9c102_store_red);
25629 static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
25630
25631
16454cff
MT
25632diff -urNp linux-2.6.38.1/drivers/message/fusion/mptbase.c linux-2.6.38.1/drivers/message/fusion/mptbase.c
25633--- linux-2.6.38.1/drivers/message/fusion/mptbase.c 2011-03-14 21:20:32.000000000 -0400
25634+++ linux-2.6.38.1/drivers/message/fusion/mptbase.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 25635@@ -6683,8 +6683,13 @@ static int mpt_iocinfo_proc_show(struct
6892158b
MT
25636 seq_printf(m, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
25637 seq_printf(m, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
57199397
MT
25638
25639+#ifdef CONFIG_GRKERNSEC_HIDESYM
6892158b 25640+ seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n", NULL, NULL);
57199397 25641+#else
6892158b 25642 seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
57199397
MT
25643 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
25644+#endif
25645+
25646 /*
25647 * Rounding UP to nearest 4-kB boundary here...
25648 */
16454cff
MT
25649diff -urNp linux-2.6.38.1/drivers/message/fusion/mptdebug.h linux-2.6.38.1/drivers/message/fusion/mptdebug.h
25650--- linux-2.6.38.1/drivers/message/fusion/mptdebug.h 2011-03-14 21:20:32.000000000 -0400
25651+++ linux-2.6.38.1/drivers/message/fusion/mptdebug.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
25652@@ -71,7 +71,7 @@
25653 CMD; \
25654 }
25655 #else
25656-#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
25657+#define MPT_CHECK_LOGGING(IOC, CMD, BITS) do {} while (0)
25658 #endif
25659
25660
16454cff
MT
25661diff -urNp linux-2.6.38.1/drivers/message/fusion/mptsas.c linux-2.6.38.1/drivers/message/fusion/mptsas.c
25662--- linux-2.6.38.1/drivers/message/fusion/mptsas.c 2011-03-14 21:20:32.000000000 -0400
25663+++ linux-2.6.38.1/drivers/message/fusion/mptsas.c 2011-03-21 18:31:35.000000000 -0400
6892158b 25664@@ -439,6 +439,23 @@ mptsas_is_end_device(struct mptsas_devin
df50ba0c
MT
25665 return 0;
25666 }
25667
25668+static inline void
25669+mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
25670+{
25671+ if (phy_info->port_details) {
25672+ phy_info->port_details->rphy = rphy;
25673+ dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
25674+ ioc->name, rphy));
25675+ }
25676+
25677+ if (rphy) {
25678+ dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
25679+ &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
25680+ dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
25681+ ioc->name, rphy, rphy->dev.release));
25682+ }
25683+}
25684+
25685 /* no mutex */
25686 static void
25687 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
6892158b 25688@@ -477,23 +494,6 @@ mptsas_get_rphy(struct mptsas_phyinfo *p
df50ba0c
MT
25689 return NULL;
25690 }
25691
25692-static inline void
25693-mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
25694-{
25695- if (phy_info->port_details) {
25696- phy_info->port_details->rphy = rphy;
25697- dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
25698- ioc->name, rphy));
25699- }
25700-
25701- if (rphy) {
25702- dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
25703- &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
25704- dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
25705- ioc->name, rphy, rphy->dev.release));
25706- }
25707-}
25708-
25709 static inline struct sas_port *
25710 mptsas_get_port(struct mptsas_phyinfo *phy_info)
25711 {
16454cff
MT
25712diff -urNp linux-2.6.38.1/drivers/message/fusion/mptscsih.c linux-2.6.38.1/drivers/message/fusion/mptscsih.c
25713--- linux-2.6.38.1/drivers/message/fusion/mptscsih.c 2011-03-14 21:20:32.000000000 -0400
25714+++ linux-2.6.38.1/drivers/message/fusion/mptscsih.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
25715@@ -1268,15 +1268,16 @@ mptscsih_info(struct Scsi_Host *SChost)
25716
25717 h = shost_priv(SChost);
25718
25719- if (h) {
25720- if (h->info_kbuf == NULL)
25721- if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
25722- return h->info_kbuf;
25723- h->info_kbuf[0] = '\0';
25724+ if (!h)
25725+ return NULL;
25726
25727- mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
25728- h->info_kbuf[size-1] = '\0';
25729- }
25730+ if (h->info_kbuf == NULL)
25731+ if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
25732+ return h->info_kbuf;
25733+ h->info_kbuf[0] = '\0';
25734+
25735+ mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
25736+ h->info_kbuf[size-1] = '\0';
25737
25738 return h->info_kbuf;
25739 }
16454cff
MT
25740diff -urNp linux-2.6.38.1/drivers/message/i2o/i2o_proc.c linux-2.6.38.1/drivers/message/i2o/i2o_proc.c
25741--- linux-2.6.38.1/drivers/message/i2o/i2o_proc.c 2011-03-14 21:20:32.000000000 -0400
25742+++ linux-2.6.38.1/drivers/message/i2o/i2o_proc.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 25743@@ -255,13 +255,6 @@ static char *scsi_devices[] = {
58c5fc13
MT
25744 "Array Controller Device"
25745 };
25746
25747-static char *chtostr(u8 * chars, int n)
25748-{
25749- char tmp[256];
25750- tmp[0] = 0;
25751- return strncat(tmp, (char *)chars, n);
25752-}
25753-
25754 static int i2o_report_query_status(struct seq_file *seq, int block_status,
25755 char *group)
25756 {
df50ba0c 25757@@ -838,8 +831,7 @@ static int i2o_seq_show_ddm_table(struct
58c5fc13
MT
25758
25759 seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id);
25760 seq_printf(seq, "%-#8x", ddm_table.module_id);
25761- seq_printf(seq, "%-29s",
25762- chtostr(ddm_table.module_name_version, 28));
25763+ seq_printf(seq, "%-.28s", ddm_table.module_name_version);
25764 seq_printf(seq, "%9d ", ddm_table.data_size);
25765 seq_printf(seq, "%8d", ddm_table.code_size);
25766
df50ba0c 25767@@ -940,8 +932,8 @@ static int i2o_seq_show_drivers_stored(s
58c5fc13
MT
25768
25769 seq_printf(seq, "%-#7x", dst->i2o_vendor_id);
25770 seq_printf(seq, "%-#8x", dst->module_id);
25771- seq_printf(seq, "%-29s", chtostr(dst->module_name_version, 28));
25772- seq_printf(seq, "%-9s", chtostr(dst->date, 8));
25773+ seq_printf(seq, "%-.28s", dst->module_name_version);
25774+ seq_printf(seq, "%-.8s", dst->date);
25775 seq_printf(seq, "%8d ", dst->module_size);
25776 seq_printf(seq, "%8d ", dst->mpb_size);
25777 seq_printf(seq, "0x%04x", dst->module_flags);
df50ba0c 25778@@ -1272,14 +1264,10 @@ static int i2o_seq_show_dev_identity(str
58c5fc13
MT
25779 seq_printf(seq, "Device Class : %s\n", i2o_get_class_name(work16[0]));
25780 seq_printf(seq, "Owner TID : %0#5x\n", work16[2]);
25781 seq_printf(seq, "Parent TID : %0#5x\n", work16[3]);
25782- seq_printf(seq, "Vendor info : %s\n",
25783- chtostr((u8 *) (work32 + 2), 16));
25784- seq_printf(seq, "Product info : %s\n",
25785- chtostr((u8 *) (work32 + 6), 16));
25786- seq_printf(seq, "Description : %s\n",
25787- chtostr((u8 *) (work32 + 10), 16));
25788- seq_printf(seq, "Product rev. : %s\n",
25789- chtostr((u8 *) (work32 + 14), 8));
25790+ seq_printf(seq, "Vendor info : %.16s\n", (u8 *) (work32 + 2));
25791+ seq_printf(seq, "Product info : %.16s\n", (u8 *) (work32 + 6));
25792+ seq_printf(seq, "Description : %.16s\n", (u8 *) (work32 + 10));
25793+ seq_printf(seq, "Product rev. : %.8s\n", (u8 *) (work32 + 14));
25794
25795 seq_printf(seq, "Serial number : ");
25796 print_serial_number(seq, (u8 *) (work32 + 16),
df50ba0c 25797@@ -1324,10 +1312,8 @@ static int i2o_seq_show_ddm_identity(str
58c5fc13
MT
25798 }
25799
25800 seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid);
25801- seq_printf(seq, "Module name : %s\n",
25802- chtostr(result.module_name, 24));
25803- seq_printf(seq, "Module revision : %s\n",
25804- chtostr(result.module_rev, 8));
25805+ seq_printf(seq, "Module name : %.24s\n", result.module_name);
25806+ seq_printf(seq, "Module revision : %.8s\n", result.module_rev);
25807
25808 seq_printf(seq, "Serial number : ");
25809 print_serial_number(seq, result.serial_number, sizeof(result) - 36);
df50ba0c 25810@@ -1358,14 +1344,10 @@ static int i2o_seq_show_uinfo(struct seq
58c5fc13
MT
25811 return 0;
25812 }
25813
25814- seq_printf(seq, "Device name : %s\n",
25815- chtostr(result.device_name, 64));
25816- seq_printf(seq, "Service name : %s\n",
25817- chtostr(result.service_name, 64));
25818- seq_printf(seq, "Physical name : %s\n",
25819- chtostr(result.physical_location, 64));
25820- seq_printf(seq, "Instance number : %s\n",
25821- chtostr(result.instance_number, 4));
25822+ seq_printf(seq, "Device name : %.64s\n", result.device_name);
25823+ seq_printf(seq, "Service name : %.64s\n", result.service_name);
25824+ seq_printf(seq, "Physical name : %.64s\n", result.physical_location);
25825+ seq_printf(seq, "Instance number : %.4s\n", result.instance_number);
25826
25827 return 0;
25828 }
16454cff
MT
25829diff -urNp linux-2.6.38.1/drivers/mfd/ab3100-core.c linux-2.6.38.1/drivers/mfd/ab3100-core.c
25830--- linux-2.6.38.1/drivers/mfd/ab3100-core.c 2011-03-14 21:20:32.000000000 -0400
25831+++ linux-2.6.38.1/drivers/mfd/ab3100-core.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
25832@@ -613,7 +613,7 @@ static void ab3100_setup_debugfs(struct
25833 ab3100_get_priv.ab3100 = ab3100;
25834 ab3100_get_priv.mode = false;
25835 ab3100_get_reg_file = debugfs_create_file("get_reg",
25836- S_IWUGO, ab3100_dir, &ab3100_get_priv,
25837+ S_IWUSR, ab3100_dir, &ab3100_get_priv,
25838 &ab3100_get_set_reg_fops);
25839 if (!ab3100_get_reg_file) {
25840 err = -ENOMEM;
25841@@ -623,7 +623,7 @@ static void ab3100_setup_debugfs(struct
25842 ab3100_set_priv.ab3100 = ab3100;
25843 ab3100_set_priv.mode = true;
25844 ab3100_set_reg_file = debugfs_create_file("set_reg",
25845- S_IWUGO, ab3100_dir, &ab3100_set_priv,
25846+ S_IWUSR, ab3100_dir, &ab3100_set_priv,
25847 &ab3100_get_set_reg_fops);
25848 if (!ab3100_set_reg_file) {
25849 err = -ENOMEM;
16454cff
MT
25850diff -urNp linux-2.6.38.1/drivers/mfd/ab3550-core.c linux-2.6.38.1/drivers/mfd/ab3550-core.c
25851--- linux-2.6.38.1/drivers/mfd/ab3550-core.c 2011-03-14 21:20:32.000000000 -0400
25852+++ linux-2.6.38.1/drivers/mfd/ab3550-core.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
25853@@ -1053,17 +1053,17 @@ static inline void ab3550_setup_debugfs(
25854 goto exit_destroy_dir;
25855
25856 ab3550_bank_file = debugfs_create_file("register-bank",
25857- (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_bank_fops);
25858+ (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_bank_fops);
25859 if (!ab3550_bank_file)
25860 goto exit_destroy_reg;
25861
25862 ab3550_address_file = debugfs_create_file("register-address",
25863- (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_address_fops);
25864+ (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_address_fops);
25865 if (!ab3550_address_file)
25866 goto exit_destroy_bank;
25867
25868 ab3550_val_file = debugfs_create_file("register-value",
25869- (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_val_fops);
25870+ (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_val_fops);
25871 if (!ab3550_val_file)
25872 goto exit_destroy_address;
25873
16454cff
MT
25874diff -urNp linux-2.6.38.1/drivers/mfd/ab8500-debugfs.c linux-2.6.38.1/drivers/mfd/ab8500-debugfs.c
25875--- linux-2.6.38.1/drivers/mfd/ab8500-debugfs.c 2011-03-14 21:20:32.000000000 -0400
25876+++ linux-2.6.38.1/drivers/mfd/ab8500-debugfs.c 2011-03-21 18:31:35.000000000 -0400
317566c1 25877@@ -585,18 +585,18 @@ static int __devinit ab8500_debug_probe(
16454cff
MT
25878 goto exit_destroy_dir;
25879
25880 ab8500_bank_file = debugfs_create_file("register-bank",
25881- (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops);
25882+ (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_bank_fops);
25883 if (!ab8500_bank_file)
25884 goto exit_destroy_reg;
25885
25886 ab8500_address_file = debugfs_create_file("register-address",
25887- (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev,
25888+ (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev,
25889 &ab8500_address_fops);
25890 if (!ab8500_address_file)
25891 goto exit_destroy_bank;
25892
25893 ab8500_val_file = debugfs_create_file("register-value",
25894- (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops);
25895+ (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_val_fops);
25896 if (!ab8500_val_file)
25897 goto exit_destroy_address;
25898
25899diff -urNp linux-2.6.38.1/drivers/mfd/janz-cmodio.c linux-2.6.38.1/drivers/mfd/janz-cmodio.c
25900--- linux-2.6.38.1/drivers/mfd/janz-cmodio.c 2011-03-14 21:20:32.000000000 -0400
25901+++ linux-2.6.38.1/drivers/mfd/janz-cmodio.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
25902@@ -13,6 +13,7 @@
25903
25904 #include <linux/kernel.h>
25905 #include <linux/module.h>
25906+#include <linux/slab.h>
25907 #include <linux/init.h>
25908 #include <linux/pci.h>
25909 #include <linux/interrupt.h>
16454cff
MT
25910diff -urNp linux-2.6.38.1/drivers/misc/ep93xx_pwm.c linux-2.6.38.1/drivers/misc/ep93xx_pwm.c
25911--- linux-2.6.38.1/drivers/misc/ep93xx_pwm.c 2011-03-14 21:20:32.000000000 -0400
25912+++ linux-2.6.38.1/drivers/misc/ep93xx_pwm.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
25913@@ -249,11 +249,11 @@ static ssize_t ep93xx_pwm_set_invert(str
25914
25915 static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL);
25916 static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL);
25917-static DEVICE_ATTR(freq, S_IWUGO | S_IRUGO,
25918+static DEVICE_ATTR(freq, S_IWUSR | S_IRUGO,
25919 ep93xx_pwm_get_freq, ep93xx_pwm_set_freq);
25920-static DEVICE_ATTR(duty_percent, S_IWUGO | S_IRUGO,
25921+static DEVICE_ATTR(duty_percent, S_IWUSR | S_IRUGO,
25922 ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent);
25923-static DEVICE_ATTR(invert, S_IWUGO | S_IRUGO,
25924+static DEVICE_ATTR(invert, S_IWUSR | S_IRUGO,
25925 ep93xx_pwm_get_invert, ep93xx_pwm_set_invert);
25926
25927 static struct attribute *ep93xx_pwm_attrs[] = {
16454cff
MT
25928diff -urNp linux-2.6.38.1/drivers/misc/kgdbts.c linux-2.6.38.1/drivers/misc/kgdbts.c
25929--- linux-2.6.38.1/drivers/misc/kgdbts.c 2011-03-14 21:20:32.000000000 -0400
25930+++ linux-2.6.38.1/drivers/misc/kgdbts.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
25931@@ -118,7 +118,7 @@
25932 } while (0)
25933 #define MAX_CONFIG_LEN 40
25934
25935-static struct kgdb_io kgdbts_io_ops;
25936+static const struct kgdb_io kgdbts_io_ops;
25937 static char get_buf[BUFMAX];
25938 static int get_buf_cnt;
25939 static char put_buf[BUFMAX];
bc901d79 25940@@ -1103,7 +1103,7 @@ static void kgdbts_post_exp_handler(void
ae4e228f
MT
25941 module_put(THIS_MODULE);
25942 }
25943
25944-static struct kgdb_io kgdbts_io_ops = {
25945+static const struct kgdb_io kgdbts_io_ops = {
25946 .name = "kgdbts",
25947 .read_char = kgdbts_get_char,
25948 .write_char = kgdbts_put_char,
16454cff
MT
25949diff -urNp linux-2.6.38.1/drivers/misc/sgi-gru/gruhandles.c linux-2.6.38.1/drivers/misc/sgi-gru/gruhandles.c
25950--- linux-2.6.38.1/drivers/misc/sgi-gru/gruhandles.c 2011-03-14 21:20:32.000000000 -0400
25951+++ linux-2.6.38.1/drivers/misc/sgi-gru/gruhandles.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
25952@@ -44,8 +44,8 @@ static void update_mcs_stats(enum mcs_op
25953 unsigned long nsec;
25954
25955 nsec = CLKS2NSEC(clks);
25956- atomic_long_inc(&mcs_op_statistics[op].count);
25957- atomic_long_add(nsec, &mcs_op_statistics[op].total);
25958+ atomic_long_inc_unchecked(&mcs_op_statistics[op].count);
25959+ atomic_long_add_unchecked(nsec, &mcs_op_statistics[op].total);
25960 if (mcs_op_statistics[op].max < nsec)
25961 mcs_op_statistics[op].max = nsec;
25962 }
16454cff
MT
25963diff -urNp linux-2.6.38.1/drivers/misc/sgi-gru/gruprocfs.c linux-2.6.38.1/drivers/misc/sgi-gru/gruprocfs.c
25964--- linux-2.6.38.1/drivers/misc/sgi-gru/gruprocfs.c 2011-03-14 21:20:32.000000000 -0400
25965+++ linux-2.6.38.1/drivers/misc/sgi-gru/gruprocfs.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
25966@@ -32,9 +32,9 @@
25967
25968 #define printstat(s, f) printstat_val(s, &gru_stats.f, #f)
25969
25970-static void printstat_val(struct seq_file *s, atomic_long_t *v, char *id)
25971+static void printstat_val(struct seq_file *s, atomic_long_unchecked_t *v, char *id)
25972 {
25973- unsigned long val = atomic_long_read(v);
25974+ unsigned long val = atomic_long_read_unchecked(v);
25975
25976 seq_printf(s, "%16lu %s\n", val, id);
25977 }
25978@@ -134,8 +134,8 @@ static int mcs_statistics_show(struct se
25979
25980 seq_printf(s, "%-20s%12s%12s%12s\n", "#id", "count", "aver-clks", "max-clks");
25981 for (op = 0; op < mcsop_last; op++) {
25982- count = atomic_long_read(&mcs_op_statistics[op].count);
25983- total = atomic_long_read(&mcs_op_statistics[op].total);
25984+ count = atomic_long_read_unchecked(&mcs_op_statistics[op].count);
25985+ total = atomic_long_read_unchecked(&mcs_op_statistics[op].total);
25986 max = mcs_op_statistics[op].max;
25987 seq_printf(s, "%-20s%12ld%12ld%12ld\n", id[op], count,
25988 count ? total / count : 0, max);
16454cff
MT
25989diff -urNp linux-2.6.38.1/drivers/misc/sgi-gru/grutables.h linux-2.6.38.1/drivers/misc/sgi-gru/grutables.h
25990--- linux-2.6.38.1/drivers/misc/sgi-gru/grutables.h 2011-03-14 21:20:32.000000000 -0400
25991+++ linux-2.6.38.1/drivers/misc/sgi-gru/grutables.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
25992@@ -167,82 +167,82 @@ extern unsigned int gru_max_gids;
25993 * GRU statistics.
25994 */
25995 struct gru_stats_s {
25996- atomic_long_t vdata_alloc;
25997- atomic_long_t vdata_free;
25998- atomic_long_t gts_alloc;
25999- atomic_long_t gts_free;
26000- atomic_long_t gms_alloc;
26001- atomic_long_t gms_free;
26002- atomic_long_t gts_double_allocate;
26003- atomic_long_t assign_context;
26004- atomic_long_t assign_context_failed;
26005- atomic_long_t free_context;
26006- atomic_long_t load_user_context;
26007- atomic_long_t load_kernel_context;
26008- atomic_long_t lock_kernel_context;
26009- atomic_long_t unlock_kernel_context;
26010- atomic_long_t steal_user_context;
26011- atomic_long_t steal_kernel_context;
26012- atomic_long_t steal_context_failed;
26013- atomic_long_t nopfn;
26014- atomic_long_t asid_new;
26015- atomic_long_t asid_next;
26016- atomic_long_t asid_wrap;
26017- atomic_long_t asid_reuse;
26018- atomic_long_t intr;
26019- atomic_long_t intr_cbr;
26020- atomic_long_t intr_tfh;
26021- atomic_long_t intr_spurious;
26022- atomic_long_t intr_mm_lock_failed;
26023- atomic_long_t call_os;
26024- atomic_long_t call_os_wait_queue;
26025- atomic_long_t user_flush_tlb;
26026- atomic_long_t user_unload_context;
26027- atomic_long_t user_exception;
26028- atomic_long_t set_context_option;
26029- atomic_long_t check_context_retarget_intr;
26030- atomic_long_t check_context_unload;
26031- atomic_long_t tlb_dropin;
26032- atomic_long_t tlb_preload_page;
26033- atomic_long_t tlb_dropin_fail_no_asid;
26034- atomic_long_t tlb_dropin_fail_upm;
26035- atomic_long_t tlb_dropin_fail_invalid;
26036- atomic_long_t tlb_dropin_fail_range_active;
26037- atomic_long_t tlb_dropin_fail_idle;
26038- atomic_long_t tlb_dropin_fail_fmm;
26039- atomic_long_t tlb_dropin_fail_no_exception;
26040- atomic_long_t tfh_stale_on_fault;
26041- atomic_long_t mmu_invalidate_range;
26042- atomic_long_t mmu_invalidate_page;
26043- atomic_long_t flush_tlb;
26044- atomic_long_t flush_tlb_gru;
26045- atomic_long_t flush_tlb_gru_tgh;
26046- atomic_long_t flush_tlb_gru_zero_asid;
26047-
26048- atomic_long_t copy_gpa;
26049- atomic_long_t read_gpa;
26050-
26051- atomic_long_t mesq_receive;
26052- atomic_long_t mesq_receive_none;
26053- atomic_long_t mesq_send;
26054- atomic_long_t mesq_send_failed;
26055- atomic_long_t mesq_noop;
26056- atomic_long_t mesq_send_unexpected_error;
26057- atomic_long_t mesq_send_lb_overflow;
26058- atomic_long_t mesq_send_qlimit_reached;
26059- atomic_long_t mesq_send_amo_nacked;
26060- atomic_long_t mesq_send_put_nacked;
26061- atomic_long_t mesq_page_overflow;
26062- atomic_long_t mesq_qf_locked;
26063- atomic_long_t mesq_qf_noop_not_full;
26064- atomic_long_t mesq_qf_switch_head_failed;
26065- atomic_long_t mesq_qf_unexpected_error;
26066- atomic_long_t mesq_noop_unexpected_error;
26067- atomic_long_t mesq_noop_lb_overflow;
26068- atomic_long_t mesq_noop_qlimit_reached;
26069- atomic_long_t mesq_noop_amo_nacked;
26070- atomic_long_t mesq_noop_put_nacked;
26071- atomic_long_t mesq_noop_page_overflow;
26072+ atomic_long_unchecked_t vdata_alloc;
26073+ atomic_long_unchecked_t vdata_free;
26074+ atomic_long_unchecked_t gts_alloc;
26075+ atomic_long_unchecked_t gts_free;
26076+ atomic_long_unchecked_t gms_alloc;
26077+ atomic_long_unchecked_t gms_free;
26078+ atomic_long_unchecked_t gts_double_allocate;
26079+ atomic_long_unchecked_t assign_context;
26080+ atomic_long_unchecked_t assign_context_failed;
26081+ atomic_long_unchecked_t free_context;
26082+ atomic_long_unchecked_t load_user_context;
26083+ atomic_long_unchecked_t load_kernel_context;
26084+ atomic_long_unchecked_t lock_kernel_context;
26085+ atomic_long_unchecked_t unlock_kernel_context;
26086+ atomic_long_unchecked_t steal_user_context;
26087+ atomic_long_unchecked_t steal_kernel_context;
26088+ atomic_long_unchecked_t steal_context_failed;
26089+ atomic_long_unchecked_t nopfn;
26090+ atomic_long_unchecked_t asid_new;
26091+ atomic_long_unchecked_t asid_next;
26092+ atomic_long_unchecked_t asid_wrap;
26093+ atomic_long_unchecked_t asid_reuse;
26094+ atomic_long_unchecked_t intr;
26095+ atomic_long_unchecked_t intr_cbr;
26096+ atomic_long_unchecked_t intr_tfh;
26097+ atomic_long_unchecked_t intr_spurious;
26098+ atomic_long_unchecked_t intr_mm_lock_failed;
26099+ atomic_long_unchecked_t call_os;
26100+ atomic_long_unchecked_t call_os_wait_queue;
26101+ atomic_long_unchecked_t user_flush_tlb;
26102+ atomic_long_unchecked_t user_unload_context;
26103+ atomic_long_unchecked_t user_exception;
26104+ atomic_long_unchecked_t set_context_option;
26105+ atomic_long_unchecked_t check_context_retarget_intr;
26106+ atomic_long_unchecked_t check_context_unload;
26107+ atomic_long_unchecked_t tlb_dropin;
26108+ atomic_long_unchecked_t tlb_preload_page;
26109+ atomic_long_unchecked_t tlb_dropin_fail_no_asid;
26110+ atomic_long_unchecked_t tlb_dropin_fail_upm;
26111+ atomic_long_unchecked_t tlb_dropin_fail_invalid;
26112+ atomic_long_unchecked_t tlb_dropin_fail_range_active;
26113+ atomic_long_unchecked_t tlb_dropin_fail_idle;
26114+ atomic_long_unchecked_t tlb_dropin_fail_fmm;
26115+ atomic_long_unchecked_t tlb_dropin_fail_no_exception;
26116+ atomic_long_unchecked_t tfh_stale_on_fault;
26117+ atomic_long_unchecked_t mmu_invalidate_range;
26118+ atomic_long_unchecked_t mmu_invalidate_page;
26119+ atomic_long_unchecked_t flush_tlb;
26120+ atomic_long_unchecked_t flush_tlb_gru;
26121+ atomic_long_unchecked_t flush_tlb_gru_tgh;
26122+ atomic_long_unchecked_t flush_tlb_gru_zero_asid;
26123+
26124+ atomic_long_unchecked_t copy_gpa;
26125+ atomic_long_unchecked_t read_gpa;
26126+
26127+ atomic_long_unchecked_t mesq_receive;
26128+ atomic_long_unchecked_t mesq_receive_none;
26129+ atomic_long_unchecked_t mesq_send;
26130+ atomic_long_unchecked_t mesq_send_failed;
26131+ atomic_long_unchecked_t mesq_noop;
26132+ atomic_long_unchecked_t mesq_send_unexpected_error;
26133+ atomic_long_unchecked_t mesq_send_lb_overflow;
26134+ atomic_long_unchecked_t mesq_send_qlimit_reached;
26135+ atomic_long_unchecked_t mesq_send_amo_nacked;
26136+ atomic_long_unchecked_t mesq_send_put_nacked;
26137+ atomic_long_unchecked_t mesq_page_overflow;
26138+ atomic_long_unchecked_t mesq_qf_locked;
26139+ atomic_long_unchecked_t mesq_qf_noop_not_full;
26140+ atomic_long_unchecked_t mesq_qf_switch_head_failed;
26141+ atomic_long_unchecked_t mesq_qf_unexpected_error;
26142+ atomic_long_unchecked_t mesq_noop_unexpected_error;
26143+ atomic_long_unchecked_t mesq_noop_lb_overflow;
26144+ atomic_long_unchecked_t mesq_noop_qlimit_reached;
26145+ atomic_long_unchecked_t mesq_noop_amo_nacked;
26146+ atomic_long_unchecked_t mesq_noop_put_nacked;
26147+ atomic_long_unchecked_t mesq_noop_page_overflow;
58c5fc13 26148
58c5fc13 26149 };
58c5fc13 26150
ae4e228f
MT
26151@@ -251,8 +251,8 @@ enum mcs_op {cchop_allocate, cchop_start
26152 tghop_invalidate, mcsop_last};
58c5fc13 26153
ae4e228f
MT
26154 struct mcs_op_statistic {
26155- atomic_long_t count;
26156- atomic_long_t total;
26157+ atomic_long_unchecked_t count;
26158+ atomic_long_unchecked_t total;
26159 unsigned long max;
58c5fc13
MT
26160 };
26161
ae4e228f 26162@@ -275,7 +275,7 @@ extern struct mcs_op_statistic mcs_op_st
58c5fc13 26163
ae4e228f
MT
26164 #define STAT(id) do { \
26165 if (gru_options & OPT_STATS) \
26166- atomic_long_inc(&gru_stats.id); \
26167+ atomic_long_inc_unchecked(&gru_stats.id); \
26168 } while (0)
58c5fc13 26169
ae4e228f 26170 #ifdef CONFIG_SGI_GRU_DEBUG
16454cff
MT
26171diff -urNp linux-2.6.38.1/drivers/mtd/devices/doc2000.c linux-2.6.38.1/drivers/mtd/devices/doc2000.c
26172--- linux-2.6.38.1/drivers/mtd/devices/doc2000.c 2011-03-14 21:20:32.000000000 -0400
26173+++ linux-2.6.38.1/drivers/mtd/devices/doc2000.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
26174@@ -776,7 +776,7 @@ static int doc_write(struct mtd_info *mt
26175
26176 /* The ECC will not be calculated correctly if less than 512 is written */
26177 /* DBB-
26178- if (len != 0x200 && eccbuf)
26179+ if (len != 0x200)
26180 printk(KERN_WARNING
26181 "ECC needs a full sector write (adr: %lx size %lx)\n",
26182 (long) to, (long) len);
16454cff
MT
26183diff -urNp linux-2.6.38.1/drivers/mtd/devices/doc2001.c linux-2.6.38.1/drivers/mtd/devices/doc2001.c
26184--- linux-2.6.38.1/drivers/mtd/devices/doc2001.c 2011-03-14 21:20:32.000000000 -0400
26185+++ linux-2.6.38.1/drivers/mtd/devices/doc2001.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
26186@@ -393,7 +393,7 @@ static int doc_read (struct mtd_info *mt
26187 struct Nand *mychip = &this->chips[from >> (this->chipshift)];
26188
58c5fc13 26189 /* Don't allow read past end of device */
ae4e228f
MT
26190- if (from >= this->totlen)
26191+ if (from >= this->totlen || !len)
58c5fc13 26192 return -EINVAL;
58c5fc13
MT
26193
26194 /* Don't allow a single read to cross a 512-byte block boundary */
16454cff
MT
26195diff -urNp linux-2.6.38.1/drivers/mtd/nand/denali.c linux-2.6.38.1/drivers/mtd/nand/denali.c
26196--- linux-2.6.38.1/drivers/mtd/nand/denali.c 2011-03-14 21:20:32.000000000 -0400
26197+++ linux-2.6.38.1/drivers/mtd/nand/denali.c 2011-03-21 18:31:35.000000000 -0400
6892158b 26198@@ -25,6 +25,7 @@
57199397
MT
26199 #include <linux/pci.h>
26200 #include <linux/mtd/mtd.h>
26201 #include <linux/module.h>
26202+#include <linux/slab.h>
26203
26204 #include "denali.h"
26205
16454cff
MT
26206diff -urNp linux-2.6.38.1/drivers/mtd/ubi/build.c linux-2.6.38.1/drivers/mtd/ubi/build.c
26207--- linux-2.6.38.1/drivers/mtd/ubi/build.c 2011-03-14 21:20:32.000000000 -0400
26208+++ linux-2.6.38.1/drivers/mtd/ubi/build.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 26209@@ -1285,7 +1285,7 @@ module_exit(ubi_exit);
ae4e228f
MT
26210 static int __init bytes_str_to_int(const char *str)
26211 {
26212 char *endp;
26213- unsigned long result;
26214+ unsigned long result, scale = 1;
58c5fc13
MT
26215
26216 result = simple_strtoul(str, &endp, 0);
ae4e228f 26217 if (str == endp || result >= INT_MAX) {
bc901d79 26218@@ -1296,11 +1296,11 @@ static int __init bytes_str_to_int(const
ae4e228f
MT
26219
26220 switch (*endp) {
26221 case 'G':
26222- result *= 1024;
26223+ scale *= 1024;
26224 case 'M':
26225- result *= 1024;
26226+ scale *= 1024;
26227 case 'K':
26228- result *= 1024;
26229+ scale *= 1024;
26230 if (endp[1] == 'i' && endp[2] == 'B')
26231 endp += 2;
26232 case '\0':
bc901d79 26233@@ -1311,7 +1311,13 @@ static int __init bytes_str_to_int(const
58c5fc13 26234 return -EINVAL;
ae4e228f
MT
26235 }
26236
26237- return result;
26238+ if ((intoverflow_t)result*scale >= INT_MAX) {
26239+ printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
26240+ str);
26241+ return -EINVAL;
26242+ }
26243+
26244+ return result*scale;
26245 }
26246
26247 /**
16454cff
MT
26248diff -urNp linux-2.6.38.1/drivers/net/e1000e/82571.c linux-2.6.38.1/drivers/net/e1000e/82571.c
26249--- linux-2.6.38.1/drivers/net/e1000e/82571.c 2011-03-14 21:20:32.000000000 -0400
26250+++ linux-2.6.38.1/drivers/net/e1000e/82571.c 2011-03-21 18:31:35.000000000 -0400
26251@@ -239,7 +239,7 @@ static s32 e1000_init_mac_params_82571(s
ae4e228f
MT
26252 {
26253 struct e1000_hw *hw = &adapter->hw;
26254 struct e1000_mac_info *mac = &hw->mac;
16454cff
MT
26255- struct e1000_mac_operations *func = &mac->ops;
26256+ struct e1000_mac_operations *func = &mac->ops; /* cannot be const */
ae4e228f
MT
26257 u32 swsm = 0;
26258 u32 swsm2 = 0;
16454cff
MT
26259 bool force_clear_smbi = false;
26260@@ -1930,7 +1930,7 @@ static void e1000_clear_hw_cntrs_82571(s
ae4e228f
MT
26261 er32(ICRXDMTC);
26262 }
26263
26264-static struct e1000_mac_operations e82571_mac_ops = {
26265+static const struct e1000_mac_operations e82571_mac_ops = {
26266 /* .check_mng_mode: mac type dependent */
26267 /* .check_for_link: media type dependent */
26268 .id_led_init = e1000e_id_led_init,
16454cff 26269@@ -1952,7 +1952,7 @@ static struct e1000_mac_operations e8257
df50ba0c 26270 .read_mac_addr = e1000_read_mac_addr_82571,
ae4e228f
MT
26271 };
26272
26273-static struct e1000_phy_operations e82_phy_ops_igp = {
26274+static const struct e1000_phy_operations e82_phy_ops_igp = {
26275 .acquire = e1000_get_hw_semaphore_82571,
26276 .check_polarity = e1000_check_polarity_igp,
26277 .check_reset_block = e1000e_check_reset_block_generic,
16454cff 26278@@ -1970,7 +1970,7 @@ static struct e1000_phy_operations e82_p
ae4e228f
MT
26279 .cfg_on_link_up = NULL,
26280 };
26281
26282-static struct e1000_phy_operations e82_phy_ops_m88 = {
26283+static const struct e1000_phy_operations e82_phy_ops_m88 = {
26284 .acquire = e1000_get_hw_semaphore_82571,
26285 .check_polarity = e1000_check_polarity_m88,
26286 .check_reset_block = e1000e_check_reset_block_generic,
16454cff 26287@@ -1988,7 +1988,7 @@ static struct e1000_phy_operations e82_p
ae4e228f
MT
26288 .cfg_on_link_up = NULL,
26289 };
26290
26291-static struct e1000_phy_operations e82_phy_ops_bm = {
26292+static const struct e1000_phy_operations e82_phy_ops_bm = {
26293 .acquire = e1000_get_hw_semaphore_82571,
26294 .check_polarity = e1000_check_polarity_m88,
26295 .check_reset_block = e1000e_check_reset_block_generic,
16454cff 26296@@ -2006,7 +2006,7 @@ static struct e1000_phy_operations e82_p
ae4e228f
MT
26297 .cfg_on_link_up = NULL,
26298 };
26299
26300-static struct e1000_nvm_operations e82571_nvm_ops = {
26301+static const struct e1000_nvm_operations e82571_nvm_ops = {
26302 .acquire = e1000_acquire_nvm_82571,
26303 .read = e1000e_read_nvm_eerd,
26304 .release = e1000_release_nvm_82571,
16454cff
MT
26305diff -urNp linux-2.6.38.1/drivers/net/e1000e/e1000.h linux-2.6.38.1/drivers/net/e1000e/e1000.h
26306--- linux-2.6.38.1/drivers/net/e1000e/e1000.h 2011-03-14 21:20:32.000000000 -0400
26307+++ linux-2.6.38.1/drivers/net/e1000e/e1000.h 2011-03-21 18:31:35.000000000 -0400
26308@@ -408,9 +408,9 @@ struct e1000_info {
ae4e228f
MT
26309 u32 pba;
26310 u32 max_hw_frame_size;
26311 s32 (*get_variants)(struct e1000_adapter *);
26312- struct e1000_mac_operations *mac_ops;
26313- struct e1000_phy_operations *phy_ops;
26314- struct e1000_nvm_operations *nvm_ops;
26315+ const struct e1000_mac_operations *mac_ops;
26316+ const struct e1000_phy_operations *phy_ops;
26317+ const struct e1000_nvm_operations *nvm_ops;
26318 };
26319
26320 /* hardware capability, feature, and workaround flags */
16454cff
MT
26321diff -urNp linux-2.6.38.1/drivers/net/e1000e/es2lan.c linux-2.6.38.1/drivers/net/e1000e/es2lan.c
26322--- linux-2.6.38.1/drivers/net/e1000e/es2lan.c 2011-03-14 21:20:32.000000000 -0400
26323+++ linux-2.6.38.1/drivers/net/e1000e/es2lan.c 2011-03-21 18:31:35.000000000 -0400
26324@@ -205,7 +205,7 @@ static s32 e1000_init_mac_params_80003es
ae4e228f
MT
26325 {
26326 struct e1000_hw *hw = &adapter->hw;
26327 struct e1000_mac_info *mac = &hw->mac;
16454cff
MT
26328- struct e1000_mac_operations *func = &mac->ops;
26329+ struct e1000_mac_operations *func = &mac->ops; /* cannot be const */
ae4e228f
MT
26330
26331 /* Set media type */
16454cff
MT
26332 switch (adapter->pdev->device) {
26333@@ -1431,7 +1431,7 @@ static void e1000_clear_hw_cntrs_80003es
ae4e228f
MT
26334 er32(ICRXDMTC);
26335 }
26336
26337-static struct e1000_mac_operations es2_mac_ops = {
26338+static const struct e1000_mac_operations es2_mac_ops = {
df50ba0c 26339 .read_mac_addr = e1000_read_mac_addr_80003es2lan,
ae4e228f
MT
26340 .id_led_init = e1000e_id_led_init,
26341 .check_mng_mode = e1000e_check_mng_mode_generic,
16454cff 26342@@ -1453,7 +1453,7 @@ static struct e1000_mac_operations es2_m
ae4e228f
MT
26343 .setup_led = e1000e_setup_led_generic,
26344 };
26345
26346-static struct e1000_phy_operations es2_phy_ops = {
26347+static const struct e1000_phy_operations es2_phy_ops = {
26348 .acquire = e1000_acquire_phy_80003es2lan,
26349 .check_polarity = e1000_check_polarity_m88,
26350 .check_reset_block = e1000e_check_reset_block_generic,
16454cff 26351@@ -1471,7 +1471,7 @@ static struct e1000_phy_operations es2_p
ae4e228f
MT
26352 .cfg_on_link_up = e1000_cfg_on_link_up_80003es2lan,
26353 };
26354
26355-static struct e1000_nvm_operations es2_nvm_ops = {
26356+static const struct e1000_nvm_operations es2_nvm_ops = {
26357 .acquire = e1000_acquire_nvm_80003es2lan,
26358 .read = e1000e_read_nvm_eerd,
26359 .release = e1000_release_nvm_80003es2lan,
16454cff
MT
26360diff -urNp linux-2.6.38.1/drivers/net/e1000e/hw.h linux-2.6.38.1/drivers/net/e1000e/hw.h
26361--- linux-2.6.38.1/drivers/net/e1000e/hw.h 2011-03-14 21:20:32.000000000 -0400
26362+++ linux-2.6.38.1/drivers/net/e1000e/hw.h 2011-03-21 18:31:35.000000000 -0400
26363@@ -801,16 +801,17 @@ struct e1000_phy_operations {
ae4e228f
MT
26364
26365 /* Function pointers for the NVM. */
26366 struct e1000_nvm_operations {
26367- s32 (*acquire)(struct e1000_hw *);
26368- s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
26369- void (*release)(struct e1000_hw *);
26370- s32 (*update)(struct e1000_hw *);
26371- s32 (*valid_led_default)(struct e1000_hw *, u16 *);
26372- s32 (*validate)(struct e1000_hw *);
26373- s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
16454cff 26374+ s32 (* acquire)(struct e1000_hw *); /* cannot be const, see drivers/net/e1000e/82571.c e1000_init_nvm_params_82571() */
ae4e228f 26375+ s32 (* const read)(struct e1000_hw *, u16, u16, u16 *);
16454cff 26376+ void (* release)(struct e1000_hw *); /* cannot be const, see drivers/net/e1000e/82571.c e1000_init_nvm_params_82571() */
ae4e228f
MT
26377+ s32 (* const update)(struct e1000_hw *);
26378+ s32 (* const valid_led_default)(struct e1000_hw *, u16 *);
26379+ s32 (* const validate)(struct e1000_hw *);
26380+ s32 (* const write)(struct e1000_hw *, u16, u16, u16 *);
26381 };
26382
26383 struct e1000_mac_info {
bc901d79
MT
26384+ /* cannot be const see e1000_init_mac_params_ich8lan */
26385 struct e1000_mac_operations ops;
26386
26387 u8 addr[6];
16454cff 26388@@ -853,6 +854,7 @@ struct e1000_mac_info {
bc901d79
MT
26389 };
26390
26391 struct e1000_phy_info {
26392+ /* Cannot be const see e1000_init_phy_params_82571() */
26393 struct e1000_phy_operations ops;
26394
26395 enum e1000_phy_type type;
16454cff 26396@@ -887,6 +889,7 @@ struct e1000_phy_info {
ae4e228f
MT
26397 };
26398
26399 struct e1000_nvm_info {
26400+ /* cannot be const */
26401 struct e1000_nvm_operations ops;
26402
26403 enum e1000_nvm_type type;
16454cff
MT
26404diff -urNp linux-2.6.38.1/drivers/net/e1000e/ich8lan.c linux-2.6.38.1/drivers/net/e1000e/ich8lan.c
26405--- linux-2.6.38.1/drivers/net/e1000e/ich8lan.c 2011-03-14 21:20:32.000000000 -0400
26406+++ linux-2.6.38.1/drivers/net/e1000e/ich8lan.c 2011-03-21 18:31:35.000000000 -0400
26407@@ -3840,7 +3840,7 @@ static void e1000_clear_hw_cntrs_ich8lan
ae4e228f
MT
26408 }
26409 }
26410
26411-static struct e1000_mac_operations ich8_mac_ops = {
26412+static const struct e1000_mac_operations ich8_mac_ops = {
26413 .id_led_init = e1000e_id_led_init,
6892158b 26414 /* check_mng_mode dependent on mac type */
ae4e228f 26415 .check_for_link = e1000_check_for_copper_link_ich8lan,
16454cff 26416@@ -3859,7 +3859,7 @@ static struct e1000_mac_operations ich8_
ae4e228f
MT
26417 /* id_led_init dependent on mac type */
26418 };
26419
26420-static struct e1000_phy_operations ich8_phy_ops = {
26421+static const struct e1000_phy_operations ich8_phy_ops = {
26422 .acquire = e1000_acquire_swflag_ich8lan,
26423 .check_reset_block = e1000_check_reset_block_ich8lan,
26424 .commit = NULL,
16454cff 26425@@ -3873,7 +3873,7 @@ static struct e1000_phy_operations ich8_
ae4e228f
MT
26426 .write_reg = e1000e_write_phy_reg_igp,
26427 };
26428
26429-static struct e1000_nvm_operations ich8_nvm_ops = {
26430+static const struct e1000_nvm_operations ich8_nvm_ops = {
26431 .acquire = e1000_acquire_nvm_ich8lan,
26432 .read = e1000_read_nvm_ich8lan,
26433 .release = e1000_release_nvm_ich8lan,
16454cff
MT
26434diff -urNp linux-2.6.38.1/drivers/net/igb/e1000_82575.c linux-2.6.38.1/drivers/net/igb/e1000_82575.c
26435--- linux-2.6.38.1/drivers/net/igb/e1000_82575.c 2011-03-14 21:20:32.000000000 -0400
26436+++ linux-2.6.38.1/drivers/net/igb/e1000_82575.c 2011-03-21 18:31:35.000000000 -0400
26437@@ -1747,7 +1747,7 @@ u16 igb_rxpbs_adjust_82580(u32 data)
ae4e228f
MT
26438 return ret_val;
26439 }
26440
26441-static struct e1000_mac_operations e1000_mac_ops_82575 = {
26442+static const struct e1000_mac_operations e1000_mac_ops_82575 = {
26443 .init_hw = igb_init_hw_82575,
26444 .check_for_link = igb_check_for_link_82575,
26445 .rar_set = igb_rar_set,
16454cff 26446@@ -1755,13 +1755,13 @@ static struct e1000_mac_operations e1000
ae4e228f
MT
26447 .get_speed_and_duplex = igb_get_speed_and_duplex_copper,
26448 };
26449
26450-static struct e1000_phy_operations e1000_phy_ops_82575 = {
26451+static const struct e1000_phy_operations e1000_phy_ops_82575 = {
26452 .acquire = igb_acquire_phy_82575,
26453 .get_cfg_done = igb_get_cfg_done_82575,
26454 .release = igb_release_phy_82575,
26455 };
26456
26457-static struct e1000_nvm_operations e1000_nvm_ops_82575 = {
26458+static const struct e1000_nvm_operations e1000_nvm_ops_82575 = {
26459 .acquire = igb_acquire_nvm_82575,
26460 .read = igb_read_nvm_eerd,
26461 .release = igb_release_nvm_82575,
16454cff
MT
26462diff -urNp linux-2.6.38.1/drivers/net/igb/e1000_hw.h linux-2.6.38.1/drivers/net/igb/e1000_hw.h
26463--- linux-2.6.38.1/drivers/net/igb/e1000_hw.h 2011-03-14 21:20:32.000000000 -0400
26464+++ linux-2.6.38.1/drivers/net/igb/e1000_hw.h 2011-03-21 18:31:35.000000000 -0400
26465@@ -327,22 +327,23 @@ struct e1000_phy_operations {
ae4e228f
MT
26466 };
26467
26468 struct e1000_nvm_operations {
26469- s32 (*acquire)(struct e1000_hw *);
26470- s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
26471- void (*release)(struct e1000_hw *);
26472- s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
26473+ s32 (* const acquire)(struct e1000_hw *);
26474+ s32 (* const read)(struct e1000_hw *, u16, u16, u16 *);
26475+ void (* const release)(struct e1000_hw *);
26476+ s32 (* const write)(struct e1000_hw *, u16, u16, u16 *);
26477 };
26478
26479 struct e1000_info {
26480 s32 (*get_invariants)(struct e1000_hw *);
26481- struct e1000_mac_operations *mac_ops;
26482- struct e1000_phy_operations *phy_ops;
26483- struct e1000_nvm_operations *nvm_ops;
26484+ const struct e1000_mac_operations *mac_ops;
26485+ const struct e1000_phy_operations *phy_ops;
26486+ const struct e1000_nvm_operations *nvm_ops;
26487 };
26488
26489 extern const struct e1000_info e1000_82575_info;
bc901d79
MT
26490
26491 struct e1000_mac_info {
26492+ /* cannot be const see igb_get_invariants_82575() */
26493 struct e1000_mac_operations ops;
26494
26495 u8 addr[6];
16454cff 26496@@ -381,6 +382,7 @@ struct e1000_mac_info {
bc901d79
MT
26497 };
26498
26499 struct e1000_phy_info {
26500+ /* cannot be const see igb_get_invariants_82575() */
26501 struct e1000_phy_operations ops;
26502
26503 enum e1000_phy_type type;
16454cff 26504@@ -416,6 +418,7 @@ struct e1000_phy_info {
ae4e228f
MT
26505 };
26506
26507 struct e1000_nvm_info {
26508+ /* cannot be const */
26509 struct e1000_nvm_operations ops;
26510
26511 enum e1000_nvm_type type;
16454cff
MT
26512diff -urNp linux-2.6.38.1/drivers/net/igbvf/vf.h linux-2.6.38.1/drivers/net/igbvf/vf.h
26513--- linux-2.6.38.1/drivers/net/igbvf/vf.h 2011-03-14 21:20:32.000000000 -0400
26514+++ linux-2.6.38.1/drivers/net/igbvf/vf.h 2011-03-21 18:31:35.000000000 -0400
26515@@ -191,6 +191,7 @@ struct e1000_mac_operations {
bc901d79
MT
26516 };
26517
26518 struct e1000_mac_info {
26519+ /* cannot be const see e1000_init_mac_params_vf() */
26520 struct e1000_mac_operations ops;
26521 u8 addr[6];
26522 u8 perm_addr[6];
16454cff
MT
26523diff -urNp linux-2.6.38.1/drivers/net/irda/vlsi_ir.c linux-2.6.38.1/drivers/net/irda/vlsi_ir.c
26524--- linux-2.6.38.1/drivers/net/irda/vlsi_ir.c 2011-03-14 21:20:32.000000000 -0400
26525+++ linux-2.6.38.1/drivers/net/irda/vlsi_ir.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 26526@@ -907,13 +907,12 @@ static netdev_tx_t vlsi_hard_start_xmit(
58c5fc13
MT
26527 /* no race - tx-ring already empty */
26528 vlsi_set_baud(idev, iobase);
26529 netif_wake_queue(ndev);
26530- }
26531- else
26532- ;
26533+ } else {
26534 /* keep the speed change pending like it would
26535 * for any len>0 packet. tx completion interrupt
26536 * will apply it when the tx ring becomes empty.
26537 */
26538+ }
26539 spin_unlock_irqrestore(&idev->lock, flags);
26540 dev_kfree_skb_any(skb);
ae4e228f 26541 return NETDEV_TX_OK;
16454cff
MT
26542diff -urNp linux-2.6.38.1/drivers/net/pcnet32.c linux-2.6.38.1/drivers/net/pcnet32.c
26543--- linux-2.6.38.1/drivers/net/pcnet32.c 2011-03-14 21:20:32.000000000 -0400
26544+++ linux-2.6.38.1/drivers/net/pcnet32.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 26545@@ -82,7 +82,7 @@ static int cards_found;
58c5fc13
MT
26546 /*
26547 * VLB I/O addresses
26548 */
26549-static unsigned int pcnet32_portlist[] __initdata =
26550+static unsigned int pcnet32_portlist[] __devinitdata =
26551 { 0x300, 0x320, 0x340, 0x360, 0 };
26552
df50ba0c 26553 static int pcnet32_debug;
16454cff
MT
26554diff -urNp linux-2.6.38.1/drivers/net/ppp_generic.c linux-2.6.38.1/drivers/net/ppp_generic.c
26555--- linux-2.6.38.1/drivers/net/ppp_generic.c 2011-03-14 21:20:32.000000000 -0400
26556+++ linux-2.6.38.1/drivers/net/ppp_generic.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 26557@@ -986,7 +986,6 @@ ppp_net_ioctl(struct net_device *dev, st
ae4e228f
MT
26558 void __user *addr = (void __user *) ifr->ifr_ifru.ifru_data;
26559 struct ppp_stats stats;
26560 struct ppp_comp_stats cstats;
26561- char *vers;
26562
26563 switch (cmd) {
26564 case SIOCGPPPSTATS:
bc901d79 26565@@ -1008,8 +1007,7 @@ ppp_net_ioctl(struct net_device *dev, st
ae4e228f
MT
26566 break;
26567
26568 case SIOCGPPPVER:
26569- vers = PPP_VERSION;
26570- if (copy_to_user(addr, vers, strlen(vers) + 1))
26571+ if (copy_to_user(addr, PPP_VERSION, sizeof(PPP_VERSION)))
26572 break;
26573 err = 0;
26574 break;
16454cff
MT
26575diff -urNp linux-2.6.38.1/drivers/net/tg3.h linux-2.6.38.1/drivers/net/tg3.h
26576--- linux-2.6.38.1/drivers/net/tg3.h 2011-03-14 21:20:32.000000000 -0400
26577+++ linux-2.6.38.1/drivers/net/tg3.h 2011-03-21 18:31:35.000000000 -0400
6892158b 26578@@ -131,6 +131,7 @@
58c5fc13
MT
26579 #define CHIPREV_ID_5750_A0 0x4000
26580 #define CHIPREV_ID_5750_A1 0x4001
26581 #define CHIPREV_ID_5750_A3 0x4003
26582+#define CHIPREV_ID_5750_C1 0x4201
26583 #define CHIPREV_ID_5750_C2 0x4202
26584 #define CHIPREV_ID_5752_A0_HW 0x5000
26585 #define CHIPREV_ID_5752_A0 0x6000
16454cff
MT
26586diff -urNp linux-2.6.38.1/drivers/net/tulip/de4x5.c linux-2.6.38.1/drivers/net/tulip/de4x5.c
26587--- linux-2.6.38.1/drivers/net/tulip/de4x5.c 2011-03-14 21:20:32.000000000 -0400
26588+++ linux-2.6.38.1/drivers/net/tulip/de4x5.c 2011-03-21 18:31:35.000000000 -0400
57199397 26589@@ -5401,7 +5401,7 @@ de4x5_ioctl(struct net_device *dev, stru
ae4e228f
MT
26590 for (i=0; i<ETH_ALEN; i++) {
26591 tmp.addr[i] = dev->dev_addr[i];
26592 }
26593- if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
bc901d79 26594+ if (ioc->len > sizeof tmp.addr || copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
ae4e228f
MT
26595 break;
26596
26597 case DE4X5_SET_HWADDR: /* Set the hardware address */
57199397 26598@@ -5441,7 +5441,7 @@ de4x5_ioctl(struct net_device *dev, stru
ae4e228f
MT
26599 spin_lock_irqsave(&lp->lock, flags);
26600 memcpy(&statbuf, &lp->pktStats, ioc->len);
26601 spin_unlock_irqrestore(&lp->lock, flags);
26602- if (copy_to_user(ioc->data, &statbuf, ioc->len))
bc901d79 26603+ if (ioc->len > sizeof statbuf || copy_to_user(ioc->data, &statbuf, ioc->len))
ae4e228f
MT
26604 return -EFAULT;
26605 break;
26606 }
16454cff
MT
26607diff -urNp linux-2.6.38.1/drivers/net/usb/hso.c linux-2.6.38.1/drivers/net/usb/hso.c
26608--- linux-2.6.38.1/drivers/net/usb/hso.c 2011-03-14 21:20:32.000000000 -0400
26609+++ linux-2.6.38.1/drivers/net/usb/hso.c 2011-03-21 18:31:35.000000000 -0400
c52201e0
MT
26610@@ -71,7 +71,7 @@
26611 #include <asm/byteorder.h>
26612 #include <linux/serial_core.h>
26613 #include <linux/serial.h>
26614-
26615+#include <asm/local.h>
26616
26617 #define MOD_AUTHOR "Option Wireless"
26618 #define MOD_DESCRIPTION "USB High Speed Option driver"
6892158b 26619@@ -257,7 +257,7 @@ struct hso_serial {
58c5fc13
MT
26620
26621 /* from usb_serial_port */
26622 struct tty_struct *tty;
26623- int open_count;
c52201e0 26624+ local_t open_count;
58c5fc13
MT
26625 spinlock_t serial_lock;
26626
26627 int (*write_data) (struct hso_serial *serial);
16454cff 26628@@ -1190,7 +1190,7 @@ static void put_rxbuf_data_and_resubmit_
58c5fc13
MT
26629 struct urb *urb;
26630
26631 urb = serial->rx_urb[0];
26632- if (serial->open_count > 0) {
c52201e0 26633+ if (local_read(&serial->open_count) > 0) {
58c5fc13
MT
26634 count = put_rxbuf_data(urb, serial);
26635 if (count == -1)
26636 return;
16454cff 26637@@ -1226,7 +1226,7 @@ static void hso_std_serial_read_bulk_cal
58c5fc13
MT
26638 DUMP1(urb->transfer_buffer, urb->actual_length);
26639
26640 /* Anyone listening? */
26641- if (serial->open_count == 0)
c52201e0 26642+ if (local_read(&serial->open_count) == 0)
58c5fc13
MT
26643 return;
26644
26645 if (status == 0) {
16454cff 26646@@ -1311,8 +1311,7 @@ static int hso_serial_open(struct tty_st
58c5fc13
MT
26647 spin_unlock_irq(&serial->serial_lock);
26648
26649 /* check for port already opened, if not set the termios */
26650- serial->open_count++;
26651- if (serial->open_count == 1) {
c52201e0 26652+ if (local_inc_return(&serial->open_count) == 1) {
58c5fc13
MT
26653 serial->rx_state = RX_IDLE;
26654 /* Force default termio settings */
57199397 26655 _hso_serial_set_termios(tty, NULL);
16454cff 26656@@ -1324,7 +1323,7 @@ static int hso_serial_open(struct tty_st
58c5fc13
MT
26657 result = hso_start_serial_device(serial->parent, GFP_KERNEL);
26658 if (result) {
26659 hso_stop_serial_device(serial->parent);
26660- serial->open_count--;
c52201e0 26661+ local_dec(&serial->open_count);
58c5fc13
MT
26662 kref_put(&serial->parent->ref, hso_serial_ref_free);
26663 }
26664 } else {
16454cff 26665@@ -1361,10 +1360,10 @@ static void hso_serial_close(struct tty_
58c5fc13
MT
26666
26667 /* reset the rts and dtr */
26668 /* do the actual close */
26669- serial->open_count--;
c52201e0 26670+ local_dec(&serial->open_count);
ae4e228f 26671
58c5fc13
MT
26672- if (serial->open_count <= 0) {
26673- serial->open_count = 0;
c52201e0
MT
26674+ if (local_read(&serial->open_count) <= 0) {
26675+ local_set(&serial->open_count, 0);
58c5fc13
MT
26676 spin_lock_irq(&serial->serial_lock);
26677 if (serial->tty == tty) {
26678 serial->tty->driver_data = NULL;
16454cff 26679@@ -1446,7 +1445,7 @@ static void hso_serial_set_termios(struc
58c5fc13
MT
26680
26681 /* the actual setup */
26682 spin_lock_irqsave(&serial->serial_lock, flags);
26683- if (serial->open_count)
c52201e0 26684+ if (local_read(&serial->open_count))
58c5fc13
MT
26685 _hso_serial_set_termios(tty, old);
26686 else
26687 tty->termios = old;
16454cff 26688@@ -1905,7 +1904,7 @@ static void intr_callback(struct urb *ur
ae4e228f
MT
26689 D1("Pending read interrupt on port %d\n", i);
26690 spin_lock(&serial->serial_lock);
26691 if (serial->rx_state == RX_IDLE &&
26692- serial->open_count > 0) {
c52201e0 26693+ local_read(&serial->open_count) > 0) {
ae4e228f
MT
26694 /* Setup and send a ctrl req read on
26695 * port i */
26696 if (!serial->rx_urb_filled[0]) {
16454cff 26697@@ -3097,7 +3096,7 @@ static int hso_resume(struct usb_interfa
58c5fc13
MT
26698 /* Start all serial ports */
26699 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
26700 if (serial_table[i] && (serial_table[i]->interface == iface)) {
26701- if (dev2ser(serial_table[i])->open_count) {
c52201e0 26702+ if (local_read(&dev2ser(serial_table[i])->open_count)) {
58c5fc13
MT
26703 result =
26704 hso_start_serial_device(serial_table[i], GFP_NOIO);
26705 hso_kick_transmit(dev2ser(serial_table[i]));
16454cff
MT
26706diff -urNp linux-2.6.38.1/drivers/net/wireless/b43/debugfs.c linux-2.6.38.1/drivers/net/wireless/b43/debugfs.c
26707--- linux-2.6.38.1/drivers/net/wireless/b43/debugfs.c 2011-03-14 21:20:32.000000000 -0400
26708+++ linux-2.6.38.1/drivers/net/wireless/b43/debugfs.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
26709@@ -43,7 +43,7 @@ static struct dentry *rootdir;
26710 struct b43_debugfs_fops {
26711 ssize_t (*read)(struct b43_wldev *dev, char *buf, size_t bufsize);
26712 int (*write)(struct b43_wldev *dev, const char *buf, size_t count);
26713- struct file_operations fops;
26714+ const struct file_operations fops;
26715 /* Offset of struct b43_dfs_file in struct b43_dfsentry */
26716 size_t file_struct_offset;
26717 };
16454cff
MT
26718diff -urNp linux-2.6.38.1/drivers/net/wireless/b43legacy/debugfs.c linux-2.6.38.1/drivers/net/wireless/b43legacy/debugfs.c
26719--- linux-2.6.38.1/drivers/net/wireless/b43legacy/debugfs.c 2011-03-14 21:20:32.000000000 -0400
26720+++ linux-2.6.38.1/drivers/net/wireless/b43legacy/debugfs.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
26721@@ -44,7 +44,7 @@ static struct dentry *rootdir;
26722 struct b43legacy_debugfs_fops {
26723 ssize_t (*read)(struct b43legacy_wldev *dev, char *buf, size_t bufsize);
26724 int (*write)(struct b43legacy_wldev *dev, const char *buf, size_t count);
26725- struct file_operations fops;
26726+ const struct file_operations fops;
26727 /* Offset of struct b43legacy_dfs_file in struct b43legacy_dfsentry */
26728 size_t file_struct_offset;
26729 /* Take wl->irq_lock before calling read/write? */
16454cff
MT
26730diff -urNp linux-2.6.38.1/drivers/net/wireless/iwlwifi/iwl-debug.h linux-2.6.38.1/drivers/net/wireless/iwlwifi/iwl-debug.h
26731--- linux-2.6.38.1/drivers/net/wireless/iwlwifi/iwl-debug.h 2011-03-14 21:20:32.000000000 -0400
26732+++ linux-2.6.38.1/drivers/net/wireless/iwlwifi/iwl-debug.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
26733@@ -68,8 +68,8 @@ do {
26734 } while (0)
ae4e228f 26735
df50ba0c
MT
26736 #else
26737-#define IWL_DEBUG(__priv, level, fmt, args...)
26738-#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
26739+#define IWL_DEBUG(__priv, level, fmt, args...) do {} while (0)
26740+#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) do {} while (0)
26741 static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
6892158b 26742 const void *p, u32 len)
df50ba0c 26743 {}
16454cff
MT
26744diff -urNp linux-2.6.38.1/drivers/net/wireless/libertas/debugfs.c linux-2.6.38.1/drivers/net/wireless/libertas/debugfs.c
26745--- linux-2.6.38.1/drivers/net/wireless/libertas/debugfs.c 2011-03-14 21:20:32.000000000 -0400
26746+++ linux-2.6.38.1/drivers/net/wireless/libertas/debugfs.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 26747@@ -702,7 +702,7 @@ out_unlock:
ae4e228f
MT
26748 struct lbs_debugfs_files {
26749 const char *name;
26750 int perm;
26751- struct file_operations fops;
26752+ const struct file_operations fops;
26753 };
26754
26755 static const struct lbs_debugfs_files debugfs_files[] = {
16454cff
MT
26756diff -urNp linux-2.6.38.1/drivers/net/wireless/rndis_wlan.c linux-2.6.38.1/drivers/net/wireless/rndis_wlan.c
26757--- linux-2.6.38.1/drivers/net/wireless/rndis_wlan.c 2011-03-14 21:20:32.000000000 -0400
26758+++ linux-2.6.38.1/drivers/net/wireless/rndis_wlan.c 2011-03-21 18:31:35.000000000 -0400
26759@@ -1277,7 +1277,7 @@ static int set_rts_threshold(struct usbn
df50ba0c
MT
26760
26761 netdev_dbg(usbdev->net, "%s(): %i\n", __func__, rts_threshold);
26762
26763- if (rts_threshold < 0 || rts_threshold > 2347)
26764+ if (rts_threshold > 2347)
26765 rts_threshold = 2347;
26766
26767 tmp = cpu_to_le32(rts_threshold);
16454cff
MT
26768diff -urNp linux-2.6.38.1/drivers/oprofile/buffer_sync.c linux-2.6.38.1/drivers/oprofile/buffer_sync.c
26769--- linux-2.6.38.1/drivers/oprofile/buffer_sync.c 2011-03-14 21:20:32.000000000 -0400
26770+++ linux-2.6.38.1/drivers/oprofile/buffer_sync.c 2011-03-21 18:31:35.000000000 -0400
6892158b 26771@@ -342,7 +342,7 @@ static void add_data(struct op_entry *en
58c5fc13
MT
26772 if (cookie == NO_COOKIE)
26773 offset = pc;
26774 if (cookie == INVALID_COOKIE) {
26775- atomic_inc(&oprofile_stats.sample_lost_no_mapping);
26776+ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
26777 offset = pc;
26778 }
26779 if (cookie != last_cookie) {
6892158b 26780@@ -386,14 +386,14 @@ add_sample(struct mm_struct *mm, struct
58c5fc13
MT
26781 /* add userspace sample */
26782
26783 if (!mm) {
26784- atomic_inc(&oprofile_stats.sample_lost_no_mm);
26785+ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mm);
26786 return 0;
26787 }
26788
26789 cookie = lookup_dcookie(mm, s->eip, &offset);
26790
26791 if (cookie == INVALID_COOKIE) {
26792- atomic_inc(&oprofile_stats.sample_lost_no_mapping);
26793+ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
26794 return 0;
26795 }
26796
6892158b 26797@@ -562,7 +562,7 @@ void sync_buffer(int cpu)
58c5fc13
MT
26798 /* ignore backtraces if failed to add a sample */
26799 if (state == sb_bt_start) {
26800 state = sb_bt_ignore;
26801- atomic_inc(&oprofile_stats.bt_lost_no_mapping);
26802+ atomic_inc_unchecked(&oprofile_stats.bt_lost_no_mapping);
26803 }
26804 }
26805 release_mm(mm);
16454cff
MT
26806diff -urNp linux-2.6.38.1/drivers/oprofile/event_buffer.c linux-2.6.38.1/drivers/oprofile/event_buffer.c
26807--- linux-2.6.38.1/drivers/oprofile/event_buffer.c 2011-03-14 21:20:32.000000000 -0400
26808+++ linux-2.6.38.1/drivers/oprofile/event_buffer.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
26809@@ -53,7 +53,7 @@ void add_event_entry(unsigned long value
26810 }
26811
58c5fc13
MT
26812 if (buffer_pos == buffer_size) {
26813- atomic_inc(&oprofile_stats.event_lost_overflow);
26814+ atomic_inc_unchecked(&oprofile_stats.event_lost_overflow);
26815 return;
26816 }
26817
16454cff
MT
26818diff -urNp linux-2.6.38.1/drivers/oprofile/oprof.c linux-2.6.38.1/drivers/oprofile/oprof.c
26819--- linux-2.6.38.1/drivers/oprofile/oprof.c 2011-03-14 21:20:32.000000000 -0400
26820+++ linux-2.6.38.1/drivers/oprofile/oprof.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
26821@@ -110,7 +110,7 @@ static void switch_worker(struct work_st
26822 if (oprofile_ops.switch_events())
26823 return;
58c5fc13 26824
ae4e228f
MT
26825- atomic_inc(&oprofile_stats.multiplex_counter);
26826+ atomic_inc_unchecked(&oprofile_stats.multiplex_counter);
26827 start_switch_worker();
26828 }
58c5fc13 26829
16454cff
MT
26830diff -urNp linux-2.6.38.1/drivers/oprofile/oprofilefs.c linux-2.6.38.1/drivers/oprofile/oprofilefs.c
26831--- linux-2.6.38.1/drivers/oprofile/oprofilefs.c 2011-03-14 21:20:32.000000000 -0400
26832+++ linux-2.6.38.1/drivers/oprofile/oprofilefs.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 26833@@ -186,7 +186,7 @@ static const struct file_operations atom
57199397
MT
26834
26835
26836 int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root,
26837- char const *name, atomic_t *val)
26838+ char const *name, atomic_unchecked_t *val)
26839 {
bc901d79
MT
26840 return __oprofilefs_create_file(sb, root, name,
26841 &atomic_ro_fops, 0444, val);
16454cff
MT
26842diff -urNp linux-2.6.38.1/drivers/oprofile/oprofile_stats.c linux-2.6.38.1/drivers/oprofile/oprofile_stats.c
26843--- linux-2.6.38.1/drivers/oprofile/oprofile_stats.c 2011-03-14 21:20:32.000000000 -0400
26844+++ linux-2.6.38.1/drivers/oprofile/oprofile_stats.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 26845@@ -30,11 +30,11 @@ void oprofile_reset_stats(void)
58c5fc13
MT
26846 cpu_buf->sample_invalid_eip = 0;
26847 }
26848
26849- atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
26850- atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
26851- atomic_set(&oprofile_stats.event_lost_overflow, 0);
26852- atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
ae4e228f 26853- atomic_set(&oprofile_stats.multiplex_counter, 0);
58c5fc13
MT
26854+ atomic_set_unchecked(&oprofile_stats.sample_lost_no_mm, 0);
26855+ atomic_set_unchecked(&oprofile_stats.sample_lost_no_mapping, 0);
26856+ atomic_set_unchecked(&oprofile_stats.event_lost_overflow, 0);
26857+ atomic_set_unchecked(&oprofile_stats.bt_lost_no_mapping, 0);
ae4e228f 26858+ atomic_set_unchecked(&oprofile_stats.multiplex_counter, 0);
58c5fc13
MT
26859 }
26860
26861
16454cff
MT
26862diff -urNp linux-2.6.38.1/drivers/oprofile/oprofile_stats.h linux-2.6.38.1/drivers/oprofile/oprofile_stats.h
26863--- linux-2.6.38.1/drivers/oprofile/oprofile_stats.h 2011-03-14 21:20:32.000000000 -0400
26864+++ linux-2.6.38.1/drivers/oprofile/oprofile_stats.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 26865@@ -13,11 +13,11 @@
58c5fc13
MT
26866 #include <asm/atomic.h>
26867
26868 struct oprofile_stat_struct {
26869- atomic_t sample_lost_no_mm;
26870- atomic_t sample_lost_no_mapping;
26871- atomic_t bt_lost_no_mapping;
26872- atomic_t event_lost_overflow;
ae4e228f 26873- atomic_t multiplex_counter;
58c5fc13
MT
26874+ atomic_unchecked_t sample_lost_no_mm;
26875+ atomic_unchecked_t sample_lost_no_mapping;
26876+ atomic_unchecked_t bt_lost_no_mapping;
26877+ atomic_unchecked_t event_lost_overflow;
ae4e228f 26878+ atomic_unchecked_t multiplex_counter;
58c5fc13
MT
26879 };
26880
26881 extern struct oprofile_stat_struct oprofile_stats;
16454cff
MT
26882diff -urNp linux-2.6.38.1/drivers/parport/procfs.c linux-2.6.38.1/drivers/parport/procfs.c
26883--- linux-2.6.38.1/drivers/parport/procfs.c 2011-03-14 21:20:32.000000000 -0400
26884+++ linux-2.6.38.1/drivers/parport/procfs.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
26885@@ -64,7 +64,7 @@ static int do_active_device(ctl_table *t
26886
26887 *ppos += len;
26888
26889- return copy_to_user(result, buffer, len) ? -EFAULT : 0;
bc901d79 26890+ return (len > sizeof buffer || copy_to_user(result, buffer, len)) ? -EFAULT : 0;
ae4e228f
MT
26891 }
26892
26893 #ifdef CONFIG_PARPORT_1284
26894@@ -106,7 +106,7 @@ static int do_autoprobe(ctl_table *table
26895
26896 *ppos += len;
26897
26898- return copy_to_user (result, buffer, len) ? -EFAULT : 0;
bc901d79 26899+ return (len > sizeof buffer || copy_to_user (result, buffer, len)) ? -EFAULT : 0;
ae4e228f
MT
26900 }
26901 #endif /* IEEE1284.3 support. */
26902
16454cff
MT
26903diff -urNp linux-2.6.38.1/drivers/pci/hotplug/acpiphp_glue.c linux-2.6.38.1/drivers/pci/hotplug/acpiphp_glue.c
26904--- linux-2.6.38.1/drivers/pci/hotplug/acpiphp_glue.c 2011-03-14 21:20:32.000000000 -0400
26905+++ linux-2.6.38.1/drivers/pci/hotplug/acpiphp_glue.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 26906@@ -110,7 +110,7 @@ static int post_dock_fixups(struct notif
ae4e228f
MT
26907 }
26908
26909
26910-static struct acpi_dock_ops acpiphp_dock_ops = {
26911+static const struct acpi_dock_ops acpiphp_dock_ops = {
26912 .handler = handle_hotplug_event_func,
26913 };
26914
16454cff
MT
26915diff -urNp linux-2.6.38.1/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.38.1/drivers/pci/hotplug/cpqphp_nvram.c
26916--- linux-2.6.38.1/drivers/pci/hotplug/cpqphp_nvram.c 2011-03-14 21:20:32.000000000 -0400
26917+++ linux-2.6.38.1/drivers/pci/hotplug/cpqphp_nvram.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
26918@@ -428,9 +428,13 @@ static u32 store_HRT (void __iomem *rom_
26919
26920 void compaq_nvram_init (void __iomem *rom_start)
26921 {
26922+
26923+#ifndef CONFIG_PAX_KERNEXEC
26924 if (rom_start) {
26925 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
26926 }
26927+#endif
26928+
26929 dbg("int15 entry = %p\n", compaq_int15_entry_point);
26930
26931 /* initialize our int15 lock */
16454cff
MT
26932diff -urNp linux-2.6.38.1/drivers/pci/intel-iommu.c linux-2.6.38.1/drivers/pci/intel-iommu.c
26933--- linux-2.6.38.1/drivers/pci/intel-iommu.c 2011-03-14 21:20:32.000000000 -0400
26934+++ linux-2.6.38.1/drivers/pci/intel-iommu.c 2011-03-21 18:31:35.000000000 -0400
6892158b 26935@@ -2934,7 +2934,7 @@ static int intel_mapping_error(struct de
ae4e228f
MT
26936 return !dma_addr;
26937 }
26938
26939-struct dma_map_ops intel_dma_ops = {
26940+const struct dma_map_ops intel_dma_ops = {
26941 .alloc_coherent = intel_alloc_coherent,
26942 .free_coherent = intel_free_coherent,
26943 .map_sg = intel_map_sg,
16454cff
MT
26944diff -urNp linux-2.6.38.1/drivers/pci/pcie/aspm.c linux-2.6.38.1/drivers/pci/pcie/aspm.c
26945--- linux-2.6.38.1/drivers/pci/pcie/aspm.c 2011-03-14 21:20:32.000000000 -0400
26946+++ linux-2.6.38.1/drivers/pci/pcie/aspm.c 2011-03-21 18:31:35.000000000 -0400
26947@@ -27,9 +27,9 @@
26948 #define MODULE_PARAM_PREFIX "pcie_aspm."
26949
26950 /* Note: those are not register definitions */
26951-#define ASPM_STATE_L0S_UP (1) /* Upstream direction L0s state */
26952-#define ASPM_STATE_L0S_DW (2) /* Downstream direction L0s state */
26953-#define ASPM_STATE_L1 (4) /* L1 state */
26954+#define ASPM_STATE_L0S_UP (1U) /* Upstream direction L0s state */
26955+#define ASPM_STATE_L0S_DW (2U) /* Downstream direction L0s state */
26956+#define ASPM_STATE_L1 (4U) /* L1 state */
26957 #define ASPM_STATE_L0S (ASPM_STATE_L0S_UP | ASPM_STATE_L0S_DW)
26958 #define ASPM_STATE_ALL (ASPM_STATE_L0S | ASPM_STATE_L1)
26959
26960diff -urNp linux-2.6.38.1/drivers/pci/pcie/portdrv_pci.c linux-2.6.38.1/drivers/pci/pcie/portdrv_pci.c
26961--- linux-2.6.38.1/drivers/pci/pcie/portdrv_pci.c 2011-03-14 21:20:32.000000000 -0400
26962+++ linux-2.6.38.1/drivers/pci/pcie/portdrv_pci.c 2011-03-21 18:31:35.000000000 -0400
26963@@ -307,7 +307,7 @@ static void pcie_portdrv_err_resume(stru
58c5fc13
MT
26964 static const struct pci_device_id port_pci_ids[] = { {
26965 /* handle any PCI-Express port */
26966 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
26967- }, { /* end: all zeroes */ }
26968+ }, { 0, 0, 0, 0, 0, 0, 0 }
26969 };
26970 MODULE_DEVICE_TABLE(pci, port_pci_ids);
26971
16454cff
MT
26972diff -urNp linux-2.6.38.1/drivers/pci/probe.c linux-2.6.38.1/drivers/pci/probe.c
26973--- linux-2.6.38.1/drivers/pci/probe.c 2011-03-14 21:20:32.000000000 -0400
26974+++ linux-2.6.38.1/drivers/pci/probe.c 2011-03-21 18:31:35.000000000 -0400
57199397 26975@@ -62,14 +62,14 @@ static ssize_t pci_bus_show_cpuaffinity(
df50ba0c
MT
26976 return ret;
26977 }
26978
26979-static ssize_t inline pci_bus_show_cpumaskaffinity(struct device *dev,
26980+static inline ssize_t pci_bus_show_cpumaskaffinity(struct device *dev,
26981 struct device_attribute *attr,
26982 char *buf)
26983 {
26984 return pci_bus_show_cpuaffinity(dev, 0, attr, buf);
26985 }
26986
26987-static ssize_t inline pci_bus_show_cpulistaffinity(struct device *dev,
26988+static inline ssize_t pci_bus_show_cpulistaffinity(struct device *dev,
26989 struct device_attribute *attr,
26990 char *buf)
26991 {
bc901d79
MT
26992@@ -165,7 +165,7 @@ int __pci_read_base(struct pci_dev *dev,
26993 u32 l, sz, mask;
26994 u16 orig_cmd;
26995
26996- mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
26997+ mask = type ? (u32)PCI_ROM_ADDRESS_MASK : ~0;
26998
26999 if (!dev->mmio_always_on) {
27000 pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);
16454cff
MT
27001diff -urNp linux-2.6.38.1/drivers/pci/proc.c linux-2.6.38.1/drivers/pci/proc.c
27002--- linux-2.6.38.1/drivers/pci/proc.c 2011-03-14 21:20:32.000000000 -0400
27003+++ linux-2.6.38.1/drivers/pci/proc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 27004@@ -476,7 +476,16 @@ static const struct file_operations proc
58c5fc13
MT
27005 static int __init pci_proc_init(void)
27006 {
27007 struct pci_dev *dev = NULL;
27008+
27009+#ifdef CONFIG_GRKERNSEC_PROC_ADD
27010+#ifdef CONFIG_GRKERNSEC_PROC_USER
27011+ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
27012+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
27013+ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
27014+#endif
27015+#else
27016 proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
27017+#endif
27018 proc_create("devices", 0, proc_bus_pci_dir,
27019 &proc_bus_pci_dev_operations);
27020 proc_initialized = 1;
16454cff
MT
27021diff -urNp linux-2.6.38.1/drivers/pcmcia/ti113x.h linux-2.6.38.1/drivers/pcmcia/ti113x.h
27022--- linux-2.6.38.1/drivers/pcmcia/ti113x.h 2011-03-14 21:20:32.000000000 -0400
27023+++ linux-2.6.38.1/drivers/pcmcia/ti113x.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c 27024@@ -936,7 +936,7 @@ static struct pci_device_id ene_tune_tbl
58c5fc13
MT
27025 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
27026 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
27027
27028- {}
27029+ { 0, 0, 0, 0, 0, 0, 0 }
27030 };
27031
27032 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
16454cff
MT
27033diff -urNp linux-2.6.38.1/drivers/pcmcia/yenta_socket.c linux-2.6.38.1/drivers/pcmcia/yenta_socket.c
27034--- linux-2.6.38.1/drivers/pcmcia/yenta_socket.c 2011-03-14 21:20:32.000000000 -0400
27035+++ linux-2.6.38.1/drivers/pcmcia/yenta_socket.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 27036@@ -1426,7 +1426,7 @@ static struct pci_device_id yenta_table[
58c5fc13
MT
27037
27038 /* match any cardbus bridge */
27039 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
27040- { /* all zeroes */ }
27041+ { 0, 0, 0, 0, 0, 0, 0 }
27042 };
27043 MODULE_DEVICE_TABLE(pci, yenta_table);
27044
16454cff
MT
27045diff -urNp linux-2.6.38.1/drivers/platform/x86/asus-laptop.c linux-2.6.38.1/drivers/platform/x86/asus-laptop.c
27046--- linux-2.6.38.1/drivers/platform/x86/asus-laptop.c 2011-03-14 21:20:32.000000000 -0400
27047+++ linux-2.6.38.1/drivers/platform/x86/asus-laptop.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 27048@@ -243,7 +243,6 @@ struct asus_laptop {
57199397
MT
27049 struct asus_led gled;
27050 struct asus_led kled;
27051 struct workqueue_struct *led_workqueue;
27052-
27053 int wireless_status;
27054 bool have_rsts;
27055 int lcd_state;
16454cff
MT
27056diff -urNp linux-2.6.38.1/drivers/pnp/pnpbios/bioscalls.c linux-2.6.38.1/drivers/pnp/pnpbios/bioscalls.c
27057--- linux-2.6.38.1/drivers/pnp/pnpbios/bioscalls.c 2011-03-14 21:20:32.000000000 -0400
27058+++ linux-2.6.38.1/drivers/pnp/pnpbios/bioscalls.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 27059@@ -59,7 +59,7 @@ do { \
ae4e228f 27060 set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
58c5fc13
MT
27061 } while(0)
27062
ae4e228f
MT
27063-static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
27064+static const struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4093,
27065 (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
58c5fc13
MT
27066
27067 /*
df50ba0c 27068@@ -96,7 +96,10 @@ static inline u16 call_pnp_bios(u16 func
58c5fc13
MT
27069
27070 cpu = get_cpu();
27071 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
27072+
ae4e228f 27073+ pax_open_kernel();
58c5fc13 27074 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
ae4e228f 27075+ pax_close_kernel();
58c5fc13 27076
58c5fc13
MT
27077 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
27078 spin_lock_irqsave(&pnp_bios_lock, flags);
df50ba0c 27079@@ -134,7 +137,10 @@ static inline u16 call_pnp_bios(u16 func
58c5fc13
MT
27080 :"memory");
27081 spin_unlock_irqrestore(&pnp_bios_lock, flags);
27082
ae4e228f 27083+ pax_open_kernel();
58c5fc13 27084 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
ae4e228f 27085+ pax_close_kernel();
58c5fc13
MT
27086+
27087 put_cpu();
27088
27089 /* If we get here and this is set then the PnP BIOS faulted on us. */
df50ba0c 27090@@ -468,7 +474,7 @@ int pnp_bios_read_escd(char *data, u32 n
58c5fc13
MT
27091 return status;
27092 }
27093
27094-void pnpbios_calls_init(union pnp_bios_install_struct *header)
27095+void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
27096 {
27097 int i;
27098
df50ba0c 27099@@ -476,6 +482,8 @@ void pnpbios_calls_init(union pnp_bios_i
58c5fc13
MT
27100 pnp_bios_callpoint.offset = header->fields.pm16offset;
27101 pnp_bios_callpoint.segment = PNP_CS16;
27102
ae4e228f 27103+ pax_open_kernel();
58c5fc13 27104+
ae4e228f
MT
27105 for_each_possible_cpu(i) {
27106 struct desc_struct *gdt = get_cpu_gdt_table(i);
27107 if (!gdt)
df50ba0c 27108@@ -487,4 +495,6 @@ void pnpbios_calls_init(union pnp_bios_i
ae4e228f
MT
27109 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_DS],
27110 (unsigned long)__va(header->fields.pm16dseg));
58c5fc13
MT
27111 }
27112+
ae4e228f 27113+ pax_close_kernel();
58c5fc13 27114 }
16454cff
MT
27115diff -urNp linux-2.6.38.1/drivers/pnp/quirks.c linux-2.6.38.1/drivers/pnp/quirks.c
27116--- linux-2.6.38.1/drivers/pnp/quirks.c 2011-03-14 21:20:32.000000000 -0400
27117+++ linux-2.6.38.1/drivers/pnp/quirks.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 27118@@ -322,7 +322,7 @@ static struct pnp_fixup pnp_fixups[] = {
58c5fc13
MT
27119 /* PnP resources that might overlap PCI BARs */
27120 {"PNP0c01", quirk_system_pci_resources},
27121 {"PNP0c02", quirk_system_pci_resources},
27122- {""}
27123+ {"", NULL}
27124 };
27125
27126 void pnp_fixup_device(struct pnp_dev *dev)
16454cff
MT
27127diff -urNp linux-2.6.38.1/drivers/pnp/resource.c linux-2.6.38.1/drivers/pnp/resource.c
27128--- linux-2.6.38.1/drivers/pnp/resource.c 2011-03-14 21:20:32.000000000 -0400
27129+++ linux-2.6.38.1/drivers/pnp/resource.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 27130@@ -360,7 +360,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
58c5fc13
MT
27131 return 1;
27132
27133 /* check if the resource is valid */
27134- if (*irq < 0 || *irq > 15)
27135+ if (*irq > 15)
27136 return 0;
27137
27138 /* check if the resource is reserved */
df50ba0c 27139@@ -424,7 +424,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
58c5fc13
MT
27140 return 1;
27141
27142 /* check if the resource is valid */
27143- if (*dma < 0 || *dma == 4 || *dma > 7)
27144+ if (*dma == 4 || *dma > 7)
27145 return 0;
27146
27147 /* check if the resource is reserved */
16454cff
MT
27148diff -urNp linux-2.6.38.1/drivers/rtc/rtc-dev.c linux-2.6.38.1/drivers/rtc/rtc-dev.c
27149--- linux-2.6.38.1/drivers/rtc/rtc-dev.c 2011-03-14 21:20:32.000000000 -0400
27150+++ linux-2.6.38.1/drivers/rtc/rtc-dev.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
27151@@ -14,6 +14,7 @@
27152 #include <linux/module.h>
27153 #include <linux/rtc.h>
27154 #include <linux/sched.h>
27155+#include <linux/grsecurity.h>
27156 #include "rtc-core.h"
27157
27158 static dev_t rtc_devt;
16454cff 27159@@ -345,6 +346,8 @@ static long rtc_dev_ioctl(struct file *f
bc901d79
MT
27160 if (copy_from_user(&tm, uarg, sizeof(tm)))
27161 return -EFAULT;
27162
27163+ gr_log_timechange();
27164+
27165 return rtc_set_time(rtc, &tm);
27166
27167 case RTC_PIE_ON:
16454cff
MT
27168diff -urNp linux-2.6.38.1/drivers/rtc/rtc-ds1511.c linux-2.6.38.1/drivers/rtc/rtc-ds1511.c
27169--- linux-2.6.38.1/drivers/rtc/rtc-ds1511.c 2011-03-14 21:20:32.000000000 -0400
27170+++ linux-2.6.38.1/drivers/rtc/rtc-ds1511.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
27171@@ -485,7 +485,7 @@ ds1511_nvram_write(struct file *filp, st
27172 static struct bin_attribute ds1511_nvram_attr = {
27173 .attr = {
27174 .name = "nvram",
27175- .mode = S_IRUGO | S_IWUGO,
27176+ .mode = S_IRUGO | S_IWUSR,
27177 },
27178 .size = DS1511_RAM_MAX,
27179 .read = ds1511_nvram_read,
16454cff
MT
27180diff -urNp linux-2.6.38.1/drivers/s390/cio/qdio_debug.c linux-2.6.38.1/drivers/s390/cio/qdio_debug.c
27181--- linux-2.6.38.1/drivers/s390/cio/qdio_debug.c 2011-03-14 21:20:32.000000000 -0400
27182+++ linux-2.6.38.1/drivers/s390/cio/qdio_debug.c 2011-03-21 18:31:35.000000000 -0400
27183@@ -225,7 +225,7 @@ static int qperf_seq_open(struct inode *
ae4e228f 27184 filp->f_path.dentry->d_inode->i_private);
58c5fc13
MT
27185 }
27186
ae4e228f
MT
27187-static struct file_operations debugfs_perf_fops = {
27188+static const struct file_operations debugfs_perf_fops = {
58c5fc13 27189 .owner = THIS_MODULE,
ae4e228f 27190 .open = qperf_seq_open,
58c5fc13 27191 .read = seq_read,
16454cff
MT
27192diff -urNp linux-2.6.38.1/drivers/scsi/aic94xx/aic94xx_init.c linux-2.6.38.1/drivers/scsi/aic94xx/aic94xx_init.c
27193--- linux-2.6.38.1/drivers/scsi/aic94xx/aic94xx_init.c 2011-03-14 21:20:32.000000000 -0400
27194+++ linux-2.6.38.1/drivers/scsi/aic94xx/aic94xx_init.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
27195@@ -486,7 +486,7 @@ static ssize_t asd_show_update_bios(stru
27196 flash_error_table[i].reason);
27197 }
27198
27199-static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUGO,
27200+static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUSR,
27201 asd_show_update_bios, asd_store_update_bios);
27202
27203 static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
16454cff
MT
27204diff -urNp linux-2.6.38.1/drivers/scsi/hpsa.c linux-2.6.38.1/drivers/scsi/hpsa.c
27205--- linux-2.6.38.1/drivers/scsi/hpsa.c 2011-03-14 21:20:32.000000000 -0400
27206+++ linux-2.6.38.1/drivers/scsi/hpsa.c 2011-03-21 18:31:35.000000000 -0400
27207@@ -2281,6 +2281,8 @@ static int hpsa_ioctl32_passthru(struct
bc901d79
MT
27208 int err;
27209 u32 cp;
27210
27211+ memset(&arg64, 0, sizeof(arg64));
27212+
27213 err = 0;
27214 err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
27215 sizeof(arg64.LUN_info));
16454cff
MT
27216diff -urNp linux-2.6.38.1/drivers/scsi/ipr.c linux-2.6.38.1/drivers/scsi/ipr.c
27217--- linux-2.6.38.1/drivers/scsi/ipr.c 2011-03-14 21:20:32.000000000 -0400
27218+++ linux-2.6.38.1/drivers/scsi/ipr.c 2011-03-21 18:31:35.000000000 -0400
27219@@ -6207,7 +6207,7 @@ static bool ipr_qc_fill_rtf(struct ata_q
ae4e228f 27220 return true;
58c5fc13
MT
27221 }
27222
ae4e228f
MT
27223-static struct ata_port_operations ipr_sata_ops = {
27224+static const struct ata_port_operations ipr_sata_ops = {
27225 .phy_reset = ipr_ata_phy_reset,
27226 .hardreset = ipr_sata_reset,
27227 .post_internal_cmd = ipr_ata_post_internal,
16454cff
MT
27228diff -urNp linux-2.6.38.1/drivers/scsi/libfc/fc_exch.c linux-2.6.38.1/drivers/scsi/libfc/fc_exch.c
27229--- linux-2.6.38.1/drivers/scsi/libfc/fc_exch.c 2011-03-14 21:20:32.000000000 -0400
27230+++ linux-2.6.38.1/drivers/scsi/libfc/fc_exch.c 2011-03-21 18:31:35.000000000 -0400
27231@@ -105,12 +105,12 @@ struct fc_exch_mgr {
58c5fc13
MT
27232 * all together if not used XXX
27233 */
27234 struct {
27235- atomic_t no_free_exch;
27236- atomic_t no_free_exch_xid;
27237- atomic_t xid_not_found;
27238- atomic_t xid_busy;
27239- atomic_t seq_not_found;
27240- atomic_t non_bls_resp;
27241+ atomic_unchecked_t no_free_exch;
27242+ atomic_unchecked_t no_free_exch_xid;
27243+ atomic_unchecked_t xid_not_found;
27244+ atomic_unchecked_t xid_busy;
27245+ atomic_unchecked_t seq_not_found;
27246+ atomic_unchecked_t non_bls_resp;
27247 } stats;
58c5fc13 27248 };
16454cff
MT
27249
27250@@ -687,7 +687,7 @@ static struct fc_exch *fc_exch_em_alloc(
58c5fc13
MT
27251 /* allocate memory for exchange */
27252 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
27253 if (!ep) {
27254- atomic_inc(&mp->stats.no_free_exch);
27255+ atomic_inc_unchecked(&mp->stats.no_free_exch);
27256 goto out;
27257 }
27258 memset(ep, 0, sizeof(*ep));
16454cff 27259@@ -748,7 +748,7 @@ out:
58c5fc13
MT
27260 return ep;
27261 err:
ae4e228f 27262 spin_unlock_bh(&pool->lock);
58c5fc13
MT
27263- atomic_inc(&mp->stats.no_free_exch_xid);
27264+ atomic_inc_unchecked(&mp->stats.no_free_exch_xid);
27265 mempool_free(ep, mp->ep_pool);
27266 return NULL;
27267 }
16454cff 27268@@ -893,7 +893,7 @@ static enum fc_pf_rjt_reason fc_seq_look
58c5fc13
MT
27269 xid = ntohs(fh->fh_ox_id); /* we originated exch */
27270 ep = fc_exch_find(mp, xid);
27271 if (!ep) {
27272- atomic_inc(&mp->stats.xid_not_found);
27273+ atomic_inc_unchecked(&mp->stats.xid_not_found);
27274 reject = FC_RJT_OX_ID;
27275 goto out;
27276 }
16454cff 27277@@ -923,7 +923,7 @@ static enum fc_pf_rjt_reason fc_seq_look
58c5fc13
MT
27278 ep = fc_exch_find(mp, xid);
27279 if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
27280 if (ep) {
27281- atomic_inc(&mp->stats.xid_busy);
27282+ atomic_inc_unchecked(&mp->stats.xid_busy);
27283 reject = FC_RJT_RX_ID;
27284 goto rel;
27285 }
16454cff 27286@@ -934,7 +934,7 @@ static enum fc_pf_rjt_reason fc_seq_look
58c5fc13
MT
27287 }
27288 xid = ep->xid; /* get our XID */
27289 } else if (!ep) {
27290- atomic_inc(&mp->stats.xid_not_found);
27291+ atomic_inc_unchecked(&mp->stats.xid_not_found);
27292 reject = FC_RJT_RX_ID; /* XID not found */
27293 goto out;
27294 }
16454cff 27295@@ -951,7 +951,7 @@ static enum fc_pf_rjt_reason fc_seq_look
58c5fc13
MT
27296 } else {
27297 sp = &ep->seq;
27298 if (sp->id != fh->fh_seq_id) {
27299- atomic_inc(&mp->stats.seq_not_found);
27300+ atomic_inc_unchecked(&mp->stats.seq_not_found);
27301 reject = FC_RJT_SEQ_ID; /* sequence/exch should exist */
27302 goto rel;
27303 }
16454cff 27304@@ -1368,22 +1368,22 @@ static void fc_exch_recv_seq_resp(struct
58c5fc13
MT
27305
27306 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
27307 if (!ep) {
27308- atomic_inc(&mp->stats.xid_not_found);
27309+ atomic_inc_unchecked(&mp->stats.xid_not_found);
27310 goto out;
27311 }
27312 if (ep->esb_stat & ESB_ST_COMPLETE) {
27313- atomic_inc(&mp->stats.xid_not_found);
27314+ atomic_inc_unchecked(&mp->stats.xid_not_found);
16454cff 27315 goto rel;
58c5fc13
MT
27316 }
27317 if (ep->rxid == FC_XID_UNKNOWN)
27318 ep->rxid = ntohs(fh->fh_rx_id);
27319 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
27320- atomic_inc(&mp->stats.xid_not_found);
27321+ atomic_inc_unchecked(&mp->stats.xid_not_found);
27322 goto rel;
27323 }
27324 if (ep->did != ntoh24(fh->fh_s_id) &&
27325 ep->did != FC_FID_FLOGI) {
27326- atomic_inc(&mp->stats.xid_not_found);
27327+ atomic_inc_unchecked(&mp->stats.xid_not_found);
27328 goto rel;
27329 }
27330 sof = fr_sof(fp);
16454cff 27331@@ -1392,7 +1392,7 @@ static void fc_exch_recv_seq_resp(struct
57199397
MT
27332 sp->ssb_stat |= SSB_ST_RESP;
27333 sp->id = fh->fh_seq_id;
27334 } else if (sp->id != fh->fh_seq_id) {
27335- atomic_inc(&mp->stats.seq_not_found);
27336+ atomic_inc_unchecked(&mp->stats.seq_not_found);
27337 goto rel;
58c5fc13 27338 }
57199397 27339
16454cff 27340@@ -1455,9 +1455,9 @@ static void fc_exch_recv_resp(struct fc_
58c5fc13 27341 sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */
ae4e228f
MT
27342
27343 if (!sp)
58c5fc13
MT
27344- atomic_inc(&mp->stats.xid_not_found);
27345+ atomic_inc_unchecked(&mp->stats.xid_not_found);
ae4e228f 27346 else
58c5fc13
MT
27347- atomic_inc(&mp->stats.non_bls_resp);
27348+ atomic_inc_unchecked(&mp->stats.non_bls_resp);
ae4e228f 27349
58c5fc13 27350 fc_frame_free(fp);
ae4e228f 27351 }
16454cff
MT
27352diff -urNp linux-2.6.38.1/drivers/scsi/libsas/sas_ata.c linux-2.6.38.1/drivers/scsi/libsas/sas_ata.c
27353--- linux-2.6.38.1/drivers/scsi/libsas/sas_ata.c 2011-03-14 21:20:32.000000000 -0400
27354+++ linux-2.6.38.1/drivers/scsi/libsas/sas_ata.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 27355@@ -348,10 +348,10 @@ static int sas_ata_scr_read(struct ata_l
ae4e228f
MT
27356 }
27357 }
27358
27359-static struct ata_port_operations sas_sata_ops = {
27360+static const struct ata_port_operations sas_sata_ops = {
27361 .phy_reset = sas_ata_phy_reset,
27362 .post_internal_cmd = sas_ata_post_internal,
bc901d79
MT
27363- .qc_defer = ata_std_qc_defer,
27364+ .qc_defer = ata_std_qc_defer,
ae4e228f 27365 .qc_prep = ata_noop_qc_prep,
bc901d79
MT
27366 .qc_issue = sas_ata_qc_issue,
27367 .qc_fill_rtf = sas_ata_qc_fill_rtf,
16454cff
MT
27368diff -urNp linux-2.6.38.1/drivers/scsi/mpt2sas/mpt2sas_debug.h linux-2.6.38.1/drivers/scsi/mpt2sas/mpt2sas_debug.h
27369--- linux-2.6.38.1/drivers/scsi/mpt2sas/mpt2sas_debug.h 2011-03-14 21:20:32.000000000 -0400
27370+++ linux-2.6.38.1/drivers/scsi/mpt2sas/mpt2sas_debug.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
27371@@ -79,7 +79,7 @@
27372 CMD; \
27373 }
27374 #else
27375-#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
27376+#define MPT_CHECK_LOGGING(IOC, CMD, BITS) do {} while (0)
27377 #endif /* CONFIG_SCSI_MPT2SAS_LOGGING */
27378
27379
16454cff
MT
27380diff -urNp linux-2.6.38.1/drivers/scsi/qla2xxx/qla_os.c linux-2.6.38.1/drivers/scsi/qla2xxx/qla_os.c
27381--- linux-2.6.38.1/drivers/scsi/qla2xxx/qla_os.c 2011-03-14 21:20:32.000000000 -0400
27382+++ linux-2.6.38.1/drivers/scsi/qla2xxx/qla_os.c 2011-03-21 18:31:35.000000000 -0400
27383@@ -4096,7 +4096,7 @@ static struct pci_driver qla2xxx_pci_dri
57199397
MT
27384 .err_handler = &qla2xxx_err_handler,
27385 };
27386
27387-static struct file_operations apidev_fops = {
27388+static const struct file_operations apidev_fops = {
27389 .owner = THIS_MODULE,
bc901d79 27390 .llseek = noop_llseek,
57199397 27391 };
16454cff
MT
27392diff -urNp linux-2.6.38.1/drivers/scsi/scsi_logging.h linux-2.6.38.1/drivers/scsi/scsi_logging.h
27393--- linux-2.6.38.1/drivers/scsi/scsi_logging.h 2011-03-14 21:20:32.000000000 -0400
27394+++ linux-2.6.38.1/drivers/scsi/scsi_logging.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
27395@@ -51,7 +51,7 @@ do { \
27396 } while (0); \
27397 } while (0)
27398 #else
27399-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
27400+#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
27401 #endif /* CONFIG_SCSI_LOGGING */
27402
27403 /*
16454cff
MT
27404diff -urNp linux-2.6.38.1/drivers/scsi/scsi_transport_iscsi.c linux-2.6.38.1/drivers/scsi/scsi_transport_iscsi.c
27405--- linux-2.6.38.1/drivers/scsi/scsi_transport_iscsi.c 2011-03-14 21:20:32.000000000 -0400
27406+++ linux-2.6.38.1/drivers/scsi/scsi_transport_iscsi.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
27407@@ -1847,7 +1847,7 @@ store_priv_session_##field(struct device
27408 #define iscsi_priv_session_rw_attr(field, format) \
27409 iscsi_priv_session_attr_show(field, format) \
27410 iscsi_priv_session_attr_store(field) \
27411-static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO | S_IWUGO, \
27412+static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO | S_IWUSR, \
27413 show_priv_session_##field, \
27414 store_priv_session_##field)
27415 iscsi_priv_session_rw_attr(recovery_tmo, "%d");
16454cff
MT
27416diff -urNp linux-2.6.38.1/drivers/scsi/sg.c linux-2.6.38.1/drivers/scsi/sg.c
27417--- linux-2.6.38.1/drivers/scsi/sg.c 2011-03-14 21:20:32.000000000 -0400
27418+++ linux-2.6.38.1/drivers/scsi/sg.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 27419@@ -2310,7 +2310,7 @@ struct sg_proc_leaf {
ae4e228f 27420 const struct file_operations * fops;
58c5fc13
MT
27421 };
27422
ae4e228f
MT
27423-static struct sg_proc_leaf sg_proc_leaf_arr[] = {
27424+static const struct sg_proc_leaf sg_proc_leaf_arr[] = {
27425 {"allow_dio", &adio_fops},
27426 {"debug", &debug_fops},
27427 {"def_reserved_size", &dressz_fops},
bc901d79 27428@@ -2325,7 +2325,7 @@ sg_proc_init(void)
ae4e228f
MT
27429 {
27430 int k, mask;
27431 int num_leaves = ARRAY_SIZE(sg_proc_leaf_arr);
27432- struct sg_proc_leaf * leaf;
27433+ const struct sg_proc_leaf * leaf;
27434
27435 sg_proc_sgp = proc_mkdir(sg_proc_sg_dirname, NULL);
27436 if (!sg_proc_sgp)
16454cff
MT
27437diff -urNp linux-2.6.38.1/drivers/staging/autofs/root.c linux-2.6.38.1/drivers/staging/autofs/root.c
27438--- linux-2.6.38.1/drivers/staging/autofs/root.c 2011-03-14 21:20:32.000000000 -0400
27439+++ linux-2.6.38.1/drivers/staging/autofs/root.c 2011-03-21 18:31:35.000000000 -0400
27440@@ -311,7 +311,8 @@ static int autofs_root_symlink(struct in
c52201e0
MT
27441 set_bit(n,sbi->symlink_bitmap);
27442 sl = &sbi->symlink[n];
27443 sl->len = strlen(symname);
27444- sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
27445+ slsize = sl->len + 1;
27446+ sl->data = kmalloc(slsize, GFP_KERNEL);
27447 if (!sl->data) {
27448 clear_bit(n,sbi->symlink_bitmap);
27449 unlock_kernel();
16454cff
MT
27450diff -urNp linux-2.6.38.1/drivers/staging/bcm/Bcmchar.c linux-2.6.38.1/drivers/staging/bcm/Bcmchar.c
27451--- linux-2.6.38.1/drivers/staging/bcm/Bcmchar.c 2011-03-14 21:20:32.000000000 -0400
27452+++ linux-2.6.38.1/drivers/staging/bcm/Bcmchar.c 2011-03-21 18:31:35.000000000 -0400
27453@@ -2093,7 +2093,7 @@ static long bcm_char_ioctl(struct file *
bc901d79
MT
27454 }
27455
27456
27457-static struct file_operations bcm_fops = {
27458+static const struct file_operations bcm_fops = {
27459 .owner = THIS_MODULE,
27460 .open = bcm_char_open,
27461 .release = bcm_char_release,
16454cff
MT
27462diff -urNp linux-2.6.38.1/drivers/staging/brcm80211/brcmfmac/dhd_linux.c linux-2.6.38.1/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
27463--- linux-2.6.38.1/drivers/staging/brcm80211/brcmfmac/dhd_linux.c 2011-03-14 21:20:32.000000000 -0400
27464+++ linux-2.6.38.1/drivers/staging/brcm80211/brcmfmac/dhd_linux.c 2011-03-21 18:31:35.000000000 -0400
27465@@ -863,14 +863,14 @@ static void dhd_op_if(dhd_if_t *ifp)
c52201e0
MT
27466 free_netdev(ifp->net);
27467 }
27468 /* Allocate etherdev, including space for private structure */
27469- ifp->net = alloc_etherdev(sizeof(dhd));
27470+ ifp->net = alloc_etherdev(sizeof(*dhd));
27471 if (!ifp->net) {
27472 DHD_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
27473 ret = -ENOMEM;
27474 }
27475 if (ret == 0) {
27476 strcpy(ifp->net->name, ifp->name);
27477- memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
27478+ memcpy(netdev_priv(ifp->net), dhd, sizeof(*dhd));
27479 err = dhd_net_attach(&dhd->pub, ifp->idx);
27480 if (err != 0) {
27481 DHD_ERROR(("%s: dhd_net_attach failed, "
16454cff 27482@@ -1969,25 +1969,23 @@ dhd_pub_t *dhd_attach(struct osl_info *o
c52201e0
MT
27483 strcpy(nv_path, nvram_path);
27484
27485 /* Allocate etherdev, including space for private structure */
27486- net = alloc_etherdev(sizeof(dhd));
27487+ net = alloc_etherdev(sizeof(*dhd));
27488 if (!net) {
27489 DHD_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
27490 goto fail;
27491 }
27492
27493 /* Allocate primary dhd_info */
27494- dhd = kmalloc(sizeof(dhd_info_t), GFP_ATOMIC);
27495+ dhd = kzalloc(sizeof(dhd_info_t), GFP_ATOMIC);
27496 if (!dhd) {
27497 DHD_ERROR(("%s: OOM - alloc dhd_info\n", __func__));
27498 goto fail;
27499 }
27500
27501- memset(dhd, 0, sizeof(dhd_info_t));
27502-
27503 /*
27504 * Save the dhd_info into the priv
27505 */
27506- memcpy(netdev_priv(net), &dhd, sizeof(dhd));
27507+ memcpy(netdev_priv(net), dhd, sizeof(*dhd));
27508 dhd->pub.osh = osh;
27509
27510 /* Set network interface name if it was provided as module parameter */
16454cff 27511@@ -2105,7 +2103,7 @@ dhd_pub_t *dhd_attach(struct osl_info *o
c52201e0
MT
27512 /*
27513 * Save the dhd_info into the priv
27514 */
27515- memcpy(netdev_priv(net), &dhd, sizeof(dhd));
27516+ memcpy(netdev_priv(net), dhd, sizeof(*dhd));
27517
27518 #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
27519 g_bus = bus;
16454cff
MT
27520diff -urNp linux-2.6.38.1/drivers/staging/brcm80211/brcmfmac/wl_iw.c linux-2.6.38.1/drivers/staging/brcm80211/brcmfmac/wl_iw.c
27521--- linux-2.6.38.1/drivers/staging/brcm80211/brcmfmac/wl_iw.c 2011-03-14 21:20:32.000000000 -0400
27522+++ linux-2.6.38.1/drivers/staging/brcm80211/brcmfmac/wl_iw.c 2011-03-21 18:31:35.000000000 -0400
27523@@ -513,7 +513,7 @@ wl_iw_get_range(struct net_device *dev,
c52201e0
MT
27524 list = (wl_u32_list_t *) channels;
27525
27526 dwrq->length = sizeof(struct iw_range);
27527- memset(range, 0, sizeof(range));
27528+ memset(range, 0, sizeof(*range));
27529
27530 range->min_nwid = range->max_nwid = 0;
27531
16454cff
MT
27532diff -urNp linux-2.6.38.1/drivers/staging/comedi/comedi_fops.c linux-2.6.38.1/drivers/staging/comedi/comedi_fops.c
27533--- linux-2.6.38.1/drivers/staging/comedi/comedi_fops.c 2011-03-14 21:20:32.000000000 -0400
27534+++ linux-2.6.38.1/drivers/staging/comedi/comedi_fops.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 27535@@ -1426,7 +1426,7 @@ static void comedi_unmap(struct vm_area_
58c5fc13
MT
27536 mutex_unlock(&dev->mutex);
27537 }
27538
27539-static struct vm_operations_struct comedi_vm_ops = {
27540+static const struct vm_operations_struct comedi_vm_ops = {
ae4e228f 27541 .close = comedi_unmap,
58c5fc13
MT
27542 };
27543
16454cff
MT
27544diff -urNp linux-2.6.38.1/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c linux-2.6.38.1/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
27545--- linux-2.6.38.1/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c 2011-03-14 21:20:32.000000000 -0400
27546+++ linux-2.6.38.1/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c 2011-03-21 18:31:35.000000000 -0400
27547@@ -55,7 +55,7 @@ int numofmsgbuf = 0;
bc901d79
MT
27548 //
27549 // Table of entry-point routines for char device
27550 //
27551-static struct file_operations ft1000fops =
27552+static const struct file_operations ft1000fops =
27553 {
16454cff
MT
27554 .unlocked_ioctl = ft1000_ioctl,
27555 .poll = ft1000_poll_dev,
27556diff -urNp linux-2.6.38.1/drivers/staging/go7007/go7007-v4l2.c linux-2.6.38.1/drivers/staging/go7007/go7007-v4l2.c
27557--- linux-2.6.38.1/drivers/staging/go7007/go7007-v4l2.c 2011-03-14 21:20:32.000000000 -0400
27558+++ linux-2.6.38.1/drivers/staging/go7007/go7007-v4l2.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 27559@@ -1672,7 +1672,7 @@ static int go7007_vm_fault(struct vm_are
58c5fc13
MT
27560 return 0;
27561 }
27562
27563-static struct vm_operations_struct go7007_vm_ops = {
27564+static const struct vm_operations_struct go7007_vm_ops = {
27565 .open = go7007_vm_open,
27566 .close = go7007_vm_close,
27567 .fault = go7007_vm_fault,
16454cff
MT
27568diff -urNp linux-2.6.38.1/drivers/staging/hv/hv.c linux-2.6.38.1/drivers/staging/hv/hv.c
27569--- linux-2.6.38.1/drivers/staging/hv/hv.c 2011-03-14 21:20:32.000000000 -0400
27570+++ linux-2.6.38.1/drivers/staging/hv/hv.c 2011-03-21 18:31:35.000000000 -0400
27571@@ -163,7 +163,7 @@ static u64 do_hypercall(u64 control, voi
27572 u64 output_address = (output) ? virt_to_phys(output) : 0;
27573 u32 output_address_hi = output_address >> 32;
27574 u32 output_address_lo = output_address & 0xFFFFFFFF;
27575- volatile void *hypercall_page = hv_context.hypercall_page;
27576+ volatile void *hypercall_page = ktva_ktla(hv_context.hypercall_page);
df50ba0c
MT
27577
27578 DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
16454cff
MT
27579 control, input, output);
27580diff -urNp linux-2.6.38.1/drivers/staging/phison/phison.c linux-2.6.38.1/drivers/staging/phison/phison.c
27581--- linux-2.6.38.1/drivers/staging/phison/phison.c 2011-03-14 21:20:32.000000000 -0400
27582+++ linux-2.6.38.1/drivers/staging/phison/phison.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
27583@@ -43,7 +43,7 @@ static struct scsi_host_template phison_
27584 ATA_BMDMA_SHT(DRV_NAME),
27585 };
27586
27587-static struct ata_port_operations phison_ops = {
27588+static const struct ata_port_operations phison_ops = {
27589 .inherits = &ata_bmdma_port_ops,
27590 .prereset = phison_pre_reset,
27591 };
16454cff
MT
27592diff -urNp linux-2.6.38.1/drivers/staging/pohmelfs/inode.c linux-2.6.38.1/drivers/staging/pohmelfs/inode.c
27593--- linux-2.6.38.1/drivers/staging/pohmelfs/inode.c 2011-03-14 21:20:32.000000000 -0400
27594+++ linux-2.6.38.1/drivers/staging/pohmelfs/inode.c 2011-03-21 18:31:35.000000000 -0400
27595@@ -1855,7 +1855,7 @@ static int pohmelfs_fill_super(struct su
ae4e228f
MT
27596 mutex_init(&psb->mcache_lock);
27597 psb->mcache_root = RB_ROOT;
27598 psb->mcache_timeout = msecs_to_jiffies(5000);
27599- atomic_long_set(&psb->mcache_gen, 0);
27600+ atomic_long_set_unchecked(&psb->mcache_gen, 0);
27601
27602 psb->trans_max_pages = 100;
27603
16454cff
MT
27604diff -urNp linux-2.6.38.1/drivers/staging/pohmelfs/mcache.c linux-2.6.38.1/drivers/staging/pohmelfs/mcache.c
27605--- linux-2.6.38.1/drivers/staging/pohmelfs/mcache.c 2011-03-14 21:20:32.000000000 -0400
27606+++ linux-2.6.38.1/drivers/staging/pohmelfs/mcache.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
27607@@ -121,7 +121,7 @@ struct pohmelfs_mcache *pohmelfs_mcache_
27608 m->data = data;
27609 m->start = start;
27610 m->size = size;
27611- m->gen = atomic_long_inc_return(&psb->mcache_gen);
27612+ m->gen = atomic_long_inc_return_unchecked(&psb->mcache_gen);
27613
27614 mutex_lock(&psb->mcache_lock);
27615 err = pohmelfs_mcache_insert(psb, m);
16454cff
MT
27616diff -urNp linux-2.6.38.1/drivers/staging/pohmelfs/netfs.h linux-2.6.38.1/drivers/staging/pohmelfs/netfs.h
27617--- linux-2.6.38.1/drivers/staging/pohmelfs/netfs.h 2011-03-14 21:20:32.000000000 -0400
27618+++ linux-2.6.38.1/drivers/staging/pohmelfs/netfs.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
27619@@ -571,7 +571,7 @@ struct pohmelfs_config;
27620 struct pohmelfs_sb {
27621 struct rb_root mcache_root;
27622 struct mutex mcache_lock;
27623- atomic_long_t mcache_gen;
27624+ atomic_long_unchecked_t mcache_gen;
27625 unsigned long mcache_timeout;
27626
27627 unsigned int idx;
16454cff
MT
27628diff -urNp linux-2.6.38.1/drivers/staging/rtl8192u/ieee80211/proc.c linux-2.6.38.1/drivers/staging/rtl8192u/ieee80211/proc.c
27629--- linux-2.6.38.1/drivers/staging/rtl8192u/ieee80211/proc.c 2011-03-14 21:20:32.000000000 -0400
27630+++ linux-2.6.38.1/drivers/staging/rtl8192u/ieee80211/proc.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
27631@@ -99,7 +99,7 @@ static int crypto_info_open(struct inode
27632 return seq_open(file, &crypto_seq_ops);
27633 }
27634
27635-static struct file_operations proc_crypto_ops = {
27636+static const struct file_operations proc_crypto_ops = {
27637 .open = crypto_info_open,
27638 .read = seq_read,
27639 .llseek = seq_lseek,
16454cff
MT
27640diff -urNp linux-2.6.38.1/drivers/staging/spectra/ffsport.c linux-2.6.38.1/drivers/staging/spectra/ffsport.c
27641--- linux-2.6.38.1/drivers/staging/spectra/ffsport.c 2011-03-14 21:20:32.000000000 -0400
27642+++ linux-2.6.38.1/drivers/staging/spectra/ffsport.c 2011-03-21 18:31:35.000000000 -0400
27643@@ -604,7 +604,7 @@ int GLOB_SBD_unlocked_ioctl(struct block
6892158b
MT
27644 return ret;
27645 }
ae4e228f 27646
6892158b
MT
27647-static struct block_device_operations GLOB_SBD_ops = {
27648+static const struct block_device_operations GLOB_SBD_ops = {
ae4e228f 27649 .owner = THIS_MODULE,
6892158b
MT
27650 .open = GLOB_SBD_open,
27651 .release = GLOB_SBD_release,
16454cff
MT
27652diff -urNp linux-2.6.38.1/drivers/staging/vme/devices/vme_user.c linux-2.6.38.1/drivers/staging/vme/devices/vme_user.c
27653--- linux-2.6.38.1/drivers/staging/vme/devices/vme_user.c 2011-03-14 21:20:32.000000000 -0400
27654+++ linux-2.6.38.1/drivers/staging/vme/devices/vme_user.c 2011-03-21 18:31:35.000000000 -0400
27655@@ -138,7 +138,7 @@ static long vme_user_unlocked_ioctl(stru
27656 static int __devinit vme_user_probe(struct device *, int, int);
27657 static int __devexit vme_user_remove(struct device *, int, int);
ae4e228f
MT
27658
27659-static struct file_operations vme_user_fops = {
27660+static const struct file_operations vme_user_fops = {
6892158b
MT
27661 .open = vme_user_open,
27662 .release = vme_user_release,
27663 .read = vme_user_read,
16454cff
MT
27664diff -urNp linux-2.6.38.1/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c linux-2.6.38.1/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
27665--- linux-2.6.38.1/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c 2011-03-14 21:20:32.000000000 -0400
27666+++ linux-2.6.38.1/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
27667@@ -426,7 +426,7 @@ int cyasblkdev_revalidate_disk(struct ge
27668
27669
27670 /*standard block device driver interface */
27671-static struct block_device_operations cyasblkdev_bdops = {
27672+static const struct block_device_operations cyasblkdev_bdops = {
27673 .open = cyasblkdev_blk_open,
27674 .release = cyasblkdev_blk_release,
27675 .ioctl = cyasblkdev_blk_ioctl,
16454cff
MT
27676diff -urNp linux-2.6.38.1/drivers/tty/hvc/hvc_console.h linux-2.6.38.1/drivers/tty/hvc/hvc_console.h
27677--- linux-2.6.38.1/drivers/tty/hvc/hvc_console.h 2011-03-14 21:20:32.000000000 -0400
27678+++ linux-2.6.38.1/drivers/tty/hvc/hvc_console.h 2011-03-21 18:31:35.000000000 -0400
27679@@ -82,6 +82,7 @@ extern int hvc_instantiate(uint32_t vter
27680 /* register a vterm for hvc tty operation (module_init or hotplug add) */
27681 extern struct hvc_struct * hvc_alloc(uint32_t vtermno, int data,
27682 const struct hv_ops *ops, int outbuf_size);
27683+
27684 /* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
27685 extern int hvc_remove(struct hvc_struct *hp);
27686
27687diff -urNp linux-2.6.38.1/drivers/tty/hvc/hvcs.c linux-2.6.38.1/drivers/tty/hvc/hvcs.c
27688--- linux-2.6.38.1/drivers/tty/hvc/hvcs.c 2011-03-14 21:20:32.000000000 -0400
27689+++ linux-2.6.38.1/drivers/tty/hvc/hvcs.c 2011-03-21 18:31:35.000000000 -0400
27690@@ -83,6 +83,7 @@
27691 #include <asm/hvcserver.h>
27692 #include <asm/uaccess.h>
27693 #include <asm/vio.h>
27694+#include <asm/local.h>
27695
27696 /*
27697 * 1.3.0 -> 1.3.1 In hvcs_open memset(..,0x00,..) instead of memset(..,0x3F,00).
27698@@ -270,7 +271,7 @@ struct hvcs_struct {
27699 unsigned int index;
27700
27701 struct tty_struct *tty;
27702- int open_count;
27703+ local_t open_count;
27704
27705 /*
27706 * Used to tell the driver kernel_thread what operations need to take
27707@@ -420,7 +421,7 @@ static ssize_t hvcs_vterm_state_store(st
27708
27709 spin_lock_irqsave(&hvcsd->lock, flags);
27710
27711- if (hvcsd->open_count > 0) {
27712+ if (local_read(&hvcsd->open_count) > 0) {
27713 spin_unlock_irqrestore(&hvcsd->lock, flags);
27714 printk(KERN_INFO "HVCS: vterm state unchanged. "
27715 "The hvcs device node is still in use.\n");
27716@@ -1136,7 +1137,7 @@ static int hvcs_open(struct tty_struct *
27717 if ((retval = hvcs_partner_connect(hvcsd)))
27718 goto error_release;
27719
27720- hvcsd->open_count = 1;
27721+ local_set(&hvcsd->open_count, 1);
27722 hvcsd->tty = tty;
27723 tty->driver_data = hvcsd;
27724
27725@@ -1170,7 +1171,7 @@ fast_open:
27726
27727 spin_lock_irqsave(&hvcsd->lock, flags);
27728 kref_get(&hvcsd->kref);
27729- hvcsd->open_count++;
27730+ local_inc(&hvcsd->open_count);
27731 hvcsd->todo_mask |= HVCS_SCHED_READ;
27732 spin_unlock_irqrestore(&hvcsd->lock, flags);
27733
27734@@ -1214,7 +1215,7 @@ static void hvcs_close(struct tty_struct
27735 hvcsd = tty->driver_data;
27736
27737 spin_lock_irqsave(&hvcsd->lock, flags);
27738- if (--hvcsd->open_count == 0) {
27739+ if (local_dec_and_test(&hvcsd->open_count)) {
27740
27741 vio_disable_interrupts(hvcsd->vdev);
27742
27743@@ -1240,10 +1241,10 @@ static void hvcs_close(struct tty_struct
27744 free_irq(irq, hvcsd);
27745 kref_put(&hvcsd->kref, destroy_hvcs_struct);
27746 return;
27747- } else if (hvcsd->open_count < 0) {
27748+ } else if (local_read(&hvcsd->open_count) < 0) {
27749 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
27750 " is missmanaged.\n",
27751- hvcsd->vdev->unit_address, hvcsd->open_count);
27752+ hvcsd->vdev->unit_address, local_read(&hvcsd->open_count));
27753 }
27754
27755 spin_unlock_irqrestore(&hvcsd->lock, flags);
27756@@ -1259,7 +1260,7 @@ static void hvcs_hangup(struct tty_struc
27757
27758 spin_lock_irqsave(&hvcsd->lock, flags);
27759 /* Preserve this so that we know how many kref refs to put */
27760- temp_open_count = hvcsd->open_count;
27761+ temp_open_count = local_read(&hvcsd->open_count);
27762
27763 /*
27764 * Don't kref put inside the spinlock because the destruction
27765@@ -1274,7 +1275,7 @@ static void hvcs_hangup(struct tty_struc
27766 hvcsd->tty->driver_data = NULL;
27767 hvcsd->tty = NULL;
27768
27769- hvcsd->open_count = 0;
27770+ local_set(&hvcsd->open_count, 0);
27771
27772 /* This will drop any buffered data on the floor which is OK in a hangup
27773 * scenario. */
27774@@ -1345,7 +1346,7 @@ static int hvcs_write(struct tty_struct
27775 * the middle of a write operation? This is a crummy place to do this
27776 * but we want to keep it all in the spinlock.
27777 */
27778- if (hvcsd->open_count <= 0) {
27779+ if (local_read(&hvcsd->open_count) <= 0) {
27780 spin_unlock_irqrestore(&hvcsd->lock, flags);
27781 return -ENODEV;
27782 }
27783@@ -1419,7 +1420,7 @@ static int hvcs_write_room(struct tty_st
27784 {
27785 struct hvcs_struct *hvcsd = tty->driver_data;
27786
27787- if (!hvcsd || hvcsd->open_count <= 0)
27788+ if (!hvcsd || local_read(&hvcsd->open_count) <= 0)
27789 return 0;
27790
27791 return HVCS_BUFF_LEN - hvcsd->chars_in_buffer;
27792diff -urNp linux-2.6.38.1/drivers/tty/hvc/hvc_xen.c linux-2.6.38.1/drivers/tty/hvc/hvc_xen.c
27793--- linux-2.6.38.1/drivers/tty/hvc/hvc_xen.c 2011-03-14 21:20:32.000000000 -0400
27794+++ linux-2.6.38.1/drivers/tty/hvc/hvc_xen.c 2011-03-21 18:31:35.000000000 -0400
27795@@ -123,7 +123,7 @@ static int domU_read_console(uint32_t vt
27796 return recv;
27797 }
27798
27799-static struct hv_ops domU_hvc_ops = {
27800+static const struct hv_ops domU_hvc_ops = {
27801 .get_chars = domU_read_console,
27802 .put_chars = domU_write_console,
27803 .notifier_add = notifier_add_irq,
27804@@ -149,7 +149,7 @@ static int dom0_write_console(uint32_t v
27805 return len;
27806 }
27807
27808-static struct hv_ops dom0_hvc_ops = {
27809+static const struct hv_ops dom0_hvc_ops = {
27810 .get_chars = dom0_read_console,
27811 .put_chars = dom0_write_console,
27812 .notifier_add = notifier_add_irq,
27813@@ -160,7 +160,7 @@ static struct hv_ops dom0_hvc_ops = {
27814 static int __init xen_hvc_init(void)
27815 {
27816 struct hvc_struct *hp;
27817- struct hv_ops *ops;
27818+ const struct hv_ops *ops;
27819
27820 if (!xen_pv_domain())
27821 return -ENODEV;
27822@@ -203,7 +203,7 @@ static void __exit xen_hvc_fini(void)
27823
27824 static int xen_cons_init(void)
27825 {
27826- struct hv_ops *ops;
27827+ const struct hv_ops *ops;
27828
27829 if (!xen_pv_domain())
27830 return 0;
27831diff -urNp linux-2.6.38.1/drivers/tty/n_gsm.c linux-2.6.38.1/drivers/tty/n_gsm.c
27832--- linux-2.6.38.1/drivers/tty/n_gsm.c 2011-03-14 21:20:32.000000000 -0400
27833+++ linux-2.6.38.1/drivers/tty/n_gsm.c 2011-03-21 18:31:35.000000000 -0400
27834@@ -1589,7 +1589,7 @@ static struct gsm_dlci *gsm_dlci_alloc(s
bc901d79
MT
27835 return NULL;
27836 spin_lock_init(&dlci->lock);
27837 dlci->fifo = &dlci->_fifo;
27838- if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) {
27839+ if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL)) {
27840 kfree(dlci);
27841 return NULL;
27842 }
16454cff
MT
27843diff -urNp linux-2.6.38.1/drivers/tty/n_tty.c linux-2.6.38.1/drivers/tty/n_tty.c
27844--- linux-2.6.38.1/drivers/tty/n_tty.c 2011-03-14 21:20:32.000000000 -0400
27845+++ linux-2.6.38.1/drivers/tty/n_tty.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
27846@@ -2116,6 +2116,7 @@ void n_tty_inherit_ops(struct tty_ldisc_
27847 {
27848 *ops = tty_ldisc_N_TTY;
27849 ops->owner = NULL;
27850- ops->refcount = ops->flags = 0;
27851+ atomic_set(&ops->refcount, 0);
27852+ ops->flags = 0;
27853 }
27854 EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
16454cff
MT
27855diff -urNp linux-2.6.38.1/drivers/tty/pty.c linux-2.6.38.1/drivers/tty/pty.c
27856--- linux-2.6.38.1/drivers/tty/pty.c 2011-03-14 21:20:32.000000000 -0400
27857+++ linux-2.6.38.1/drivers/tty/pty.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
27858@@ -700,7 +700,18 @@ out:
27859 return retval;
27860 }
27861
27862-static struct file_operations ptmx_fops;
27863+static const struct file_operations ptmx_fops = {
27864+ .llseek = no_llseek,
27865+ .read = tty_read,
27866+ .write = tty_write,
27867+ .poll = tty_poll,
27868+ .unlocked_ioctl = tty_ioctl,
27869+ .compat_ioctl = tty_compat_ioctl,
27870+ .open = ptmx_open,
27871+ .release = tty_release,
27872+ .fasync = tty_fasync,
27873+};
27874+
27875
27876 static void __init unix98_pty_init(void)
27877 {
27878@@ -753,10 +764,6 @@ static void __init unix98_pty_init(void)
27879
27880 register_sysctl_table(pty_root_table);
27881
27882- /* Now create the /dev/ptmx special device */
27883- tty_default_fops(&ptmx_fops);
27884- ptmx_fops.open = ptmx_open;
27885-
27886 cdev_init(&ptmx_cdev, &ptmx_fops);
27887 if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
27888 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
16454cff
MT
27889diff -urNp linux-2.6.38.1/drivers/tty/serial/8250_pci.c linux-2.6.38.1/drivers/tty/serial/8250_pci.c
27890--- linux-2.6.38.1/drivers/tty/serial/8250_pci.c 2011-03-14 21:20:32.000000000 -0400
27891+++ linux-2.6.38.1/drivers/tty/serial/8250_pci.c 2011-03-21 18:31:35.000000000 -0400
27892@@ -3818,7 +3818,7 @@ static struct pci_device_id serial_pci_t
27893 PCI_ANY_ID, PCI_ANY_ID,
27894 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
27895 0xffff00, pbn_default },
27896- { 0, }
27897+ { 0, 0, 0, 0, 0, 0, 0 }
27898 };
27899
27900 static struct pci_driver serial_pci_driver = {
27901diff -urNp linux-2.6.38.1/drivers/tty/serial/kgdboc.c linux-2.6.38.1/drivers/tty/serial/kgdboc.c
27902--- linux-2.6.38.1/drivers/tty/serial/kgdboc.c 2011-03-14 21:20:32.000000000 -0400
27903+++ linux-2.6.38.1/drivers/tty/serial/kgdboc.c 2011-03-21 18:31:35.000000000 -0400
27904@@ -22,7 +22,7 @@
27905
27906 #define MAX_CONFIG_LEN 40
27907
27908-static struct kgdb_io kgdboc_io_ops;
27909+static struct kgdb_io kgdboc_io_ops; /* cannot be const, see configure_kgdboc() */
27910
27911 /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
27912 static int configured = -1;
27913@@ -293,7 +293,7 @@ static void kgdboc_post_exp_handler(void
27914 kgdboc_restore_input();
27915 }
27916
27917-static struct kgdb_io kgdboc_io_ops = {
27918+static struct kgdb_io kgdboc_io_ops = { /* cannot be const, see configure_kgdboc() */
27919 .name = "kgdboc",
27920 .read_char = kgdboc_get_char,
27921 .write_char = kgdboc_put_char,
27922diff -urNp linux-2.6.38.1/drivers/tty/tty_io.c linux-2.6.38.1/drivers/tty/tty_io.c
27923--- linux-2.6.38.1/drivers/tty/tty_io.c 2011-03-14 21:20:32.000000000 -0400
27924+++ linux-2.6.38.1/drivers/tty/tty_io.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
27925@@ -140,21 +140,11 @@ EXPORT_SYMBOL(tty_mutex);
27926 /* Spinlock to protect the tty->tty_files list */
27927 DEFINE_SPINLOCK(tty_files_lock);
27928
27929-static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
27930-static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
27931 ssize_t redirected_tty_write(struct file *, const char __user *,
27932 size_t, loff_t *);
27933-static unsigned int tty_poll(struct file *, poll_table *);
27934 static int tty_open(struct inode *, struct file *);
27935 long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
27936-#ifdef CONFIG_COMPAT
27937-static long tty_compat_ioctl(struct file *file, unsigned int cmd,
27938- unsigned long arg);
27939-#else
27940-#define tty_compat_ioctl NULL
27941-#endif
27942 static int __tty_fasync(int fd, struct file *filp, int on);
27943-static int tty_fasync(int fd, struct file *filp, int on);
27944 static void release_tty(struct tty_struct *tty, int idx);
27945 static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
27946 static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
27947@@ -938,7 +928,7 @@ EXPORT_SYMBOL(start_tty);
27948 * read calls may be outstanding in parallel.
27949 */
27950
27951-static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
27952+ssize_t tty_read(struct file *file, char __user *buf, size_t count,
27953 loff_t *ppos)
27954 {
27955 int i;
27956@@ -964,6 +954,8 @@ static ssize_t tty_read(struct file *fil
27957 return i;
27958 }
27959
27960+EXPORT_SYMBOL(tty_read);
27961+
27962 void tty_write_unlock(struct tty_struct *tty)
27963 {
27964 mutex_unlock(&tty->atomic_write_lock);
27965@@ -1113,7 +1105,7 @@ void tty_write_message(struct tty_struct
27966 * write method will not be invoked in parallel for each device.
27967 */
27968
27969-static ssize_t tty_write(struct file *file, const char __user *buf,
27970+ssize_t tty_write(struct file *file, const char __user *buf,
27971 size_t count, loff_t *ppos)
27972 {
27973 struct inode *inode = file->f_path.dentry->d_inode;
27974@@ -1139,6 +1131,8 @@ static ssize_t tty_write(struct file *fi
27975 return ret;
27976 }
27977
27978+EXPORT_SYMBOL(tty_write);
27979+
27980 ssize_t redirected_tty_write(struct file *file, const char __user *buf,
27981 size_t count, loff_t *ppos)
27982 {
27983@@ -1778,6 +1772,8 @@ int tty_release(struct inode *inode, str
27984 return 0;
27985 }
27986
27987+EXPORT_SYMBOL(tty_release);
27988+
27989 /**
27990 * tty_open - open a tty device
27991 * @inode: inode of device file
27992@@ -1969,7 +1965,7 @@ got_driver:
27993 * may be re-entered freely by other callers.
27994 */
27995
27996-static unsigned int tty_poll(struct file *filp, poll_table *wait)
27997+unsigned int tty_poll(struct file *filp, poll_table *wait)
27998 {
27999 struct tty_struct *tty = file_tty(filp);
28000 struct tty_ldisc *ld;
28001@@ -1985,6 +1981,8 @@ static unsigned int tty_poll(struct file
28002 return ret;
28003 }
28004
28005+EXPORT_SYMBOL(tty_poll);
28006+
28007 static int __tty_fasync(int fd, struct file *filp, int on)
28008 {
28009 struct tty_struct *tty = file_tty(filp);
28010@@ -2026,7 +2024,7 @@ out:
28011 return retval;
28012 }
28013
28014-static int tty_fasync(int fd, struct file *filp, int on)
28015+int tty_fasync(int fd, struct file *filp, int on)
28016 {
28017 int retval;
28018 tty_lock();
28019@@ -2035,6 +2033,8 @@ static int tty_fasync(int fd, struct fil
28020 return retval;
28021 }
28022
28023+EXPORT_SYMBOL(tty_fasync);
28024+
28025 /**
28026 * tiocsti - fake input character
28027 * @tty: tty to fake input into
16454cff 28028@@ -2692,8 +2692,10 @@ long tty_ioctl(struct file *file, unsign
bc901d79
MT
28029 return retval;
28030 }
28031
28032+EXPORT_SYMBOL(tty_ioctl);
28033+
28034 #ifdef CONFIG_COMPAT
28035-static long tty_compat_ioctl(struct file *file, unsigned int cmd,
28036+long tty_compat_ioctl(struct file *file, unsigned int cmd,
28037 unsigned long arg)
28038 {
28039 struct inode *inode = file->f_dentry->d_inode;
16454cff 28040@@ -2717,6 +2719,9 @@ static long tty_compat_ioctl(struct file
bc901d79
MT
28041
28042 return retval;
28043 }
28044+
28045+EXPORT_SYMBOL(tty_compat_ioctl);
28046+
28047 #endif
28048
28049 /*
16454cff 28050@@ -3195,11 +3200,6 @@ struct tty_struct *get_current_tty(void)
bc901d79
MT
28051 }
28052 EXPORT_SYMBOL_GPL(get_current_tty);
28053
28054-void tty_default_fops(struct file_operations *fops)
28055-{
28056- *fops = tty_fops;
28057-}
28058-
28059 /*
28060 * Initialize the console device. This is called *early*, so
28061 * we can't necessarily depend on lots of kernel help here.
16454cff
MT
28062diff -urNp linux-2.6.38.1/drivers/tty/tty_ldisc.c linux-2.6.38.1/drivers/tty/tty_ldisc.c
28063--- linux-2.6.38.1/drivers/tty/tty_ldisc.c 2011-03-14 21:20:32.000000000 -0400
28064+++ linux-2.6.38.1/drivers/tty/tty_ldisc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
28065@@ -76,7 +76,7 @@ static void put_ldisc(struct tty_ldisc *
28066 if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) {
28067 struct tty_ldisc_ops *ldo = ld->ops;
28068
28069- ldo->refcount--;
28070+ atomic_dec(&ldo->refcount);
28071 module_put(ldo->owner);
28072 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
28073
28074@@ -111,7 +111,7 @@ int tty_register_ldisc(int disc, struct
28075 spin_lock_irqsave(&tty_ldisc_lock, flags);
28076 tty_ldiscs[disc] = new_ldisc;
28077 new_ldisc->num = disc;
28078- new_ldisc->refcount = 0;
28079+ atomic_set(&new_ldisc->refcount, 0);
28080 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
28081
28082 return ret;
28083@@ -139,7 +139,7 @@ int tty_unregister_ldisc(int disc)
28084 return -EINVAL;
28085
28086 spin_lock_irqsave(&tty_ldisc_lock, flags);
28087- if (tty_ldiscs[disc]->refcount)
28088+ if (atomic_read(&tty_ldiscs[disc]->refcount))
28089 ret = -EBUSY;
28090 else
28091 tty_ldiscs[disc] = NULL;
28092@@ -160,7 +160,7 @@ static struct tty_ldisc_ops *get_ldops(i
28093 if (ldops) {
28094 ret = ERR_PTR(-EAGAIN);
28095 if (try_module_get(ldops->owner)) {
28096- ldops->refcount++;
28097+ atomic_inc(&ldops->refcount);
28098 ret = ldops;
28099 }
28100 }
28101@@ -173,7 +173,7 @@ static void put_ldops(struct tty_ldisc_o
28102 unsigned long flags;
28103
28104 spin_lock_irqsave(&tty_ldisc_lock, flags);
28105- ldops->refcount--;
28106+ atomic_dec(&ldops->refcount);
28107 module_put(ldops->owner);
28108 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
28109 }
16454cff
MT
28110diff -urNp linux-2.6.38.1/drivers/tty/vt/keyboard.c linux-2.6.38.1/drivers/tty/vt/keyboard.c
28111--- linux-2.6.38.1/drivers/tty/vt/keyboard.c 2011-03-14 21:20:32.000000000 -0400
28112+++ linux-2.6.38.1/drivers/tty/vt/keyboard.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
28113@@ -657,6 +657,16 @@ static void k_spec(struct vc_data *vc, u
28114 kbd->kbdmode == VC_MEDIUMRAW) &&
28115 value != KVAL(K_SAK))
28116 return; /* SAK is allowed even in raw mode */
28117+
28118+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
28119+ {
28120+ void *func = fn_handler[value];
28121+ if (func == fn_show_state || func == fn_show_ptregs ||
28122+ func == fn_show_mem)
28123+ return;
28124+ }
28125+#endif
28126+
28127 fn_handler[value](vc);
28128 }
28129
28130@@ -1413,7 +1423,7 @@ static const struct input_device_id kbd_
28131 .evbit = { BIT_MASK(EV_SND) },
28132 },
28133
28134- { }, /* Terminating entry */
28135+ { 0 }, /* Terminating entry */
28136 };
28137
28138 MODULE_DEVICE_TABLE(input, kbd_ids);
16454cff
MT
28139diff -urNp linux-2.6.38.1/drivers/tty/vt/vt.c linux-2.6.38.1/drivers/tty/vt/vt.c
28140--- linux-2.6.38.1/drivers/tty/vt/vt.c 2011-03-14 21:20:32.000000000 -0400
28141+++ linux-2.6.38.1/drivers/tty/vt/vt.c 2011-03-21 18:31:35.000000000 -0400
28142@@ -262,7 +262,7 @@ EXPORT_SYMBOL_GPL(unregister_vt_notifier
28143
28144 static void notify_write(struct vc_data *vc, unsigned int unicode)
28145 {
28146- struct vt_notifier_param param = { .vc = vc, unicode = unicode };
28147+ struct vt_notifier_param param = { .vc = vc, .c = unicode };
28148 atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
28149 }
28150
28151diff -urNp linux-2.6.38.1/drivers/tty/vt/vt_ioctl.c linux-2.6.38.1/drivers/tty/vt/vt_ioctl.c
28152--- linux-2.6.38.1/drivers/tty/vt/vt_ioctl.c 2011-03-14 21:20:32.000000000 -0400
28153+++ linux-2.6.38.1/drivers/tty/vt/vt_ioctl.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
28154@@ -210,9 +210,6 @@ do_kdsk_ioctl(int cmd, struct kbentry __
28155 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
28156 return -EFAULT;
28157
28158- if (!capable(CAP_SYS_TTY_CONFIG))
28159- perm = 0;
28160-
28161 switch (cmd) {
28162 case KDGKBENT:
28163 key_map = key_maps[s];
28164@@ -224,6 +221,9 @@ do_kdsk_ioctl(int cmd, struct kbentry __
28165 val = (i ? K_HOLE : K_NOSUCHMAP);
28166 return put_user(val, &user_kbe->kb_value);
28167 case KDSKBENT:
28168+ if (!capable(CAP_SYS_TTY_CONFIG))
28169+ perm = 0;
28170+
28171 if (!perm)
28172 return -EPERM;
28173 if (!i && v == K_NOSUCHMAP) {
28174@@ -325,9 +325,6 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
28175 int i, j, k;
28176 int ret;
28177
28178- if (!capable(CAP_SYS_TTY_CONFIG))
28179- perm = 0;
28180-
28181 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
28182 if (!kbs) {
28183 ret = -ENOMEM;
28184@@ -361,6 +358,9 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
28185 kfree(kbs);
28186 return ((p && *p) ? -EOVERFLOW : 0);
28187 case KDSKBSENT:
28188+ if (!capable(CAP_SYS_TTY_CONFIG))
28189+ perm = 0;
28190+
28191 if (!perm) {
28192 ret = -EPERM;
28193 goto reterr;
16454cff
MT
28194diff -urNp linux-2.6.38.1/drivers/uio/uio.c linux-2.6.38.1/drivers/uio/uio.c
28195--- linux-2.6.38.1/drivers/uio/uio.c 2011-03-14 21:20:32.000000000 -0400
28196+++ linux-2.6.38.1/drivers/uio/uio.c 2011-03-21 18:31:35.000000000 -0400
c52201e0
MT
28197@@ -25,6 +25,7 @@
28198 #include <linux/kobject.h>
28199 #include <linux/cdev.h>
28200 #include <linux/uio_driver.h>
28201+#include <asm/local.h>
28202
28203 #define UIO_MAX_DEVICES (1U << MINORBITS)
28204
28205@@ -35,7 +36,7 @@ struct uio_device {
28206 atomic_t event;
28207 struct fasync_struct *async_queue;
28208 wait_queue_head_t wait;
28209- int vma_count;
28210+ local_t vma_count;
28211 struct uio_info *info;
28212 struct kobject *map_dir;
28213 struct kobject *portio_dir;
28214@@ -602,13 +603,13 @@ static int uio_find_mem_index(struct vm_
28215 static void uio_vma_open(struct vm_area_struct *vma)
28216 {
28217 struct uio_device *idev = vma->vm_private_data;
28218- idev->vma_count++;
28219+ local_inc(&idev->vma_count);
28220 }
28221
28222 static void uio_vma_close(struct vm_area_struct *vma)
28223 {
28224 struct uio_device *idev = vma->vm_private_data;
28225- idev->vma_count--;
28226+ local_dec(&idev->vma_count);
28227 }
28228
28229 static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
16454cff
MT
28230diff -urNp linux-2.6.38.1/drivers/usb/atm/cxacru.c linux-2.6.38.1/drivers/usb/atm/cxacru.c
28231--- linux-2.6.38.1/drivers/usb/atm/cxacru.c 2011-03-14 21:20:32.000000000 -0400
28232+++ linux-2.6.38.1/drivers/usb/atm/cxacru.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
28233@@ -473,7 +473,7 @@ static ssize_t cxacru_sysfs_store_adsl_c
28234 ret = sscanf(buf + pos, "%x=%x%n", &index, &value, &tmp);
28235 if (ret < 2)
28236 return -EINVAL;
28237- if (index < 0 || index > 0x7f)
28238+ if (index > 0x7f)
28239 return -EINVAL;
28240 pos += tmp;
28241
16454cff
MT
28242diff -urNp linux-2.6.38.1/drivers/usb/atm/usbatm.c linux-2.6.38.1/drivers/usb/atm/usbatm.c
28243--- linux-2.6.38.1/drivers/usb/atm/usbatm.c 2011-03-14 21:20:32.000000000 -0400
28244+++ linux-2.6.38.1/drivers/usb/atm/usbatm.c 2011-03-21 18:31:35.000000000 -0400
6892158b 28245@@ -332,7 +332,7 @@ static void usbatm_extract_one_cell(stru
58c5fc13
MT
28246 if (printk_ratelimit())
28247 atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n",
28248 __func__, vpi, vci);
28249- atomic_inc(&vcc->stats->rx_err);
28250+ atomic_inc_unchecked(&vcc->stats->rx_err);
28251 return;
28252 }
28253
6892158b 28254@@ -360,7 +360,7 @@ static void usbatm_extract_one_cell(stru
58c5fc13
MT
28255 if (length > ATM_MAX_AAL5_PDU) {
28256 atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n",
28257 __func__, length, vcc);
28258- atomic_inc(&vcc->stats->rx_err);
28259+ atomic_inc_unchecked(&vcc->stats->rx_err);
28260 goto out;
28261 }
28262
6892158b 28263@@ -369,14 +369,14 @@ static void usbatm_extract_one_cell(stru
58c5fc13
MT
28264 if (sarb->len < pdu_length) {
28265 atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n",
28266 __func__, pdu_length, sarb->len, vcc);
28267- atomic_inc(&vcc->stats->rx_err);
28268+ atomic_inc_unchecked(&vcc->stats->rx_err);
28269 goto out;
28270 }
28271
28272 if (crc32_be(~0, skb_tail_pointer(sarb) - pdu_length, pdu_length) != 0xc704dd7b) {
28273 atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n",
28274 __func__, vcc);
28275- atomic_inc(&vcc->stats->rx_err);
28276+ atomic_inc_unchecked(&vcc->stats->rx_err);
28277 goto out;
28278 }
28279
6892158b 28280@@ -386,7 +386,7 @@ static void usbatm_extract_one_cell(stru
58c5fc13
MT
28281 if (printk_ratelimit())
28282 atm_err(instance, "%s: no memory for skb (length: %u)!\n",
28283 __func__, length);
28284- atomic_inc(&vcc->stats->rx_drop);
28285+ atomic_inc_unchecked(&vcc->stats->rx_drop);
28286 goto out;
28287 }
28288
6892158b 28289@@ -411,7 +411,7 @@ static void usbatm_extract_one_cell(stru
58c5fc13
MT
28290
28291 vcc->push(vcc, skb);
28292
28293- atomic_inc(&vcc->stats->rx);
28294+ atomic_inc_unchecked(&vcc->stats->rx);
28295 out:
28296 skb_trim(sarb, 0);
28297 }
6892158b 28298@@ -614,7 +614,7 @@ static void usbatm_tx_process(unsigned l
58c5fc13
MT
28299 struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc;
28300
28301 usbatm_pop(vcc, skb);
28302- atomic_inc(&vcc->stats->tx);
28303+ atomic_inc_unchecked(&vcc->stats->tx);
28304
28305 skb = skb_dequeue(&instance->sndqueue);
28306 }
6892158b 28307@@ -773,11 +773,11 @@ static int usbatm_atm_proc_read(struct a
58c5fc13
MT
28308 if (!left--)
28309 return sprintf(page,
28310 "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
28311- atomic_read(&atm_dev->stats.aal5.tx),
28312- atomic_read(&atm_dev->stats.aal5.tx_err),
28313- atomic_read(&atm_dev->stats.aal5.rx),
28314- atomic_read(&atm_dev->stats.aal5.rx_err),
28315- atomic_read(&atm_dev->stats.aal5.rx_drop));
28316+ atomic_read_unchecked(&atm_dev->stats.aal5.tx),
28317+ atomic_read_unchecked(&atm_dev->stats.aal5.tx_err),
28318+ atomic_read_unchecked(&atm_dev->stats.aal5.rx),
28319+ atomic_read_unchecked(&atm_dev->stats.aal5.rx_err),
28320+ atomic_read_unchecked(&atm_dev->stats.aal5.rx_drop));
28321
28322 if (!left--) {
28323 if (instance->disconnected)
16454cff
MT
28324diff -urNp linux-2.6.38.1/drivers/usb/class/cdc-acm.c linux-2.6.38.1/drivers/usb/class/cdc-acm.c
28325--- linux-2.6.38.1/drivers/usb/class/cdc-acm.c 2011-03-14 21:20:32.000000000 -0400
28326+++ linux-2.6.38.1/drivers/usb/class/cdc-acm.c 2011-03-21 18:31:35.000000000 -0400
c52201e0 28327@@ -1635,7 +1635,7 @@ static const struct usb_device_id acm_id
ae4e228f 28328 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
58c5fc13
MT
28329 USB_CDC_ACM_PROTO_AT_CDMA) },
28330
58c5fc13
MT
28331- { }
28332+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
28333 };
28334
28335 MODULE_DEVICE_TABLE(usb, acm_ids);
16454cff
MT
28336diff -urNp linux-2.6.38.1/drivers/usb/class/usblp.c linux-2.6.38.1/drivers/usb/class/usblp.c
28337--- linux-2.6.38.1/drivers/usb/class/usblp.c 2011-03-14 21:20:32.000000000 -0400
28338+++ linux-2.6.38.1/drivers/usb/class/usblp.c 2011-03-21 18:31:35.000000000 -0400
6892158b 28339@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
58c5fc13
MT
28340 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
28341 { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
28342 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
28343- { 0, 0 }
28344+ { 0, 0, 0 }
28345 };
28346
28347 static int usblp_wwait(struct usblp *usblp, int nonblock);
bc901d79 28348@@ -1398,7 +1398,7 @@ static const struct usb_device_id usblp_
58c5fc13
MT
28349 { USB_INTERFACE_INFO(7, 1, 2) },
28350 { USB_INTERFACE_INFO(7, 1, 3) },
28351 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
28352- { } /* Terminating entry */
28353+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
28354 };
28355
6892158b 28356 MODULE_DEVICE_TABLE(usb, usblp_ids);
16454cff
MT
28357diff -urNp linux-2.6.38.1/drivers/usb/core/hcd.c linux-2.6.38.1/drivers/usb/core/hcd.c
28358--- linux-2.6.38.1/drivers/usb/core/hcd.c 2011-03-23 17:20:07.000000000 -0400
28359+++ linux-2.6.38.1/drivers/usb/core/hcd.c 2011-03-26 20:49:43.000000000 -0400
28360@@ -2457,7 +2457,7 @@ EXPORT_SYMBOL_GPL(usb_hcd_platform_shutd
ae4e228f
MT
28361
28362 #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
28363
28364-struct usb_mon_operations *mon_ops;
28365+const struct usb_mon_operations *mon_ops;
28366
28367 /*
28368 * The registration is unlocked.
16454cff 28369@@ -2467,7 +2467,7 @@ struct usb_mon_operations *mon_ops;
ae4e228f
MT
28370 * symbols from usbcore, usbcore gets referenced and cannot be unloaded first.
28371 */
28372
28373-int usb_mon_register (struct usb_mon_operations *ops)
28374+int usb_mon_register (const struct usb_mon_operations *ops)
28375 {
28376
28377 if (mon_ops)
16454cff
MT
28378diff -urNp linux-2.6.38.1/drivers/usb/core/hub.c linux-2.6.38.1/drivers/usb/core/hub.c
28379--- linux-2.6.38.1/drivers/usb/core/hub.c 2011-03-14 21:20:32.000000000 -0400
28380+++ linux-2.6.38.1/drivers/usb/core/hub.c 2011-03-21 18:31:35.000000000 -0400
28381@@ -3492,7 +3492,7 @@ static const struct usb_device_id hub_id
58c5fc13
MT
28382 .bDeviceClass = USB_CLASS_HUB},
28383 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
28384 .bInterfaceClass = USB_CLASS_HUB},
28385- { } /* Terminating entry */
28386+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
28387 };
28388
28389 MODULE_DEVICE_TABLE (usb, hub_id_table);
16454cff
MT
28390diff -urNp linux-2.6.38.1/drivers/usb/core/message.c linux-2.6.38.1/drivers/usb/core/message.c
28391--- linux-2.6.38.1/drivers/usb/core/message.c 2011-03-14 21:20:32.000000000 -0400
28392+++ linux-2.6.38.1/drivers/usb/core/message.c 2011-03-21 18:31:35.000000000 -0400
57199397 28393@@ -869,8 +869,8 @@ char *usb_cache_string(struct usb_device
ae4e228f 28394 buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
58c5fc13
MT
28395 if (buf) {
28396 len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
28397- if (len > 0) {
ae4e228f 28398- smallbuf = kmalloc(++len, GFP_NOIO);
58c5fc13 28399+ if (len++ > 0) {
ae4e228f 28400+ smallbuf = kmalloc(len, GFP_NOIO);
58c5fc13
MT
28401 if (!smallbuf)
28402 return buf;
28403 memcpy(smallbuf, buf, len);
16454cff
MT
28404diff -urNp linux-2.6.38.1/drivers/usb/early/ehci-dbgp.c linux-2.6.38.1/drivers/usb/early/ehci-dbgp.c
28405--- linux-2.6.38.1/drivers/usb/early/ehci-dbgp.c 2011-03-14 21:20:32.000000000 -0400
28406+++ linux-2.6.38.1/drivers/usb/early/ehci-dbgp.c 2011-03-21 18:31:35.000000000 -0400
28407@@ -96,7 +96,7 @@ static inline u32 dbgp_len_update(u32 x,
6892158b
MT
28408 }
28409
28410 #ifdef CONFIG_KGDB
16454cff
MT
28411-static struct kgdb_io kgdbdbgp_io_ops;
28412+static struct kgdb_io kgdbdbgp_io_ops; /* cannot be const, see kgdbdbgp_parse_config */
6892158b
MT
28413 #define dbgp_kgdb_mode (dbg_io_ops == &kgdbdbgp_io_ops)
28414 #else
16454cff
MT
28415 #define dbgp_kgdb_mode (0)
28416@@ -1026,7 +1026,7 @@ static void kgdbdbgp_write_char(u8 chr)
57199397
MT
28417 early_dbgp_write(NULL, &chr, 1);
28418 }
28419
16454cff
MT
28420-static struct kgdb_io kgdbdbgp_io_ops = {
28421+static struct kgdb_io kgdbdbgp_io_ops = { /* cannot be const, see kgdbdbgp_parse_config() */
57199397
MT
28422 .name = "kgdbdbgp",
28423 .read_char = kgdbdbgp_read_char,
16454cff
MT
28424 .write_char = kgdbdbgp_write_char,
28425diff -urNp linux-2.6.38.1/drivers/usb/host/ehci-pci.c linux-2.6.38.1/drivers/usb/host/ehci-pci.c
28426--- linux-2.6.38.1/drivers/usb/host/ehci-pci.c 2011-03-14 21:20:32.000000000 -0400
28427+++ linux-2.6.38.1/drivers/usb/host/ehci-pci.c 2011-03-21 18:31:35.000000000 -0400
28428@@ -516,7 +516,7 @@ static const struct pci_device_id pci_id
58c5fc13
MT
28429 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
28430 .driver_data = (unsigned long) &ehci_pci_hc_driver,
28431 },
28432- { /* end: all zeroes */ }
28433+ { 0, 0, 0, 0, 0, 0, 0 }
28434 };
28435 MODULE_DEVICE_TABLE(pci, pci_ids);
28436
16454cff
MT
28437diff -urNp linux-2.6.38.1/drivers/usb/host/uhci-hcd.c linux-2.6.38.1/drivers/usb/host/uhci-hcd.c
28438--- linux-2.6.38.1/drivers/usb/host/uhci-hcd.c 2011-03-14 21:20:32.000000000 -0400
28439+++ linux-2.6.38.1/drivers/usb/host/uhci-hcd.c 2011-03-21 18:31:35.000000000 -0400
6892158b 28440@@ -948,7 +948,7 @@ static const struct pci_device_id uhci_p
58c5fc13
MT
28441 /* handle any USB UHCI controller */
28442 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
28443 .driver_data = (unsigned long) &uhci_driver,
28444- }, { /* end: all zeroes */ }
28445+ }, { 0, 0, 0, 0, 0, 0, 0 }
28446 };
28447
28448 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
16454cff
MT
28449diff -urNp linux-2.6.38.1/drivers/usb/mon/mon_main.c linux-2.6.38.1/drivers/usb/mon/mon_main.c
28450--- linux-2.6.38.1/drivers/usb/mon/mon_main.c 2011-03-14 21:20:32.000000000 -0400
28451+++ linux-2.6.38.1/drivers/usb/mon/mon_main.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 28452@@ -238,7 +238,7 @@ static struct notifier_block mon_nb = {
ae4e228f
MT
28453 /*
28454 * Ops
28455 */
28456-static struct usb_mon_operations mon_ops_0 = {
28457+static const struct usb_mon_operations mon_ops_0 = {
28458 .urb_submit = mon_submit,
28459 .urb_submit_error = mon_submit_error,
28460 .urb_complete = mon_complete,
16454cff
MT
28461diff -urNp linux-2.6.38.1/drivers/usb/storage/debug.h linux-2.6.38.1/drivers/usb/storage/debug.h
28462--- linux-2.6.38.1/drivers/usb/storage/debug.h 2011-03-14 21:20:32.000000000 -0400
28463+++ linux-2.6.38.1/drivers/usb/storage/debug.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
28464@@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
28465 #define US_DEBUGPX(x...) printk( x )
28466 #define US_DEBUG(x) x
28467 #else
28468-#define US_DEBUGP(x...)
28469-#define US_DEBUGPX(x...)
28470-#define US_DEBUG(x)
28471+#define US_DEBUGP(x...) do {} while (0)
28472+#define US_DEBUGPX(x...) do {} while (0)
28473+#define US_DEBUG(x) do {} while (0)
28474 #endif
28475
28476 #endif
16454cff
MT
28477diff -urNp linux-2.6.38.1/drivers/usb/storage/usb.c linux-2.6.38.1/drivers/usb/storage/usb.c
28478--- linux-2.6.38.1/drivers/usb/storage/usb.c 2011-03-14 21:20:32.000000000 -0400
28479+++ linux-2.6.38.1/drivers/usb/storage/usb.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 28480@@ -122,7 +122,7 @@ MODULE_PARM_DESC(quirks, "supplemental l
58c5fc13
MT
28481
28482 static struct us_unusual_dev us_unusual_dev_list[] = {
28483 # include "unusual_devs.h"
28484- { } /* Terminating entry */
28485+ { NULL, NULL, 0, 0, NULL } /* Terminating entry */
28486 };
28487
28488 #undef UNUSUAL_DEV
16454cff
MT
28489diff -urNp linux-2.6.38.1/drivers/usb/storage/usual-tables.c linux-2.6.38.1/drivers/usb/storage/usual-tables.c
28490--- linux-2.6.38.1/drivers/usb/storage/usual-tables.c 2011-03-14 21:20:32.000000000 -0400
28491+++ linux-2.6.38.1/drivers/usb/storage/usual-tables.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
28492@@ -48,7 +48,7 @@
28493
28494 struct usb_device_id usb_storage_usb_ids[] = {
28495 # include "unusual_devs.h"
28496- { } /* Terminating entry */
28497+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
28498 };
28499 EXPORT_SYMBOL_GPL(usb_storage_usb_ids);
28500
16454cff
MT
28501diff -urNp linux-2.6.38.1/drivers/vhost/vhost.c linux-2.6.38.1/drivers/vhost/vhost.c
28502--- linux-2.6.38.1/drivers/vhost/vhost.c 2011-03-14 21:20:32.000000000 -0400
28503+++ linux-2.6.38.1/drivers/vhost/vhost.c 2011-03-21 18:31:35.000000000 -0400
28504@@ -565,7 +565,7 @@ static int init_used(struct vhost_virtqu
57199397
MT
28505 return get_user(vq->last_used_idx, &used->idx);
28506 }
28507
28508-static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
28509+static long vhost_set_vring(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
28510 {
28511 struct file *eventfp, *filep = NULL,
28512 *pollstart = NULL, *pollstop = NULL;
16454cff
MT
28513diff -urNp linux-2.6.38.1/drivers/video/fbcmap.c linux-2.6.38.1/drivers/video/fbcmap.c
28514--- linux-2.6.38.1/drivers/video/fbcmap.c 2011-03-14 21:20:32.000000000 -0400
28515+++ linux-2.6.38.1/drivers/video/fbcmap.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 28516@@ -285,8 +285,7 @@ int fb_set_user_cmap(struct fb_cmap_user
df50ba0c
MT
28517 rc = -ENODEV;
28518 goto out;
28519 }
28520- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
28521- !info->fbops->fb_setcmap)) {
28522+ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap) {
28523 rc = -EINVAL;
28524 goto out1;
28525 }
16454cff
MT
28526diff -urNp linux-2.6.38.1/drivers/video/fbmem.c linux-2.6.38.1/drivers/video/fbmem.c
28527--- linux-2.6.38.1/drivers/video/fbmem.c 2011-03-14 21:20:32.000000000 -0400
28528+++ linux-2.6.38.1/drivers/video/fbmem.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
28529@@ -403,7 +403,7 @@ static void fb_do_show_logo(struct fb_in
28530 image->dx += image->width + 8;
28531 }
28532 } else if (rotate == FB_ROTATE_UD) {
28533- for (x = 0; x < num && image->dx >= 0; x++) {
28534+ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
28535 info->fbops->fb_imageblit(info, image);
28536 image->dx -= image->width + 8;
28537 }
28538@@ -415,7 +415,7 @@ static void fb_do_show_logo(struct fb_in
28539 image->dy += image->height + 8;
28540 }
28541 } else if (rotate == FB_ROTATE_CCW) {
28542- for (x = 0; x < num && image->dy >= 0; x++) {
28543+ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
28544 info->fbops->fb_imageblit(info, image);
28545 image->dy -= image->height + 8;
28546 }
bc901d79 28547@@ -1101,7 +1101,7 @@ static long do_fb_ioctl(struct fb_info *
58c5fc13
MT
28548 return -EFAULT;
28549 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
28550 return -EINVAL;
28551- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
28552+ if (con2fb.framebuffer >= FB_MAX)
28553 return -EINVAL;
28554 if (!registered_fb[con2fb.framebuffer])
28555 request_module("fb%d", con2fb.framebuffer);
16454cff
MT
28556diff -urNp linux-2.6.38.1/drivers/video/fbmon.c linux-2.6.38.1/drivers/video/fbmon.c
28557--- linux-2.6.38.1/drivers/video/fbmon.c 2011-03-14 21:20:32.000000000 -0400
28558+++ linux-2.6.38.1/drivers/video/fbmon.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 28559@@ -46,7 +46,7 @@
58c5fc13
MT
28560 #ifdef DEBUG
28561 #define DPRINTK(fmt, args...) printk(fmt,## args)
28562 #else
28563-#define DPRINTK(fmt, args...)
28564+#define DPRINTK(fmt, args...) do {} while (0)
28565 #endif
28566
28567 #define FBMON_FIX_HEADER 1
16454cff
MT
28568diff -urNp linux-2.6.38.1/drivers/video/i810/i810_accel.c linux-2.6.38.1/drivers/video/i810/i810_accel.c
28569--- linux-2.6.38.1/drivers/video/i810/i810_accel.c 2011-03-14 21:20:32.000000000 -0400
28570+++ linux-2.6.38.1/drivers/video/i810/i810_accel.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
28571@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
28572 }
28573 }
28574 printk("ringbuffer lockup!!!\n");
28575+ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
28576 i810_report_error(mmio);
28577 par->dev_flags |= LOCKUP;
28578 info->pixmap.scan_align = 1;
16454cff
MT
28579diff -urNp linux-2.6.38.1/drivers/video/i810/i810_main.c linux-2.6.38.1/drivers/video/i810/i810_main.c
28580--- linux-2.6.38.1/drivers/video/i810/i810_main.c 2011-03-14 21:20:32.000000000 -0400
28581+++ linux-2.6.38.1/drivers/video/i810/i810_main.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
28582@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
28583 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
28584 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
28585 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
28586- { 0 },
28587+ { 0, 0, 0, 0, 0, 0, 0 },
28588 };
28589
28590 static struct pci_driver i810fb_driver = {
16454cff
MT
28591diff -urNp linux-2.6.38.1/drivers/video/modedb.c linux-2.6.38.1/drivers/video/modedb.c
28592--- linux-2.6.38.1/drivers/video/modedb.c 2011-03-14 21:20:32.000000000 -0400
28593+++ linux-2.6.38.1/drivers/video/modedb.c 2011-03-21 18:31:35.000000000 -0400
28594@@ -40,255 +40,255 @@ static const struct fb_videomode modedb[
28595
58c5fc13 28596 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
16454cff
MT
28597 { NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, 0,
28598- FB_VMODE_NONINTERLACED },
28599+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28600
58c5fc13 28601 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
16454cff
MT
28602 { NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, 0,
28603- FB_VMODE_NONINTERLACED },
28604+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28605
58c5fc13 28606 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
16454cff
MT
28607 { NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, 0,
28608- FB_VMODE_NONINTERLACED },
28609+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28610
58c5fc13 28611 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
16454cff
MT
28612 { NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, 0,
28613- FB_VMODE_INTERLACED },
28614+ FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN },
28615
58c5fc13 28616 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
16454cff
MT
28617 { NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
28618- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED },
28619+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28620
58c5fc13 28621 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
16454cff
MT
28622 { NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, 0,
28623- FB_VMODE_NONINTERLACED },
28624+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28625
58c5fc13 28626 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
16454cff
MT
28627 { NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0,
28628- FB_VMODE_NONINTERLACED },
28629+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28630
58c5fc13 28631 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
16454cff
MT
28632 { NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
28633 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28634- FB_VMODE_NONINTERLACED },
28635+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28636
58c5fc13 28637 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
16454cff
MT
28638 { NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, 0,
28639- FB_VMODE_NONINTERLACED },
28640+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28641
58c5fc13 28642 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
16454cff
MT
28643 { NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, 0,
28644- FB_VMODE_INTERLACED },
28645+ FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN },
58c5fc13 28646 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
16454cff
MT
28647 { NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
28648 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28649- FB_VMODE_NONINTERLACED },
28650+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28651
58c5fc13 28652 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
16454cff
MT
28653 { NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, 0,
28654- FB_VMODE_NONINTERLACED },
28655+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28656
58c5fc13 28657 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
16454cff
MT
28658 { NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, 0,
28659- FB_VMODE_NONINTERLACED },
28660+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28661
58c5fc13 28662 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
16454cff
MT
28663 { NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, 0,
28664- FB_VMODE_NONINTERLACED },
28665+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28666
58c5fc13 28667 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
16454cff
MT
28668 { NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, 0,
28669- FB_VMODE_NONINTERLACED },
28670+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28671
58c5fc13 28672 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
16454cff
MT
28673 { NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0,
28674- FB_VMODE_NONINTERLACED },
28675+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28676
58c5fc13 28677 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
16454cff
MT
28678 { NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, 0,
28679- FB_VMODE_INTERLACED },
28680+ FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN },
28681
58c5fc13 28682 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
16454cff
MT
28683 { NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, 0,
28684- FB_VMODE_NONINTERLACED },
28685+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28686
58c5fc13 28687 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
16454cff
MT
28688 { NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, 0,
28689- FB_VMODE_NONINTERLACED },
28690+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28691
58c5fc13 28692 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
16454cff
MT
28693 { NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, 0,
28694- FB_VMODE_NONINTERLACED },
28695+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28696
58c5fc13 28697 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
16454cff
MT
28698 { NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 0,
28699- FB_VMODE_NONINTERLACED },
28700+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28701
58c5fc13 28702 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
16454cff
MT
28703 { NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, 0,
28704- FB_VMODE_NONINTERLACED },
28705+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28706
58c5fc13 28707 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
16454cff
MT
28708 { NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
28709 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28710- FB_VMODE_NONINTERLACED },
28711+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28712
58c5fc13 28713 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
16454cff
MT
28714 { NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
28715 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28716- FB_VMODE_NONINTERLACED },
28717+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28718
58c5fc13 28719 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
16454cff
MT
28720 { NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, 0,
28721- FB_VMODE_NONINTERLACED },
28722+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28723
58c5fc13 28724 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
16454cff
MT
28725 { NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, 0,
28726- FB_VMODE_NONINTERLACED },
28727+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28728
58c5fc13 28729 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
16454cff
MT
28730 { NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, 0,
28731- FB_VMODE_NONINTERLACED },
28732+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28733
58c5fc13 28734 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
16454cff
MT
28735 { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
28736 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28737- FB_VMODE_NONINTERLACED },
28738+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28739
58c5fc13 28740 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
16454cff
MT
28741 { NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, 0,
28742- FB_VMODE_NONINTERLACED },
28743+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28744
58c5fc13 28745 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
16454cff
MT
28746 { NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, 0,
28747- FB_VMODE_NONINTERLACED },
28748+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28749
58c5fc13 28750 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
16454cff
MT
28751 { NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, 0,
28752- FB_VMODE_NONINTERLACED },
28753+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28754
58c5fc13 28755 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
16454cff
MT
28756 { NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, 0,
28757- FB_VMODE_NONINTERLACED },
28758+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28759
58c5fc13 28760 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
16454cff
MT
28761 { NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, 0,
28762- FB_VMODE_NONINTERLACED },
28763+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28764
58c5fc13 28765 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
16454cff
MT
28766 { NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, 0,
28767- FB_VMODE_NONINTERLACED },
28768+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28769
58c5fc13 28770 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
16454cff
MT
28771 { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
28772 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28773- FB_VMODE_NONINTERLACED },
28774+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28775
58c5fc13 28776 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
16454cff
MT
28777 { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
28778 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28779- FB_VMODE_NONINTERLACED },
28780+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28781
58c5fc13 28782 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
16454cff
MT
28783 { NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
28784 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28785- FB_VMODE_NONINTERLACED },
28786+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28787
58c5fc13 28788 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
16454cff
MT
28789 { NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
28790 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28791- FB_VMODE_NONINTERLACED },
28792+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28793
58c5fc13 28794 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
16454cff
MT
28795 { NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, 0,
28796- FB_VMODE_NONINTERLACED },
28797+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28798
58c5fc13 28799 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
16454cff
MT
28800 { NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
28801 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28802- FB_VMODE_NONINTERLACED },
28803+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28804
58c5fc13 28805 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
16454cff
MT
28806 { NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
28807 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28808- FB_VMODE_NONINTERLACED },
28809+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28810
58c5fc13 28811 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
16454cff
MT
28812 { NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, 0,
28813- FB_VMODE_NONINTERLACED },
28814+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28815
58c5fc13 28816 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
16454cff
MT
28817 { NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, 0,
28818- FB_VMODE_NONINTERLACED },
28819+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28820
58c5fc13 28821 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
16454cff
MT
28822 { NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, 0,
28823- FB_VMODE_DOUBLE },
28824+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28825
58c5fc13 28826 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
16454cff
MT
28827 { NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, 0,
28828- FB_VMODE_DOUBLE },
28829+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28830
58c5fc13 28831 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
16454cff
MT
28832 { NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, 0,
28833- FB_VMODE_DOUBLE },
28834+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28835
58c5fc13 28836 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
16454cff
MT
28837 { NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, 0,
28838- FB_VMODE_DOUBLE },
28839+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28840
58c5fc13 28841 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
16454cff
MT
28842 { NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, 0,
28843- FB_VMODE_DOUBLE },
28844+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28845
58c5fc13 28846 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
16454cff
MT
28847 { NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, 0,
28848- FB_VMODE_DOUBLE },
28849+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28850
58c5fc13 28851 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
16454cff
MT
28852 { NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, 0,
28853- FB_VMODE_DOUBLE },
28854+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28855
58c5fc13 28856 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
16454cff
MT
28857 { NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, 0,
28858- FB_VMODE_DOUBLE },
28859+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28860
58c5fc13 28861 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
16454cff
MT
28862 { NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, 0,
28863- FB_VMODE_DOUBLE },
28864+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28865
58c5fc13 28866 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
16454cff
MT
28867 { NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 0,
28868- FB_VMODE_DOUBLE },
28869+ FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN },
28870
58c5fc13 28871 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
16454cff
MT
28872 { NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
28873 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28874- FB_VMODE_NONINTERLACED },
28875+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28876
58c5fc13 28877 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
16454cff
MT
28878 { NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
28879 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28880- FB_VMODE_NONINTERLACED },
28881+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
ae4e228f 28882
16454cff
MT
28883 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
28884 { NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, 0,
28885- FB_VMODE_NONINTERLACED },
28886+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
ae4e228f 28887
16454cff
MT
28888 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
28889 { NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, 0,
28890- FB_VMODE_NONINTERLACED },
28891+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28892
28893 /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
28894 { NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5, 0,
28895- FB_VMODE_INTERLACED },
28896+ FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN },
28897
28898 /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
28899 { NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5, 0,
28900- FB_VMODE_INTERLACED },
28901+ FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN },
28902
28903 /* 864x480 @ 60 Hz, 35.15 kHz hsync */
28904 { NULL, 60, 864, 480, 27777, 1, 1, 1, 1, 0, 0,
28905- 0, FB_VMODE_NONINTERLACED },
28906+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN },
28907 };
28908
28909 #ifdef CONFIG_FB_MODE_HELPERS
28910diff -urNp linux-2.6.38.1/drivers/video/pxa3xx-gcu.c linux-2.6.38.1/drivers/video/pxa3xx-gcu.c
28911--- linux-2.6.38.1/drivers/video/pxa3xx-gcu.c 2011-03-14 21:20:32.000000000 -0400
28912+++ linux-2.6.38.1/drivers/video/pxa3xx-gcu.c 2011-03-21 18:31:35.000000000 -0400
28913@@ -103,7 +103,7 @@ struct pxa3xx_gcu_priv {
28914 dma_addr_t shared_phys;
28915 struct resource *resource_mem;
28916 struct miscdevice misc_dev;
28917- struct file_operations misc_fops;
28918+ const struct file_operations misc_fops;
28919 wait_queue_head_t wait_idle;
28920 wait_queue_head_t wait_free;
28921 spinlock_t spinlock;
28922diff -urNp linux-2.6.38.1/drivers/video/uvesafb.c linux-2.6.38.1/drivers/video/uvesafb.c
28923--- linux-2.6.38.1/drivers/video/uvesafb.c 2011-03-14 21:20:32.000000000 -0400
28924+++ linux-2.6.38.1/drivers/video/uvesafb.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 28925@@ -19,6 +19,7 @@
58c5fc13
MT
28926 #include <linux/io.h>
28927 #include <linux/mutex.h>
df50ba0c 28928 #include <linux/slab.h>
58c5fc13
MT
28929+#include <linux/moduleloader.h>
28930 #include <video/edid.h>
28931 #include <video/uvesafb.h>
28932 #ifdef CONFIG_X86
df50ba0c 28933@@ -121,7 +122,7 @@ static int uvesafb_helper_start(void)
58c5fc13
MT
28934 NULL,
28935 };
28936
28937- return call_usermodehelper(v86d_path, argv, envp, 1);
28938+ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
28939 }
28940
28941 /*
df50ba0c 28942@@ -569,10 +570,32 @@ static int __devinit uvesafb_vbe_getpmi(
58c5fc13
MT
28943 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
28944 par->pmi_setpal = par->ypan = 0;
28945 } else {
28946+
28947+#ifdef CONFIG_PAX_KERNEXEC
28948+#ifdef CONFIG_MODULES
58c5fc13
MT
28949+ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
28950+#endif
28951+ if (!par->pmi_code) {
28952+ par->pmi_setpal = par->ypan = 0;
28953+ return 0;
28954+ }
28955+#endif
28956+
28957 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
28958 + task->t.regs.edi);
28959+
28960+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
ae4e228f 28961+ pax_open_kernel();
58c5fc13 28962+ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
ae4e228f 28963+ pax_close_kernel();
58c5fc13
MT
28964+
28965+ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
28966+ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
28967+#else
28968 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
28969 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
28970+#endif
28971+
28972 printk(KERN_INFO "uvesafb: protected mode interface info at "
28973 "%04x:%04x\n",
28974 (u16)task->t.regs.es, (u16)task->t.regs.edi);
df50ba0c 28975@@ -1800,6 +1823,11 @@ out:
58c5fc13
MT
28976 if (par->vbe_modes)
28977 kfree(par->vbe_modes);
28978
28979+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
28980+ if (par->pmi_code)
28981+ module_free_exec(NULL, par->pmi_code);
28982+#endif
28983+
28984 framebuffer_release(info);
28985 return err;
28986 }
df50ba0c 28987@@ -1826,6 +1854,12 @@ static int uvesafb_remove(struct platfor
58c5fc13
MT
28988 kfree(par->vbe_state_orig);
28989 if (par->vbe_state_saved)
28990 kfree(par->vbe_state_saved);
28991+
28992+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
28993+ if (par->pmi_code)
28994+ module_free_exec(NULL, par->pmi_code);
28995+#endif
28996+
28997 }
28998
28999 framebuffer_release(info);
16454cff
MT
29000diff -urNp linux-2.6.38.1/drivers/video/vesafb.c linux-2.6.38.1/drivers/video/vesafb.c
29001--- linux-2.6.38.1/drivers/video/vesafb.c 2011-03-14 21:20:32.000000000 -0400
29002+++ linux-2.6.38.1/drivers/video/vesafb.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
29003@@ -9,6 +9,7 @@
29004 */
29005
29006 #include <linux/module.h>
29007+#include <linux/moduleloader.h>
29008 #include <linux/kernel.h>
29009 #include <linux/errno.h>
29010 #include <linux/string.h>
df50ba0c 29011@@ -52,8 +53,8 @@ static int vram_remap __initdata; /*
58c5fc13
MT
29012 static int vram_total __initdata; /* Set total amount of memory */
29013 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
29014 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
29015-static void (*pmi_start)(void) __read_mostly;
29016-static void (*pmi_pal) (void) __read_mostly;
29017+static void (*pmi_start)(void) __read_only;
29018+static void (*pmi_pal) (void) __read_only;
29019 static int depth __read_mostly;
29020 static int vga_compat __read_mostly;
29021 /* --------------------------------------------------------------------- */
df50ba0c 29022@@ -232,6 +233,7 @@ static int __init vesafb_probe(struct pl
58c5fc13
MT
29023 unsigned int size_vmode;
29024 unsigned int size_remap;
29025 unsigned int size_total;
29026+ void *pmi_code = NULL;
29027
29028 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
29029 return -ENODEV;
df50ba0c 29030@@ -274,10 +276,6 @@ static int __init vesafb_probe(struct pl
58c5fc13
MT
29031 size_remap = size_total;
29032 vesafb_fix.smem_len = size_remap;
29033
29034-#ifndef __i386__
29035- screen_info.vesapm_seg = 0;
29036-#endif
29037-
29038 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
29039 printk(KERN_WARNING
29040 "vesafb: cannot reserve video memory at 0x%lx\n",
57199397 29041@@ -319,9 +317,21 @@ static int __init vesafb_probe(struct pl
58c5fc13
MT
29042 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
29043 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
29044
29045+#ifdef __i386__
29046+
29047+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
29048+ pmi_code = module_alloc_exec(screen_info.vesapm_size);
29049+ if (!pmi_code)
29050+#elif !defined(CONFIG_PAX_KERNEXEC)
29051+ if (0)
29052+#endif
29053+
29054+#endif
29055+ screen_info.vesapm_seg = 0;
29056+
29057 if (screen_info.vesapm_seg) {
29058- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
29059- screen_info.vesapm_seg,screen_info.vesapm_off);
29060+ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
29061+ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
29062 }
29063
29064 if (screen_info.vesapm_seg < 0xc000)
57199397 29065@@ -329,9 +339,25 @@ static int __init vesafb_probe(struct pl
58c5fc13
MT
29066
29067 if (ypan || pmi_setpal) {
29068 unsigned short *pmi_base;
29069- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
29070- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
29071- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
29072+
58c5fc13
MT
29073+ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
29074+
29075+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
ae4e228f 29076+ pax_open_kernel();
58c5fc13
MT
29077+ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
29078+#else
29079+ pmi_code = pmi_base;
29080+#endif
29081+
29082+ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
29083+ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
29084+
29085+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
29086+ pmi_start = ktva_ktla(pmi_start);
29087+ pmi_pal = ktva_ktla(pmi_pal);
ae4e228f 29088+ pax_close_kernel();
58c5fc13
MT
29089+#endif
29090+
29091 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
29092 if (pmi_base[3]) {
29093 printk(KERN_INFO "vesafb: pmi: ports = ");
57199397 29094@@ -473,6 +499,11 @@ static int __init vesafb_probe(struct pl
58c5fc13
MT
29095 info->node, info->fix.id);
29096 return 0;
29097 err:
29098+
29099+#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
29100+ module_free_exec(NULL, pmi_code);
29101+#endif
29102+
29103 if (info->screen_base)
29104 iounmap(info->screen_base);
29105 framebuffer_release(info);
16454cff
MT
29106diff -urNp linux-2.6.38.1/fs/9p/vfs_inode.c linux-2.6.38.1/fs/9p/vfs_inode.c
29107--- linux-2.6.38.1/fs/9p/vfs_inode.c 2011-03-14 21:20:32.000000000 -0400
29108+++ linux-2.6.38.1/fs/9p/vfs_inode.c 2011-03-21 18:31:35.000000000 -0400
29109@@ -1094,7 +1094,7 @@ static void *v9fs_vfs_follow_link(struct
29110 void
58c5fc13
MT
29111 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
29112 {
29113- char *s = nd_get_link(nd);
29114+ const char *s = nd_get_link(nd);
29115
29116 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name,
29117 IS_ERR(s) ? "<error>" : s);
16454cff
MT
29118diff -urNp linux-2.6.38.1/fs/aio.c linux-2.6.38.1/fs/aio.c
29119--- linux-2.6.38.1/fs/aio.c 2011-03-14 21:20:32.000000000 -0400
29120+++ linux-2.6.38.1/fs/aio.c 2011-03-21 18:31:35.000000000 -0400
efbe55a5 29121@@ -130,7 +130,7 @@ static int aio_setup_ring(struct kioctx
58c5fc13
MT
29122 size += sizeof(struct io_event) * nr_events;
29123 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
29124
29125- if (nr_pages < 0)
29126+ if (nr_pages <= 0)
29127 return -EINVAL;
29128
29129 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
16454cff
MT
29130diff -urNp linux-2.6.38.1/fs/attr.c linux-2.6.38.1/fs/attr.c
29131--- linux-2.6.38.1/fs/attr.c 2011-03-14 21:20:32.000000000 -0400
29132+++ linux-2.6.38.1/fs/attr.c 2011-03-21 18:31:35.000000000 -0400
6892158b 29133@@ -98,6 +98,7 @@ int inode_newsize_ok(const struct inode
ae4e228f
MT
29134 unsigned long limit;
29135
df50ba0c 29136 limit = rlimit(RLIMIT_FSIZE);
ae4e228f
MT
29137+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long)offset, 1);
29138 if (limit != RLIM_INFINITY && offset > limit)
29139 goto out_sig;
29140 if (offset > inode->i_sb->s_maxbytes)
16454cff
MT
29141diff -urNp linux-2.6.38.1/fs/befs/linuxvfs.c linux-2.6.38.1/fs/befs/linuxvfs.c
29142--- linux-2.6.38.1/fs/befs/linuxvfs.c 2011-03-14 21:20:32.000000000 -0400
29143+++ linux-2.6.38.1/fs/befs/linuxvfs.c 2011-03-21 18:31:35.000000000 -0400
29144@@ -499,7 +499,7 @@ static void befs_put_link(struct dentry
58c5fc13
MT
29145 {
29146 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
29147 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
29148- char *link = nd_get_link(nd);
29149+ const char *link = nd_get_link(nd);
29150 if (!IS_ERR(link))
29151 kfree(link);
29152 }
16454cff
MT
29153diff -urNp linux-2.6.38.1/fs/binfmt_aout.c linux-2.6.38.1/fs/binfmt_aout.c
29154--- linux-2.6.38.1/fs/binfmt_aout.c 2011-03-14 21:20:32.000000000 -0400
29155+++ linux-2.6.38.1/fs/binfmt_aout.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
29156@@ -16,6 +16,7 @@
29157 #include <linux/string.h>
29158 #include <linux/fs.h>
29159 #include <linux/file.h>
29160+#include <linux/security.h>
29161 #include <linux/stat.h>
29162 #include <linux/fcntl.h>
29163 #include <linux/ptrace.h>
6892158b
MT
29164@@ -86,6 +87,8 @@ static int aout_core_dump(struct coredum
29165 #endif
29166 # define START_STACK(u) ((void __user *)u.start_stack)
29167
29168+ memset(&dump, 0, sizeof(dump));
29169+
29170 fs = get_fs();
29171 set_fs(KERNEL_DS);
29172 has_dumped = 1;
29173@@ -97,10 +100,12 @@ static int aout_core_dump(struct coredum
58c5fc13
MT
29174
29175 /* If the size of the dump file exceeds the rlimit, then see what would happen
29176 if we wrote the stack, but not the data area. */
29177+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
ae4e228f 29178 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > cprm->limit)
58c5fc13
MT
29179 dump.u_dsize = 0;
29180
29181 /* Make sure we have enough room to write the stack and data areas. */
29182+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
ae4e228f 29183 if ((dump.u_ssize + 1) * PAGE_SIZE > cprm->limit)
58c5fc13
MT
29184 dump.u_ssize = 0;
29185
6892158b 29186@@ -234,6 +239,8 @@ static int load_aout_binary(struct linux
df50ba0c 29187 rlim = rlimit(RLIMIT_DATA);
58c5fc13
MT
29188 if (rlim >= RLIM_INFINITY)
29189 rlim = ~0;
29190+
29191+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
29192 if (ex.a_data + ex.a_bss > rlim)
29193 return -ENOMEM;
29194
6892158b 29195@@ -262,6 +269,27 @@ static int load_aout_binary(struct linux
58c5fc13
MT
29196 install_exec_creds(bprm);
29197 current->flags &= ~PF_FORKNOEXEC;
29198
29199+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29200+ current->mm->pax_flags = 0UL;
29201+#endif
29202+
29203+#ifdef CONFIG_PAX_PAGEEXEC
29204+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
29205+ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
29206+
29207+#ifdef CONFIG_PAX_EMUTRAMP
29208+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
29209+ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
29210+#endif
29211+
29212+#ifdef CONFIG_PAX_MPROTECT
29213+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
29214+ current->mm->pax_flags |= MF_PAX_MPROTECT;
29215+#endif
29216+
29217+ }
29218+#endif
29219+
29220 if (N_MAGIC(ex) == OMAGIC) {
29221 unsigned long text_addr, map_size;
29222 loff_t pos;
6892158b 29223@@ -334,7 +362,7 @@ static int load_aout_binary(struct linux
58c5fc13
MT
29224
29225 down_write(&current->mm->mmap_sem);
29226 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
29227- PROT_READ | PROT_WRITE | PROT_EXEC,
29228+ PROT_READ | PROT_WRITE,
29229 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
29230 fd_offset + ex.a_text);
29231 up_write(&current->mm->mmap_sem);
16454cff
MT
29232diff -urNp linux-2.6.38.1/fs/binfmt_elf.c linux-2.6.38.1/fs/binfmt_elf.c
29233--- linux-2.6.38.1/fs/binfmt_elf.c 2011-03-14 21:20:32.000000000 -0400
29234+++ linux-2.6.38.1/fs/binfmt_elf.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 29235@@ -51,6 +51,10 @@ static int elf_core_dump(struct coredump
58c5fc13
MT
29236 #define elf_core_dump NULL
29237 #endif
29238
29239+#ifdef CONFIG_PAX_MPROTECT
29240+static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags);
29241+#endif
29242+
29243 #if ELF_EXEC_PAGESIZE > PAGE_SIZE
29244 #define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
29245 #else
df50ba0c 29246@@ -70,6 +74,11 @@ static struct linux_binfmt elf_format =
16454cff
MT
29247 .load_binary = load_elf_binary,
29248 .load_shlib = load_elf_library,
29249 .core_dump = elf_core_dump,
58c5fc13
MT
29250+
29251+#ifdef CONFIG_PAX_MPROTECT
29252+ .handle_mprotect= elf_handle_mprotect,
29253+#endif
29254+
16454cff 29255 .min_coredump = ELF_EXEC_PAGESIZE,
58c5fc13 29256 };
16454cff
MT
29257
29258@@ -77,6 +86,8 @@ static struct linux_binfmt elf_format =
58c5fc13
MT
29259
29260 static int set_brk(unsigned long start, unsigned long end)
29261 {
29262+ unsigned long e = end;
29263+
29264 start = ELF_PAGEALIGN(start);
29265 end = ELF_PAGEALIGN(end);
29266 if (end > start) {
16454cff 29267@@ -87,7 +98,7 @@ static int set_brk(unsigned long start,
58c5fc13
MT
29268 if (BAD_ADDR(addr))
29269 return addr;
29270 }
29271- current->mm->start_brk = current->mm->brk = end;
29272+ current->mm->start_brk = current->mm->brk = e;
29273 return 0;
29274 }
29275
16454cff 29276@@ -148,7 +159,7 @@ create_elf_tables(struct linux_binprm *b
58c5fc13
MT
29277 elf_addr_t __user *u_rand_bytes;
29278 const char *k_platform = ELF_PLATFORM;
29279 const char *k_base_platform = ELF_BASE_PLATFORM;
29280- unsigned char k_rand_bytes[16];
29281+ u32 k_rand_bytes[4];
29282 int items;
29283 elf_addr_t *elf_info;
29284 int ei_index = 0;
16454cff 29285@@ -195,8 +206,12 @@ create_elf_tables(struct linux_binprm *b
58c5fc13
MT
29286 * Generate 16 random bytes for userspace PRNG seeding.
29287 */
29288 get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));
df50ba0c
MT
29289- u_rand_bytes = (elf_addr_t __user *)
29290- STACK_ALLOC(p, sizeof(k_rand_bytes));
58c5fc13
MT
29291+ srandom32(k_rand_bytes[0] ^ random32());
29292+ srandom32(k_rand_bytes[1] ^ random32());
29293+ srandom32(k_rand_bytes[2] ^ random32());
29294+ srandom32(k_rand_bytes[3] ^ random32());
df50ba0c
MT
29295+ p = STACK_ROUND(p, sizeof(k_rand_bytes));
29296+ u_rand_bytes = (elf_addr_t __user *) p;
58c5fc13 29297 if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
df50ba0c
MT
29298 return -EFAULT;
29299
16454cff 29300@@ -381,10 +396,10 @@ static unsigned long load_elf_interp(str
58c5fc13
MT
29301 {
29302 struct elf_phdr *elf_phdata;
29303 struct elf_phdr *eppnt;
29304- unsigned long load_addr = 0;
29305+ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
29306 int load_addr_set = 0;
29307 unsigned long last_bss = 0, elf_bss = 0;
29308- unsigned long error = ~0UL;
29309+ unsigned long error = -EINVAL;
29310 unsigned long total_size;
29311 int retval, i, size;
29312
16454cff 29313@@ -430,6 +445,11 @@ static unsigned long load_elf_interp(str
58c5fc13
MT
29314 goto out_close;
29315 }
29316
29317+#ifdef CONFIG_PAX_SEGMEXEC
29318+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
29319+ pax_task_size = SEGMEXEC_TASK_SIZE;
29320+#endif
29321+
29322 eppnt = elf_phdata;
29323 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
29324 if (eppnt->p_type == PT_LOAD) {
16454cff 29325@@ -473,8 +493,8 @@ static unsigned long load_elf_interp(str
58c5fc13
MT
29326 k = load_addr + eppnt->p_vaddr;
29327 if (BAD_ADDR(k) ||
29328 eppnt->p_filesz > eppnt->p_memsz ||
29329- eppnt->p_memsz > TASK_SIZE ||
29330- TASK_SIZE - eppnt->p_memsz < k) {
29331+ eppnt->p_memsz > pax_task_size ||
29332+ pax_task_size - eppnt->p_memsz < k) {
29333 error = -ENOMEM;
29334 goto out_close;
29335 }
16454cff 29336@@ -528,6 +548,177 @@ out:
58c5fc13
MT
29337 return error;
29338 }
29339
29340+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
29341+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
29342+{
29343+ unsigned long pax_flags = 0UL;
29344+
29345+#ifdef CONFIG_PAX_PAGEEXEC
29346+ if (elf_phdata->p_flags & PF_PAGEEXEC)
29347+ pax_flags |= MF_PAX_PAGEEXEC;
29348+#endif
29349+
29350+#ifdef CONFIG_PAX_SEGMEXEC
29351+ if (elf_phdata->p_flags & PF_SEGMEXEC)
29352+ pax_flags |= MF_PAX_SEGMEXEC;
29353+#endif
29354+
29355+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
29356+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
ae4e228f 29357+ if ((__supported_pte_mask & _PAGE_NX))
58c5fc13
MT
29358+ pax_flags &= ~MF_PAX_SEGMEXEC;
29359+ else
29360+ pax_flags &= ~MF_PAX_PAGEEXEC;
29361+ }
29362+#endif
29363+
29364+#ifdef CONFIG_PAX_EMUTRAMP
29365+ if (elf_phdata->p_flags & PF_EMUTRAMP)
29366+ pax_flags |= MF_PAX_EMUTRAMP;
29367+#endif
29368+
29369+#ifdef CONFIG_PAX_MPROTECT
29370+ if (elf_phdata->p_flags & PF_MPROTECT)
29371+ pax_flags |= MF_PAX_MPROTECT;
29372+#endif
29373+
29374+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
29375+ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
29376+ pax_flags |= MF_PAX_RANDMMAP;
29377+#endif
29378+
29379+ return pax_flags;
29380+}
29381+#endif
29382+
29383+#ifdef CONFIG_PAX_PT_PAX_FLAGS
29384+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
29385+{
29386+ unsigned long pax_flags = 0UL;
29387+
29388+#ifdef CONFIG_PAX_PAGEEXEC
29389+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
29390+ pax_flags |= MF_PAX_PAGEEXEC;
29391+#endif
29392+
29393+#ifdef CONFIG_PAX_SEGMEXEC
29394+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
29395+ pax_flags |= MF_PAX_SEGMEXEC;
29396+#endif
29397+
29398+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
29399+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
ae4e228f 29400+ if ((__supported_pte_mask & _PAGE_NX))
58c5fc13
MT
29401+ pax_flags &= ~MF_PAX_SEGMEXEC;
29402+ else
29403+ pax_flags &= ~MF_PAX_PAGEEXEC;
29404+ }
29405+#endif
29406+
29407+#ifdef CONFIG_PAX_EMUTRAMP
29408+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
29409+ pax_flags |= MF_PAX_EMUTRAMP;
29410+#endif
29411+
29412+#ifdef CONFIG_PAX_MPROTECT
29413+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
29414+ pax_flags |= MF_PAX_MPROTECT;
29415+#endif
29416+
29417+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
29418+ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
29419+ pax_flags |= MF_PAX_RANDMMAP;
29420+#endif
29421+
29422+ return pax_flags;
29423+}
29424+#endif
29425+
29426+#ifdef CONFIG_PAX_EI_PAX
29427+static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
29428+{
29429+ unsigned long pax_flags = 0UL;
29430+
29431+#ifdef CONFIG_PAX_PAGEEXEC
29432+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
29433+ pax_flags |= MF_PAX_PAGEEXEC;
29434+#endif
29435+
29436+#ifdef CONFIG_PAX_SEGMEXEC
29437+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
29438+ pax_flags |= MF_PAX_SEGMEXEC;
29439+#endif
29440+
29441+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
29442+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
ae4e228f 29443+ if ((__supported_pte_mask & _PAGE_NX))
58c5fc13
MT
29444+ pax_flags &= ~MF_PAX_SEGMEXEC;
29445+ else
29446+ pax_flags &= ~MF_PAX_PAGEEXEC;
29447+ }
29448+#endif
29449+
29450+#ifdef CONFIG_PAX_EMUTRAMP
29451+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
29452+ pax_flags |= MF_PAX_EMUTRAMP;
29453+#endif
29454+
29455+#ifdef CONFIG_PAX_MPROTECT
29456+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
29457+ pax_flags |= MF_PAX_MPROTECT;
29458+#endif
29459+
29460+#ifdef CONFIG_PAX_ASLR
29461+ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
29462+ pax_flags |= MF_PAX_RANDMMAP;
29463+#endif
29464+
29465+ return pax_flags;
29466+}
29467+#endif
29468+
29469+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
29470+static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
29471+{
29472+ unsigned long pax_flags = 0UL;
29473+
29474+#ifdef CONFIG_PAX_PT_PAX_FLAGS
29475+ unsigned long i;
29476+#endif
29477+
29478+#ifdef CONFIG_PAX_EI_PAX
29479+ pax_flags = pax_parse_ei_pax(elf_ex);
29480+#endif
29481+
29482+#ifdef CONFIG_PAX_PT_PAX_FLAGS
29483+ for (i = 0UL; i < elf_ex->e_phnum; i++)
29484+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
29485+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
29486+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
29487+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
29488+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
29489+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
29490+ return -EINVAL;
29491+
29492+#ifdef CONFIG_PAX_SOFTMODE
29493+ if (pax_softmode)
29494+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
29495+ else
29496+#endif
29497+
29498+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
29499+ break;
29500+ }
29501+#endif
29502+
29503+ if (0 > pax_check_flags(&pax_flags))
29504+ return -EINVAL;
29505+
29506+ current->mm->pax_flags = pax_flags;
29507+ return 0;
29508+}
29509+#endif
29510+
29511 /*
29512 * These are the functions used to load ELF style executables and shared
29513 * libraries. There is no binary dependent code anywhere else.
16454cff 29514@@ -544,6 +735,11 @@ static unsigned long randomize_stack_top
58c5fc13
MT
29515 {
29516 unsigned int random_variable = 0;
29517
29518+#ifdef CONFIG_PAX_RANDUSTACK
29519+ if (randomize_va_space)
29520+ return stack_top - current->mm->delta_stack;
29521+#endif
29522+
29523 if ((current->flags & PF_RANDOMIZE) &&
29524 !(current->personality & ADDR_NO_RANDOMIZE)) {
29525 random_variable = get_random_int() & STACK_RND_MASK;
16454cff 29526@@ -562,7 +758,7 @@ static int load_elf_binary(struct linux_
58c5fc13
MT
29527 unsigned long load_addr = 0, load_bias = 0;
29528 int load_addr_set = 0;
29529 char * elf_interpreter = NULL;
29530- unsigned long error;
29531+ unsigned long error = 0;
29532 struct elf_phdr *elf_ppnt, *elf_phdata;
29533 unsigned long elf_bss, elf_brk;
29534 int retval, i;
16454cff 29535@@ -572,11 +768,11 @@ static int load_elf_binary(struct linux_
58c5fc13
MT
29536 unsigned long start_code, end_code, start_data, end_data;
29537 unsigned long reloc_func_desc = 0;
29538 int executable_stack = EXSTACK_DEFAULT;
29539- unsigned long def_flags = 0;
29540 struct {
29541 struct elfhdr elf_ex;
29542 struct elfhdr interp_elf_ex;
29543 } *loc;
29544+ unsigned long pax_task_size = TASK_SIZE;
29545
29546 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
29547 if (!loc) {
16454cff 29548@@ -714,11 +910,80 @@ static int load_elf_binary(struct linux_
58c5fc13
MT
29549
29550 /* OK, This is the point of no return */
29551 current->flags &= ~PF_FORKNOEXEC;
29552- current->mm->def_flags = def_flags;
29553+
29554+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29555+ current->mm->pax_flags = 0UL;
29556+#endif
29557+
29558+#ifdef CONFIG_PAX_DLRESOLVE
29559+ current->mm->call_dl_resolve = 0UL;
29560+#endif
29561+
29562+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
29563+ current->mm->call_syscall = 0UL;
29564+#endif
29565+
29566+#ifdef CONFIG_PAX_ASLR
29567+ current->mm->delta_mmap = 0UL;
29568+ current->mm->delta_stack = 0UL;
29569+#endif
29570+
29571+ current->mm->def_flags = 0;
29572+
29573+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
29574+ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
29575+ send_sig(SIGKILL, current, 0);
29576+ goto out_free_dentry;
29577+ }
29578+#endif
29579+
29580+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
29581+ pax_set_initial_flags(bprm);
29582+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
29583+ if (pax_set_initial_flags_func)
29584+ (pax_set_initial_flags_func)(bprm);
29585+#endif
29586+
29587+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
ae4e228f 29588+ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !(__supported_pte_mask & _PAGE_NX)) {
58c5fc13
MT
29589+ current->mm->context.user_cs_limit = PAGE_SIZE;
29590+ current->mm->def_flags |= VM_PAGEEXEC;
29591+ }
29592+#endif
29593+
29594+#ifdef CONFIG_PAX_SEGMEXEC
29595+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
29596+ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
29597+ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
29598+ pax_task_size = SEGMEXEC_TASK_SIZE;
29599+ }
29600+#endif
29601+
29602+#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
29603+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29604+ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
29605+ put_cpu();
29606+ }
29607+#endif
ae4e228f
MT
29608
29609 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
29610 may depend on the personality. */
29611 SET_PERSONALITY(loc->elf_ex);
58c5fc13
MT
29612+
29613+#ifdef CONFIG_PAX_ASLR
29614+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
29615+ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
29616+ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
29617+ }
29618+#endif
58c5fc13
MT
29619+
29620+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
29621+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29622+ executable_stack = EXSTACK_DISABLE_X;
29623+ current->personality &= ~READ_IMPLIES_EXEC;
29624+ } else
29625+#endif
29626+
29627 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
29628 current->personality |= READ_IMPLIES_EXEC;
29629
16454cff 29630@@ -800,6 +1065,20 @@ static int load_elf_binary(struct linux_
58c5fc13
MT
29631 #else
29632 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
29633 #endif
29634+
29635+#ifdef CONFIG_PAX_RANDMMAP
29636+ /* PaX: randomize base address at the default exe base if requested */
29637+ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
29638+#ifdef CONFIG_SPARC64
29639+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
29640+#else
29641+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
29642+#endif
29643+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
29644+ elf_flags |= MAP_FIXED;
29645+ }
29646+#endif
29647+
29648 }
29649
29650 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
16454cff 29651@@ -832,9 +1111,9 @@ static int load_elf_binary(struct linux_
58c5fc13
MT
29652 * allowed task size. Note that p_filesz must always be
29653 * <= p_memsz so it is only necessary to check p_memsz.
29654 */
29655- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
29656- elf_ppnt->p_memsz > TASK_SIZE ||
29657- TASK_SIZE - elf_ppnt->p_memsz < k) {
29658+ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
29659+ elf_ppnt->p_memsz > pax_task_size ||
29660+ pax_task_size - elf_ppnt->p_memsz < k) {
29661 /* set_brk can never work. Avoid overflows. */
29662 send_sig(SIGKILL, current, 0);
29663 retval = -EINVAL;
16454cff 29664@@ -862,6 +1141,11 @@ static int load_elf_binary(struct linux_
58c5fc13
MT
29665 start_data += load_bias;
29666 end_data += load_bias;
29667
29668+#ifdef CONFIG_PAX_RANDMMAP
29669+ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
29670+ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
29671+#endif
29672+
29673 /* Calling set_brk effectively mmaps the pages that we need
29674 * for the bss and break sections. We must do this before
29675 * mapping in the interpreter, to make sure it doesn't wind
16454cff 29676@@ -873,9 +1157,11 @@ static int load_elf_binary(struct linux_
58c5fc13
MT
29677 goto out_free_dentry;
29678 }
29679 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
29680- send_sig(SIGSEGV, current, 0);
29681- retval = -EFAULT; /* Nobody gets to see this, but.. */
29682- goto out_free_dentry;
29683+ /*
29684+ * This bss-zeroing can fail if the ELF
29685+ * file specifies odd protections. So
29686+ * we don't check the return value
29687+ */
29688 }
29689
29690 if (elf_interpreter) {
16454cff 29691@@ -1086,7 +1372,7 @@ out:
58c5fc13
MT
29692 * Decide what to dump of a segment, part, all or none.
29693 */
29694 static unsigned long vma_dump_size(struct vm_area_struct *vma,
29695- unsigned long mm_flags)
29696+ unsigned long mm_flags, long signr)
29697 {
29698 #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
29699
16454cff 29700@@ -1120,7 +1406,7 @@ static unsigned long vma_dump_size(struc
58c5fc13
MT
29701 if (vma->vm_file == NULL)
29702 return 0;
29703
29704- if (FILTER(MAPPED_PRIVATE))
29705+ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
29706 goto whole;
29707
29708 /*
16454cff 29709@@ -1342,9 +1628,9 @@ static void fill_auxv_note(struct memelf
ae4e228f
MT
29710 {
29711 elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv;
29712 int i = 0;
29713- do
29714+ do {
29715 i += 2;
29716- while (auxv[i - 2] != AT_NULL);
29717+ } while (auxv[i - 2] != AT_NULL);
29718 fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
29719 }
29720
16454cff 29721@@ -1850,14 +2136,14 @@ static void fill_extnum_info(struct elfh
df50ba0c
MT
29722 }
29723
29724 static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
29725- unsigned long mm_flags)
29726+ struct coredump_params *cprm)
29727 {
29728 struct vm_area_struct *vma;
29729 size_t size = 0;
29730
29731 for (vma = first_vma(current, gate_vma); vma != NULL;
29732 vma = next_vma(vma, gate_vma))
29733- size += vma_dump_size(vma, mm_flags);
29734+ size += vma_dump_size(vma, cprm->mm_flags, cprm->signr);
29735 return size;
29736 }
29737
16454cff 29738@@ -1951,7 +2237,7 @@ static int elf_core_dump(struct coredump
df50ba0c
MT
29739
29740 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
29741
29742- offset += elf_core_vma_data_size(gate_vma, cprm->mm_flags);
29743+ offset += elf_core_vma_data_size(gate_vma, cprm);
29744 offset += elf_core_extra_data_size();
29745 e_shoff = offset;
29746
16454cff 29747@@ -1965,10 +2251,12 @@ static int elf_core_dump(struct coredump
df50ba0c
MT
29748 offset = dataoff;
29749
29750 size += sizeof(*elf);
29751+ gr_learn_resource(current, RLIMIT_CORE, size, 1);
29752 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
29753 goto end_coredump;
29754
29755 size += sizeof(*phdr4note);
29756+ gr_learn_resource(current, RLIMIT_CORE, size, 1);
29757 if (size > cprm->limit
29758 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
29759 goto end_coredump;
16454cff 29760@@ -1982,7 +2270,7 @@ static int elf_core_dump(struct coredump
58c5fc13
MT
29761 phdr.p_offset = offset;
29762 phdr.p_vaddr = vma->vm_start;
29763 phdr.p_paddr = 0;
df50ba0c
MT
29764- phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags);
29765+ phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags, cprm->signr);
58c5fc13
MT
29766 phdr.p_memsz = vma->vm_end - vma->vm_start;
29767 offset += phdr.p_filesz;
29768 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
16454cff 29769@@ -1993,6 +2281,7 @@ static int elf_core_dump(struct coredump
df50ba0c
MT
29770 phdr.p_align = ELF_EXEC_PAGESIZE;
29771
29772 size += sizeof(phdr);
29773+ gr_learn_resource(current, RLIMIT_CORE, size, 1);
29774 if (size > cprm->limit
29775 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
29776 goto end_coredump;
16454cff 29777@@ -2017,7 +2306,7 @@ static int elf_core_dump(struct coredump
58c5fc13
MT
29778 unsigned long addr;
29779 unsigned long end;
29780
df50ba0c
MT
29781- end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags);
29782+ end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags, cprm->signr);
58c5fc13
MT
29783
29784 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
29785 struct page *page;
16454cff 29786@@ -2026,6 +2315,7 @@ static int elf_core_dump(struct coredump
ae4e228f
MT
29787 page = get_dump_page(addr);
29788 if (page) {
29789 void *kaddr = kmap(page);
29790+ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
29791 stop = ((size += PAGE_SIZE) > cprm->limit) ||
29792 !dump_write(cprm->file, kaddr,
29793 PAGE_SIZE);
16454cff 29794@@ -2043,6 +2333,7 @@ static int elf_core_dump(struct coredump
df50ba0c
MT
29795
29796 if (e_phnum == PN_XNUM) {
29797 size += sizeof(*shdr4extnum);
29798+ gr_learn_resource(current, RLIMIT_CORE, size, 1);
29799 if (size > cprm->limit
29800 || !dump_write(cprm->file, shdr4extnum,
29801 sizeof(*shdr4extnum)))
16454cff 29802@@ -2063,6 +2354,97 @@ out:
ae4e228f
MT
29803
29804 #endif /* CONFIG_ELF_CORE */
58c5fc13
MT
29805
29806+#ifdef CONFIG_PAX_MPROTECT
29807+/* PaX: non-PIC ELF libraries need relocations on their executable segments
29808+ * therefore we'll grant them VM_MAYWRITE once during their life. Similarly
29809+ * we'll remove VM_MAYWRITE for good on RELRO segments.
29810+ *
29811+ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
29812+ * basis because we want to allow the common case and not the special ones.
29813+ */
29814+static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags)
29815+{
29816+ struct elfhdr elf_h;
29817+ struct elf_phdr elf_p;
29818+ unsigned long i;
29819+ unsigned long oldflags;
29820+ bool is_textrel_rw, is_textrel_rx, is_relro;
29821+
29822+ if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT))
29823+ return;
29824+
29825+ oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ);
29826+ newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ;
29827+
57199397 29828+#ifdef CONFIG_PAX_ELFRELOCS
58c5fc13
MT
29829+ /* possible TEXTREL */
29830+ is_textrel_rw = vma->vm_file && !vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ);
29831+ 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);
57199397
MT
29832+#else
29833+ is_textrel_rw = false;
29834+ is_textrel_rx = false;
58c5fc13
MT
29835+#endif
29836+
29837+ /* possible RELRO */
29838+ is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ);
29839+
29840+ if (!is_textrel_rw && !is_textrel_rx && !is_relro)
29841+ return;
29842+
29843+ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
29844+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
29845+
29846+#ifdef CONFIG_PAX_ETEXECRELOCS
29847+ ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
29848+#else
29849+ ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) ||
29850+#endif
29851+
29852+ (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
29853+ !elf_check_arch(&elf_h) ||
29854+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
29855+ elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr))
29856+ return;
29857+
29858+ for (i = 0UL; i < elf_h.e_phnum; i++) {
29859+ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
29860+ return;
29861+ switch (elf_p.p_type) {
29862+ case PT_DYNAMIC:
29863+ if (!is_textrel_rw && !is_textrel_rx)
29864+ continue;
29865+ i = 0UL;
29866+ while ((i+1) * sizeof(elf_dyn) <= elf_p.p_filesz) {
29867+ elf_dyn dyn;
29868+
29869+ if (sizeof(dyn) != kernel_read(vma->vm_file, elf_p.p_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
29870+ return;
29871+ if (dyn.d_tag == DT_NULL)
29872+ return;
29873+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
29874+ gr_log_textrel(vma);
29875+ if (is_textrel_rw)
29876+ vma->vm_flags |= VM_MAYWRITE;
29877+ else
29878+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
29879+ vma->vm_flags &= ~VM_MAYWRITE;
29880+ return;
29881+ }
29882+ i++;
29883+ }
29884+ return;
29885+
29886+ case PT_GNU_RELRO:
29887+ if (!is_relro)
29888+ continue;
29889+ if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start)
29890+ vma->vm_flags &= ~VM_MAYWRITE;
29891+ return;
29892+ }
29893+ }
29894+}
29895+#endif
29896+
29897 static int __init init_elf_binfmt(void)
29898 {
29899 return register_binfmt(&elf_format);
16454cff
MT
29900diff -urNp linux-2.6.38.1/fs/binfmt_flat.c linux-2.6.38.1/fs/binfmt_flat.c
29901--- linux-2.6.38.1/fs/binfmt_flat.c 2011-03-14 21:20:32.000000000 -0400
29902+++ linux-2.6.38.1/fs/binfmt_flat.c 2011-03-21 18:31:35.000000000 -0400
57199397 29903@@ -567,7 +567,9 @@ static int load_flat_file(struct linux_b
58c5fc13
MT
29904 realdatastart = (unsigned long) -ENOMEM;
29905 printk("Unable to allocate RAM for process data, errno %d\n",
29906 (int)-realdatastart);
29907+ down_write(&current->mm->mmap_sem);
29908 do_munmap(current->mm, textpos, text_len);
29909+ up_write(&current->mm->mmap_sem);
29910 ret = realdatastart;
29911 goto err;
29912 }
57199397 29913@@ -591,8 +593,10 @@ static int load_flat_file(struct linux_b
58c5fc13 29914 }
ae4e228f 29915 if (IS_ERR_VALUE(result)) {
58c5fc13
MT
29916 printk("Unable to read data+bss, errno %d\n", (int)-result);
29917+ down_write(&current->mm->mmap_sem);
29918 do_munmap(current->mm, textpos, text_len);
57199397 29919 do_munmap(current->mm, realdatastart, len);
58c5fc13
MT
29920+ up_write(&current->mm->mmap_sem);
29921 ret = result;
29922 goto err;
29923 }
57199397 29924@@ -661,8 +665,10 @@ static int load_flat_file(struct linux_b
58c5fc13 29925 }
ae4e228f 29926 if (IS_ERR_VALUE(result)) {
58c5fc13
MT
29927 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
29928+ down_write(&current->mm->mmap_sem);
29929 do_munmap(current->mm, textpos, text_len + data_len + extra +
29930 MAX_SHARED_LIBS * sizeof(unsigned long));
29931+ up_write(&current->mm->mmap_sem);
29932 ret = result;
29933 goto err;
29934 }
16454cff
MT
29935diff -urNp linux-2.6.38.1/fs/binfmt_misc.c linux-2.6.38.1/fs/binfmt_misc.c
29936--- linux-2.6.38.1/fs/binfmt_misc.c 2011-03-14 21:20:32.000000000 -0400
29937+++ linux-2.6.38.1/fs/binfmt_misc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 29938@@ -698,7 +698,7 @@ static int bm_fill_super(struct super_bl
58c5fc13
MT
29939 static struct tree_descr bm_files[] = {
29940 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
29941 [3] = {"register", &bm_register_operations, S_IWUSR},
29942- /* last one */ {""}
29943+ /* last one */ {"", NULL, 0}
29944 };
29945 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
29946 if (!err)
16454cff
MT
29947diff -urNp linux-2.6.38.1/fs/bio.c linux-2.6.38.1/fs/bio.c
29948--- linux-2.6.38.1/fs/bio.c 2011-03-14 21:20:32.000000000 -0400
29949+++ linux-2.6.38.1/fs/bio.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 29950@@ -1233,7 +1233,7 @@ static void bio_copy_kern_endio(struct b
ae4e228f
MT
29951 const int read = bio_data_dir(bio) == READ;
29952 struct bio_map_data *bmd = bio->bi_private;
29953 int i;
29954- char *p = bmd->sgvecs[0].iov_base;
29955+ char *p = (__force char *)bmd->sgvecs[0].iov_base;
29956
29957 __bio_for_each_segment(bvec, bio, i, 0) {
29958 char *addr = page_address(bvec->bv_page);
16454cff
MT
29959diff -urNp linux-2.6.38.1/fs/block_dev.c linux-2.6.38.1/fs/block_dev.c
29960--- linux-2.6.38.1/fs/block_dev.c 2011-03-14 21:20:32.000000000 -0400
29961+++ linux-2.6.38.1/fs/block_dev.c 2011-03-21 18:31:35.000000000 -0400
29962@@ -669,7 +669,7 @@ static bool bd_may_claim(struct block_de
df50ba0c 29963 else if (bdev->bd_contains == bdev)
57199397
MT
29964 return true; /* is a whole device which isn't held */
29965
16454cff
MT
29966- else if (whole->bd_holder == bd_may_claim)
29967+ else if (whole->bd_holder == (void *)bd_may_claim)
57199397
MT
29968 return true; /* is a partition of a device that is being partitioned */
29969 else if (whole->bd_holder != NULL)
29970 return false; /* is a partition of a held device */
16454cff
MT
29971diff -urNp linux-2.6.38.1/fs/btrfs/ctree.c linux-2.6.38.1/fs/btrfs/ctree.c
29972--- linux-2.6.38.1/fs/btrfs/ctree.c 2011-03-14 21:20:32.000000000 -0400
29973+++ linux-2.6.38.1/fs/btrfs/ctree.c 2011-03-21 18:31:35.000000000 -0400
29974@@ -468,9 +468,12 @@ static noinline int __btrfs_cow_block(st
6892158b
MT
29975 free_extent_buffer(buf);
29976 add_root_to_dirty_list(root);
29977 } else {
29978- if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID)
29979- parent_start = parent->start;
29980- else
29981+ if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
29982+ if (parent)
29983+ parent_start = parent->start;
29984+ else
29985+ parent_start = 0;
29986+ } else
29987 parent_start = 0;
29988
29989 WARN_ON(trans->transid != btrfs_header_generation(parent));
16454cff 29990@@ -3776,7 +3779,6 @@ setup_items_for_insert(struct btrfs_tran
ae4e228f
MT
29991
29992 ret = 0;
29993 if (slot == 0) {
29994- struct btrfs_disk_key disk_key;
29995 btrfs_cpu_key_to_disk(&disk_key, cpu_key);
29996 ret = fixup_low_keys(trans, root, path, &disk_key, 1);
29997 }
16454cff
MT
29998diff -urNp linux-2.6.38.1/fs/btrfs/disk-io.c linux-2.6.38.1/fs/btrfs/disk-io.c
29999--- linux-2.6.38.1/fs/btrfs/disk-io.c 2011-03-14 21:20:32.000000000 -0400
30000+++ linux-2.6.38.1/fs/btrfs/disk-io.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 30001@@ -41,7 +41,7 @@
ae4e228f
MT
30002 #include "tree-log.h"
30003 #include "free-space-cache.h"
30004
30005-static struct extent_io_ops btree_extent_io_ops;
30006+static const struct extent_io_ops btree_extent_io_ops;
30007 static void end_workqueue_fn(struct btrfs_work *work);
30008 static void free_fs_root(struct btrfs_root *root);
16454cff
MT
30009 static void btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
30010@@ -3028,7 +3028,7 @@ static int btrfs_cleanup_transaction(str
58c5fc13
MT
30011 return 0;
30012 }
30013
ae4e228f
MT
30014-static struct extent_io_ops btree_extent_io_ops = {
30015+static const struct extent_io_ops btree_extent_io_ops = {
30016 .write_cache_pages_lock_hook = btree_lock_page_hook,
30017 .readpage_end_io_hook = btree_readpage_end_io_hook,
30018 .submit_bio_hook = btree_submit_bio_hook,
16454cff
MT
30019diff -urNp linux-2.6.38.1/fs/btrfs/extent_io.h linux-2.6.38.1/fs/btrfs/extent_io.h
30020--- linux-2.6.38.1/fs/btrfs/extent_io.h 2011-03-14 21:20:32.000000000 -0400
30021+++ linux-2.6.38.1/fs/btrfs/extent_io.h 2011-03-21 18:31:35.000000000 -0400
30022@@ -55,36 +55,36 @@ typedef int (extent_submit_bio_hook_t)(s
ae4e228f 30023 struct bio *bio, int mirror_num,
57199397 30024 unsigned long bio_flags, u64 bio_offset);
ae4e228f
MT
30025 struct extent_io_ops {
30026- int (*fill_delalloc)(struct inode *inode, struct page *locked_page,
30027+ int (* const fill_delalloc)(struct inode *inode, struct page *locked_page,
30028 u64 start, u64 end, int *page_started,
30029 unsigned long *nr_written);
30030- int (*writepage_start_hook)(struct page *page, u64 start, u64 end);
30031- int (*writepage_io_hook)(struct page *page, u64 start, u64 end);
30032+ int (* const writepage_start_hook)(struct page *page, u64 start, u64 end);
30033+ int (* const writepage_io_hook)(struct page *page, u64 start, u64 end);
30034 extent_submit_bio_hook_t *submit_bio_hook;
30035- int (*merge_bio_hook)(struct page *page, unsigned long offset,
30036+ int (* const merge_bio_hook)(struct page *page, unsigned long offset,
30037 size_t size, struct bio *bio,
30038 unsigned long bio_flags);
30039- int (*readpage_io_hook)(struct page *page, u64 start, u64 end);
30040- int (*readpage_io_failed_hook)(struct bio *bio, struct page *page,
30041+ int (* const readpage_io_hook)(struct page *page, u64 start, u64 end);
30042+ int (* const readpage_io_failed_hook)(struct bio *bio, struct page *page,
30043 u64 start, u64 end,
30044 struct extent_state *state);
30045- int (*writepage_io_failed_hook)(struct bio *bio, struct page *page,
30046+ int (* const writepage_io_failed_hook)(struct bio *bio, struct page *page,
30047 u64 start, u64 end,
30048 struct extent_state *state);
30049- int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end,
30050+ int (* const readpage_end_io_hook)(struct page *page, u64 start, u64 end,
30051 struct extent_state *state);
30052- int (*writepage_end_io_hook)(struct page *page, u64 start, u64 end,
30053+ int (* const writepage_end_io_hook)(struct page *page, u64 start, u64 end,
30054 struct extent_state *state, int uptodate);
57199397
MT
30055- int (*set_bit_hook)(struct inode *inode, struct extent_state *state,
30056+ int (* const set_bit_hook)(struct inode *inode, struct extent_state *state,
30057 int *bits);
ae4e228f
MT
30058- int (*clear_bit_hook)(struct inode *inode, struct extent_state *state,
30059+ int (* const clear_bit_hook)(struct inode *inode, struct extent_state *state,
57199397 30060 int *bits);
ae4e228f
MT
30061- int (*merge_extent_hook)(struct inode *inode,
30062+ int (* const merge_extent_hook)(struct inode *inode,
30063 struct extent_state *new,
30064 struct extent_state *other);
30065- int (*split_extent_hook)(struct inode *inode,
30066+ int (* const split_extent_hook)(struct inode *inode,
30067 struct extent_state *orig, u64 split);
30068- int (*write_cache_pages_lock_hook)(struct page *page);
30069+ int (* const write_cache_pages_lock_hook)(struct page *page);
30070 };
30071
30072 struct extent_io_tree {
16454cff 30073@@ -94,7 +94,7 @@ struct extent_io_tree {
ae4e228f
MT
30074 u64 dirty_bytes;
30075 spinlock_t lock;
30076 spinlock_t buffer_lock;
30077- struct extent_io_ops *ops;
30078+ const struct extent_io_ops *ops;
30079 };
30080
30081 struct extent_state {
16454cff
MT
30082diff -urNp linux-2.6.38.1/fs/btrfs/free-space-cache.c linux-2.6.38.1/fs/btrfs/free-space-cache.c
30083--- linux-2.6.38.1/fs/btrfs/free-space-cache.c 2011-03-14 21:20:32.000000000 -0400
30084+++ linux-2.6.38.1/fs/btrfs/free-space-cache.c 2011-03-21 18:31:35.000000000 -0400
30085@@ -1855,8 +1855,6 @@ u64 btrfs_alloc_from_cluster(struct btrf
ae4e228f
MT
30086
30087 while(1) {
30088 if (entry->bytes < bytes || entry->offset < min_start) {
30089- struct rb_node *node;
30090-
30091 node = rb_next(&entry->offset_index);
30092 if (!node)
30093 break;
16454cff 30094@@ -2018,7 +2016,7 @@ again:
ae4e228f
MT
30095 */
30096 while (entry->bitmap || found_bitmap ||
30097 (!entry->bitmap && entry->bytes < min_bytes)) {
30098- struct rb_node *node = rb_next(&entry->offset_index);
30099+ node = rb_next(&entry->offset_index);
30100
30101 if (entry->bitmap && entry->bytes > bytes + empty_size) {
30102 ret = btrfs_bitmap_cluster(block_group, entry, cluster,
16454cff
MT
30103diff -urNp linux-2.6.38.1/fs/btrfs/inode.c linux-2.6.38.1/fs/btrfs/inode.c
30104--- linux-2.6.38.1/fs/btrfs/inode.c 2011-03-14 21:20:32.000000000 -0400
30105+++ linux-2.6.38.1/fs/btrfs/inode.c 2011-03-24 23:08:20.000000000 -0400
df50ba0c 30106@@ -64,7 +64,7 @@ static const struct inode_operations btr
ae4e228f
MT
30107 static const struct address_space_operations btrfs_aops;
30108 static const struct address_space_operations btrfs_symlink_aops;
30109 static const struct file_operations btrfs_dir_file_operations;
30110-static struct extent_io_ops btrfs_extent_io_ops;
30111+static const struct extent_io_ops btrfs_extent_io_ops;
58c5fc13
MT
30112
30113 static struct kmem_cache *btrfs_inode_cachep;
ae4e228f 30114 struct kmem_cache *btrfs_trans_handle_cachep;
16454cff
MT
30115@@ -6796,7 +6796,7 @@ fail:
30116 return -ENOMEM;
30117 }
30118
30119-static int btrfs_getattr(struct vfsmount *mnt,
30120+int btrfs_getattr(struct vfsmount *mnt,
30121 struct dentry *dentry, struct kstat *stat)
30122 {
30123 struct inode *inode = dentry->d_inode;
30124@@ -6808,6 +6808,14 @@ static int btrfs_getattr(struct vfsmount
30125 return 0;
30126 }
30127
30128+EXPORT_SYMBOL(btrfs_getattr);
30129+
30130+dev_t get_btrfs_dev_from_inode(struct inode *inode)
30131+{
30132+ return BTRFS_I(inode)->root->anon_super.s_dev;
30133+}
30134+EXPORT_SYMBOL(get_btrfs_dev_from_inode);
30135+
30136 static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
30137 struct inode *new_dir, struct dentry *new_dentry)
30138 {
30139@@ -7311,7 +7319,7 @@ static const struct file_operations btrf
ae4e228f
MT
30140 .fsync = btrfs_sync_file,
30141 };
58c5fc13 30142
ae4e228f
MT
30143-static struct extent_io_ops btrfs_extent_io_ops = {
30144+static const struct extent_io_ops btrfs_extent_io_ops = {
30145 .fill_delalloc = run_delalloc_range,
30146 .submit_bio_hook = btrfs_submit_bio_hook,
30147 .merge_bio_hook = btrfs_merge_bio_hook,
16454cff
MT
30148diff -urNp linux-2.6.38.1/fs/btrfs/ioctl.c linux-2.6.38.1/fs/btrfs/ioctl.c
30149--- linux-2.6.38.1/fs/btrfs/ioctl.c 2011-03-14 21:20:32.000000000 -0400
30150+++ linux-2.6.38.1/fs/btrfs/ioctl.c 2011-03-21 18:31:35.000000000 -0400
30151@@ -2270,9 +2270,12 @@ long btrfs_ioctl_space_info(struct btrfs
c52201e0
MT
30152 for (i = 0; i < num_types; i++) {
30153 struct btrfs_space_info *tmp;
30154
30155+ /* Don't copy in more than we allocated */
317566c1
MT
30156 if (!slot_count)
30157 break;
30158
c52201e0
MT
30159+ slot_count--;
30160+
30161 info = NULL;
30162 rcu_read_lock();
30163 list_for_each_entry_rcu(tmp, &root->fs_info->space_info,
16454cff 30164@@ -2294,10 +2297,7 @@ long btrfs_ioctl_space_info(struct btrfs
317566c1
MT
30165 memcpy(dest, &space, sizeof(space));
30166 dest++;
30167 space_args.total_spaces++;
30168- slot_count--;
30169 }
30170- if (!slot_count)
30171- break;
30172 }
30173 up_read(&info->groups_sem);
30174 }
16454cff
MT
30175diff -urNp linux-2.6.38.1/fs/btrfs/relocation.c linux-2.6.38.1/fs/btrfs/relocation.c
30176--- linux-2.6.38.1/fs/btrfs/relocation.c 2011-03-14 21:20:32.000000000 -0400
30177+++ linux-2.6.38.1/fs/btrfs/relocation.c 2011-03-21 18:31:35.000000000 -0400
30178@@ -1239,7 +1239,7 @@ static int __update_reloc_root(struct bt
6892158b
MT
30179 }
30180 spin_unlock(&rc->reloc_root_tree.lock);
30181
30182- BUG_ON((struct btrfs_root *)node->data != root);
30183+ BUG_ON(!node || (struct btrfs_root *)node->data != root);
30184
30185 if (!del) {
30186 spin_lock(&rc->reloc_root_tree.lock);
16454cff
MT
30187diff -urNp linux-2.6.38.1/fs/cachefiles/bind.c linux-2.6.38.1/fs/cachefiles/bind.c
30188--- linux-2.6.38.1/fs/cachefiles/bind.c 2011-03-14 21:20:32.000000000 -0400
30189+++ linux-2.6.38.1/fs/cachefiles/bind.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
30190@@ -39,13 +39,11 @@ int cachefiles_daemon_bind(struct cachef
30191 args);
30192
30193 /* start by checking things over */
30194- ASSERT(cache->fstop_percent >= 0 &&
30195- cache->fstop_percent < cache->fcull_percent &&
30196+ ASSERT(cache->fstop_percent < cache->fcull_percent &&
30197 cache->fcull_percent < cache->frun_percent &&
30198 cache->frun_percent < 100);
30199
30200- ASSERT(cache->bstop_percent >= 0 &&
30201- cache->bstop_percent < cache->bcull_percent &&
30202+ ASSERT(cache->bstop_percent < cache->bcull_percent &&
30203 cache->bcull_percent < cache->brun_percent &&
30204 cache->brun_percent < 100);
30205
16454cff
MT
30206diff -urNp linux-2.6.38.1/fs/cachefiles/daemon.c linux-2.6.38.1/fs/cachefiles/daemon.c
30207--- linux-2.6.38.1/fs/cachefiles/daemon.c 2011-03-14 21:20:32.000000000 -0400
30208+++ linux-2.6.38.1/fs/cachefiles/daemon.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 30209@@ -196,7 +196,7 @@ static ssize_t cachefiles_daemon_read(st
ae4e228f
MT
30210 if (n > buflen)
30211 return -EMSGSIZE;
30212
30213- if (copy_to_user(_buffer, buffer, n) != 0)
30214+ if (n > sizeof(buffer) || copy_to_user(_buffer, buffer, n) != 0)
30215 return -EFAULT;
58c5fc13 30216
ae4e228f 30217 return n;
bc901d79 30218@@ -222,7 +222,7 @@ static ssize_t cachefiles_daemon_write(s
df50ba0c
MT
30219 if (test_bit(CACHEFILES_DEAD, &cache->flags))
30220 return -EIO;
30221
30222- if (datalen < 0 || datalen > PAGE_SIZE - 1)
30223+ if (datalen > PAGE_SIZE - 1)
30224 return -EOPNOTSUPP;
30225
30226 /* drag the command string into the kernel so we can parse it */
bc901d79 30227@@ -386,7 +386,7 @@ static int cachefiles_daemon_fstop(struc
df50ba0c
MT
30228 if (args[0] != '%' || args[1] != '\0')
30229 return -EINVAL;
30230
30231- if (fstop < 0 || fstop >= cache->fcull_percent)
30232+ if (fstop >= cache->fcull_percent)
30233 return cachefiles_daemon_range_error(cache, args);
30234
30235 cache->fstop_percent = fstop;
bc901d79 30236@@ -458,7 +458,7 @@ static int cachefiles_daemon_bstop(struc
df50ba0c
MT
30237 if (args[0] != '%' || args[1] != '\0')
30238 return -EINVAL;
30239
30240- if (bstop < 0 || bstop >= cache->bcull_percent)
30241+ if (bstop >= cache->bcull_percent)
30242 return cachefiles_daemon_range_error(cache, args);
30243
30244 cache->bstop_percent = bstop;
16454cff
MT
30245diff -urNp linux-2.6.38.1/fs/cachefiles/rdwr.c linux-2.6.38.1/fs/cachefiles/rdwr.c
30246--- linux-2.6.38.1/fs/cachefiles/rdwr.c 2011-03-14 21:20:32.000000000 -0400
30247+++ linux-2.6.38.1/fs/cachefiles/rdwr.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 30248@@ -945,7 +945,7 @@ int cachefiles_write_page(struct fscache
ae4e228f
MT
30249 old_fs = get_fs();
30250 set_fs(KERNEL_DS);
30251 ret = file->f_op->write(
30252- file, (const void __user *) data, len, &pos);
30253+ file, (__force const void __user *) data, len, &pos);
30254 set_fs(old_fs);
30255 kunmap(page);
30256 if (ret != len)
16454cff
MT
30257diff -urNp linux-2.6.38.1/fs/ceph/dir.c linux-2.6.38.1/fs/ceph/dir.c
30258--- linux-2.6.38.1/fs/ceph/dir.c 2011-03-14 21:20:32.000000000 -0400
30259+++ linux-2.6.38.1/fs/ceph/dir.c 2011-03-21 18:31:35.000000000 -0400
30260@@ -226,7 +226,7 @@ static int ceph_readdir(struct file *fil
bc901d79
MT
30261 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
30262 struct ceph_mds_client *mdsc = fsc->mdsc;
6892158b
MT
30263 unsigned frag = fpos_frag(filp->f_pos);
30264- int off = fpos_off(filp->f_pos);
30265+ unsigned int off = fpos_off(filp->f_pos);
30266 int err;
30267 u32 ftype;
30268 struct ceph_mds_reply_info_parsed *rinfo;
16454cff 30269@@ -358,7 +358,7 @@ more:
6892158b
MT
30270 rinfo = &fi->last_readdir->r_reply_info;
30271 dout("readdir frag %x num %d off %d chunkoff %d\n", frag,
30272 rinfo->dir_nr, off, fi->offset);
30273- while (off - fi->offset >= 0 && off - fi->offset < rinfo->dir_nr) {
30274+ while (off >= fi->offset && off - fi->offset < rinfo->dir_nr) {
30275 u64 pos = ceph_make_fpos(frag, off);
30276 struct ceph_mds_reply_inode *in =
30277 rinfo->dir_in[off - fi->offset].in;
16454cff
MT
30278diff -urNp linux-2.6.38.1/fs/cifs/cifs_uniupr.h linux-2.6.38.1/fs/cifs/cifs_uniupr.h
30279--- linux-2.6.38.1/fs/cifs/cifs_uniupr.h 2011-03-14 21:20:32.000000000 -0400
30280+++ linux-2.6.38.1/fs/cifs/cifs_uniupr.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
30281@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
30282 {0x0490, 0x04cc, UniCaseRangeU0490},
30283 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
30284 {0xff40, 0xff5a, UniCaseRangeUff40},
30285- {0}
30286+ {0, 0, NULL}
30287 };
30288 #endif
30289
16454cff
MT
30290diff -urNp linux-2.6.38.1/fs/cifs/link.c linux-2.6.38.1/fs/cifs/link.c
30291--- linux-2.6.38.1/fs/cifs/link.c 2011-03-14 21:20:32.000000000 -0400
30292+++ linux-2.6.38.1/fs/cifs/link.c 2011-03-21 18:31:35.000000000 -0400
30293@@ -577,7 +577,7 @@ symlink_exit:
58c5fc13
MT
30294
30295 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
30296 {
30297- char *p = nd_get_link(nd);
30298+ const char *p = nd_get_link(nd);
30299 if (!IS_ERR(p))
30300 kfree(p);
30301 }
16454cff
MT
30302diff -urNp linux-2.6.38.1/fs/compat_binfmt_elf.c linux-2.6.38.1/fs/compat_binfmt_elf.c
30303--- linux-2.6.38.1/fs/compat_binfmt_elf.c 2011-03-14 21:20:32.000000000 -0400
30304+++ linux-2.6.38.1/fs/compat_binfmt_elf.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
30305@@ -30,11 +30,13 @@
30306 #undef elf_phdr
30307 #undef elf_shdr
30308 #undef elf_note
30309+#undef elf_dyn
30310 #undef elf_addr_t
30311 #define elfhdr elf32_hdr
30312 #define elf_phdr elf32_phdr
30313 #define elf_shdr elf32_shdr
30314 #define elf_note elf32_note
30315+#define elf_dyn Elf32_Dyn
30316 #define elf_addr_t Elf32_Addr
30317
30318 /*
16454cff
MT
30319diff -urNp linux-2.6.38.1/fs/compat.c linux-2.6.38.1/fs/compat.c
30320--- linux-2.6.38.1/fs/compat.c 2011-03-14 21:20:32.000000000 -0400
30321+++ linux-2.6.38.1/fs/compat.c 2011-03-21 18:31:35.000000000 -0400
30322@@ -594,7 +594,7 @@ ssize_t compat_rw_copy_check_uvector(int
6892158b
MT
30323 goto out;
30324
30325 ret = -EINVAL;
30326- if (nr_segs > UIO_MAXIOV || nr_segs < 0)
30327+ if (nr_segs > UIO_MAXIOV)
30328 goto out;
30329 if (nr_segs > fast_segs) {
30330 ret = -ENOMEM;
bc901d79 30331@@ -876,6 +876,7 @@ struct compat_old_linux_dirent {
58c5fc13 30332
bc901d79
MT
30333 struct compat_readdir_callback {
30334 struct compat_old_linux_dirent __user *dirent;
30335+ struct file * file;
30336 int result;
30337 };
30338
30339@@ -893,6 +894,10 @@ static int compat_fillonedir(void *__buf
30340 buf->result = -EOVERFLOW;
30341 return -EOVERFLOW;
30342 }
30343+
30344+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
30345+ return 0;
30346+
30347 buf->result++;
30348 dirent = buf->dirent;
30349 if (!access_ok(VERIFY_WRITE, dirent,
30350@@ -925,6 +930,7 @@ asmlinkage long compat_sys_old_readdir(u
30351
30352 buf.result = 0;
30353 buf.dirent = dirent;
30354+ buf.file = file;
30355
30356 error = vfs_readdir(file, compat_fillonedir, &buf);
30357 if (buf.result)
30358@@ -945,6 +951,7 @@ struct compat_linux_dirent {
30359 struct compat_getdents_callback {
30360 struct compat_linux_dirent __user *current_dir;
30361 struct compat_linux_dirent __user *previous;
30362+ struct file * file;
30363 int count;
30364 int error;
30365 };
30366@@ -966,6 +973,10 @@ static int compat_filldir(void *__buf, c
30367 buf->error = -EOVERFLOW;
30368 return -EOVERFLOW;
30369 }
30370+
30371+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
30372+ return 0;
30373+
30374 dirent = buf->previous;
30375 if (dirent) {
30376 if (__put_user(offset, &dirent->d_off))
30377@@ -1013,6 +1024,7 @@ asmlinkage long compat_sys_getdents(unsi
30378 buf.previous = NULL;
30379 buf.count = count;
30380 buf.error = 0;
30381+ buf.file = file;
30382
30383 error = vfs_readdir(file, compat_filldir, &buf);
30384 if (error >= 0)
30385@@ -1034,6 +1046,7 @@ out:
30386 struct compat_getdents_callback64 {
30387 struct linux_dirent64 __user *current_dir;
30388 struct linux_dirent64 __user *previous;
30389+ struct file * file;
30390 int count;
30391 int error;
30392 };
30393@@ -1050,6 +1063,10 @@ static int compat_filldir64(void * __buf
30394 buf->error = -EINVAL; /* only used if we fail.. */
30395 if (reclen > buf->count)
30396 return -EINVAL;
30397+
30398+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
30399+ return 0;
30400+
30401 dirent = buf->previous;
30402
30403 if (dirent) {
30404@@ -1101,6 +1118,7 @@ asmlinkage long compat_sys_getdents64(un
30405 buf.previous = NULL;
30406 buf.count = count;
30407 buf.error = 0;
30408+ buf.file = file;
30409
30410 error = vfs_readdir(file, compat_filldir64, &buf);
30411 if (error >= 0)
16454cff 30412@@ -1423,6 +1441,7 @@ static int compat_copy_strings(int argc,
bc901d79
MT
30413
30414 page = get_arg_page(bprm, pos, 1);
30415 if (!page) {
30416+ /* We've exceed the stack rlimit. */
58c5fc13
MT
30417 ret = -E2BIG;
30418 goto out;
30419 }
16454cff 30420@@ -1464,6 +1483,11 @@ int compat_do_execve(char * filename,
58c5fc13
MT
30421 compat_uptr_t __user *envp,
30422 struct pt_regs * regs)
30423 {
30424+#ifdef CONFIG_GRKERNSEC
30425+ struct file *old_exec_file;
30426+ struct acl_subject_label *old_acl;
30427+ struct rlimit old_rlim[RLIM_NLIMITS];
30428+#endif
30429 struct linux_binprm *bprm;
30430 struct file *file;
30431 struct files_struct *displaced;
16454cff 30432@@ -1500,6 +1524,14 @@ int compat_do_execve(char * filename,
58c5fc13
MT
30433 bprm->filename = filename;
30434 bprm->interp = filename;
30435
30436+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->cred->user->processes), 1);
30437+ retval = -EAGAIN;
30438+ if (gr_handle_nproc())
30439+ goto out_file;
30440+ retval = -EACCES;
30441+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
30442+ goto out_file;
30443+
30444 retval = bprm_mm_init(bprm);
30445 if (retval)
30446 goto out_file;
16454cff 30447@@ -1529,9 +1561,40 @@ int compat_do_execve(char * filename,
58c5fc13
MT
30448 if (retval < 0)
30449 goto out;
30450
30451+ if (!gr_tpe_allow(file)) {
30452+ retval = -EACCES;
30453+ goto out;
30454+ }
30455+
30456+ if (gr_check_crash_exec(file)) {
30457+ retval = -EACCES;
30458+ goto out;
30459+ }
30460+
30461+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
30462+
bc901d79 30463+ gr_handle_exec_args_compat(bprm, argv);
58c5fc13
MT
30464+
30465+#ifdef CONFIG_GRKERNSEC
30466+ old_acl = current->acl;
30467+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
30468+ old_exec_file = current->exec_file;
30469+ get_file(file);
30470+ current->exec_file = file;
30471+#endif
30472+
30473+ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
30474+ bprm->unsafe & LSM_UNSAFE_SHARE);
30475+ if (retval < 0)
30476+ goto out_fail;
30477+
30478 retval = search_binary_handler(bprm, regs);
30479 if (retval < 0)
30480- goto out;
30481+ goto out_fail;
30482+#ifdef CONFIG_GRKERNSEC
30483+ if (old_exec_file)
30484+ fput(old_exec_file);
30485+#endif
30486
df50ba0c
MT
30487 /* execve succeeded */
30488 current->fs->in_exec = 0;
16454cff 30489@@ -1542,6 +1605,14 @@ int compat_do_execve(char * filename,
58c5fc13
MT
30490 put_files_struct(displaced);
30491 return retval;
30492
30493+out_fail:
30494+#ifdef CONFIG_GRKERNSEC
30495+ current->acl = old_acl;
30496+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
30497+ fput(current->exec_file);
30498+ current->exec_file = old_exec_file;
30499+#endif
30500+
30501 out:
bc901d79
MT
30502 if (bprm->mm) {
30503 acct_arg_size(bprm, 0);
16454cff
MT
30504diff -urNp linux-2.6.38.1/fs/compat_ioctl.c linux-2.6.38.1/fs/compat_ioctl.c
30505--- linux-2.6.38.1/fs/compat_ioctl.c 2011-03-14 21:20:32.000000000 -0400
30506+++ linux-2.6.38.1/fs/compat_ioctl.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 30507@@ -208,6 +208,8 @@ static int do_video_set_spu_palette(unsi
6892158b
MT
30508
30509 err = get_user(palp, &up->palette);
30510 err |= get_user(length, &up->length);
30511+ if (err)
30512+ return -EFAULT;
30513
30514 up_native = compat_alloc_user_space(sizeof(struct video_spu_palette));
30515 err = put_user(compat_ptr(palp), &up_native->palette);
16454cff 30516@@ -1638,8 +1640,8 @@ asmlinkage long compat_sys_ioctl(unsigne
bc901d79
MT
30517 static int __init init_sys32_ioctl_cmp(const void *p, const void *q)
30518 {
30519 unsigned int a, b;
30520- a = *(unsigned int *)p;
30521- b = *(unsigned int *)q;
30522+ a = *(const unsigned int *)p;
30523+ b = *(const unsigned int *)q;
30524 if (a > b)
30525 return 1;
30526 if (a < b)
16454cff
MT
30527diff -urNp linux-2.6.38.1/fs/debugfs/inode.c linux-2.6.38.1/fs/debugfs/inode.c
30528--- linux-2.6.38.1/fs/debugfs/inode.c 2011-03-14 21:20:32.000000000 -0400
30529+++ linux-2.6.38.1/fs/debugfs/inode.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 30530@@ -130,7 +130,7 @@ static inline int debugfs_positive(struc
58c5fc13
MT
30531
30532 static int debug_fill_super(struct super_block *sb, void *data, int silent)
30533 {
30534- static struct tree_descr debug_files[] = {{""}};
30535+ static struct tree_descr debug_files[] = {{"", NULL, 0}};
30536
30537 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
30538 }
16454cff
MT
30539diff -urNp linux-2.6.38.1/fs/dlm/lockspace.c linux-2.6.38.1/fs/dlm/lockspace.c
30540--- linux-2.6.38.1/fs/dlm/lockspace.c 2011-03-14 21:20:32.000000000 -0400
30541+++ linux-2.6.38.1/fs/dlm/lockspace.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
30542@@ -200,7 +200,7 @@ static int dlm_uevent(struct kset *kset,
30543 return 0;
58c5fc13
MT
30544 }
30545
df50ba0c
MT
30546-static struct kset_uevent_ops dlm_uevent_ops = {
30547+static const struct kset_uevent_ops dlm_uevent_ops = {
30548 .uevent = dlm_uevent,
ae4e228f 30549 };
df50ba0c 30550
16454cff
MT
30551diff -urNp linux-2.6.38.1/fs/ecryptfs/inode.c linux-2.6.38.1/fs/ecryptfs/inode.c
30552--- linux-2.6.38.1/fs/ecryptfs/inode.c 2011-03-14 21:20:32.000000000 -0400
30553+++ linux-2.6.38.1/fs/ecryptfs/inode.c 2011-03-21 18:31:35.000000000 -0400
30554@@ -658,7 +658,7 @@ static int ecryptfs_readlink_lower(struc
ae4e228f
MT
30555 old_fs = get_fs();
30556 set_fs(get_ds());
30557 rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
30558- (char __user *)lower_buf,
30559+ (__force char __user *)lower_buf,
30560 lower_bufsiz);
30561 set_fs(old_fs);
df50ba0c 30562 if (rc < 0)
16454cff 30563@@ -704,7 +704,7 @@ static void *ecryptfs_follow_link(struct
ae4e228f
MT
30564 }
30565 old_fs = get_fs();
30566 set_fs(get_ds());
30567- rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
30568+ rc = dentry->d_inode->i_op->readlink(dentry, (__force char __user *)buf, len);
30569 set_fs(old_fs);
30570 if (rc < 0) {
30571 kfree(buf);
16454cff 30572@@ -719,7 +719,7 @@ out:
ae4e228f
MT
30573 static void
30574 ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
30575 {
30576- char *buf = nd_get_link(nd);
30577+ const char *buf = nd_get_link(nd);
30578 if (!IS_ERR(buf)) {
30579 /* Free the char* */
30580 kfree(buf);
16454cff
MT
30581diff -urNp linux-2.6.38.1/fs/ecryptfs/miscdev.c linux-2.6.38.1/fs/ecryptfs/miscdev.c
30582--- linux-2.6.38.1/fs/ecryptfs/miscdev.c 2011-03-14 21:20:32.000000000 -0400
30583+++ linux-2.6.38.1/fs/ecryptfs/miscdev.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 30584@@ -328,7 +328,7 @@ check_list:
ae4e228f
MT
30585 goto out_unlock_msg_ctx;
30586 i = 5;
30587 if (msg_ctx->msg) {
30588- if (copy_to_user(&buf[i], packet_length, packet_length_size))
30589+ if (packet_length_size > sizeof(packet_length) || copy_to_user(&buf[i], packet_length, packet_length_size))
30590 goto out_unlock_msg_ctx;
30591 i += packet_length_size;
30592 if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
16454cff
MT
30593diff -urNp linux-2.6.38.1/fs/exec.c linux-2.6.38.1/fs/exec.c
30594--- linux-2.6.38.1/fs/exec.c 2011-03-14 21:20:32.000000000 -0400
30595+++ linux-2.6.38.1/fs/exec.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 30596@@ -55,12 +55,24 @@
58c5fc13 30597 #include <linux/fs_struct.h>
ae4e228f 30598 #include <linux/pipe_fs_i.h>
bc901d79 30599 #include <linux/oom.h>
58c5fc13
MT
30600+#include <linux/random.h>
30601+#include <linux/seq_file.h>
30602+
30603+#ifdef CONFIG_PAX_REFCOUNT
30604+#include <linux/kallsyms.h>
30605+#include <linux/kdebug.h>
30606+#endif
30607
30608 #include <asm/uaccess.h>
30609 #include <asm/mmu_context.h>
30610 #include <asm/tlb.h>
30611 #include "internal.h"
30612
30613+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
30614+void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
30615+EXPORT_SYMBOL(pax_set_initial_flags_func);
30616+#endif
30617+
30618 int core_uses_pid;
30619 char core_pattern[CORENAME_MAX_SIZE] = "core";
ae4e228f 30620 unsigned int core_pipe_limit;
bc901d79 30621@@ -120,7 +132,7 @@ SYSCALL_DEFINE1(uselib, const char __use
58c5fc13
MT
30622 goto out;
30623
30624 file = do_filp_open(AT_FDCWD, tmp,
16454cff
MT
30625- O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 0,
30626+ O_LARGEFILE | O_RDONLY | __FMODE_EXEC | FMODE_GREXEC, 0,
58c5fc13
MT
30627 MAY_READ | MAY_EXEC | MAY_OPEN);
30628 putname(tmp);
30629 error = PTR_ERR(file);
bc901d79 30630@@ -187,18 +199,10 @@ struct page *get_arg_page(struct linux_b
58c5fc13
MT
30631 int write)
30632 {
30633 struct page *page;
30634- int ret;
30635
30636-#ifdef CONFIG_STACK_GROWSUP
30637- if (write) {
30638- ret = expand_stack_downwards(bprm->vma, pos);
30639- if (ret < 0)
30640- return NULL;
30641- }
30642-#endif
30643- ret = get_user_pages(current, bprm->mm, pos,
30644- 1, write, 1, &page, NULL);
30645- if (ret <= 0)
30646+ if (0 > expand_stack_downwards(bprm->vma, pos))
30647+ return NULL;
30648+ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
30649 return NULL;
30650
30651 if (write) {
bc901d79 30652@@ -273,6 +277,11 @@ static int __bprm_mm_init(struct linux_b
58c5fc13
MT
30653 vma->vm_end = STACK_TOP_MAX;
30654 vma->vm_start = vma->vm_end - PAGE_SIZE;
57199397 30655 vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
58c5fc13
MT
30656+
30657+#ifdef CONFIG_PAX_SEGMEXEC
30658+ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
30659+#endif
30660+
30661 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
df50ba0c 30662 INIT_LIST_HEAD(&vma->anon_vma_chain);
bc901d79
MT
30663
30664@@ -287,6 +296,12 @@ static int __bprm_mm_init(struct linux_b
58c5fc13
MT
30665 mm->stack_vm = mm->total_vm = 1;
30666 up_write(&mm->mmap_sem);
30667 bprm->p = vma->vm_end - sizeof(void *);
30668+
30669+#ifdef CONFIG_PAX_RANDUSTACK
30670+ if (randomize_va_space)
30671+ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
30672+#endif
30673+
30674 return 0;
30675 err:
30676 up_write(&mm->mmap_sem);
bc901d79 30677@@ -522,7 +537,7 @@ int copy_strings_kernel(int argc, const
ae4e228f
MT
30678 int r;
30679 mm_segment_t oldfs = get_fs();
30680 set_fs(KERNEL_DS);
6892158b
MT
30681- r = copy_strings(argc, (const char __user *const __user *)argv, bprm);
30682+ r = copy_strings(argc, (__force const char __user *const __user *)argv, bprm);
ae4e228f
MT
30683 set_fs(oldfs);
30684 return r;
30685 }
bc901d79 30686@@ -552,7 +567,8 @@ static int shift_arg_pages(struct vm_are
58c5fc13
MT
30687 unsigned long new_end = old_end - shift;
30688 struct mmu_gather *tlb;
30689
30690- BUG_ON(new_start > new_end);
30691+ if (new_start >= new_end || new_start < mmap_min_addr)
bc901d79 30692+ return -ENOMEM;
58c5fc13
MT
30693
30694 /*
30695 * ensure there are no vmas between where we want to go
bc901d79 30696@@ -561,6 +577,10 @@ static int shift_arg_pages(struct vm_are
58c5fc13
MT
30697 if (vma != find_vma(mm, new_start))
30698 return -EFAULT;
30699
30700+#ifdef CONFIG_PAX_SEGMEXEC
30701+ BUG_ON(pax_find_mirror_vma(vma));
30702+#endif
30703+
30704 /*
30705 * cover the whole range: [new_start, old_end)
30706 */
bc901d79
MT
30707@@ -641,10 +661,6 @@ int setup_arg_pages(struct linux_binprm
30708 stack_top = arch_align_stack(stack_top);
30709 stack_top = PAGE_ALIGN(stack_top);
30710
30711- if (unlikely(stack_top < mmap_min_addr) ||
30712- unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr))
30713- return -ENOMEM;
30714-
30715 stack_shift = vma->vm_end - stack_top;
30716
30717 bprm->p -= stack_shift;
30718@@ -656,8 +672,28 @@ int setup_arg_pages(struct linux_binprm
58c5fc13
MT
30719 bprm->exec -= stack_shift;
30720
30721 down_write(&mm->mmap_sem);
30722+
30723+ /* Move stack pages down in memory. */
30724+ if (stack_shift) {
30725+ ret = shift_arg_pages(vma, stack_shift);
30726+ if (ret)
30727+ goto out_unlock;
30728+ }
30729+
30730 vm_flags = VM_STACK_FLAGS;
30731
58c5fc13
MT
30732+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30733+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
30734+ vm_flags &= ~VM_EXEC;
30735+
30736+#ifdef CONFIG_PAX_MPROTECT
30737+ if (mm->pax_flags & MF_PAX_MPROTECT)
30738+ vm_flags &= ~VM_MAYEXEC;
30739+#endif
30740+
30741+ }
30742+#endif
30743+
ae4e228f
MT
30744 /*
30745 * Adjust stack execute permissions; explicitly enable for
30746 * EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X and leave alone
bc901d79 30747@@ -676,13 +712,6 @@ int setup_arg_pages(struct linux_binprm
58c5fc13
MT
30748 goto out_unlock;
30749 BUG_ON(prev != vma);
30750
30751- /* Move stack pages down in memory. */
30752- if (stack_shift) {
30753- ret = shift_arg_pages(vma, stack_shift);
ae4e228f
MT
30754- if (ret)
30755- goto out_unlock;
58c5fc13
MT
30756- }
30757-
57199397
MT
30758 /* mprotect_fixup is overkill to remove the temporary stack flags */
30759 vma->vm_flags &= ~VM_STACK_INCOMPLETE_SETUP;
30760
bc901d79 30761@@ -723,7 +752,7 @@ struct file *open_exec(const char *name)
58c5fc13
MT
30762 int err;
30763
30764 file = do_filp_open(AT_FDCWD, name,
16454cff
MT
30765- O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 0,
30766+ O_LARGEFILE | O_RDONLY | __FMODE_EXEC | FMODE_GREXEC, 0,
58c5fc13
MT
30767 MAY_EXEC | MAY_OPEN);
30768 if (IS_ERR(file))
30769 goto out;
bc901d79 30770@@ -760,7 +789,7 @@ int kernel_read(struct file *file, loff_
ae4e228f
MT
30771 old_fs = get_fs();
30772 set_fs(get_ds());
30773 /* The cast to a user pointer is valid due to the set_fs() */
30774- result = vfs_read(file, (void __user *)addr, count, &pos);
30775+ result = vfs_read(file, (__force void __user *)addr, count, &pos);
30776 set_fs(old_fs);
30777 return result;
30778 }
bc901d79 30779@@ -1182,7 +1211,7 @@ int check_unsafe_exec(struct linux_binpr
58c5fc13
MT
30780 }
30781 rcu_read_unlock();
30782
30783- if (p->fs->users > n_fs) {
30784+ if (atomic_read(&p->fs->users) > n_fs) {
30785 bprm->unsafe |= LSM_UNSAFE_SHARE;
30786 } else {
30787 res = -EAGAIN;
bc901d79 30788@@ -1378,6 +1407,11 @@ int do_execve(const char * filename,
6892158b 30789 const char __user *const __user *envp,
58c5fc13
MT
30790 struct pt_regs * regs)
30791 {
30792+#ifdef CONFIG_GRKERNSEC
30793+ struct file *old_exec_file;
30794+ struct acl_subject_label *old_acl;
30795+ struct rlimit old_rlim[RLIM_NLIMITS];
30796+#endif
30797 struct linux_binprm *bprm;
30798 struct file *file;
30799 struct files_struct *displaced;
bc901d79 30800@@ -1414,6 +1448,18 @@ int do_execve(const char * filename,
58c5fc13
MT
30801 bprm->filename = filename;
30802 bprm->interp = filename;
30803
30804+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->cred->user->processes), 1);
30805+
30806+ if (gr_handle_nproc()) {
30807+ retval = -EAGAIN;
30808+ goto out_file;
30809+ }
30810+
30811+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
30812+ retval = -EACCES;
30813+ goto out_file;
30814+ }
30815+
30816 retval = bprm_mm_init(bprm);
30817 if (retval)
30818 goto out_file;
bc901d79 30819@@ -1443,9 +1489,40 @@ int do_execve(const char * filename,
58c5fc13
MT
30820 if (retval < 0)
30821 goto out;
30822
30823+ if (!gr_tpe_allow(file)) {
30824+ retval = -EACCES;
30825+ goto out;
30826+ }
30827+
30828+ if (gr_check_crash_exec(file)) {
30829+ retval = -EACCES;
30830+ goto out;
30831+ }
30832+
30833+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
30834+
30835+ gr_handle_exec_args(bprm, argv);
30836+
30837+#ifdef CONFIG_GRKERNSEC
30838+ old_acl = current->acl;
30839+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
30840+ old_exec_file = current->exec_file;
30841+ get_file(file);
30842+ current->exec_file = file;
30843+#endif
30844+
30845+ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
bc901d79 30846+ bprm->unsafe & LSM_UNSAFE_SHARE);
58c5fc13
MT
30847+ if (retval < 0)
30848+ goto out_fail;
30849+
58c5fc13
MT
30850 retval = search_binary_handler(bprm,regs);
30851 if (retval < 0)
30852- goto out;
30853+ goto out_fail;
30854+#ifdef CONFIG_GRKERNSEC
30855+ if (old_exec_file)
30856+ fput(old_exec_file);
30857+#endif
30858
df50ba0c
MT
30859 /* execve succeeded */
30860 current->fs->in_exec = 0;
bc901d79 30861@@ -1456,6 +1533,14 @@ int do_execve(const char * filename,
58c5fc13
MT
30862 put_files_struct(displaced);
30863 return retval;
30864
30865+out_fail:
30866+#ifdef CONFIG_GRKERNSEC
30867+ current->acl = old_acl;
30868+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
30869+ fput(current->exec_file);
30870+ current->exec_file = old_exec_file;
30871+#endif
30872+
30873 out:
bc901d79
MT
30874 if (bprm->mm) {
30875 acct_arg_size(bprm, 0);
30876@@ -1642,6 +1727,217 @@ out:
58c5fc13
MT
30877 return ispipe;
30878 }
30879
30880+int pax_check_flags(unsigned long *flags)
30881+{
30882+ int retval = 0;
30883+
30884+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
30885+ if (*flags & MF_PAX_SEGMEXEC)
30886+ {
30887+ *flags &= ~MF_PAX_SEGMEXEC;
30888+ retval = -EINVAL;
30889+ }
30890+#endif
30891+
30892+ if ((*flags & MF_PAX_PAGEEXEC)
30893+
30894+#ifdef CONFIG_PAX_PAGEEXEC
30895+ && (*flags & MF_PAX_SEGMEXEC)
30896+#endif
30897+
30898+ )
30899+ {
30900+ *flags &= ~MF_PAX_PAGEEXEC;
30901+ retval = -EINVAL;
30902+ }
30903+
30904+ if ((*flags & MF_PAX_MPROTECT)
30905+
30906+#ifdef CONFIG_PAX_MPROTECT
30907+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
30908+#endif
30909+
30910+ )
30911+ {
30912+ *flags &= ~MF_PAX_MPROTECT;
30913+ retval = -EINVAL;
30914+ }
30915+
30916+ if ((*flags & MF_PAX_EMUTRAMP)
30917+
30918+#ifdef CONFIG_PAX_EMUTRAMP
30919+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
30920+#endif
30921+
30922+ )
30923+ {
30924+ *flags &= ~MF_PAX_EMUTRAMP;
30925+ retval = -EINVAL;
30926+ }
30927+
30928+ return retval;
30929+}
30930+
30931+EXPORT_SYMBOL(pax_check_flags);
30932+
30933+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30934+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
30935+{
30936+ struct task_struct *tsk = current;
30937+ struct mm_struct *mm = current->mm;
30938+ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
30939+ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
30940+ char *path_exec = NULL;
30941+ char *path_fault = NULL;
30942+ unsigned long start = 0UL, end = 0UL, offset = 0UL;
30943+
30944+ if (buffer_exec && buffer_fault) {
30945+ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
30946+
30947+ down_read(&mm->mmap_sem);
30948+ vma = mm->mmap;
30949+ while (vma && (!vma_exec || !vma_fault)) {
30950+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
30951+ vma_exec = vma;
30952+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
30953+ vma_fault = vma;
30954+ vma = vma->vm_next;
30955+ }
30956+ if (vma_exec) {
30957+ path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
30958+ if (IS_ERR(path_exec))
30959+ path_exec = "<path too long>";
30960+ else {
30961+ path_exec = mangle_path(buffer_exec, path_exec, "\t\n\\");
30962+ if (path_exec) {
30963+ *path_exec = 0;
30964+ path_exec = buffer_exec;
30965+ } else
30966+ path_exec = "<path too long>";
30967+ }
30968+ }
30969+ if (vma_fault) {
30970+ start = vma_fault->vm_start;
30971+ end = vma_fault->vm_end;
30972+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
30973+ if (vma_fault->vm_file) {
30974+ path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
30975+ if (IS_ERR(path_fault))
30976+ path_fault = "<path too long>";
30977+ else {
30978+ path_fault = mangle_path(buffer_fault, path_fault, "\t\n\\");
30979+ if (path_fault) {
30980+ *path_fault = 0;
30981+ path_fault = buffer_fault;
30982+ } else
30983+ path_fault = "<path too long>";
30984+ }
30985+ } else
30986+ path_fault = "<anonymous mapping>";
30987+ }
30988+ up_read(&mm->mmap_sem);
30989+ }
30990+ if (tsk->signal->curr_ip)
ae4e228f 30991+ printk(KERN_ERR "PAX: From %pI4: execution attempt in: %s, %08lx-%08lx %08lx\n", &tsk->signal->curr_ip, path_fault, start, end, offset);
58c5fc13
MT
30992+ else
30993+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
30994+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
30995+ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
30996+ task_uid(tsk), task_euid(tsk), pc, sp);
30997+ free_page((unsigned long)buffer_exec);
30998+ free_page((unsigned long)buffer_fault);
30999+ pax_report_insns(pc, sp);
31000+ do_coredump(SIGKILL, SIGKILL, regs);
31001+}
31002+#endif
31003+
31004+#ifdef CONFIG_PAX_REFCOUNT
31005+void pax_report_refcount_overflow(struct pt_regs *regs)
31006+{
31007+ if (current->signal->curr_ip)
ae4e228f
MT
31008+ printk(KERN_ERR "PAX: From %pI4: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
31009+ &current->signal->curr_ip, current->comm, task_pid_nr(current), current_uid(), current_euid());
58c5fc13
MT
31010+ else
31011+ printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
31012+ current->comm, task_pid_nr(current), current_uid(), current_euid());
31013+ print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
31014+ show_regs(regs);
ae4e228f 31015+ force_sig_info(SIGKILL, SEND_SIG_FORCED, current);
58c5fc13
MT
31016+}
31017+#endif
31018+
31019+#ifdef CONFIG_PAX_USERCOPY
6892158b
MT
31020+/* 0: not at all, 1: fully, 2: fully inside frame, -1: partially (implies an error) */
31021+int object_is_on_stack(const void *obj, unsigned long len)
31022+{
31023+ const void * const stack = task_stack_page(current);
31024+ const void * const stackend = stack + THREAD_SIZE;
31025+
57199397 31026+#if defined(CONFIG_FRAME_POINTER) && defined(CONFIG_X86)
6892158b
MT
31027+ const void *frame = NULL;
31028+ const void *oldframe;
57199397
MT
31029+#endif
31030+
6892158b
MT
31031+ if (obj + len < obj)
31032+ return -1;
57199397 31033+
6892158b
MT
31034+ if (obj + len <= stack || stackend <= obj)
31035+ return 0;
57199397 31036+
6892158b 31037+ if (obj < stack || stackend < obj + len)
57199397
MT
31038+ return -1;
31039+
57199397 31040+#if defined(CONFIG_FRAME_POINTER) && defined(CONFIG_X86)
6892158b
MT
31041+ oldframe = __builtin_frame_address(1);
31042+ if (oldframe)
31043+ frame = __builtin_frame_address(2);
31044+ /*
31045+ low ----------------------------------------------> high
31046+ [saved bp][saved ip][args][local vars][saved bp][saved ip]
31047+ ^----------------^
31048+ allow copies only within here
31049+ */
31050+ while (stack <= frame && frame < stackend) {
31051+ /* if obj + len extends past the last frame, this
31052+ check won't pass and the next frame will be 0,
31053+ causing us to bail out and correctly report
31054+ the copy as invalid
57199397 31055+ */
6892158b
MT
31056+ if (obj + len <= frame)
31057+ return obj >= oldframe + 2 * sizeof(void *) ? 2 : -1;
31058+ oldframe = frame;
31059+ frame = *(const void * const *)frame;
57199397 31060+ }
57199397 31061+ return -1;
6892158b
MT
31062+#else
31063+ return 1;
31064+#endif
57199397
MT
31065+}
31066+
31067+
58c5fc13
MT
31068+void pax_report_leak_to_user(const void *ptr, unsigned long len)
31069+{
31070+ if (current->signal->curr_ip)
ae4e228f
MT
31071+ printk(KERN_ERR "PAX: From %pI4: kernel memory leak attempt detected from %p (%lu bytes)\n",
31072+ &current->signal->curr_ip, ptr, len);
58c5fc13
MT
31073+ else
31074+ printk(KERN_ERR "PAX: kernel memory leak attempt detected from %p (%lu bytes)\n", ptr, len);
31075+ dump_stack();
31076+ do_group_exit(SIGKILL);
31077+}
31078+
31079+void pax_report_overflow_from_user(const void *ptr, unsigned long len)
31080+{
ae4e228f
MT
31081+ if (current->signal->curr_ip)
31082+ printk(KERN_ERR "PAX: From %pI4: kernel memory overflow attempt detected to %p (%lu bytes)\n",
31083+ &current->signal->curr_ip, ptr, len);
31084+ else
31085+ printk(KERN_ERR "PAX: kernel memory overflow attempt detected to %p (%lu bytes)\n", ptr, len);
58c5fc13
MT
31086+ dump_stack();
31087+ do_group_exit(SIGKILL);
31088+}
31089+#endif
31090+
df50ba0c 31091 static int zap_process(struct task_struct *start, int exit_code)
58c5fc13
MT
31092 {
31093 struct task_struct *t;
bc901d79 31094@@ -1852,17 +2148,17 @@ static void wait_for_dump_helpers(struct
ae4e228f
MT
31095 pipe = file->f_path.dentry->d_inode->i_pipe;
31096
31097 pipe_lock(pipe);
31098- pipe->readers++;
31099- pipe->writers--;
31100+ atomic_inc(&pipe->readers);
31101+ atomic_dec(&pipe->writers);
31102
31103- while ((pipe->readers > 1) && (!signal_pending(current))) {
31104+ while ((atomic_read(&pipe->readers) > 1) && (!signal_pending(current))) {
31105 wake_up_interruptible_sync(&pipe->wait);
31106 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
31107 pipe_wait(pipe);
31108 }
31109
31110- pipe->readers--;
31111- pipe->writers++;
31112+ atomic_dec(&pipe->readers);
31113+ atomic_inc(&pipe->writers);
31114 pipe_unlock(pipe);
31115
31116 }
bc901d79
MT
31117@@ -1978,6 +2274,10 @@ void do_coredump(long signr, int exit_co
31118 goto fail_corename;
31119 }
58c5fc13 31120
c52201e0 31121+ if (signr == SIGSEGV || signr == SIGBUS || signr == SIGKILL || signr == SIGILL)
58c5fc13
MT
31122+ gr_handle_brute_attach(current);
31123+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
31124+
6892158b 31125 if (ispipe) {
bc901d79
MT
31126 int dump_count;
31127 char **helper_argv;
16454cff
MT
31128diff -urNp linux-2.6.38.1/fs/ext2/balloc.c linux-2.6.38.1/fs/ext2/balloc.c
31129--- linux-2.6.38.1/fs/ext2/balloc.c 2011-03-14 21:20:32.000000000 -0400
31130+++ linux-2.6.38.1/fs/ext2/balloc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 31131@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
58c5fc13
MT
31132
31133 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
31134 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
31135- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
31136+ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
31137 sbi->s_resuid != current_fsuid() &&
31138 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
31139 return 0;
16454cff
MT
31140diff -urNp linux-2.6.38.1/fs/ext2/xattr.c linux-2.6.38.1/fs/ext2/xattr.c
31141--- linux-2.6.38.1/fs/ext2/xattr.c 2011-03-14 21:20:32.000000000 -0400
31142+++ linux-2.6.38.1/fs/ext2/xattr.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
31143@@ -86,8 +86,8 @@
31144 printk("\n"); \
31145 } while (0)
31146 #else
31147-# define ea_idebug(f...)
31148-# define ea_bdebug(f...)
31149+# define ea_idebug(inode, f...) do {} while (0)
31150+# define ea_bdebug(bh, f...) do {} while (0)
31151 #endif
31152
31153 static int ext2_xattr_set2(struct inode *, struct buffer_head *,
16454cff
MT
31154diff -urNp linux-2.6.38.1/fs/ext3/balloc.c linux-2.6.38.1/fs/ext3/balloc.c
31155--- linux-2.6.38.1/fs/ext3/balloc.c 2011-03-14 21:20:32.000000000 -0400
31156+++ linux-2.6.38.1/fs/ext3/balloc.c 2011-03-21 18:31:35.000000000 -0400
31157@@ -1441,7 +1441,7 @@ static int ext3_has_free_blocks(struct e
58c5fc13
MT
31158
31159 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
31160 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
31161- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
31162+ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
31163 sbi->s_resuid != current_fsuid() &&
31164 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
31165 return 0;
16454cff
MT
31166diff -urNp linux-2.6.38.1/fs/ext3/namei.c linux-2.6.38.1/fs/ext3/namei.c
31167--- linux-2.6.38.1/fs/ext3/namei.c 2011-03-23 17:20:08.000000000 -0400
31168+++ linux-2.6.38.1/fs/ext3/namei.c 2011-03-23 17:21:51.000000000 -0400
31169@@ -1159,7 +1159,7 @@ static struct ext3_dir_entry_2 *do_split
58c5fc13
MT
31170 char *data1 = (*bh)->b_data, *data2;
31171 unsigned split, move, size;
31172 struct ext3_dir_entry_2 *de = NULL, *de2;
31173- int err = 0, i;
31174+ int i, err = 0;
31175
31176 bh2 = ext3_append (handle, dir, &newblock, &err);
31177 if (!(bh2)) {
16454cff
MT
31178diff -urNp linux-2.6.38.1/fs/ext3/xattr.c linux-2.6.38.1/fs/ext3/xattr.c
31179--- linux-2.6.38.1/fs/ext3/xattr.c 2011-03-14 21:20:32.000000000 -0400
31180+++ linux-2.6.38.1/fs/ext3/xattr.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
31181@@ -89,8 +89,8 @@
31182 printk("\n"); \
31183 } while (0)
31184 #else
31185-# define ea_idebug(f...)
31186-# define ea_bdebug(f...)
31187+# define ea_idebug(f...) do {} while (0)
31188+# define ea_bdebug(f...) do {} while (0)
31189 #endif
31190
31191 static void ext3_xattr_cache_insert(struct buffer_head *);
16454cff
MT
31192diff -urNp linux-2.6.38.1/fs/ext4/balloc.c linux-2.6.38.1/fs/ext4/balloc.c
31193--- linux-2.6.38.1/fs/ext4/balloc.c 2011-03-14 21:20:32.000000000 -0400
31194+++ linux-2.6.38.1/fs/ext4/balloc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 31195@@ -519,7 +519,7 @@ static int ext4_has_free_blocks(struct e
58c5fc13
MT
31196 /* Hm, nope. Are (enough) root reserved blocks available? */
31197 if (sbi->s_resuid == current_fsuid() ||
31198 ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
31199- capable(CAP_SYS_RESOURCE)) {
31200+ capable_nolog(CAP_SYS_RESOURCE)) {
31201 if (free_blocks >= (nblocks + dirty_blocks))
31202 return 1;
31203 }
16454cff
MT
31204diff -urNp linux-2.6.38.1/fs/ext4/ext4.h linux-2.6.38.1/fs/ext4/ext4.h
31205--- linux-2.6.38.1/fs/ext4/ext4.h 2011-03-14 21:20:32.000000000 -0400
31206+++ linux-2.6.38.1/fs/ext4/ext4.h 2011-03-21 18:31:35.000000000 -0400
31207@@ -1166,19 +1166,19 @@ struct ext4_sb_info {
bc901d79
MT
31208 unsigned long s_mb_last_start;
31209
31210 /* stats for buddy allocator */
31211- atomic_t s_bal_reqs; /* number of reqs with len > 1 */
31212- atomic_t s_bal_success; /* we found long enough chunks */
31213- atomic_t s_bal_allocated; /* in blocks */
31214- atomic_t s_bal_ex_scanned; /* total extents scanned */
31215- atomic_t s_bal_goals; /* goal hits */
31216- atomic_t s_bal_breaks; /* too long searches */
31217- atomic_t s_bal_2orders; /* 2^order hits */
31218+ atomic_unchecked_t s_bal_reqs; /* number of reqs with len > 1 */
31219+ atomic_unchecked_t s_bal_success; /* we found long enough chunks */
31220+ atomic_unchecked_t s_bal_allocated; /* in blocks */
31221+ atomic_unchecked_t s_bal_ex_scanned; /* total extents scanned */
31222+ atomic_unchecked_t s_bal_goals; /* goal hits */
31223+ atomic_unchecked_t s_bal_breaks; /* too long searches */
31224+ atomic_unchecked_t s_bal_2orders; /* 2^order hits */
31225 spinlock_t s_bal_lock;
31226 unsigned long s_mb_buddies_generated;
31227 unsigned long long s_mb_generation_time;
31228- atomic_t s_mb_lost_chunks;
31229- atomic_t s_mb_preallocated;
31230- atomic_t s_mb_discarded;
31231+ atomic_unchecked_t s_mb_lost_chunks;
31232+ atomic_unchecked_t s_mb_preallocated;
31233+ atomic_unchecked_t s_mb_discarded;
31234 atomic_t s_lock_busy;
31235
31236 /* locality groups */
16454cff
MT
31237diff -urNp linux-2.6.38.1/fs/ext4/mballoc.c linux-2.6.38.1/fs/ext4/mballoc.c
31238--- linux-2.6.38.1/fs/ext4/mballoc.c 2011-03-14 21:20:32.000000000 -0400
31239+++ linux-2.6.38.1/fs/ext4/mballoc.c 2011-03-21 18:31:35.000000000 -0400
c52201e0 31240@@ -1846,7 +1846,7 @@ void ext4_mb_simple_scan_group(struct ex
bc901d79
MT
31241 BUG_ON(ac->ac_b_ex.fe_len != ac->ac_g_ex.fe_len);
31242
31243 if (EXT4_SB(sb)->s_mb_stats)
31244- atomic_inc(&EXT4_SB(sb)->s_bal_2orders);
31245+ atomic_inc_unchecked(&EXT4_SB(sb)->s_bal_2orders);
31246
31247 break;
31248 }
c52201e0 31249@@ -2140,7 +2140,7 @@ repeat:
bc901d79
MT
31250 ac->ac_status = AC_STATUS_CONTINUE;
31251 ac->ac_flags |= EXT4_MB_HINT_FIRST;
31252 cr = 3;
31253- atomic_inc(&sbi->s_mb_lost_chunks);
31254+ atomic_inc_unchecked(&sbi->s_mb_lost_chunks);
31255 goto repeat;
31256 }
31257 }
c52201e0 31258@@ -2606,25 +2606,25 @@ int ext4_mb_release(struct super_block *
bc901d79
MT
31259 if (sbi->s_mb_stats) {
31260 printk(KERN_INFO
31261 "EXT4-fs: mballoc: %u blocks %u reqs (%u success)\n",
31262- atomic_read(&sbi->s_bal_allocated),
31263- atomic_read(&sbi->s_bal_reqs),
31264- atomic_read(&sbi->s_bal_success));
31265+ atomic_read_unchecked(&sbi->s_bal_allocated),
31266+ atomic_read_unchecked(&sbi->s_bal_reqs),
31267+ atomic_read_unchecked(&sbi->s_bal_success));
31268 printk(KERN_INFO
31269 "EXT4-fs: mballoc: %u extents scanned, %u goal hits, "
31270 "%u 2^N hits, %u breaks, %u lost\n",
31271- atomic_read(&sbi->s_bal_ex_scanned),
31272- atomic_read(&sbi->s_bal_goals),
31273- atomic_read(&sbi->s_bal_2orders),
31274- atomic_read(&sbi->s_bal_breaks),
31275- atomic_read(&sbi->s_mb_lost_chunks));
31276+ atomic_read_unchecked(&sbi->s_bal_ex_scanned),
31277+ atomic_read_unchecked(&sbi->s_bal_goals),
31278+ atomic_read_unchecked(&sbi->s_bal_2orders),
31279+ atomic_read_unchecked(&sbi->s_bal_breaks),
31280+ atomic_read_unchecked(&sbi->s_mb_lost_chunks));
31281 printk(KERN_INFO
31282 "EXT4-fs: mballoc: %lu generated and it took %Lu\n",
31283 sbi->s_mb_buddies_generated++,
31284 sbi->s_mb_generation_time);
31285 printk(KERN_INFO
31286 "EXT4-fs: mballoc: %u preallocated, %u discarded\n",
31287- atomic_read(&sbi->s_mb_preallocated),
31288- atomic_read(&sbi->s_mb_discarded));
31289+ atomic_read_unchecked(&sbi->s_mb_preallocated),
31290+ atomic_read_unchecked(&sbi->s_mb_discarded));
31291 }
31292
31293 free_percpu(sbi->s_locality_groups);
c52201e0 31294@@ -3100,16 +3100,16 @@ static void ext4_mb_collect_stats(struct
bc901d79
MT
31295 struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
31296
31297 if (sbi->s_mb_stats && ac->ac_g_ex.fe_len > 1) {
31298- atomic_inc(&sbi->s_bal_reqs);
31299- atomic_add(ac->ac_b_ex.fe_len, &sbi->s_bal_allocated);
31300+ atomic_inc_unchecked(&sbi->s_bal_reqs);
31301+ atomic_add_unchecked(ac->ac_b_ex.fe_len, &sbi->s_bal_allocated);
31302 if (ac->ac_b_ex.fe_len >= ac->ac_o_ex.fe_len)
31303- atomic_inc(&sbi->s_bal_success);
31304- atomic_add(ac->ac_found, &sbi->s_bal_ex_scanned);
31305+ atomic_inc_unchecked(&sbi->s_bal_success);
31306+ atomic_add_unchecked(ac->ac_found, &sbi->s_bal_ex_scanned);
31307 if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start &&
31308 ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group)
31309- atomic_inc(&sbi->s_bal_goals);
31310+ atomic_inc_unchecked(&sbi->s_bal_goals);
31311 if (ac->ac_found > sbi->s_mb_max_to_scan)
31312- atomic_inc(&sbi->s_bal_breaks);
31313+ atomic_inc_unchecked(&sbi->s_bal_breaks);
31314 }
31315
31316 if (ac->ac_op == EXT4_MB_HISTORY_ALLOC)
c52201e0 31317@@ -3507,7 +3507,7 @@ ext4_mb_new_inode_pa(struct ext4_allocat
bc901d79
MT
31318 trace_ext4_mb_new_inode_pa(ac, pa);
31319
31320 ext4_mb_use_inode_pa(ac, pa);
31321- atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
31322+ atomic_add_unchecked(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
31323
31324 ei = EXT4_I(ac->ac_inode);
31325 grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
c52201e0 31326@@ -3567,7 +3567,7 @@ ext4_mb_new_group_pa(struct ext4_allocat
bc901d79
MT
31327 trace_ext4_mb_new_group_pa(ac, pa);
31328
31329 ext4_mb_use_group_pa(ac, pa);
31330- atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
31331+ atomic_add_unchecked(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
31332
31333 grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
31334 lg = ac->ac_lg;
c52201e0 31335@@ -3654,7 +3654,7 @@ ext4_mb_release_inode_pa(struct ext4_bud
bc901d79
MT
31336 * from the bitmap and continue.
31337 */
31338 }
31339- atomic_add(free, &sbi->s_mb_discarded);
31340+ atomic_add_unchecked(free, &sbi->s_mb_discarded);
31341
31342 return err;
31343 }
c52201e0 31344@@ -3672,7 +3672,7 @@ ext4_mb_release_group_pa(struct ext4_bud
bc901d79
MT
31345 ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
31346 BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
31347 mb_free_blocks(pa->pa_inode, e4b, bit, pa->pa_len);
31348- atomic_add(pa->pa_len, &EXT4_SB(sb)->s_mb_discarded);
31349+ atomic_add_unchecked(pa->pa_len, &EXT4_SB(sb)->s_mb_discarded);
31350 trace_ext4_mballoc_discard(sb, NULL, group, bit, pa->pa_len);
31351
31352 return 0;
16454cff
MT
31353diff -urNp linux-2.6.38.1/fs/ext4/namei.c linux-2.6.38.1/fs/ext4/namei.c
31354--- linux-2.6.38.1/fs/ext4/namei.c 2011-03-14 21:20:32.000000000 -0400
31355+++ linux-2.6.38.1/fs/ext4/namei.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 31356@@ -1161,7 +1161,7 @@ static struct ext4_dir_entry_2 *do_split
58c5fc13
MT
31357 char *data1 = (*bh)->b_data, *data2;
31358 unsigned split, move, size;
31359 struct ext4_dir_entry_2 *de = NULL, *de2;
31360- int err = 0, i;
31361+ int i, err = 0;
31362
31363 bh2 = ext4_append (handle, dir, &newblock, &err);
31364 if (!(bh2)) {
16454cff
MT
31365diff -urNp linux-2.6.38.1/fs/ext4/xattr.c linux-2.6.38.1/fs/ext4/xattr.c
31366--- linux-2.6.38.1/fs/ext4/xattr.c 2011-03-14 21:20:32.000000000 -0400
31367+++ linux-2.6.38.1/fs/ext4/xattr.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
31368@@ -82,8 +82,8 @@
31369 printk("\n"); \
31370 } while (0)
31371 #else
31372-# define ea_idebug(f...)
31373-# define ea_bdebug(f...)
31374+# define ea_idebug(inode, f...) do {} while (0)
31375+# define ea_bdebug(bh, f...) do {} while (0)
31376 #endif
ae4e228f 31377
df50ba0c 31378 static void ext4_xattr_cache_insert(struct buffer_head *);
16454cff
MT
31379diff -urNp linux-2.6.38.1/fs/fcntl.c linux-2.6.38.1/fs/fcntl.c
31380--- linux-2.6.38.1/fs/fcntl.c 2011-03-14 21:20:32.000000000 -0400
31381+++ linux-2.6.38.1/fs/fcntl.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
31382@@ -224,6 +224,11 @@ int __f_setown(struct file *filp, struct
31383 if (err)
31384 return err;
31385
31386+ if (gr_handle_chroot_fowner(pid, type))
31387+ return -ENOENT;
31388+ if (gr_check_protected_task_fowner(pid, type))
31389+ return -EACCES;
31390+
31391 f_modown(filp, pid, type, force);
31392 return 0;
31393 }
31394@@ -348,6 +353,7 @@ static long do_fcntl(int fd, unsigned in
58c5fc13
MT
31395 switch (cmd) {
31396 case F_DUPFD:
31397 case F_DUPFD_CLOEXEC:
31398+ gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
df50ba0c 31399 if (arg >= rlimit(RLIMIT_NOFILE))
58c5fc13
MT
31400 break;
31401 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
bc901d79
MT
31402@@ -808,14 +814,14 @@ static int __init fcntl_init(void)
31403 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
31404 * is defined as O_NONBLOCK on some platforms and not on others.
31405 */
31406- BUILD_BUG_ON(18 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
31407+ BUILD_BUG_ON(19 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
31408 O_RDONLY | O_WRONLY | O_RDWR |
31409 O_CREAT | O_EXCL | O_NOCTTY |
31410 O_TRUNC | O_APPEND | /* O_NONBLOCK | */
31411 __O_SYNC | O_DSYNC | FASYNC |
31412 O_DIRECT | O_LARGEFILE | O_DIRECTORY |
31413 O_NOFOLLOW | O_NOATIME | O_CLOEXEC |
16454cff
MT
31414- __FMODE_EXEC
31415+ __FMODE_EXEC | FMODE_GREXEC
bc901d79
MT
31416 ));
31417
31418 fasync_cache = kmem_cache_create("fasync_cache",
16454cff
MT
31419diff -urNp linux-2.6.38.1/fs/fifo.c linux-2.6.38.1/fs/fifo.c
31420--- linux-2.6.38.1/fs/fifo.c 2011-03-14 21:20:32.000000000 -0400
31421+++ linux-2.6.38.1/fs/fifo.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 31422@@ -58,10 +58,10 @@ static int fifo_open(struct inode *inode
ae4e228f
MT
31423 */
31424 filp->f_op = &read_pipefifo_fops;
31425 pipe->r_counter++;
31426- if (pipe->readers++ == 0)
31427+ if (atomic_inc_return(&pipe->readers) == 1)
31428 wake_up_partner(inode);
31429
31430- if (!pipe->writers) {
31431+ if (!atomic_read(&pipe->writers)) {
31432 if ((filp->f_flags & O_NONBLOCK)) {
31433 /* suppress POLLHUP until we have
31434 * seen a writer */
df50ba0c 31435@@ -82,15 +82,15 @@ static int fifo_open(struct inode *inode
ae4e228f
MT
31436 * errno=ENXIO when there is no process reading the FIFO.
31437 */
31438 ret = -ENXIO;
31439- if ((filp->f_flags & O_NONBLOCK) && !pipe->readers)
31440+ if ((filp->f_flags & O_NONBLOCK) && !atomic_read(&pipe->readers))
31441 goto err;
31442
31443 filp->f_op = &write_pipefifo_fops;
31444 pipe->w_counter++;
31445- if (!pipe->writers++)
31446+ if (atomic_inc_return(&pipe->writers) == 1)
31447 wake_up_partner(inode);
31448
31449- if (!pipe->readers) {
31450+ if (!atomic_read(&pipe->readers)) {
31451 wait_for_partner(inode, &pipe->r_counter);
31452 if (signal_pending(current))
31453 goto err_wr;
df50ba0c 31454@@ -106,11 +106,11 @@ static int fifo_open(struct inode *inode
ae4e228f
MT
31455 */
31456 filp->f_op = &rdwr_pipefifo_fops;
31457
31458- pipe->readers++;
31459- pipe->writers++;
31460+ atomic_inc(&pipe->readers);
31461+ atomic_inc(&pipe->writers);
31462 pipe->r_counter++;
31463 pipe->w_counter++;
31464- if (pipe->readers == 1 || pipe->writers == 1)
31465+ if (atomic_read(&pipe->readers) == 1 || atomic_read(&pipe->writers) == 1)
31466 wake_up_partner(inode);
31467 break;
31468
df50ba0c 31469@@ -124,19 +124,19 @@ static int fifo_open(struct inode *inode
ae4e228f
MT
31470 return 0;
31471
31472 err_rd:
31473- if (!--pipe->readers)
31474+ if (atomic_dec_and_test(&pipe->readers))
31475 wake_up_interruptible(&pipe->wait);
31476 ret = -ERESTARTSYS;
31477 goto err;
31478
31479 err_wr:
31480- if (!--pipe->writers)
31481+ if (atomic_dec_and_test(&pipe->writers))
31482 wake_up_interruptible(&pipe->wait);
31483 ret = -ERESTARTSYS;
31484 goto err;
31485
31486 err:
31487- if (!pipe->readers && !pipe->writers)
31488+ if (!atomic_read(&pipe->readers) && !atomic_read(&pipe->writers))
31489 free_pipe_info(inode);
31490
31491 err_nocleanup:
16454cff
MT
31492diff -urNp linux-2.6.38.1/fs/file.c linux-2.6.38.1/fs/file.c
31493--- linux-2.6.38.1/fs/file.c 2011-03-14 21:20:32.000000000 -0400
31494+++ linux-2.6.38.1/fs/file.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 31495@@ -14,6 +14,7 @@
58c5fc13
MT
31496 #include <linux/slab.h>
31497 #include <linux/vmalloc.h>
31498 #include <linux/file.h>
31499+#include <linux/security.h>
31500 #include <linux/fdtable.h>
31501 #include <linux/bitops.h>
31502 #include <linux/interrupt.h>
6892158b 31503@@ -250,6 +251,7 @@ int expand_files(struct files_struct *fi
58c5fc13
MT
31504 * N.B. For clone tasks sharing a files structure, this test
31505 * will limit the total number of files that can be opened.
31506 */
58c5fc13 31507+ gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
df50ba0c 31508 if (nr >= rlimit(RLIMIT_NOFILE))
58c5fc13
MT
31509 return -EMFILE;
31510
16454cff
MT
31511diff -urNp linux-2.6.38.1/fs/fs_struct.c linux-2.6.38.1/fs/fs_struct.c
31512--- linux-2.6.38.1/fs/fs_struct.c 2011-03-14 21:20:32.000000000 -0400
31513+++ linux-2.6.38.1/fs/fs_struct.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
31514@@ -4,6 +4,7 @@
31515 #include <linux/path.h>
31516 #include <linux/slab.h>
31517 #include <linux/fs_struct.h>
31518+#include <linux/grsecurity.h>
16454cff 31519 #include "internal.h"
ae4e228f 31520
16454cff
MT
31521 static inline void path_get_longterm(struct path *path)
31522@@ -31,6 +32,7 @@ void set_fs_root(struct fs_struct *fs, s
df50ba0c
MT
31523 old_root = fs->root;
31524 fs->root = *path;
16454cff 31525 path_get_longterm(path);
df50ba0c 31526+ gr_set_chroot_entries(current, path);
16454cff 31527 write_seqcount_end(&fs->seq);
6892158b 31528 spin_unlock(&fs->lock);
df50ba0c 31529 if (old_root.dentry)
16454cff 31530@@ -74,6 +76,7 @@ void chroot_fs_refs(struct path *old_roo
df50ba0c 31531 && fs->root.mnt == old_root->mnt) {
16454cff 31532 path_get_longterm(new_root);
df50ba0c
MT
31533 fs->root = *new_root;
31534+ gr_set_chroot_entries(p, new_root);
31535 count++;
ae4e228f 31536 }
df50ba0c 31537 if (fs->pwd.dentry == old_root->dentry
16454cff 31538@@ -109,7 +112,8 @@ void exit_fs(struct task_struct *tsk)
6892158b 31539 spin_lock(&fs->lock);
16454cff 31540 write_seqcount_begin(&fs->seq);
58c5fc13
MT
31541 tsk->fs = NULL;
31542- kill = !--fs->users;
df50ba0c 31543+ gr_clear_chroot_entries(tsk);
58c5fc13 31544+ kill = !atomic_dec_return(&fs->users);
16454cff 31545 write_seqcount_end(&fs->seq);
6892158b 31546 spin_unlock(&fs->lock);
58c5fc13 31547 task_unlock(tsk);
16454cff 31548@@ -123,7 +127,7 @@ struct fs_struct *copy_fs_struct(struct
58c5fc13
MT
31549 struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
31550 /* We don't need to lock fs - think why ;-) */
31551 if (fs) {
31552- fs->users = 1;
31553+ atomic_set(&fs->users, 1);
31554 fs->in_exec = 0;
6892158b 31555 spin_lock_init(&fs->lock);
16454cff
MT
31556 seqcount_init(&fs->seq);
31557@@ -132,6 +136,9 @@ struct fs_struct *copy_fs_struct(struct
31558 spin_lock(&old->lock);
31559 fs->root = old->root;
31560 path_get_longterm(&fs->root);
31561+ /* instead of calling gr_set_chroot_entries here,
31562+ we call it from every caller of this function
31563+ */
31564 fs->pwd = old->pwd;
31565 path_get_longterm(&fs->pwd);
31566 spin_unlock(&old->lock);
31567@@ -150,8 +157,9 @@ int unshare_fs_struct(void)
58c5fc13
MT
31568
31569 task_lock(current);
6892158b 31570 spin_lock(&fs->lock);
58c5fc13
MT
31571- kill = !--fs->users;
31572+ kill = !atomic_dec_return(&fs->users);
31573 current->fs = new_fs;
df50ba0c 31574+ gr_set_chroot_entries(current, &new_fs->root);
6892158b 31575 spin_unlock(&fs->lock);
58c5fc13 31576 task_unlock(current);
ae4e228f 31577
16454cff 31578@@ -170,7 +178,7 @@ EXPORT_SYMBOL(current_umask);
58c5fc13
MT
31579
31580 /* to be mentioned only in INIT_TASK */
31581 struct fs_struct init_fs = {
31582- .users = 1,
31583+ .users = ATOMIC_INIT(1),
6892158b 31584 .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock),
16454cff 31585 .seq = SEQCNT_ZERO,
58c5fc13 31586 .umask = 0022,
16454cff 31587@@ -186,12 +194,13 @@ void daemonize_fs_struct(void)
58c5fc13
MT
31588 task_lock(current);
31589
6892158b 31590 spin_lock(&init_fs.lock);
58c5fc13
MT
31591- init_fs.users++;
31592+ atomic_inc(&init_fs.users);
6892158b 31593 spin_unlock(&init_fs.lock);
58c5fc13 31594
6892158b 31595 spin_lock(&fs->lock);
58c5fc13
MT
31596 current->fs = &init_fs;
31597- kill = !--fs->users;
df50ba0c 31598+ gr_set_chroot_entries(current, &current->fs->root);
58c5fc13 31599+ kill = !atomic_dec_return(&fs->users);
6892158b 31600 spin_unlock(&fs->lock);
58c5fc13
MT
31601
31602 task_unlock(current);
16454cff
MT
31603diff -urNp linux-2.6.38.1/fs/fuse/control.c linux-2.6.38.1/fs/fuse/control.c
31604--- linux-2.6.38.1/fs/fuse/control.c 2011-03-14 21:20:32.000000000 -0400
31605+++ linux-2.6.38.1/fs/fuse/control.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 31606@@ -298,7 +298,7 @@ void fuse_ctl_remove_conn(struct fuse_co
58c5fc13
MT
31607
31608 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
31609 {
31610- struct tree_descr empty_descr = {""};
31611+ struct tree_descr empty_descr = {"", NULL, 0};
31612 struct fuse_conn *fc;
31613 int err;
31614
16454cff
MT
31615diff -urNp linux-2.6.38.1/fs/fuse/cuse.c linux-2.6.38.1/fs/fuse/cuse.c
31616--- linux-2.6.38.1/fs/fuse/cuse.c 2011-03-14 21:20:32.000000000 -0400
31617+++ linux-2.6.38.1/fs/fuse/cuse.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 31618@@ -530,8 +530,18 @@ static int cuse_channel_release(struct i
ae4e228f
MT
31619 return rc;
31620 }
31621
31622-static struct file_operations cuse_channel_fops; /* initialized during init */
31623-
31624+static const struct file_operations cuse_channel_fops = { /* initialized during init */
31625+ .owner = THIS_MODULE,
31626+ .llseek = no_llseek,
31627+ .read = do_sync_read,
31628+ .aio_read = fuse_dev_read,
31629+ .write = do_sync_write,
31630+ .aio_write = fuse_dev_write,
31631+ .poll = fuse_dev_poll,
31632+ .open = cuse_channel_open,
31633+ .release = cuse_channel_release,
31634+ .fasync = fuse_dev_fasync,
31635+};
31636
31637 /**************************************************************************
31638 * Misc stuff and module initializatiion
bc901d79 31639@@ -577,12 +587,6 @@ static int __init cuse_init(void)
ae4e228f
MT
31640 for (i = 0; i < CUSE_CONNTBL_LEN; i++)
31641 INIT_LIST_HEAD(&cuse_conntbl[i]);
31642
31643- /* inherit and extend fuse_dev_operations */
31644- cuse_channel_fops = fuse_dev_operations;
31645- cuse_channel_fops.owner = THIS_MODULE;
31646- cuse_channel_fops.open = cuse_channel_open;
31647- cuse_channel_fops.release = cuse_channel_release;
31648-
31649 cuse_class = class_create(THIS_MODULE, "cuse");
31650 if (IS_ERR(cuse_class))
31651 return PTR_ERR(cuse_class);
16454cff
MT
31652diff -urNp linux-2.6.38.1/fs/fuse/dev.c linux-2.6.38.1/fs/fuse/dev.c
31653--- linux-2.6.38.1/fs/fuse/dev.c 2011-03-14 21:20:32.000000000 -0400
31654+++ linux-2.6.38.1/fs/fuse/dev.c 2011-03-21 18:31:35.000000000 -0400
31655@@ -1183,7 +1183,7 @@ static ssize_t fuse_dev_do_read(struct f
57199397
MT
31656 return err;
31657 }
31658
ae4e228f
MT
31659-static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
31660+ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
31661 unsigned long nr_segs, loff_t pos)
31662 {
57199397 31663 struct fuse_copy_state cs;
16454cff 31664@@ -1197,6 +1197,8 @@ static ssize_t fuse_dev_read(struct kioc
57199397 31665 return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs));
ae4e228f
MT
31666 }
31667
31668+EXPORT_SYMBOL_GPL(fuse_dev_read);
31669+
57199397
MT
31670 static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe,
31671 struct pipe_buffer *buf)
ae4e228f 31672 {
16454cff 31673@@ -1240,7 +1242,7 @@ static ssize_t fuse_dev_splice_read(stru
57199397
MT
31674 ret = 0;
31675 pipe_lock(pipe);
31676
31677- if (!pipe->readers) {
31678+ if (!atomic_read(&pipe->readers)) {
31679 send_sig(SIGPIPE, current, 0);
31680 if (!ret)
31681 ret = -EPIPE;
16454cff 31682@@ -1733,7 +1735,7 @@ static ssize_t fuse_dev_do_write(struct
57199397
MT
31683 return err;
31684 }
31685
ae4e228f
MT
31686-static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
31687+ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
57199397 31688 unsigned long nr_segs, loff_t pos)
ae4e228f 31689 {
57199397 31690 struct fuse_copy_state cs;
16454cff 31691@@ -1746,6 +1748,8 @@ static ssize_t fuse_dev_write(struct kio
57199397 31692 return fuse_dev_do_write(fc, &cs, iov_length(iov, nr_segs));
ae4e228f
MT
31693 }
31694
ae4e228f
MT
31695+EXPORT_SYMBOL_GPL(fuse_dev_write);
31696+
57199397
MT
31697 static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
31698 struct file *out, loff_t *ppos,
31699 size_t len, unsigned int flags)
16454cff 31700@@ -1824,7 +1828,7 @@ out:
57199397
MT
31701 return ret;
31702 }
31703
31704-static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
ae4e228f
MT
31705+unsigned fuse_dev_poll(struct file *file, poll_table *wait)
31706 {
31707 unsigned mask = POLLOUT | POLLWRNORM;
31708 struct fuse_conn *fc = fuse_get_conn(file);
16454cff 31709@@ -1843,6 +1847,8 @@ static unsigned fuse_dev_poll(struct fil
ae4e228f
MT
31710 return mask;
31711 }
31712
31713+EXPORT_SYMBOL_GPL(fuse_dev_poll);
31714+
31715 /*
31716 * Abort all requests on the given list (pending or processing)
31717 *
16454cff 31718@@ -1962,7 +1968,7 @@ int fuse_dev_release(struct inode *inode
ae4e228f
MT
31719 }
31720 EXPORT_SYMBOL_GPL(fuse_dev_release);
31721
31722-static int fuse_dev_fasync(int fd, struct file *file, int on)
31723+int fuse_dev_fasync(int fd, struct file *file, int on)
31724 {
31725 struct fuse_conn *fc = fuse_get_conn(file);
31726 if (!fc)
16454cff 31727@@ -1972,6 +1978,8 @@ static int fuse_dev_fasync(int fd, struc
ae4e228f
MT
31728 return fasync_helper(fd, file, on, &fc->fasync);
31729 }
31730
31731+EXPORT_SYMBOL_GPL(fuse_dev_fasync);
31732+
31733 const struct file_operations fuse_dev_operations = {
31734 .owner = THIS_MODULE,
31735 .llseek = no_llseek,
16454cff
MT
31736diff -urNp linux-2.6.38.1/fs/fuse/dir.c linux-2.6.38.1/fs/fuse/dir.c
31737--- linux-2.6.38.1/fs/fuse/dir.c 2011-03-14 21:20:32.000000000 -0400
31738+++ linux-2.6.38.1/fs/fuse/dir.c 2011-03-21 18:31:35.000000000 -0400
31739@@ -1133,7 +1133,7 @@ static char *read_link(struct dentry *de
58c5fc13
MT
31740 return link;
31741 }
31742
31743-static void free_link(char *link)
31744+static void free_link(const char *link)
31745 {
31746 if (!IS_ERR(link))
31747 free_page((unsigned long) link);
16454cff
MT
31748diff -urNp linux-2.6.38.1/fs/fuse/fuse_i.h linux-2.6.38.1/fs/fuse/fuse_i.h
31749--- linux-2.6.38.1/fs/fuse/fuse_i.h 2011-03-14 21:20:32.000000000 -0400
31750+++ linux-2.6.38.1/fs/fuse/fuse_i.h 2011-03-21 18:31:35.000000000 -0400
31751@@ -541,6 +541,16 @@ extern const struct file_operations fuse
ae4e228f
MT
31752
31753 extern const struct dentry_operations fuse_dentry_operations;
31754
31755+extern ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
31756+ unsigned long nr_segs, loff_t pos);
31757+
31758+extern ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
31759+ unsigned long nr_segs, loff_t pos);
31760+
31761+extern unsigned fuse_dev_poll(struct file *file, poll_table *wait);
31762+
31763+extern int fuse_dev_fasync(int fd, struct file *file, int on);
31764+
31765 /**
31766 * Inode to nodeid comparison.
31767 */
16454cff
MT
31768diff -urNp linux-2.6.38.1/fs/hfs/inode.c linux-2.6.38.1/fs/hfs/inode.c
31769--- linux-2.6.38.1/fs/hfs/inode.c 2011-03-14 21:20:32.000000000 -0400
31770+++ linux-2.6.38.1/fs/hfs/inode.c 2011-03-21 18:31:35.000000000 -0400
6892158b 31771@@ -447,7 +447,7 @@ int hfs_write_inode(struct inode *inode,
58c5fc13
MT
31772
31773 if (S_ISDIR(main_inode->i_mode)) {
31774 if (fd.entrylength < sizeof(struct hfs_cat_dir))
31775- /* panic? */;
31776+ {/* panic? */}
31777 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
31778 sizeof(struct hfs_cat_dir));
31779 if (rec.type != HFS_CDR_DIR ||
6892158b 31780@@ -468,7 +468,7 @@ int hfs_write_inode(struct inode *inode,
58c5fc13
MT
31781 sizeof(struct hfs_cat_file));
31782 } else {
31783 if (fd.entrylength < sizeof(struct hfs_cat_file))
31784- /* panic? */;
31785+ {/* panic? */}
31786 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
31787 sizeof(struct hfs_cat_file));
31788 if (rec.type != HFS_CDR_FIL ||
16454cff
MT
31789diff -urNp linux-2.6.38.1/fs/hfsplus/inode.c linux-2.6.38.1/fs/hfsplus/inode.c
31790--- linux-2.6.38.1/fs/hfsplus/inode.c 2011-03-14 21:20:32.000000000 -0400
31791+++ linux-2.6.38.1/fs/hfsplus/inode.c 2011-03-21 18:31:35.000000000 -0400
31792@@ -498,7 +498,7 @@ int hfsplus_cat_read_inode(struct inode
58c5fc13
MT
31793 struct hfsplus_cat_folder *folder = &entry.folder;
31794
31795 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
31796- /* panic? */;
31797+ {/* panic? */}
31798 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
31799 sizeof(struct hfsplus_cat_folder));
31800 hfsplus_get_perms(inode, &folder->permissions, 1);
16454cff 31801@@ -515,7 +515,7 @@ int hfsplus_cat_read_inode(struct inode
58c5fc13
MT
31802 struct hfsplus_cat_file *file = &entry.file;
31803
31804 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
31805- /* panic? */;
31806+ {/* panic? */}
31807 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
31808 sizeof(struct hfsplus_cat_file));
31809
16454cff 31810@@ -572,7 +572,7 @@ int hfsplus_cat_write_inode(struct inode
58c5fc13
MT
31811 struct hfsplus_cat_folder *folder = &entry.folder;
31812
31813 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
31814- /* panic? */;
31815+ {/* panic? */}
31816 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
31817 sizeof(struct hfsplus_cat_folder));
31818 /* simple node checks? */
16454cff 31819@@ -594,7 +594,7 @@ int hfsplus_cat_write_inode(struct inode
58c5fc13
MT
31820 struct hfsplus_cat_file *file = &entry.file;
31821
31822 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
31823- /* panic? */;
31824+ {/* panic? */}
31825 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
31826 sizeof(struct hfsplus_cat_file));
31827 hfsplus_inode_write_fork(inode, &file->data_fork);
16454cff
MT
31828diff -urNp linux-2.6.38.1/fs/hugetlbfs/inode.c linux-2.6.38.1/fs/hugetlbfs/inode.c
31829--- linux-2.6.38.1/fs/hugetlbfs/inode.c 2011-03-14 21:20:32.000000000 -0400
31830+++ linux-2.6.38.1/fs/hugetlbfs/inode.c 2011-03-21 18:31:35.000000000 -0400
31831@@ -915,7 +915,7 @@ static struct file_system_type hugetlbfs
df50ba0c
MT
31832 .kill_sb = kill_litter_super,
31833 };
31834
31835-static struct vfsmount *hugetlbfs_vfsmount;
31836+struct vfsmount *hugetlbfs_vfsmount;
31837
31838 static int can_do_hugetlb_shm(void)
31839 {
16454cff
MT
31840diff -urNp linux-2.6.38.1/fs/jffs2/debug.h linux-2.6.38.1/fs/jffs2/debug.h
31841--- linux-2.6.38.1/fs/jffs2/debug.h 2011-03-14 21:20:32.000000000 -0400
31842+++ linux-2.6.38.1/fs/jffs2/debug.h 2011-03-21 18:31:35.000000000 -0400
6892158b 31843@@ -53,13 +53,13 @@
58c5fc13
MT
31844 #if CONFIG_JFFS2_FS_DEBUG > 0
31845 #define D1(x) x
31846 #else
31847-#define D1(x)
31848+#define D1(x) do {} while (0);
31849 #endif
31850
31851 #if CONFIG_JFFS2_FS_DEBUG > 1
31852 #define D2(x) x
31853 #else
31854-#define D2(x)
31855+#define D2(x) do {} while (0);
31856 #endif
31857
31858 /* The prefixes of JFFS2 messages */
6892158b 31859@@ -115,73 +115,73 @@
58c5fc13
MT
31860 #ifdef JFFS2_DBG_READINODE_MESSAGES
31861 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31862 #else
31863-#define dbg_readinode(fmt, ...)
31864+#define dbg_readinode(fmt, ...) do {} while (0)
31865 #endif
31866 #ifdef JFFS2_DBG_READINODE2_MESSAGES
31867 #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31868 #else
31869-#define dbg_readinode2(fmt, ...)
31870+#define dbg_readinode2(fmt, ...) do {} while (0)
31871 #endif
31872
31873 /* Fragtree build debugging messages */
31874 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
31875 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31876 #else
31877-#define dbg_fragtree(fmt, ...)
31878+#define dbg_fragtree(fmt, ...) do {} while (0)
31879 #endif
31880 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
31881 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31882 #else
31883-#define dbg_fragtree2(fmt, ...)
31884+#define dbg_fragtree2(fmt, ...) do {} while (0)
31885 #endif
31886
31887 /* Directory entry list manilulation debugging messages */
31888 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
31889 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31890 #else
31891-#define dbg_dentlist(fmt, ...)
31892+#define dbg_dentlist(fmt, ...) do {} while (0)
31893 #endif
31894
31895 /* Print the messages about manipulating node_refs */
31896 #ifdef JFFS2_DBG_NODEREF_MESSAGES
31897 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31898 #else
31899-#define dbg_noderef(fmt, ...)
31900+#define dbg_noderef(fmt, ...) do {} while (0)
31901 #endif
31902
31903 /* Manipulations with the list of inodes (JFFS2 inocache) */
31904 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
31905 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31906 #else
31907-#define dbg_inocache(fmt, ...)
31908+#define dbg_inocache(fmt, ...) do {} while (0)
31909 #endif
31910
31911 /* Summary debugging messages */
31912 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
31913 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31914 #else
31915-#define dbg_summary(fmt, ...)
31916+#define dbg_summary(fmt, ...) do {} while (0)
31917 #endif
31918
31919 /* File system build messages */
31920 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
31921 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31922 #else
31923-#define dbg_fsbuild(fmt, ...)
31924+#define dbg_fsbuild(fmt, ...) do {} while (0)
31925 #endif
31926
31927 /* Watch the object allocations */
31928 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
31929 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31930 #else
31931-#define dbg_memalloc(fmt, ...)
31932+#define dbg_memalloc(fmt, ...) do {} while (0)
31933 #endif
31934
31935 /* Watch the XATTR subsystem */
31936 #ifdef JFFS2_DBG_XATTR_MESSAGES
31937 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31938 #else
31939-#define dbg_xattr(fmt, ...)
31940+#define dbg_xattr(fmt, ...) do {} while (0)
31941 #endif
31942
31943 /* "Sanity" checks */
16454cff
MT
31944diff -urNp linux-2.6.38.1/fs/jffs2/erase.c linux-2.6.38.1/fs/jffs2/erase.c
31945--- linux-2.6.38.1/fs/jffs2/erase.c 2011-03-14 21:20:32.000000000 -0400
31946+++ linux-2.6.38.1/fs/jffs2/erase.c 2011-03-21 18:31:35.000000000 -0400
6892158b 31947@@ -439,7 +439,8 @@ static void jffs2_mark_erased_block(stru
58c5fc13
MT
31948 struct jffs2_unknown_node marker = {
31949 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
31950 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
31951- .totlen = cpu_to_je32(c->cleanmarker_size)
31952+ .totlen = cpu_to_je32(c->cleanmarker_size),
31953+ .hdr_crc = cpu_to_je32(0)
31954 };
31955
31956 jffs2_prealloc_raw_node_refs(c, jeb, 1);
16454cff
MT
31957diff -urNp linux-2.6.38.1/fs/jffs2/summary.h linux-2.6.38.1/fs/jffs2/summary.h
31958--- linux-2.6.38.1/fs/jffs2/summary.h 2011-03-14 21:20:32.000000000 -0400
31959+++ linux-2.6.38.1/fs/jffs2/summary.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
31960@@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
31961
31962 #define jffs2_sum_active() (0)
31963 #define jffs2_sum_init(a) (0)
31964-#define jffs2_sum_exit(a)
31965-#define jffs2_sum_disable_collecting(a)
31966+#define jffs2_sum_exit(a) do {} while (0)
31967+#define jffs2_sum_disable_collecting(a) do {} while (0)
31968 #define jffs2_sum_is_disabled(a) (0)
31969-#define jffs2_sum_reset_collected(a)
31970+#define jffs2_sum_reset_collected(a) do {} while (0)
31971 #define jffs2_sum_add_kvec(a,b,c,d) (0)
31972-#define jffs2_sum_move_collected(a,b)
31973+#define jffs2_sum_move_collected(a,b) do {} while (0)
31974 #define jffs2_sum_write_sumnode(a) (0)
31975-#define jffs2_sum_add_padding_mem(a,b)
31976-#define jffs2_sum_add_inode_mem(a,b,c)
31977-#define jffs2_sum_add_dirent_mem(a,b,c)
31978-#define jffs2_sum_add_xattr_mem(a,b,c)
31979-#define jffs2_sum_add_xref_mem(a,b,c)
31980+#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
31981+#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
31982+#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
31983+#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
31984+#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
31985 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
31986
31987 #endif /* CONFIG_JFFS2_SUMMARY */
16454cff
MT
31988diff -urNp linux-2.6.38.1/fs/jffs2/wbuf.c linux-2.6.38.1/fs/jffs2/wbuf.c
31989--- linux-2.6.38.1/fs/jffs2/wbuf.c 2011-03-14 21:20:32.000000000 -0400
31990+++ linux-2.6.38.1/fs/jffs2/wbuf.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
31991@@ -1012,7 +1012,8 @@ static const struct jffs2_unknown_node o
31992 {
31993 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
31994 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
31995- .totlen = constant_cpu_to_je32(8)
31996+ .totlen = constant_cpu_to_je32(8),
31997+ .hdr_crc = constant_cpu_to_je32(0)
31998 };
31999
32000 /*
16454cff
MT
32001diff -urNp linux-2.6.38.1/fs/Kconfig.binfmt linux-2.6.38.1/fs/Kconfig.binfmt
32002--- linux-2.6.38.1/fs/Kconfig.binfmt 2011-03-14 21:20:32.000000000 -0400
32003+++ linux-2.6.38.1/fs/Kconfig.binfmt 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
32004@@ -86,7 +86,7 @@ config HAVE_AOUT
32005
32006 config BINFMT_AOUT
32007 tristate "Kernel support for a.out and ECOFF binaries"
32008- depends on HAVE_AOUT
32009+ depends on HAVE_AOUT && BROKEN
32010 ---help---
32011 A.out (Assembler.OUTput) is a set of formats for libraries and
32012 executables used in the earliest versions of UNIX. Linux used
16454cff
MT
32013diff -urNp linux-2.6.38.1/fs/lockd/svc.c linux-2.6.38.1/fs/lockd/svc.c
32014--- linux-2.6.38.1/fs/lockd/svc.c 2011-03-14 21:20:32.000000000 -0400
32015+++ linux-2.6.38.1/fs/lockd/svc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 32016@@ -41,7 +41,7 @@
ae4e228f
MT
32017
32018 static struct svc_program nlmsvc_program;
32019
32020-struct nlmsvc_binding * nlmsvc_ops;
32021+const struct nlmsvc_binding * nlmsvc_ops;
32022 EXPORT_SYMBOL_GPL(nlmsvc_ops);
32023
32024 static DEFINE_MUTEX(nlmsvc_mutex);
16454cff
MT
32025diff -urNp linux-2.6.38.1/fs/locks.c linux-2.6.38.1/fs/locks.c
32026--- linux-2.6.38.1/fs/locks.c 2011-03-14 21:20:32.000000000 -0400
32027+++ linux-2.6.38.1/fs/locks.c 2011-03-21 18:31:35.000000000 -0400
32028@@ -2044,16 +2044,16 @@ void locks_remove_flock(struct file *fil
58c5fc13
MT
32029 return;
32030
32031 if (filp->f_op && filp->f_op->flock) {
32032- struct file_lock fl = {
32033+ struct file_lock flock = {
32034 .fl_pid = current->tgid,
32035 .fl_file = filp,
32036 .fl_flags = FL_FLOCK,
32037 .fl_type = F_UNLCK,
32038 .fl_end = OFFSET_MAX,
32039 };
32040- filp->f_op->flock(filp, F_SETLKW, &fl);
32041- if (fl.fl_ops && fl.fl_ops->fl_release_private)
32042- fl.fl_ops->fl_release_private(&fl);
32043+ filp->f_op->flock(filp, F_SETLKW, &flock);
32044+ if (flock.fl_ops && flock.fl_ops->fl_release_private)
32045+ flock.fl_ops->fl_release_private(&flock);
32046 }
32047
bc901d79 32048 lock_flocks();
16454cff
MT
32049diff -urNp linux-2.6.38.1/fs/namei.c linux-2.6.38.1/fs/namei.c
32050--- linux-2.6.38.1/fs/namei.c 2011-03-14 21:20:32.000000000 -0400
32051+++ linux-2.6.38.1/fs/namei.c 2011-03-25 18:59:30.000000000 -0400
32052@@ -226,14 +226,6 @@ int generic_permission(struct inode *ino
bc901d79
MT
32053 return ret;
32054
32055 /*
32056- * Read/write DACs are always overridable.
32057- * Executable DACs are overridable if at least one exec bit is set.
32058- */
32059- if (!(mask & MAY_EXEC) || execute_ok(inode))
32060- if (capable(CAP_DAC_OVERRIDE))
32061- return 0;
32062-
32063- /*
32064 * Searching includes executable on directories, else just read.
32065 */
32066 mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
16454cff 32067@@ -241,6 +233,14 @@ int generic_permission(struct inode *ino
bc901d79
MT
32068 if (capable(CAP_DAC_READ_SEARCH))
32069 return 0;
32070
32071+ /*
32072+ * Read/write DACs are always overridable.
32073+ * Executable DACs are overridable if at least one exec bit is set.
32074+ */
32075+ if (!(mask & MAY_EXEC) || execute_ok(inode))
32076+ if (capable(CAP_DAC_OVERRIDE))
32077+ return 0;
32078+
32079 return -EACCES;
32080 }
32081
16454cff
MT
32082@@ -687,7 +687,8 @@ static inline int exec_permission(struct
32083 if (ret == -ECHILD)
32084 return ret;
bc901d79
MT
32085
32086- if (capable(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH))
32087+ if (capable_nolog(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH) ||
32088+ capable(CAP_DAC_OVERRIDE))
32089 goto ok;
32090
32091 return ret;
16454cff 32092@@ -775,7 +776,7 @@ __do_follow_link(const struct path *link
df50ba0c
MT
32093 *p = dentry->d_inode->i_op->follow_link(dentry, nd);
32094 error = PTR_ERR(*p);
32095 if (!IS_ERR(*p)) {
58c5fc13
MT
32096- char *s = nd_get_link(nd);
32097+ const char *s = nd_get_link(nd);
32098 error = 0;
32099 if (s)
32100 error = __vfs_follow_link(nd, s);
16454cff 32101@@ -814,6 +815,13 @@ static inline int do_follow_link(struct
58c5fc13
MT
32102 err = security_inode_follow_link(path->dentry, nd);
32103 if (err)
32104 goto loop;
32105+
32106+ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
32107+ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
32108+ err = -EACCES;
32109+ goto loop;
32110+ }
32111+
32112 current->link_count++;
32113 current->total_link_count++;
32114 nd->depth++;
16454cff 32115@@ -1505,13 +1513,36 @@ return_reval:
58c5fc13 32116 return_base:
16454cff
MT
32117 if (nameidata_drop_rcu_last_maybe(nd))
32118 return -ECHILD;
32119+
df50ba0c 32120+ if (!(nd->flags & LOOKUP_PARENT) && !gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
16454cff
MT
32121+ err = -ENOENT;
32122+ goto err_and_ret;
58c5fc13 32123+ }
16454cff 32124+
58c5fc13
MT
32125 return 0;
32126 out_dput:
16454cff
MT
32127 if (!(nd->flags & LOOKUP_RCU))
32128 path_put_conditional(&next, nd);
58c5fc13
MT
32129 break;
32130 }
16454cff
MT
32131+#ifdef CONFIG_GRKERNSEC
32132+ /* we do this because we can't operate here on an rcu'd dentry,
32133+ acquire a properly-referenced copy
32134+ */
32135+ if (nameidata_drop_rcu_last_maybe(nd))
32136+ return -ECHILD;
32137+#endif
32138+
df50ba0c 32139+ if (!(nd->flags & LOOKUP_PARENT) && !gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
58c5fc13
MT
32140+ err = -ENOENT;
32141+
16454cff
MT
32142+err_and_ret:
32143+#ifndef CONFIG_GRKERNSEC
32144+ /* since we convert to ref-walk above, always put the path if we reach
32145+ here
32146+ */
32147 if (!(nd->flags & LOOKUP_RCU))
32148+#endif
32149 path_put(&nd->path);
58c5fc13
MT
32150 return_err:
32151 return err;
16454cff
MT
32152@@ -1738,6 +1769,9 @@ static int do_path_lookup(int dfd, const
32153 }
32154
32155 if (likely(!retval)) {
32156+ if (*name != '/' && nd->path.dentry && nd->inode && !gr_chroot_fchdir(nd->path.dentry, nd->path.mnt))
32157+ return -ENOENT;
32158+
32159 if (unlikely(!audit_dummy_context())) {
32160 if (nd->path.dentry && nd->inode)
32161 audit_inode(name, nd->path.dentry);
32162@@ -1789,6 +1823,7 @@ int vfs_path_lookup(struct dentry *dentr
32163 nd->inode = nd->path.dentry->d_inode;
32164
32165 retval = path_walk(name, nd);
32166+
32167 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
32168 nd->inode))
32169 audit_inode(name, nd->path.dentry);
32170@@ -2078,6 +2113,30 @@ int vfs_create(struct inode *dir, struct
bc901d79
MT
32171 return error;
32172 }
32173
32174+/*
32175+ * Note that while the flag value (low two bits) for sys_open means:
32176+ * 00 - read-only
32177+ * 01 - write-only
32178+ * 10 - read-write
32179+ * 11 - special
32180+ * it is changed into
32181+ * 00 - no permissions needed
32182+ * 01 - read-permission
32183+ * 10 - write-permission
32184+ * 11 - read-write
32185+ * for the internal routines (ie open_namei()/follow_link() etc)
32186+ * This is more logical, and also allows the 00 "no perm needed"
32187+ * to be used for symlinks (where the permissions are checked
32188+ * later).
32189+ *
32190+*/
32191+static inline int open_to_namei_flags(int flag)
32192+{
32193+ if ((flag+1) & O_ACCMODE)
32194+ flag++;
32195+ return flag;
32196+}
32197+
32198 int may_open(struct path *path, int acc_mode, int flag)
32199 {
32200 struct dentry *dentry = path->dentry;
16454cff 32201@@ -2126,7 +2185,27 @@ int may_open(struct path *path, int acc_
bc901d79
MT
32202 /*
32203 * Ensure there are no outstanding leases on the file.
32204 */
32205- return break_lease(inode, flag);
32206+ error = break_lease(inode, flag);
16454cff 32207+
bc901d79
MT
32208+ if (error)
32209+ return error;
32210+
32211+ if (gr_handle_rofs_blockwrite(dentry, path->mnt, acc_mode)) {
32212+ error = -EPERM;
32213+ goto exit;
32214+ }
32215+
32216+ if (gr_handle_rawio(inode)) {
32217+ error = -EPERM;
32218+ goto exit;
32219+ }
32220+
32221+ if (!gr_acl_handle_open(dentry, path->mnt, open_to_namei_flags(flag))) {
32222+ error = -EACCES;
32223+ goto exit;
32224+ }
32225+exit:
32226+ return error;
32227 }
32228
16454cff
MT
32229 static int handle_truncate(struct file *filp)
32230@@ -2161,6 +2240,12 @@ static int __open_namei_create(struct na
bc901d79 32231 {
58c5fc13
MT
32232 int error;
32233 struct dentry *dir = nd->path.dentry;
bc901d79
MT
32234+ int flag = open_to_namei_flags(open_flag);
32235+
32236+ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
58c5fc13
MT
32237+ error = -EACCES;
32238+ goto out_unlock;
32239+ }
bc901d79 32240
58c5fc13
MT
32241 if (!IS_POSIXACL(dir->d_inode))
32242 mode &= ~current_umask();
16454cff 32243@@ -2168,6 +2253,8 @@ static int __open_namei_create(struct na
58c5fc13
MT
32244 if (error)
32245 goto out_unlock;
32246 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
32247+ if (!error)
32248+ gr_handle_create(path->dentry, nd->path.mnt);
32249 out_unlock:
32250 mutex_unlock(&dir->d_inode->i_mutex);
32251 dput(nd->path.dentry);
16454cff 32252@@ -2179,30 +2266,6 @@ out_unlock:
bc901d79
MT
32253 return may_open(&nd->path, 0, open_flag & ~O_TRUNC);
32254 }
32255
32256-/*
32257- * Note that while the flag value (low two bits) for sys_open means:
32258- * 00 - read-only
32259- * 01 - write-only
32260- * 10 - read-write
32261- * 11 - special
32262- * it is changed into
32263- * 00 - no permissions needed
32264- * 01 - read-permission
32265- * 10 - write-permission
32266- * 11 - read-write
32267- * for the internal routines (ie open_namei()/follow_link() etc)
32268- * This is more logical, and also allows the 00 "no perm needed"
32269- * to be used for symlinks (where the permissions are checked
32270- * later).
32271- *
32272-*/
32273-static inline int open_to_namei_flags(int flag)
32274-{
32275- if ((flag+1) & O_ACCMODE)
32276- flag++;
32277- return flag;
32278-}
32279-
32280 static int open_will_truncate(int flag, struct inode *inode)
32281 {
32282 /*
16454cff 32283@@ -2273,6 +2336,7 @@ static struct file *do_last(struct namei
df50ba0c
MT
32284 int mode, const char *pathname)
32285 {
32286 struct dentry *dir = nd->path.dentry;
32287+ int flag = open_to_namei_flags(open_flag);
32288 struct file *filp;
32289 int error = -EISDIR;
32290
16454cff 32291@@ -2351,6 +2415,14 @@ static struct file *do_last(struct namei
58c5fc13
MT
32292 /*
32293 * It already exists.
32294 */
32295+
bc901d79
MT
32296+ /* only check if O_CREAT is specified, all other checks need to go
32297+ into may_open */
32298+ if (gr_handle_fifo(path->dentry, path->mnt, dir, flag, acc_mode)) {
58c5fc13
MT
32299+ error = -EACCES;
32300+ goto exit_mutex_unlock;
32301+ }
32302+
32303 mutex_unlock(&dir->d_inode->i_mutex);
df50ba0c 32304 audit_inode(pathname, path->dentry);
58c5fc13 32305
16454cff
MT
32306@@ -2467,6 +2539,7 @@ struct file *do_filp_open(int dfd, const
32307 if (!nd.inode->i_op->lookup)
32308 goto out_path2;
32309 }
32310+
32311 audit_inode(pathname, nd.path.dentry);
32312 filp = finish_open(&nd, open_flag, acc_mode);
32313 out2:
32314@@ -2500,6 +2573,7 @@ reval:
32315
32316 error = path_walk_simple(pathname, &nd);
32317 }
32318+
32319 if (unlikely(error))
32320 goto out_filp;
32321 if (unlikely(!audit_dummy_context()))
32322@@ -2534,6 +2608,11 @@ reval:
32323 error = security_inode_follow_link(link.dentry, &nd);
c52201e0
MT
32324 if (error)
32325 goto exit_dput;
16454cff
MT
32326+ if (gr_handle_follow_link(link.dentry->d_parent->d_inode,
32327+ link.dentry->d_inode, link.dentry, nd.path.mnt)) {
c52201e0
MT
32328+ error = -EACCES;
32329+ goto exit_dput;
32330+ }
16454cff 32331 error = __do_follow_link(&link, &nd, &cookie);
c52201e0 32332 if (unlikely(error)) {
16454cff
MT
32333 if (!IS_ERR(cookie) && linki->i_op->put_link)
32334@@ -2704,6 +2783,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
58c5fc13
MT
32335 error = may_mknod(mode);
32336 if (error)
32337 goto out_dput;
32338+
32339+ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
32340+ error = -EPERM;
32341+ goto out_dput;
32342+ }
32343+
32344+ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
32345+ error = -EACCES;
32346+ goto out_dput;
32347+ }
32348+
32349 error = mnt_want_write(nd.path.mnt);
32350 if (error)
32351 goto out_dput;
16454cff 32352@@ -2724,6 +2814,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
58c5fc13
MT
32353 }
32354 out_drop_write:
32355 mnt_drop_write(nd.path.mnt);
32356+
32357+ if (!error)
32358+ gr_handle_create(dentry, nd.path.mnt);
32359 out_dput:
32360 dput(dentry);
32361 out_unlock:
16454cff 32362@@ -2776,6 +2869,11 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
58c5fc13
MT
32363 if (IS_ERR(dentry))
32364 goto out_unlock;
32365
32366+ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
32367+ error = -EACCES;
32368+ goto out_dput;
32369+ }
32370+
32371 if (!IS_POSIXACL(nd.path.dentry->d_inode))
32372 mode &= ~current_umask();
32373 error = mnt_want_write(nd.path.mnt);
16454cff 32374@@ -2787,6 +2885,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
58c5fc13
MT
32375 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
32376 out_drop_write:
32377 mnt_drop_write(nd.path.mnt);
32378+
32379+ if (!error)
32380+ gr_handle_create(dentry, nd.path.mnt);
32381+
32382 out_dput:
32383 dput(dentry);
32384 out_unlock:
16454cff 32385@@ -2866,6 +2968,8 @@ static long do_rmdir(int dfd, const char
58c5fc13
MT
32386 char * name;
32387 struct dentry *dentry;
32388 struct nameidata nd;
32389+ ino_t saved_ino = 0;
32390+ dev_t saved_dev = 0;
32391
32392 error = user_path_parent(dfd, pathname, &nd, &name);
32393 if (error)
16454cff 32394@@ -2890,6 +2994,19 @@ static long do_rmdir(int dfd, const char
58c5fc13
MT
32395 error = PTR_ERR(dentry);
32396 if (IS_ERR(dentry))
32397 goto exit2;
32398+
32399+ if (dentry->d_inode != NULL) {
32400+ if (dentry->d_inode->i_nlink <= 1) {
32401+ saved_ino = dentry->d_inode->i_ino;
16454cff 32402+ saved_dev = gr_get_dev_from_dentry(dentry);
58c5fc13
MT
32403+ }
32404+
32405+ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
32406+ error = -EACCES;
32407+ goto exit3;
32408+ }
32409+ }
32410+
32411 error = mnt_want_write(nd.path.mnt);
32412 if (error)
32413 goto exit3;
16454cff 32414@@ -2897,6 +3014,8 @@ static long do_rmdir(int dfd, const char
58c5fc13
MT
32415 if (error)
32416 goto exit4;
32417 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
32418+ if (!error && (saved_dev || saved_ino))
32419+ gr_handle_delete(saved_ino, saved_dev);
32420 exit4:
32421 mnt_drop_write(nd.path.mnt);
32422 exit3:
16454cff 32423@@ -2959,6 +3078,8 @@ static long do_unlinkat(int dfd, const c
58c5fc13
MT
32424 struct dentry *dentry;
32425 struct nameidata nd;
32426 struct inode *inode = NULL;
32427+ ino_t saved_ino = 0;
32428+ dev_t saved_dev = 0;
32429
32430 error = user_path_parent(dfd, pathname, &nd, &name);
32431 if (error)
16454cff 32432@@ -2978,8 +3099,17 @@ static long do_unlinkat(int dfd, const c
58c5fc13
MT
32433 if (nd.last.name[nd.last.len])
32434 goto slashes;
32435 inode = dentry->d_inode;
32436- if (inode)
32437+ if (inode) {
bc901d79 32438 ihold(inode);
58c5fc13
MT
32439+ if (inode->i_nlink <= 1) {
32440+ saved_ino = inode->i_ino;
16454cff 32441+ saved_dev = gr_get_dev_from_dentry(dentry);
58c5fc13 32442+ }
58c5fc13
MT
32443+ if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
32444+ error = -EACCES;
32445+ goto exit2;
32446+ }
32447+ }
32448 error = mnt_want_write(nd.path.mnt);
32449 if (error)
32450 goto exit2;
16454cff 32451@@ -2987,6 +3117,8 @@ static long do_unlinkat(int dfd, const c
58c5fc13
MT
32452 if (error)
32453 goto exit3;
32454 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
32455+ if (!error && (saved_ino || saved_dev))
32456+ gr_handle_delete(saved_ino, saved_dev);
32457 exit3:
32458 mnt_drop_write(nd.path.mnt);
32459 exit2:
16454cff 32460@@ -3064,6 +3196,11 @@ SYSCALL_DEFINE3(symlinkat, const char __
58c5fc13
MT
32461 if (IS_ERR(dentry))
32462 goto out_unlock;
32463
32464+ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
32465+ error = -EACCES;
32466+ goto out_dput;
32467+ }
32468+
32469 error = mnt_want_write(nd.path.mnt);
32470 if (error)
32471 goto out_dput;
16454cff 32472@@ -3071,6 +3208,8 @@ SYSCALL_DEFINE3(symlinkat, const char __
58c5fc13
MT
32473 if (error)
32474 goto out_drop_write;
32475 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
32476+ if (!error)
32477+ gr_handle_create(dentry, nd.path.mnt);
32478 out_drop_write:
32479 mnt_drop_write(nd.path.mnt);
32480 out_dput:
16454cff 32481@@ -3163,6 +3302,20 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
58c5fc13
MT
32482 error = PTR_ERR(new_dentry);
32483 if (IS_ERR(new_dentry))
32484 goto out_unlock;
32485+
32486+ if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
32487+ old_path.dentry->d_inode,
32488+ old_path.dentry->d_inode->i_mode, to)) {
32489+ error = -EACCES;
32490+ goto out_dput;
32491+ }
32492+
32493+ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
32494+ old_path.dentry, old_path.mnt, to)) {
32495+ error = -EACCES;
32496+ goto out_dput;
32497+ }
32498+
32499 error = mnt_want_write(nd.path.mnt);
32500 if (error)
32501 goto out_dput;
16454cff 32502@@ -3170,6 +3323,8 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
58c5fc13
MT
32503 if (error)
32504 goto out_drop_write;
32505 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
32506+ if (!error)
32507+ gr_handle_create(new_dentry, nd.path.mnt);
32508 out_drop_write:
32509 mnt_drop_write(nd.path.mnt);
32510 out_dput:
16454cff 32511@@ -3403,6 +3558,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
58c5fc13
MT
32512 if (new_dentry == trap)
32513 goto exit5;
32514
32515+ error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
32516+ old_dentry, old_dir->d_inode, oldnd.path.mnt,
32517+ to);
32518+ if (error)
32519+ goto exit5;
32520+
32521 error = mnt_want_write(oldnd.path.mnt);
32522 if (error)
32523 goto exit5;
16454cff 32524@@ -3412,6 +3573,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
58c5fc13
MT
32525 goto exit6;
32526 error = vfs_rename(old_dir->d_inode, old_dentry,
32527 new_dir->d_inode, new_dentry);
32528+ if (!error)
32529+ gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
32530+ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
32531 exit6:
32532 mnt_drop_write(oldnd.path.mnt);
32533 exit5:
16454cff
MT
32534diff -urNp linux-2.6.38.1/fs/namespace.c linux-2.6.38.1/fs/namespace.c
32535--- linux-2.6.38.1/fs/namespace.c 2011-03-14 21:20:32.000000000 -0400
32536+++ linux-2.6.38.1/fs/namespace.c 2011-03-21 18:31:35.000000000 -0400
32537@@ -1285,6 +1285,9 @@ static int do_umount(struct vfsmount *mn
58c5fc13
MT
32538 if (!(sb->s_flags & MS_RDONLY))
32539 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
32540 up_write(&sb->s_umount);
32541+
32542+ gr_log_remount(mnt->mnt_devname, retval);
32543+
32544 return retval;
32545 }
32546
16454cff 32547@@ -1304,6 +1307,9 @@ static int do_umount(struct vfsmount *mn
6892158b 32548 br_write_unlock(vfsmount_lock);
58c5fc13
MT
32549 up_write(&namespace_sem);
32550 release_mounts(&umount_list);
32551+
32552+ gr_log_unmount(mnt->mnt_devname, retval);
32553+
32554 return retval;
32555 }
32556
16454cff 32557@@ -2241,6 +2247,16 @@ long do_mount(char *dev_name, char *dir_
ae4e228f
MT
32558 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
32559 MS_STRICTATIME);
58c5fc13 32560
ae4e228f
MT
32561+ if (gr_handle_rofs_mount(path.dentry, path.mnt, mnt_flags)) {
32562+ retval = -EPERM;
32563+ goto dput_out;
32564+ }
32565+
58c5fc13
MT
32566+ if (gr_handle_chroot_mount(path.dentry, path.mnt, dev_name)) {
32567+ retval = -EPERM;
32568+ goto dput_out;
32569+ }
32570+
32571 if (flags & MS_REMOUNT)
32572 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
32573 data_page);
16454cff 32574@@ -2255,6 +2271,9 @@ long do_mount(char *dev_name, char *dir_
58c5fc13
MT
32575 dev_name, data_page);
32576 dput_out:
32577 path_put(&path);
32578+
32579+ gr_log_mount(dev_name, dir_name, retval);
32580+
32581 return retval;
32582 }
32583
16454cff 32584@@ -2483,6 +2502,12 @@ SYSCALL_DEFINE2(pivot_root, const char _
58c5fc13
MT
32585 goto out1;
32586 }
32587
32588+ if (gr_handle_chroot_pivot()) {
32589+ error = -EPERM;
32590+ path_put(&old);
32591+ goto out1;
32592+ }
32593+
6892158b
MT
32594 get_fs_root(current->fs, &root);
32595 down_write(&namespace_sem);
32596 mutex_lock(&old.dentry->d_inode->i_mutex);
16454cff
MT
32597diff -urNp linux-2.6.38.1/fs/nfs/inode.c linux-2.6.38.1/fs/nfs/inode.c
32598--- linux-2.6.38.1/fs/nfs/inode.c 2011-03-14 21:20:32.000000000 -0400
32599+++ linux-2.6.38.1/fs/nfs/inode.c 2011-03-21 18:31:35.000000000 -0400
32600@@ -998,16 +998,16 @@ static int nfs_size_need_update(const st
ae4e228f
MT
32601 return nfs_size_to_loff_t(fattr->size) > i_size_read(inode);
32602 }
32603
32604-static atomic_long_t nfs_attr_generation_counter;
32605+static atomic_long_unchecked_t nfs_attr_generation_counter;
32606
32607 static unsigned long nfs_read_attr_generation_counter(void)
32608 {
32609- return atomic_long_read(&nfs_attr_generation_counter);
32610+ return atomic_long_read_unchecked(&nfs_attr_generation_counter);
32611 }
32612
32613 unsigned long nfs_inc_attr_generation_counter(void)
32614 {
32615- return atomic_long_inc_return(&nfs_attr_generation_counter);
32616+ return atomic_long_inc_return_unchecked(&nfs_attr_generation_counter);
32617 }
32618
32619 void nfs_fattr_init(struct nfs_fattr *fattr)
16454cff
MT
32620diff -urNp linux-2.6.38.1/fs/nfs/nfs4proc.c linux-2.6.38.1/fs/nfs/nfs4proc.c
32621--- linux-2.6.38.1/fs/nfs/nfs4proc.c 2011-03-14 21:20:32.000000000 -0400
32622+++ linux-2.6.38.1/fs/nfs/nfs4proc.c 2011-03-21 18:31:35.000000000 -0400
32623@@ -1198,7 +1198,7 @@ static int _nfs4_do_open_reclaim(struct
58c5fc13
MT
32624 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
32625 {
32626 struct nfs_server *server = NFS_SERVER(state->inode);
32627- struct nfs4_exception exception = { };
32628+ struct nfs4_exception exception = {0, 0};
32629 int err;
32630 do {
32631 err = _nfs4_do_open_reclaim(ctx, state);
16454cff 32632@@ -1240,7 +1240,7 @@ static int _nfs4_open_delegation_recall(
58c5fc13
MT
32633
32634 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
32635 {
32636- struct nfs4_exception exception = { };
32637+ struct nfs4_exception exception = {0, 0};
32638 struct nfs_server *server = NFS_SERVER(state->inode);
32639 int err;
32640 do {
16454cff 32641@@ -1615,7 +1615,7 @@ static int _nfs4_open_expired(struct nfs
ae4e228f 32642 static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
58c5fc13
MT
32643 {
32644 struct nfs_server *server = NFS_SERVER(state->inode);
32645- struct nfs4_exception exception = { };
32646+ struct nfs4_exception exception = {0, 0};
32647 int err;
32648
32649 do {
16454cff 32650@@ -1730,7 +1730,7 @@ out_err:
58c5fc13
MT
32651
32652 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)
32653 {
32654- struct nfs4_exception exception = { };
32655+ struct nfs4_exception exception = {0, 0};
32656 struct nfs4_state *res;
32657 int status;
32658
16454cff 32659@@ -1821,7 +1821,7 @@ static int nfs4_do_setattr(struct inode
58c5fc13
MT
32660 struct nfs4_state *state)
32661 {
32662 struct nfs_server *server = NFS_SERVER(inode);
32663- struct nfs4_exception exception = { };
32664+ struct nfs4_exception exception = {0, 0};
32665 int err;
32666 do {
32667 err = nfs4_handle_exception(server,
16454cff 32668@@ -2111,7 +2111,7 @@ static int _nfs4_server_capabilities(str
58c5fc13
MT
32669
32670 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
32671 {
32672- struct nfs4_exception exception = { };
32673+ struct nfs4_exception exception = {0, 0};
32674 int err;
32675 do {
32676 err = nfs4_handle_exception(server,
16454cff 32677@@ -2145,7 +2145,7 @@ static int _nfs4_lookup_root(struct nfs_
58c5fc13
MT
32678 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
32679 struct nfs_fsinfo *info)
32680 {
32681- struct nfs4_exception exception = { };
32682+ struct nfs4_exception exception = {0, 0};
32683 int err;
32684 do {
32685 err = nfs4_handle_exception(server,
16454cff 32686@@ -2233,7 +2233,7 @@ static int _nfs4_proc_getattr(struct nfs
58c5fc13
MT
32687
32688 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
32689 {
32690- struct nfs4_exception exception = { };
32691+ struct nfs4_exception exception = {0, 0};
32692 int err;
32693 do {
32694 err = nfs4_handle_exception(server,
16454cff 32695@@ -2321,7 +2321,7 @@ static int nfs4_proc_lookupfh(struct nfs
58c5fc13
MT
32696 struct qstr *name, struct nfs_fh *fhandle,
32697 struct nfs_fattr *fattr)
32698 {
32699- struct nfs4_exception exception = { };
32700+ struct nfs4_exception exception = {0, 0};
32701 int err;
32702 do {
32703 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
16454cff 32704@@ -2350,7 +2350,7 @@ static int _nfs4_proc_lookup(struct inod
58c5fc13
MT
32705
32706 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
32707 {
32708- struct nfs4_exception exception = { };
32709+ struct nfs4_exception exception = {0, 0};
32710 int err;
32711 do {
32712 err = nfs4_handle_exception(NFS_SERVER(dir),
16454cff 32713@@ -2417,7 +2417,7 @@ static int _nfs4_proc_access(struct inod
58c5fc13
MT
32714
32715 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
32716 {
32717- struct nfs4_exception exception = { };
32718+ struct nfs4_exception exception = {0, 0};
32719 int err;
32720 do {
32721 err = nfs4_handle_exception(NFS_SERVER(inode),
16454cff 32722@@ -2473,7 +2473,7 @@ static int _nfs4_proc_readlink(struct in
58c5fc13
MT
32723 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
32724 unsigned int pgbase, unsigned int pglen)
32725 {
32726- struct nfs4_exception exception = { };
32727+ struct nfs4_exception exception = {0, 0};
32728 int err;
32729 do {
32730 err = nfs4_handle_exception(NFS_SERVER(inode),
16454cff 32731@@ -2568,7 +2568,7 @@ out:
58c5fc13
MT
32732
32733 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
32734 {
32735- struct nfs4_exception exception = { };
32736+ struct nfs4_exception exception = {0, 0};
32737 int err;
32738 do {
32739 err = nfs4_handle_exception(NFS_SERVER(dir),
16454cff 32740@@ -2673,7 +2673,7 @@ out:
58c5fc13
MT
32741 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
32742 struct inode *new_dir, struct qstr *new_name)
32743 {
32744- struct nfs4_exception exception = { };
32745+ struct nfs4_exception exception = {0, 0};
32746 int err;
32747 do {
32748 err = nfs4_handle_exception(NFS_SERVER(old_dir),
16454cff 32749@@ -2722,7 +2722,7 @@ out:
58c5fc13
MT
32750
32751 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
32752 {
32753- struct nfs4_exception exception = { };
32754+ struct nfs4_exception exception = {0, 0};
32755 int err;
32756 do {
32757 err = nfs4_handle_exception(NFS_SERVER(inode),
16454cff 32758@@ -2814,7 +2814,7 @@ out:
58c5fc13
MT
32759 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
32760 struct page *page, unsigned int len, struct iattr *sattr)
32761 {
32762- struct nfs4_exception exception = { };
32763+ struct nfs4_exception exception = {0, 0};
32764 int err;
32765 do {
32766 err = nfs4_handle_exception(NFS_SERVER(dir),
16454cff 32767@@ -2845,7 +2845,7 @@ out:
58c5fc13
MT
32768 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
32769 struct iattr *sattr)
32770 {
32771- struct nfs4_exception exception = { };
32772+ struct nfs4_exception exception = {0, 0};
32773 int err;
16454cff
MT
32774
32775 sattr->ia_mode &= ~current_umask();
32776@@ -2899,7 +2899,7 @@ static int _nfs4_proc_readdir(struct den
58c5fc13 32777 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
bc901d79 32778 u64 cookie, struct page **pages, unsigned int count, int plus)
58c5fc13
MT
32779 {
32780- struct nfs4_exception exception = { };
32781+ struct nfs4_exception exception = {0, 0};
32782 int err;
32783 do {
32784 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
16454cff 32785@@ -2947,7 +2947,7 @@ out:
58c5fc13
MT
32786 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
32787 struct iattr *sattr, dev_t rdev)
32788 {
32789- struct nfs4_exception exception = { };
32790+ struct nfs4_exception exception = {0, 0};
32791 int err;
16454cff
MT
32792
32793 sattr->ia_mode &= ~current_umask();
32794@@ -2981,7 +2981,7 @@ static int _nfs4_proc_statfs(struct nfs_
58c5fc13
MT
32795
32796 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
32797 {
32798- struct nfs4_exception exception = { };
32799+ struct nfs4_exception exception = {0, 0};
32800 int err;
32801 do {
32802 err = nfs4_handle_exception(server,
16454cff 32803@@ -3012,7 +3012,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
58c5fc13
MT
32804
32805 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
32806 {
32807- struct nfs4_exception exception = { };
32808+ struct nfs4_exception exception = {0, 0};
32809 int err;
32810
32811 do {
16454cff 32812@@ -3058,7 +3058,7 @@ static int _nfs4_proc_pathconf(struct nf
58c5fc13
MT
32813 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
32814 struct nfs_pathconf *pathconf)
32815 {
32816- struct nfs4_exception exception = { };
32817+ struct nfs4_exception exception = {0, 0};
32818 int err;
32819
32820 do {
16454cff 32821@@ -3404,7 +3404,7 @@ out_free:
58c5fc13
MT
32822
32823 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
32824 {
32825- struct nfs4_exception exception = { };
32826+ struct nfs4_exception exception = {0, 0};
32827 ssize_t ret;
32828 do {
32829 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
16454cff 32830@@ -3479,7 +3479,7 @@ static int __nfs4_proc_set_acl(struct in
58c5fc13
MT
32831
32832 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
32833 {
32834- struct nfs4_exception exception = { };
32835+ struct nfs4_exception exception = {0, 0};
32836 int err;
32837 do {
32838 err = nfs4_handle_exception(NFS_SERVER(inode),
16454cff 32839@@ -3760,7 +3760,7 @@ out:
58c5fc13
MT
32840 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
32841 {
32842 struct nfs_server *server = NFS_SERVER(inode);
32843- struct nfs4_exception exception = { };
32844+ struct nfs4_exception exception = {0, 0};
32845 int err;
32846 do {
32847 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
16454cff 32848@@ -3834,7 +3834,7 @@ out:
58c5fc13
MT
32849
32850 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
32851 {
32852- struct nfs4_exception exception = { };
32853+ struct nfs4_exception exception = {0, 0};
32854 int err;
32855
32856 do {
16454cff 32857@@ -4239,7 +4239,7 @@ static int _nfs4_do_setlk(struct nfs4_st
58c5fc13
MT
32858 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
32859 {
32860 struct nfs_server *server = NFS_SERVER(state->inode);
32861- struct nfs4_exception exception = { };
32862+ struct nfs4_exception exception = {0, 0};
32863 int err;
32864
32865 do {
16454cff 32866@@ -4257,7 +4257,7 @@ static int nfs4_lock_reclaim(struct nfs4
58c5fc13
MT
32867 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
32868 {
32869 struct nfs_server *server = NFS_SERVER(state->inode);
32870- struct nfs4_exception exception = { };
32871+ struct nfs4_exception exception = {0, 0};
32872 int err;
32873
32874 err = nfs4_set_lock_state(state, request);
16454cff 32875@@ -4321,7 +4321,7 @@ out:
58c5fc13
MT
32876
32877 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
32878 {
32879- struct nfs4_exception exception = { };
32880+ struct nfs4_exception exception = {0, 0};
32881 int err;
32882
32883 do {
16454cff 32884@@ -4381,7 +4381,7 @@ nfs4_proc_lock(struct file *filp, int cm
58c5fc13
MT
32885 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
32886 {
32887 struct nfs_server *server = NFS_SERVER(state->inode);
32888- struct nfs4_exception exception = { };
32889+ struct nfs4_exception exception = {0, 0};
32890 int err;
32891
32892 err = nfs4_set_lock_state(state, fl);
16454cff
MT
32893diff -urNp linux-2.6.38.1/fs/nfsd/lockd.c linux-2.6.38.1/fs/nfsd/lockd.c
32894--- linux-2.6.38.1/fs/nfsd/lockd.c 2011-03-14 21:20:32.000000000 -0400
32895+++ linux-2.6.38.1/fs/nfsd/lockd.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
32896@@ -61,7 +61,7 @@ nlm_fclose(struct file *filp)
32897 fput(filp);
58c5fc13
MT
32898 }
32899
ae4e228f
MT
32900-static struct nlmsvc_binding nfsd_nlm_ops = {
32901+static const struct nlmsvc_binding nfsd_nlm_ops = {
32902 .fopen = nlm_fopen, /* open file for locking */
32903 .fclose = nlm_fclose, /* close file */
58c5fc13 32904 };
16454cff
MT
32905diff -urNp linux-2.6.38.1/fs/nfsd/nfsctl.c linux-2.6.38.1/fs/nfsd/nfsctl.c
32906--- linux-2.6.38.1/fs/nfsd/nfsctl.c 2011-03-14 21:20:32.000000000 -0400
32907+++ linux-2.6.38.1/fs/nfsd/nfsctl.c 2011-03-21 18:31:35.000000000 -0400
32908@@ -180,7 +180,7 @@ static int export_features_open(struct i
ae4e228f 32909 return single_open(file, export_features_show, NULL);
58c5fc13
MT
32910 }
32911
ae4e228f
MT
32912-static struct file_operations export_features_operations = {
32913+static const struct file_operations export_features_operations = {
32914 .open = export_features_open,
32915 .read = seq_read,
32916 .llseek = seq_lseek,
16454cff
MT
32917diff -urNp linux-2.6.38.1/fs/nfsd/vfs.c linux-2.6.38.1/fs/nfsd/vfs.c
32918--- linux-2.6.38.1/fs/nfsd/vfs.c 2011-03-14 21:20:32.000000000 -0400
32919+++ linux-2.6.38.1/fs/nfsd/vfs.c 2011-03-21 18:31:35.000000000 -0400
32920@@ -898,7 +898,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, st
ae4e228f
MT
32921 } else {
32922 oldfs = get_fs();
32923 set_fs(KERNEL_DS);
32924- host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
32925+ host_err = vfs_readv(file, (__force struct iovec __user *)vec, vlen, &offset);
32926 set_fs(oldfs);
32927 }
32928
16454cff 32929@@ -1002,7 +1002,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
ae4e228f
MT
32930
32931 /* Write the data. */
32932 oldfs = get_fs(); set_fs(KERNEL_DS);
32933- host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
32934+ host_err = vfs_writev(file, (__force struct iovec __user *)vec, vlen, &offset);
32935 set_fs(oldfs);
32936 if (host_err < 0)
32937 goto out_nfserr;
16454cff 32938@@ -1518,7 +1518,7 @@ nfsd_readlink(struct svc_rqst *rqstp, st
ae4e228f 32939 */
58c5fc13 32940
ae4e228f
MT
32941 oldfs = get_fs(); set_fs(KERNEL_DS);
32942- host_err = inode->i_op->readlink(dentry, buf, *lenp);
32943+ host_err = inode->i_op->readlink(dentry, (__force char __user *)buf, *lenp);
32944 set_fs(oldfs);
58c5fc13 32945
ae4e228f 32946 if (host_err < 0)
16454cff
MT
32947diff -urNp linux-2.6.38.1/fs/nls/nls_base.c linux-2.6.38.1/fs/nls/nls_base.c
32948--- linux-2.6.38.1/fs/nls/nls_base.c 2011-03-14 21:20:32.000000000 -0400
32949+++ linux-2.6.38.1/fs/nls/nls_base.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
32950@@ -41,7 +41,7 @@ static const struct utf8_table utf8_tabl
32951 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
32952 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
32953 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
32954- {0, /* end of table */}
32955+ {0, 0, 0, 0, 0, /* end of table */}
32956 };
32957
32958 #define UNICODE_MAX 0x0010ffff
16454cff
MT
32959diff -urNp linux-2.6.38.1/fs/ntfs/dir.c linux-2.6.38.1/fs/ntfs/dir.c
32960--- linux-2.6.38.1/fs/ntfs/dir.c 2011-03-14 21:20:32.000000000 -0400
32961+++ linux-2.6.38.1/fs/ntfs/dir.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
32962@@ -1329,7 +1329,7 @@ find_next_index_buffer:
32963 ia = (INDEX_ALLOCATION*)(kaddr + (ia_pos & ~PAGE_CACHE_MASK &
32964 ~(s64)(ndir->itype.index.block_size - 1)));
32965 /* Bounds checks. */
32966- if (unlikely((u8*)ia < kaddr || (u8*)ia > kaddr + PAGE_CACHE_SIZE)) {
32967+ if (unlikely(!kaddr || (u8*)ia < kaddr || (u8*)ia > kaddr + PAGE_CACHE_SIZE)) {
32968 ntfs_error(sb, "Out of bounds check failed. Corrupt directory "
32969 "inode 0x%lx or driver bug.", vdir->i_ino);
32970 goto err_out;
16454cff
MT
32971diff -urNp linux-2.6.38.1/fs/ntfs/file.c linux-2.6.38.1/fs/ntfs/file.c
32972--- linux-2.6.38.1/fs/ntfs/file.c 2011-03-14 21:20:32.000000000 -0400
32973+++ linux-2.6.38.1/fs/ntfs/file.c 2011-03-21 18:31:35.000000000 -0400
32974@@ -2222,6 +2222,6 @@ const struct inode_operations ntfs_file_
58c5fc13
MT
32975 #endif /* NTFS_RW */
32976 };
32977
32978-const struct file_operations ntfs_empty_file_ops = {};
ae4e228f 32979+const struct file_operations ntfs_empty_file_ops __read_only;
58c5fc13
MT
32980
32981-const struct inode_operations ntfs_empty_inode_ops = {};
ae4e228f 32982+const struct inode_operations ntfs_empty_inode_ops __read_only;
16454cff
MT
32983diff -urNp linux-2.6.38.1/fs/ocfs2/localalloc.c linux-2.6.38.1/fs/ocfs2/localalloc.c
32984--- linux-2.6.38.1/fs/ocfs2/localalloc.c 2011-03-14 21:20:32.000000000 -0400
32985+++ linux-2.6.38.1/fs/ocfs2/localalloc.c 2011-03-21 18:31:35.000000000 -0400
57199397 32986@@ -1307,7 +1307,7 @@ static int ocfs2_local_alloc_slide_windo
58c5fc13
MT
32987 goto bail;
32988 }
32989
32990- atomic_inc(&osb->alloc_stats.moves);
32991+ atomic_inc_unchecked(&osb->alloc_stats.moves);
32992
58c5fc13 32993 bail:
57199397 32994 if (handle)
16454cff
MT
32995diff -urNp linux-2.6.38.1/fs/ocfs2/ocfs2.h linux-2.6.38.1/fs/ocfs2/ocfs2.h
32996--- linux-2.6.38.1/fs/ocfs2/ocfs2.h 2011-03-14 21:20:32.000000000 -0400
32997+++ linux-2.6.38.1/fs/ocfs2/ocfs2.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 32998@@ -230,11 +230,11 @@ enum ocfs2_vol_state
58c5fc13
MT
32999
33000 struct ocfs2_alloc_stats
33001 {
33002- atomic_t moves;
33003- atomic_t local_data;
33004- atomic_t bitmap_data;
33005- atomic_t bg_allocs;
33006- atomic_t bg_extends;
33007+ atomic_unchecked_t moves;
33008+ atomic_unchecked_t local_data;
33009+ atomic_unchecked_t bitmap_data;
33010+ atomic_unchecked_t bg_allocs;
33011+ atomic_unchecked_t bg_extends;
33012 };
33013
33014 enum ocfs2_local_alloc_state
16454cff
MT
33015diff -urNp linux-2.6.38.1/fs/ocfs2/suballoc.c linux-2.6.38.1/fs/ocfs2/suballoc.c
33016--- linux-2.6.38.1/fs/ocfs2/suballoc.c 2011-03-14 21:20:32.000000000 -0400
33017+++ linux-2.6.38.1/fs/ocfs2/suballoc.c 2011-03-21 18:31:35.000000000 -0400
6892158b 33018@@ -877,7 +877,7 @@ static int ocfs2_reserve_suballoc_bits(s
58c5fc13
MT
33019 mlog_errno(status);
33020 goto bail;
33021 }
33022- atomic_inc(&osb->alloc_stats.bg_extends);
33023+ atomic_inc_unchecked(&osb->alloc_stats.bg_extends);
33024
33025 /* You should never ask for this much metadata */
33026 BUG_ON(bits_wanted >
bc901d79 33027@@ -2012,7 +2012,7 @@ int ocfs2_claim_metadata(handle_t *handl
58c5fc13
MT
33028 mlog_errno(status);
33029 goto bail;
33030 }
57199397
MT
33031- atomic_inc(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
33032+ atomic_inc_unchecked(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
58c5fc13 33033
57199397
MT
33034 *suballoc_loc = res.sr_bg_blkno;
33035 *suballoc_bit_start = res.sr_bit_offset;
bc901d79 33036@@ -2219,7 +2219,7 @@ int ocfs2_claim_new_inode(handle_t *hand
58c5fc13
MT
33037 mlog_errno(status);
33038 goto bail;
33039 }
57199397
MT
33040- atomic_inc(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
33041+ atomic_inc_unchecked(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
58c5fc13 33042
57199397 33043 BUG_ON(res.sr_bits != 1);
58c5fc13 33044
bc901d79 33045@@ -2324,7 +2324,7 @@ int __ocfs2_claim_clusters(handle_t *han
58c5fc13
MT
33046 cluster_start,
33047 num_clusters);
33048 if (!status)
33049- atomic_inc(&osb->alloc_stats.local_data);
33050+ atomic_inc_unchecked(&osb->alloc_stats.local_data);
33051 } else {
33052 if (min_clusters > (osb->bitmap_cpg - 1)) {
33053 /* The only paths asking for contiguousness
bc901d79 33054@@ -2350,7 +2350,7 @@ int __ocfs2_claim_clusters(handle_t *han
58c5fc13 33055 ocfs2_desc_bitmap_to_cluster_off(ac->ac_inode,
57199397
MT
33056 res.sr_bg_blkno,
33057 res.sr_bit_offset);
58c5fc13
MT
33058- atomic_inc(&osb->alloc_stats.bitmap_data);
33059+ atomic_inc_unchecked(&osb->alloc_stats.bitmap_data);
57199397 33060 *num_clusters = res.sr_bits;
58c5fc13
MT
33061 }
33062 }
16454cff
MT
33063diff -urNp linux-2.6.38.1/fs/ocfs2/super.c linux-2.6.38.1/fs/ocfs2/super.c
33064--- linux-2.6.38.1/fs/ocfs2/super.c 2011-03-14 21:20:32.000000000 -0400
33065+++ linux-2.6.38.1/fs/ocfs2/super.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 33066@@ -297,11 +297,11 @@ static int ocfs2_osb_dump(struct ocfs2_s
58c5fc13
MT
33067 "%10s => GlobalAllocs: %d LocalAllocs: %d "
33068 "SubAllocs: %d LAWinMoves: %d SAExtends: %d\n",
33069 "Stats",
33070- atomic_read(&osb->alloc_stats.bitmap_data),
33071- atomic_read(&osb->alloc_stats.local_data),
33072- atomic_read(&osb->alloc_stats.bg_allocs),
33073- atomic_read(&osb->alloc_stats.moves),
33074- atomic_read(&osb->alloc_stats.bg_extends));
33075+ atomic_read_unchecked(&osb->alloc_stats.bitmap_data),
33076+ atomic_read_unchecked(&osb->alloc_stats.local_data),
33077+ atomic_read_unchecked(&osb->alloc_stats.bg_allocs),
33078+ atomic_read_unchecked(&osb->alloc_stats.moves),
33079+ atomic_read_unchecked(&osb->alloc_stats.bg_extends));
33080
33081 out += snprintf(buf + out, len - out,
33082 "%10s => State: %u Descriptor: %llu Size: %u bits "
16454cff 33083@@ -2141,11 +2141,11 @@ static int ocfs2_initialize_super(struct
58c5fc13 33084 spin_lock_init(&osb->osb_xattr_lock);
df50ba0c 33085 ocfs2_init_steal_slots(osb);
58c5fc13
MT
33086
33087- atomic_set(&osb->alloc_stats.moves, 0);
33088- atomic_set(&osb->alloc_stats.local_data, 0);
33089- atomic_set(&osb->alloc_stats.bitmap_data, 0);
33090- atomic_set(&osb->alloc_stats.bg_allocs, 0);
33091- atomic_set(&osb->alloc_stats.bg_extends, 0);
33092+ atomic_set_unchecked(&osb->alloc_stats.moves, 0);
33093+ atomic_set_unchecked(&osb->alloc_stats.local_data, 0);
33094+ atomic_set_unchecked(&osb->alloc_stats.bitmap_data, 0);
33095+ atomic_set_unchecked(&osb->alloc_stats.bg_allocs, 0);
33096+ atomic_set_unchecked(&osb->alloc_stats.bg_extends, 0);
33097
33098 /* Copy the blockcheck stats from the superblock probe */
33099 osb->osb_ecc_stats = *stats;
16454cff
MT
33100diff -urNp linux-2.6.38.1/fs/ocfs2/symlink.c linux-2.6.38.1/fs/ocfs2/symlink.c
33101--- linux-2.6.38.1/fs/ocfs2/symlink.c 2011-03-14 21:20:32.000000000 -0400
33102+++ linux-2.6.38.1/fs/ocfs2/symlink.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 33103@@ -148,7 +148,7 @@ bail:
58c5fc13 33104
ae4e228f
MT
33105 static void ocfs2_fast_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
33106 {
33107- char *link = nd_get_link(nd);
33108+ const char *link = nd_get_link(nd);
33109 if (!IS_ERR(link))
33110 kfree(link);
58c5fc13 33111 }
16454cff
MT
33112diff -urNp linux-2.6.38.1/fs/open.c linux-2.6.38.1/fs/open.c
33113--- linux-2.6.38.1/fs/open.c 2011-03-14 21:20:32.000000000 -0400
33114+++ linux-2.6.38.1/fs/open.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
33115@@ -112,6 +112,10 @@ static long do_sys_truncate(const char _
33116 error = locks_verify_truncate(inode, NULL, length);
33117 if (!error)
33118 error = security_path_truncate(&path);
58c5fc13 33119+
bc901d79
MT
33120+ if (!error && !gr_acl_handle_truncate(path.dentry, path.mnt))
33121+ error = -EACCES;
33122+
33123 if (!error)
33124 error = do_truncate(path.dentry, length, 0, NULL);
33125
16454cff 33126@@ -358,6 +362,9 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con
58c5fc13
MT
33127 if (__mnt_is_readonly(path.mnt))
33128 res = -EROFS;
33129
33130+ if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
33131+ res = -EACCES;
33132+
33133 out_path_release:
33134 path_put(&path);
33135 out:
16454cff 33136@@ -384,6 +391,8 @@ SYSCALL_DEFINE1(chdir, const char __user
58c5fc13
MT
33137 if (error)
33138 goto dput_and_out;
33139
33140+ gr_log_chdir(path.dentry, path.mnt);
33141+
33142 set_fs_pwd(current->fs, &path);
33143
33144 dput_and_out:
16454cff 33145@@ -410,6 +419,13 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd
58c5fc13
MT
33146 goto out_putf;
33147
6892158b 33148 error = inode_permission(inode, MAY_EXEC | MAY_CHDIR);
58c5fc13
MT
33149+
33150+ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
33151+ error = -EPERM;
33152+
33153+ if (!error)
33154+ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
33155+
33156 if (!error)
33157 set_fs_pwd(current->fs, &file->f_path);
33158 out_putf:
16454cff 33159@@ -438,7 +454,18 @@ SYSCALL_DEFINE1(chroot, const char __use
ae4e228f 33160 if (error)
58c5fc13
MT
33161 goto dput_and_out;
33162
33163+ if (gr_handle_chroot_chroot(path.dentry, path.mnt))
33164+ goto dput_and_out;
33165+
33166+ if (gr_handle_chroot_caps(&path)) {
33167+ error = -ENOMEM;
33168+ goto dput_and_out;
33169+ }
33170+
33171 set_fs_root(current->fs, &path);
33172+
33173+ gr_handle_chroot_chdir(&path);
33174+
33175 error = 0;
33176 dput_and_out:
33177 path_put(&path);
16454cff 33178@@ -466,12 +493,25 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd
58c5fc13
MT
33179 err = mnt_want_write_file(file);
33180 if (err)
33181 goto out_putf;
33182+
6892158b
MT
33183 mutex_lock(&inode->i_mutex);
33184+
33185+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
58c5fc13 33186+ err = -EACCES;
6892158b 33187+ goto out_unlock;
58c5fc13
MT
33188+ }
33189+
ae4e228f
MT
33190 err = security_path_chmod(dentry, file->f_vfsmnt, mode);
33191 if (err)
6892158b
MT
33192 goto out_unlock;
33193 if (mode == (mode_t) -1)
33194 mode = inode->i_mode;
33195+
33196+ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
33197+ err = -EACCES;
33198+ goto out_unlock;
33199+ }
33200+
33201 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
33202 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
58c5fc13 33203 err = notify_change(dentry, &newattrs);
16454cff 33204@@ -499,12 +539,25 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
58c5fc13
MT
33205 error = mnt_want_write(path.mnt);
33206 if (error)
33207 goto dput_and_out;
6892158b
MT
33208+
33209 mutex_lock(&inode->i_mutex);
58c5fc13
MT
33210+
33211+ if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
33212+ error = -EACCES;
6892158b 33213+ goto out_unlock;
58c5fc13
MT
33214+ }
33215+
ae4e228f
MT
33216 error = security_path_chmod(path.dentry, path.mnt, mode);
33217 if (error)
33218 goto out_unlock;
58c5fc13
MT
33219 if (mode == (mode_t) -1)
33220 mode = inode->i_mode;
33221+
33222+ if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
33223+ error = -EACCES;
ae4e228f 33224+ goto out_unlock;
58c5fc13
MT
33225+ }
33226+
33227 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
33228 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
33229 error = notify_change(path.dentry, &newattrs);
16454cff 33230@@ -528,6 +581,9 @@ static int chown_common(struct path *pat
58c5fc13
MT
33231 int error;
33232 struct iattr newattrs;
33233
ae4e228f 33234+ if (!gr_acl_handle_chown(path->dentry, path->mnt))
58c5fc13
MT
33235+ return -EACCES;
33236+
33237 newattrs.ia_valid = ATTR_CTIME;
33238 if (user != (uid_t) -1) {
33239 newattrs.ia_valid |= ATTR_UID;
16454cff 33240@@ -898,7 +954,10 @@ long do_sys_open(int dfd, const char __u
bc901d79
MT
33241 if (!IS_ERR(tmp)) {
33242 fd = get_unused_fd_flags(flags);
33243 if (fd >= 0) {
33244- struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
33245+ struct file *f;
33246+ /* don't allow to be set by userland */
33247+ flags &= ~FMODE_GREXEC;
33248+ f = do_filp_open(dfd, tmp, flags, mode, 0);
33249 if (IS_ERR(f)) {
33250 put_unused_fd(fd);
33251 fd = PTR_ERR(f);
16454cff
MT
33252diff -urNp linux-2.6.38.1/fs/partitions/ldm.c linux-2.6.38.1/fs/partitions/ldm.c
33253--- linux-2.6.38.1/fs/partitions/ldm.c 2011-03-14 21:20:32.000000000 -0400
33254+++ linux-2.6.38.1/fs/partitions/ldm.c 2011-03-21 18:31:35.000000000 -0400
33255@@ -1313,7 +1313,7 @@ static bool ldm_frag_add (const u8 *data
317566c1 33256 goto found;
c52201e0 33257 }
317566c1
MT
33258
33259- f = kmalloc (sizeof (*f) + size*num, GFP_KERNEL);
33260+ f = kmalloc (size*num + sizeof (*f), GFP_KERNEL);
33261 if (!f) {
33262 ldm_crit ("Out of memory.");
33263 return false;
16454cff
MT
33264diff -urNp linux-2.6.38.1/fs/pipe.c linux-2.6.38.1/fs/pipe.c
33265--- linux-2.6.38.1/fs/pipe.c 2011-03-14 21:20:32.000000000 -0400
33266+++ linux-2.6.38.1/fs/pipe.c 2011-03-21 18:31:35.000000000 -0400
57199397 33267@@ -420,9 +420,9 @@ redo:
ae4e228f
MT
33268 }
33269 if (bufs) /* More to do? */
33270 continue;
33271- if (!pipe->writers)
33272+ if (!atomic_read(&pipe->writers))
33273 break;
33274- if (!pipe->waiting_writers) {
33275+ if (!atomic_read(&pipe->waiting_writers)) {
33276 /* syscall merging: Usually we must not sleep
33277 * if O_NONBLOCK is set, or if we got some data.
33278 * But if a writer sleeps in kernel space, then
57199397 33279@@ -481,7 +481,7 @@ pipe_write(struct kiocb *iocb, const str
ae4e228f
MT
33280 mutex_lock(&inode->i_mutex);
33281 pipe = inode->i_pipe;
33282
33283- if (!pipe->readers) {
33284+ if (!atomic_read(&pipe->readers)) {
33285 send_sig(SIGPIPE, current, 0);
33286 ret = -EPIPE;
33287 goto out;
57199397 33288@@ -530,7 +530,7 @@ redo1:
ae4e228f
MT
33289 for (;;) {
33290 int bufs;
33291
33292- if (!pipe->readers) {
33293+ if (!atomic_read(&pipe->readers)) {
33294 send_sig(SIGPIPE, current, 0);
33295 if (!ret)
33296 ret = -EPIPE;
57199397 33297@@ -616,9 +616,9 @@ redo2:
ae4e228f
MT
33298 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
33299 do_wakeup = 0;
33300 }
33301- pipe->waiting_writers++;
33302+ atomic_inc(&pipe->waiting_writers);
33303 pipe_wait(pipe);
33304- pipe->waiting_writers--;
33305+ atomic_dec(&pipe->waiting_writers);
33306 }
33307 out:
33308 mutex_unlock(&inode->i_mutex);
57199397 33309@@ -685,7 +685,7 @@ pipe_poll(struct file *filp, poll_table
ae4e228f
MT
33310 mask = 0;
33311 if (filp->f_mode & FMODE_READ) {
33312 mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
33313- if (!pipe->writers && filp->f_version != pipe->w_counter)
33314+ if (!atomic_read(&pipe->writers) && filp->f_version != pipe->w_counter)
33315 mask |= POLLHUP;
33316 }
33317
57199397 33318@@ -695,7 +695,7 @@ pipe_poll(struct file *filp, poll_table
ae4e228f
MT
33319 * Most Unices do not set POLLERR for FIFOs but on Linux they
33320 * behave exactly like pipes for poll().
33321 */
33322- if (!pipe->readers)
33323+ if (!atomic_read(&pipe->readers))
33324 mask |= POLLERR;
33325 }
33326
57199397 33327@@ -709,10 +709,10 @@ pipe_release(struct inode *inode, int de
ae4e228f
MT
33328
33329 mutex_lock(&inode->i_mutex);
33330 pipe = inode->i_pipe;
33331- pipe->readers -= decr;
33332- pipe->writers -= decw;
33333+ atomic_sub(decr, &pipe->readers);
33334+ atomic_sub(decw, &pipe->writers);
33335
33336- if (!pipe->readers && !pipe->writers) {
33337+ if (!atomic_read(&pipe->readers) && !atomic_read(&pipe->writers)) {
33338 free_pipe_info(inode);
33339 } else {
16454cff 33340 wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP);
57199397 33341@@ -802,7 +802,7 @@ pipe_read_open(struct inode *inode, stru
ae4e228f
MT
33342
33343 if (inode->i_pipe) {
33344 ret = 0;
33345- inode->i_pipe->readers++;
33346+ atomic_inc(&inode->i_pipe->readers);
33347 }
33348
33349 mutex_unlock(&inode->i_mutex);
57199397 33350@@ -819,7 +819,7 @@ pipe_write_open(struct inode *inode, str
ae4e228f
MT
33351
33352 if (inode->i_pipe) {
33353 ret = 0;
33354- inode->i_pipe->writers++;
33355+ atomic_inc(&inode->i_pipe->writers);
33356 }
33357
33358 mutex_unlock(&inode->i_mutex);
57199397 33359@@ -837,9 +837,9 @@ pipe_rdwr_open(struct inode *inode, stru
ae4e228f
MT
33360 if (inode->i_pipe) {
33361 ret = 0;
33362 if (filp->f_mode & FMODE_READ)
33363- inode->i_pipe->readers++;
33364+ atomic_inc(&inode->i_pipe->readers);
33365 if (filp->f_mode & FMODE_WRITE)
33366- inode->i_pipe->writers++;
33367+ atomic_inc(&inode->i_pipe->writers);
33368 }
33369
33370 mutex_unlock(&inode->i_mutex);
57199397 33371@@ -931,7 +931,7 @@ void free_pipe_info(struct inode *inode)
58c5fc13
MT
33372 inode->i_pipe = NULL;
33373 }
33374
33375-static struct vfsmount *pipe_mnt __read_mostly;
33376+struct vfsmount *pipe_mnt __read_mostly;
ae4e228f
MT
33377
33378 /*
33379 * pipefs_dname() is called from d_path().
bc901d79 33380@@ -961,7 +961,8 @@ static struct inode * get_pipe_inode(voi
ae4e228f
MT
33381 goto fail_iput;
33382 inode->i_pipe = pipe;
33383
33384- pipe->readers = pipe->writers = 1;
33385+ atomic_set(&pipe->readers, 1);
33386+ atomic_set(&pipe->writers, 1);
33387 inode->i_fop = &rdwr_pipefifo_fops;
33388
58c5fc13 33389 /*
16454cff
MT
33390diff -urNp linux-2.6.38.1/fs/proc/array.c linux-2.6.38.1/fs/proc/array.c
33391--- linux-2.6.38.1/fs/proc/array.c 2011-03-14 21:20:32.000000000 -0400
33392+++ linux-2.6.38.1/fs/proc/array.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
33393@@ -60,6 +60,7 @@
33394 #include <linux/tty.h>
33395 #include <linux/string.h>
33396 #include <linux/mman.h>
33397+#include <linux/grsecurity.h>
33398 #include <linux/proc_fs.h>
33399 #include <linux/ioport.h>
33400 #include <linux/uaccess.h>
33401@@ -337,6 +338,21 @@ static void task_cpus_allowed(struct seq
16454cff 33402 seq_putc(m, '\n');
57199397
MT
33403 }
33404
33405+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
33406+static inline void task_pax(struct seq_file *m, struct task_struct *p)
33407+{
33408+ if (p->mm)
33409+ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
33410+ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
33411+ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
33412+ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
33413+ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
33414+ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
33415+ else
33416+ seq_printf(m, "PaX:\t-----\n");
33417+}
33418+#endif
33419+
33420 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
33421 struct pid *pid, struct task_struct *task)
33422 {
317566c1 33423@@ -354,9 +370,24 @@ int proc_pid_status(struct seq_file *m,
c52201e0
MT
33424 task_cpus_allowed(m, task);
33425 cpuset_task_status_allowed(m, task);
57199397
MT
33426 task_context_switch_counts(m, task);
33427+
33428+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
33429+ task_pax(m, task);
33430+#endif
6892158b
MT
33431+
33432+#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
33433+ task_grsec_rbac(m, task);
33434+#endif
57199397
MT
33435+
33436 return 0;
33437 }
33438
33439+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33440+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
33441+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
33442+ _mm->pax_flags & MF_PAX_SEGMEXEC))
33443+#endif
33444+
33445 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
33446 struct pid *pid, struct task_struct *task, int whole)
33447 {
317566c1 33448@@ -449,6 +480,19 @@ static int do_task_stat(struct seq_file
57199397
MT
33449 gtime = task->gtime;
33450 }
33451
33452+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33453+ if (PAX_RAND_FLAGS(mm)) {
33454+ eip = 0;
33455+ esp = 0;
33456+ wchan = 0;
33457+ }
33458+#endif
33459+#ifdef CONFIG_GRKERNSEC_HIDESYM
33460+ wchan = 0;
33461+ eip =0;
33462+ esp =0;
33463+#endif
33464+
33465 /* scale priority and nice values from timeslices to -20..20 */
33466 /* to make it look like a "normal" Unix priority/nice value */
33467 priority = task_prio(task);
317566c1 33468@@ -489,9 +533,15 @@ static int do_task_stat(struct seq_file
57199397
MT
33469 vsize,
33470 mm ? get_mm_rss(mm) : 0,
33471 rsslim,
33472+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33473+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
33474+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
33475+ PAX_RAND_FLAGS(mm) ? 0 : ((permitted && mm) ? mm->start_stack : 0),
33476+#else
33477 mm ? mm->start_code : 0,
33478 mm ? mm->end_code : 0,
33479 (permitted && mm) ? mm->start_stack : 0,
33480+#endif
33481 esp,
33482 eip,
33483 /* The signal information here is obsolete.
317566c1 33484@@ -544,3 +594,10 @@ int proc_pid_statm(struct seq_file *m, s
57199397
MT
33485
33486 return 0;
33487 }
33488+
33489+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
33490+int proc_pid_ipaddr(struct task_struct *task, char *buffer)
33491+{
33492+ return sprintf(buffer, "%pI4\n", &task->signal->curr_ip);
33493+}
33494+#endif
16454cff
MT
33495diff -urNp linux-2.6.38.1/fs/proc/base.c linux-2.6.38.1/fs/proc/base.c
33496--- linux-2.6.38.1/fs/proc/base.c 2011-03-14 21:20:32.000000000 -0400
33497+++ linux-2.6.38.1/fs/proc/base.c 2011-03-26 11:59:10.000000000 -0400
6892158b 33498@@ -104,6 +104,22 @@ struct pid_entry {
57199397
MT
33499 union proc_op op;
33500 };
33501
33502+struct getdents_callback {
33503+ struct linux_dirent __user * current_dir;
33504+ struct linux_dirent __user * previous;
33505+ struct file * file;
33506+ int count;
33507+ int error;
33508+};
33509+
33510+static int gr_fake_filldir(void * __buf, const char *name, int namlen,
33511+ loff_t offset, u64 ino, unsigned int d_type)
33512+{
33513+ struct getdents_callback * buf = (struct getdents_callback *) __buf;
33514+ buf->error = -EINVAL;
33515+ return 0;
33516+}
33517+
33518 #define NOD(NAME, MODE, IOP, FOP, OP) { \
33519 .name = (NAME), \
33520 .len = sizeof(NAME) - 1, \
6892158b 33521@@ -203,6 +219,9 @@ static int check_mem_permission(struct t
57199397
MT
33522 if (task == current)
33523 return 0;
33524
33525+ if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
33526+ return -EPERM;
33527+
33528 /*
33529 * If current is actively ptrace'ing, and would also be
33530 * permitted to freshly attach with ptrace now, permit it.
6892158b 33531@@ -250,6 +269,9 @@ static int proc_pid_cmdline(struct task_
57199397
MT
33532 if (!mm->arg_end)
33533 goto out_mm; /* Shh! No looking before we're done */
33534
33535+ if (gr_acl_handle_procpidmem(task))
33536+ goto out_mm;
33537+
33538 len = mm->arg_end - mm->arg_start;
33539
33540 if (len > PAGE_SIZE)
6892158b 33541@@ -277,12 +299,28 @@ out:
57199397
MT
33542 return res;
33543 }
33544
33545+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33546+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
33547+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
33548+ _mm->pax_flags & MF_PAX_SEGMEXEC))
33549+#endif
33550+
33551 static int proc_pid_auxv(struct task_struct *task, char *buffer)
33552 {
33553 int res = 0;
33554 struct mm_struct *mm = get_task_mm(task);
33555 if (mm) {
33556 unsigned int nwords = 0;
33557+
33558+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6892158b
MT
33559+ /* allow if we're currently ptracing this task */
33560+ if (PAX_RAND_FLAGS(mm) &&
33561+ (!(task->ptrace & PT_PTRACED) || (task->parent != current))) {
57199397
MT
33562+ mmput(mm);
33563+ return res;
33564+ }
33565+#endif
33566+
33567 do {
33568 nwords += 2;
33569 } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
6892158b
MT
33570@@ -296,7 +334,7 @@ static int proc_pid_auxv(struct task_str
33571 }
33572
33573
33574-#ifdef CONFIG_KALLSYMS
33575+#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33576 /*
33577 * Provides a wchan file via kallsyms in a proper one-value-per-file format.
33578 * Returns the resolved symbol. If that fails, simply return the address.
33579@@ -318,7 +356,7 @@ static int proc_pid_wchan(struct task_st
57199397
MT
33580 }
33581 #endif /* CONFIG_KALLSYMS */
33582
33583-#ifdef CONFIG_STACKTRACE
33584+#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33585
33586 #define MAX_STACK_TRACE_DEPTH 64
33587
16454cff 33588@@ -503,7 +541,7 @@ static int proc_pid_limits(struct task_s
57199397
MT
33589 return count;
33590 }
33591
33592-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
33593+#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
33594 static int proc_pid_syscall(struct task_struct *task, char *buffer)
33595 {
33596 long nr;
16454cff
MT
33597@@ -528,7 +566,7 @@ static int proc_pid_syscall(struct task_
33598 /************************************************************************/
33599
33600 /* permission checks */
33601-static int proc_fd_access_allowed(struct inode *inode)
33602+static int proc_fd_access_allowed(struct inode *inode, unsigned int log)
33603 {
33604 struct task_struct *task;
33605 int allowed = 0;
33606@@ -538,7 +576,10 @@ static int proc_fd_access_allowed(struct
33607 */
33608 task = get_proc_task(inode);
33609 if (task) {
33610- allowed = ptrace_may_access(task, PTRACE_MODE_READ);
33611+ if (log)
33612+ allowed = ptrace_may_access_log(task, PTRACE_MODE_READ);
33613+ else
33614+ allowed = ptrace_may_access(task, PTRACE_MODE_READ);
33615 put_task_struct(task);
33616 }
33617 return allowed;
33618@@ -917,6 +958,9 @@ static ssize_t environ_read(struct file
57199397
MT
33619 if (!task)
33620 goto out_no_task;
33621
33622+ if (gr_acl_handle_procpidmem(task))
33623+ goto out;
33624+
33625 if (!ptrace_may_access(task, PTRACE_MODE_READ))
33626 goto out;
33627
16454cff
MT
33628@@ -1606,7 +1650,7 @@ static void *proc_pid_follow_link(struct
33629 path_put(&nd->path);
33630
33631 /* Are we allowed to snoop on the tasks file descriptors? */
33632- if (!proc_fd_access_allowed(inode))
33633+ if (!proc_fd_access_allowed(inode,0))
33634 goto out;
33635
33636 error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
33637@@ -1645,8 +1689,18 @@ static int proc_pid_readlink(struct dent
33638 struct path path;
33639
33640 /* Are we allowed to snoop on the tasks file descriptors? */
33641- if (!proc_fd_access_allowed(inode))
33642- goto out;
33643+ /* logging this is needed for learning on chromium to work properly,
33644+ but we don't want to flood the logs from 'ps' which does a readlink
33645+ on /proc/fd/2 of tasks in the listing, nor do we want 'ps' to learn
33646+ CAP_SYS_PTRACE as it's not necessary for its basic functionality
33647+ */
33648+ if (dentry->d_name.name[0] == '2' && dentry->d_name.name[1] == '\0') {
33649+ if (!proc_fd_access_allowed(inode,0))
33650+ goto out;
33651+ } else {
33652+ if (!proc_fd_access_allowed(inode,1))
33653+ goto out;
33654+ }
33655
33656 error = PROC_I(inode)->op.proc_get_link(inode, &path);
33657 if (error)
33658@@ -1712,7 +1766,11 @@ static struct inode *proc_pid_make_inode
57199397
MT
33659 rcu_read_lock();
33660 cred = __task_cred(task);
33661 inode->i_uid = cred->euid;
33662+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33663+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
33664+#else
33665 inode->i_gid = cred->egid;
33666+#endif
33667 rcu_read_unlock();
33668 }
33669 security_task_to_inode(task, inode);
16454cff 33670@@ -1730,6 +1788,9 @@ static int pid_getattr(struct vfsmount *
57199397
MT
33671 struct inode *inode = dentry->d_inode;
33672 struct task_struct *task;
33673 const struct cred *cred;
33674+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33675+ const struct cred *tmpcred = current_cred();
33676+#endif
33677
33678 generic_fillattr(inode, stat);
33679
16454cff 33680@@ -1737,12 +1798,34 @@ static int pid_getattr(struct vfsmount *
57199397
MT
33681 stat->uid = 0;
33682 stat->gid = 0;
33683 task = pid_task(proc_pid(inode), PIDTYPE_PID);
33684+
33685+ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
33686+ rcu_read_unlock();
33687+ return -ENOENT;
33688+ }
33689+
33690 if (task) {
33691+ cred = __task_cred(task);
33692+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33693+ if (!tmpcred->uid || (tmpcred->uid == cred->uid)
33694+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33695+ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
33696+#endif
33697+ )
33698+#endif
33699 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
33700+#ifdef CONFIG_GRKERNSEC_PROC_USER
33701+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
33702+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33703+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
33704+#endif
33705 task_dumpable(task)) {
33706- cred = __task_cred(task);
33707 stat->uid = cred->euid;
33708+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33709+ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
33710+#else
33711 stat->gid = cred->egid;
33712+#endif
33713 }
33714 }
33715 rcu_read_unlock();
16454cff 33716@@ -1780,11 +1863,20 @@ static int pid_revalidate(struct dentry
57199397
MT
33717
33718 if (task) {
33719 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
33720+#ifdef CONFIG_GRKERNSEC_PROC_USER
33721+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
33722+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33723+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
33724+#endif
33725 task_dumpable(task)) {
33726 rcu_read_lock();
33727 cred = __task_cred(task);
33728 inode->i_uid = cred->euid;
33729+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33730+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
33731+#else
33732 inode->i_gid = cred->egid;
33733+#endif
33734 rcu_read_unlock();
33735 } else {
33736 inode->i_uid = 0;
16454cff 33737@@ -1905,7 +1997,8 @@ static int proc_fd_info(struct inode *in
57199397
MT
33738 int fd = proc_fd(inode);
33739
33740 if (task) {
33741- files = get_files_struct(task);
33742+ if (!gr_acl_handle_procpidmem(task))
33743+ files = get_files_struct(task);
33744 put_task_struct(task);
33745 }
33746 if (files) {
16454cff
MT
33747@@ -2165,15 +2258,25 @@ static const struct file_operations proc
33748 */
33749 static int proc_fd_permission(struct inode *inode, int mask, unsigned int flags)
57199397 33750 {
57199397 33751+ struct task_struct *task;
16454cff 33752 int rv;
57199397 33753
16454cff
MT
33754 if (flags & IPERM_FLAG_RCU)
33755 return -ECHILD;
33756 rv = generic_permission(inode, mask, flags, NULL);
57199397
MT
33757- if (rv == 0)
33758- return 0;
33759+
33760 if (task_pid(current) == proc_pid(inode))
33761 rv = 0;
33762+
33763+ task = get_proc_task(inode);
33764+ if (task == NULL)
33765+ return rv;
33766+
33767+ if (gr_acl_handle_procpidmem(task))
33768+ rv = -EACCES;
33769+
33770+ put_task_struct(task);
33771+
33772 return rv;
33773 }
33774
16454cff 33775@@ -2283,6 +2386,9 @@ static struct dentry *proc_pident_lookup
57199397
MT
33776 if (!task)
33777 goto out_no_task;
33778
33779+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
33780+ goto out;
33781+
33782 /*
33783 * Yes, it does not scale. And it should not. Don't add
33784 * new entries into /proc/<tgid>/ without very good reasons.
16454cff 33785@@ -2327,6 +2433,9 @@ static int proc_pident_readdir(struct fi
57199397
MT
33786 if (!task)
33787 goto out_no_task;
33788
33789+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
33790+ goto out;
33791+
33792 ret = 0;
33793 i = filp->f_pos;
33794 switch (i) {
16454cff 33795@@ -2597,7 +2706,7 @@ static void *proc_self_follow_link(struc
57199397
MT
33796 static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
33797 void *cookie)
33798 {
33799- char *s = nd_get_link(nd);
33800+ const char *s = nd_get_link(nd);
33801 if (!IS_ERR(s))
33802 __putname(s);
33803 }
16454cff
MT
33804@@ -2777,7 +2886,7 @@ static const struct pid_entry tgid_base_
33805 REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations),
57199397
MT
33806 #endif
33807 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
33808-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
33809+#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
33810 INF("syscall", S_IRUSR, proc_pid_syscall),
33811 #endif
33812 INF("cmdline", S_IRUGO, proc_pid_cmdline),
16454cff 33813@@ -2802,10 +2911,10 @@ static const struct pid_entry tgid_base_
6892158b
MT
33814 #ifdef CONFIG_SECURITY
33815 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
33816 #endif
33817-#ifdef CONFIG_KALLSYMS
33818+#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
57199397
MT
33819 INF("wchan", S_IRUGO, proc_pid_wchan),
33820 #endif
33821-#ifdef CONFIG_STACKTRACE
33822+#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33823 ONE("stack", S_IRUSR, proc_pid_stack),
33824 #endif
33825 #ifdef CONFIG_SCHEDSTATS
16454cff 33826@@ -2836,6 +2945,9 @@ static const struct pid_entry tgid_base_
57199397
MT
33827 #ifdef CONFIG_TASK_IO_ACCOUNTING
33828 INF("io", S_IRUGO, proc_tgid_io_accounting),
33829 #endif
33830+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
33831+ INF("ipaddr", S_IRUSR, proc_pid_ipaddr),
33832+#endif
33833 };
33834
33835 static int proc_tgid_base_readdir(struct file * filp,
16454cff 33836@@ -2961,7 +3073,14 @@ static struct dentry *proc_pid_instantia
57199397
MT
33837 if (!inode)
33838 goto out;
33839
33840+#ifdef CONFIG_GRKERNSEC_PROC_USER
33841+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
33842+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33843+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
33844+ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
33845+#else
33846 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
33847+#endif
33848 inode->i_op = &proc_tgid_base_inode_operations;
33849 inode->i_fop = &proc_tgid_base_operations;
33850 inode->i_flags|=S_IMMUTABLE;
16454cff 33851@@ -3003,7 +3122,11 @@ struct dentry *proc_pid_lookup(struct in
57199397
MT
33852 if (!task)
33853 goto out;
33854
33855+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
33856+ goto out_put_task;
33857+
33858 result = proc_pid_instantiate(dir, dentry, task, NULL);
33859+out_put_task:
33860 put_task_struct(task);
33861 out:
33862 return result;
16454cff 33863@@ -3068,6 +3191,11 @@ int proc_pid_readdir(struct file * filp,
57199397
MT
33864 {
33865 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
33866 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
33867+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33868+ const struct cred *tmpcred = current_cred();
33869+ const struct cred *itercred;
33870+#endif
33871+ filldir_t __filldir = filldir;
33872 struct tgid_iter iter;
33873 struct pid_namespace *ns;
33874
16454cff 33875@@ -3086,8 +3214,27 @@ int proc_pid_readdir(struct file * filp,
57199397
MT
33876 for (iter = next_tgid(ns, iter);
33877 iter.task;
33878 iter.tgid += 1, iter = next_tgid(ns, iter)) {
33879+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33880+ rcu_read_lock();
33881+ itercred = __task_cred(iter.task);
33882+#endif
33883+ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
33884+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33885+ || (tmpcred->uid && (itercred->uid != tmpcred->uid)
33886+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33887+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
33888+#endif
33889+ )
33890+#endif
33891+ )
33892+ __filldir = &gr_fake_filldir;
33893+ else
33894+ __filldir = filldir;
33895+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33896+ rcu_read_unlock();
33897+#endif
33898 filp->f_pos = iter.tgid + TGID_OFFSET;
33899- if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
33900+ if (proc_pid_fill_cache(filp, dirent, __filldir, iter) < 0) {
33901 put_task_struct(iter.task);
33902 goto out;
33903 }
16454cff 33904@@ -3114,7 +3261,7 @@ static const struct pid_entry tid_base_s
57199397
MT
33905 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
33906 #endif
33907 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
33908-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
33909+#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
33910 INF("syscall", S_IRUSR, proc_pid_syscall),
33911 #endif
33912 INF("cmdline", S_IRUGO, proc_pid_cmdline),
16454cff 33913@@ -3138,10 +3285,10 @@ static const struct pid_entry tid_base_s
6892158b
MT
33914 #ifdef CONFIG_SECURITY
33915 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
33916 #endif
33917-#ifdef CONFIG_KALLSYMS
33918+#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
57199397
MT
33919 INF("wchan", S_IRUGO, proc_pid_wchan),
33920 #endif
33921-#ifdef CONFIG_STACKTRACE
33922+#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33923 ONE("stack", S_IRUSR, proc_pid_stack),
33924 #endif
33925 #ifdef CONFIG_SCHEDSTATS
16454cff
MT
33926diff -urNp linux-2.6.38.1/fs/proc/cmdline.c linux-2.6.38.1/fs/proc/cmdline.c
33927--- linux-2.6.38.1/fs/proc/cmdline.c 2011-03-14 21:20:32.000000000 -0400
33928+++ linux-2.6.38.1/fs/proc/cmdline.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
33929@@ -23,7 +23,11 @@ static const struct file_operations cmdl
33930
33931 static int __init proc_cmdline_init(void)
33932 {
33933+#ifdef CONFIG_GRKERNSEC_PROC_ADD
33934+ proc_create_grsec("cmdline", 0, NULL, &cmdline_proc_fops);
33935+#else
33936 proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
33937+#endif
33938 return 0;
33939 }
33940 module_init(proc_cmdline_init);
16454cff
MT
33941diff -urNp linux-2.6.38.1/fs/proc/devices.c linux-2.6.38.1/fs/proc/devices.c
33942--- linux-2.6.38.1/fs/proc/devices.c 2011-03-14 21:20:32.000000000 -0400
33943+++ linux-2.6.38.1/fs/proc/devices.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
33944@@ -64,7 +64,11 @@ static const struct file_operations proc
33945
33946 static int __init proc_devices_init(void)
33947 {
33948+#ifdef CONFIG_GRKERNSEC_PROC_ADD
33949+ proc_create_grsec("devices", 0, NULL, &proc_devinfo_operations);
33950+#else
33951 proc_create("devices", 0, NULL, &proc_devinfo_operations);
33952+#endif
33953 return 0;
33954 }
33955 module_init(proc_devices_init);
16454cff
MT
33956diff -urNp linux-2.6.38.1/fs/proc/inode.c linux-2.6.38.1/fs/proc/inode.c
33957--- linux-2.6.38.1/fs/proc/inode.c 2011-03-14 21:20:32.000000000 -0400
33958+++ linux-2.6.38.1/fs/proc/inode.c 2011-03-21 18:31:35.000000000 -0400
33959@@ -435,7 +435,11 @@ struct inode *proc_get_inode(struct supe
57199397
MT
33960 if (de->mode) {
33961 inode->i_mode = de->mode;
33962 inode->i_uid = de->uid;
33963+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33964+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
33965+#else
33966 inode->i_gid = de->gid;
33967+#endif
33968 }
33969 if (de->size)
33970 inode->i_size = de->size;
16454cff
MT
33971diff -urNp linux-2.6.38.1/fs/proc/internal.h linux-2.6.38.1/fs/proc/internal.h
33972--- linux-2.6.38.1/fs/proc/internal.h 2011-03-14 21:20:32.000000000 -0400
33973+++ linux-2.6.38.1/fs/proc/internal.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
33974@@ -51,6 +51,9 @@ extern int proc_pid_status(struct seq_fi
33975 struct pid *pid, struct task_struct *task);
33976 extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
33977 struct pid *pid, struct task_struct *task);
33978+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
33979+extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
33980+#endif
33981 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
33982
33983 extern const struct file_operations proc_maps_operations;
16454cff
MT
33984diff -urNp linux-2.6.38.1/fs/proc/Kconfig linux-2.6.38.1/fs/proc/Kconfig
33985--- linux-2.6.38.1/fs/proc/Kconfig 2011-03-14 21:20:32.000000000 -0400
33986+++ linux-2.6.38.1/fs/proc/Kconfig 2011-03-21 18:31:35.000000000 -0400
efbe55a5
MT
33987@@ -30,12 +30,12 @@ config PROC_FS
33988
33989 config PROC_KCORE
33990 bool "/proc/kcore support" if !ARM
33991- depends on PROC_FS && MMU
33992+ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
33993
33994 config PROC_VMCORE
bc901d79
MT
33995 bool "/proc/vmcore support"
33996- depends on PROC_FS && CRASH_DUMP
efbe55a5 33997- default y
bc901d79 33998+ depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
efbe55a5
MT
33999+ default n
34000 help
34001 Exports the dump image of crashed kernel in ELF format.
34002
34003@@ -59,8 +59,8 @@ config PROC_SYSCTL
34004 limited in memory.
34005
34006 config PROC_PAGE_MONITOR
34007- default y
34008- depends on PROC_FS && MMU
34009+ default n
34010+ depends on PROC_FS && MMU && !GRKERNSEC
16454cff 34011 bool "Enable /proc page monitoring" if EXPERT
efbe55a5
MT
34012 help
34013 Various /proc files exist to monitor process memory utilization:
16454cff
MT
34014diff -urNp linux-2.6.38.1/fs/proc/kcore.c linux-2.6.38.1/fs/proc/kcore.c
34015--- linux-2.6.38.1/fs/proc/kcore.c 2011-03-14 21:20:32.000000000 -0400
34016+++ linux-2.6.38.1/fs/proc/kcore.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
34017@@ -478,9 +478,10 @@ read_kcore(struct file *file, char __use
34018 * the addresses in the elf_phdr on our list.
34019 */
34020 start = kc_offset_to_vaddr(*fpos - elf_buflen);
34021- if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
34022+ tsz = PAGE_SIZE - (start & ~PAGE_MASK);
34023+ if (tsz > buflen)
34024 tsz = buflen;
34025-
58c5fc13 34026+
57199397
MT
34027 while (buflen) {
34028 struct kcore_list *m;
58c5fc13 34029
bc901d79 34030@@ -509,20 +510,23 @@ read_kcore(struct file *file, char __use
57199397 34031 kfree(elf_buf);
58c5fc13 34032 } else {
57199397
MT
34033 if (kern_addr_valid(start)) {
34034- unsigned long n;
34035+ char *elf_buf;
bc901d79 34036+ mm_segment_t oldfs;
57199397
MT
34037
34038- n = copy_to_user(buffer, (char *)start, tsz);
34039- /*
34040- * We cannot distingush between fault on source
34041- * and fault on destination. When this happens
34042- * we clear too and hope it will trigger the
34043- * EFAULT again.
34044- */
34045- if (n) {
34046- if (clear_user(buffer + tsz - n,
34047- n))
34048+ elf_buf = kmalloc(tsz, GFP_KERNEL);
34049+ if (!elf_buf)
34050+ return -ENOMEM;
bc901d79
MT
34051+ oldfs = get_fs();
34052+ set_fs(KERNEL_DS);
57199397 34053+ if (!__copy_from_user(elf_buf, (const void __user *)start, tsz)) {
bc901d79 34054+ set_fs(oldfs);
57199397
MT
34055+ if (copy_to_user(buffer, elf_buf, tsz)) {
34056+ kfree(elf_buf);
34057 return -EFAULT;
34058+ }
34059 }
bc901d79 34060+ set_fs(oldfs);
57199397
MT
34061+ kfree(elf_buf);
34062 } else {
34063 if (clear_user(buffer, tsz))
34064 return -EFAULT;
bc901d79 34065@@ -542,6 +546,9 @@ read_kcore(struct file *file, char __use
58c5fc13 34066
ae4e228f 34067 static int open_kcore(struct inode *inode, struct file *filp)
58c5fc13 34068 {
ae4e228f
MT
34069+#if defined(CONFIG_GRKERNSEC_PROC_ADD) || defined(CONFIG_GRKERNSEC_HIDESYM)
34070+ return -EPERM;
58c5fc13 34071+#endif
ae4e228f
MT
34072 if (!capable(CAP_SYS_RAWIO))
34073 return -EPERM;
34074 if (kcore_need_update)
16454cff
MT
34075diff -urNp linux-2.6.38.1/fs/proc/meminfo.c linux-2.6.38.1/fs/proc/meminfo.c
34076--- linux-2.6.38.1/fs/proc/meminfo.c 2011-03-14 21:20:32.000000000 -0400
34077+++ linux-2.6.38.1/fs/proc/meminfo.c 2011-03-21 18:31:35.000000000 -0400
34078@@ -157,7 +157,7 @@ static int meminfo_proc_show(struct seq_
ae4e228f
MT
34079 vmi.used >> 10,
34080 vmi.largest_chunk >> 10
34081 #ifdef CONFIG_MEMORY_FAILURE
34082- ,atomic_long_read(&mce_bad_pages) << (PAGE_SHIFT - 10)
34083+ ,atomic_long_read_unchecked(&mce_bad_pages) << (PAGE_SHIFT - 10)
34084 #endif
16454cff
MT
34085 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
34086 ,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) *
34087diff -urNp linux-2.6.38.1/fs/proc/nommu.c linux-2.6.38.1/fs/proc/nommu.c
34088--- linux-2.6.38.1/fs/proc/nommu.c 2011-03-14 21:20:32.000000000 -0400
34089+++ linux-2.6.38.1/fs/proc/nommu.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 34090@@ -66,7 +66,7 @@ static int nommu_region_show(struct seq_
58c5fc13
MT
34091 if (len < 1)
34092 len = 1;
34093 seq_printf(m, "%*c", len, ' ');
34094- seq_path(m, &file->f_path, "");
34095+ seq_path(m, &file->f_path, "\n\\");
34096 }
34097
34098 seq_putc(m, '\n');
16454cff
MT
34099diff -urNp linux-2.6.38.1/fs/proc/proc_net.c linux-2.6.38.1/fs/proc/proc_net.c
34100--- linux-2.6.38.1/fs/proc/proc_net.c 2011-03-14 21:20:32.000000000 -0400
34101+++ linux-2.6.38.1/fs/proc/proc_net.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 34102@@ -105,6 +105,17 @@ static struct net *get_proc_task_net(str
58c5fc13
MT
34103 struct task_struct *task;
34104 struct nsproxy *ns;
34105 struct net *net = NULL;
34106+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
34107+ const struct cred *cred = current_cred();
34108+#endif
34109+
34110+#ifdef CONFIG_GRKERNSEC_PROC_USER
34111+ if (cred->fsuid)
34112+ return net;
34113+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
34114+ if (cred->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
34115+ return net;
34116+#endif
34117
34118 rcu_read_lock();
34119 task = pid_task(proc_pid(dir), PIDTYPE_PID);
16454cff
MT
34120diff -urNp linux-2.6.38.1/fs/proc/proc_sysctl.c linux-2.6.38.1/fs/proc/proc_sysctl.c
34121--- linux-2.6.38.1/fs/proc/proc_sysctl.c 2011-03-14 21:20:32.000000000 -0400
34122+++ linux-2.6.38.1/fs/proc/proc_sysctl.c 2011-03-21 18:31:35.000000000 -0400
34123@@ -8,6 +8,8 @@
34124 #include <linux/namei.h>
58c5fc13
MT
34125 #include "internal.h"
34126
34127+extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
34128+
34129 static const struct dentry_operations proc_sys_dentry_operations;
34130 static const struct file_operations proc_sys_file_operations;
34131 static const struct inode_operations proc_sys_inode_operations;
16454cff 34132@@ -112,6 +114,9 @@ static struct dentry *proc_sys_lookup(st
58c5fc13
MT
34133 if (!p)
34134 goto out;
34135
34136+ if (gr_handle_sysctl(p, MAY_EXEC))
34137+ goto out;
34138+
34139 err = ERR_PTR(-ENOMEM);
34140 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
34141 if (h)
16454cff 34142@@ -231,6 +236,9 @@ static int scan(struct ctl_table_header
58c5fc13
MT
34143 if (*pos < file->f_pos)
34144 continue;
34145
34146+ if (gr_handle_sysctl(table, 0))
34147+ continue;
34148+
34149 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
34150 if (res)
34151 return res;
16454cff 34152@@ -359,6 +367,9 @@ static int proc_sys_getattr(struct vfsmo
58c5fc13
MT
34153 if (IS_ERR(head))
34154 return PTR_ERR(head);
34155
34156+ if (table && gr_handle_sysctl(table, MAY_EXEC))
34157+ return -ENOENT;
34158+
34159 generic_fillattr(inode, stat);
34160 if (table)
34161 stat->mode = (stat->mode & S_IFMT) | table->mode;
16454cff
MT
34162diff -urNp linux-2.6.38.1/fs/proc/root.c linux-2.6.38.1/fs/proc/root.c
34163--- linux-2.6.38.1/fs/proc/root.c 2011-03-14 21:20:32.000000000 -0400
34164+++ linux-2.6.38.1/fs/proc/root.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 34165@@ -132,7 +132,15 @@ void __init proc_root_init(void)
58c5fc13
MT
34166 #ifdef CONFIG_PROC_DEVICETREE
34167 proc_device_tree_init();
34168 #endif
34169+#ifdef CONFIG_GRKERNSEC_PROC_ADD
34170+#ifdef CONFIG_GRKERNSEC_PROC_USER
34171+ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
34172+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
34173+ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
34174+#endif
34175+#else
34176 proc_mkdir("bus", NULL);
34177+#endif
34178 proc_sys_init();
34179 }
34180
16454cff
MT
34181diff -urNp linux-2.6.38.1/fs/proc/task_mmu.c linux-2.6.38.1/fs/proc/task_mmu.c
34182--- linux-2.6.38.1/fs/proc/task_mmu.c 2011-03-14 21:20:32.000000000 -0400
34183+++ linux-2.6.38.1/fs/proc/task_mmu.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 34184@@ -49,8 +49,13 @@ void task_mem(struct seq_file *m, struct
58c5fc13
MT
34185 "VmExe:\t%8lu kB\n"
34186 "VmLib:\t%8lu kB\n"
df50ba0c
MT
34187 "VmPTE:\t%8lu kB\n"
34188- "VmSwap:\t%8lu kB\n",
58c5fc13 34189- hiwater_vm << (PAGE_SHIFT-10),
df50ba0c 34190+ "VmSwap:\t%8lu kB\n"
58c5fc13
MT
34191+
34192+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
34193+ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
34194+#endif
34195+
34196+ ,hiwater_vm << (PAGE_SHIFT-10),
34197 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
34198 mm->locked_vm << (PAGE_SHIFT-10),
34199 hiwater_rss << (PAGE_SHIFT-10),
df50ba0c 34200@@ -58,7 +63,13 @@ void task_mem(struct seq_file *m, struct
58c5fc13
MT
34201 data << (PAGE_SHIFT-10),
34202 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
df50ba0c
MT
34203 (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
34204- swap << (PAGE_SHIFT-10));
34205+ swap << (PAGE_SHIFT-10)
58c5fc13
MT
34206+
34207+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
34208+ , mm->context.user_cs_base, mm->context.user_cs_limit
34209+#endif
34210+
34211+ );
34212 }
34213
34214 unsigned long task_vsize(struct mm_struct *mm)
16454cff 34215@@ -204,6 +215,12 @@ static int do_maps_open(struct inode *in
58c5fc13
MT
34216 return ret;
34217 }
34218
34219+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
34220+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
34221+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
34222+ _mm->pax_flags & MF_PAX_SEGMEXEC))
34223+#endif
34224+
34225 static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
34226 {
34227 struct mm_struct *mm = vma->vm_mm;
16454cff 34228@@ -211,7 +228,6 @@ static void show_map_vma(struct seq_file
57199397
MT
34229 int flags = vma->vm_flags;
34230 unsigned long ino = 0;
34231 unsigned long long pgoff = 0;
34232- unsigned long start;
34233 dev_t dev = 0;
34234 int len;
34235
16454cff 34236@@ -222,20 +238,24 @@ static void show_map_vma(struct seq_file
57199397 34237 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
58c5fc13
MT
34238 }
34239
57199397
MT
34240- /* We don't show the stack guard page in /proc/maps */
34241- start = vma->vm_start;
34242- if (vma->vm_flags & VM_GROWSDOWN)
6892158b
MT
34243- if (!vma_stack_continue(vma->vm_prev, vma->vm_start))
34244- start += PAGE_SIZE;
57199397 34245
58c5fc13 34246 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
57199397 34247- start,
58c5fc13
MT
34248+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
34249+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
34250+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
34251+#else
57199397 34252+ vma->vm_start,
58c5fc13
MT
34253 vma->vm_end,
34254+#endif
34255 flags & VM_READ ? 'r' : '-',
34256 flags & VM_WRITE ? 'w' : '-',
34257 flags & VM_EXEC ? 'x' : '-',
34258 flags & VM_MAYSHARE ? 's' : 'p',
34259+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
34260+ PAX_RAND_FLAGS(mm) ? 0UL : pgoff,
34261+#else
34262 pgoff,
34263+#endif
34264 MAJOR(dev), MINOR(dev), ino, &len);
34265
34266 /*
16454cff 34267@@ -244,16 +264,16 @@ static void show_map_vma(struct seq_file
58c5fc13
MT
34268 */
34269 if (file) {
34270 pad_len_spaces(m, len);
34271- seq_path(m, &file->f_path, "\n");
34272+ seq_path(m, &file->f_path, "\n\\");
34273 } else {
34274 const char *name = arch_vma_name(vma);
34275 if (!name) {
34276 if (mm) {
34277- if (vma->vm_start <= mm->start_brk &&
34278- vma->vm_end >= mm->brk) {
34279+ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
34280 name = "[heap]";
34281- } else if (vma->vm_start <= mm->start_stack &&
34282- vma->vm_end >= mm->start_stack) {
34283+ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
34284+ (vma->vm_start <= mm->start_stack &&
34285+ vma->vm_end >= mm->start_stack)) {
34286 name = "[stack]";
df50ba0c
MT
34287 }
34288 } else {
16454cff 34289@@ -399,11 +419,16 @@ static int show_smap(struct seq_file *m,
58c5fc13
MT
34290 };
34291
34292 memset(&mss, 0, sizeof mss);
34293- mss.vma = vma;
df50ba0c 34294- /* mmap_sem is held in m_start */
58c5fc13
MT
34295- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
34296- walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
df50ba0c 34297-
58c5fc13
MT
34298+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
34299+ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
34300+#endif
34301+ mss.vma = vma;
df50ba0c 34302+ /* mmap_sem is held in m_start */
58c5fc13
MT
34303+ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
34304+ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
34305+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
34306+ }
34307+#endif
58c5fc13
MT
34308 show_map_vma(m, vma);
34309
df50ba0c 34310 seq_printf(m,
16454cff 34311@@ -420,7 +445,11 @@ static int show_smap(struct seq_file *m,
58c5fc13 34312 "KernelPageSize: %8lu kB\n"
16454cff
MT
34313 "MMUPageSize: %8lu kB\n"
34314 "Locked: %8lu kB\n",
58c5fc13
MT
34315+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
34316+ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
34317+#else
34318 (vma->vm_end - vma->vm_start) >> 10,
34319+#endif
34320 mss.resident >> 10,
34321 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
34322 mss.shared_clean >> 10,
16454cff
MT
34323diff -urNp linux-2.6.38.1/fs/proc/task_nommu.c linux-2.6.38.1/fs/proc/task_nommu.c
34324--- linux-2.6.38.1/fs/proc/task_nommu.c 2011-03-14 21:20:32.000000000 -0400
34325+++ linux-2.6.38.1/fs/proc/task_nommu.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 34326@@ -51,7 +51,7 @@ void task_mem(struct seq_file *m, struct
58c5fc13
MT
34327 else
34328 bytes += kobjsize(mm);
34329
34330- if (current->fs && current->fs->users > 1)
34331+ if (current->fs && atomic_read(&current->fs->users) > 1)
34332 sbytes += kobjsize(current->fs);
34333 else
34334 bytes += kobjsize(current->fs);
16454cff 34335@@ -166,7 +166,7 @@ static int nommu_vma_show(struct seq_fil
57199397
MT
34336
34337 if (file) {
34338 pad_len_spaces(m, len);
58c5fc13
MT
34339- seq_path(m, &file->f_path, "");
34340+ seq_path(m, &file->f_path, "\n\\");
57199397
MT
34341 } else if (mm) {
34342 if (vma->vm_start <= mm->start_stack &&
34343 vma->vm_end >= mm->start_stack) {
16454cff
MT
34344diff -urNp linux-2.6.38.1/fs/readdir.c linux-2.6.38.1/fs/readdir.c
34345--- linux-2.6.38.1/fs/readdir.c 2011-03-14 21:20:32.000000000 -0400
34346+++ linux-2.6.38.1/fs/readdir.c 2011-03-21 18:31:35.000000000 -0400
6892158b 34347@@ -17,6 +17,7 @@
58c5fc13
MT
34348 #include <linux/security.h>
34349 #include <linux/syscalls.h>
34350 #include <linux/unistd.h>
34351+#include <linux/namei.h>
34352
34353 #include <asm/uaccess.h>
34354
34355@@ -67,6 +68,7 @@ struct old_linux_dirent {
34356
34357 struct readdir_callback {
34358 struct old_linux_dirent __user * dirent;
34359+ struct file * file;
34360 int result;
34361 };
34362
34363@@ -84,6 +86,10 @@ static int fillonedir(void * __buf, cons
34364 buf->result = -EOVERFLOW;
34365 return -EOVERFLOW;
34366 }
34367+
34368+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
34369+ return 0;
34370+
34371 buf->result++;
34372 dirent = buf->dirent;
34373 if (!access_ok(VERIFY_WRITE, dirent,
34374@@ -116,6 +122,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned in
34375
34376 buf.result = 0;
34377 buf.dirent = dirent;
34378+ buf.file = file;
34379
34380 error = vfs_readdir(file, fillonedir, &buf);
34381 if (buf.result)
34382@@ -142,6 +149,7 @@ struct linux_dirent {
34383 struct getdents_callback {
34384 struct linux_dirent __user * current_dir;
34385 struct linux_dirent __user * previous;
34386+ struct file * file;
34387 int count;
34388 int error;
34389 };
6892158b 34390@@ -163,6 +171,10 @@ static int filldir(void * __buf, const c
58c5fc13
MT
34391 buf->error = -EOVERFLOW;
34392 return -EOVERFLOW;
34393 }
34394+
34395+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
34396+ return 0;
34397+
34398 dirent = buf->previous;
34399 if (dirent) {
34400 if (__put_user(offset, &dirent->d_off))
6892158b 34401@@ -210,6 +222,7 @@ SYSCALL_DEFINE3(getdents, unsigned int,
58c5fc13
MT
34402 buf.previous = NULL;
34403 buf.count = count;
34404 buf.error = 0;
34405+ buf.file = file;
34406
34407 error = vfs_readdir(file, filldir, &buf);
34408 if (error >= 0)
6892158b 34409@@ -229,6 +242,7 @@ out:
58c5fc13
MT
34410 struct getdents_callback64 {
34411 struct linux_dirent64 __user * current_dir;
34412 struct linux_dirent64 __user * previous;
34413+ struct file *file;
34414 int count;
34415 int error;
34416 };
6892158b 34417@@ -244,6 +258,10 @@ static int filldir64(void * __buf, const
58c5fc13
MT
34418 buf->error = -EINVAL; /* only used if we fail.. */
34419 if (reclen > buf->count)
34420 return -EINVAL;
34421+
34422+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
34423+ return 0;
34424+
34425 dirent = buf->previous;
34426 if (dirent) {
34427 if (__put_user(offset, &dirent->d_off))
6892158b 34428@@ -291,6 +309,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int
58c5fc13
MT
34429
34430 buf.current_dir = dirent;
34431 buf.previous = NULL;
34432+ buf.file = file;
34433 buf.count = count;
34434 buf.error = 0;
34435
16454cff
MT
34436diff -urNp linux-2.6.38.1/fs/reiserfs/do_balan.c linux-2.6.38.1/fs/reiserfs/do_balan.c
34437--- linux-2.6.38.1/fs/reiserfs/do_balan.c 2011-03-14 21:20:32.000000000 -0400
34438+++ linux-2.6.38.1/fs/reiserfs/do_balan.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 34439@@ -2051,7 +2051,7 @@ void do_balance(struct tree_balance *tb,
58c5fc13
MT
34440 return;
34441 }
34442
34443- atomic_inc(&(fs_generation(tb->tb_sb)));
34444+ atomic_inc_unchecked(&(fs_generation(tb->tb_sb)));
34445 do_balance_starts(tb);
34446
34447 /* balance leaf returns 0 except if combining L R and S into
16454cff
MT
34448diff -urNp linux-2.6.38.1/fs/reiserfs/item_ops.c linux-2.6.38.1/fs/reiserfs/item_ops.c
34449--- linux-2.6.38.1/fs/reiserfs/item_ops.c 2011-03-14 21:20:32.000000000 -0400
34450+++ linux-2.6.38.1/fs/reiserfs/item_ops.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
34451@@ -102,7 +102,7 @@ static void sd_print_vi(struct virtual_i
34452 vi->vi_index, vi->vi_type, vi->vi_ih);
34453 }
34454
34455-static struct item_operations stat_data_ops = {
34456+static const struct item_operations stat_data_ops = {
34457 .bytes_number = sd_bytes_number,
34458 .decrement_key = sd_decrement_key,
34459 .is_left_mergeable = sd_is_left_mergeable,
34460@@ -196,7 +196,7 @@ static void direct_print_vi(struct virtu
34461 vi->vi_index, vi->vi_type, vi->vi_ih);
34462 }
34463
34464-static struct item_operations direct_ops = {
34465+static const struct item_operations direct_ops = {
34466 .bytes_number = direct_bytes_number,
34467 .decrement_key = direct_decrement_key,
34468 .is_left_mergeable = direct_is_left_mergeable,
34469@@ -341,7 +341,7 @@ static void indirect_print_vi(struct vir
34470 vi->vi_index, vi->vi_type, vi->vi_ih);
34471 }
34472
34473-static struct item_operations indirect_ops = {
34474+static const struct item_operations indirect_ops = {
34475 .bytes_number = indirect_bytes_number,
34476 .decrement_key = indirect_decrement_key,
34477 .is_left_mergeable = indirect_is_left_mergeable,
34478@@ -628,7 +628,7 @@ static void direntry_print_vi(struct vir
34479 printk("\n");
34480 }
34481
34482-static struct item_operations direntry_ops = {
34483+static const struct item_operations direntry_ops = {
34484 .bytes_number = direntry_bytes_number,
34485 .decrement_key = direntry_decrement_key,
34486 .is_left_mergeable = direntry_is_left_mergeable,
34487@@ -724,7 +724,7 @@ static void errcatch_print_vi(struct vir
34488 "Invalid item type observed, run fsck ASAP");
34489 }
34490
34491-static struct item_operations errcatch_ops = {
34492+static const struct item_operations errcatch_ops = {
34493 errcatch_bytes_number,
34494 errcatch_decrement_key,
34495 errcatch_is_left_mergeable,
34496@@ -746,7 +746,7 @@ static struct item_operations errcatch_o
34497 #error Item types must use disk-format assigned values.
34498 #endif
34499
34500-struct item_operations *item_ops[TYPE_ANY + 1] = {
34501+const struct item_operations * const item_ops[TYPE_ANY + 1] = {
34502 &stat_data_ops,
34503 &indirect_ops,
34504 &direct_ops,
16454cff
MT
34505diff -urNp linux-2.6.38.1/fs/reiserfs/procfs.c linux-2.6.38.1/fs/reiserfs/procfs.c
34506--- linux-2.6.38.1/fs/reiserfs/procfs.c 2011-03-14 21:20:32.000000000 -0400
34507+++ linux-2.6.38.1/fs/reiserfs/procfs.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 34508@@ -113,7 +113,7 @@ static int show_super(struct seq_file *m
58c5fc13
MT
34509 "SMALL_TAILS " : "NO_TAILS ",
34510 replay_only(sb) ? "REPLAY_ONLY " : "",
34511 convert_reiserfs(sb) ? "CONV " : "",
34512- atomic_read(&r->s_generation_counter),
34513+ atomic_read_unchecked(&r->s_generation_counter),
34514 SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes),
34515 SF(s_do_balance), SF(s_unneeded_left_neighbor),
34516 SF(s_good_search_by_key_reada), SF(s_bmaps),
16454cff
MT
34517diff -urNp linux-2.6.38.1/fs/select.c linux-2.6.38.1/fs/select.c
34518--- linux-2.6.38.1/fs/select.c 2011-03-14 21:20:32.000000000 -0400
34519+++ linux-2.6.38.1/fs/select.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 34520@@ -20,6 +20,7 @@
58c5fc13
MT
34521 #include <linux/module.h>
34522 #include <linux/slab.h>
34523 #include <linux/poll.h>
34524+#include <linux/security.h>
34525 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
34526 #include <linux/file.h>
34527 #include <linux/fdtable.h>
16454cff 34528@@ -840,6 +841,7 @@ int do_sys_poll(struct pollfd __user *uf
58c5fc13
MT
34529 struct poll_list *walk = head;
34530 unsigned long todo = nfds;
34531
34532+ gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
df50ba0c 34533 if (nfds > rlimit(RLIMIT_NOFILE))
58c5fc13
MT
34534 return -EINVAL;
34535
16454cff
MT
34536diff -urNp linux-2.6.38.1/fs/seq_file.c linux-2.6.38.1/fs/seq_file.c
34537--- linux-2.6.38.1/fs/seq_file.c 2011-03-14 21:20:32.000000000 -0400
34538+++ linux-2.6.38.1/fs/seq_file.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
34539@@ -76,7 +76,8 @@ static int traverse(struct seq_file *m,
34540 return 0;
34541 }
34542 if (!m->buf) {
34543- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
34544+ m->size = PAGE_SIZE;
ae4e228f 34545+ m->buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
58c5fc13
MT
34546 if (!m->buf)
34547 return -ENOMEM;
34548 }
34549@@ -116,7 +117,8 @@ static int traverse(struct seq_file *m,
34550 Eoverflow:
34551 m->op->stop(m, p);
34552 kfree(m->buf);
34553- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
34554+ m->size <<= 1;
34555+ m->buf = kmalloc(m->size, GFP_KERNEL);
34556 return !m->buf ? -ENOMEM : -EAGAIN;
34557 }
34558
34559@@ -169,7 +171,8 @@ ssize_t seq_read(struct file *file, char
34560 m->version = file->f_version;
34561 /* grab buffer if we didn't have one */
34562 if (!m->buf) {
34563- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
34564+ m->size = PAGE_SIZE;
ae4e228f 34565+ m->buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
58c5fc13
MT
34566 if (!m->buf)
34567 goto Enomem;
34568 }
34569@@ -210,7 +213,8 @@ ssize_t seq_read(struct file *file, char
34570 goto Fill;
34571 m->op->stop(m, p);
34572 kfree(m->buf);
34573- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
34574+ m->size <<= 1;
34575+ m->buf = kmalloc(m->size, GFP_KERNEL);
34576 if (!m->buf)
34577 goto Enomem;
34578 m->count = 0;
16454cff
MT
34579diff -urNp linux-2.6.38.1/fs/splice.c linux-2.6.38.1/fs/splice.c
34580--- linux-2.6.38.1/fs/splice.c 2011-03-14 21:20:32.000000000 -0400
34581+++ linux-2.6.38.1/fs/splice.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 34582@@ -186,7 +186,7 @@ ssize_t splice_to_pipe(struct pipe_inode
ae4e228f
MT
34583 pipe_lock(pipe);
34584
34585 for (;;) {
34586- if (!pipe->readers) {
34587+ if (!atomic_read(&pipe->readers)) {
34588 send_sig(SIGPIPE, current, 0);
34589 if (!ret)
34590 ret = -EPIPE;
df50ba0c 34591@@ -240,9 +240,9 @@ ssize_t splice_to_pipe(struct pipe_inode
ae4e228f
MT
34592 do_wakeup = 0;
34593 }
34594
34595- pipe->waiting_writers++;
34596+ atomic_inc(&pipe->waiting_writers);
34597 pipe_wait(pipe);
34598- pipe->waiting_writers--;
34599+ atomic_dec(&pipe->waiting_writers);
34600 }
34601
34602 pipe_unlock(pipe);
6892158b 34603@@ -556,7 +556,7 @@ static ssize_t kernel_readv(struct file
ae4e228f
MT
34604 old_fs = get_fs();
34605 set_fs(get_ds());
34606 /* The cast to a user pointer is valid due to the set_fs() */
34607- res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos);
34608+ res = vfs_readv(file, (__force const struct iovec __user *)vec, vlen, &pos);
34609 set_fs(old_fs);
34610
34611 return res;
6892158b 34612@@ -571,7 +571,7 @@ static ssize_t kernel_write(struct file
ae4e228f
MT
34613 old_fs = get_fs();
34614 set_fs(get_ds());
34615 /* The cast to a user pointer is valid due to the set_fs() */
34616- res = vfs_write(file, (const char __user *)buf, count, &pos);
34617+ res = vfs_write(file, (__force const char __user *)buf, count, &pos);
34618 set_fs(old_fs);
34619
34620 return res;
6892158b 34621@@ -622,7 +622,7 @@ ssize_t default_file_splice_read(struct
ae4e228f
MT
34622 goto err;
34623
34624 this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset);
34625- vec[i].iov_base = (void __user *) page_address(page);
34626+ vec[i].iov_base = (__force void __user *) page_address(page);
34627 vec[i].iov_len = this_len;
57199397 34628 spd.pages[i] = page;
ae4e228f 34629 spd.nr_pages++;
16454cff 34630@@ -842,10 +842,10 @@ EXPORT_SYMBOL(splice_from_pipe_feed);
ae4e228f
MT
34631 int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
34632 {
34633 while (!pipe->nrbufs) {
34634- if (!pipe->writers)
34635+ if (!atomic_read(&pipe->writers))
34636 return 0;
34637
34638- if (!pipe->waiting_writers && sd->num_spliced)
34639+ if (!atomic_read(&pipe->waiting_writers) && sd->num_spliced)
34640 return 0;
34641
34642 if (sd->flags & SPLICE_F_NONBLOCK)
16454cff 34643@@ -1178,7 +1178,7 @@ ssize_t splice_direct_to_actor(struct fi
ae4e228f
MT
34644 * out of the pipe right after the splice_to_pipe(). So set
34645 * PIPE_READERS appropriately.
34646 */
34647- pipe->readers = 1;
34648+ atomic_set(&pipe->readers, 1);
34649
34650 current->splice_pipe = pipe;
34651 }
16454cff 34652@@ -1730,9 +1730,9 @@ static int ipipe_prep(struct pipe_inode_
ae4e228f
MT
34653 ret = -ERESTARTSYS;
34654 break;
34655 }
34656- if (!pipe->writers)
34657+ if (!atomic_read(&pipe->writers))
34658 break;
34659- if (!pipe->waiting_writers) {
34660+ if (!atomic_read(&pipe->waiting_writers)) {
34661 if (flags & SPLICE_F_NONBLOCK) {
34662 ret = -EAGAIN;
34663 break;
16454cff 34664@@ -1764,7 +1764,7 @@ static int opipe_prep(struct pipe_inode_
ae4e228f
MT
34665 pipe_lock(pipe);
34666
57199397 34667 while (pipe->nrbufs >= pipe->buffers) {
ae4e228f
MT
34668- if (!pipe->readers) {
34669+ if (!atomic_read(&pipe->readers)) {
34670 send_sig(SIGPIPE, current, 0);
34671 ret = -EPIPE;
34672 break;
16454cff 34673@@ -1777,9 +1777,9 @@ static int opipe_prep(struct pipe_inode_
ae4e228f
MT
34674 ret = -ERESTARTSYS;
34675 break;
34676 }
34677- pipe->waiting_writers++;
34678+ atomic_inc(&pipe->waiting_writers);
34679 pipe_wait(pipe);
34680- pipe->waiting_writers--;
34681+ atomic_dec(&pipe->waiting_writers);
34682 }
58c5fc13 34683
ae4e228f 34684 pipe_unlock(pipe);
16454cff 34685@@ -1815,14 +1815,14 @@ retry:
ae4e228f
MT
34686 pipe_double_lock(ipipe, opipe);
34687
34688 do {
34689- if (!opipe->readers) {
34690+ if (!atomic_read(&opipe->readers)) {
34691 send_sig(SIGPIPE, current, 0);
34692 if (!ret)
34693 ret = -EPIPE;
34694 break;
34695 }
34696
34697- if (!ipipe->nrbufs && !ipipe->writers)
34698+ if (!ipipe->nrbufs && !atomic_read(&ipipe->writers))
34699 break;
34700
34701 /*
16454cff 34702@@ -1922,7 +1922,7 @@ static int link_pipe(struct pipe_inode_i
ae4e228f
MT
34703 pipe_double_lock(ipipe, opipe);
34704
34705 do {
34706- if (!opipe->readers) {
34707+ if (!atomic_read(&opipe->readers)) {
34708 send_sig(SIGPIPE, current, 0);
34709 if (!ret)
34710 ret = -EPIPE;
16454cff 34711@@ -1967,7 +1967,7 @@ static int link_pipe(struct pipe_inode_i
ae4e228f
MT
34712 * return EAGAIN if we have the potential of some data in the
34713 * future, otherwise just return 0
34714 */
34715- if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK))
34716+ if (!ret && atomic_read(&ipipe->waiting_writers) && (flags & SPLICE_F_NONBLOCK))
34717 ret = -EAGAIN;
34718
34719 pipe_unlock(ipipe);
16454cff
MT
34720diff -urNp linux-2.6.38.1/fs/sysfs/mount.c linux-2.6.38.1/fs/sysfs/mount.c
34721--- linux-2.6.38.1/fs/sysfs/mount.c 2011-03-14 21:20:32.000000000 -0400
34722+++ linux-2.6.38.1/fs/sysfs/mount.c 2011-03-21 18:31:35.000000000 -0400
34723@@ -36,7 +36,11 @@ struct sysfs_dirent sysfs_root = {
34724 .s_name = "",
34725 .s_count = ATOMIC_INIT(1),
34726 .s_flags = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT),
34727+#ifdef CONFIG_GRKERNSEC_SYSFS_RESTRICT
34728+ .s_mode = S_IFDIR | S_IRWXU,
34729+#else
34730 .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
34731+#endif
34732 .s_ino = 1,
34733 };
34734
34735diff -urNp linux-2.6.38.1/fs/sysfs/symlink.c linux-2.6.38.1/fs/sysfs/symlink.c
34736--- linux-2.6.38.1/fs/sysfs/symlink.c 2011-03-14 21:20:32.000000000 -0400
34737+++ linux-2.6.38.1/fs/sysfs/symlink.c 2011-03-21 18:31:35.000000000 -0400
57199397 34738@@ -286,7 +286,7 @@ static void *sysfs_follow_link(struct de
58c5fc13
MT
34739
34740 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
34741 {
34742- char *page = nd_get_link(nd);
34743+ const char *page = nd_get_link(nd);
34744 if (!IS_ERR(page))
34745 free_page((unsigned long)page);
34746 }
16454cff
MT
34747diff -urNp linux-2.6.38.1/fs/ubifs/debug.c linux-2.6.38.1/fs/ubifs/debug.c
34748--- linux-2.6.38.1/fs/ubifs/debug.c 2011-03-14 21:20:32.000000000 -0400
34749+++ linux-2.6.38.1/fs/ubifs/debug.c 2011-03-21 18:31:35.000000000 -0400
317566c1
MT
34750@@ -2813,19 +2813,19 @@ int dbg_debugfs_init_fs(struct ubifs_inf
34751 }
34752
34753 fname = "dump_lprops";
34754- dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
34755+ dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
34756 if (IS_ERR(dent))
34757 goto out_remove;
34758 d->dfs_dump_lprops = dent;
34759
34760 fname = "dump_budg";
34761- dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
34762+ dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
34763 if (IS_ERR(dent))
34764 goto out_remove;
34765 d->dfs_dump_budg = dent;
34766
34767 fname = "dump_tnc";
34768- dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
34769+ dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
34770 if (IS_ERR(dent))
34771 goto out_remove;
34772 d->dfs_dump_tnc = dent;
16454cff
MT
34773diff -urNp linux-2.6.38.1/fs/udf/misc.c linux-2.6.38.1/fs/udf/misc.c
34774--- linux-2.6.38.1/fs/udf/misc.c 2011-03-14 21:20:32.000000000 -0400
34775+++ linux-2.6.38.1/fs/udf/misc.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
34776@@ -142,8 +142,8 @@ struct genericFormat *udf_add_extendedat
34777 iinfo->i_lenEAttr += size;
34778 return (struct genericFormat *)&ea[offset];
34779 }
34780- if (loc & 0x02)
34781- ;
34782+ if (loc & 0x02) {
34783+ }
34784
34785 return NULL;
34786 }
bc901d79
MT
34787@@ -286,7 +286,7 @@ void udf_new_tag(char *data, uint16_t id
34788
34789 u8 udf_tag_checksum(const struct tag *t)
34790 {
34791- u8 *data = (u8 *)t;
34792+ const u8 *data = (const u8 *)t;
34793 u8 checksum = 0;
34794 int i;
34795 for (i = 0; i < sizeof(struct tag); ++i)
16454cff
MT
34796diff -urNp linux-2.6.38.1/fs/udf/udfdecl.h linux-2.6.38.1/fs/udf/udfdecl.h
34797--- linux-2.6.38.1/fs/udf/udfdecl.h 2011-03-14 21:20:32.000000000 -0400
34798+++ linux-2.6.38.1/fs/udf/udfdecl.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
34799@@ -26,7 +26,7 @@ do { \
34800 printk(f, ##a); \
34801 } while (0)
34802 #else
34803-#define udf_debug(f, a...) /**/
34804+#define udf_debug(f, a...) do {} while (0)
34805 #endif
34806
34807 #define udf_info(f, a...) \
16454cff
MT
34808diff -urNp linux-2.6.38.1/fs/utimes.c linux-2.6.38.1/fs/utimes.c
34809--- linux-2.6.38.1/fs/utimes.c 2011-03-14 21:20:32.000000000 -0400
34810+++ linux-2.6.38.1/fs/utimes.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
34811@@ -1,6 +1,7 @@
34812 #include <linux/compiler.h>
34813 #include <linux/file.h>
34814 #include <linux/fs.h>
34815+#include <linux/security.h>
34816 #include <linux/linkage.h>
34817 #include <linux/mount.h>
34818 #include <linux/namei.h>
34819@@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
34820 goto mnt_drop_write_and_out;
34821 }
34822 }
34823+
34824+ if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
34825+ error = -EACCES;
34826+ goto mnt_drop_write_and_out;
34827+ }
34828+
34829 mutex_lock(&inode->i_mutex);
34830 error = notify_change(path->dentry, &newattrs);
34831 mutex_unlock(&inode->i_mutex);
16454cff
MT
34832diff -urNp linux-2.6.38.1/fs/xattr_acl.c linux-2.6.38.1/fs/xattr_acl.c
34833--- linux-2.6.38.1/fs/xattr_acl.c 2011-03-14 21:20:32.000000000 -0400
34834+++ linux-2.6.38.1/fs/xattr_acl.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
34835@@ -17,8 +17,8 @@
34836 struct posix_acl *
34837 posix_acl_from_xattr(const void *value, size_t size)
34838 {
34839- posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
34840- posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
34841+ const posix_acl_xattr_header *header = (const posix_acl_xattr_header *)value;
34842+ const posix_acl_xattr_entry *entry = (const posix_acl_xattr_entry *)(header+1), *end;
34843 int count;
34844 struct posix_acl *acl;
34845 struct posix_acl_entry *acl_e;
16454cff
MT
34846diff -urNp linux-2.6.38.1/fs/xattr.c linux-2.6.38.1/fs/xattr.c
34847--- linux-2.6.38.1/fs/xattr.c 2011-03-14 21:20:32.000000000 -0400
34848+++ linux-2.6.38.1/fs/xattr.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
34849@@ -247,7 +247,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
34850 * Extended attribute SET operations
34851 */
34852 static long
34853-setxattr(struct dentry *d, const char __user *name, const void __user *value,
34854+setxattr(struct path *path, const char __user *name, const void __user *value,
34855 size_t size, int flags)
34856 {
34857 int error;
34858@@ -271,7 +271,13 @@ setxattr(struct dentry *d, const char __
34859 return PTR_ERR(kvalue);
34860 }
34861
34862- error = vfs_setxattr(d, kname, kvalue, size, flags);
34863+ if (!gr_acl_handle_setxattr(path->dentry, path->mnt)) {
34864+ error = -EACCES;
34865+ goto out;
34866+ }
34867+
34868+ error = vfs_setxattr(path->dentry, kname, kvalue, size, flags);
34869+out:
34870 kfree(kvalue);
34871 return error;
34872 }
34873@@ -288,7 +294,7 @@ SYSCALL_DEFINE5(setxattr, const char __u
34874 return error;
34875 error = mnt_want_write(path.mnt);
34876 if (!error) {
34877- error = setxattr(path.dentry, name, value, size, flags);
34878+ error = setxattr(&path, name, value, size, flags);
34879 mnt_drop_write(path.mnt);
34880 }
34881 path_put(&path);
34882@@ -307,7 +313,7 @@ SYSCALL_DEFINE5(lsetxattr, const char __
34883 return error;
34884 error = mnt_want_write(path.mnt);
34885 if (!error) {
34886- error = setxattr(path.dentry, name, value, size, flags);
34887+ error = setxattr(&path, name, value, size, flags);
34888 mnt_drop_write(path.mnt);
34889 }
34890 path_put(&path);
34891@@ -318,17 +324,15 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons
34892 const void __user *,value, size_t, size, int, flags)
34893 {
34894 struct file *f;
34895- struct dentry *dentry;
34896 int error = -EBADF;
34897
34898 f = fget(fd);
34899 if (!f)
34900 return error;
34901- dentry = f->f_path.dentry;
34902- audit_inode(NULL, dentry);
34903+ audit_inode(NULL, f->f_path.dentry);
34904 error = mnt_want_write_file(f);
34905 if (!error) {
34906- error = setxattr(dentry, name, value, size, flags);
34907+ error = setxattr(&f->f_path, name, value, size, flags);
34908 mnt_drop_write(f->f_path.mnt);
34909 }
34910 fput(f);
16454cff
MT
34911diff -urNp linux-2.6.38.1/fs/xfs/linux-2.6/xfs_ioctl32.c linux-2.6.38.1/fs/xfs/linux-2.6/xfs_ioctl32.c
34912--- linux-2.6.38.1/fs/xfs/linux-2.6/xfs_ioctl32.c 2011-03-14 21:20:32.000000000 -0400
34913+++ linux-2.6.38.1/fs/xfs/linux-2.6/xfs_ioctl32.c 2011-03-21 18:31:35.000000000 -0400
34914@@ -73,6 +73,7 @@ xfs_compat_ioc_fsgeometry_v1(
34915 xfs_fsop_geom_t fsgeo;
34916 int error;
34917
34918+ memset(&fsgeo, 0, sizeof(fsgeo));
34919 error = xfs_fs_geometry(mp, &fsgeo, 3);
34920 if (error)
34921 return -error;
34922diff -urNp linux-2.6.38.1/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.38.1/fs/xfs/linux-2.6/xfs_ioctl.c
34923--- linux-2.6.38.1/fs/xfs/linux-2.6/xfs_ioctl.c 2011-03-14 21:20:32.000000000 -0400
34924+++ linux-2.6.38.1/fs/xfs/linux-2.6/xfs_ioctl.c 2011-03-21 18:31:35.000000000 -0400
34925@@ -128,7 +128,7 @@ xfs_find_handle(
ae4e228f 34926 }
58c5fc13 34927
ae4e228f
MT
34928 error = -EFAULT;
34929- if (copy_to_user(hreq->ohandle, &handle, hsize) ||
bc901d79 34930+ if (hsize > sizeof handle || copy_to_user(hreq->ohandle, &handle, hsize) ||
ae4e228f
MT
34931 copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
34932 goto out_put;
58c5fc13 34933
16454cff
MT
34934@@ -720,6 +720,7 @@ xfs_ioc_fsgeometry(
34935 xfs_fsop_geom_t fsgeo;
34936 int error;
34937
34938+ memset(&fsgeo, 0, sizeof(fsgeo));
34939 error = xfs_fs_geometry(mp, &fsgeo, 4);
34940 if (error)
34941 return -error;
34942diff -urNp linux-2.6.38.1/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.38.1/fs/xfs/linux-2.6/xfs_iops.c
34943--- linux-2.6.38.1/fs/xfs/linux-2.6/xfs_iops.c 2011-03-14 21:20:32.000000000 -0400
34944+++ linux-2.6.38.1/fs/xfs/linux-2.6/xfs_iops.c 2011-03-21 18:31:35.000000000 -0400
34945@@ -436,7 +436,7 @@ xfs_vn_put_link(
58c5fc13
MT
34946 struct nameidata *nd,
34947 void *p)
34948 {
34949- char *s = nd_get_link(nd);
34950+ const char *s = nd_get_link(nd);
34951
34952 if (!IS_ERR(s))
34953 kfree(s);
16454cff
MT
34954diff -urNp linux-2.6.38.1/fs/xfs/xfs_bmap.c linux-2.6.38.1/fs/xfs/xfs_bmap.c
34955--- linux-2.6.38.1/fs/xfs/xfs_bmap.c 2011-03-14 21:20:32.000000000 -0400
34956+++ linux-2.6.38.1/fs/xfs/xfs_bmap.c 2011-03-21 18:31:35.000000000 -0400
6892158b 34957@@ -287,7 +287,7 @@ xfs_bmap_validate_ret(
58c5fc13
MT
34958 int nmap,
34959 int ret_nmap);
34960 #else
34961-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
34962+#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
34963 #endif /* DEBUG */
34964
ae4e228f 34965 STATIC int
16454cff
MT
34966diff -urNp linux-2.6.38.1/grsecurity/gracl_alloc.c linux-2.6.38.1/grsecurity/gracl_alloc.c
34967--- linux-2.6.38.1/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
34968+++ linux-2.6.38.1/grsecurity/gracl_alloc.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
34969@@ -0,0 +1,105 @@
34970+#include <linux/kernel.h>
34971+#include <linux/mm.h>
34972+#include <linux/slab.h>
34973+#include <linux/vmalloc.h>
34974+#include <linux/gracl.h>
34975+#include <linux/grsecurity.h>
58c5fc13 34976+
57199397
MT
34977+static unsigned long alloc_stack_next = 1;
34978+static unsigned long alloc_stack_size = 1;
34979+static void **alloc_stack;
58c5fc13 34980+
57199397
MT
34981+static __inline__ int
34982+alloc_pop(void)
34983+{
34984+ if (alloc_stack_next == 1)
34985+ return 0;
58c5fc13 34986+
57199397 34987+ kfree(alloc_stack[alloc_stack_next - 2]);
58c5fc13 34988+
57199397 34989+ alloc_stack_next--;
58c5fc13 34990+
57199397
MT
34991+ return 1;
34992+}
58c5fc13 34993+
57199397
MT
34994+static __inline__ int
34995+alloc_push(void *buf)
34996+{
34997+ if (alloc_stack_next >= alloc_stack_size)
34998+ return 1;
58c5fc13 34999+
57199397 35000+ alloc_stack[alloc_stack_next - 1] = buf;
58c5fc13 35001+
57199397 35002+ alloc_stack_next++;
58c5fc13 35003+
57199397
MT
35004+ return 0;
35005+}
58c5fc13 35006+
57199397
MT
35007+void *
35008+acl_alloc(unsigned long len)
35009+{
35010+ void *ret = NULL;
58c5fc13 35011+
57199397
MT
35012+ if (!len || len > PAGE_SIZE)
35013+ goto out;
58c5fc13 35014+
57199397 35015+ ret = kmalloc(len, GFP_KERNEL);
58c5fc13 35016+
57199397
MT
35017+ if (ret) {
35018+ if (alloc_push(ret)) {
35019+ kfree(ret);
35020+ ret = NULL;
35021+ }
35022+ }
58c5fc13 35023+
57199397
MT
35024+out:
35025+ return ret;
35026+}
58c5fc13 35027+
57199397
MT
35028+void *
35029+acl_alloc_num(unsigned long num, unsigned long len)
35030+{
35031+ if (!len || (num > (PAGE_SIZE / len)))
35032+ return NULL;
58c5fc13 35033+
57199397
MT
35034+ return acl_alloc(num * len);
35035+}
58c5fc13 35036+
57199397
MT
35037+void
35038+acl_free_all(void)
35039+{
35040+ if (gr_acl_is_enabled() || !alloc_stack)
35041+ return;
58c5fc13 35042+
57199397 35043+ while (alloc_pop()) ;
58c5fc13 35044+
57199397
MT
35045+ if (alloc_stack) {
35046+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
35047+ kfree(alloc_stack);
35048+ else
35049+ vfree(alloc_stack);
35050+ }
58c5fc13 35051+
57199397
MT
35052+ alloc_stack = NULL;
35053+ alloc_stack_size = 1;
35054+ alloc_stack_next = 1;
58c5fc13 35055+
57199397
MT
35056+ return;
35057+}
58c5fc13 35058+
57199397
MT
35059+int
35060+acl_alloc_stack_init(unsigned long size)
35061+{
35062+ if ((size * sizeof (void *)) <= PAGE_SIZE)
35063+ alloc_stack =
35064+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
35065+ else
35066+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
58c5fc13 35067+
57199397 35068+ alloc_stack_size = size;
58c5fc13 35069+
57199397
MT
35070+ if (!alloc_stack)
35071+ return 0;
35072+ else
35073+ return 1;
35074+}
16454cff
MT
35075diff -urNp linux-2.6.38.1/grsecurity/gracl.c linux-2.6.38.1/grsecurity/gracl.c
35076--- linux-2.6.38.1/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
35077+++ linux-2.6.38.1/grsecurity/gracl.c 2011-03-26 17:50:26.000000000 -0400
35078@@ -0,0 +1,4078 @@
57199397
MT
35079+#include <linux/kernel.h>
35080+#include <linux/module.h>
35081+#include <linux/sched.h>
35082+#include <linux/mm.h>
35083+#include <linux/file.h>
35084+#include <linux/fs.h>
35085+#include <linux/namei.h>
35086+#include <linux/mount.h>
35087+#include <linux/tty.h>
35088+#include <linux/proc_fs.h>
35089+#include <linux/smp_lock.h>
bc901d79 35090+#include <linux/lglock.h>
57199397
MT
35091+#include <linux/slab.h>
35092+#include <linux/vmalloc.h>
35093+#include <linux/types.h>
35094+#include <linux/sysctl.h>
35095+#include <linux/netdevice.h>
35096+#include <linux/ptrace.h>
35097+#include <linux/gracl.h>
35098+#include <linux/gralloc.h>
35099+#include <linux/grsecurity.h>
35100+#include <linux/grinternal.h>
35101+#include <linux/pid_namespace.h>
35102+#include <linux/fdtable.h>
35103+#include <linux/percpu.h>
58c5fc13 35104+
57199397
MT
35105+#include <asm/uaccess.h>
35106+#include <asm/errno.h>
35107+#include <asm/mman.h>
58c5fc13 35108+
57199397
MT
35109+static struct acl_role_db acl_role_set;
35110+static struct name_db name_set;
35111+static struct inodev_db inodev_set;
58c5fc13 35112+
57199397
MT
35113+/* for keeping track of userspace pointers used for subjects, so we
35114+ can share references in the kernel as well
35115+*/
58c5fc13 35116+
6892158b 35117+static struct path real_root;
58c5fc13 35118+
57199397 35119+static struct acl_subj_map_db subj_map_set;
ae4e228f 35120+
57199397 35121+static struct acl_role_label *default_role;
58c5fc13 35122+
57199397 35123+static struct acl_role_label *role_list;
58c5fc13 35124+
57199397 35125+static u16 acl_sp_role_value;
58c5fc13 35126+
57199397 35127+extern char *gr_shared_page[4];
bc901d79 35128+static DEFINE_MUTEX(gr_dev_mutex);
57199397 35129+DEFINE_RWLOCK(gr_inode_lock);
58c5fc13 35130+
57199397 35131+struct gr_arg *gr_usermode;
58c5fc13 35132+
57199397 35133+static unsigned int gr_status __read_only = GR_STATUS_INIT;
58c5fc13 35134+
57199397
MT
35135+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
35136+extern void gr_clear_learn_entries(void);
58c5fc13 35137+
57199397
MT
35138+#ifdef CONFIG_GRKERNSEC_RESLOG
35139+extern void gr_log_resource(const struct task_struct *task,
35140+ const int res, const unsigned long wanted, const int gt);
35141+#endif
58c5fc13 35142+
57199397
MT
35143+unsigned char *gr_system_salt;
35144+unsigned char *gr_system_sum;
58c5fc13 35145+
57199397
MT
35146+static struct sprole_pw **acl_special_roles = NULL;
35147+static __u16 num_sprole_pws = 0;
58c5fc13 35148+
57199397 35149+static struct acl_role_label *kernel_role = NULL;
df50ba0c 35150+
57199397
MT
35151+static unsigned int gr_auth_attempts = 0;
35152+static unsigned long gr_auth_expires = 0UL;
58c5fc13 35153+
57199397
MT
35154+extern struct vfsmount *sock_mnt;
35155+extern struct vfsmount *pipe_mnt;
35156+extern struct vfsmount *shm_mnt;
35157+#ifdef CONFIG_HUGETLBFS
35158+extern struct vfsmount *hugetlbfs_vfsmount;
35159+#endif
58c5fc13 35160+
57199397 35161+static struct acl_object_label *fakefs_obj;
df50ba0c 35162+
57199397
MT
35163+extern int gr_init_uidset(void);
35164+extern void gr_free_uidset(void);
35165+extern void gr_remove_uid(uid_t uid);
35166+extern int gr_find_uid(uid_t uid);
58c5fc13 35167+
bc901d79 35168+DECLARE_BRLOCK(vfsmount_lock);
58c5fc13 35169+
57199397
MT
35170+__inline__ int
35171+gr_acl_is_enabled(void)
35172+{
35173+ return (gr_status & GR_READY);
35174+}
58c5fc13 35175+
16454cff
MT
35176+#ifdef CONFIG_BTRFS_FS
35177+extern dev_t get_btrfs_dev_from_inode(struct inode *inode);
35178+extern int btrfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
35179+#endif
35180+
35181+static inline dev_t __get_dev(const struct dentry *dentry)
35182+{
35183+#ifdef CONFIG_BTRFS_FS
35184+ if (dentry->d_inode->i_op && dentry->d_inode->i_op->getattr == &btrfs_getattr)
35185+ return get_btrfs_dev_from_inode(dentry->d_inode);
35186+ else
35187+#endif
35188+ return dentry->d_inode->i_sb->s_dev;
35189+}
35190+
35191+dev_t gr_get_dev_from_dentry(struct dentry *dentry)
35192+{
35193+ return __get_dev(dentry);
35194+}
35195+
6892158b 35196+static char gr_task_roletype_to_char(struct task_struct *task)
57199397 35197+{
6892158b 35198+ switch (task->role->roletype &
57199397
MT
35199+ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
35200+ GR_ROLE_SPECIAL)) {
35201+ case GR_ROLE_DEFAULT:
35202+ return 'D';
35203+ case GR_ROLE_USER:
35204+ return 'U';
35205+ case GR_ROLE_GROUP:
35206+ return 'G';
35207+ case GR_ROLE_SPECIAL:
35208+ return 'S';
35209+ }
58c5fc13 35210+
57199397
MT
35211+ return 'X';
35212+}
58c5fc13 35213+
6892158b
MT
35214+char gr_roletype_to_char(void)
35215+{
35216+ return gr_task_roletype_to_char(current);
35217+}
35218+
57199397
MT
35219+__inline__ int
35220+gr_acl_tpe_check(void)
35221+{
35222+ if (unlikely(!(gr_status & GR_READY)))
35223+ return 0;
35224+ if (current->role->roletype & GR_ROLE_TPE)
35225+ return 1;
35226+ else
35227+ return 0;
35228+}
58c5fc13 35229+
57199397
MT
35230+int
35231+gr_handle_rawio(const struct inode *inode)
35232+{
35233+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
35234+ if (inode && S_ISBLK(inode->i_mode) &&
35235+ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
35236+ !capable(CAP_SYS_RAWIO))
35237+ return 1;
35238+#endif
35239+ return 0;
35240+}
58c5fc13 35241+
57199397
MT
35242+static int
35243+gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
35244+{
35245+ if (likely(lena != lenb))
35246+ return 0;
58c5fc13 35247+
57199397
MT
35248+ return !memcmp(a, b, lena);
35249+}
58c5fc13 35250+
bc901d79
MT
35251+static int prepend(char **buffer, int *buflen, const char *str, int namelen)
35252+{
35253+ *buflen -= namelen;
35254+ if (*buflen < 0)
35255+ return -ENAMETOOLONG;
35256+ *buffer -= namelen;
35257+ memcpy(*buffer, str, namelen);
35258+ return 0;
35259+}
35260+
35261+static int prepend_name(char **buffer, int *buflen, struct qstr *name)
35262+{
35263+ return prepend(buffer, buflen, name->name, name->len);
35264+}
35265+
35266+static int prepend_path(const struct path *path, struct path *root,
35267+ char **buffer, int *buflen)
35268+{
35269+ struct dentry *dentry = path->dentry;
35270+ struct vfsmount *vfsmnt = path->mnt;
35271+ bool slash = false;
35272+ int error = 0;
35273+
35274+ while (dentry != root->dentry || vfsmnt != root->mnt) {
35275+ struct dentry * parent;
35276+
35277+ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
35278+ /* Global root? */
35279+ if (vfsmnt->mnt_parent == vfsmnt) {
35280+ goto out;
35281+ }
35282+ dentry = vfsmnt->mnt_mountpoint;
35283+ vfsmnt = vfsmnt->mnt_parent;
35284+ continue;
35285+ }
35286+ parent = dentry->d_parent;
35287+ prefetch(parent);
16454cff 35288+ spin_lock(&dentry->d_lock);
bc901d79 35289+ error = prepend_name(buffer, buflen, &dentry->d_name);
16454cff 35290+ spin_unlock(&dentry->d_lock);
bc901d79
MT
35291+ if (!error)
35292+ error = prepend(buffer, buflen, "/", 1);
35293+ if (error)
35294+ break;
35295+
35296+ slash = true;
35297+ dentry = parent;
35298+ }
35299+
35300+out:
35301+ if (!error && !slash)
35302+ error = prepend(buffer, buflen, "/", 1);
35303+
35304+ return error;
35305+}
35306+
16454cff 35307+/* this must be called with vfsmount_lock and rename_lock held */
bc901d79
MT
35308+
35309+static char *__our_d_path(const struct path *path, struct path *root,
35310+ char *buf, int buflen)
35311+{
35312+ char *res = buf + buflen;
35313+ int error;
35314+
35315+ prepend(&res, &buflen, "\0", 1);
35316+ error = prepend_path(path, root, &res, &buflen);
35317+ if (error)
35318+ return ERR_PTR(error);
35319+
35320+ return res;
35321+}
35322+
57199397 35323+static char *
6892158b 35324+gen_full_path(struct path *path, struct path *root, char *buf, int buflen)
57199397
MT
35325+{
35326+ char *retval;
58c5fc13 35327+
bc901d79 35328+ retval = __our_d_path(path, root, buf, buflen);
57199397
MT
35329+ if (unlikely(IS_ERR(retval)))
35330+ retval = strcpy(buf, "<path too long>");
35331+ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
35332+ retval[1] = '\0';
58c5fc13 35333+
57199397
MT
35334+ return retval;
35335+}
58c5fc13 35336+
57199397
MT
35337+static char *
35338+__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
35339+ char *buf, int buflen)
35340+{
6892158b 35341+ struct path path;
57199397 35342+ char *res;
58c5fc13 35343+
6892158b
MT
35344+ path.dentry = (struct dentry *)dentry;
35345+ path.mnt = (struct vfsmount *)vfsmnt;
35346+
35347+ /* we can use real_root.dentry, real_root.mnt, because this is only called
57199397 35348+ by the RBAC system */
6892158b 35349+ res = gen_full_path(&path, &real_root, buf, buflen);
58c5fc13 35350+
57199397
MT
35351+ return res;
35352+}
58c5fc13 35353+
57199397
MT
35354+static char *
35355+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
35356+ char *buf, int buflen)
35357+{
35358+ char *res;
6892158b
MT
35359+ struct path path;
35360+ struct path root;
57199397 35361+ struct task_struct *reaper = &init_task;
58c5fc13 35362+
6892158b
MT
35363+ path.dentry = (struct dentry *)dentry;
35364+ path.mnt = (struct vfsmount *)vfsmnt;
35365+
35366+ /* we can't use real_root.dentry, real_root.mnt, because they belong only to the RBAC system */
16454cff
MT
35367+ root.dentry = reaper->nsproxy->mnt_ns->root->mnt_root;
35368+ root.mnt = reaper->nsproxy->mnt_ns->root;
35369+ path_get(&root);
58c5fc13 35370+
16454cff 35371+ write_seqlock(&rename_lock);
bc901d79 35372+ br_read_lock(vfsmount_lock);
6892158b 35373+ res = gen_full_path(&path, &root, buf, buflen);
bc901d79 35374+ br_read_unlock(vfsmount_lock);
16454cff 35375+ write_sequnlock(&rename_lock);
58c5fc13 35376+
6892158b 35377+ path_put(&root);
57199397
MT
35378+ return res;
35379+}
58c5fc13 35380+
57199397
MT
35381+static char *
35382+gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
35383+{
35384+ char *ret;
16454cff 35385+ write_seqlock(&rename_lock);
bc901d79 35386+ br_read_lock(vfsmount_lock);
57199397
MT
35387+ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
35388+ PAGE_SIZE);
bc901d79 35389+ br_read_unlock(vfsmount_lock);
16454cff 35390+ write_sequnlock(&rename_lock);
57199397
MT
35391+ return ret;
35392+}
58c5fc13 35393+
57199397
MT
35394+char *
35395+gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
35396+{
35397+ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
35398+ PAGE_SIZE);
35399+}
58c5fc13 35400+
57199397
MT
35401+char *
35402+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
35403+{
35404+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
35405+ PAGE_SIZE);
35406+}
58c5fc13 35407+
57199397
MT
35408+char *
35409+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
35410+{
35411+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
35412+ PAGE_SIZE);
35413+}
58c5fc13 35414+
57199397
MT
35415+char *
35416+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
35417+{
35418+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
35419+ PAGE_SIZE);
35420+}
58c5fc13 35421+
57199397
MT
35422+char *
35423+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
35424+{
35425+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
35426+ PAGE_SIZE);
35427+}
58c5fc13 35428+
57199397
MT
35429+__inline__ __u32
35430+to_gr_audit(const __u32 reqmode)
35431+{
35432+ /* masks off auditable permission flags, then shifts them to create
35433+ auditing flags, and adds the special case of append auditing if
35434+ we're requesting write */
35435+ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
35436+}
58c5fc13 35437+
57199397
MT
35438+struct acl_subject_label *
35439+lookup_subject_map(const struct acl_subject_label *userp)
35440+{
35441+ unsigned int index = shash(userp, subj_map_set.s_size);
35442+ struct subject_map *match;
58c5fc13 35443+
57199397 35444+ match = subj_map_set.s_hash[index];
58c5fc13 35445+
57199397
MT
35446+ while (match && match->user != userp)
35447+ match = match->next;
58c5fc13 35448+
57199397
MT
35449+ if (match != NULL)
35450+ return match->kernel;
35451+ else
35452+ return NULL;
35453+}
58c5fc13 35454+
57199397
MT
35455+static void
35456+insert_subj_map_entry(struct subject_map *subjmap)
35457+{
35458+ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
35459+ struct subject_map **curr;
58c5fc13 35460+
57199397 35461+ subjmap->prev = NULL;
58c5fc13 35462+
57199397
MT
35463+ curr = &subj_map_set.s_hash[index];
35464+ if (*curr != NULL)
35465+ (*curr)->prev = subjmap;
58c5fc13 35466+
57199397
MT
35467+ subjmap->next = *curr;
35468+ *curr = subjmap;
58c5fc13 35469+
57199397
MT
35470+ return;
35471+}
58c5fc13 35472+
57199397
MT
35473+static struct acl_role_label *
35474+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
35475+ const gid_t gid)
35476+{
35477+ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
35478+ struct acl_role_label *match;
35479+ struct role_allowed_ip *ipp;
35480+ unsigned int x;
bc901d79
MT
35481+ u32 curr_ip = task->signal->curr_ip;
35482+
35483+ task->signal->saved_ip = curr_ip;
58c5fc13 35484+
57199397 35485+ match = acl_role_set.r_hash[index];
58c5fc13 35486+
57199397
MT
35487+ while (match) {
35488+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
35489+ for (x = 0; x < match->domain_child_num; x++) {
35490+ if (match->domain_children[x] == uid)
35491+ goto found;
35492+ }
35493+ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
35494+ break;
35495+ match = match->next;
35496+ }
35497+found:
35498+ if (match == NULL) {
35499+ try_group:
35500+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
35501+ match = acl_role_set.r_hash[index];
58c5fc13 35502+
57199397
MT
35503+ while (match) {
35504+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
35505+ for (x = 0; x < match->domain_child_num; x++) {
35506+ if (match->domain_children[x] == gid)
35507+ goto found2;
35508+ }
35509+ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
35510+ break;
35511+ match = match->next;
35512+ }
35513+found2:
35514+ if (match == NULL)
35515+ match = default_role;
35516+ if (match->allowed_ips == NULL)
35517+ return match;
35518+ else {
35519+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
35520+ if (likely
bc901d79 35521+ ((ntohl(curr_ip) & ipp->netmask) ==
57199397
MT
35522+ (ntohl(ipp->addr) & ipp->netmask)))
35523+ return match;
35524+ }
35525+ match = default_role;
35526+ }
35527+ } else if (match->allowed_ips == NULL) {
35528+ return match;
35529+ } else {
35530+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
35531+ if (likely
bc901d79 35532+ ((ntohl(curr_ip) & ipp->netmask) ==
57199397
MT
35533+ (ntohl(ipp->addr) & ipp->netmask)))
35534+ return match;
35535+ }
35536+ goto try_group;
35537+ }
58c5fc13 35538+
57199397
MT
35539+ return match;
35540+}
58c5fc13 35541+
57199397
MT
35542+struct acl_subject_label *
35543+lookup_acl_subj_label(const ino_t ino, const dev_t dev,
35544+ const struct acl_role_label *role)
35545+{
35546+ unsigned int index = fhash(ino, dev, role->subj_hash_size);
35547+ struct acl_subject_label *match;
58c5fc13 35548+
57199397 35549+ match = role->subj_hash[index];
58c5fc13 35550+
57199397
MT
35551+ while (match && (match->inode != ino || match->device != dev ||
35552+ (match->mode & GR_DELETED))) {
35553+ match = match->next;
35554+ }
58c5fc13 35555+
57199397
MT
35556+ if (match && !(match->mode & GR_DELETED))
35557+ return match;
35558+ else
35559+ return NULL;
35560+}
58c5fc13 35561+
57199397
MT
35562+struct acl_subject_label *
35563+lookup_acl_subj_label_deleted(const ino_t ino, const dev_t dev,
35564+ const struct acl_role_label *role)
35565+{
35566+ unsigned int index = fhash(ino, dev, role->subj_hash_size);
35567+ struct acl_subject_label *match;
58c5fc13 35568+
57199397 35569+ match = role->subj_hash[index];
58c5fc13 35570+
57199397
MT
35571+ while (match && (match->inode != ino || match->device != dev ||
35572+ !(match->mode & GR_DELETED))) {
35573+ match = match->next;
35574+ }
58c5fc13 35575+
57199397
MT
35576+ if (match && (match->mode & GR_DELETED))
35577+ return match;
35578+ else
35579+ return NULL;
35580+}
58c5fc13 35581+
57199397
MT
35582+static struct acl_object_label *
35583+lookup_acl_obj_label(const ino_t ino, const dev_t dev,
35584+ const struct acl_subject_label *subj)
35585+{
35586+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
35587+ struct acl_object_label *match;
58c5fc13 35588+
57199397 35589+ match = subj->obj_hash[index];
58c5fc13 35590+
57199397
MT
35591+ while (match && (match->inode != ino || match->device != dev ||
35592+ (match->mode & GR_DELETED))) {
35593+ match = match->next;
35594+ }
58c5fc13 35595+
57199397
MT
35596+ if (match && !(match->mode & GR_DELETED))
35597+ return match;
35598+ else
35599+ return NULL;
35600+}
58c5fc13 35601+
57199397
MT
35602+static struct acl_object_label *
35603+lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
35604+ const struct acl_subject_label *subj)
35605+{
35606+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
35607+ struct acl_object_label *match;
58c5fc13 35608+
57199397 35609+ match = subj->obj_hash[index];
58c5fc13 35610+
57199397
MT
35611+ while (match && (match->inode != ino || match->device != dev ||
35612+ !(match->mode & GR_DELETED))) {
35613+ match = match->next;
35614+ }
58c5fc13 35615+
57199397
MT
35616+ if (match && (match->mode & GR_DELETED))
35617+ return match;
58c5fc13 35618+
57199397 35619+ match = subj->obj_hash[index];
58c5fc13 35620+
57199397
MT
35621+ while (match && (match->inode != ino || match->device != dev ||
35622+ (match->mode & GR_DELETED))) {
35623+ match = match->next;
35624+ }
58c5fc13 35625+
57199397
MT
35626+ if (match && !(match->mode & GR_DELETED))
35627+ return match;
35628+ else
35629+ return NULL;
35630+}
58c5fc13 35631+
57199397
MT
35632+static struct name_entry *
35633+lookup_name_entry(const char *name)
35634+{
35635+ unsigned int len = strlen(name);
35636+ unsigned int key = full_name_hash(name, len);
35637+ unsigned int index = key % name_set.n_size;
35638+ struct name_entry *match;
58c5fc13 35639+
57199397 35640+ match = name_set.n_hash[index];
58c5fc13 35641+
57199397
MT
35642+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
35643+ match = match->next;
58c5fc13 35644+
57199397
MT
35645+ return match;
35646+}
58c5fc13 35647+
57199397
MT
35648+static struct name_entry *
35649+lookup_name_entry_create(const char *name)
35650+{
35651+ unsigned int len = strlen(name);
35652+ unsigned int key = full_name_hash(name, len);
35653+ unsigned int index = key % name_set.n_size;
35654+ struct name_entry *match;
58c5fc13 35655+
57199397 35656+ match = name_set.n_hash[index];
58c5fc13 35657+
57199397
MT
35658+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
35659+ !match->deleted))
35660+ match = match->next;
58c5fc13 35661+
57199397
MT
35662+ if (match && match->deleted)
35663+ return match;
58c5fc13 35664+
57199397 35665+ match = name_set.n_hash[index];
58c5fc13 35666+
57199397
MT
35667+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
35668+ match->deleted))
35669+ match = match->next;
58c5fc13 35670+
57199397
MT
35671+ if (match && !match->deleted)
35672+ return match;
35673+ else
35674+ return NULL;
35675+}
58c5fc13 35676+
57199397
MT
35677+static struct inodev_entry *
35678+lookup_inodev_entry(const ino_t ino, const dev_t dev)
35679+{
35680+ unsigned int index = fhash(ino, dev, inodev_set.i_size);
35681+ struct inodev_entry *match;
58c5fc13 35682+
57199397 35683+ match = inodev_set.i_hash[index];
58c5fc13 35684+
57199397
MT
35685+ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
35686+ match = match->next;
58c5fc13 35687+
57199397 35688+ return match;
58c5fc13
MT
35689+}
35690+
57199397
MT
35691+static void
35692+insert_inodev_entry(struct inodev_entry *entry)
58c5fc13 35693+{
57199397
MT
35694+ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
35695+ inodev_set.i_size);
35696+ struct inodev_entry **curr;
58c5fc13 35697+
57199397 35698+ entry->prev = NULL;
58c5fc13 35699+
57199397
MT
35700+ curr = &inodev_set.i_hash[index];
35701+ if (*curr != NULL)
35702+ (*curr)->prev = entry;
35703+
35704+ entry->next = *curr;
35705+ *curr = entry;
ae4e228f 35706+
57199397 35707+ return;
58c5fc13 35708+}
efbe55a5 35709+
57199397
MT
35710+static void
35711+__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
efbe55a5
MT
35712+{
35713+ unsigned int index =
35714+ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
35715+ struct acl_role_label **curr;
35716+ struct acl_role_label *tmp;
35717+
35718+ curr = &acl_role_set.r_hash[index];
35719+
35720+ /* if role was already inserted due to domains and already has
35721+ a role in the same bucket as it attached, then we need to
35722+ combine these two buckets
35723+ */
35724+ if (role->next) {
35725+ tmp = role->next;
35726+ while (tmp->next)
35727+ tmp = tmp->next;
35728+ tmp->next = *curr;
35729+ } else
35730+ role->next = *curr;
35731+ *curr = role;
35732+
35733+ return;
35734+}
35735+
35736+static void
35737+insert_acl_role_label(struct acl_role_label *role)
35738+{
35739+ int i;
35740+
35741+ if (role_list == NULL) {
35742+ role_list = role;
35743+ role->prev = NULL;
35744+ } else {
35745+ role->prev = role_list;
35746+ role_list = role;
35747+ }
35748+
35749+ /* used for hash chains */
35750+ role->next = NULL;
35751+
35752+ if (role->roletype & GR_ROLE_DOMAIN) {
35753+ for (i = 0; i < role->domain_child_num; i++)
35754+ __insert_acl_role_label(role, role->domain_children[i]);
35755+ } else
35756+ __insert_acl_role_label(role, role->uidgid);
35757+}
35758+
35759+static int
35760+insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
35761+{
35762+ struct name_entry **curr, *nentry;
35763+ struct inodev_entry *ientry;
35764+ unsigned int len = strlen(name);
35765+ unsigned int key = full_name_hash(name, len);
35766+ unsigned int index = key % name_set.n_size;
35767+
35768+ curr = &name_set.n_hash[index];
35769+
35770+ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
35771+ curr = &((*curr)->next);
35772+
35773+ if (*curr != NULL)
35774+ return 1;
35775+
35776+ nentry = acl_alloc(sizeof (struct name_entry));
35777+ if (nentry == NULL)
35778+ return 0;
35779+ ientry = acl_alloc(sizeof (struct inodev_entry));
35780+ if (ientry == NULL)
35781+ return 0;
35782+ ientry->nentry = nentry;
35783+
35784+ nentry->key = key;
35785+ nentry->name = name;
35786+ nentry->inode = inode;
35787+ nentry->device = device;
35788+ nentry->len = len;
35789+ nentry->deleted = deleted;
35790+
35791+ nentry->prev = NULL;
35792+ curr = &name_set.n_hash[index];
35793+ if (*curr != NULL)
35794+ (*curr)->prev = nentry;
35795+ nentry->next = *curr;
35796+ *curr = nentry;
35797+
35798+ /* insert us into the table searchable by inode/dev */
35799+ insert_inodev_entry(ientry);
35800+
35801+ return 1;
35802+}
35803+
35804+static void
35805+insert_acl_obj_label(struct acl_object_label *obj,
35806+ struct acl_subject_label *subj)
35807+{
35808+ unsigned int index =
35809+ fhash(obj->inode, obj->device, subj->obj_hash_size);
35810+ struct acl_object_label **curr;
35811+
35812+
35813+ obj->prev = NULL;
35814+
35815+ curr = &subj->obj_hash[index];
35816+ if (*curr != NULL)
35817+ (*curr)->prev = obj;
35818+
35819+ obj->next = *curr;
35820+ *curr = obj;
35821+
35822+ return;
35823+}
35824+
35825+static void
35826+insert_acl_subj_label(struct acl_subject_label *obj,
35827+ struct acl_role_label *role)
35828+{
35829+ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
35830+ struct acl_subject_label **curr;
35831+
35832+ obj->prev = NULL;
35833+
35834+ curr = &role->subj_hash[index];
35835+ if (*curr != NULL)
35836+ (*curr)->prev = obj;
35837+
35838+ obj->next = *curr;
35839+ *curr = obj;
35840+
35841+ return;
35842+}
35843+
35844+/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
35845+
35846+static void *
35847+create_table(__u32 * len, int elementsize)
35848+{
35849+ unsigned int table_sizes[] = {
35850+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
35851+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
35852+ 4194301, 8388593, 16777213, 33554393, 67108859
35853+ };
35854+ void *newtable = NULL;
35855+ unsigned int pwr = 0;
35856+
35857+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
35858+ table_sizes[pwr] <= *len)
35859+ pwr++;
35860+
35861+ if (table_sizes[pwr] <= *len || (table_sizes[pwr] > ULONG_MAX / elementsize))
35862+ return newtable;
35863+
35864+ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
35865+ newtable =
35866+ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
35867+ else
35868+ newtable = vmalloc(table_sizes[pwr] * elementsize);
35869+
35870+ *len = table_sizes[pwr];
35871+
35872+ return newtable;
35873+}
35874+
35875+static int
35876+init_variables(const struct gr_arg *arg)
35877+{
35878+ struct task_struct *reaper = &init_task;
35879+ unsigned int stacksize;
58c5fc13
MT
35880+
35881+ subj_map_set.s_size = arg->role_db.num_subjects;
35882+ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
35883+ name_set.n_size = arg->role_db.num_objects;
35884+ inodev_set.i_size = arg->role_db.num_objects;
35885+
35886+ if (!subj_map_set.s_size || !acl_role_set.r_size ||
35887+ !name_set.n_size || !inodev_set.i_size)
35888+ return 1;
35889+
35890+ if (!gr_init_uidset())
35891+ return 1;
35892+
35893+ /* set up the stack that holds allocation info */
35894+
35895+ stacksize = arg->role_db.num_pointers + 5;
35896+
35897+ if (!acl_alloc_stack_init(stacksize))
35898+ return 1;
35899+
35900+ /* grab reference for the real root dentry and vfsmount */
16454cff
MT
35901+ real_root.dentry = reaper->nsproxy->mnt_ns->root->mnt_root;
35902+ real_root.mnt = reaper->nsproxy->mnt_ns->root;
35903+ path_get(&real_root);
58c5fc13 35904+
16454cff
MT
35905+#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG
35906+ printk(KERN_ALERT "Obtained real root device=%d, inode=%lu\n", __get_dev(real_root.dentry), real_root.dentry->d_inode->i_ino);
35907+#endif
35908+
58c5fc13
MT
35909+ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
35910+ if (fakefs_obj == NULL)
35911+ return 1;
35912+ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
35913+
35914+ subj_map_set.s_hash =
35915+ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
35916+ acl_role_set.r_hash =
35917+ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
35918+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
35919+ inodev_set.i_hash =
35920+ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
35921+
35922+ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
35923+ !name_set.n_hash || !inodev_set.i_hash)
35924+ return 1;
35925+
35926+ memset(subj_map_set.s_hash, 0,
35927+ sizeof(struct subject_map *) * subj_map_set.s_size);
35928+ memset(acl_role_set.r_hash, 0,
35929+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
35930+ memset(name_set.n_hash, 0,
35931+ sizeof (struct name_entry *) * name_set.n_size);
35932+ memset(inodev_set.i_hash, 0,
35933+ sizeof (struct inodev_entry *) * inodev_set.i_size);
35934+
35935+ return 0;
35936+}
35937+
35938+/* free information not needed after startup
35939+ currently contains user->kernel pointer mappings for subjects
35940+*/
35941+
35942+static void
35943+free_init_variables(void)
35944+{
35945+ __u32 i;
35946+
35947+ if (subj_map_set.s_hash) {
35948+ for (i = 0; i < subj_map_set.s_size; i++) {
35949+ if (subj_map_set.s_hash[i]) {
35950+ kfree(subj_map_set.s_hash[i]);
35951+ subj_map_set.s_hash[i] = NULL;
35952+ }
35953+ }
35954+
35955+ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
35956+ PAGE_SIZE)
35957+ kfree(subj_map_set.s_hash);
35958+ else
35959+ vfree(subj_map_set.s_hash);
35960+ }
35961+
35962+ return;
35963+}
35964+
35965+static void
35966+free_variables(void)
35967+{
35968+ struct acl_subject_label *s;
35969+ struct acl_role_label *r;
35970+ struct task_struct *task, *task2;
ae4e228f 35971+ unsigned int x;
58c5fc13
MT
35972+
35973+ gr_clear_learn_entries();
35974+
35975+ read_lock(&tasklist_lock);
35976+ do_each_thread(task2, task) {
35977+ task->acl_sp_role = 0;
35978+ task->acl_role_id = 0;
35979+ task->acl = NULL;
35980+ task->role = NULL;
35981+ } while_each_thread(task2, task);
35982+ read_unlock(&tasklist_lock);
35983+
35984+ /* release the reference to the real root dentry and vfsmount */
6892158b 35985+ path_put(&real_root);
58c5fc13
MT
35986+
35987+ /* free all object hash tables */
35988+
ae4e228f 35989+ FOR_EACH_ROLE_START(r)
58c5fc13 35990+ if (r->subj_hash == NULL)
ae4e228f 35991+ goto next_role;
58c5fc13
MT
35992+ FOR_EACH_SUBJECT_START(r, s, x)
35993+ if (s->obj_hash == NULL)
35994+ break;
35995+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
35996+ kfree(s->obj_hash);
35997+ else
35998+ vfree(s->obj_hash);
35999+ FOR_EACH_SUBJECT_END(s, x)
36000+ FOR_EACH_NESTED_SUBJECT_START(r, s)
36001+ if (s->obj_hash == NULL)
36002+ break;
36003+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
36004+ kfree(s->obj_hash);
36005+ else
36006+ vfree(s->obj_hash);
36007+ FOR_EACH_NESTED_SUBJECT_END(s)
36008+ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
36009+ kfree(r->subj_hash);
36010+ else
36011+ vfree(r->subj_hash);
36012+ r->subj_hash = NULL;
ae4e228f
MT
36013+next_role:
36014+ FOR_EACH_ROLE_END(r)
58c5fc13
MT
36015+
36016+ acl_free_all();
36017+
36018+ if (acl_role_set.r_hash) {
36019+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
36020+ PAGE_SIZE)
36021+ kfree(acl_role_set.r_hash);
36022+ else
36023+ vfree(acl_role_set.r_hash);
36024+ }
36025+ if (name_set.n_hash) {
36026+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
36027+ PAGE_SIZE)
36028+ kfree(name_set.n_hash);
36029+ else
36030+ vfree(name_set.n_hash);
36031+ }
36032+
36033+ if (inodev_set.i_hash) {
36034+ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
36035+ PAGE_SIZE)
36036+ kfree(inodev_set.i_hash);
36037+ else
36038+ vfree(inodev_set.i_hash);
36039+ }
36040+
36041+ gr_free_uidset();
36042+
36043+ memset(&name_set, 0, sizeof (struct name_db));
36044+ memset(&inodev_set, 0, sizeof (struct inodev_db));
36045+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
36046+ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
36047+
36048+ default_role = NULL;
ae4e228f 36049+ role_list = NULL;
58c5fc13
MT
36050+
36051+ return;
36052+}
36053+
36054+static __u32
36055+count_user_objs(struct acl_object_label *userp)
36056+{
36057+ struct acl_object_label o_tmp;
36058+ __u32 num = 0;
36059+
36060+ while (userp) {
36061+ if (copy_from_user(&o_tmp, userp,
36062+ sizeof (struct acl_object_label)))
36063+ break;
36064+
36065+ userp = o_tmp.prev;
36066+ num++;
36067+ }
36068+
36069+ return num;
36070+}
36071+
36072+static struct acl_subject_label *
36073+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
36074+
36075+static int
36076+copy_user_glob(struct acl_object_label *obj)
36077+{
36078+ struct acl_object_label *g_tmp, **guser;
36079+ unsigned int len;
36080+ char *tmp;
36081+
36082+ if (obj->globbed == NULL)
36083+ return 0;
36084+
36085+ guser = &obj->globbed;
36086+ while (*guser) {
36087+ g_tmp = (struct acl_object_label *)
36088+ acl_alloc(sizeof (struct acl_object_label));
36089+ if (g_tmp == NULL)
36090+ return -ENOMEM;
36091+
36092+ if (copy_from_user(g_tmp, *guser,
36093+ sizeof (struct acl_object_label)))
36094+ return -EFAULT;
36095+
36096+ len = strnlen_user(g_tmp->filename, PATH_MAX);
36097+
36098+ if (!len || len >= PATH_MAX)
36099+ return -EINVAL;
36100+
36101+ if ((tmp = (char *) acl_alloc(len)) == NULL)
36102+ return -ENOMEM;
36103+
36104+ if (copy_from_user(tmp, g_tmp->filename, len))
36105+ return -EFAULT;
36106+ tmp[len-1] = '\0';
36107+ g_tmp->filename = tmp;
36108+
36109+ *guser = g_tmp;
36110+ guser = &(g_tmp->next);
36111+ }
36112+
36113+ return 0;
36114+}
36115+
36116+static int
36117+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
36118+ struct acl_role_label *role)
36119+{
36120+ struct acl_object_label *o_tmp;
36121+ unsigned int len;
36122+ int ret;
36123+ char *tmp;
36124+
36125+ while (userp) {
36126+ if ((o_tmp = (struct acl_object_label *)
36127+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
36128+ return -ENOMEM;
36129+
36130+ if (copy_from_user(o_tmp, userp,
36131+ sizeof (struct acl_object_label)))
36132+ return -EFAULT;
36133+
36134+ userp = o_tmp->prev;
36135+
36136+ len = strnlen_user(o_tmp->filename, PATH_MAX);
36137+
36138+ if (!len || len >= PATH_MAX)
36139+ return -EINVAL;
36140+
36141+ if ((tmp = (char *) acl_alloc(len)) == NULL)
36142+ return -ENOMEM;
36143+
36144+ if (copy_from_user(tmp, o_tmp->filename, len))
36145+ return -EFAULT;
36146+ tmp[len-1] = '\0';
36147+ o_tmp->filename = tmp;
36148+
36149+ insert_acl_obj_label(o_tmp, subj);
36150+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
36151+ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
36152+ return -ENOMEM;
36153+
36154+ ret = copy_user_glob(o_tmp);
36155+ if (ret)
36156+ return ret;
36157+
36158+ if (o_tmp->nested) {
36159+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
36160+ if (IS_ERR(o_tmp->nested))
36161+ return PTR_ERR(o_tmp->nested);
36162+
36163+ /* insert into nested subject list */
36164+ o_tmp->nested->next = role->hash->first;
36165+ role->hash->first = o_tmp->nested;
36166+ }
36167+ }
36168+
36169+ return 0;
36170+}
36171+
36172+static __u32
36173+count_user_subjs(struct acl_subject_label *userp)
36174+{
36175+ struct acl_subject_label s_tmp;
36176+ __u32 num = 0;
36177+
36178+ while (userp) {
36179+ if (copy_from_user(&s_tmp, userp,
36180+ sizeof (struct acl_subject_label)))
36181+ break;
36182+
36183+ userp = s_tmp.prev;
36184+ /* do not count nested subjects against this count, since
36185+ they are not included in the hash table, but are
36186+ attached to objects. We have already counted
36187+ the subjects in userspace for the allocation
36188+ stack
36189+ */
36190+ if (!(s_tmp.mode & GR_NESTED))
36191+ num++;
36192+ }
36193+
36194+ return num;
36195+}
36196+
36197+static int
36198+copy_user_allowedips(struct acl_role_label *rolep)
36199+{
36200+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
36201+
36202+ ruserip = rolep->allowed_ips;
36203+
36204+ while (ruserip) {
36205+ rlast = rtmp;
36206+
36207+ if ((rtmp = (struct role_allowed_ip *)
36208+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
36209+ return -ENOMEM;
36210+
36211+ if (copy_from_user(rtmp, ruserip,
36212+ sizeof (struct role_allowed_ip)))
36213+ return -EFAULT;
36214+
36215+ ruserip = rtmp->prev;
36216+
36217+ if (!rlast) {
36218+ rtmp->prev = NULL;
36219+ rolep->allowed_ips = rtmp;
36220+ } else {
36221+ rlast->next = rtmp;
36222+ rtmp->prev = rlast;
36223+ }
36224+
36225+ if (!ruserip)
36226+ rtmp->next = NULL;
36227+ }
36228+
36229+ return 0;
36230+}
36231+
36232+static int
36233+copy_user_transitions(struct acl_role_label *rolep)
36234+{
36235+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
36236+
36237+ unsigned int len;
36238+ char *tmp;
36239+
36240+ rusertp = rolep->transitions;
36241+
36242+ while (rusertp) {
36243+ rlast = rtmp;
36244+
36245+ if ((rtmp = (struct role_transition *)
36246+ acl_alloc(sizeof (struct role_transition))) == NULL)
36247+ return -ENOMEM;
36248+
36249+ if (copy_from_user(rtmp, rusertp,
36250+ sizeof (struct role_transition)))
36251+ return -EFAULT;
36252+
36253+ rusertp = rtmp->prev;
36254+
36255+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
36256+
36257+ if (!len || len >= GR_SPROLE_LEN)
36258+ return -EINVAL;
36259+
36260+ if ((tmp = (char *) acl_alloc(len)) == NULL)
36261+ return -ENOMEM;
36262+
36263+ if (copy_from_user(tmp, rtmp->rolename, len))
36264+ return -EFAULT;
36265+ tmp[len-1] = '\0';
36266+ rtmp->rolename = tmp;
36267+
36268+ if (!rlast) {
36269+ rtmp->prev = NULL;
36270+ rolep->transitions = rtmp;
36271+ } else {
36272+ rlast->next = rtmp;
36273+ rtmp->prev = rlast;
36274+ }
36275+
36276+ if (!rusertp)
36277+ rtmp->next = NULL;
36278+ }
36279+
36280+ return 0;
36281+}
36282+
36283+static struct acl_subject_label *
36284+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
36285+{
36286+ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
36287+ unsigned int len;
36288+ char *tmp;
36289+ __u32 num_objs;
36290+ struct acl_ip_label **i_tmp, *i_utmp2;
36291+ struct gr_hash_struct ghash;
36292+ struct subject_map *subjmap;
36293+ unsigned int i_num;
36294+ int err;
36295+
36296+ s_tmp = lookup_subject_map(userp);
36297+
36298+ /* we've already copied this subject into the kernel, just return
36299+ the reference to it, and don't copy it over again
36300+ */
36301+ if (s_tmp)
36302+ return(s_tmp);
36303+
36304+ if ((s_tmp = (struct acl_subject_label *)
36305+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
36306+ return ERR_PTR(-ENOMEM);
36307+
36308+ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
36309+ if (subjmap == NULL)
36310+ return ERR_PTR(-ENOMEM);
36311+
36312+ subjmap->user = userp;
36313+ subjmap->kernel = s_tmp;
36314+ insert_subj_map_entry(subjmap);
36315+
36316+ if (copy_from_user(s_tmp, userp,
36317+ sizeof (struct acl_subject_label)))
36318+ return ERR_PTR(-EFAULT);
36319+
36320+ len = strnlen_user(s_tmp->filename, PATH_MAX);
36321+
36322+ if (!len || len >= PATH_MAX)
36323+ return ERR_PTR(-EINVAL);
36324+
36325+ if ((tmp = (char *) acl_alloc(len)) == NULL)
36326+ return ERR_PTR(-ENOMEM);
36327+
36328+ if (copy_from_user(tmp, s_tmp->filename, len))
36329+ return ERR_PTR(-EFAULT);
36330+ tmp[len-1] = '\0';
36331+ s_tmp->filename = tmp;
36332+
36333+ if (!strcmp(s_tmp->filename, "/"))
36334+ role->root_label = s_tmp;
36335+
36336+ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
36337+ return ERR_PTR(-EFAULT);
36338+
36339+ /* copy user and group transition tables */
36340+
36341+ if (s_tmp->user_trans_num) {
36342+ uid_t *uidlist;
36343+
36344+ uidlist = (uid_t *)acl_alloc_num(s_tmp->user_trans_num, sizeof(uid_t));
36345+ if (uidlist == NULL)
36346+ return ERR_PTR(-ENOMEM);
36347+ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
36348+ return ERR_PTR(-EFAULT);
36349+
36350+ s_tmp->user_transitions = uidlist;
36351+ }
36352+
36353+ if (s_tmp->group_trans_num) {
36354+ gid_t *gidlist;
36355+
36356+ gidlist = (gid_t *)acl_alloc_num(s_tmp->group_trans_num, sizeof(gid_t));
36357+ if (gidlist == NULL)
36358+ return ERR_PTR(-ENOMEM);
36359+ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
36360+ return ERR_PTR(-EFAULT);
36361+
36362+ s_tmp->group_transitions = gidlist;
36363+ }
36364+
36365+ /* set up object hash table */
36366+ num_objs = count_user_objs(ghash.first);
36367+
36368+ s_tmp->obj_hash_size = num_objs;
36369+ s_tmp->obj_hash =
36370+ (struct acl_object_label **)
36371+ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
36372+
36373+ if (!s_tmp->obj_hash)
36374+ return ERR_PTR(-ENOMEM);
36375+
36376+ memset(s_tmp->obj_hash, 0,
36377+ s_tmp->obj_hash_size *
36378+ sizeof (struct acl_object_label *));
36379+
36380+ /* add in objects */
36381+ err = copy_user_objs(ghash.first, s_tmp, role);
36382+
36383+ if (err)
36384+ return ERR_PTR(err);
36385+
36386+ /* set pointer for parent subject */
36387+ if (s_tmp->parent_subject) {
36388+ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
36389+
36390+ if (IS_ERR(s_tmp2))
36391+ return s_tmp2;
36392+
36393+ s_tmp->parent_subject = s_tmp2;
36394+ }
36395+
36396+ /* add in ip acls */
36397+
36398+ if (!s_tmp->ip_num) {
36399+ s_tmp->ips = NULL;
36400+ goto insert;
36401+ }
36402+
36403+ i_tmp =
36404+ (struct acl_ip_label **) acl_alloc_num(s_tmp->ip_num,
36405+ sizeof (struct acl_ip_label *));
36406+
36407+ if (!i_tmp)
36408+ return ERR_PTR(-ENOMEM);
36409+
36410+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
36411+ *(i_tmp + i_num) =
36412+ (struct acl_ip_label *)
36413+ acl_alloc(sizeof (struct acl_ip_label));
36414+ if (!*(i_tmp + i_num))
36415+ return ERR_PTR(-ENOMEM);
36416+
36417+ if (copy_from_user
36418+ (&i_utmp2, s_tmp->ips + i_num,
36419+ sizeof (struct acl_ip_label *)))
36420+ return ERR_PTR(-EFAULT);
36421+
36422+ if (copy_from_user
36423+ (*(i_tmp + i_num), i_utmp2,
36424+ sizeof (struct acl_ip_label)))
36425+ return ERR_PTR(-EFAULT);
36426+
36427+ if ((*(i_tmp + i_num))->iface == NULL)
36428+ continue;
36429+
36430+ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
36431+ if (!len || len >= IFNAMSIZ)
36432+ return ERR_PTR(-EINVAL);
36433+ tmp = acl_alloc(len);
36434+ if (tmp == NULL)
36435+ return ERR_PTR(-ENOMEM);
36436+ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
36437+ return ERR_PTR(-EFAULT);
36438+ (*(i_tmp + i_num))->iface = tmp;
36439+ }
36440+
36441+ s_tmp->ips = i_tmp;
36442+
36443+insert:
36444+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
36445+ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
36446+ return ERR_PTR(-ENOMEM);
36447+
36448+ return s_tmp;
36449+}
36450+
36451+static int
36452+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
36453+{
36454+ struct acl_subject_label s_pre;
36455+ struct acl_subject_label * ret;
36456+ int err;
36457+
36458+ while (userp) {
36459+ if (copy_from_user(&s_pre, userp,
36460+ sizeof (struct acl_subject_label)))
36461+ return -EFAULT;
36462+
36463+ /* do not add nested subjects here, add
36464+ while parsing objects
36465+ */
36466+
36467+ if (s_pre.mode & GR_NESTED) {
36468+ userp = s_pre.prev;
36469+ continue;
36470+ }
36471+
36472+ ret = do_copy_user_subj(userp, role);
36473+
36474+ err = PTR_ERR(ret);
36475+ if (IS_ERR(ret))
36476+ return err;
36477+
36478+ insert_acl_subj_label(ret, role);
36479+
36480+ userp = s_pre.prev;
36481+ }
36482+
36483+ return 0;
36484+}
36485+
36486+static int
36487+copy_user_acl(struct gr_arg *arg)
36488+{
36489+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
36490+ struct sprole_pw *sptmp;
36491+ struct gr_hash_struct *ghash;
36492+ uid_t *domainlist;
36493+ unsigned int r_num;
36494+ unsigned int len;
36495+ char *tmp;
36496+ int err = 0;
36497+ __u16 i;
36498+ __u32 num_subjs;
36499+
36500+ /* we need a default and kernel role */
36501+ if (arg->role_db.num_roles < 2)
36502+ return -EINVAL;
36503+
36504+ /* copy special role authentication info from userspace */
36505+
36506+ num_sprole_pws = arg->num_sprole_pws;
36507+ acl_special_roles = (struct sprole_pw **) acl_alloc_num(num_sprole_pws, sizeof(struct sprole_pw *));
36508+
36509+ if (!acl_special_roles) {
36510+ err = -ENOMEM;
36511+ goto cleanup;
36512+ }
36513+
36514+ for (i = 0; i < num_sprole_pws; i++) {
36515+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
36516+ if (!sptmp) {
36517+ err = -ENOMEM;
36518+ goto cleanup;
36519+ }
36520+ if (copy_from_user(sptmp, arg->sprole_pws + i,
36521+ sizeof (struct sprole_pw))) {
36522+ err = -EFAULT;
36523+ goto cleanup;
36524+ }
36525+
36526+ len =
36527+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
36528+
36529+ if (!len || len >= GR_SPROLE_LEN) {
36530+ err = -EINVAL;
36531+ goto cleanup;
36532+ }
36533+
36534+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
36535+ err = -ENOMEM;
36536+ goto cleanup;
36537+ }
36538+
36539+ if (copy_from_user(tmp, sptmp->rolename, len)) {
36540+ err = -EFAULT;
36541+ goto cleanup;
36542+ }
36543+ tmp[len-1] = '\0';
16454cff 36544+#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG
58c5fc13
MT
36545+ printk(KERN_ALERT "Copying special role %s\n", tmp);
36546+#endif
36547+ sptmp->rolename = tmp;
36548+ acl_special_roles[i] = sptmp;
36549+ }
36550+
36551+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
36552+
36553+ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
36554+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
36555+
36556+ if (!r_tmp) {
36557+ err = -ENOMEM;
36558+ goto cleanup;
36559+ }
36560+
36561+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
36562+ sizeof (struct acl_role_label *))) {
36563+ err = -EFAULT;
36564+ goto cleanup;
36565+ }
36566+
36567+ if (copy_from_user(r_tmp, r_utmp2,
36568+ sizeof (struct acl_role_label))) {
36569+ err = -EFAULT;
36570+ goto cleanup;
36571+ }
36572+
36573+ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
36574+
36575+ if (!len || len >= PATH_MAX) {
36576+ err = -EINVAL;
36577+ goto cleanup;
36578+ }
36579+
36580+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
36581+ err = -ENOMEM;
36582+ goto cleanup;
36583+ }
36584+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
36585+ err = -EFAULT;
36586+ goto cleanup;
36587+ }
36588+ tmp[len-1] = '\0';
36589+ r_tmp->rolename = tmp;
36590+
36591+ if (!strcmp(r_tmp->rolename, "default")
36592+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
36593+ default_role = r_tmp;
36594+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
36595+ kernel_role = r_tmp;
36596+ }
36597+
36598+ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
36599+ err = -ENOMEM;
36600+ goto cleanup;
36601+ }
36602+ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
36603+ err = -EFAULT;
36604+ goto cleanup;
36605+ }
36606+
36607+ r_tmp->hash = ghash;
36608+
36609+ num_subjs = count_user_subjs(r_tmp->hash->first);
36610+
36611+ r_tmp->subj_hash_size = num_subjs;
36612+ r_tmp->subj_hash =
36613+ (struct acl_subject_label **)
36614+ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
36615+
36616+ if (!r_tmp->subj_hash) {
36617+ err = -ENOMEM;
36618+ goto cleanup;
36619+ }
36620+
36621+ err = copy_user_allowedips(r_tmp);
36622+ if (err)
36623+ goto cleanup;
36624+
36625+ /* copy domain info */
36626+ if (r_tmp->domain_children != NULL) {
36627+ domainlist = acl_alloc_num(r_tmp->domain_child_num, sizeof(uid_t));
36628+ if (domainlist == NULL) {
36629+ err = -ENOMEM;
36630+ goto cleanup;
36631+ }
36632+ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
36633+ err = -EFAULT;
36634+ goto cleanup;
36635+ }
36636+ r_tmp->domain_children = domainlist;
36637+ }
36638+
36639+ err = copy_user_transitions(r_tmp);
36640+ if (err)
36641+ goto cleanup;
36642+
36643+ memset(r_tmp->subj_hash, 0,
36644+ r_tmp->subj_hash_size *
36645+ sizeof (struct acl_subject_label *));
36646+
36647+ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
36648+
36649+ if (err)
36650+ goto cleanup;
36651+
36652+ /* set nested subject list to null */
36653+ r_tmp->hash->first = NULL;
36654+
36655+ insert_acl_role_label(r_tmp);
36656+ }
36657+
36658+ goto return_err;
36659+ cleanup:
36660+ free_variables();
36661+ return_err:
36662+ return err;
36663+
36664+}
36665+
36666+static int
36667+gracl_init(struct gr_arg *args)
36668+{
36669+ int error = 0;
36670+
36671+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
36672+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
36673+
36674+ if (init_variables(args)) {
36675+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
36676+ error = -ENOMEM;
36677+ free_variables();
36678+ goto out;
36679+ }
36680+
36681+ error = copy_user_acl(args);
36682+ free_init_variables();
36683+ if (error) {
36684+ free_variables();
36685+ goto out;
36686+ }
36687+
36688+ if ((error = gr_set_acls(0))) {
36689+ free_variables();
36690+ goto out;
36691+ }
36692+
ae4e228f 36693+ pax_open_kernel();
58c5fc13 36694+ gr_status |= GR_READY;
ae4e228f 36695+ pax_close_kernel();
58c5fc13
MT
36696+
36697+ out:
36698+ return error;
36699+}
36700+
36701+/* derived from glibc fnmatch() 0: match, 1: no match*/
36702+
36703+static int
36704+glob_match(const char *p, const char *n)
36705+{
36706+ char c;
36707+
36708+ while ((c = *p++) != '\0') {
36709+ switch (c) {
36710+ case '?':
36711+ if (*n == '\0')
36712+ return 1;
36713+ else if (*n == '/')
36714+ return 1;
36715+ break;
36716+ case '\\':
36717+ if (*n != c)
36718+ return 1;
36719+ break;
36720+ case '*':
36721+ for (c = *p++; c == '?' || c == '*'; c = *p++) {
36722+ if (*n == '/')
36723+ return 1;
36724+ else if (c == '?') {
36725+ if (*n == '\0')
36726+ return 1;
36727+ else
36728+ ++n;
36729+ }
36730+ }
36731+ if (c == '\0') {
36732+ return 0;
36733+ } else {
36734+ const char *endp;
36735+
36736+ if ((endp = strchr(n, '/')) == NULL)
36737+ endp = n + strlen(n);
36738+
36739+ if (c == '[') {
36740+ for (--p; n < endp; ++n)
36741+ if (!glob_match(p, n))
36742+ return 0;
36743+ } else if (c == '/') {
36744+ while (*n != '\0' && *n != '/')
36745+ ++n;
36746+ if (*n == '/' && !glob_match(p, n + 1))
36747+ return 0;
36748+ } else {
36749+ for (--p; n < endp; ++n)
36750+ if (*n == c && !glob_match(p, n))
36751+ return 0;
36752+ }
36753+
36754+ return 1;
36755+ }
36756+ case '[':
36757+ {
36758+ int not;
36759+ char cold;
36760+
36761+ if (*n == '\0' || *n == '/')
36762+ return 1;
36763+
36764+ not = (*p == '!' || *p == '^');
36765+ if (not)
36766+ ++p;
36767+
36768+ c = *p++;
36769+ for (;;) {
36770+ unsigned char fn = (unsigned char)*n;
36771+
36772+ if (c == '\0')
36773+ return 1;
36774+ else {
36775+ if (c == fn)
36776+ goto matched;
36777+ cold = c;
36778+ c = *p++;
36779+
36780+ if (c == '-' && *p != ']') {
36781+ unsigned char cend = *p++;
36782+
36783+ if (cend == '\0')
36784+ return 1;
36785+
36786+ if (cold <= fn && fn <= cend)
36787+ goto matched;
36788+
36789+ c = *p++;
36790+ }
36791+ }
36792+
36793+ if (c == ']')
36794+ break;
36795+ }
36796+ if (!not)
36797+ return 1;
36798+ break;
36799+ matched:
36800+ while (c != ']') {
36801+ if (c == '\0')
36802+ return 1;
36803+
36804+ c = *p++;
36805+ }
36806+ if (not)
36807+ return 1;
36808+ }
36809+ break;
36810+ default:
36811+ if (c != *n)
36812+ return 1;
36813+ }
36814+
36815+ ++n;
36816+ }
36817+
36818+ if (*n == '\0')
36819+ return 0;
36820+
36821+ if (*n == '/')
36822+ return 0;
36823+
36824+ return 1;
36825+}
36826+
36827+static struct acl_object_label *
36828+chk_glob_label(struct acl_object_label *globbed,
36829+ struct dentry *dentry, struct vfsmount *mnt, char **path)
36830+{
36831+ struct acl_object_label *tmp;
36832+
36833+ if (*path == NULL)
36834+ *path = gr_to_filename_nolock(dentry, mnt);
36835+
36836+ tmp = globbed;
36837+
36838+ while (tmp) {
36839+ if (!glob_match(tmp->filename, *path))
36840+ return tmp;
36841+ tmp = tmp->next;
36842+ }
36843+
36844+ return NULL;
36845+}
36846+
36847+static struct acl_object_label *
36848+__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
36849+ const ino_t curr_ino, const dev_t curr_dev,
36850+ const struct acl_subject_label *subj, char **path, const int checkglob)
36851+{
36852+ struct acl_subject_label *tmpsubj;
36853+ struct acl_object_label *retval;
36854+ struct acl_object_label *retval2;
36855+
36856+ tmpsubj = (struct acl_subject_label *) subj;
36857+ read_lock(&gr_inode_lock);
36858+ do {
36859+ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
36860+ if (retval) {
36861+ if (checkglob && retval->globbed) {
36862+ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
36863+ (struct vfsmount *)orig_mnt, path);
36864+ if (retval2)
36865+ retval = retval2;
36866+ }
36867+ break;
36868+ }
36869+ } while ((tmpsubj = tmpsubj->parent_subject));
36870+ read_unlock(&gr_inode_lock);
36871+
36872+ return retval;
36873+}
36874+
36875+static __inline__ struct acl_object_label *
36876+full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
16454cff 36877+ struct dentry *curr_dentry,
58c5fc13
MT
36878+ const struct acl_subject_label *subj, char **path, const int checkglob)
36879+{
bc901d79 36880+ int newglob = checkglob;
16454cff
MT
36881+ ino_t inode;
36882+ dev_t device;
bc901d79
MT
36883+
36884+ /* if we aren't checking a subdirectory of the original path yet, don't do glob checking
36885+ as we don't want a / * rule to match instead of the / object
36886+ don't do this for create lookups that call this function though, since they're looking up
36887+ on the parent and thus need globbing checks on all paths
36888+ */
36889+ if (orig_dentry == curr_dentry && newglob != GR_CREATE_GLOB)
36890+ newglob = GR_NO_GLOB;
36891+
16454cff
MT
36892+ spin_lock(&curr_dentry->d_lock);
36893+ inode = curr_dentry->d_inode->i_ino;
36894+ device = __get_dev(curr_dentry);
36895+ spin_unlock(&curr_dentry->d_lock);
36896+
36897+ return __full_lookup(orig_dentry, orig_mnt, inode, device, subj, path, newglob);
58c5fc13
MT
36898+}
36899+
36900+static struct acl_object_label *
36901+__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36902+ const struct acl_subject_label *subj, char *path, const int checkglob)
36903+{
36904+ struct dentry *dentry = (struct dentry *) l_dentry;
36905+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
36906+ struct acl_object_label *retval;
16454cff 36907+ struct dentry *parent;
58c5fc13 36908+
16454cff 36909+ write_seqlock(&rename_lock);
bc901d79 36910+ br_read_lock(vfsmount_lock);
58c5fc13
MT
36911+
36912+ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
df50ba0c
MT
36913+#ifdef CONFIG_HUGETLBFS
36914+ mnt == hugetlbfs_vfsmount ||
36915+#endif
58c5fc13
MT
36916+ /* ignore Eric Biederman */
36917+ IS_PRIVATE(l_dentry->d_inode))) {
36918+ retval = fakefs_obj;
36919+ goto out;
36920+ }
36921+
36922+ for (;;) {
6892158b 36923+ if (dentry == real_root.dentry && mnt == real_root.mnt)
58c5fc13
MT
36924+ break;
36925+
36926+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
36927+ if (mnt->mnt_parent == mnt)
36928+ break;
36929+
36930+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
36931+ if (retval != NULL)
36932+ goto out;
36933+
36934+ dentry = mnt->mnt_mountpoint;
36935+ mnt = mnt->mnt_parent;
36936+ continue;
36937+ }
36938+
16454cff 36939+ parent = dentry->d_parent;
58c5fc13
MT
36940+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
36941+ if (retval != NULL)
36942+ goto out;
36943+
16454cff 36944+ dentry = parent;
58c5fc13
MT
36945+ }
36946+
36947+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
36948+
16454cff 36949+ /* real_root is pinned so we don't have to hold a reference */
58c5fc13 36950+ if (retval == NULL)
6892158b 36951+ retval = full_lookup(l_dentry, l_mnt, real_root.dentry, subj, &path, checkglob);
58c5fc13 36952+out:
bc901d79 36953+ br_read_unlock(vfsmount_lock);
16454cff 36954+ write_sequnlock(&rename_lock);
bc901d79
MT
36955+
36956+ BUG_ON(retval == NULL);
36957+
58c5fc13
MT
36958+ return retval;
36959+}
36960+
36961+static __inline__ struct acl_object_label *
36962+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36963+ const struct acl_subject_label *subj)
36964+{
36965+ char *path = NULL;
bc901d79 36966+ return __chk_obj_label(l_dentry, l_mnt, subj, path, GR_REG_GLOB);
58c5fc13
MT
36967+}
36968+
36969+static __inline__ struct acl_object_label *
36970+chk_obj_label_noglob(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36971+ const struct acl_subject_label *subj)
36972+{
36973+ char *path = NULL;
bc901d79 36974+ return __chk_obj_label(l_dentry, l_mnt, subj, path, GR_NO_GLOB);
58c5fc13
MT
36975+}
36976+
36977+static __inline__ struct acl_object_label *
36978+chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36979+ const struct acl_subject_label *subj, char *path)
36980+{
bc901d79 36981+ return __chk_obj_label(l_dentry, l_mnt, subj, path, GR_CREATE_GLOB);
58c5fc13
MT
36982+}
36983+
36984+static struct acl_subject_label *
36985+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36986+ const struct acl_role_label *role)
36987+{
36988+ struct dentry *dentry = (struct dentry *) l_dentry;
36989+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
36990+ struct acl_subject_label *retval;
16454cff 36991+ struct dentry *parent;
58c5fc13 36992+
16454cff 36993+ write_seqlock(&rename_lock);
bc901d79 36994+ br_read_lock(vfsmount_lock);
58c5fc13
MT
36995+
36996+ for (;;) {
6892158b 36997+ if (dentry == real_root.dentry && mnt == real_root.mnt)
58c5fc13
MT
36998+ break;
36999+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
37000+ if (mnt->mnt_parent == mnt)
37001+ break;
37002+
16454cff 37003+ spin_lock(&dentry->d_lock);
58c5fc13
MT
37004+ read_lock(&gr_inode_lock);
37005+ retval =
37006+ lookup_acl_subj_label(dentry->d_inode->i_ino,
16454cff 37007+ __get_dev(dentry), role);
58c5fc13 37008+ read_unlock(&gr_inode_lock);
16454cff 37009+ spin_unlock(&dentry->d_lock);
58c5fc13
MT
37010+ if (retval != NULL)
37011+ goto out;
37012+
37013+ dentry = mnt->mnt_mountpoint;
37014+ mnt = mnt->mnt_parent;
37015+ continue;
37016+ }
37017+
16454cff 37018+ spin_lock(&dentry->d_lock);
58c5fc13
MT
37019+ read_lock(&gr_inode_lock);
37020+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
16454cff 37021+ __get_dev(dentry), role);
58c5fc13 37022+ read_unlock(&gr_inode_lock);
16454cff
MT
37023+ parent = dentry->d_parent;
37024+ spin_unlock(&dentry->d_lock);
37025+
58c5fc13
MT
37026+ if (retval != NULL)
37027+ goto out;
37028+
16454cff 37029+ dentry = parent;
58c5fc13
MT
37030+ }
37031+
16454cff 37032+ spin_lock(&dentry->d_lock);
58c5fc13
MT
37033+ read_lock(&gr_inode_lock);
37034+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
16454cff 37035+ __get_dev(dentry), role);
58c5fc13 37036+ read_unlock(&gr_inode_lock);
16454cff 37037+ spin_unlock(&dentry->d_lock);
58c5fc13
MT
37038+
37039+ if (unlikely(retval == NULL)) {
16454cff 37040+ /* real_root is pinned, we don't need to hold a reference */
58c5fc13 37041+ read_lock(&gr_inode_lock);
6892158b 37042+ retval = lookup_acl_subj_label(real_root.dentry->d_inode->i_ino,
16454cff 37043+ __get_dev(real_root.dentry), role);
58c5fc13
MT
37044+ read_unlock(&gr_inode_lock);
37045+ }
37046+out:
bc901d79 37047+ br_read_unlock(vfsmount_lock);
16454cff 37048+ write_sequnlock(&rename_lock);
58c5fc13 37049+
bc901d79
MT
37050+ BUG_ON(retval == NULL);
37051+
58c5fc13
MT
37052+ return retval;
37053+}
37054+
37055+static void
37056+gr_log_learn(const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
37057+{
37058+ struct task_struct *task = current;
37059+ const struct cred *cred = current_cred();
37060+
37061+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
37062+ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
37063+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
bc901d79 37064+ 1UL, 1UL, gr_to_filename(dentry, mnt), (unsigned long) mode, &task->signal->saved_ip);
58c5fc13
MT
37065+
37066+ return;
37067+}
37068+
37069+static void
37070+gr_log_learn_sysctl(const char *path, const __u32 mode)
37071+{
37072+ struct task_struct *task = current;
37073+ const struct cred *cred = current_cred();
37074+
37075+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
37076+ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
37077+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
bc901d79 37078+ 1UL, 1UL, path, (unsigned long) mode, &task->signal->saved_ip);
58c5fc13
MT
37079+
37080+ return;
37081+}
37082+
37083+static void
37084+gr_log_learn_id_change(const char type, const unsigned int real,
37085+ const unsigned int effective, const unsigned int fs)
37086+{
37087+ struct task_struct *task = current;
37088+ const struct cred *cred = current_cred();
37089+
37090+ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
37091+ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
37092+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
bc901d79 37093+ type, real, effective, fs, &task->signal->saved_ip);
58c5fc13
MT
37094+
37095+ return;
37096+}
37097+
37098+__u32
37099+gr_check_link(const struct dentry * new_dentry,
37100+ const struct dentry * parent_dentry,
37101+ const struct vfsmount * parent_mnt,
37102+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
37103+{
37104+ struct acl_object_label *obj;
37105+ __u32 oldmode, newmode;
37106+ __u32 needmode;
37107+
37108+ if (unlikely(!(gr_status & GR_READY)))
37109+ return (GR_CREATE | GR_LINK);
37110+
37111+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
37112+ oldmode = obj->mode;
37113+
37114+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
37115+ oldmode |= (GR_CREATE | GR_LINK);
37116+
37117+ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
37118+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
37119+ needmode |= GR_SETID | GR_AUDIT_SETID;
37120+
37121+ newmode =
37122+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
37123+ oldmode | needmode);
37124+
37125+ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
37126+ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
37127+ GR_INHERIT | GR_AUDIT_INHERIT);
37128+
37129+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
37130+ goto bad;
37131+
37132+ if ((oldmode & needmode) != needmode)
37133+ goto bad;
37134+
37135+ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
37136+ if ((newmode & needmode) != needmode)
37137+ goto bad;
37138+
37139+ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
37140+ return newmode;
37141+bad:
37142+ needmode = oldmode;
37143+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
37144+ needmode |= GR_SETID;
37145+
37146+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
37147+ gr_log_learn(old_dentry, old_mnt, needmode);
37148+ return (GR_CREATE | GR_LINK);
37149+ } else if (newmode & GR_SUPPRESS)
37150+ return GR_SUPPRESS;
37151+ else
37152+ return 0;
37153+}
37154+
37155+__u32
37156+gr_search_file(const struct dentry * dentry, const __u32 mode,
37157+ const struct vfsmount * mnt)
37158+{
37159+ __u32 retval = mode;
37160+ struct acl_subject_label *curracl;
37161+ struct acl_object_label *currobj;
37162+
37163+ if (unlikely(!(gr_status & GR_READY)))
37164+ return (mode & ~GR_AUDITS);
37165+
37166+ curracl = current->acl;
37167+
37168+ currobj = chk_obj_label(dentry, mnt, curracl);
37169+ retval = currobj->mode & mode;
37170+
16454cff
MT
37171+ /* if we're opening a specified transfer file for writing
37172+ (e.g. /dev/initctl), then transfer our role to init
37173+ */
37174+ if (unlikely(currobj->mode & GR_INIT_TRANSFER && retval & GR_WRITE &&
37175+ current->role->roletype & GR_ROLE_PERSIST)) {
37176+ struct task_struct *task = init_pid_ns.child_reaper;
37177+
37178+ if (task->role != current->role) {
37179+ task->acl_sp_role = 0;
37180+ task->acl_role_id = current->acl_role_id;
37181+ task->role = current->role;
37182+ rcu_read_lock();
37183+ read_lock(&grsec_exec_file_lock);
37184+ gr_apply_subject_to_task(task);
37185+ read_unlock(&grsec_exec_file_lock);
37186+ rcu_read_unlock();
37187+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_INIT_TRANSFER_MSG);
37188+ }
37189+ }
37190+
58c5fc13
MT
37191+ if (unlikely
37192+ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
37193+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
37194+ __u32 new_mode = mode;
37195+
37196+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
37197+
37198+ retval = new_mode;
37199+
37200+ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
37201+ new_mode |= GR_INHERIT;
37202+
37203+ if (!(mode & GR_NOLEARN))
37204+ gr_log_learn(dentry, mnt, new_mode);
37205+ }
37206+
37207+ return retval;
37208+}
37209+
37210+__u32
37211+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
37212+ const struct vfsmount * mnt, const __u32 mode)
37213+{
37214+ struct name_entry *match;
37215+ struct acl_object_label *matchpo;
37216+ struct acl_subject_label *curracl;
37217+ char *path;
37218+ __u32 retval;
37219+
37220+ if (unlikely(!(gr_status & GR_READY)))
37221+ return (mode & ~GR_AUDITS);
37222+
37223+ preempt_disable();
37224+ path = gr_to_filename_rbac(new_dentry, mnt);
37225+ match = lookup_name_entry_create(path);
37226+
37227+ if (!match)
37228+ goto check_parent;
37229+
37230+ curracl = current->acl;
37231+
37232+ read_lock(&gr_inode_lock);
37233+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
37234+ read_unlock(&gr_inode_lock);
37235+
37236+ if (matchpo) {
37237+ if ((matchpo->mode & mode) !=
37238+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
37239+ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
37240+ __u32 new_mode = mode;
37241+
37242+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
37243+
37244+ gr_log_learn(new_dentry, mnt, new_mode);
37245+
37246+ preempt_enable();
37247+ return new_mode;
37248+ }
37249+ preempt_enable();
37250+ return (matchpo->mode & mode);
37251+ }
37252+
37253+ check_parent:
37254+ curracl = current->acl;
37255+
37256+ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
37257+ retval = matchpo->mode & mode;
37258+
37259+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
37260+ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
37261+ __u32 new_mode = mode;
37262+
37263+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
37264+
37265+ gr_log_learn(new_dentry, mnt, new_mode);
37266+ preempt_enable();
37267+ return new_mode;
37268+ }
37269+
37270+ preempt_enable();
37271+ return retval;
37272+}
37273+
37274+int
37275+gr_check_hidden_task(const struct task_struct *task)
37276+{
37277+ if (unlikely(!(gr_status & GR_READY)))
37278+ return 0;
37279+
37280+ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
37281+ return 1;
37282+
37283+ return 0;
37284+}
37285+
37286+int
37287+gr_check_protected_task(const struct task_struct *task)
37288+{
37289+ if (unlikely(!(gr_status & GR_READY) || !task))
37290+ return 0;
37291+
37292+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
37293+ task->acl != current->acl)
37294+ return 1;
37295+
37296+ return 0;
37297+}
37298+
57199397
MT
37299+int
37300+gr_check_protected_task_fowner(struct pid *pid, enum pid_type type)
37301+{
37302+ struct task_struct *p;
37303+ int ret = 0;
37304+
37305+ if (unlikely(!(gr_status & GR_READY) || !pid))
37306+ return ret;
37307+
37308+ read_lock(&tasklist_lock);
37309+ do_each_pid_task(pid, type, p) {
37310+ if ((p->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
37311+ p->acl != current->acl) {
37312+ ret = 1;
37313+ goto out;
37314+ }
37315+ } while_each_pid_task(pid, type, p);
37316+out:
37317+ read_unlock(&tasklist_lock);
37318+
37319+ return ret;
37320+}
37321+
58c5fc13
MT
37322+void
37323+gr_copy_label(struct task_struct *tsk)
37324+{
37325+ tsk->signal->used_accept = 0;
37326+ tsk->acl_sp_role = 0;
37327+ tsk->acl_role_id = current->acl_role_id;
37328+ tsk->acl = current->acl;
37329+ tsk->role = current->role;
37330+ tsk->signal->curr_ip = current->signal->curr_ip;
bc901d79 37331+ tsk->signal->saved_ip = current->signal->saved_ip;
58c5fc13
MT
37332+ if (current->exec_file)
37333+ get_file(current->exec_file);
37334+ tsk->exec_file = current->exec_file;
37335+ tsk->is_writable = current->is_writable;
bc901d79 37336+ if (unlikely(current->signal->used_accept)) {
58c5fc13 37337+ current->signal->curr_ip = 0;
bc901d79
MT
37338+ current->signal->saved_ip = 0;
37339+ }
58c5fc13
MT
37340+
37341+ return;
37342+}
37343+
37344+static void
37345+gr_set_proc_res(struct task_struct *task)
37346+{
37347+ struct acl_subject_label *proc;
37348+ unsigned short i;
37349+
37350+ proc = task->acl;
37351+
37352+ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
37353+ return;
37354+
37355+ for (i = 0; i < RLIM_NLIMITS; i++) {
37356+ if (!(proc->resmask & (1 << i)))
37357+ continue;
37358+
37359+ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
37360+ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
37361+ }
37362+
37363+ return;
37364+}
37365+
37366+int
37367+gr_check_user_change(int real, int effective, int fs)
37368+{
37369+ unsigned int i;
37370+ __u16 num;
37371+ uid_t *uidlist;
37372+ int curuid;
37373+ int realok = 0;
37374+ int effectiveok = 0;
37375+ int fsok = 0;
37376+
37377+ if (unlikely(!(gr_status & GR_READY)))
37378+ return 0;
37379+
37380+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
37381+ gr_log_learn_id_change('u', real, effective, fs);
37382+
37383+ num = current->acl->user_trans_num;
37384+ uidlist = current->acl->user_transitions;
37385+
37386+ if (uidlist == NULL)
37387+ return 0;
37388+
37389+ if (real == -1)
37390+ realok = 1;
37391+ if (effective == -1)
37392+ effectiveok = 1;
37393+ if (fs == -1)
37394+ fsok = 1;
37395+
37396+ if (current->acl->user_trans_type & GR_ID_ALLOW) {
37397+ for (i = 0; i < num; i++) {
37398+ curuid = (int)uidlist[i];
37399+ if (real == curuid)
37400+ realok = 1;
37401+ if (effective == curuid)
37402+ effectiveok = 1;
37403+ if (fs == curuid)
37404+ fsok = 1;
37405+ }
37406+ } else if (current->acl->user_trans_type & GR_ID_DENY) {
37407+ for (i = 0; i < num; i++) {
37408+ curuid = (int)uidlist[i];
37409+ if (real == curuid)
37410+ break;
37411+ if (effective == curuid)
37412+ break;
37413+ if (fs == curuid)
37414+ break;
37415+ }
37416+ /* not in deny list */
37417+ if (i == num) {
37418+ realok = 1;
37419+ effectiveok = 1;
37420+ fsok = 1;
37421+ }
37422+ }
37423+
37424+ if (realok && effectiveok && fsok)
37425+ return 0;
37426+ else {
37427+ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
37428+ return 1;
37429+ }
37430+}
37431+
37432+int
37433+gr_check_group_change(int real, int effective, int fs)
37434+{
37435+ unsigned int i;
37436+ __u16 num;
37437+ gid_t *gidlist;
37438+ int curgid;
37439+ int realok = 0;
37440+ int effectiveok = 0;
37441+ int fsok = 0;
37442+
37443+ if (unlikely(!(gr_status & GR_READY)))
37444+ return 0;
37445+
37446+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
37447+ gr_log_learn_id_change('g', real, effective, fs);
37448+
37449+ num = current->acl->group_trans_num;
37450+ gidlist = current->acl->group_transitions;
37451+
37452+ if (gidlist == NULL)
37453+ return 0;
37454+
37455+ if (real == -1)
37456+ realok = 1;
37457+ if (effective == -1)
37458+ effectiveok = 1;
37459+ if (fs == -1)
37460+ fsok = 1;
37461+
37462+ if (current->acl->group_trans_type & GR_ID_ALLOW) {
37463+ for (i = 0; i < num; i++) {
37464+ curgid = (int)gidlist[i];
37465+ if (real == curgid)
37466+ realok = 1;
37467+ if (effective == curgid)
37468+ effectiveok = 1;
37469+ if (fs == curgid)
37470+ fsok = 1;
37471+ }
37472+ } else if (current->acl->group_trans_type & GR_ID_DENY) {
37473+ for (i = 0; i < num; i++) {
37474+ curgid = (int)gidlist[i];
37475+ if (real == curgid)
37476+ break;
37477+ if (effective == curgid)
37478+ break;
37479+ if (fs == curgid)
37480+ break;
37481+ }
37482+ /* not in deny list */
37483+ if (i == num) {
37484+ realok = 1;
37485+ effectiveok = 1;
37486+ fsok = 1;
37487+ }
37488+ }
37489+
37490+ if (realok && effectiveok && fsok)
37491+ return 0;
37492+ else {
37493+ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
37494+ return 1;
37495+ }
37496+}
37497+
37498+void
37499+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
37500+{
37501+ struct acl_role_label *role = task->role;
37502+ struct acl_subject_label *subj = NULL;
37503+ struct acl_object_label *obj;
37504+ struct file *filp;
37505+
37506+ if (unlikely(!(gr_status & GR_READY)))
37507+ return;
37508+
37509+ filp = task->exec_file;
37510+
37511+ /* kernel process, we'll give them the kernel role */
37512+ if (unlikely(!filp)) {
37513+ task->role = kernel_role;
37514+ task->acl = kernel_role->root_label;
37515+ return;
37516+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
37517+ role = lookup_acl_role_label(task, uid, gid);
37518+
37519+ /* perform subject lookup in possibly new role
37520+ we can use this result below in the case where role == task->role
37521+ */
37522+ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
37523+
37524+ /* if we changed uid/gid, but result in the same role
37525+ and are using inheritance, don't lose the inherited subject
37526+ if current subject is other than what normal lookup
37527+ would result in, we arrived via inheritance, don't
37528+ lose subject
37529+ */
37530+ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
37531+ (subj == task->acl)))
37532+ task->acl = subj;
37533+
37534+ task->role = role;
37535+
37536+ task->is_writable = 0;
37537+
37538+ /* ignore additional mmap checks for processes that are writable
37539+ by the default ACL */
37540+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
37541+ if (unlikely(obj->mode & GR_WRITE))
37542+ task->is_writable = 1;
37543+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
37544+ if (unlikely(obj->mode & GR_WRITE))
37545+ task->is_writable = 1;
37546+
16454cff 37547+#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG
58c5fc13
MT
37548+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
37549+#endif
37550+
37551+ gr_set_proc_res(task);
37552+
37553+ return;
37554+}
37555+
37556+int
37557+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
37558+ const int unsafe_share)
37559+{
37560+ struct task_struct *task = current;
37561+ struct acl_subject_label *newacl;
37562+ struct acl_object_label *obj;
37563+ __u32 retmode;
37564+
37565+ if (unlikely(!(gr_status & GR_READY)))
37566+ return 0;
37567+
37568+ newacl = chk_subj_label(dentry, mnt, task->role);
37569+
37570+ task_lock(task);
ae4e228f
MT
37571+ if ((((task->ptrace & PT_PTRACED) || unsafe_share) &&
37572+ !(task->acl->mode & GR_POVERRIDE) && (task->acl != newacl) &&
58c5fc13
MT
37573+ !(task->role->roletype & GR_ROLE_GOD) &&
37574+ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
ae4e228f 37575+ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))) {
58c5fc13 37576+ task_unlock(task);
ae4e228f
MT
37577+ if (unsafe_share)
37578+ gr_log_fs_generic(GR_DONT_AUDIT, GR_UNSAFESHARE_EXEC_ACL_MSG, dentry, mnt);
37579+ else
37580+ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
58c5fc13
MT
37581+ return -EACCES;
37582+ }
37583+ task_unlock(task);
37584+
37585+ obj = chk_obj_label(dentry, mnt, task->acl);
37586+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
37587+
37588+ if (!(task->acl->mode & GR_INHERITLEARN) &&
37589+ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
37590+ if (obj->nested)
37591+ task->acl = obj->nested;
37592+ else
37593+ task->acl = newacl;
37594+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
37595+ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
37596+
37597+ task->is_writable = 0;
37598+
37599+ /* ignore additional mmap checks for processes that are writable
37600+ by the default ACL */
37601+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
37602+ if (unlikely(obj->mode & GR_WRITE))
37603+ task->is_writable = 1;
37604+ obj = chk_obj_label(dentry, mnt, task->role->root_label);
37605+ if (unlikely(obj->mode & GR_WRITE))
37606+ task->is_writable = 1;
37607+
37608+ gr_set_proc_res(task);
37609+
16454cff 37610+#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG
58c5fc13
MT
37611+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
37612+#endif
37613+ return 0;
37614+}
37615+
37616+/* always called with valid inodev ptr */
37617+static void
37618+do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
37619+{
37620+ struct acl_object_label *matchpo;
37621+ struct acl_subject_label *matchps;
37622+ struct acl_subject_label *subj;
37623+ struct acl_role_label *role;
ae4e228f 37624+ unsigned int x;
58c5fc13 37625+
ae4e228f 37626+ FOR_EACH_ROLE_START(role)
58c5fc13
MT
37627+ FOR_EACH_SUBJECT_START(role, subj, x)
37628+ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
37629+ matchpo->mode |= GR_DELETED;
37630+ FOR_EACH_SUBJECT_END(subj,x)
37631+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
37632+ if (subj->inode == ino && subj->device == dev)
37633+ subj->mode |= GR_DELETED;
37634+ FOR_EACH_NESTED_SUBJECT_END(subj)
37635+ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
37636+ matchps->mode |= GR_DELETED;
ae4e228f 37637+ FOR_EACH_ROLE_END(role)
58c5fc13
MT
37638+
37639+ inodev->nentry->deleted = 1;
37640+
37641+ return;
37642+}
37643+
37644+void
37645+gr_handle_delete(const ino_t ino, const dev_t dev)
37646+{
37647+ struct inodev_entry *inodev;
37648+
37649+ if (unlikely(!(gr_status & GR_READY)))
37650+ return;
37651+
37652+ write_lock(&gr_inode_lock);
37653+ inodev = lookup_inodev_entry(ino, dev);
37654+ if (inodev != NULL)
37655+ do_handle_delete(inodev, ino, dev);
37656+ write_unlock(&gr_inode_lock);
37657+
37658+ return;
37659+}
37660+
37661+static void
37662+update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
37663+ const ino_t newinode, const dev_t newdevice,
37664+ struct acl_subject_label *subj)
37665+{
37666+ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
37667+ struct acl_object_label *match;
37668+
37669+ match = subj->obj_hash[index];
37670+
37671+ while (match && (match->inode != oldinode ||
37672+ match->device != olddevice ||
37673+ !(match->mode & GR_DELETED)))
37674+ match = match->next;
37675+
37676+ if (match && (match->inode == oldinode)
37677+ && (match->device == olddevice)
37678+ && (match->mode & GR_DELETED)) {
37679+ if (match->prev == NULL) {
37680+ subj->obj_hash[index] = match->next;
37681+ if (match->next != NULL)
37682+ match->next->prev = NULL;
37683+ } else {
37684+ match->prev->next = match->next;
37685+ if (match->next != NULL)
37686+ match->next->prev = match->prev;
37687+ }
37688+ match->prev = NULL;
37689+ match->next = NULL;
37690+ match->inode = newinode;
37691+ match->device = newdevice;
37692+ match->mode &= ~GR_DELETED;
37693+
37694+ insert_acl_obj_label(match, subj);
37695+ }
37696+
37697+ return;
37698+}
37699+
37700+static void
37701+update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
37702+ const ino_t newinode, const dev_t newdevice,
37703+ struct acl_role_label *role)
37704+{
37705+ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
37706+ struct acl_subject_label *match;
37707+
37708+ match = role->subj_hash[index];
37709+
37710+ while (match && (match->inode != oldinode ||
37711+ match->device != olddevice ||
37712+ !(match->mode & GR_DELETED)))
37713+ match = match->next;
37714+
37715+ if (match && (match->inode == oldinode)
37716+ && (match->device == olddevice)
37717+ && (match->mode & GR_DELETED)) {
37718+ if (match->prev == NULL) {
37719+ role->subj_hash[index] = match->next;
37720+ if (match->next != NULL)
37721+ match->next->prev = NULL;
37722+ } else {
37723+ match->prev->next = match->next;
37724+ if (match->next != NULL)
37725+ match->next->prev = match->prev;
37726+ }
37727+ match->prev = NULL;
37728+ match->next = NULL;
37729+ match->inode = newinode;
37730+ match->device = newdevice;
37731+ match->mode &= ~GR_DELETED;
37732+
37733+ insert_acl_subj_label(match, role);
37734+ }
37735+
37736+ return;
37737+}
37738+
37739+static void
37740+update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
37741+ const ino_t newinode, const dev_t newdevice)
37742+{
37743+ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
37744+ struct inodev_entry *match;
37745+
37746+ match = inodev_set.i_hash[index];
37747+
37748+ while (match && (match->nentry->inode != oldinode ||
37749+ match->nentry->device != olddevice || !match->nentry->deleted))
37750+ match = match->next;
37751+
37752+ if (match && (match->nentry->inode == oldinode)
37753+ && (match->nentry->device == olddevice) &&
37754+ match->nentry->deleted) {
37755+ if (match->prev == NULL) {
37756+ inodev_set.i_hash[index] = match->next;
37757+ if (match->next != NULL)
37758+ match->next->prev = NULL;
37759+ } else {
37760+ match->prev->next = match->next;
37761+ if (match->next != NULL)
37762+ match->next->prev = match->prev;
37763+ }
37764+ match->prev = NULL;
37765+ match->next = NULL;
37766+ match->nentry->inode = newinode;
37767+ match->nentry->device = newdevice;
37768+ match->nentry->deleted = 0;
37769+
37770+ insert_inodev_entry(match);
37771+ }
37772+
37773+ return;
37774+}
37775+
37776+static void
37777+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
37778+ const struct vfsmount *mnt)
37779+{
37780+ struct acl_subject_label *subj;
37781+ struct acl_role_label *role;
ae4e228f 37782+ unsigned int x;
16454cff
MT
37783+ ino_t ino = dentry->d_inode->i_ino;
37784+ dev_t dev = __get_dev(dentry);
ae4e228f
MT
37785+
37786+ FOR_EACH_ROLE_START(role)
16454cff 37787+ update_acl_subj_label(matchn->inode, matchn->device, ino, dev, role);
58c5fc13
MT
37788+
37789+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
16454cff
MT
37790+ if ((subj->inode == ino) && (subj->device == dev)) {
37791+ subj->inode = ino;
37792+ subj->device = dev;
58c5fc13
MT
37793+ }
37794+ FOR_EACH_NESTED_SUBJECT_END(subj)
37795+ FOR_EACH_SUBJECT_START(role, subj, x)
37796+ update_acl_obj_label(matchn->inode, matchn->device,
16454cff 37797+ ino, dev, subj);
58c5fc13 37798+ FOR_EACH_SUBJECT_END(subj,x)
ae4e228f 37799+ FOR_EACH_ROLE_END(role)
58c5fc13 37800+
16454cff 37801+ update_inodev_entry(matchn->inode, matchn->device, ino, dev);
58c5fc13
MT
37802+
37803+ return;
37804+}
37805+
37806+void
37807+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
37808+{
37809+ struct name_entry *matchn;
37810+
37811+ if (unlikely(!(gr_status & GR_READY)))
37812+ return;
37813+
37814+ preempt_disable();
37815+ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
37816+
37817+ if (unlikely((unsigned long)matchn)) {
37818+ write_lock(&gr_inode_lock);
37819+ do_handle_create(matchn, dentry, mnt);
37820+ write_unlock(&gr_inode_lock);
37821+ }
37822+ preempt_enable();
37823+
37824+ return;
37825+}
37826+
37827+void
37828+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
37829+ struct dentry *old_dentry,
37830+ struct dentry *new_dentry,
37831+ struct vfsmount *mnt, const __u8 replace)
37832+{
37833+ struct name_entry *matchn;
37834+ struct inodev_entry *inodev;
16454cff
MT
37835+ ino_t old_ino = old_dentry->d_inode->i_ino;
37836+ dev_t old_dev = __get_dev(old_dentry);
58c5fc13
MT
37837+
37838+ /* vfs_rename swaps the name and parent link for old_dentry and
37839+ new_dentry
37840+ at this point, old_dentry has the new name, parent link, and inode
37841+ for the renamed file
37842+ if a file is being replaced by a rename, new_dentry has the inode
37843+ and name for the replaced file
37844+ */
37845+
37846+ if (unlikely(!(gr_status & GR_READY)))
37847+ return;
37848+
37849+ preempt_disable();
37850+ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
37851+
37852+ /* we wouldn't have to check d_inode if it weren't for
37853+ NFS silly-renaming
37854+ */
37855+
37856+ write_lock(&gr_inode_lock);
37857+ if (unlikely(replace && new_dentry->d_inode)) {
16454cff
MT
37858+ ino_t new_ino = new_dentry->d_inode->i_ino;
37859+ dev_t new_dev = __get_dev(new_dentry);
37860+
37861+ inodev = lookup_inodev_entry(new_ino, new_dev);
58c5fc13 37862+ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
16454cff 37863+ do_handle_delete(inodev, new_ino, new_dev);
58c5fc13
MT
37864+ }
37865+
16454cff 37866+ inodev = lookup_inodev_entry(old_ino, old_dev);
58c5fc13 37867+ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
16454cff 37868+ do_handle_delete(inodev, old_ino, old_dev);
58c5fc13
MT
37869+
37870+ if (unlikely((unsigned long)matchn))
37871+ do_handle_create(matchn, old_dentry, mnt);
37872+
37873+ write_unlock(&gr_inode_lock);
37874+ preempt_enable();
37875+
37876+ return;
37877+}
37878+
37879+static int
37880+lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
37881+ unsigned char **sum)
37882+{
37883+ struct acl_role_label *r;
37884+ struct role_allowed_ip *ipp;
37885+ struct role_transition *trans;
37886+ unsigned int i;
37887+ int found = 0;
bc901d79
MT
37888+ u32 curr_ip = current->signal->curr_ip;
37889+
37890+ current->signal->saved_ip = curr_ip;
58c5fc13
MT
37891+
37892+ /* check transition table */
37893+
37894+ for (trans = current->role->transitions; trans; trans = trans->next) {
37895+ if (!strcmp(rolename, trans->rolename)) {
37896+ found = 1;
37897+ break;
37898+ }
37899+ }
37900+
37901+ if (!found)
37902+ return 0;
37903+
37904+ /* handle special roles that do not require authentication
37905+ and check ip */
37906+
ae4e228f 37907+ FOR_EACH_ROLE_START(r)
58c5fc13
MT
37908+ if (!strcmp(rolename, r->rolename) &&
37909+ (r->roletype & GR_ROLE_SPECIAL)) {
37910+ found = 0;
37911+ if (r->allowed_ips != NULL) {
37912+ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
bc901d79 37913+ if ((ntohl(curr_ip) & ipp->netmask) ==
58c5fc13
MT
37914+ (ntohl(ipp->addr) & ipp->netmask))
37915+ found = 1;
37916+ }
37917+ } else
37918+ found = 2;
37919+ if (!found)
37920+ return 0;
37921+
37922+ if (((mode == GR_SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
37923+ ((mode == GR_SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
37924+ *salt = NULL;
37925+ *sum = NULL;
37926+ return 1;
37927+ }
37928+ }
ae4e228f 37929+ FOR_EACH_ROLE_END(r)
58c5fc13
MT
37930+
37931+ for (i = 0; i < num_sprole_pws; i++) {
37932+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
37933+ *salt = acl_special_roles[i]->salt;
37934+ *sum = acl_special_roles[i]->sum;
37935+ return 1;
37936+ }
37937+ }
37938+
37939+ return 0;
37940+}
37941+
37942+static void
37943+assign_special_role(char *rolename)
37944+{
37945+ struct acl_object_label *obj;
37946+ struct acl_role_label *r;
37947+ struct acl_role_label *assigned = NULL;
37948+ struct task_struct *tsk;
37949+ struct file *filp;
58c5fc13 37950+
ae4e228f 37951+ FOR_EACH_ROLE_START(r)
58c5fc13 37952+ if (!strcmp(rolename, r->rolename) &&
ae4e228f 37953+ (r->roletype & GR_ROLE_SPECIAL)) {
58c5fc13 37954+ assigned = r;
ae4e228f
MT
37955+ break;
37956+ }
37957+ FOR_EACH_ROLE_END(r)
58c5fc13
MT
37958+
37959+ if (!assigned)
37960+ return;
37961+
37962+ read_lock(&tasklist_lock);
37963+ read_lock(&grsec_exec_file_lock);
37964+
6892158b 37965+ tsk = current->real_parent;
58c5fc13
MT
37966+ if (tsk == NULL)
37967+ goto out_unlock;
37968+
37969+ filp = tsk->exec_file;
37970+ if (filp == NULL)
37971+ goto out_unlock;
37972+
37973+ tsk->is_writable = 0;
37974+
37975+ tsk->acl_sp_role = 1;
37976+ tsk->acl_role_id = ++acl_sp_role_value;
37977+ tsk->role = assigned;
37978+ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
37979+
37980+ /* ignore additional mmap checks for processes that are writable
37981+ by the default ACL */
37982+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
37983+ if (unlikely(obj->mode & GR_WRITE))
37984+ tsk->is_writable = 1;
37985+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
37986+ if (unlikely(obj->mode & GR_WRITE))
37987+ tsk->is_writable = 1;
37988+
16454cff 37989+#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG
58c5fc13
MT
37990+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
37991+#endif
37992+
37993+out_unlock:
37994+ read_unlock(&grsec_exec_file_lock);
37995+ read_unlock(&tasklist_lock);
37996+ return;
37997+}
37998+
37999+int gr_check_secure_terminal(struct task_struct *task)
38000+{
38001+ struct task_struct *p, *p2, *p3;
38002+ struct files_struct *files;
38003+ struct fdtable *fdt;
38004+ struct file *our_file = NULL, *file;
38005+ int i;
38006+
38007+ if (task->signal->tty == NULL)
38008+ return 1;
38009+
38010+ files = get_files_struct(task);
38011+ if (files != NULL) {
38012+ rcu_read_lock();
38013+ fdt = files_fdtable(files);
38014+ for (i=0; i < fdt->max_fds; i++) {
38015+ file = fcheck_files(files, i);
38016+ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
38017+ get_file(file);
38018+ our_file = file;
38019+ }
38020+ }
38021+ rcu_read_unlock();
38022+ put_files_struct(files);
38023+ }
38024+
38025+ if (our_file == NULL)
38026+ return 1;
38027+
38028+ read_lock(&tasklist_lock);
38029+ do_each_thread(p2, p) {
38030+ files = get_files_struct(p);
38031+ if (files == NULL ||
38032+ (p->signal && p->signal->tty == task->signal->tty)) {
38033+ if (files != NULL)
38034+ put_files_struct(files);
38035+ continue;
38036+ }
38037+ rcu_read_lock();
38038+ fdt = files_fdtable(files);
38039+ for (i=0; i < fdt->max_fds; i++) {
38040+ file = fcheck_files(files, i);
38041+ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
38042+ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
38043+ p3 = task;
38044+ while (p3->pid > 0) {
38045+ if (p3 == p)
38046+ break;
6892158b 38047+ p3 = p3->real_parent;
58c5fc13
MT
38048+ }
38049+ if (p3 == p)
38050+ break;
38051+ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
38052+ gr_handle_alertkill(p);
38053+ rcu_read_unlock();
38054+ put_files_struct(files);
38055+ read_unlock(&tasklist_lock);
38056+ fput(our_file);
38057+ return 0;
38058+ }
38059+ }
38060+ rcu_read_unlock();
38061+ put_files_struct(files);
38062+ } while_each_thread(p2, p);
38063+ read_unlock(&tasklist_lock);
38064+
38065+ fput(our_file);
38066+ return 1;
38067+}
38068+
38069+ssize_t
38070+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
38071+{
38072+ struct gr_arg_wrapper uwrap;
ae4e228f
MT
38073+ unsigned char *sprole_salt = NULL;
38074+ unsigned char *sprole_sum = NULL;
58c5fc13
MT
38075+ int error = sizeof (struct gr_arg_wrapper);
38076+ int error2 = 0;
38077+
bc901d79 38078+ mutex_lock(&gr_dev_mutex);
58c5fc13
MT
38079+
38080+ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
38081+ error = -EPERM;
38082+ goto out;
38083+ }
38084+
38085+ if (count != sizeof (struct gr_arg_wrapper)) {
38086+ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
38087+ error = -EINVAL;
38088+ goto out;
38089+ }
38090+
38091+
38092+ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
38093+ gr_auth_expires = 0;
38094+ gr_auth_attempts = 0;
38095+ }
38096+
38097+ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
38098+ error = -EFAULT;
38099+ goto out;
38100+ }
38101+
38102+ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
38103+ error = -EINVAL;
38104+ goto out;
38105+ }
38106+
38107+ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
38108+ error = -EFAULT;
38109+ goto out;
38110+ }
38111+
38112+ if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_SPROLEPAM &&
38113+ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
38114+ time_after(gr_auth_expires, get_seconds())) {
38115+ error = -EBUSY;
38116+ goto out;
38117+ }
38118+
38119+ /* if non-root trying to do anything other than use a special role,
38120+ do not attempt authentication, do not count towards authentication
38121+ locking
38122+ */
38123+
38124+ if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_STATUS &&
38125+ gr_usermode->mode != GR_UNSPROLE && gr_usermode->mode != GR_SPROLEPAM &&
38126+ current_uid()) {
38127+ error = -EPERM;
38128+ goto out;
38129+ }
38130+
38131+ /* ensure pw and special role name are null terminated */
38132+
38133+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
38134+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
38135+
38136+ /* Okay.
38137+ * We have our enough of the argument structure..(we have yet
38138+ * to copy_from_user the tables themselves) . Copy the tables
38139+ * only if we need them, i.e. for loading operations. */
38140+
38141+ switch (gr_usermode->mode) {
38142+ case GR_STATUS:
38143+ if (gr_status & GR_READY) {
38144+ error = 1;
38145+ if (!gr_check_secure_terminal(current))
38146+ error = 3;
38147+ } else
38148+ error = 2;
38149+ goto out;
38150+ case GR_SHUTDOWN:
38151+ if ((gr_status & GR_READY)
38152+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
ae4e228f 38153+ pax_open_kernel();
58c5fc13 38154+ gr_status &= ~GR_READY;
ae4e228f
MT
38155+ pax_close_kernel();
38156+
58c5fc13
MT
38157+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
38158+ free_variables();
38159+ memset(gr_usermode, 0, sizeof (struct gr_arg));
38160+ memset(gr_system_salt, 0, GR_SALT_LEN);
38161+ memset(gr_system_sum, 0, GR_SHA_LEN);
38162+ } else if (gr_status & GR_READY) {
38163+ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
38164+ error = -EPERM;
38165+ } else {
38166+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
38167+ error = -EAGAIN;
38168+ }
38169+ break;
38170+ case GR_ENABLE:
38171+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
38172+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
38173+ else {
38174+ if (gr_status & GR_READY)
38175+ error = -EAGAIN;
38176+ else
38177+ error = error2;
38178+ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
38179+ }
38180+ break;
38181+ case GR_RELOAD:
38182+ if (!(gr_status & GR_READY)) {
38183+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
38184+ error = -EAGAIN;
38185+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
c52201e0 38186+ preempt_disable();
58c5fc13 38187+
ae4e228f 38188+ pax_open_kernel();
58c5fc13 38189+ gr_status &= ~GR_READY;
ae4e228f
MT
38190+ pax_close_kernel();
38191+
58c5fc13
MT
38192+ free_variables();
38193+ if (!(error2 = gracl_init(gr_usermode))) {
c52201e0 38194+ preempt_enable();
58c5fc13
MT
38195+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
38196+ } else {
c52201e0 38197+ preempt_enable();
58c5fc13
MT
38198+ error = error2;
38199+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
38200+ }
38201+ } else {
38202+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
38203+ error = -EPERM;
38204+ }
38205+ break;
38206+ case GR_SEGVMOD:
38207+ if (unlikely(!(gr_status & GR_READY))) {
38208+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
38209+ error = -EAGAIN;
38210+ break;
38211+ }
38212+
38213+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
38214+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
38215+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
38216+ struct acl_subject_label *segvacl;
38217+ segvacl =
38218+ lookup_acl_subj_label(gr_usermode->segv_inode,
38219+ gr_usermode->segv_device,
38220+ current->role);
38221+ if (segvacl) {
38222+ segvacl->crashes = 0;
38223+ segvacl->expires = 0;
38224+ }
38225+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
38226+ gr_remove_uid(gr_usermode->segv_uid);
38227+ }
38228+ } else {
38229+ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
38230+ error = -EPERM;
38231+ }
38232+ break;
38233+ case GR_SPROLE:
38234+ case GR_SPROLEPAM:
38235+ if (unlikely(!(gr_status & GR_READY))) {
38236+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
38237+ error = -EAGAIN;
38238+ break;
38239+ }
38240+
38241+ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
38242+ current->role->expires = 0;
38243+ current->role->auth_attempts = 0;
38244+ }
38245+
38246+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
38247+ time_after(current->role->expires, get_seconds())) {
38248+ error = -EBUSY;
38249+ goto out;
38250+ }
38251+
38252+ if (lookup_special_role_auth
38253+ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
38254+ && ((!sprole_salt && !sprole_sum)
38255+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
38256+ char *p = "";
38257+ assign_special_role(gr_usermode->sp_role);
38258+ read_lock(&tasklist_lock);
6892158b
MT
38259+ if (current->real_parent)
38260+ p = current->real_parent->role->rolename;
58c5fc13
MT
38261+ read_unlock(&tasklist_lock);
38262+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
38263+ p, acl_sp_role_value);
38264+ } else {
38265+ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
38266+ error = -EPERM;
38267+ if(!(current->role->auth_attempts++))
38268+ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
38269+
38270+ goto out;
38271+ }
38272+ break;
38273+ case GR_UNSPROLE:
38274+ if (unlikely(!(gr_status & GR_READY))) {
38275+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
38276+ error = -EAGAIN;
38277+ break;
38278+ }
38279+
38280+ if (current->role->roletype & GR_ROLE_SPECIAL) {
38281+ char *p = "";
38282+ int i = 0;
38283+
38284+ read_lock(&tasklist_lock);
6892158b
MT
38285+ if (current->real_parent) {
38286+ p = current->real_parent->role->rolename;
38287+ i = current->real_parent->acl_role_id;
58c5fc13
MT
38288+ }
38289+ read_unlock(&tasklist_lock);
38290+
38291+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
38292+ gr_set_acls(1);
38293+ } else {
58c5fc13
MT
38294+ error = -EPERM;
38295+ goto out;
38296+ }
38297+ break;
38298+ default:
38299+ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
38300+ error = -EINVAL;
38301+ break;
38302+ }
38303+
38304+ if (error != -EPERM)
38305+ goto out;
38306+
38307+ if(!(gr_auth_attempts++))
38308+ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
38309+
38310+ out:
bc901d79 38311+ mutex_unlock(&gr_dev_mutex);
58c5fc13
MT
38312+ return error;
38313+}
38314+
16454cff
MT
38315+/* must be called with
38316+ rcu_read_lock();
38317+ read_lock(&tasklist_lock);
38318+ read_lock(&grsec_exec_file_lock);
38319+*/
38320+int gr_apply_subject_to_task(struct task_struct *task)
38321+{
38322+ struct acl_object_label *obj;
38323+ char *tmpname;
38324+ struct acl_subject_label *tmpsubj;
38325+ struct file *filp;
38326+ struct name_entry *nmatch;
38327+
38328+ filp = task->exec_file;
38329+ if (filp == NULL)
38330+ return 0;
38331+
38332+ /* the following is to apply the correct subject
38333+ on binaries running when the RBAC system
38334+ is enabled, when the binaries have been
38335+ replaced or deleted since their execution
38336+ -----
38337+ when the RBAC system starts, the inode/dev
38338+ from exec_file will be one the RBAC system
38339+ is unaware of. It only knows the inode/dev
38340+ of the present file on disk, or the absence
38341+ of it.
38342+ */
38343+ preempt_disable();
38344+ tmpname = gr_to_filename_rbac(filp->f_path.dentry, filp->f_path.mnt);
38345+
38346+ nmatch = lookup_name_entry(tmpname);
38347+ preempt_enable();
38348+ tmpsubj = NULL;
38349+ if (nmatch) {
38350+ if (nmatch->deleted)
38351+ tmpsubj = lookup_acl_subj_label_deleted(nmatch->inode, nmatch->device, task->role);
38352+ else
38353+ tmpsubj = lookup_acl_subj_label(nmatch->inode, nmatch->device, task->role);
38354+ if (tmpsubj != NULL)
38355+ task->acl = tmpsubj;
38356+ }
38357+ if (tmpsubj == NULL)
38358+ task->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
38359+ task->role);
38360+ if (task->acl) {
38361+ struct acl_subject_label *curr;
38362+ curr = task->acl;
38363+
38364+ task->is_writable = 0;
38365+ /* ignore additional mmap checks for processes that are writable
38366+ by the default ACL */
38367+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
38368+ if (unlikely(obj->mode & GR_WRITE))
38369+ task->is_writable = 1;
38370+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
38371+ if (unlikely(obj->mode & GR_WRITE))
38372+ task->is_writable = 1;
38373+
38374+ gr_set_proc_res(task);
38375+
38376+#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG
38377+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
38378+#endif
38379+ } else {
38380+ return 1;
38381+ }
38382+
38383+ return 0;
38384+}
38385+
58c5fc13
MT
38386+int
38387+gr_set_acls(const int type)
38388+{
58c5fc13 38389+ struct task_struct *task, *task2;
58c5fc13
MT
38390+ struct acl_role_label *role = current->role;
38391+ __u16 acl_role_id = current->acl_role_id;
38392+ const struct cred *cred;
16454cff 38393+ int ret;
58c5fc13 38394+
ae4e228f 38395+ rcu_read_lock();
58c5fc13
MT
38396+ read_lock(&tasklist_lock);
38397+ read_lock(&grsec_exec_file_lock);
38398+ do_each_thread(task2, task) {
38399+ /* check to see if we're called from the exit handler,
38400+ if so, only replace ACLs that have inherited the admin
38401+ ACL */
38402+
38403+ if (type && (task->role != role ||
38404+ task->acl_role_id != acl_role_id))
38405+ continue;
38406+
38407+ task->acl_role_id = 0;
38408+ task->acl_sp_role = 0;
38409+
16454cff 38410+ if (task->exec_file) {
58c5fc13
MT
38411+ cred = __task_cred(task);
38412+ task->role = lookup_acl_role_label(task, cred->uid, cred->gid);
16454cff
MT
38413+ ret = gr_apply_subject_to_task(task);
38414+ if (ret) {
58c5fc13
MT
38415+ read_unlock(&grsec_exec_file_lock);
38416+ read_unlock(&tasklist_lock);
ae4e228f 38417+ rcu_read_unlock();
58c5fc13 38418+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
16454cff 38419+ return ret;
58c5fc13
MT
38420+ }
38421+ } else {
38422+ // it's a kernel process
38423+ task->role = kernel_role;
38424+ task->acl = kernel_role->root_label;
38425+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
38426+ task->acl->mode &= ~GR_PROCFIND;
38427+#endif
38428+ }
38429+ } while_each_thread(task2, task);
38430+ read_unlock(&grsec_exec_file_lock);
38431+ read_unlock(&tasklist_lock);
ae4e228f
MT
38432+ rcu_read_unlock();
38433+
58c5fc13
MT
38434+ return 0;
38435+}
38436+
38437+void
38438+gr_learn_resource(const struct task_struct *task,
38439+ const int res, const unsigned long wanted, const int gt)
38440+{
38441+ struct acl_subject_label *acl;
38442+ const struct cred *cred;
38443+
38444+ if (unlikely((gr_status & GR_READY) &&
38445+ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
38446+ goto skip_reslog;
38447+
38448+#ifdef CONFIG_GRKERNSEC_RESLOG
38449+ gr_log_resource(task, res, wanted, gt);
38450+#endif
38451+ skip_reslog:
38452+
38453+ if (unlikely(!(gr_status & GR_READY) || !wanted || res >= GR_NLIMITS))
38454+ return;
38455+
38456+ acl = task->acl;
38457+
38458+ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
38459+ !(acl->resmask & (1 << (unsigned short) res))))
38460+ return;
38461+
38462+ if (wanted >= acl->res[res].rlim_cur) {
38463+ unsigned long res_add;
38464+
38465+ res_add = wanted;
38466+ switch (res) {
38467+ case RLIMIT_CPU:
38468+ res_add += GR_RLIM_CPU_BUMP;
38469+ break;
38470+ case RLIMIT_FSIZE:
38471+ res_add += GR_RLIM_FSIZE_BUMP;
38472+ break;
38473+ case RLIMIT_DATA:
38474+ res_add += GR_RLIM_DATA_BUMP;
38475+ break;
38476+ case RLIMIT_STACK:
38477+ res_add += GR_RLIM_STACK_BUMP;
38478+ break;
38479+ case RLIMIT_CORE:
38480+ res_add += GR_RLIM_CORE_BUMP;
38481+ break;
38482+ case RLIMIT_RSS:
38483+ res_add += GR_RLIM_RSS_BUMP;
38484+ break;
38485+ case RLIMIT_NPROC:
38486+ res_add += GR_RLIM_NPROC_BUMP;
38487+ break;
38488+ case RLIMIT_NOFILE:
38489+ res_add += GR_RLIM_NOFILE_BUMP;
38490+ break;
38491+ case RLIMIT_MEMLOCK:
38492+ res_add += GR_RLIM_MEMLOCK_BUMP;
38493+ break;
38494+ case RLIMIT_AS:
38495+ res_add += GR_RLIM_AS_BUMP;
38496+ break;
38497+ case RLIMIT_LOCKS:
38498+ res_add += GR_RLIM_LOCKS_BUMP;
38499+ break;
38500+ case RLIMIT_SIGPENDING:
38501+ res_add += GR_RLIM_SIGPENDING_BUMP;
38502+ break;
38503+ case RLIMIT_MSGQUEUE:
38504+ res_add += GR_RLIM_MSGQUEUE_BUMP;
38505+ break;
38506+ case RLIMIT_NICE:
38507+ res_add += GR_RLIM_NICE_BUMP;
38508+ break;
38509+ case RLIMIT_RTPRIO:
38510+ res_add += GR_RLIM_RTPRIO_BUMP;
38511+ break;
38512+ case RLIMIT_RTTIME:
38513+ res_add += GR_RLIM_RTTIME_BUMP;
38514+ break;
38515+ }
38516+
38517+ acl->res[res].rlim_cur = res_add;
38518+
38519+ if (wanted > acl->res[res].rlim_max)
38520+ acl->res[res].rlim_max = res_add;
38521+
38522+ /* only log the subject filename, since resource logging is supported for
38523+ single-subject learning only */
ae4e228f 38524+ rcu_read_lock();
58c5fc13
MT
38525+ cred = __task_cred(task);
38526+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
38527+ task->role->roletype, cred->uid, cred->gid, acl->filename,
38528+ acl->filename, acl->res[res].rlim_cur, acl->res[res].rlim_max,
bc901d79 38529+ "", (unsigned long) res, &task->signal->saved_ip);
ae4e228f 38530+ rcu_read_unlock();
58c5fc13
MT
38531+ }
38532+
38533+ return;
38534+}
38535+
38536+#if defined(CONFIG_PAX_HAVE_ACL_FLAGS) && (defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR))
38537+void
38538+pax_set_initial_flags(struct linux_binprm *bprm)
38539+{
38540+ struct task_struct *task = current;
38541+ struct acl_subject_label *proc;
38542+ unsigned long flags;
38543+
38544+ if (unlikely(!(gr_status & GR_READY)))
38545+ return;
38546+
38547+ flags = pax_get_flags(task);
38548+
38549+ proc = task->acl;
38550+
38551+ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
38552+ flags &= ~MF_PAX_PAGEEXEC;
38553+ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
38554+ flags &= ~MF_PAX_SEGMEXEC;
38555+ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
38556+ flags &= ~MF_PAX_RANDMMAP;
38557+ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
38558+ flags &= ~MF_PAX_EMUTRAMP;
38559+ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
38560+ flags &= ~MF_PAX_MPROTECT;
38561+
38562+ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
38563+ flags |= MF_PAX_PAGEEXEC;
38564+ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
38565+ flags |= MF_PAX_SEGMEXEC;
38566+ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
38567+ flags |= MF_PAX_RANDMMAP;
38568+ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
38569+ flags |= MF_PAX_EMUTRAMP;
38570+ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
38571+ flags |= MF_PAX_MPROTECT;
38572+
38573+ pax_set_flags(task, flags);
38574+
38575+ return;
38576+}
38577+#endif
38578+
38579+#ifdef CONFIG_SYSCTL
38580+/* Eric Biederman likes breaking userland ABI and every inode-based security
38581+ system to save 35kb of memory */
38582+
38583+/* we modify the passed in filename, but adjust it back before returning */
38584+static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
38585+{
38586+ struct name_entry *nmatch;
38587+ char *p, *lastp = NULL;
38588+ struct acl_object_label *obj = NULL, *tmp;
38589+ struct acl_subject_label *tmpsubj;
38590+ char c = '\0';
38591+
38592+ read_lock(&gr_inode_lock);
38593+
38594+ p = name + len - 1;
38595+ do {
38596+ nmatch = lookup_name_entry(name);
38597+ if (lastp != NULL)
38598+ *lastp = c;
38599+
38600+ if (nmatch == NULL)
38601+ goto next_component;
38602+ tmpsubj = current->acl;
38603+ do {
38604+ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
38605+ if (obj != NULL) {
38606+ tmp = obj->globbed;
38607+ while (tmp) {
38608+ if (!glob_match(tmp->filename, name)) {
38609+ obj = tmp;
38610+ goto found_obj;
38611+ }
38612+ tmp = tmp->next;
38613+ }
38614+ goto found_obj;
38615+ }
38616+ } while ((tmpsubj = tmpsubj->parent_subject));
38617+next_component:
38618+ /* end case */
38619+ if (p == name)
38620+ break;
38621+
38622+ while (*p != '/')
38623+ p--;
38624+ if (p == name)
38625+ lastp = p + 1;
38626+ else {
38627+ lastp = p;
38628+ p--;
38629+ }
38630+ c = *lastp;
38631+ *lastp = '\0';
38632+ } while (1);
38633+found_obj:
38634+ read_unlock(&gr_inode_lock);
38635+ /* obj returned will always be non-null */
38636+ return obj;
38637+}
38638+
38639+/* returns 0 when allowing, non-zero on error
38640+ op of 0 is used for readdir, so we don't log the names of hidden files
38641+*/
38642+__u32
38643+gr_handle_sysctl(const struct ctl_table *table, const int op)
38644+{
57199397 38645+ struct ctl_table *tmp;
58c5fc13
MT
38646+ const char *proc_sys = "/proc/sys";
38647+ char *path;
38648+ struct acl_object_label *obj;
38649+ unsigned short len = 0, pos = 0, depth = 0, i;
38650+ __u32 err = 0;
38651+ __u32 mode = 0;
38652+
38653+ if (unlikely(!(gr_status & GR_READY)))
38654+ return 0;
38655+
38656+ /* for now, ignore operations on non-sysctl entries if it's not a
38657+ readdir*/
38658+ if (table->child != NULL && op != 0)
38659+ return 0;
38660+
38661+ mode |= GR_FIND;
38662+ /* it's only a read if it's an entry, read on dirs is for readdir */
38663+ if (op & MAY_READ)
38664+ mode |= GR_READ;
38665+ if (op & MAY_WRITE)
38666+ mode |= GR_WRITE;
38667+
38668+ preempt_disable();
38669+
38670+ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
38671+
38672+ /* it's only a read/write if it's an actual entry, not a dir
38673+ (which are opened for readdir)
38674+ */
38675+
38676+ /* convert the requested sysctl entry into a pathname */
38677+
57199397 38678+ for (tmp = (struct ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
58c5fc13
MT
38679+ len += strlen(tmp->procname);
38680+ len++;
38681+ depth++;
38682+ }
38683+
38684+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
38685+ /* deny */
38686+ goto out;
38687+ }
38688+
38689+ memset(path, 0, PAGE_SIZE);
38690+
38691+ memcpy(path, proc_sys, strlen(proc_sys));
38692+
38693+ pos += strlen(proc_sys);
38694+
38695+ for (; depth > 0; depth--) {
38696+ path[pos] = '/';
38697+ pos++;
57199397 38698+ for (i = 1, tmp = (struct ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
58c5fc13
MT
38699+ if (depth == i) {
38700+ memcpy(path + pos, tmp->procname,
38701+ strlen(tmp->procname));
38702+ pos += strlen(tmp->procname);
38703+ }
38704+ i++;
38705+ }
38706+ }
38707+
38708+ obj = gr_lookup_by_name(path, pos);
38709+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
38710+
38711+ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
38712+ ((err & mode) != mode))) {
38713+ __u32 new_mode = mode;
38714+
38715+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
38716+
38717+ err = 0;
38718+ gr_log_learn_sysctl(path, new_mode);
38719+ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
38720+ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
38721+ err = -ENOENT;
38722+ } else if (!(err & GR_FIND)) {
38723+ err = -ENOENT;
38724+ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
38725+ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
38726+ path, (mode & GR_READ) ? " reading" : "",
38727+ (mode & GR_WRITE) ? " writing" : "");
38728+ err = -EACCES;
38729+ } else if ((err & mode) != mode) {
38730+ err = -EACCES;
38731+ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
38732+ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
38733+ path, (mode & GR_READ) ? " reading" : "",
38734+ (mode & GR_WRITE) ? " writing" : "");
38735+ err = 0;
38736+ } else
38737+ err = 0;
38738+
38739+ out:
38740+ preempt_enable();
38741+
38742+ return err;
38743+}
38744+#endif
38745+
38746+int
38747+gr_handle_proc_ptrace(struct task_struct *task)
38748+{
38749+ struct file *filp;
38750+ struct task_struct *tmp = task;
38751+ struct task_struct *curtemp = current;
38752+ __u32 retmode;
38753+
38754+#ifndef CONFIG_GRKERNSEC_HARDEN_PTRACE
38755+ if (unlikely(!(gr_status & GR_READY)))
38756+ return 0;
38757+#endif
38758+
38759+ read_lock(&tasklist_lock);
38760+ read_lock(&grsec_exec_file_lock);
38761+ filp = task->exec_file;
38762+
38763+ while (tmp->pid > 0) {
38764+ if (tmp == curtemp)
38765+ break;
6892158b 38766+ tmp = tmp->real_parent;
58c5fc13
MT
38767+ }
38768+
38769+ if (!filp || (tmp->pid == 0 && ((grsec_enable_harden_ptrace && current_uid() && !(gr_status & GR_READY)) ||
38770+ ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE))))) {
38771+ read_unlock(&grsec_exec_file_lock);
38772+ read_unlock(&tasklist_lock);
38773+ return 1;
38774+ }
38775+
38776+#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
38777+ if (!(gr_status & GR_READY)) {
38778+ read_unlock(&grsec_exec_file_lock);
38779+ read_unlock(&tasklist_lock);
38780+ return 0;
38781+ }
38782+#endif
38783+
38784+ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
38785+ read_unlock(&grsec_exec_file_lock);
38786+ read_unlock(&tasklist_lock);
38787+
38788+ if (retmode & GR_NOPTRACE)
38789+ return 1;
38790+
38791+ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
38792+ && (current->acl != task->acl || (current->acl != current->role->root_label
38793+ && current->pid != task->pid)))
38794+ return 1;
38795+
38796+ return 0;
38797+}
38798+
6892158b
MT
38799+void task_grsec_rbac(struct seq_file *m, struct task_struct *p)
38800+{
38801+ if (unlikely(!(gr_status & GR_READY)))
38802+ return;
38803+
38804+ if (!(current->role->roletype & GR_ROLE_GOD))
38805+ return;
38806+
38807+ seq_printf(m, "RBAC:\t%.64s:%c:%.950s\n",
38808+ p->role->rolename, gr_task_roletype_to_char(p),
38809+ p->acl->filename);
38810+}
38811+
58c5fc13
MT
38812+int
38813+gr_handle_ptrace(struct task_struct *task, const long request)
38814+{
38815+ struct task_struct *tmp = task;
38816+ struct task_struct *curtemp = current;
38817+ __u32 retmode;
38818+
38819+#ifndef CONFIG_GRKERNSEC_HARDEN_PTRACE
38820+ if (unlikely(!(gr_status & GR_READY)))
38821+ return 0;
38822+#endif
38823+
38824+ read_lock(&tasklist_lock);
38825+ while (tmp->pid > 0) {
38826+ if (tmp == curtemp)
38827+ break;
6892158b 38828+ tmp = tmp->real_parent;
58c5fc13
MT
38829+ }
38830+
38831+ if (tmp->pid == 0 && ((grsec_enable_harden_ptrace && current_uid() && !(gr_status & GR_READY)) ||
38832+ ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE)))) {
38833+ read_unlock(&tasklist_lock);
38834+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
38835+ return 1;
38836+ }
38837+ read_unlock(&tasklist_lock);
38838+
38839+#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
38840+ if (!(gr_status & GR_READY))
38841+ return 0;
38842+#endif
38843+
38844+ read_lock(&grsec_exec_file_lock);
38845+ if (unlikely(!task->exec_file)) {
38846+ read_unlock(&grsec_exec_file_lock);
38847+ return 0;
38848+ }
38849+
38850+ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
38851+ read_unlock(&grsec_exec_file_lock);
38852+
38853+ if (retmode & GR_NOPTRACE) {
38854+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
38855+ return 1;
38856+ }
38857+
38858+ if (retmode & GR_PTRACERD) {
38859+ switch (request) {
38860+ case PTRACE_POKETEXT:
38861+ case PTRACE_POKEDATA:
38862+ case PTRACE_POKEUSR:
38863+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
38864+ case PTRACE_SETREGS:
38865+ case PTRACE_SETFPREGS:
38866+#endif
38867+#ifdef CONFIG_X86
38868+ case PTRACE_SETFPXREGS:
38869+#endif
38870+#ifdef CONFIG_ALTIVEC
38871+ case PTRACE_SETVRREGS:
38872+#endif
38873+ return 1;
38874+ default:
38875+ return 0;
38876+ }
38877+ } else if (!(current->acl->mode & GR_POVERRIDE) &&
38878+ !(current->role->roletype & GR_ROLE_GOD) &&
38879+ (current->acl != task->acl)) {
38880+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
38881+ return 1;
38882+ }
38883+
38884+ return 0;
38885+}
38886+
38887+static int is_writable_mmap(const struct file *filp)
38888+{
38889+ struct task_struct *task = current;
38890+ struct acl_object_label *obj, *obj2;
38891+
38892+ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
57199397 38893+ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode) && filp->f_path.mnt != shm_mnt) {
58c5fc13
MT
38894+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
38895+ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
38896+ task->role->root_label);
38897+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
38898+ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
38899+ return 1;
38900+ }
38901+ }
38902+ return 0;
38903+}
38904+
38905+int
38906+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
38907+{
38908+ __u32 mode;
38909+
38910+ if (unlikely(!file || !(prot & PROT_EXEC)))
38911+ return 1;
38912+
38913+ if (is_writable_mmap(file))
38914+ return 0;
38915+
38916+ mode =
38917+ gr_search_file(file->f_path.dentry,
38918+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
38919+ file->f_path.mnt);
38920+
38921+ if (!gr_tpe_allow(file))
38922+ return 0;
38923+
38924+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
38925+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
38926+ return 0;
38927+ } else if (unlikely(!(mode & GR_EXEC))) {
38928+ return 0;
38929+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
38930+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
38931+ return 1;
38932+ }
38933+
38934+ return 1;
38935+}
38936+
38937+int
38938+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
38939+{
38940+ __u32 mode;
38941+
38942+ if (unlikely(!file || !(prot & PROT_EXEC)))
38943+ return 1;
38944+
38945+ if (is_writable_mmap(file))
38946+ return 0;
38947+
38948+ mode =
38949+ gr_search_file(file->f_path.dentry,
38950+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
38951+ file->f_path.mnt);
38952+
38953+ if (!gr_tpe_allow(file))
38954+ return 0;
38955+
38956+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
38957+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
38958+ return 0;
38959+ } else if (unlikely(!(mode & GR_EXEC))) {
38960+ return 0;
38961+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
38962+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
38963+ return 1;
38964+ }
38965+
38966+ return 1;
38967+}
38968+
38969+void
38970+gr_acl_handle_psacct(struct task_struct *task, const long code)
38971+{
38972+ unsigned long runtime;
38973+ unsigned long cputime;
38974+ unsigned int wday, cday;
38975+ __u8 whr, chr;
38976+ __u8 wmin, cmin;
38977+ __u8 wsec, csec;
38978+ struct timespec timeval;
38979+
38980+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
38981+ !(task->acl->mode & GR_PROCACCT)))
38982+ return;
38983+
38984+ do_posix_clock_monotonic_gettime(&timeval);
38985+ runtime = timeval.tv_sec - task->start_time.tv_sec;
38986+ wday = runtime / (3600 * 24);
38987+ runtime -= wday * (3600 * 24);
38988+ whr = runtime / 3600;
38989+ runtime -= whr * 3600;
38990+ wmin = runtime / 60;
38991+ runtime -= wmin * 60;
38992+ wsec = runtime;
38993+
38994+ cputime = (task->utime + task->stime) / HZ;
38995+ cday = cputime / (3600 * 24);
38996+ cputime -= cday * (3600 * 24);
38997+ chr = cputime / 3600;
38998+ cputime -= chr * 3600;
38999+ cmin = cputime / 60;
39000+ cputime -= cmin * 60;
39001+ csec = cputime;
39002+
39003+ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
39004+
39005+ return;
39006+}
39007+
39008+void gr_set_kernel_label(struct task_struct *task)
39009+{
39010+ if (gr_status & GR_READY) {
39011+ task->role = kernel_role;
39012+ task->acl = kernel_role->root_label;
39013+ }
39014+ return;
39015+}
39016+
39017+#ifdef CONFIG_TASKSTATS
39018+int gr_is_taskstats_denied(int pid)
39019+{
39020+ struct task_struct *task;
39021+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
39022+ const struct cred *cred;
39023+#endif
39024+ int ret = 0;
39025+
39026+ /* restrict taskstats viewing to un-chrooted root users
39027+ who have the 'view' subject flag if the RBAC system is enabled
39028+ */
39029+
df50ba0c 39030+ rcu_read_lock();
58c5fc13
MT
39031+ read_lock(&tasklist_lock);
39032+ task = find_task_by_vpid(pid);
39033+ if (task) {
58c5fc13
MT
39034+#ifdef CONFIG_GRKERNSEC_CHROOT
39035+ if (proc_is_chrooted(task))
39036+ ret = -EACCES;
39037+#endif
39038+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
39039+ cred = __task_cred(task);
39040+#ifdef CONFIG_GRKERNSEC_PROC_USER
39041+ if (cred->uid != 0)
39042+ ret = -EACCES;
39043+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
39044+ if (cred->uid != 0 && !groups_search(cred->group_info, CONFIG_GRKERNSEC_PROC_GID))
39045+ ret = -EACCES;
39046+#endif
39047+#endif
39048+ if (gr_status & GR_READY) {
39049+ if (!(task->acl->mode & GR_VIEW))
39050+ ret = -EACCES;
39051+ }
58c5fc13
MT
39052+ } else
39053+ ret = -ENOENT;
39054+
39055+ read_unlock(&tasklist_lock);
df50ba0c 39056+ rcu_read_unlock();
58c5fc13
MT
39057+
39058+ return ret;
39059+}
39060+#endif
39061+
bc901d79
MT
39062+/* AUXV entries are filled via a descendant of search_binary_handler
39063+ after we've already applied the subject for the target
39064+*/
39065+int gr_acl_enable_at_secure(void)
39066+{
39067+ if (unlikely(!(gr_status & GR_READY)))
39068+ return 0;
39069+
39070+ if (current->acl->mode & GR_ATSECURE)
39071+ return 1;
39072+
39073+ return 0;
39074+}
39075+
58c5fc13
MT
39076+int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
39077+{
39078+ struct task_struct *task = current;
39079+ struct dentry *dentry = file->f_path.dentry;
39080+ struct vfsmount *mnt = file->f_path.mnt;
39081+ struct acl_object_label *obj, *tmp;
39082+ struct acl_subject_label *subj;
39083+ unsigned int bufsize;
39084+ int is_not_root;
39085+ char *path;
16454cff 39086+ dev_t dev = __get_dev(dentry);
58c5fc13
MT
39087+
39088+ if (unlikely(!(gr_status & GR_READY)))
39089+ return 1;
39090+
39091+ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
39092+ return 1;
39093+
39094+ /* ignore Eric Biederman */
39095+ if (IS_PRIVATE(dentry->d_inode))
39096+ return 1;
39097+
39098+ subj = task->acl;
39099+ do {
16454cff 39100+ obj = lookup_acl_obj_label(ino, dev, subj);
58c5fc13
MT
39101+ if (obj != NULL)
39102+ return (obj->mode & GR_FIND) ? 1 : 0;
39103+ } while ((subj = subj->parent_subject));
39104+
39105+ /* this is purely an optimization since we're looking for an object
39106+ for the directory we're doing a readdir on
39107+ if it's possible for any globbed object to match the entry we're
39108+ filling into the directory, then the object we find here will be
39109+ an anchor point with attached globbed objects
39110+ */
39111+ obj = chk_obj_label_noglob(dentry, mnt, task->acl);
39112+ if (obj->globbed == NULL)
39113+ return (obj->mode & GR_FIND) ? 1 : 0;
39114+
39115+ is_not_root = ((obj->filename[0] == '/') &&
39116+ (obj->filename[1] == '\0')) ? 0 : 1;
39117+ bufsize = PAGE_SIZE - namelen - is_not_root;
39118+
39119+ /* check bufsize > PAGE_SIZE || bufsize == 0 */
39120+ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
39121+ return 1;
39122+
39123+ preempt_disable();
39124+ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
39125+ bufsize);
39126+
39127+ bufsize = strlen(path);
39128+
39129+ /* if base is "/", don't append an additional slash */
39130+ if (is_not_root)
39131+ *(path + bufsize) = '/';
39132+ memcpy(path + bufsize + is_not_root, name, namelen);
39133+ *(path + bufsize + namelen + is_not_root) = '\0';
39134+
39135+ tmp = obj->globbed;
39136+ while (tmp) {
39137+ if (!glob_match(tmp->filename, path)) {
39138+ preempt_enable();
39139+ return (tmp->mode & GR_FIND) ? 1 : 0;
39140+ }
39141+ tmp = tmp->next;
39142+ }
39143+ preempt_enable();
39144+ return (obj->mode & GR_FIND) ? 1 : 0;
39145+}
39146+
6892158b
MT
39147+#ifdef CONFIG_NETFILTER_XT_MATCH_GRADM_MODULE
39148+EXPORT_SYMBOL(gr_acl_is_enabled);
39149+#endif
58c5fc13
MT
39150+EXPORT_SYMBOL(gr_learn_resource);
39151+EXPORT_SYMBOL(gr_set_kernel_label);
39152+#ifdef CONFIG_SECURITY
39153+EXPORT_SYMBOL(gr_check_user_change);
39154+EXPORT_SYMBOL(gr_check_group_change);
39155+#endif
39156+
16454cff
MT
39157diff -urNp linux-2.6.38.1/grsecurity/gracl_cap.c linux-2.6.38.1/grsecurity/gracl_cap.c
39158--- linux-2.6.38.1/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
39159+++ linux-2.6.38.1/grsecurity/gracl_cap.c 2011-03-21 20:22:36.000000000 -0400
39160@@ -0,0 +1,139 @@
58c5fc13
MT
39161+#include <linux/kernel.h>
39162+#include <linux/module.h>
39163+#include <linux/sched.h>
39164+#include <linux/gracl.h>
39165+#include <linux/grsecurity.h>
39166+#include <linux/grinternal.h>
39167+
39168+static const char *captab_log[] = {
39169+ "CAP_CHOWN",
39170+ "CAP_DAC_OVERRIDE",
39171+ "CAP_DAC_READ_SEARCH",
39172+ "CAP_FOWNER",
39173+ "CAP_FSETID",
39174+ "CAP_KILL",
39175+ "CAP_SETGID",
39176+ "CAP_SETUID",
39177+ "CAP_SETPCAP",
39178+ "CAP_LINUX_IMMUTABLE",
39179+ "CAP_NET_BIND_SERVICE",
39180+ "CAP_NET_BROADCAST",
39181+ "CAP_NET_ADMIN",
39182+ "CAP_NET_RAW",
39183+ "CAP_IPC_LOCK",
39184+ "CAP_IPC_OWNER",
39185+ "CAP_SYS_MODULE",
39186+ "CAP_SYS_RAWIO",
39187+ "CAP_SYS_CHROOT",
39188+ "CAP_SYS_PTRACE",
39189+ "CAP_SYS_PACCT",
39190+ "CAP_SYS_ADMIN",
39191+ "CAP_SYS_BOOT",
39192+ "CAP_SYS_NICE",
39193+ "CAP_SYS_RESOURCE",
39194+ "CAP_SYS_TIME",
39195+ "CAP_SYS_TTY_CONFIG",
39196+ "CAP_MKNOD",
39197+ "CAP_LEASE",
39198+ "CAP_AUDIT_WRITE",
39199+ "CAP_AUDIT_CONTROL",
39200+ "CAP_SETFCAP",
39201+ "CAP_MAC_OVERRIDE",
16454cff
MT
39202+ "CAP_MAC_ADMIN",
39203+ "CAP_SYSLOG"
58c5fc13
MT
39204+};
39205+
39206+EXPORT_SYMBOL(gr_is_capable);
39207+EXPORT_SYMBOL(gr_is_capable_nolog);
39208+
39209+int
39210+gr_is_capable(const int cap)
39211+{
39212+ struct task_struct *task = current;
39213+ const struct cred *cred = current_cred();
39214+ struct acl_subject_label *curracl;
39215+ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
df50ba0c 39216+ kernel_cap_t cap_audit = __cap_empty_set;
58c5fc13
MT
39217+
39218+ if (!gr_acl_is_enabled())
39219+ return 1;
39220+
39221+ curracl = task->acl;
39222+
39223+ cap_drop = curracl->cap_lower;
39224+ cap_mask = curracl->cap_mask;
df50ba0c 39225+ cap_audit = curracl->cap_invert_audit;
58c5fc13
MT
39226+
39227+ while ((curracl = curracl->parent_subject)) {
39228+ /* if the cap isn't specified in the current computed mask but is specified in the
39229+ current level subject, and is lowered in the current level subject, then add
39230+ it to the set of dropped capabilities
39231+ otherwise, add the current level subject's mask to the current computed mask
39232+ */
39233+ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
39234+ cap_raise(cap_mask, cap);
39235+ if (cap_raised(curracl->cap_lower, cap))
39236+ cap_raise(cap_drop, cap);
df50ba0c
MT
39237+ if (cap_raised(curracl->cap_invert_audit, cap))
39238+ cap_raise(cap_audit, cap);
58c5fc13
MT
39239+ }
39240+ }
39241+
df50ba0c
MT
39242+ if (!cap_raised(cap_drop, cap)) {
39243+ if (cap_raised(cap_audit, cap))
39244+ gr_log_cap(GR_DO_AUDIT, GR_CAP_ACL_MSG2, task, captab_log[cap]);
58c5fc13 39245+ return 1;
df50ba0c 39246+ }
58c5fc13
MT
39247+
39248+ curracl = task->acl;
39249+
39250+ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
39251+ && cap_raised(cred->cap_effective, cap)) {
39252+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
39253+ task->role->roletype, cred->uid,
39254+ cred->gid, task->exec_file ?
39255+ gr_to_filename(task->exec_file->f_path.dentry,
39256+ task->exec_file->f_path.mnt) : curracl->filename,
39257+ curracl->filename, 0UL,
bc901d79 39258+ 0UL, "", (unsigned long) cap, &task->signal->saved_ip);
58c5fc13
MT
39259+ return 1;
39260+ }
39261+
df50ba0c 39262+ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(cred->cap_effective, cap) && !cap_raised(cap_audit, cap))
58c5fc13
MT
39263+ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
39264+ return 0;
39265+}
39266+
39267+int
39268+gr_is_capable_nolog(const int cap)
39269+{
39270+ struct acl_subject_label *curracl;
39271+ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
39272+
39273+ if (!gr_acl_is_enabled())
39274+ return 1;
39275+
39276+ curracl = current->acl;
39277+
39278+ cap_drop = curracl->cap_lower;
39279+ cap_mask = curracl->cap_mask;
39280+
39281+ while ((curracl = curracl->parent_subject)) {
39282+ /* if the cap isn't specified in the current computed mask but is specified in the
39283+ current level subject, and is lowered in the current level subject, then add
39284+ it to the set of dropped capabilities
39285+ otherwise, add the current level subject's mask to the current computed mask
39286+ */
39287+ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
39288+ cap_raise(cap_mask, cap);
39289+ if (cap_raised(curracl->cap_lower, cap))
39290+ cap_raise(cap_drop, cap);
39291+ }
39292+ }
39293+
39294+ if (!cap_raised(cap_drop, cap))
39295+ return 1;
39296+
39297+ return 0;
39298+}
39299+
16454cff
MT
39300diff -urNp linux-2.6.38.1/grsecurity/gracl_fs.c linux-2.6.38.1/grsecurity/gracl_fs.c
39301--- linux-2.6.38.1/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
39302+++ linux-2.6.38.1/grsecurity/gracl_fs.c 2011-03-26 14:32:42.000000000 -0400
39303@@ -0,0 +1,431 @@
58c5fc13
MT
39304+#include <linux/kernel.h>
39305+#include <linux/sched.h>
39306+#include <linux/types.h>
39307+#include <linux/fs.h>
39308+#include <linux/file.h>
39309+#include <linux/stat.h>
39310+#include <linux/grsecurity.h>
39311+#include <linux/grinternal.h>
39312+#include <linux/gracl.h>
39313+
39314+__u32
39315+gr_acl_handle_hidden_file(const struct dentry * dentry,
39316+ const struct vfsmount * mnt)
39317+{
39318+ __u32 mode;
39319+
39320+ if (unlikely(!dentry->d_inode))
39321+ return GR_FIND;
39322+
39323+ mode =
39324+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
39325+
39326+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
39327+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
39328+ return mode;
39329+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
39330+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
39331+ return 0;
39332+ } else if (unlikely(!(mode & GR_FIND)))
39333+ return 0;
39334+
39335+ return GR_FIND;
39336+}
39337+
39338+__u32
39339+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
39340+ const int fmode)
39341+{
39342+ __u32 reqmode = GR_FIND;
39343+ __u32 mode;
39344+
39345+ if (unlikely(!dentry->d_inode))
39346+ return reqmode;
39347+
39348+ if (unlikely(fmode & O_APPEND))
39349+ reqmode |= GR_APPEND;
39350+ else if (unlikely(fmode & FMODE_WRITE))
39351+ reqmode |= GR_WRITE;
39352+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
39353+ reqmode |= GR_READ;
16454cff 39354+ if ((fmode & FMODE_GREXEC) && (fmode & __FMODE_EXEC))
58c5fc13
MT
39355+ reqmode &= ~GR_READ;
39356+ mode =
39357+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
39358+ mnt);
39359+
39360+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
39361+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
39362+ reqmode & GR_READ ? " reading" : "",
39363+ reqmode & GR_WRITE ? " writing" : reqmode &
39364+ GR_APPEND ? " appending" : "");
39365+ return reqmode;
39366+ } else
39367+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
39368+ {
39369+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
39370+ reqmode & GR_READ ? " reading" : "",
39371+ reqmode & GR_WRITE ? " writing" : reqmode &
39372+ GR_APPEND ? " appending" : "");
39373+ return 0;
39374+ } else if (unlikely((mode & reqmode) != reqmode))
39375+ return 0;
39376+
39377+ return reqmode;
39378+}
39379+
39380+__u32
39381+gr_acl_handle_creat(const struct dentry * dentry,
39382+ const struct dentry * p_dentry,
39383+ const struct vfsmount * p_mnt, const int fmode,
39384+ const int imode)
39385+{
39386+ __u32 reqmode = GR_WRITE | GR_CREATE;
39387+ __u32 mode;
39388+
39389+ if (unlikely(fmode & O_APPEND))
39390+ reqmode |= GR_APPEND;
39391+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
39392+ reqmode |= GR_READ;
39393+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
39394+ reqmode |= GR_SETID;
39395+
39396+ mode =
39397+ gr_check_create(dentry, p_dentry, p_mnt,
39398+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
39399+
39400+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
39401+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
39402+ reqmode & GR_READ ? " reading" : "",
39403+ reqmode & GR_WRITE ? " writing" : reqmode &
39404+ GR_APPEND ? " appending" : "");
39405+ return reqmode;
39406+ } else
39407+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
39408+ {
39409+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
39410+ reqmode & GR_READ ? " reading" : "",
39411+ reqmode & GR_WRITE ? " writing" : reqmode &
39412+ GR_APPEND ? " appending" : "");
39413+ return 0;
39414+ } else if (unlikely((mode & reqmode) != reqmode))
39415+ return 0;
39416+
39417+ return reqmode;
39418+}
39419+
39420+__u32
39421+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
39422+ const int fmode)
39423+{
39424+ __u32 mode, reqmode = GR_FIND;
39425+
39426+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
39427+ reqmode |= GR_EXEC;
39428+ if (fmode & S_IWOTH)
39429+ reqmode |= GR_WRITE;
39430+ if (fmode & S_IROTH)
39431+ reqmode |= GR_READ;
39432+
39433+ mode =
39434+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
39435+ mnt);
39436+
39437+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
39438+ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
39439+ reqmode & GR_READ ? " reading" : "",
39440+ reqmode & GR_WRITE ? " writing" : "",
39441+ reqmode & GR_EXEC ? " executing" : "");
39442+ return reqmode;
39443+ } else
39444+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
39445+ {
39446+ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
39447+ reqmode & GR_READ ? " reading" : "",
39448+ reqmode & GR_WRITE ? " writing" : "",
39449+ reqmode & GR_EXEC ? " executing" : "");
39450+ return 0;
39451+ } else if (unlikely((mode & reqmode) != reqmode))
39452+ return 0;
39453+
39454+ return reqmode;
39455+}
39456+
39457+static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
39458+{
39459+ __u32 mode;
39460+
39461+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
39462+
39463+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
39464+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
39465+ return mode;
39466+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
39467+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
39468+ return 0;
39469+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
39470+ return 0;
39471+
39472+ return (reqmode);
39473+}
39474+
39475+__u32
39476+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
39477+{
39478+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
39479+}
39480+
39481+__u32
39482+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
39483+{
39484+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
39485+}
39486+
39487+__u32
39488+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
39489+{
39490+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
39491+}
39492+
39493+__u32
39494+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
39495+{
39496+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
39497+}
39498+
39499+__u32
39500+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
39501+ mode_t mode)
39502+{
39503+ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
39504+ return 1;
39505+
39506+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
39507+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
39508+ GR_FCHMOD_ACL_MSG);
39509+ } else {
39510+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
39511+ }
39512+}
39513+
39514+__u32
39515+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
39516+ mode_t mode)
39517+{
39518+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
39519+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
39520+ GR_CHMOD_ACL_MSG);
39521+ } else {
39522+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
39523+ }
39524+}
39525+
39526+__u32
39527+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
39528+{
39529+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
39530+}
39531+
39532+__u32
bc901d79
MT
39533+gr_acl_handle_setxattr(const struct dentry *dentry, const struct vfsmount *mnt)
39534+{
39535+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_SETXATTR_ACL_MSG);
39536+}
39537+
39538+__u32
58c5fc13
MT
39539+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
39540+{
39541+ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
39542+}
39543+
39544+__u32
39545+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
39546+{
39547+ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
39548+ GR_UNIXCONNECT_ACL_MSG);
39549+}
39550+
39551+/* hardlinks require at minimum create permission,
39552+ any additional privilege required is based on the
39553+ privilege of the file being linked to
39554+*/
39555+__u32
39556+gr_acl_handle_link(const struct dentry * new_dentry,
39557+ const struct dentry * parent_dentry,
39558+ const struct vfsmount * parent_mnt,
39559+ const struct dentry * old_dentry,
39560+ const struct vfsmount * old_mnt, const char *to)
39561+{
39562+ __u32 mode;
39563+ __u32 needmode = GR_CREATE | GR_LINK;
39564+ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
39565+
39566+ mode =
39567+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
39568+ old_mnt);
39569+
39570+ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
39571+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
39572+ return mode;
39573+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
39574+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
39575+ return 0;
39576+ } else if (unlikely((mode & needmode) != needmode))
39577+ return 0;
39578+
39579+ return 1;
39580+}
39581+
39582+__u32
39583+gr_acl_handle_symlink(const struct dentry * new_dentry,
39584+ const struct dentry * parent_dentry,
39585+ const struct vfsmount * parent_mnt, const char *from)
39586+{
39587+ __u32 needmode = GR_WRITE | GR_CREATE;
39588+ __u32 mode;
39589+
39590+ mode =
39591+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
39592+ GR_CREATE | GR_AUDIT_CREATE |
39593+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
39594+
39595+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
39596+ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
39597+ return mode;
39598+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
39599+ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
39600+ return 0;
39601+ } else if (unlikely((mode & needmode) != needmode))
39602+ return 0;
39603+
39604+ return (GR_WRITE | GR_CREATE);
39605+}
39606+
39607+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)
39608+{
39609+ __u32 mode;
39610+
39611+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
39612+
39613+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
39614+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
39615+ return mode;
39616+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
39617+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
39618+ return 0;
39619+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
39620+ return 0;
39621+
39622+ return (reqmode);
39623+}
39624+
39625+__u32
39626+gr_acl_handle_mknod(const struct dentry * new_dentry,
39627+ const struct dentry * parent_dentry,
39628+ const struct vfsmount * parent_mnt,
39629+ const int mode)
39630+{
39631+ __u32 reqmode = GR_WRITE | GR_CREATE;
39632+ if (unlikely(mode & (S_ISUID | S_ISGID)))
39633+ reqmode |= GR_SETID;
39634+
39635+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
39636+ reqmode, GR_MKNOD_ACL_MSG);
39637+}
39638+
39639+__u32
39640+gr_acl_handle_mkdir(const struct dentry *new_dentry,
39641+ const struct dentry *parent_dentry,
39642+ const struct vfsmount *parent_mnt)
39643+{
39644+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
39645+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
39646+}
39647+
39648+#define RENAME_CHECK_SUCCESS(old, new) \
39649+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
39650+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
39651+
39652+int
39653+gr_acl_handle_rename(struct dentry *new_dentry,
39654+ struct dentry *parent_dentry,
39655+ const struct vfsmount *parent_mnt,
39656+ struct dentry *old_dentry,
39657+ struct inode *old_parent_inode,
39658+ struct vfsmount *old_mnt, const char *newname)
39659+{
39660+ __u32 comp1, comp2;
39661+ int error = 0;
39662+
39663+ if (unlikely(!gr_acl_is_enabled()))
39664+ return 0;
39665+
39666+ if (!new_dentry->d_inode) {
39667+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
39668+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
39669+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
39670+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
39671+ GR_DELETE | GR_AUDIT_DELETE |
39672+ GR_AUDIT_READ | GR_AUDIT_WRITE |
39673+ GR_SUPPRESS, old_mnt);
39674+ } else {
39675+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
39676+ GR_CREATE | GR_DELETE |
39677+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
39678+ GR_AUDIT_READ | GR_AUDIT_WRITE |
39679+ GR_SUPPRESS, parent_mnt);
39680+ comp2 =
39681+ gr_search_file(old_dentry,
39682+ GR_READ | GR_WRITE | GR_AUDIT_READ |
39683+ GR_DELETE | GR_AUDIT_DELETE |
39684+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
39685+ }
39686+
39687+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
39688+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
39689+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
39690+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
39691+ && !(comp2 & GR_SUPPRESS)) {
39692+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
39693+ error = -EACCES;
39694+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
39695+ error = -EACCES;
39696+
39697+ return error;
39698+}
39699+
39700+void
39701+gr_acl_handle_exit(void)
39702+{
39703+ u16 id;
39704+ char *rolename;
39705+ struct file *exec_file;
39706+
16454cff
MT
39707+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled() &&
39708+ !(current->role->roletype & GR_ROLE_PERSIST))) {
58c5fc13
MT
39709+ id = current->acl_role_id;
39710+ rolename = current->role->rolename;
39711+ gr_set_acls(1);
39712+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
39713+ }
39714+
39715+ write_lock(&grsec_exec_file_lock);
39716+ exec_file = current->exec_file;
39717+ current->exec_file = NULL;
39718+ write_unlock(&grsec_exec_file_lock);
39719+
39720+ if (exec_file)
39721+ fput(exec_file);
39722+}
39723+
39724+int
39725+gr_acl_handle_procpidmem(const struct task_struct *task)
39726+{
39727+ if (unlikely(!gr_acl_is_enabled()))
39728+ return 0;
39729+
39730+ if (task != current && task->acl->mode & GR_PROTPROCFD)
39731+ return -EACCES;
39732+
39733+ return 0;
39734+}
16454cff
MT
39735diff -urNp linux-2.6.38.1/grsecurity/gracl_ip.c linux-2.6.38.1/grsecurity/gracl_ip.c
39736--- linux-2.6.38.1/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
39737+++ linux-2.6.38.1/grsecurity/gracl_ip.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 39738@@ -0,0 +1,382 @@
58c5fc13
MT
39739+#include <linux/kernel.h>
39740+#include <asm/uaccess.h>
39741+#include <asm/errno.h>
39742+#include <net/sock.h>
39743+#include <linux/file.h>
39744+#include <linux/fs.h>
39745+#include <linux/net.h>
39746+#include <linux/in.h>
39747+#include <linux/skbuff.h>
39748+#include <linux/ip.h>
39749+#include <linux/udp.h>
39750+#include <linux/smp_lock.h>
39751+#include <linux/types.h>
39752+#include <linux/sched.h>
39753+#include <linux/netdevice.h>
39754+#include <linux/inetdevice.h>
39755+#include <linux/gracl.h>
39756+#include <linux/grsecurity.h>
39757+#include <linux/grinternal.h>
39758+
39759+#define GR_BIND 0x01
39760+#define GR_CONNECT 0x02
39761+#define GR_INVERT 0x04
39762+#define GR_BINDOVERRIDE 0x08
39763+#define GR_CONNECTOVERRIDE 0x10
bc901d79 39764+#define GR_SOCK_FAMILY 0x20
58c5fc13 39765+
bc901d79 39766+static const char * gr_protocols[IPPROTO_MAX] = {
58c5fc13
MT
39767+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
39768+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
39769+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
39770+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
39771+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
39772+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
39773+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
39774+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
39775+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
39776+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
39777+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
39778+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
39779+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
39780+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
39781+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
39782+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
39783+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
39784+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
39785+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
39786+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
39787+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
39788+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
39789+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
39790+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
39791+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
39792+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
39793+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
39794+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
39795+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
39796+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
39797+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
39798+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
39799+ };
39800+
bc901d79 39801+static const char * gr_socktypes[SOCK_MAX] = {
58c5fc13
MT
39802+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
39803+ "unknown:7", "unknown:8", "unknown:9", "packet"
39804+ };
39805+
bc901d79
MT
39806+static const char * gr_sockfamilies[AF_MAX+1] = {
39807+ "unspec", "unix", "inet", "ax25", "ipx", "appletalk", "netrom", "bridge", "atmpvc", "x25",
39808+ "inet6", "rose", "decnet", "netbeui", "security", "key", "netlink", "packet", "ash",
c52201e0
MT
39809+ "econet", "atmsvc", "rds", "sna", "irda", "ppox", "wanpipe", "llc", "fam_27", "fam_28",
39810+ "tipc", "bluetooth", "iucv", "rxrpc", "isdn", "phonet", "ieee802154", "ciaf"
bc901d79
MT
39811+ };
39812+
58c5fc13
MT
39813+const char *
39814+gr_proto_to_name(unsigned char proto)
39815+{
39816+ return gr_protocols[proto];
39817+}
39818+
39819+const char *
39820+gr_socktype_to_name(unsigned char type)
39821+{
39822+ return gr_socktypes[type];
39823+}
39824+
bc901d79
MT
39825+const char *
39826+gr_sockfamily_to_name(unsigned char family)
39827+{
39828+ return gr_sockfamilies[family];
39829+}
39830+
58c5fc13
MT
39831+int
39832+gr_search_socket(const int domain, const int type, const int protocol)
39833+{
39834+ struct acl_subject_label *curr;
39835+ const struct cred *cred = current_cred();
39836+
39837+ if (unlikely(!gr_acl_is_enabled()))
39838+ goto exit;
39839+
bc901d79
MT
39840+ if ((domain < 0) || (type < 0) || (protocol < 0) ||
39841+ (domain >= AF_MAX) || (type >= SOCK_MAX) || (protocol >= IPPROTO_MAX))
58c5fc13
MT
39842+ goto exit; // let the kernel handle it
39843+
39844+ curr = current->acl;
39845+
bc901d79
MT
39846+ if (curr->sock_families[domain / 32] & (1 << (domain % 32))) {
39847+ /* the family is allowed, if this is PF_INET allow it only if
39848+ the extra sock type/protocol checks pass */
39849+ if (domain == PF_INET)
39850+ goto inet_check;
39851+ goto exit;
39852+ } else {
39853+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
39854+ __u32 fakeip = 0;
39855+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
39856+ current->role->roletype, cred->uid,
39857+ cred->gid, current->exec_file ?
39858+ gr_to_filename(current->exec_file->f_path.dentry,
39859+ current->exec_file->f_path.mnt) :
39860+ curr->filename, curr->filename,
39861+ &fakeip, domain, 0, 0, GR_SOCK_FAMILY,
39862+ &current->signal->saved_ip);
39863+ goto exit;
39864+ }
39865+ goto exit_fail;
39866+ }
39867+
39868+inet_check:
39869+ /* the rest of this checking is for IPv4 only */
58c5fc13
MT
39870+ if (!curr->ips)
39871+ goto exit;
39872+
39873+ if ((curr->ip_type & (1 << type)) &&
39874+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
39875+ goto exit;
39876+
39877+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
39878+ /* we don't place acls on raw sockets , and sometimes
39879+ dgram/ip sockets are opened for ioctl and not
39880+ bind/connect, so we'll fake a bind learn log */
39881+ if (type == SOCK_RAW || type == SOCK_PACKET) {
39882+ __u32 fakeip = 0;
39883+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
39884+ current->role->roletype, cred->uid,
39885+ cred->gid, current->exec_file ?
39886+ gr_to_filename(current->exec_file->f_path.dentry,
39887+ current->exec_file->f_path.mnt) :
39888+ curr->filename, curr->filename,
ae4e228f 39889+ &fakeip, 0, type,
bc901d79 39890+ protocol, GR_CONNECT, &current->signal->saved_ip);
58c5fc13
MT
39891+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
39892+ __u32 fakeip = 0;
39893+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
39894+ current->role->roletype, cred->uid,
39895+ cred->gid, current->exec_file ?
39896+ gr_to_filename(current->exec_file->f_path.dentry,
39897+ current->exec_file->f_path.mnt) :
39898+ curr->filename, curr->filename,
ae4e228f 39899+ &fakeip, 0, type,
bc901d79 39900+ protocol, GR_BIND, &current->signal->saved_ip);
58c5fc13
MT
39901+ }
39902+ /* we'll log when they use connect or bind */
39903+ goto exit;
39904+ }
39905+
bc901d79
MT
39906+exit_fail:
39907+ if (domain == PF_INET)
39908+ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, gr_sockfamily_to_name(domain),
39909+ gr_socktype_to_name(type), gr_proto_to_name(protocol));
39910+ else
39911+ gr_log_str2_int(GR_DONT_AUDIT, GR_SOCK_NOINET_MSG, gr_sockfamily_to_name(domain),
39912+ gr_socktype_to_name(type), protocol);
58c5fc13
MT
39913+
39914+ return 0;
bc901d79 39915+exit:
58c5fc13
MT
39916+ return 1;
39917+}
39918+
39919+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)
39920+{
39921+ if ((ip->mode & mode) &&
39922+ (ip_port >= ip->low) &&
39923+ (ip_port <= ip->high) &&
39924+ ((ntohl(ip_addr) & our_netmask) ==
39925+ (ntohl(our_addr) & our_netmask))
39926+ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
39927+ && (ip->type & (1 << type))) {
39928+ if (ip->mode & GR_INVERT)
39929+ return 2; // specifically denied
39930+ else
39931+ return 1; // allowed
39932+ }
39933+
39934+ return 0; // not specifically allowed, may continue parsing
39935+}
39936+
39937+static int
39938+gr_search_connectbind(const int full_mode, struct sock *sk,
39939+ struct sockaddr_in *addr, const int type)
39940+{
39941+ char iface[IFNAMSIZ] = {0};
39942+ struct acl_subject_label *curr;
39943+ struct acl_ip_label *ip;
39944+ struct inet_sock *isk;
39945+ struct net_device *dev;
39946+ struct in_device *idev;
39947+ unsigned long i;
39948+ int ret;
39949+ int mode = full_mode & (GR_BIND | GR_CONNECT);
39950+ __u32 ip_addr = 0;
39951+ __u32 our_addr;
39952+ __u32 our_netmask;
39953+ char *p;
39954+ __u16 ip_port = 0;
39955+ const struct cred *cred = current_cred();
39956+
39957+ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
39958+ return 0;
39959+
39960+ curr = current->acl;
39961+ isk = inet_sk(sk);
39962+
39963+ /* INADDR_ANY overriding for binds, inaddr_any_override is already in network order */
39964+ if ((full_mode & GR_BINDOVERRIDE) && addr->sin_addr.s_addr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0)
39965+ addr->sin_addr.s_addr = curr->inaddr_any_override;
ae4e228f 39966+ if ((full_mode & GR_CONNECT) && isk->inet_saddr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) {
58c5fc13
MT
39967+ struct sockaddr_in saddr;
39968+ int err;
39969+
39970+ saddr.sin_family = AF_INET;
39971+ saddr.sin_addr.s_addr = curr->inaddr_any_override;
ae4e228f 39972+ saddr.sin_port = isk->inet_sport;
58c5fc13
MT
39973+
39974+ err = security_socket_bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
39975+ if (err)
39976+ return err;
39977+
39978+ err = sk->sk_socket->ops->bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
39979+ if (err)
39980+ return err;
39981+ }
39982+
39983+ if (!curr->ips)
39984+ return 0;
39985+
39986+ ip_addr = addr->sin_addr.s_addr;
39987+ ip_port = ntohs(addr->sin_port);
39988+
39989+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
39990+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
39991+ current->role->roletype, cred->uid,
39992+ cred->gid, current->exec_file ?
39993+ gr_to_filename(current->exec_file->f_path.dentry,
39994+ current->exec_file->f_path.mnt) :
39995+ curr->filename, curr->filename,
ae4e228f 39996+ &ip_addr, ip_port, type,
bc901d79 39997+ sk->sk_protocol, mode, &current->signal->saved_ip);
58c5fc13
MT
39998+ return 0;
39999+ }
40000+
40001+ for (i = 0; i < curr->ip_num; i++) {
40002+ ip = *(curr->ips + i);
40003+ if (ip->iface != NULL) {
40004+ strncpy(iface, ip->iface, IFNAMSIZ - 1);
40005+ p = strchr(iface, ':');
40006+ if (p != NULL)
40007+ *p = '\0';
40008+ dev = dev_get_by_name(sock_net(sk), iface);
40009+ if (dev == NULL)
40010+ continue;
40011+ idev = in_dev_get(dev);
40012+ if (idev == NULL) {
40013+ dev_put(dev);
40014+ continue;
40015+ }
40016+ rcu_read_lock();
40017+ for_ifa(idev) {
40018+ if (!strcmp(ip->iface, ifa->ifa_label)) {
40019+ our_addr = ifa->ifa_address;
40020+ our_netmask = 0xffffffff;
40021+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
40022+ if (ret == 1) {
40023+ rcu_read_unlock();
40024+ in_dev_put(idev);
40025+ dev_put(dev);
40026+ return 0;
40027+ } else if (ret == 2) {
40028+ rcu_read_unlock();
40029+ in_dev_put(idev);
40030+ dev_put(dev);
40031+ goto denied;
40032+ }
40033+ }
40034+ } endfor_ifa(idev);
40035+ rcu_read_unlock();
40036+ in_dev_put(idev);
40037+ dev_put(dev);
40038+ } else {
40039+ our_addr = ip->addr;
40040+ our_netmask = ip->netmask;
40041+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
40042+ if (ret == 1)
40043+ return 0;
40044+ else if (ret == 2)
40045+ goto denied;
40046+ }
40047+ }
40048+
40049+denied:
40050+ if (mode == GR_BIND)
ae4e228f 40051+ gr_log_int5_str2(GR_DONT_AUDIT, GR_BIND_ACL_MSG, &ip_addr, ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
58c5fc13 40052+ else if (mode == GR_CONNECT)
ae4e228f 40053+ gr_log_int5_str2(GR_DONT_AUDIT, GR_CONNECT_ACL_MSG, &ip_addr, ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
58c5fc13
MT
40054+
40055+ return -EACCES;
40056+}
40057+
40058+int
40059+gr_search_connect(struct socket *sock, struct sockaddr_in *addr)
40060+{
40061+ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sock->sk, addr, sock->type);
40062+}
40063+
40064+int
40065+gr_search_bind(struct socket *sock, struct sockaddr_in *addr)
40066+{
40067+ return gr_search_connectbind(GR_BIND | GR_BINDOVERRIDE, sock->sk, addr, sock->type);
40068+}
40069+
40070+int gr_search_listen(struct socket *sock)
40071+{
40072+ struct sock *sk = sock->sk;
40073+ struct sockaddr_in addr;
40074+
ae4e228f
MT
40075+ addr.sin_addr.s_addr = inet_sk(sk)->inet_saddr;
40076+ addr.sin_port = inet_sk(sk)->inet_sport;
58c5fc13
MT
40077+
40078+ return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
40079+}
40080+
40081+int gr_search_accept(struct socket *sock)
40082+{
40083+ struct sock *sk = sock->sk;
40084+ struct sockaddr_in addr;
40085+
ae4e228f
MT
40086+ addr.sin_addr.s_addr = inet_sk(sk)->inet_saddr;
40087+ addr.sin_port = inet_sk(sk)->inet_sport;
58c5fc13
MT
40088+
40089+ return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
40090+}
40091+
40092+int
40093+gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr)
40094+{
40095+ if (addr)
40096+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
40097+ else {
40098+ struct sockaddr_in sin;
40099+ const struct inet_sock *inet = inet_sk(sk);
40100+
ae4e228f
MT
40101+ sin.sin_addr.s_addr = inet->inet_daddr;
40102+ sin.sin_port = inet->inet_dport;
58c5fc13
MT
40103+
40104+ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
40105+ }
40106+}
40107+
40108+int
40109+gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb)
40110+{
40111+ struct sockaddr_in sin;
40112+
40113+ if (unlikely(skb->len < sizeof (struct udphdr)))
40114+ return 0; // skip this packet
40115+
40116+ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
40117+ sin.sin_port = udp_hdr(skb)->source;
40118+
40119+ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
40120+}
16454cff
MT
40121diff -urNp linux-2.6.38.1/grsecurity/gracl_learn.c linux-2.6.38.1/grsecurity/gracl_learn.c
40122--- linux-2.6.38.1/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
40123+++ linux-2.6.38.1/grsecurity/gracl_learn.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
40124@@ -0,0 +1,211 @@
40125+#include <linux/kernel.h>
40126+#include <linux/mm.h>
40127+#include <linux/sched.h>
40128+#include <linux/poll.h>
40129+#include <linux/smp_lock.h>
40130+#include <linux/string.h>
40131+#include <linux/file.h>
40132+#include <linux/types.h>
40133+#include <linux/vmalloc.h>
40134+#include <linux/grinternal.h>
40135+
40136+extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
40137+ size_t count, loff_t *ppos);
40138+extern int gr_acl_is_enabled(void);
40139+
40140+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
40141+static int gr_learn_attached;
40142+
40143+/* use a 512k buffer */
40144+#define LEARN_BUFFER_SIZE (512 * 1024)
40145+
40146+static DEFINE_SPINLOCK(gr_learn_lock);
bc901d79 40147+static DEFINE_MUTEX(gr_learn_user_mutex);
58c5fc13
MT
40148+
40149+/* we need to maintain two buffers, so that the kernel context of grlearn
40150+ uses a semaphore around the userspace copying, and the other kernel contexts
40151+ use a spinlock when copying into the buffer, since they cannot sleep
40152+*/
40153+static char *learn_buffer;
40154+static char *learn_buffer_user;
40155+static int learn_buffer_len;
40156+static int learn_buffer_user_len;
40157+
40158+static ssize_t
40159+read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
40160+{
40161+ DECLARE_WAITQUEUE(wait, current);
40162+ ssize_t retval = 0;
40163+
40164+ add_wait_queue(&learn_wait, &wait);
40165+ set_current_state(TASK_INTERRUPTIBLE);
40166+ do {
bc901d79 40167+ mutex_lock(&gr_learn_user_mutex);
58c5fc13
MT
40168+ spin_lock(&gr_learn_lock);
40169+ if (learn_buffer_len)
40170+ break;
40171+ spin_unlock(&gr_learn_lock);
bc901d79 40172+ mutex_unlock(&gr_learn_user_mutex);
58c5fc13
MT
40173+ if (file->f_flags & O_NONBLOCK) {
40174+ retval = -EAGAIN;
40175+ goto out;
40176+ }
40177+ if (signal_pending(current)) {
40178+ retval = -ERESTARTSYS;
40179+ goto out;
40180+ }
40181+
40182+ schedule();
40183+ } while (1);
40184+
40185+ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
40186+ learn_buffer_user_len = learn_buffer_len;
40187+ retval = learn_buffer_len;
40188+ learn_buffer_len = 0;
40189+
40190+ spin_unlock(&gr_learn_lock);
40191+
40192+ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
40193+ retval = -EFAULT;
40194+
bc901d79 40195+ mutex_unlock(&gr_learn_user_mutex);
58c5fc13
MT
40196+out:
40197+ set_current_state(TASK_RUNNING);
40198+ remove_wait_queue(&learn_wait, &wait);
40199+ return retval;
40200+}
40201+
40202+static unsigned int
40203+poll_learn(struct file * file, poll_table * wait)
40204+{
40205+ poll_wait(file, &learn_wait, wait);
40206+
40207+ if (learn_buffer_len)
40208+ return (POLLIN | POLLRDNORM);
40209+
40210+ return 0;
40211+}
40212+
40213+void
40214+gr_clear_learn_entries(void)
40215+{
40216+ char *tmp;
40217+
bc901d79 40218+ mutex_lock(&gr_learn_user_mutex);
58c5fc13
MT
40219+ if (learn_buffer != NULL) {
40220+ spin_lock(&gr_learn_lock);
40221+ tmp = learn_buffer;
40222+ learn_buffer = NULL;
40223+ spin_unlock(&gr_learn_lock);
40224+ vfree(learn_buffer);
40225+ }
40226+ if (learn_buffer_user != NULL) {
40227+ vfree(learn_buffer_user);
40228+ learn_buffer_user = NULL;
40229+ }
40230+ learn_buffer_len = 0;
bc901d79 40231+ mutex_unlock(&gr_learn_user_mutex);
58c5fc13
MT
40232+
40233+ return;
40234+}
40235+
40236+void
40237+gr_add_learn_entry(const char *fmt, ...)
40238+{
40239+ va_list args;
40240+ unsigned int len;
40241+
40242+ if (!gr_learn_attached)
40243+ return;
40244+
40245+ spin_lock(&gr_learn_lock);
40246+
40247+ /* leave a gap at the end so we know when it's "full" but don't have to
40248+ compute the exact length of the string we're trying to append
40249+ */
40250+ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
40251+ spin_unlock(&gr_learn_lock);
40252+ wake_up_interruptible(&learn_wait);
40253+ return;
40254+ }
40255+ if (learn_buffer == NULL) {
40256+ spin_unlock(&gr_learn_lock);
40257+ return;
40258+ }
40259+
40260+ va_start(args, fmt);
40261+ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
40262+ va_end(args);
40263+
40264+ learn_buffer_len += len + 1;
40265+
40266+ spin_unlock(&gr_learn_lock);
40267+ wake_up_interruptible(&learn_wait);
40268+
40269+ return;
40270+}
40271+
40272+static int
40273+open_learn(struct inode *inode, struct file *file)
40274+{
40275+ if (file->f_mode & FMODE_READ && gr_learn_attached)
40276+ return -EBUSY;
40277+ if (file->f_mode & FMODE_READ) {
40278+ int retval = 0;
bc901d79 40279+ mutex_lock(&gr_learn_user_mutex);
58c5fc13
MT
40280+ if (learn_buffer == NULL)
40281+ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
40282+ if (learn_buffer_user == NULL)
40283+ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
40284+ if (learn_buffer == NULL) {
40285+ retval = -ENOMEM;
40286+ goto out_error;
40287+ }
40288+ if (learn_buffer_user == NULL) {
40289+ retval = -ENOMEM;
40290+ goto out_error;
40291+ }
40292+ learn_buffer_len = 0;
40293+ learn_buffer_user_len = 0;
40294+ gr_learn_attached = 1;
40295+out_error:
bc901d79 40296+ mutex_unlock(&gr_learn_user_mutex);
58c5fc13
MT
40297+ return retval;
40298+ }
40299+ return 0;
40300+}
40301+
40302+static int
40303+close_learn(struct inode *inode, struct file *file)
40304+{
40305+ char *tmp;
40306+
40307+ if (file->f_mode & FMODE_READ) {
bc901d79 40308+ mutex_lock(&gr_learn_user_mutex);
58c5fc13
MT
40309+ if (learn_buffer != NULL) {
40310+ spin_lock(&gr_learn_lock);
40311+ tmp = learn_buffer;
40312+ learn_buffer = NULL;
40313+ spin_unlock(&gr_learn_lock);
40314+ vfree(tmp);
40315+ }
40316+ if (learn_buffer_user != NULL) {
40317+ vfree(learn_buffer_user);
40318+ learn_buffer_user = NULL;
40319+ }
40320+ learn_buffer_len = 0;
40321+ learn_buffer_user_len = 0;
40322+ gr_learn_attached = 0;
bc901d79 40323+ mutex_unlock(&gr_learn_user_mutex);
58c5fc13
MT
40324+ }
40325+
40326+ return 0;
40327+}
40328+
40329+const struct file_operations grsec_fops = {
40330+ .read = read_learn,
40331+ .write = write_grsec_handler,
40332+ .open = open_learn,
40333+ .release = close_learn,
40334+ .poll = poll_learn,
40335+};
16454cff
MT
40336diff -urNp linux-2.6.38.1/grsecurity/gracl_res.c linux-2.6.38.1/grsecurity/gracl_res.c
40337--- linux-2.6.38.1/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
40338+++ linux-2.6.38.1/grsecurity/gracl_res.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 40339@@ -0,0 +1,68 @@
58c5fc13
MT
40340+#include <linux/kernel.h>
40341+#include <linux/sched.h>
40342+#include <linux/gracl.h>
40343+#include <linux/grinternal.h>
40344+
40345+static const char *restab_log[] = {
40346+ [RLIMIT_CPU] = "RLIMIT_CPU",
40347+ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
40348+ [RLIMIT_DATA] = "RLIMIT_DATA",
40349+ [RLIMIT_STACK] = "RLIMIT_STACK",
40350+ [RLIMIT_CORE] = "RLIMIT_CORE",
40351+ [RLIMIT_RSS] = "RLIMIT_RSS",
40352+ [RLIMIT_NPROC] = "RLIMIT_NPROC",
40353+ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
40354+ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
40355+ [RLIMIT_AS] = "RLIMIT_AS",
40356+ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
40357+ [RLIMIT_SIGPENDING] = "RLIMIT_SIGPENDING",
40358+ [RLIMIT_MSGQUEUE] = "RLIMIT_MSGQUEUE",
40359+ [RLIMIT_NICE] = "RLIMIT_NICE",
40360+ [RLIMIT_RTPRIO] = "RLIMIT_RTPRIO",
40361+ [RLIMIT_RTTIME] = "RLIMIT_RTTIME",
40362+ [GR_CRASH_RES] = "RLIMIT_CRASH"
40363+};
40364+
40365+void
40366+gr_log_resource(const struct task_struct *task,
40367+ const int res, const unsigned long wanted, const int gt)
40368+{
ae4e228f 40369+ const struct cred *cred;
df50ba0c 40370+ unsigned long rlim;
58c5fc13
MT
40371+
40372+ if (!gr_acl_is_enabled() && !grsec_resource_logging)
40373+ return;
40374+
40375+ // not yet supported resource
df50ba0c
MT
40376+ if (unlikely(!restab_log[res]))
40377+ return;
40378+
40379+ if (res == RLIMIT_CPU || res == RLIMIT_RTTIME)
40380+ rlim = task_rlimit_max(task, res);
40381+ else
40382+ rlim = task_rlimit(task, res);
40383+
40384+ if (likely((rlim == RLIM_INFINITY) || (gt && wanted <= rlim) || (!gt && wanted < rlim)))
58c5fc13
MT
40385+ return;
40386+
ae4e228f
MT
40387+ rcu_read_lock();
40388+ cred = __task_cred(task);
40389+
40390+ if (res == RLIMIT_NPROC &&
40391+ (cap_raised(cred->cap_effective, CAP_SYS_ADMIN) ||
40392+ cap_raised(cred->cap_effective, CAP_SYS_RESOURCE)))
40393+ goto out_rcu_unlock;
40394+ else if (res == RLIMIT_MEMLOCK &&
40395+ cap_raised(cred->cap_effective, CAP_IPC_LOCK))
40396+ goto out_rcu_unlock;
40397+ else if (res == RLIMIT_NICE && cap_raised(cred->cap_effective, CAP_SYS_NICE))
40398+ goto out_rcu_unlock;
40399+ rcu_read_unlock();
40400+
df50ba0c 40401+ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], rlim);
58c5fc13
MT
40402+
40403+ return;
ae4e228f
MT
40404+out_rcu_unlock:
40405+ rcu_read_unlock();
40406+ return;
58c5fc13 40407+}
16454cff
MT
40408diff -urNp linux-2.6.38.1/grsecurity/gracl_segv.c linux-2.6.38.1/grsecurity/gracl_segv.c
40409--- linux-2.6.38.1/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
40410+++ linux-2.6.38.1/grsecurity/gracl_segv.c 2011-03-24 23:09:37.000000000 -0400
40411@@ -0,0 +1,326 @@
58c5fc13
MT
40412+#include <linux/kernel.h>
40413+#include <linux/mm.h>
40414+#include <asm/uaccess.h>
40415+#include <asm/errno.h>
40416+#include <asm/mman.h>
40417+#include <net/sock.h>
40418+#include <linux/file.h>
40419+#include <linux/fs.h>
40420+#include <linux/net.h>
40421+#include <linux/in.h>
40422+#include <linux/smp_lock.h>
40423+#include <linux/slab.h>
40424+#include <linux/types.h>
40425+#include <linux/sched.h>
40426+#include <linux/timer.h>
40427+#include <linux/gracl.h>
40428+#include <linux/grsecurity.h>
40429+#include <linux/grinternal.h>
40430+
40431+static struct crash_uid *uid_set;
40432+static unsigned short uid_used;
40433+static DEFINE_SPINLOCK(gr_uid_lock);
40434+extern rwlock_t gr_inode_lock;
40435+extern struct acl_subject_label *
40436+ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
40437+ struct acl_role_label *role);
40438+extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
40439+
16454cff
MT
40440+
40441+#ifdef CONFIG_BTRFS_FS
40442+extern dev_t get_btrfs_dev_from_inode(struct inode *inode);
40443+extern int btrfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
40444+#endif
40445+
40446+static inline dev_t __get_dev(const struct dentry *dentry)
40447+{
40448+#ifdef CONFIG_BTRFS_FS
40449+ if (dentry->d_inode->i_op && dentry->d_inode->i_op->getattr == &btrfs_getattr)
40450+ return get_btrfs_dev_from_inode(dentry->d_inode);
40451+ else
40452+#endif
40453+ return dentry->d_inode->i_sb->s_dev;
40454+}
40455+
58c5fc13
MT
40456+int
40457+gr_init_uidset(void)
40458+{
40459+ uid_set =
40460+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
40461+ uid_used = 0;
40462+
40463+ return uid_set ? 1 : 0;
40464+}
40465+
40466+void
40467+gr_free_uidset(void)
40468+{
40469+ if (uid_set)
40470+ kfree(uid_set);
40471+
40472+ return;
40473+}
40474+
40475+int
40476+gr_find_uid(const uid_t uid)
40477+{
40478+ struct crash_uid *tmp = uid_set;
40479+ uid_t buid;
40480+ int low = 0, high = uid_used - 1, mid;
40481+
40482+ while (high >= low) {
40483+ mid = (low + high) >> 1;
40484+ buid = tmp[mid].uid;
40485+ if (buid == uid)
40486+ return mid;
40487+ if (buid > uid)
40488+ high = mid - 1;
40489+ if (buid < uid)
40490+ low = mid + 1;
40491+ }
40492+
40493+ return -1;
40494+}
40495+
40496+static __inline__ void
40497+gr_insertsort(void)
40498+{
40499+ unsigned short i, j;
40500+ struct crash_uid index;
40501+
40502+ for (i = 1; i < uid_used; i++) {
40503+ index = uid_set[i];
40504+ j = i;
40505+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
40506+ uid_set[j] = uid_set[j - 1];
40507+ j--;
40508+ }
40509+ uid_set[j] = index;
40510+ }
40511+
40512+ return;
40513+}
40514+
40515+static __inline__ void
40516+gr_insert_uid(const uid_t uid, const unsigned long expires)
40517+{
40518+ int loc;
40519+
40520+ if (uid_used == GR_UIDTABLE_MAX)
40521+ return;
40522+
40523+ loc = gr_find_uid(uid);
40524+
40525+ if (loc >= 0) {
40526+ uid_set[loc].expires = expires;
40527+ return;
40528+ }
40529+
40530+ uid_set[uid_used].uid = uid;
40531+ uid_set[uid_used].expires = expires;
40532+ uid_used++;
40533+
40534+ gr_insertsort();
40535+
40536+ return;
40537+}
40538+
40539+void
40540+gr_remove_uid(const unsigned short loc)
40541+{
40542+ unsigned short i;
40543+
40544+ for (i = loc + 1; i < uid_used; i++)
40545+ uid_set[i - 1] = uid_set[i];
40546+
40547+ uid_used--;
40548+
40549+ return;
40550+}
40551+
40552+int
40553+gr_check_crash_uid(const uid_t uid)
40554+{
40555+ int loc;
40556+ int ret = 0;
40557+
40558+ if (unlikely(!gr_acl_is_enabled()))
40559+ return 0;
40560+
40561+ spin_lock(&gr_uid_lock);
40562+ loc = gr_find_uid(uid);
40563+
40564+ if (loc < 0)
40565+ goto out_unlock;
40566+
40567+ if (time_before_eq(uid_set[loc].expires, get_seconds()))
40568+ gr_remove_uid(loc);
40569+ else
40570+ ret = 1;
40571+
40572+out_unlock:
40573+ spin_unlock(&gr_uid_lock);
40574+ return ret;
40575+}
40576+
40577+static __inline__ int
40578+proc_is_setxid(const struct cred *cred)
40579+{
40580+ if (cred->uid != cred->euid || cred->uid != cred->suid ||
40581+ cred->uid != cred->fsuid)
40582+ return 1;
40583+ if (cred->gid != cred->egid || cred->gid != cred->sgid ||
40584+ cred->gid != cred->fsgid)
40585+ return 1;
40586+
40587+ return 0;
40588+}
40589+static __inline__ int
40590+gr_fake_force_sig(int sig, struct task_struct *t)
40591+{
40592+ unsigned long int flags;
40593+ int ret, blocked, ignored;
40594+ struct k_sigaction *action;
40595+
40596+ spin_lock_irqsave(&t->sighand->siglock, flags);
40597+ action = &t->sighand->action[sig-1];
40598+ ignored = action->sa.sa_handler == SIG_IGN;
40599+ blocked = sigismember(&t->blocked, sig);
40600+ if (blocked || ignored) {
40601+ action->sa.sa_handler = SIG_DFL;
40602+ if (blocked) {
40603+ sigdelset(&t->blocked, sig);
40604+ recalc_sigpending_and_wake(t);
40605+ }
40606+ }
40607+ if (action->sa.sa_handler == SIG_DFL)
40608+ t->signal->flags &= ~SIGNAL_UNKILLABLE;
40609+ ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
40610+
40611+ spin_unlock_irqrestore(&t->sighand->siglock, flags);
40612+
40613+ return ret;
40614+}
40615+
40616+void
40617+gr_handle_crash(struct task_struct *task, const int sig)
40618+{
40619+ struct acl_subject_label *curr;
40620+ struct acl_subject_label *curr2;
40621+ struct task_struct *tsk, *tsk2;
ae4e228f 40622+ const struct cred *cred;
58c5fc13
MT
40623+ const struct cred *cred2;
40624+
40625+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
40626+ return;
40627+
40628+ if (unlikely(!gr_acl_is_enabled()))
40629+ return;
40630+
40631+ curr = task->acl;
40632+
40633+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
40634+ return;
40635+
40636+ if (time_before_eq(curr->expires, get_seconds())) {
40637+ curr->expires = 0;
40638+ curr->crashes = 0;
40639+ }
40640+
40641+ curr->crashes++;
40642+
40643+ if (!curr->expires)
40644+ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
40645+
40646+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
40647+ time_after(curr->expires, get_seconds())) {
ae4e228f
MT
40648+ rcu_read_lock();
40649+ cred = __task_cred(task);
58c5fc13
MT
40650+ if (cred->uid && proc_is_setxid(cred)) {
40651+ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
40652+ spin_lock(&gr_uid_lock);
40653+ gr_insert_uid(cred->uid, curr->expires);
40654+ spin_unlock(&gr_uid_lock);
40655+ curr->expires = 0;
40656+ curr->crashes = 0;
40657+ read_lock(&tasklist_lock);
40658+ do_each_thread(tsk2, tsk) {
40659+ cred2 = __task_cred(tsk);
40660+ if (tsk != task && cred2->uid == cred->uid)
40661+ gr_fake_force_sig(SIGKILL, tsk);
40662+ } while_each_thread(tsk2, tsk);
40663+ read_unlock(&tasklist_lock);
40664+ } else {
40665+ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
40666+ read_lock(&tasklist_lock);
40667+ do_each_thread(tsk2, tsk) {
40668+ if (likely(tsk != task)) {
40669+ curr2 = tsk->acl;
40670+
40671+ if (curr2->device == curr->device &&
40672+ curr2->inode == curr->inode)
40673+ gr_fake_force_sig(SIGKILL, tsk);
40674+ }
40675+ } while_each_thread(tsk2, tsk);
40676+ read_unlock(&tasklist_lock);
40677+ }
ae4e228f 40678+ rcu_read_unlock();
58c5fc13
MT
40679+ }
40680+
40681+ return;
40682+}
40683+
40684+int
40685+gr_check_crash_exec(const struct file *filp)
40686+{
40687+ struct acl_subject_label *curr;
40688+
40689+ if (unlikely(!gr_acl_is_enabled()))
40690+ return 0;
40691+
40692+ read_lock(&gr_inode_lock);
40693+ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
16454cff 40694+ __get_dev(filp->f_path.dentry),
58c5fc13
MT
40695+ current->role);
40696+ read_unlock(&gr_inode_lock);
40697+
40698+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
40699+ (!curr->crashes && !curr->expires))
40700+ return 0;
40701+
40702+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
40703+ time_after(curr->expires, get_seconds()))
40704+ return 1;
40705+ else if (time_before_eq(curr->expires, get_seconds())) {
40706+ curr->crashes = 0;
40707+ curr->expires = 0;
40708+ }
40709+
40710+ return 0;
40711+}
40712+
40713+void
40714+gr_handle_alertkill(struct task_struct *task)
40715+{
40716+ struct acl_subject_label *curracl;
40717+ __u32 curr_ip;
40718+ struct task_struct *p, *p2;
40719+
40720+ if (unlikely(!gr_acl_is_enabled()))
40721+ return;
40722+
40723+ curracl = task->acl;
40724+ curr_ip = task->signal->curr_ip;
40725+
40726+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
40727+ read_lock(&tasklist_lock);
40728+ do_each_thread(p2, p) {
40729+ if (p->signal->curr_ip == curr_ip)
40730+ gr_fake_force_sig(SIGKILL, p);
40731+ } while_each_thread(p2, p);
40732+ read_unlock(&tasklist_lock);
40733+ } else if (curracl->mode & GR_KILLPROC)
40734+ gr_fake_force_sig(SIGKILL, task);
40735+
40736+ return;
40737+}
16454cff
MT
40738diff -urNp linux-2.6.38.1/grsecurity/gracl_shm.c linux-2.6.38.1/grsecurity/gracl_shm.c
40739--- linux-2.6.38.1/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
40740+++ linux-2.6.38.1/grsecurity/gracl_shm.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 40741@@ -0,0 +1,40 @@
58c5fc13
MT
40742+#include <linux/kernel.h>
40743+#include <linux/mm.h>
40744+#include <linux/sched.h>
40745+#include <linux/file.h>
40746+#include <linux/ipc.h>
40747+#include <linux/gracl.h>
40748+#include <linux/grsecurity.h>
40749+#include <linux/grinternal.h>
40750+
40751+int
40752+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
40753+ const time_t shm_createtime, const uid_t cuid, const int shmid)
40754+{
40755+ struct task_struct *task;
40756+
40757+ if (!gr_acl_is_enabled())
40758+ return 1;
40759+
df50ba0c 40760+ rcu_read_lock();
58c5fc13
MT
40761+ read_lock(&tasklist_lock);
40762+
40763+ task = find_task_by_vpid(shm_cprid);
40764+
40765+ if (unlikely(!task))
40766+ task = find_task_by_vpid(shm_lapid);
40767+
40768+ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
40769+ (task->pid == shm_lapid)) &&
40770+ (task->acl->mode & GR_PROTSHM) &&
40771+ (task->acl != current->acl))) {
40772+ read_unlock(&tasklist_lock);
df50ba0c 40773+ rcu_read_unlock();
58c5fc13
MT
40774+ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
40775+ return 0;
40776+ }
40777+ read_unlock(&tasklist_lock);
df50ba0c 40778+ rcu_read_unlock();
58c5fc13
MT
40779+
40780+ return 1;
40781+}
16454cff
MT
40782diff -urNp linux-2.6.38.1/grsecurity/grsec_chdir.c linux-2.6.38.1/grsecurity/grsec_chdir.c
40783--- linux-2.6.38.1/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
40784+++ linux-2.6.38.1/grsecurity/grsec_chdir.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
40785@@ -0,0 +1,19 @@
40786+#include <linux/kernel.h>
40787+#include <linux/sched.h>
40788+#include <linux/fs.h>
40789+#include <linux/file.h>
40790+#include <linux/grsecurity.h>
40791+#include <linux/grinternal.h>
40792+
40793+void
40794+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
40795+{
40796+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
40797+ if ((grsec_enable_chdir && grsec_enable_group &&
40798+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
40799+ !grsec_enable_group)) {
40800+ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
40801+ }
40802+#endif
40803+ return;
40804+}
16454cff
MT
40805diff -urNp linux-2.6.38.1/grsecurity/grsec_chroot.c linux-2.6.38.1/grsecurity/grsec_chroot.c
40806--- linux-2.6.38.1/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
40807+++ linux-2.6.38.1/grsecurity/grsec_chroot.c 2011-03-21 21:24:10.000000000 -0400
40808@@ -0,0 +1,351 @@
58c5fc13
MT
40809+#include <linux/kernel.h>
40810+#include <linux/module.h>
40811+#include <linux/sched.h>
40812+#include <linux/file.h>
40813+#include <linux/fs.h>
40814+#include <linux/mount.h>
40815+#include <linux/types.h>
40816+#include <linux/pid_namespace.h>
40817+#include <linux/grsecurity.h>
40818+#include <linux/grinternal.h>
40819+
df50ba0c
MT
40820+void gr_set_chroot_entries(struct task_struct *task, struct path *path)
40821+{
40822+#ifdef CONFIG_GRKERNSEC
40823+ if (task->pid > 1 && path->dentry != init_task.fs->root.dentry &&
40824+ path->dentry != task->nsproxy->mnt_ns->root->mnt_root)
40825+ task->gr_is_chrooted = 1;
40826+ else
40827+ task->gr_is_chrooted = 0;
40828+
40829+ task->gr_chroot_dentry = path->dentry;
40830+#endif
40831+ return;
40832+}
40833+
40834+void gr_clear_chroot_entries(struct task_struct *task)
40835+{
40836+#ifdef CONFIG_GRKERNSEC
40837+ task->gr_is_chrooted = 0;
40838+ task->gr_chroot_dentry = NULL;
40839+#endif
40840+ return;
40841+}
40842+
58c5fc13 40843+int
6892158b 40844+gr_handle_chroot_unix(struct pid *pid)
58c5fc13
MT
40845+{
40846+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
6892158b 40847+ struct task_struct *p;
58c5fc13
MT
40848+
40849+ if (unlikely(!grsec_enable_chroot_unix))
40850+ return 1;
40851+
40852+ if (likely(!proc_is_chrooted(current)))
40853+ return 1;
40854+
df50ba0c 40855+ rcu_read_lock();
58c5fc13 40856+ read_lock(&tasklist_lock);
6892158b
MT
40857+ p = pid_task(pid, PIDTYPE_PID);
40858+ if (unlikely(!have_same_root(current, p))) {
40859+ read_unlock(&tasklist_lock);
40860+ rcu_read_unlock();
40861+ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
40862+ return 0;
58c5fc13
MT
40863+ }
40864+ read_unlock(&tasklist_lock);
df50ba0c 40865+ rcu_read_unlock();
58c5fc13
MT
40866+#endif
40867+ return 1;
40868+}
40869+
40870+int
40871+gr_handle_chroot_nice(void)
40872+{
40873+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
40874+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
40875+ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
40876+ return -EPERM;
40877+ }
40878+#endif
40879+ return 0;
40880+}
40881+
40882+int
40883+gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
40884+{
40885+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
40886+ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
40887+ && proc_is_chrooted(current)) {
40888+ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
40889+ return -EACCES;
40890+ }
40891+#endif
40892+ return 0;
40893+}
40894+
40895+int
40896+gr_handle_chroot_rawio(const struct inode *inode)
40897+{
40898+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
40899+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
40900+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
40901+ return 1;
40902+#endif
40903+ return 0;
40904+}
40905+
40906+int
57199397
MT
40907+gr_handle_chroot_fowner(struct pid *pid, enum pid_type type)
40908+{
40909+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
40910+ struct task_struct *p;
40911+ int ret = 0;
40912+ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !pid)
40913+ return ret;
40914+
40915+ read_lock(&tasklist_lock);
40916+ do_each_pid_task(pid, type, p) {
40917+ if (!have_same_root(current, p)) {
40918+ ret = 1;
40919+ goto out;
40920+ }
40921+ } while_each_pid_task(pid, type, p);
40922+out:
40923+ read_unlock(&tasklist_lock);
40924+ return ret;
40925+#endif
40926+ return 0;
40927+}
40928+
40929+int
58c5fc13
MT
40930+gr_pid_is_chrooted(struct task_struct *p)
40931+{
40932+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
40933+ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
40934+ return 0;
40935+
58c5fc13
MT
40936+ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
40937+ !have_same_root(current, p)) {
58c5fc13
MT
40938+ return 1;
40939+ }
58c5fc13
MT
40940+#endif
40941+ return 0;
40942+}
40943+
40944+EXPORT_SYMBOL(gr_pid_is_chrooted);
40945+
40946+#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
40947+int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
40948+{
16454cff
MT
40949+ struct path path, currentroot;
40950+ int ret = 0;
58c5fc13 40951+
16454cff
MT
40952+ path.dentry = (struct dentry *)u_dentry;
40953+ path.mnt = (struct vfsmount *)u_mnt;
6892158b 40954+ get_fs_root(current->fs, &currentroot);
16454cff
MT
40955+ if (path_is_under(&path, &currentroot))
40956+ ret = 1;
6892158b 40957+ path_put(&currentroot);
58c5fc13 40958+
58c5fc13
MT
40959+ return ret;
40960+}
40961+#endif
40962+
40963+int
40964+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
40965+{
40966+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
40967+ if (!grsec_enable_chroot_fchdir)
40968+ return 1;
40969+
40970+ if (!proc_is_chrooted(current))
40971+ return 1;
40972+ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
40973+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
40974+ return 0;
40975+ }
40976+#endif
40977+ return 1;
40978+}
40979+
40980+int
40981+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
40982+ const time_t shm_createtime)
40983+{
40984+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
40985+ struct pid *pid = NULL;
40986+ time_t starttime;
40987+
40988+ if (unlikely(!grsec_enable_chroot_shmat))
40989+ return 1;
40990+
40991+ if (likely(!proc_is_chrooted(current)))
40992+ return 1;
40993+
df50ba0c 40994+ rcu_read_lock();
58c5fc13
MT
40995+ read_lock(&tasklist_lock);
40996+
40997+ pid = find_vpid(shm_cprid);
40998+ if (pid) {
40999+ struct task_struct *p;
41000+ p = pid_task(pid, PIDTYPE_PID);
58c5fc13
MT
41001+ starttime = p->start_time.tv_sec;
41002+ if (unlikely(!have_same_root(current, p) &&
41003+ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
58c5fc13 41004+ read_unlock(&tasklist_lock);
df50ba0c 41005+ rcu_read_unlock();
58c5fc13
MT
41006+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
41007+ return 0;
41008+ }
58c5fc13
MT
41009+ } else {
41010+ pid = find_vpid(shm_lapid);
41011+ if (pid) {
41012+ struct task_struct *p;
41013+ p = pid_task(pid, PIDTYPE_PID);
58c5fc13 41014+ if (unlikely(!have_same_root(current, p))) {
58c5fc13 41015+ read_unlock(&tasklist_lock);
df50ba0c 41016+ rcu_read_unlock();
58c5fc13
MT
41017+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
41018+ return 0;
41019+ }
58c5fc13
MT
41020+ }
41021+ }
41022+
41023+ read_unlock(&tasklist_lock);
df50ba0c 41024+ rcu_read_unlock();
58c5fc13
MT
41025+#endif
41026+ return 1;
41027+}
41028+
41029+void
41030+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
41031+{
41032+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
41033+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
41034+ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
41035+#endif
41036+ return;
41037+}
41038+
41039+int
41040+gr_handle_chroot_mknod(const struct dentry *dentry,
41041+ const struct vfsmount *mnt, const int mode)
41042+{
41043+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
41044+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
41045+ proc_is_chrooted(current)) {
41046+ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
41047+ return -EPERM;
41048+ }
41049+#endif
41050+ return 0;
41051+}
41052+
41053+int
41054+gr_handle_chroot_mount(const struct dentry *dentry,
41055+ const struct vfsmount *mnt, const char *dev_name)
41056+{
41057+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
41058+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
41059+ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
41060+ return -EPERM;
41061+ }
41062+#endif
41063+ return 0;
41064+}
41065+
41066+int
41067+gr_handle_chroot_pivot(void)
41068+{
41069+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
41070+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
41071+ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
41072+ return -EPERM;
41073+ }
41074+#endif
41075+ return 0;
41076+}
41077+
41078+int
41079+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
41080+{
41081+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
41082+ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
41083+ !gr_is_outside_chroot(dentry, mnt)) {
41084+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
41085+ return -EPERM;
41086+ }
41087+#endif
41088+ return 0;
41089+}
41090+
41091+int
41092+gr_handle_chroot_caps(struct path *path)
41093+{
41094+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
41095+ if (grsec_enable_chroot_caps && current->pid > 1 && current->fs != NULL &&
41096+ (init_task.fs->root.dentry != path->dentry) &&
41097+ (current->nsproxy->mnt_ns->root->mnt_root != path->dentry)) {
41098+
41099+ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
41100+ const struct cred *old = current_cred();
41101+ struct cred *new = prepare_creds();
41102+ if (new == NULL)
41103+ return 1;
41104+
41105+ new->cap_permitted = cap_drop(old->cap_permitted,
41106+ chroot_caps);
41107+ new->cap_inheritable = cap_drop(old->cap_inheritable,
41108+ chroot_caps);
41109+ new->cap_effective = cap_drop(old->cap_effective,
41110+ chroot_caps);
41111+
41112+ commit_creds(new);
41113+
41114+ return 0;
41115+ }
41116+#endif
41117+ return 0;
41118+}
41119+
41120+int
41121+gr_handle_chroot_sysctl(const int op)
41122+{
41123+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
ae4e228f
MT
41124+ if (grsec_enable_chroot_sysctl && (op & MAY_WRITE) &&
41125+ proc_is_chrooted(current))
58c5fc13
MT
41126+ return -EACCES;
41127+#endif
41128+ return 0;
41129+}
41130+
41131+void
41132+gr_handle_chroot_chdir(struct path *path)
41133+{
41134+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
41135+ if (grsec_enable_chroot_chdir)
41136+ set_fs_pwd(current->fs, path);
41137+#endif
41138+ return;
41139+}
41140+
41141+int
41142+gr_handle_chroot_chmod(const struct dentry *dentry,
41143+ const struct vfsmount *mnt, const int mode)
41144+{
41145+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
bc901d79
MT
41146+ /* allow chmod +s on directories, but not files */
41147+ if (grsec_enable_chroot_chmod && !S_ISDIR(dentry->d_inode->i_mode) &&
58c5fc13
MT
41148+ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
41149+ proc_is_chrooted(current)) {
41150+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
41151+ return -EPERM;
41152+ }
41153+#endif
41154+ return 0;
41155+}
41156+
41157+#ifdef CONFIG_SECURITY
41158+EXPORT_SYMBOL(gr_handle_chroot_caps);
41159+#endif
16454cff
MT
41160diff -urNp linux-2.6.38.1/grsecurity/grsec_disabled.c linux-2.6.38.1/grsecurity/grsec_disabled.c
41161--- linux-2.6.38.1/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
41162+++ linux-2.6.38.1/grsecurity/grsec_disabled.c 2011-03-25 18:57:41.000000000 -0400
41163@@ -0,0 +1,447 @@
58c5fc13
MT
41164+#include <linux/kernel.h>
41165+#include <linux/module.h>
41166+#include <linux/sched.h>
41167+#include <linux/file.h>
41168+#include <linux/fs.h>
41169+#include <linux/kdev_t.h>
41170+#include <linux/net.h>
41171+#include <linux/in.h>
41172+#include <linux/ip.h>
41173+#include <linux/skbuff.h>
41174+#include <linux/sysctl.h>
41175+
41176+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
41177+void
41178+pax_set_initial_flags(struct linux_binprm *bprm)
41179+{
41180+ return;
41181+}
41182+#endif
41183+
41184+#ifdef CONFIG_SYSCTL
41185+__u32
41186+gr_handle_sysctl(const struct ctl_table * table, const int op)
41187+{
41188+ return 0;
41189+}
41190+#endif
41191+
41192+#ifdef CONFIG_TASKSTATS
41193+int gr_is_taskstats_denied(int pid)
41194+{
41195+ return 0;
41196+}
41197+#endif
41198+
41199+int
41200+gr_acl_is_enabled(void)
41201+{
41202+ return 0;
41203+}
41204+
41205+int
41206+gr_handle_rawio(const struct inode *inode)
41207+{
41208+ return 0;
41209+}
41210+
41211+void
41212+gr_acl_handle_psacct(struct task_struct *task, const long code)
41213+{
41214+ return;
41215+}
41216+
41217+int
41218+gr_handle_ptrace(struct task_struct *task, const long request)
41219+{
41220+ return 0;
41221+}
41222+
41223+int
41224+gr_handle_proc_ptrace(struct task_struct *task)
41225+{
41226+ return 0;
41227+}
41228+
41229+void
41230+gr_learn_resource(const struct task_struct *task,
41231+ const int res, const unsigned long wanted, const int gt)
41232+{
41233+ return;
41234+}
41235+
41236+int
41237+gr_set_acls(const int type)
41238+{
41239+ return 0;
41240+}
41241+
41242+int
41243+gr_check_hidden_task(const struct task_struct *tsk)
41244+{
41245+ return 0;
41246+}
41247+
41248+int
41249+gr_check_protected_task(const struct task_struct *task)
41250+{
41251+ return 0;
41252+}
41253+
57199397
MT
41254+int
41255+gr_check_protected_task_fowner(struct pid *pid, enum pid_type type)
41256+{
41257+ return 0;
41258+}
41259+
58c5fc13
MT
41260+void
41261+gr_copy_label(struct task_struct *tsk)
41262+{
41263+ return;
41264+}
41265+
41266+void
41267+gr_set_pax_flags(struct task_struct *task)
41268+{
41269+ return;
41270+}
41271+
41272+int
41273+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
41274+ const int unsafe_share)
41275+{
41276+ return 0;
41277+}
41278+
41279+void
41280+gr_handle_delete(const ino_t ino, const dev_t dev)
41281+{
41282+ return;
41283+}
41284+
41285+void
41286+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
41287+{
41288+ return;
41289+}
41290+
41291+void
41292+gr_handle_crash(struct task_struct *task, const int sig)
41293+{
41294+ return;
41295+}
41296+
41297+int
41298+gr_check_crash_exec(const struct file *filp)
41299+{
41300+ return 0;
41301+}
41302+
41303+int
41304+gr_check_crash_uid(const uid_t uid)
41305+{
41306+ return 0;
41307+}
41308+
41309+void
41310+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
41311+ struct dentry *old_dentry,
41312+ struct dentry *new_dentry,
41313+ struct vfsmount *mnt, const __u8 replace)
41314+{
41315+ return;
41316+}
41317+
41318+int
41319+gr_search_socket(const int family, const int type, const int protocol)
41320+{
41321+ return 1;
41322+}
41323+
41324+int
41325+gr_search_connectbind(const int mode, const struct socket *sock,
41326+ const struct sockaddr_in *addr)
41327+{
41328+ return 0;
41329+}
41330+
41331+int
41332+gr_is_capable(const int cap)
41333+{
41334+ return 1;
41335+}
41336+
41337+int
41338+gr_is_capable_nolog(const int cap)
41339+{
41340+ return 1;
41341+}
41342+
41343+void
41344+gr_handle_alertkill(struct task_struct *task)
41345+{
41346+ return;
41347+}
41348+
41349+__u32
41350+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
41351+{
41352+ return 1;
41353+}
41354+
41355+__u32
41356+gr_acl_handle_hidden_file(const struct dentry * dentry,
41357+ const struct vfsmount * mnt)
41358+{
41359+ return 1;
41360+}
41361+
41362+__u32
41363+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
41364+ const int fmode)
41365+{
41366+ return 1;
41367+}
41368+
41369+__u32
41370+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
41371+{
41372+ return 1;
41373+}
41374+
41375+__u32
41376+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
41377+{
41378+ return 1;
41379+}
41380+
41381+int
41382+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
41383+ unsigned int *vm_flags)
41384+{
41385+ return 1;
41386+}
41387+
41388+__u32
41389+gr_acl_handle_truncate(const struct dentry * dentry,
41390+ const struct vfsmount * mnt)
41391+{
41392+ return 1;
41393+}
41394+
41395+__u32
41396+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
41397+{
41398+ return 1;
41399+}
41400+
41401+__u32
41402+gr_acl_handle_access(const struct dentry * dentry,
41403+ const struct vfsmount * mnt, const int fmode)
41404+{
41405+ return 1;
41406+}
41407+
41408+__u32
41409+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
41410+ mode_t mode)
41411+{
41412+ return 1;
41413+}
41414+
41415+__u32
41416+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
41417+ mode_t mode)
41418+{
41419+ return 1;
41420+}
41421+
41422+__u32
41423+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
41424+{
41425+ return 1;
41426+}
41427+
bc901d79
MT
41428+__u32
41429+gr_acl_handle_setxattr(const struct dentry * dentry, const struct vfsmount * mnt)
41430+{
41431+ return 1;
41432+}
41433+
58c5fc13
MT
41434+void
41435+grsecurity_init(void)
41436+{
41437+ return;
41438+}
41439+
41440+__u32
41441+gr_acl_handle_mknod(const struct dentry * new_dentry,
41442+ const struct dentry * parent_dentry,
41443+ const struct vfsmount * parent_mnt,
41444+ const int mode)
41445+{
41446+ return 1;
41447+}
41448+
41449+__u32
41450+gr_acl_handle_mkdir(const struct dentry * new_dentry,
41451+ const struct dentry * parent_dentry,
41452+ const struct vfsmount * parent_mnt)
41453+{
41454+ return 1;
41455+}
41456+
41457+__u32
41458+gr_acl_handle_symlink(const struct dentry * new_dentry,
41459+ const struct dentry * parent_dentry,
41460+ const struct vfsmount * parent_mnt, const char *from)
41461+{
41462+ return 1;
41463+}
41464+
41465+__u32
41466+gr_acl_handle_link(const struct dentry * new_dentry,
41467+ const struct dentry * parent_dentry,
41468+ const struct vfsmount * parent_mnt,
41469+ const struct dentry * old_dentry,
41470+ const struct vfsmount * old_mnt, const char *to)
41471+{
41472+ return 1;
41473+}
41474+
41475+int
41476+gr_acl_handle_rename(const struct dentry *new_dentry,
41477+ const struct dentry *parent_dentry,
41478+ const struct vfsmount *parent_mnt,
41479+ const struct dentry *old_dentry,
41480+ const struct inode *old_parent_inode,
41481+ const struct vfsmount *old_mnt, const char *newname)
41482+{
41483+ return 0;
41484+}
41485+
41486+int
41487+gr_acl_handle_filldir(const struct file *file, const char *name,
41488+ const int namelen, const ino_t ino)
41489+{
41490+ return 1;
41491+}
41492+
41493+int
41494+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
41495+ const time_t shm_createtime, const uid_t cuid, const int shmid)
41496+{
41497+ return 1;
41498+}
41499+
41500+int
41501+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
41502+{
41503+ return 0;
41504+}
41505+
41506+int
41507+gr_search_accept(const struct socket *sock)
41508+{
41509+ return 0;
41510+}
41511+
41512+int
41513+gr_search_listen(const struct socket *sock)
41514+{
41515+ return 0;
41516+}
41517+
41518+int
41519+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
41520+{
41521+ return 0;
41522+}
41523+
41524+__u32
41525+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
41526+{
41527+ return 1;
41528+}
41529+
41530+__u32
41531+gr_acl_handle_creat(const struct dentry * dentry,
41532+ const struct dentry * p_dentry,
41533+ const struct vfsmount * p_mnt, const int fmode,
41534+ const int imode)
41535+{
41536+ return 1;
41537+}
41538+
41539+void
41540+gr_acl_handle_exit(void)
41541+{
41542+ return;
41543+}
41544+
41545+int
41546+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
41547+{
41548+ return 1;
41549+}
41550+
41551+void
41552+gr_set_role_label(const uid_t uid, const gid_t gid)
41553+{
41554+ return;
41555+}
41556+
41557+int
41558+gr_acl_handle_procpidmem(const struct task_struct *task)
41559+{
41560+ return 0;
41561+}
41562+
41563+int
41564+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
41565+{
41566+ return 0;
41567+}
41568+
41569+int
41570+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
41571+{
41572+ return 0;
41573+}
41574+
41575+void
41576+gr_set_kernel_label(struct task_struct *task)
41577+{
41578+ return;
41579+}
41580+
41581+int
41582+gr_check_user_change(int real, int effective, int fs)
41583+{
41584+ return 0;
41585+}
41586+
41587+int
41588+gr_check_group_change(int real, int effective, int fs)
41589+{
41590+ return 0;
41591+}
41592+
bc901d79
MT
41593+int gr_acl_enable_at_secure(void)
41594+{
41595+ return 0;
41596+}
41597+
16454cff
MT
41598+dev_t gr_get_dev_from_dentry(struct dentry *dentry)
41599+{
41600+ return dentry->d_inode->i_sb->s_dev;
41601+}
41602+
58c5fc13
MT
41603+EXPORT_SYMBOL(gr_is_capable);
41604+EXPORT_SYMBOL(gr_is_capable_nolog);
41605+EXPORT_SYMBOL(gr_learn_resource);
41606+EXPORT_SYMBOL(gr_set_kernel_label);
41607+#ifdef CONFIG_SECURITY
41608+EXPORT_SYMBOL(gr_check_user_change);
41609+EXPORT_SYMBOL(gr_check_group_change);
41610+#endif
16454cff
MT
41611diff -urNp linux-2.6.38.1/grsecurity/grsec_exec.c linux-2.6.38.1/grsecurity/grsec_exec.c
41612--- linux-2.6.38.1/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
41613+++ linux-2.6.38.1/grsecurity/grsec_exec.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 41614@@ -0,0 +1,147 @@
58c5fc13
MT
41615+#include <linux/kernel.h>
41616+#include <linux/sched.h>
41617+#include <linux/file.h>
41618+#include <linux/binfmts.h>
41619+#include <linux/smp_lock.h>
41620+#include <linux/fs.h>
41621+#include <linux/types.h>
41622+#include <linux/grdefs.h>
41623+#include <linux/grinternal.h>
41624+#include <linux/capability.h>
bc901d79 41625+#include <linux/compat.h>
58c5fc13
MT
41626+
41627+#include <asm/uaccess.h>
41628+
41629+#ifdef CONFIG_GRKERNSEC_EXECLOG
41630+static char gr_exec_arg_buf[132];
bc901d79 41631+static DEFINE_MUTEX(gr_exec_arg_mutex);
58c5fc13
MT
41632+#endif
41633+
41634+int
41635+gr_handle_nproc(void)
41636+{
41637+#ifdef CONFIG_GRKERNSEC_EXECVE
41638+ const struct cred *cred = current_cred();
41639+ if (grsec_enable_execve && cred->user &&
df50ba0c 41640+ (atomic_read(&cred->user->processes) > rlimit(RLIMIT_NPROC)) &&
58c5fc13
MT
41641+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
41642+ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
41643+ return -EAGAIN;
41644+ }
41645+#endif
41646+ return 0;
41647+}
41648+
41649+void
6892158b 41650+gr_handle_exec_args(struct linux_binprm *bprm, const char __user *const __user *argv)
58c5fc13
MT
41651+{
41652+#ifdef CONFIG_GRKERNSEC_EXECLOG
41653+ char *grarg = gr_exec_arg_buf;
41654+ unsigned int i, x, execlen = 0;
41655+ char c;
41656+
41657+ if (!((grsec_enable_execlog && grsec_enable_group &&
41658+ in_group_p(grsec_audit_gid))
41659+ || (grsec_enable_execlog && !grsec_enable_group)))
41660+ return;
41661+
bc901d79 41662+ mutex_lock(&gr_exec_arg_mutex);
58c5fc13
MT
41663+ memset(grarg, 0, sizeof(gr_exec_arg_buf));
41664+
41665+ if (unlikely(argv == NULL))
41666+ goto log;
41667+
41668+ for (i = 0; i < bprm->argc && execlen < 128; i++) {
41669+ const char __user *p;
41670+ unsigned int len;
41671+
41672+ if (copy_from_user(&p, argv + i, sizeof(p)))
41673+ goto log;
41674+ if (!p)
41675+ goto log;
41676+ len = strnlen_user(p, 128 - execlen);
41677+ if (len > 128 - execlen)
41678+ len = 128 - execlen;
41679+ else if (len > 0)
41680+ len--;
41681+ if (copy_from_user(grarg + execlen, p, len))
41682+ goto log;
41683+
41684+ /* rewrite unprintable characters */
41685+ for (x = 0; x < len; x++) {
41686+ c = *(grarg + execlen + x);
41687+ if (c < 32 || c > 126)
41688+ *(grarg + execlen + x) = ' ';
41689+ }
41690+
41691+ execlen += len;
41692+ *(grarg + execlen) = ' ';
41693+ *(grarg + execlen + 1) = '\0';
41694+ execlen++;
41695+ }
41696+
41697+ log:
41698+ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
41699+ bprm->file->f_path.mnt, grarg);
bc901d79 41700+ mutex_unlock(&gr_exec_arg_mutex);
58c5fc13
MT
41701+#endif
41702+ return;
41703+}
bc901d79
MT
41704+
41705+#ifdef CONFIG_COMPAT
41706+void
41707+gr_handle_exec_args_compat(struct linux_binprm *bprm, compat_uptr_t __user *argv)
41708+{
41709+#ifdef CONFIG_GRKERNSEC_EXECLOG
41710+ char *grarg = gr_exec_arg_buf;
41711+ unsigned int i, x, execlen = 0;
41712+ char c;
41713+
41714+ if (!((grsec_enable_execlog && grsec_enable_group &&
41715+ in_group_p(grsec_audit_gid))
41716+ || (grsec_enable_execlog && !grsec_enable_group)))
41717+ return;
41718+
41719+ mutex_lock(&gr_exec_arg_mutex);
41720+ memset(grarg, 0, sizeof(gr_exec_arg_buf));
41721+
41722+ if (unlikely(argv == NULL))
41723+ goto log;
41724+
41725+ for (i = 0; i < bprm->argc && execlen < 128; i++) {
41726+ compat_uptr_t p;
41727+ unsigned int len;
41728+
41729+ if (get_user(p, argv + i))
41730+ goto log;
41731+ len = strnlen_user(compat_ptr(p), 128 - execlen);
41732+ if (len > 128 - execlen)
41733+ len = 128 - execlen;
41734+ else if (len > 0)
41735+ len--;
41736+ else
41737+ goto log;
41738+ if (copy_from_user(grarg + execlen, compat_ptr(p), len))
41739+ goto log;
41740+
41741+ /* rewrite unprintable characters */
41742+ for (x = 0; x < len; x++) {
41743+ c = *(grarg + execlen + x);
41744+ if (c < 32 || c > 126)
41745+ *(grarg + execlen + x) = ' ';
41746+ }
41747+
41748+ execlen += len;
41749+ *(grarg + execlen) = ' ';
41750+ *(grarg + execlen + 1) = '\0';
41751+ execlen++;
41752+ }
41753+
41754+ log:
41755+ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
41756+ bprm->file->f_path.mnt, grarg);
41757+ mutex_unlock(&gr_exec_arg_mutex);
41758+#endif
41759+ return;
41760+}
41761+#endif
16454cff
MT
41762diff -urNp linux-2.6.38.1/grsecurity/grsec_fifo.c linux-2.6.38.1/grsecurity/grsec_fifo.c
41763--- linux-2.6.38.1/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
41764+++ linux-2.6.38.1/grsecurity/grsec_fifo.c 2011-03-21 20:33:29.000000000 -0400
58c5fc13
MT
41765@@ -0,0 +1,24 @@
41766+#include <linux/kernel.h>
41767+#include <linux/sched.h>
41768+#include <linux/fs.h>
41769+#include <linux/file.h>
41770+#include <linux/grinternal.h>
41771+
41772+int
41773+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
41774+ const struct dentry *dir, const int flag, const int acc_mode)
41775+{
41776+#ifdef CONFIG_GRKERNSEC_FIFO
41777+ const struct cred *cred = current_cred();
41778+
41779+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
41780+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
41781+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
41782+ (cred->fsuid != dentry->d_inode->i_uid)) {
16454cff 41783+ if (!inode_permission(dentry->d_inode, acc_mode))
58c5fc13
MT
41784+ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
41785+ return -EACCES;
41786+ }
41787+#endif
41788+ return 0;
41789+}
16454cff
MT
41790diff -urNp linux-2.6.38.1/grsecurity/grsec_fork.c linux-2.6.38.1/grsecurity/grsec_fork.c
41791--- linux-2.6.38.1/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
41792+++ linux-2.6.38.1/grsecurity/grsec_fork.c 2011-03-21 18:31:35.000000000 -0400
6892158b 41793@@ -0,0 +1,23 @@
58c5fc13
MT
41794+#include <linux/kernel.h>
41795+#include <linux/sched.h>
41796+#include <linux/grsecurity.h>
41797+#include <linux/grinternal.h>
41798+#include <linux/errno.h>
41799+
41800+void
41801+gr_log_forkfail(const int retval)
41802+{
41803+#ifdef CONFIG_GRKERNSEC_FORKFAIL
6892158b
MT
41804+ if (grsec_enable_forkfail && (retval == -EAGAIN || retval == -ENOMEM)) {
41805+ switch (retval) {
41806+ case -EAGAIN:
41807+ gr_log_str(GR_DONT_AUDIT, GR_FAILFORK_MSG, "EAGAIN");
41808+ break;
41809+ case -ENOMEM:
41810+ gr_log_str(GR_DONT_AUDIT, GR_FAILFORK_MSG, "ENOMEM");
41811+ break;
41812+ }
41813+ }
58c5fc13
MT
41814+#endif
41815+ return;
41816+}
16454cff
MT
41817diff -urNp linux-2.6.38.1/grsecurity/grsec_init.c linux-2.6.38.1/grsecurity/grsec_init.c
41818--- linux-2.6.38.1/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
41819+++ linux-2.6.38.1/grsecurity/grsec_init.c 2011-03-21 18:31:35.000000000 -0400
6892158b 41820@@ -0,0 +1,270 @@
58c5fc13
MT
41821+#include <linux/kernel.h>
41822+#include <linux/sched.h>
41823+#include <linux/mm.h>
41824+#include <linux/smp_lock.h>
41825+#include <linux/gracl.h>
41826+#include <linux/slab.h>
41827+#include <linux/vmalloc.h>
41828+#include <linux/percpu.h>
df50ba0c 41829+#include <linux/module.h>
58c5fc13
MT
41830+
41831+int grsec_enable_link;
41832+int grsec_enable_dmesg;
41833+int grsec_enable_harden_ptrace;
41834+int grsec_enable_fifo;
41835+int grsec_enable_execve;
41836+int grsec_enable_execlog;
41837+int grsec_enable_signal;
41838+int grsec_enable_forkfail;
ae4e228f 41839+int grsec_enable_audit_ptrace;
58c5fc13
MT
41840+int grsec_enable_time;
41841+int grsec_enable_audit_textrel;
41842+int grsec_enable_group;
41843+int grsec_audit_gid;
41844+int grsec_enable_chdir;
41845+int grsec_enable_mount;
ae4e228f 41846+int grsec_enable_rofs;
58c5fc13
MT
41847+int grsec_enable_chroot_findtask;
41848+int grsec_enable_chroot_mount;
41849+int grsec_enable_chroot_shmat;
41850+int grsec_enable_chroot_fchdir;
41851+int grsec_enable_chroot_double;
41852+int grsec_enable_chroot_pivot;
41853+int grsec_enable_chroot_chdir;
41854+int grsec_enable_chroot_chmod;
41855+int grsec_enable_chroot_mknod;
41856+int grsec_enable_chroot_nice;
41857+int grsec_enable_chroot_execlog;
41858+int grsec_enable_chroot_caps;
41859+int grsec_enable_chroot_sysctl;
41860+int grsec_enable_chroot_unix;
41861+int grsec_enable_tpe;
41862+int grsec_tpe_gid;
ae4e228f 41863+int grsec_enable_blackhole;
df50ba0c
MT
41864+#ifdef CONFIG_IPV6_MODULE
41865+EXPORT_SYMBOL(grsec_enable_blackhole);
41866+#endif
ae4e228f 41867+int grsec_lastack_retries;
58c5fc13 41868+int grsec_enable_tpe_all;
57199397 41869+int grsec_enable_tpe_invert;
58c5fc13
MT
41870+int grsec_enable_socket_all;
41871+int grsec_socket_all_gid;
41872+int grsec_enable_socket_client;
41873+int grsec_socket_client_gid;
41874+int grsec_enable_socket_server;
41875+int grsec_socket_server_gid;
41876+int grsec_resource_logging;
df50ba0c 41877+int grsec_disable_privio;
6892158b 41878+int grsec_enable_log_rwxmaps;
58c5fc13
MT
41879+int grsec_lock;
41880+
41881+DEFINE_SPINLOCK(grsec_alert_lock);
41882+unsigned long grsec_alert_wtime = 0;
41883+unsigned long grsec_alert_fyet = 0;
41884+
41885+DEFINE_SPINLOCK(grsec_audit_lock);
41886+
41887+DEFINE_RWLOCK(grsec_exec_file_lock);
41888+
41889+char *gr_shared_page[4];
41890+
41891+char *gr_alert_log_fmt;
41892+char *gr_audit_log_fmt;
41893+char *gr_alert_log_buf;
41894+char *gr_audit_log_buf;
41895+
41896+extern struct gr_arg *gr_usermode;
41897+extern unsigned char *gr_system_salt;
41898+extern unsigned char *gr_system_sum;
41899+
41900+void __init
41901+grsecurity_init(void)
41902+{
41903+ int j;
41904+ /* create the per-cpu shared pages */
41905+
41906+#ifdef CONFIG_X86
41907+ memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
41908+#endif
41909+
41910+ for (j = 0; j < 4; j++) {
41911+ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(unsigned long long));
41912+ if (gr_shared_page[j] == NULL) {
41913+ panic("Unable to allocate grsecurity shared page");
41914+ return;
41915+ }
41916+ }
41917+
41918+ /* allocate log buffers */
41919+ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
41920+ if (!gr_alert_log_fmt) {
41921+ panic("Unable to allocate grsecurity alert log format buffer");
41922+ return;
41923+ }
41924+ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
41925+ if (!gr_audit_log_fmt) {
41926+ panic("Unable to allocate grsecurity audit log format buffer");
41927+ return;
41928+ }
41929+ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
41930+ if (!gr_alert_log_buf) {
41931+ panic("Unable to allocate grsecurity alert log buffer");
41932+ return;
41933+ }
41934+ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
41935+ if (!gr_audit_log_buf) {
41936+ panic("Unable to allocate grsecurity audit log buffer");
41937+ return;
41938+ }
41939+
41940+ /* allocate memory for authentication structure */
41941+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
41942+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
41943+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
41944+
41945+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
41946+ panic("Unable to allocate grsecurity authentication structure");
41947+ return;
41948+ }
41949+
df50ba0c
MT
41950+
41951+#ifdef CONFIG_GRKERNSEC_IO
41952+#if !defined(CONFIG_GRKERNSEC_SYSCTL_DISTRO)
41953+ grsec_disable_privio = 1;
41954+#elif defined(CONFIG_GRKERNSEC_SYSCTL_ON)
41955+ grsec_disable_privio = 1;
41956+#else
41957+ grsec_disable_privio = 0;
41958+#endif
41959+#endif
41960+
57199397
MT
41961+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
41962+ /* for backward compatibility, tpe_invert always defaults to on if
41963+ enabled in the kernel
41964+ */
41965+ grsec_enable_tpe_invert = 1;
41966+#endif
41967+
58c5fc13
MT
41968+#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
41969+#ifndef CONFIG_GRKERNSEC_SYSCTL
41970+ grsec_lock = 1;
41971+#endif
df50ba0c 41972+
58c5fc13
MT
41973+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
41974+ grsec_enable_audit_textrel = 1;
41975+#endif
6892158b
MT
41976+#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
41977+ grsec_enable_log_rwxmaps = 1;
41978+#endif
58c5fc13
MT
41979+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
41980+ grsec_enable_group = 1;
41981+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
41982+#endif
41983+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
41984+ grsec_enable_chdir = 1;
41985+#endif
41986+#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
41987+ grsec_enable_harden_ptrace = 1;
41988+#endif
41989+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
41990+ grsec_enable_mount = 1;
41991+#endif
41992+#ifdef CONFIG_GRKERNSEC_LINK
41993+ grsec_enable_link = 1;
41994+#endif
41995+#ifdef CONFIG_GRKERNSEC_DMESG
41996+ grsec_enable_dmesg = 1;
41997+#endif
ae4e228f
MT
41998+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
41999+ grsec_enable_blackhole = 1;
42000+ grsec_lastack_retries = 4;
42001+#endif
58c5fc13
MT
42002+#ifdef CONFIG_GRKERNSEC_FIFO
42003+ grsec_enable_fifo = 1;
42004+#endif
42005+#ifdef CONFIG_GRKERNSEC_EXECVE
42006+ grsec_enable_execve = 1;
42007+#endif
42008+#ifdef CONFIG_GRKERNSEC_EXECLOG
42009+ grsec_enable_execlog = 1;
42010+#endif
42011+#ifdef CONFIG_GRKERNSEC_SIGNAL
42012+ grsec_enable_signal = 1;
42013+#endif
42014+#ifdef CONFIG_GRKERNSEC_FORKFAIL
42015+ grsec_enable_forkfail = 1;
42016+#endif
42017+#ifdef CONFIG_GRKERNSEC_TIME
42018+ grsec_enable_time = 1;
42019+#endif
42020+#ifdef CONFIG_GRKERNSEC_RESLOG
42021+ grsec_resource_logging = 1;
42022+#endif
42023+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
42024+ grsec_enable_chroot_findtask = 1;
42025+#endif
42026+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
42027+ grsec_enable_chroot_unix = 1;
42028+#endif
42029+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
42030+ grsec_enable_chroot_mount = 1;
42031+#endif
42032+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
42033+ grsec_enable_chroot_fchdir = 1;
42034+#endif
42035+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
42036+ grsec_enable_chroot_shmat = 1;
42037+#endif
ae4e228f
MT
42038+#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
42039+ grsec_enable_audit_ptrace = 1;
42040+#endif
58c5fc13
MT
42041+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
42042+ grsec_enable_chroot_double = 1;
42043+#endif
42044+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
42045+ grsec_enable_chroot_pivot = 1;
42046+#endif
42047+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
42048+ grsec_enable_chroot_chdir = 1;
42049+#endif
42050+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
42051+ grsec_enable_chroot_chmod = 1;
42052+#endif
42053+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
42054+ grsec_enable_chroot_mknod = 1;
42055+#endif
42056+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
42057+ grsec_enable_chroot_nice = 1;
42058+#endif
42059+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
42060+ grsec_enable_chroot_execlog = 1;
42061+#endif
42062+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
42063+ grsec_enable_chroot_caps = 1;
42064+#endif
42065+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
42066+ grsec_enable_chroot_sysctl = 1;
42067+#endif
42068+#ifdef CONFIG_GRKERNSEC_TPE
42069+ grsec_enable_tpe = 1;
42070+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
42071+#ifdef CONFIG_GRKERNSEC_TPE_ALL
42072+ grsec_enable_tpe_all = 1;
42073+#endif
42074+#endif
42075+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
42076+ grsec_enable_socket_all = 1;
42077+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
42078+#endif
42079+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
42080+ grsec_enable_socket_client = 1;
42081+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
42082+#endif
42083+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
42084+ grsec_enable_socket_server = 1;
42085+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
42086+#endif
42087+#endif
42088+
42089+ return;
42090+}
16454cff
MT
42091diff -urNp linux-2.6.38.1/grsecurity/grsec_link.c linux-2.6.38.1/grsecurity/grsec_link.c
42092--- linux-2.6.38.1/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
42093+++ linux-2.6.38.1/grsecurity/grsec_link.c 2011-03-21 20:34:41.000000000 -0400
58c5fc13
MT
42094@@ -0,0 +1,43 @@
42095+#include <linux/kernel.h>
42096+#include <linux/sched.h>
42097+#include <linux/fs.h>
42098+#include <linux/file.h>
42099+#include <linux/grinternal.h>
42100+
42101+int
42102+gr_handle_follow_link(const struct inode *parent,
42103+ const struct inode *inode,
42104+ const struct dentry *dentry, const struct vfsmount *mnt)
42105+{
42106+#ifdef CONFIG_GRKERNSEC_LINK
42107+ const struct cred *cred = current_cred();
42108+
42109+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
42110+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
42111+ (parent->i_mode & S_IWOTH) && (cred->fsuid != inode->i_uid)) {
42112+ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
42113+ return -EACCES;
42114+ }
42115+#endif
42116+ return 0;
42117+}
42118+
42119+int
42120+gr_handle_hardlink(const struct dentry *dentry,
42121+ const struct vfsmount *mnt,
42122+ struct inode *inode, const int mode, const char *to)
42123+{
42124+#ifdef CONFIG_GRKERNSEC_LINK
42125+ const struct cred *cred = current_cred();
42126+
42127+ if (grsec_enable_link && cred->fsuid != inode->i_uid &&
42128+ (!S_ISREG(mode) || (mode & S_ISUID) ||
42129+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
16454cff 42130+ (inode_permission(inode, MAY_READ | MAY_WRITE))) &&
58c5fc13
MT
42131+ !capable(CAP_FOWNER) && cred->uid) {
42132+ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
42133+ return -EPERM;
42134+ }
42135+#endif
42136+ return 0;
42137+}
16454cff
MT
42138diff -urNp linux-2.6.38.1/grsecurity/grsec_log.c linux-2.6.38.1/grsecurity/grsec_log.c
42139--- linux-2.6.38.1/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
42140+++ linux-2.6.38.1/grsecurity/grsec_log.c 2011-03-21 18:31:35.000000000 -0400
6892158b 42141@@ -0,0 +1,310 @@
58c5fc13
MT
42142+#include <linux/kernel.h>
42143+#include <linux/sched.h>
42144+#include <linux/file.h>
42145+#include <linux/tty.h>
42146+#include <linux/fs.h>
42147+#include <linux/grinternal.h>
42148+
df50ba0c
MT
42149+#ifdef CONFIG_TREE_PREEMPT_RCU
42150+#define DISABLE_PREEMPT() preempt_disable()
42151+#define ENABLE_PREEMPT() preempt_enable()
42152+#else
42153+#define DISABLE_PREEMPT()
42154+#define ENABLE_PREEMPT()
42155+#endif
42156+
58c5fc13 42157+#define BEGIN_LOCKS(x) \
df50ba0c 42158+ DISABLE_PREEMPT(); \
ae4e228f 42159+ rcu_read_lock(); \
58c5fc13
MT
42160+ read_lock(&tasklist_lock); \
42161+ read_lock(&grsec_exec_file_lock); \
42162+ if (x != GR_DO_AUDIT) \
42163+ spin_lock(&grsec_alert_lock); \
42164+ else \
42165+ spin_lock(&grsec_audit_lock)
42166+
42167+#define END_LOCKS(x) \
42168+ if (x != GR_DO_AUDIT) \
42169+ spin_unlock(&grsec_alert_lock); \
42170+ else \
42171+ spin_unlock(&grsec_audit_lock); \
42172+ read_unlock(&grsec_exec_file_lock); \
42173+ read_unlock(&tasklist_lock); \
ae4e228f 42174+ rcu_read_unlock(); \
df50ba0c 42175+ ENABLE_PREEMPT(); \
58c5fc13
MT
42176+ if (x == GR_DONT_AUDIT) \
42177+ gr_handle_alertkill(current)
42178+
42179+enum {
42180+ FLOODING,
42181+ NO_FLOODING
42182+};
42183+
42184+extern char *gr_alert_log_fmt;
42185+extern char *gr_audit_log_fmt;
42186+extern char *gr_alert_log_buf;
42187+extern char *gr_audit_log_buf;
42188+
42189+static int gr_log_start(int audit)
42190+{
42191+ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
42192+ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
42193+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
42194+
42195+ if (audit == GR_DO_AUDIT)
42196+ goto set_fmt;
42197+
42198+ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
42199+ grsec_alert_wtime = jiffies;
42200+ grsec_alert_fyet = 0;
42201+ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
42202+ grsec_alert_fyet++;
42203+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
42204+ grsec_alert_wtime = jiffies;
42205+ grsec_alert_fyet++;
42206+ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
42207+ return FLOODING;
42208+ } else return FLOODING;
42209+
42210+set_fmt:
42211+ memset(buf, 0, PAGE_SIZE);
42212+ if (current->signal->curr_ip && gr_acl_is_enabled()) {
ae4e228f
MT
42213+ sprintf(fmt, "%s%s", loglevel, "grsec: From %pI4: (%.64s:%c:%.950s) ");
42214+ snprintf(buf, PAGE_SIZE - 1, fmt, &current->signal->curr_ip, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
58c5fc13 42215+ } else if (current->signal->curr_ip) {
ae4e228f
MT
42216+ sprintf(fmt, "%s%s", loglevel, "grsec: From %pI4: ");
42217+ snprintf(buf, PAGE_SIZE - 1, fmt, &current->signal->curr_ip);
58c5fc13
MT
42218+ } else if (gr_acl_is_enabled()) {
42219+ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
42220+ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
42221+ } else {
42222+ sprintf(fmt, "%s%s", loglevel, "grsec: ");
42223+ strcpy(buf, fmt);
42224+ }
42225+
42226+ return NO_FLOODING;
42227+}
42228+
42229+static void gr_log_middle(int audit, const char *msg, va_list ap)
42230+ __attribute__ ((format (printf, 2, 0)));
42231+
42232+static void gr_log_middle(int audit, const char *msg, va_list ap)
42233+{
42234+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
42235+ unsigned int len = strlen(buf);
42236+
42237+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
42238+
42239+ return;
42240+}
42241+
42242+static void gr_log_middle_varargs(int audit, const char *msg, ...)
42243+ __attribute__ ((format (printf, 2, 3)));
42244+
42245+static void gr_log_middle_varargs(int audit, const char *msg, ...)
42246+{
42247+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
42248+ unsigned int len = strlen(buf);
42249+ va_list ap;
42250+
42251+ va_start(ap, msg);
42252+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
42253+ va_end(ap);
42254+
42255+ return;
42256+}
42257+
42258+static void gr_log_end(int audit)
42259+{
42260+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
42261+ unsigned int len = strlen(buf);
42262+
6892158b 42263+ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current, current_cred(), __task_cred(current->real_parent)));
58c5fc13
MT
42264+ printk("%s\n", buf);
42265+
42266+ return;
42267+}
42268+
42269+void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
42270+{
42271+ int logtype;
42272+ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
42273+ char *str1, *str2, *str3;
42274+ void *voidptr;
42275+ int num1, num2;
42276+ unsigned long ulong1, ulong2;
42277+ struct dentry *dentry;
42278+ struct vfsmount *mnt;
42279+ struct file *file;
42280+ struct task_struct *task;
42281+ const struct cred *cred, *pcred;
42282+ va_list ap;
42283+
42284+ BEGIN_LOCKS(audit);
42285+ logtype = gr_log_start(audit);
42286+ if (logtype == FLOODING) {
42287+ END_LOCKS(audit);
42288+ return;
42289+ }
42290+ va_start(ap, argtypes);
42291+ switch (argtypes) {
42292+ case GR_TTYSNIFF:
42293+ task = va_arg(ap, struct task_struct *);
6892158b 42294+ gr_log_middle_varargs(audit, msg, &task->signal->curr_ip, gr_task_fullpath0(task), task->comm, task->pid, gr_parent_task_fullpath0(task), task->real_parent->comm, task->real_parent->pid);
58c5fc13
MT
42295+ break;
42296+ case GR_SYSCTL_HIDDEN:
42297+ str1 = va_arg(ap, char *);
42298+ gr_log_middle_varargs(audit, msg, result, str1);
42299+ break;
42300+ case GR_RBAC:
42301+ dentry = va_arg(ap, struct dentry *);
42302+ mnt = va_arg(ap, struct vfsmount *);
42303+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
42304+ break;
42305+ case GR_RBAC_STR:
42306+ dentry = va_arg(ap, struct dentry *);
42307+ mnt = va_arg(ap, struct vfsmount *);
42308+ str1 = va_arg(ap, char *);
42309+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
42310+ break;
42311+ case GR_STR_RBAC:
42312+ str1 = va_arg(ap, char *);
42313+ dentry = va_arg(ap, struct dentry *);
42314+ mnt = va_arg(ap, struct vfsmount *);
42315+ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
42316+ break;
42317+ case GR_RBAC_MODE2:
42318+ dentry = va_arg(ap, struct dentry *);
42319+ mnt = va_arg(ap, struct vfsmount *);
42320+ str1 = va_arg(ap, char *);
42321+ str2 = va_arg(ap, char *);
42322+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
42323+ break;
42324+ case GR_RBAC_MODE3:
42325+ dentry = va_arg(ap, struct dentry *);
42326+ mnt = va_arg(ap, struct vfsmount *);
42327+ str1 = va_arg(ap, char *);
42328+ str2 = va_arg(ap, char *);
42329+ str3 = va_arg(ap, char *);
42330+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
42331+ break;
42332+ case GR_FILENAME:
42333+ dentry = va_arg(ap, struct dentry *);
42334+ mnt = va_arg(ap, struct vfsmount *);
42335+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
42336+ break;
42337+ case GR_STR_FILENAME:
42338+ str1 = va_arg(ap, char *);
42339+ dentry = va_arg(ap, struct dentry *);
42340+ mnt = va_arg(ap, struct vfsmount *);
42341+ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
42342+ break;
42343+ case GR_FILENAME_STR:
42344+ dentry = va_arg(ap, struct dentry *);
42345+ mnt = va_arg(ap, struct vfsmount *);
42346+ str1 = va_arg(ap, char *);
42347+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
42348+ break;
42349+ case GR_FILENAME_TWO_INT:
42350+ dentry = va_arg(ap, struct dentry *);
42351+ mnt = va_arg(ap, struct vfsmount *);
42352+ num1 = va_arg(ap, int);
42353+ num2 = va_arg(ap, int);
42354+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
42355+ break;
42356+ case GR_FILENAME_TWO_INT_STR:
42357+ dentry = va_arg(ap, struct dentry *);
42358+ mnt = va_arg(ap, struct vfsmount *);
42359+ num1 = va_arg(ap, int);
42360+ num2 = va_arg(ap, int);
42361+ str1 = va_arg(ap, char *);
42362+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
42363+ break;
42364+ case GR_TEXTREL:
42365+ file = va_arg(ap, struct file *);
42366+ ulong1 = va_arg(ap, unsigned long);
42367+ ulong2 = va_arg(ap, unsigned long);
42368+ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
42369+ break;
42370+ case GR_PTRACE:
42371+ task = va_arg(ap, struct task_struct *);
42372+ 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);
42373+ break;
42374+ case GR_RESOURCE:
42375+ task = va_arg(ap, struct task_struct *);
42376+ cred = __task_cred(task);
6892158b 42377+ pcred = __task_cred(task->real_parent);
58c5fc13
MT
42378+ ulong1 = va_arg(ap, unsigned long);
42379+ str1 = va_arg(ap, char *);
42380+ ulong2 = va_arg(ap, unsigned long);
6892158b 42381+ 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->real_parent->comm, task->real_parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
58c5fc13
MT
42382+ break;
42383+ case GR_CAP:
42384+ task = va_arg(ap, struct task_struct *);
42385+ cred = __task_cred(task);
6892158b 42386+ pcred = __task_cred(task->real_parent);
58c5fc13 42387+ str1 = va_arg(ap, char *);
6892158b 42388+ 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->real_parent->comm, task->real_parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
58c5fc13
MT
42389+ break;
42390+ case GR_SIG:
42391+ str1 = va_arg(ap, char *);
42392+ voidptr = va_arg(ap, void *);
42393+ gr_log_middle_varargs(audit, msg, str1, voidptr);
42394+ break;
42395+ case GR_SIG2:
42396+ task = va_arg(ap, struct task_struct *);
42397+ cred = __task_cred(task);
6892158b 42398+ pcred = __task_cred(task->real_parent);
58c5fc13 42399+ num1 = va_arg(ap, int);
6892158b 42400+ 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->real_parent->comm, task->real_parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
58c5fc13
MT
42401+ break;
42402+ case GR_CRASH1:
42403+ task = va_arg(ap, struct task_struct *);
42404+ cred = __task_cred(task);
6892158b 42405+ pcred = __task_cred(task->real_parent);
58c5fc13 42406+ ulong1 = va_arg(ap, unsigned long);
6892158b 42407+ 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->real_parent->comm, task->real_parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid, cred->uid, ulong1);
58c5fc13
MT
42408+ break;
42409+ case GR_CRASH2:
42410+ task = va_arg(ap, struct task_struct *);
42411+ cred = __task_cred(task);
6892158b 42412+ pcred = __task_cred(task->real_parent);
58c5fc13 42413+ ulong1 = va_arg(ap, unsigned long);
6892158b
MT
42414+ 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->real_parent->comm, task->real_parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid, ulong1);
42415+ break;
42416+ case GR_RWXMAP:
42417+ file = va_arg(ap, struct file *);
42418+ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>");
58c5fc13
MT
42419+ break;
42420+ case GR_PSACCT:
42421+ {
42422+ unsigned int wday, cday;
42423+ __u8 whr, chr;
42424+ __u8 wmin, cmin;
42425+ __u8 wsec, csec;
42426+ char cur_tty[64] = { 0 };
42427+ char parent_tty[64] = { 0 };
42428+
42429+ task = va_arg(ap, struct task_struct *);
42430+ wday = va_arg(ap, unsigned int);
42431+ cday = va_arg(ap, unsigned int);
42432+ whr = va_arg(ap, int);
42433+ chr = va_arg(ap, int);
42434+ wmin = va_arg(ap, int);
42435+ cmin = va_arg(ap, int);
42436+ wsec = va_arg(ap, int);
42437+ csec = va_arg(ap, int);
42438+ ulong1 = va_arg(ap, unsigned long);
42439+ cred = __task_cred(task);
6892158b 42440+ pcred = __task_cred(task->real_parent);
58c5fc13 42441+
6892158b 42442+ gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, &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->real_parent->comm, task->real_parent->pid, &task->real_parent->signal->curr_ip, tty_name(task->real_parent->signal->tty, parent_tty), pcred->uid, pcred->euid, pcred->gid, pcred->egid);
58c5fc13
MT
42443+ }
42444+ break;
42445+ default:
42446+ gr_log_middle(audit, msg, ap);
42447+ }
42448+ va_end(ap);
42449+ gr_log_end(audit);
42450+ END_LOCKS(audit);
42451+}
16454cff
MT
42452diff -urNp linux-2.6.38.1/grsecurity/grsec_mem.c linux-2.6.38.1/grsecurity/grsec_mem.c
42453--- linux-2.6.38.1/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
42454+++ linux-2.6.38.1/grsecurity/grsec_mem.c 2011-03-26 14:40:33.000000000 -0400
42455@@ -0,0 +1,100 @@
58c5fc13
MT
42456+#include <linux/kernel.h>
42457+#include <linux/sched.h>
42458+#include <linux/mm.h>
42459+#include <linux/mman.h>
42460+#include <linux/grinternal.h>
42461+
42462+void
42463+gr_handle_ioperm(void)
42464+{
42465+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
42466+ return;
42467+}
42468+
42469+void
42470+gr_handle_iopl(void)
42471+{
42472+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
42473+ return;
42474+}
42475+
42476+void
42477+gr_handle_mem_write(void)
42478+{
42479+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
42480+ return;
42481+}
42482+
42483+void
42484+gr_handle_kmem_write(void)
42485+{
42486+ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
42487+ return;
42488+}
42489+
42490+void
42491+gr_handle_open_port(void)
42492+{
42493+ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
42494+ return;
42495+}
42496+
42497+int
42498+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
42499+{
42500+ unsigned long start, end;
42501+
42502+ start = offset;
42503+ end = start + vma->vm_end - vma->vm_start;
42504+
42505+ if (start > end) {
42506+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
42507+ return -EPERM;
42508+ }
42509+
16454cff
MT
42510+/* if raw i/o is disabled, prevent writes to /dev/mem entirely */
42511+#ifndef CONFIG_GRKERNSEC_IO
58c5fc13
MT
42512+ /* allowed ranges : ISA I/O BIOS */
42513+ if ((start >= __pa(high_memory))
42514+#if defined(CONFIG_X86) || defined(CONFIG_PPC)
42515+ || (start >= 0x000a0000 && end <= 0x00100000)
42516+ || (start >= 0x00000000 && end <= 0x00001000)
42517+#endif
42518+ )
42519+ return 0;
16454cff 42520+#endif
58c5fc13
MT
42521+
42522+ if (vma->vm_flags & VM_WRITE) {
42523+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
42524+ return -EPERM;
42525+ } else
42526+ vma->vm_flags &= ~VM_MAYWRITE;
42527+
42528+ return 0;
42529+}
42530+
42531+void
42532+gr_log_nonroot_mod_load(const char *modname)
42533+{
16454cff
MT
42534+ if (1
42535+#if !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE)
42536+ /* There are known knowns. These are things we know
42537+ that we know. There are known unknowns. That is to say,
42538+ there are things that we know we don't know. But there are
42539+ also unknown unknowns. There are things we don't know
42540+ we don't know.
42541+ This here is a known unknown.
42542+ */
42543+ && strcmp(modname, "net-pf-10")
42544+#endif
42545+ )
42546+ gr_log_str(GR_DONT_AUDIT, GR_NONROOT_MODLOAD_MSG, modname);
58c5fc13
MT
42547+ return;
42548+}
42549+
ae4e228f
MT
42550+void
42551+gr_handle_vm86(void)
42552+{
42553+ gr_log_noargs(GR_DONT_AUDIT, GR_VM86_MSG);
42554+ return;
42555+}
16454cff
MT
42556diff -urNp linux-2.6.38.1/grsecurity/grsec_mount.c linux-2.6.38.1/grsecurity/grsec_mount.c
42557--- linux-2.6.38.1/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
42558+++ linux-2.6.38.1/grsecurity/grsec_mount.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 42559@@ -0,0 +1,62 @@
58c5fc13
MT
42560+#include <linux/kernel.h>
42561+#include <linux/sched.h>
ae4e228f 42562+#include <linux/mount.h>
58c5fc13
MT
42563+#include <linux/grsecurity.h>
42564+#include <linux/grinternal.h>
42565+
42566+void
42567+gr_log_remount(const char *devname, const int retval)
42568+{
42569+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
42570+ if (grsec_enable_mount && (retval >= 0))
42571+ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
42572+#endif
42573+ return;
42574+}
42575+
42576+void
42577+gr_log_unmount(const char *devname, const int retval)
42578+{
42579+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
42580+ if (grsec_enable_mount && (retval >= 0))
42581+ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
42582+#endif
42583+ return;
42584+}
42585+
42586+void
42587+gr_log_mount(const char *from, const char *to, const int retval)
42588+{
42589+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
42590+ if (grsec_enable_mount && (retval >= 0))
42591+ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
42592+#endif
42593+ return;
42594+}
ae4e228f
MT
42595+
42596+int
42597+gr_handle_rofs_mount(struct dentry *dentry, struct vfsmount *mnt, int mnt_flags)
42598+{
42599+#ifdef CONFIG_GRKERNSEC_ROFS
42600+ if (grsec_enable_rofs && !(mnt_flags & MNT_READONLY)) {
42601+ gr_log_fs_generic(GR_DO_AUDIT, GR_ROFS_MOUNT_MSG, dentry, mnt);
42602+ return -EPERM;
42603+ } else
42604+ return 0;
42605+#endif
42606+ return 0;
42607+}
42608+
42609+int
42610+gr_handle_rofs_blockwrite(struct dentry *dentry, struct vfsmount *mnt, int acc_mode)
42611+{
42612+#ifdef CONFIG_GRKERNSEC_ROFS
42613+ if (grsec_enable_rofs && (acc_mode & MAY_WRITE) &&
42614+ dentry->d_inode && S_ISBLK(dentry->d_inode->i_mode)) {
42615+ gr_log_fs_generic(GR_DO_AUDIT, GR_ROFS_BLOCKWRITE_MSG, dentry, mnt);
42616+ return -EPERM;
42617+ } else
42618+ return 0;
42619+#endif
42620+ return 0;
42621+}
16454cff
MT
42622diff -urNp linux-2.6.38.1/grsecurity/grsec_pax.c linux-2.6.38.1/grsecurity/grsec_pax.c
42623--- linux-2.6.38.1/grsecurity/grsec_pax.c 1969-12-31 19:00:00.000000000 -0500
42624+++ linux-2.6.38.1/grsecurity/grsec_pax.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
42625@@ -0,0 +1,36 @@
42626+#include <linux/kernel.h>
42627+#include <linux/sched.h>
42628+#include <linux/mm.h>
42629+#include <linux/file.h>
42630+#include <linux/grinternal.h>
42631+#include <linux/grsecurity.h>
42632+
42633+void
42634+gr_log_textrel(struct vm_area_struct * vma)
42635+{
42636+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
42637+ if (grsec_enable_audit_textrel)
42638+ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
42639+#endif
42640+ return;
42641+}
42642+
42643+void
42644+gr_log_rwxmmap(struct file *file)
42645+{
42646+#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
42647+ if (grsec_enable_log_rwxmaps)
42648+ gr_log_rwxmap(GR_DONT_AUDIT, GR_RWXMMAP_MSG, file);
42649+#endif
42650+ return;
42651+}
42652+
42653+void
42654+gr_log_rwxmprotect(struct file *file)
42655+{
42656+#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
42657+ if (grsec_enable_log_rwxmaps)
42658+ gr_log_rwxmap(GR_DONT_AUDIT, GR_RWXMPROTECT_MSG, file);
42659+#endif
42660+ return;
42661+}
16454cff
MT
42662diff -urNp linux-2.6.38.1/grsecurity/grsec_ptrace.c linux-2.6.38.1/grsecurity/grsec_ptrace.c
42663--- linux-2.6.38.1/grsecurity/grsec_ptrace.c 1969-12-31 19:00:00.000000000 -0500
42664+++ linux-2.6.38.1/grsecurity/grsec_ptrace.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
42665@@ -0,0 +1,14 @@
42666+#include <linux/kernel.h>
42667+#include <linux/sched.h>
42668+#include <linux/grinternal.h>
42669+#include <linux/grsecurity.h>
42670+
42671+void
42672+gr_audit_ptrace(struct task_struct *task)
42673+{
42674+#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
42675+ if (grsec_enable_audit_ptrace)
42676+ gr_log_ptrace(GR_DO_AUDIT, GR_PTRACE_AUDIT_MSG, task);
42677+#endif
42678+ return;
42679+}
16454cff
MT
42680diff -urNp linux-2.6.38.1/grsecurity/grsec_sig.c linux-2.6.38.1/grsecurity/grsec_sig.c
42681--- linux-2.6.38.1/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
42682+++ linux-2.6.38.1/grsecurity/grsec_sig.c 2011-03-26 19:58:27.000000000 -0400
58c5fc13
MT
42683@@ -0,0 +1,65 @@
42684+#include <linux/kernel.h>
42685+#include <linux/sched.h>
42686+#include <linux/delay.h>
42687+#include <linux/grsecurity.h>
42688+#include <linux/grinternal.h>
42689+
42690+char *signames[] = {
42691+ [SIGSEGV] = "Segmentation fault",
42692+ [SIGILL] = "Illegal instruction",
42693+ [SIGABRT] = "Abort",
42694+ [SIGBUS] = "Invalid alignment/Bus error"
42695+};
42696+
42697+void
42698+gr_log_signal(const int sig, const void *addr, const struct task_struct *t)
42699+{
42700+#ifdef CONFIG_GRKERNSEC_SIGNAL
42701+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
42702+ (sig == SIGABRT) || (sig == SIGBUS))) {
42703+ if (t->pid == current->pid) {
42704+ gr_log_sig_addr(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, signames[sig], addr);
42705+ } else {
42706+ gr_log_sig_task(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
42707+ }
42708+ }
42709+#endif
42710+ return;
42711+}
42712+
42713+int
42714+gr_handle_signal(const struct task_struct *p, const int sig)
42715+{
42716+#ifdef CONFIG_GRKERNSEC
42717+ if (current->pid > 1 && gr_check_protected_task(p)) {
42718+ gr_log_sig_task(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
42719+ return -EPERM;
42720+ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
42721+ return -EPERM;
42722+ }
42723+#endif
42724+ return 0;
42725+}
42726+
42727+void gr_handle_brute_attach(struct task_struct *p)
42728+{
42729+#ifdef CONFIG_GRKERNSEC_BRUTE
42730+ read_lock(&tasklist_lock);
42731+ read_lock(&grsec_exec_file_lock);
6892158b
MT
42732+ if (p->real_parent && p->real_parent->exec_file == p->exec_file)
42733+ p->real_parent->brute = 1;
58c5fc13
MT
42734+ read_unlock(&grsec_exec_file_lock);
42735+ read_unlock(&tasklist_lock);
42736+#endif
42737+ return;
42738+}
42739+
42740+void gr_handle_brute_check(void)
42741+{
42742+#ifdef CONFIG_GRKERNSEC_BRUTE
42743+ if (current->brute)
42744+ msleep(30 * 1000);
42745+#endif
42746+ return;
42747+}
42748+
16454cff
MT
42749diff -urNp linux-2.6.38.1/grsecurity/grsec_sock.c linux-2.6.38.1/grsecurity/grsec_sock.c
42750--- linux-2.6.38.1/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
42751+++ linux-2.6.38.1/grsecurity/grsec_sock.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 42752@@ -0,0 +1,275 @@
58c5fc13
MT
42753+#include <linux/kernel.h>
42754+#include <linux/module.h>
42755+#include <linux/sched.h>
42756+#include <linux/file.h>
42757+#include <linux/net.h>
42758+#include <linux/in.h>
42759+#include <linux/ip.h>
42760+#include <net/sock.h>
42761+#include <net/inet_sock.h>
42762+#include <linux/grsecurity.h>
42763+#include <linux/grinternal.h>
42764+#include <linux/gracl.h>
42765+
42766+kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
42767+EXPORT_SYMBOL(gr_cap_rtnetlink);
42768+
42769+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
42770+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
42771+
42772+EXPORT_SYMBOL(gr_search_udp_recvmsg);
42773+EXPORT_SYMBOL(gr_search_udp_sendmsg);
42774+
42775+#ifdef CONFIG_UNIX_MODULE
42776+EXPORT_SYMBOL(gr_acl_handle_unix);
42777+EXPORT_SYMBOL(gr_acl_handle_mknod);
42778+EXPORT_SYMBOL(gr_handle_chroot_unix);
42779+EXPORT_SYMBOL(gr_handle_create);
42780+#endif
42781+
42782+#ifdef CONFIG_GRKERNSEC
42783+#define gr_conn_table_size 32749
42784+struct conn_table_entry {
42785+ struct conn_table_entry *next;
42786+ struct signal_struct *sig;
42787+};
42788+
42789+struct conn_table_entry *gr_conn_table[gr_conn_table_size];
42790+DEFINE_SPINLOCK(gr_conn_table_lock);
42791+
42792+extern const char * gr_socktype_to_name(unsigned char type);
42793+extern const char * gr_proto_to_name(unsigned char proto);
bc901d79 42794+extern const char * gr_sockfamily_to_name(unsigned char family);
58c5fc13
MT
42795+
42796+static __inline__ int
42797+conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
42798+{
42799+ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
42800+}
42801+
42802+static __inline__ int
42803+conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
42804+ __u16 sport, __u16 dport)
42805+{
42806+ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
42807+ sig->gr_sport == sport && sig->gr_dport == dport))
42808+ return 1;
42809+ else
42810+ return 0;
42811+}
42812+
42813+static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
42814+{
42815+ struct conn_table_entry **match;
42816+ unsigned int index;
42817+
42818+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
42819+ sig->gr_sport, sig->gr_dport,
42820+ gr_conn_table_size);
42821+
42822+ newent->sig = sig;
42823+
42824+ match = &gr_conn_table[index];
42825+ newent->next = *match;
42826+ *match = newent;
42827+
42828+ return;
42829+}
42830+
42831+static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
42832+{
42833+ struct conn_table_entry *match, *last = NULL;
42834+ unsigned int index;
42835+
42836+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
42837+ sig->gr_sport, sig->gr_dport,
42838+ gr_conn_table_size);
42839+
42840+ match = gr_conn_table[index];
42841+ while (match && !conn_match(match->sig,
42842+ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
42843+ sig->gr_dport)) {
42844+ last = match;
42845+ match = match->next;
42846+ }
42847+
42848+ if (match) {
42849+ if (last)
42850+ last->next = match->next;
42851+ else
42852+ gr_conn_table[index] = NULL;
42853+ kfree(match);
42854+ }
42855+
42856+ return;
42857+}
42858+
42859+static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
42860+ __u16 sport, __u16 dport)
42861+{
42862+ struct conn_table_entry *match;
42863+ unsigned int index;
42864+
42865+ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
42866+
42867+ match = gr_conn_table[index];
42868+ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
42869+ match = match->next;
42870+
42871+ if (match)
42872+ return match->sig;
42873+ else
42874+ return NULL;
42875+}
42876+
42877+#endif
42878+
42879+void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
42880+{
42881+#ifdef CONFIG_GRKERNSEC
42882+ struct signal_struct *sig = task->signal;
42883+ struct conn_table_entry *newent;
42884+
42885+ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
42886+ if (newent == NULL)
42887+ return;
42888+ /* no bh lock needed since we are called with bh disabled */
42889+ spin_lock(&gr_conn_table_lock);
42890+ gr_del_task_from_ip_table_nolock(sig);
ae4e228f
MT
42891+ sig->gr_saddr = inet->inet_rcv_saddr;
42892+ sig->gr_daddr = inet->inet_daddr;
42893+ sig->gr_sport = inet->inet_sport;
42894+ sig->gr_dport = inet->inet_dport;
58c5fc13
MT
42895+ gr_add_to_task_ip_table_nolock(sig, newent);
42896+ spin_unlock(&gr_conn_table_lock);
42897+#endif
42898+ return;
42899+}
42900+
42901+void gr_del_task_from_ip_table(struct task_struct *task)
42902+{
42903+#ifdef CONFIG_GRKERNSEC
42904+ spin_lock_bh(&gr_conn_table_lock);
42905+ gr_del_task_from_ip_table_nolock(task->signal);
42906+ spin_unlock_bh(&gr_conn_table_lock);
42907+#endif
42908+ return;
42909+}
42910+
42911+void
42912+gr_attach_curr_ip(const struct sock *sk)
42913+{
42914+#ifdef CONFIG_GRKERNSEC
42915+ struct signal_struct *p, *set;
42916+ const struct inet_sock *inet = inet_sk(sk);
42917+
42918+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
42919+ return;
42920+
42921+ set = current->signal;
42922+
42923+ spin_lock_bh(&gr_conn_table_lock);
ae4e228f
MT
42924+ p = gr_lookup_task_ip_table(inet->inet_daddr, inet->inet_rcv_saddr,
42925+ inet->inet_dport, inet->inet_sport);
58c5fc13
MT
42926+ if (unlikely(p != NULL)) {
42927+ set->curr_ip = p->curr_ip;
42928+ set->used_accept = 1;
42929+ gr_del_task_from_ip_table_nolock(p);
42930+ spin_unlock_bh(&gr_conn_table_lock);
42931+ return;
42932+ }
42933+ spin_unlock_bh(&gr_conn_table_lock);
42934+
ae4e228f 42935+ set->curr_ip = inet->inet_daddr;
58c5fc13
MT
42936+ set->used_accept = 1;
42937+#endif
42938+ return;
42939+}
42940+
42941+int
42942+gr_handle_sock_all(const int family, const int type, const int protocol)
42943+{
42944+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
42945+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
bc901d79
MT
42946+ (family != AF_UNIX)) {
42947+ if (family == AF_INET)
42948+ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, gr_sockfamily_to_name(family), gr_socktype_to_name(type), gr_proto_to_name(protocol));
42949+ else
42950+ gr_log_str2_int(GR_DONT_AUDIT, GR_SOCK_NOINET_MSG, gr_sockfamily_to_name(family), gr_socktype_to_name(type), protocol);
58c5fc13
MT
42951+ return -EACCES;
42952+ }
42953+#endif
42954+ return 0;
42955+}
42956+
42957+int
42958+gr_handle_sock_server(const struct sockaddr *sck)
42959+{
42960+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
42961+ if (grsec_enable_socket_server &&
42962+ in_group_p(grsec_socket_server_gid) &&
42963+ sck && (sck->sa_family != AF_UNIX) &&
42964+ (sck->sa_family != AF_LOCAL)) {
42965+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
42966+ return -EACCES;
42967+ }
42968+#endif
42969+ return 0;
42970+}
42971+
42972+int
42973+gr_handle_sock_server_other(const struct sock *sck)
42974+{
42975+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
42976+ if (grsec_enable_socket_server &&
42977+ in_group_p(grsec_socket_server_gid) &&
42978+ sck && (sck->sk_family != AF_UNIX) &&
42979+ (sck->sk_family != AF_LOCAL)) {
42980+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
42981+ return -EACCES;
42982+ }
42983+#endif
42984+ return 0;
42985+}
42986+
42987+int
42988+gr_handle_sock_client(const struct sockaddr *sck)
42989+{
42990+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
42991+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
42992+ sck && (sck->sa_family != AF_UNIX) &&
42993+ (sck->sa_family != AF_LOCAL)) {
42994+ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
42995+ return -EACCES;
42996+ }
42997+#endif
42998+ return 0;
42999+}
43000+
43001+kernel_cap_t
43002+gr_cap_rtnetlink(struct sock *sock)
43003+{
43004+#ifdef CONFIG_GRKERNSEC
43005+ if (!gr_acl_is_enabled())
43006+ return current_cap();
43007+ else if (sock->sk_protocol == NETLINK_ISCSI &&
43008+ cap_raised(current_cap(), CAP_SYS_ADMIN) &&
43009+ gr_is_capable(CAP_SYS_ADMIN))
43010+ return current_cap();
43011+ else if (sock->sk_protocol == NETLINK_AUDIT &&
43012+ cap_raised(current_cap(), CAP_AUDIT_WRITE) &&
43013+ gr_is_capable(CAP_AUDIT_WRITE) &&
43014+ cap_raised(current_cap(), CAP_AUDIT_CONTROL) &&
43015+ gr_is_capable(CAP_AUDIT_CONTROL))
43016+ return current_cap();
43017+ else if (cap_raised(current_cap(), CAP_NET_ADMIN) &&
ae4e228f
MT
43018+ ((sock->sk_protocol == NETLINK_ROUTE) ?
43019+ gr_is_capable_nolog(CAP_NET_ADMIN) :
43020+ gr_is_capable(CAP_NET_ADMIN)))
58c5fc13
MT
43021+ return current_cap();
43022+ else
43023+ return __cap_empty_set;
43024+#else
43025+ return current_cap();
43026+#endif
43027+}
16454cff
MT
43028diff -urNp linux-2.6.38.1/grsecurity/grsec_sysctl.c linux-2.6.38.1/grsecurity/grsec_sysctl.c
43029--- linux-2.6.38.1/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
43030+++ linux-2.6.38.1/grsecurity/grsec_sysctl.c 2011-03-21 18:31:35.000000000 -0400
6892158b 43031@@ -0,0 +1,433 @@
58c5fc13
MT
43032+#include <linux/kernel.h>
43033+#include <linux/sched.h>
43034+#include <linux/sysctl.h>
43035+#include <linux/grsecurity.h>
43036+#include <linux/grinternal.h>
43037+
43038+int
43039+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
43040+{
43041+#ifdef CONFIG_GRKERNSEC_SYSCTL
43042+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
43043+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
43044+ return -EACCES;
43045+ }
43046+#endif
43047+ return 0;
43048+}
43049+
ae4e228f
MT
43050+#ifdef CONFIG_GRKERNSEC_ROFS
43051+static int __maybe_unused one = 1;
43052+#endif
43053+
43054+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_ROFS)
57199397 43055+struct ctl_table grsecurity_table[] = {
58c5fc13 43056+#ifdef CONFIG_GRKERNSEC_SYSCTL
df50ba0c
MT
43057+#ifdef CONFIG_GRKERNSEC_SYSCTL_DISTRO
43058+#ifdef CONFIG_GRKERNSEC_IO
43059+ {
43060+ .procname = "disable_priv_io",
43061+ .data = &grsec_disable_privio,
43062+ .maxlen = sizeof(int),
43063+ .mode = 0600,
43064+ .proc_handler = &proc_dointvec,
43065+ },
43066+#endif
43067+#endif
58c5fc13
MT
43068+#ifdef CONFIG_GRKERNSEC_LINK
43069+ {
58c5fc13
MT
43070+ .procname = "linking_restrictions",
43071+ .data = &grsec_enable_link,
43072+ .maxlen = sizeof(int),
43073+ .mode = 0600,
43074+ .proc_handler = &proc_dointvec,
43075+ },
43076+#endif
43077+#ifdef CONFIG_GRKERNSEC_FIFO
43078+ {
58c5fc13
MT
43079+ .procname = "fifo_restrictions",
43080+ .data = &grsec_enable_fifo,
43081+ .maxlen = sizeof(int),
43082+ .mode = 0600,
43083+ .proc_handler = &proc_dointvec,
43084+ },
43085+#endif
43086+#ifdef CONFIG_GRKERNSEC_EXECVE
43087+ {
58c5fc13
MT
43088+ .procname = "execve_limiting",
43089+ .data = &grsec_enable_execve,
43090+ .maxlen = sizeof(int),
43091+ .mode = 0600,
43092+ .proc_handler = &proc_dointvec,
43093+ },
43094+#endif
ae4e228f
MT
43095+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
43096+ {
43097+ .procname = "ip_blackhole",
43098+ .data = &grsec_enable_blackhole,
43099+ .maxlen = sizeof(int),
43100+ .mode = 0600,
43101+ .proc_handler = &proc_dointvec,
43102+ },
43103+ {
43104+ .procname = "lastack_retries",
43105+ .data = &grsec_lastack_retries,
43106+ .maxlen = sizeof(int),
43107+ .mode = 0600,
43108+ .proc_handler = &proc_dointvec,
43109+ },
43110+#endif
58c5fc13
MT
43111+#ifdef CONFIG_GRKERNSEC_EXECLOG
43112+ {
58c5fc13
MT
43113+ .procname = "exec_logging",
43114+ .data = &grsec_enable_execlog,
43115+ .maxlen = sizeof(int),
43116+ .mode = 0600,
43117+ .proc_handler = &proc_dointvec,
43118+ },
43119+#endif
6892158b
MT
43120+#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
43121+ {
43122+ .procname = "rwxmap_logging",
43123+ .data = &grsec_enable_log_rwxmaps,
43124+ .maxlen = sizeof(int),
43125+ .mode = 0600,
43126+ .proc_handler = &proc_dointvec,
43127+ },
43128+#endif
58c5fc13
MT
43129+#ifdef CONFIG_GRKERNSEC_SIGNAL
43130+ {
58c5fc13
MT
43131+ .procname = "signal_logging",
43132+ .data = &grsec_enable_signal,
43133+ .maxlen = sizeof(int),
43134+ .mode = 0600,
43135+ .proc_handler = &proc_dointvec,
43136+ },
43137+#endif
43138+#ifdef CONFIG_GRKERNSEC_FORKFAIL
43139+ {
58c5fc13
MT
43140+ .procname = "forkfail_logging",
43141+ .data = &grsec_enable_forkfail,
43142+ .maxlen = sizeof(int),
43143+ .mode = 0600,
43144+ .proc_handler = &proc_dointvec,
43145+ },
43146+#endif
43147+#ifdef CONFIG_GRKERNSEC_TIME
43148+ {
58c5fc13
MT
43149+ .procname = "timechange_logging",
43150+ .data = &grsec_enable_time,
43151+ .maxlen = sizeof(int),
43152+ .mode = 0600,
43153+ .proc_handler = &proc_dointvec,
43154+ },
43155+#endif
43156+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
43157+ {
58c5fc13
MT
43158+ .procname = "chroot_deny_shmat",
43159+ .data = &grsec_enable_chroot_shmat,
43160+ .maxlen = sizeof(int),
43161+ .mode = 0600,
43162+ .proc_handler = &proc_dointvec,
43163+ },
43164+#endif
43165+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
43166+ {
58c5fc13
MT
43167+ .procname = "chroot_deny_unix",
43168+ .data = &grsec_enable_chroot_unix,
43169+ .maxlen = sizeof(int),
43170+ .mode = 0600,
43171+ .proc_handler = &proc_dointvec,
43172+ },
43173+#endif
43174+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
43175+ {
58c5fc13
MT
43176+ .procname = "chroot_deny_mount",
43177+ .data = &grsec_enable_chroot_mount,
43178+ .maxlen = sizeof(int),
43179+ .mode = 0600,
43180+ .proc_handler = &proc_dointvec,
43181+ },
43182+#endif
43183+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
43184+ {
58c5fc13
MT
43185+ .procname = "chroot_deny_fchdir",
43186+ .data = &grsec_enable_chroot_fchdir,
43187+ .maxlen = sizeof(int),
43188+ .mode = 0600,
43189+ .proc_handler = &proc_dointvec,
43190+ },
43191+#endif
43192+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
43193+ {
58c5fc13
MT
43194+ .procname = "chroot_deny_chroot",
43195+ .data = &grsec_enable_chroot_double,
43196+ .maxlen = sizeof(int),
43197+ .mode = 0600,
43198+ .proc_handler = &proc_dointvec,
43199+ },
43200+#endif
43201+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
43202+ {
58c5fc13
MT
43203+ .procname = "chroot_deny_pivot",
43204+ .data = &grsec_enable_chroot_pivot,
43205+ .maxlen = sizeof(int),
43206+ .mode = 0600,
43207+ .proc_handler = &proc_dointvec,
43208+ },
43209+#endif
43210+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
43211+ {
58c5fc13
MT
43212+ .procname = "chroot_enforce_chdir",
43213+ .data = &grsec_enable_chroot_chdir,
43214+ .maxlen = sizeof(int),
43215+ .mode = 0600,
43216+ .proc_handler = &proc_dointvec,
43217+ },
43218+#endif
43219+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
43220+ {
58c5fc13
MT
43221+ .procname = "chroot_deny_chmod",
43222+ .data = &grsec_enable_chroot_chmod,
43223+ .maxlen = sizeof(int),
43224+ .mode = 0600,
43225+ .proc_handler = &proc_dointvec,
43226+ },
43227+#endif
43228+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
43229+ {
58c5fc13
MT
43230+ .procname = "chroot_deny_mknod",
43231+ .data = &grsec_enable_chroot_mknod,
43232+ .maxlen = sizeof(int),
43233+ .mode = 0600,
43234+ .proc_handler = &proc_dointvec,
43235+ },
43236+#endif
43237+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
43238+ {
58c5fc13
MT
43239+ .procname = "chroot_restrict_nice",
43240+ .data = &grsec_enable_chroot_nice,
43241+ .maxlen = sizeof(int),
43242+ .mode = 0600,
43243+ .proc_handler = &proc_dointvec,
43244+ },
43245+#endif
43246+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
43247+ {
58c5fc13
MT
43248+ .procname = "chroot_execlog",
43249+ .data = &grsec_enable_chroot_execlog,
43250+ .maxlen = sizeof(int),
43251+ .mode = 0600,
43252+ .proc_handler = &proc_dointvec,
43253+ },
43254+#endif
43255+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
43256+ {
58c5fc13
MT
43257+ .procname = "chroot_caps",
43258+ .data = &grsec_enable_chroot_caps,
43259+ .maxlen = sizeof(int),
43260+ .mode = 0600,
43261+ .proc_handler = &proc_dointvec,
43262+ },
43263+#endif
43264+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
43265+ {
58c5fc13
MT
43266+ .procname = "chroot_deny_sysctl",
43267+ .data = &grsec_enable_chroot_sysctl,
43268+ .maxlen = sizeof(int),
43269+ .mode = 0600,
43270+ .proc_handler = &proc_dointvec,
43271+ },
43272+#endif
43273+#ifdef CONFIG_GRKERNSEC_TPE
43274+ {
58c5fc13
MT
43275+ .procname = "tpe",
43276+ .data = &grsec_enable_tpe,
43277+ .maxlen = sizeof(int),
43278+ .mode = 0600,
43279+ .proc_handler = &proc_dointvec,
43280+ },
43281+ {
58c5fc13
MT
43282+ .procname = "tpe_gid",
43283+ .data = &grsec_tpe_gid,
43284+ .maxlen = sizeof(int),
43285+ .mode = 0600,
43286+ .proc_handler = &proc_dointvec,
43287+ },
43288+#endif
57199397
MT
43289+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
43290+ {
43291+ .procname = "tpe_invert",
43292+ .data = &grsec_enable_tpe_invert,
43293+ .maxlen = sizeof(int),
43294+ .mode = 0600,
43295+ .proc_handler = &proc_dointvec,
43296+ },
43297+#endif
58c5fc13
MT
43298+#ifdef CONFIG_GRKERNSEC_TPE_ALL
43299+ {
58c5fc13
MT
43300+ .procname = "tpe_restrict_all",
43301+ .data = &grsec_enable_tpe_all,
43302+ .maxlen = sizeof(int),
43303+ .mode = 0600,
43304+ .proc_handler = &proc_dointvec,
43305+ },
43306+#endif
43307+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
43308+ {
58c5fc13
MT
43309+ .procname = "socket_all",
43310+ .data = &grsec_enable_socket_all,
43311+ .maxlen = sizeof(int),
43312+ .mode = 0600,
43313+ .proc_handler = &proc_dointvec,
43314+ },
43315+ {
58c5fc13
MT
43316+ .procname = "socket_all_gid",
43317+ .data = &grsec_socket_all_gid,
43318+ .maxlen = sizeof(int),
43319+ .mode = 0600,
43320+ .proc_handler = &proc_dointvec,
43321+ },
43322+#endif
43323+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
43324+ {
58c5fc13
MT
43325+ .procname = "socket_client",
43326+ .data = &grsec_enable_socket_client,
43327+ .maxlen = sizeof(int),
43328+ .mode = 0600,
43329+ .proc_handler = &proc_dointvec,
efbe55a5
MT
43330+ },
43331+ {
43332+ .procname = "socket_client_gid",
43333+ .data = &grsec_socket_client_gid,
43334+ .maxlen = sizeof(int),
43335+ .mode = 0600,
43336+ .proc_handler = &proc_dointvec,
43337+ },
43338+#endif
43339+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
43340+ {
43341+ .procname = "socket_server",
43342+ .data = &grsec_enable_socket_server,
43343+ .maxlen = sizeof(int),
43344+ .mode = 0600,
43345+ .proc_handler = &proc_dointvec,
43346+ },
43347+ {
43348+ .procname = "socket_server_gid",
43349+ .data = &grsec_socket_server_gid,
43350+ .maxlen = sizeof(int),
43351+ .mode = 0600,
43352+ .proc_handler = &proc_dointvec,
43353+ },
43354+#endif
43355+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
43356+ {
43357+ .procname = "audit_group",
43358+ .data = &grsec_enable_group,
43359+ .maxlen = sizeof(int),
43360+ .mode = 0600,
43361+ .proc_handler = &proc_dointvec,
43362+ },
43363+ {
43364+ .procname = "audit_gid",
43365+ .data = &grsec_audit_gid,
43366+ .maxlen = sizeof(int),
43367+ .mode = 0600,
43368+ .proc_handler = &proc_dointvec,
43369+ },
43370+#endif
43371+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
43372+ {
43373+ .procname = "audit_chdir",
43374+ .data = &grsec_enable_chdir,
43375+ .maxlen = sizeof(int),
43376+ .mode = 0600,
43377+ .proc_handler = &proc_dointvec,
43378+ },
43379+#endif
43380+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
43381+ {
43382+ .procname = "audit_mount",
43383+ .data = &grsec_enable_mount,
43384+ .maxlen = sizeof(int),
43385+ .mode = 0600,
43386+ .proc_handler = &proc_dointvec,
43387+ },
43388+#endif
43389+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
43390+ {
43391+ .procname = "audit_textrel",
43392+ .data = &grsec_enable_audit_textrel,
43393+ .maxlen = sizeof(int),
43394+ .mode = 0600,
43395+ .proc_handler = &proc_dointvec,
43396+ },
43397+#endif
43398+#ifdef CONFIG_GRKERNSEC_DMESG
43399+ {
43400+ .procname = "dmesg",
43401+ .data = &grsec_enable_dmesg,
43402+ .maxlen = sizeof(int),
43403+ .mode = 0600,
43404+ .proc_handler = &proc_dointvec,
43405+ },
43406+#endif
43407+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
43408+ {
43409+ .procname = "chroot_findtask",
43410+ .data = &grsec_enable_chroot_findtask,
43411+ .maxlen = sizeof(int),
43412+ .mode = 0600,
43413+ .proc_handler = &proc_dointvec,
43414+ },
43415+#endif
43416+#ifdef CONFIG_GRKERNSEC_RESLOG
43417+ {
43418+ .procname = "resource_logging",
43419+ .data = &grsec_resource_logging,
43420+ .maxlen = sizeof(int),
43421+ .mode = 0600,
43422+ .proc_handler = &proc_dointvec,
43423+ },
43424+#endif
43425+#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
43426+ {
43427+ .procname = "audit_ptrace",
43428+ .data = &grsec_enable_audit_ptrace,
43429+ .maxlen = sizeof(int),
43430+ .mode = 0600,
43431+ .proc_handler = &proc_dointvec,
43432+ },
43433+#endif
43434+#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
43435+ {
43436+ .procname = "harden_ptrace",
43437+ .data = &grsec_enable_harden_ptrace,
43438+ .maxlen = sizeof(int),
43439+ .mode = 0600,
43440+ .proc_handler = &proc_dointvec,
43441+ },
43442+#endif
43443+ {
43444+ .procname = "grsec_lock",
43445+ .data = &grsec_lock,
43446+ .maxlen = sizeof(int),
43447+ .mode = 0600,
43448+ .proc_handler = &proc_dointvec,
43449+ },
43450+#endif
43451+#ifdef CONFIG_GRKERNSEC_ROFS
43452+ {
43453+ .procname = "romount_protect",
43454+ .data = &grsec_enable_rofs,
43455+ .maxlen = sizeof(int),
43456+ .mode = 0600,
43457+ .proc_handler = &proc_dointvec_minmax,
43458+ .extra1 = &one,
43459+ .extra2 = &one,
43460+ },
43461+#endif
43462+ { }
43463+};
43464+#endif
16454cff
MT
43465diff -urNp linux-2.6.38.1/grsecurity/grsec_time.c linux-2.6.38.1/grsecurity/grsec_time.c
43466--- linux-2.6.38.1/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
43467+++ linux-2.6.38.1/grsecurity/grsec_time.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 43468@@ -0,0 +1,16 @@
57199397
MT
43469+#include <linux/kernel.h>
43470+#include <linux/sched.h>
43471+#include <linux/grinternal.h>
bc901d79 43472+#include <linux/module.h>
57199397
MT
43473+
43474+void
43475+gr_log_timechange(void)
43476+{
43477+#ifdef CONFIG_GRKERNSEC_TIME
43478+ if (grsec_enable_time)
43479+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
43480+#endif
43481+ return;
43482+}
bc901d79
MT
43483+
43484+EXPORT_SYMBOL(gr_log_timechange);
16454cff
MT
43485diff -urNp linux-2.6.38.1/grsecurity/grsec_tpe.c linux-2.6.38.1/grsecurity/grsec_tpe.c
43486--- linux-2.6.38.1/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
43487+++ linux-2.6.38.1/grsecurity/grsec_tpe.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
43488@@ -0,0 +1,39 @@
43489+#include <linux/kernel.h>
43490+#include <linux/sched.h>
43491+#include <linux/file.h>
43492+#include <linux/fs.h>
43493+#include <linux/grinternal.h>
43494+
43495+extern int gr_acl_tpe_check(void);
43496+
43497+int
43498+gr_tpe_allow(const struct file *file)
43499+{
43500+#ifdef CONFIG_GRKERNSEC
43501+ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
43502+ const struct cred *cred = current_cred();
43503+
43504+ if (cred->uid && ((grsec_enable_tpe &&
43505+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
43506+ ((grsec_enable_tpe_invert && !in_group_p(grsec_tpe_gid)) ||
43507+ (!grsec_enable_tpe_invert && in_group_p(grsec_tpe_gid)))
43508+#else
43509+ in_group_p(grsec_tpe_gid)
43510+#endif
43511+ ) || gr_acl_tpe_check()) &&
43512+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
43513+ (inode->i_mode & S_IWOTH))))) {
43514+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
43515+ return 0;
43516+ }
43517+#ifdef CONFIG_GRKERNSEC_TPE_ALL
43518+ if (cred->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
43519+ ((inode->i_uid && (inode->i_uid != cred->uid)) ||
43520+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
43521+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
43522+ return 0;
43523+ }
43524+#endif
43525+#endif
43526+ return 1;
43527+}
16454cff
MT
43528diff -urNp linux-2.6.38.1/grsecurity/grsum.c linux-2.6.38.1/grsecurity/grsum.c
43529--- linux-2.6.38.1/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
43530+++ linux-2.6.38.1/grsecurity/grsum.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
43531@@ -0,0 +1,61 @@
43532+#include <linux/err.h>
43533+#include <linux/kernel.h>
43534+#include <linux/sched.h>
43535+#include <linux/mm.h>
43536+#include <linux/scatterlist.h>
43537+#include <linux/crypto.h>
43538+#include <linux/gracl.h>
43539+
43540+
43541+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
43542+#error "crypto and sha256 must be built into the kernel"
43543+#endif
43544+
43545+int
43546+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
43547+{
43548+ char *p;
43549+ struct crypto_hash *tfm;
43550+ struct hash_desc desc;
43551+ struct scatterlist sg;
43552+ unsigned char temp_sum[GR_SHA_LEN];
43553+ volatile int retval = 0;
43554+ volatile int dummy = 0;
43555+ unsigned int i;
43556+
43557+ sg_init_table(&sg, 1);
43558+
43559+ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
43560+ if (IS_ERR(tfm)) {
43561+ /* should never happen, since sha256 should be built in */
43562+ return 1;
43563+ }
43564+
43565+ desc.tfm = tfm;
43566+ desc.flags = 0;
43567+
43568+ crypto_hash_init(&desc);
43569+
43570+ p = salt;
43571+ sg_set_buf(&sg, p, GR_SALT_LEN);
43572+ crypto_hash_update(&desc, &sg, sg.length);
43573+
43574+ p = entry->pw;
43575+ sg_set_buf(&sg, p, strlen(p));
43576+
43577+ crypto_hash_update(&desc, &sg, sg.length);
43578+
43579+ crypto_hash_final(&desc, temp_sum);
43580+
43581+ memset(entry->pw, 0, GR_PW_LEN);
43582+
43583+ for (i = 0; i < GR_SHA_LEN; i++)
43584+ if (sum[i] != temp_sum[i])
43585+ retval = 1;
43586+ else
43587+ dummy = 1; // waste a cycle
43588+
43589+ crypto_free_hash(tfm);
43590+
43591+ return retval;
43592+}
16454cff
MT
43593diff -urNp linux-2.6.38.1/grsecurity/Kconfig linux-2.6.38.1/grsecurity/Kconfig
43594--- linux-2.6.38.1/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
43595+++ linux-2.6.38.1/grsecurity/Kconfig 2011-03-26 19:54:37.000000000 -0400
43596@@ -0,0 +1,1020 @@
57199397
MT
43597+#
43598+# grecurity configuration
43599+#
43600+
43601+menu "Grsecurity"
43602+
43603+config GRKERNSEC
43604+ bool "Grsecurity"
43605+ select CRYPTO
43606+ select CRYPTO_SHA256
43607+ help
43608+ If you say Y here, you will be able to configure many features
43609+ that will enhance the security of your system. It is highly
43610+ recommended that you say Y here and read through the help
43611+ for each option so that you fully understand the features and
43612+ can evaluate their usefulness for your machine.
43613+
43614+choice
43615+ prompt "Security Level"
43616+ depends on GRKERNSEC
43617+ default GRKERNSEC_CUSTOM
43618+
43619+config GRKERNSEC_LOW
43620+ bool "Low"
43621+ select GRKERNSEC_LINK
43622+ select GRKERNSEC_FIFO
43623+ select GRKERNSEC_EXECVE
43624+ select GRKERNSEC_RANDNET
43625+ select GRKERNSEC_DMESG
43626+ select GRKERNSEC_CHROOT
43627+ select GRKERNSEC_CHROOT_CHDIR
43628+
43629+ help
43630+ If you choose this option, several of the grsecurity options will
43631+ be enabled that will give you greater protection against a number
43632+ of attacks, while assuring that none of your software will have any
43633+ conflicts with the additional security measures. If you run a lot
43634+ of unusual software, or you are having problems with the higher
43635+ security levels, you should say Y here. With this option, the
43636+ following features are enabled:
43637+
43638+ - Linking restrictions
43639+ - FIFO restrictions
43640+ - Enforcing RLIMIT_NPROC on execve
43641+ - Restricted dmesg
43642+ - Enforced chdir("/") on chroot
43643+ - Runtime module disabling
43644+
43645+config GRKERNSEC_MEDIUM
43646+ bool "Medium"
43647+ select PAX
43648+ select PAX_EI_PAX
43649+ select PAX_PT_PAX_FLAGS
43650+ select PAX_HAVE_ACL_FLAGS
43651+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
43652+ select GRKERNSEC_CHROOT
43653+ select GRKERNSEC_CHROOT_SYSCTL
43654+ select GRKERNSEC_LINK
43655+ select GRKERNSEC_FIFO
43656+ select GRKERNSEC_EXECVE
43657+ select GRKERNSEC_DMESG
43658+ select GRKERNSEC_RANDNET
43659+ select GRKERNSEC_FORKFAIL
43660+ select GRKERNSEC_TIME
43661+ select GRKERNSEC_SIGNAL
43662+ select GRKERNSEC_CHROOT
43663+ select GRKERNSEC_CHROOT_UNIX
43664+ select GRKERNSEC_CHROOT_MOUNT
43665+ select GRKERNSEC_CHROOT_PIVOT
43666+ select GRKERNSEC_CHROOT_DOUBLE
43667+ select GRKERNSEC_CHROOT_CHDIR
43668+ select GRKERNSEC_CHROOT_MKNOD
43669+ select GRKERNSEC_PROC
43670+ select GRKERNSEC_PROC_USERGROUP
43671+ select PAX_RANDUSTACK
43672+ select PAX_ASLR
43673+ select PAX_RANDMMAP
43674+ select PAX_REFCOUNT if (X86 || SPARC64)
43675+ select PAX_USERCOPY if ((X86 || SPARC32 || SPARC64 || PPC) && (SLAB || SLUB || SLOB))
43676+
43677+ help
43678+ If you say Y here, several features in addition to those included
43679+ in the low additional security level will be enabled. These
43680+ features provide even more security to your system, though in rare
43681+ cases they may be incompatible with very old or poorly written
43682+ software. If you enable this option, make sure that your auth
43683+ service (identd) is running as gid 1001. With this option,
43684+ the following features (in addition to those provided in the
43685+ low additional security level) will be enabled:
43686+
43687+ - Failed fork logging
43688+ - Time change logging
43689+ - Signal logging
43690+ - Deny mounts in chroot
43691+ - Deny double chrooting
43692+ - Deny sysctl writes in chroot
43693+ - Deny mknod in chroot
43694+ - Deny access to abstract AF_UNIX sockets out of chroot
43695+ - Deny pivot_root in chroot
43696+ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
43697+ - /proc restrictions with special GID set to 10 (usually wheel)
43698+ - Address Space Layout Randomization (ASLR)
43699+ - Prevent exploitation of most refcount overflows
43700+ - Bounds checking of copying between the kernel and userland
43701+
43702+config GRKERNSEC_HIGH
43703+ bool "High"
43704+ select GRKERNSEC_LINK
43705+ select GRKERNSEC_FIFO
43706+ select GRKERNSEC_EXECVE
43707+ select GRKERNSEC_DMESG
43708+ select GRKERNSEC_FORKFAIL
43709+ select GRKERNSEC_TIME
43710+ select GRKERNSEC_SIGNAL
43711+ select GRKERNSEC_CHROOT
43712+ select GRKERNSEC_CHROOT_SHMAT
43713+ select GRKERNSEC_CHROOT_UNIX
43714+ select GRKERNSEC_CHROOT_MOUNT
43715+ select GRKERNSEC_CHROOT_FCHDIR
43716+ select GRKERNSEC_CHROOT_PIVOT
43717+ select GRKERNSEC_CHROOT_DOUBLE
43718+ select GRKERNSEC_CHROOT_CHDIR
43719+ select GRKERNSEC_CHROOT_MKNOD
43720+ select GRKERNSEC_CHROOT_CAPS
43721+ select GRKERNSEC_CHROOT_SYSCTL
43722+ select GRKERNSEC_CHROOT_FINDTASK
16454cff 43723+ select GRKERNSEC_SYSFS_RESTRICT
57199397
MT
43724+ select GRKERNSEC_PROC
43725+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
43726+ select GRKERNSEC_HIDESYM
43727+ select GRKERNSEC_BRUTE
43728+ select GRKERNSEC_PROC_USERGROUP
43729+ select GRKERNSEC_KMEM
43730+ select GRKERNSEC_RESLOG
43731+ select GRKERNSEC_RANDNET
43732+ select GRKERNSEC_PROC_ADD
43733+ select GRKERNSEC_CHROOT_CHMOD
43734+ select GRKERNSEC_CHROOT_NICE
43735+ select GRKERNSEC_AUDIT_MOUNT
43736+ select GRKERNSEC_MODHARDEN if (MODULES)
43737+ select GRKERNSEC_HARDEN_PTRACE
43738+ select GRKERNSEC_VM86 if (X86_32)
43739+ select PAX
43740+ select PAX_RANDUSTACK
43741+ select PAX_ASLR
43742+ select PAX_RANDMMAP
43743+ select PAX_NOEXEC
43744+ select PAX_MPROTECT
43745+ select PAX_EI_PAX
43746+ select PAX_PT_PAX_FLAGS
43747+ select PAX_HAVE_ACL_FLAGS
43748+ select PAX_KERNEXEC if ((PPC || X86) && (!X86_32 || X86_WP_WORKS_OK) && !XEN)
43749+ select PAX_MEMORY_UDEREF if (X86 && !XEN)
43750+ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
43751+ select PAX_SEGMEXEC if (X86_32)
43752+ select PAX_PAGEEXEC
43753+ select PAX_EMUPLT if (ALPHA || PARISC || SPARC32 || SPARC64)
43754+ select PAX_EMUTRAMP if (PARISC)
43755+ select PAX_EMUSIGRT if (PARISC)
43756+ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
43757+ select PAX_ELFRELOCS if (PAX_ETEXECRELOCS || (IA64 || PPC || X86))
43758+ select PAX_REFCOUNT if (X86 || SPARC64)
43759+ select PAX_USERCOPY if ((X86 || PPC || SPARC32 || SPARC64) && (SLAB || SLUB || SLOB))
43760+ help
43761+ If you say Y here, many of the features of grsecurity will be
43762+ enabled, which will protect you against many kinds of attacks
43763+ against your system. The heightened security comes at a cost
43764+ of an increased chance of incompatibilities with rare software
43765+ on your machine. Since this security level enables PaX, you should
43766+ view <http://pax.grsecurity.net> and read about the PaX
43767+ project. While you are there, download chpax and run it on
43768+ binaries that cause problems with PaX. Also remember that
43769+ since the /proc restrictions are enabled, you must run your
43770+ identd as gid 1001. This security level enables the following
43771+ features in addition to those listed in the low and medium
43772+ security levels:
43773+
43774+ - Additional /proc restrictions
43775+ - Chmod restrictions in chroot
43776+ - No signals, ptrace, or viewing of processes outside of chroot
43777+ - Capability restrictions in chroot
43778+ - Deny fchdir out of chroot
43779+ - Priority restrictions in chroot
43780+ - Segmentation-based implementation of PaX
43781+ - Mprotect restrictions
43782+ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
43783+ - Kernel stack randomization
43784+ - Mount/unmount/remount logging
43785+ - Kernel symbol hiding
43786+ - Prevention of memory exhaustion-based exploits
43787+ - Hardening of module auto-loading
43788+ - Ptrace restrictions
43789+ - Restricted vm86 mode
16454cff 43790+ - Restricted sysfs/debugfs
57199397
MT
43791+
43792+config GRKERNSEC_CUSTOM
43793+ bool "Custom"
43794+ help
43795+ If you say Y here, you will be able to configure every grsecurity
43796+ option, which allows you to enable many more features that aren't
43797+ covered in the basic security levels. These additional features
43798+ include TPE, socket restrictions, and the sysctl system for
43799+ grsecurity. It is advised that you read through the help for
43800+ each option to determine its usefulness in your situation.
43801+
43802+endchoice
43803+
43804+menu "Address Space Protection"
43805+depends on GRKERNSEC
43806+
43807+config GRKERNSEC_KMEM
43808+ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
43809+ help
43810+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
43811+ be written to via mmap or otherwise to modify the running kernel.
43812+ /dev/port will also not be allowed to be opened. If you have module
43813+ support disabled, enabling this will close up four ways that are
43814+ currently used to insert malicious code into the running kernel.
43815+ Even with all these features enabled, we still highly recommend that
43816+ you use the RBAC system, as it is still possible for an attacker to
43817+ modify the running kernel through privileged I/O granted by ioperm/iopl.
43818+ If you are not using XFree86, you may be able to stop this additional
43819+ case by enabling the 'Disable privileged I/O' option. Though nothing
43820+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
43821+ but only to video memory, which is the only writing we allow in this
43822+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
43823+ not be allowed to mprotect it with PROT_WRITE later.
43824+ It is highly recommended that you say Y here if you meet all the
43825+ conditions above.
43826+
43827+config GRKERNSEC_VM86
43828+ bool "Restrict VM86 mode"
43829+ depends on X86_32
43830+
43831+ help
43832+ If you say Y here, only processes with CAP_SYS_RAWIO will be able to
43833+ make use of a special execution mode on 32bit x86 processors called
43834+ Virtual 8086 (VM86) mode. XFree86 may need vm86 mode for certain
43835+ video cards and will still work with this option enabled. The purpose
43836+ of the option is to prevent exploitation of emulation errors in
43837+ virtualization of vm86 mode like the one discovered in VMWare in 2009.
43838+ Nearly all users should be able to enable this option.
43839+
43840+config GRKERNSEC_IO
43841+ bool "Disable privileged I/O"
43842+ depends on X86
43843+ select RTC_CLASS
43844+ select RTC_INTF_DEV
43845+ select RTC_DRV_CMOS
43846+
43847+ help
43848+ If you say Y here, all ioperm and iopl calls will return an error.
43849+ Ioperm and iopl can be used to modify the running kernel.
43850+ Unfortunately, some programs need this access to operate properly,
43851+ the most notable of which are XFree86 and hwclock. hwclock can be
43852+ remedied by having RTC support in the kernel, so real-time
43853+ clock support is enabled if this option is enabled, to ensure
43854+ that hwclock operates correctly. XFree86 still will not
43855+ operate correctly with this option enabled, so DO NOT CHOOSE Y
43856+ IF YOU USE XFree86. If you use XFree86 and you still want to
43857+ protect your kernel against modification, use the RBAC system.
43858+
43859+config GRKERNSEC_PROC_MEMMAP
43860+ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
43861+ default y if (PAX_NOEXEC || PAX_ASLR)
43862+ depends on PAX_NOEXEC || PAX_ASLR
43863+ help
43864+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
43865+ give no information about the addresses of its mappings if
43866+ PaX features that rely on random addresses are enabled on the task.
43867+ If you use PaX it is greatly recommended that you say Y here as it
43868+ closes up a hole that makes the full ASLR useless for suid
43869+ binaries.
43870+
43871+config GRKERNSEC_BRUTE
43872+ bool "Deter exploit bruteforcing"
43873+ help
43874+ If you say Y here, attempts to bruteforce exploits against forking
43875+ daemons such as apache or sshd will be deterred. When a child of a
43876+ forking daemon is killed by PaX or crashes due to an illegal
43877+ instruction, the parent process will be delayed 30 seconds upon every
43878+ subsequent fork until the administrator is able to assess the
43879+ situation and restart the daemon. It is recommended that you also
43880+ enable signal logging in the auditing section so that logs are
43881+ generated when a process performs an illegal instruction.
43882+
43883+config GRKERNSEC_MODHARDEN
43884+ bool "Harden module auto-loading"
43885+ depends on MODULES
43886+ help
43887+ If you say Y here, module auto-loading in response to use of some
43888+ feature implemented by an unloaded module will be restricted to
43889+ root users. Enabling this option helps defend against attacks
43890+ by unprivileged users who abuse the auto-loading behavior to
43891+ cause a vulnerable module to load that is then exploited.
43892+
43893+ If this option prevents a legitimate use of auto-loading for a
43894+ non-root user, the administrator can execute modprobe manually
43895+ with the exact name of the module mentioned in the alert log.
43896+ Alternatively, the administrator can add the module to the list
43897+ of modules loaded at boot by modifying init scripts.
43898+
43899+ Modification of init scripts will most likely be needed on
43900+ Ubuntu servers with encrypted home directory support enabled,
43901+ as the first non-root user logging in will cause the ecb(aes),
43902+ ecb(aes)-all, cbc(aes), and cbc(aes)-all modules to be loaded.
43903+
43904+config GRKERNSEC_HIDESYM
43905+ bool "Hide kernel symbols"
43906+ help
43907+ If you say Y here, getting information on loaded modules, and
43908+ displaying all kernel symbols through a syscall will be restricted
43909+ to users with CAP_SYS_MODULE. For software compatibility reasons,
43910+ /proc/kallsyms will be restricted to the root user. The RBAC
43911+ system can hide that entry even from root.
43912+
43913+ This option also prevents leaking of kernel addresses through
43914+ several /proc entries.
43915+
43916+ Note that this option is only effective provided the following
43917+ conditions are met:
43918+ 1) The kernel using grsecurity is not precompiled by some distribution
bc901d79
MT
43919+ 2) You have also enabled GRKERNSEC_DMESG
43920+ 3) You are using the RBAC system and hiding other files such as your
57199397
MT
43921+ kernel image and System.map. Alternatively, enabling this option
43922+ causes the permissions on /boot, /lib/modules, and the kernel
43923+ source directory to change at compile time to prevent
43924+ reading by non-root users.
43925+ If the above conditions are met, this option will aid in providing a
43926+ useful protection against local kernel exploitation of overflows
43927+ and arbitrary read/write vulnerabilities.
43928+
43929+endmenu
43930+menu "Role Based Access Control Options"
43931+depends on GRKERNSEC
43932+
16454cff
MT
43933+config GRKERNSEC_RBAC_DEBUG
43934+ bool
43935+
57199397
MT
43936+config GRKERNSEC_NO_RBAC
43937+ bool "Disable RBAC system"
43938+ help
43939+ If you say Y here, the /dev/grsec device will be removed from the kernel,
43940+ preventing the RBAC system from being enabled. You should only say Y
43941+ here if you have no intention of using the RBAC system, so as to prevent
43942+ an attacker with root access from misusing the RBAC system to hide files
43943+ and processes when loadable module support and /dev/[k]mem have been
43944+ locked down.
43945+
43946+config GRKERNSEC_ACL_HIDEKERN
43947+ bool "Hide kernel processes"
43948+ help
43949+ If you say Y here, all kernel threads will be hidden to all
43950+ processes but those whose subject has the "view hidden processes"
43951+ flag.
43952+
43953+config GRKERNSEC_ACL_MAXTRIES
43954+ int "Maximum tries before password lockout"
43955+ default 3
43956+ help
43957+ This option enforces the maximum number of times a user can attempt
43958+ to authorize themselves with the grsecurity RBAC system before being
43959+ denied the ability to attempt authorization again for a specified time.
43960+ The lower the number, the harder it will be to brute-force a password.
43961+
43962+config GRKERNSEC_ACL_TIMEOUT
43963+ int "Time to wait after max password tries, in seconds"
43964+ default 30
43965+ help
43966+ This option specifies the time the user must wait after attempting to
43967+ authorize to the RBAC system with the maximum number of invalid
43968+ passwords. The higher the number, the harder it will be to brute-force
43969+ a password.
43970+
43971+endmenu
43972+menu "Filesystem Protections"
43973+depends on GRKERNSEC
43974+
43975+config GRKERNSEC_PROC
43976+ bool "Proc restrictions"
43977+ help
43978+ If you say Y here, the permissions of the /proc filesystem
43979+ will be altered to enhance system security and privacy. You MUST
43980+ choose either a user only restriction or a user and group restriction.
43981+ Depending upon the option you choose, you can either restrict users to
43982+ see only the processes they themselves run, or choose a group that can
43983+ view all processes and files normally restricted to root if you choose
43984+ the "restrict to user only" option. NOTE: If you're running identd as
43985+ a non-root user, you will have to run it as the group you specify here.
43986+
43987+config GRKERNSEC_PROC_USER
43988+ bool "Restrict /proc to user only"
43989+ depends on GRKERNSEC_PROC
43990+ help
43991+ If you say Y here, non-root users will only be able to view their own
43992+ processes, and restricts them from viewing network-related information,
43993+ and viewing kernel symbol and module information.
43994+
43995+config GRKERNSEC_PROC_USERGROUP
43996+ bool "Allow special group"
43997+ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
43998+ help
43999+ If you say Y here, you will be able to select a group that will be
bc901d79
MT
44000+ able to view all processes and network-related information. If you've
44001+ enabled GRKERNSEC_HIDESYM, kernel and symbol information may still
44002+ remain hidden. This option is useful if you want to run identd as
44003+ a non-root user.
57199397
MT
44004+
44005+config GRKERNSEC_PROC_GID
44006+ int "GID for special group"
44007+ depends on GRKERNSEC_PROC_USERGROUP
44008+ default 1001
44009+
44010+config GRKERNSEC_PROC_ADD
44011+ bool "Additional restrictions"
44012+ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
44013+ help
44014+ If you say Y here, additional restrictions will be placed on
44015+ /proc that keep normal users from viewing device information and
44016+ slabinfo information that could be useful for exploits.
44017+
44018+config GRKERNSEC_LINK
44019+ bool "Linking restrictions"
44020+ help
44021+ If you say Y here, /tmp race exploits will be prevented, since users
44022+ will no longer be able to follow symlinks owned by other users in
16454cff 44023+ world-writable +t directories (e.g. /tmp), unless the owner of the
57199397
MT
44024+ symlink is the owner of the directory. users will also not be
44025+ able to hardlink to files they do not own. If the sysctl option is
44026+ enabled, a sysctl option with name "linking_restrictions" is created.
44027+
44028+config GRKERNSEC_FIFO
44029+ bool "FIFO restrictions"
44030+ help
44031+ If you say Y here, users will not be able to write to FIFOs they don't
16454cff 44032+ own in world-writable +t directories (e.g. /tmp), unless the owner of
57199397
MT
44033+ the FIFO is the same owner of the directory it's held in. If the sysctl
44034+ option is enabled, a sysctl option with name "fifo_restrictions" is
44035+ created.
44036+
16454cff
MT
44037+config GRKERNSEC_SYSFS_RESTRICT
44038+ bool "Sysfs/debugfs restriction"
44039+ depends on SYSFS
44040+ help
44041+ If you say Y here, sysfs (the pseudo-filesystem mounted at /sys) and
44042+ any filesystem normally mounted under it (e.g. debugfs) will only
44043+ be accessible by root. These filesystems generally provide access
44044+ to hardware and debug information that isn't appropriate for unprivileged
44045+ users of the system. Sysfs and debugfs have also become a large source
44046+ of new vulnerabilities, ranging from infoleaks to local compromise.
44047+ There has been very little oversight with an eye toward security involved
44048+ in adding new exporters of information to these filesystems, so their
44049+ use is discouraged.
44050+ This option is equivalent to a chmod 0700 of the mount paths.
44051+
57199397
MT
44052+config GRKERNSEC_ROFS
44053+ bool "Runtime read-only mount protection"
44054+ help
44055+ If you say Y here, a sysctl option with name "romount_protect" will
44056+ be created. By setting this option to 1 at runtime, filesystems
44057+ will be protected in the following ways:
44058+ * No new writable mounts will be allowed
44059+ * Existing read-only mounts won't be able to be remounted read/write
44060+ * Write operations will be denied on all block devices
44061+ This option acts independently of grsec_lock: once it is set to 1,
44062+ it cannot be turned off. Therefore, please be mindful of the resulting
44063+ behavior if this option is enabled in an init script on a read-only
44064+ filesystem. This feature is mainly intended for secure embedded systems.
44065+
44066+config GRKERNSEC_CHROOT
44067+ bool "Chroot jail restrictions"
44068+ help
44069+ If you say Y here, you will be able to choose several options that will
44070+ make breaking out of a chrooted jail much more difficult. If you
44071+ encounter no software incompatibilities with the following options, it
44072+ is recommended that you enable each one.
44073+
44074+config GRKERNSEC_CHROOT_MOUNT
44075+ bool "Deny mounts"
44076+ depends on GRKERNSEC_CHROOT
44077+ help
44078+ If you say Y here, processes inside a chroot will not be able to
44079+ mount or remount filesystems. If the sysctl option is enabled, a
44080+ sysctl option with name "chroot_deny_mount" is created.
44081+
44082+config GRKERNSEC_CHROOT_DOUBLE
44083+ bool "Deny double-chroots"
44084+ depends on GRKERNSEC_CHROOT
44085+ help
44086+ If you say Y here, processes inside a chroot will not be able to chroot
44087+ again outside the chroot. This is a widely used method of breaking
44088+ out of a chroot jail and should not be allowed. If the sysctl
44089+ option is enabled, a sysctl option with name
44090+ "chroot_deny_chroot" is created.
44091+
44092+config GRKERNSEC_CHROOT_PIVOT
44093+ bool "Deny pivot_root in chroot"
44094+ depends on GRKERNSEC_CHROOT
44095+ help
44096+ If you say Y here, processes inside a chroot will not be able to use
44097+ a function called pivot_root() that was introduced in Linux 2.3.41. It
44098+ works similar to chroot in that it changes the root filesystem. This
44099+ function could be misused in a chrooted process to attempt to break out
44100+ of the chroot, and therefore should not be allowed. If the sysctl
44101+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
44102+ created.
44103+
44104+config GRKERNSEC_CHROOT_CHDIR
44105+ bool "Enforce chdir(\"/\") on all chroots"
44106+ depends on GRKERNSEC_CHROOT
44107+ help
44108+ If you say Y here, the current working directory of all newly-chrooted
44109+ applications will be set to the the root directory of the chroot.
44110+ The man page on chroot(2) states:
44111+ Note that this call does not change the current working
44112+ directory, so that `.' can be outside the tree rooted at
44113+ `/'. In particular, the super-user can escape from a
44114+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
44115+
44116+ It is recommended that you say Y here, since it's not known to break
44117+ any software. If the sysctl option is enabled, a sysctl option with
44118+ name "chroot_enforce_chdir" is created.
44119+
44120+config GRKERNSEC_CHROOT_CHMOD
44121+ bool "Deny (f)chmod +s"
44122+ depends on GRKERNSEC_CHROOT
44123+ help
44124+ If you say Y here, processes inside a chroot will not be able to chmod
44125+ or fchmod files to make them have suid or sgid bits. This protects
44126+ against another published method of breaking a chroot. If the sysctl
44127+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
44128+ created.
44129+
44130+config GRKERNSEC_CHROOT_FCHDIR
44131+ bool "Deny fchdir out of chroot"
44132+ depends on GRKERNSEC_CHROOT
44133+ help
44134+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
44135+ to a file descriptor of the chrooting process that points to a directory
44136+ outside the filesystem will be stopped. If the sysctl option
44137+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
44138+
44139+config GRKERNSEC_CHROOT_MKNOD
44140+ bool "Deny mknod"
44141+ depends on GRKERNSEC_CHROOT
44142+ help
44143+ If you say Y here, processes inside a chroot will not be allowed to
44144+ mknod. The problem with using mknod inside a chroot is that it
44145+ would allow an attacker to create a device entry that is the same
44146+ as one on the physical root of your system, which could range from
44147+ anything from the console device to a device for your harddrive (which
44148+ they could then use to wipe the drive or steal data). It is recommended
44149+ that you say Y here, unless you run into software incompatibilities.
44150+ If the sysctl option is enabled, a sysctl option with name
44151+ "chroot_deny_mknod" is created.
44152+
44153+config GRKERNSEC_CHROOT_SHMAT
44154+ bool "Deny shmat() out of chroot"
44155+ depends on GRKERNSEC_CHROOT
44156+ help
44157+ If you say Y here, processes inside a chroot will not be able to attach
44158+ to shared memory segments that were created outside of the chroot jail.
44159+ It is recommended that you say Y here. If the sysctl option is enabled,
44160+ a sysctl option with name "chroot_deny_shmat" is created.
44161+
44162+config GRKERNSEC_CHROOT_UNIX
44163+ bool "Deny access to abstract AF_UNIX sockets out of chroot"
44164+ depends on GRKERNSEC_CHROOT
44165+ help
44166+ If you say Y here, processes inside a chroot will not be able to
44167+ connect to abstract (meaning not belonging to a filesystem) Unix
44168+ domain sockets that were bound outside of a chroot. It is recommended
44169+ that you say Y here. If the sysctl option is enabled, a sysctl option
44170+ with name "chroot_deny_unix" is created.
44171+
44172+config GRKERNSEC_CHROOT_FINDTASK
44173+ bool "Protect outside processes"
44174+ depends on GRKERNSEC_CHROOT
44175+ help
44176+ If you say Y here, processes inside a chroot will not be able to
44177+ kill, send signals with fcntl, ptrace, capget, getpgid, setpgid,
44178+ getsid, or view any process outside of the chroot. If the sysctl
44179+ option is enabled, a sysctl option with name "chroot_findtask" is
44180+ created.
44181+
44182+config GRKERNSEC_CHROOT_NICE
44183+ bool "Restrict priority changes"
44184+ depends on GRKERNSEC_CHROOT
44185+ help
44186+ If you say Y here, processes inside a chroot will not be able to raise
44187+ the priority of processes in the chroot, or alter the priority of
44188+ processes outside the chroot. This provides more security than simply
44189+ removing CAP_SYS_NICE from the process' capability set. If the
44190+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
44191+ is created.
44192+
44193+config GRKERNSEC_CHROOT_SYSCTL
44194+ bool "Deny sysctl writes"
44195+ depends on GRKERNSEC_CHROOT
44196+ help
44197+ If you say Y here, an attacker in a chroot will not be able to
44198+ write to sysctl entries, either by sysctl(2) or through a /proc
44199+ interface. It is strongly recommended that you say Y here. If the
44200+ sysctl option is enabled, a sysctl option with name
44201+ "chroot_deny_sysctl" is created.
44202+
44203+config GRKERNSEC_CHROOT_CAPS
44204+ bool "Capability restrictions"
44205+ depends on GRKERNSEC_CHROOT
44206+ help
44207+ If you say Y here, the capabilities on all root processes within a
44208+ chroot jail will be lowered to stop module insertion, raw i/o,
44209+ system and net admin tasks, rebooting the system, modifying immutable
44210+ files, modifying IPC owned by another, and changing the system time.
44211+ This is left an option because it can break some apps. Disable this
44212+ if your chrooted apps are having problems performing those kinds of
44213+ tasks. If the sysctl option is enabled, a sysctl option with
44214+ name "chroot_caps" is created.
44215+
44216+endmenu
44217+menu "Kernel Auditing"
44218+depends on GRKERNSEC
44219+
44220+config GRKERNSEC_AUDIT_GROUP
44221+ bool "Single group for auditing"
44222+ help
44223+ If you say Y here, the exec, chdir, and (un)mount logging features
44224+ will only operate on a group you specify. This option is recommended
44225+ if you only want to watch certain users instead of having a large
44226+ amount of logs from the entire system. If the sysctl option is enabled,
44227+ a sysctl option with name "audit_group" is created.
44228+
44229+config GRKERNSEC_AUDIT_GID
44230+ int "GID for auditing"
44231+ depends on GRKERNSEC_AUDIT_GROUP
44232+ default 1007
44233+
44234+config GRKERNSEC_EXECLOG
44235+ bool "Exec logging"
44236+ help
44237+ If you say Y here, all execve() calls will be logged (since the
44238+ other exec*() calls are frontends to execve(), all execution
44239+ will be logged). Useful for shell-servers that like to keep track
44240+ of their users. If the sysctl option is enabled, a sysctl option with
44241+ name "exec_logging" is created.
44242+ WARNING: This option when enabled will produce a LOT of logs, especially
44243+ on an active system.
44244+
44245+config GRKERNSEC_RESLOG
44246+ bool "Resource logging"
44247+ help
44248+ If you say Y here, all attempts to overstep resource limits will
44249+ be logged with the resource name, the requested size, and the current
44250+ limit. It is highly recommended that you say Y here. If the sysctl
44251+ option is enabled, a sysctl option with name "resource_logging" is
44252+ created. If the RBAC system is enabled, the sysctl value is ignored.
44253+
44254+config GRKERNSEC_CHROOT_EXECLOG
44255+ bool "Log execs within chroot"
44256+ help
44257+ If you say Y here, all executions inside a chroot jail will be logged
44258+ to syslog. This can cause a large amount of logs if certain
44259+ applications (eg. djb's daemontools) are installed on the system, and
44260+ is therefore left as an option. If the sysctl option is enabled, a
44261+ sysctl option with name "chroot_execlog" is created.
44262+
44263+config GRKERNSEC_AUDIT_PTRACE
44264+ bool "Ptrace logging"
44265+ help
44266+ If you say Y here, all attempts to attach to a process via ptrace
44267+ will be logged. If the sysctl option is enabled, a sysctl option
44268+ with name "audit_ptrace" is created.
44269+
44270+config GRKERNSEC_AUDIT_CHDIR
44271+ bool "Chdir logging"
44272+ help
44273+ If you say Y here, all chdir() calls will be logged. If the sysctl
44274+ option is enabled, a sysctl option with name "audit_chdir" is created.
44275+
44276+config GRKERNSEC_AUDIT_MOUNT
44277+ bool "(Un)Mount logging"
44278+ help
44279+ If you say Y here, all mounts and unmounts will be logged. If the
44280+ sysctl option is enabled, a sysctl option with name "audit_mount" is
44281+ created.
44282+
44283+config GRKERNSEC_SIGNAL
44284+ bool "Signal logging"
44285+ help
44286+ If you say Y here, certain important signals will be logged, such as
44287+ SIGSEGV, which will as a result inform you of when a error in a program
44288+ occurred, which in some cases could mean a possible exploit attempt.
44289+ If the sysctl option is enabled, a sysctl option with name
44290+ "signal_logging" is created.
44291+
44292+config GRKERNSEC_FORKFAIL
44293+ bool "Fork failure logging"
44294+ help
44295+ If you say Y here, all failed fork() attempts will be logged.
44296+ This could suggest a fork bomb, or someone attempting to overstep
44297+ their process limit. If the sysctl option is enabled, a sysctl option
44298+ with name "forkfail_logging" is created.
44299+
44300+config GRKERNSEC_TIME
44301+ bool "Time change logging"
44302+ help
44303+ If you say Y here, any changes of the system clock will be logged.
44304+ If the sysctl option is enabled, a sysctl option with name
44305+ "timechange_logging" is created.
44306+
44307+config GRKERNSEC_PROC_IPADDR
44308+ bool "/proc/<pid>/ipaddr support"
44309+ help
44310+ If you say Y here, a new entry will be added to each /proc/<pid>
44311+ directory that contains the IP address of the person using the task.
44312+ The IP is carried across local TCP and AF_UNIX stream sockets.
44313+ This information can be useful for IDS/IPSes to perform remote response
44314+ to a local attack. The entry is readable by only the owner of the
44315+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
44316+ the RBAC system), and thus does not create privacy concerns.
44317+
6892158b
MT
44318+config GRKERNSEC_RWXMAP_LOG
44319+ bool 'Denied RWX mmap/mprotect logging'
44320+ depends on PAX_MPROTECT && !PAX_EMUPLT && !PAX_EMUSIGRT
44321+ help
44322+ If you say Y here, calls to mmap() and mprotect() with explicit
44323+ usage of PROT_WRITE and PROT_EXEC together will be logged when
44324+ denied by the PAX_MPROTECT feature. If the sysctl option is
44325+ enabled, a sysctl option with name "rwxmap_logging" is created.
44326+
57199397
MT
44327+config GRKERNSEC_AUDIT_TEXTREL
44328+ bool 'ELF text relocations logging (READ HELP)'
44329+ depends on PAX_MPROTECT
44330+ help
44331+ If you say Y here, text relocations will be logged with the filename
44332+ of the offending library or binary. The purpose of the feature is
44333+ to help Linux distribution developers get rid of libraries and
44334+ binaries that need text relocations which hinder the future progress
44335+ of PaX. Only Linux distribution developers should say Y here, and
44336+ never on a production machine, as this option creates an information
44337+ leak that could aid an attacker in defeating the randomization of
44338+ a single memory region. If the sysctl option is enabled, a sysctl
44339+ option with name "audit_textrel" is created.
44340+
44341+endmenu
44342+
44343+menu "Executable Protections"
44344+depends on GRKERNSEC
44345+
44346+config GRKERNSEC_EXECVE
44347+ bool "Enforce RLIMIT_NPROC on execs"
44348+ help
44349+ If you say Y here, users with a resource limit on processes will
44350+ have the value checked during execve() calls. The current system
44351+ only checks the system limit during fork() calls. If the sysctl option
44352+ is enabled, a sysctl option with name "execve_limiting" is created.
44353+
44354+config GRKERNSEC_DMESG
44355+ bool "Dmesg(8) restriction"
44356+ help
44357+ If you say Y here, non-root users will not be able to use dmesg(8)
44358+ to view up to the last 4kb of messages in the kernel's log buffer.
bc901d79
MT
44359+ The kernel's log buffer often contains kernel addresses and other
44360+ identifying information useful to an attacker in fingerprinting a
44361+ system for a targeted exploit.
57199397
MT
44362+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
44363+ created.
44364+
44365+config GRKERNSEC_HARDEN_PTRACE
44366+ bool "Deter ptrace-based process snooping"
44367+ help
44368+ If you say Y here, TTY sniffers and other malicious monitoring
44369+ programs implemented through ptrace will be defeated. If you
44370+ have been using the RBAC system, this option has already been
44371+ enabled for several years for all users, with the ability to make
44372+ fine-grained exceptions.
44373+
44374+ This option only affects the ability of non-root users to ptrace
44375+ processes that are not a descendent of the ptracing process.
44376+ This means that strace ./binary and gdb ./binary will still work,
44377+ but attaching to arbitrary processes will not. If the sysctl
44378+ option is enabled, a sysctl option with name "harden_ptrace" is
44379+ created.
44380+
44381+config GRKERNSEC_TPE
44382+ bool "Trusted Path Execution (TPE)"
44383+ help
44384+ If you say Y here, you will be able to choose a gid to add to the
44385+ supplementary groups of users you want to mark as "untrusted."
44386+ These users will not be able to execute any files that are not in
44387+ root-owned directories writable only by root. If the sysctl option
44388+ is enabled, a sysctl option with name "tpe" is created.
44389+
44390+config GRKERNSEC_TPE_ALL
44391+ bool "Partially restrict all non-root users"
44392+ depends on GRKERNSEC_TPE
44393+ help
44394+ If you say Y here, all non-root users will be covered under
44395+ a weaker TPE restriction. This is separate from, and in addition to,
44396+ the main TPE options that you have selected elsewhere. Thus, if a
44397+ "trusted" GID is chosen, this restriction applies to even that GID.
44398+ Under this restriction, all non-root users will only be allowed to
44399+ execute files in directories they own that are not group or
44400+ world-writable, or in directories owned by root and writable only by
44401+ root. If the sysctl option is enabled, a sysctl option with name
44402+ "tpe_restrict_all" is created.
44403+
44404+config GRKERNSEC_TPE_INVERT
44405+ bool "Invert GID option"
44406+ depends on GRKERNSEC_TPE
44407+ help
44408+ If you say Y here, the group you specify in the TPE configuration will
44409+ decide what group TPE restrictions will be *disabled* for. This
44410+ option is useful if you want TPE restrictions to be applied to most
44411+ users on the system. If the sysctl option is enabled, a sysctl option
44412+ with name "tpe_invert" is created. Unlike other sysctl options, this
44413+ entry will default to on for backward-compatibility.
58c5fc13 44414+
57199397
MT
44415+config GRKERNSEC_TPE_GID
44416+ int "GID for untrusted users"
44417+ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
44418+ default 1005
44419+ help
44420+ Setting this GID determines what group TPE restrictions will be
44421+ *enabled* for. If the sysctl option is enabled, a sysctl option
44422+ with name "tpe_gid" is created.
58c5fc13 44423+
57199397
MT
44424+config GRKERNSEC_TPE_GID
44425+ int "GID for trusted users"
44426+ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
44427+ default 1005
44428+ help
44429+ Setting this GID determines what group TPE restrictions will be
44430+ *disabled* for. If the sysctl option is enabled, a sysctl option
44431+ with name "tpe_gid" is created.
58c5fc13 44432+
57199397
MT
44433+endmenu
44434+menu "Network Protections"
44435+depends on GRKERNSEC
58c5fc13 44436+
57199397
MT
44437+config GRKERNSEC_RANDNET
44438+ bool "Larger entropy pools"
44439+ help
44440+ If you say Y here, the entropy pools used for many features of Linux
44441+ and grsecurity will be doubled in size. Since several grsecurity
44442+ features use additional randomness, it is recommended that you say Y
44443+ here. Saying Y here has a similar effect as modifying
44444+ /proc/sys/kernel/random/poolsize.
58c5fc13 44445+
57199397
MT
44446+config GRKERNSEC_BLACKHOLE
44447+ bool "TCP/UDP blackhole and LAST_ACK DoS prevention"
44448+ help
44449+ If you say Y here, neither TCP resets nor ICMP
44450+ destination-unreachable packets will be sent in response to packets
44451+ sent to ports for which no associated listening process exists.
44452+ This feature supports both IPV4 and IPV6 and exempts the
44453+ loopback interface from blackholing. Enabling this feature
44454+ makes a host more resilient to DoS attacks and reduces network
44455+ visibility against scanners.
58c5fc13 44456+
57199397
MT
44457+ The blackhole feature as-implemented is equivalent to the FreeBSD
44458+ blackhole feature, as it prevents RST responses to all packets, not
44459+ just SYNs. Under most application behavior this causes no
44460+ problems, but applications (like haproxy) may not close certain
44461+ connections in a way that cleanly terminates them on the remote
44462+ end, leaving the remote host in LAST_ACK state. Because of this
44463+ side-effect and to prevent intentional LAST_ACK DoSes, this
44464+ feature also adds automatic mitigation against such attacks.
44465+ The mitigation drastically reduces the amount of time a socket
44466+ can spend in LAST_ACK state. If you're using haproxy and not
44467+ all servers it connects to have this option enabled, consider
44468+ disabling this feature on the haproxy host.
58c5fc13 44469+
57199397
MT
44470+ If the sysctl option is enabled, two sysctl options with names
44471+ "ip_blackhole" and "lastack_retries" will be created.
44472+ While "ip_blackhole" takes the standard zero/non-zero on/off
44473+ toggle, "lastack_retries" uses the same kinds of values as
44474+ "tcp_retries1" and "tcp_retries2". The default value of 4
44475+ prevents a socket from lasting more than 45 seconds in LAST_ACK
44476+ state.
df50ba0c 44477+
57199397
MT
44478+config GRKERNSEC_SOCKET
44479+ bool "Socket restrictions"
44480+ help
44481+ If you say Y here, you will be able to choose from several options.
44482+ If you assign a GID on your system and add it to the supplementary
44483+ groups of users you want to restrict socket access to, this patch
44484+ will perform up to three things, based on the option(s) you choose.
df50ba0c 44485+
57199397
MT
44486+config GRKERNSEC_SOCKET_ALL
44487+ bool "Deny any sockets to group"
44488+ depends on GRKERNSEC_SOCKET
44489+ help
44490+ If you say Y here, you will be able to choose a GID of whose users will
44491+ be unable to connect to other hosts from your machine or run server
44492+ applications from your machine. If the sysctl option is enabled, a
44493+ sysctl option with name "socket_all" is created.
58c5fc13 44494+
57199397
MT
44495+config GRKERNSEC_SOCKET_ALL_GID
44496+ int "GID to deny all sockets for"
44497+ depends on GRKERNSEC_SOCKET_ALL
44498+ default 1004
44499+ help
44500+ Here you can choose the GID to disable socket access for. Remember to
44501+ add the users you want socket access disabled for to the GID
44502+ specified here. If the sysctl option is enabled, a sysctl option
44503+ with name "socket_all_gid" is created.
58c5fc13 44504+
57199397
MT
44505+config GRKERNSEC_SOCKET_CLIENT
44506+ bool "Deny client sockets to group"
44507+ depends on GRKERNSEC_SOCKET
44508+ help
44509+ If you say Y here, you will be able to choose a GID of whose users will
44510+ be unable to connect to other hosts from your machine, but will be
44511+ able to run servers. If this option is enabled, all users in the group
44512+ you specify will have to use passive mode when initiating ftp transfers
44513+ from the shell on your machine. If the sysctl option is enabled, a
44514+ sysctl option with name "socket_client" is created.
58c5fc13 44515+
57199397
MT
44516+config GRKERNSEC_SOCKET_CLIENT_GID
44517+ int "GID to deny client sockets for"
44518+ depends on GRKERNSEC_SOCKET_CLIENT
44519+ default 1003
44520+ help
44521+ Here you can choose the GID to disable client socket access for.
44522+ Remember to add the users you want client socket access disabled for to
44523+ the GID specified here. If the sysctl option is enabled, a sysctl
44524+ option with name "socket_client_gid" is created.
58c5fc13 44525+
57199397
MT
44526+config GRKERNSEC_SOCKET_SERVER
44527+ bool "Deny server sockets to group"
44528+ depends on GRKERNSEC_SOCKET
44529+ help
44530+ If you say Y here, you will be able to choose a GID of whose users will
44531+ be unable to run server applications from your machine. If the sysctl
44532+ option is enabled, a sysctl option with name "socket_server" is created.
58c5fc13 44533+
57199397
MT
44534+config GRKERNSEC_SOCKET_SERVER_GID
44535+ int "GID to deny server sockets for"
44536+ depends on GRKERNSEC_SOCKET_SERVER
44537+ default 1002
44538+ help
44539+ Here you can choose the GID to disable server socket access for.
44540+ Remember to add the users you want server socket access disabled for to
44541+ the GID specified here. If the sysctl option is enabled, a sysctl
44542+ option with name "socket_server_gid" is created.
58c5fc13 44543+
57199397
MT
44544+endmenu
44545+menu "Sysctl support"
44546+depends on GRKERNSEC && SYSCTL
58c5fc13 44547+
57199397
MT
44548+config GRKERNSEC_SYSCTL
44549+ bool "Sysctl support"
44550+ help
44551+ If you say Y here, you will be able to change the options that
44552+ grsecurity runs with at bootup, without having to recompile your
44553+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
44554+ to enable (1) or disable (0) various features. All the sysctl entries
44555+ are mutable until the "grsec_lock" entry is set to a non-zero value.
44556+ All features enabled in the kernel configuration are disabled at boot
44557+ if you do not say Y to the "Turn on features by default" option.
44558+ All options should be set at startup, and the grsec_lock entry should
44559+ be set to a non-zero value after all the options are set.
44560+ *THIS IS EXTREMELY IMPORTANT*
58c5fc13 44561+
57199397
MT
44562+config GRKERNSEC_SYSCTL_DISTRO
44563+ bool "Extra sysctl support for distro makers (READ HELP)"
44564+ depends on GRKERNSEC_SYSCTL && GRKERNSEC_IO
44565+ help
44566+ If you say Y here, additional sysctl options will be created
44567+ for features that affect processes running as root. Therefore,
44568+ it is critical when using this option that the grsec_lock entry be
44569+ enabled after boot. Only distros with prebuilt kernel packages
44570+ with this option enabled that can ensure grsec_lock is enabled
44571+ after boot should use this option.
44572+ *Failure to set grsec_lock after boot makes all grsec features
44573+ this option covers useless*
58c5fc13 44574+
57199397
MT
44575+ Currently this option creates the following sysctl entries:
44576+ "Disable Privileged I/O": "disable_priv_io"
44577+
44578+config GRKERNSEC_SYSCTL_ON
44579+ bool "Turn on features by default"
44580+ depends on GRKERNSEC_SYSCTL
44581+ help
44582+ If you say Y here, instead of having all features enabled in the
44583+ kernel configuration disabled at boot time, the features will be
44584+ enabled at boot time. It is recommended you say Y here unless
44585+ there is some reason you would want all sysctl-tunable features to
44586+ be disabled by default. As mentioned elsewhere, it is important
44587+ to enable the grsec_lock entry once you have finished modifying
44588+ the sysctl entries.
44589+
44590+endmenu
44591+menu "Logging Options"
44592+depends on GRKERNSEC
44593+
44594+config GRKERNSEC_FLOODTIME
44595+ int "Seconds in between log messages (minimum)"
44596+ default 10
44597+ help
44598+ This option allows you to enforce the number of seconds between
44599+ grsecurity log messages. The default should be suitable for most
44600+ people, however, if you choose to change it, choose a value small enough
44601+ to allow informative logs to be produced, but large enough to
44602+ prevent flooding.
44603+
44604+config GRKERNSEC_FLOODBURST
44605+ int "Number of messages in a burst (maximum)"
44606+ default 4
44607+ help
44608+ This option allows you to choose the maximum number of messages allowed
44609+ within the flood time interval you chose in a separate option. The
44610+ default should be suitable for most people, however if you find that
44611+ many of your logs are being interpreted as flooding, you may want to
44612+ raise this value.
44613+
44614+endmenu
44615+
44616+endmenu
16454cff
MT
44617diff -urNp linux-2.6.38.1/grsecurity/Makefile linux-2.6.38.1/grsecurity/Makefile
44618--- linux-2.6.38.1/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
44619+++ linux-2.6.38.1/grsecurity/Makefile 2011-03-21 18:31:35.000000000 -0400
57199397
MT
44620@@ -0,0 +1,29 @@
44621+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
44622+# during 2001-2009 it has been completely redesigned by Brad Spengler
44623+# into an RBAC system
44624+#
44625+# All code in this directory and various hooks inserted throughout the kernel
44626+# are copyright Brad Spengler - Open Source Security, Inc., and released
44627+# under the GPL v2 or higher
44628+
44629+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
44630+ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
6892158b 44631+ grsec_time.o grsec_tpe.o grsec_link.o grsec_pax.o grsec_ptrace.o
57199397
MT
44632+
44633+obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
44634+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
44635+ gracl_learn.o grsec_log.o
44636+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
44637+
44638+ifndef CONFIG_GRKERNSEC
44639+obj-y += grsec_disabled.o
44640+endif
44641+
44642+ifdef CONFIG_GRKERNSEC_HIDESYM
44643+extra-y := grsec_hidesym.o
44644+$(obj)/grsec_hidesym.o:
44645+ @-chmod -f 500 /boot
44646+ @-chmod -f 500 /lib/modules
44647+ @-chmod -f 700 .
44648+ @echo ' grsec: protected kernel image paths'
44649+endif
16454cff
MT
44650diff -urNp linux-2.6.38.1/include/acpi/acoutput.h linux-2.6.38.1/include/acpi/acoutput.h
44651--- linux-2.6.38.1/include/acpi/acoutput.h 2011-03-14 21:20:32.000000000 -0400
44652+++ linux-2.6.38.1/include/acpi/acoutput.h 2011-03-21 18:31:35.000000000 -0400
6892158b 44653@@ -269,8 +269,8 @@
df50ba0c
MT
44654 * leaving no executable debug code!
44655 */
44656 #define ACPI_FUNCTION_NAME(a)
44657-#define ACPI_DEBUG_PRINT(pl)
44658-#define ACPI_DEBUG_PRINT_RAW(pl)
44659+#define ACPI_DEBUG_PRINT(pl) do {} while (0)
44660+#define ACPI_DEBUG_PRINT_RAW(pl) do {} while (0)
44661
44662 #endif /* ACPI_DEBUG_OUTPUT */
44663
16454cff
MT
44664diff -urNp linux-2.6.38.1/include/acpi/acpi_drivers.h linux-2.6.38.1/include/acpi/acpi_drivers.h
44665--- linux-2.6.38.1/include/acpi/acpi_drivers.h 2011-03-14 21:20:32.000000000 -0400
44666+++ linux-2.6.38.1/include/acpi/acpi_drivers.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 44667@@ -119,8 +119,8 @@ void pci_acpi_crs_quirks(void);
ae4e228f
MT
44668 Dock Station
44669 -------------------------------------------------------------------------- */
44670 struct acpi_dock_ops {
44671- acpi_notify_handler handler;
44672- acpi_notify_handler uevent;
44673+ const acpi_notify_handler handler;
44674+ const acpi_notify_handler uevent;
44675 };
58c5fc13 44676
ae4e228f 44677 #if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
bc901d79 44678@@ -128,7 +128,7 @@ extern int is_dock_device(acpi_handle ha
ae4e228f
MT
44679 extern int register_dock_notifier(struct notifier_block *nb);
44680 extern void unregister_dock_notifier(struct notifier_block *nb);
44681 extern int register_hotplug_dock_device(acpi_handle handle,
44682- struct acpi_dock_ops *ops,
44683+ const struct acpi_dock_ops *ops,
44684 void *context);
44685 extern void unregister_hotplug_dock_device(acpi_handle handle);
44686 #else
bc901d79 44687@@ -144,7 +144,7 @@ static inline void unregister_dock_notif
ae4e228f
MT
44688 {
44689 }
44690 static inline int register_hotplug_dock_device(acpi_handle handle,
44691- struct acpi_dock_ops *ops,
44692+ const struct acpi_dock_ops *ops,
44693 void *context)
44694 {
44695 return -ENODEV;
16454cff
MT
44696diff -urNp linux-2.6.38.1/include/asm-generic/atomic-long.h linux-2.6.38.1/include/asm-generic/atomic-long.h
44697--- linux-2.6.38.1/include/asm-generic/atomic-long.h 2011-03-14 21:20:32.000000000 -0400
44698+++ linux-2.6.38.1/include/asm-generic/atomic-long.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
44699@@ -22,6 +22,12 @@
44700
44701 typedef atomic64_t atomic_long_t;
44702
44703+#ifdef CONFIG_PAX_REFCOUNT
44704+typedef atomic64_unchecked_t atomic_long_unchecked_t;
44705+#else
44706+typedef atomic64_t atomic_long_unchecked_t;
44707+#endif
58c5fc13 44708+
ae4e228f 44709 #define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i)
58c5fc13 44710
ae4e228f
MT
44711 static inline long atomic_long_read(atomic_long_t *l)
44712@@ -31,6 +37,15 @@ static inline long atomic_long_read(atom
44713 return (long)atomic64_read(v);
44714 }
44715
44716+#ifdef CONFIG_PAX_REFCOUNT
44717+static inline long atomic_long_read_unchecked(atomic_long_unchecked_t *l)
44718+{
44719+ atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
58c5fc13 44720+
ae4e228f
MT
44721+ return (long)atomic64_read_unchecked(v);
44722+}
44723+#endif
44724+
44725 static inline void atomic_long_set(atomic_long_t *l, long i)
44726 {
44727 atomic64_t *v = (atomic64_t *)l;
44728@@ -38,6 +53,15 @@ static inline void atomic_long_set(atomi
44729 atomic64_set(v, i);
44730 }
58c5fc13 44731
ae4e228f
MT
44732+#ifdef CONFIG_PAX_REFCOUNT
44733+static inline void atomic_long_set_unchecked(atomic_long_unchecked_t *l, long i)
44734+{
44735+ atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
44736+
44737+ atomic64_set_unchecked(v, i);
44738+}
44739+#endif
44740+
44741 static inline void atomic_long_inc(atomic_long_t *l)
44742 {
44743 atomic64_t *v = (atomic64_t *)l;
44744@@ -45,6 +69,15 @@ static inline void atomic_long_inc(atomi
44745 atomic64_inc(v);
58c5fc13
MT
44746 }
44747
ae4e228f
MT
44748+#ifdef CONFIG_PAX_REFCOUNT
44749+static inline void atomic_long_inc_unchecked(atomic_long_unchecked_t *l)
58c5fc13 44750+{
ae4e228f
MT
44751+ atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
44752+
44753+ atomic64_inc_unchecked(v);
58c5fc13 44754+}
ae4e228f 44755+#endif
58c5fc13 44756+
ae4e228f 44757 static inline void atomic_long_dec(atomic_long_t *l)
58c5fc13 44758 {
ae4e228f 44759 atomic64_t *v = (atomic64_t *)l;
df50ba0c
MT
44760@@ -52,6 +85,15 @@ static inline void atomic_long_dec(atomi
44761 atomic64_dec(v);
44762 }
44763
44764+#ifdef CONFIG_PAX_REFCOUNT
44765+static inline void atomic_long_dec_unchecked(atomic_long_unchecked_t *l)
44766+{
44767+ atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
44768+
44769+ atomic64_dec_unchecked(v);
44770+}
44771+#endif
44772+
44773 static inline void atomic_long_add(long i, atomic_long_t *l)
44774 {
44775 atomic64_t *v = (atomic64_t *)l;
44776@@ -59,6 +101,15 @@ static inline void atomic_long_add(long
ae4e228f 44777 atomic64_add(i, v);
58c5fc13
MT
44778 }
44779
ae4e228f
MT
44780+#ifdef CONFIG_PAX_REFCOUNT
44781+static inline void atomic_long_add_unchecked(long i, atomic_long_unchecked_t *l)
58c5fc13 44782+{
ae4e228f
MT
44783+ atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
44784+
44785+ atomic64_add_unchecked(i, v);
58c5fc13 44786+}
ae4e228f 44787+#endif
58c5fc13 44788+
ae4e228f 44789 static inline void atomic_long_sub(long i, atomic_long_t *l)
58c5fc13 44790 {
ae4e228f 44791 atomic64_t *v = (atomic64_t *)l;
6892158b
MT
44792@@ -66,6 +117,15 @@ static inline void atomic_long_sub(long
44793 atomic64_sub(i, v);
44794 }
44795
44796+#ifdef CONFIG_PAX_REFCOUNT
44797+static inline void atomic_long_sub_unchecked(long i, atomic_long_unchecked_t *l)
44798+{
44799+ atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
44800+
44801+ atomic64_sub_unchecked(i, v);
44802+}
44803+#endif
44804+
44805 static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
44806 {
44807 atomic64_t *v = (atomic64_t *)l;
44808@@ -115,6 +175,15 @@ static inline long atomic_long_inc_retur
ae4e228f 44809 return (long)atomic64_inc_return(v);
58c5fc13
MT
44810 }
44811
ae4e228f
MT
44812+#ifdef CONFIG_PAX_REFCOUNT
44813+static inline long atomic_long_inc_return_unchecked(atomic_long_unchecked_t *l)
58c5fc13 44814+{
ae4e228f
MT
44815+ atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
44816+
44817+ return (long)atomic64_inc_return_unchecked(v);
58c5fc13 44818+}
ae4e228f 44819+#endif
58c5fc13 44820+
ae4e228f
MT
44821 static inline long atomic_long_dec_return(atomic_long_t *l)
44822 {
44823 atomic64_t *v = (atomic64_t *)l;
6892158b 44824@@ -140,6 +209,12 @@ static inline long atomic_long_add_unles
ae4e228f
MT
44825
44826 typedef atomic_t atomic_long_t;
44827
44828+#ifdef CONFIG_PAX_REFCOUNT
44829+typedef atomic_unchecked_t atomic_long_unchecked_t;
44830+#else
44831+typedef atomic_t atomic_long_unchecked_t;
44832+#endif
44833+
44834 #define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i)
44835 static inline long atomic_long_read(atomic_long_t *l)
44836 {
6892158b 44837@@ -148,6 +223,15 @@ static inline long atomic_long_read(atom
ae4e228f
MT
44838 return (long)atomic_read(v);
44839 }
44840
44841+#ifdef CONFIG_PAX_REFCOUNT
44842+static inline long atomic_long_read_unchecked(atomic_long_unchecked_t *l)
44843+{
44844+ atomic_unchecked_t *v = (atomic_unchecked_t *)l;
44845+
44846+ return (long)atomic_read_unchecked(v);
44847+}
44848+#endif
44849+
44850 static inline void atomic_long_set(atomic_long_t *l, long i)
44851 {
44852 atomic_t *v = (atomic_t *)l;
6892158b 44853@@ -155,6 +239,15 @@ static inline void atomic_long_set(atomi
ae4e228f
MT
44854 atomic_set(v, i);
44855 }
44856
44857+#ifdef CONFIG_PAX_REFCOUNT
44858+static inline void atomic_long_set_unchecked(atomic_long_unchecked_t *l, long i)
44859+{
44860+ atomic_unchecked_t *v = (atomic_unchecked_t *)l;
44861+
44862+ atomic_set_unchecked(v, i);
44863+}
44864+#endif
44865+
44866 static inline void atomic_long_inc(atomic_long_t *l)
44867 {
44868 atomic_t *v = (atomic_t *)l;
6892158b 44869@@ -162,6 +255,15 @@ static inline void atomic_long_inc(atomi
ae4e228f
MT
44870 atomic_inc(v);
44871 }
44872
44873+#ifdef CONFIG_PAX_REFCOUNT
44874+static inline void atomic_long_inc_unchecked(atomic_long_unchecked_t *l)
44875+{
44876+ atomic_unchecked_t *v = (atomic_unchecked_t *)l;
44877+
44878+ atomic_inc_unchecked(v);
44879+}
44880+#endif
44881+
44882 static inline void atomic_long_dec(atomic_long_t *l)
44883 {
44884 atomic_t *v = (atomic_t *)l;
6892158b 44885@@ -169,6 +271,15 @@ static inline void atomic_long_dec(atomi
df50ba0c
MT
44886 atomic_dec(v);
44887 }
44888
44889+#ifdef CONFIG_PAX_REFCOUNT
44890+static inline void atomic_long_dec_unchecked(atomic_long_unchecked_t *l)
44891+{
44892+ atomic_unchecked_t *v = (atomic_unchecked_t *)l;
44893+
44894+ atomic_dec_unchecked(v);
44895+}
44896+#endif
44897+
44898 static inline void atomic_long_add(long i, atomic_long_t *l)
44899 {
44900 atomic_t *v = (atomic_t *)l;
6892158b 44901@@ -176,6 +287,15 @@ static inline void atomic_long_add(long
ae4e228f
MT
44902 atomic_add(i, v);
44903 }
44904
44905+#ifdef CONFIG_PAX_REFCOUNT
44906+static inline void atomic_long_add_unchecked(long i, atomic_long_unchecked_t *l)
44907+{
44908+ atomic_unchecked_t *v = (atomic_unchecked_t *)l;
44909+
44910+ atomic_add_unchecked(i, v);
44911+}
44912+#endif
44913+
44914 static inline void atomic_long_sub(long i, atomic_long_t *l)
58c5fc13 44915 {
ae4e228f 44916 atomic_t *v = (atomic_t *)l;
6892158b
MT
44917@@ -183,6 +303,15 @@ static inline void atomic_long_sub(long
44918 atomic_sub(i, v);
44919 }
44920
44921+#ifdef CONFIG_PAX_REFCOUNT
44922+static inline void atomic_long_sub_unchecked(long i, atomic_long_unchecked_t *l)
44923+{
44924+ atomic_unchecked_t *v = (atomic_unchecked_t *)l;
44925+
44926+ atomic_sub_unchecked(i, v);
44927+}
44928+#endif
44929+
44930 static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
44931 {
44932 atomic_t *v = (atomic_t *)l;
44933@@ -232,6 +361,15 @@ static inline long atomic_long_inc_retur
ae4e228f
MT
44934 return (long)atomic_inc_return(v);
44935 }
44936
44937+#ifdef CONFIG_PAX_REFCOUNT
44938+static inline long atomic_long_inc_return_unchecked(atomic_long_unchecked_t *l)
44939+{
44940+ atomic_unchecked_t *v = (atomic_unchecked_t *)l;
44941+
44942+ return (long)atomic_inc_return_unchecked(v);
44943+}
44944+#endif
44945+
44946 static inline long atomic_long_dec_return(atomic_long_t *l)
44947 {
44948 atomic_t *v = (atomic_t *)l;
6892158b 44949@@ -255,4 +393,41 @@ static inline long atomic_long_add_unles
ae4e228f
MT
44950
44951 #endif /* BITS_PER_LONG == 64 */
44952
44953+#ifdef CONFIG_PAX_REFCOUNT
44954+static inline void pax_refcount_needs_these_functions(void)
44955+{
44956+ atomic_read_unchecked((atomic_unchecked_t *)NULL);
44957+ atomic_set_unchecked((atomic_unchecked_t *)NULL, 0);
44958+ atomic_add_unchecked(0, (atomic_unchecked_t *)NULL);
44959+ atomic_sub_unchecked(0, (atomic_unchecked_t *)NULL);
44960+ atomic_inc_unchecked((atomic_unchecked_t *)NULL);
57199397 44961+ atomic_inc_return_unchecked((atomic_unchecked_t *)NULL);
6892158b 44962+ atomic_add_return_unchecked(0, (atomic_unchecked_t *)NULL);
ae4e228f
MT
44963+
44964+ atomic_long_read_unchecked((atomic_long_unchecked_t *)NULL);
44965+ atomic_long_set_unchecked((atomic_long_unchecked_t *)NULL, 0);
44966+ atomic_long_add_unchecked(0, (atomic_long_unchecked_t *)NULL);
6892158b 44967+ atomic_long_sub_unchecked(0, (atomic_long_unchecked_t *)NULL);
ae4e228f
MT
44968+ atomic_long_inc_unchecked((atomic_long_unchecked_t *)NULL);
44969+ atomic_long_inc_return_unchecked((atomic_long_unchecked_t *)NULL);
df50ba0c 44970+ atomic_long_dec_unchecked((atomic_long_unchecked_t *)NULL);
ae4e228f
MT
44971+}
44972+#else
44973+#define atomic_read_unchecked(v) atomic_read(v)
44974+#define atomic_set_unchecked(v, i) atomic_set((v), (i))
44975+#define atomic_add_unchecked(i, v) atomic_add((i), (v))
44976+#define atomic_sub_unchecked(i, v) atomic_sub((i), (v))
44977+#define atomic_inc_unchecked(v) atomic_inc(v)
57199397 44978+#define atomic_inc_return_unchecked(v) atomic_inc_return(v)
6892158b 44979+#define atomic_add_return_unchecked(i, v) atomic_add_return((i), (v))
ae4e228f
MT
44980+
44981+#define atomic_long_read_unchecked(v) atomic_long_read(v)
44982+#define atomic_long_set_unchecked(v, i) atomic_long_set((v), (i))
44983+#define atomic_long_add_unchecked(i, v) atomic_long_add((i), (v))
6892158b 44984+#define atomic_long_sub_unchecked(i, v) atomic_long_sub((i), (v))
ae4e228f
MT
44985+#define atomic_long_inc_unchecked(v) atomic_long_inc(v)
44986+#define atomic_long_inc_return_unchecked(v) atomic_long_inc_return(v)
df50ba0c 44987+#define atomic_long_dec_unchecked(v) atomic_long_dec(v)
ae4e228f
MT
44988+#endif
44989+
44990 #endif /* _ASM_GENERIC_ATOMIC_LONG_H */
16454cff
MT
44991diff -urNp linux-2.6.38.1/include/asm-generic/dma-mapping-common.h linux-2.6.38.1/include/asm-generic/dma-mapping-common.h
44992--- linux-2.6.38.1/include/asm-generic/dma-mapping-common.h 2011-03-14 21:20:32.000000000 -0400
44993+++ linux-2.6.38.1/include/asm-generic/dma-mapping-common.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
44994@@ -11,7 +11,7 @@ static inline dma_addr_t dma_map_single_
44995 enum dma_data_direction dir,
44996 struct dma_attrs *attrs)
44997 {
44998- struct dma_map_ops *ops = get_dma_ops(dev);
44999+ const struct dma_map_ops *ops = get_dma_ops(dev);
45000 dma_addr_t addr;
45001
45002 kmemcheck_mark_initialized(ptr, size);
45003@@ -30,7 +30,7 @@ static inline void dma_unmap_single_attr
45004 enum dma_data_direction dir,
45005 struct dma_attrs *attrs)
45006 {
45007- struct dma_map_ops *ops = get_dma_ops(dev);
45008+ const struct dma_map_ops *ops = get_dma_ops(dev);
45009
45010 BUG_ON(!valid_dma_direction(dir));
45011 if (ops->unmap_page)
45012@@ -42,7 +42,7 @@ static inline int dma_map_sg_attrs(struc
45013 int nents, enum dma_data_direction dir,
45014 struct dma_attrs *attrs)
45015 {
45016- struct dma_map_ops *ops = get_dma_ops(dev);
45017+ const struct dma_map_ops *ops = get_dma_ops(dev);
45018 int i, ents;
45019 struct scatterlist *s;
45020
45021@@ -59,7 +59,7 @@ static inline void dma_unmap_sg_attrs(st
45022 int nents, enum dma_data_direction dir,
45023 struct dma_attrs *attrs)
45024 {
45025- struct dma_map_ops *ops = get_dma_ops(dev);
45026+ const struct dma_map_ops *ops = get_dma_ops(dev);
45027
45028 BUG_ON(!valid_dma_direction(dir));
45029 debug_dma_unmap_sg(dev, sg, nents, dir);
45030@@ -71,7 +71,7 @@ static inline dma_addr_t dma_map_page(st
45031 size_t offset, size_t size,
45032 enum dma_data_direction dir)
45033 {
45034- struct dma_map_ops *ops = get_dma_ops(dev);
45035+ const struct dma_map_ops *ops = get_dma_ops(dev);
45036 dma_addr_t addr;
45037
45038 kmemcheck_mark_initialized(page_address(page) + offset, size);
45039@@ -85,7 +85,7 @@ static inline dma_addr_t dma_map_page(st
45040 static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
45041 size_t size, enum dma_data_direction dir)
45042 {
45043- struct dma_map_ops *ops = get_dma_ops(dev);
45044+ const struct dma_map_ops *ops = get_dma_ops(dev);
45045
45046 BUG_ON(!valid_dma_direction(dir));
45047 if (ops->unmap_page)
45048@@ -97,7 +97,7 @@ static inline void dma_sync_single_for_c
45049 size_t size,
45050 enum dma_data_direction dir)
45051 {
45052- struct dma_map_ops *ops = get_dma_ops(dev);
45053+ const struct dma_map_ops *ops = get_dma_ops(dev);
45054
45055 BUG_ON(!valid_dma_direction(dir));
45056 if (ops->sync_single_for_cpu)
45057@@ -109,7 +109,7 @@ static inline void dma_sync_single_for_d
45058 dma_addr_t addr, size_t size,
45059 enum dma_data_direction dir)
45060 {
45061- struct dma_map_ops *ops = get_dma_ops(dev);
45062+ const struct dma_map_ops *ops = get_dma_ops(dev);
45063
45064 BUG_ON(!valid_dma_direction(dir));
45065 if (ops->sync_single_for_device)
57199397 45066@@ -139,7 +139,7 @@ static inline void
ae4e228f
MT
45067 dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
45068 int nelems, enum dma_data_direction dir)
45069 {
45070- struct dma_map_ops *ops = get_dma_ops(dev);
45071+ const struct dma_map_ops *ops = get_dma_ops(dev);
45072
45073 BUG_ON(!valid_dma_direction(dir));
45074 if (ops->sync_sg_for_cpu)
57199397 45075@@ -151,7 +151,7 @@ static inline void
ae4e228f
MT
45076 dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
45077 int nelems, enum dma_data_direction dir)
45078 {
45079- struct dma_map_ops *ops = get_dma_ops(dev);
45080+ const struct dma_map_ops *ops = get_dma_ops(dev);
45081
45082 BUG_ON(!valid_dma_direction(dir));
45083 if (ops->sync_sg_for_device)
16454cff
MT
45084diff -urNp linux-2.6.38.1/include/asm-generic/futex.h linux-2.6.38.1/include/asm-generic/futex.h
45085--- linux-2.6.38.1/include/asm-generic/futex.h 2011-03-14 21:20:32.000000000 -0400
45086+++ linux-2.6.38.1/include/asm-generic/futex.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
45087@@ -6,7 +6,7 @@
45088 #include <asm/errno.h>
45089
45090 static inline int
45091-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
45092+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
45093 {
45094 int op = (encoded_op >> 28) & 7;
45095 int cmp = (encoded_op >> 24) & 15;
45096@@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
45097 }
45098
45099 static inline int
45100-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
45101+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
45102 {
45103 return -ENOSYS;
45104 }
16454cff
MT
45105diff -urNp linux-2.6.38.1/include/asm-generic/int-l64.h linux-2.6.38.1/include/asm-generic/int-l64.h
45106--- linux-2.6.38.1/include/asm-generic/int-l64.h 2011-03-14 21:20:32.000000000 -0400
45107+++ linux-2.6.38.1/include/asm-generic/int-l64.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
45108@@ -46,6 +46,8 @@ typedef unsigned int u32;
45109 typedef signed long s64;
45110 typedef unsigned long u64;
45111
45112+typedef unsigned int intoverflow_t __attribute__ ((mode(TI)));
45113+
45114 #define S8_C(x) x
45115 #define U8_C(x) x ## U
45116 #define S16_C(x) x
16454cff
MT
45117diff -urNp linux-2.6.38.1/include/asm-generic/int-ll64.h linux-2.6.38.1/include/asm-generic/int-ll64.h
45118--- linux-2.6.38.1/include/asm-generic/int-ll64.h 2011-03-14 21:20:32.000000000 -0400
45119+++ linux-2.6.38.1/include/asm-generic/int-ll64.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
45120@@ -51,6 +51,8 @@ typedef unsigned int u32;
45121 typedef signed long long s64;
45122 typedef unsigned long long u64;
45123
45124+typedef unsigned long long intoverflow_t;
45125+
45126 #define S8_C(x) x
45127 #define U8_C(x) x ## U
45128 #define S16_C(x) x
16454cff
MT
45129diff -urNp linux-2.6.38.1/include/asm-generic/kmap_types.h linux-2.6.38.1/include/asm-generic/kmap_types.h
45130--- linux-2.6.38.1/include/asm-generic/kmap_types.h 2011-03-14 21:20:32.000000000 -0400
45131+++ linux-2.6.38.1/include/asm-generic/kmap_types.h 2011-03-21 18:31:35.000000000 -0400
57199397 45132@@ -29,10 +29,11 @@ KMAP_D(16) KM_IRQ_PTE,
ae4e228f
MT
45133 KMAP_D(17) KM_NMI,
45134 KMAP_D(18) KM_NMI_PTE,
57199397
MT
45135 KMAP_D(19) KM_KDB,
45136+KMAP_D(20) KM_CLEARPAGE,
45137 /*
45138 * Remember to update debug_kmap_atomic() when adding new kmap types!
45139 */
45140-KMAP_D(20) KM_TYPE_NR
45141+KMAP_D(21) KM_TYPE_NR
58c5fc13
MT
45142 };
45143
ae4e228f 45144 #undef KMAP_D
16454cff
MT
45145diff -urNp linux-2.6.38.1/include/asm-generic/pgtable.h linux-2.6.38.1/include/asm-generic/pgtable.h
45146--- linux-2.6.38.1/include/asm-generic/pgtable.h 2011-03-14 21:20:32.000000000 -0400
45147+++ linux-2.6.38.1/include/asm-generic/pgtable.h 2011-03-21 18:31:35.000000000 -0400
45148@@ -447,6 +447,14 @@ static inline int pmd_write(pmd_t pmd)
45149 #endif /* __HAVE_ARCH_PMD_WRITE */
ae4e228f
MT
45150 #endif
45151
45152+#ifndef __HAVE_ARCH_PAX_OPEN_KERNEL
45153+static inline unsigned long pax_open_kernel(void) { return 0; }
45154+#endif
45155+
45156+#ifndef __HAVE_ARCH_PAX_CLOSE_KERNEL
45157+static inline unsigned long pax_close_kernel(void) { return 0; }
45158+#endif
45159+
45160 #endif /* !__ASSEMBLY__ */
45161
45162 #endif /* _ASM_GENERIC_PGTABLE_H */
16454cff
MT
45163diff -urNp linux-2.6.38.1/include/asm-generic/pgtable-nopmd.h linux-2.6.38.1/include/asm-generic/pgtable-nopmd.h
45164--- linux-2.6.38.1/include/asm-generic/pgtable-nopmd.h 2011-03-14 21:20:32.000000000 -0400
45165+++ linux-2.6.38.1/include/asm-generic/pgtable-nopmd.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
45166@@ -1,14 +1,19 @@
45167 #ifndef _PGTABLE_NOPMD_H
45168 #define _PGTABLE_NOPMD_H
45169
45170-#ifndef __ASSEMBLY__
45171-
45172 #include <asm-generic/pgtable-nopud.h>
45173
45174-struct mm_struct;
45175-
45176 #define __PAGETABLE_PMD_FOLDED
45177
45178+#define PMD_SHIFT PUD_SHIFT
45179+#define PTRS_PER_PMD 1
45180+#define PMD_SIZE (_AC(1,UL) << PMD_SHIFT)
45181+#define PMD_MASK (~(PMD_SIZE-1))
45182+
45183+#ifndef __ASSEMBLY__
45184+
45185+struct mm_struct;
45186+
45187 /*
45188 * Having the pmd type consist of a pud gets the size right, and allows
45189 * us to conceptually access the pud entry that this pmd is folded into
45190@@ -16,11 +21,6 @@ struct mm_struct;
45191 */
45192 typedef struct { pud_t pud; } pmd_t;
45193
45194-#define PMD_SHIFT PUD_SHIFT
45195-#define PTRS_PER_PMD 1
45196-#define PMD_SIZE (1UL << PMD_SHIFT)
45197-#define PMD_MASK (~(PMD_SIZE-1))
45198-
45199 /*
45200 * The "pud_xxx()" functions here are trivial for a folded two-level
45201 * setup: the pmd is never bad, and a pmd always exists (as it's folded
16454cff
MT
45202diff -urNp linux-2.6.38.1/include/asm-generic/pgtable-nopud.h linux-2.6.38.1/include/asm-generic/pgtable-nopud.h
45203--- linux-2.6.38.1/include/asm-generic/pgtable-nopud.h 2011-03-14 21:20:32.000000000 -0400
45204+++ linux-2.6.38.1/include/asm-generic/pgtable-nopud.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
45205@@ -1,10 +1,15 @@
45206 #ifndef _PGTABLE_NOPUD_H
45207 #define _PGTABLE_NOPUD_H
45208
45209-#ifndef __ASSEMBLY__
45210-
45211 #define __PAGETABLE_PUD_FOLDED
45212
45213+#define PUD_SHIFT PGDIR_SHIFT
45214+#define PTRS_PER_PUD 1
45215+#define PUD_SIZE (_AC(1,UL) << PUD_SHIFT)
45216+#define PUD_MASK (~(PUD_SIZE-1))
45217+
45218+#ifndef __ASSEMBLY__
45219+
45220 /*
45221 * Having the pud type consist of a pgd gets the size right, and allows
45222 * us to conceptually access the pgd entry that this pud is folded into
45223@@ -12,11 +17,6 @@
45224 */
45225 typedef struct { pgd_t pgd; } pud_t;
45226
45227-#define PUD_SHIFT PGDIR_SHIFT
45228-#define PTRS_PER_PUD 1
45229-#define PUD_SIZE (1UL << PUD_SHIFT)
45230-#define PUD_MASK (~(PUD_SIZE-1))
45231-
45232 /*
45233 * The "pgd_xxx()" functions here are trivial for a folded two-level
45234 * setup: the pud is never bad, and a pud always exists (as it's folded
16454cff
MT
45235diff -urNp linux-2.6.38.1/include/asm-generic/vmlinux.lds.h linux-2.6.38.1/include/asm-generic/vmlinux.lds.h
45236--- linux-2.6.38.1/include/asm-generic/vmlinux.lds.h 2011-03-14 21:20:32.000000000 -0400
45237+++ linux-2.6.38.1/include/asm-generic/vmlinux.lds.h 2011-03-21 18:31:35.000000000 -0400
45238@@ -213,6 +213,7 @@
58c5fc13
MT
45239 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
45240 VMLINUX_SYMBOL(__start_rodata) = .; \
45241 *(.rodata) *(.rodata.*) \
57199397 45242+ *(.data..read_only) \
58c5fc13 45243 *(__vermagic) /* Kernel version magic */ \
16454cff
MT
45244 . = ALIGN(8); \
45245 VMLINUX_SYMBOL(__start___tracepoints_ptrs) = .; \
45246@@ -696,14 +697,15 @@
58c5fc13
MT
45247 * section in the linker script will go there too. @phdr should have
45248 * a leading colon.
45249 *
45250- * Note that this macros defines __per_cpu_load as an absolute symbol.
45251+ * Note that this macros defines per_cpu_load as an absolute symbol.
45252 * If there is no need to put the percpu section at a predetermined
45253 * address, use PERCPU().
45254 */
45255 #define PERCPU_VADDR(vaddr, phdr) \
45256- VMLINUX_SYMBOL(__per_cpu_load) = .; \
57199397 45257- .data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
58c5fc13 45258+ per_cpu_load = .; \
57199397 45259+ .data..percpu vaddr : AT(VMLINUX_SYMBOL(per_cpu_load) \
58c5fc13
MT
45260 - LOAD_OFFSET) { \
45261+ VMLINUX_SYMBOL(__per_cpu_load) = . + per_cpu_load; \
45262 VMLINUX_SYMBOL(__per_cpu_start) = .; \
57199397 45263 *(.data..percpu..first) \
bc901d79 45264 . = ALIGN(PAGE_SIZE); \
16454cff 45265@@ -713,7 +715,7 @@
57199397 45266 *(.data..percpu..shared_aligned) \
58c5fc13
MT
45267 VMLINUX_SYMBOL(__per_cpu_end) = .; \
45268 } phdr \
57199397
MT
45269- . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu);
45270+ . = VMLINUX_SYMBOL(per_cpu_load) + SIZEOF(.data..percpu);
58c5fc13
MT
45271
45272 /**
45273 * PERCPU - define output section for percpu area, simple version
16454cff
MT
45274diff -urNp linux-2.6.38.1/include/drm/drm_pciids.h linux-2.6.38.1/include/drm/drm_pciids.h
45275--- linux-2.6.38.1/include/drm/drm_pciids.h 2011-03-14 21:20:32.000000000 -0400
45276+++ linux-2.6.38.1/include/drm/drm_pciids.h 2011-03-21 18:31:35.000000000 -0400
45277@@ -458,7 +458,7 @@
45278 {0x1002, 0x9803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
45279 {0x1002, 0x9804, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
45280 {0x1002, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
58c5fc13
MT
45281- {0, 0, 0}
45282+ {0, 0, 0, 0, 0, 0}
45283
45284 #define r128_PCI_IDS \
45285 {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
16454cff 45286@@ -498,14 +498,14 @@
58c5fc13
MT
45287 {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45288 {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45289 {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45290- {0, 0, 0}
45291+ {0, 0, 0, 0, 0, 0}
45292
45293 #define mga_PCI_IDS \
45294 {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
45295 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
45296 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
45297 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
45298- {0, 0, 0}
45299+ {0, 0, 0, 0, 0, 0}
45300
45301 #define mach64_PCI_IDS \
45302 {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
16454cff 45303@@ -528,7 +528,7 @@
58c5fc13
MT
45304 {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45305 {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45306 {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45307- {0, 0, 0}
45308+ {0, 0, 0, 0, 0, 0}
45309
45310 #define sisdrv_PCI_IDS \
45311 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
16454cff 45312@@ -539,7 +539,7 @@
58c5fc13
MT
45313 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45314 {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
45315 {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
45316- {0, 0, 0}
45317+ {0, 0, 0, 0, 0, 0}
45318
45319 #define tdfx_PCI_IDS \
45320 {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
16454cff 45321@@ -548,7 +548,7 @@
58c5fc13
MT
45322 {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45323 {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45324 {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45325- {0, 0, 0}
45326+ {0, 0, 0, 0, 0, 0}
45327
45328 #define viadrv_PCI_IDS \
45329 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
16454cff 45330@@ -560,14 +560,14 @@
58c5fc13
MT
45331 {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45332 {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
45333 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
45334- {0, 0, 0}
45335+ {0, 0, 0, 0, 0, 0}
45336
45337 #define i810_PCI_IDS \
45338 {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45339 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45340 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45341 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45342- {0, 0, 0}
45343+ {0, 0, 0, 0, 0, 0}
45344
45345 #define i830_PCI_IDS \
45346 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
16454cff 45347@@ -575,11 +575,11 @@
58c5fc13
MT
45348 {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45349 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45350 {0x8086, 0x358e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45351- {0, 0, 0}
45352+ {0, 0, 0, 0, 0, 0}
45353
45354 #define gamma_PCI_IDS \
45355 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
45356- {0, 0, 0}
45357+ {0, 0, 0, 0, 0, 0}
45358
45359 #define savage_PCI_IDS \
45360 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
16454cff 45361@@ -605,10 +605,10 @@
58c5fc13
MT
45362 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
45363 {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
45364 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
45365- {0, 0, 0}
45366+ {0, 0, 0, 0, 0, 0}
45367
45368 #define ffb_PCI_IDS \
45369- {0, 0, 0}
45370+ {0, 0, 0, 0, 0, 0}
45371
45372 #define i915_PCI_IDS \
45373 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
16454cff 45374@@ -642,4 +642,4 @@
58c5fc13
MT
45375 {0x8086, 0x0042, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
45376 {0x8086, 0x0046, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
df50ba0c 45377 {0x8086, 0x0102, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
58c5fc13
MT
45378- {0, 0, 0}
45379+ {0, 0, 0, 0, 0, 0}
16454cff
MT
45380diff -urNp linux-2.6.38.1/include/drm/drmP.h linux-2.6.38.1/include/drm/drmP.h
45381--- linux-2.6.38.1/include/drm/drmP.h 2011-03-14 21:20:32.000000000 -0400
45382+++ linux-2.6.38.1/include/drm/drmP.h 2011-03-21 18:31:35.000000000 -0400
c52201e0
MT
45383@@ -73,6 +73,7 @@
45384 #include <linux/workqueue.h>
45385 #include <linux/poll.h>
45386 #include <asm/pgalloc.h>
45387+#include <asm/local.h>
45388 #include "drm.h"
45389
45390 #include <linux/idr.h>
16454cff 45391@@ -881,7 +882,7 @@ struct drm_driver {
57199397
MT
45392 void (*vgaarb_irq)(struct drm_device *dev, bool state);
45393
45394 /* Driver private ops for this object */
45395- struct vm_operations_struct *gem_vm_ops;
45396+ const struct vm_operations_struct *gem_vm_ops;
45397
45398 int major;
45399 int minor;
16454cff 45400@@ -894,7 +895,7 @@ struct drm_driver {
bc901d79
MT
45401 int dev_priv_size;
45402 struct drm_ioctl_desc *ioctls;
45403 int num_ioctls;
45404- struct file_operations fops;
45405+ const struct file_operations fops;
45406 struct pci_driver pci_driver;
45407 struct platform_device *platform_device;
45408 /* List of devices hanging off this driver */
16454cff 45409@@ -991,7 +992,7 @@ struct drm_device {
57199397
MT
45410
45411 /** \name Usage Counters */
45412 /*@{ */
45413- int open_count; /**< Outstanding files open */
c52201e0 45414+ local_t open_count; /**< Outstanding files open */
57199397
MT
45415 atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
45416 atomic_t vma_count; /**< Outstanding vma areas open */
45417 int buf_use; /**< Buffers in use -- cannot alloc */
16454cff 45418@@ -1002,7 +1003,7 @@ struct drm_device {
57199397
MT
45419 /*@{ */
45420 unsigned long counters;
45421 enum drm_stat_type types[15];
45422- atomic_t counts[15];
45423+ atomic_unchecked_t counts[15];
45424 /*@} */
45425
45426 struct list_head filelist;
16454cff
MT
45427@@ -1101,7 +1102,7 @@ struct drm_device {
45428 struct platform_device *platformdev; /**< Platform device struture */
45429
45430 struct drm_sg_mem *sg; /**< Scatter gather memory */
45431- unsigned int num_crtcs; /**< Number of CRTCs on this device */
45432+ unsigned int num_crtcs; /**< Number of CRTCs on this device */
45433 void *dev_private; /**< device private data */
45434 void *mm_private;
45435 struct address_space *dev_mapping;
45436diff -urNp linux-2.6.38.1/include/linux/a.out.h linux-2.6.38.1/include/linux/a.out.h
45437--- linux-2.6.38.1/include/linux/a.out.h 2011-03-14 21:20:32.000000000 -0400
45438+++ linux-2.6.38.1/include/linux/a.out.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
45439@@ -39,6 +39,14 @@ enum machine_type {
45440 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
45441 };
45442
45443+/* Constants for the N_FLAGS field */
45444+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
45445+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
45446+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
45447+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
45448+/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
45449+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
45450+
45451 #if !defined (N_MAGIC)
45452 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
45453 #endif
16454cff
MT
45454diff -urNp linux-2.6.38.1/include/linux/atmdev.h linux-2.6.38.1/include/linux/atmdev.h
45455--- linux-2.6.38.1/include/linux/atmdev.h 2011-03-14 21:20:32.000000000 -0400
45456+++ linux-2.6.38.1/include/linux/atmdev.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
45457@@ -237,7 +237,7 @@ struct compat_atm_iobuf {
45458 #endif
45459
45460 struct k_atm_aal_stats {
45461-#define __HANDLE_ITEM(i) atomic_t i
45462+#define __HANDLE_ITEM(i) atomic_unchecked_t i
45463 __AAL_STAT_ITEMS
45464 #undef __HANDLE_ITEM
45465 };
16454cff
MT
45466diff -urNp linux-2.6.38.1/include/linux/binfmts.h linux-2.6.38.1/include/linux/binfmts.h
45467--- linux-2.6.38.1/include/linux/binfmts.h 2011-03-14 21:20:32.000000000 -0400
45468+++ linux-2.6.38.1/include/linux/binfmts.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 45469@@ -92,6 +92,7 @@ struct linux_binfmt {
58c5fc13
MT
45470 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
45471 int (*load_shlib)(struct file *);
ae4e228f 45472 int (*core_dump)(struct coredump_params *cprm);
58c5fc13
MT
45473+ void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags);
45474 unsigned long min_coredump; /* minimal dump size */
58c5fc13 45475 };
16454cff
MT
45476
45477diff -urNp linux-2.6.38.1/include/linux/blkdev.h linux-2.6.38.1/include/linux/blkdev.h
45478--- linux-2.6.38.1/include/linux/blkdev.h 2011-03-14 21:20:32.000000000 -0400
45479+++ linux-2.6.38.1/include/linux/blkdev.h 2011-03-21 18:31:35.000000000 -0400
45480@@ -1247,22 +1247,22 @@ queue_max_integrity_segments(struct requ
ae4e228f
MT
45481 #endif /* CONFIG_BLK_DEV_INTEGRITY */
45482
45483 struct block_device_operations {
45484- int (*open) (struct block_device *, fmode_t);
45485- int (*release) (struct gendisk *, fmode_t);
ae4e228f
MT
45486- int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
45487- int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
45488- int (*direct_access) (struct block_device *, sector_t,
45489+ int (* const open) (struct block_device *, fmode_t);
45490+ int (* const release) (struct gendisk *, fmode_t);
ae4e228f
MT
45491+ int (* const ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
45492+ int (* const compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
45493+ int (* const direct_access) (struct block_device *, sector_t,
45494 void **, unsigned long *);
16454cff
MT
45495- unsigned int (*check_events) (struct gendisk *disk,
45496+ unsigned int (* const check_events) (struct gendisk *disk,
45497 unsigned int clearing);
45498 /* ->media_changed() is DEPRECATED, use ->check_events() instead */
ae4e228f 45499- int (*media_changed) (struct gendisk *);
57199397 45500- void (*unlock_native_capacity) (struct gendisk *);
ae4e228f
MT
45501- int (*revalidate_disk) (struct gendisk *);
45502- int (*getgeo)(struct block_device *, struct hd_geometry *);
57199397
MT
45503+ int (* const media_changed) (struct gendisk *);
45504+ void (* const unlock_native_capacity) (struct gendisk *);
ae4e228f 45505+ int (* const revalidate_disk) (struct gendisk *);
6892158b 45506+ int (* const getgeo)(struct block_device *, struct hd_geometry *);
57199397
MT
45507 /* this callback is with swap_lock and sometimes page table lock held */
45508- void (*swap_slot_free_notify) (struct block_device *, unsigned long);
45509- struct module *owner;
45510+ void (* const swap_slot_free_notify) (struct block_device *, unsigned long);
ae4e228f
MT
45511+ struct module * const owner;
45512 };
45513
45514 extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
16454cff
MT
45515diff -urNp linux-2.6.38.1/include/linux/byteorder/little_endian.h linux-2.6.38.1/include/linux/byteorder/little_endian.h
45516--- linux-2.6.38.1/include/linux/byteorder/little_endian.h 2011-03-14 21:20:32.000000000 -0400
45517+++ linux-2.6.38.1/include/linux/byteorder/little_endian.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
45518@@ -42,51 +42,51 @@
45519
45520 static inline __le64 __cpu_to_le64p(const __u64 *p)
45521 {
45522- return (__force __le64)*p;
45523+ return (__force const __le64)*p;
45524 }
45525 static inline __u64 __le64_to_cpup(const __le64 *p)
45526 {
45527- return (__force __u64)*p;
45528+ return (__force const __u64)*p;
45529 }
45530 static inline __le32 __cpu_to_le32p(const __u32 *p)
45531 {
45532- return (__force __le32)*p;
45533+ return (__force const __le32)*p;
45534 }
45535 static inline __u32 __le32_to_cpup(const __le32 *p)
45536 {
45537- return (__force __u32)*p;
45538+ return (__force const __u32)*p;
45539 }
45540 static inline __le16 __cpu_to_le16p(const __u16 *p)
45541 {
45542- return (__force __le16)*p;
45543+ return (__force const __le16)*p;
45544 }
45545 static inline __u16 __le16_to_cpup(const __le16 *p)
45546 {
45547- return (__force __u16)*p;
45548+ return (__force const __u16)*p;
45549 }
45550 static inline __be64 __cpu_to_be64p(const __u64 *p)
45551 {
45552- return (__force __be64)__swab64p(p);
45553+ return (__force const __be64)__swab64p(p);
45554 }
45555 static inline __u64 __be64_to_cpup(const __be64 *p)
45556 {
45557- return __swab64p((__u64 *)p);
45558+ return __swab64p((const __u64 *)p);
45559 }
45560 static inline __be32 __cpu_to_be32p(const __u32 *p)
45561 {
45562- return (__force __be32)__swab32p(p);
45563+ return (__force const __be32)__swab32p(p);
45564 }
45565 static inline __u32 __be32_to_cpup(const __be32 *p)
45566 {
45567- return __swab32p((__u32 *)p);
45568+ return __swab32p((const __u32 *)p);
45569 }
45570 static inline __be16 __cpu_to_be16p(const __u16 *p)
45571 {
45572- return (__force __be16)__swab16p(p);
45573+ return (__force const __be16)__swab16p(p);
45574 }
45575 static inline __u16 __be16_to_cpup(const __be16 *p)
45576 {
45577- return __swab16p((__u16 *)p);
45578+ return __swab16p((const __u16 *)p);
45579 }
45580 #define __cpu_to_le64s(x) do { (void)(x); } while (0)
45581 #define __le64_to_cpus(x) do { (void)(x); } while (0)
16454cff
MT
45582diff -urNp linux-2.6.38.1/include/linux/cache.h linux-2.6.38.1/include/linux/cache.h
45583--- linux-2.6.38.1/include/linux/cache.h 2011-03-14 21:20:32.000000000 -0400
45584+++ linux-2.6.38.1/include/linux/cache.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
45585@@ -16,6 +16,10 @@
45586 #define __read_mostly
45587 #endif
45588
45589+#ifndef __read_only
45590+#define __read_only __read_mostly
45591+#endif
45592+
45593 #ifndef ____cacheline_aligned
45594 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
45595 #endif
16454cff
MT
45596diff -urNp linux-2.6.38.1/include/linux/capability.h linux-2.6.38.1/include/linux/capability.h
45597--- linux-2.6.38.1/include/linux/capability.h 2011-03-14 21:20:32.000000000 -0400
45598+++ linux-2.6.38.1/include/linux/capability.h 2011-03-21 18:31:35.000000000 -0400
45599@@ -561,6 +561,7 @@ extern const kernel_cap_t __cap_init_eff
58c5fc13
MT
45600 (security_real_capable_noaudit((t), (cap)) == 0)
45601
45602 extern int capable(int cap);
45603+int capable_nolog(int cap);
45604
45605 /* audit system wants to get cap info from files as well */
45606 struct dentry;
16454cff
MT
45607diff -urNp linux-2.6.38.1/include/linux/compiler-gcc4.h linux-2.6.38.1/include/linux/compiler-gcc4.h
45608--- linux-2.6.38.1/include/linux/compiler-gcc4.h 2011-03-14 21:20:32.000000000 -0400
45609+++ linux-2.6.38.1/include/linux/compiler-gcc4.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
45610@@ -54,6 +54,10 @@
45611
ae4e228f 45612 #endif
58c5fc13
MT
45613
45614+#define __alloc_size(...) __attribute((alloc_size(__VA_ARGS__)))
45615+#define __bos(ptr, arg) __builtin_object_size((ptr), (arg))
45616+#define __bos0(ptr) __bos((ptr), 0)
45617+#define __bos1(ptr) __bos((ptr), 1)
45618 #endif
ae4e228f
MT
45619
45620 #if __GNUC_MINOR__ > 0
16454cff
MT
45621diff -urNp linux-2.6.38.1/include/linux/compiler.h linux-2.6.38.1/include/linux/compiler.h
45622--- linux-2.6.38.1/include/linux/compiler.h 2011-03-14 21:20:32.000000000 -0400
45623+++ linux-2.6.38.1/include/linux/compiler.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 45624@@ -273,6 +273,22 @@ void ftrace_likely_update(struct ftrace_
58c5fc13
MT
45625 #define __cold
45626 #endif
45627
45628+#ifndef __alloc_size
45629+#define __alloc_size
45630+#endif
45631+
45632+#ifndef __bos
45633+#define __bos
45634+#endif
45635+
45636+#ifndef __bos0
45637+#define __bos0
45638+#endif
45639+
45640+#ifndef __bos1
45641+#define __bos1
45642+#endif
45643+
45644 /* Simple shorthand for a section definition */
45645 #ifndef __section
45646 # define __section(S) __attribute__ ((__section__(#S)))
bc901d79
MT
45647@@ -306,6 +322,7 @@ void ftrace_likely_update(struct ftrace_
45648 * use is to mediate communication between process-level code and irq/NMI
45649 * handlers, all running on the same CPU.
45650 */
45651-#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
45652+#define ACCESS_ONCE(x) (*(volatile const typeof(x) *)&(x))
45653+#define ACCESS_ONCE_RW(x) (*(volatile typeof(x) *)&(x))
45654
45655 #endif /* __LINUX_COMPILER_H */
16454cff
MT
45656diff -urNp linux-2.6.38.1/include/linux/cpuset.h linux-2.6.38.1/include/linux/cpuset.h
45657--- linux-2.6.38.1/include/linux/cpuset.h 2011-03-14 21:20:32.000000000 -0400
45658+++ linux-2.6.38.1/include/linux/cpuset.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
45659@@ -118,7 +118,7 @@ static inline void put_mems_allowed(void
45660 * nodemask.
45661 */
45662 smp_mb();
45663- --ACCESS_ONCE(current->mems_allowed_change_disable);
45664+ --ACCESS_ONCE_RW(current->mems_allowed_change_disable);
45665 }
45666
45667 static inline void set_mems_allowed(nodemask_t nodemask)
16454cff
MT
45668diff -urNp linux-2.6.38.1/include/linux/decompress/mm.h linux-2.6.38.1/include/linux/decompress/mm.h
45669--- linux-2.6.38.1/include/linux/decompress/mm.h 2011-03-14 21:20:32.000000000 -0400
45670+++ linux-2.6.38.1/include/linux/decompress/mm.h 2011-03-21 18:31:35.000000000 -0400
45671@@ -77,7 +77,7 @@ static void free(void *where)
58c5fc13
MT
45672 * warnings when not needed (indeed large_malloc / large_free are not
45673 * needed by inflate */
45674
45675-#define malloc(a) kmalloc(a, GFP_KERNEL)
45676+#define malloc(a) kmalloc((a), GFP_KERNEL)
45677 #define free(a) kfree(a)
45678
45679 #define large_malloc(a) vmalloc(a)
16454cff
MT
45680diff -urNp linux-2.6.38.1/include/linux/dma-mapping.h linux-2.6.38.1/include/linux/dma-mapping.h
45681--- linux-2.6.38.1/include/linux/dma-mapping.h 2011-03-14 21:20:32.000000000 -0400
45682+++ linux-2.6.38.1/include/linux/dma-mapping.h 2011-03-21 18:31:35.000000000 -0400
57199397 45683@@ -16,40 +16,40 @@ enum dma_data_direction {
ae4e228f
MT
45684 };
45685
45686 struct dma_map_ops {
45687- void* (*alloc_coherent)(struct device *dev, size_t size,
45688+ void* (* const alloc_coherent)(struct device *dev, size_t size,
45689 dma_addr_t *dma_handle, gfp_t gfp);
45690- void (*free_coherent)(struct device *dev, size_t size,
45691+ void (* const free_coherent)(struct device *dev, size_t size,
45692 void *vaddr, dma_addr_t dma_handle);
45693- dma_addr_t (*map_page)(struct device *dev, struct page *page,
45694+ dma_addr_t (* const map_page)(struct device *dev, struct page *page,
45695 unsigned long offset, size_t size,
45696 enum dma_data_direction dir,
45697 struct dma_attrs *attrs);
45698- void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
45699+ void (* const unmap_page)(struct device *dev, dma_addr_t dma_handle,
45700 size_t size, enum dma_data_direction dir,
45701 struct dma_attrs *attrs);
45702- int (*map_sg)(struct device *dev, struct scatterlist *sg,
45703+ int (* const map_sg)(struct device *dev, struct scatterlist *sg,
45704 int nents, enum dma_data_direction dir,
45705 struct dma_attrs *attrs);
45706- void (*unmap_sg)(struct device *dev,
45707+ void (* const unmap_sg)(struct device *dev,
45708 struct scatterlist *sg, int nents,
45709 enum dma_data_direction dir,
45710 struct dma_attrs *attrs);
45711- void (*sync_single_for_cpu)(struct device *dev,
45712+ void (* const sync_single_for_cpu)(struct device *dev,
45713 dma_addr_t dma_handle, size_t size,
45714 enum dma_data_direction dir);
45715- void (*sync_single_for_device)(struct device *dev,
45716+ void (* const sync_single_for_device)(struct device *dev,
45717 dma_addr_t dma_handle, size_t size,
45718 enum dma_data_direction dir);
ae4e228f
MT
45719- void (*sync_sg_for_cpu)(struct device *dev,
45720+ void (* const sync_sg_for_cpu)(struct device *dev,
45721 struct scatterlist *sg, int nents,
45722 enum dma_data_direction dir);
45723- void (*sync_sg_for_device)(struct device *dev,
45724+ void (* const sync_sg_for_device)(struct device *dev,
45725 struct scatterlist *sg, int nents,
45726 enum dma_data_direction dir);
45727- int (*mapping_error)(struct device *dev, dma_addr_t dma_addr);
45728- int (*dma_supported)(struct device *dev, u64 mask);
45729- int (*set_dma_mask)(struct device *dev, u64 mask);
45730- int is_phys;
45731+ int (* const mapping_error)(struct device *dev, dma_addr_t dma_addr);
45732+ int (* const dma_supported)(struct device *dev, u64 mask);
45733+ int (* set_dma_mask)(struct device *dev, u64 mask);
45734+ const int is_phys;
45735 };
45736
45737 #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
16454cff
MT
45738diff -urNp linux-2.6.38.1/include/linux/elf.h linux-2.6.38.1/include/linux/elf.h
45739--- linux-2.6.38.1/include/linux/elf.h 2011-03-14 21:20:32.000000000 -0400
45740+++ linux-2.6.38.1/include/linux/elf.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
45741@@ -49,6 +49,17 @@ typedef __s64 Elf64_Sxword;
45742 #define PT_GNU_EH_FRAME 0x6474e550
45743
45744 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
45745+#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
45746+
45747+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
45748+
45749+/* Constants for the e_flags field */
45750+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
45751+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
45752+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
45753+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
45754+/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
45755+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
45756
df50ba0c
MT
45757 /*
45758 * Extended Numbering
45759@@ -106,6 +117,8 @@ typedef __s64 Elf64_Sxword;
58c5fc13
MT
45760 #define DT_DEBUG 21
45761 #define DT_TEXTREL 22
45762 #define DT_JMPREL 23
45763+#define DT_FLAGS 30
45764+ #define DF_TEXTREL 0x00000004
45765 #define DT_ENCODING 32
45766 #define OLD_DT_LOOS 0x60000000
45767 #define DT_LOOS 0x6000000d
df50ba0c 45768@@ -252,6 +265,19 @@ typedef struct elf64_hdr {
58c5fc13
MT
45769 #define PF_W 0x2
45770 #define PF_X 0x1
45771
45772+#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
45773+#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
45774+#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
45775+#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
45776+#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
45777+#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
45778+/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
45779+/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
45780+#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
45781+#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
45782+#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
45783+#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
45784+
45785 typedef struct elf32_phdr{
45786 Elf32_Word p_type;
45787 Elf32_Off p_offset;
df50ba0c 45788@@ -344,6 +370,8 @@ typedef struct elf64_shdr {
58c5fc13
MT
45789 #define EI_OSABI 7
45790 #define EI_PAD 8
45791
45792+#define EI_PAX 14
45793+
45794 #define ELFMAG0 0x7f /* EI_MAG */
45795 #define ELFMAG1 'E'
45796 #define ELFMAG2 'L'
57199397 45797@@ -421,6 +449,7 @@ extern Elf32_Dyn _DYNAMIC [];
58c5fc13
MT
45798 #define elf_note elf32_note
45799 #define elf_addr_t Elf32_Off
df50ba0c 45800 #define Elf_Half Elf32_Half
58c5fc13
MT
45801+#define elf_dyn Elf32_Dyn
45802
45803 #else
45804
57199397 45805@@ -431,6 +460,7 @@ extern Elf64_Dyn _DYNAMIC [];
58c5fc13
MT
45806 #define elf_note elf64_note
45807 #define elf_addr_t Elf64_Off
df50ba0c 45808 #define Elf_Half Elf64_Half
58c5fc13
MT
45809+#define elf_dyn Elf64_Dyn
45810
45811 #endif
45812
16454cff
MT
45813diff -urNp linux-2.6.38.1/include/linux/fs.h linux-2.6.38.1/include/linux/fs.h
45814--- linux-2.6.38.1/include/linux/fs.h 2011-03-14 21:20:32.000000000 -0400
45815+++ linux-2.6.38.1/include/linux/fs.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
45816@@ -105,6 +105,11 @@ struct inodes_stat_t {
45817 /* File was opened by fanotify and shouldn't generate fanotify events */
45818 #define FMODE_NONOTIFY ((__force fmode_t)0x1000000)
58c5fc13
MT
45819
45820+/* Hack for grsec so as not to require read permission simply to execute
ae4e228f
MT
45821+ * a binary
45822+ */
bc901d79 45823+#define FMODE_GREXEC ((__force fmode_t)0x2000000)
58c5fc13 45824+
bc901d79
MT
45825 /*
45826 * The below are the various read and write types that we support. Some of
45827 * them include behavioral modifiers that send information down to the
16454cff 45828@@ -581,42 +586,42 @@ typedef int (*read_actor_t)(read_descrip
ae4e228f
MT
45829 unsigned long, unsigned long);
45830
45831 struct address_space_operations {
45832- int (*writepage)(struct page *page, struct writeback_control *wbc);
45833- int (*readpage)(struct file *, struct page *);
45834- void (*sync_page)(struct page *);
45835+ int (* const writepage)(struct page *page, struct writeback_control *wbc);
45836+ int (* const readpage)(struct file *, struct page *);
45837+ void (* const sync_page)(struct page *);
45838
45839 /* Write back some dirty pages from this mapping. */
45840- int (*writepages)(struct address_space *, struct writeback_control *);
45841+ int (* const writepages)(struct address_space *, struct writeback_control *);
45842
45843 /* Set a page dirty. Return true if this dirtied it */
45844- int (*set_page_dirty)(struct page *page);
45845+ int (* const set_page_dirty)(struct page *page);
45846
45847- int (*readpages)(struct file *filp, struct address_space *mapping,
45848+ int (* const readpages)(struct file *filp, struct address_space *mapping,
45849 struct list_head *pages, unsigned nr_pages);
45850
45851- int (*write_begin)(struct file *, struct address_space *mapping,
45852+ int (* const write_begin)(struct file *, struct address_space *mapping,
45853 loff_t pos, unsigned len, unsigned flags,
45854 struct page **pagep, void **fsdata);
45855- int (*write_end)(struct file *, struct address_space *mapping,
45856+ int (* const write_end)(struct file *, struct address_space *mapping,
45857 loff_t pos, unsigned len, unsigned copied,
45858 struct page *page, void *fsdata);
45859
45860 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
45861- sector_t (*bmap)(struct address_space *, sector_t);
45862- void (*invalidatepage) (struct page *, unsigned long);
45863- int (*releasepage) (struct page *, gfp_t);
bc901d79 45864- void (*freepage)(struct page *);
ae4e228f
MT
45865- ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
45866+ sector_t (* const bmap)(struct address_space *, sector_t);
45867+ void (* const invalidatepage) (struct page *, unsigned long);
45868+ int (* const releasepage) (struct page *, gfp_t);
bc901d79 45869+ void (* const freepage)(struct page *);
ae4e228f
MT
45870+ ssize_t (* const direct_IO)(int, struct kiocb *, const struct iovec *iov,
45871 loff_t offset, unsigned long nr_segs);
45872- int (*get_xip_mem)(struct address_space *, pgoff_t, int,
45873+ int (* const get_xip_mem)(struct address_space *, pgoff_t, int,
45874 void **, unsigned long *);
45875 /* migrate the contents of a page to the specified target */
45876- int (*migratepage) (struct address_space *,
45877+ int (* const migratepage) (struct address_space *,
45878 struct page *, struct page *);
45879- int (*launder_page) (struct page *);
45880- int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
45881+ int (* const launder_page) (struct page *);
45882+ int (* const is_partially_uptodate) (struct page *, read_descriptor_t *,
45883 unsigned long);
45884- int (*error_remove_page)(struct address_space *, struct page *);
45885+ int (* const error_remove_page)(struct address_space *, struct page *);
45886 };
45887
45888 /*
16454cff 45889@@ -1059,17 +1064,17 @@ static inline int file_check_writeable(s
ae4e228f
MT
45890 typedef struct files_struct *fl_owner_t;
45891
45892 struct file_lock_operations {
45893- void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
45894- void (*fl_release_private)(struct file_lock *);
45895+ void (* const fl_copy_lock)(struct file_lock *, struct file_lock *);
45896+ void (* const fl_release_private)(struct file_lock *);
45897 };
45898
45899 struct lock_manager_operations {
45900- int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
45901- void (*fl_notify)(struct file_lock *); /* unblock callback */
45902- int (*fl_grant)(struct file_lock *, struct file_lock *, int);
ae4e228f
MT
45903- void (*fl_release_private)(struct file_lock *);
45904- void (*fl_break)(struct file_lock *);
ae4e228f
MT
45905- int (*fl_change)(struct file_lock **, int);
45906+ int (* const fl_compare_owner)(struct file_lock *, struct file_lock *);
45907+ void (* const fl_notify)(struct file_lock *); /* unblock callback */
45908+ int (* const fl_grant)(struct file_lock *, struct file_lock *, int);
ae4e228f
MT
45909+ void (* const fl_release_private)(struct file_lock *);
45910+ void (* const fl_break)(struct file_lock *);
ae4e228f
MT
45911+ int (* const fl_change)(struct file_lock **, int);
45912 };
45913
45914 struct lock_manager {
16454cff 45915@@ -1604,29 +1609,29 @@ extern ssize_t vfs_writev(struct file *,
ae4e228f
MT
45916 unsigned long, loff_t *);
45917
45918 struct super_operations {
45919- struct inode *(*alloc_inode)(struct super_block *sb);
45920- void (*destroy_inode)(struct inode *);
45921+ struct inode *(* const alloc_inode)(struct super_block *sb);
45922+ void (* const destroy_inode)(struct inode *);
45923
45924- void (*dirty_inode) (struct inode *);
df50ba0c 45925- int (*write_inode) (struct inode *, struct writeback_control *wbc);
6892158b
MT
45926- int (*drop_inode) (struct inode *);
45927- void (*evict_inode) (struct inode *);
ae4e228f
MT
45928- void (*put_super) (struct super_block *);
45929- void (*write_super) (struct super_block *);
45930- int (*sync_fs)(struct super_block *sb, int wait);
45931- int (*freeze_fs) (struct super_block *);
45932- int (*unfreeze_fs) (struct super_block *);
45933- int (*statfs) (struct dentry *, struct kstatfs *);
45934- int (*remount_fs) (struct super_block *, int *, char *);
ae4e228f
MT
45935- void (*umount_begin) (struct super_block *);
45936+ void (* const dirty_inode) (struct inode *);
df50ba0c 45937+ int (* const write_inode) (struct inode *, struct writeback_control *wbc);
6892158b
MT
45938+ int (* const drop_inode) (struct inode *);
45939+ void (* const evict_inode) (struct inode *);
ae4e228f
MT
45940+ void (* const put_super) (struct super_block *);
45941+ void (* const write_super) (struct super_block *);
45942+ int (* const sync_fs)(struct super_block *sb, int wait);
45943+ int (* const freeze_fs) (struct super_block *);
45944+ int (* const unfreeze_fs) (struct super_block *);
45945+ int (* const statfs) (struct dentry *, struct kstatfs *);
45946+ int (* const remount_fs) (struct super_block *, int *, char *);
ae4e228f
MT
45947+ void (* const umount_begin) (struct super_block *);
45948
45949- int (*show_options)(struct seq_file *, struct vfsmount *);
45950- int (*show_stats)(struct seq_file *, struct vfsmount *);
45951+ int (* const show_options)(struct seq_file *, struct vfsmount *);
45952+ int (* const show_stats)(struct seq_file *, struct vfsmount *);
45953 #ifdef CONFIG_QUOTA
45954- ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
45955- ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
45956+ ssize_t (* const quota_read)(struct super_block *, int, char *, size_t, loff_t);
45957+ ssize_t (* const quota_write)(struct super_block *, int, const char *, size_t, loff_t);
45958 #endif
45959- int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
45960+ int (* const bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
45961 };
45962
45963 /*
16454cff
MT
45964diff -urNp linux-2.6.38.1/include/linux/fs_struct.h linux-2.6.38.1/include/linux/fs_struct.h
45965--- linux-2.6.38.1/include/linux/fs_struct.h 2011-03-14 21:20:32.000000000 -0400
45966+++ linux-2.6.38.1/include/linux/fs_struct.h 2011-03-21 18:31:35.000000000 -0400
45967@@ -6,7 +6,7 @@
45968 #include <linux/seqlock.h>
58c5fc13
MT
45969
45970 struct fs_struct {
45971- int users;
45972+ atomic_t users;
6892158b 45973 spinlock_t lock;
16454cff 45974 seqcount_t seq;
58c5fc13 45975 int umask;
16454cff
MT
45976diff -urNp linux-2.6.38.1/include/linux/genhd.h linux-2.6.38.1/include/linux/genhd.h
45977--- linux-2.6.38.1/include/linux/genhd.h 2011-03-14 21:20:32.000000000 -0400
45978+++ linux-2.6.38.1/include/linux/genhd.h 2011-03-21 18:31:35.000000000 -0400
45979@@ -183,7 +183,7 @@ struct gendisk {
45980 struct kobject *slave_dir;
58c5fc13
MT
45981
45982 struct timer_rand_state *random;
58c5fc13
MT
45983- atomic_t sync_io; /* RAID */
45984+ atomic_unchecked_t sync_io; /* RAID */
16454cff 45985 struct disk_events *ev;
58c5fc13
MT
45986 #ifdef CONFIG_BLK_DEV_INTEGRITY
45987 struct blk_integrity *integrity;
16454cff
MT
45988diff -urNp linux-2.6.38.1/include/linux/gracl.h linux-2.6.38.1/include/linux/gracl.h
45989--- linux-2.6.38.1/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
45990+++ linux-2.6.38.1/include/linux/gracl.h 2011-03-26 14:27:27.000000000 -0400
bc901d79 45991@@ -0,0 +1,317 @@
58c5fc13
MT
45992+#ifndef GR_ACL_H
45993+#define GR_ACL_H
45994+
45995+#include <linux/grdefs.h>
45996+#include <linux/resource.h>
45997+#include <linux/capability.h>
45998+#include <linux/dcache.h>
45999+#include <asm/resource.h>
46000+
46001+/* Major status information */
46002+
16454cff
MT
46003+#define GR_VERSION "grsecurity 2.2.2"
46004+#define GRSECURITY_VERSION 0x2202
58c5fc13
MT
46005+
46006+enum {
46007+ GR_SHUTDOWN = 0,
46008+ GR_ENABLE = 1,
46009+ GR_SPROLE = 2,
46010+ GR_RELOAD = 3,
46011+ GR_SEGVMOD = 4,
46012+ GR_STATUS = 5,
46013+ GR_UNSPROLE = 6,
46014+ GR_PASSSET = 7,
46015+ GR_SPROLEPAM = 8,
46016+};
46017+
46018+/* Password setup definitions
46019+ * kernel/grhash.c */
46020+enum {
46021+ GR_PW_LEN = 128,
46022+ GR_SALT_LEN = 16,
46023+ GR_SHA_LEN = 32,
46024+};
46025+
46026+enum {
46027+ GR_SPROLE_LEN = 64,
46028+};
46029+
bc901d79
MT
46030+enum {
46031+ GR_NO_GLOB = 0,
46032+ GR_REG_GLOB,
46033+ GR_CREATE_GLOB
46034+};
46035+
58c5fc13
MT
46036+#define GR_NLIMITS 32
46037+
46038+/* Begin Data Structures */
46039+
46040+struct sprole_pw {
46041+ unsigned char *rolename;
46042+ unsigned char salt[GR_SALT_LEN];
46043+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
46044+};
46045+
46046+struct name_entry {
46047+ __u32 key;
46048+ ino_t inode;
46049+ dev_t device;
46050+ char *name;
46051+ __u16 len;
46052+ __u8 deleted;
46053+ struct name_entry *prev;
46054+ struct name_entry *next;
46055+};
46056+
46057+struct inodev_entry {
46058+ struct name_entry *nentry;
46059+ struct inodev_entry *prev;
46060+ struct inodev_entry *next;
46061+};
46062+
46063+struct acl_role_db {
46064+ struct acl_role_label **r_hash;
46065+ __u32 r_size;
46066+};
46067+
46068+struct inodev_db {
46069+ struct inodev_entry **i_hash;
46070+ __u32 i_size;
46071+};
46072+
46073+struct name_db {
46074+ struct name_entry **n_hash;
46075+ __u32 n_size;
46076+};
46077+
46078+struct crash_uid {
46079+ uid_t uid;
46080+ unsigned long expires;
46081+};
46082+
46083+struct gr_hash_struct {
46084+ void **table;
46085+ void **nametable;
46086+ void *first;
46087+ __u32 table_size;
46088+ __u32 used_size;
46089+ int type;
46090+};
46091+
46092+/* Userspace Grsecurity ACL data structures */
46093+
46094+struct acl_subject_label {
46095+ char *filename;
46096+ ino_t inode;
46097+ dev_t device;
46098+ __u32 mode;
46099+ kernel_cap_t cap_mask;
46100+ kernel_cap_t cap_lower;
df50ba0c 46101+ kernel_cap_t cap_invert_audit;
58c5fc13
MT
46102+
46103+ struct rlimit res[GR_NLIMITS];
46104+ __u32 resmask;
46105+
46106+ __u8 user_trans_type;
46107+ __u8 group_trans_type;
46108+ uid_t *user_transitions;
46109+ gid_t *group_transitions;
46110+ __u16 user_trans_num;
46111+ __u16 group_trans_num;
46112+
bc901d79 46113+ __u32 sock_families[2];
58c5fc13
MT
46114+ __u32 ip_proto[8];
46115+ __u32 ip_type;
46116+ struct acl_ip_label **ips;
46117+ __u32 ip_num;
46118+ __u32 inaddr_any_override;
46119+
46120+ __u32 crashes;
46121+ unsigned long expires;
46122+
46123+ struct acl_subject_label *parent_subject;
46124+ struct gr_hash_struct *hash;
46125+ struct acl_subject_label *prev;
46126+ struct acl_subject_label *next;
46127+
46128+ struct acl_object_label **obj_hash;
46129+ __u32 obj_hash_size;
46130+ __u16 pax_flags;
46131+};
46132+
46133+struct role_allowed_ip {
46134+ __u32 addr;
46135+ __u32 netmask;
46136+
46137+ struct role_allowed_ip *prev;
46138+ struct role_allowed_ip *next;
46139+};
46140+
46141+struct role_transition {
46142+ char *rolename;
46143+
46144+ struct role_transition *prev;
46145+ struct role_transition *next;
46146+};
46147+
46148+struct acl_role_label {
46149+ char *rolename;
46150+ uid_t uidgid;
46151+ __u16 roletype;
46152+
46153+ __u16 auth_attempts;
46154+ unsigned long expires;
46155+
46156+ struct acl_subject_label *root_label;
46157+ struct gr_hash_struct *hash;
46158+
46159+ struct acl_role_label *prev;
46160+ struct acl_role_label *next;
46161+
46162+ struct role_transition *transitions;
46163+ struct role_allowed_ip *allowed_ips;
46164+ uid_t *domain_children;
46165+ __u16 domain_child_num;
46166+
46167+ struct acl_subject_label **subj_hash;
46168+ __u32 subj_hash_size;
46169+};
46170+
46171+struct user_acl_role_db {
46172+ struct acl_role_label **r_table;
46173+ __u32 num_pointers; /* Number of allocations to track */
46174+ __u32 num_roles; /* Number of roles */
46175+ __u32 num_domain_children; /* Number of domain children */
46176+ __u32 num_subjects; /* Number of subjects */
46177+ __u32 num_objects; /* Number of objects */
46178+};
46179+
46180+struct acl_object_label {
46181+ char *filename;
46182+ ino_t inode;
46183+ dev_t device;
46184+ __u32 mode;
46185+
46186+ struct acl_subject_label *nested;
46187+ struct acl_object_label *globbed;
46188+
46189+ /* next two structures not used */
46190+
46191+ struct acl_object_label *prev;
46192+ struct acl_object_label *next;
46193+};
46194+
46195+struct acl_ip_label {
46196+ char *iface;
46197+ __u32 addr;
46198+ __u32 netmask;
46199+ __u16 low, high;
46200+ __u8 mode;
46201+ __u32 type;
46202+ __u32 proto[8];
46203+
46204+ /* next two structures not used */
46205+
46206+ struct acl_ip_label *prev;
46207+ struct acl_ip_label *next;
46208+};
46209+
46210+struct gr_arg {
46211+ struct user_acl_role_db role_db;
46212+ unsigned char pw[GR_PW_LEN];
46213+ unsigned char salt[GR_SALT_LEN];
46214+ unsigned char sum[GR_SHA_LEN];
46215+ unsigned char sp_role[GR_SPROLE_LEN];
46216+ struct sprole_pw *sprole_pws;
46217+ dev_t segv_device;
46218+ ino_t segv_inode;
46219+ uid_t segv_uid;
46220+ __u16 num_sprole_pws;
46221+ __u16 mode;
46222+};
46223+
46224+struct gr_arg_wrapper {
46225+ struct gr_arg *arg;
46226+ __u32 version;
46227+ __u32 size;
46228+};
46229+
46230+struct subject_map {
46231+ struct acl_subject_label *user;
46232+ struct acl_subject_label *kernel;
46233+ struct subject_map *prev;
46234+ struct subject_map *next;
46235+};
46236+
46237+struct acl_subj_map_db {
46238+ struct subject_map **s_hash;
46239+ __u32 s_size;
46240+};
46241+
46242+/* End Data Structures Section */
46243+
46244+/* Hash functions generated by empirical testing by Brad Spengler
46245+ Makes good use of the low bits of the inode. Generally 0-1 times
46246+ in loop for successful match. 0-3 for unsuccessful match.
46247+ Shift/add algorithm with modulus of table size and an XOR*/
46248+
46249+static __inline__ unsigned int
46250+rhash(const uid_t uid, const __u16 type, const unsigned int sz)
46251+{
ae4e228f 46252+ return ((((uid + type) << (16 + type)) ^ uid) % sz);
58c5fc13
MT
46253+}
46254+
46255+ static __inline__ unsigned int
46256+shash(const struct acl_subject_label *userp, const unsigned int sz)
46257+{
46258+ return ((const unsigned long)userp % sz);
46259+}
46260+
46261+static __inline__ unsigned int
46262+fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
46263+{
46264+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
46265+}
46266+
46267+static __inline__ unsigned int
46268+nhash(const char *name, const __u16 len, const unsigned int sz)
46269+{
46270+ return full_name_hash((const unsigned char *)name, len) % sz;
46271+}
46272+
ae4e228f
MT
46273+#define FOR_EACH_ROLE_START(role) \
46274+ role = role_list; \
46275+ while (role) {
58c5fc13 46276+
ae4e228f
MT
46277+#define FOR_EACH_ROLE_END(role) \
46278+ role = role->prev; \
58c5fc13
MT
46279+ }
46280+
46281+#define FOR_EACH_SUBJECT_START(role,subj,iter) \
46282+ subj = NULL; \
46283+ iter = 0; \
46284+ while (iter < role->subj_hash_size) { \
46285+ if (subj == NULL) \
46286+ subj = role->subj_hash[iter]; \
46287+ if (subj == NULL) { \
46288+ iter++; \
46289+ continue; \
46290+ }
46291+
46292+#define FOR_EACH_SUBJECT_END(subj,iter) \
46293+ subj = subj->next; \
46294+ if (subj == NULL) \
46295+ iter++; \
46296+ }
46297+
46298+
46299+#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
46300+ subj = role->hash->first; \
46301+ while (subj != NULL) {
46302+
46303+#define FOR_EACH_NESTED_SUBJECT_END(subj) \
46304+ subj = subj->next; \
46305+ }
46306+
46307+#endif
46308+
16454cff
MT
46309diff -urNp linux-2.6.38.1/include/linux/gralloc.h linux-2.6.38.1/include/linux/gralloc.h
46310--- linux-2.6.38.1/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
46311+++ linux-2.6.38.1/include/linux/gralloc.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
46312@@ -0,0 +1,9 @@
46313+#ifndef __GRALLOC_H
46314+#define __GRALLOC_H
46315+
46316+void acl_free_all(void);
46317+int acl_alloc_stack_init(unsigned long size);
46318+void *acl_alloc(unsigned long len);
46319+void *acl_alloc_num(unsigned long num, unsigned long len);
46320+
46321+#endif
16454cff
MT
46322diff -urNp linux-2.6.38.1/include/linux/grdefs.h linux-2.6.38.1/include/linux/grdefs.h
46323--- linux-2.6.38.1/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
46324+++ linux-2.6.38.1/include/linux/grdefs.h 2011-03-26 16:39:14.000000000 -0400
46325@@ -0,0 +1,139 @@
58c5fc13
MT
46326+#ifndef GRDEFS_H
46327+#define GRDEFS_H
46328+
46329+/* Begin grsecurity status declarations */
46330+
46331+enum {
46332+ GR_READY = 0x01,
46333+ GR_STATUS_INIT = 0x00 // disabled state
46334+};
46335+
46336+/* Begin ACL declarations */
46337+
46338+/* Role flags */
46339+
46340+enum {
46341+ GR_ROLE_USER = 0x0001,
46342+ GR_ROLE_GROUP = 0x0002,
46343+ GR_ROLE_DEFAULT = 0x0004,
46344+ GR_ROLE_SPECIAL = 0x0008,
46345+ GR_ROLE_AUTH = 0x0010,
46346+ GR_ROLE_NOPW = 0x0020,
46347+ GR_ROLE_GOD = 0x0040,
46348+ GR_ROLE_LEARN = 0x0080,
46349+ GR_ROLE_TPE = 0x0100,
46350+ GR_ROLE_DOMAIN = 0x0200,
16454cff
MT
46351+ GR_ROLE_PAM = 0x0400,
46352+ GR_ROLE_PERSIST = 0x0800
58c5fc13
MT
46353+};
46354+
46355+/* ACL Subject and Object mode flags */
46356+enum {
46357+ GR_DELETED = 0x80000000
46358+};
46359+
46360+/* ACL Object-only mode flags */
46361+enum {
46362+ GR_READ = 0x00000001,
46363+ GR_APPEND = 0x00000002,
46364+ GR_WRITE = 0x00000004,
46365+ GR_EXEC = 0x00000008,
46366+ GR_FIND = 0x00000010,
46367+ GR_INHERIT = 0x00000020,
46368+ GR_SETID = 0x00000040,
46369+ GR_CREATE = 0x00000080,
46370+ GR_DELETE = 0x00000100,
46371+ GR_LINK = 0x00000200,
46372+ GR_AUDIT_READ = 0x00000400,
46373+ GR_AUDIT_APPEND = 0x00000800,
46374+ GR_AUDIT_WRITE = 0x00001000,
46375+ GR_AUDIT_EXEC = 0x00002000,
46376+ GR_AUDIT_FIND = 0x00004000,
46377+ GR_AUDIT_INHERIT= 0x00008000,
46378+ GR_AUDIT_SETID = 0x00010000,
46379+ GR_AUDIT_CREATE = 0x00020000,
46380+ GR_AUDIT_DELETE = 0x00040000,
46381+ GR_AUDIT_LINK = 0x00080000,
46382+ GR_PTRACERD = 0x00100000,
46383+ GR_NOPTRACE = 0x00200000,
46384+ GR_SUPPRESS = 0x00400000,
16454cff
MT
46385+ GR_NOLEARN = 0x00800000,
46386+ GR_INIT_TRANSFER= 0x01000000
58c5fc13
MT
46387+};
46388+
46389+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
46390+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
46391+ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
46392+
46393+/* ACL subject-only mode flags */
46394+enum {
46395+ GR_KILL = 0x00000001,
46396+ GR_VIEW = 0x00000002,
46397+ GR_PROTECTED = 0x00000004,
46398+ GR_LEARN = 0x00000008,
46399+ GR_OVERRIDE = 0x00000010,
46400+ /* just a placeholder, this mode is only used in userspace */
46401+ GR_DUMMY = 0x00000020,
46402+ GR_PROTSHM = 0x00000040,
46403+ GR_KILLPROC = 0x00000080,
46404+ GR_KILLIPPROC = 0x00000100,
46405+ /* just a placeholder, this mode is only used in userspace */
46406+ GR_NOTROJAN = 0x00000200,
46407+ GR_PROTPROCFD = 0x00000400,
46408+ GR_PROCACCT = 0x00000800,
46409+ GR_RELAXPTRACE = 0x00001000,
46410+ GR_NESTED = 0x00002000,
46411+ GR_INHERITLEARN = 0x00004000,
46412+ GR_PROCFIND = 0x00008000,
46413+ GR_POVERRIDE = 0x00010000,
46414+ GR_KERNELAUTH = 0x00020000,
bc901d79 46415+ GR_ATSECURE = 0x00040000
58c5fc13
MT
46416+};
46417+
46418+enum {
46419+ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
46420+ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
46421+ GR_PAX_ENABLE_MPROTECT = 0x0004,
46422+ GR_PAX_ENABLE_RANDMMAP = 0x0008,
46423+ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
46424+ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
46425+ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
46426+ GR_PAX_DISABLE_MPROTECT = 0x0400,
46427+ GR_PAX_DISABLE_RANDMMAP = 0x0800,
46428+ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
46429+};
46430+
46431+enum {
46432+ GR_ID_USER = 0x01,
46433+ GR_ID_GROUP = 0x02,
46434+};
46435+
46436+enum {
46437+ GR_ID_ALLOW = 0x01,
46438+ GR_ID_DENY = 0x02,
46439+};
46440+
46441+#define GR_CRASH_RES 31
46442+#define GR_UIDTABLE_MAX 500
46443+
46444+/* begin resource learning section */
46445+enum {
46446+ GR_RLIM_CPU_BUMP = 60,
46447+ GR_RLIM_FSIZE_BUMP = 50000,
46448+ GR_RLIM_DATA_BUMP = 10000,
46449+ GR_RLIM_STACK_BUMP = 1000,
46450+ GR_RLIM_CORE_BUMP = 10000,
46451+ GR_RLIM_RSS_BUMP = 500000,
46452+ GR_RLIM_NPROC_BUMP = 1,
46453+ GR_RLIM_NOFILE_BUMP = 5,
46454+ GR_RLIM_MEMLOCK_BUMP = 50000,
46455+ GR_RLIM_AS_BUMP = 500000,
46456+ GR_RLIM_LOCKS_BUMP = 2,
46457+ GR_RLIM_SIGPENDING_BUMP = 5,
46458+ GR_RLIM_MSGQUEUE_BUMP = 10000,
46459+ GR_RLIM_NICE_BUMP = 1,
46460+ GR_RLIM_RTPRIO_BUMP = 1,
46461+ GR_RLIM_RTTIME_BUMP = 1000000
46462+};
46463+
46464+#endif
16454cff
MT
46465diff -urNp linux-2.6.38.1/include/linux/grinternal.h linux-2.6.38.1/include/linux/grinternal.h
46466--- linux-2.6.38.1/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
46467+++ linux-2.6.38.1/include/linux/grinternal.h 2011-03-26 16:51:07.000000000 -0400
46468@@ -0,0 +1,217 @@
58c5fc13
MT
46469+#ifndef __GRINTERNAL_H
46470+#define __GRINTERNAL_H
46471+
46472+#ifdef CONFIG_GRKERNSEC
46473+
46474+#include <linux/fs.h>
46475+#include <linux/mnt_namespace.h>
46476+#include <linux/nsproxy.h>
46477+#include <linux/gracl.h>
46478+#include <linux/grdefs.h>
46479+#include <linux/grmsg.h>
46480+
46481+void gr_add_learn_entry(const char *fmt, ...)
46482+ __attribute__ ((format (printf, 1, 2)));
46483+__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
46484+ const struct vfsmount *mnt);
46485+__u32 gr_check_create(const struct dentry *new_dentry,
46486+ const struct dentry *parent,
46487+ const struct vfsmount *mnt, const __u32 mode);
46488+int gr_check_protected_task(const struct task_struct *task);
46489+__u32 to_gr_audit(const __u32 reqmode);
46490+int gr_set_acls(const int type);
16454cff 46491+int gr_apply_subject_to_task(struct task_struct *task);
58c5fc13
MT
46492+int gr_acl_is_enabled(void);
46493+char gr_roletype_to_char(void);
46494+
46495+void gr_handle_alertkill(struct task_struct *task);
46496+char *gr_to_filename(const struct dentry *dentry,
46497+ const struct vfsmount *mnt);
46498+char *gr_to_filename1(const struct dentry *dentry,
46499+ const struct vfsmount *mnt);
46500+char *gr_to_filename2(const struct dentry *dentry,
46501+ const struct vfsmount *mnt);
46502+char *gr_to_filename3(const struct dentry *dentry,
46503+ const struct vfsmount *mnt);
46504+
46505+extern int grsec_enable_harden_ptrace;
46506+extern int grsec_enable_link;
46507+extern int grsec_enable_fifo;
46508+extern int grsec_enable_execve;
46509+extern int grsec_enable_shm;
46510+extern int grsec_enable_execlog;
46511+extern int grsec_enable_signal;
ae4e228f 46512+extern int grsec_enable_audit_ptrace;
58c5fc13
MT
46513+extern int grsec_enable_forkfail;
46514+extern int grsec_enable_time;
ae4e228f 46515+extern int grsec_enable_rofs;
58c5fc13
MT
46516+extern int grsec_enable_chroot_shmat;
46517+extern int grsec_enable_chroot_findtask;
46518+extern int grsec_enable_chroot_mount;
46519+extern int grsec_enable_chroot_double;
46520+extern int grsec_enable_chroot_pivot;
46521+extern int grsec_enable_chroot_chdir;
46522+extern int grsec_enable_chroot_chmod;
46523+extern int grsec_enable_chroot_mknod;
46524+extern int grsec_enable_chroot_fchdir;
46525+extern int grsec_enable_chroot_nice;
46526+extern int grsec_enable_chroot_execlog;
46527+extern int grsec_enable_chroot_caps;
46528+extern int grsec_enable_chroot_sysctl;
46529+extern int grsec_enable_chroot_unix;
46530+extern int grsec_enable_tpe;
46531+extern int grsec_tpe_gid;
46532+extern int grsec_enable_tpe_all;
57199397 46533+extern int grsec_enable_tpe_invert;
58c5fc13
MT
46534+extern int grsec_enable_socket_all;
46535+extern int grsec_socket_all_gid;
46536+extern int grsec_enable_socket_client;
46537+extern int grsec_socket_client_gid;
46538+extern int grsec_enable_socket_server;
46539+extern int grsec_socket_server_gid;
46540+extern int grsec_audit_gid;
46541+extern int grsec_enable_group;
46542+extern int grsec_enable_audit_textrel;
6892158b 46543+extern int grsec_enable_log_rwxmaps;
58c5fc13
MT
46544+extern int grsec_enable_mount;
46545+extern int grsec_enable_chdir;
46546+extern int grsec_resource_logging;
ae4e228f
MT
46547+extern int grsec_enable_blackhole;
46548+extern int grsec_lastack_retries;
58c5fc13
MT
46549+extern int grsec_lock;
46550+
46551+extern spinlock_t grsec_alert_lock;
46552+extern unsigned long grsec_alert_wtime;
46553+extern unsigned long grsec_alert_fyet;
46554+
46555+extern spinlock_t grsec_audit_lock;
46556+
46557+extern rwlock_t grsec_exec_file_lock;
46558+
6892158b
MT
46559+#define gr_task_fullpath(tsk) ((tsk)->exec_file ? \
46560+ gr_to_filename2((tsk)->exec_file->f_path.dentry, \
46561+ (tsk)->exec_file->f_vfsmnt) : "/")
58c5fc13 46562+
6892158b
MT
46563+#define gr_parent_task_fullpath(tsk) ((tsk)->real_parent->exec_file ? \
46564+ gr_to_filename3((tsk)->real_parent->exec_file->f_path.dentry, \
46565+ (tsk)->real_parent->exec_file->f_vfsmnt) : "/")
58c5fc13 46566+
6892158b
MT
46567+#define gr_task_fullpath0(tsk) ((tsk)->exec_file ? \
46568+ gr_to_filename((tsk)->exec_file->f_path.dentry, \
46569+ (tsk)->exec_file->f_vfsmnt) : "/")
58c5fc13 46570+
6892158b
MT
46571+#define gr_parent_task_fullpath0(tsk) ((tsk)->real_parent->exec_file ? \
46572+ gr_to_filename1((tsk)->real_parent->exec_file->f_path.dentry, \
46573+ (tsk)->real_parent->exec_file->f_vfsmnt) : "/")
58c5fc13 46574+
6892158b 46575+#define proc_is_chrooted(tsk_a) ((tsk_a)->gr_is_chrooted)
58c5fc13 46576+
6892158b 46577+#define have_same_root(tsk_a,tsk_b) ((tsk_a)->gr_chroot_dentry == (tsk_b)->gr_chroot_dentry)
58c5fc13 46578+
6892158b
MT
46579+#define DEFAULTSECARGS(task, cred, pcred) gr_task_fullpath(task), (task)->comm, \
46580+ (task)->pid, (cred)->uid, \
46581+ (cred)->euid, (cred)->gid, (cred)->egid, \
58c5fc13 46582+ gr_parent_task_fullpath(task), \
6892158b
MT
46583+ (task)->real_parent->comm, (task)->real_parent->pid, \
46584+ (pcred)->uid, (pcred)->euid, \
46585+ (pcred)->gid, (pcred)->egid
58c5fc13
MT
46586+
46587+#define GR_CHROOT_CAPS {{ \
46588+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
46589+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
46590+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
46591+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
46592+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
46593+ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
46594+
46595+#define security_learn(normal_msg,args...) \
46596+({ \
46597+ read_lock(&grsec_exec_file_lock); \
46598+ gr_add_learn_entry(normal_msg "\n", ## args); \
46599+ read_unlock(&grsec_exec_file_lock); \
46600+})
46601+
46602+enum {
46603+ GR_DO_AUDIT,
46604+ GR_DONT_AUDIT,
16454cff 46605+ /* used for non-audit messages that we shouldn't kill the task on */
58c5fc13
MT
46606+ GR_DONT_AUDIT_GOOD
46607+};
46608+
46609+enum {
46610+ GR_TTYSNIFF,
46611+ GR_RBAC,
46612+ GR_RBAC_STR,
46613+ GR_STR_RBAC,
46614+ GR_RBAC_MODE2,
46615+ GR_RBAC_MODE3,
46616+ GR_FILENAME,
46617+ GR_SYSCTL_HIDDEN,
46618+ GR_NOARGS,
46619+ GR_ONE_INT,
46620+ GR_ONE_INT_TWO_STR,
46621+ GR_ONE_STR,
46622+ GR_STR_INT,
bc901d79 46623+ GR_TWO_STR_INT,
58c5fc13
MT
46624+ GR_TWO_INT,
46625+ GR_THREE_INT,
46626+ GR_FIVE_INT_TWO_STR,
46627+ GR_TWO_STR,
46628+ GR_THREE_STR,
46629+ GR_FOUR_STR,
46630+ GR_STR_FILENAME,
46631+ GR_FILENAME_STR,
46632+ GR_FILENAME_TWO_INT,
46633+ GR_FILENAME_TWO_INT_STR,
46634+ GR_TEXTREL,
46635+ GR_PTRACE,
46636+ GR_RESOURCE,
46637+ GR_CAP,
46638+ GR_SIG,
46639+ GR_SIG2,
46640+ GR_CRASH1,
46641+ GR_CRASH2,
6892158b
MT
46642+ GR_PSACCT,
46643+ GR_RWXMAP
58c5fc13
MT
46644+};
46645+
46646+#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
46647+#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
46648+#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
46649+#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
46650+#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
46651+#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
46652+#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)
46653+#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
46654+#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
46655+#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
46656+#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
46657+#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
46658+#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
46659+#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
46660+#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
46661+#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)
46662+#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
bc901d79 46663+#define gr_log_str2_int(audit, msg, str1, str2, num) gr_log_varargs(audit, msg, GR_TWO_STR_INT, str1, str2, num)
58c5fc13
MT
46664+#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
46665+#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
46666+#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
46667+#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
46668+#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
46669+#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)
46670+#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
46671+#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
46672+#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
46673+#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
46674+#define gr_log_sig_addr(audit, msg, str, addr) gr_log_varargs(audit, msg, GR_SIG, str, addr)
46675+#define gr_log_sig_task(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG2, task, num)
46676+#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
46677+#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
46678+#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)
6892158b 46679+#define gr_log_rwxmap(audit, msg, str) gr_log_varargs(audit, msg, GR_RWXMAP, str)
58c5fc13
MT
46680+
46681+void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
46682+
46683+#endif
46684+
46685+#endif
16454cff
MT
46686diff -urNp linux-2.6.38.1/include/linux/grmsg.h linux-2.6.38.1/include/linux/grmsg.h
46687--- linux-2.6.38.1/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
46688+++ linux-2.6.38.1/include/linux/grmsg.h 2011-03-26 16:52:08.000000000 -0400
46689@@ -0,0 +1,112 @@
58c5fc13 46690+#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"
ae4e228f 46691+#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%pI4 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:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
58c5fc13
MT
46692+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
46693+#define GR_STOPMOD_MSG "denied modification of module state by "
ae4e228f
MT
46694+#define GR_ROFS_BLOCKWRITE_MSG "denied write to block device %.950s by "
46695+#define GR_ROFS_MOUNT_MSG "denied writable mount of %.950s by "
58c5fc13
MT
46696+#define GR_IOPERM_MSG "denied use of ioperm() by "
46697+#define GR_IOPL_MSG "denied use of iopl() by "
46698+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
46699+#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
46700+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
46701+#define GR_KMEM_MSG "denied write of /dev/kmem by "
46702+#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
46703+#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
46704+#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
46705+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
ae4e228f
MT
46706+#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%pI4"
46707+#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%pI4"
58c5fc13
MT
46708+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
46709+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
46710+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
46711+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
46712+#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
46713+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
46714+#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
ae4e228f 46715+#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%pI4 %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
58c5fc13
MT
46716+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
46717+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
46718+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
46719+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
46720+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
46721+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
46722+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
46723+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
ae4e228f 46724+#define GR_UNSAFESHARE_EXEC_ACL_MSG "denied exec with cloned fs of %.950s by "
58c5fc13
MT
46725+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
46726+#define GR_NPROC_MSG "denied overstep of process limit by "
46727+#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
46728+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
46729+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
46730+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
46731+#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
46732+#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
46733+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
46734+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
46735+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
46736+#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
46737+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
46738+#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
46739+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
46740+#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
46741+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
bc901d79 46742+#define GR_SETXATTR_ACL_MSG "%s setting extended attributes of %.950s by "
58c5fc13
MT
46743+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
46744+#define GR_INITF_ACL_MSG "init_variables() failed %s by "
46745+#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"
46746+#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
46747+#define GR_SHUTS_ACL_MSG "shutdown auth success for "
46748+#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
46749+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
46750+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
46751+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
46752+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
46753+#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
46754+#define GR_ENABLEF_ACL_MSG "unable to load %s for "
46755+#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
46756+#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
46757+#define GR_RELOADF_ACL_MSG "failed reload of %s for "
46758+#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
46759+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
46760+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
46761+#define GR_SPROLEF_ACL_MSG "special role %s failure for "
46762+#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
46763+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
58c5fc13
MT
46764+#define GR_INVMODE_ACL_MSG "invalid mode %d by "
46765+#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
6892158b 46766+#define GR_FAILFORK_MSG "failed fork with errno %s by "
58c5fc13
MT
46767+#define GR_NICE_CHROOT_MSG "denied priority change by "
46768+#define GR_UNISIGLOG_MSG "%.32s occurred at %p in "
46769+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
46770+#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
46771+#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
46772+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
46773+#define GR_TIME_MSG "time set by "
46774+#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
46775+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
46776+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
46777+#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
bc901d79 46778+#define GR_SOCK_NOINET_MSG "denied socket(%.16s,%.16s,%d) by "
58c5fc13
MT
46779+#define GR_BIND_MSG "denied bind() by "
46780+#define GR_CONNECT_MSG "denied connect() by "
ae4e228f
MT
46781+#define GR_BIND_ACL_MSG "denied bind() to %pI4 port %u sock type %.16s protocol %.16s by "
46782+#define GR_CONNECT_ACL_MSG "denied connect() to %pI4 port %u sock type %.16s protocol %.16s by "
46783+#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%pI4\t%u\t%u\t%u\t%u\t%pI4"
58c5fc13
MT
46784+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
46785+#define GR_CAP_ACL_MSG "use of %s denied for "
df50ba0c 46786+#define GR_CAP_ACL_MSG2 "use of %s permitted for "
58c5fc13
MT
46787+#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
46788+#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
46789+#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
46790+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
46791+#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
46792+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
46793+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
46794+#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
6892158b
MT
46795+#define GR_RWXMMAP_MSG "denied RWX mmap of %.950s by "
46796+#define GR_RWXMPROTECT_MSG "denied RWX mprotect of %.950s by "
58c5fc13
MT
46797+#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
46798+#define GR_NONROOT_MODLOAD_MSG "denied kernel module auto-load of %.64s by "
ae4e228f
MT
46799+#define GR_VM86_MSG "denied use of vm86 by "
46800+#define GR_PTRACE_AUDIT_MSG "process %.950s(%.16s:%d) attached to via ptrace by "
16454cff
MT
46801+#define GR_INIT_TRANSFER_MSG "persistent special role transferred privilege to init by "
46802diff -urNp linux-2.6.38.1/include/linux/grsecurity.h linux-2.6.38.1/include/linux/grsecurity.h
46803--- linux-2.6.38.1/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
46804+++ linux-2.6.38.1/include/linux/grsecurity.h 2011-03-26 19:58:41.000000000 -0400
46805@@ -0,0 +1,215 @@
58c5fc13
MT
46806+#ifndef GR_SECURITY_H
46807+#define GR_SECURITY_H
46808+#include <linux/fs.h>
46809+#include <linux/fs_struct.h>
46810+#include <linux/binfmts.h>
46811+#include <linux/gracl.h>
bc901d79 46812+#include <linux/compat.h>
58c5fc13
MT
46813+
46814+/* notify of brain-dead configs */
46815+#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
46816+#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
46817+#endif
46818+#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
46819+#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
46820+#endif
46821+#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
46822+#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
46823+#endif
46824+#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
46825+#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
46826+#endif
46827+#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
46828+#error "CONFIG_PAX enabled, but no PaX options are enabled."
46829+#endif
46830+
46831+void gr_handle_brute_attach(struct task_struct *p);
46832+void gr_handle_brute_check(void);
46833+
46834+char gr_roletype_to_char(void);
46835+
bc901d79
MT
46836+int gr_acl_enable_at_secure(void);
46837+
58c5fc13
MT
46838+int gr_check_user_change(int real, int effective, int fs);
46839+int gr_check_group_change(int real, int effective, int fs);
46840+
46841+void gr_del_task_from_ip_table(struct task_struct *p);
46842+
46843+int gr_pid_is_chrooted(struct task_struct *p);
57199397 46844+int gr_handle_chroot_fowner(struct pid *pid, enum pid_type type);
58c5fc13
MT
46845+int gr_handle_chroot_nice(void);
46846+int gr_handle_chroot_sysctl(const int op);
46847+int gr_handle_chroot_setpriority(struct task_struct *p,
46848+ const int niceval);
46849+int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
46850+int gr_handle_chroot_chroot(const struct dentry *dentry,
46851+ const struct vfsmount *mnt);
46852+int gr_handle_chroot_caps(struct path *path);
46853+void gr_handle_chroot_chdir(struct path *path);
46854+int gr_handle_chroot_chmod(const struct dentry *dentry,
46855+ const struct vfsmount *mnt, const int mode);
46856+int gr_handle_chroot_mknod(const struct dentry *dentry,
46857+ const struct vfsmount *mnt, const int mode);
46858+int gr_handle_chroot_mount(const struct dentry *dentry,
46859+ const struct vfsmount *mnt,
46860+ const char *dev_name);
46861+int gr_handle_chroot_pivot(void);
6892158b 46862+int gr_handle_chroot_unix(struct pid *pid);
58c5fc13
MT
46863+
46864+int gr_handle_rawio(const struct inode *inode);
46865+int gr_handle_nproc(void);
46866+
46867+void gr_handle_ioperm(void);
46868+void gr_handle_iopl(void);
46869+
46870+int gr_tpe_allow(const struct file *file);
46871+
df50ba0c
MT
46872+void gr_set_chroot_entries(struct task_struct *task, struct path *path);
46873+void gr_clear_chroot_entries(struct task_struct *task);
58c5fc13
MT
46874+
46875+void gr_log_forkfail(const int retval);
46876+void gr_log_timechange(void);
46877+void gr_log_signal(const int sig, const void *addr, const struct task_struct *t);
46878+void gr_log_chdir(const struct dentry *dentry,
46879+ const struct vfsmount *mnt);
46880+void gr_log_chroot_exec(const struct dentry *dentry,
46881+ const struct vfsmount *mnt);
6892158b 46882+void gr_handle_exec_args(struct linux_binprm *bprm, const char __user *const __user *argv);
bc901d79
MT
46883+#ifdef CONFIG_COMPAT
46884+void gr_handle_exec_args_compat(struct linux_binprm *bprm, compat_uptr_t __user *argv);
46885+#endif
58c5fc13
MT
46886+void gr_log_remount(const char *devname, const int retval);
46887+void gr_log_unmount(const char *devname, const int retval);
46888+void gr_log_mount(const char *from, const char *to, const int retval);
46889+void gr_log_textrel(struct vm_area_struct *vma);
6892158b
MT
46890+void gr_log_rwxmmap(struct file *file);
46891+void gr_log_rwxmprotect(struct file *file);
58c5fc13
MT
46892+
46893+int gr_handle_follow_link(const struct inode *parent,
46894+ const struct inode *inode,
46895+ const struct dentry *dentry,
46896+ const struct vfsmount *mnt);
46897+int gr_handle_fifo(const struct dentry *dentry,
46898+ const struct vfsmount *mnt,
46899+ const struct dentry *dir, const int flag,
46900+ const int acc_mode);
46901+int gr_handle_hardlink(const struct dentry *dentry,
46902+ const struct vfsmount *mnt,
46903+ struct inode *inode,
46904+ const int mode, const char *to);
46905+
46906+int gr_is_capable(const int cap);
46907+int gr_is_capable_nolog(const int cap);
46908+void gr_learn_resource(const struct task_struct *task, const int limit,
46909+ const unsigned long wanted, const int gt);
46910+void gr_copy_label(struct task_struct *tsk);
46911+void gr_handle_crash(struct task_struct *task, const int sig);
46912+int gr_handle_signal(const struct task_struct *p, const int sig);
46913+int gr_check_crash_uid(const uid_t uid);
46914+int gr_check_protected_task(const struct task_struct *task);
57199397 46915+int gr_check_protected_task_fowner(struct pid *pid, enum pid_type type);
58c5fc13
MT
46916+int gr_acl_handle_mmap(const struct file *file,
46917+ const unsigned long prot);
46918+int gr_acl_handle_mprotect(const struct file *file,
46919+ const unsigned long prot);
46920+int gr_check_hidden_task(const struct task_struct *tsk);
46921+__u32 gr_acl_handle_truncate(const struct dentry *dentry,
46922+ const struct vfsmount *mnt);
46923+__u32 gr_acl_handle_utime(const struct dentry *dentry,
46924+ const struct vfsmount *mnt);
46925+__u32 gr_acl_handle_access(const struct dentry *dentry,
46926+ const struct vfsmount *mnt, const int fmode);
46927+__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
46928+ const struct vfsmount *mnt, mode_t mode);
46929+__u32 gr_acl_handle_chmod(const struct dentry *dentry,
46930+ const struct vfsmount *mnt, mode_t mode);
46931+__u32 gr_acl_handle_chown(const struct dentry *dentry,
46932+ const struct vfsmount *mnt);
bc901d79
MT
46933+__u32 gr_acl_handle_setxattr(const struct dentry *dentry,
46934+ const struct vfsmount *mnt);
58c5fc13
MT
46935+int gr_handle_ptrace(struct task_struct *task, const long request);
46936+int gr_handle_proc_ptrace(struct task_struct *task);
46937+__u32 gr_acl_handle_execve(const struct dentry *dentry,
46938+ const struct vfsmount *mnt);
46939+int gr_check_crash_exec(const struct file *filp);
46940+int gr_acl_is_enabled(void);
46941+void gr_set_kernel_label(struct task_struct *task);
46942+void gr_set_role_label(struct task_struct *task, const uid_t uid,
46943+ const gid_t gid);
46944+int gr_set_proc_label(const struct dentry *dentry,
46945+ const struct vfsmount *mnt,
46946+ const int unsafe_share);
46947+__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
46948+ const struct vfsmount *mnt);
46949+__u32 gr_acl_handle_open(const struct dentry *dentry,
46950+ const struct vfsmount *mnt, const int fmode);
46951+__u32 gr_acl_handle_creat(const struct dentry *dentry,
46952+ const struct dentry *p_dentry,
46953+ const struct vfsmount *p_mnt, const int fmode,
46954+ const int imode);
46955+void gr_handle_create(const struct dentry *dentry,
46956+ const struct vfsmount *mnt);
46957+__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
46958+ const struct dentry *parent_dentry,
46959+ const struct vfsmount *parent_mnt,
46960+ const int mode);
46961+__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
46962+ const struct dentry *parent_dentry,
46963+ const struct vfsmount *parent_mnt);
46964+__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
46965+ const struct vfsmount *mnt);
46966+void gr_handle_delete(const ino_t ino, const dev_t dev);
46967+__u32 gr_acl_handle_unlink(const struct dentry *dentry,
46968+ const struct vfsmount *mnt);
46969+__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
46970+ const struct dentry *parent_dentry,
46971+ const struct vfsmount *parent_mnt,
46972+ const char *from);
46973+__u32 gr_acl_handle_link(const struct dentry *new_dentry,
46974+ const struct dentry *parent_dentry,
46975+ const struct vfsmount *parent_mnt,
46976+ const struct dentry *old_dentry,
46977+ const struct vfsmount *old_mnt, const char *to);
46978+int gr_acl_handle_rename(struct dentry *new_dentry,
46979+ struct dentry *parent_dentry,
46980+ const struct vfsmount *parent_mnt,
46981+ struct dentry *old_dentry,
46982+ struct inode *old_parent_inode,
46983+ struct vfsmount *old_mnt, const char *newname);
46984+void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
46985+ struct dentry *old_dentry,
46986+ struct dentry *new_dentry,
46987+ struct vfsmount *mnt, const __u8 replace);
46988+__u32 gr_check_link(const struct dentry *new_dentry,
46989+ const struct dentry *parent_dentry,
46990+ const struct vfsmount *parent_mnt,
46991+ const struct dentry *old_dentry,
46992+ const struct vfsmount *old_mnt);
46993+int gr_acl_handle_filldir(const struct file *file, const char *name,
46994+ const unsigned int namelen, const ino_t ino);
46995+
46996+__u32 gr_acl_handle_unix(const struct dentry *dentry,
46997+ const struct vfsmount *mnt);
46998+void gr_acl_handle_exit(void);
46999+void gr_acl_handle_psacct(struct task_struct *task, const long code);
47000+int gr_acl_handle_procpidmem(const struct task_struct *task);
ae4e228f
MT
47001+int gr_handle_rofs_mount(struct dentry *dentry, struct vfsmount *mnt, int mnt_flags);
47002+int gr_handle_rofs_blockwrite(struct dentry *dentry, struct vfsmount *mnt, int acc_mode);
47003+void gr_audit_ptrace(struct task_struct *task);
16454cff 47004+dev_t gr_get_dev_from_dentry(struct dentry *dentry);
58c5fc13
MT
47005+
47006+#ifdef CONFIG_GRKERNSEC
6892158b 47007+void task_grsec_rbac(struct seq_file *m, struct task_struct *p);
58c5fc13 47008+void gr_log_nonroot_mod_load(const char *modname);
ae4e228f 47009+void gr_handle_vm86(void);
58c5fc13
MT
47010+void gr_handle_mem_write(void);
47011+void gr_handle_kmem_write(void);
47012+void gr_handle_open_port(void);
47013+int gr_handle_mem_mmap(const unsigned long offset,
47014+ struct vm_area_struct *vma);
47015+
47016+extern int grsec_enable_dmesg;
df50ba0c 47017+extern int grsec_disable_privio;
58c5fc13
MT
47018+#endif
47019+
47020+#endif
16454cff
MT
47021diff -urNp linux-2.6.38.1/include/linux/grsock.h linux-2.6.38.1/include/linux/grsock.h
47022--- linux-2.6.38.1/include/linux/grsock.h 1969-12-31 19:00:00.000000000 -0500
47023+++ linux-2.6.38.1/include/linux/grsock.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
47024@@ -0,0 +1,19 @@
47025+#ifndef __GRSOCK_H
47026+#define __GRSOCK_H
47027+
47028+extern void gr_attach_curr_ip(const struct sock *sk);
47029+extern int gr_handle_sock_all(const int family, const int type,
47030+ const int protocol);
47031+extern int gr_handle_sock_server(const struct sockaddr *sck);
df50ba0c 47032+extern int gr_handle_sock_server_other(const struct sock *sck);
ae4e228f
MT
47033+extern int gr_handle_sock_client(const struct sockaddr *sck);
47034+extern int gr_search_connect(struct socket * sock,
47035+ struct sockaddr_in * addr);
47036+extern int gr_search_bind(struct socket * sock,
47037+ struct sockaddr_in * addr);
47038+extern int gr_search_listen(struct socket * sock);
47039+extern int gr_search_accept(struct socket * sock);
47040+extern int gr_search_socket(const int domain, const int type,
47041+ const int protocol);
47042+
47043+#endif
16454cff
MT
47044diff -urNp linux-2.6.38.1/include/linux/highmem.h linux-2.6.38.1/include/linux/highmem.h
47045--- linux-2.6.38.1/include/linux/highmem.h 2011-03-14 21:20:32.000000000 -0400
47046+++ linux-2.6.38.1/include/linux/highmem.h 2011-03-21 18:31:35.000000000 -0400
47047@@ -185,6 +185,18 @@ static inline void clear_highpage(struct
58c5fc13
MT
47048 kunmap_atomic(kaddr, KM_USER0);
47049 }
47050
47051+static inline void sanitize_highpage(struct page *page)
47052+{
47053+ void *kaddr;
47054+ unsigned long flags;
47055+
47056+ local_irq_save(flags);
47057+ kaddr = kmap_atomic(page, KM_CLEARPAGE);
47058+ clear_page(kaddr);
47059+ kunmap_atomic(kaddr, KM_CLEARPAGE);
47060+ local_irq_restore(flags);
47061+}
47062+
47063 static inline void zero_user_segments(struct page *page,
47064 unsigned start1, unsigned end1,
47065 unsigned start2, unsigned end2)
16454cff
MT
47066diff -urNp linux-2.6.38.1/include/linux/init.h linux-2.6.38.1/include/linux/init.h
47067--- linux-2.6.38.1/include/linux/init.h 2011-03-14 21:20:32.000000000 -0400
47068+++ linux-2.6.38.1/include/linux/init.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 47069@@ -293,13 +293,13 @@ void __init parse_early_options(char *cm
6892158b
MT
47070
47071 /* Each module must use one module_init(). */
47072 #define module_init(initfn) \
47073- static inline initcall_t __inittest(void) \
47074+ static inline __used initcall_t __inittest(void) \
47075 { return initfn; } \
47076 int init_module(void) __attribute__((alias(#initfn)));
47077
47078 /* This is only required if you want to be unloadable. */
47079 #define module_exit(exitfn) \
47080- static inline exitcall_t __exittest(void) \
47081+ static inline __used exitcall_t __exittest(void) \
47082 { return exitfn; } \
47083 void cleanup_module(void) __attribute__((alias(#exitfn)));
47084
16454cff
MT
47085diff -urNp linux-2.6.38.1/include/linux/interrupt.h linux-2.6.38.1/include/linux/interrupt.h
47086--- linux-2.6.38.1/include/linux/interrupt.h 2011-03-14 21:20:32.000000000 -0400
47087+++ linux-2.6.38.1/include/linux/interrupt.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 47088@@ -393,7 +393,7 @@ enum
ae4e228f
MT
47089 /* map softirq index to softirq name. update 'softirq_to_name' in
47090 * kernel/softirq.c when adding a new softirq.
47091 */
47092-extern char *softirq_to_name[NR_SOFTIRQS];
47093+extern const char * const softirq_to_name[NR_SOFTIRQS];
47094
47095 /* softirq mask and active fields moved to irq_cpustat_t in
47096 * asm/hardirq.h to get better cache usage. KAO
bc901d79 47097@@ -401,12 +401,12 @@ extern char *softirq_to_name[NR_SOFTIRQS
ae4e228f
MT
47098
47099 struct softirq_action
47100 {
47101- void (*action)(struct softirq_action *);
47102+ void (*action)(void);
47103 };
47104
47105 asmlinkage void do_softirq(void);
47106 asmlinkage void __do_softirq(void);
47107-extern void open_softirq(int nr, void (*action)(struct softirq_action *));
47108+extern void open_softirq(int nr, void (*action)(void));
47109 extern void softirq_init(void);
bc901d79
MT
47110 static inline void __raise_softirq_irqoff(unsigned int nr)
47111 {
16454cff
MT
47112diff -urNp linux-2.6.38.1/include/linux/jbd2.h linux-2.6.38.1/include/linux/jbd2.h
47113--- linux-2.6.38.1/include/linux/jbd2.h 2011-03-14 21:20:32.000000000 -0400
47114+++ linux-2.6.38.1/include/linux/jbd2.h 2011-03-21 18:31:35.000000000 -0400
57199397 47115@@ -67,7 +67,7 @@ extern u8 jbd2_journal_enable_debug;
58c5fc13
MT
47116 } \
47117 } while (0)
47118 #else
47119-#define jbd_debug(f, a...) /**/
47120+#define jbd_debug(f, a...) do {} while (0)
47121 #endif
47122
57199397 47123 extern void *jbd2_alloc(size_t size, gfp_t flags);
16454cff
MT
47124diff -urNp linux-2.6.38.1/include/linux/jbd.h linux-2.6.38.1/include/linux/jbd.h
47125--- linux-2.6.38.1/include/linux/jbd.h 2011-03-14 21:20:32.000000000 -0400
47126+++ linux-2.6.38.1/include/linux/jbd.h 2011-03-21 18:31:35.000000000 -0400
57199397 47127@@ -67,7 +67,7 @@ extern u8 journal_enable_debug;
58c5fc13
MT
47128 } \
47129 } while (0)
47130 #else
47131-#define jbd_debug(f, a...) /**/
47132+#define jbd_debug(f, a...) do {} while (0)
47133 #endif
47134
57199397 47135 static inline void *jbd_alloc(size_t size, gfp_t flags)
16454cff
MT
47136diff -urNp linux-2.6.38.1/include/linux/kallsyms.h linux-2.6.38.1/include/linux/kallsyms.h
47137--- linux-2.6.38.1/include/linux/kallsyms.h 2011-03-14 21:20:32.000000000 -0400
47138+++ linux-2.6.38.1/include/linux/kallsyms.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
47139@@ -15,7 +15,8 @@
47140
47141 struct module;
47142
47143-#ifdef CONFIG_KALLSYMS
bc901d79 47144+#if !defined(__INCLUDED_BY_HIDESYM) || !defined(CONFIG_KALLSYMS)
58c5fc13
MT
47145+#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
47146 /* Lookup the address for a symbol. Returns 0 if not found. */
47147 unsigned long kallsyms_lookup_name(const char *name);
47148
bc901d79 47149@@ -92,6 +93,15 @@ static inline int lookup_symbol_attrs(un
58c5fc13
MT
47150 /* Stupid that this does nothing, but I didn't create this mess. */
47151 #define __print_symbol(fmt, addr)
47152 #endif /*CONFIG_KALLSYMS*/
bc901d79
MT
47153+#else /* when included by kallsyms.c, vsnprintf.c, or
47154+ arch/x86/kernel/dumpstack.c, with HIDESYM enabled */
58c5fc13 47155+extern void __print_symbol(const char *fmt, unsigned long address);
bc901d79
MT
47156+extern int sprint_symbol(char *buffer, unsigned long address);
47157+const char *kallsyms_lookup(unsigned long addr,
47158+ unsigned long *symbolsize,
47159+ unsigned long *offset,
47160+ char **modname, char *namebuf);
58c5fc13
MT
47161+#endif
47162
47163 /* This macro allows us to keep printk typechecking */
47164 static void __check_printsym_format(const char *fmt, ...)
16454cff
MT
47165diff -urNp linux-2.6.38.1/include/linux/kgdb.h linux-2.6.38.1/include/linux/kgdb.h
47166--- linux-2.6.38.1/include/linux/kgdb.h 2011-03-14 21:20:32.000000000 -0400
47167+++ linux-2.6.38.1/include/linux/kgdb.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 47168@@ -269,22 +269,22 @@ struct kgdb_arch {
ae4e228f
MT
47169 */
47170 struct kgdb_io {
47171 const char *name;
47172- int (*read_char) (void);
47173- void (*write_char) (u8);
47174- void (*flush) (void);
47175- int (*init) (void);
47176- void (*pre_exception) (void);
47177- void (*post_exception) (void);
47178+ int (* const read_char) (void);
47179+ void (* const write_char) (u8);
47180+ void (* const flush) (void);
47181+ int (* const init) (void);
47182+ void (* const pre_exception) (void);
47183+ void (* const post_exception) (void);
57199397 47184 int is_console;
ae4e228f
MT
47185 };
47186
47187-extern struct kgdb_arch arch_kgdb_ops;
47188+extern const struct kgdb_arch arch_kgdb_ops;
47189
47190 extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs);
47191
47192-extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops);
47193-extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops);
57199397 47194-extern struct kgdb_io *dbg_io_ops;
ae4e228f
MT
47195+extern int kgdb_register_io_module(const struct kgdb_io *local_kgdb_io_ops);
47196+extern void kgdb_unregister_io_module(const struct kgdb_io *local_kgdb_io_ops);
57199397 47197+extern const struct kgdb_io *dbg_io_ops;
ae4e228f
MT
47198
47199 extern int kgdb_hex2long(char **ptr, unsigned long *long_val);
6892158b 47200 extern char *kgdb_mem2hex(char *mem, char *buf, int count);
16454cff
MT
47201diff -urNp linux-2.6.38.1/include/linux/kvm_host.h linux-2.6.38.1/include/linux/kvm_host.h
47202--- linux-2.6.38.1/include/linux/kvm_host.h 2011-03-14 21:20:32.000000000 -0400
47203+++ linux-2.6.38.1/include/linux/kvm_host.h 2011-03-21 18:31:35.000000000 -0400
47204@@ -288,7 +288,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vc
58c5fc13
MT
47205 void vcpu_load(struct kvm_vcpu *vcpu);
47206 void vcpu_put(struct kvm_vcpu *vcpu);
47207
57199397
MT
47208-int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
47209+int kvm_init(const void *opaque, unsigned vcpu_size, unsigned vcpu_align,
58c5fc13
MT
47210 struct module *module);
47211 void kvm_exit(void);
47212
16454cff 47213@@ -428,7 +428,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(
58c5fc13
MT
47214 struct kvm_guest_debug *dbg);
47215 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
47216
47217-int kvm_arch_init(void *opaque);
47218+int kvm_arch_init(const void *opaque);
47219 void kvm_arch_exit(void);
47220
47221 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu);
16454cff
MT
47222diff -urNp linux-2.6.38.1/include/linux/libata.h linux-2.6.38.1/include/linux/libata.h
47223--- linux-2.6.38.1/include/linux/libata.h 2011-03-14 21:20:32.000000000 -0400
47224+++ linux-2.6.38.1/include/linux/libata.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 47225@@ -65,11 +65,11 @@
58c5fc13
MT
47226 #ifdef ATA_VERBOSE_DEBUG
47227 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
47228 #else
47229-#define VPRINTK(fmt, args...)
47230+#define VPRINTK(fmt, args...) do {} while (0)
47231 #endif /* ATA_VERBOSE_DEBUG */
47232 #else
47233-#define DPRINTK(fmt, args...)
47234-#define VPRINTK(fmt, args...)
47235+#define DPRINTK(fmt, args...) do {} while (0)
47236+#define VPRINTK(fmt, args...) do {} while (0)
47237 #endif /* ATA_DEBUG */
47238
47239 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
bc901d79 47240@@ -530,11 +530,11 @@ struct ata_ioports {
ae4e228f
MT
47241
47242 struct ata_host {
47243 spinlock_t lock;
47244- struct device *dev;
47245+ struct device *dev;
47246 void __iomem * const *iomap;
47247 unsigned int n_ports;
47248 void *private_data;
47249- struct ata_port_operations *ops;
47250+ const struct ata_port_operations *ops;
47251 unsigned long flags;
bc901d79
MT
47252
47253 struct mutex eh_mutex;
47254@@ -725,7 +725,7 @@ struct ata_link {
ae4e228f
MT
47255
47256 struct ata_port {
47257 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */
47258- struct ata_port_operations *ops;
47259+ const struct ata_port_operations *ops;
47260 spinlock_t *lock;
47261 /* Flags owned by the EH context. Only EH should touch these once the
47262 port is active */
bc901d79 47263@@ -913,7 +913,7 @@ struct ata_port_info {
ae4e228f
MT
47264 unsigned long pio_mask;
47265 unsigned long mwdma_mask;
47266 unsigned long udma_mask;
47267- struct ata_port_operations *port_ops;
47268+ const struct ata_port_operations *port_ops;
47269 void *private_data;
47270 };
47271
bc901d79 47272@@ -937,7 +937,7 @@ extern const unsigned long sata_deb_timi
ae4e228f
MT
47273 extern const unsigned long sata_deb_timing_hotplug[];
47274 extern const unsigned long sata_deb_timing_long[];
47275
47276-extern struct ata_port_operations ata_dummy_port_ops;
47277+extern const struct ata_port_operations ata_dummy_port_ops;
47278 extern const struct ata_port_info ata_dummy_port_info;
47279
47280 static inline const unsigned long *
bc901d79 47281@@ -983,7 +983,7 @@ extern int ata_host_activate(struct ata_
ae4e228f
MT
47282 struct scsi_host_template *sht);
47283 extern void ata_host_detach(struct ata_host *host);
47284 extern void ata_host_init(struct ata_host *, struct device *,
47285- unsigned long, struct ata_port_operations *);
47286+ unsigned long, const struct ata_port_operations *);
47287 extern int ata_scsi_detect(struct scsi_host_template *sht);
47288 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
bc901d79 47289 extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd);
16454cff
MT
47290diff -urNp linux-2.6.38.1/include/linux/lockd/bind.h linux-2.6.38.1/include/linux/lockd/bind.h
47291--- linux-2.6.38.1/include/linux/lockd/bind.h 2011-03-14 21:20:32.000000000 -0400
47292+++ linux-2.6.38.1/include/linux/lockd/bind.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
47293@@ -23,13 +23,13 @@ struct svc_rqst;
47294 * This is the set of functions for lockd->nfsd communication
47295 */
47296 struct nlmsvc_binding {
47297- __be32 (*fopen)(struct svc_rqst *,
47298+ __be32 (* const fopen)(struct svc_rqst *,
47299 struct nfs_fh *,
47300 struct file **);
47301- void (*fclose)(struct file *);
47302+ void (* const fclose)(struct file *);
47303 };
47304
47305-extern struct nlmsvc_binding * nlmsvc_ops;
47306+extern const struct nlmsvc_binding * nlmsvc_ops;
47307
47308 /*
47309 * Similar to nfs_client_initdata, but without the NFS-specific
16454cff
MT
47310diff -urNp linux-2.6.38.1/include/linux/mm.h linux-2.6.38.1/include/linux/mm.h
47311--- linux-2.6.38.1/include/linux/mm.h 2011-03-14 21:20:32.000000000 -0400
47312+++ linux-2.6.38.1/include/linux/mm.h 2011-03-21 18:31:35.000000000 -0400
47313@@ -113,7 +113,14 @@ extern unsigned int kobjsize(const void
58c5fc13 47314
df50ba0c
MT
47315 #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
47316 #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
47317+
47318+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
47319+#define VM_SAO 0x00000000 /* Strong Access Ordering (powerpc) */
47320+#define VM_PAGEEXEC 0x20000000 /* vma->vm_page_prot needs special handling */
47321+#else
47322 #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
58c5fc13
MT
47323+#endif
47324+
df50ba0c
MT
47325 #define VM_PFN_AT_MMAP 0x40000000 /* PFNMAP vma that is fully mapped at mmap time */
47326 #define VM_MERGEABLE 0x80000000 /* KSM may merge identical pages */
47327
16454cff 47328@@ -985,12 +992,6 @@ int set_page_dirty(struct page *page);
bc901d79
MT
47329 int set_page_dirty_lock(struct page *page);
47330 int clear_page_dirty_for_io(struct page *page);
47331
47332-/* Is the vma a continuation of the stack vma above it? */
47333-static inline int vma_stack_continue(struct vm_area_struct *vma, unsigned long addr)
47334-{
47335- return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN);
47336-}
47337-
47338 extern unsigned long move_page_tables(struct vm_area_struct *vma,
47339 unsigned long old_addr, struct vm_area_struct *new_vma,
47340 unsigned long new_addr, unsigned long len);
16454cff 47341@@ -1142,6 +1143,15 @@ struct shrinker {
58c5fc13
MT
47342 extern void register_shrinker(struct shrinker *);
47343 extern void unregister_shrinker(struct shrinker *);
47344
6892158b 47345+#ifdef CONFIG_MMU
58c5fc13 47346+pgprot_t vm_get_page_prot(unsigned long vm_flags);
6892158b
MT
47347+#else
47348+static inline pgprot_t vm_get_page_prot(unsigned long vm_flags)
47349+{
47350+ return __pgprot(0);
47351+}
47352+#endif
58c5fc13
MT
47353+
47354 int vma_wants_writenotify(struct vm_area_struct *vma);
47355
bc901d79 47356 extern pte_t *__get_locked_pte(struct mm_struct *mm, unsigned long addr,
16454cff 47357@@ -1431,6 +1441,7 @@ out:
58c5fc13
MT
47358 }
47359
47360 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
47361+extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
47362
47363 extern unsigned long do_brk(unsigned long, unsigned long);
47364
16454cff 47365@@ -1487,6 +1498,10 @@ extern struct vm_area_struct * find_vma(
58c5fc13
MT
47366 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
47367 struct vm_area_struct **pprev);
47368
47369+extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
df50ba0c 47370+extern __must_check long pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
58c5fc13
MT
47371+extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
47372+
47373 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
47374 NULL if none. Assume start_addr < end_addr. */
47375 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
16454cff 47376@@ -1503,15 +1518,6 @@ static inline unsigned long vma_pages(st
58c5fc13
MT
47377 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
47378 }
47379
6892158b 47380-#ifdef CONFIG_MMU
58c5fc13 47381-pgprot_t vm_get_page_prot(unsigned long vm_flags);
6892158b
MT
47382-#else
47383-static inline pgprot_t vm_get_page_prot(unsigned long vm_flags)
47384-{
47385- return __pgprot(0);
47386-}
47387-#endif
47388-
58c5fc13
MT
47389 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
47390 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
47391 unsigned long pfn, unsigned long size, pgprot_t);
16454cff 47392@@ -1620,7 +1626,7 @@ extern int unpoison_memory(unsigned long
ae4e228f
MT
47393 extern int sysctl_memory_failure_early_kill;
47394 extern int sysctl_memory_failure_recovery;
47395 extern void shake_page(struct page *p, int access);
47396-extern atomic_long_t mce_bad_pages;
47397+extern atomic_long_unchecked_t mce_bad_pages;
47398 extern int soft_offline_page(struct page *page, int flags);
6892158b
MT
47399 #ifdef CONFIG_MEMORY_FAILURE
47400 int is_hwpoison_address(unsigned long addr);
16454cff
MT
47401@@ -1642,5 +1648,11 @@ extern void copy_user_huge_page(struct p
47402 unsigned int pages_per_huge_page);
47403 #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
df50ba0c 47404
58c5fc13
MT
47405+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
47406+extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
47407+#else
47408+static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
47409+#endif
47410+
47411 #endif /* __KERNEL__ */
47412 #endif /* _LINUX_MM_H */
16454cff
MT
47413diff -urNp linux-2.6.38.1/include/linux/mm_types.h linux-2.6.38.1/include/linux/mm_types.h
47414--- linux-2.6.38.1/include/linux/mm_types.h 2011-03-14 21:20:32.000000000 -0400
47415+++ linux-2.6.38.1/include/linux/mm_types.h 2011-03-21 18:31:35.000000000 -0400
df50ba0c 47416@@ -183,6 +183,8 @@ struct vm_area_struct {
58c5fc13
MT
47417 #ifdef CONFIG_NUMA
47418 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
47419 #endif
47420+
47421+ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
47422 };
47423
47424 struct core_thread {
16454cff 47425@@ -315,6 +317,24 @@ struct mm_struct {
58c5fc13 47426 #endif
bc901d79
MT
47427 /* How many tasks sharing this mm are OOM_DISABLE */
47428 atomic_t oom_disable_count;
58c5fc13
MT
47429+
47430+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
47431+ unsigned long pax_flags;
47432+#endif
47433+
47434+#ifdef CONFIG_PAX_DLRESOLVE
47435+ unsigned long call_dl_resolve;
47436+#endif
47437+
47438+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
47439+ unsigned long call_syscall;
47440+#endif
47441+
47442+#ifdef CONFIG_PAX_ASLR
47443+ unsigned long delta_mmap; /* randomized offset */
47444+ unsigned long delta_stack; /* randomized offset */
47445+#endif
47446+
47447 };
47448
47449 /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */
16454cff
MT
47450diff -urNp linux-2.6.38.1/include/linux/mmu_notifier.h linux-2.6.38.1/include/linux/mmu_notifier.h
47451--- linux-2.6.38.1/include/linux/mmu_notifier.h 2011-03-14 21:20:32.000000000 -0400
47452+++ linux-2.6.38.1/include/linux/mmu_notifier.h 2011-03-21 18:31:35.000000000 -0400
47453@@ -255,12 +255,12 @@ static inline void mmu_notifier_mm_destr
ae4e228f
MT
47454 */
47455 #define ptep_clear_flush_notify(__vma, __address, __ptep) \
47456 ({ \
47457- pte_t __pte; \
47458+ pte_t ___pte; \
47459 struct vm_area_struct *___vma = __vma; \
47460 unsigned long ___address = __address; \
47461- __pte = ptep_clear_flush(___vma, ___address, __ptep); \
47462+ ___pte = ptep_clear_flush(___vma, ___address, __ptep); \
47463 mmu_notifier_invalidate_page(___vma->vm_mm, ___address); \
47464- __pte; \
47465+ ___pte; \
47466 })
47467
16454cff
MT
47468 #define pmdp_clear_flush_notify(__vma, __address, __pmdp) \
47469diff -urNp linux-2.6.38.1/include/linux/mmzone.h linux-2.6.38.1/include/linux/mmzone.h
47470--- linux-2.6.38.1/include/linux/mmzone.h 2011-03-14 21:20:32.000000000 -0400
47471+++ linux-2.6.38.1/include/linux/mmzone.h 2011-03-21 18:31:35.000000000 -0400
47472@@ -355,7 +355,7 @@ struct zone {
57199397
MT
47473 unsigned long flags; /* zone flags, see below */
47474
47475 /* Zone statistics */
47476- atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
47477+ atomic_long_unchecked_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
47478
47479 /*
6892158b 47480 * The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on
16454cff
MT
47481diff -urNp linux-2.6.38.1/include/linux/mod_devicetable.h linux-2.6.38.1/include/linux/mod_devicetable.h
47482--- linux-2.6.38.1/include/linux/mod_devicetable.h 2011-03-14 21:20:32.000000000 -0400
47483+++ linux-2.6.38.1/include/linux/mod_devicetable.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
47484@@ -12,7 +12,7 @@
47485 typedef unsigned long kernel_ulong_t;
47486 #endif
47487
47488-#define PCI_ANY_ID (~0)
47489+#define PCI_ANY_ID ((__u16)~0)
47490
47491 struct pci_device_id {
47492 __u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
47493@@ -131,7 +131,7 @@ struct usb_device_id {
47494 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
47495 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
47496
47497-#define HID_ANY_ID (~0)
47498+#define HID_ANY_ID (~0U)
47499
47500 struct hid_device_id {
47501 __u16 bus;
16454cff
MT
47502diff -urNp linux-2.6.38.1/include/linux/module.h linux-2.6.38.1/include/linux/module.h
47503--- linux-2.6.38.1/include/linux/module.h 2011-03-14 21:20:32.000000000 -0400
47504+++ linux-2.6.38.1/include/linux/module.h 2011-03-21 18:31:35.000000000 -0400
47505@@ -324,19 +324,16 @@ struct module
58c5fc13
MT
47506 int (*init)(void);
47507
47508 /* If this is non-NULL, vfree after init() returns */
47509- void *module_init;
47510+ void *module_init_rx, *module_init_rw;
47511
47512 /* Here is the actual code + data, vfree'd on unload. */
47513- void *module_core;
47514+ void *module_core_rx, *module_core_rw;
47515
47516 /* Here are the sizes of the init and core sections */
47517- unsigned int init_size, core_size;
47518+ unsigned int init_size_rw, core_size_rw;
47519
47520 /* The size of the executable code in each section. */
47521- unsigned int init_text_size, core_text_size;
16454cff
MT
47522-
47523- /* Size of RO sections of the module (text+rodata) */
47524- unsigned int init_ro_size, core_ro_size;
58c5fc13
MT
47525+ unsigned int init_size_rx, core_size_rx;
47526
47527 /* Arch-specific module values */
47528 struct mod_arch_specific arch;
16454cff 47529@@ -441,16 +438,46 @@ bool is_module_address(unsigned long add
df50ba0c 47530 bool is_module_percpu_address(unsigned long addr);
58c5fc13
MT
47531 bool is_module_text_address(unsigned long addr);
47532
47533+static inline int within_module_range(unsigned long addr, void *start, unsigned long size)
47534+{
47535+
47536+#ifdef CONFIG_PAX_KERNEXEC
47537+ if (ktla_ktva(addr) >= (unsigned long)start &&
47538+ ktla_ktva(addr) < (unsigned long)start + size)
47539+ return 1;
47540+#endif
47541+
47542+ return ((void *)addr >= start && (void *)addr < start + size);
47543+}
47544+
47545+static inline int within_module_core_rx(unsigned long addr, struct module *mod)
47546+{
47547+ return within_module_range(addr, mod->module_core_rx, mod->core_size_rx);
47548+}
47549+
47550+static inline int within_module_core_rw(unsigned long addr, struct module *mod)
47551+{
47552+ return within_module_range(addr, mod->module_core_rw, mod->core_size_rw);
47553+}
47554+
47555+static inline int within_module_init_rx(unsigned long addr, struct module *mod)
47556+{
47557+ return within_module_range(addr, mod->module_init_rx, mod->init_size_rx);
47558+}
47559+
47560+static inline int within_module_init_rw(unsigned long addr, struct module *mod)
47561+{
47562+ return within_module_range(addr, mod->module_init_rw, mod->init_size_rw);
47563+}
47564+
47565 static inline int within_module_core(unsigned long addr, struct module *mod)
47566 {
47567- return (unsigned long)mod->module_core <= addr &&
47568- addr < (unsigned long)mod->module_core + mod->core_size;
47569+ return within_module_core_rx(addr, mod) || within_module_core_rw(addr, mod);
47570 }
47571
47572 static inline int within_module_init(unsigned long addr, struct module *mod)
47573 {
47574- return (unsigned long)mod->module_init <= addr &&
47575- addr < (unsigned long)mod->module_init + mod->init_size;
47576+ return within_module_init_rx(addr, mod) || within_module_init_rw(addr, mod);
47577 }
47578
47579 /* Search for module by name: must hold module_mutex. */
16454cff
MT
47580diff -urNp linux-2.6.38.1/include/linux/moduleloader.h linux-2.6.38.1/include/linux/moduleloader.h
47581--- linux-2.6.38.1/include/linux/moduleloader.h 2011-03-14 21:20:32.000000000 -0400
47582+++ linux-2.6.38.1/include/linux/moduleloader.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
47583@@ -20,9 +20,21 @@ unsigned int arch_mod_section_prepend(st
47584 sections. Returns NULL on failure. */
47585 void *module_alloc(unsigned long size);
47586
47587+#ifdef CONFIG_PAX_KERNEXEC
47588+void *module_alloc_exec(unsigned long size);
47589+#else
47590+#define module_alloc_exec(x) module_alloc(x)
47591+#endif
47592+
47593 /* Free memory returned from module_alloc. */
47594 void module_free(struct module *mod, void *module_region);
47595
47596+#ifdef CONFIG_PAX_KERNEXEC
47597+void module_free_exec(struct module *mod, void *module_region);
47598+#else
ae4e228f 47599+#define module_free_exec(x, y) module_free((x), (y))
58c5fc13
MT
47600+#endif
47601+
47602 /* Apply the given relocation to the (simplified) ELF. Return -error
47603 or 0. */
47604 int apply_relocate(Elf_Shdr *sechdrs,
16454cff
MT
47605diff -urNp linux-2.6.38.1/include/linux/moduleparam.h linux-2.6.38.1/include/linux/moduleparam.h
47606--- linux-2.6.38.1/include/linux/moduleparam.h 2011-03-14 21:20:32.000000000 -0400
47607+++ linux-2.6.38.1/include/linux/moduleparam.h 2011-03-21 18:31:35.000000000 -0400
47608@@ -255,7 +255,7 @@ static inline void __kernel_param_unlock
6892158b
MT
47609 * @len is usually just sizeof(string).
47610 */
47611 #define module_param_string(name, string, len, perm) \
47612- static const struct kparam_string __param_string_##name \
47613+ static const struct kparam_string __param_string_##name __used \
47614 = { len, string }; \
47615 __module_param_call(MODULE_PARAM_PREFIX, name, \
47616 &param_ops_string, \
16454cff 47617@@ -370,7 +370,7 @@ extern int param_get_invbool(char *buffe
6892158b
MT
47618 * module_param_named() for why this might be necessary.
47619 */
47620 #define module_param_array_named(name, array, type, nump, perm) \
47621- static const struct kparam_array __param_arr_##name \
47622+ static const struct kparam_array __param_arr_##name __used \
47623 = { ARRAY_SIZE(array), nump, &param_ops_##type, \
47624 sizeof(array[0]), array }; \
47625 __module_param_call(MODULE_PARAM_PREFIX, name, \
16454cff
MT
47626diff -urNp linux-2.6.38.1/include/linux/namei.h linux-2.6.38.1/include/linux/namei.h
47627--- linux-2.6.38.1/include/linux/namei.h 2011-03-14 21:20:32.000000000 -0400
47628+++ linux-2.6.38.1/include/linux/namei.h 2011-03-21 18:31:35.000000000 -0400
47629@@ -25,7 +25,7 @@ struct nameidata {
47630 unsigned seq;
58c5fc13
MT
47631 int last_type;
47632 unsigned depth;
47633- char *saved_names[MAX_NESTED_LINKS + 1];
47634+ const char *saved_names[MAX_NESTED_LINKS + 1];
47635
47636 /* Intent data */
47637 union {
16454cff 47638@@ -88,12 +88,12 @@ extern int follow_up(struct path *);
58c5fc13
MT
47639 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
47640 extern void unlock_rename(struct dentry *, struct dentry *);
47641
47642-static inline void nd_set_link(struct nameidata *nd, char *path)
47643+static inline void nd_set_link(struct nameidata *nd, const char *path)
47644 {
47645 nd->saved_names[nd->depth] = path;
47646 }
47647
47648-static inline char *nd_get_link(struct nameidata *nd)
ae4e228f 47649+static inline const char *nd_get_link(const struct nameidata *nd)
58c5fc13
MT
47650 {
47651 return nd->saved_names[nd->depth];
47652 }
16454cff
MT
47653diff -urNp linux-2.6.38.1/include/linux/netfilter/xt_gradm.h linux-2.6.38.1/include/linux/netfilter/xt_gradm.h
47654--- linux-2.6.38.1/include/linux/netfilter/xt_gradm.h 1969-12-31 19:00:00.000000000 -0500
47655+++ linux-2.6.38.1/include/linux/netfilter/xt_gradm.h 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
47656@@ -0,0 +1,9 @@
47657+#ifndef _LINUX_NETFILTER_XT_GRADM_H
47658+#define _LINUX_NETFILTER_XT_GRADM_H 1
47659+
47660+struct xt_gradm_mtinfo {
47661+ __u16 flags;
47662+ __u16 invflags;
47663+};
47664+
47665+#endif
16454cff
MT
47666diff -urNp linux-2.6.38.1/include/linux/oprofile.h linux-2.6.38.1/include/linux/oprofile.h
47667--- linux-2.6.38.1/include/linux/oprofile.h 2011-03-14 21:20:32.000000000 -0400
47668+++ linux-2.6.38.1/include/linux/oprofile.h 2011-03-21 18:31:35.000000000 -0400
c52201e0 47669@@ -132,9 +132,9 @@ int oprofilefs_create_ulong(struct super
ae4e228f
MT
47670 int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root,
47671 char const * name, ulong * val);
58c5fc13 47672
ae4e228f
MT
47673-/** Create a file for read-only access to an atomic_t. */
47674+/** Create a file for read-only access to an atomic_unchecked_t. */
58c5fc13
MT
47675 int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root,
47676- char const * name, atomic_t * val);
47677+ char const * name, atomic_unchecked_t * val);
47678
47679 /** create a directory */
47680 struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root,
16454cff
MT
47681diff -urNp linux-2.6.38.1/include/linux/pipe_fs_i.h linux-2.6.38.1/include/linux/pipe_fs_i.h
47682--- linux-2.6.38.1/include/linux/pipe_fs_i.h 2011-03-14 21:20:32.000000000 -0400
47683+++ linux-2.6.38.1/include/linux/pipe_fs_i.h 2011-03-21 18:31:35.000000000 -0400
47684@@ -46,9 +46,9 @@ struct pipe_buffer {
57199397 47685 struct pipe_inode_info {
ae4e228f 47686 wait_queue_head_t wait;
57199397 47687 unsigned int nrbufs, curbuf, buffers;
ae4e228f
MT
47688- unsigned int readers;
47689- unsigned int writers;
47690- unsigned int waiting_writers;
47691+ atomic_t readers;
47692+ atomic_t writers;
47693+ atomic_t waiting_writers;
47694 unsigned int r_counter;
47695 unsigned int w_counter;
57199397 47696 struct page *tmp_page;
16454cff
MT
47697diff -urNp linux-2.6.38.1/include/linux/pm_runtime.h linux-2.6.38.1/include/linux/pm_runtime.h
47698--- linux-2.6.38.1/include/linux/pm_runtime.h 2011-03-14 21:20:32.000000000 -0400
47699+++ linux-2.6.38.1/include/linux/pm_runtime.h 2011-03-21 18:31:35.000000000 -0400
47700@@ -89,7 +89,7 @@ static inline bool pm_runtime_enabled(st
bc901d79
MT
47701
47702 static inline void pm_runtime_mark_last_busy(struct device *dev)
47703 {
47704- ACCESS_ONCE(dev->power.last_busy) = jiffies;
47705+ ACCESS_ONCE_RW(dev->power.last_busy) = jiffies;
47706 }
47707
47708 #else /* !CONFIG_PM_RUNTIME */
16454cff
MT
47709diff -urNp linux-2.6.38.1/include/linux/poison.h linux-2.6.38.1/include/linux/poison.h
47710--- linux-2.6.38.1/include/linux/poison.h 2011-03-14 21:20:32.000000000 -0400
47711+++ linux-2.6.38.1/include/linux/poison.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 47712@@ -19,8 +19,8 @@
58c5fc13
MT
47713 * under normal circumstances, used to verify that nobody uses
47714 * non-initialized list entries.
47715 */
ae4e228f
MT
47716-#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)
47717-#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA)
47718+#define LIST_POISON1 ((void *) (long)0xFFFFFF01)
47719+#define LIST_POISON2 ((void *) (long)0xFFFFFF02)
58c5fc13
MT
47720
47721 /********** include/linux/timer.h **********/
47722 /*
16454cff
MT
47723diff -urNp linux-2.6.38.1/include/linux/proc_fs.h linux-2.6.38.1/include/linux/proc_fs.h
47724--- linux-2.6.38.1/include/linux/proc_fs.h 2011-03-14 21:20:32.000000000 -0400
47725+++ linux-2.6.38.1/include/linux/proc_fs.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 47726@@ -155,6 +155,19 @@ static inline struct proc_dir_entry *pro
58c5fc13
MT
47727 return proc_create_data(name, mode, parent, proc_fops, NULL);
47728 }
47729
47730+static inline struct proc_dir_entry *proc_create_grsec(const char *name, mode_t mode,
47731+ struct proc_dir_entry *parent, const struct file_operations *proc_fops)
47732+{
47733+#ifdef CONFIG_GRKERNSEC_PROC_USER
47734+ return proc_create_data(name, S_IRUSR, parent, proc_fops, NULL);
47735+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
47736+ return proc_create_data(name, S_IRUSR | S_IRGRP, parent, proc_fops, NULL);
47737+#else
47738+ return proc_create_data(name, mode, parent, proc_fops, NULL);
47739+#endif
47740+}
47741+
47742+
47743 static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
47744 mode_t mode, struct proc_dir_entry *base,
47745 read_proc_t *read_proc, void * data)
16454cff
MT
47746diff -urNp linux-2.6.38.1/include/linux/ptrace.h linux-2.6.38.1/include/linux/ptrace.h
47747--- linux-2.6.38.1/include/linux/ptrace.h 2011-03-14 21:20:32.000000000 -0400
47748+++ linux-2.6.38.1/include/linux/ptrace.h 2011-03-26 11:36:13.000000000 -0400
47749@@ -115,10 +115,10 @@ extern void __ptrace_unlink(struct task_
47750 extern void exit_ptrace(struct task_struct *tracer);
47751 #define PTRACE_MODE_READ 1
47752 #define PTRACE_MODE_ATTACH 2
47753-/* Returns 0 on success, -errno on denial. */
47754-extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);
47755 /* Returns true on success, false on denial. */
47756 extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
47757+/* Returns true on success, false on denial. */
47758+extern bool ptrace_may_access_log(struct task_struct *task, unsigned int mode);
47759
47760 static inline int ptrace_reparented(struct task_struct *child)
47761 {
47762diff -urNp linux-2.6.38.1/include/linux/random.h linux-2.6.38.1/include/linux/random.h
47763--- linux-2.6.38.1/include/linux/random.h 2011-03-14 21:20:32.000000000 -0400
47764+++ linux-2.6.38.1/include/linux/random.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
47765@@ -80,12 +80,17 @@ void srandom32(u32 seed);
47766
47767 u32 prandom32(struct rnd_state *);
58c5fc13
MT
47768
47769+static inline unsigned long pax_get_random_long(void)
47770+{
47771+ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
47772+}
47773+
57199397
MT
47774 /*
47775 * Handle minimum values for seeds
47776 */
47777 static inline u32 __seed(u32 x, u32 m)
47778 {
47779- return (x < m) ? x + m : x;
47780+ return (x <= m) ? x + m + 1 : x;
47781 }
58c5fc13 47782
57199397 47783 /**
16454cff
MT
47784diff -urNp linux-2.6.38.1/include/linux/reiserfs_fs.h linux-2.6.38.1/include/linux/reiserfs_fs.h
47785--- linux-2.6.38.1/include/linux/reiserfs_fs.h 2011-03-14 21:20:32.000000000 -0400
47786+++ linux-2.6.38.1/include/linux/reiserfs_fs.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 47787@@ -1403,7 +1403,7 @@ static inline loff_t max_reiserfs_offset
58c5fc13
MT
47788 #define REISERFS_USER_MEM 1 /* reiserfs user memory mode */
47789
47790 #define fs_generation(s) (REISERFS_SB(s)->s_generation_counter)
47791-#define get_generation(s) atomic_read (&fs_generation(s))
47792+#define get_generation(s) atomic_read_unchecked (&fs_generation(s))
47793 #define FILESYSTEM_CHANGED_TB(tb) (get_generation((tb)->tb_sb) != (tb)->fs_gen)
47794 #define __fs_changed(gen,s) (gen != get_generation (s))
ae4e228f 47795 #define fs_changed(gen,s) \
bc901d79 47796@@ -1615,24 +1615,24 @@ static inline struct super_block *sb_fro
ae4e228f
MT
47797 */
47798
47799 struct item_operations {
47800- int (*bytes_number) (struct item_head * ih, int block_size);
47801- void (*decrement_key) (struct cpu_key *);
47802- int (*is_left_mergeable) (struct reiserfs_key * ih,
47803+ int (* const bytes_number) (struct item_head * ih, int block_size);
47804+ void (* const decrement_key) (struct cpu_key *);
47805+ int (* const is_left_mergeable) (struct reiserfs_key * ih,
47806 unsigned long bsize);
47807- void (*print_item) (struct item_head *, char *item);
47808- void (*check_item) (struct item_head *, char *item);
47809+ void (* const print_item) (struct item_head *, char *item);
47810+ void (* const check_item) (struct item_head *, char *item);
47811
47812- int (*create_vi) (struct virtual_node * vn, struct virtual_item * vi,
47813+ int (* const create_vi) (struct virtual_node * vn, struct virtual_item * vi,
47814 int is_affected, int insert_size);
47815- int (*check_left) (struct virtual_item * vi, int free,
47816+ int (* const check_left) (struct virtual_item * vi, int free,
47817 int start_skip, int end_skip);
47818- int (*check_right) (struct virtual_item * vi, int free);
47819- int (*part_size) (struct virtual_item * vi, int from, int to);
47820- int (*unit_num) (struct virtual_item * vi);
47821- void (*print_vi) (struct virtual_item * vi);
47822+ int (* const check_right) (struct virtual_item * vi, int free);
47823+ int (* const part_size) (struct virtual_item * vi, int from, int to);
47824+ int (* const unit_num) (struct virtual_item * vi);
47825+ void (* const print_vi) (struct virtual_item * vi);
47826 };
47827
47828-extern struct item_operations *item_ops[TYPE_ANY + 1];
47829+extern const struct item_operations * const item_ops[TYPE_ANY + 1];
47830
47831 #define op_bytes_number(ih,bsize) item_ops[le_ih_k_type (ih)]->bytes_number (ih, bsize)
47832 #define op_is_left_mergeable(key,bsize) item_ops[le_key_k_type (le_key_version (key), key)]->is_left_mergeable (key, bsize)
16454cff
MT
47833diff -urNp linux-2.6.38.1/include/linux/reiserfs_fs_sb.h linux-2.6.38.1/include/linux/reiserfs_fs_sb.h
47834--- linux-2.6.38.1/include/linux/reiserfs_fs_sb.h 2011-03-14 21:20:32.000000000 -0400
47835+++ linux-2.6.38.1/include/linux/reiserfs_fs_sb.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 47836@@ -386,7 +386,7 @@ struct reiserfs_sb_info {
58c5fc13
MT
47837 /* Comment? -Hans */
47838 wait_queue_head_t s_wait;
47839 /* To be obsoleted soon by per buffer seals.. -Hans */
47840- atomic_t s_generation_counter; // increased by one every time the
47841+ atomic_unchecked_t s_generation_counter; // increased by one every time the
47842 // tree gets re-balanced
47843 unsigned long s_properties; /* File system properties. Currently holds
47844 on-disk FS format */
16454cff
MT
47845diff -urNp linux-2.6.38.1/include/linux/rmap.h linux-2.6.38.1/include/linux/rmap.h
47846--- linux-2.6.38.1/include/linux/rmap.h 2011-03-14 21:20:32.000000000 -0400
47847+++ linux-2.6.38.1/include/linux/rmap.h 2011-03-21 18:31:35.000000000 -0400
6892158b 47848@@ -145,8 +145,8 @@ static inline void anon_vma_unlock(struc
57199397
MT
47849 void anon_vma_init(void); /* create anon_vma_cachep */
47850 int anon_vma_prepare(struct vm_area_struct *);
47851 void unlink_anon_vmas(struct vm_area_struct *);
47852-int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
47853-int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
47854+int anon_vma_clone(struct vm_area_struct *, const struct vm_area_struct *);
47855+int anon_vma_fork(struct vm_area_struct *, const struct vm_area_struct *);
47856 void __anon_vma_link(struct vm_area_struct *);
47857 void anon_vma_free(struct anon_vma *);
47858
16454cff
MT
47859diff -urNp linux-2.6.38.1/include/linux/sched.h linux-2.6.38.1/include/linux/sched.h
47860--- linux-2.6.38.1/include/linux/sched.h 2011-03-14 21:20:32.000000000 -0400
47861+++ linux-2.6.38.1/include/linux/sched.h 2011-03-26 17:18:15.000000000 -0400
47862@@ -99,6 +99,7 @@ struct robust_list_head;
57199397 47863 struct bio_list;
58c5fc13 47864 struct fs_struct;
ae4e228f 47865 struct perf_event_context;
58c5fc13
MT
47866+struct linux_binprm;
47867
47868 /*
47869 * List of flags we want to share for kernel threads,
16454cff 47870@@ -380,10 +381,13 @@ struct user_namespace;
57199397
MT
47871 #define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN)
47872
47873 extern int sysctl_max_map_count;
47874+extern unsigned long sysctl_heap_stack_gap;
47875
47876 #include <linux/aio.h>
47877
47878 #ifdef CONFIG_MMU
16454cff
MT
47879+extern bool check_heap_stack_gap(const struct vm_area_struct *vma, unsigned long addr, unsigned long len);
47880+extern unsigned long skip_heap_stack_gap(const struct vm_area_struct *vma, unsigned long len);
57199397
MT
47881 extern void arch_pick_mmap_layout(struct mm_struct *mm);
47882 extern unsigned long
47883 arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
16454cff
MT
47884@@ -628,6 +632,17 @@ struct signal_struct {
47885 #ifdef CONFIG_TASKSTATS
47886 struct taskstats *stats;
58c5fc13 47887 #endif
16454cff 47888+
58c5fc13
MT
47889+#ifdef CONFIG_GRKERNSEC
47890+ u32 curr_ip;
bc901d79 47891+ u32 saved_ip;
58c5fc13
MT
47892+ u32 gr_saddr;
47893+ u32 gr_daddr;
47894+ u16 gr_sport;
47895+ u16 gr_dport;
47896+ u8 used_accept:1;
47897+#endif
ae4e228f 47898+
16454cff
MT
47899 #ifdef CONFIG_AUDIT
47900 unsigned audit_tty;
47901 struct tty_audit_buf *tty_audit_buf;
47902@@ -1192,7 +1207,7 @@ enum perf_event_task_context {
58c5fc13
MT
47903
47904 struct task_struct {
47905 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
47906- void *stack;
47907+ struct thread_info *stack;
47908 atomic_t usage;
47909 unsigned int flags; /* per process flags, defined below */
47910 unsigned int ptrace;
16454cff 47911@@ -1307,8 +1322,8 @@ struct task_struct {
58c5fc13
MT
47912 struct list_head thread_group;
47913
47914 struct completion *vfork_done; /* for vfork() */
47915- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
47916- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
47917+ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
47918+ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
47919
47920 cputime_t utime, stime, utimescaled, stimescaled;
47921 cputime_t gtime;
16454cff 47922@@ -1324,13 +1339,6 @@ struct task_struct {
58c5fc13
MT
47923 struct task_cputime cputime_expires;
47924 struct list_head cpu_timers[3];
47925
47926-/* process credentials */
bc901d79 47927- const struct cred __rcu *real_cred; /* objective and real subjective task
58c5fc13 47928- * credentials (COW) */
bc901d79 47929- const struct cred __rcu *cred; /* effective (overridable) subjective task
58c5fc13 47930- * credentials (COW) */
ae4e228f 47931- struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */
58c5fc13
MT
47932-
47933 char comm[TASK_COMM_LEN]; /* executable name excluding path
47934 - access with [gs]et_task_comm (which lock
47935 it with task_lock())
16454cff 47936@@ -1349,6 +1357,10 @@ struct task_struct {
bc901d79
MT
47937 struct thread_struct thread;
47938 /* filesystem information */
47939 struct fs_struct *fs;
58c5fc13 47940+
bc901d79 47941+ const struct cred __rcu *cred; /* effective (overridable) subjective task
58c5fc13 47942+ * credentials (COW) */
58c5fc13 47943+
bc901d79
MT
47944 /* open file information */
47945 struct files_struct *files;
47946 /* namespaces */
16454cff 47947@@ -1395,6 +1407,11 @@ struct task_struct {
bc901d79
MT
47948 struct rt_mutex_waiter *pi_blocked_on;
47949 #endif
ae4e228f 47950
bc901d79
MT
47951+/* process credentials */
47952+ const struct cred __rcu *real_cred; /* objective and real subjective task
ae4e228f 47953+ * credentials (COW) */
bc901d79 47954+ struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */
ae4e228f 47955+
bc901d79
MT
47956 #ifdef CONFIG_DEBUG_MUTEXES
47957 /* mutex deadlock detection */
47958 struct mutex_waiter *blocked_on;
16454cff 47959@@ -1499,6 +1516,21 @@ struct task_struct {
ae4e228f
MT
47960 unsigned long default_timer_slack_ns;
47961
47962 struct list_head *scm_work_list;
58c5fc13
MT
47963+
47964+#ifdef CONFIG_GRKERNSEC
47965+ /* grsecurity */
df50ba0c 47966+ struct dentry *gr_chroot_dentry;
58c5fc13
MT
47967+ struct acl_subject_label *acl;
47968+ struct acl_role_label *role;
47969+ struct file *exec_file;
47970+ u16 acl_role_id;
16454cff 47971+ /* is this the task that authenticated to the special role */
58c5fc13
MT
47972+ u8 acl_sp_role;
47973+ u8 is_writable;
47974+ u8 brute;
df50ba0c 47975+ u8 gr_is_chrooted;
58c5fc13
MT
47976+#endif
47977+
ae4e228f 47978 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
df50ba0c 47979 /* Index of current stored address in ret_stack */
ae4e228f 47980 int curr_ret_stack;
16454cff 47981@@ -1530,6 +1562,52 @@ struct task_struct {
ae4e228f 47982 #endif
58c5fc13
MT
47983 };
47984
47985+#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
47986+#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
47987+#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
47988+#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
47989+/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
47990+#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
47991+
47992+#ifdef CONFIG_PAX_SOFTMODE
47993+extern unsigned int pax_softmode;
47994+#endif
47995+
47996+extern int pax_check_flags(unsigned long *);
47997+
47998+/* if tsk != current then task_lock must be held on it */
47999+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
48000+static inline unsigned long pax_get_flags(struct task_struct *tsk)
48001+{
48002+ if (likely(tsk->mm))
48003+ return tsk->mm->pax_flags;
48004+ else
48005+ return 0UL;
48006+}
48007+
48008+/* if tsk != current then task_lock must be held on it */
48009+static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
48010+{
48011+ if (likely(tsk->mm)) {
48012+ tsk->mm->pax_flags = flags;
48013+ return 0;
48014+ }
48015+ return -EINVAL;
48016+}
48017+#endif
48018+
48019+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
48020+extern void pax_set_initial_flags(struct linux_binprm *bprm);
48021+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
48022+extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
48023+#endif
48024+
48025+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
48026+void pax_report_insns(void *pc, void *sp);
48027+void pax_report_refcount_overflow(struct pt_regs *regs);
48028+void pax_report_leak_to_user(const void *ptr, unsigned long len);
48029+void pax_report_overflow_from_user(const void *ptr, unsigned long len);
48030+
48031 /* Future-safe accessor for struct task_struct's cpus_allowed. */
ae4e228f 48032 #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
58c5fc13 48033
16454cff 48034@@ -2169,7 +2247,7 @@ extern void __cleanup_sighand(struct sig
58c5fc13
MT
48035 extern void exit_itimers(struct signal_struct *);
48036 extern void flush_itimer_signals(void);
48037
48038-extern NORET_TYPE void do_group_exit(int);
48039+extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
48040
48041 extern void daemonize(const char *, ...);
48042 extern int allow_signal(int);
16454cff 48043@@ -2294,8 +2372,8 @@ static inline void unlock_task_sighand(s
58c5fc13
MT
48044
48045 #ifndef __HAVE_THREAD_FUNCTIONS
48046
48047-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
48048-#define task_stack_page(task) ((task)->stack)
48049+#define task_thread_info(task) ((task)->stack)
48050+#define task_stack_page(task) ((void *)(task)->stack)
48051
48052 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
48053 {
16454cff 48054@@ -2310,13 +2388,17 @@ static inline unsigned long *end_of_stac
58c5fc13
MT
48055
48056 #endif
48057
48058-static inline int object_is_on_stack(void *obj)
ae4e228f 48059+static inline int object_starts_on_stack(void *obj)
58c5fc13 48060 {
ae4e228f
MT
48061- void *stack = task_stack_page(current);
48062+ const void *stack = task_stack_page(current);
58c5fc13 48063
ae4e228f
MT
48064 return (obj >= stack) && (obj < (stack + THREAD_SIZE));
48065 }
48066
57199397
MT
48067+#ifdef CONFIG_PAX_USERCOPY
48068+extern int object_is_on_stack(const void *obj, unsigned long len);
48069+#endif
ae4e228f
MT
48070+
48071 extern void thread_info_cache_init(void);
48072
48073 #ifdef CONFIG_DEBUG_STACK_USAGE
16454cff
MT
48074diff -urNp linux-2.6.38.1/include/linux/screen_info.h linux-2.6.38.1/include/linux/screen_info.h
48075--- linux-2.6.38.1/include/linux/screen_info.h 2011-03-14 21:20:32.000000000 -0400
48076+++ linux-2.6.38.1/include/linux/screen_info.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 48077@@ -43,7 +43,8 @@ struct screen_info {
58c5fc13
MT
48078 __u16 pages; /* 0x32 */
48079 __u16 vesa_attributes; /* 0x34 */
48080 __u32 capabilities; /* 0x36 */
48081- __u8 _reserved[6]; /* 0x3a */
48082+ __u16 vesapm_size; /* 0x3a */
48083+ __u8 _reserved[4]; /* 0x3c */
48084 } __attribute__((packed));
48085
48086 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
16454cff
MT
48087diff -urNp linux-2.6.38.1/include/linux/security.h linux-2.6.38.1/include/linux/security.h
48088--- linux-2.6.38.1/include/linux/security.h 2011-03-14 21:20:32.000000000 -0400
48089+++ linux-2.6.38.1/include/linux/security.h 2011-03-21 18:31:35.000000000 -0400
6892158b 48090@@ -35,6 +35,7 @@
58c5fc13
MT
48091 #include <linux/key.h>
48092 #include <linux/xfrm.h>
df50ba0c 48093 #include <linux/slab.h>
58c5fc13
MT
48094+#include <linux/grsecurity.h>
48095 #include <net/flow.h>
48096
48097 /* Maximum number of letters for an LSM name string */
16454cff
MT
48098diff -urNp linux-2.6.38.1/include/linux/shm.h linux-2.6.38.1/include/linux/shm.h
48099--- linux-2.6.38.1/include/linux/shm.h 2011-03-14 21:20:32.000000000 -0400
48100+++ linux-2.6.38.1/include/linux/shm.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
48101@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
48102 pid_t shm_cprid;
48103 pid_t shm_lprid;
48104 struct user_struct *mlock_user;
48105+#ifdef CONFIG_GRKERNSEC
48106+ time_t shm_createtime;
48107+ pid_t shm_lapid;
48108+#endif
48109 };
48110
48111 /* shm_mode upper byte flags */
16454cff
MT
48112diff -urNp linux-2.6.38.1/include/linux/skbuff.h linux-2.6.38.1/include/linux/skbuff.h
48113--- linux-2.6.38.1/include/linux/skbuff.h 2011-03-14 21:20:32.000000000 -0400
48114+++ linux-2.6.38.1/include/linux/skbuff.h 2011-03-21 18:31:35.000000000 -0400
48115@@ -589,7 +589,7 @@ static inline struct skb_shared_hwtstamp
bc901d79
MT
48116 */
48117 static inline int skb_queue_empty(const struct sk_buff_head *list)
48118 {
48119- return list->next == (struct sk_buff *)list;
48120+ return list->next == (const struct sk_buff *)list;
48121 }
48122
48123 /**
16454cff 48124@@ -602,7 +602,7 @@ static inline int skb_queue_empty(const
bc901d79
MT
48125 static inline bool skb_queue_is_last(const struct sk_buff_head *list,
48126 const struct sk_buff *skb)
48127 {
48128- return skb->next == (struct sk_buff *)list;
48129+ return skb->next == (const struct sk_buff *)list;
48130 }
48131
48132 /**
16454cff 48133@@ -615,7 +615,7 @@ static inline bool skb_queue_is_last(con
bc901d79
MT
48134 static inline bool skb_queue_is_first(const struct sk_buff_head *list,
48135 const struct sk_buff *skb)
48136 {
48137- return skb->prev == (struct sk_buff *)list;
48138+ return skb->prev == (const struct sk_buff *)list;
48139 }
48140
48141 /**
16454cff
MT
48142diff -urNp linux-2.6.38.1/include/linux/slab.h linux-2.6.38.1/include/linux/slab.h
48143--- linux-2.6.38.1/include/linux/slab.h 2011-03-14 21:20:32.000000000 -0400
48144+++ linux-2.6.38.1/include/linux/slab.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
48145@@ -11,6 +11,7 @@
48146
48147 #include <linux/gfp.h>
48148 #include <linux/types.h>
48149+#include <linux/err.h>
48150
48151 /*
48152 * Flags to pass to kmem_cache_create().
df50ba0c 48153@@ -87,10 +88,13 @@
58c5fc13
MT
48154 * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
48155 * Both make kfree a no-op.
48156 */
48157-#define ZERO_SIZE_PTR ((void *)16)
ae4e228f
MT
48158+#define ZERO_SIZE_PTR \
48159+({ \
48160+ BUILD_BUG_ON(!(MAX_ERRNO & ~PAGE_MASK));\
48161+ (void *)(-MAX_ERRNO-1L); \
48162+})
58c5fc13
MT
48163
48164-#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
48165- (unsigned long)ZERO_SIZE_PTR)
df50ba0c 48166+#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) - 1 >= (unsigned long)ZERO_SIZE_PTR - 1)
58c5fc13
MT
48167
48168 /*
48169 * struct kmem_cache related prototypes
16454cff 48170@@ -142,6 +146,7 @@ void * __must_check krealloc(const void
58c5fc13
MT
48171 void kfree(const void *);
48172 void kzfree(const void *);
48173 size_t ksize(const void *);
48174+void check_object_size(const void *ptr, unsigned long n, bool to);
48175
48176 /*
48177 * Allocator specific definitions. These are mainly used to establish optimized
16454cff 48178@@ -334,4 +339,37 @@ static inline void *kzalloc_node(size_t
58c5fc13
MT
48179
48180 void __init kmem_cache_init_late(void);
48181
48182+#define kmalloc(x, y) \
48183+({ \
48184+ void *___retval; \
48185+ intoverflow_t ___x = (intoverflow_t)x; \
48186+ if (WARN(___x > ULONG_MAX, "kmalloc size overflow\n"))\
48187+ ___retval = NULL; \
48188+ else \
48189+ ___retval = kmalloc((size_t)___x, (y)); \
48190+ ___retval; \
48191+})
48192+
48193+#define kmalloc_node(x, y, z) \
48194+({ \
48195+ void *___retval; \
48196+ intoverflow_t ___x = (intoverflow_t)x; \
48197+ if (WARN(___x > ULONG_MAX, "kmalloc_node size overflow\n"))\
48198+ ___retval = NULL; \
48199+ else \
48200+ ___retval = kmalloc_node((size_t)___x, (y), (z));\
48201+ ___retval; \
48202+})
48203+
48204+#define kzalloc(x, y) \
48205+({ \
48206+ void *___retval; \
48207+ intoverflow_t ___x = (intoverflow_t)x; \
48208+ if (WARN(___x > ULONG_MAX, "kzalloc size overflow\n"))\
48209+ ___retval = NULL; \
48210+ else \
48211+ ___retval = kzalloc((size_t)___x, (y)); \
48212+ ___retval; \
48213+})
48214+
48215 #endif /* _LINUX_SLAB_H */
16454cff
MT
48216diff -urNp linux-2.6.38.1/include/linux/slub_def.h linux-2.6.38.1/include/linux/slub_def.h
48217--- linux-2.6.38.1/include/linux/slub_def.h 2011-03-14 21:20:32.000000000 -0400
48218+++ linux-2.6.38.1/include/linux/slub_def.h 2011-03-21 18:31:35.000000000 -0400
48219@@ -79,7 +79,7 @@ struct kmem_cache {
58c5fc13
MT
48220 struct kmem_cache_order_objects max;
48221 struct kmem_cache_order_objects min;
48222 gfp_t allocflags; /* gfp flags to use on each alloc */
48223- int refcount; /* Refcount for slab cache destroy */
48224+ atomic_t refcount; /* Refcount for slab cache destroy */
48225 void (*ctor)(void *);
48226 int inuse; /* Offset to metadata */
48227 int align; /* Alignment */
16454cff
MT
48228diff -urNp linux-2.6.38.1/include/linux/sonet.h linux-2.6.38.1/include/linux/sonet.h
48229--- linux-2.6.38.1/include/linux/sonet.h 2011-03-14 21:20:32.000000000 -0400
48230+++ linux-2.6.38.1/include/linux/sonet.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
48231@@ -61,7 +61,7 @@ struct sonet_stats {
48232 #include <asm/atomic.h>
48233
48234 struct k_sonet_stats {
48235-#define __HANDLE_ITEM(i) atomic_t i
48236+#define __HANDLE_ITEM(i) atomic_unchecked_t i
48237 __SONET_ITEMS
48238 #undef __HANDLE_ITEM
48239 };
16454cff
MT
48240diff -urNp linux-2.6.38.1/include/linux/sunrpc/clnt.h linux-2.6.38.1/include/linux/sunrpc/clnt.h
48241--- linux-2.6.38.1/include/linux/sunrpc/clnt.h 2011-03-14 21:20:32.000000000 -0400
48242+++ linux-2.6.38.1/include/linux/sunrpc/clnt.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
48243@@ -168,9 +168,9 @@ static inline unsigned short rpc_get_por
48244 {
48245 switch (sap->sa_family) {
48246 case AF_INET:
48247- return ntohs(((struct sockaddr_in *)sap)->sin_port);
48248+ return ntohs(((const struct sockaddr_in *)sap)->sin_port);
48249 case AF_INET6:
48250- return ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
48251+ return ntohs(((const struct sockaddr_in6 *)sap)->sin6_port);
48252 }
48253 return 0;
48254 }
48255@@ -203,7 +203,7 @@ static inline bool __rpc_cmp_addr4(const
48256 static inline bool __rpc_copy_addr4(struct sockaddr *dst,
48257 const struct sockaddr *src)
48258 {
48259- const struct sockaddr_in *ssin = (struct sockaddr_in *) src;
48260+ const struct sockaddr_in *ssin = (const struct sockaddr_in *) src;
48261 struct sockaddr_in *dsin = (struct sockaddr_in *) dst;
48262
48263 dsin->sin_family = ssin->sin_family;
48264@@ -300,7 +300,7 @@ static inline u32 rpc_get_scope_id(const
48265 if (sa->sa_family != AF_INET6)
48266 return 0;
48267
48268- return ((struct sockaddr_in6 *) sa)->sin6_scope_id;
48269+ return ((const struct sockaddr_in6 *) sa)->sin6_scope_id;
48270 }
48271
48272 #endif /* __KERNEL__ */
16454cff
MT
48273diff -urNp linux-2.6.38.1/include/linux/suspend.h linux-2.6.38.1/include/linux/suspend.h
48274--- linux-2.6.38.1/include/linux/suspend.h 2011-03-14 21:20:32.000000000 -0400
48275+++ linux-2.6.38.1/include/linux/suspend.h 2011-03-21 18:31:35.000000000 -0400
6892158b 48276@@ -106,15 +106,15 @@ typedef int __bitwise suspend_state_t;
ae4e228f
MT
48277 * which require special recovery actions in that situation.
48278 */
48279 struct platform_suspend_ops {
48280- int (*valid)(suspend_state_t state);
48281- int (*begin)(suspend_state_t state);
48282- int (*prepare)(void);
48283- int (*prepare_late)(void);
48284- int (*enter)(suspend_state_t state);
48285- void (*wake)(void);
48286- void (*finish)(void);
48287- void (*end)(void);
48288- void (*recover)(void);
48289+ int (* const valid)(suspend_state_t state);
48290+ int (* const begin)(suspend_state_t state);
48291+ int (* const prepare)(void);
48292+ int (* const prepare_late)(void);
48293+ int (* const enter)(suspend_state_t state);
48294+ void (* const wake)(void);
48295+ void (* const finish)(void);
48296+ void (* const end)(void);
48297+ void (* const recover)(void);
48298 };
48299
48300 #ifdef CONFIG_SUSPEND
6892158b 48301@@ -217,16 +217,16 @@ extern void mark_free_pages(struct zone
ae4e228f
MT
48302 * platforms which require special recovery actions in that situation.
48303 */
48304 struct platform_hibernation_ops {
48305- int (*begin)(void);
48306- void (*end)(void);
48307- int (*pre_snapshot)(void);
48308- void (*finish)(void);
48309- int (*prepare)(void);
48310- int (*enter)(void);
48311- void (*leave)(void);
48312- int (*pre_restore)(void);
48313- void (*restore_cleanup)(void);
48314- void (*recover)(void);
48315+ int (* const begin)(void);
48316+ void (* const end)(void);
48317+ int (* const pre_snapshot)(void);
48318+ void (* const finish)(void);
48319+ int (* const prepare)(void);
48320+ int (* const enter)(void);
48321+ void (* const leave)(void);
48322+ int (* const pre_restore)(void);
48323+ void (* const restore_cleanup)(void);
48324+ void (* const recover)(void);
48325 };
48326
48327 #ifdef CONFIG_HIBERNATION
16454cff
MT
48328diff -urNp linux-2.6.38.1/include/linux/sysctl.h linux-2.6.38.1/include/linux/sysctl.h
48329--- linux-2.6.38.1/include/linux/sysctl.h 2011-03-14 21:20:32.000000000 -0400
48330+++ linux-2.6.38.1/include/linux/sysctl.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f 48331@@ -155,7 +155,11 @@ enum
58c5fc13
MT
48332 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
48333 };
48334
48335-
48336+#ifdef CONFIG_PAX_SOFTMODE
48337+enum {
48338+ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
48339+};
48340+#endif
48341
48342 /* CTL_VM names: */
48343 enum
16454cff 48344@@ -967,6 +971,8 @@ typedef int proc_handler (struct ctl_tab
bc901d79
MT
48345
48346 extern int proc_dostring(struct ctl_table *, int,
48347 void __user *, size_t *, loff_t *);
48348+extern int proc_dostring_modpriv(struct ctl_table *, int,
48349+ void __user *, size_t *, loff_t *);
48350 extern int proc_dointvec(struct ctl_table *, int,
48351 void __user *, size_t *, loff_t *);
48352 extern int proc_dointvec_minmax(struct ctl_table *, int,
16454cff
MT
48353diff -urNp linux-2.6.38.1/include/linux/sysfs.h linux-2.6.38.1/include/linux/sysfs.h
48354--- linux-2.6.38.1/include/linux/sysfs.h 2011-03-14 21:20:32.000000000 -0400
48355+++ linux-2.6.38.1/include/linux/sysfs.h 2011-03-21 18:31:35.000000000 -0400
6892158b 48356@@ -110,8 +110,8 @@ struct bin_attribute {
df50ba0c 48357 #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr)
ae4e228f
MT
48358
48359 struct sysfs_ops {
48360- ssize_t (*show)(struct kobject *, struct attribute *,char *);
48361- ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
48362+ ssize_t (* const show)(struct kobject *, struct attribute *,char *);
48363+ ssize_t (* const store)(struct kobject *,struct attribute *,const char *, size_t);
48364 };
48365
48366 struct sysfs_dirent;
16454cff
MT
48367diff -urNp linux-2.6.38.1/include/linux/tty.h linux-2.6.38.1/include/linux/tty.h
48368--- linux-2.6.38.1/include/linux/tty.h 2011-03-14 21:20:32.000000000 -0400
48369+++ linux-2.6.38.1/include/linux/tty.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 48370@@ -13,6 +13,8 @@
ae4e228f
MT
48371 #include <linux/tty_driver.h>
48372 #include <linux/tty_ldisc.h>
48373 #include <linux/mutex.h>
48374+#include <linux/poll.h>
bc901d79 48375+#include <linux/smp_lock.h>
ae4e228f
MT
48376
48377 #include <asm/system.h>
bc901d79
MT
48378
48379@@ -465,7 +467,6 @@ extern int tty_perform_flush(struct tty_
ae4e228f
MT
48380 extern dev_t tty_devnum(struct tty_struct *tty);
48381 extern void proc_clear_tty(struct task_struct *p);
48382 extern struct tty_struct *get_current_tty(void);
48383-extern void tty_default_fops(struct file_operations *fops);
48384 extern struct tty_struct *alloc_tty_struct(void);
bc901d79 48385 extern int tty_add_file(struct tty_struct *tty, struct file *file);
ae4e228f 48386 extern void free_tty_struct(struct tty_struct *tty);
bc901d79 48387@@ -528,6 +529,18 @@ extern void tty_ldisc_begin(void);
ae4e228f
MT
48388 /* This last one is just for the tty layer internals and shouldn't be used elsewhere */
48389 extern void tty_ldisc_enable(struct tty_struct *tty);
48390
48391+/* tty_io.c */
48392+extern ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
48393+extern ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
48394+extern unsigned int tty_poll(struct file *, poll_table *);
48395+#ifdef CONFIG_COMPAT
48396+extern long tty_compat_ioctl(struct file *file, unsigned int cmd,
48397+ unsigned long arg);
48398+#else
48399+#define tty_compat_ioctl NULL
48400+#endif
48401+extern int tty_release(struct inode *, struct file *);
48402+extern int tty_fasync(int fd, struct file *filp, int on);
48403
48404 /* n_tty.c */
48405 extern struct tty_ldisc_ops tty_ldisc_N_TTY;
16454cff
MT
48406diff -urNp linux-2.6.38.1/include/linux/tty_ldisc.h linux-2.6.38.1/include/linux/tty_ldisc.h
48407--- linux-2.6.38.1/include/linux/tty_ldisc.h 2011-03-14 21:20:32.000000000 -0400
48408+++ linux-2.6.38.1/include/linux/tty_ldisc.h 2011-03-21 18:31:35.000000000 -0400
48409@@ -148,7 +148,7 @@ struct tty_ldisc_ops {
58c5fc13
MT
48410
48411 struct module *owner;
48412
48413- int refcount;
48414+ atomic_t refcount;
48415 };
48416
48417 struct tty_ldisc {
16454cff
MT
48418diff -urNp linux-2.6.38.1/include/linux/types.h linux-2.6.38.1/include/linux/types.h
48419--- linux-2.6.38.1/include/linux/types.h 2011-03-14 21:20:32.000000000 -0400
48420+++ linux-2.6.38.1/include/linux/types.h 2011-03-21 18:31:35.000000000 -0400
6892158b 48421@@ -207,10 +207,26 @@ typedef struct {
57199397 48422 int counter;
58c5fc13
MT
48423 } atomic_t;
48424
48425+#ifdef CONFIG_PAX_REFCOUNT
48426+typedef struct {
57199397 48427+ int counter;
58c5fc13
MT
48428+} atomic_unchecked_t;
48429+#else
48430+typedef atomic_t atomic_unchecked_t;
48431+#endif
48432+
48433 #ifdef CONFIG_64BIT
48434 typedef struct {
57199397 48435 long counter;
58c5fc13
MT
48436 } atomic64_t;
48437+
48438+#ifdef CONFIG_PAX_REFCOUNT
48439+typedef struct {
57199397 48440+ long counter;
58c5fc13
MT
48441+} atomic64_unchecked_t;
48442+#else
48443+typedef atomic64_t atomic64_unchecked_t;
48444+#endif
48445 #endif
48446
6892158b 48447 struct list_head {
16454cff
MT
48448diff -urNp linux-2.6.38.1/include/linux/uaccess.h linux-2.6.38.1/include/linux/uaccess.h
48449--- linux-2.6.38.1/include/linux/uaccess.h 2011-03-14 21:20:32.000000000 -0400
48450+++ linux-2.6.38.1/include/linux/uaccess.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
48451@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
48452 long ret; \
48453 mm_segment_t old_fs = get_fs(); \
48454 \
48455- set_fs(KERNEL_DS); \
48456 pagefault_disable(); \
48457+ set_fs(KERNEL_DS); \
48458 ret = __copy_from_user_inatomic(&(retval), (__force typeof(retval) __user *)(addr), sizeof(retval)); \
48459- pagefault_enable(); \
48460 set_fs(old_fs); \
48461+ pagefault_enable(); \
48462 ret; \
48463 })
48464
ae4e228f
MT
48465@@ -93,8 +93,8 @@ static inline unsigned long __copy_from_
48466 * Safely read from address @src to the buffer at @dst. If a kernel fault
48467 * happens, handle that and return -EFAULT.
48468 */
48469-extern long probe_kernel_read(void *dst, void *src, size_t size);
48470-extern long __probe_kernel_read(void *dst, void *src, size_t size);
48471+extern long probe_kernel_read(void *dst, const void *src, size_t size);
48472+extern long __probe_kernel_read(void *dst, const void *src, size_t size);
48473
48474 /*
48475 * probe_kernel_write(): safely attempt to write to a location
48476@@ -105,7 +105,7 @@ extern long __probe_kernel_read(void *ds
48477 * Safely write to address @dst from the buffer at @src. If a kernel fault
48478 * happens, handle that and return -EFAULT.
48479 */
48480-extern long notrace probe_kernel_write(void *dst, void *src, size_t size);
48481-extern long notrace __probe_kernel_write(void *dst, void *src, size_t size);
48482+extern long notrace probe_kernel_write(void *dst, const void *src, size_t size);
48483+extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size);
48484
48485 #endif /* __LINUX_UACCESS_H__ */
16454cff
MT
48486diff -urNp linux-2.6.38.1/include/linux/unaligned/access_ok.h linux-2.6.38.1/include/linux/unaligned/access_ok.h
48487--- linux-2.6.38.1/include/linux/unaligned/access_ok.h 2011-03-14 21:20:32.000000000 -0400
48488+++ linux-2.6.38.1/include/linux/unaligned/access_ok.h 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
48489@@ -6,32 +6,32 @@
48490
48491 static inline u16 get_unaligned_le16(const void *p)
48492 {
48493- return le16_to_cpup((__le16 *)p);
48494+ return le16_to_cpup((const __le16 *)p);
48495 }
48496
48497 static inline u32 get_unaligned_le32(const void *p)
48498 {
48499- return le32_to_cpup((__le32 *)p);
48500+ return le32_to_cpup((const __le32 *)p);
48501 }
48502
48503 static inline u64 get_unaligned_le64(const void *p)
48504 {
48505- return le64_to_cpup((__le64 *)p);
48506+ return le64_to_cpup((const __le64 *)p);
48507 }
48508
48509 static inline u16 get_unaligned_be16(const void *p)
48510 {
48511- return be16_to_cpup((__be16 *)p);
48512+ return be16_to_cpup((const __be16 *)p);
48513 }
48514
48515 static inline u32 get_unaligned_be32(const void *p)
48516 {
48517- return be32_to_cpup((__be32 *)p);
48518+ return be32_to_cpup((const __be32 *)p);
48519 }
48520
48521 static inline u64 get_unaligned_be64(const void *p)
48522 {
48523- return be64_to_cpup((__be64 *)p);
48524+ return be64_to_cpup((const __be64 *)p);
48525 }
48526
48527 static inline void put_unaligned_le16(u16 val, void *p)
16454cff
MT
48528diff -urNp linux-2.6.38.1/include/linux/usb/hcd.h linux-2.6.38.1/include/linux/usb/hcd.h
48529--- linux-2.6.38.1/include/linux/usb/hcd.h 2011-03-23 17:20:08.000000000 -0400
48530+++ linux-2.6.38.1/include/linux/usb/hcd.h 2011-03-23 17:21:51.000000000 -0400
48531@@ -589,7 +589,7 @@ struct usb_mon_operations {
57199397
MT
48532 /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
48533 };
48534
48535-extern struct usb_mon_operations *mon_ops;
48536+extern const struct usb_mon_operations *mon_ops;
48537
48538 static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb)
48539 {
16454cff 48540@@ -611,7 +611,7 @@ static inline void usbmon_urb_complete(s
57199397
MT
48541 (*mon_ops->urb_complete)(bus, urb, status);
48542 }
48543
48544-int usb_mon_register(struct usb_mon_operations *ops);
48545+int usb_mon_register(const struct usb_mon_operations *ops);
48546 void usb_mon_deregister(void);
48547
48548 #else
16454cff
MT
48549diff -urNp linux-2.6.38.1/include/linux/vmalloc.h linux-2.6.38.1/include/linux/vmalloc.h
48550--- linux-2.6.38.1/include/linux/vmalloc.h 2011-03-14 21:20:32.000000000 -0400
48551+++ linux-2.6.38.1/include/linux/vmalloc.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 48552@@ -13,6 +13,11 @@ struct vm_area_struct; /* vma defining
58c5fc13
MT
48553 #define VM_MAP 0x00000004 /* vmap()ed pages */
48554 #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
48555 #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
48556+
df50ba0c 48557+#if defined(CONFIG_MODULES) && defined(CONFIG_X86) && defined(CONFIG_PAX_KERNEXEC)
58c5fc13
MT
48558+#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
48559+#endif
48560+
48561 /* bits [20..32] reserved for arch specific ioremap internals */
48562
48563 /*
16454cff 48564@@ -123,4 +128,103 @@ struct vm_struct **pcpu_get_vm_areas(con
ae4e228f 48565 void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms);
bc901d79 48566 #endif
58c5fc13
MT
48567
48568+#define vmalloc(x) \
48569+({ \
48570+ void *___retval; \
48571+ intoverflow_t ___x = (intoverflow_t)x; \
48572+ if (WARN(___x > ULONG_MAX, "vmalloc size overflow\n")) \
48573+ ___retval = NULL; \
48574+ else \
48575+ ___retval = vmalloc((unsigned long)___x); \
48576+ ___retval; \
48577+})
48578+
bc901d79
MT
48579+#define vzalloc(x) \
48580+({ \
48581+ void *___retval; \
48582+ intoverflow_t ___x = (intoverflow_t)x; \
48583+ if (WARN(___x > ULONG_MAX, "vzalloc size overflow\n")) \
48584+ ___retval = NULL; \
48585+ else \
48586+ ___retval = vzalloc((unsigned long)___x); \
48587+ ___retval; \
48588+})
48589+
58c5fc13
MT
48590+#define __vmalloc(x, y, z) \
48591+({ \
48592+ void *___retval; \
48593+ intoverflow_t ___x = (intoverflow_t)x; \
48594+ if (WARN(___x > ULONG_MAX, "__vmalloc size overflow\n"))\
48595+ ___retval = NULL; \
48596+ else \
48597+ ___retval = __vmalloc((unsigned long)___x, (y), (z));\
48598+ ___retval; \
48599+})
48600+
48601+#define vmalloc_user(x) \
48602+({ \
48603+ void *___retval; \
48604+ intoverflow_t ___x = (intoverflow_t)x; \
48605+ if (WARN(___x > ULONG_MAX, "vmalloc_user size overflow\n"))\
48606+ ___retval = NULL; \
48607+ else \
48608+ ___retval = vmalloc_user((unsigned long)___x); \
48609+ ___retval; \
48610+})
48611+
48612+#define vmalloc_exec(x) \
48613+({ \
48614+ void *___retval; \
48615+ intoverflow_t ___x = (intoverflow_t)x; \
48616+ if (WARN(___x > ULONG_MAX, "vmalloc_exec size overflow\n"))\
48617+ ___retval = NULL; \
48618+ else \
48619+ ___retval = vmalloc_exec((unsigned long)___x); \
48620+ ___retval; \
48621+})
48622+
48623+#define vmalloc_node(x, y) \
48624+({ \
48625+ void *___retval; \
48626+ intoverflow_t ___x = (intoverflow_t)x; \
48627+ if (WARN(___x > ULONG_MAX, "vmalloc_node size overflow\n"))\
48628+ ___retval = NULL; \
48629+ else \
48630+ ___retval = vmalloc_node((unsigned long)___x, (y));\
48631+ ___retval; \
48632+})
48633+
bc901d79
MT
48634+#define vzalloc_node(x, y) \
48635+({ \
48636+ void *___retval; \
48637+ intoverflow_t ___x = (intoverflow_t)x; \
48638+ if (WARN(___x > ULONG_MAX, "vzalloc_node size overflow\n"))\
48639+ ___retval = NULL; \
48640+ else \
48641+ ___retval = vzalloc_node((unsigned long)___x, (y));\
48642+ ___retval; \
48643+})
48644+
58c5fc13
MT
48645+#define vmalloc_32(x) \
48646+({ \
48647+ void *___retval; \
48648+ intoverflow_t ___x = (intoverflow_t)x; \
48649+ if (WARN(___x > ULONG_MAX, "vmalloc_32 size overflow\n"))\
48650+ ___retval = NULL; \
48651+ else \
48652+ ___retval = vmalloc_32((unsigned long)___x); \
48653+ ___retval; \
48654+})
48655+
48656+#define vmalloc_32_user(x) \
48657+({ \
bc901d79 48658+void *___retval; \
58c5fc13
MT
48659+ intoverflow_t ___x = (intoverflow_t)x; \
48660+ if (WARN(___x > ULONG_MAX, "vmalloc_32_user size overflow\n"))\
48661+ ___retval = NULL; \
48662+ else \
48663+ ___retval = vmalloc_32_user((unsigned long)___x);\
48664+ ___retval; \
48665+})
48666+
48667 #endif /* _LINUX_VMALLOC_H */
16454cff
MT
48668diff -urNp linux-2.6.38.1/include/linux/vmstat.h linux-2.6.38.1/include/linux/vmstat.h
48669--- linux-2.6.38.1/include/linux/vmstat.h 2011-03-14 21:20:32.000000000 -0400
48670+++ linux-2.6.38.1/include/linux/vmstat.h 2011-03-21 18:31:35.000000000 -0400
57199397
MT
48671@@ -140,18 +140,18 @@ static inline void vm_events_fold_cpu(in
48672 /*
48673 * Zone based page accounting with per cpu differentials.
48674 */
48675-extern atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
48676+extern atomic_long_unchecked_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
48677
48678 static inline void zone_page_state_add(long x, struct zone *zone,
48679 enum zone_stat_item item)
48680 {
48681- atomic_long_add(x, &zone->vm_stat[item]);
48682- atomic_long_add(x, &vm_stat[item]);
48683+ atomic_long_add_unchecked(x, &zone->vm_stat[item]);
48684+ atomic_long_add_unchecked(x, &vm_stat[item]);
48685 }
48686
48687 static inline unsigned long global_page_state(enum zone_stat_item item)
48688 {
48689- long x = atomic_long_read(&vm_stat[item]);
48690+ long x = atomic_long_read_unchecked(&vm_stat[item]);
48691 #ifdef CONFIG_SMP
48692 if (x < 0)
48693 x = 0;
48694@@ -162,7 +162,7 @@ static inline unsigned long global_page_
48695 static inline unsigned long zone_page_state(struct zone *zone,
48696 enum zone_stat_item item)
48697 {
48698- long x = atomic_long_read(&zone->vm_stat[item]);
48699+ long x = atomic_long_read_unchecked(&zone->vm_stat[item]);
48700 #ifdef CONFIG_SMP
48701 if (x < 0)
48702 x = 0;
6892158b
MT
48703@@ -179,7 +179,7 @@ static inline unsigned long zone_page_st
48704 static inline unsigned long zone_page_state_snapshot(struct zone *zone,
48705 enum zone_stat_item item)
48706 {
48707- long x = atomic_long_read(&zone->vm_stat[item]);
48708+ long x = atomic_long_read_unchecked(&zone->vm_stat[item]);
48709
48710 #ifdef CONFIG_SMP
48711 int cpu;
16454cff 48712@@ -273,8 +273,8 @@ static inline void __mod_zone_page_state
57199397
MT
48713
48714 static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
48715 {
48716- atomic_long_inc(&zone->vm_stat[item]);
48717- atomic_long_inc(&vm_stat[item]);
48718+ atomic_long_inc_unchecked(&zone->vm_stat[item]);
48719+ atomic_long_inc_unchecked(&vm_stat[item]);
48720 }
48721
48722 static inline void __inc_zone_page_state(struct page *page,
16454cff 48723@@ -285,8 +285,8 @@ static inline void __inc_zone_page_state
57199397
MT
48724
48725 static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
48726 {
48727- atomic_long_dec(&zone->vm_stat[item]);
48728- atomic_long_dec(&vm_stat[item]);
48729+ atomic_long_dec_unchecked(&zone->vm_stat[item]);
48730+ atomic_long_dec_unchecked(&vm_stat[item]);
48731 }
48732
48733 static inline void __dec_zone_page_state(struct page *page,
16454cff
MT
48734diff -urNp linux-2.6.38.1/include/net/inetpeer.h linux-2.6.38.1/include/net/inetpeer.h
48735--- linux-2.6.38.1/include/net/inetpeer.h 2011-03-14 21:20:32.000000000 -0400
48736+++ linux-2.6.38.1/include/net/inetpeer.h 2011-03-21 18:31:35.000000000 -0400
48737@@ -38,8 +38,8 @@ struct inet_peer {
6892158b
MT
48738 */
48739 union {
48740 struct {
48741- atomic_t rid; /* Frag reception counter */
48742- atomic_t ip_id_count; /* IP ID for the next packet */
48743+ atomic_unchecked_t rid; /* Frag reception counter */
48744+ atomic_unchecked_t ip_id_count; /* IP ID for the next packet */
48745 __u32 tcp_ts;
48746 __u32 tcp_ts_stamp;
48747 };
16454cff 48748@@ -88,7 +88,7 @@ static inline __u16 inet_getid(struct in
6892158b
MT
48749 {
48750 more++;
48751 inet_peer_refcheck(p);
48752- return atomic_add_return(more, &p->ip_id_count) - more;
48753+ return atomic_add_return_unchecked(more, &p->ip_id_count) - more;
48754 }
48755
48756 #endif /* _NET_INETPEER_H */
16454cff
MT
48757diff -urNp linux-2.6.38.1/include/net/irda/ircomm_tty.h linux-2.6.38.1/include/net/irda/ircomm_tty.h
48758--- linux-2.6.38.1/include/net/irda/ircomm_tty.h 2011-03-14 21:20:32.000000000 -0400
48759+++ linux-2.6.38.1/include/net/irda/ircomm_tty.h 2011-03-21 18:31:35.000000000 -0400
c52201e0
MT
48760@@ -35,6 +35,7 @@
48761 #include <linux/termios.h>
48762 #include <linux/timer.h>
48763 #include <linux/tty.h> /* struct tty_struct */
48764+#include <asm/local.h>
48765
48766 #include <net/irda/irias_object.h>
48767 #include <net/irda/ircomm_core.h>
48768@@ -105,8 +106,8 @@ struct ircomm_tty_cb {
58c5fc13
MT
48769 unsigned short close_delay;
48770 unsigned short closing_wait; /* time to wait before closing */
48771
48772- int open_count;
48773- int blocked_open; /* # of blocked opens */
c52201e0
MT
48774+ local_t open_count;
48775+ local_t blocked_open; /* # of blocked opens */
58c5fc13
MT
48776
48777 /* Protect concurent access to :
48778 * o self->open_count
16454cff
MT
48779diff -urNp linux-2.6.38.1/include/net/neighbour.h linux-2.6.38.1/include/net/neighbour.h
48780--- linux-2.6.38.1/include/net/neighbour.h 2011-03-14 21:20:32.000000000 -0400
48781+++ linux-2.6.38.1/include/net/neighbour.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 48782@@ -118,12 +118,12 @@ struct neighbour {
ae4e228f
MT
48783
48784 struct neigh_ops {
48785 int family;
48786- void (*solicit)(struct neighbour *, struct sk_buff*);
48787- void (*error_report)(struct neighbour *, struct sk_buff*);
48788- int (*output)(struct sk_buff*);
48789- int (*connected_output)(struct sk_buff*);
48790- int (*hh_output)(struct sk_buff*);
48791- int (*queue_xmit)(struct sk_buff*);
48792+ void (* const solicit)(struct neighbour *, struct sk_buff*);
48793+ void (* const error_report)(struct neighbour *, struct sk_buff*);
48794+ int (* const output)(struct sk_buff*);
48795+ int (* const connected_output)(struct sk_buff*);
48796+ int (* const hh_output)(struct sk_buff*);
48797+ int (* const queue_xmit)(struct sk_buff*);
48798 };
48799
48800 struct pneigh_entry {
16454cff
MT
48801diff -urNp linux-2.6.38.1/include/net/netlink.h linux-2.6.38.1/include/net/netlink.h
48802--- linux-2.6.38.1/include/net/netlink.h 2011-03-14 21:20:32.000000000 -0400
48803+++ linux-2.6.38.1/include/net/netlink.h 2011-03-21 18:31:35.000000000 -0400
48804@@ -562,7 +562,7 @@ static inline void *nlmsg_get_pos(struct
bc901d79
MT
48805 static inline void nlmsg_trim(struct sk_buff *skb, const void *mark)
48806 {
48807 if (mark)
48808- skb_trim(skb, (unsigned char *) mark - skb->data);
48809+ skb_trim(skb, (const unsigned char *) mark - skb->data);
48810 }
48811
48812 /**
16454cff
MT
48813diff -urNp linux-2.6.38.1/include/net/sctp/sctp.h linux-2.6.38.1/include/net/sctp/sctp.h
48814--- linux-2.6.38.1/include/net/sctp/sctp.h 2011-03-14 21:20:32.000000000 -0400
48815+++ linux-2.6.38.1/include/net/sctp/sctp.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 48816@@ -316,9 +316,9 @@ do { \
58c5fc13
MT
48817
48818 #else /* SCTP_DEBUG */
48819
48820-#define SCTP_DEBUG_PRINTK(whatever...)
bc901d79 48821-#define SCTP_DEBUG_PRINTK_CONT(fmt, args...)
58c5fc13
MT
48822-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
48823+#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
bc901d79 48824+#define SCTP_DEBUG_PRINTK_CONT(fmt, args...) do {} while (0)
58c5fc13
MT
48825+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
48826 #define SCTP_ENABLE_DEBUG
48827 #define SCTP_DISABLE_DEBUG
48828 #define SCTP_ASSERT(expr, str, func)
16454cff
MT
48829diff -urNp linux-2.6.38.1/include/net/tcp.h linux-2.6.38.1/include/net/tcp.h
48830--- linux-2.6.38.1/include/net/tcp.h 2011-03-14 21:20:32.000000000 -0400
48831+++ linux-2.6.38.1/include/net/tcp.h 2011-03-21 18:31:35.000000000 -0400
48832@@ -1382,7 +1382,7 @@ enum tcp_seq_states {
ae4e228f
MT
48833 struct tcp_seq_afinfo {
48834 char *name;
48835 sa_family_t family;
16454cff
MT
48836- struct file_operations seq_fops;
48837+ struct file_operations seq_fops; /* cannot be const */
ae4e228f
MT
48838 struct seq_operations seq_ops;
48839 };
16454cff
MT
48840
48841diff -urNp linux-2.6.38.1/include/net/udp.h linux-2.6.38.1/include/net/udp.h
48842--- linux-2.6.38.1/include/net/udp.h 2011-03-14 21:20:32.000000000 -0400
48843+++ linux-2.6.38.1/include/net/udp.h 2011-03-21 18:31:35.000000000 -0400
48844@@ -223,7 +223,7 @@ struct udp_seq_afinfo {
ae4e228f
MT
48845 char *name;
48846 sa_family_t family;
48847 struct udp_table *udp_table;
16454cff
MT
48848- struct file_operations seq_fops;
48849+ struct file_operations seq_fops; /* cannot be const */
ae4e228f
MT
48850 struct seq_operations seq_ops;
48851 };
16454cff
MT
48852
48853diff -urNp linux-2.6.38.1/include/sound/ac97_codec.h linux-2.6.38.1/include/sound/ac97_codec.h
48854--- linux-2.6.38.1/include/sound/ac97_codec.h 2011-03-14 21:20:32.000000000 -0400
48855+++ linux-2.6.38.1/include/sound/ac97_codec.h 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
48856@@ -419,15 +419,15 @@
48857 struct snd_ac97;
48858
48859 struct snd_ac97_build_ops {
48860- int (*build_3d) (struct snd_ac97 *ac97);
48861- int (*build_specific) (struct snd_ac97 *ac97);
48862- int (*build_spdif) (struct snd_ac97 *ac97);
48863- int (*build_post_spdif) (struct snd_ac97 *ac97);
48864+ int (* const build_3d) (struct snd_ac97 *ac97);
48865+ int (* const build_specific) (struct snd_ac97 *ac97);
48866+ int (* const build_spdif) (struct snd_ac97 *ac97);
48867+ int (* const build_post_spdif) (struct snd_ac97 *ac97);
48868 #ifdef CONFIG_PM
48869- void (*suspend) (struct snd_ac97 *ac97);
48870- void (*resume) (struct snd_ac97 *ac97);
48871+ void (* const suspend) (struct snd_ac97 *ac97);
48872+ void (* const resume) (struct snd_ac97 *ac97);
58c5fc13 48873 #endif
ae4e228f
MT
48874- void (*update_jacks) (struct snd_ac97 *ac97); /* for jack-sharing */
48875+ void (* const update_jacks) (struct snd_ac97 *ac97); /* for jack-sharing */
48876 };
48877
48878 struct snd_ac97_bus_ops {
16454cff
MT
48879diff -urNp linux-2.6.38.1/include/trace/events/irq.h linux-2.6.38.1/include/trace/events/irq.h
48880--- linux-2.6.38.1/include/trace/events/irq.h 2011-03-14 21:20:32.000000000 -0400
48881+++ linux-2.6.38.1/include/trace/events/irq.h 2011-03-21 18:31:35.000000000 -0400
bc901d79 48882@@ -36,7 +36,7 @@ struct softirq_action;
ae4e228f
MT
48883 */
48884 TRACE_EVENT(irq_handler_entry,
48885
48886- TP_PROTO(int irq, struct irqaction *action),
48887+ TP_PROTO(int irq, const struct irqaction *action),
48888
48889 TP_ARGS(irq, action),
48890
bc901d79 48891@@ -66,7 +66,7 @@ TRACE_EVENT(irq_handler_entry,
ae4e228f
MT
48892 */
48893 TRACE_EVENT(irq_handler_exit,
48894
48895- TP_PROTO(int irq, struct irqaction *action, int ret),
48896+ TP_PROTO(int irq, const struct irqaction *action, int ret),
48897
48898 TP_ARGS(irq, action, ret),
48899
16454cff
MT
48900diff -urNp linux-2.6.38.1/include/video/uvesafb.h linux-2.6.38.1/include/video/uvesafb.h
48901--- linux-2.6.38.1/include/video/uvesafb.h 2011-03-14 21:20:32.000000000 -0400
48902+++ linux-2.6.38.1/include/video/uvesafb.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
48903@@ -177,6 +177,7 @@ struct uvesafb_par {
48904 u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
48905 u8 pmi_setpal; /* PMI for palette changes */
48906 u16 *pmi_base; /* protected mode interface location */
48907+ u8 *pmi_code; /* protected mode code location */
48908 void *pmi_start;
48909 void *pmi_pal;
48910 u8 *vbe_state_orig; /*
16454cff
MT
48911diff -urNp linux-2.6.38.1/init/do_mounts.c linux-2.6.38.1/init/do_mounts.c
48912--- linux-2.6.38.1/init/do_mounts.c 2011-03-14 21:20:32.000000000 -0400
48913+++ linux-2.6.38.1/init/do_mounts.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 48914@@ -287,7 +287,7 @@ static void __init get_fs_names(char *pa
58c5fc13
MT
48915
48916 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
48917 {
48918- int err = sys_mount(name, "/root", fs, flags, data);
ae4e228f 48919+ int err = sys_mount((__force char __user *)name, (__force char __user *)"/root", (__force char __user *)fs, flags, (__force void __user *)data);
58c5fc13
MT
48920 if (err)
48921 return err;
48922
bc901d79 48923@@ -382,18 +382,18 @@ void __init change_floppy(char *fmt, ...
58c5fc13
MT
48924 va_start(args, fmt);
48925 vsprintf(buf, fmt, args);
48926 va_end(args);
48927- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
48928+ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
48929 if (fd >= 0) {
48930 sys_ioctl(fd, FDEJECT, 0);
48931 sys_close(fd);
48932 }
48933 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
48934- fd = sys_open("/dev/console", O_RDWR, 0);
df50ba0c 48935+ fd = sys_open((__force const char __user *)"/dev/console", O_RDWR, 0);
58c5fc13
MT
48936 if (fd >= 0) {
48937 sys_ioctl(fd, TCGETS, (long)&termios);
48938 termios.c_lflag &= ~ICANON;
48939 sys_ioctl(fd, TCSETSF, (long)&termios);
48940- sys_read(fd, &c, 1);
48941+ sys_read(fd, (char __user *)&c, 1);
48942 termios.c_lflag |= ICANON;
48943 sys_ioctl(fd, TCSETSF, (long)&termios);
48944 sys_close(fd);
bc901d79 48945@@ -487,6 +487,6 @@ void __init prepare_namespace(void)
58c5fc13
MT
48946 mount_root();
48947 out:
ae4e228f 48948 devtmpfs_mount("dev");
58c5fc13 48949- sys_mount(".", "/", NULL, MS_MOVE, NULL);
ae4e228f 48950+ sys_mount((__force char __user *)".", (__force char __user *)"/", NULL, MS_MOVE, NULL);
bc901d79 48951 sys_chroot((const char __user __force *)".");
58c5fc13 48952 }
16454cff
MT
48953diff -urNp linux-2.6.38.1/init/do_mounts.h linux-2.6.38.1/init/do_mounts.h
48954--- linux-2.6.38.1/init/do_mounts.h 2011-03-14 21:20:32.000000000 -0400
48955+++ linux-2.6.38.1/init/do_mounts.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
48956@@ -15,15 +15,15 @@ extern int root_mountflags;
48957
48958 static inline int create_dev(char *name, dev_t dev)
48959 {
48960- sys_unlink(name);
48961- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
ae4e228f
MT
48962+ sys_unlink((__force char __user *)name);
48963+ return sys_mknod((__force char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
58c5fc13
MT
48964 }
48965
48966 #if BITS_PER_LONG == 32
48967 static inline u32 bstat(char *name)
48968 {
48969 struct stat64 stat;
48970- if (sys_stat64(name, &stat) != 0)
ae4e228f 48971+ if (sys_stat64((__force char __user *)name, (__force struct stat64 __user *)&stat) != 0)
58c5fc13
MT
48972 return 0;
48973 if (!S_ISBLK(stat.st_mode))
48974 return 0;
16454cff
MT
48975diff -urNp linux-2.6.38.1/init/do_mounts_initrd.c linux-2.6.38.1/init/do_mounts_initrd.c
48976--- linux-2.6.38.1/init/do_mounts_initrd.c 2011-03-14 21:20:32.000000000 -0400
48977+++ linux-2.6.38.1/init/do_mounts_initrd.c 2011-03-21 18:31:35.000000000 -0400
6892158b 48978@@ -44,13 +44,13 @@ static void __init handle_initrd(void)
58c5fc13
MT
48979 create_dev("/dev/root.old", Root_RAM0);
48980 /* mount initrd on rootfs' /root */
48981 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
48982- sys_mkdir("/old", 0700);
48983- root_fd = sys_open("/", 0, 0);
48984- old_fd = sys_open("/old", 0, 0);
ae4e228f
MT
48985+ sys_mkdir((__force const char __user *)"/old", 0700);
48986+ root_fd = sys_open((__force const char __user *)"/", 0, 0);
48987+ old_fd = sys_open((__force const char __user *)"/old", 0, 0);
58c5fc13
MT
48988 /* move initrd over / and chdir/chroot in initrd root */
48989- sys_chdir("/root");
48990- sys_mount(".", "/", NULL, MS_MOVE, NULL);
48991- sys_chroot(".");
ae4e228f
MT
48992+ sys_chdir((__force const char __user *)"/root");
48993+ sys_mount((__force char __user *)".", (__force char __user *)"/", NULL, MS_MOVE, NULL);
48994+ sys_chroot((__force const char __user *)".");
58c5fc13
MT
48995
48996 /*
48997 * In case that a resume from disk is carried out by linuxrc or one of
6892158b 48998@@ -67,15 +67,15 @@ static void __init handle_initrd(void)
58c5fc13
MT
48999
49000 /* move initrd to rootfs' /old */
49001 sys_fchdir(old_fd);
49002- sys_mount("/", ".", NULL, MS_MOVE, NULL);
ae4e228f 49003+ sys_mount((__force char __user *)"/", (__force char __user *)".", NULL, MS_MOVE, NULL);
58c5fc13
MT
49004 /* switch root and cwd back to / of rootfs */
49005 sys_fchdir(root_fd);
49006- sys_chroot(".");
ae4e228f 49007+ sys_chroot((__force const char __user *)".");
58c5fc13
MT
49008 sys_close(old_fd);
49009 sys_close(root_fd);
49010
49011 if (new_decode_dev(real_root_dev) == Root_RAM0) {
49012- sys_chdir("/old");
ae4e228f 49013+ sys_chdir((__force const char __user *)"/old");
58c5fc13
MT
49014 return;
49015 }
49016
6892158b 49017@@ -83,17 +83,17 @@ static void __init handle_initrd(void)
58c5fc13
MT
49018 mount_root();
49019
49020 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
49021- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
ae4e228f 49022+ error = sys_mount((__force char __user *)"/old", (__force char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
58c5fc13
MT
49023 if (!error)
49024 printk("okay\n");
49025 else {
49026- int fd = sys_open("/dev/root.old", O_RDWR, 0);
ae4e228f 49027+ int fd = sys_open((__force const char __user *)"/dev/root.old", O_RDWR, 0);
58c5fc13
MT
49028 if (error == -ENOENT)
49029 printk("/initrd does not exist. Ignored.\n");
49030 else
49031 printk("failed\n");
49032 printk(KERN_NOTICE "Unmounting old root\n");
49033- sys_umount("/old", MNT_DETACH);
ae4e228f 49034+ sys_umount((__force char __user *)"/old", MNT_DETACH);
58c5fc13
MT
49035 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
49036 if (fd < 0) {
49037 error = fd;
6892158b 49038@@ -116,11 +116,11 @@ int __init initrd_load(void)
58c5fc13
MT
49039 * mounted in the normal path.
49040 */
49041 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
49042- sys_unlink("/initrd.image");
ae4e228f 49043+ sys_unlink((__force const char __user *)"/initrd.image");
58c5fc13
MT
49044 handle_initrd();
49045 return 1;
49046 }
49047 }
49048- sys_unlink("/initrd.image");
ae4e228f 49049+ sys_unlink((__force const char __user *)"/initrd.image");
58c5fc13
MT
49050 return 0;
49051 }
16454cff
MT
49052diff -urNp linux-2.6.38.1/init/do_mounts_md.c linux-2.6.38.1/init/do_mounts_md.c
49053--- linux-2.6.38.1/init/do_mounts_md.c 2011-03-14 21:20:32.000000000 -0400
49054+++ linux-2.6.38.1/init/do_mounts_md.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
49055@@ -170,7 +170,7 @@ static void __init md_setup_drive(void)
49056 partitioned ? "_d" : "", minor,
49057 md_setup_args[ent].device_names);
49058
49059- fd = sys_open(name, 0, 0);
ae4e228f 49060+ fd = sys_open((__force char __user *)name, 0, 0);
58c5fc13
MT
49061 if (fd < 0) {
49062 printk(KERN_ERR "md: open failed - cannot start "
49063 "array %s\n", name);
49064@@ -233,7 +233,7 @@ static void __init md_setup_drive(void)
49065 * array without it
49066 */
49067 sys_close(fd);
49068- fd = sys_open(name, 0, 0);
ae4e228f 49069+ fd = sys_open((__force char __user *)name, 0, 0);
58c5fc13
MT
49070 sys_ioctl(fd, BLKRRPART, 0);
49071 }
49072 sys_close(fd);
16454cff
MT
49073diff -urNp linux-2.6.38.1/init/initramfs.c linux-2.6.38.1/init/initramfs.c
49074--- linux-2.6.38.1/init/initramfs.c 2011-03-14 21:20:32.000000000 -0400
49075+++ linux-2.6.38.1/init/initramfs.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
49076@@ -74,7 +74,7 @@ static void __init free_hash(void)
49077 }
49078 }
49079
49080-static long __init do_utime(char __user *filename, time_t mtime)
49081+static long __init do_utime(__force char __user *filename, time_t mtime)
49082 {
49083 struct timespec t[2];
49084
49085@@ -109,7 +109,7 @@ static void __init dir_utime(void)
49086 struct dir_entry *de, *tmp;
49087 list_for_each_entry_safe(de, tmp, &dir_list, list) {
49088 list_del(&de->list);
49089- do_utime(de->name, de->mtime);
49090+ do_utime((__force char __user *)de->name, de->mtime);
49091 kfree(de->name);
49092 kfree(de);
49093 }
58c5fc13
MT
49094@@ -271,7 +271,7 @@ static int __init maybe_link(void)
49095 if (nlink >= 2) {
49096 char *old = find_link(major, minor, ino, mode, collected);
49097 if (old)
49098- return (sys_link(old, collected) < 0) ? -1 : 1;
ae4e228f 49099+ return (sys_link((__force char __user *)old, (__force char __user *)collected) < 0) ? -1 : 1;
58c5fc13
MT
49100 }
49101 return 0;
49102 }
49103@@ -280,11 +280,11 @@ static void __init clean_path(char *path
49104 {
49105 struct stat st;
49106
49107- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
ae4e228f 49108+ if (!sys_newlstat((__force char __user *)path, (__force struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
58c5fc13
MT
49109 if (S_ISDIR(st.st_mode))
49110- sys_rmdir(path);
ae4e228f 49111+ sys_rmdir((__force char __user *)path);
58c5fc13
MT
49112 else
49113- sys_unlink(path);
ae4e228f 49114+ sys_unlink((__force char __user *)path);
58c5fc13
MT
49115 }
49116 }
49117
49118@@ -305,7 +305,7 @@ static int __init do_name(void)
49119 int openflags = O_WRONLY|O_CREAT;
49120 if (ml != 1)
49121 openflags |= O_TRUNC;
49122- wfd = sys_open(collected, openflags, mode);
ae4e228f 49123+ wfd = sys_open((__force char __user *)collected, openflags, mode);
58c5fc13
MT
49124
49125 if (wfd >= 0) {
49126 sys_fchown(wfd, uid, gid);
ae4e228f 49127@@ -317,17 +317,17 @@ static int __init do_name(void)
58c5fc13
MT
49128 }
49129 }
49130 } else if (S_ISDIR(mode)) {
49131- sys_mkdir(collected, mode);
49132- sys_chown(collected, uid, gid);
49133- sys_chmod(collected, mode);
ae4e228f
MT
49134+ sys_mkdir((__force char __user *)collected, mode);
49135+ sys_chown((__force char __user *)collected, uid, gid);
49136+ sys_chmod((__force char __user *)collected, mode);
58c5fc13
MT
49137 dir_add(collected, mtime);
49138 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
49139 S_ISFIFO(mode) || S_ISSOCK(mode)) {
49140 if (maybe_link() == 0) {
49141- sys_mknod(collected, mode, rdev);
49142- sys_chown(collected, uid, gid);
49143- sys_chmod(collected, mode);
ae4e228f
MT
49144- do_utime(collected, mtime);
49145+ sys_mknod((__force char __user *)collected, mode, rdev);
49146+ sys_chown((__force char __user *)collected, uid, gid);
49147+ sys_chmod((__force char __user *)collected, mode);
49148+ do_utime((__force char __user *)collected, mtime);
58c5fc13
MT
49149 }
49150 }
ae4e228f
MT
49151 return 0;
49152@@ -336,15 +336,15 @@ static int __init do_name(void)
58c5fc13
MT
49153 static int __init do_copy(void)
49154 {
49155 if (count >= body_len) {
49156- sys_write(wfd, victim, body_len);
ae4e228f 49157+ sys_write(wfd, (__force char __user *)victim, body_len);
58c5fc13 49158 sys_close(wfd);
ae4e228f
MT
49159- do_utime(vcollected, mtime);
49160+ do_utime((__force char __user *)vcollected, mtime);
58c5fc13 49161 kfree(vcollected);
ae4e228f 49162 eat(body_len);
58c5fc13
MT
49163 state = SkipIt;
49164 return 0;
49165 } else {
49166- sys_write(wfd, victim, count);
ae4e228f 49167+ sys_write(wfd, (__force char __user *)victim, count);
58c5fc13
MT
49168 body_len -= count;
49169 eat(count);
49170 return 1;
ae4e228f 49171@@ -355,9 +355,9 @@ static int __init do_symlink(void)
58c5fc13
MT
49172 {
49173 collected[N_ALIGN(name_len) + body_len] = '\0';
49174 clean_path(collected, 0);
49175- sys_symlink(collected + N_ALIGN(name_len), collected);
49176- sys_lchown(collected, uid, gid);
ae4e228f
MT
49177- do_utime(collected, mtime);
49178+ sys_symlink((__force char __user *)collected + N_ALIGN(name_len), (__force char __user *)collected);
49179+ sys_lchown((__force char __user *)collected, uid, gid);
49180+ do_utime((__force char __user *)collected, mtime);
58c5fc13
MT
49181 state = SkipIt;
49182 next_state = Reset;
ae4e228f 49183 return 0;
16454cff
MT
49184diff -urNp linux-2.6.38.1/init/Kconfig linux-2.6.38.1/init/Kconfig
49185--- linux-2.6.38.1/init/Kconfig 2011-03-14 21:20:32.000000000 -0400
49186+++ linux-2.6.38.1/init/Kconfig 2011-03-21 18:31:35.000000000 -0400
49187@@ -1185,7 +1185,7 @@ config SLUB_DEBUG
57199397
MT
49188
49189 config COMPAT_BRK
49190 bool "Disable heap randomization"
49191- default y
49192+ default n
49193 help
49194 Randomizing heap placement makes heap exploits harder, but it
49195 also breaks ancient binaries (including anything libc5 based).
16454cff
MT
49196diff -urNp linux-2.6.38.1/init/main.c linux-2.6.38.1/init/main.c
49197--- linux-2.6.38.1/init/main.c 2011-03-14 21:20:32.000000000 -0400
49198+++ linux-2.6.38.1/init/main.c 2011-03-21 18:31:35.000000000 -0400
49199@@ -96,6 +96,8 @@ static inline void mark_rodata_ro(void)
58c5fc13
MT
49200 extern void tc_init(void);
49201 #endif
58c5fc13 49202
16454cff
MT
49203+extern void grsecurity_init(void);
49204+
49205 /*
49206 * Debug helper: via this flag we know that we are in 'early bootup code'
49207 * where only the boot processor is running with IRQ disabled. This means
49208@@ -206,6 +208,47 @@ static int __init set_reset_devices(char
58c5fc13
MT
49209
49210 __setup("reset_devices", set_reset_devices);
49211
df50ba0c 49212+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
bc901d79
MT
49213+extern char pax_enter_kernel_user[];
49214+extern char pax_exit_kernel_user[];
df50ba0c
MT
49215+extern pgdval_t clone_pgd_mask;
49216+#endif
49217+
49218+#if defined(CONFIG_X86) && defined(CONFIG_PAX_MEMORY_UDEREF)
58c5fc13
MT
49219+static int __init setup_pax_nouderef(char *str)
49220+{
df50ba0c 49221+#ifdef CONFIG_X86_32
58c5fc13
MT
49222+ unsigned int cpu;
49223+
49224+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
49225+ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].type = 3;
49226+ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].limit = 0xf;
bc901d79
MT
49227+ get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].limit = 0xf;
49228+ get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].limit = 0xf;
58c5fc13 49229+ }
bc901d79 49230+ asm("mov %0, %%ds; mov %0, %%es; mov %0, %%ss" : : "r" (__KERNEL_DS) : "memory");
df50ba0c 49231+#else
6892158b
MT
49232+ memcpy(pax_enter_kernel_user, (unsigned char []){0xc3}, 1);
49233+ memcpy(pax_exit_kernel_user, (unsigned char []){0xc3}, 1);
df50ba0c
MT
49234+ clone_pgd_mask = ~(pgdval_t)0UL;
49235+#endif
58c5fc13
MT
49236+
49237+ return 0;
49238+}
49239+early_param("pax_nouderef", setup_pax_nouderef);
49240+#endif
49241+
49242+#ifdef CONFIG_PAX_SOFTMODE
49243+unsigned int pax_softmode;
49244+
49245+static int __init setup_pax_softmode(char *str)
49246+{
49247+ get_option(&str, &pax_softmode);
49248+ return 1;
49249+}
49250+__setup("pax_softmode=", setup_pax_softmode);
49251+#endif
49252+
6892158b
MT
49253 static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
49254 const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
58c5fc13 49255 static const char *panic_later, *panic_param;
16454cff 49256@@ -751,6 +794,7 @@ int __init_or_module do_one_initcall(ini
58c5fc13
MT
49257 {
49258 int count = preempt_count();
6892158b 49259 int ret;
58c5fc13
MT
49260+ const char *msg1 = "", *msg2 = "";
49261
6892158b
MT
49262 if (initcall_debug)
49263 ret = do_one_initcall_debug(fn);
16454cff 49264@@ -763,15 +807,15 @@ int __init_or_module do_one_initcall(ini
6892158b 49265 sprintf(msgbuf, "error code %d ", ret);
58c5fc13
MT
49266
49267 if (preempt_count() != count) {
49268- strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
49269+ msg1 = " preemption imbalance";
49270 preempt_count() = count;
49271 }
49272 if (irqs_disabled()) {
49273- strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
49274+ msg2 = " disabled interrupts";
49275 local_irq_enable();
49276 }
49277- if (msgbuf[0]) {
49278- printk("initcall %pF returned with %s\n", fn, msgbuf);
49279+ if (msgbuf[0] || *msg1 || *msg2) {
49280+ printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
49281 }
49282
6892158b 49283 return ret;
16454cff 49284@@ -898,7 +942,7 @@ static int __init kernel_init(void * unu
df50ba0c
MT
49285 do_basic_setup();
49286
49287 /* Open the /dev/console on the rootfs, this should never fail */
49288- if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
49289+ if (sys_open((__force const char __user *) "/dev/console", O_RDWR, 0) < 0)
49290 printk(KERN_WARNING "Warning: unable to open an initial console.\n");
49291
49292 (void) sys_dup(0);
16454cff 49293@@ -911,11 +955,13 @@ static int __init kernel_init(void * unu
ae4e228f
MT
49294 if (!ramdisk_execute_command)
49295 ramdisk_execute_command = "/init";
49296
49297- if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
49298+ if (sys_access((__force const char __user *) ramdisk_execute_command, 0) != 0) {
49299 ramdisk_execute_command = NULL;
58c5fc13
MT
49300 prepare_namespace();
49301 }
49302
49303+ grsecurity_init();
49304+
49305 /*
49306 * Ok, we have completed the initial bootup, and
49307 * we're essentially up and running. Get rid of the
16454cff
MT
49308diff -urNp linux-2.6.38.1/ipc/mqueue.c linux-2.6.38.1/ipc/mqueue.c
49309--- linux-2.6.38.1/ipc/mqueue.c 2011-03-14 21:20:32.000000000 -0400
49310+++ linux-2.6.38.1/ipc/mqueue.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 49311@@ -154,6 +154,7 @@ static struct inode *mqueue_get_inode(st
58c5fc13
MT
49312 mq_bytes = (mq_msg_tblsz +
49313 (info->attr.mq_maxmsg * info->attr.mq_msgsize));
49314
49315+ gr_learn_resource(current, RLIMIT_MSGQUEUE, u->mq_bytes + mq_bytes, 1);
49316 spin_lock(&mq_lock);
49317 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
49318 u->mq_bytes + mq_bytes >
16454cff
MT
49319diff -urNp linux-2.6.38.1/ipc/shm.c linux-2.6.38.1/ipc/shm.c
49320--- linux-2.6.38.1/ipc/shm.c 2011-03-14 21:20:32.000000000 -0400
49321+++ linux-2.6.38.1/ipc/shm.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 49322@@ -69,6 +69,14 @@ static void shm_destroy (struct ipc_name
58c5fc13
MT
49323 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
49324 #endif
49325
49326+#ifdef CONFIG_GRKERNSEC
49327+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
49328+ const time_t shm_createtime, const uid_t cuid,
49329+ const int shmid);
49330+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
49331+ const time_t shm_createtime);
49332+#endif
49333+
49334 void shm_init_ns(struct ipc_namespace *ns)
49335 {
49336 ns->shm_ctlmax = SHMMAX;
bc901d79 49337@@ -401,6 +409,14 @@ static int newseg(struct ipc_namespace *
58c5fc13
MT
49338 shp->shm_lprid = 0;
49339 shp->shm_atim = shp->shm_dtim = 0;
49340 shp->shm_ctim = get_seconds();
49341+#ifdef CONFIG_GRKERNSEC
49342+ {
49343+ struct timespec timeval;
49344+ do_posix_clock_monotonic_gettime(&timeval);
49345+
49346+ shp->shm_createtime = timeval.tv_sec;
49347+ }
49348+#endif
49349 shp->shm_segsz = size;
49350 shp->shm_nattch = 0;
49351 shp->shm_file = file;
16454cff
MT
49352@@ -761,8 +777,6 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
49353 case SHM_LOCK:
49354 case SHM_UNLOCK:
49355 {
49356- struct file *uninitialized_var(shm_file);
49357-
49358 lru_add_drain_all(); /* drain pagevecs to lru lists */
49359
49360 shp = shm_lock_check(ns, shmid);
49361@@ -895,9 +909,21 @@ long do_shmat(int shmid, char __user *sh
58c5fc13
MT
49362 if (err)
49363 goto out_unlock;
49364
49365+#ifdef CONFIG_GRKERNSEC
49366+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
49367+ shp->shm_perm.cuid, shmid) ||
49368+ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
49369+ err = -EACCES;
49370+ goto out_unlock;
49371+ }
49372+#endif
49373+
ae4e228f
MT
49374 path = shp->shm_file->f_path;
49375 path_get(&path);
58c5fc13
MT
49376 shp->shm_nattch++;
49377+#ifdef CONFIG_GRKERNSEC
49378+ shp->shm_lapid = current->pid;
49379+#endif
49380 size = i_size_read(path.dentry->d_inode);
49381 shm_unlock(shp);
49382
16454cff
MT
49383diff -urNp linux-2.6.38.1/kernel/acct.c linux-2.6.38.1/kernel/acct.c
49384--- linux-2.6.38.1/kernel/acct.c 2011-03-14 21:20:32.000000000 -0400
49385+++ linux-2.6.38.1/kernel/acct.c 2011-03-21 18:31:35.000000000 -0400
57199397 49386@@ -570,7 +570,7 @@ static void do_acct_process(struct bsd_a
58c5fc13
MT
49387 */
49388 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
49389 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
49390- file->f_op->write(file, (char *)&ac,
ae4e228f 49391+ file->f_op->write(file, (__force char __user *)&ac,
58c5fc13
MT
49392 sizeof(acct_t), &file->f_pos);
49393 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
49394 set_fs(fs);
16454cff
MT
49395diff -urNp linux-2.6.38.1/kernel/capability.c linux-2.6.38.1/kernel/capability.c
49396--- linux-2.6.38.1/kernel/capability.c 2011-03-14 21:20:32.000000000 -0400
49397+++ linux-2.6.38.1/kernel/capability.c 2011-03-21 18:31:35.000000000 -0400
57199397 49398@@ -205,6 +205,9 @@ SYSCALL_DEFINE2(capget, cap_user_header_
ae4e228f
MT
49399 * before modification is attempted and the application
49400 * fails.
49401 */
49402+ if (tocopy > ARRAY_SIZE(kdata))
49403+ return -EFAULT;
49404+
49405 if (copy_to_user(dataptr, kdata, tocopy
49406 * sizeof(struct __user_cap_data_struct))) {
49407 return -EFAULT;
bc901d79 49408@@ -306,10 +309,26 @@ int capable(int cap)
58c5fc13
MT
49409 BUG();
49410 }
49411
317566c1 49412- if (security_capable(current_cred(), cap) == 0) {
c52201e0 49413+ if (security_capable(current_cred(), cap) == 0 && gr_is_capable(cap)) {
ae4e228f
MT
49414 current->flags |= PF_SUPERPRIV;
49415 return 1;
49416 }
49417 return 0;
49418 }
bc901d79
MT
49419+
49420+int capable_nolog(int cap)
49421+{
49422+ if (unlikely(!cap_valid(cap))) {
49423+ printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap);
49424+ BUG();
49425+ }
49426+
c52201e0 49427+ if (security_capable(current_cred(), cap) == 0 && gr_is_capable_nolog(cap)) {
bc901d79
MT
49428+ current->flags |= PF_SUPERPRIV;
49429+ return 1;
49430+ }
49431+ return 0;
49432+}
58c5fc13
MT
49433+
49434 EXPORT_SYMBOL(capable);
49435+EXPORT_SYMBOL(capable_nolog);
16454cff
MT
49436diff -urNp linux-2.6.38.1/kernel/compat.c linux-2.6.38.1/kernel/compat.c
49437--- linux-2.6.38.1/kernel/compat.c 2011-03-14 21:20:32.000000000 -0400
49438+++ linux-2.6.38.1/kernel/compat.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
49439@@ -13,6 +13,7 @@
49440
49441 #include <linux/linkage.h>
49442 #include <linux/compat.h>
49443+#include <linux/module.h>
49444 #include <linux/errno.h>
49445 #include <linux/time.h>
49446 #include <linux/signal.h>
16454cff
MT
49447diff -urNp linux-2.6.38.1/kernel/configs.c linux-2.6.38.1/kernel/configs.c
49448--- linux-2.6.38.1/kernel/configs.c 2011-03-14 21:20:32.000000000 -0400
49449+++ linux-2.6.38.1/kernel/configs.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 49450@@ -74,8 +74,19 @@ static int __init ikconfig_init(void)
58c5fc13
MT
49451 struct proc_dir_entry *entry;
49452
49453 /* create the current config file */
49454+#if defined(CONFIG_GRKERNSEC_PROC_ADD) || defined(CONFIG_GRKERNSEC_HIDESYM)
49455+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_HIDESYM)
49456+ entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
49457+ &ikconfig_file_ops);
49458+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
49459+ entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
49460+ &ikconfig_file_ops);
49461+#endif
49462+#else
49463 entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
49464 &ikconfig_file_ops);
49465+#endif
49466+
49467 if (!entry)
49468 return -ENOMEM;
49469
16454cff
MT
49470diff -urNp linux-2.6.38.1/kernel/cred.c linux-2.6.38.1/kernel/cred.c
49471--- linux-2.6.38.1/kernel/cred.c 2011-03-14 21:20:32.000000000 -0400
49472+++ linux-2.6.38.1/kernel/cred.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 49473@@ -483,6 +483,8 @@ int commit_creds(struct cred *new)
58c5fc13
MT
49474
49475 get_cred(new); /* we will require a ref for the subj creds too */
49476
49477+ gr_set_role_label(task, new->uid, new->gid);
49478+
49479 /* dumpability changes */
49480 if (old->euid != new->euid ||
49481 old->egid != new->egid ||
16454cff
MT
49482diff -urNp linux-2.6.38.1/kernel/debug/debug_core.c linux-2.6.38.1/kernel/debug/debug_core.c
49483--- linux-2.6.38.1/kernel/debug/debug_core.c 2011-03-14 21:20:32.000000000 -0400
49484+++ linux-2.6.38.1/kernel/debug/debug_core.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 49485@@ -72,7 +72,7 @@ int kgdb_io_module_registered;
57199397
MT
49486 /* Guard for recursive entry */
49487 static int exception_level;
49488
49489-struct kgdb_io *dbg_io_ops;
49490+const struct kgdb_io *dbg_io_ops;
49491 static DEFINE_SPINLOCK(kgdb_registration_lock);
49492
49493 /* kgdb console driver is loaded */
bc901d79 49494@@ -864,7 +864,7 @@ static void kgdb_initial_breakpoint(void
57199397
MT
49495 *
49496 * Register it with the KGDB core.
49497 */
49498-int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops)
49499+int kgdb_register_io_module(const struct kgdb_io *new_dbg_io_ops)
49500 {
49501 int err;
49502
bc901d79 49503@@ -909,7 +909,7 @@ EXPORT_SYMBOL_GPL(kgdb_register_io_modul
57199397
MT
49504 *
49505 * Unregister it with the KGDB core.
49506 */
49507-void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops)
49508+void kgdb_unregister_io_module(const struct kgdb_io *old_dbg_io_ops)
49509 {
49510 BUG_ON(kgdb_connected);
49511
16454cff
MT
49512diff -urNp linux-2.6.38.1/kernel/debug/kdb/kdb_main.c linux-2.6.38.1/kernel/debug/kdb/kdb_main.c
49513--- linux-2.6.38.1/kernel/debug/kdb/kdb_main.c 2011-03-14 21:20:32.000000000 -0400
49514+++ linux-2.6.38.1/kernel/debug/kdb/kdb_main.c 2011-03-21 18:31:35.000000000 -0400
6892158b 49515@@ -1980,7 +1980,7 @@ static int kdb_lsmod(int argc, const cha
57199397
MT
49516 list_for_each_entry(mod, kdb_modules, list) {
49517
49518 kdb_printf("%-20s%8u 0x%p ", mod->name,
49519- mod->core_size, (void *)mod);
49520+ mod->core_size_rx + mod->core_size_rw, (void *)mod);
49521 #ifdef CONFIG_MODULE_UNLOAD
49522 kdb_printf("%4d ", module_refcount(mod));
49523 #endif
6892158b 49524@@ -1990,7 +1990,7 @@ static int kdb_lsmod(int argc, const cha
57199397
MT
49525 kdb_printf(" (Loading)");
49526 else
49527 kdb_printf(" (Live)");
49528- kdb_printf(" 0x%p", mod->module_core);
49529+ kdb_printf(" 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
49530
49531 #ifdef CONFIG_MODULE_UNLOAD
49532 {
16454cff
MT
49533diff -urNp linux-2.6.38.1/kernel/exit.c linux-2.6.38.1/kernel/exit.c
49534--- linux-2.6.38.1/kernel/exit.c 2011-03-14 21:20:32.000000000 -0400
49535+++ linux-2.6.38.1/kernel/exit.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 49536@@ -57,6 +57,10 @@
57199397 49537 #include <asm/pgtable.h>
58c5fc13 49538 #include <asm/mmu_context.h>
58c5fc13
MT
49539
49540+#ifdef CONFIG_GRKERNSEC
49541+extern rwlock_t grsec_exec_file_lock;
49542+#endif
49543+
49544 static void exit_mm(struct task_struct * tsk);
49545
57199397 49546 static void __unhash_process(struct task_struct *p, bool group_dead)
bc901d79 49547@@ -169,6 +173,8 @@ void release_task(struct task_struct * p
58c5fc13
MT
49548 struct task_struct *leader;
49549 int zap_leader;
49550 repeat:
49551+ gr_del_task_from_ip_table(p);
49552+
49553 tracehook_prepare_release_task(p);
49554 /* don't need to get the RCU readlock here - the process is dead and
df50ba0c 49555 * can't be modifying its own credentials. But shut RCU-lockdep up */
bc901d79 49556@@ -338,11 +344,22 @@ static void reparent_to_kthreadd(void)
58c5fc13
MT
49557 {
49558 write_lock_irq(&tasklist_lock);
49559
49560+#ifdef CONFIG_GRKERNSEC
49561+ write_lock(&grsec_exec_file_lock);
49562+ if (current->exec_file) {
49563+ fput(current->exec_file);
49564+ current->exec_file = NULL;
49565+ }
49566+ write_unlock(&grsec_exec_file_lock);
49567+#endif
49568+
49569 ptrace_unlink(current);
49570 /* Reparent to init */
49571 current->real_parent = current->parent = kthreadd_task;
49572 list_move_tail(&current->sibling, &current->real_parent->children);
49573
49574+ gr_set_kernel_label(current);
49575+
49576 /* Set the exit signal to SIGCHLD so we signal init on exit */
49577 current->exit_signal = SIGCHLD;
49578
bc901d79 49579@@ -394,7 +411,7 @@ int allow_signal(int sig)
ae4e228f
MT
49580 * know it'll be handled, so that they don't get converted to
49581 * SIGKILL or just silently dropped.
49582 */
49583- current->sighand->action[(sig)-1].sa.sa_handler = (void __user *)2;
49584+ current->sighand->action[(sig)-1].sa.sa_handler = (__force void __user *)2;
49585 recalc_sigpending();
49586 spin_unlock_irq(&current->sighand->siglock);
49587 return 0;
bc901d79 49588@@ -430,6 +447,17 @@ void daemonize(const char *name, ...)
58c5fc13
MT
49589 vsnprintf(current->comm, sizeof(current->comm), name, args);
49590 va_end(args);
49591
49592+#ifdef CONFIG_GRKERNSEC
49593+ write_lock(&grsec_exec_file_lock);
49594+ if (current->exec_file) {
49595+ fput(current->exec_file);
49596+ current->exec_file = NULL;
49597+ }
49598+ write_unlock(&grsec_exec_file_lock);
49599+#endif
49600+
49601+ gr_set_kernel_label(current);
49602+
49603 /*
49604 * If we were started as result of loading a module, close all of the
49605 * user space pages. We don't need them, and if we didn't close them
bc901d79
MT
49606@@ -905,17 +933,17 @@ NORET_TYPE void do_exit(long code)
49607 struct task_struct *tsk = current;
49608 int group_dead;
49609
49610- profile_task_exit(tsk);
49611-
49612- WARN_ON(atomic_read(&tsk->fs_excl));
49613-
49614+ /*
49615+ * Check this first since set_fs() below depends on
49616+ * current_thread_info(), which we better not access when we're in
49617+ * interrupt context. Other than that, we want to do the set_fs()
49618+ * as early as possible.
49619+ */
49620 if (unlikely(in_interrupt()))
49621 panic("Aiee, killing interrupt handler!");
49622- if (unlikely(!tsk->pid))
49623- panic("Attempted to kill the idle task!");
49624
49625 /*
49626- * If do_exit is called because this processes oopsed, it's possible
49627+ * If do_exit is called because this processes Oops'ed, it's possible
49628 * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
49629 * continuing. Amongst other possible reasons, this is to prevent
49630 * mm_release()->clear_child_tid() from writing to a user-controlled
49631@@ -923,6 +951,13 @@ NORET_TYPE void do_exit(long code)
49632 */
49633 set_fs(USER_DS);
49634
49635+ profile_task_exit(tsk);
49636+
49637+ WARN_ON(atomic_read(&tsk->fs_excl));
49638+
49639+ if (unlikely(!tsk->pid))
49640+ panic("Attempted to kill the idle task!");
49641+
49642 tracehook_report_exit(&code);
49643
49644 validate_creds_for_do_exit(tsk);
49645@@ -983,6 +1018,9 @@ NORET_TYPE void do_exit(long code)
58c5fc13
MT
49646 tsk->exit_code = code;
49647 taskstats_exit(tsk, group_dead);
49648
49649+ gr_acl_handle_psacct(tsk, code);
49650+ gr_acl_handle_exit();
49651+
49652 exit_mm(tsk);
49653
49654 if (group_dead)
16454cff
MT
49655diff -urNp linux-2.6.38.1/kernel/fork.c linux-2.6.38.1/kernel/fork.c
49656--- linux-2.6.38.1/kernel/fork.c 2011-03-14 21:20:32.000000000 -0400
49657+++ linux-2.6.38.1/kernel/fork.c 2011-03-21 18:31:35.000000000 -0400
49658@@ -280,7 +280,7 @@ static struct task_struct *dup_task_stru
58c5fc13
MT
49659 *stackend = STACK_END_MAGIC; /* for overflow detection */
49660
49661 #ifdef CONFIG_CC_STACKPROTECTOR
49662- tsk->stack_canary = get_random_int();
49663+ tsk->stack_canary = pax_get_random_long();
49664 #endif
49665
49666 /* One for us, one for whoever does the "release_task()" (usually parent) */
16454cff 49667@@ -302,13 +302,78 @@ out:
57199397
MT
49668 }
49669
49670 #ifdef CONFIG_MMU
49671+static struct vm_area_struct *dup_vma(struct mm_struct *mm, struct vm_area_struct *mpnt)
49672+{
49673+ struct vm_area_struct *tmp;
49674+ unsigned long charge;
49675+ struct mempolicy *pol;
49676+ struct file *file;
49677+
49678+ charge = 0;
49679+ if (mpnt->vm_flags & VM_ACCOUNT) {
49680+ unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
49681+ if (security_vm_enough_memory(len))
49682+ goto fail_nomem;
49683+ charge = len;
49684+ }
49685+ tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
49686+ if (!tmp)
49687+ goto fail_nomem;
49688+ *tmp = *mpnt;
49689+ tmp->vm_mm = mm;
49690+ INIT_LIST_HEAD(&tmp->anon_vma_chain);
49691+ pol = mpol_dup(vma_policy(mpnt));
49692+ if (IS_ERR(pol))
49693+ goto fail_nomem_policy;
49694+ vma_set_policy(tmp, pol);
49695+ if (anon_vma_fork(tmp, mpnt))
49696+ goto fail_nomem_anon_vma_fork;
49697+ tmp->vm_flags &= ~VM_LOCKED;
6892158b 49698+ tmp->vm_next = tmp->vm_prev = NULL;
57199397
MT
49699+ tmp->vm_mirror = NULL;
49700+ file = tmp->vm_file;
49701+ if (file) {
49702+ struct inode *inode = file->f_path.dentry->d_inode;
49703+ struct address_space *mapping = file->f_mapping;
49704+
49705+ get_file(file);
49706+ if (tmp->vm_flags & VM_DENYWRITE)
49707+ atomic_dec(&inode->i_writecount);
49708+ spin_lock(&mapping->i_mmap_lock);
49709+ if (tmp->vm_flags & VM_SHARED)
49710+ mapping->i_mmap_writable++;
49711+ tmp->vm_truncate_count = mpnt->vm_truncate_count;
49712+ flush_dcache_mmap_lock(mapping);
49713+ /* insert tmp into the share list, just after mpnt */
49714+ vma_prio_tree_add(tmp, mpnt);
49715+ flush_dcache_mmap_unlock(mapping);
49716+ spin_unlock(&mapping->i_mmap_lock);
49717+ }
49718+
49719+ /*
49720+ * Clear hugetlb-related page reserves for children. This only
49721+ * affects MAP_PRIVATE mappings. Faults generated by the child
49722+ * are not guaranteed to succeed, even if read-only
49723+ */
49724+ if (is_vm_hugetlb_page(tmp))
49725+ reset_vma_resv_huge_pages(tmp);
49726+
49727+ return tmp;
49728+
49729+fail_nomem_anon_vma_fork:
49730+ mpol_put(pol);
49731+fail_nomem_policy:
49732+ kmem_cache_free(vm_area_cachep, tmp);
49733+fail_nomem:
49734+ vm_unacct_memory(charge);
49735+ return NULL;
49736+}
49737+
49738 static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
49739 {
49740 struct vm_area_struct *mpnt, *tmp, *prev, **pprev;
49741 struct rb_node **rb_link, *rb_parent;
49742 int retval;
49743- unsigned long charge;
49744- struct mempolicy *pol;
49745
49746 down_write(&oldmm->mmap_sem);
49747 flush_cache_dup_mm(oldmm);
16454cff 49748@@ -320,8 +385,8 @@ static int dup_mmap(struct mm_struct *mm
58c5fc13
MT
49749 mm->locked_vm = 0;
49750 mm->mmap = NULL;
49751 mm->mmap_cache = NULL;
49752- mm->free_area_cache = oldmm->mmap_base;
49753- mm->cached_hole_size = ~0UL;
49754+ mm->free_area_cache = oldmm->free_area_cache;
49755+ mm->cached_hole_size = oldmm->cached_hole_size;
49756 mm->map_count = 0;
49757 cpumask_clear(mm_cpumask(mm));
49758 mm->mm_rb = RB_ROOT;
16454cff 49759@@ -337,8 +402,6 @@ static int dup_mmap(struct mm_struct *mm
57199397
MT
49760
49761 prev = NULL;
49762 for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
49763- struct file *file;
49764-
49765 if (mpnt->vm_flags & VM_DONTCOPY) {
49766 long pages = vma_pages(mpnt);
49767 mm->total_vm -= pages;
16454cff 49768@@ -346,56 +409,13 @@ static int dup_mmap(struct mm_struct *mm
57199397
MT
49769 -pages);
49770 continue;
49771 }
49772- charge = 0;
49773- if (mpnt->vm_flags & VM_ACCOUNT) {
49774- unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
49775- if (security_vm_enough_memory(len))
49776- goto fail_nomem;
49777- charge = len;
49778- }
49779- tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
49780- if (!tmp)
49781- goto fail_nomem;
49782- *tmp = *mpnt;
49783- INIT_LIST_HEAD(&tmp->anon_vma_chain);
49784- pol = mpol_dup(vma_policy(mpnt));
49785- retval = PTR_ERR(pol);
49786- if (IS_ERR(pol))
49787- goto fail_nomem_policy;
49788- vma_set_policy(tmp, pol);
6892158b 49789- tmp->vm_mm = mm;
57199397
MT
49790- if (anon_vma_fork(tmp, mpnt))
49791- goto fail_nomem_anon_vma_fork;
49792- tmp->vm_flags &= ~VM_LOCKED;
57199397
MT
49793- tmp->vm_next = tmp->vm_prev = NULL;
49794- file = tmp->vm_file;
49795- if (file) {
49796- struct inode *inode = file->f_path.dentry->d_inode;
49797- struct address_space *mapping = file->f_mapping;
49798-
49799- get_file(file);
49800- if (tmp->vm_flags & VM_DENYWRITE)
49801- atomic_dec(&inode->i_writecount);
49802- spin_lock(&mapping->i_mmap_lock);
49803- if (tmp->vm_flags & VM_SHARED)
49804- mapping->i_mmap_writable++;
49805- tmp->vm_truncate_count = mpnt->vm_truncate_count;
49806- flush_dcache_mmap_lock(mapping);
49807- /* insert tmp into the share list, just after mpnt */
49808- vma_prio_tree_add(tmp, mpnt);
49809- flush_dcache_mmap_unlock(mapping);
49810- spin_unlock(&mapping->i_mmap_lock);
49811+ tmp = dup_vma(mm, mpnt);
49812+ if (!tmp) {
49813+ retval = -ENOMEM;
49814+ goto out;
49815 }
49816
49817 /*
49818- * Clear hugetlb-related page reserves for children. This only
49819- * affects MAP_PRIVATE mappings. Faults generated by the child
49820- * are not guaranteed to succeed, even if read-only
49821- */
49822- if (is_vm_hugetlb_page(tmp))
49823- reset_vma_resv_huge_pages(tmp);
49824-
49825- /*
49826 * Link in the new vma and copy the page table entries.
49827 */
49828 *pprev = tmp;
16454cff 49829@@ -416,6 +436,31 @@ static int dup_mmap(struct mm_struct *mm
58c5fc13
MT
49830 if (retval)
49831 goto out;
49832 }
49833+
49834+#ifdef CONFIG_PAX_SEGMEXEC
49835+ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
49836+ struct vm_area_struct *mpnt_m;
49837+
49838+ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
49839+ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
49840+
49841+ if (!mpnt->vm_mirror)
49842+ continue;
49843+
49844+ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
49845+ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
49846+ mpnt->vm_mirror = mpnt_m;
49847+ } else {
49848+ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
49849+ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
49850+ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
49851+ mpnt->vm_mirror->vm_mirror = mpnt;
49852+ }
49853+ }
49854+ BUG_ON(mpnt_m);
49855+ }
49856+#endif
49857+
49858 /* a new mm has just been created */
49859 arch_dup_mmap(oldmm, mm);
49860 retval = 0;
16454cff 49861@@ -424,14 +469,6 @@ out:
57199397
MT
49862 flush_tlb_mm(oldmm);
49863 up_write(&oldmm->mmap_sem);
49864 return retval;
49865-fail_nomem_anon_vma_fork:
49866- mpol_put(pol);
49867-fail_nomem_policy:
49868- kmem_cache_free(vm_area_cachep, tmp);
49869-fail_nomem:
49870- retval = -ENOMEM;
49871- vm_unacct_memory(charge);
49872- goto out;
49873 }
49874
49875 static inline int mm_alloc_pgd(struct mm_struct * mm)
16454cff 49876@@ -778,13 +815,14 @@ static int copy_fs(unsigned long clone_f
6892158b 49877 spin_unlock(&fs->lock);
58c5fc13
MT
49878 return -EAGAIN;
49879 }
49880- fs->users++;
49881+ atomic_inc(&fs->users);
6892158b 49882 spin_unlock(&fs->lock);
58c5fc13
MT
49883 return 0;
49884 }
df50ba0c
MT
49885 tsk->fs = copy_fs_struct(fs);
49886 if (!tsk->fs)
49887 return -ENOMEM;
49888+ gr_set_chroot_entries(tsk, &tsk->fs->root);
49889 return 0;
49890 }
49891
16454cff 49892@@ -1042,10 +1080,13 @@ static struct task_struct *copy_process(
58c5fc13
MT
49893 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
49894 #endif
49895 retval = -EAGAIN;
49896+
49897+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->real_cred->user->processes), 0);
49898+
49899 if (atomic_read(&p->real_cred->user->processes) >=
df50ba0c 49900 task_rlimit(p, RLIMIT_NPROC)) {
ae4e228f
MT
49901- if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
49902- p->real_cred->user != INIT_USER)
49903+ if (p->real_cred->user != INIT_USER &&
df50ba0c 49904+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
ae4e228f
MT
49905 goto bad_fork_free;
49906 }
49907
16454cff 49908@@ -1199,6 +1240,8 @@ static struct task_struct *copy_process(
58c5fc13
MT
49909 goto bad_fork_free_pid;
49910 }
49911
49912+ gr_copy_label(p);
49913+
49914 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
49915 /*
49916 * Clear TID on mm_release()?
16454cff 49917@@ -1356,6 +1399,8 @@ bad_fork_cleanup_count:
58c5fc13
MT
49918 bad_fork_free:
49919 free_task(p);
49920 fork_out:
49921+ gr_log_forkfail(retval);
49922+
49923 return ERR_PTR(retval);
49924 }
49925
16454cff 49926@@ -1444,6 +1489,8 @@ long do_fork(unsigned long clone_flags,
58c5fc13
MT
49927 if (clone_flags & CLONE_PARENT_SETTID)
49928 put_user(nr, parent_tidptr);
49929
49930+ gr_handle_brute_check();
49931+
49932 if (clone_flags & CLONE_VFORK) {
49933 p->vfork_done = &vfork;
49934 init_completion(&vfork);
16454cff 49935@@ -1559,7 +1606,7 @@ static int unshare_fs(unsigned long unsh
58c5fc13
MT
49936 return 0;
49937
49938 /* don't need lock here; in the worst case we'll do useless copy */
49939- if (fs->users == 1)
49940+ if (atomic_read(&fs->users) == 1)
49941 return 0;
49942
49943 *new_fsp = copy_fs_struct(fs);
16454cff 49944@@ -1682,7 +1729,8 @@ SYSCALL_DEFINE1(unshare, unsigned long,
58c5fc13 49945 fs = current->fs;
6892158b 49946 spin_lock(&fs->lock);
58c5fc13
MT
49947 current->fs = new_fs;
49948- if (--fs->users)
df50ba0c 49949+ gr_set_chroot_entries(current, &current->fs->root);
58c5fc13
MT
49950+ if (atomic_dec_return(&fs->users))
49951 new_fs = NULL;
49952 else
49953 new_fs = fs;
16454cff
MT
49954diff -urNp linux-2.6.38.1/kernel/futex.c linux-2.6.38.1/kernel/futex.c
49955--- linux-2.6.38.1/kernel/futex.c 2011-03-14 21:20:32.000000000 -0400
49956+++ linux-2.6.38.1/kernel/futex.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
49957@@ -54,6 +54,7 @@
49958 #include <linux/mount.h>
49959 #include <linux/pagemap.h>
49960 #include <linux/syscalls.h>
49961+#include <linux/ptrace.h>
49962 #include <linux/signal.h>
49963 #include <linux/module.h>
49964 #include <linux/magic.h>
16454cff
MT
49965@@ -236,6 +237,11 @@ get_futex_key(u32 __user *uaddr, int fsh
49966 struct page *page, *page_head;
58c5fc13
MT
49967 int err;
49968
49969+#ifdef CONFIG_PAX_SEGMEXEC
49970+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
49971+ return -EFAULT;
49972+#endif
49973+
49974 /*
49975 * The futex address must be "naturally" aligned.
49976 */
16454cff 49977@@ -2404,7 +2410,9 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
ae4e228f
MT
49978 {
49979 struct robust_list_head __user *head;
49980 unsigned long ret;
ae4e228f 49981+#ifndef CONFIG_GRKERNSEC_PROC_MEMMAP
57199397 49982 const struct cred *cred = current_cred(), *pcred;
ae4e228f
MT
49983+#endif
49984
49985 if (!futex_cmpxchg_enabled)
49986 return -ENOSYS;
16454cff 49987@@ -2420,11 +2428,16 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
ae4e228f
MT
49988 if (!p)
49989 goto err_unlock;
49990 ret = -EPERM;
49991+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
49992+ if (!ptrace_may_access(p, PTRACE_MODE_READ))
49993+ goto err_unlock;
49994+#else
49995 pcred = __task_cred(p);
49996 if (cred->euid != pcred->euid &&
49997 cred->euid != pcred->uid &&
49998 !capable(CAP_SYS_PTRACE))
49999 goto err_unlock;
50000+#endif
50001 head = p->robust_list;
50002 rcu_read_unlock();
50003 }
16454cff 50004@@ -2667,6 +2680,7 @@ static int __init futex_init(void)
58c5fc13 50005 {
bc901d79
MT
50006 u32 curval;
50007 int i;
50008+ mm_segment_t oldfs;
58c5fc13 50009
bc901d79
MT
50010 /*
50011 * This will fail and we want it. Some arch implementations do
16454cff 50012@@ -2678,7 +2692,10 @@ static int __init futex_init(void)
bc901d79
MT
50013 * implementation, the non-functional ones will return
50014 * -ENOSYS.
50015 */
50016+ oldfs = get_fs();
50017+ set_fs(USER_DS);
50018 curval = cmpxchg_futex_value_locked(NULL, 0, 0);
50019+ set_fs(oldfs);
50020 if (curval == -EFAULT)
50021 futex_cmpxchg_enabled = 1;
50022
16454cff
MT
50023diff -urNp linux-2.6.38.1/kernel/futex_compat.c linux-2.6.38.1/kernel/futex_compat.c
50024--- linux-2.6.38.1/kernel/futex_compat.c 2011-03-14 21:20:32.000000000 -0400
50025+++ linux-2.6.38.1/kernel/futex_compat.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
50026@@ -10,6 +10,7 @@
50027 #include <linux/compat.h>
50028 #include <linux/nsproxy.h>
50029 #include <linux/futex.h>
50030+#include <linux/ptrace.h>
50031
50032 #include <asm/uaccess.h>
50033
bc901d79 50034@@ -136,7 +137,10 @@ compat_sys_get_robust_list(int pid, comp
ae4e228f
MT
50035 {
50036 struct compat_robust_list_head __user *head;
50037 unsigned long ret;
50038- const struct cred *cred = current_cred(), *pcred;
ae4e228f 50039+#ifndef CONFIG_GRKERNSEC_PROC_MEMMAP
57199397 50040+ const struct cred *cred = current_cred();
ae4e228f
MT
50041+ const struct cred *pcred;
50042+#endif
50043
50044 if (!futex_cmpxchg_enabled)
50045 return -ENOSYS;
bc901d79 50046@@ -152,11 +156,16 @@ compat_sys_get_robust_list(int pid, comp
ae4e228f
MT
50047 if (!p)
50048 goto err_unlock;
50049 ret = -EPERM;
50050+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
50051+ if (!ptrace_may_access(p, PTRACE_MODE_READ))
50052+ goto err_unlock;
50053+#else
50054 pcred = __task_cred(p);
50055 if (cred->euid != pcred->euid &&
50056 cred->euid != pcred->uid &&
50057 !capable(CAP_SYS_PTRACE))
50058 goto err_unlock;
50059+#endif
50060 head = p->compat_robust_list;
df50ba0c 50061 rcu_read_unlock();
ae4e228f 50062 }
16454cff
MT
50063diff -urNp linux-2.6.38.1/kernel/gcov/base.c linux-2.6.38.1/kernel/gcov/base.c
50064--- linux-2.6.38.1/kernel/gcov/base.c 2011-03-14 21:20:32.000000000 -0400
50065+++ linux-2.6.38.1/kernel/gcov/base.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
50066@@ -102,11 +102,6 @@ void gcov_enable_events(void)
50067 }
50068
50069 #ifdef CONFIG_MODULES
50070-static inline int within(void *addr, void *start, unsigned long size)
50071-{
50072- return ((addr >= start) && (addr < start + size));
50073-}
50074-
50075 /* Update list and generate events when modules are unloaded. */
50076 static int gcov_module_notifier(struct notifier_block *nb, unsigned long event,
50077 void *data)
50078@@ -121,7 +116,7 @@ static int gcov_module_notifier(struct n
50079 prev = NULL;
50080 /* Remove entries located in module from linked list. */
50081 for (info = gcov_info_head; info; info = info->next) {
50082- if (within(info, mod->module_core, mod->core_size)) {
50083+ if (within_module_core_rw((unsigned long)info, mod)) {
50084 if (prev)
50085 prev->next = info->next;
50086 else
16454cff
MT
50087diff -urNp linux-2.6.38.1/kernel/hrtimer.c linux-2.6.38.1/kernel/hrtimer.c
50088--- linux-2.6.38.1/kernel/hrtimer.c 2011-03-14 21:20:32.000000000 -0400
50089+++ linux-2.6.38.1/kernel/hrtimer.c 2011-03-21 18:31:35.000000000 -0400
50090@@ -1371,7 +1371,7 @@ void hrtimer_peek_ahead_timers(void)
ae4e228f
MT
50091 local_irq_restore(flags);
50092 }
50093
50094-static void run_hrtimer_softirq(struct softirq_action *h)
50095+static void run_hrtimer_softirq(void)
50096 {
50097 hrtimer_peek_ahead_timers();
50098 }
16454cff
MT
50099diff -urNp linux-2.6.38.1/kernel/jump_label.c linux-2.6.38.1/kernel/jump_label.c
50100--- linux-2.6.38.1/kernel/jump_label.c 2011-03-14 21:20:32.000000000 -0400
50101+++ linux-2.6.38.1/kernel/jump_label.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
50102@@ -49,6 +49,17 @@ void jump_label_unlock(void)
50103 mutex_unlock(&jump_label_mutex);
50104 }
50105
50106+static void jump_label_swap(void *a, void *b, int size)
50107+{
50108+ struct jump_entry t;
50109+
50110+ t = *(struct jump_entry *)a;
50111+ pax_open_kernel();
50112+ *(struct jump_entry *)a = *(struct jump_entry *)b;
50113+ *(struct jump_entry *)b = t;
50114+ pax_close_kernel();
50115+}
50116+
50117 static int jump_label_cmp(const void *a, const void *b)
50118 {
50119 const struct jump_entry *jea = a;
50120@@ -70,7 +81,7 @@ sort_jump_label_entries(struct jump_entr
50121
50122 size = (((unsigned long)stop - (unsigned long)start)
50123 / sizeof(struct jump_entry));
50124- sort(start, size, sizeof(struct jump_entry), jump_label_cmp, NULL);
50125+ sort(start, size, sizeof(struct jump_entry), jump_label_cmp, jump_label_swap);
50126 }
50127
50128 static struct jump_label_entry *get_jump_label_entry(jump_label_t key)
50129@@ -407,8 +418,11 @@ static void remove_jump_label_module_ini
50130 count = e_module->nr_entries;
50131 iter = e_module->table;
50132 while (count--) {
50133- if (within_module_init(iter->code, mod))
50134+ if (within_module_init(iter->code, mod)) {
50135+ pax_open_kernel();
50136 iter->key = 0;
50137+ pax_close_kernel();
50138+ }
50139 iter++;
50140 }
50141 }
16454cff
MT
50142diff -urNp linux-2.6.38.1/kernel/kallsyms.c linux-2.6.38.1/kernel/kallsyms.c
50143--- linux-2.6.38.1/kernel/kallsyms.c 2011-03-14 21:20:32.000000000 -0400
50144+++ linux-2.6.38.1/kernel/kallsyms.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
50145@@ -11,6 +11,9 @@
50146 * Changed the compression method from stem compression to "table lookup"
50147 * compression (see scripts/kallsyms.c for a more complete description)
50148 */
50149+#ifdef CONFIG_GRKERNSEC_HIDESYM
50150+#define __INCLUDED_BY_HIDESYM 1
50151+#endif
50152 #include <linux/kallsyms.h>
50153 #include <linux/module.h>
50154 #include <linux/init.h>
57199397 50155@@ -53,12 +56,33 @@ extern const unsigned long kallsyms_mark
58c5fc13
MT
50156
50157 static inline int is_kernel_inittext(unsigned long addr)
50158 {
50159+ if (system_state != SYSTEM_BOOTING)
50160+ return 0;
50161+
50162 if (addr >= (unsigned long)_sinittext
50163 && addr <= (unsigned long)_einittext)
50164 return 1;
57199397
MT
50165 return 0;
50166 }
58c5fc13 50167
ae4e228f 50168+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
df50ba0c 50169+#ifdef CONFIG_MODULES
57199397
MT
50170+static inline int is_module_text(unsigned long addr)
50171+{
50172+ if ((unsigned long)MODULES_EXEC_VADDR <= addr && addr <= (unsigned long)MODULES_EXEC_END)
50173+ return 1;
50174+
50175+ addr = ktla_ktva(addr);
50176+ return (unsigned long)MODULES_EXEC_VADDR <= addr && addr <= (unsigned long)MODULES_EXEC_END;
50177+}
50178+#else
50179+static inline int is_module_text(unsigned long addr)
50180+{
50181+ return 0;
50182+}
50183+#endif
df50ba0c 50184+#endif
58c5fc13 50185+
57199397
MT
50186 static inline int is_kernel_text(unsigned long addr)
50187 {
50188 if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) ||
50189@@ -69,13 +93,28 @@ static inline int is_kernel_text(unsigne
50190
50191 static inline int is_kernel(unsigned long addr)
50192 {
ae4e228f 50193+
57199397
MT
50194+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
50195+ if (is_kernel_text(addr) || is_kernel_inittext(addr))
58c5fc13 50196+ return 1;
ae4e228f 50197+
57199397
MT
50198+ if (ktla_ktva((unsigned long)_text) <= addr && addr < (unsigned long)_end)
50199+#else
50200 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
ae4e228f 50201+#endif
58c5fc13 50202+
58c5fc13
MT
50203 return 1;
50204 return in_gate_area_no_task(addr);
57199397
MT
50205 }
50206
50207 static int is_ksym_addr(unsigned long addr)
50208 {
50209+
50210+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
50211+ if (is_module_text(addr))
50212+ return 0;
50213+#endif
50214+
50215 if (all_var)
50216 return is_kernel(addr);
50217
50218@@ -416,7 +455,6 @@ static unsigned long get_ksymbol_core(st
58c5fc13
MT
50219
50220 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
50221 {
50222- iter->name[0] = '\0';
50223 iter->nameoff = get_symbol_offset(new_pos);
50224 iter->pos = new_pos;
50225 }
57199397 50226@@ -464,6 +502,11 @@ static int s_show(struct seq_file *m, vo
ae4e228f
MT
50227 {
50228 struct kallsym_iter *iter = m->private;
50229
50230+#ifdef CONFIG_GRKERNSEC_HIDESYM
50231+ if (current_uid())
50232+ return 0;
50233+#endif
50234+
50235 /* Some debugging symbols have no name. Ignore them. */
50236 if (!iter->name[0])
50237 return 0;
57199397 50238@@ -504,7 +547,7 @@ static int kallsyms_open(struct inode *i
58c5fc13
MT
50239 struct kallsym_iter *iter;
50240 int ret;
50241
50242- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
50243+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
50244 if (!iter)
50245 return -ENOMEM;
50246 reset_iter(iter, 0);
16454cff
MT
50247diff -urNp linux-2.6.38.1/kernel/kmod.c linux-2.6.38.1/kernel/kmod.c
50248--- linux-2.6.38.1/kernel/kmod.c 2011-03-14 21:20:32.000000000 -0400
50249+++ linux-2.6.38.1/kernel/kmod.c 2011-03-26 13:28:34.000000000 -0400
50250@@ -90,6 +90,18 @@ int __request_module(bool wait, const ch
ae4e228f
MT
50251 if (ret)
50252 return ret;
58c5fc13
MT
50253
50254+#ifdef CONFIG_GRKERNSEC_MODHARDEN
50255+ /* we could do a tighter check here, but some distros
50256+ are taking it upon themselves to remove CAP_SYS_MODULE
ae4e228f 50257+ from even root-running apps which cause modules to be
58c5fc13
MT
50258+ auto-loaded
50259+ */
50260+ if (current_uid()) {
16454cff 50261+ gr_log_nonroot_mod_load(module_name);
58c5fc13
MT
50262+ return -EPERM;
50263+ }
50264+#endif
50265+
50266 /* If modprobe needs a service that is in a module, we get a recursive
50267 * loop. Limit the number of running kmod threads to max_threads/2 or
50268 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
16454cff
MT
50269diff -urNp linux-2.6.38.1/kernel/kprobes.c linux-2.6.38.1/kernel/kprobes.c
50270--- linux-2.6.38.1/kernel/kprobes.c 2011-03-14 21:20:32.000000000 -0400
50271+++ linux-2.6.38.1/kernel/kprobes.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 50272@@ -185,7 +185,7 @@ static kprobe_opcode_t __kprobes *__get_
58c5fc13
MT
50273 * kernel image and loaded module images reside. This is required
50274 * so x86_64 can correctly handle the %rip-relative fixups.
50275 */
50276- kip->insns = module_alloc(PAGE_SIZE);
50277+ kip->insns = module_alloc_exec(PAGE_SIZE);
50278 if (!kip->insns) {
50279 kfree(kip);
50280 return NULL;
bc901d79 50281@@ -225,7 +225,7 @@ static int __kprobes collect_one_slot(st
ae4e228f 50282 */
df50ba0c 50283 if (!list_is_singular(&kip->list)) {
ae4e228f 50284 list_del(&kip->list);
58c5fc13
MT
50285- module_free(NULL, kip->insns);
50286+ module_free_exec(NULL, kip->insns);
50287 kfree(kip);
50288 }
50289 return 1;
16454cff 50290@@ -1936,7 +1936,7 @@ static int __init init_kprobes(void)
df50ba0c
MT
50291 {
50292 int i, err = 0;
50293 unsigned long offset = 0, size = 0;
50294- char *modname, namebuf[128];
50295+ char *modname, namebuf[KSYM_NAME_LEN];
50296 const char *symbol_name;
50297 void *addr;
50298 struct kprobe_blackpoint *kb;
16454cff 50299@@ -2062,7 +2062,7 @@ static int __kprobes show_kprobe_addr(st
df50ba0c
MT
50300 const char *sym = NULL;
50301 unsigned int i = *(loff_t *) v;
50302 unsigned long offset = 0;
50303- char *modname, namebuf[128];
50304+ char *modname, namebuf[KSYM_NAME_LEN];
50305
50306 head = &kprobe_table[i];
50307 preempt_disable();
16454cff
MT
50308diff -urNp linux-2.6.38.1/kernel/lockdep.c linux-2.6.38.1/kernel/lockdep.c
50309--- linux-2.6.38.1/kernel/lockdep.c 2011-03-14 21:20:32.000000000 -0400
50310+++ linux-2.6.38.1/kernel/lockdep.c 2011-03-21 18:31:35.000000000 -0400
57199397 50311@@ -571,6 +571,10 @@ static int static_obj(void *obj)
df50ba0c
MT
50312 end = (unsigned long) &_end,
50313 addr = (unsigned long) obj;
58c5fc13
MT
50314
50315+#ifdef CONFIG_PAX_KERNEXEC
ae4e228f 50316+ start = ktla_ktva(start);
58c5fc13
MT
50317+#endif
50318+
50319 /*
50320 * static variable?
50321 */
bc901d79 50322@@ -706,6 +710,7 @@ register_lock_class(struct lockdep_map *
ae4e228f
MT
50323 if (!static_obj(lock->key)) {
50324 debug_locks_off();
50325 printk("INFO: trying to register non-static key.\n");
50326+ printk("lock:%pS key:%pS.\n", lock, lock->key);
50327 printk("the code is fine but needs lockdep annotation.\n");
50328 printk("turning off the locking correctness validator.\n");
50329 dump_stack();
16454cff 50330@@ -2752,7 +2757,7 @@ static int __lock_acquire(struct lockdep
bc901d79
MT
50331 if (!class)
50332 return 0;
50333 }
50334- atomic_inc((atomic_t *)&class->ops);
50335+ atomic_inc_unchecked((atomic_unchecked_t *)&class->ops);
50336 if (very_verbose(class)) {
50337 printk("\nacquire class [%p] %s", class->key, class->name);
50338 if (class->name_version > 1)
16454cff
MT
50339diff -urNp linux-2.6.38.1/kernel/lockdep_proc.c linux-2.6.38.1/kernel/lockdep_proc.c
50340--- linux-2.6.38.1/kernel/lockdep_proc.c 2011-03-14 21:20:32.000000000 -0400
50341+++ linux-2.6.38.1/kernel/lockdep_proc.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
50342@@ -39,7 +39,7 @@ static void l_stop(struct seq_file *m, v
50343
50344 static void print_name(struct seq_file *m, struct lock_class *class)
50345 {
50346- char str[128];
50347+ char str[KSYM_NAME_LEN];
50348 const char *name = class->name;
50349
50350 if (!name) {
16454cff
MT
50351diff -urNp linux-2.6.38.1/kernel/module.c linux-2.6.38.1/kernel/module.c
50352--- linux-2.6.38.1/kernel/module.c 2011-03-14 21:20:32.000000000 -0400
50353+++ linux-2.6.38.1/kernel/module.c 2011-03-21 18:31:35.000000000 -0400
50354@@ -118,7 +118,8 @@ static BLOCKING_NOTIFIER_HEAD(module_not
58c5fc13 50355
57199397
MT
50356 /* Bounds of module allocation, for speeding __module_address.
50357 * Protected by module_mutex. */
58c5fc13
MT
50358-static unsigned long module_addr_min = -1UL, module_addr_max = 0;
50359+static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
50360+static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
50361
50362 int register_module_notifier(struct notifier_block * nb)
50363 {
16454cff 50364@@ -282,7 +283,7 @@ bool each_symbol(bool (*fn)(const struct
58c5fc13
MT
50365 return true;
50366
50367 list_for_each_entry_rcu(mod, &modules, list) {
50368- struct symsearch arr[] = {
50369+ struct symsearch modarr[] = {
50370 { mod->syms, mod->syms + mod->num_syms, mod->crcs,
50371 NOT_GPL_ONLY, false },
50372 { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
16454cff 50373@@ -304,7 +305,7 @@ bool each_symbol(bool (*fn)(const struct
58c5fc13
MT
50374 #endif
50375 };
50376
50377- if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
50378+ if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
50379 return true;
50380 }
50381 return false;
16454cff 50382@@ -415,7 +416,7 @@ static inline void __percpu *mod_percpu(
df50ba0c
MT
50383 static int percpu_modalloc(struct module *mod,
50384 unsigned long size, unsigned long align)
ae4e228f 50385 {
58c5fc13
MT
50386- if (align > PAGE_SIZE) {
50387+ if (align-1 >= PAGE_SIZE) {
50388 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
df50ba0c 50389 mod->name, align, PAGE_SIZE);
58c5fc13 50390 align = PAGE_SIZE;
16454cff 50391@@ -1143,7 +1144,7 @@ resolve_symbol_wait(struct module *mod,
c52201e0
MT
50392 */
50393 #ifdef CONFIG_SYSFS
50394
50395-#ifdef CONFIG_KALLSYMS
50396+#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
50397 static inline bool sect_empty(const Elf_Shdr *sect)
50398 {
50399 return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0;
16454cff
MT
50400@@ -1612,17 +1613,17 @@ void unset_section_ro_nx(struct module *
50401 {
50402 unsigned long total_pages;
50403
50404- if (mod->module_core == module_region) {
50405+ if (mod->module_core_rx == module_region) {
50406 /* Set core as NX+RW */
50407- total_pages = MOD_NUMBER_OF_PAGES(mod->module_core, mod->core_size);
50408- set_memory_nx((unsigned long)mod->module_core, total_pages);
50409- set_memory_rw((unsigned long)mod->module_core, total_pages);
50410+ total_pages = MOD_NUMBER_OF_PAGES(mod->module_core_rx, mod->core_size_rx);
50411+ set_memory_nx((unsigned long)mod->module_core_rx, total_pages);
50412+ set_memory_rw((unsigned long)mod->module_core_rx, total_pages);
50413
50414- } else if (mod->module_init == module_region) {
50415+ } else if (mod->module_init_rx == module_region) {
50416 /* Set init as NX+RW */
50417- total_pages = MOD_NUMBER_OF_PAGES(mod->module_init, mod->init_size);
50418- set_memory_nx((unsigned long)mod->module_init, total_pages);
50419- set_memory_rw((unsigned long)mod->module_init, total_pages);
50420+ total_pages = MOD_NUMBER_OF_PAGES(mod->module_init_rx, mod->init_size_rx);
50421+ set_memory_nx((unsigned long)mod->module_init_rx, total_pages);
50422+ set_memory_rw((unsigned long)mod->module_init_rx, total_pages);
50423 }
50424 }
50425
50426@@ -1633,14 +1634,14 @@ void set_all_modules_text_rw()
50427
50428 mutex_lock(&module_mutex);
50429 list_for_each_entry_rcu(mod, &modules, list) {
50430- if ((mod->module_core) && (mod->core_text_size)) {
50431- set_page_attributes(mod->module_core,
50432- mod->module_core + mod->core_text_size,
50433+ if ((mod->module_core_rx) && (mod->core_size_rx)) {
50434+ set_page_attributes(mod->module_core_rx,
50435+ mod->module_core_rx + mod->core_size_rx,
50436 set_memory_rw);
50437 }
50438- if ((mod->module_init) && (mod->init_text_size)) {
50439- set_page_attributes(mod->module_init,
50440- mod->module_init + mod->init_text_size,
50441+ if ((mod->module_init_rx) && (mod->init_size_rx)) {
50442+ set_page_attributes(mod->module_init_rx,
50443+ mod->module_init_rx + mod->init_size_rx,
50444 set_memory_rw);
50445 }
50446 }
50447@@ -1654,14 +1655,14 @@ void set_all_modules_text_ro()
50448
50449 mutex_lock(&module_mutex);
50450 list_for_each_entry_rcu(mod, &modules, list) {
50451- if ((mod->module_core) && (mod->core_text_size)) {
50452- set_page_attributes(mod->module_core,
50453- mod->module_core + mod->core_text_size,
50454+ if ((mod->module_core_rx) && (mod->core_size_rx)) {
50455+ set_page_attributes(mod->module_core_rx,
50456+ mod->module_core_rx + mod->core_size_rx,
50457 set_memory_ro);
50458 }
50459- if ((mod->module_init) && (mod->init_text_size)) {
50460- set_page_attributes(mod->module_init,
50461- mod->module_init + mod->init_text_size,
50462+ if ((mod->module_init_rx) && (mod->init_size_rx)) {
50463+ set_page_attributes(mod->module_init_rx,
50464+ mod->module_init_rx + mod->init_size_rx,
50465 set_memory_ro);
50466 }
50467 }
50468@@ -1696,17 +1697,20 @@ static void free_module(struct module *m
58c5fc13
MT
50469 destroy_params(mod->kp, mod->num_kp);
50470
50471 /* This may be NULL, but that's OK */
16454cff 50472- unset_section_ro_nx(mod, mod->module_init);
58c5fc13 50473- module_free(mod, mod->module_init);
16454cff 50474+ unset_section_ro_nx(mod, mod->module_init_rx);
58c5fc13
MT
50475+ module_free(mod, mod->module_init_rw);
50476+ module_free_exec(mod, mod->module_init_rx);
50477 kfree(mod->args);
df50ba0c 50478 percpu_modfree(mod);
6892158b 50479
58c5fc13
MT
50480 /* Free lock-classes: */
50481- lockdep_free_key_range(mod->module_core, mod->core_size);
50482+ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
50483+ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
50484
50485 /* Finally, free the core (containing the module structure) */
16454cff 50486- unset_section_ro_nx(mod, mod->module_core);
58c5fc13 50487- module_free(mod, mod->module_core);
16454cff 50488+ unset_section_ro_nx(mod, mod->module_core_rx);
58c5fc13
MT
50489+ module_free_exec(mod, mod->module_core_rx);
50490+ module_free(mod, mod->module_core_rw);
58c5fc13 50491
ae4e228f
MT
50492 #ifdef CONFIG_MPU
50493 update_protections(current->mm);
16454cff 50494@@ -1799,7 +1803,9 @@ static int simplify_symbols(struct modul
6892158b 50495 ksym = resolve_symbol_wait(mod, info, name);
58c5fc13 50496 /* Ok if resolved. */
57199397 50497 if (ksym && !IS_ERR(ksym)) {
ae4e228f 50498+ pax_open_kernel();
58c5fc13 50499 sym[i].st_value = ksym->value;
ae4e228f 50500+ pax_close_kernel();
58c5fc13
MT
50501 break;
50502 }
50503
16454cff 50504@@ -1818,7 +1824,9 @@ static int simplify_symbols(struct modul
df50ba0c 50505 secbase = (unsigned long)mod_percpu(mod);
58c5fc13 50506 else
6892158b 50507 secbase = info->sechdrs[sym[i].st_shndx].sh_addr;
ae4e228f 50508+ pax_open_kernel();
58c5fc13 50509 sym[i].st_value += secbase;
ae4e228f 50510+ pax_close_kernel();
58c5fc13
MT
50511 break;
50512 }
50513 }
16454cff 50514@@ -1906,22 +1914,12 @@ static void layout_sections(struct modul
58c5fc13 50515 || s->sh_entsize != ~0UL
6892158b 50516 || strstarts(sname, ".init"))
58c5fc13
MT
50517 continue;
50518- s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
50519+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
50520+ s->sh_entsize = get_offset(mod, &mod->core_size_rw, s, i);
50521+ else
50522+ s->sh_entsize = get_offset(mod, &mod->core_size_rx, s, i);
6892158b 50523 DEBUGP("\t%s\n", name);
58c5fc13 50524 }
16454cff
MT
50525- switch (m) {
50526- case 0: /* executable */
50527- mod->core_size = debug_align(mod->core_size);
58c5fc13 50528- mod->core_text_size = mod->core_size;
16454cff
MT
50529- break;
50530- case 1: /* RO: text and ro-data */
50531- mod->core_size = debug_align(mod->core_size);
50532- mod->core_ro_size = mod->core_size;
50533- break;
50534- case 3: /* whole core */
50535- mod->core_size = debug_align(mod->core_size);
50536- break;
50537- }
58c5fc13
MT
50538 }
50539
50540 DEBUGP("Init section allocation order:\n");
16454cff 50541@@ -1935,23 +1933,13 @@ static void layout_sections(struct modul
58c5fc13 50542 || s->sh_entsize != ~0UL
6892158b 50543 || !strstarts(sname, ".init"))
58c5fc13
MT
50544 continue;
50545- s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
50546- | INIT_OFFSET_MASK);
50547+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
50548+ s->sh_entsize = get_offset(mod, &mod->init_size_rw, s, i);
50549+ else
50550+ s->sh_entsize = get_offset(mod, &mod->init_size_rx, s, i);
50551+ s->sh_entsize |= INIT_OFFSET_MASK;
6892158b 50552 DEBUGP("\t%s\n", sname);
58c5fc13 50553 }
16454cff
MT
50554- switch (m) {
50555- case 0: /* executable */
50556- mod->init_size = debug_align(mod->init_size);
58c5fc13 50557- mod->init_text_size = mod->init_size;
16454cff
MT
50558- break;
50559- case 1: /* RO: text and ro-data */
50560- mod->init_size = debug_align(mod->init_size);
50561- mod->init_ro_size = mod->init_size;
50562- break;
50563- case 3: /* whole init */
50564- mod->init_size = debug_align(mod->init_size);
50565- break;
50566- }
58c5fc13
MT
50567 }
50568 }
50569
16454cff 50570@@ -2119,7 +2107,7 @@ static void layout_symtab(struct module
58c5fc13 50571
ae4e228f
MT
50572 /* Put symbol section at end of init part of module. */
50573 symsect->sh_flags |= SHF_ALLOC;
50574- symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect,
50575+ symsect->sh_entsize = get_offset(mod, &mod->init_size_rx, symsect,
6892158b
MT
50576 info->index.sym) | INIT_OFFSET_MASK;
50577 DEBUGP("\t%s\n", info->secstrings + symsect->sh_name);
ae4e228f 50578
16454cff 50579@@ -2136,19 +2124,19 @@ static void layout_symtab(struct module
ae4e228f
MT
50580 }
50581
50582 /* Append room for core symbols at end of core part. */
6892158b
MT
50583- info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
50584- mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym);
50585+ info->symoffs = ALIGN(mod->core_size_rx, symsect->sh_addralign ?: 1);
50586+ mod->core_size_rx = info->symoffs + ndst * sizeof(Elf_Sym);
ae4e228f
MT
50587
50588 /* Put string table section at end of init part of module. */
50589 strsect->sh_flags |= SHF_ALLOC;
50590- strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
50591+ strsect->sh_entsize = get_offset(mod, &mod->init_size_rx, strsect,
6892158b
MT
50592 info->index.str) | INIT_OFFSET_MASK;
50593 DEBUGP("\t%s\n", info->secstrings + strsect->sh_name);
ae4e228f
MT
50594
50595 /* Append room for core symbols' strings at end of core part. */
6892158b
MT
50596- info->stroffs = mod->core_size;
50597+ info->stroffs = mod->core_size_rx;
50598 __set_bit(0, info->strmap);
50599- mod->core_size += bitmap_weight(info->strmap, strsect->sh_size);
50600+ mod->core_size_rx += bitmap_weight(info->strmap, strsect->sh_size);
ae4e228f 50601 }
6892158b
MT
50602
50603 static void add_kallsyms(struct module *mod, const struct load_info *info)
16454cff 50604@@ -2164,11 +2152,13 @@ static void add_kallsyms(struct module *
6892158b
MT
50605 /* Make sure we get permanent strtab: don't use info->strtab. */
50606 mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
58c5fc13 50607
ae4e228f
MT
50608+ pax_open_kernel();
50609+
58c5fc13 50610 /* Set types up while we still have access to sections. */
ae4e228f 50611 for (i = 0; i < mod->num_symtab; i++)
6892158b 50612 mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
ae4e228f 50613
6892158b
MT
50614- mod->core_symtab = dst = mod->module_core + info->symoffs;
50615+ mod->core_symtab = dst = mod->module_core_rx + info->symoffs;
ae4e228f
MT
50616 src = mod->symtab;
50617 *dst = *src;
50618 for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
16454cff 50619@@ -2181,10 +2171,12 @@ static void add_kallsyms(struct module *
ae4e228f
MT
50620 }
50621 mod->core_num_syms = ndst;
50622
6892158b
MT
50623- mod->core_strtab = s = mod->module_core + info->stroffs;
50624+ mod->core_strtab = s = mod->module_core_rx + info->stroffs;
50625 for (*s = 0, i = 1; i < info->sechdrs[info->index.str].sh_size; ++i)
50626 if (test_bit(i, info->strmap))
ae4e228f 50627 *++s = mod->strtab[i];
58c5fc13 50628+
ae4e228f 50629+ pax_close_kernel();
58c5fc13
MT
50630 }
50631 #else
6892158b 50632 static inline void layout_symtab(struct module *mod, struct load_info *info)
16454cff 50633@@ -2213,17 +2205,33 @@ static void dynamic_debug_remove(struct
57199397 50634 ddebug_remove_module(debug->modname);
58c5fc13
MT
50635 }
50636
50637-static void *module_alloc_update_bounds(unsigned long size)
50638+static void *module_alloc_update_bounds_rw(unsigned long size)
50639 {
50640 void *ret = module_alloc(size);
50641
50642 if (ret) {
57199397 50643 mutex_lock(&module_mutex);
58c5fc13
MT
50644 /* Update module bounds. */
50645- if ((unsigned long)ret < module_addr_min)
50646- module_addr_min = (unsigned long)ret;
50647- if ((unsigned long)ret + size > module_addr_max)
50648- module_addr_max = (unsigned long)ret + size;
50649+ if ((unsigned long)ret < module_addr_min_rw)
50650+ module_addr_min_rw = (unsigned long)ret;
50651+ if ((unsigned long)ret + size > module_addr_max_rw)
50652+ module_addr_max_rw = (unsigned long)ret + size;
57199397 50653+ mutex_unlock(&module_mutex);
58c5fc13
MT
50654+ }
50655+ return ret;
50656+}
50657+
50658+static void *module_alloc_update_bounds_rx(unsigned long size)
50659+{
50660+ void *ret = module_alloc_exec(size);
50661+
50662+ if (ret) {
57199397 50663+ mutex_lock(&module_mutex);
58c5fc13
MT
50664+ /* Update module bounds. */
50665+ if ((unsigned long)ret < module_addr_min_rx)
50666+ module_addr_min_rx = (unsigned long)ret;
50667+ if ((unsigned long)ret + size > module_addr_max_rx)
50668+ module_addr_max_rx = (unsigned long)ret + size;
57199397 50669 mutex_unlock(&module_mutex);
58c5fc13
MT
50670 }
50671 return ret;
16454cff 50672@@ -2516,7 +2524,7 @@ static int move_module(struct module *mo
6892158b 50673 void *ptr;
58c5fc13
MT
50674
50675 /* Do the allocs. */
50676- ptr = module_alloc_update_bounds(mod->core_size);
50677+ ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
50678 /*
50679 * The pointer to this block is stored in the module structure
50680 * which is inside the block. Just mark it as not being a
16454cff 50681@@ -2526,23 +2534,50 @@ static int move_module(struct module *mo
6892158b
MT
50682 if (!ptr)
50683 return -ENOMEM;
50684
58c5fc13
MT
50685- memset(ptr, 0, mod->core_size);
50686- mod->module_core = ptr;
50687+ memset(ptr, 0, mod->core_size_rw);
50688+ mod->module_core_rw = ptr;
50689
50690- ptr = module_alloc_update_bounds(mod->init_size);
50691+ ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
50692 /*
50693 * The pointer to this block is stored in the module structure
50694 * which is inside the block. This block doesn't need to be
50695 * scanned as it contains data and code that will be freed
50696 * after the module is initialized.
50697 */
50698- kmemleak_ignore(ptr);
50699- if (!ptr && mod->init_size) {
6892158b 50700- module_free(mod, mod->module_core);
58c5fc13
MT
50701+ kmemleak_not_leak(ptr);
50702+ if (!ptr && mod->init_size_rw) {
6892158b 50703+ module_free(mod, mod->module_core_rw);
16454cff
MT
50704 return -ENOMEM;
50705 }
50706- memset(ptr, 0, mod->init_size);
50707- mod->module_init = ptr;
58c5fc13
MT
50708+ memset(ptr, 0, mod->init_size_rw);
50709+ mod->module_init_rw = ptr;
50710+
50711+ ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
50712+ kmemleak_not_leak(ptr);
50713+ if (!ptr) {
6892158b
MT
50714+ module_free(mod, mod->module_init_rw);
50715+ module_free(mod, mod->module_core_rw);
c52201e0
MT
50716+ return -ENOMEM;
50717+ }
58c5fc13 50718+
ae4e228f 50719+ pax_open_kernel();
58c5fc13 50720+ memset(ptr, 0, mod->core_size_rx);
ae4e228f 50721+ pax_close_kernel();
58c5fc13
MT
50722+ mod->module_core_rx = ptr;
50723+
50724+ ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
50725+ kmemleak_not_leak(ptr);
50726+ if (!ptr && mod->init_size_rx) {
6892158b
MT
50727+ module_free_exec(mod, mod->module_core_rx);
50728+ module_free(mod, mod->module_init_rw);
50729+ module_free(mod, mod->module_core_rw);
16454cff
MT
50730+ return -ENOMEM;
50731+ }
58c5fc13 50732+
ae4e228f 50733+ pax_open_kernel();
58c5fc13 50734+ memset(ptr, 0, mod->init_size_rx);
ae4e228f 50735+ pax_close_kernel();
58c5fc13
MT
50736+ mod->module_init_rx = ptr;
50737
50738 /* Transfer each section which specifies SHF_ALLOC */
50739 DEBUGP("final section addresses:\n");
16454cff 50740@@ -2553,16 +2588,45 @@ static int move_module(struct module *mo
6892158b 50741 if (!(shdr->sh_flags & SHF_ALLOC))
58c5fc13
MT
50742 continue;
50743
6892158b 50744- if (shdr->sh_entsize & INIT_OFFSET_MASK)
58c5fc13 50745- dest = mod->module_init
6892158b 50746- + (shdr->sh_entsize & ~INIT_OFFSET_MASK);
58c5fc13 50747- else
6892158b
MT
50748- dest = mod->module_core + shdr->sh_entsize;
50749+ if (shdr->sh_entsize & INIT_OFFSET_MASK) {
50750+ if ((shdr->sh_flags & SHF_WRITE) || !(shdr->sh_flags & SHF_ALLOC))
58c5fc13 50751+ dest = mod->module_init_rw
6892158b 50752+ + (shdr->sh_entsize & ~INIT_OFFSET_MASK);
58c5fc13
MT
50753+ else
50754+ dest = mod->module_init_rx
6892158b 50755+ + (shdr->sh_entsize & ~INIT_OFFSET_MASK);
58c5fc13 50756+ } else {
6892158b
MT
50757+ if ((shdr->sh_flags & SHF_WRITE) || !(shdr->sh_flags & SHF_ALLOC))
50758+ dest = mod->module_core_rw + shdr->sh_entsize;
58c5fc13 50759+ else
6892158b 50760+ dest = mod->module_core_rx + shdr->sh_entsize;
58c5fc13
MT
50761+ }
50762+
6892158b
MT
50763+ if (shdr->sh_type != SHT_NOBITS) {
50764+
58c5fc13 50765+#ifdef CONFIG_PAX_KERNEXEC
bc901d79
MT
50766+#ifdef CONFIG_X86_64
50767+ if ((shdr->sh_flags & SHF_WRITE) && (shdr->sh_flags & SHF_EXECINSTR))
50768+ set_memory_x((unsigned long)dest, (shdr->sh_size + PAGE_SIZE) >> PAGE_SHIFT);
50769+#endif
6892158b 50770+ if (!(shdr->sh_flags & SHF_WRITE) && (shdr->sh_flags & SHF_ALLOC)) {
ae4e228f 50771+ pax_open_kernel();
6892158b 50772+ memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
ae4e228f 50773+ pax_close_kernel();
58c5fc13
MT
50774+ } else
50775+#endif
6892158b
MT
50776
50777- if (shdr->sh_type != SHT_NOBITS)
50778 memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
58c5fc13
MT
50779+ }
50780 /* Update sh_addr to point to copy in image. */
6892158b 50781- shdr->sh_addr = (unsigned long)dest;
58c5fc13
MT
50782+
50783+#ifdef CONFIG_PAX_KERNEXEC
6892158b
MT
50784+ if (shdr->sh_flags & SHF_EXECINSTR)
50785+ shdr->sh_addr = ktva_ktla((unsigned long)dest);
58c5fc13
MT
50786+ else
50787+#endif
50788+
6892158b
MT
50789+ shdr->sh_addr = (unsigned long)dest;
50790 DEBUGP("\t0x%lx %s\n",
50791 shdr->sh_addr, info->secstrings + shdr->sh_name);
58c5fc13 50792 }
16454cff 50793@@ -2613,12 +2677,12 @@ static void flush_module_icache(const st
58c5fc13
MT
50794 * Do it before processing of module parameters, so the module
50795 * can provide parameter accessor functions of its own.
50796 */
50797- if (mod->module_init)
50798- flush_icache_range((unsigned long)mod->module_init,
50799- (unsigned long)mod->module_init
50800- + mod->init_size);
50801- flush_icache_range((unsigned long)mod->module_core,
50802- (unsigned long)mod->module_core + mod->core_size);
50803+ if (mod->module_init_rx)
50804+ flush_icache_range((unsigned long)mod->module_init_rx,
50805+ (unsigned long)mod->module_init_rx
50806+ + mod->init_size_rx);
50807+ flush_icache_range((unsigned long)mod->module_core_rx,
50808+ (unsigned long)mod->module_core_rx + mod->core_size_rx);
50809
50810 set_fs(old_fs);
6892158b 50811 }
16454cff 50812@@ -2690,8 +2754,10 @@ static void module_deallocate(struct mod
6892158b
MT
50813 {
50814 kfree(info->strmap);
50815 percpu_modfree(mod);
58c5fc13 50816- module_free(mod, mod->module_init);
58c5fc13
MT
50817- module_free(mod, mod->module_core);
50818+ module_free_exec(mod, mod->module_init_rx);
58c5fc13 50819+ module_free_exec(mod, mod->module_core_rx);
58c5fc13 50820+ module_free(mod, mod->module_init_rw);
58c5fc13 50821+ module_free(mod, mod->module_core_rw);
6892158b
MT
50822 }
50823
50824 static int post_relocation(struct module *mod, const struct load_info *info)
16454cff
MT
50825@@ -2877,16 +2943,16 @@ SYSCALL_DEFINE3(init_module, void __user
50826 MODULE_STATE_COMING, mod);
50827
50828 /* Set RO and NX regions for core */
50829- set_section_ro_nx(mod->module_core,
50830- mod->core_text_size,
50831- mod->core_ro_size,
50832- mod->core_size);
50833+ set_section_ro_nx(mod->module_core_rx,
50834+ mod->core_size_rx,
50835+ mod->core_size_rx,
50836+ mod->core_size_rx);
50837
50838 /* Set RO and NX regions for init */
50839- set_section_ro_nx(mod->module_init,
50840- mod->init_text_size,
50841- mod->init_ro_size,
50842- mod->init_size);
50843+ set_section_ro_nx(mod->module_init_rx,
50844+ mod->init_size_rx,
50845+ mod->init_size_rx,
50846+ mod->init_size_rx);
50847
50848 do_mod_ctors(mod);
50849 /* Start the module */
50850@@ -2931,11 +2997,13 @@ SYSCALL_DEFINE3(init_module, void __user
ae4e228f
MT
50851 mod->symtab = mod->core_symtab;
50852 mod->strtab = mod->core_strtab;
50853 #endif
16454cff 50854- unset_section_ro_nx(mod, mod->module_init);
58c5fc13
MT
50855- module_free(mod, mod->module_init);
50856- mod->module_init = NULL;
50857- mod->init_size = 0;
50858- mod->init_text_size = 0;
16454cff 50859+ unset_section_ro_nx(mod, mod->module_init_rx);
58c5fc13
MT
50860+ module_free(mod, mod->module_init_rw);
50861+ module_free_exec(mod, mod->module_init_rx);
50862+ mod->module_init_rw = NULL;
50863+ mod->module_init_rx = NULL;
50864+ mod->init_size_rw = 0;
50865+ mod->init_size_rx = 0;
50866 mutex_unlock(&module_mutex);
50867
50868 return 0;
16454cff 50869@@ -2966,10 +3034,16 @@ static const char *get_ksymbol(struct mo
58c5fc13
MT
50870 unsigned long nextval;
50871
50872 /* At worse, next value is at end of module */
50873- if (within_module_init(addr, mod))
50874- nextval = (unsigned long)mod->module_init+mod->init_text_size;
50875+ if (within_module_init_rx(addr, mod))
50876+ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
50877+ else if (within_module_init_rw(addr, mod))
50878+ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
50879+ else if (within_module_core_rx(addr, mod))
50880+ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
50881+ else if (within_module_core_rw(addr, mod))
50882+ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
50883 else
50884- nextval = (unsigned long)mod->module_core+mod->core_text_size;
50885+ return NULL;
50886
50887 /* Scan for closest preceeding symbol, and next symbol. (ELF
50888 starts real symbols at 1). */
16454cff 50889@@ -3215,7 +3289,7 @@ static int m_show(struct seq_file *m, vo
58c5fc13
MT
50890 char buf[8];
50891
50892 seq_printf(m, "%s %u",
50893- mod->name, mod->init_size + mod->core_size);
50894+ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
50895 print_unload_info(m, mod);
50896
50897 /* Informative for users. */
16454cff 50898@@ -3224,7 +3298,7 @@ static int m_show(struct seq_file *m, vo
58c5fc13
MT
50899 mod->state == MODULE_STATE_COMING ? "Loading":
50900 "Live");
50901 /* Used by oprofile and other similar tools. */
50902- seq_printf(m, " 0x%p", mod->module_core);
50903+ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
50904
50905 /* Taints info */
50906 if (mod->taints)
16454cff 50907@@ -3260,7 +3334,17 @@ static const struct file_operations proc
58c5fc13
MT
50908
50909 static int __init proc_modules_init(void)
50910 {
50911+#ifndef CONFIG_GRKERNSEC_HIDESYM
50912+#ifdef CONFIG_GRKERNSEC_PROC_USER
50913+ proc_create("modules", S_IRUSR, NULL, &proc_modules_operations);
50914+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
50915+ proc_create("modules", S_IRUSR | S_IRGRP, NULL, &proc_modules_operations);
50916+#else
50917 proc_create("modules", 0, NULL, &proc_modules_operations);
50918+#endif
50919+#else
50920+ proc_create("modules", S_IRUSR, NULL, &proc_modules_operations);
50921+#endif
50922 return 0;
50923 }
50924 module_init(proc_modules_init);
16454cff 50925@@ -3319,12 +3403,12 @@ struct module *__module_address(unsigned
58c5fc13
MT
50926 {
50927 struct module *mod;
50928
50929- if (addr < module_addr_min || addr > module_addr_max)
50930+ if ((addr < module_addr_min_rx || addr > module_addr_max_rx) &&
50931+ (addr < module_addr_min_rw || addr > module_addr_max_rw))
50932 return NULL;
50933
50934 list_for_each_entry_rcu(mod, &modules, list)
50935- if (within_module_core(addr, mod)
50936- || within_module_init(addr, mod))
50937+ if (within_module_init(addr, mod) || within_module_core(addr, mod))
50938 return mod;
50939 return NULL;
50940 }
16454cff 50941@@ -3358,11 +3442,20 @@ bool is_module_text_address(unsigned lon
58c5fc13
MT
50942 */
50943 struct module *__module_text_address(unsigned long addr)
50944 {
50945- struct module *mod = __module_address(addr);
50946+ struct module *mod;
50947+
50948+#ifdef CONFIG_X86_32
50949+ addr = ktla_ktva(addr);
50950+#endif
50951+
50952+ if (addr < module_addr_min_rx || addr > module_addr_max_rx)
50953+ return NULL;
50954+
50955+ mod = __module_address(addr);
50956+
50957 if (mod) {
50958 /* Make sure it's within the text section. */
50959- if (!within(addr, mod->module_init, mod->init_text_size)
50960- && !within(addr, mod->module_core, mod->core_text_size))
50961+ if (!within_module_init_rx(addr, mod) && !within_module_core_rx(addr, mod))
50962 mod = NULL;
50963 }
50964 return mod;
16454cff
MT
50965diff -urNp linux-2.6.38.1/kernel/panic.c linux-2.6.38.1/kernel/panic.c
50966--- linux-2.6.38.1/kernel/panic.c 2011-03-14 21:20:32.000000000 -0400
50967+++ linux-2.6.38.1/kernel/panic.c 2011-03-21 18:31:35.000000000 -0400
50968@@ -369,7 +369,7 @@ static void warn_slowpath_common(const c
bc901d79
MT
50969 const char *board;
50970
50971 printk(KERN_WARNING "------------[ cut here ]------------\n");
50972- printk(KERN_WARNING "WARNING: at %s:%d %pS()\n", file, line, caller);
50973+ printk(KERN_WARNING "WARNING: at %s:%d %pA()\n", file, line, caller);
50974 board = dmi_get_system_info(DMI_PRODUCT_NAME);
50975 if (board)
50976 printk(KERN_WARNING "Hardware name: %s\n", board);
16454cff 50977@@ -424,7 +424,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
58c5fc13
MT
50978 */
50979 void __stack_chk_fail(void)
50980 {
50981- panic("stack-protector: Kernel stack is corrupted in: %p\n",
50982+ dump_stack();
bc901d79 50983+ panic("stack-protector: Kernel stack is corrupted in: %pA\n",
58c5fc13
MT
50984 __builtin_return_address(0));
50985 }
50986 EXPORT_SYMBOL(__stack_chk_fail);
16454cff
MT
50987diff -urNp linux-2.6.38.1/kernel/pid.c linux-2.6.38.1/kernel/pid.c
50988--- linux-2.6.38.1/kernel/pid.c 2011-03-14 21:20:32.000000000 -0400
50989+++ linux-2.6.38.1/kernel/pid.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
50990@@ -33,6 +33,7 @@
50991 #include <linux/rculist.h>
50992 #include <linux/bootmem.h>
50993 #include <linux/hash.h>
50994+#include <linux/security.h>
50995 #include <linux/pid_namespace.h>
50996 #include <linux/init_task.h>
50997 #include <linux/syscalls.h>
50998@@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
50999
51000 int pid_max = PID_MAX_DEFAULT;
51001
51002-#define RESERVED_PIDS 300
51003+#define RESERVED_PIDS 500
51004
51005 int pid_max_min = RESERVED_PIDS + 1;
51006 int pid_max_max = PID_MAX_LIMIT;
bc901d79 51007@@ -416,8 +417,15 @@ EXPORT_SYMBOL(pid_task);
58c5fc13
MT
51008 */
51009 struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
51010 {
58c5fc13 51011+ struct task_struct *task;
bc901d79
MT
51012+
51013 rcu_lockdep_assert(rcu_read_lock_held());
51014- return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
58c5fc13
MT
51015+ task = pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
51016+
51017+ if (gr_pid_is_chrooted(task))
51018+ return NULL;
51019+
51020+ return task;
51021 }
51022
51023 struct task_struct *find_task_by_vpid(pid_t vnr)
16454cff
MT
51024diff -urNp linux-2.6.38.1/kernel/posix-cpu-timers.c linux-2.6.38.1/kernel/posix-cpu-timers.c
51025--- linux-2.6.38.1/kernel/posix-cpu-timers.c 2011-03-14 21:20:32.000000000 -0400
51026+++ linux-2.6.38.1/kernel/posix-cpu-timers.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
51027@@ -6,6 +6,7 @@
51028 #include <linux/posix-timers.h>
51029 #include <linux/errno.h>
51030 #include <linux/math64.h>
51031+#include <linux/security.h>
51032 #include <asm/uaccess.h>
51033 #include <linux/kernel_stat.h>
ae4e228f 51034 #include <trace/events/timer.h>
16454cff
MT
51035diff -urNp linux-2.6.38.1/kernel/posix-timers.c linux-2.6.38.1/kernel/posix-timers.c
51036--- linux-2.6.38.1/kernel/posix-timers.c 2011-03-14 21:20:32.000000000 -0400
51037+++ linux-2.6.38.1/kernel/posix-timers.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
51038@@ -42,6 +42,7 @@
51039 #include <linux/compiler.h>
51040 #include <linux/idr.h>
51041 #include <linux/posix-timers.h>
51042+#include <linux/grsecurity.h>
51043 #include <linux/syscalls.h>
51044 #include <linux/wait.h>
51045 #include <linux/workqueue.h>
16454cff 51046@@ -955,6 +956,13 @@ SYSCALL_DEFINE2(clock_settime, const clo
bc901d79
MT
51047 if (copy_from_user(&new_tp, tp, sizeof (*tp)))
51048 return -EFAULT;
df50ba0c 51049
bc901d79
MT
51050+ /* only the CLOCK_REALTIME clock can be set, all other clocks
51051+ have their clock_set fptr set to a nosettime dummy function
51052+ CLOCK_REALTIME has a NULL clock_set fptr which causes it to
51053+ call common_clock_set, which calls do_sys_settimeofday, which
51054+ we hook
51055+ */
51056+
51057 return CLOCK_DISPATCH(which_clock, clock_set, (which_clock, &new_tp));
51058 }
51059
16454cff
MT
51060diff -urNp linux-2.6.38.1/kernel/power/poweroff.c linux-2.6.38.1/kernel/power/poweroff.c
51061--- linux-2.6.38.1/kernel/power/poweroff.c 2011-03-14 21:20:32.000000000 -0400
51062+++ linux-2.6.38.1/kernel/power/poweroff.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
51063@@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
51064 .enable_mask = SYSRQ_ENABLE_BOOT,
51065 };
51066
51067-static int pm_sysrq_init(void)
51068+static int __init pm_sysrq_init(void)
51069 {
51070 register_sysrq_key('o', &sysrq_poweroff_op);
51071 return 0;
16454cff
MT
51072diff -urNp linux-2.6.38.1/kernel/power/process.c linux-2.6.38.1/kernel/power/process.c
51073--- linux-2.6.38.1/kernel/power/process.c 2011-03-14 21:20:32.000000000 -0400
51074+++ linux-2.6.38.1/kernel/power/process.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 51075@@ -41,6 +41,7 @@ static int try_to_freeze_tasks(bool sig_
58c5fc13
MT
51076 u64 elapsed_csecs64;
51077 unsigned int elapsed_csecs;
bc901d79 51078 bool wakeup = false;
58c5fc13
MT
51079+ bool timedout = false;
51080
51081 do_gettimeofday(&start);
51082
bc901d79 51083@@ -51,6 +52,8 @@ static int try_to_freeze_tasks(bool sig_
6892158b 51084
ae4e228f 51085 while (true) {
58c5fc13
MT
51086 todo = 0;
51087+ if (time_after(jiffies, end_time))
51088+ timedout = true;
51089 read_lock(&tasklist_lock);
51090 do_each_thread(g, p) {
16454cff
MT
51091 if (frozen(p) || !freezable(p))
51092@@ -71,9 +74,13 @@ static int try_to_freeze_tasks(bool sig_
51093 * try_to_stop() after schedule() in ptrace/signal
51094 * stop sees TIF_FREEZE.
58c5fc13
MT
51095 */
51096- if (!task_is_stopped_or_traced(p) &&
51097- !freezer_should_skip(p))
51098+ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) {
51099 todo++;
51100+ if (timedout) {
51101+ printk(KERN_ERR "Task refusing to freeze:\n");
51102+ sched_show_task(p);
51103+ }
51104+ }
51105 } while_each_thread(g, p);
51106 read_unlock(&tasklist_lock);
6892158b 51107
16454cff 51108@@ -82,7 +89,7 @@ static int try_to_freeze_tasks(bool sig_
6892158b
MT
51109 todo += wq_busy;
51110 }
51111
ae4e228f
MT
51112- if (!todo || time_after(jiffies, end_time))
51113+ if (!todo || timedout)
51114 break;
51115
16454cff
MT
51116 if (pm_wakeup_pending()) {
51117diff -urNp linux-2.6.38.1/kernel/printk.c linux-2.6.38.1/kernel/printk.c
51118--- linux-2.6.38.1/kernel/printk.c 2011-03-14 21:20:32.000000000 -0400
51119+++ linux-2.6.38.1/kernel/printk.c 2011-03-23 22:30:08.000000000 -0400
51120@@ -279,12 +279,17 @@ static int check_syslog_permissions(int
51121 if (from_file && type != SYSLOG_ACTION_OPEN)
51122 return 0;
58c5fc13
MT
51123
51124+#ifdef CONFIG_GRKERNSEC_DMESG
16454cff 51125+ if (grsec_enable_dmesg && !capable(CAP_SYSLOG) && !capable_nolog(CAP_SYS_ADMIN))
58c5fc13
MT
51126+ return -EPERM;
51127+#endif
51128+
16454cff
MT
51129 if (syslog_action_restricted(type)) {
51130 if (capable(CAP_SYSLOG))
51131 return 0;
51132 /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
51133 if (capable(CAP_SYS_ADMIN)) {
51134- WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
51135+ printk_once(KERN_WARNING "Attempt to access syslog with CAP_SYS_ADMIN "
51136 "but no CAP_SYSLOG (deprecated).\n");
51137 return 0;
51138 }
51139diff -urNp linux-2.6.38.1/kernel/ptrace.c linux-2.6.38.1/kernel/ptrace.c
51140--- linux-2.6.38.1/kernel/ptrace.c 2011-03-14 21:20:32.000000000 -0400
51141+++ linux-2.6.38.1/kernel/ptrace.c 2011-03-26 11:42:34.000000000 -0400
51142@@ -116,7 +116,8 @@ int ptrace_check_attach(struct task_stru
51143 return ret;
51144 }
51145
51146-int __ptrace_may_access(struct task_struct *task, unsigned int mode)
51147+static int __ptrace_may_access(struct task_struct *task, unsigned int mode,
51148+ unsigned int log)
51149 {
51150 const struct cred *cred = current_cred(), *tcred;
51151
51152@@ -140,7 +141,9 @@ int __ptrace_may_access(struct task_stru
58c5fc13
MT
51153 cred->gid != tcred->egid ||
51154 cred->gid != tcred->sgid ||
51155 cred->gid != tcred->gid) &&
51156- !capable(CAP_SYS_PTRACE)) {
16454cff
MT
51157+ ((!log && !capable_nolog(CAP_SYS_PTRACE)) ||
51158+ (log && !capable(CAP_SYS_PTRACE)))
51159+ ) {
58c5fc13
MT
51160 rcu_read_unlock();
51161 return -EPERM;
51162 }
16454cff 51163@@ -148,7 +151,9 @@ int __ptrace_may_access(struct task_stru
58c5fc13
MT
51164 smp_rmb();
51165 if (task->mm)
51166 dumpable = get_dumpable(task->mm);
51167- if (!dumpable && !capable(CAP_SYS_PTRACE))
16454cff
MT
51168+ if (!dumpable &&
51169+ ((!log && !capable_nolog(CAP_SYS_PTRACE)) ||
51170+ (log && !capable(CAP_SYS_PTRACE))))
58c5fc13
MT
51171 return -EPERM;
51172
ae4e228f 51173 return security_ptrace_access_check(task, mode);
16454cff
MT
51174@@ -158,7 +163,16 @@ bool ptrace_may_access(struct task_struc
51175 {
51176 int err;
51177 task_lock(task);
51178- err = __ptrace_may_access(task, mode);
51179+ err = __ptrace_may_access(task, mode, 0);
51180+ task_unlock(task);
51181+ return !err;
51182+}
51183+
51184+bool ptrace_may_access_log(struct task_struct *task, unsigned int mode)
51185+{
51186+ int err;
51187+ task_lock(task);
51188+ err = __ptrace_may_access(task, mode, 1);
51189 task_unlock(task);
51190 return !err;
51191 }
51192@@ -185,7 +199,7 @@ static int ptrace_attach(struct task_str
51193 goto out;
51194
51195 task_lock(task);
51196- retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
51197+ retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH, 1);
51198 task_unlock(task);
51199 if (retval)
51200 goto unlock_creds;
51201@@ -198,7 +212,7 @@ static int ptrace_attach(struct task_str
58c5fc13
MT
51202 goto unlock_tasklist;
51203
51204 task->ptrace = PT_PTRACED;
51205- if (capable(CAP_SYS_PTRACE))
51206+ if (capable_nolog(CAP_SYS_PTRACE))
51207 task->ptrace |= PT_PTRACE_CAP;
51208
51209 __ptrace_link(task, current);
16454cff 51210@@ -369,7 +383,7 @@ int ptrace_readdata(struct task_struct *
ae4e228f
MT
51211 break;
51212 return -EIO;
51213 }
51214- if (copy_to_user(dst, buf, retval))
51215+ if (retval > sizeof(buf) || copy_to_user(dst, buf, retval))
51216 return -EFAULT;
51217 copied += retval;
51218 src += retval;
16454cff 51219@@ -565,7 +579,7 @@ int ptrace_request(struct task_struct *c
bc901d79
MT
51220 {
51221 int ret = -EIO;
51222 siginfo_t siginfo;
51223- void __user *datavp = (void __user *) data;
51224+ void __user *datavp = (__force void __user *) data;
51225 unsigned long __user *datalp = datavp;
ae4e228f 51226
bc901d79 51227 switch (request) {
16454cff 51228@@ -713,14 +727,21 @@ SYSCALL_DEFINE4(ptrace, long, request, l
ae4e228f
MT
51229 goto out;
51230 }
58c5fc13
MT
51231
51232+ if (gr_handle_ptrace(child, request)) {
51233+ ret = -EPERM;
51234+ goto out_put_task_struct;
51235+ }
51236+
ae4e228f
MT
51237 if (request == PTRACE_ATTACH) {
51238 ret = ptrace_attach(child);
51239 /*
51240 * Some architectures need to do book-keeping after
51241 * a ptrace attach.
51242 */
51243- if (!ret)
51244+ if (!ret) {
51245 arch_ptrace_attach(child);
51246+ gr_audit_ptrace(child);
51247+ }
51248 goto out_put_task_struct;
51249 }
58c5fc13 51250
16454cff 51251@@ -745,7 +766,7 @@ int generic_ptrace_peekdata(struct task_
ae4e228f
MT
51252 copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
51253 if (copied != sizeof(tmp))
51254 return -EIO;
51255- return put_user(tmp, (unsigned long __user *)data);
51256+ return put_user(tmp, (__force unsigned long __user *)data);
58c5fc13
MT
51257 }
51258
bc901d79 51259 int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
16454cff 51260@@ -855,14 +876,21 @@ asmlinkage long compat_sys_ptrace(compat
bc901d79
MT
51261 goto out;
51262 }
51263
51264+ if (gr_handle_ptrace(child, request)) {
51265+ ret = -EPERM;
51266+ goto out_put_task_struct;
51267+ }
51268+
51269 if (request == PTRACE_ATTACH) {
51270 ret = ptrace_attach(child);
51271 /*
51272 * Some architectures need to do book-keeping after
51273 * a ptrace attach.
51274 */
51275- if (!ret)
51276+ if (!ret) {
51277 arch_ptrace_attach(child);
51278+ gr_audit_ptrace(child);
51279+ }
51280 goto out_put_task_struct;
51281 }
51282
16454cff
MT
51283diff -urNp linux-2.6.38.1/kernel/rcutree.c linux-2.6.38.1/kernel/rcutree.c
51284--- linux-2.6.38.1/kernel/rcutree.c 2011-03-14 21:20:32.000000000 -0400
51285+++ linux-2.6.38.1/kernel/rcutree.c 2011-03-21 18:31:35.000000000 -0400
51286@@ -1389,7 +1389,7 @@ __rcu_process_callbacks(struct rcu_state
58c5fc13 51287 /*
ae4e228f 51288 * Do softirq processing for the current CPU.
58c5fc13 51289 */
ae4e228f
MT
51290-static void rcu_process_callbacks(struct softirq_action *unused)
51291+static void rcu_process_callbacks(void)
51292 {
51293 /*
51294 * Memory references from any prior RCU read-side critical sections
16454cff
MT
51295diff -urNp linux-2.6.38.1/kernel/rcutree_plugin.h linux-2.6.38.1/kernel/rcutree_plugin.h
51296--- linux-2.6.38.1/kernel/rcutree_plugin.h 2011-03-14 21:20:32.000000000 -0400
51297+++ linux-2.6.38.1/kernel/rcutree_plugin.h 2011-03-21 18:31:35.000000000 -0400
51298@@ -730,7 +730,7 @@ void synchronize_rcu_expedited(void)
bc901d79
MT
51299
51300 /* Clean up and exit. */
51301 smp_mb(); /* ensure expedited GP seen before counter increment. */
51302- ACCESS_ONCE(sync_rcu_preempt_exp_count)++;
51303+ ACCESS_ONCE_RW(sync_rcu_preempt_exp_count)++;
51304 unlock_mb_ret:
51305 mutex_unlock(&sync_rcu_preempt_exp_mutex);
51306 mb_ret:
16454cff
MT
51307diff -urNp linux-2.6.38.1/kernel/resource.c linux-2.6.38.1/kernel/resource.c
51308--- linux-2.6.38.1/kernel/resource.c 2011-03-14 21:20:32.000000000 -0400
51309+++ linux-2.6.38.1/kernel/resource.c 2011-03-21 18:31:35.000000000 -0400
57199397 51310@@ -133,8 +133,18 @@ static const struct file_operations proc
58c5fc13
MT
51311
51312 static int __init ioresources_init(void)
51313 {
51314+#ifdef CONFIG_GRKERNSEC_PROC_ADD
51315+#ifdef CONFIG_GRKERNSEC_PROC_USER
51316+ proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
51317+ proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
51318+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
51319+ proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
51320+ proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
51321+#endif
51322+#else
51323 proc_create("ioports", 0, NULL, &proc_ioports_operations);
51324 proc_create("iomem", 0, NULL, &proc_iomem_operations);
51325+#endif
51326 return 0;
51327 }
51328 __initcall(ioresources_init);
16454cff
MT
51329diff -urNp linux-2.6.38.1/kernel/rtmutex.c linux-2.6.38.1/kernel/rtmutex.c
51330--- linux-2.6.38.1/kernel/rtmutex.c 2011-03-14 21:20:32.000000000 -0400
51331+++ linux-2.6.38.1/kernel/rtmutex.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
51332@@ -511,7 +511,7 @@ static void wakeup_next_waiter(struct rt
51333 */
51334 raw_spin_lock_irqsave(&pendowner->pi_lock, flags);
51335
51336- WARN_ON(!pendowner->pi_blocked_on);
51337+ BUG_ON(!pendowner->pi_blocked_on);
51338 WARN_ON(pendowner->pi_blocked_on != waiter);
51339 WARN_ON(pendowner->pi_blocked_on->lock != lock);
51340
16454cff
MT
51341diff -urNp linux-2.6.38.1/kernel/sched.c linux-2.6.38.1/kernel/sched.c
51342--- linux-2.6.38.1/kernel/sched.c 2011-03-23 17:20:08.000000000 -0400
51343+++ linux-2.6.38.1/kernel/sched.c 2011-03-23 17:21:51.000000000 -0400
51344@@ -4638,6 +4638,8 @@ int can_nice(const struct task_struct *p
58c5fc13
MT
51345 /* convert nice value [19,-20] to rlimit style value [1,40] */
51346 int nice_rlim = 20 - nice;
51347
51348+ gr_learn_resource(p, RLIMIT_NICE, nice_rlim, 1);
51349+
df50ba0c 51350 return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
58c5fc13
MT
51351 capable(CAP_SYS_NICE));
51352 }
16454cff 51353@@ -4671,7 +4673,8 @@ SYSCALL_DEFINE1(nice, int, increment)
58c5fc13
MT
51354 if (nice > 19)
51355 nice = 19;
51356
51357- if (increment < 0 && !can_nice(current, nice))
51358+ if (increment < 0 && (!can_nice(current, nice) ||
51359+ gr_handle_chroot_nice()))
51360 return -EPERM;
51361
51362 retval = security_task_setnice(current, nice);
16454cff 51363@@ -4814,6 +4817,7 @@ recheck:
6892158b
MT
51364 unsigned long rlim_rtprio =
51365 task_rlimit(p, RLIMIT_RTPRIO);
58c5fc13 51366
6892158b 51367+ gr_learn_resource(p, RLIMIT_RTPRIO, param->sched_priority, 1);
df50ba0c
MT
51368 /* can't set/change the rt policy */
51369 if (policy != p->policy && !rlim_rtprio)
51370 return -EPERM;
16454cff 51371@@ -6942,7 +6946,7 @@ static void init_sched_groups_power(int
6892158b
MT
51372 long power;
51373 int weight;
51374
51375- WARN_ON(!sd || !sd->groups);
51376+ BUG_ON(!sd || !sd->groups);
51377
51378 if (cpu != group_first_cpu(sd->groups))
51379 return;
16454cff
MT
51380diff -urNp linux-2.6.38.1/kernel/sched_fair.c linux-2.6.38.1/kernel/sched_fair.c
51381--- linux-2.6.38.1/kernel/sched_fair.c 2011-03-14 21:20:32.000000000 -0400
51382+++ linux-2.6.38.1/kernel/sched_fair.c 2011-03-21 18:31:35.000000000 -0400
51383@@ -3960,7 +3960,7 @@ static void nohz_idle_balance(int this_c
6892158b
MT
51384 * run_rebalance_domains is triggered when needed from the scheduler tick.
51385 * Also triggered for nohz idle balancing (with nohz_balancing_kick set).
df50ba0c
MT
51386 */
51387-static void run_rebalance_domains(struct softirq_action *h)
51388+static void run_rebalance_domains(void)
51389 {
51390 int this_cpu = smp_processor_id();
51391 struct rq *this_rq = cpu_rq(this_cpu);
16454cff
MT
51392diff -urNp linux-2.6.38.1/kernel/signal.c linux-2.6.38.1/kernel/signal.c
51393--- linux-2.6.38.1/kernel/signal.c 2011-03-14 21:20:32.000000000 -0400
51394+++ linux-2.6.38.1/kernel/signal.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
51395@@ -45,12 +45,12 @@ static struct kmem_cache *sigqueue_cache
51396
51397 int print_fatal_signals __read_mostly;
51398
51399-static void __user *sig_handler(struct task_struct *t, int sig)
51400+static __sighandler_t sig_handler(struct task_struct *t, int sig)
51401 {
51402 return t->sighand->action[sig - 1].sa.sa_handler;
51403 }
51404
51405-static int sig_handler_ignored(void __user *handler, int sig)
51406+static int sig_handler_ignored(__sighandler_t handler, int sig)
51407 {
51408 /* Is it explicitly or implicitly ignored? */
51409 return handler == SIG_IGN ||
51410@@ -60,7 +60,7 @@ static int sig_handler_ignored(void __us
51411 static int sig_task_ignored(struct task_struct *t, int sig,
51412 int from_ancestor_ns)
51413 {
51414- void __user *handler;
51415+ __sighandler_t handler;
51416
51417 handler = sig_handler(t, sig);
51418
51419@@ -243,6 +243,9 @@ __sigqueue_alloc(int sig, struct task_st
58c5fc13 51420 atomic_inc(&user->sigpending);
ae4e228f
MT
51421 rcu_read_unlock();
51422
58c5fc13
MT
51423+ if (!override_rlimit)
51424+ gr_learn_resource(t, RLIMIT_SIGPENDING, atomic_read(&user->sigpending), 1);
ae4e228f 51425+
58c5fc13
MT
51426 if (override_rlimit ||
51427 atomic_read(&user->sigpending) <=
df50ba0c
MT
51428 task_rlimit(t, RLIMIT_SIGPENDING)) {
51429@@ -367,7 +370,7 @@ flush_signal_handlers(struct task_struct
51430
51431 int unhandled_signal(struct task_struct *tsk, int sig)
51432 {
51433- void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler;
51434+ __sighandler_t handler = tsk->sighand->action[sig-1].sa.sa_handler;
51435 if (is_global_init(tsk))
51436 return 1;
51437 if (handler != SIG_IGN && handler != SIG_DFL)
efbe55a5 51438@@ -678,6 +681,9 @@ static int check_kill_permission(int sig
58c5fc13
MT
51439 }
51440 }
51441
51442+ if (gr_handle_signal(t, sig))
51443+ return -EPERM;
51444+
51445 return security_task_kill(t, info, sig, 0);
51446 }
51447
efbe55a5 51448@@ -1025,7 +1031,7 @@ __group_send_sig_info(int sig, struct si
58c5fc13
MT
51449 return send_signal(sig, info, p, 1);
51450 }
51451
51452-static int
51453+int
51454 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
51455 {
51456 return send_signal(sig, info, t, 0);
c52201e0
MT
51457@@ -1062,6 +1068,7 @@ force_sig_info(int sig, struct siginfo *
51458 unsigned long int flags;
51459 int ret, blocked, ignored;
51460 struct k_sigaction *action;
51461+ int is_unhandled = 0;
51462
51463 spin_lock_irqsave(&t->sighand->siglock, flags);
51464 action = &t->sighand->action[sig-1];
51465@@ -1076,9 +1083,18 @@ force_sig_info(int sig, struct siginfo *
51466 }
51467 if (action->sa.sa_handler == SIG_DFL)
51468 t->signal->flags &= ~SIGNAL_UNKILLABLE;
51469+ if (action->sa.sa_handler == SIG_IGN || action->sa.sa_handler == SIG_DFL)
51470+ is_unhandled = 1;
58c5fc13
MT
51471 ret = specific_send_sig_info(sig, info, t);
51472 spin_unlock_irqrestore(&t->sighand->siglock, flags);
51473
c52201e0
MT
51474+ /* only deal with unhandled signals, java etc trigger SIGSEGV during
51475+ normal operation */
51476+ if (is_unhandled) {
51477+ gr_log_signal(sig, !is_si_special(info) ? info->si_addr : NULL, t);
51478+ gr_handle_crash(t, sig);
51479+ }
58c5fc13
MT
51480+
51481 return ret;
51482 }
51483
c52201e0 51484@@ -1137,8 +1153,11 @@ int group_send_sig_info(int sig, struct
57199397
MT
51485 ret = check_kill_permission(sig, info, p);
51486 rcu_read_unlock();
ae4e228f
MT
51487
51488- if (!ret && sig)
51489+ if (!ret && sig) {
51490 ret = do_send_sig_info(sig, info, p, true);
58c5fc13
MT
51491+ if (!ret)
51492+ gr_log_signal(sig, !is_si_special(info) ? info->si_addr : NULL, p);
ae4e228f 51493+ }
58c5fc13
MT
51494
51495 return ret;
ae4e228f 51496 }
16454cff
MT
51497diff -urNp linux-2.6.38.1/kernel/smp.c linux-2.6.38.1/kernel/smp.c
51498--- linux-2.6.38.1/kernel/smp.c 2011-03-23 17:20:08.000000000 -0400
51499+++ linux-2.6.38.1/kernel/smp.c 2011-03-26 20:50:44.000000000 -0400
51500@@ -583,22 +583,22 @@ int smp_call_function(smp_call_func_t fu
ae4e228f
MT
51501 }
51502 EXPORT_SYMBOL(smp_call_function);
51503
51504-void ipi_call_lock(void)
51505+void ipi_call_lock(void) __acquires(call_function.lock)
51506 {
51507 raw_spin_lock(&call_function.lock);
51508 }
51509
51510-void ipi_call_unlock(void)
51511+void ipi_call_unlock(void) __releases(call_function.lock)
51512 {
51513 raw_spin_unlock(&call_function.lock);
51514 }
51515
51516-void ipi_call_lock_irq(void)
51517+void ipi_call_lock_irq(void) __acquires(call_function.lock)
51518 {
51519 raw_spin_lock_irq(&call_function.lock);
51520 }
51521
51522-void ipi_call_unlock_irq(void)
51523+void ipi_call_unlock_irq(void) __releases(call_function.lock)
51524 {
51525 raw_spin_unlock_irq(&call_function.lock);
51526 }
16454cff
MT
51527diff -urNp linux-2.6.38.1/kernel/softirq.c linux-2.6.38.1/kernel/softirq.c
51528--- linux-2.6.38.1/kernel/softirq.c 2011-03-14 21:20:32.000000000 -0400
51529+++ linux-2.6.38.1/kernel/softirq.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
51530@@ -56,7 +56,7 @@ static struct softirq_action softirq_vec
51531
51532 static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
51533
51534-char *softirq_to_name[NR_SOFTIRQS] = {
51535+const char * const softirq_to_name[NR_SOFTIRQS] = {
51536 "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
51537 "TASKLET", "SCHED", "HRTIMER", "RCU"
51538 };
bc901d79 51539@@ -206,7 +206,7 @@ EXPORT_SYMBOL(local_bh_enable_ip);
ae4e228f
MT
51540
51541 asmlinkage void __do_softirq(void)
51542 {
51543- struct softirq_action *h;
51544+ const struct softirq_action *h;
51545 __u32 pending;
51546 int max_restart = MAX_SOFTIRQ_RESTART;
51547 int cpu;
bc901d79
MT
51548@@ -235,7 +235,7 @@ restart:
51549 kstat_incr_softirqs_this_cpu(vec_nr);
ae4e228f 51550
bc901d79 51551 trace_softirq_entry(vec_nr);
ae4e228f
MT
51552- h->action(h);
51553+ h->action();
bc901d79 51554 trace_softirq_exit(vec_nr);
ae4e228f 51555 if (unlikely(prev_count != preempt_count())) {
bc901d79
MT
51556 printk(KERN_ERR "huh, entered softirq %u %s %p"
51557@@ -365,7 +365,7 @@ void raise_softirq(unsigned int nr)
ae4e228f
MT
51558 local_irq_restore(flags);
51559 }
51560
51561-void open_softirq(int nr, void (*action)(struct softirq_action *))
51562+void open_softirq(int nr, void (*action)(void))
51563 {
51564 softirq_vec[nr].action = action;
51565 }
bc901d79 51566@@ -421,7 +421,7 @@ void __tasklet_hi_schedule_first(struct
ae4e228f
MT
51567
51568 EXPORT_SYMBOL(__tasklet_hi_schedule_first);
51569
51570-static void tasklet_action(struct softirq_action *a)
51571+static void tasklet_action(void)
51572 {
51573 struct tasklet_struct *list;
51574
bc901d79 51575@@ -456,7 +456,7 @@ static void tasklet_action(struct softir
ae4e228f
MT
51576 }
51577 }
51578
51579-static void tasklet_hi_action(struct softirq_action *a)
51580+static void tasklet_hi_action(void)
51581 {
51582 struct tasklet_struct *list;
51583
16454cff
MT
51584diff -urNp linux-2.6.38.1/kernel/sys.c linux-2.6.38.1/kernel/sys.c
51585--- linux-2.6.38.1/kernel/sys.c 2011-03-14 21:20:32.000000000 -0400
51586+++ linux-2.6.38.1/kernel/sys.c 2011-03-21 18:31:35.000000000 -0400
51587@@ -136,6 +136,12 @@ static int set_one_prio(struct task_stru
58c5fc13
MT
51588 error = -EACCES;
51589 goto out;
51590 }
51591+
51592+ if (gr_handle_chroot_setpriority(p, niceval)) {
51593+ error = -EACCES;
51594+ goto out;
51595+ }
51596+
51597 no_nice = security_task_setnice(p, niceval);
51598 if (no_nice) {
51599 error = no_nice;
16454cff 51600@@ -517,6 +523,9 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g
58c5fc13
MT
51601 goto error;
51602 }
51603
51604+ if (gr_check_group_change(new->gid, new->egid, -1))
51605+ goto error;
51606+
51607 if (rgid != (gid_t) -1 ||
51608 (egid != (gid_t) -1 && egid != old->gid))
51609 new->sgid = new->egid;
16454cff 51610@@ -546,6 +555,10 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
57199397 51611 old = current_cred();
58c5fc13
MT
51612
51613 retval = -EPERM;
51614+
51615+ if (gr_check_group_change(gid, gid, gid))
51616+ goto error;
51617+
51618 if (capable(CAP_SETGID))
51619 new->gid = new->egid = new->sgid = new->fsgid = gid;
51620 else if (gid == old->gid || gid == old->sgid)
16454cff 51621@@ -626,6 +639,9 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, u
58c5fc13
MT
51622 goto error;
51623 }
51624
51625+ if (gr_check_user_change(new->uid, new->euid, -1))
51626+ goto error;
51627+
51628 if (new->uid != old->uid) {
51629 retval = set_user(new);
51630 if (retval < 0)
16454cff 51631@@ -670,6 +686,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
57199397 51632 old = current_cred();
58c5fc13
MT
51633
51634 retval = -EPERM;
51635+
51636+ if (gr_check_crash_uid(uid))
51637+ goto error;
51638+ if (gr_check_user_change(uid, uid, uid))
51639+ goto error;
51640+
51641 if (capable(CAP_SETUID)) {
51642 new->suid = new->uid = uid;
51643 if (uid != old->uid) {
16454cff 51644@@ -724,6 +746,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid,
58c5fc13
MT
51645 goto error;
51646 }
51647
51648+ if (gr_check_user_change(ruid, euid, -1))
51649+ goto error;
51650+
51651 if (ruid != (uid_t) -1) {
51652 new->uid = ruid;
51653 if (ruid != old->uid) {
16454cff 51654@@ -788,6 +813,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid,
58c5fc13
MT
51655 goto error;
51656 }
51657
51658+ if (gr_check_group_change(rgid, egid, -1))
51659+ goto error;
51660+
51661 if (rgid != (gid_t) -1)
51662 new->gid = rgid;
51663 if (egid != (gid_t) -1)
16454cff 51664@@ -834,6 +862,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
57199397
MT
51665 old = current_cred();
51666 old_fsuid = old->fsuid;
58c5fc13
MT
51667
51668+ if (gr_check_user_change(-1, -1, uid))
51669+ goto error;
51670+
51671 if (uid == old->uid || uid == old->euid ||
51672 uid == old->suid || uid == old->fsuid ||
51673 capable(CAP_SETUID)) {
16454cff 51674@@ -844,6 +875,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
57199397
MT
51675 }
51676 }
51677
51678+error:
51679 abort_creds(new);
51680 return old_fsuid;
51681
16454cff 51682@@ -870,12 +902,16 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
58c5fc13
MT
51683 if (gid == old->gid || gid == old->egid ||
51684 gid == old->sgid || gid == old->fsgid ||
51685 capable(CAP_SETGID)) {
51686+ if (gr_check_group_change(-1, -1, gid))
51687+ goto error;
51688+
51689 if (gid != old_fsgid) {
51690 new->fsgid = gid;
51691 goto change_okay;
57199397
MT
51692 }
51693 }
51694
51695+error:
51696 abort_creds(new);
51697 return old_fsgid;
51698
16454cff 51699@@ -1616,7 +1652,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
58c5fc13
MT
51700 error = get_dumpable(me->mm);
51701 break;
51702 case PR_SET_DUMPABLE:
51703- if (arg2 < 0 || arg2 > 1) {
51704+ if (arg2 > 1) {
51705 error = -EINVAL;
51706 break;
51707 }
16454cff
MT
51708diff -urNp linux-2.6.38.1/kernel/sysctl.c linux-2.6.38.1/kernel/sysctl.c
51709--- linux-2.6.38.1/kernel/sysctl.c 2011-03-14 21:20:32.000000000 -0400
51710+++ linux-2.6.38.1/kernel/sysctl.c 2011-03-21 18:31:35.000000000 -0400
51711@@ -84,6 +84,13 @@
ae4e228f 51712
58c5fc13
MT
51713
51714 #if defined(CONFIG_SYSCTL)
51715+#include <linux/grsecurity.h>
51716+#include <linux/grinternal.h>
51717+
51718+extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
51719+extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
51720+ const int op);
51721+extern int gr_handle_chroot_sysctl(const int op);
51722
51723 /* External variables not in a header file. */
df50ba0c 51724 extern int sysctl_overcommit_memory;
16454cff 51725@@ -190,6 +197,7 @@ static int sysrq_sysctl_handler(ctl_tabl
57199397
MT
51726 }
51727
58c5fc13 51728 #endif
57199397 51729+extern struct ctl_table grsecurity_table[];
58c5fc13
MT
51730
51731 static struct ctl_table root_table[];
51732 static struct ctl_table_root sysctl_table_root;
16454cff 51733@@ -219,6 +227,20 @@ extern struct ctl_table epoll_table[];
58c5fc13
MT
51734 int sysctl_legacy_va_layout;
51735 #endif
51736
51737+#ifdef CONFIG_PAX_SOFTMODE
51738+static ctl_table pax_table[] = {
51739+ {
58c5fc13
MT
51740+ .procname = "softmode",
51741+ .data = &pax_softmode,
51742+ .maxlen = sizeof(unsigned int),
51743+ .mode = 0600,
51744+ .proc_handler = &proc_dointvec,
51745+ },
51746+
ae4e228f 51747+ { }
58c5fc13
MT
51748+};
51749+#endif
51750+
df50ba0c 51751 /* The default sysctl tables: */
58c5fc13 51752
df50ba0c 51753 static struct ctl_table root_table[] = {
16454cff 51754@@ -265,6 +287,22 @@ static int max_extfrag_threshold = 1000;
58c5fc13
MT
51755 #endif
51756
51757 static struct ctl_table kern_table[] = {
ae4e228f 51758+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_ROFS)
58c5fc13 51759+ {
58c5fc13
MT
51760+ .procname = "grsecurity",
51761+ .mode = 0500,
51762+ .child = grsecurity_table,
51763+ },
51764+#endif
51765+
51766+#ifdef CONFIG_PAX_SOFTMODE
51767+ {
58c5fc13
MT
51768+ .procname = "pax",
51769+ .mode = 0500,
51770+ .child = pax_table,
51771+ },
51772+#endif
51773+
58c5fc13 51774 {
ae4e228f
MT
51775 .procname = "sched_child_runs_first",
51776 .data = &sysctl_sched_child_runs_first,
16454cff 51777@@ -546,7 +584,7 @@ static struct ctl_table kern_table[] = {
bc901d79
MT
51778 .data = &modprobe_path,
51779 .maxlen = KMOD_PATH_LEN,
51780 .mode = 0644,
51781- .proc_handler = proc_dostring,
51782+ .proc_handler = proc_dostring_modpriv,
51783 },
51784 {
51785 .procname = "modules_disabled",
16454cff
MT
51786@@ -708,16 +746,20 @@ static struct ctl_table kern_table[] = {
51787 .extra1 = &zero,
51788 .extra2 = &one,
51789 },
51790+#endif
51791 {
51792 .procname = "kptr_restrict",
51793 .data = &kptr_restrict,
51794 .maxlen = sizeof(int),
51795 .mode = 0644,
51796 .proc_handler = proc_dointvec_minmax,
51797+#ifdef CONFIG_GRKERNSEC_HIDESYM
51798+ .extra1 = &two,
51799+#else
51800 .extra1 = &zero,
51801+#endif
51802 .extra2 = &two,
51803 },
51804-#endif
51805 {
51806 .procname = "ngroups_max",
51807 .data = &ngroups_max,
51808@@ -1182,6 +1224,13 @@ static struct ctl_table vm_table[] = {
57199397
MT
51809 .proc_handler = proc_dointvec_minmax,
51810 .extra1 = &zero,
51811 },
51812+ {
51813+ .procname = "heap_stack_gap",
51814+ .data = &sysctl_heap_stack_gap,
51815+ .maxlen = sizeof(sysctl_heap_stack_gap),
51816+ .mode = 0644,
51817+ .proc_handler = proc_doulongvec_minmax,
51818+ },
51819 #else
51820 {
51821 .procname = "nr_trim_pages",
16454cff 51822@@ -1693,6 +1742,16 @@ int sysctl_perm(struct ctl_table_root *r
58c5fc13
MT
51823 int error;
51824 int mode;
51825
51826+ if (table->parent != NULL && table->parent->procname != NULL &&
51827+ table->procname != NULL &&
51828+ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
51829+ return -EACCES;
51830+ if (gr_handle_chroot_sysctl(op))
51831+ return -EACCES;
51832+ error = gr_handle_sysctl(table, op);
51833+ if (error)
51834+ return error;
58c5fc13
MT
51835+
51836 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
51837 if (error)
51838 return error;
16454cff 51839@@ -2100,6 +2159,16 @@ int proc_dostring(struct ctl_table *tabl
bc901d79
MT
51840 buffer, lenp, ppos);
51841 }
51842
51843+int proc_dostring_modpriv(struct ctl_table *table, int write,
51844+ void __user *buffer, size_t *lenp, loff_t *ppos)
51845+{
51846+ if (write && !capable(CAP_SYS_MODULE))
51847+ return -EPERM;
51848+
51849+ return _proc_do_string(table->data, table->maxlen, write,
51850+ buffer, lenp, ppos);
51851+}
51852+
51853 static size_t proc_skip_spaces(char **buf)
51854 {
51855 size_t ret;
16454cff 51856@@ -2205,6 +2274,8 @@ static int proc_put_long(void __user **b
57199397
MT
51857 len = strlen(tmp);
51858 if (len > *size)
51859 len = *size;
51860+ if (len > sizeof(tmp))
51861+ len = sizeof(tmp);
51862 if (copy_to_user(*buf, tmp, len))
51863 return -EFAULT;
51864 *size -= len;
16454cff 51865@@ -2510,8 +2581,11 @@ static int __do_proc_doulongvec_minmax(v
6892158b
MT
51866 *i = val;
51867 } else {
51868 val = convdiv * (*i) / convmul;
51869- if (!first)
51870+ if (!first) {
51871 err = proc_put_char(&buffer, &left, '\t');
51872+ if (err)
51873+ break;
51874+ }
51875 err = proc_put_long(&buffer, &left, val, false);
51876 if (err)
51877 break;
16454cff 51878@@ -2906,6 +2980,12 @@ int proc_dostring(struct ctl_table *tabl
bc901d79
MT
51879 return -ENOSYS;
51880 }
51881
51882+int proc_dostring_modpriv(struct ctl_table *table, int write,
51883+ void __user *buffer, size_t *lenp, loff_t *ppos)
51884+{
51885+ return -ENOSYS;
51886+}
51887+
51888 int proc_dointvec(struct ctl_table *table, int write,
51889 void __user *buffer, size_t *lenp, loff_t *ppos)
51890 {
16454cff 51891@@ -2962,6 +3042,7 @@ EXPORT_SYMBOL(proc_dointvec_minmax);
bc901d79
MT
51892 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
51893 EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
51894 EXPORT_SYMBOL(proc_dostring);
51895+EXPORT_SYMBOL(proc_dostring_modpriv);
51896 EXPORT_SYMBOL(proc_doulongvec_minmax);
51897 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
51898 EXPORT_SYMBOL(register_sysctl_table);
16454cff
MT
51899diff -urNp linux-2.6.38.1/kernel/sysctl_check.c linux-2.6.38.1/kernel/sysctl_check.c
51900--- linux-2.6.38.1/kernel/sysctl_check.c 2011-03-14 21:20:32.000000000 -0400
51901+++ linux-2.6.38.1/kernel/sysctl_check.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
51902@@ -131,6 +131,7 @@ int sysctl_check_table(struct nsproxy *n
51903 set_fail(&fail, table, "Directory with extra2");
51904 } else {
51905 if ((table->proc_handler == proc_dostring) ||
51906+ (table->proc_handler == proc_dostring_modpriv) ||
51907 (table->proc_handler == proc_dointvec) ||
51908 (table->proc_handler == proc_dointvec_minmax) ||
51909 (table->proc_handler == proc_dointvec_jiffies) ||
16454cff
MT
51910diff -urNp linux-2.6.38.1/kernel/taskstats.c linux-2.6.38.1/kernel/taskstats.c
51911--- linux-2.6.38.1/kernel/taskstats.c 2011-03-14 21:20:32.000000000 -0400
51912+++ linux-2.6.38.1/kernel/taskstats.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 51913@@ -27,9 +27,12 @@
58c5fc13
MT
51914 #include <linux/cgroup.h>
51915 #include <linux/fs.h>
51916 #include <linux/file.h>
51917+#include <linux/grsecurity.h>
51918 #include <net/genetlink.h>
51919 #include <asm/atomic.h>
51920
51921+extern int gr_is_taskstats_denied(int pid);
51922+
51923 /*
51924 * Maximum length of a cpumask that can be specified in
51925 * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute
16454cff 51926@@ -549,6 +552,9 @@ err:
58c5fc13 51927
bc901d79
MT
51928 static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
51929 {
58c5fc13
MT
51930+ if (gr_is_taskstats_denied(current->pid))
51931+ return -EACCES;
51932+
bc901d79
MT
51933 if (info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK])
51934 return cmd_attr_register_cpumask(info);
51935 else if (info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK])
16454cff
MT
51936diff -urNp linux-2.6.38.1/kernel/time/tick-broadcast.c linux-2.6.38.1/kernel/time/tick-broadcast.c
51937--- linux-2.6.38.1/kernel/time/tick-broadcast.c 2011-03-14 21:20:32.000000000 -0400
51938+++ linux-2.6.38.1/kernel/time/tick-broadcast.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
51939@@ -116,7 +116,7 @@ int tick_device_uses_broadcast(struct cl
51940 * then clear the broadcast bit.
51941 */
51942 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
51943- int cpu = smp_processor_id();
51944+ cpu = smp_processor_id();
51945
51946 cpumask_clear_cpu(cpu, tick_get_broadcast_mask());
51947 tick_broadcast_clear_oneshot(cpu);
16454cff
MT
51948diff -urNp linux-2.6.38.1/kernel/time/timekeeping.c linux-2.6.38.1/kernel/time/timekeeping.c
51949--- linux-2.6.38.1/kernel/time/timekeeping.c 2011-03-14 21:20:32.000000000 -0400
51950+++ linux-2.6.38.1/kernel/time/timekeeping.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
51951@@ -14,6 +14,7 @@
51952 #include <linux/init.h>
51953 #include <linux/mm.h>
51954 #include <linux/sched.h>
51955+#include <linux/grsecurity.h>
51956 #include <linux/sysdev.h>
51957 #include <linux/clocksource.h>
51958 #include <linux/jiffies.h>
16454cff 51959@@ -361,6 +362,8 @@ int do_settimeofday(struct timespec *tv)
bc901d79
MT
51960 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
51961 return -EINVAL;
51962
51963+ gr_log_timechange();
51964+
51965 write_seqlock_irqsave(&xtime_lock, flags);
51966
51967 timekeeping_forward_now();
16454cff
MT
51968diff -urNp linux-2.6.38.1/kernel/time/timer_list.c linux-2.6.38.1/kernel/time/timer_list.c
51969--- linux-2.6.38.1/kernel/time/timer_list.c 2011-03-14 21:20:32.000000000 -0400
51970+++ linux-2.6.38.1/kernel/time/timer_list.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
51971@@ -38,12 +38,16 @@ DECLARE_PER_CPU(struct hrtimer_cpu_base,
51972
51973 static void print_name_offset(struct seq_file *m, void *sym)
51974 {
51975+#ifdef CONFIG_GRKERNSEC_HIDESYM
51976+ SEQ_printf(m, "<%p>", NULL);
51977+#else
51978 char symname[KSYM_NAME_LEN];
51979
51980 if (lookup_symbol_name((unsigned long)sym, symname) < 0)
16454cff 51981 SEQ_printf(m, "<%pK>", sym);
57199397
MT
51982 else
51983 SEQ_printf(m, "%s", symname);
51984+#endif
51985 }
51986
51987 static void
51988@@ -112,7 +116,11 @@ next_one:
51989 static void
51990 print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
51991 {
51992+#ifdef CONFIG_GRKERNSEC_HIDESYM
51993+ SEQ_printf(m, " .base: %p\n", NULL);
51994+#else
16454cff 51995 SEQ_printf(m, " .base: %pK\n", base);
57199397
MT
51996+#endif
51997 SEQ_printf(m, " .index: %d\n",
51998 base->index);
51999 SEQ_printf(m, " .resolution: %Lu nsecs\n",
52000@@ -293,7 +301,11 @@ static int __init init_timer_list_procfs
52001 {
52002 struct proc_dir_entry *pe;
52003
52004+#ifdef CONFIG_GRKERNSEC_PROC_ADD
52005+ pe = proc_create("timer_list", 0400, NULL, &timer_list_fops);
52006+#else
52007 pe = proc_create("timer_list", 0444, NULL, &timer_list_fops);
52008+#endif
52009 if (!pe)
52010 return -ENOMEM;
52011 return 0;
16454cff
MT
52012diff -urNp linux-2.6.38.1/kernel/time/timer_stats.c linux-2.6.38.1/kernel/time/timer_stats.c
52013--- linux-2.6.38.1/kernel/time/timer_stats.c 2011-03-14 21:20:32.000000000 -0400
52014+++ linux-2.6.38.1/kernel/time/timer_stats.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
52015@@ -269,12 +269,16 @@ void timer_stats_update_stats(void *time
52016
52017 static void print_name_offset(struct seq_file *m, unsigned long addr)
52018 {
52019+#ifdef CONFIG_GRKERNSEC_HIDESYM
52020+ seq_printf(m, "<%p>", NULL);
52021+#else
52022 char symname[KSYM_NAME_LEN];
52023
52024 if (lookup_symbol_name(addr, symname) < 0)
52025 seq_printf(m, "<%p>", (void *)addr);
52026 else
52027 seq_printf(m, "%s", symname);
52028+#endif
52029 }
52030
52031 static int tstats_show(struct seq_file *m, void *v)
52032@@ -417,7 +421,11 @@ static int __init init_tstats_procfs(voi
52033 {
52034 struct proc_dir_entry *pe;
52035
52036+#ifdef CONFIG_GRKERNSEC_PROC_ADD
52037+ pe = proc_create("timer_stats", 0600, NULL, &tstats_fops);
52038+#else
52039 pe = proc_create("timer_stats", 0644, NULL, &tstats_fops);
52040+#endif
52041 if (!pe)
52042 return -ENOMEM;
52043 return 0;
16454cff
MT
52044diff -urNp linux-2.6.38.1/kernel/time.c linux-2.6.38.1/kernel/time.c
52045--- linux-2.6.38.1/kernel/time.c 2011-03-14 21:20:32.000000000 -0400
52046+++ linux-2.6.38.1/kernel/time.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
52047@@ -163,6 +163,11 @@ int do_sys_settimeofday(struct timespec
52048 return error;
58c5fc13 52049
bc901d79
MT
52050 if (tz) {
52051+ /* we log in do_settimeofday called below, so don't log twice
52052+ */
52053+ if (!tv)
52054+ gr_log_timechange();
58c5fc13 52055+
bc901d79
MT
52056 /* SMP safe, global irq locking makes it work. */
52057 sys_tz = *tz;
52058 update_vsyscall_tz();
16454cff
MT
52059diff -urNp linux-2.6.38.1/kernel/timer.c linux-2.6.38.1/kernel/timer.c
52060--- linux-2.6.38.1/kernel/timer.c 2011-03-14 21:20:32.000000000 -0400
52061+++ linux-2.6.38.1/kernel/timer.c 2011-03-21 18:31:35.000000000 -0400
52062@@ -1276,7 +1276,7 @@ void update_process_times(int user_tick)
ae4e228f
MT
52063 /*
52064 * This function runs timers and the timer-tq in bottom half context.
52065 */
52066-static void run_timer_softirq(struct softirq_action *h)
52067+static void run_timer_softirq(void)
52068 {
16454cff 52069 struct tvec_base *base = __this_cpu_read(tvec_bases);
58c5fc13 52070
16454cff
MT
52071diff -urNp linux-2.6.38.1/kernel/trace/ftrace.c linux-2.6.38.1/kernel/trace/ftrace.c
52072--- linux-2.6.38.1/kernel/trace/ftrace.c 2011-03-23 17:20:08.000000000 -0400
52073+++ linux-2.6.38.1/kernel/trace/ftrace.c 2011-03-23 17:21:51.000000000 -0400
bc901d79 52074@@ -1107,13 +1107,18 @@ ftrace_code_disable(struct module *mod,
ae4e228f
MT
52075
52076 ip = rec->ip;
52077
52078+ ret = ftrace_arch_code_modify_prepare();
52079+ FTRACE_WARN_ON(ret);
52080+ if (ret)
52081+ return 0;
52082+
52083 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
52084+ FTRACE_WARN_ON(ftrace_arch_code_modify_post_process());
52085 if (ret) {
52086 ftrace_bug(ret, ip);
52087 rec->flags |= FTRACE_FL_FAILED;
52088- return 0;
52089 }
52090- return 1;
52091+ return ret ? 0 : 1;
58c5fc13
MT
52092 }
52093
ae4e228f 52094 /*
16454cff
MT
52095diff -urNp linux-2.6.38.1/kernel/trace/ring_buffer.c linux-2.6.38.1/kernel/trace/ring_buffer.c
52096--- linux-2.6.38.1/kernel/trace/ring_buffer.c 2011-03-14 21:20:32.000000000 -0400
52097+++ linux-2.6.38.1/kernel/trace/ring_buffer.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 52098@@ -669,7 +669,7 @@ static struct list_head *rb_list_head(st
df50ba0c
MT
52099 * the reader page). But if the next page is a header page,
52100 * its flags will be non zero.
52101 */
52102-static int inline
52103+static inline int
52104 rb_is_head_page(struct ring_buffer_per_cpu *cpu_buffer,
52105 struct buffer_page *page, struct list_head *list)
52106 {
16454cff
MT
52107diff -urNp linux-2.6.38.1/kernel/trace/trace.c linux-2.6.38.1/kernel/trace/trace.c
52108--- linux-2.6.38.1/kernel/trace/trace.c 2011-03-14 21:20:32.000000000 -0400
52109+++ linux-2.6.38.1/kernel/trace/trace.c 2011-03-21 18:31:35.000000000 -0400
c52201e0 52110@@ -3967,10 +3967,9 @@ static const struct file_operations trac
ae4e228f
MT
52111 };
52112 #endif
58c5fc13 52113
ae4e228f
MT
52114-static struct dentry *d_tracer;
52115-
52116 struct dentry *tracing_init_dentry(void)
52117 {
52118+ static struct dentry *d_tracer;
52119 static int once;
52120
52121 if (d_tracer)
c52201e0 52122@@ -3990,10 +3989,9 @@ struct dentry *tracing_init_dentry(void)
ae4e228f 52123 return d_tracer;
58c5fc13
MT
52124 }
52125
ae4e228f
MT
52126-static struct dentry *d_percpu;
52127-
52128 struct dentry *tracing_dentry_percpu(void)
52129 {
52130+ static struct dentry *d_percpu;
52131 static int once;
52132 struct dentry *d_tracer;
52133
16454cff
MT
52134diff -urNp linux-2.6.38.1/kernel/trace/trace_events.c linux-2.6.38.1/kernel/trace/trace_events.c
52135--- linux-2.6.38.1/kernel/trace/trace_events.c 2011-03-14 21:20:32.000000000 -0400
52136+++ linux-2.6.38.1/kernel/trace/trace_events.c 2011-03-21 18:31:35.000000000 -0400
52137@@ -1240,10 +1240,10 @@ static LIST_HEAD(ftrace_module_file_list
bc901d79
MT
52138 struct ftrace_module_file_ops {
52139 struct list_head list;
52140 struct module *mod;
16454cff
MT
52141- struct file_operations id;
52142- struct file_operations enable;
52143- struct file_operations format;
52144- struct file_operations filter;
52145+ struct file_operations id; /* cannot be const, see trace_create_file_ops() */
52146+ struct file_operations enable; /* cannot be const, see trace_create_file_ops() */
52147+ struct file_operations format; /* cannot be const, see trace_create_file_ops() */
52148+ struct file_operations filter; /* cannot be const, see trace_create_file_ops() */
52149 };
52150
52151 static struct ftrace_module_file_ops *
52152diff -urNp linux-2.6.38.1/kernel/trace/trace_output.c linux-2.6.38.1/kernel/trace/trace_output.c
52153--- linux-2.6.38.1/kernel/trace/trace_output.c 2011-03-14 21:20:32.000000000 -0400
52154+++ linux-2.6.38.1/kernel/trace/trace_output.c 2011-03-21 18:31:35.000000000 -0400
6892158b 52155@@ -278,7 +278,7 @@ int trace_seq_path(struct trace_seq *s,
ae4e228f 52156
58c5fc13
MT
52157 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
52158 if (!IS_ERR(p)) {
52159- p = mangle_path(s->buffer + s->len, p, "\n");
52160+ p = mangle_path(s->buffer + s->len, p, "\n\\");
52161 if (p) {
52162 s->len = p - s->buffer;
52163 return 1;
16454cff
MT
52164diff -urNp linux-2.6.38.1/kernel/trace/trace_stack.c linux-2.6.38.1/kernel/trace/trace_stack.c
52165--- linux-2.6.38.1/kernel/trace/trace_stack.c 2011-03-14 21:20:32.000000000 -0400
52166+++ linux-2.6.38.1/kernel/trace/trace_stack.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
52167@@ -50,7 +50,7 @@ static inline void check_stack(void)
52168 return;
58c5fc13 52169
ae4e228f
MT
52170 /* we do not handle interrupt stacks yet */
52171- if (!object_is_on_stack(&this_size))
52172+ if (!object_starts_on_stack(&this_size))
52173 return;
52174
52175 local_irq_save(flags);
16454cff
MT
52176diff -urNp linux-2.6.38.1/lib/bug.c linux-2.6.38.1/lib/bug.c
52177--- linux-2.6.38.1/lib/bug.c 2011-03-14 21:20:32.000000000 -0400
52178+++ linux-2.6.38.1/lib/bug.c 2011-03-21 18:31:35.000000000 -0400
6892158b 52179@@ -133,6 +133,8 @@ enum bug_trap_type report_bug(unsigned l
ae4e228f
MT
52180 return BUG_TRAP_TYPE_NONE;
52181
52182 bug = find_bug(bugaddr);
52183+ if (!bug)
52184+ return BUG_TRAP_TYPE_NONE;
52185
6892158b
MT
52186 file = NULL;
52187 line = 0;
16454cff
MT
52188diff -urNp linux-2.6.38.1/lib/debugobjects.c linux-2.6.38.1/lib/debugobjects.c
52189--- linux-2.6.38.1/lib/debugobjects.c 2011-03-14 21:20:32.000000000 -0400
52190+++ linux-2.6.38.1/lib/debugobjects.c 2011-03-21 18:31:35.000000000 -0400
57199397 52191@@ -281,7 +281,7 @@ static void debug_object_is_on_stack(voi
ae4e228f
MT
52192 if (limit > 4)
52193 return;
52194
52195- is_on_stack = object_is_on_stack(addr);
52196+ is_on_stack = object_starts_on_stack(addr);
52197 if (is_on_stack == onstack)
52198 return;
52199
16454cff
MT
52200diff -urNp linux-2.6.38.1/lib/dma-debug.c linux-2.6.38.1/lib/dma-debug.c
52201--- linux-2.6.38.1/lib/dma-debug.c 2011-03-14 21:20:32.000000000 -0400
52202+++ linux-2.6.38.1/lib/dma-debug.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 52203@@ -862,7 +862,7 @@ out:
58c5fc13 52204
ae4e228f
MT
52205 static void check_for_stack(struct device *dev, void *addr)
52206 {
52207- if (object_is_on_stack(addr))
52208+ if (object_starts_on_stack(addr))
52209 err_printk(dev, NULL, "DMA-API: device driver maps memory from"
52210 "stack [addr=%p]\n", addr);
52211 }
16454cff
MT
52212diff -urNp linux-2.6.38.1/lib/inflate.c linux-2.6.38.1/lib/inflate.c
52213--- linux-2.6.38.1/lib/inflate.c 2011-03-14 21:20:32.000000000 -0400
52214+++ linux-2.6.38.1/lib/inflate.c 2011-03-21 18:31:35.000000000 -0400
6892158b 52215@@ -269,7 +269,7 @@ static void free(void *where)
58c5fc13
MT
52216 malloc_ptr = free_mem_ptr;
52217 }
52218 #else
52219-#define malloc(a) kmalloc(a, GFP_KERNEL)
52220+#define malloc(a) kmalloc((a), GFP_KERNEL)
52221 #define free(a) kfree(a)
52222 #endif
52223
16454cff
MT
52224diff -urNp linux-2.6.38.1/lib/Kconfig.debug linux-2.6.38.1/lib/Kconfig.debug
52225--- linux-2.6.38.1/lib/Kconfig.debug 2011-03-14 21:20:32.000000000 -0400
52226+++ linux-2.6.38.1/lib/Kconfig.debug 2011-03-21 18:31:35.000000000 -0400
52227@@ -1066,6 +1066,7 @@ config LATENCYTOP
6892158b
MT
52228 depends on DEBUG_KERNEL
52229 depends on STACKTRACE_SUPPORT
52230 depends on PROC_FS
52231+ depends on !GRKERNSEC_HIDESYM
52232 select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE
52233 select KALLSYMS
52234 select KALLSYMS_ALL
16454cff
MT
52235diff -urNp linux-2.6.38.1/lib/kref.c linux-2.6.38.1/lib/kref.c
52236--- linux-2.6.38.1/lib/kref.c 2011-03-14 21:20:32.000000000 -0400
52237+++ linux-2.6.38.1/lib/kref.c 2011-03-21 18:31:35.000000000 -0400
52238@@ -52,7 +52,7 @@ void kref_get(struct kref *kref)
6892158b
MT
52239 */
52240 int kref_put(struct kref *kref, void (*release)(struct kref *kref))
52241 {
52242- WARN_ON(release == NULL);
52243+ BUG_ON(release == NULL);
52244 WARN_ON(release == (void (*)(struct kref *))kfree);
52245
52246 if (atomic_dec_and_test(&kref->refcount)) {
16454cff
MT
52247diff -urNp linux-2.6.38.1/lib/radix-tree.c linux-2.6.38.1/lib/radix-tree.c
52248--- linux-2.6.38.1/lib/radix-tree.c 2011-03-14 21:20:32.000000000 -0400
52249+++ linux-2.6.38.1/lib/radix-tree.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 52250@@ -80,7 +80,7 @@ struct radix_tree_preload {
58c5fc13
MT
52251 int nr;
52252 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
52253 };
52254-static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
52255+static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
52256
bc901d79 52257 static inline void *ptr_to_indirect(void *ptr)
58c5fc13 52258 {
16454cff
MT
52259diff -urNp linux-2.6.38.1/lib/vsprintf.c linux-2.6.38.1/lib/vsprintf.c
52260--- linux-2.6.38.1/lib/vsprintf.c 2011-03-14 21:20:32.000000000 -0400
52261+++ linux-2.6.38.1/lib/vsprintf.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
52262@@ -16,6 +16,9 @@
52263 * - scnprintf and vscnprintf
52264 */
52265
52266+#ifdef CONFIG_GRKERNSEC_HIDESYM
52267+#define __INCLUDED_BY_HIDESYM 1
52268+#endif
52269 #include <stdarg.h>
52270 #include <linux/module.h>
52271 #include <linux/types.h>
52272@@ -574,7 +577,7 @@ char *symbol_string(char *buf, char *end
52273 unsigned long value = (unsigned long) ptr;
52274 #ifdef CONFIG_KALLSYMS
52275 char sym[KSYM_SYMBOL_LEN];
52276- if (ext != 'f' && ext != 's')
52277+ if (ext != 'f' && ext != 's' && ext != 'a')
52278 sprint_symbol(sym, value);
52279 else
52280 kallsyms_lookup(value, NULL, NULL, NULL, sym);
16454cff
MT
52281@@ -936,7 +939,11 @@ char *uuid_string(char *buf, char *end,
52282 return string(buf, end, uuid, spec);
52283 }
52284
52285+#ifdef CONFIG_GRKERNSEC_HIDESYM
52286+int kptr_restrict = 2;
52287+#else
52288 int kptr_restrict = 1;
52289+#endif
52290
52291 /*
52292 * Show a '%p' thing. A kernel extension is that the '%p' is followed
52293@@ -949,6 +956,8 @@ int kptr_restrict = 1;
bc901d79
MT
52294 * - 'f' For simple symbolic function names without offset
52295 * - 'S' For symbolic direct pointers with offset
52296 * - 's' For symbolic direct pointers without offset
52297+ * - 'A' For symbolic direct pointers with offset approved for use with GRKERNSEC_HIDESYM
52298+ * - 'a' For symbolic direct pointers without offset approved for use with GRKERNSEC_HIDESYM
52299 * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
52300 * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
52301 * - 'M' For a 6-byte MAC address, it prints the address in the
16454cff 52302@@ -993,12 +1002,12 @@ char *pointer(const char *fmt, char *buf
bc901d79
MT
52303 {
52304 if (!ptr) {
52305 /*
52306- * Print (null) with the same width as a pointer so it makes
52307+ * Print (nil) with the same width as a pointer so it makes
52308 * tabular output look nice.
52309 */
52310 if (spec.field_width == -1)
52311 spec.field_width = 2 * sizeof(void *);
6892158b
MT
52312- return string(buf, end, "(null)", spec);
52313+ return string(buf, end, "(nil)", spec);
bc901d79 52314 }
6892158b
MT
52315
52316 switch (*fmt) {
16454cff 52317@@ -1008,6 +1017,13 @@ char *pointer(const char *fmt, char *buf
bc901d79
MT
52318 /* Fallthrough */
52319 case 'S':
52320 case 's':
52321+#ifdef CONFIG_GRKERNSEC_HIDESYM
52322+ break;
52323+#else
52324+ return symbol_string(buf, end, ptr, spec, *fmt);
52325+#endif
52326+ case 'A':
52327+ case 'a':
52328 return symbol_string(buf, end, ptr, spec, *fmt);
52329 case 'R':
52330 case 'r':
16454cff 52331@@ -1772,11 +1788,11 @@ int bstr_printf(char *buf, size_t size,
bc901d79
MT
52332 typeof(type) value; \
52333 if (sizeof(type) == 8) { \
52334 args = PTR_ALIGN(args, sizeof(u32)); \
52335- *(u32 *)&value = *(u32 *)args; \
52336- *((u32 *)&value + 1) = *(u32 *)(args + 4); \
52337+ *(u32 *)&value = *(const u32 *)args; \
52338+ *((u32 *)&value + 1) = *(const u32 *)(args + 4); \
52339 } else { \
52340 args = PTR_ALIGN(args, sizeof(type)); \
52341- value = *(typeof(type) *)args; \
52342+ value = *(const typeof(type) *)args; \
52343 } \
52344 args += sizeof(type); \
52345 value; \
16454cff 52346@@ -1839,7 +1855,7 @@ int bstr_printf(char *buf, size_t size,
bc901d79
MT
52347 case FORMAT_TYPE_STR: {
52348 const char *str_arg = args;
52349 args += strlen(str_arg) + 1;
52350- str = string(str, end, (char *)str_arg, spec);
52351+ str = string(str, end, str_arg, spec);
52352 break;
52353 }
52354
16454cff
MT
52355diff -urNp linux-2.6.38.1/localversion-grsec linux-2.6.38.1/localversion-grsec
52356--- linux-2.6.38.1/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
52357+++ linux-2.6.38.1/localversion-grsec 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
52358@@ -0,0 +1 @@
52359+-grsec
16454cff
MT
52360diff -urNp linux-2.6.38.1/Makefile linux-2.6.38.1/Makefile
52361--- linux-2.6.38.1/Makefile 2011-03-23 17:20:06.000000000 -0400
52362+++ linux-2.6.38.1/Makefile 2011-03-23 17:21:43.000000000 -0400
52363@@ -233,8 +233,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
57199397
MT
52364
52365 HOSTCC = gcc
52366 HOSTCXX = g++
52367-HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
52368-HOSTCXXFLAGS = -O2
52369+HOSTCFLAGS = -Wall -W -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-delete-null-pointer-checks
52370+HOSTCXXFLAGS = -O2 -fno-delete-null-pointer-checks
52371
52372 # Decide whether to build built-in, modular, or both.
52373 # Normally, just do built-in.
16454cff 52374@@ -681,7 +681,7 @@ export mod_strip_cmd
57199397
MT
52375
52376
52377 ifeq ($(KBUILD_EXTMOD),)
52378-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
52379+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
52380
52381 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
52382 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
16454cff
MT
52383diff -urNp linux-2.6.38.1/mm/bootmem.c linux-2.6.38.1/mm/bootmem.c
52384--- linux-2.6.38.1/mm/bootmem.c 2011-03-14 21:20:32.000000000 -0400
52385+++ linux-2.6.38.1/mm/bootmem.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 52386@@ -201,19 +201,30 @@ static void __init __free_pages_memory(u
57199397
MT
52387 unsigned long __init free_all_memory_core_early(int nodeid)
52388 {
52389 int i;
52390- u64 start, end;
52391+ u64 start, end, startrange, endrange;
52392 unsigned long count = 0;
52393- struct range *range = NULL;
52394+ struct range *range = NULL, rangerange = { 0, 0 };
52395 int nr_range;
52396
52397 nr_range = get_free_all_memory_range(&range, nodeid);
52398+ startrange = __pa(range) >> PAGE_SHIFT;
52399+ endrange = (__pa(range + nr_range) - 1) >> PAGE_SHIFT;
52400
52401 for (i = 0; i < nr_range; i++) {
52402 start = range[i].start;
52403 end = range[i].end;
52404+ if (start <= endrange && startrange < end) {
52405+ BUG_ON(rangerange.start | rangerange.end);
52406+ rangerange = range[i];
52407+ continue;
52408+ }
52409 count += end - start;
52410 __free_pages_memory(start, end);
52411 }
52412+ start = rangerange.start;
52413+ end = rangerange.end;
52414+ count += end - start;
52415+ __free_pages_memory(start, end);
52416
52417 return count;
52418 }
16454cff
MT
52419diff -urNp linux-2.6.38.1/mm/filemap.c linux-2.6.38.1/mm/filemap.c
52420--- linux-2.6.38.1/mm/filemap.c 2011-03-14 21:20:32.000000000 -0400
52421+++ linux-2.6.38.1/mm/filemap.c 2011-03-21 18:31:35.000000000 -0400
52422@@ -1664,7 +1664,7 @@ int generic_file_mmap(struct file * file
58c5fc13
MT
52423 struct address_space *mapping = file->f_mapping;
52424
52425 if (!mapping->a_ops->readpage)
52426- return -ENOEXEC;
52427+ return -ENODEV;
52428 file_accessed(file);
52429 vma->vm_ops = &generic_file_vm_ops;
52430 vma->vm_flags |= VM_CAN_NONLINEAR;
16454cff 52431@@ -2060,6 +2060,7 @@ inline int generic_write_checks(struct f
58c5fc13
MT
52432 *pos = i_size_read(inode);
52433
52434 if (limit != RLIM_INFINITY) {
52435+ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
52436 if (*pos >= limit) {
52437 send_sig(SIGXFSZ, current, 0);
52438 return -EFBIG;
16454cff
MT
52439diff -urNp linux-2.6.38.1/mm/fremap.c linux-2.6.38.1/mm/fremap.c
52440--- linux-2.6.38.1/mm/fremap.c 2011-03-14 21:20:32.000000000 -0400
52441+++ linux-2.6.38.1/mm/fremap.c 2011-03-21 18:31:35.000000000 -0400
6892158b 52442@@ -156,6 +156,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
58c5fc13
MT
52443 retry:
52444 vma = find_vma(mm, start);
52445
52446+#ifdef CONFIG_PAX_SEGMEXEC
52447+ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC))
52448+ goto out;
52449+#endif
52450+
52451 /*
52452 * Make sure the vma is shared, that it supports prefaulting,
52453 * and that the remapped range is valid and fully within
6892158b 52454@@ -224,7 +229,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
57199397
MT
52455 /*
52456 * drop PG_Mlocked flag for over-mapped range
52457 */
52458- unsigned int saved_flags = vma->vm_flags;
52459+ unsigned long saved_flags = vma->vm_flags;
52460 munlock_vma_pages_range(vma, start, start + size);
52461 vma->vm_flags = saved_flags;
52462 }
16454cff
MT
52463diff -urNp linux-2.6.38.1/mm/highmem.c linux-2.6.38.1/mm/highmem.c
52464--- linux-2.6.38.1/mm/highmem.c 2011-03-14 21:20:32.000000000 -0400
52465+++ linux-2.6.38.1/mm/highmem.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 52466@@ -125,9 +125,10 @@ static void flush_all_zero_pkmaps(void)
58c5fc13
MT
52467 * So no dangers, even with speculative execution.
52468 */
52469 page = pte_page(pkmap_page_table[i]);
ae4e228f 52470+ pax_open_kernel();
58c5fc13
MT
52471 pte_clear(&init_mm, (unsigned long)page_address(page),
52472 &pkmap_page_table[i]);
ae4e228f
MT
52473-
52474+ pax_close_kernel();
58c5fc13
MT
52475 set_page_address(page, NULL);
52476 need_flush = 1;
52477 }
bc901d79 52478@@ -186,9 +187,11 @@ start:
58c5fc13
MT
52479 }
52480 }
52481 vaddr = PKMAP_ADDR(last_pkmap_nr);
ae4e228f
MT
52482+
52483+ pax_open_kernel();
58c5fc13
MT
52484 set_pte_at(&init_mm, vaddr,
52485 &(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot));
ae4e228f
MT
52486-
52487+ pax_close_kernel();
58c5fc13
MT
52488 pkmap_count[last_pkmap_nr] = 1;
52489 set_page_address(page, (void *)vaddr);
58c5fc13 52490
16454cff
MT
52491diff -urNp linux-2.6.38.1/mm/hugetlb.c linux-2.6.38.1/mm/hugetlb.c
52492--- linux-2.6.38.1/mm/hugetlb.c 2011-03-14 21:20:32.000000000 -0400
52493+++ linux-2.6.38.1/mm/hugetlb.c 2011-03-21 18:31:35.000000000 -0400
52494@@ -2333,6 +2333,27 @@ static int unmap_ref_private(struct mm_s
58c5fc13
MT
52495 return 1;
52496 }
52497
52498+#ifdef CONFIG_PAX_SEGMEXEC
52499+static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
52500+{
52501+ struct mm_struct *mm = vma->vm_mm;
52502+ struct vm_area_struct *vma_m;
52503+ unsigned long address_m;
52504+ pte_t *ptep_m;
52505+
52506+ vma_m = pax_find_mirror_vma(vma);
52507+ if (!vma_m)
52508+ return;
52509+
52510+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
52511+ address_m = address + SEGMEXEC_TASK_SIZE;
52512+ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
52513+ get_page(page_m);
6892158b 52514+ hugepage_add_anon_rmap(page_m, vma_m, address_m);
58c5fc13
MT
52515+ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
52516+}
52517+#endif
52518+
6892158b
MT
52519 /*
52520 * Hugetlb_cow() should be called with page lock of the original hugepage held.
52521 */
16454cff 52522@@ -2434,6 +2455,11 @@ retry_avoidcopy:
58c5fc13 52523 make_huge_pte(vma, new_page, 1));
6892158b
MT
52524 page_remove_rmap(old_page);
52525 hugepage_add_new_anon_rmap(new_page, vma, address);
58c5fc13
MT
52526+
52527+#ifdef CONFIG_PAX_SEGMEXEC
52528+ pax_mirror_huge_pte(vma, address, new_page);
52529+#endif
52530+
52531 /* Make the old page be freed below */
52532 new_page = old_page;
6892158b 52533 mmu_notifier_invalidate_range_end(mm,
16454cff 52534@@ -2585,6 +2611,10 @@ retry:
58c5fc13
MT
52535 && (vma->vm_flags & VM_SHARED)));
52536 set_huge_pte_at(mm, address, ptep, new_pte);
52537
52538+#ifdef CONFIG_PAX_SEGMEXEC
52539+ pax_mirror_huge_pte(vma, address, page);
52540+#endif
52541+
52542 if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
52543 /* Optimization, do the COW without a second fault */
52544 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
16454cff 52545@@ -2614,6 +2644,10 @@ int hugetlb_fault(struct mm_struct *mm,
58c5fc13
MT
52546 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
52547 struct hstate *h = hstate_vma(vma);
52548
52549+#ifdef CONFIG_PAX_SEGMEXEC
52550+ struct vm_area_struct *vma_m;
6892158b 52551+#endif
58c5fc13 52552+
6892158b
MT
52553 ptep = huge_pte_offset(mm, address);
52554 if (ptep) {
52555 entry = huge_ptep_get(ptep);
16454cff 52556@@ -2625,6 +2659,26 @@ int hugetlb_fault(struct mm_struct *mm,
bc901d79 52557 VM_FAULT_SET_HINDEX(h - hstates);
6892158b
MT
52558 }
52559
52560+#ifdef CONFIG_PAX_SEGMEXEC
58c5fc13
MT
52561+ vma_m = pax_find_mirror_vma(vma);
52562+ if (vma_m) {
52563+ unsigned long address_m;
52564+
52565+ if (vma->vm_start > vma_m->vm_start) {
52566+ address_m = address;
52567+ address -= SEGMEXEC_TASK_SIZE;
52568+ vma = vma_m;
52569+ h = hstate_vma(vma);
52570+ } else
52571+ address_m = address + SEGMEXEC_TASK_SIZE;
52572+
52573+ if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
52574+ return VM_FAULT_OOM;
52575+ address_m &= HPAGE_MASK;
52576+ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
52577+ }
52578+#endif
52579+
52580 ptep = huge_pte_alloc(mm, address, huge_page_size(h));
52581 if (!ptep)
52582 return VM_FAULT_OOM;
16454cff
MT
52583diff -urNp linux-2.6.38.1/mm/Kconfig linux-2.6.38.1/mm/Kconfig
52584--- linux-2.6.38.1/mm/Kconfig 2011-03-14 21:20:32.000000000 -0400
52585+++ linux-2.6.38.1/mm/Kconfig 2011-03-21 18:31:35.000000000 -0400
57199397
MT
52586@@ -240,7 +240,7 @@ config KSM
52587 config DEFAULT_MMAP_MIN_ADDR
52588 int "Low address space to protect from user allocation"
52589 depends on MMU
52590- default 4096
52591+ default 65536
52592 help
52593 This is the portion of low virtual memory which should be protected
52594 from userspace allocation. Keeping a user from writing to low pages
16454cff
MT
52595diff -urNp linux-2.6.38.1/mm/kmemleak.c linux-2.6.38.1/mm/kmemleak.c
52596--- linux-2.6.38.1/mm/kmemleak.c 2011-03-14 21:20:32.000000000 -0400
52597+++ linux-2.6.38.1/mm/kmemleak.c 2011-03-21 18:31:35.000000000 -0400
52598@@ -357,7 +357,7 @@ static void print_unreferenced(struct se
bc901d79
MT
52599
52600 for (i = 0; i < object->trace_len; i++) {
52601 void *ptr = (void *)object->trace[i];
52602- seq_printf(seq, " [<%p>] %pS\n", ptr, ptr);
52603+ seq_printf(seq, " [<%p>] %pA\n", ptr, ptr);
52604 }
52605 }
52606
16454cff
MT
52607diff -urNp linux-2.6.38.1/mm/maccess.c linux-2.6.38.1/mm/maccess.c
52608--- linux-2.6.38.1/mm/maccess.c 2011-03-14 21:20:32.000000000 -0400
52609+++ linux-2.6.38.1/mm/maccess.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
52610@@ -15,10 +15,10 @@
52611 * happens, handle that and return -EFAULT.
52612 */
52613
52614-long __weak probe_kernel_read(void *dst, void *src, size_t size)
52615+long __weak probe_kernel_read(void *dst, const void *src, size_t size)
52616 __attribute__((alias("__probe_kernel_read")));
52617
52618-long __probe_kernel_read(void *dst, void *src, size_t size)
52619+long __probe_kernel_read(void *dst, const void *src, size_t size)
52620 {
52621 long ret;
52622 mm_segment_t old_fs = get_fs();
52623@@ -43,10 +43,10 @@ EXPORT_SYMBOL_GPL(probe_kernel_read);
52624 * Safely write to address @dst from the buffer at @src. If a kernel fault
52625 * happens, handle that and return -EFAULT.
52626 */
52627-long __weak probe_kernel_write(void *dst, void *src, size_t size)
52628+long __weak probe_kernel_write(void *dst, const void *src, size_t size)
52629 __attribute__((alias("__probe_kernel_write")));
52630
52631-long __probe_kernel_write(void *dst, void *src, size_t size)
52632+long __probe_kernel_write(void *dst, const void *src, size_t size)
52633 {
52634 long ret;
52635 mm_segment_t old_fs = get_fs();
16454cff
MT
52636diff -urNp linux-2.6.38.1/mm/madvise.c linux-2.6.38.1/mm/madvise.c
52637--- linux-2.6.38.1/mm/madvise.c 2011-03-14 21:20:32.000000000 -0400
52638+++ linux-2.6.38.1/mm/madvise.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 52639@@ -45,6 +45,10 @@ static long madvise_behavior(struct vm_a
58c5fc13 52640 pgoff_t pgoff;
ae4e228f 52641 unsigned long new_flags = vma->vm_flags;
58c5fc13
MT
52642
52643+#ifdef CONFIG_PAX_SEGMEXEC
52644+ struct vm_area_struct *vma_m;
52645+#endif
52646+
52647 switch (behavior) {
52648 case MADV_NORMAL:
52649 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
16454cff 52650@@ -110,6 +114,13 @@ success:
58c5fc13
MT
52651 /*
52652 * vm_flags is protected by the mmap_sem held in write mode.
52653 */
52654+
52655+#ifdef CONFIG_PAX_SEGMEXEC
52656+ vma_m = pax_find_mirror_vma(vma);
52657+ if (vma_m)
52658+ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
52659+#endif
52660+
52661 vma->vm_flags = new_flags;
52662
52663 out:
16454cff 52664@@ -168,6 +179,11 @@ static long madvise_dontneed(struct vm_a
ae4e228f
MT
52665 struct vm_area_struct ** prev,
52666 unsigned long start, unsigned long end)
52667 {
58c5fc13
MT
52668+
52669+#ifdef CONFIG_PAX_SEGMEXEC
ae4e228f
MT
52670+ struct vm_area_struct *vma_m;
52671+#endif
58c5fc13 52672+
ae4e228f
MT
52673 *prev = vma;
52674 if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
52675 return -EINVAL;
16454cff 52676@@ -180,6 +196,21 @@ static long madvise_dontneed(struct vm_a
ae4e228f
MT
52677 zap_page_range(vma, start, end - start, &details);
52678 } else
52679 zap_page_range(vma, start, end - start, NULL);
52680+
52681+#ifdef CONFIG_PAX_SEGMEXEC
52682+ vma_m = pax_find_mirror_vma(vma);
52683+ if (vma_m) {
52684+ if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
52685+ struct zap_details details = {
52686+ .nonlinear_vma = vma_m,
52687+ .last_index = ULONG_MAX,
52688+ };
52689+ zap_page_range(vma, start + SEGMEXEC_TASK_SIZE, end - start, &details);
52690+ } else
52691+ zap_page_range(vma, start + SEGMEXEC_TASK_SIZE, end - start, NULL);
52692+ }
58c5fc13
MT
52693+#endif
52694+
ae4e228f
MT
52695 return 0;
52696 }
58c5fc13 52697
16454cff 52698@@ -376,6 +407,16 @@ SYSCALL_DEFINE3(madvise, unsigned long,
58c5fc13
MT
52699 if (end < start)
52700 goto out;
52701
52702+#ifdef CONFIG_PAX_SEGMEXEC
52703+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
52704+ if (end > SEGMEXEC_TASK_SIZE)
52705+ goto out;
52706+ } else
52707+#endif
52708+
52709+ if (end > TASK_SIZE)
52710+ goto out;
52711+
52712 error = 0;
52713 if (end == start)
52714 goto out;
16454cff
MT
52715diff -urNp linux-2.6.38.1/mm/memory.c linux-2.6.38.1/mm/memory.c
52716--- linux-2.6.38.1/mm/memory.c 2011-03-14 21:20:32.000000000 -0400
52717+++ linux-2.6.38.1/mm/memory.c 2011-03-21 18:31:35.000000000 -0400
57199397 52718@@ -259,8 +259,12 @@ static inline void free_pmd_range(struct
df50ba0c
MT
52719 return;
52720
52721 pmd = pmd_offset(pud, start);
52722+
52723+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_PER_CPU_PGD)
52724 pud_clear(pud);
52725 pmd_free_tlb(tlb, pmd, start);
52726+#endif
52727+
52728 }
52729
52730 static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
6892158b
MT
52731@@ -291,9 +295,12 @@ static inline void free_pud_range(struct
52732 if (end - 1 > ceiling - 1)
df50ba0c
MT
52733 return;
52734
df50ba0c 52735+#if !defined(CONFIG_X86_64) || !defined(CONFIG_PAX_PER_CPU_PGD)
6892158b 52736 pud = pud_offset(pgd, start);
df50ba0c
MT
52737 pgd_clear(pgd);
52738 pud_free_tlb(tlb, pud, start);
52739+#endif
52740+
52741 }
52742
52743 /*
16454cff 52744@@ -1433,10 +1440,10 @@ int __get_user_pages(struct task_struct
ae4e228f 52745 (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
58c5fc13
MT
52746 i = 0;
52747
52748- do {
52749+ while (nr_pages) {
52750 struct vm_area_struct *vma;
58c5fc13
MT
52751
52752- vma = find_extend_vma(mm, start);
52753+ vma = find_vma(mm, start);
52754 if (!vma && in_gate_area(tsk, start)) {
52755 unsigned long pg = start & PAGE_MASK;
52756 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
16454cff 52757@@ -1489,7 +1496,7 @@ int __get_user_pages(struct task_struct
58c5fc13
MT
52758 continue;
52759 }
52760
52761- if (!vma ||
52762+ if (!vma || start < vma->vm_start ||
52763 (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
ae4e228f 52764 !(vm_flags & vma->vm_flags))
58c5fc13 52765 return i ? : -EFAULT;
16454cff 52766@@ -1575,7 +1582,7 @@ int __get_user_pages(struct task_struct
58c5fc13
MT
52767 start += PAGE_SIZE;
52768 nr_pages--;
52769 } while (nr_pages && start < vma->vm_end);
52770- } while (nr_pages);
52771+ }
52772 return i;
52773 }
52774
16454cff 52775@@ -1724,6 +1731,10 @@ static int insert_page(struct vm_area_st
6892158b
MT
52776 page_add_file_rmap(page);
52777 set_pte_at(mm, addr, pte, mk_pte(page, prot));
52778
52779+#ifdef CONFIG_PAX_SEGMEXEC
52780+ pax_mirror_file_pte(vma, addr, page, ptl);
52781+#endif
52782+
52783 retval = 0;
52784 pte_unmap_unlock(pte, ptl);
52785 return retval;
16454cff 52786@@ -1758,10 +1769,22 @@ out:
6892158b
MT
52787 int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
52788 struct page *page)
52789 {
52790+
52791+#ifdef CONFIG_PAX_SEGMEXEC
52792+ struct vm_area_struct *vma_m;
52793+#endif
52794+
52795 if (addr < vma->vm_start || addr >= vma->vm_end)
52796 return -EFAULT;
52797 if (!page_count(page))
52798 return -EINVAL;
52799+
52800+#ifdef CONFIG_PAX_SEGMEXEC
52801+ vma_m = pax_find_mirror_vma(vma);
52802+ if (vma_m)
52803+ vma_m->vm_flags |= VM_INSERTPAGE;
52804+#endif
52805+
52806 vma->vm_flags |= VM_INSERTPAGE;
52807 return insert_page(vma, addr, page, vma->vm_page_prot);
52808 }
16454cff 52809@@ -1847,6 +1870,7 @@ int vm_insert_mixed(struct vm_area_struc
6892158b
MT
52810 unsigned long pfn)
52811 {
52812 BUG_ON(!(vma->vm_flags & VM_MIXEDMAP));
52813+ BUG_ON(vma->vm_mirror);
52814
52815 if (addr < vma->vm_start || addr >= vma->vm_end)
52816 return -EFAULT;
16454cff 52817@@ -2162,6 +2186,186 @@ static inline void cow_user_page(struct
58c5fc13
MT
52818 copy_user_highpage(dst, src, va, vma);
52819 }
52820
52821+#ifdef CONFIG_PAX_SEGMEXEC
52822+static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
52823+{
52824+ struct mm_struct *mm = vma->vm_mm;
52825+ spinlock_t *ptl;
52826+ pte_t *pte, entry;
52827+
52828+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
52829+ entry = *pte;
52830+ if (!pte_present(entry)) {
52831+ if (!pte_none(entry)) {
52832+ BUG_ON(pte_file(entry));
52833+ free_swap_and_cache(pte_to_swp_entry(entry));
52834+ pte_clear_not_present_full(mm, address, pte, 0);
52835+ }
52836+ } else {
52837+ struct page *page;
52838+
52839+ flush_cache_page(vma, address, pte_pfn(entry));
52840+ entry = ptep_clear_flush(vma, address, pte);
52841+ BUG_ON(pte_dirty(entry));
52842+ page = vm_normal_page(vma, address, entry);
52843+ if (page) {
52844+ update_hiwater_rss(mm);
52845+ if (PageAnon(page))
df50ba0c 52846+ dec_mm_counter_fast(mm, MM_ANONPAGES);
58c5fc13 52847+ else
df50ba0c 52848+ dec_mm_counter_fast(mm, MM_FILEPAGES);
58c5fc13
MT
52849+ page_remove_rmap(page);
52850+ page_cache_release(page);
52851+ }
52852+ }
52853+ pte_unmap_unlock(pte, ptl);
52854+}
52855+
52856+/* PaX: if vma is mirrored, synchronize the mirror's PTE
52857+ *
52858+ * the ptl of the lower mapped page is held on entry and is not released on exit
52859+ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
52860+ */
52861+static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
52862+{
52863+ struct mm_struct *mm = vma->vm_mm;
52864+ unsigned long address_m;
52865+ spinlock_t *ptl_m;
52866+ struct vm_area_struct *vma_m;
52867+ pmd_t *pmd_m;
52868+ pte_t *pte_m, entry_m;
52869+
52870+ BUG_ON(!page_m || !PageAnon(page_m));
52871+
52872+ vma_m = pax_find_mirror_vma(vma);
52873+ if (!vma_m)
52874+ return;
52875+
52876+ BUG_ON(!PageLocked(page_m));
52877+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
52878+ address_m = address + SEGMEXEC_TASK_SIZE;
52879+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
bc901d79 52880+ pte_m = pte_offset_map(pmd_m, address_m);
58c5fc13
MT
52881+ ptl_m = pte_lockptr(mm, pmd_m);
52882+ if (ptl != ptl_m) {
52883+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
52884+ if (!pte_none(*pte_m))
52885+ goto out;
52886+ }
52887+
52888+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
52889+ page_cache_get(page_m);
52890+ page_add_anon_rmap(page_m, vma_m, address_m);
df50ba0c 52891+ inc_mm_counter_fast(mm, MM_ANONPAGES);
58c5fc13
MT
52892+ set_pte_at(mm, address_m, pte_m, entry_m);
52893+ update_mmu_cache(vma_m, address_m, entry_m);
52894+out:
52895+ if (ptl != ptl_m)
52896+ spin_unlock(ptl_m);
bc901d79 52897+ pte_unmap(pte_m);
58c5fc13
MT
52898+ unlock_page(page_m);
52899+}
52900+
52901+void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
52902+{
52903+ struct mm_struct *mm = vma->vm_mm;
52904+ unsigned long address_m;
52905+ spinlock_t *ptl_m;
52906+ struct vm_area_struct *vma_m;
52907+ pmd_t *pmd_m;
52908+ pte_t *pte_m, entry_m;
52909+
52910+ BUG_ON(!page_m || PageAnon(page_m));
52911+
52912+ vma_m = pax_find_mirror_vma(vma);
52913+ if (!vma_m)
52914+ return;
52915+
52916+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
52917+ address_m = address + SEGMEXEC_TASK_SIZE;
52918+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
bc901d79 52919+ pte_m = pte_offset_map(pmd_m, address_m);
58c5fc13
MT
52920+ ptl_m = pte_lockptr(mm, pmd_m);
52921+ if (ptl != ptl_m) {
52922+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
52923+ if (!pte_none(*pte_m))
52924+ goto out;
52925+ }
52926+
52927+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
52928+ page_cache_get(page_m);
52929+ page_add_file_rmap(page_m);
df50ba0c 52930+ inc_mm_counter_fast(mm, MM_FILEPAGES);
58c5fc13
MT
52931+ set_pte_at(mm, address_m, pte_m, entry_m);
52932+ update_mmu_cache(vma_m, address_m, entry_m);
52933+out:
52934+ if (ptl != ptl_m)
52935+ spin_unlock(ptl_m);
bc901d79 52936+ pte_unmap(pte_m);
58c5fc13
MT
52937+}
52938+
52939+static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
52940+{
52941+ struct mm_struct *mm = vma->vm_mm;
52942+ unsigned long address_m;
52943+ spinlock_t *ptl_m;
52944+ struct vm_area_struct *vma_m;
52945+ pmd_t *pmd_m;
52946+ pte_t *pte_m, entry_m;
52947+
52948+ vma_m = pax_find_mirror_vma(vma);
52949+ if (!vma_m)
52950+ return;
52951+
52952+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
52953+ address_m = address + SEGMEXEC_TASK_SIZE;
52954+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
bc901d79 52955+ pte_m = pte_offset_map(pmd_m, address_m);
58c5fc13
MT
52956+ ptl_m = pte_lockptr(mm, pmd_m);
52957+ if (ptl != ptl_m) {
52958+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
52959+ if (!pte_none(*pte_m))
52960+ goto out;
52961+ }
52962+
52963+ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
52964+ set_pte_at(mm, address_m, pte_m, entry_m);
52965+out:
52966+ if (ptl != ptl_m)
52967+ spin_unlock(ptl_m);
bc901d79 52968+ pte_unmap(pte_m);
58c5fc13
MT
52969+}
52970+
52971+static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
52972+{
52973+ struct page *page_m;
52974+ pte_t entry;
52975+
52976+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
52977+ goto out;
52978+
52979+ entry = *pte;
52980+ page_m = vm_normal_page(vma, address, entry);
52981+ if (!page_m)
52982+ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
52983+ else if (PageAnon(page_m)) {
52984+ if (pax_find_mirror_vma(vma)) {
52985+ pte_unmap_unlock(pte, ptl);
52986+ lock_page(page_m);
52987+ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
52988+ if (pte_same(entry, *pte))
52989+ pax_mirror_anon_pte(vma, address, page_m, ptl);
52990+ else
52991+ unlock_page(page_m);
52992+ }
52993+ } else
52994+ pax_mirror_file_pte(vma, address, page_m, ptl);
52995+
52996+out:
52997+ pte_unmap_unlock(pte, ptl);
52998+}
52999+#endif
53000+
53001 /*
53002 * This routine handles present pages, when users try to write
53003 * to a shared page. It is done by copying the page to a new address
16454cff 53004@@ -2373,6 +2577,12 @@ gotten:
58c5fc13
MT
53005 */
53006 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
53007 if (likely(pte_same(*page_table, orig_pte))) {
53008+
53009+#ifdef CONFIG_PAX_SEGMEXEC
53010+ if (pax_find_mirror_vma(vma))
53011+ BUG_ON(!trylock_page(new_page));
53012+#endif
53013+
53014 if (old_page) {
53015 if (!PageAnon(old_page)) {
df50ba0c 53016 dec_mm_counter_fast(mm, MM_FILEPAGES);
16454cff 53017@@ -2424,6 +2634,10 @@ gotten:
58c5fc13
MT
53018 page_remove_rmap(old_page);
53019 }
53020
53021+#ifdef CONFIG_PAX_SEGMEXEC
53022+ pax_mirror_anon_pte(vma, address, new_page, ptl);
53023+#endif
53024+
53025 /* Free the old page.. */
53026 new_page = old_page;
53027 ret |= VM_FAULT_WRITE;
16454cff 53028@@ -2834,6 +3048,11 @@ static int do_swap_page(struct mm_struct
58c5fc13
MT
53029 swap_free(entry);
53030 if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
53031 try_to_free_swap(page);
53032+
53033+#ifdef CONFIG_PAX_SEGMEXEC
53034+ if ((flags & FAULT_FLAG_WRITE) || !pax_find_mirror_vma(vma))
53035+#endif
53036+
53037 unlock_page(page);
bc901d79
MT
53038 if (swapcache) {
53039 /*
16454cff 53040@@ -2857,6 +3076,11 @@ static int do_swap_page(struct mm_struct
58c5fc13
MT
53041
53042 /* No need to invalidate - it was non-present before */
df50ba0c 53043 update_mmu_cache(vma, address, page_table);
58c5fc13
MT
53044+
53045+#ifdef CONFIG_PAX_SEGMEXEC
53046+ pax_mirror_anon_pte(vma, address, page, ptl);
53047+#endif
53048+
53049 unlock:
53050 pte_unmap_unlock(page_table, ptl);
53051 out:
16454cff 53052@@ -2876,40 +3100,6 @@ out_release:
57199397
MT
53053 }
53054
53055 /*
6892158b
MT
53056- * This is like a special single-page "expand_{down|up}wards()",
53057- * except we must first make sure that 'address{-|+}PAGE_SIZE'
57199397 53058- * doesn't hit another vma.
57199397
MT
53059- */
53060-static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
53061-{
53062- address &= PAGE_MASK;
53063- if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
53064- struct vm_area_struct *prev = vma->vm_prev;
53065-
53066- /*
53067- * Is there a mapping abutting this one below?
53068- *
53069- * That's only ok if it's the same stack mapping
53070- * that has gotten split..
53071- */
53072- if (prev && prev->vm_end == address)
53073- return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
53074-
53075- expand_stack(vma, address - PAGE_SIZE);
53076- }
6892158b
MT
53077- if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) {
53078- struct vm_area_struct *next = vma->vm_next;
53079-
53080- /* As VM_GROWSDOWN but s/below/above/ */
53081- if (next && next->vm_start == address + PAGE_SIZE)
53082- return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM;
53083-
53084- expand_upwards(vma, address + PAGE_SIZE);
53085- }
57199397
MT
53086- return 0;
53087-}
53088-
53089-/*
53090 * We enter with non-exclusive mmap_sem (to exclude vma changes,
53091 * but allow concurrent faults), and pte mapped but not yet locked.
53092 * We return with mmap_sem still held, but pte unmapped and unlocked.
16454cff 53093@@ -2918,27 +3108,23 @@ static int do_anonymous_page(struct mm_s
ae4e228f
MT
53094 unsigned long address, pte_t *page_table, pmd_t *pmd,
53095 unsigned int flags)
53096 {
53097- struct page *page;
53098+ struct page *page = NULL;
53099 spinlock_t *ptl;
53100 pte_t entry;
53101
57199397
MT
53102- pte_unmap(page_table);
53103-
53104- /* Check if we need to add a guard page to the stack */
53105- if (check_stack_guard_page(vma, address) < 0)
53106- return VM_FAULT_SIGBUS;
53107-
53108- /* Use the zero-page for reads */
53109 if (!(flags & FAULT_FLAG_WRITE)) {
53110 entry = pte_mkspecial(pfn_pte(my_zero_pfn(address),
53111 vma->vm_page_prot));
53112- page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
53113+ ptl = pte_lockptr(mm, pmd);
53114+ spin_lock(ptl);
53115 if (!pte_none(*page_table))
53116 goto unlock;
53117 goto setpte;
53118 }
53119
53120 /* Allocate our own private page. */
53121+ pte_unmap(page_table);
53122+
53123 if (unlikely(anon_vma_prepare(vma)))
53124 goto oom;
53125 page = alloc_zeroed_user_highpage_movable(vma, address);
16454cff 53126@@ -2957,6 +3143,11 @@ static int do_anonymous_page(struct mm_s
58c5fc13
MT
53127 if (!pte_none(*page_table))
53128 goto release;
ae4e228f 53129
58c5fc13
MT
53130+#ifdef CONFIG_PAX_SEGMEXEC
53131+ if (pax_find_mirror_vma(vma))
53132+ BUG_ON(!trylock_page(page));
53133+#endif
53134+
df50ba0c 53135 inc_mm_counter_fast(mm, MM_ANONPAGES);
58c5fc13 53136 page_add_new_anon_rmap(page, vma, address);
ae4e228f 53137 setpte:
16454cff 53138@@ -2964,6 +3155,12 @@ setpte:
58c5fc13
MT
53139
53140 /* No need to invalidate - it was non-present before */
df50ba0c 53141 update_mmu_cache(vma, address, page_table);
58c5fc13
MT
53142+
53143+#ifdef CONFIG_PAX_SEGMEXEC
ae4e228f
MT
53144+ if (page)
53145+ pax_mirror_anon_pte(vma, address, page, ptl);
58c5fc13
MT
53146+#endif
53147+
53148 unlock:
53149 pte_unmap_unlock(page_table, ptl);
53150 return 0;
16454cff 53151@@ -3101,6 +3298,12 @@ static int __do_fault(struct mm_struct *
58c5fc13
MT
53152 */
53153 /* Only go through if we didn't race with anybody else... */
53154 if (likely(pte_same(*page_table, orig_pte))) {
53155+
53156+#ifdef CONFIG_PAX_SEGMEXEC
53157+ if (anon && pax_find_mirror_vma(vma))
53158+ BUG_ON(!trylock_page(page));
53159+#endif
53160+
53161 flush_icache_page(vma, page);
53162 entry = mk_pte(page, vma->vm_page_prot);
53163 if (flags & FAULT_FLAG_WRITE)
16454cff 53164@@ -3120,6 +3323,14 @@ static int __do_fault(struct mm_struct *
58c5fc13
MT
53165
53166 /* no need to invalidate: a not-present page won't be cached */
df50ba0c 53167 update_mmu_cache(vma, address, page_table);
58c5fc13
MT
53168+
53169+#ifdef CONFIG_PAX_SEGMEXEC
53170+ if (anon)
53171+ pax_mirror_anon_pte(vma, address, page, ptl);
53172+ else
53173+ pax_mirror_file_pte(vma, address, page, ptl);
53174+#endif
53175+
53176 } else {
53177 if (charged)
53178 mem_cgroup_uncharge_page(page);
16454cff 53179@@ -3267,6 +3478,12 @@ int handle_pte_fault(struct mm_struct *m
58c5fc13 53180 if (flags & FAULT_FLAG_WRITE)
bc901d79 53181 flush_tlb_fix_spurious_fault(vma, address);
58c5fc13
MT
53182 }
53183+
53184+#ifdef CONFIG_PAX_SEGMEXEC
53185+ pax_mirror_pte(vma, address, pte, pmd, ptl);
53186+ return 0;
53187+#endif
53188+
53189 unlock:
53190 pte_unmap_unlock(pte, ptl);
53191 return 0;
16454cff 53192@@ -3283,6 +3500,10 @@ int handle_mm_fault(struct mm_struct *mm
58c5fc13
MT
53193 pmd_t *pmd;
53194 pte_t *pte;
53195
53196+#ifdef CONFIG_PAX_SEGMEXEC
53197+ struct vm_area_struct *vma_m;
53198+#endif
53199+
53200 __set_current_state(TASK_RUNNING);
53201
53202 count_vm_event(PGFAULT);
16454cff 53203@@ -3293,6 +3514,34 @@ int handle_mm_fault(struct mm_struct *mm
58c5fc13
MT
53204 if (unlikely(is_vm_hugetlb_page(vma)))
53205 return hugetlb_fault(mm, vma, address, flags);
53206
53207+#ifdef CONFIG_PAX_SEGMEXEC
53208+ vma_m = pax_find_mirror_vma(vma);
53209+ if (vma_m) {
53210+ unsigned long address_m;
53211+ pgd_t *pgd_m;
53212+ pud_t *pud_m;
53213+ pmd_t *pmd_m;
53214+
53215+ if (vma->vm_start > vma_m->vm_start) {
53216+ address_m = address;
53217+ address -= SEGMEXEC_TASK_SIZE;
53218+ vma = vma_m;
53219+ } else
53220+ address_m = address + SEGMEXEC_TASK_SIZE;
53221+
53222+ pgd_m = pgd_offset(mm, address_m);
53223+ pud_m = pud_alloc(mm, pgd_m, address_m);
53224+ if (!pud_m)
53225+ return VM_FAULT_OOM;
53226+ pmd_m = pmd_alloc(mm, pud_m, address_m);
53227+ if (!pmd_m)
53228+ return VM_FAULT_OOM;
16454cff 53229+ if (!pmd_present(*pmd_m) && __pte_alloc(mm, vma_m, pmd_m, address_m))
58c5fc13
MT
53230+ return VM_FAULT_OOM;
53231+ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
53232+ }
53233+#endif
53234+
53235 pgd = pgd_offset(mm, address);
53236 pud = pud_alloc(mm, pgd, address);
53237 if (!pud)
16454cff 53238@@ -3426,7 +3675,7 @@ static int __init gate_vma_init(void)
58c5fc13
MT
53239 gate_vma.vm_start = FIXADDR_USER_START;
53240 gate_vma.vm_end = FIXADDR_USER_END;
53241 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
53242- gate_vma.vm_page_prot = __P101;
53243+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
53244 /*
53245 * Make sure the vDSO gets into every core dump.
53246 * Dumping its contents makes post-mortem fully interpretable later
16454cff
MT
53247diff -urNp linux-2.6.38.1/mm/memory-failure.c linux-2.6.38.1/mm/memory-failure.c
53248--- linux-2.6.38.1/mm/memory-failure.c 2011-03-14 21:20:32.000000000 -0400
53249+++ linux-2.6.38.1/mm/memory-failure.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 53250@@ -58,7 +58,7 @@ int sysctl_memory_failure_early_kill __r
57199397
MT
53251
53252 int sysctl_memory_failure_recovery __read_mostly = 1;
53253
53254-atomic_long_t mce_bad_pages __read_mostly = ATOMIC_LONG_INIT(0);
53255+atomic_long_unchecked_t mce_bad_pages __read_mostly = ATOMIC_LONG_INIT(0);
53256
53257 #if defined(CONFIG_HWPOISON_INJECT) || defined(CONFIG_HWPOISON_INJECT_MODULE)
53258
16454cff 53259@@ -1012,7 +1012,7 @@ int __memory_failure(unsigned long pfn,
57199397
MT
53260 }
53261
16454cff 53262 nr_pages = 1 << compound_trans_order(hpage);
6892158b
MT
53263- atomic_long_add(nr_pages, &mce_bad_pages);
53264+ atomic_long_add_unchecked(nr_pages, &mce_bad_pages);
57199397
MT
53265
53266 /*
53267 * We need/can do nothing about count=0 pages.
16454cff 53268@@ -1042,7 +1042,7 @@ int __memory_failure(unsigned long pfn,
bc901d79
MT
53269 if (!PageHWPoison(hpage)
53270 || (hwpoison_filter(p) && TestClearPageHWPoison(p))
53271 || (p != hpage && TestSetPageHWPoison(hpage))) {
53272- atomic_long_sub(nr_pages, &mce_bad_pages);
53273+ atomic_long_sub_unchecked(nr_pages, &mce_bad_pages);
53274 return 0;
53275 }
53276 set_page_hwpoison_huge_page(hpage);
16454cff 53277@@ -1100,7 +1100,7 @@ int __memory_failure(unsigned long pfn,
57199397
MT
53278 }
53279 if (hwpoison_filter(p)) {
53280 if (TestClearPageHWPoison(p))
6892158b
MT
53281- atomic_long_sub(nr_pages, &mce_bad_pages);
53282+ atomic_long_sub_unchecked(nr_pages, &mce_bad_pages);
53283 unlock_page(hpage);
53284 put_page(hpage);
57199397 53285 return 0;
16454cff 53286@@ -1226,7 +1226,7 @@ int unpoison_memory(unsigned long pfn)
bc901d79
MT
53287 return 0;
53288 }
57199397 53289 if (TestClearPageHWPoison(p))
6892158b
MT
53290- atomic_long_sub(nr_pages, &mce_bad_pages);
53291+ atomic_long_sub_unchecked(nr_pages, &mce_bad_pages);
bc901d79 53292 pr_info("MCE: Software-unpoisoned free page %#lx\n", pfn);
57199397
MT
53293 return 0;
53294 }
16454cff 53295@@ -1240,7 +1240,7 @@ int unpoison_memory(unsigned long pfn)
57199397 53296 */
6892158b 53297 if (TestClearPageHWPoison(page)) {
bc901d79 53298 pr_info("MCE: Software-unpoisoned page %#lx\n", pfn);
6892158b
MT
53299- atomic_long_sub(nr_pages, &mce_bad_pages);
53300+ atomic_long_sub_unchecked(nr_pages, &mce_bad_pages);
57199397 53301 freeit = 1;
bc901d79
MT
53302 if (PageHuge(page))
53303 clear_page_hwpoison_huge_page(page);
16454cff 53304@@ -1353,7 +1353,7 @@ static int soft_offline_huge_page(struct
57199397 53305 }
bc901d79
MT
53306 done:
53307 if (!PageHWPoison(hpage))
16454cff
MT
53308- atomic_long_add(1 << compound_trans_order(hpage), &mce_bad_pages);
53309+ atomic_long_add_unchecked(1 << compound_trans_order(hpage), &mce_bad_pages);
bc901d79
MT
53310 set_page_hwpoison_huge_page(hpage);
53311 dequeue_hwpoisoned_huge_page(hpage);
53312 /* keep elevated page count for bad page */
16454cff 53313@@ -1482,7 +1482,7 @@ int soft_offline_page(struct page *page,
57199397
MT
53314 return ret;
53315
53316 done:
53317- atomic_long_add(1, &mce_bad_pages);
53318+ atomic_long_add_unchecked(1, &mce_bad_pages);
53319 SetPageHWPoison(page);
53320 /* keep elevated page count for bad page */
53321 return ret;
16454cff
MT
53322diff -urNp linux-2.6.38.1/mm/mempolicy.c linux-2.6.38.1/mm/mempolicy.c
53323--- linux-2.6.38.1/mm/mempolicy.c 2011-03-14 21:20:32.000000000 -0400
53324+++ linux-2.6.38.1/mm/mempolicy.c 2011-03-21 18:31:35.000000000 -0400
53325@@ -643,6 +643,10 @@ static int mbind_range(struct mm_struct
df50ba0c
MT
53326 unsigned long vmstart;
53327 unsigned long vmend;
58c5fc13
MT
53328
53329+#ifdef CONFIG_PAX_SEGMEXEC
53330+ struct vm_area_struct *vma_m;
53331+#endif
53332+
df50ba0c
MT
53333 vma = find_vma_prev(mm, start, &prev);
53334 if (!vma || vma->vm_start > start)
53335 return -EFAULT;
16454cff 53336@@ -673,6 +677,16 @@ static int mbind_range(struct mm_struct
df50ba0c 53337 err = policy_vma(vma, new_pol);
58c5fc13 53338 if (err)
df50ba0c 53339 goto out;
58c5fc13
MT
53340+
53341+#ifdef CONFIG_PAX_SEGMEXEC
53342+ vma_m = pax_find_mirror_vma(vma);
53343+ if (vma_m) {
df50ba0c 53344+ err = policy_vma(vma_m, new_pol);
58c5fc13 53345+ if (err)
df50ba0c 53346+ goto out;
58c5fc13
MT
53347+ }
53348+#endif
53349+
53350 }
df50ba0c
MT
53351
53352 out:
16454cff 53353@@ -1106,6 +1120,17 @@ static long do_mbind(unsigned long start
58c5fc13
MT
53354
53355 if (end < start)
53356 return -EINVAL;
53357+
53358+#ifdef CONFIG_PAX_SEGMEXEC
53359+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
53360+ if (end > SEGMEXEC_TASK_SIZE)
53361+ return -EINVAL;
53362+ } else
53363+#endif
53364+
53365+ if (end > TASK_SIZE)
53366+ return -EINVAL;
53367+
53368 if (end == start)
53369 return 0;
53370
bc901d79 53371@@ -1324,6 +1349,14 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi
58c5fc13 53372 if (!mm)
6892158b 53373 goto out;
58c5fc13
MT
53374
53375+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
53376+ if (mm != current->mm &&
53377+ (mm->pax_flags & MF_PAX_RANDMMAP || mm->pax_flags & MF_PAX_SEGMEXEC)) {
53378+ err = -EPERM;
53379+ goto out;
53380+ }
53381+#endif
53382+
53383 /*
53384 * Check if this process has the right to modify the specified
53385 * process. The right exists if the process has administrative
bc901d79 53386@@ -1333,8 +1366,7 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi
58c5fc13
MT
53387 rcu_read_lock();
53388 tcred = __task_cred(task);
53389 if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
53390- cred->uid != tcred->suid && cred->uid != tcred->uid &&
53391- !capable(CAP_SYS_NICE)) {
53392+ cred->uid != tcred->suid && !capable(CAP_SYS_NICE)) {
53393 rcu_read_unlock();
53394 err = -EPERM;
53395 goto out;
16454cff 53396@@ -2635,7 +2667,7 @@ int show_numa_map(struct seq_file *m, vo
58c5fc13
MT
53397
53398 if (file) {
53399 seq_printf(m, " file=");
53400- seq_path(m, &file->f_path, "\n\t= ");
53401+ seq_path(m, &file->f_path, "\n\t\\= ");
53402 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
53403 seq_printf(m, " heap");
53404 } else if (vma->vm_start <= mm->start_stack &&
16454cff
MT
53405diff -urNp linux-2.6.38.1/mm/migrate.c linux-2.6.38.1/mm/migrate.c
53406--- linux-2.6.38.1/mm/migrate.c 2011-03-14 21:20:32.000000000 -0400
53407+++ linux-2.6.38.1/mm/migrate.c 2011-03-21 18:31:35.000000000 -0400
53408@@ -1299,6 +1299,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
58c5fc13
MT
53409 if (!mm)
53410 return -EINVAL;
53411
53412+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
53413+ if (mm != current->mm &&
53414+ (mm->pax_flags & MF_PAX_RANDMMAP || mm->pax_flags & MF_PAX_SEGMEXEC)) {
53415+ err = -EPERM;
53416+ goto out;
53417+ }
53418+#endif
53419+
53420 /*
53421 * Check if this process has the right to modify the specified
53422 * process. The right exists if the process has administrative
16454cff 53423@@ -1308,8 +1316,7 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
58c5fc13
MT
53424 rcu_read_lock();
53425 tcred = __task_cred(task);
53426 if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
53427- cred->uid != tcred->suid && cred->uid != tcred->uid &&
53428- !capable(CAP_SYS_NICE)) {
53429+ cred->uid != tcred->suid && !capable(CAP_SYS_NICE)) {
53430 rcu_read_unlock();
53431 err = -EPERM;
53432 goto out;
16454cff
MT
53433diff -urNp linux-2.6.38.1/mm/mlock.c linux-2.6.38.1/mm/mlock.c
53434--- linux-2.6.38.1/mm/mlock.c 2011-03-14 21:20:32.000000000 -0400
53435+++ linux-2.6.38.1/mm/mlock.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
53436@@ -13,6 +13,7 @@
53437 #include <linux/pagemap.h>
53438 #include <linux/mempolicy.h>
53439 #include <linux/syscalls.h>
53440+#include <linux/security.h>
53441 #include <linux/sched.h>
53442 #include <linux/module.h>
53443 #include <linux/rmap.h>
6892158b 53444@@ -135,13 +136,6 @@ void munlock_vma_page(struct page *page)
57199397
MT
53445 }
53446 }
53447
57199397
MT
53448-static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr)
53449-{
53450- return (vma->vm_flags & VM_GROWSDOWN) &&
53451- (vma->vm_start == addr) &&
53452- !vma_stack_continue(vma->vm_prev, addr);
53453-}
53454-
53455 /**
53456 * __mlock_vma_pages_range() - mlock a range of pages in the vma.
53457 * @vma: target vma
16454cff
MT
53458@@ -188,12 +182,6 @@ static long __mlock_vma_pages_range(stru
53459 if (vma->vm_flags & VM_LOCKED)
53460 gup_flags |= FOLL_MLOCK;
57199397
MT
53461
53462- /* We don't try to access the guard page of a stack vma */
53463- if (stack_guard_page(vma, start)) {
53464- addr += PAGE_SIZE;
53465- nr_pages--;
53466- }
53467-
16454cff
MT
53468 return __get_user_pages(current, mm, addr, nr_pages, gup_flags,
53469 NULL, NULL, nonblocking);
53470 }
53471@@ -393,6 +381,9 @@ static int do_mlock(unsigned long start,
58c5fc13
MT
53472 return -EINVAL;
53473 if (end == start)
53474 return 0;
58c5fc13
MT
53475+ if (end > TASK_SIZE)
53476+ return -EINVAL;
53477+
53478 vma = find_vma_prev(current->mm, start, &prev);
53479 if (!vma || vma->vm_start > start)
53480 return -ENOMEM;
16454cff 53481@@ -403,6 +394,11 @@ static int do_mlock(unsigned long start,
57199397
MT
53482 for (nstart = start ; ; ) {
53483 unsigned int newflags;
53484
53485+#ifdef CONFIG_PAX_SEGMEXEC
53486+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
53487+ break;
53488+#endif
53489+
53490 /* Here we know that vma->vm_start <= nstart < vma->vm_end. */
53491
53492 newflags = vma->vm_flags | VM_LOCKED;
16454cff 53493@@ -508,6 +504,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
58c5fc13
MT
53494 lock_limit >>= PAGE_SHIFT;
53495
53496 /* check against resource limits */
53497+ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
53498 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
53499 error = do_mlock(start, len, 1);
53500 up_write(&current->mm->mmap_sem);
16454cff 53501@@ -531,17 +528,23 @@ SYSCALL_DEFINE2(munlock, unsigned long,
58c5fc13
MT
53502 static int do_mlockall(int flags)
53503 {
53504 struct vm_area_struct * vma, * prev = NULL;
53505- unsigned int def_flags = 0;
58c5fc13
MT
53506
53507 if (flags & MCL_FUTURE)
53508- def_flags = VM_LOCKED;
57199397
MT
53509- current->mm->def_flags = def_flags;
53510+ current->mm->def_flags |= VM_LOCKED;
53511+ else
53512+ current->mm->def_flags &= ~VM_LOCKED;
58c5fc13
MT
53513 if (flags == MCL_FUTURE)
53514 goto out;
58c5fc13 53515
57199397
MT
53516 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
53517- unsigned int newflags;
53518+ unsigned long newflags;
53519+
58c5fc13
MT
53520+#ifdef CONFIG_PAX_SEGMEXEC
53521+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
53522+ break;
53523+#endif
57199397 53524
58c5fc13
MT
53525+ BUG_ON(vma->vm_end > TASK_SIZE);
53526 newflags = vma->vm_flags | VM_LOCKED;
53527 if (!(flags & MCL_CURRENT))
53528 newflags &= ~VM_LOCKED;
16454cff 53529@@ -573,6 +576,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
58c5fc13
MT
53530 lock_limit >>= PAGE_SHIFT;
53531
53532 ret = -ENOMEM;
57199397 53533+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm << PAGE_SHIFT, 1);
58c5fc13
MT
53534 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
53535 capable(CAP_IPC_LOCK))
53536 ret = do_mlockall(flags);
16454cff
MT
53537diff -urNp linux-2.6.38.1/mm/mmap.c linux-2.6.38.1/mm/mmap.c
53538--- linux-2.6.38.1/mm/mmap.c 2011-03-14 21:20:32.000000000 -0400
53539+++ linux-2.6.38.1/mm/mmap.c 2011-03-21 23:47:41.000000000 -0400
53540@@ -46,6 +46,16 @@
58c5fc13
MT
53541 #define arch_rebalance_pgtables(addr, len) (addr)
53542 #endif
53543
53544+static inline void verify_mm_writelocked(struct mm_struct *mm)
53545+{
53546+#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
53547+ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
53548+ up_read(&mm->mmap_sem);
53549+ BUG();
53550+ }
53551+#endif
53552+}
53553+
53554 static void unmap_region(struct mm_struct *mm,
53555 struct vm_area_struct *vma, struct vm_area_struct *prev,
53556 unsigned long start, unsigned long end);
16454cff 53557@@ -71,22 +81,32 @@ static void unmap_region(struct mm_struc
58c5fc13
MT
53558 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
53559 *
53560 */
53561-pgprot_t protection_map[16] = {
53562+pgprot_t protection_map[16] __read_only = {
53563 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
53564 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
53565 };
53566
53567 pgprot_t vm_get_page_prot(unsigned long vm_flags)
53568 {
53569- return __pgprot(pgprot_val(protection_map[vm_flags &
53570+ pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
53571 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
53572 pgprot_val(arch_vm_get_page_prot(vm_flags)));
53573+
53574+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
ae4e228f 53575+ if (!(__supported_pte_mask & _PAGE_NX) &&
58c5fc13
MT
53576+ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
53577+ (vm_flags & (VM_READ | VM_WRITE)))
53578+ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
53579+#endif
53580+
53581+ return prot;
53582 }
53583 EXPORT_SYMBOL(vm_get_page_prot);
53584
57199397
MT
53585 int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
53586 int sysctl_overcommit_ratio = 50; /* default is 50% */
53587 int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
53588+unsigned long sysctl_heap_stack_gap __read_mostly = 64*1024;
53589 struct percpu_counter vm_committed_as;
53590
53591 /*
16454cff 53592@@ -232,6 +252,7 @@ static struct vm_area_struct *remove_vma
58c5fc13
MT
53593 struct vm_area_struct *next = vma->vm_next;
53594
53595 might_sleep();
53596+ BUG_ON(vma->vm_mirror);
53597 if (vma->vm_ops && vma->vm_ops->close)
53598 vma->vm_ops->close(vma);
53599 if (vma->vm_file) {
16454cff 53600@@ -276,6 +297,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
58c5fc13
MT
53601 * not page aligned -Ram Gupta
53602 */
df50ba0c 53603 rlim = rlimit(RLIMIT_DATA);
58c5fc13
MT
53604+ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
53605 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
53606 (mm->end_data - mm->start_data) > rlim)
53607 goto out;
16454cff 53608@@ -719,6 +741,12 @@ static int
58c5fc13
MT
53609 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
53610 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
53611 {
53612+
53613+#ifdef CONFIG_PAX_SEGMEXEC
53614+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
53615+ return 0;
53616+#endif
53617+
53618 if (is_mergeable_vma(vma, file, vm_flags) &&
53619 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
53620 if (vma->vm_pgoff == vm_pgoff)
16454cff 53621@@ -738,6 +766,12 @@ static int
58c5fc13
MT
53622 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
53623 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
53624 {
53625+
53626+#ifdef CONFIG_PAX_SEGMEXEC
53627+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
53628+ return 0;
53629+#endif
53630+
53631 if (is_mergeable_vma(vma, file, vm_flags) &&
53632 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
53633 pgoff_t vm_pglen;
16454cff 53634@@ -780,13 +814,20 @@ can_vma_merge_after(struct vm_area_struc
58c5fc13
MT
53635 struct vm_area_struct *vma_merge(struct mm_struct *mm,
53636 struct vm_area_struct *prev, unsigned long addr,
53637 unsigned long end, unsigned long vm_flags,
53638- struct anon_vma *anon_vma, struct file *file,
53639+ struct anon_vma *anon_vma, struct file *file,
53640 pgoff_t pgoff, struct mempolicy *policy)
53641 {
53642 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
53643 struct vm_area_struct *area, *next;
df50ba0c 53644 int err;
58c5fc13
MT
53645
53646+#ifdef CONFIG_PAX_SEGMEXEC
53647+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
53648+ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
53649+
53650+ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
53651+#endif
53652+
53653 /*
53654 * We later require that vma->vm_flags == vm_flags,
53655 * so this tests vma->vm_flags & VM_SPECIAL, too.
16454cff 53656@@ -802,6 +843,15 @@ struct vm_area_struct *vma_merge(struct
58c5fc13
MT
53657 if (next && next->vm_end == end) /* cases 6, 7, 8 */
53658 next = next->vm_next;
53659
53660+#ifdef CONFIG_PAX_SEGMEXEC
53661+ if (prev)
53662+ prev_m = pax_find_mirror_vma(prev);
53663+ if (area)
53664+ area_m = pax_find_mirror_vma(area);
53665+ if (next)
53666+ next_m = pax_find_mirror_vma(next);
53667+#endif
53668+
53669 /*
53670 * Can it merge with the predecessor?
53671 */
16454cff 53672@@ -821,9 +871,24 @@ struct vm_area_struct *vma_merge(struct
58c5fc13 53673 /* cases 1, 6 */
df50ba0c 53674 err = vma_adjust(prev, prev->vm_start,
58c5fc13
MT
53675 next->vm_end, prev->vm_pgoff, NULL);
53676- } else /* cases 2, 5, 7 */
53677+
53678+#ifdef CONFIG_PAX_SEGMEXEC
df50ba0c
MT
53679+ if (!err && prev_m)
53680+ err = vma_adjust(prev_m, prev_m->vm_start,
58c5fc13
MT
53681+ next_m->vm_end, prev_m->vm_pgoff, NULL);
53682+#endif
53683+
53684+ } else { /* cases 2, 5, 7 */
df50ba0c 53685 err = vma_adjust(prev, prev->vm_start,
58c5fc13
MT
53686 end, prev->vm_pgoff, NULL);
53687+
53688+#ifdef CONFIG_PAX_SEGMEXEC
df50ba0c
MT
53689+ if (!err && prev_m)
53690+ err = vma_adjust(prev_m, prev_m->vm_start,
53691+ end_m, prev_m->vm_pgoff, NULL);
58c5fc13
MT
53692+#endif
53693+
53694+ }
df50ba0c
MT
53695 if (err)
53696 return NULL;
16454cff
MT
53697 khugepaged_enter_vma_merge(prev);
53698@@ -837,12 +902,27 @@ struct vm_area_struct *vma_merge(struct
58c5fc13
MT
53699 mpol_equal(policy, vma_policy(next)) &&
53700 can_vma_merge_before(next, vm_flags,
53701 anon_vma, file, pgoff+pglen)) {
53702- if (prev && addr < prev->vm_end) /* case 4 */
53703+ if (prev && addr < prev->vm_end) { /* case 4 */
df50ba0c 53704 err = vma_adjust(prev, prev->vm_start,
58c5fc13
MT
53705 addr, prev->vm_pgoff, NULL);
53706- else /* cases 3, 8 */
53707+
53708+#ifdef CONFIG_PAX_SEGMEXEC
df50ba0c
MT
53709+ if (!err && prev_m)
53710+ err = vma_adjust(prev_m, prev_m->vm_start,
53711+ addr_m, prev_m->vm_pgoff, NULL);
58c5fc13
MT
53712+#endif
53713+
53714+ } else { /* cases 3, 8 */
df50ba0c 53715 err = vma_adjust(area, addr, next->vm_end,
58c5fc13
MT
53716 next->vm_pgoff - pglen, NULL);
53717+
53718+#ifdef CONFIG_PAX_SEGMEXEC
df50ba0c
MT
53719+ if (!err && area_m)
53720+ err = vma_adjust(area_m, addr_m, next_m->vm_end,
53721+ next_m->vm_pgoff - pglen, NULL);
58c5fc13
MT
53722+#endif
53723+
53724+ }
df50ba0c
MT
53725 if (err)
53726 return NULL;
16454cff
MT
53727 khugepaged_enter_vma_merge(area);
53728@@ -958,14 +1038,11 @@ none:
58c5fc13
MT
53729 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
53730 struct file *file, long pages)
53731 {
53732- const unsigned long stack_flags
53733- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
53734-
53735 if (file) {
53736 mm->shared_vm += pages;
53737 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
53738 mm->exec_vm += pages;
53739- } else if (flags & stack_flags)
53740+ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
53741 mm->stack_vm += pages;
53742 if (flags & (VM_RESERVED|VM_IO))
53743 mm->reserved_vm += pages;
16454cff 53744@@ -992,7 +1069,7 @@ unsigned long do_mmap_pgoff(struct file
58c5fc13
MT
53745 * (the exception is when the underlying filesystem is noexec
53746 * mounted, in which case we dont add PROT_EXEC.)
53747 */
53748- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
53749+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
53750 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
53751 prot |= PROT_EXEC;
53752
16454cff 53753@@ -1018,7 +1095,7 @@ unsigned long do_mmap_pgoff(struct file
58c5fc13
MT
53754 /* Obtain the address to map to. we verify (or select) it and ensure
53755 * that it represents a valid section of the address space.
53756 */
53757- addr = get_unmapped_area(file, addr, len, pgoff, flags);
53758+ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
53759 if (addr & ~PAGE_MASK)
53760 return addr;
53761
16454cff 53762@@ -1029,6 +1106,36 @@ unsigned long do_mmap_pgoff(struct file
58c5fc13
MT
53763 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
53764 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
53765
58c5fc13 53766+#ifdef CONFIG_PAX_MPROTECT
57199397 53767+ if (mm->pax_flags & MF_PAX_MPROTECT) {
c52201e0 53768+#ifndef CONFIG_PAX_MPROTECT_COMPAT
6892158b
MT
53769+ if ((vm_flags & (VM_WRITE | VM_EXEC)) == (VM_WRITE | VM_EXEC)) {
53770+ gr_log_rwxmmap(file);
57199397
MT
53771+
53772+#ifdef CONFIG_PAX_EMUPLT
53773+ vm_flags &= ~VM_EXEC;
53774+#else
53775+ return -EPERM;
58c5fc13
MT
53776+#endif
53777+
6892158b
MT
53778+ }
53779+
57199397
MT
53780+ if (!(vm_flags & VM_EXEC))
53781+ vm_flags &= ~VM_MAYEXEC;
c52201e0
MT
53782+#else
53783+ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
53784+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
53785+#endif
57199397
MT
53786+ else
53787+ vm_flags &= ~VM_MAYWRITE;
58c5fc13
MT
53788+ }
53789+#endif
53790+
53791+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
53792+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
53793+ vm_flags &= ~VM_PAGEEXEC;
53794+#endif
53795+
ae4e228f 53796 if (flags & MAP_LOCKED)
58c5fc13
MT
53797 if (!can_do_mlock())
53798 return -EPERM;
16454cff 53799@@ -1040,6 +1147,7 @@ unsigned long do_mmap_pgoff(struct file
58c5fc13 53800 locked += mm->locked_vm;
df50ba0c 53801 lock_limit = rlimit(RLIMIT_MEMLOCK);
58c5fc13
MT
53802 lock_limit >>= PAGE_SHIFT;
53803+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
53804 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
53805 return -EAGAIN;
53806 }
16454cff 53807@@ -1110,6 +1218,9 @@ unsigned long do_mmap_pgoff(struct file
58c5fc13
MT
53808 if (error)
53809 return error;
53810
53811+ if (!gr_acl_handle_mmap(file, prot))
53812+ return -EACCES;
53813+
53814 return mmap_region(file, addr, len, flags, vm_flags, pgoff);
53815 }
53816 EXPORT_SYMBOL(do_mmap_pgoff);
16454cff 53817@@ -1187,10 +1298,10 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_ar
58c5fc13
MT
53818 */
53819 int vma_wants_writenotify(struct vm_area_struct *vma)
53820 {
53821- unsigned int vm_flags = vma->vm_flags;
53822+ unsigned long vm_flags = vma->vm_flags;
53823
53824 /* If it was private or non-writable, the write bit is already clear */
53825- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
53826+ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
53827 return 0;
53828
53829 /* The backer wishes to know when pages are first written to? */
16454cff 53830@@ -1239,14 +1350,24 @@ unsigned long mmap_region(struct file *f
58c5fc13
MT
53831 unsigned long charged = 0;
53832 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
53833
53834+#ifdef CONFIG_PAX_SEGMEXEC
53835+ struct vm_area_struct *vma_m = NULL;
53836+#endif
53837+
53838+ /*
53839+ * mm->mmap_sem is required to protect against another thread
53840+ * changing the mappings in case we sleep.
53841+ */
53842+ verify_mm_writelocked(mm);
53843+
53844 /* Clear old maps */
53845 error = -ENOMEM;
53846-munmap_back:
53847 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
53848 if (vma && vma->vm_start < addr + len) {
53849 if (do_munmap(mm, addr, len))
53850 return -ENOMEM;
53851- goto munmap_back;
53852+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
53853+ BUG_ON(vma && vma->vm_start < addr + len);
53854 }
53855
53856 /* Check against address space limit. */
16454cff 53857@@ -1295,6 +1416,16 @@ munmap_back:
58c5fc13
MT
53858 goto unacct_error;
53859 }
53860
53861+#ifdef CONFIG_PAX_SEGMEXEC
53862+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
53863+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
53864+ if (!vma_m) {
53865+ error = -ENOMEM;
53866+ goto free_vma;
53867+ }
53868+ }
53869+#endif
53870+
53871 vma->vm_mm = mm;
53872 vma->vm_start = addr;
53873 vma->vm_end = addr + len;
16454cff 53874@@ -1318,6 +1449,19 @@ munmap_back:
58c5fc13
MT
53875 error = file->f_op->mmap(file, vma);
53876 if (error)
53877 goto unmap_and_free_vma;
53878+
53879+#ifdef CONFIG_PAX_SEGMEXEC
53880+ if (vma_m && (vm_flags & VM_EXECUTABLE))
53881+ added_exe_file_vma(mm);
53882+#endif
53883+
53884+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
53885+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
53886+ vma->vm_flags |= VM_PAGEEXEC;
53887+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
53888+ }
53889+#endif
53890+
53891 if (vm_flags & VM_EXECUTABLE)
53892 added_exe_file_vma(mm);
ae4e228f 53893
16454cff 53894@@ -1353,6 +1497,11 @@ munmap_back:
58c5fc13
MT
53895 vma_link(mm, vma, prev, rb_link, rb_parent);
53896 file = vma->vm_file;
53897
53898+#ifdef CONFIG_PAX_SEGMEXEC
53899+ if (vma_m)
df50ba0c 53900+ BUG_ON(pax_mirror_vma(vma_m, vma));
58c5fc13
MT
53901+#endif
53902+
53903 /* Once vma denies write, undo our temporary denial count */
53904 if (correct_wcount)
53905 atomic_inc(&inode->i_writecount);
16454cff 53906@@ -1361,6 +1510,7 @@ out:
58c5fc13
MT
53907
53908 mm->total_vm += len >> PAGE_SHIFT;
53909 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
53910+ track_exec_limit(mm, addr, addr + len, vm_flags);
53911 if (vm_flags & VM_LOCKED) {
df50ba0c
MT
53912 if (!mlock_vma_pages_range(vma, addr, addr + len))
53913 mm->locked_vm += (len >> PAGE_SHIFT);
16454cff 53914@@ -1378,6 +1528,12 @@ unmap_and_free_vma:
58c5fc13
MT
53915 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
53916 charged = 0;
53917 free_vma:
53918+
53919+#ifdef CONFIG_PAX_SEGMEXEC
53920+ if (vma_m)
53921+ kmem_cache_free(vm_area_cachep, vma_m);
53922+#endif
53923+
53924 kmem_cache_free(vm_area_cachep, vma);
53925 unacct_error:
53926 if (charged)
16454cff 53927@@ -1385,6 +1541,44 @@ unacct_error:
57199397
MT
53928 return error;
53929 }
53930
16454cff 53931+bool check_heap_stack_gap(const struct vm_area_struct *vma, unsigned long addr, unsigned long len)
57199397
MT
53932+{
53933+ if (!vma) {
53934+#ifdef CONFIG_STACK_GROWSUP
53935+ if (addr > sysctl_heap_stack_gap)
53936+ vma = find_vma(current->mm, addr - sysctl_heap_stack_gap);
53937+ else
53938+ vma = find_vma(current->mm, 0);
53939+ if (vma && (vma->vm_flags & VM_GROWSUP))
53940+ return false;
53941+#endif
53942+ return true;
53943+ }
53944+
53945+ if (addr + len > vma->vm_start)
53946+ return false;
53947+
53948+ if (vma->vm_flags & VM_GROWSDOWN)
53949+ return sysctl_heap_stack_gap <= vma->vm_start - addr - len;
53950+#ifdef CONFIG_STACK_GROWSUP
53951+ else if (vma->vm_prev && (vma->vm_prev->vm_flags & VM_GROWSUP))
53952+ return addr - vma->vm_prev->vm_end <= sysctl_heap_stack_gap;
53953+#endif
53954+
53955+ return true;
53956+}
16454cff
MT
53957+
53958+unsigned long skip_heap_stack_gap(const struct vm_area_struct *vma, unsigned long len)
53959+{
53960+ if (vma->vm_start < len)
53961+ return -ENOMEM;
53962+ if (!(vma->vm_flags & VM_GROWSDOWN))
53963+ return vma->vm_start - len;
53964+ if (sysctl_heap_stack_gap <= vma->vm_start - len)
53965+ return vma->vm_start - len - sysctl_heap_stack_gap;
53966+ return -ENOMEM;
53967+}
57199397
MT
53968+
53969 /* Get an address range which is currently unmapped.
53970 * For shmat() with addr=0.
53971 *
16454cff 53972@@ -1411,18 +1605,23 @@ arch_get_unmapped_area(struct file *filp
58c5fc13
MT
53973 if (flags & MAP_FIXED)
53974 return addr;
53975
53976+#ifdef CONFIG_PAX_RANDMMAP
53977+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
53978+#endif
53979+
53980 if (addr) {
53981 addr = PAGE_ALIGN(addr);
57199397
MT
53982- vma = find_vma(mm, addr);
53983- if (TASK_SIZE - len >= addr &&
53984- (!vma || addr + len <= vma->vm_start))
53985- return addr;
53986+ if (TASK_SIZE - len >= addr) {
53987+ vma = find_vma(mm, addr);
53988+ if (check_heap_stack_gap(vma, addr, len))
53989+ return addr;
53990+ }
58c5fc13
MT
53991 }
53992 if (len > mm->cached_hole_size) {
53993- start_addr = addr = mm->free_area_cache;
53994+ start_addr = addr = mm->free_area_cache;
53995 } else {
53996- start_addr = addr = TASK_UNMAPPED_BASE;
53997- mm->cached_hole_size = 0;
53998+ start_addr = addr = mm->mmap_base;
53999+ mm->cached_hole_size = 0;
54000 }
54001
54002 full_search:
16454cff 54003@@ -1433,34 +1632,40 @@ full_search:
58c5fc13
MT
54004 * Start a new search - just in case we missed
54005 * some holes.
54006 */
54007- if (start_addr != TASK_UNMAPPED_BASE) {
54008- addr = TASK_UNMAPPED_BASE;
54009- start_addr = addr;
54010+ if (start_addr != mm->mmap_base) {
54011+ start_addr = addr = mm->mmap_base;
54012 mm->cached_hole_size = 0;
54013 goto full_search;
54014 }
57199397
MT
54015 return -ENOMEM;
54016 }
54017- if (!vma || addr + len <= vma->vm_start) {
54018- /*
54019- * Remember the place where we stopped the search:
54020- */
54021- mm->free_area_cache = addr + len;
54022- return addr;
54023- }
54024+ if (check_heap_stack_gap(vma, addr, len))
54025+ break;
54026 if (addr + mm->cached_hole_size < vma->vm_start)
54027 mm->cached_hole_size = vma->vm_start - addr;
54028 addr = vma->vm_end;
54029 }
54030+
54031+ /*
54032+ * Remember the place where we stopped the search:
54033+ */
54034+ mm->free_area_cache = addr + len;
54035+ return addr;
54036 }
54037 #endif
58c5fc13
MT
54038
54039 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
54040 {
54041+
54042+#ifdef CONFIG_PAX_SEGMEXEC
54043+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
54044+ return;
54045+#endif
54046+
54047 /*
54048 * Is this a new hole at the lowest possible address?
54049 */
54050- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
54051+ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
54052 mm->free_area_cache = addr;
54053 mm->cached_hole_size = ~0UL;
54054 }
16454cff 54055@@ -1478,7 +1683,7 @@ arch_get_unmapped_area_topdown(struct fi
58c5fc13
MT
54056 {
54057 struct vm_area_struct *vma;
54058 struct mm_struct *mm = current->mm;
54059- unsigned long addr = addr0;
54060+ unsigned long base = mm->mmap_base, addr = addr0;
54061
54062 /* requested length too big for entire address space */
54063 if (len > TASK_SIZE)
16454cff 54064@@ -1487,13 +1692,18 @@ arch_get_unmapped_area_topdown(struct fi
58c5fc13
MT
54065 if (flags & MAP_FIXED)
54066 return addr;
54067
54068+#ifdef CONFIG_PAX_RANDMMAP
54069+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
54070+#endif
54071+
54072 /* requesting a specific address */
54073 if (addr) {
54074 addr = PAGE_ALIGN(addr);
57199397
MT
54075- vma = find_vma(mm, addr);
54076- if (TASK_SIZE - len >= addr &&
54077- (!vma || addr + len <= vma->vm_start))
54078- return addr;
54079+ if (TASK_SIZE - len >= addr) {
54080+ vma = find_vma(mm, addr);
54081+ if (check_heap_stack_gap(vma, addr, len))
54082+ return addr;
54083+ }
54084 }
54085
54086 /* check if free_area_cache is useful for us */
16454cff 54087@@ -1508,7 +1718,7 @@ arch_get_unmapped_area_topdown(struct fi
57199397
MT
54088 /* make sure it can fit in the remaining address space */
54089 if (addr > len) {
54090 vma = find_vma(mm, addr-len);
54091- if (!vma || addr <= vma->vm_start)
54092+ if (check_heap_stack_gap(vma, addr - len, len))
54093 /* remember the address as a hint for next time */
54094 return (mm->free_area_cache = addr-len);
54095 }
16454cff 54096@@ -1525,7 +1735,7 @@ arch_get_unmapped_area_topdown(struct fi
57199397
MT
54097 * return with success:
54098 */
54099 vma = find_vma(mm, addr);
54100- if (!vma || addr+len <= vma->vm_start)
54101+ if (check_heap_stack_gap(vma, addr, len))
54102 /* remember the address as a hint for next time */
54103 return (mm->free_area_cache = addr);
54104
16454cff
MT
54105@@ -1534,8 +1744,8 @@ arch_get_unmapped_area_topdown(struct fi
54106 mm->cached_hole_size = vma->vm_start - addr;
54107
54108 /* try just below the current vma->vm_start */
54109- addr = vma->vm_start-len;
54110- } while (len < vma->vm_start);
54111+ addr = skip_heap_stack_gap(vma, len);
54112+ } while (!IS_ERR_VALUE(addr));
54113
54114 bottomup:
54115 /*
54116@@ -1544,13 +1754,21 @@ bottomup:
58c5fc13
MT
54117 * can happen with large stack limits and large mmap()
54118 * allocations.
54119 */
54120+ mm->mmap_base = TASK_UNMAPPED_BASE;
54121+
54122+#ifdef CONFIG_PAX_RANDMMAP
54123+ if (mm->pax_flags & MF_PAX_RANDMMAP)
54124+ mm->mmap_base += mm->delta_mmap;
54125+#endif
54126+
54127+ mm->free_area_cache = mm->mmap_base;
54128 mm->cached_hole_size = ~0UL;
54129- mm->free_area_cache = TASK_UNMAPPED_BASE;
54130 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
54131 /*
54132 * Restore the topdown base:
54133 */
54134- mm->free_area_cache = mm->mmap_base;
54135+ mm->mmap_base = base;
54136+ mm->free_area_cache = base;
54137 mm->cached_hole_size = ~0UL;
54138
54139 return addr;
16454cff 54140@@ -1559,6 +1777,12 @@ bottomup:
58c5fc13
MT
54141
54142 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
54143 {
54144+
54145+#ifdef CONFIG_PAX_SEGMEXEC
54146+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
54147+ return;
54148+#endif
54149+
54150 /*
54151 * Is this a new hole at the highest possible address?
54152 */
16454cff 54153@@ -1566,8 +1790,10 @@ void arch_unmap_area_topdown(struct mm_s
58c5fc13
MT
54154 mm->free_area_cache = addr;
54155
54156 /* dont allow allocations above current base */
54157- if (mm->free_area_cache > mm->mmap_base)
54158+ if (mm->free_area_cache > mm->mmap_base) {
54159 mm->free_area_cache = mm->mmap_base;
54160+ mm->cached_hole_size = ~0UL;
54161+ }
54162 }
54163
54164 unsigned long
16454cff 54165@@ -1675,6 +1901,28 @@ out:
58c5fc13
MT
54166 return prev ? prev->vm_next : vma;
54167 }
54168
54169+#ifdef CONFIG_PAX_SEGMEXEC
54170+struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
54171+{
54172+ struct vm_area_struct *vma_m;
54173+
54174+ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
54175+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
54176+ BUG_ON(vma->vm_mirror);
54177+ return NULL;
54178+ }
54179+ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
54180+ vma_m = vma->vm_mirror;
54181+ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
54182+ BUG_ON(vma->vm_file != vma_m->vm_file);
54183+ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
57199397 54184+ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff);
6892158b
MT
54185+ BUG_ON(vma->anon_vma != vma_m->anon_vma && vma->anon_vma->root != vma_m->anon_vma->root);
54186+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_RESERVED));
58c5fc13
MT
54187+ return vma_m;
54188+}
54189+#endif
54190+
54191 /*
54192 * Verify that the stack growth is acceptable and
54193 * update accounting. This is shared with both the
16454cff 54194@@ -1691,6 +1939,7 @@ static int acct_stack_growth(struct vm_a
58c5fc13
MT
54195 return -ENOMEM;
54196
54197 /* Stack limit test */
54198+ gr_learn_resource(current, RLIMIT_STACK, size, 1);
df50ba0c 54199 if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
58c5fc13
MT
54200 return -ENOMEM;
54201
16454cff 54202@@ -1701,6 +1950,7 @@ static int acct_stack_growth(struct vm_a
58c5fc13 54203 locked = mm->locked_vm + grow;
df50ba0c
MT
54204 limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur);
54205 limit >>= PAGE_SHIFT;
58c5fc13
MT
54206+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
54207 if (locked > limit && !capable(CAP_IPC_LOCK))
54208 return -ENOMEM;
54209 }
16454cff 54210@@ -1731,37 +1981,48 @@ static int acct_stack_growth(struct vm_a
6892158b
MT
54211 * PA-RISC uses this for its stack; IA64 for its Register Backing Store.
54212 * vma is the last one with address > vma->vm_end. Have to extend vma.
54213 */
54214+#ifndef CONFIG_IA64
54215+static
54216+#endif
58c5fc13
MT
54217 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
54218 {
bc901d79
MT
54219 int error;
54220+ bool locknext;
58c5fc13
MT
54221
54222 if (!(vma->vm_flags & VM_GROWSUP))
54223 return -EFAULT;
54224
54225+ /* Also guard against wrapping around to address 0. */
54226+ if (address < PAGE_ALIGN(address+1))
54227+ address = PAGE_ALIGN(address+1);
54228+ else
54229+ return -ENOMEM;
54230+
54231 /*
54232 * We must make sure the anon_vma is allocated
54233 * so that the anon_vma locking is not a noop.
54234 */
54235 if (unlikely(anon_vma_prepare(vma)))
54236 return -ENOMEM;
54237+ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
57199397 54238+ if (locknext && anon_vma_prepare(vma->vm_next))
58c5fc13 54239+ return -ENOMEM;
6892158b 54240 vma_lock_anon_vma(vma);
58c5fc13 54241+ if (locknext)
6892158b 54242+ vma_lock_anon_vma(vma->vm_next);
58c5fc13
MT
54243
54244 /*
54245 * vma->vm_start/vm_end cannot change under us because the caller
54246 * is required to hold the mmap_sem in read mode. We need the
54247- * anon_vma lock to serialize against concurrent expand_stacks.
54248- * Also guard against wrapping around to address 0.
54249+ * anon_vma locks to serialize against concurrent expand_stacks
54250+ * and expand_upwards.
54251 */
54252- if (address < PAGE_ALIGN(address+4))
54253- address = PAGE_ALIGN(address+4);
54254- else {
6892158b 54255- vma_unlock_anon_vma(vma);
58c5fc13
MT
54256- return -ENOMEM;
54257- }
54258 error = 0;
54259
54260 /* Somebody else might have raced and expanded it already */
54261- if (address > vma->vm_end) {
57199397
MT
54262+ if (vma->vm_next && (vma->vm_next->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) && vma->vm_next->vm_start - address < sysctl_heap_stack_gap)
54263+ error = -ENOMEM;
54264+ else if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
58c5fc13
MT
54265 unsigned long size, grow;
54266
54267 size = address - vma->vm_start;
16454cff 54268@@ -1773,6 +2034,8 @@ int expand_upwards(struct vm_area_struct
6892158b
MT
54269 perf_event_mmap(vma);
54270 }
58c5fc13
MT
54271 }
54272+ if (locknext)
6892158b
MT
54273+ vma_unlock_anon_vma(vma->vm_next);
54274 vma_unlock_anon_vma(vma);
16454cff 54275 khugepaged_enter_vma_merge(vma);
58c5fc13 54276 return error;
16454cff 54277@@ -1786,6 +2049,8 @@ static int expand_downwards(struct vm_ar
58c5fc13
MT
54278 unsigned long address)
54279 {
bc901d79
MT
54280 int error;
54281+ bool lockprev = false;
57199397 54282+ struct vm_area_struct *prev;
58c5fc13
MT
54283
54284 /*
54285 * We must make sure the anon_vma is allocated
16454cff 54286@@ -1799,6 +2064,15 @@ static int expand_downwards(struct vm_ar
58c5fc13
MT
54287 if (error)
54288 return error;
54289
57199397 54290+ prev = vma->vm_prev;
58c5fc13 54291+#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
58c5fc13
MT
54292+ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
54293+#endif
57199397 54294+ if (lockprev && anon_vma_prepare(prev))
58c5fc13
MT
54295+ return -ENOMEM;
54296+ if (lockprev)
6892158b 54297+ vma_lock_anon_vma(prev);
58c5fc13 54298+
6892158b 54299 vma_lock_anon_vma(vma);
58c5fc13
MT
54300
54301 /*
16454cff 54302@@ -1808,9 +2082,17 @@ static int expand_downwards(struct vm_ar
58c5fc13
MT
54303 */
54304
54305 /* Somebody else might have raced and expanded it already */
54306- if (address < vma->vm_start) {
57199397
MT
54307+ if (prev && (prev->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) && address - prev->vm_end < sysctl_heap_stack_gap)
54308+ error = -ENOMEM;
54309+ else if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
58c5fc13
MT
54310 unsigned long size, grow;
54311
54312+#ifdef CONFIG_PAX_SEGMEXEC
54313+ struct vm_area_struct *vma_m;
54314+
54315+ vma_m = pax_find_mirror_vma(vma);
54316+#endif
54317+
54318 size = vma->vm_end - address;
54319 grow = (vma->vm_start - address) >> PAGE_SHIFT;
54320
16454cff 54321@@ -1818,10 +2100,21 @@ static int expand_downwards(struct vm_ar
58c5fc13
MT
54322 if (!error) {
54323 vma->vm_start = address;
54324 vma->vm_pgoff -= grow;
54325+ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
54326+
54327+#ifdef CONFIG_PAX_SEGMEXEC
54328+ if (vma_m) {
54329+ vma_m->vm_start -= grow << PAGE_SHIFT;
54330+ vma_m->vm_pgoff -= grow;
54331+ }
54332+#endif
54333+
6892158b 54334 perf_event_mmap(vma);
58c5fc13
MT
54335 }
54336 }
6892158b 54337 vma_unlock_anon_vma(vma);
58c5fc13 54338+ if (lockprev)
6892158b 54339+ vma_unlock_anon_vma(prev);
16454cff 54340 khugepaged_enter_vma_merge(vma);
58c5fc13
MT
54341 return error;
54342 }
16454cff 54343@@ -1896,6 +2189,13 @@ static void remove_vma_list(struct mm_st
58c5fc13
MT
54344 do {
54345 long nrpages = vma_pages(vma);
54346
54347+#ifdef CONFIG_PAX_SEGMEXEC
54348+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
54349+ vma = remove_vma(vma);
54350+ continue;
54351+ }
54352+#endif
54353+
54354 mm->total_vm -= nrpages;
54355 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
54356 vma = remove_vma(vma);
16454cff 54357@@ -1941,6 +2241,16 @@ detach_vmas_to_be_unmapped(struct mm_str
58c5fc13 54358 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
57199397 54359 vma->vm_prev = NULL;
58c5fc13
MT
54360 do {
54361+
54362+#ifdef CONFIG_PAX_SEGMEXEC
54363+ if (vma->vm_mirror) {
54364+ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
54365+ vma->vm_mirror->vm_mirror = NULL;
54366+ vma->vm_mirror->vm_flags &= ~VM_EXEC;
54367+ vma->vm_mirror = NULL;
54368+ }
54369+#endif
54370+
54371 rb_erase(&vma->vm_rb, &mm->mm_rb);
54372 mm->map_count--;
54373 tail_vma = vma;
16454cff 54374@@ -1969,14 +2279,33 @@ static int __split_vma(struct mm_struct
ae4e228f 54375 struct vm_area_struct *new;
df50ba0c 54376 int err = -ENOMEM;
ae4e228f 54377
58c5fc13 54378+#ifdef CONFIG_PAX_SEGMEXEC
ae4e228f 54379+ struct vm_area_struct *vma_m, *new_m = NULL;
58c5fc13 54380+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
ae4e228f 54381+#endif
58c5fc13 54382+
ae4e228f
MT
54383 if (is_vm_hugetlb_page(vma) && (addr &
54384 ~(huge_page_mask(hstate_vma(vma)))))
54385 return -EINVAL;
54386
54387+#ifdef CONFIG_PAX_SEGMEXEC
58c5fc13 54388+ vma_m = pax_find_mirror_vma(vma);
ae4e228f 54389+#endif
58c5fc13 54390+
ae4e228f
MT
54391 new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
54392 if (!new)
df50ba0c 54393 goto out_err;
ae4e228f
MT
54394
54395+#ifdef CONFIG_PAX_SEGMEXEC
58c5fc13
MT
54396+ if (vma_m) {
54397+ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
54398+ if (!new_m) {
54399+ kmem_cache_free(vm_area_cachep, new);
df50ba0c 54400+ goto out_err;
58c5fc13
MT
54401+ }
54402+ }
ae4e228f 54403+#endif
58c5fc13 54404+
ae4e228f
MT
54405 /* most fields are the same, copy all, and then fixup */
54406 *new = *vma;
54407
16454cff 54408@@ -1989,6 +2318,22 @@ static int __split_vma(struct mm_struct
ae4e228f
MT
54409 new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
54410 }
54411
54412+#ifdef CONFIG_PAX_SEGMEXEC
58c5fc13
MT
54413+ if (vma_m) {
54414+ *new_m = *vma_m;
df50ba0c 54415+ INIT_LIST_HEAD(&new_m->anon_vma_chain);
58c5fc13
MT
54416+ new_m->vm_mirror = new;
54417+ new->vm_mirror = new_m;
54418+
54419+ if (new_below)
54420+ new_m->vm_end = addr_m;
54421+ else {
54422+ new_m->vm_start = addr_m;
54423+ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
54424+ }
54425+ }
ae4e228f
MT
54426+#endif
54427+
54428 pol = mpol_dup(vma_policy(vma));
54429 if (IS_ERR(pol)) {
df50ba0c 54430 err = PTR_ERR(pol);
16454cff 54431@@ -2014,6 +2359,42 @@ static int __split_vma(struct mm_struct
ae4e228f 54432 else
df50ba0c 54433 err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
ae4e228f
MT
54434
54435+#ifdef CONFIG_PAX_SEGMEXEC
df50ba0c
MT
54436+ if (!err && vma_m) {
54437+ if (anon_vma_clone(new_m, vma_m))
54438+ goto out_free_mpol;
54439+
58c5fc13
MT
54440+ mpol_get(pol);
54441+ vma_set_policy(new_m, pol);
54442+
54443+ if (new_m->vm_file) {
54444+ get_file(new_m->vm_file);
54445+ if (vma_m->vm_flags & VM_EXECUTABLE)
54446+ added_exe_file_vma(mm);
54447+ }
54448+
54449+ if (new_m->vm_ops && new_m->vm_ops->open)
54450+ new_m->vm_ops->open(new_m);
54451+
54452+ if (new_below)
df50ba0c 54453+ err = vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
58c5fc13
MT
54454+ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
54455+ else
df50ba0c
MT
54456+ err = vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
54457+
54458+ if (err) {
54459+ if (new_m->vm_ops && new_m->vm_ops->close)
54460+ new_m->vm_ops->close(new_m);
54461+ if (new_m->vm_file) {
54462+ if (vma_m->vm_flags & VM_EXECUTABLE)
54463+ removed_exe_file_vma(mm);
54464+ fput(new_m->vm_file);
54465+ }
54466+ mpol_put(pol);
54467+ }
58c5fc13 54468+ }
ae4e228f 54469+#endif
58c5fc13 54470+
df50ba0c
MT
54471 /* Success. */
54472 if (!err)
54473 return 0;
16454cff 54474@@ -2026,10 +2407,18 @@ static int __split_vma(struct mm_struct
6892158b
MT
54475 removed_exe_file_vma(mm);
54476 fput(new->vm_file);
54477 }
54478- unlink_anon_vmas(new);
df50ba0c
MT
54479 out_free_mpol:
54480 mpol_put(pol);
54481 out_free_vma:
54482+
54483+#ifdef CONFIG_PAX_SEGMEXEC
54484+ if (new_m) {
54485+ unlink_anon_vmas(new_m);
54486+ kmem_cache_free(vm_area_cachep, new_m);
54487+ }
54488+#endif
54489+
54490+ unlink_anon_vmas(new);
54491 kmem_cache_free(vm_area_cachep, new);
54492 out_err:
54493 return err;
16454cff 54494@@ -2042,6 +2431,15 @@ static int __split_vma(struct mm_struct
ae4e228f
MT
54495 int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
54496 unsigned long addr, int new_below)
54497 {
54498+
54499+#ifdef CONFIG_PAX_SEGMEXEC
54500+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
54501+ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
54502+ if (mm->map_count >= sysctl_max_map_count-1)
54503+ return -ENOMEM;
54504+ } else
58c5fc13 54505+#endif
ae4e228f
MT
54506+
54507 if (mm->map_count >= sysctl_max_map_count)
54508 return -ENOMEM;
58c5fc13 54509
16454cff 54510@@ -2053,11 +2451,30 @@ int split_vma(struct mm_struct *mm, stru
58c5fc13
MT
54511 * work. This now handles partial unmappings.
54512 * Jeremy Fitzhardinge <jeremy@goop.org>
54513 */
54514+#ifdef CONFIG_PAX_SEGMEXEC
16454cff
MT
54515 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
54516 {
58c5fc13
MT
54517+ int ret = __do_munmap(mm, start, len);
54518+ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
54519+ return ret;
54520+
54521+ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
54522+}
54523+
54524+int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
54525+#else
16454cff 54526+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
58c5fc13 54527+#endif
16454cff 54528+{
58c5fc13
MT
54529 unsigned long end;
54530 struct vm_area_struct *vma, *prev, *last;
54531
54532+ /*
54533+ * mm->mmap_sem is required to protect against another thread
54534+ * changing the mappings in case we sleep.
54535+ */
54536+ verify_mm_writelocked(mm);
54537+
54538 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
54539 return -EINVAL;
54540
16454cff 54541@@ -2131,6 +2548,8 @@ int do_munmap(struct mm_struct *mm, unsi
58c5fc13
MT
54542 /* Fix up all other VM information */
54543 remove_vma_list(mm, vma);
54544
54545+ track_exec_limit(mm, start, end, 0UL);
54546+
54547 return 0;
54548 }
54549
16454cff 54550@@ -2143,22 +2562,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, a
58c5fc13
MT
54551
54552 profile_munmap(addr);
54553
54554+#ifdef CONFIG_PAX_SEGMEXEC
54555+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
54556+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
54557+ return -EINVAL;
54558+#endif
54559+
54560 down_write(&mm->mmap_sem);
54561 ret = do_munmap(mm, addr, len);
54562 up_write(&mm->mmap_sem);
54563 return ret;
54564 }
54565
54566-static inline void verify_mm_writelocked(struct mm_struct *mm)
54567-{
54568-#ifdef CONFIG_DEBUG_VM
54569- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
54570- WARN_ON(1);
54571- up_read(&mm->mmap_sem);
54572- }
54573-#endif
54574-}
54575-
54576 /*
54577 * this is really a simplified "do_mmap". it only handles
54578 * anonymous maps. eventually we may be able to do some
16454cff 54579@@ -2172,6 +2587,7 @@ unsigned long do_brk(unsigned long addr,
58c5fc13
MT
54580 struct rb_node ** rb_link, * rb_parent;
54581 pgoff_t pgoff = addr >> PAGE_SHIFT;
54582 int error;
54583+ unsigned long charged;
58c5fc13
MT
54584
54585 len = PAGE_ALIGN(len);
54586 if (!len)
16454cff 54587@@ -2183,16 +2599,30 @@ unsigned long do_brk(unsigned long addr,
58c5fc13
MT
54588
54589 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
54590
54591+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
54592+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
54593+ flags &= ~VM_EXEC;
54594+
54595+#ifdef CONFIG_PAX_MPROTECT
54596+ if (mm->pax_flags & MF_PAX_MPROTECT)
54597+ flags &= ~VM_MAYEXEC;
54598+#endif
54599+
54600+ }
54601+#endif
54602+
ae4e228f
MT
54603 error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
54604 if (error & ~PAGE_MASK)
58c5fc13
MT
54605 return error;
54606
54607+ charged = len >> PAGE_SHIFT;
54608+
54609 /*
54610 * mlock MCL_FUTURE?
54611 */
54612 if (mm->def_flags & VM_LOCKED) {
54613 unsigned long locked, lock_limit;
54614- locked = len >> PAGE_SHIFT;
54615+ locked = charged;
54616 locked += mm->locked_vm;
df50ba0c 54617 lock_limit = rlimit(RLIMIT_MEMLOCK);
58c5fc13 54618 lock_limit >>= PAGE_SHIFT;
16454cff 54619@@ -2209,22 +2639,22 @@ unsigned long do_brk(unsigned long addr,
58c5fc13
MT
54620 /*
54621 * Clear old maps. this also does some error checking for us
54622 */
54623- munmap_back:
54624 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
54625 if (vma && vma->vm_start < addr + len) {
54626 if (do_munmap(mm, addr, len))
54627 return -ENOMEM;
54628- goto munmap_back;
54629+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
54630+ BUG_ON(vma && vma->vm_start < addr + len);
54631 }
54632
54633 /* Check against address space limits *after* clearing old maps... */
54634- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
54635+ if (!may_expand_vm(mm, charged))
54636 return -ENOMEM;
54637
54638 if (mm->map_count > sysctl_max_map_count)
54639 return -ENOMEM;
54640
54641- if (security_vm_enough_memory(len >> PAGE_SHIFT))
54642+ if (security_vm_enough_memory(charged))
54643 return -ENOMEM;
54644
54645 /* Can we just expand an old private anonymous mapping? */
16454cff 54646@@ -2238,7 +2668,7 @@ unsigned long do_brk(unsigned long addr,
58c5fc13
MT
54647 */
54648 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
54649 if (!vma) {
54650- vm_unacct_memory(len >> PAGE_SHIFT);
54651+ vm_unacct_memory(charged);
54652 return -ENOMEM;
54653 }
54654
16454cff 54655@@ -2252,11 +2682,12 @@ unsigned long do_brk(unsigned long addr,
58c5fc13
MT
54656 vma_link(mm, vma, prev, rb_link, rb_parent);
54657 out:
6892158b 54658 perf_event_mmap(vma);
58c5fc13
MT
54659- mm->total_vm += len >> PAGE_SHIFT;
54660+ mm->total_vm += charged;
54661 if (flags & VM_LOCKED) {
54662 if (!mlock_vma_pages_range(vma, addr, addr + len))
54663- mm->locked_vm += (len >> PAGE_SHIFT);
54664+ mm->locked_vm += charged;
54665 }
54666+ track_exec_limit(mm, addr, addr + len, flags);
54667 return addr;
54668 }
54669
16454cff 54670@@ -2303,8 +2734,10 @@ void exit_mmap(struct mm_struct *mm)
58c5fc13
MT
54671 * Walk the list again, actually closing and freeing it,
54672 * with preemption enabled, without holding any MM locks.
54673 */
54674- while (vma)
54675+ while (vma) {
54676+ vma->vm_mirror = NULL;
54677 vma = remove_vma(vma);
54678+ }
54679
54680 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
54681 }
16454cff 54682@@ -2318,6 +2751,13 @@ int insert_vm_struct(struct mm_struct *
58c5fc13
MT
54683 struct vm_area_struct * __vma, * prev;
54684 struct rb_node ** rb_link, * rb_parent;
54685
54686+#ifdef CONFIG_PAX_SEGMEXEC
54687+ struct vm_area_struct *vma_m = NULL;
54688+#endif
bc901d79
MT
54689+
54690+ if (security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1))
54691+ return -EPERM;
58c5fc13
MT
54692+
54693 /*
54694 * The vm_pgoff of a purely anonymous vma should be irrelevant
54695 * until its first write fault, when page's anon_vma and index
16454cff 54696@@ -2340,7 +2780,22 @@ int insert_vm_struct(struct mm_struct *
58c5fc13
MT
54697 if ((vma->vm_flags & VM_ACCOUNT) &&
54698 security_vm_enough_memory_mm(mm, vma_pages(vma)))
54699 return -ENOMEM;
54700+
54701+#ifdef CONFIG_PAX_SEGMEXEC
54702+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
54703+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
54704+ if (!vma_m)
54705+ return -ENOMEM;
54706+ }
54707+#endif
54708+
54709 vma_link(mm, vma, prev, rb_link, rb_parent);
54710+
54711+#ifdef CONFIG_PAX_SEGMEXEC
54712+ if (vma_m)
df50ba0c 54713+ BUG_ON(pax_mirror_vma(vma_m, vma));
58c5fc13
MT
54714+#endif
54715+
54716 return 0;
54717 }
54718
16454cff 54719@@ -2358,6 +2813,8 @@ struct vm_area_struct *copy_vma(struct v
58c5fc13
MT
54720 struct rb_node **rb_link, *rb_parent;
54721 struct mempolicy *pol;
54722
54723+ BUG_ON(vma->vm_mirror);
54724+
54725 /*
54726 * If anonymous vma has not yet been faulted, update new pgoff
54727 * to match new location, to increase its chance of merging.
16454cff 54728@@ -2407,6 +2864,39 @@ struct vm_area_struct *copy_vma(struct v
df50ba0c
MT
54729 kmem_cache_free(vm_area_cachep, new_vma);
54730 return NULL;
58c5fc13 54731 }
df50ba0c 54732+
58c5fc13 54733+#ifdef CONFIG_PAX_SEGMEXEC
df50ba0c 54734+long pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
58c5fc13
MT
54735+{
54736+ struct vm_area_struct *prev_m;
54737+ struct rb_node **rb_link_m, *rb_parent_m;
54738+ struct mempolicy *pol_m;
54739+
54740+ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
54741+ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
54742+ BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
54743+ *vma_m = *vma;
df50ba0c
MT
54744+ INIT_LIST_HEAD(&vma_m->anon_vma_chain);
54745+ if (anon_vma_clone(vma_m, vma))
54746+ return -ENOMEM;
58c5fc13
MT
54747+ pol_m = vma_policy(vma_m);
54748+ mpol_get(pol_m);
54749+ vma_set_policy(vma_m, pol_m);
54750+ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
54751+ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
54752+ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
54753+ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
54754+ if (vma_m->vm_file)
54755+ get_file(vma_m->vm_file);
54756+ if (vma_m->vm_ops && vma_m->vm_ops->open)
54757+ vma_m->vm_ops->open(vma_m);
54758+ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
54759+ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
54760+ vma_m->vm_mirror = vma;
54761+ vma->vm_mirror = vma_m;
df50ba0c 54762+ return 0;
58c5fc13
MT
54763+}
54764+#endif
df50ba0c 54765
58c5fc13
MT
54766 /*
54767 * Return true if the calling process may expand its vm space by the passed
16454cff 54768@@ -2418,7 +2908,7 @@ int may_expand_vm(struct mm_struct *mm,
58c5fc13
MT
54769 unsigned long lim;
54770
df50ba0c 54771 lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT;
58c5fc13
MT
54772-
54773+ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
54774 if (cur + npages > lim)
54775 return 0;
54776 return 1;
16454cff 54777@@ -2489,6 +2979,22 @@ int install_special_mapping(struct mm_st
58c5fc13
MT
54778 vma->vm_start = addr;
54779 vma->vm_end = addr + len;
54780
54781+#ifdef CONFIG_PAX_MPROTECT
54782+ if (mm->pax_flags & MF_PAX_MPROTECT) {
c52201e0 54783+#ifndef CONFIG_PAX_MPROTECT_COMPAT
57199397
MT
54784+ if ((vm_flags & (VM_WRITE | VM_EXEC)) == (VM_WRITE | VM_EXEC))
54785+ return -EPERM;
54786+ if (!(vm_flags & VM_EXEC))
54787+ vm_flags &= ~VM_MAYEXEC;
c52201e0
MT
54788+#else
54789+ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
54790+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
54791+#endif
58c5fc13 54792+ else
57199397 54793+ vm_flags &= ~VM_MAYWRITE;
58c5fc13
MT
54794+ }
54795+#endif
54796+
54797 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
54798 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
54799
16454cff
MT
54800diff -urNp linux-2.6.38.1/mm/mprotect.c linux-2.6.38.1/mm/mprotect.c
54801--- linux-2.6.38.1/mm/mprotect.c 2011-03-14 21:20:32.000000000 -0400
54802+++ linux-2.6.38.1/mm/mprotect.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 54803@@ -23,10 +23,16 @@
58c5fc13
MT
54804 #include <linux/mmu_notifier.h>
54805 #include <linux/migrate.h>
ae4e228f 54806 #include <linux/perf_event.h>
58c5fc13
MT
54807+
54808+#ifdef CONFIG_PAX_MPROTECT
54809+#include <linux/elf.h>
54810+#endif
54811+
54812 #include <asm/uaccess.h>
54813 #include <asm/pgtable.h>
54814 #include <asm/cacheflush.h>
54815 #include <asm/tlbflush.h>
54816+#include <asm/mmu_context.h>
54817
54818 #ifndef pgprot_modify
54819 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
16454cff 54820@@ -141,6 +147,48 @@ static void change_protection(struct vm_
58c5fc13
MT
54821 flush_tlb_range(vma, start, end);
54822 }
54823
54824+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
54825+/* called while holding the mmap semaphor for writing except stack expansion */
54826+void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
54827+{
54828+ unsigned long oldlimit, newlimit = 0UL;
54829+
ae4e228f 54830+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || (__supported_pte_mask & _PAGE_NX))
58c5fc13
MT
54831+ return;
54832+
54833+ spin_lock(&mm->page_table_lock);
54834+ oldlimit = mm->context.user_cs_limit;
54835+ if ((prot & VM_EXEC) && oldlimit < end)
54836+ /* USER_CS limit moved up */
54837+ newlimit = end;
54838+ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
54839+ /* USER_CS limit moved down */
54840+ newlimit = start;
54841+
54842+ if (newlimit) {
54843+ mm->context.user_cs_limit = newlimit;
54844+
54845+#ifdef CONFIG_SMP
54846+ wmb();
54847+ cpus_clear(mm->context.cpu_user_cs_mask);
54848+ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
54849+#endif
54850+
54851+ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
54852+ }
54853+ spin_unlock(&mm->page_table_lock);
54854+ if (newlimit == end) {
54855+ struct vm_area_struct *vma = find_vma(mm, oldlimit);
54856+
54857+ for (; vma && vma->vm_start < end; vma = vma->vm_next)
54858+ if (is_vm_hugetlb_page(vma))
54859+ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
54860+ else
54861+ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
54862+ }
54863+}
54864+#endif
54865+
54866 int
54867 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
54868 unsigned long start, unsigned long end, unsigned long newflags)
16454cff 54869@@ -153,11 +201,29 @@ mprotect_fixup(struct vm_area_struct *vm
58c5fc13
MT
54870 int error;
54871 int dirty_accountable = 0;
54872
54873+#ifdef CONFIG_PAX_SEGMEXEC
54874+ struct vm_area_struct *vma_m = NULL;
54875+ unsigned long start_m, end_m;
54876+
54877+ start_m = start + SEGMEXEC_TASK_SIZE;
54878+ end_m = end + SEGMEXEC_TASK_SIZE;
54879+#endif
54880+
54881 if (newflags == oldflags) {
54882 *pprev = vma;
54883 return 0;
57199397
MT
54884 }
54885
54886+ if (newflags & (VM_READ | VM_WRITE | VM_EXEC)) {
54887+ struct vm_area_struct *prev = vma->vm_prev, *next = vma->vm_next;
54888+
54889+ if (next && (next->vm_flags & VM_GROWSDOWN) && sysctl_heap_stack_gap > next->vm_start - end)
54890+ return -ENOMEM;
54891+
54892+ if (prev && (prev->vm_flags & VM_GROWSUP) && sysctl_heap_stack_gap > start - prev->vm_end)
54893+ return -ENOMEM;
54894+ }
54895+
54896 /*
54897 * If we make a private mapping writable we increase our commit;
54898 * but (without finer accounting) cannot reduce our commit if we
16454cff 54899@@ -174,6 +240,42 @@ mprotect_fixup(struct vm_area_struct *vm
58c5fc13
MT
54900 }
54901 }
54902
54903+#ifdef CONFIG_PAX_SEGMEXEC
54904+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
54905+ if (start != vma->vm_start) {
54906+ error = split_vma(mm, vma, start, 1);
54907+ if (error)
54908+ goto fail;
54909+ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
54910+ *pprev = (*pprev)->vm_next;
54911+ }
54912+
54913+ if (end != vma->vm_end) {
54914+ error = split_vma(mm, vma, end, 0);
54915+ if (error)
54916+ goto fail;
54917+ }
54918+
54919+ if (pax_find_mirror_vma(vma)) {
54920+ error = __do_munmap(mm, start_m, end_m - start_m);
54921+ if (error)
54922+ goto fail;
54923+ } else {
54924+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
54925+ if (!vma_m) {
54926+ error = -ENOMEM;
54927+ goto fail;
54928+ }
54929+ vma->vm_flags = newflags;
df50ba0c
MT
54930+ error = pax_mirror_vma(vma_m, vma);
54931+ if (error) {
54932+ vma->vm_flags = oldflags;
54933+ goto fail;
54934+ }
58c5fc13
MT
54935+ }
54936+ }
54937+#endif
54938+
54939 /*
54940 * First try to merge with previous and/or next vma.
54941 */
16454cff 54942@@ -204,9 +306,21 @@ success:
df50ba0c 54943 * vm_flags and vm_page_prot are protected by the mmap_sem
58c5fc13
MT
54944 * held in write mode.
54945 */
df50ba0c
MT
54946+
54947+#ifdef CONFIG_PAX_SEGMEXEC
54948+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (newflags & VM_EXEC) && ((vma->vm_flags ^ newflags) & VM_READ))
54949+ pax_find_mirror_vma(vma)->vm_flags ^= VM_READ;
54950+#endif
54951+
58c5fc13
MT
54952 vma->vm_flags = newflags;
54953+
54954+#ifdef CONFIG_PAX_MPROTECT
ae4e228f
MT
54955+ if (mm->binfmt && mm->binfmt->handle_mprotect)
54956+ mm->binfmt->handle_mprotect(vma, newflags);
58c5fc13
MT
54957+#endif
54958+
54959 vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
54960- vm_get_page_prot(newflags));
54961+ vm_get_page_prot(vma->vm_flags));
54962
54963 if (vma_wants_writenotify(vma)) {
54964 vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
16454cff 54965@@ -248,6 +362,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
58c5fc13
MT
54966 end = start + len;
54967 if (end <= start)
54968 return -ENOMEM;
54969+
54970+#ifdef CONFIG_PAX_SEGMEXEC
54971+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
54972+ if (end > SEGMEXEC_TASK_SIZE)
54973+ return -EINVAL;
54974+ } else
54975+#endif
54976+
54977+ if (end > TASK_SIZE)
54978+ return -EINVAL;
54979+
54980 if (!arch_validate_prot(prot))
54981 return -EINVAL;
54982
16454cff 54983@@ -255,7 +380,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
58c5fc13
MT
54984 /*
54985 * Does the application expect PROT_READ to imply PROT_EXEC:
54986 */
54987- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
54988+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
54989 prot |= PROT_EXEC;
54990
54991 vm_flags = calc_vm_prot_bits(prot);
16454cff 54992@@ -287,6 +412,11 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
58c5fc13
MT
54993 if (start > vma->vm_start)
54994 prev = vma;
54995
58c5fc13 54996+#ifdef CONFIG_PAX_MPROTECT
ae4e228f
MT
54997+ if (current->mm->binfmt && current->mm->binfmt->handle_mprotect)
54998+ current->mm->binfmt->handle_mprotect(vma, vm_flags);
58c5fc13
MT
54999+#endif
55000+
55001 for (nstart = start ; ; ) {
55002 unsigned long newflags;
55003
16454cff 55004@@ -296,6 +426,14 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
6892158b
MT
55005
55006 /* newflags >> 4 shift VM_MAY% in place of VM_% */
55007 if ((newflags & ~(newflags >> 4)) & (VM_READ | VM_WRITE | VM_EXEC)) {
55008+ if (prot & (PROT_WRITE | PROT_EXEC))
55009+ gr_log_rwxmprotect(vma->vm_file);
55010+
55011+ error = -EACCES;
55012+ goto out;
55013+ }
55014+
55015+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
55016 error = -EACCES;
55017 goto out;
55018 }
16454cff 55019@@ -310,6 +448,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
bc901d79 55020 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
58c5fc13
MT
55021 if (error)
55022 goto out;
58c5fc13
MT
55023+
55024+ track_exec_limit(current->mm, nstart, tmp, vm_flags);
55025+
55026 nstart = tmp;
55027
55028 if (nstart < prev->vm_end)
16454cff
MT
55029diff -urNp linux-2.6.38.1/mm/mremap.c linux-2.6.38.1/mm/mremap.c
55030--- linux-2.6.38.1/mm/mremap.c 2011-03-14 21:20:32.000000000 -0400
55031+++ linux-2.6.38.1/mm/mremap.c 2011-03-21 18:31:35.000000000 -0400
55032@@ -114,6 +114,12 @@ static void move_ptes(struct vm_area_str
58c5fc13
MT
55033 continue;
55034 pte = ptep_clear_flush(vma, old_addr, old_pte);
55035 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
55036+
55037+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
ae4e228f 55038+ if (!(__supported_pte_mask & _PAGE_NX) && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
58c5fc13
MT
55039+ pte = pte_exprotect(pte);
55040+#endif
55041+
55042 set_pte_at(mm, new_addr, new_pte, pte);
55043 }
55044
16454cff 55045@@ -273,6 +279,11 @@ static struct vm_area_struct *vma_to_res
ae4e228f
MT
55046 if (is_vm_hugetlb_page(vma))
55047 goto Einval;
55048
55049+#ifdef CONFIG_PAX_SEGMEXEC
55050+ if (pax_find_mirror_vma(vma))
55051+ goto Einval;
55052+#endif
55053+
55054 /* We can't remap across vm area boundaries */
55055 if (old_len > vma->vm_end - addr)
55056 goto Efault;
16454cff 55057@@ -322,20 +333,25 @@ static unsigned long mremap_to(unsigned
ae4e228f
MT
55058 unsigned long ret = -EINVAL;
55059 unsigned long charged = 0;
55060 unsigned long map_flags;
55061+ unsigned long pax_task_size = TASK_SIZE;
55062
55063 if (new_addr & ~PAGE_MASK)
55064 goto out;
55065
55066- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
55067+#ifdef CONFIG_PAX_SEGMEXEC
55068+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
55069+ pax_task_size = SEGMEXEC_TASK_SIZE;
55070+#endif
55071+
6892158b
MT
55072+ pax_task_size -= PAGE_SIZE;
55073+
ae4e228f
MT
55074+ if (new_len > TASK_SIZE || new_addr > pax_task_size - new_len)
55075 goto out;
55076
55077 /* Check if the location we're moving into overlaps the
55078 * old location at all, and fail if it does.
55079 */
55080- if ((new_addr <= addr) && (new_addr+new_len) > addr)
55081- goto out;
55082-
55083- if ((addr <= new_addr) && (addr+old_len) > new_addr)
55084+ if (addr + old_len > new_addr && new_addr + new_len > addr)
55085 goto out;
55086
55087 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
16454cff 55088@@ -407,6 +423,7 @@ unsigned long do_mremap(unsigned long ad
58c5fc13
MT
55089 struct vm_area_struct *vma;
55090 unsigned long ret = -EINVAL;
55091 unsigned long charged = 0;
55092+ unsigned long pax_task_size = TASK_SIZE;
55093
55094 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
55095 goto out;
16454cff 55096@@ -425,6 +442,17 @@ unsigned long do_mremap(unsigned long ad
58c5fc13
MT
55097 if (!new_len)
55098 goto out;
55099
55100+#ifdef CONFIG_PAX_SEGMEXEC
ae4e228f 55101+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
58c5fc13
MT
55102+ pax_task_size = SEGMEXEC_TASK_SIZE;
55103+#endif
55104+
6892158b
MT
55105+ pax_task_size -= PAGE_SIZE;
55106+
58c5fc13
MT
55107+ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
55108+ old_len > pax_task_size || addr > pax_task_size-old_len)
55109+ goto out;
55110+
58c5fc13 55111 if (flags & MREMAP_FIXED) {
ae4e228f
MT
55112 if (flags & MREMAP_MAYMOVE)
55113 ret = mremap_to(addr, old_len, new_addr, new_len);
16454cff 55114@@ -474,6 +502,7 @@ unsigned long do_mremap(unsigned long ad
58c5fc13
MT
55115 addr + new_len);
55116 }
55117 ret = addr;
55118+ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
55119 goto out;
55120 }
55121 }
16454cff 55122@@ -500,7 +529,13 @@ unsigned long do_mremap(unsigned long ad
ae4e228f
MT
55123 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
55124 if (ret)
55125 goto out;
55126+
58c5fc13
MT
55127+ map_flags = vma->vm_flags;
55128 ret = move_vma(vma, addr, old_len, new_len, new_addr);
55129+ if (!(ret & ~PAGE_MASK)) {
55130+ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
55131+ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
55132+ }
55133 }
55134 out:
55135 if (ret & ~PAGE_MASK)
16454cff
MT
55136diff -urNp linux-2.6.38.1/mm/nommu.c linux-2.6.38.1/mm/nommu.c
55137--- linux-2.6.38.1/mm/nommu.c 2011-03-14 21:20:32.000000000 -0400
55138+++ linux-2.6.38.1/mm/nommu.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 55139@@ -63,7 +63,6 @@ int sysctl_overcommit_memory = OVERCOMMI
57199397
MT
55140 int sysctl_overcommit_ratio = 50; /* default is 50% */
55141 int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
55142 int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
55143-int heap_stack_gap = 0;
55144
55145 atomic_long_t mmap_pages_allocated;
55146
16454cff 55147@@ -833,15 +832,6 @@ struct vm_area_struct *find_vma(struct m
58c5fc13
MT
55148 EXPORT_SYMBOL(find_vma);
55149
55150 /*
55151- * find a VMA
55152- * - we don't extend stack VMAs under NOMMU conditions
55153- */
55154-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
55155-{
55156- return find_vma(mm, addr);
55157-}
55158-
55159-/*
55160 * expand a stack to a given address
55161 * - not supported under NOMMU conditions
55162 */
16454cff 55163@@ -1563,6 +1553,7 @@ int split_vma(struct mm_struct *mm, stru
df50ba0c
MT
55164
55165 /* most fields are the same, copy all, and then fixup */
55166 *new = *vma;
55167+ INIT_LIST_HEAD(&new->anon_vma_chain);
55168 *region = *vma->vm_region;
55169 new->vm_region = region;
55170
16454cff
MT
55171diff -urNp linux-2.6.38.1/mm/page_alloc.c linux-2.6.38.1/mm/page_alloc.c
55172--- linux-2.6.38.1/mm/page_alloc.c 2011-03-14 21:20:32.000000000 -0400
55173+++ linux-2.6.38.1/mm/page_alloc.c 2011-03-21 18:31:35.000000000 -0400
55174@@ -644,6 +644,10 @@ static bool free_pages_prepare(struct pa
57199397 55175 int i;
58c5fc13 55176 int bad = 0;
58c5fc13
MT
55177
55178+#ifdef CONFIG_PAX_MEMORY_SANITIZE
55179+ unsigned long index = 1UL << order;
55180+#endif
55181+
df50ba0c 55182 trace_mm_page_free_direct(page, order);
58c5fc13
MT
55183 kmemcheck_free_shadow(page, order);
55184
16454cff 55185@@ -659,6 +663,12 @@ static bool free_pages_prepare(struct pa
58c5fc13
MT
55186 debug_check_no_obj_freed(page_address(page),
55187 PAGE_SIZE << order);
55188 }
55189+
55190+#ifdef CONFIG_PAX_MEMORY_SANITIZE
55191+ for (; index; --index)
55192+ sanitize_highpage(page + index - 1);
55193+#endif
55194+
55195 arch_free_page(page, order);
55196 kernel_map_pages(page, 1 << order, 0);
55197
16454cff 55198@@ -773,8 +783,10 @@ static int prep_new_page(struct page *pa
58c5fc13
MT
55199 arch_alloc_page(page, order);
55200 kernel_map_pages(page, 1 << order, 1);
55201
55202+#ifndef CONFIG_PAX_MEMORY_SANITIZE
55203 if (gfp_flags & __GFP_ZERO)
55204 prep_zero_page(page, order, gfp_flags);
55205+#endif
55206
55207 if (order && (gfp_flags & __GFP_COMP))
55208 prep_compound_page(page, order);
16454cff
MT
55209diff -urNp linux-2.6.38.1/mm/percpu.c linux-2.6.38.1/mm/percpu.c
55210--- linux-2.6.38.1/mm/percpu.c 2011-03-14 21:20:32.000000000 -0400
55211+++ linux-2.6.38.1/mm/percpu.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 55212@@ -121,7 +121,7 @@ static unsigned int pcpu_first_unit_cpu
ae4e228f 55213 static unsigned int pcpu_last_unit_cpu __read_mostly;
58c5fc13
MT
55214
55215 /* the address of the first chunk which starts with the kernel static area */
55216-void *pcpu_base_addr __read_mostly;
55217+void *pcpu_base_addr __read_only;
55218 EXPORT_SYMBOL_GPL(pcpu_base_addr);
55219
ae4e228f 55220 static const int *pcpu_unit_map __read_mostly; /* cpu -> unit */
16454cff
MT
55221diff -urNp linux-2.6.38.1/mm/rmap.c linux-2.6.38.1/mm/rmap.c
55222--- linux-2.6.38.1/mm/rmap.c 2011-03-14 21:20:32.000000000 -0400
55223+++ linux-2.6.38.1/mm/rmap.c 2011-03-21 18:31:35.000000000 -0400
6892158b 55224@@ -117,6 +117,10 @@ int anon_vma_prepare(struct vm_area_stru
df50ba0c
MT
55225 struct anon_vma *anon_vma = vma->anon_vma;
55226 struct anon_vma_chain *avc;
55227
55228+#ifdef CONFIG_PAX_SEGMEXEC
55229+ struct anon_vma_chain *avc_m = NULL;
55230+#endif
55231+
55232 might_sleep();
55233 if (unlikely(!anon_vma)) {
58c5fc13 55234 struct mm_struct *mm = vma->vm_mm;
6892158b 55235@@ -126,6 +130,12 @@ int anon_vma_prepare(struct vm_area_stru
df50ba0c
MT
55236 if (!avc)
55237 goto out_enomem;
55238
55239+#ifdef CONFIG_PAX_SEGMEXEC
55240+ avc_m = anon_vma_chain_alloc();
55241+ if (!avc_m)
55242+ goto out_enomem_free_avc;
55243+#endif
58c5fc13
MT
55244+
55245 anon_vma = find_mergeable_anon_vma(vma);
55246 allocated = NULL;
55247 if (!anon_vma) {
6892158b 55248@@ -144,6 +154,21 @@ int anon_vma_prepare(struct vm_area_stru
57199397
MT
55249 /* page_table_lock to protect against threads */
55250 spin_lock(&mm->page_table_lock);
55251 if (likely(!vma->anon_vma)) {
58c5fc13
MT
55252+
55253+#ifdef CONFIG_PAX_SEGMEXEC
57199397
MT
55254+ struct vm_area_struct *vma_m = pax_find_mirror_vma(vma);
55255+
58c5fc13 55256+ if (vma_m) {
df50ba0c 55257+ BUG_ON(vma_m->anon_vma);
58c5fc13 55258+ vma_m->anon_vma = anon_vma;
df50ba0c
MT
55259+ avc_m->anon_vma = anon_vma;
55260+ avc_m->vma = vma;
55261+ list_add(&avc_m->same_vma, &vma_m->anon_vma_chain);
55262+ list_add(&avc_m->same_anon_vma, &anon_vma->head);
55263+ avc_m = NULL;
58c5fc13
MT
55264+ }
55265+#endif
55266+
57199397
MT
55267 vma->anon_vma = anon_vma;
55268 avc->anon_vma = anon_vma;
55269 avc->vma = vma;
6892158b 55270@@ -157,12 +182,24 @@ int anon_vma_prepare(struct vm_area_stru
df50ba0c
MT
55271
55272 if (unlikely(allocated))
55273 anon_vma_free(allocated);
55274+
55275+#ifdef CONFIG_PAX_SEGMEXEC
55276+ if (unlikely(avc_m))
55277+ anon_vma_chain_free(avc_m);
55278+#endif
55279+
55280 if (unlikely(avc))
55281 anon_vma_chain_free(avc);
55282 }
55283 return 0;
55284
55285 out_enomem_free_avc:
55286+
55287+#ifdef CONFIG_PAX_SEGMEXEC
55288+ if (avc_m)
55289+ anon_vma_chain_free(avc_m);
55290+#endif
55291+
55292 anon_vma_chain_free(avc);
55293 out_enomem:
55294 return -ENOMEM;
16454cff 55295@@ -189,7 +226,7 @@ static void anon_vma_chain_link(struct v
57199397
MT
55296 * Attach the anon_vmas from src to dst.
55297 * Returns 0 on success, -ENOMEM on failure.
55298 */
55299-int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
55300+int anon_vma_clone(struct vm_area_struct *dst, const struct vm_area_struct *src)
55301 {
55302 struct anon_vma_chain *avc, *pavc;
55303
16454cff 55304@@ -211,7 +248,7 @@ int anon_vma_clone(struct vm_area_struct
57199397
MT
55305 * the corresponding VMA in the parent process is attached to.
55306 * Returns 0 on success, non-zero on failure.
55307 */
55308-int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
55309+int anon_vma_fork(struct vm_area_struct *vma, const struct vm_area_struct *pvma)
55310 {
55311 struct anon_vma_chain *avc;
55312 struct anon_vma *anon_vma;
16454cff
MT
55313diff -urNp linux-2.6.38.1/mm/shmem.c linux-2.6.38.1/mm/shmem.c
55314--- linux-2.6.38.1/mm/shmem.c 2011-03-14 21:20:32.000000000 -0400
55315+++ linux-2.6.38.1/mm/shmem.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
55316@@ -31,7 +31,7 @@
55317 #include <linux/percpu_counter.h>
58c5fc13 55318 #include <linux/swap.h>
58c5fc13
MT
55319
55320-static struct vfsmount *shm_mnt;
55321+struct vfsmount *shm_mnt;
55322
55323 #ifdef CONFIG_SHMEM
55324 /*
c52201e0
MT
55325@@ -1070,6 +1070,8 @@ static int shmem_writepage(struct page *
55326 goto unlock;
55327 }
55328 entry = shmem_swp_entry(info, index, NULL);
55329+ if (!entry)
55330+ goto unlock;
55331 if (entry->val) {
55332 /*
55333 * The more uptodate page coming down from a stacked
16454cff
MT
55334diff -urNp linux-2.6.38.1/mm/slab.c linux-2.6.38.1/mm/slab.c
55335--- linux-2.6.38.1/mm/slab.c 2011-03-14 21:20:32.000000000 -0400
55336+++ linux-2.6.38.1/mm/slab.c 2011-03-21 18:31:35.000000000 -0400
6892158b 55337@@ -284,7 +284,7 @@ struct kmem_list3 {
58c5fc13
MT
55338 * Need this for bootstrapping a per node allocator.
55339 */
55340 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
16454cff
MT
55341-static struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
55342+static struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
58c5fc13
MT
55343 #define CACHE_CACHE 0
55344 #define SIZE_AC MAX_NUMNODES
55345 #define SIZE_L3 (2 * MAX_NUMNODES)
6892158b 55346@@ -534,7 +534,7 @@ static inline void *index_to_obj(struct
58c5fc13
MT
55347 * reciprocal_divide(offset, cache->reciprocal_buffer_size)
55348 */
55349 static inline unsigned int obj_to_index(const struct kmem_cache *cache,
55350- const struct slab *slab, void *obj)
55351+ const struct slab *slab, const void *obj)
55352 {
55353 u32 offset = (obj - slab->s_mem);
55354 return reciprocal_divide(offset, cache->reciprocal_buffer_size);
6892158b 55355@@ -560,14 +560,14 @@ struct cache_names {
58c5fc13
MT
55356 static struct cache_names __initdata cache_names[] = {
55357 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
55358 #include <linux/kmalloc_sizes.h>
55359- {NULL,}
55360+ {NULL, NULL}
55361 #undef CACHE
55362 };
55363
55364 static struct arraycache_init initarray_cache __initdata =
55365- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
55366+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
55367 static struct arraycache_init initarray_generic =
55368- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
55369+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
55370
55371 /* internal cache of cache description objs */
55372 static struct kmem_cache cache_cache = {
16454cff 55373@@ -4535,15 +4535,66 @@ static const struct file_operations proc
58c5fc13 55374
df50ba0c 55375 static int __init slab_proc_init(void)
58c5fc13 55376 {
df50ba0c
MT
55377- proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
55378+ mode_t gr_mode = S_IRUGO;
55379+
55380+#ifdef CONFIG_GRKERNSEC_PROC_ADD
55381+ gr_mode = S_IRUSR;
55382+#endif
55383+
55384+ proc_create("slabinfo",S_IWUSR|gr_mode,NULL,&proc_slabinfo_operations);
55385 #ifdef CONFIG_DEBUG_SLAB_LEAK
55386- proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
55387+ proc_create("slab_allocators", gr_mode, NULL, &proc_slabstats_operations);
55388 #endif
55389 return 0;
55390 }
58c5fc13
MT
55391 module_init(slab_proc_init);
55392 #endif
55393
55394+void check_object_size(const void *ptr, unsigned long n, bool to)
55395+{
55396+
55397+#ifdef CONFIG_PAX_USERCOPY
55398+ struct kmem_cache *cachep;
55399+ struct slab *slabp;
55400+ struct page *page;
55401+ unsigned int objnr;
55402+ unsigned long offset;
55403+
55404+ if (!n)
55405+ return;
55406+
55407+ if (ZERO_OR_NULL_PTR(ptr))
55408+ goto report;
55409+
55410+ if (!virt_addr_valid(ptr))
55411+ return;
55412+
55413+ page = virt_to_head_page(ptr);
55414+
ae4e228f
MT
55415+ if (!PageSlab(page)) {
55416+ if (object_is_on_stack(ptr, n) == -1)
55417+ goto report;
58c5fc13 55418+ return;
ae4e228f 55419+ }
58c5fc13
MT
55420+
55421+ cachep = page_get_cache(page);
55422+ slabp = page_get_slab(page);
55423+ objnr = obj_to_index(cachep, slabp, ptr);
55424+ BUG_ON(objnr >= cachep->num);
55425+ offset = ptr - index_to_obj(cachep, slabp, objnr) - obj_offset(cachep);
55426+ if (offset <= obj_size(cachep) && n <= obj_size(cachep) - offset)
55427+ return;
55428+
55429+report:
55430+ if (to)
55431+ pax_report_leak_to_user(ptr, n);
55432+ else
55433+ pax_report_overflow_from_user(ptr, n);
55434+#endif
55435+
55436+}
55437+EXPORT_SYMBOL(check_object_size);
55438+
55439 /**
55440 * ksize - get the actual amount of memory allocated for a given object
55441 * @objp: Pointer to the object
16454cff
MT
55442diff -urNp linux-2.6.38.1/mm/slob.c linux-2.6.38.1/mm/slob.c
55443--- linux-2.6.38.1/mm/slob.c 2011-03-14 21:20:32.000000000 -0400
55444+++ linux-2.6.38.1/mm/slob.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
55445@@ -29,7 +29,7 @@
55446 * If kmalloc is asked for objects of PAGE_SIZE or larger, it calls
55447 * alloc_pages() directly, allocating compound pages so the page order
55448 * does not have to be separately tracked, and also stores the exact
55449- * allocation size in page->private so that it can be used to accurately
55450+ * allocation size in slob_page->size so that it can be used to accurately
55451 * provide ksize(). These objects are detected in kfree() because slob_page()
55452 * is false for them.
55453 *
55454@@ -58,6 +58,7 @@
55455 */
55456
55457 #include <linux/kernel.h>
55458+#include <linux/sched.h>
55459 #include <linux/slab.h>
55460 #include <linux/mm.h>
55461 #include <linux/swap.h> /* struct reclaim_state */
6892158b 55462@@ -102,7 +103,8 @@ struct slob_page {
58c5fc13
MT
55463 unsigned long flags; /* mandatory */
55464 atomic_t _count; /* mandatory */
55465 slobidx_t units; /* free units left in page */
55466- unsigned long pad[2];
55467+ unsigned long pad[1];
55468+ unsigned long size; /* size when >=PAGE_SIZE */
55469 slob_t *free; /* first free slob_t in page */
55470 struct list_head list; /* linked list of free pages */
55471 };
6892158b 55472@@ -135,7 +137,7 @@ static LIST_HEAD(free_slob_large);
58c5fc13
MT
55473 */
55474 static inline int is_slob_page(struct slob_page *sp)
55475 {
55476- return PageSlab((struct page *)sp);
55477+ return PageSlab((struct page *)sp) && !sp->size;
55478 }
55479
55480 static inline void set_slob_page(struct slob_page *sp)
6892158b 55481@@ -150,7 +152,7 @@ static inline void clear_slob_page(struc
58c5fc13
MT
55482
55483 static inline struct slob_page *slob_page(const void *addr)
55484 {
55485- return (struct slob_page *)virt_to_page(addr);
55486+ return (struct slob_page *)virt_to_head_page(addr);
55487 }
55488
55489 /*
6892158b 55490@@ -210,7 +212,7 @@ static void set_slob(slob_t *s, slobidx_
58c5fc13
MT
55491 /*
55492 * Return the size of a slob block.
55493 */
55494-static slobidx_t slob_units(slob_t *s)
55495+static slobidx_t slob_units(const slob_t *s)
55496 {
55497 if (s->units > 0)
55498 return s->units;
6892158b 55499@@ -220,7 +222,7 @@ static slobidx_t slob_units(slob_t *s)
58c5fc13
MT
55500 /*
55501 * Return the next free slob block pointer after this one.
55502 */
55503-static slob_t *slob_next(slob_t *s)
55504+static slob_t *slob_next(const slob_t *s)
55505 {
55506 slob_t *base = (slob_t *)((unsigned long)s & PAGE_MASK);
55507 slobidx_t next;
6892158b 55508@@ -235,7 +237,7 @@ static slob_t *slob_next(slob_t *s)
58c5fc13
MT
55509 /*
55510 * Returns true if s is the last free block in its page.
55511 */
55512-static int slob_last(slob_t *s)
55513+static int slob_last(const slob_t *s)
55514 {
55515 return !((unsigned long)slob_next(s) & ~PAGE_MASK);
55516 }
6892158b 55517@@ -254,6 +256,7 @@ static void *slob_new_pages(gfp_t gfp, i
58c5fc13
MT
55518 if (!page)
55519 return NULL;
55520
55521+ set_slob_page(page);
55522 return page_address(page);
55523 }
55524
6892158b 55525@@ -370,11 +373,11 @@ static void *slob_alloc(size_t size, gfp
58c5fc13
MT
55526 if (!b)
55527 return NULL;
55528 sp = slob_page(b);
55529- set_slob_page(sp);
55530
55531 spin_lock_irqsave(&slob_lock, flags);
55532 sp->units = SLOB_UNITS(PAGE_SIZE);
55533 sp->free = b;
55534+ sp->size = 0;
55535 INIT_LIST_HEAD(&sp->list);
55536 set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
55537 set_slob_page_free(sp, slob_list);
6892158b 55538@@ -476,10 +479,9 @@ out:
57199397
MT
55539 * End of slob allocator proper. Begin kmem_cache_alloc and kmalloc frontend.
55540 */
58c5fc13
MT
55541
55542-void *__kmalloc_node(size_t size, gfp_t gfp, int node)
55543+static void *__kmalloc_node_align(size_t size, gfp_t gfp, int node, int align)
55544 {
55545- unsigned int *m;
55546- int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
55547+ slob_t *m;
55548 void *ret;
55549
55550 lockdep_trace_alloc(gfp);
6892158b 55551@@ -492,7 +494,10 @@ void *__kmalloc_node(size_t size, gfp_t
58c5fc13
MT
55552
55553 if (!m)
55554 return NULL;
55555- *m = size;
55556+ BUILD_BUG_ON(ARCH_KMALLOC_MINALIGN < 2 * SLOB_UNIT);
55557+ BUILD_BUG_ON(ARCH_SLAB_MINALIGN < 2 * SLOB_UNIT);
55558+ m[0].units = size;
55559+ m[1].units = align;
55560 ret = (void *)m + align;
55561
55562 trace_kmalloc_node(_RET_IP_, ret,
bc901d79
MT
55563@@ -504,9 +509,9 @@ void *__kmalloc_node(size_t size, gfp_t
55564 gfp |= __GFP_COMP;
55565 ret = slob_new_pages(gfp, order, node);
58c5fc13
MT
55566 if (ret) {
55567- struct page *page;
55568- page = virt_to_page(ret);
55569- page->private = size;
55570+ struct slob_page *sp;
55571+ sp = slob_page(ret);
55572+ sp->size = size;
55573 }
55574
55575 trace_kmalloc_node(_RET_IP_, ret,
bc901d79 55576@@ -516,6 +521,13 @@ void *__kmalloc_node(size_t size, gfp_t
58c5fc13
MT
55577 kmemleak_alloc(ret, size, 1, gfp);
55578 return ret;
55579 }
55580+
55581+void *__kmalloc_node(size_t size, gfp_t gfp, int node)
55582+{
55583+ int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
55584+
55585+ return __kmalloc_node_align(size, gfp, node, align);
55586+}
55587 EXPORT_SYMBOL(__kmalloc_node);
55588
55589 void kfree(const void *block)
bc901d79 55590@@ -531,13 +543,84 @@ void kfree(const void *block)
58c5fc13
MT
55591 sp = slob_page(block);
55592 if (is_slob_page(sp)) {
55593 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
55594- unsigned int *m = (unsigned int *)(block - align);
55595- slob_free(m, *m + align);
55596- } else
55597+ slob_t *m = (slob_t *)(block - align);
55598+ slob_free(m, m[0].units + align);
55599+ } else {
55600+ clear_slob_page(sp);
55601+ free_slob_page(sp);
55602+ sp->size = 0;
55603 put_page(&sp->page);
55604+ }
55605 }
55606 EXPORT_SYMBOL(kfree);
55607
55608+void check_object_size(const void *ptr, unsigned long n, bool to)
55609+{
55610+
55611+#ifdef CONFIG_PAX_USERCOPY
55612+ struct slob_page *sp;
55613+ const slob_t *free;
55614+ const void *base;
55615+
55616+ if (!n)
55617+ return;
55618+
55619+ if (ZERO_OR_NULL_PTR(ptr))
55620+ goto report;
55621+
55622+ if (!virt_addr_valid(ptr))
55623+ return;
55624+
55625+ sp = slob_page(ptr);
ae4e228f
MT
55626+ if (!PageSlab((struct page*)sp)) {
55627+ if (object_is_on_stack(ptr, n) == -1)
55628+ goto report;
58c5fc13 55629+ return;
ae4e228f 55630+ }
58c5fc13
MT
55631+
55632+ if (sp->size) {
55633+ base = page_address(&sp->page);
55634+ if (base <= ptr && n <= sp->size - (ptr - base))
55635+ return;
55636+ goto report;
55637+ }
55638+
55639+ /* some tricky double walking to find the chunk */
55640+ base = (void *)((unsigned long)ptr & PAGE_MASK);
55641+ free = sp->free;
55642+
55643+ while (!slob_last(free) && (void *)free <= ptr) {
55644+ base = free + slob_units(free);
55645+ free = slob_next(free);
55646+ }
55647+
55648+ while (base < (void *)free) {
55649+ slobidx_t m = ((slob_t *)base)[0].units, align = ((slob_t *)base)[1].units;
55650+ int size = SLOB_UNIT * SLOB_UNITS(m + align);
55651+ int offset;
55652+
55653+ if (ptr < base + align)
55654+ goto report;
55655+
55656+ offset = ptr - base - align;
55657+ if (offset < m) {
55658+ if (n <= m - offset)
55659+ return;
55660+ goto report;
55661+ }
55662+ base += size;
55663+ }
55664+
55665+report:
55666+ if (to)
55667+ pax_report_leak_to_user(ptr, n);
55668+ else
55669+ pax_report_overflow_from_user(ptr, n);
55670+#endif
55671+
55672+}
55673+EXPORT_SYMBOL(check_object_size);
55674+
55675 /* can't use ksize for kmem_cache_alloc memory, only kmalloc */
55676 size_t ksize(const void *block)
55677 {
bc901d79 55678@@ -550,10 +633,10 @@ size_t ksize(const void *block)
58c5fc13
MT
55679 sp = slob_page(block);
55680 if (is_slob_page(sp)) {
55681 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
55682- unsigned int *m = (unsigned int *)(block - align);
55683- return SLOB_UNITS(*m) * SLOB_UNIT;
55684+ slob_t *m = (slob_t *)(block - align);
55685+ return SLOB_UNITS(m[0].units) * SLOB_UNIT;
55686 } else
55687- return sp->page.private;
55688+ return sp->size;
55689 }
55690 EXPORT_SYMBOL(ksize);
55691
bc901d79 55692@@ -608,17 +691,25 @@ void *kmem_cache_alloc_node(struct kmem_
58c5fc13
MT
55693 {
55694 void *b;
55695
55696+#ifdef CONFIG_PAX_USERCOPY
55697+ b = __kmalloc_node_align(c->size, flags, node, c->align);
55698+#else
55699 if (c->size < PAGE_SIZE) {
55700 b = slob_alloc(c->size, flags, c->align, node);
55701 trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
55702 SLOB_UNITS(c->size) * SLOB_UNIT,
55703 flags, node);
55704 } else {
55705+ struct slob_page *sp;
55706+
55707 b = slob_new_pages(flags, get_order(c->size), node);
55708+ sp = slob_page(b);
55709+ sp->size = c->size;
55710 trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
55711 PAGE_SIZE << get_order(c->size),
55712 flags, node);
55713 }
55714+#endif
55715
55716 if (c->ctor)
55717 c->ctor(b);
bc901d79 55718@@ -630,10 +721,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
58c5fc13
MT
55719
55720 static void __kmem_cache_free(void *b, int size)
55721 {
55722- if (size < PAGE_SIZE)
55723+ struct slob_page *sp = slob_page(b);
55724+
55725+ if (is_slob_page(sp))
55726 slob_free(b, size);
55727- else
55728+ else {
55729+ clear_slob_page(sp);
55730+ free_slob_page(sp);
55731+ sp->size = 0;
55732 slob_free_pages(b, get_order(size));
55733+ }
55734 }
55735
55736 static void kmem_rcu_free(struct rcu_head *head)
bc901d79 55737@@ -646,14 +743,23 @@ static void kmem_rcu_free(struct rcu_hea
58c5fc13
MT
55738
55739 void kmem_cache_free(struct kmem_cache *c, void *b)
55740 {
55741+ int size = c->size;
55742+
55743+#ifdef CONFIG_PAX_USERCOPY
55744+ if (size + c->align < PAGE_SIZE) {
55745+ size += c->align;
55746+ b -= c->align;
55747+ }
55748+#endif
55749+
55750 kmemleak_free_recursive(b, c->flags);
55751 if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
55752 struct slob_rcu *slob_rcu;
55753- slob_rcu = b + (c->size - sizeof(struct slob_rcu));
58c5fc13 55754- slob_rcu->size = c->size;
6892158b 55755+ slob_rcu = b + (size - sizeof(struct slob_rcu));
58c5fc13
MT
55756+ slob_rcu->size = size;
55757 call_rcu(&slob_rcu->head, kmem_rcu_free);
55758 } else {
55759- __kmem_cache_free(b, c->size);
55760+ __kmem_cache_free(b, size);
55761 }
55762
55763 trace_kmem_cache_free(_RET_IP_, b);
16454cff
MT
55764diff -urNp linux-2.6.38.1/mm/slub.c linux-2.6.38.1/mm/slub.c
55765--- linux-2.6.38.1/mm/slub.c 2011-03-14 21:20:32.000000000 -0400
55766+++ linux-2.6.38.1/mm/slub.c 2011-03-21 18:31:35.000000000 -0400
55767@@ -390,7 +390,7 @@ static void print_track(const char *s, s
bc901d79
MT
55768 if (!t->addr)
55769 return;
55770
55771- printk(KERN_ERR "INFO: %s in %pS age=%lu cpu=%u pid=%d\n",
55772+ printk(KERN_ERR "INFO: %s in %pA age=%lu cpu=%u pid=%d\n",
55773 s, (void *)t->addr, jiffies - t->when, t->cpu, t->pid);
55774 }
55775
16454cff 55776@@ -1927,6 +1927,8 @@ void kmem_cache_free(struct kmem_cache *
ae4e228f
MT
55777
55778 page = virt_to_head_page(x);
55779
55780+ BUG_ON(!PageSlab(page));
55781+
55782 slab_free(s, page, x, _RET_IP_);
55783
55784 trace_kmem_cache_free(_RET_IP_, x);
16454cff 55785@@ -1960,7 +1962,7 @@ static int slub_min_objects;
58c5fc13
MT
55786 * Merge control. If this is set then no merging of slab caches will occur.
55787 * (Could be removed. This was introduced to pacify the merge skeptics.)
55788 */
55789-static int slub_nomerge;
55790+static int slub_nomerge = 1;
55791
55792 /*
55793 * Calculate the order of allocation given an slab object size.
16454cff 55794@@ -2370,7 +2372,7 @@ static int kmem_cache_open(struct kmem_c
58c5fc13
MT
55795 * list to avoid pounding the page allocator excessively.
55796 */
55797 set_min_partial(s, ilog2(s->size));
55798- s->refcount = 1;
55799+ atomic_set(&s->refcount, 1);
55800 #ifdef CONFIG_NUMA
55801 s->remote_node_defrag_ratio = 1000;
55802 #endif
16454cff 55803@@ -2482,8 +2484,7 @@ static inline int kmem_cache_close(struc
58c5fc13
MT
55804 void kmem_cache_destroy(struct kmem_cache *s)
55805 {
55806 down_write(&slub_lock);
55807- s->refcount--;
55808- if (!s->refcount) {
55809+ if (atomic_dec_and_test(&s->refcount)) {
55810 list_del(&s->list);
58c5fc13 55811 if (kmem_cache_close(s)) {
6892158b 55812 printk(KERN_ERR "SLUB %s: %s called for cache that "
16454cff 55813@@ -2693,6 +2694,46 @@ void *__kmalloc_node(size_t size, gfp_t
58c5fc13
MT
55814 EXPORT_SYMBOL(__kmalloc_node);
55815 #endif
55816
55817+void check_object_size(const void *ptr, unsigned long n, bool to)
55818+{
55819+
55820+#ifdef CONFIG_PAX_USERCOPY
55821+ struct page *page;
55822+ struct kmem_cache *s;
55823+ unsigned long offset;
55824+
55825+ if (!n)
55826+ return;
55827+
55828+ if (ZERO_OR_NULL_PTR(ptr))
55829+ goto report;
55830+
55831+ if (!virt_addr_valid(ptr))
55832+ return;
55833+
16454cff 55834+ page = virt_to_head_page(ptr);
58c5fc13 55835+
16454cff 55836+ if (!PageSlab(page)) {
ae4e228f
MT
55837+ if (object_is_on_stack(ptr, n) == -1)
55838+ goto report;
58c5fc13 55839+ return;
ae4e228f 55840+ }
58c5fc13
MT
55841+
55842+ s = page->slab;
55843+ offset = (ptr - page_address(page)) % s->size;
55844+ if (offset <= s->objsize && n <= s->objsize - offset)
55845+ return;
55846+
55847+report:
55848+ if (to)
55849+ pax_report_leak_to_user(ptr, n);
55850+ else
55851+ pax_report_overflow_from_user(ptr, n);
55852+#endif
55853+
55854+}
55855+EXPORT_SYMBOL(check_object_size);
55856+
55857 size_t ksize(const void *object)
55858 {
55859 struct page *page;
16454cff 55860@@ -2958,7 +2999,7 @@ static void __init kmem_cache_bootstrap_
bc901d79
MT
55861 int node;
55862
55863 list_add(&s->list, &slab_caches);
55864- s->refcount = -1;
55865+ atomic_set(&s->refcount, -1);
55866
55867 for_each_node_state(node, N_NORMAL_MEMORY) {
55868 struct kmem_cache_node *n = get_node(s, node);
16454cff 55869@@ -3153,7 +3194,7 @@ static int slab_unmergeable(struct kmem_
58c5fc13
MT
55870 /*
55871 * We may have set a slab to be unmergeable during bootstrap.
55872 */
55873- if (s->refcount < 0)
55874+ if (atomic_read(&s->refcount) < 0)
55875 return 1;
55876
55877 return 0;
16454cff 55878@@ -3212,7 +3253,7 @@ struct kmem_cache *kmem_cache_create(con
df50ba0c
MT
55879 down_write(&slub_lock);
55880 s = find_mergeable(size, align, flags, name, ctor);
58c5fc13 55881 if (s) {
58c5fc13
MT
55882- s->refcount++;
55883+ atomic_inc(&s->refcount);
55884 /*
55885 * Adjust the object sizes so that we clear
55886 * the complete object on kzalloc.
16454cff 55887@@ -3221,7 +3262,7 @@ struct kmem_cache *kmem_cache_create(con
6892158b 55888 s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
58c5fc13
MT
55889
55890 if (sysfs_slab_alias(s, name)) {
58c5fc13
MT
55891- s->refcount--;
55892+ atomic_dec(&s->refcount);
58c5fc13
MT
55893 goto err;
55894 }
6892158b 55895 up_write(&slub_lock);
16454cff 55896@@ -3954,7 +3995,7 @@ SLAB_ATTR_RO(ctor);
58c5fc13
MT
55897
55898 static ssize_t aliases_show(struct kmem_cache *s, char *buf)
55899 {
55900- return sprintf(buf, "%d\n", s->refcount - 1);
55901+ return sprintf(buf, "%d\n", atomic_read(&s->refcount) - 1);
55902 }
55903 SLAB_ATTR_RO(aliases);
55904
16454cff 55905@@ -4691,7 +4732,13 @@ static const struct file_operations proc
58c5fc13 55906
df50ba0c
MT
55907 static int __init slab_proc_init(void)
55908 {
55909- proc_create("slabinfo", S_IRUGO, NULL, &proc_slabinfo_operations);
55910+ mode_t gr_mode = S_IRUGO;
55911+
55912+#ifdef CONFIG_GRKERNSEC_PROC_ADD
55913+ gr_mode = S_IRUSR;
55914+#endif
55915+
55916+ proc_create("slabinfo", gr_mode, NULL, &proc_slabinfo_operations);
58c5fc13
MT
55917 return 0;
55918 }
df50ba0c 55919 module_init(slab_proc_init);
16454cff
MT
55920diff -urNp linux-2.6.38.1/mm/util.c linux-2.6.38.1/mm/util.c
55921--- linux-2.6.38.1/mm/util.c 2011-03-14 21:20:32.000000000 -0400
55922+++ linux-2.6.38.1/mm/util.c 2011-03-21 18:31:35.000000000 -0400
55923@@ -219,6 +219,12 @@ EXPORT_SYMBOL(strndup_user);
58c5fc13
MT
55924 void arch_pick_mmap_layout(struct mm_struct *mm)
55925 {
55926 mm->mmap_base = TASK_UNMAPPED_BASE;
55927+
55928+#ifdef CONFIG_PAX_RANDMMAP
55929+ if (mm->pax_flags & MF_PAX_RANDMMAP)
55930+ mm->mmap_base += mm->delta_mmap;
55931+#endif
55932+
55933 mm->get_unmapped_area = arch_get_unmapped_area;
55934 mm->unmap_area = arch_unmap_area;
55935 }
16454cff
MT
55936diff -urNp linux-2.6.38.1/mm/vmalloc.c linux-2.6.38.1/mm/vmalloc.c
55937--- linux-2.6.38.1/mm/vmalloc.c 2011-03-14 21:20:32.000000000 -0400
55938+++ linux-2.6.38.1/mm/vmalloc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 55939@@ -39,8 +39,19 @@ static void vunmap_pte_range(pmd_t *pmd,
ae4e228f
MT
55940
55941 pte = pte_offset_kernel(pmd, addr);
55942 do {
55943- pte_t ptent = ptep_get_and_clear(&init_mm, addr, pte);
55944- WARN_ON(!pte_none(ptent) && !pte_present(ptent));
55945+
55946+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
55947+ if ((unsigned long)MODULES_EXEC_VADDR <= addr && addr < (unsigned long)MODULES_EXEC_END) {
55948+ BUG_ON(!pte_exec(*pte));
55949+ set_pte_at(&init_mm, addr, pte, pfn_pte(__pa(addr) >> PAGE_SHIFT, PAGE_KERNEL_EXEC));
55950+ continue;
55951+ }
55952+#endif
55953+
55954+ {
55955+ pte_t ptent = ptep_get_and_clear(&init_mm, addr, pte);
55956+ WARN_ON(!pte_none(ptent) && !pte_present(ptent));
55957+ }
55958 } while (pte++, addr += PAGE_SIZE, addr != end);
55959 }
55960
bc901d79 55961@@ -91,6 +102,7 @@ static int vmap_pte_range(pmd_t *pmd, un
58c5fc13
MT
55962 unsigned long end, pgprot_t prot, struct page **pages, int *nr)
55963 {
55964 pte_t *pte;
55965+ int ret = -ENOMEM;
58c5fc13
MT
55966
55967 /*
55968 * nr is a running index into the array which helps higher level
bc901d79 55969@@ -100,17 +112,30 @@ static int vmap_pte_range(pmd_t *pmd, un
58c5fc13
MT
55970 pte = pte_alloc_kernel(pmd, addr);
55971 if (!pte)
55972 return -ENOMEM;
55973+
ae4e228f 55974+ pax_open_kernel();
58c5fc13
MT
55975 do {
55976 struct page *page = pages[*nr];
55977
55978- if (WARN_ON(!pte_none(*pte)))
55979- return -EBUSY;
55980- if (WARN_ON(!page))
55981- return -ENOMEM;
ae4e228f 55982+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
57199397 55983+ if (pgprot_val(prot) & _PAGE_NX)
ae4e228f
MT
55984+#endif
55985+
58c5fc13
MT
55986+ if (WARN_ON(!pte_none(*pte))) {
55987+ ret = -EBUSY;
55988+ goto out;
55989+ }
55990+ if (WARN_ON(!page)) {
55991+ ret = -ENOMEM;
55992+ goto out;
55993+ }
55994 set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
55995 (*nr)++;
55996 } while (pte++, addr += PAGE_SIZE, addr != end);
55997- return 0;
55998+ ret = 0;
55999+out:
ae4e228f
MT
56000+ pax_close_kernel();
56001+ return ret;
56002 }
56003
56004 static int vmap_pmd_range(pud_t *pud, unsigned long addr,
bc901d79 56005@@ -191,11 +216,20 @@ int is_vmalloc_or_module_addr(const void
ae4e228f
MT
56006 * and fall back on vmalloc() if that fails. Others
56007 * just put it in the vmalloc space.
56008 */
56009-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
56010+#ifdef CONFIG_MODULES
56011+#ifdef MODULES_VADDR
56012 unsigned long addr = (unsigned long)x;
56013 if (addr >= MODULES_VADDR && addr < MODULES_END)
56014 return 1;
56015 #endif
58c5fc13 56016+
ae4e228f
MT
56017+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
56018+ if (x >= (const void *)MODULES_EXEC_VADDR && x < (const void *)MODULES_EXEC_END)
56019+ return 1;
58c5fc13
MT
56020+#endif
56021+
ae4e228f
MT
56022+#endif
56023+
56024 return is_vmalloc_addr(x);
58c5fc13
MT
56025 }
56026
bc901d79 56027@@ -216,8 +250,14 @@ struct page *vmalloc_to_page(const void
57199397
MT
56028
56029 if (!pgd_none(*pgd)) {
56030 pud_t *pud = pud_offset(pgd, addr);
56031+#ifdef CONFIG_X86
56032+ if (!pud_large(*pud))
56033+#endif
56034 if (!pud_none(*pud)) {
56035 pmd_t *pmd = pmd_offset(pud, addr);
56036+#ifdef CONFIG_X86
56037+ if (!pmd_large(*pmd))
56038+#endif
56039 if (!pmd_none(*pmd)) {
56040 pte_t *ptep, pte;
56041
16454cff 56042@@ -1244,6 +1284,16 @@ static struct vm_struct *__get_vm_area_n
ae4e228f 56043 struct vm_struct *area;
58c5fc13
MT
56044
56045 BUG_ON(in_interrupt());
56046+
df50ba0c 56047+#if defined(CONFIG_MODULES) && defined(CONFIG_X86) && defined(CONFIG_PAX_KERNEXEC)
58c5fc13
MT
56048+ if (flags & VM_KERNEXEC) {
56049+ if (start != VMALLOC_START || end != VMALLOC_END)
56050+ return NULL;
df50ba0c
MT
56051+ start = (unsigned long)MODULES_EXEC_VADDR;
56052+ end = (unsigned long)MODULES_EXEC_END;
58c5fc13
MT
56053+ }
56054+#endif
56055+
56056 if (flags & VM_IOREMAP) {
56057 int bit = fls(size);
56058
16454cff 56059@@ -1462,6 +1512,11 @@ void *vmap(struct page **pages, unsigned
ae4e228f 56060 if (count > totalram_pages)
58c5fc13
MT
56061 return NULL;
56062
df50ba0c 56063+#if defined(CONFIG_MODULES) && defined(CONFIG_X86) && defined(CONFIG_PAX_KERNEXEC)
58c5fc13
MT
56064+ if (!(pgprot_val(prot) & _PAGE_NX))
56065+ flags |= VM_KERNEXEC;
56066+#endif
56067+
56068 area = get_vm_area_caller((count << PAGE_SHIFT), flags,
56069 __builtin_return_address(0));
56070 if (!area)
16454cff 56071@@ -1558,6 +1613,13 @@ void *__vmalloc_node_range(unsigned long
ae4e228f 56072 if (!size || (size >> PAGE_SHIFT) > totalram_pages)
58c5fc13
MT
56073 return NULL;
56074
df50ba0c 56075+#if defined(CONFIG_MODULES) && defined(CONFIG_X86) && defined(CONFIG_PAX_KERNEXEC)
58c5fc13 56076+ if (!(pgprot_val(prot) & _PAGE_NX))
ae4e228f 56077+ area = __get_vm_area_node(size, align, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
58c5fc13
MT
56078+ node, gfp_mask, caller);
56079+ else
56080+#endif
56081+
16454cff
MT
56082 area = __get_vm_area_node(size, align, VM_ALLOC, start, end, node,
56083 gfp_mask, caller);
58c5fc13 56084
16454cff
MT
56085@@ -1597,6 +1659,7 @@ static void *__vmalloc_node(unsigned lon
56086 gfp_mask, prot, node, caller);
58c5fc13
MT
56087 }
56088
56089+#undef __vmalloc
56090 void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
56091 {
ae4e228f 56092 return __vmalloc_node(size, 1, gfp_mask, prot, -1,
16454cff 56093@@ -1620,6 +1683,7 @@ static inline void *__vmalloc_node_flags
58c5fc13
MT
56094 * For tight control over page level allocator and protection flags
56095 * use __vmalloc() instead.
56096 */
56097+#undef vmalloc
56098 void *vmalloc(unsigned long size)
56099 {
bc901d79 56100 return __vmalloc_node_flags(size, -1, GFP_KERNEL | __GFP_HIGHMEM);
16454cff 56101@@ -1636,6 +1700,7 @@ EXPORT_SYMBOL(vmalloc);
bc901d79
MT
56102 * For tight control over page level allocator and protection flags
56103 * use __vmalloc() instead.
56104 */
56105+#undef vzalloc
56106 void *vzalloc(unsigned long size)
56107 {
56108 return __vmalloc_node_flags(size, -1,
16454cff 56109@@ -1650,6 +1715,7 @@ EXPORT_SYMBOL(vzalloc);
58c5fc13
MT
56110 * The resulting memory area is zeroed so it can be mapped to userspace
56111 * without leaking data.
56112 */
56113+#undef vmalloc_user
56114 void *vmalloc_user(unsigned long size)
56115 {
56116 struct vm_struct *area;
16454cff 56117@@ -1677,6 +1743,7 @@ EXPORT_SYMBOL(vmalloc_user);
58c5fc13
MT
56118 * For tight control over page level allocator and protection flags
56119 * use __vmalloc() instead.
56120 */
56121+#undef vmalloc_node
56122 void *vmalloc_node(unsigned long size, int node)
56123 {
ae4e228f 56124 return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
16454cff 56125@@ -1696,6 +1763,7 @@ EXPORT_SYMBOL(vmalloc_node);
bc901d79
MT
56126 * For tight control over page level allocator and protection flags
56127 * use __vmalloc_node() instead.
56128 */
56129+#undef vzalloc_node
56130 void *vzalloc_node(unsigned long size, int node)
56131 {
56132 return __vmalloc_node_flags(size, node,
16454cff 56133@@ -1718,10 +1786,10 @@ EXPORT_SYMBOL(vzalloc_node);
58c5fc13
MT
56134 * For tight control over page level allocator and protection flags
56135 * use __vmalloc() instead.
56136 */
56137-
56138+#undef vmalloc_exec
56139 void *vmalloc_exec(unsigned long size)
56140 {
ae4e228f
MT
56141- return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
56142+ return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC,
58c5fc13
MT
56143 -1, __builtin_return_address(0));
56144 }
56145
16454cff 56146@@ -1740,6 +1808,7 @@ void *vmalloc_exec(unsigned long size)
58c5fc13
MT
56147 * Allocate enough 32bit PA addressable pages to cover @size from the
56148 * page level allocator and map them into contiguous kernel virtual space.
56149 */
56150+#undef vmalloc_32
56151 void *vmalloc_32(unsigned long size)
56152 {
ae4e228f 56153 return __vmalloc_node(size, 1, GFP_VMALLOC32, PAGE_KERNEL,
16454cff 56154@@ -1754,6 +1823,7 @@ EXPORT_SYMBOL(vmalloc_32);
58c5fc13
MT
56155 * The resulting memory area is 32bit addressable and zeroed so it can be
56156 * mapped to userspace without leaking data.
56157 */
56158+#undef vmalloc_32_user
56159 void *vmalloc_32_user(unsigned long size)
56160 {
56161 struct vm_struct *area;
16454cff 56162@@ -2018,6 +2088,8 @@ int remap_vmalloc_range(struct vm_area_s
6892158b
MT
56163 unsigned long uaddr = vma->vm_start;
56164 unsigned long usize = vma->vm_end - vma->vm_start;
56165
56166+ BUG_ON(vma->vm_mirror);
56167+
56168 if ((PAGE_SIZE-1) & (unsigned long)addr)
56169 return -EINVAL;
56170
16454cff
MT
56171diff -urNp linux-2.6.38.1/mm/vmstat.c linux-2.6.38.1/mm/vmstat.c
56172--- linux-2.6.38.1/mm/vmstat.c 2011-03-14 21:20:32.000000000 -0400
56173+++ linux-2.6.38.1/mm/vmstat.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 56174@@ -78,7 +78,7 @@ void vm_events_fold_cpu(int cpu)
57199397
MT
56175 *
56176 * vm_stat contains the global counters
56177 */
56178-atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
56179+atomic_long_unchecked_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
56180 EXPORT_SYMBOL(vm_stat);
56181
56182 #ifdef CONFIG_SMP
16454cff 56183@@ -451,7 +451,7 @@ void refresh_cpu_vm_stats(int cpu)
57199397
MT
56184 v = p->vm_stat_diff[i];
56185 p->vm_stat_diff[i] = 0;
56186 local_irq_restore(flags);
56187- atomic_long_add(v, &zone->vm_stat[i]);
56188+ atomic_long_add_unchecked(v, &zone->vm_stat[i]);
56189 global_diff[i] += v;
56190 #ifdef CONFIG_NUMA
56191 /* 3 seconds idle till flush */
16454cff 56192@@ -489,7 +489,7 @@ void refresh_cpu_vm_stats(int cpu)
57199397
MT
56193
56194 for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
56195 if (global_diff[i])
56196- atomic_long_add(global_diff[i], &vm_stat[i]);
56197+ atomic_long_add_unchecked(global_diff[i], &vm_stat[i]);
56198 }
56199
56200 #endif
16454cff 56201@@ -1188,10 +1188,20 @@ static int __init setup_vmstat(void)
57199397
MT
56202 start_cpu_timer(cpu);
56203 #endif
56204 #ifdef CONFIG_PROC_FS
56205- proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
56206- proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
56207- proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
56208- proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
56209+ {
56210+ mode_t gr_mode = S_IRUGO;
56211+#ifdef CONFIG_GRKERNSEC_PROC_ADD
56212+ gr_mode = S_IRUSR;
56213+#endif
56214+ proc_create("buddyinfo", gr_mode, NULL, &fragmentation_file_operations);
56215+ proc_create("pagetypeinfo", gr_mode, NULL, &pagetypeinfo_file_ops);
bc901d79
MT
56216+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
56217+ proc_create("vmstat", gr_mode | S_IRGRP, NULL, &proc_vmstat_file_operations);
56218+#else
57199397 56219+ proc_create("vmstat", gr_mode, NULL, &proc_vmstat_file_operations);
bc901d79 56220+#endif
57199397
MT
56221+ proc_create("zoneinfo", gr_mode, NULL, &proc_zoneinfo_file_operations);
56222+ }
56223 #endif
56224 return 0;
56225 }
16454cff
MT
56226diff -urNp linux-2.6.38.1/net/8021q/vlan.c linux-2.6.38.1/net/8021q/vlan.c
56227--- linux-2.6.38.1/net/8021q/vlan.c 2011-03-14 21:20:32.000000000 -0400
56228+++ linux-2.6.38.1/net/8021q/vlan.c 2011-03-21 18:31:35.000000000 -0400
56229@@ -589,8 +589,7 @@ static int vlan_ioctl_handler(struct net
df50ba0c
MT
56230 err = -EPERM;
56231 if (!capable(CAP_NET_ADMIN))
56232 break;
56233- if ((args.u.name_type >= 0) &&
56234- (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
56235+ if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
56236 struct vlan_net *vn;
56237
56238 vn = net_generic(net, vlan_net_id);
16454cff
MT
56239diff -urNp linux-2.6.38.1/net/atm/atm_misc.c linux-2.6.38.1/net/atm/atm_misc.c
56240--- linux-2.6.38.1/net/atm/atm_misc.c 2011-03-14 21:20:32.000000000 -0400
56241+++ linux-2.6.38.1/net/atm/atm_misc.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 56242@@ -17,7 +17,7 @@ int atm_charge(struct atm_vcc *vcc, int
58c5fc13
MT
56243 if (atomic_read(&sk_atm(vcc)->sk_rmem_alloc) <= sk_atm(vcc)->sk_rcvbuf)
56244 return 1;
df50ba0c 56245 atm_return(vcc, truesize);
58c5fc13
MT
56246- atomic_inc(&vcc->stats->rx_drop);
56247+ atomic_inc_unchecked(&vcc->stats->rx_drop);
56248 return 0;
56249 }
df50ba0c
MT
56250 EXPORT_SYMBOL(atm_charge);
56251@@ -39,7 +39,7 @@ struct sk_buff *atm_alloc_charge(struct
58c5fc13
MT
56252 }
56253 }
df50ba0c 56254 atm_return(vcc, guess);
58c5fc13
MT
56255- atomic_inc(&vcc->stats->rx_drop);
56256+ atomic_inc_unchecked(&vcc->stats->rx_drop);
56257 return NULL;
56258 }
df50ba0c
MT
56259 EXPORT_SYMBOL(atm_alloc_charge);
56260@@ -86,7 +86,7 @@ EXPORT_SYMBOL(atm_pcr_goal);
58c5fc13 56261
df50ba0c 56262 void sonet_copy_stats(struct k_sonet_stats *from, struct sonet_stats *to)
58c5fc13
MT
56263 {
56264-#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
56265+#define __HANDLE_ITEM(i) to->i = atomic_read_unchecked(&from->i)
56266 __SONET_ITEMS
56267 #undef __HANDLE_ITEM
56268 }
df50ba0c 56269@@ -94,7 +94,7 @@ EXPORT_SYMBOL(sonet_copy_stats);
58c5fc13 56270
df50ba0c 56271 void sonet_subtract_stats(struct k_sonet_stats *from, struct sonet_stats *to)
58c5fc13 56272 {
df50ba0c 56273-#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
58c5fc13
MT
56274+#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i,&from->i)
56275 __SONET_ITEMS
56276 #undef __HANDLE_ITEM
56277 }
16454cff
MT
56278diff -urNp linux-2.6.38.1/net/atm/proc.c linux-2.6.38.1/net/atm/proc.c
56279--- linux-2.6.38.1/net/atm/proc.c 2011-03-14 21:20:32.000000000 -0400
56280+++ linux-2.6.38.1/net/atm/proc.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 56281@@ -45,9 +45,9 @@ static void add_stats(struct seq_file *s
58c5fc13
MT
56282 const struct k_atm_aal_stats *stats)
56283 {
56284 seq_printf(seq, "%s ( %d %d %d %d %d )", aal,
df50ba0c
MT
56285- atomic_read(&stats->tx), atomic_read(&stats->tx_err),
56286- atomic_read(&stats->rx), atomic_read(&stats->rx_err),
56287- atomic_read(&stats->rx_drop));
56288+ atomic_read_unchecked(&stats->tx),atomic_read_unchecked(&stats->tx_err),
56289+ atomic_read_unchecked(&stats->rx),atomic_read_unchecked(&stats->rx_err),
56290+ atomic_read_unchecked(&stats->rx_drop));
58c5fc13
MT
56291 }
56292
56293 static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev)
bc901d79 56294@@ -191,7 +191,12 @@ static void vcc_info(struct seq_file *se
57199397
MT
56295 {
56296 struct sock *sk = sk_atm(vcc);
56297
56298+#ifdef CONFIG_GRKERNSEC_HIDESYM
56299+ seq_printf(seq, "%p ", NULL);
56300+#else
56301 seq_printf(seq, "%p ", vcc);
56302+#endif
56303+
56304 if (!vcc->dev)
56305 seq_printf(seq, "Unassigned ");
56306 else
16454cff
MT
56307@@ -218,7 +223,11 @@ static void svc_info(struct seq_file *se
56308 {
56309 if (!vcc->dev)
56310 seq_printf(seq, sizeof(void *) == 4 ?
56311+#ifdef CONFIG_GRKERNSEC_HIDESYM
56312+ "N/A@%p%10s" : "N/A@%p%2s", NULL, "");
56313+#else
56314 "N/A@%p%10s" : "N/A@%p%2s", vcc, "");
56315+#endif
56316 else
56317 seq_printf(seq, "%3d %3d %5d ",
56318 vcc->dev->number, vcc->vpi, vcc->vci);
56319diff -urNp linux-2.6.38.1/net/atm/resources.c linux-2.6.38.1/net/atm/resources.c
56320--- linux-2.6.38.1/net/atm/resources.c 2011-03-14 21:20:32.000000000 -0400
56321+++ linux-2.6.38.1/net/atm/resources.c 2011-03-21 18:31:35.000000000 -0400
bc901d79 56322@@ -160,7 +160,7 @@ EXPORT_SYMBOL(atm_dev_deregister);
58c5fc13
MT
56323 static void copy_aal_stats(struct k_atm_aal_stats *from,
56324 struct atm_aal_stats *to)
56325 {
56326-#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
56327+#define __HANDLE_ITEM(i) to->i = atomic_read_unchecked(&from->i)
56328 __AAL_STAT_ITEMS
56329 #undef __HANDLE_ITEM
56330 }
bc901d79 56331@@ -168,7 +168,7 @@ static void copy_aal_stats(struct k_atm_
58c5fc13
MT
56332 static void subtract_aal_stats(struct k_atm_aal_stats *from,
56333 struct atm_aal_stats *to)
56334 {
56335-#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
56336+#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i, &from->i)
56337 __AAL_STAT_ITEMS
56338 #undef __HANDLE_ITEM
56339 }
16454cff
MT
56340diff -urNp linux-2.6.38.1/net/bluetooth/bnep/sock.c linux-2.6.38.1/net/bluetooth/bnep/sock.c
56341--- linux-2.6.38.1/net/bluetooth/bnep/sock.c 2011-03-14 21:20:32.000000000 -0400
56342+++ linux-2.6.38.1/net/bluetooth/bnep/sock.c 2011-03-21 18:31:35.000000000 -0400
56343@@ -88,6 +88,7 @@ static int bnep_sock_ioctl(struct socket
56344 sockfd_put(nsock);
56345 return -EBADFD;
56346 }
56347+ ca.device[sizeof(ca.device)-1] = 0;
56348
56349 err = bnep_add_connection(&ca, nsock);
56350 if (!err) {
56351diff -urNp linux-2.6.38.1/net/bluetooth/sco.c linux-2.6.38.1/net/bluetooth/sco.c
56352--- linux-2.6.38.1/net/bluetooth/sco.c 2011-03-14 21:20:32.000000000 -0400
56353+++ linux-2.6.38.1/net/bluetooth/sco.c 2011-03-21 18:31:35.000000000 -0400
56354@@ -703,6 +703,7 @@ static int sco_sock_getsockopt_old(struc
56355 break;
56356 }
56357
56358+ memset(&cinfo, 0, sizeof(cinfo));
56359 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
56360 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
56361
56362diff -urNp linux-2.6.38.1/net/bridge/br_multicast.c linux-2.6.38.1/net/bridge/br_multicast.c
56363--- linux-2.6.38.1/net/bridge/br_multicast.c 2011-03-14 21:20:32.000000000 -0400
56364+++ linux-2.6.38.1/net/bridge/br_multicast.c 2011-03-21 18:31:35.000000000 -0400
56365@@ -1482,7 +1482,7 @@ static int br_multicast_ipv6_rcv(struct
6892158b
MT
56366 nexthdr = ip6h->nexthdr;
56367 offset = ipv6_skip_exthdr(skb, sizeof(*ip6h), &nexthdr);
56368
56369- if (offset < 0 || nexthdr != IPPROTO_ICMPV6)
56370+ if (nexthdr != IPPROTO_ICMPV6)
56371 return 0;
56372
56373 /* Okay, we found ICMPv6 header */
16454cff
MT
56374diff -urNp linux-2.6.38.1/net/bridge/netfilter/ebtables.c linux-2.6.38.1/net/bridge/netfilter/ebtables.c
56375--- linux-2.6.38.1/net/bridge/netfilter/ebtables.c 2011-03-14 21:20:32.000000000 -0400
56376+++ linux-2.6.38.1/net/bridge/netfilter/ebtables.c 2011-03-21 18:31:35.000000000 -0400
56377@@ -1107,6 +1107,8 @@ static int do_replace(struct net *net, c
56378 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
56379 return -ENOMEM;
56380
56381+ tmp.name[sizeof(tmp.name)-1] = 0;
56382+
56383 countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids;
56384 newinfo = vmalloc(sizeof(*newinfo) + countersize);
56385 if (!newinfo)
56386@@ -1510,7 +1512,7 @@ static int do_ebt_get_ctl(struct sock *s
ae4e228f
MT
56387 tmp.valid_hooks = t->table->valid_hooks;
56388 }
56389 mutex_unlock(&ebt_mutex);
56390- if (copy_to_user(user, &tmp, *len) != 0){
56391+ if (*len > sizeof(tmp) || copy_to_user(user, &tmp, *len) != 0){
56392 BUGPRINT("c2u Didn't work\n");
56393 ret = -EFAULT;
56394 break;
16454cff
MT
56395diff -urNp linux-2.6.38.1/net/can/bcm.c linux-2.6.38.1/net/can/bcm.c
56396--- linux-2.6.38.1/net/can/bcm.c 2011-03-14 21:20:32.000000000 -0400
56397+++ linux-2.6.38.1/net/can/bcm.c 2011-03-21 18:31:35.000000000 -0400
56398@@ -165,9 +165,15 @@ static int bcm_proc_show(struct seq_file
56399 struct bcm_sock *bo = bcm_sk(sk);
56400 struct bcm_op *op;
56401
56402+#ifdef CONFIG_GRKERNSEC_HIDESYM
56403+ seq_printf(m, ">>> socket %p", NULL);
56404+ seq_printf(m, " / sk %p", NULL);
56405+ seq_printf(m, " / bo %p", NULL);
56406+#else
56407 seq_printf(m, ">>> socket %p", sk->sk_socket);
56408 seq_printf(m, " / sk %p", sk);
56409 seq_printf(m, " / bo %p", bo);
56410+#endif
56411 seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs);
56412 seq_printf(m, " / bound %s", bcm_proc_getifname(ifname, bo->ifindex));
56413 seq_printf(m, " <<<\n");
56414diff -urNp linux-2.6.38.1/net/core/dev.c linux-2.6.38.1/net/core/dev.c
56415--- linux-2.6.38.1/net/core/dev.c 2011-03-14 21:20:32.000000000 -0400
56416+++ linux-2.6.38.1/net/core/dev.c 2011-03-21 18:31:35.000000000 -0400
56417@@ -1124,7 +1124,7 @@ void dev_load(struct net *net, const cha
56418 if (no_module && capable(CAP_NET_ADMIN))
56419 no_module = request_module("netdev-%s", name);
56420 if (no_module && capable(CAP_SYS_MODULE)) {
56421- if (!request_module("%s", name))
56422+ if (!request_module("%s", name))
56423 pr_err("Loading kernel module for a network device "
56424 "with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s "
56425 "instead\n", name);
56426@@ -2787,7 +2787,7 @@ int netif_rx_ni(struct sk_buff *skb)
ae4e228f
MT
56427 }
56428 EXPORT_SYMBOL(netif_rx_ni);
56429
56430-static void net_tx_action(struct softirq_action *h)
56431+static void net_tx_action(void)
56432 {
56433 struct softnet_data *sd = &__get_cpu_var(softnet_data);
56434
16454cff 56435@@ -3697,7 +3697,7 @@ void netif_napi_del(struct napi_struct *
57199397 56436 }
ae4e228f
MT
56437 EXPORT_SYMBOL(netif_napi_del);
56438
ae4e228f
MT
56439-static void net_rx_action(struct softirq_action *h)
56440+static void net_rx_action(void)
56441 {
57199397 56442 struct softnet_data *sd = &__get_cpu_var(softnet_data);
ae4e228f 56443 unsigned long time_limit = jiffies + 2;
16454cff
MT
56444diff -urNp linux-2.6.38.1/net/core/sock.c linux-2.6.38.1/net/core/sock.c
56445--- linux-2.6.38.1/net/core/sock.c 2011-03-14 21:20:32.000000000 -0400
56446+++ linux-2.6.38.1/net/core/sock.c 2011-03-21 18:31:35.000000000 -0400
6892158b 56447@@ -934,7 +934,7 @@ int sock_getsockopt(struct socket *sock,
ae4e228f
MT
56448 return -ENOTCONN;
56449 if (lv < len)
56450 return -EINVAL;
56451- if (copy_to_user(optval, address, len))
56452+ if (len > sizeof(address) || copy_to_user(optval, address, len))
56453 return -EFAULT;
56454 goto lenout;
56455 }
6892158b 56456@@ -967,7 +967,7 @@ int sock_getsockopt(struct socket *sock,
ae4e228f
MT
56457
56458 if (len > lv)
56459 len = lv;
56460- if (copy_to_user(optval, &v, len))
56461+ if (len > sizeof(v) || copy_to_user(optval, &v, len))
56462 return -EFAULT;
56463 lenout:
56464 if (put_user(len, optlen))
16454cff
MT
56465diff -urNp linux-2.6.38.1/net/dccp/ccids/ccid3.c linux-2.6.38.1/net/dccp/ccids/ccid3.c
56466--- linux-2.6.38.1/net/dccp/ccids/ccid3.c 2011-03-14 21:20:32.000000000 -0400
56467+++ linux-2.6.38.1/net/dccp/ccids/ccid3.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f 56468@@ -41,7 +41,7 @@
58c5fc13
MT
56469 static int ccid3_debug;
56470 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
56471 #else
56472-#define ccid3_pr_debug(format, a...)
56473+#define ccid3_pr_debug(format, a...) do {} while (0)
56474 #endif
56475
56476 /*
16454cff
MT
56477diff -urNp linux-2.6.38.1/net/dccp/dccp.h linux-2.6.38.1/net/dccp/dccp.h
56478--- linux-2.6.38.1/net/dccp/dccp.h 2011-03-14 21:20:32.000000000 -0400
56479+++ linux-2.6.38.1/net/dccp/dccp.h 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
56480@@ -44,9 +44,9 @@ extern int dccp_debug;
56481 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
56482 #define dccp_debug(fmt, a...) dccp_pr_debug_cat(KERN_DEBUG fmt, ##a)
56483 #else
56484-#define dccp_pr_debug(format, a...)
56485-#define dccp_pr_debug_cat(format, a...)
56486-#define dccp_debug(format, a...)
56487+#define dccp_pr_debug(format, a...) do {} while (0)
56488+#define dccp_pr_debug_cat(format, a...) do {} while (0)
56489+#define dccp_debug(format, a...) do {} while (0)
56490 #endif
56491
56492 extern struct inet_hashinfo dccp_hashinfo;
16454cff
MT
56493diff -urNp linux-2.6.38.1/net/decnet/sysctl_net_decnet.c linux-2.6.38.1/net/decnet/sysctl_net_decnet.c
56494--- linux-2.6.38.1/net/decnet/sysctl_net_decnet.c 2011-03-14 21:20:32.000000000 -0400
56495+++ linux-2.6.38.1/net/decnet/sysctl_net_decnet.c 2011-03-21 18:31:35.000000000 -0400
ae4e228f
MT
56496@@ -173,7 +173,7 @@ static int dn_node_address_handler(ctl_t
56497
56498 if (len > *lenp) len = *lenp;
56499
56500- if (copy_to_user(buffer, addr, len))
bc901d79 56501+ if (len > sizeof addr || copy_to_user(buffer, addr, len))
ae4e228f
MT
56502 return -EFAULT;
56503
56504 *lenp = len;
56505@@ -236,7 +236,7 @@ static int dn_def_dev_handler(ctl_table
56506
56507 if (len > *lenp) len = *lenp;
56508
56509- if (copy_to_user(buffer, devname, len))
bc901d79 56510+ if (len > sizeof devname || copy_to_user(buffer, devname, len))
ae4e228f
MT
56511 return -EFAULT;
56512
56513 *lenp = len;
16454cff
MT
56514diff -urNp linux-2.6.38.1/net/econet/Kconfig linux-2.6.38.1/net/econet/Kconfig
56515--- linux-2.6.38.1/net/econet/Kconfig 2011-03-14 21:20:32.000000000 -0400
56516+++ linux-2.6.38.1/net/econet/Kconfig 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
56517@@ -4,7 +4,7 @@
56518
56519 config ECONET
56520 tristate "Acorn Econet/AUN protocols (EXPERIMENTAL)"
56521- depends on EXPERIMENTAL && INET
56522+ depends on EXPERIMENTAL && INET && BROKEN
56523 ---help---
56524 Econet is a fairly old and slow networking protocol mainly used by
56525 Acorn computers to access file and print servers. It uses native
16454cff
MT
56526diff -urNp linux-2.6.38.1/net/ipv4/inet_diag.c linux-2.6.38.1/net/ipv4/inet_diag.c
56527--- linux-2.6.38.1/net/ipv4/inet_diag.c 2011-03-14 21:20:32.000000000 -0400
56528+++ linux-2.6.38.1/net/ipv4/inet_diag.c 2011-03-21 18:31:35.000000000 -0400
bc901d79
MT
56529@@ -114,8 +114,14 @@ static int inet_csk_diag_fill(struct soc
56530 r->idiag_retrans = 0;
56531
56532 r->id.idiag_if = sk->sk_bound_dev_if;
56533+
56534+#ifdef CONFIG_GRKERNSEC_HIDESYM
56535+ r->id.idiag_cookie[0] = 0;
56536+ r->id.idiag_cookie[1] = 0;
56537+#else
56538 r->id.idiag_cookie[0] = (u32)(unsigned long)sk;
56539 r->id.idiag_cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1);
56540+#endif
56541
56542 r->id.idiag_sport = inet->inet_sport;
56543 r->id.idiag_dport = inet->inet_dport;
56544@@ -201,8 +207,15 @@ static int inet_twsk_diag_fill(struct in
56545 r->idiag_family = tw->tw_family;
56546 r->idiag_retrans = 0;
56547 r->id.idiag_if = tw->tw_bound_dev_if;
56548+
56549+#ifdef CONFIG_GRKERNSEC_HIDESYM
56550+ r->id.idiag_cookie[0] = 0;
56551+ r->id.idiag_cookie[1] = 0;
56552+#else
56553 r->id.idiag_cookie[0] = (u32)(unsigned long)tw;
56554 r->id.idiag_cookie[1] = (u32)(((unsigned long)tw >> 31) >> 1);
56555+#endif
56556+
56557 r->id.idiag_sport = tw->tw_sport;
56558 r->id.idiag_dport = tw->tw_dport;
56559 r->id.idiag_src[0] = tw->tw_rcv_saddr;
56560@@ -285,12 +298,14 @@ static int inet_diag_get_exact(struct sk
56561 if (sk == NULL)
56562 goto unlock;
56563
56564+#ifndef CONFIG_GRKERNSEC_HIDESYM
56565 err = -ESTALE;
56566 if ((req->id.idiag_cookie[0] != INET_DIAG_NOCOOKIE ||
56567 req->id.idiag_cookie[1] != INET_DIAG_NOCOOKIE) &&
56568 ((u32)(unsigned long)sk != req->id.idiag_cookie[0] ||
56569 (u32)((((unsigned long)sk) >> 31) >> 1) != req->id.idiag_cookie[1]))
56570 goto out;
56571+#endif
56572
56573 err = -ENOMEM;
56574 rep = alloc_skb(NLMSG_SPACE((sizeof(struct inet_diag_msg) +
56575@@ -582,8 +597,14 @@ static int inet_diag_fill_req(struct sk_
56576 r->idiag_retrans = req->retrans;
56577
56578 r->id.idiag_if = sk->sk_bound_dev_if;
56579+
56580+#ifdef CONFIG_GRKERNSEC_HIDESYM
56581+ r->id.idiag_cookie[0] = 0;
56582+ r->id.idiag_cookie[1] = 0;
56583+#else
56584 r->id.idiag_cookie[0] = (u32)(unsigned long)req;
56585 r->id.idiag_cookie[1] = (u32)(((unsigned long)req >> 31) >> 1);
56586+#endif
56587
56588 tmo = req->expires - jiffies;
56589 if (tmo < 0)
16454cff
MT
56590diff -urNp linux-2.6.38.1/net/ipv4/inet_hashtables.c linux-2.6.38.1/net/ipv4/inet_hashtables.c
56591--- linux-2.6.38.1/net/ipv4/inet_hashtables.c 2011-03-14 21:20:32.000000000 -0400
56592+++ linux-2.6.38.1/net/ipv4/inet_hashtables.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
56593@@ -18,11 +18,14 @@
56594 #include <linux/sched.h>
56595 #include <linux/slab.h>
56596 #include <linux/wait.h>
56597+#include <linux/security.h>
56598
56599 #include <net/inet_connection_sock.h>
56600 #include <net/inet_hashtables.h>
56601 #include <net/ip.h>
56602
56603+extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
56604+
56605 /*
56606 * Allocate and initialize a new local port bind bucket.
56607 * The bindhash mutex for snum's hash chain must be held here.
bc901d79 56608@@ -529,6 +532,8 @@ ok:
ae4e228f 56609 twrefcnt += inet_twsk_bind_unhash(tw, hinfo);
58c5fc13
MT
56610 spin_unlock(&head->lock);
56611
56612+ gr_update_task_in_ip_table(current, inet_sk(sk));
56613+
56614 if (tw) {
56615 inet_twsk_deschedule(tw, death_row);
ae4e228f 56616 while (twrefcnt) {
16454cff
MT
56617diff -urNp linux-2.6.38.1/net/ipv4/inetpeer.c linux-2.6.38.1/net/ipv4/inetpeer.c
56618--- linux-2.6.38.1/net/ipv4/inetpeer.c 2011-03-14 21:20:32.000000000 -0400
56619+++ linux-2.6.38.1/net/ipv4/inetpeer.c 2011-03-21 18:31:35.000000000 -0400
56620@@ -509,8 +509,8 @@ struct inet_peer *inet_getpeer(struct in
6892158b 56621 if (p) {
16454cff 56622 p->daddr = *daddr;
6892158b
MT
56623 atomic_set(&p->refcnt, 1);
56624- atomic_set(&p->rid, 0);
16454cff 56625- atomic_set(&p->ip_id_count, secure_ip_id(daddr->a4));
6892158b 56626+ atomic_set_unchecked(&p->rid, 0);
16454cff 56627+ atomic_set_unchecked(&p->ip_id_count, secure_ip_id(daddr->a4));
6892158b
MT
56628 p->tcp_ts_stamp = 0;
56629 INIT_LIST_HEAD(&p->unused);
56630
16454cff
MT
56631diff -urNp linux-2.6.38.1/net/ipv4/ip_fragment.c linux-2.6.38.1/net/ipv4/ip_fragment.c
56632--- linux-2.6.38.1/net/ipv4/ip_fragment.c 2011-03-14 21:20:32.000000000 -0400
56633+++ linux-2.6.38.1/net/ipv4/ip_fragment.c 2011-03-21 18:31:35.000000000 -0400
c52201e0 56634@@ -298,7 +298,7 @@ static inline int ip_frag_too_far(struct
6892158b
MT
56635 return 0;
56636
56637 start = qp->rid;
56638- end = atomic_inc_return(&peer->rid);
56639+ end = atomic_inc_return_unchecked(&peer->rid);
56640 qp->rid = end;
56641
56642 rc = qp->q.fragments && (end - start) > max;
16454cff
MT
56643diff -urNp linux-2.6.38.1/net/ipv4/netfilter/nf_nat_snmp_basic.c linux-2.6.38.1/net/ipv4/netfilter/nf_nat_snmp_basic.c
56644--- linux-2.6.38.1/net/ipv4/netfilter/nf_nat_snmp_basic.c 2011-03-14 21:20:32.000000000 -0400
56645+++ linux-2.6.38.1/net/ipv4/netfilter/nf_nat_snmp_basic.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 56646@@ -398,7 +398,7 @@ static unsigned char asn1_octets_decode(
58c5fc13
MT
56647
56648 *len = 0;
56649
56650- *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
56651+ *octets = kmalloc((eoc - ctx->pointer), GFP_ATOMIC);
56652 if (*octets == NULL) {
56653 if (net_ratelimit())
57199397 56654 pr_notice("OOM in bsalg (%d)\n", __LINE__);
16454cff
MT
56655diff -urNp linux-2.6.38.1/net/ipv4/route.c linux-2.6.38.1/net/ipv4/route.c
56656--- linux-2.6.38.1/net/ipv4/route.c 2011-03-14 21:20:32.000000000 -0400
56657+++ linux-2.6.38.1/net/ipv4/route.c 2011-03-21 18:31:35.000000000 -0400
56658@@ -2857,7 +2857,7 @@ static int rt_fill_info(struct net *net,
6892158b
MT
56659 expires = rt->dst.expires ? rt->dst.expires - jiffies : 0;
56660 if (rt->peer) {
56661 inet_peer_refcheck(rt->peer);
56662- id = atomic_read(&rt->peer->ip_id_count) & 0xffff;
56663+ id = atomic_read_unchecked(&rt->peer->ip_id_count) & 0xffff;
56664 if (rt->peer->tcp_ts_stamp) {
56665 ts = rt->peer->tcp_ts;
56666 tsage = get_seconds() - rt->peer->tcp_ts_stamp;
16454cff
MT
56667diff -urNp linux-2.6.38.1/net/ipv4/tcp_ipv4.c linux-2.6.38.1/net/ipv4/tcp_ipv4.c
56668--- linux-2.6.38.1/net/ipv4/tcp_ipv4.c 2011-03-14 21:20:32.000000000 -0400
56669+++ linux-2.6.38.1/net/ipv4/tcp_ipv4.c 2011-03-21 18:31:35.000000000 -0400
6892158b 56670@@ -86,6 +86,9 @@ int sysctl_tcp_tw_reuse __read_mostly;
ae4e228f 56671 int sysctl_tcp_low_latency __read_mostly;
6892158b 56672 EXPORT_SYMBOL(sysctl_tcp_low_latency);
58c5fc13 56673
58c5fc13 56674+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
ae4e228f 56675+extern int grsec_enable_blackhole;
58c5fc13 56676+#endif
ae4e228f
MT
56677
56678 #ifdef CONFIG_TCP_MD5SIG
56679 static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
16454cff 56680@@ -1593,6 +1596,9 @@ int tcp_v4_do_rcv(struct sock *sk, struc
57199397
MT
56681 return 0;
56682
56683 reset:
56684+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56685+ if (!grsec_enable_blackhole)
56686+#endif
56687 tcp_v4_send_reset(rsk, skb);
56688 discard:
56689 kfree_skb(skb);
16454cff 56690@@ -1655,12 +1661,19 @@ int tcp_v4_rcv(struct sk_buff *skb)
ae4e228f
MT
56691 TCP_SKB_CB(skb)->sacked = 0;
56692
56693 sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
56694- if (!sk)
56695+ if (!sk) {
56696+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56697+ ret = 1;
56698+#endif
56699 goto no_tcp_socket;
df50ba0c 56700-
ae4e228f 56701+ }
ae4e228f
MT
56702 process:
56703- if (sk->sk_state == TCP_TIME_WAIT)
56704+ if (sk->sk_state == TCP_TIME_WAIT) {
56705+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56706+ ret = 2;
56707+#endif
56708 goto do_time_wait;
56709+ }
56710
df50ba0c
MT
56711 if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
56712 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
16454cff 56713@@ -1710,6 +1723,10 @@ no_tcp_socket:
58c5fc13
MT
56714 bad_packet:
56715 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
56716 } else {
56717+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
ae4e228f
MT
56718+ if (!grsec_enable_blackhole || (ret == 1 &&
56719+ (skb->dev->flags & IFF_LOOPBACK)))
58c5fc13
MT
56720+#endif
56721 tcp_v4_send_reset(NULL, skb);
56722 }
56723
16454cff 56724@@ -2373,7 +2390,11 @@ static void get_openreq4(struct sock *sk
57199397
MT
56725 0, /* non standard timer */
56726 0, /* open_requests have no inode */
56727 atomic_read(&sk->sk_refcnt),
56728+#ifdef CONFIG_GRKERNSEC_HIDESYM
56729+ NULL,
56730+#else
56731 req,
56732+#endif
56733 len);
56734 }
56735
16454cff 56736@@ -2423,7 +2444,12 @@ static void get_tcp4_sock(struct sock *s
57199397
MT
56737 sock_i_uid(sk),
56738 icsk->icsk_probes_out,
56739 sock_i_ino(sk),
56740- atomic_read(&sk->sk_refcnt), sk,
56741+ atomic_read(&sk->sk_refcnt),
56742+#ifdef CONFIG_GRKERNSEC_HIDESYM
56743+ NULL,
56744+#else
56745+ sk,
56746+#endif
56747 jiffies_to_clock_t(icsk->icsk_rto),
56748 jiffies_to_clock_t(icsk->icsk_ack.ato),
56749 (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
16454cff 56750@@ -2451,7 +2477,13 @@ static void get_timewait4_sock(struct in
57199397
MT
56751 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p%n",
56752 i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
56753 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
56754- atomic_read(&tw->tw_refcnt), tw, len);
56755+ atomic_read(&tw->tw_refcnt),
56756+#ifdef CONFIG_GRKERNSEC_HIDESYM
56757+ NULL,
56758+#else
56759+ tw,
56760+#endif
56761+ len);
56762 }
56763
56764 #define TMPSZ 150
16454cff
MT
56765diff -urNp linux-2.6.38.1/net/ipv4/tcp_minisocks.c linux-2.6.38.1/net/ipv4/tcp_minisocks.c
56766--- linux-2.6.38.1/net/ipv4/tcp_minisocks.c 2011-03-14 21:20:32.000000000 -0400
56767+++ linux-2.6.38.1/net/ipv4/tcp_minisocks.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 56768@@ -27,6 +27,10 @@
ae4e228f
MT
56769 #include <net/inet_common.h>
56770 #include <net/xfrm.h>
56771
56772+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56773+extern int grsec_enable_blackhole;
56774+#endif
56775+
56776 int sysctl_tcp_syncookies __read_mostly = 1;
56777 EXPORT_SYMBOL(sysctl_tcp_syncookies);
56778
16454cff 56779@@ -745,6 +749,10 @@ listen_overflow:
58c5fc13
MT
56780
56781 embryonic_reset:
56782 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS);
56783+
df50ba0c
MT
56784+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56785+ if (!grsec_enable_blackhole)
58c5fc13 56786+#endif
df50ba0c
MT
56787 if (!(flg & TCP_FLAG_RST))
56788 req->rsk_ops->send_reset(sk, skb);
58c5fc13 56789
16454cff
MT
56790diff -urNp linux-2.6.38.1/net/ipv4/tcp_probe.c linux-2.6.38.1/net/ipv4/tcp_probe.c
56791--- linux-2.6.38.1/net/ipv4/tcp_probe.c 2011-03-14 21:20:32.000000000 -0400
56792+++ linux-2.6.38.1/net/ipv4/tcp_probe.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 56793@@ -202,7 +202,7 @@ static ssize_t tcpprobe_read(struct file
ae4e228f
MT
56794 if (cnt + width >= len)
56795 break;
56796
56797- if (copy_to_user(buf + cnt, tbuf, width))
bc901d79 56798+ if (width > sizeof tbuf || copy_to_user(buf + cnt, tbuf, width))
ae4e228f
MT
56799 return -EFAULT;
56800 cnt += width;
56801 }
16454cff
MT
56802diff -urNp linux-2.6.38.1/net/ipv4/tcp_timer.c linux-2.6.38.1/net/ipv4/tcp_timer.c
56803--- linux-2.6.38.1/net/ipv4/tcp_timer.c 2011-03-14 21:20:32.000000000 -0400
56804+++ linux-2.6.38.1/net/ipv4/tcp_timer.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
56805@@ -22,6 +22,10 @@
56806 #include <linux/gfp.h>
ae4e228f
MT
56807 #include <net/tcp.h>
56808
56809+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56810+extern int grsec_lastack_retries;
56811+#endif
56812+
56813 int sysctl_tcp_syn_retries __read_mostly = TCP_SYN_RETRIES;
56814 int sysctl_tcp_synack_retries __read_mostly = TCP_SYNACK_RETRIES;
56815 int sysctl_tcp_keepalive_time __read_mostly = TCP_KEEPALIVE_TIME;
bc901d79 56816@@ -199,6 +203,13 @@ static int tcp_write_timeout(struct sock
ae4e228f
MT
56817 }
56818 }
56819
56820+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56821+ if ((sk->sk_state == TCP_LAST_ACK) &&
56822+ (grsec_lastack_retries > 0) &&
56823+ (grsec_lastack_retries < retry_until))
56824+ retry_until = grsec_lastack_retries;
56825+#endif
56826+
bc901d79
MT
56827 if (retransmits_timed_out(sk, retry_until,
56828 syn_set ? 0 : icsk->icsk_user_timeout, syn_set)) {
ae4e228f 56829 /* Has it gone just too far? */
16454cff
MT
56830diff -urNp linux-2.6.38.1/net/ipv4/udp.c linux-2.6.38.1/net/ipv4/udp.c
56831--- linux-2.6.38.1/net/ipv4/udp.c 2011-03-14 21:20:32.000000000 -0400
56832+++ linux-2.6.38.1/net/ipv4/udp.c 2011-03-21 18:31:35.000000000 -0400
58c5fc13
MT
56833@@ -86,6 +86,7 @@
56834 #include <linux/types.h>
56835 #include <linux/fcntl.h>
56836 #include <linux/module.h>
56837+#include <linux/security.h>
56838 #include <linux/socket.h>
56839 #include <linux/sockios.h>
56840 #include <linux/igmp.h>
df50ba0c 56841@@ -107,6 +108,10 @@
ae4e228f
MT
56842 #include <net/xfrm.h>
56843 #include "udp_impl.h"
56844
56845+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56846+extern int grsec_enable_blackhole;
56847+#endif
56848+
56849 struct udp_table udp_table __read_mostly;
56850 EXPORT_SYMBOL(udp_table);
56851
57199397 56852@@ -564,6 +569,9 @@ found:
58c5fc13
MT
56853 return s;
56854 }
56855
56856+extern int gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb);
56857+extern int gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr);
56858+
56859 /*
56860 * This routine is called by the ICMP module when it gets some
56861 * sort of error condition. If err < 0 then the socket should
57199397 56862@@ -832,9 +840,18 @@ int udp_sendmsg(struct kiocb *iocb, stru
58c5fc13
MT
56863 dport = usin->sin_port;
56864 if (dport == 0)
56865 return -EINVAL;
56866+
56867+ err = gr_search_udp_sendmsg(sk, usin);
56868+ if (err)
56869+ return err;
56870 } else {
56871 if (sk->sk_state != TCP_ESTABLISHED)
56872 return -EDESTADDRREQ;
56873+
56874+ err = gr_search_udp_sendmsg(sk, NULL);
56875+ if (err)
56876+ return err;
56877+
ae4e228f
MT
56878 daddr = inet->inet_daddr;
56879 dport = inet->inet_dport;
58c5fc13 56880 /* Open fast path for connected socket.
16454cff 56881@@ -1139,6 +1156,10 @@ try_again:
58c5fc13
MT
56882 if (!skb)
56883 goto out;
56884
56885+ err = gr_search_udp_recvmsg(sk, skb);
56886+ if (err)
56887+ goto out_free;
56888+
56889 ulen = skb->len - sizeof(struct udphdr);
df50ba0c
MT
56890 if (len > ulen)
56891 len = ulen;
16454cff 56892@@ -1623,6 +1644,9 @@ int __udp4_lib_rcv(struct sk_buff *skb,
58c5fc13
MT
56893 goto csum_error;
56894
56895 UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
56896+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
ae4e228f 56897+ if (!grsec_enable_blackhole || (skb->dev->flags & IFF_LOOPBACK))
58c5fc13
MT
56898+#endif
56899 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
56900
56901 /*
16454cff 56902@@ -2050,7 +2074,12 @@ static void udp4_format_sock(struct sock
57199397
MT
56903 sk_wmem_alloc_get(sp),
56904 sk_rmem_alloc_get(sp),
56905 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
56906- atomic_read(&sp->sk_refcnt), sp,
56907+ atomic_read(&sp->sk_refcnt),
56908+#ifdef CONFIG_GRKERNSEC_HIDESYM
56909+ NULL,
56910+#else
56911+ sp,
56912+#endif
56913 atomic_read(&sp->sk_drops), len);
56914 }
56915
16454cff
MT
56916diff -urNp linux-2.6.38.1/net/ipv6/exthdrs.c linux-2.6.38.1/net/ipv6/exthdrs.c
56917--- linux-2.6.38.1/net/ipv6/exthdrs.c 2011-03-14 21:20:32.000000000 -0400
56918+++ linux-2.6.38.1/net/ipv6/exthdrs.c 2011-03-21 18:31:35.000000000 -0400
6892158b 56919@@ -634,7 +634,7 @@ static struct tlvtype_proc tlvprochopopt
58c5fc13
MT
56920 .type = IPV6_TLV_JUMBO,
56921 .func = ipv6_hop_jumbo,
56922 },
56923- { -1, }
56924+ { -1, NULL }
56925 };
56926
56927 int ipv6_parse_hopopts(struct sk_buff *skb)
16454cff
MT
56928diff -urNp linux-2.6.38.1/net/ipv6/raw.c linux-2.6.38.1/net/ipv6/raw.c
56929--- linux-2.6.38.1/net/ipv6/raw.c 2011-03-14 21:20:32.000000000 -0400
56930+++ linux-2.6.38.1/net/ipv6/raw.c 2011-03-21 18:31:35.000000000 -0400
56931@@ -602,7 +602,7 @@ out:
58c5fc13
MT
56932 return err;
56933 }
56934
56935-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
56936+static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
6892158b 56937 struct flowi *fl, struct dst_entry **dstp,
58c5fc13
MT
56938 unsigned int flags)
56939 {
16454cff 56940@@ -1262,7 +1262,13 @@ static void raw6_sock_seq_show(struct se
6892158b
MT
56941 0, 0L, 0,
56942 sock_i_uid(sp), 0,
56943 sock_i_ino(sp),
56944- atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
56945+ atomic_read(&sp->sk_refcnt),
56946+#ifdef CONFIG_GRKERNSEC_HIDESYM
56947+ NULL,
56948+#else
56949+ sp,
56950+#endif
56951+ atomic_read(&sp->sk_drops));
56952 }
56953
56954 static int raw6_seq_show(struct seq_file *seq, void *v)
16454cff
MT
56955diff -urNp linux-2.6.38.1/net/ipv6/tcp_ipv6.c linux-2.6.38.1/net/ipv6/tcp_ipv6.c
56956--- linux-2.6.38.1/net/ipv6/tcp_ipv6.c 2011-03-14 21:20:32.000000000 -0400
56957+++ linux-2.6.38.1/net/ipv6/tcp_ipv6.c 2011-03-21 18:31:35.000000000 -0400
57199397 56958@@ -92,6 +92,10 @@ static struct tcp_md5sig_key *tcp_v6_md5
df50ba0c
MT
56959 }
56960 #endif
56961
56962+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56963+extern int grsec_enable_blackhole;
56964+#endif
56965+
56966 static void tcp_v6_hash(struct sock *sk)
56967 {
56968 if (sk->sk_state != TCP_CLOSE) {
16454cff 56969@@ -1676,6 +1680,9 @@ static int tcp_v6_do_rcv(struct sock *sk
57199397
MT
56970 return 0;
56971
56972 reset:
56973+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56974+ if (!grsec_enable_blackhole)
56975+#endif
56976 tcp_v6_send_reset(sk, skb);
56977 discard:
56978 if (opt_skb)
16454cff 56979@@ -1755,12 +1762,20 @@ static int tcp_v6_rcv(struct sk_buff *sk
df50ba0c 56980 TCP_SKB_CB(skb)->sacked = 0;
58c5fc13 56981
df50ba0c
MT
56982 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
56983- if (!sk)
56984+ if (!sk) {
56985+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
56986+ ret = 1;
56987+#endif
56988 goto no_tcp_socket;
56989+ }
56990
56991 process:
56992- if (sk->sk_state == TCP_TIME_WAIT)
56993+ if (sk->sk_state == TCP_TIME_WAIT) {
58c5fc13 56994+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
df50ba0c 56995+ ret = 2;
58c5fc13 56996+#endif
df50ba0c
MT
56997 goto do_time_wait;
56998+ }
56999
57199397
MT
57000 if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) {
57001 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
16454cff 57002@@ -1808,6 +1823,10 @@ no_tcp_socket:
58c5fc13
MT
57003 bad_packet:
57004 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
57005 } else {
57006+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
df50ba0c
MT
57007+ if (!grsec_enable_blackhole || (ret == 1 &&
57008+ (skb->dev->flags & IFF_LOOPBACK)))
58c5fc13
MT
57009+#endif
57010 tcp_v6_send_reset(NULL, skb);
57011 }
57012
16454cff 57013@@ -2068,7 +2087,13 @@ static void get_openreq6(struct seq_file
6892158b
MT
57014 uid,
57015 0, /* non standard timer */
57016 0, /* open_requests have no inode */
57017- 0, req);
57018+ 0,
57019+#ifdef CONFIG_GRKERNSEC_HIDESYM
57020+ NULL
57021+#else
57022+ req
57023+#endif
57024+ );
57025 }
57026
57027 static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
16454cff 57028@@ -2118,7 +2143,12 @@ static void get_tcp6_sock(struct seq_fil
6892158b
MT
57029 sock_i_uid(sp),
57030 icsk->icsk_probes_out,
57031 sock_i_ino(sp),
57032- atomic_read(&sp->sk_refcnt), sp,
57033+ atomic_read(&sp->sk_refcnt),
57034+#ifdef CONFIG_GRKERNSEC_HIDESYM
57035+ NULL,
57036+#else
57037+ sp,
57038+#endif
57039 jiffies_to_clock_t(icsk->icsk_rto),
57040 jiffies_to_clock_t(icsk->icsk_ack.ato),
57041 (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
16454cff 57042@@ -2153,7 +2183,13 @@ static void get_timewait6_sock(struct se
6892158b
MT
57043 dest->s6_addr32[2], dest->s6_addr32[3], destp,
57044 tw->tw_substate, 0, 0,
57045 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
57046- atomic_read(&tw->tw_refcnt), tw);
57047+ atomic_read(&tw->tw_refcnt),
57048+#ifdef CONFIG_GRKERNSEC_HIDESYM
57049+ NULL
57050+#else
57051+ tw
57052+#endif
57053+ );
57054 }
57055
57056 static int tcp6_seq_show(struct seq_file *seq, void *v)
16454cff
MT
57057diff -urNp linux-2.6.38.1/net/ipv6/udp.c linux-2.6.38.1/net/ipv6/udp.c
57058--- linux-2.6.38.1/net/ipv6/udp.c 2011-03-14 21:20:32.000000000 -0400
57059+++ linux-2.6.38.1/net/ipv6/udp.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
57060@@ -50,6 +50,10 @@
57061 #include <linux/seq_file.h>
57062 #include "udp_impl.h"
57063
57064+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
57065+extern int grsec_enable_blackhole;
57066+#endif
57067+
57068 int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
57069 {
57070 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
bc901d79 57071@@ -773,6 +777,9 @@ int __udp6_lib_rcv(struct sk_buff *skb,
58c5fc13
MT
57072 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS,
57073 proto == IPPROTO_UDPLITE);
57074
57075+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
df50ba0c 57076+ if (!grsec_enable_blackhole || (skb->dev->flags & IFF_LOOPBACK))
58c5fc13 57077+#endif
df50ba0c 57078 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
58c5fc13
MT
57079
57080 kfree_skb(skb);
bc901d79 57081@@ -1407,7 +1414,12 @@ static void udp6_sock_seq_show(struct se
6892158b
MT
57082 0, 0L, 0,
57083 sock_i_uid(sp), 0,
57084 sock_i_ino(sp),
57085- atomic_read(&sp->sk_refcnt), sp,
57086+ atomic_read(&sp->sk_refcnt),
57087+#ifdef CONFIG_GRKERNSEC_HIDESYM
57088+ NULL,
57089+#else
57090+ sp,
57091+#endif
57092 atomic_read(&sp->sk_drops));
57093 }
57094
16454cff
MT
57095diff -urNp linux-2.6.38.1/net/irda/ircomm/ircomm_tty.c linux-2.6.38.1/net/irda/ircomm/ircomm_tty.c
57096--- linux-2.6.38.1/net/irda/ircomm/ircomm_tty.c 2011-03-14 21:20:32.000000000 -0400
57097+++ linux-2.6.38.1/net/irda/ircomm/ircomm_tty.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 57098@@ -281,16 +281,16 @@ static int ircomm_tty_block_til_ready(st
58c5fc13
MT
57099 add_wait_queue(&self->open_wait, &wait);
57100
57101 IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
57102- __FILE__,__LINE__, tty->driver->name, self->open_count );
c52201e0 57103+ __FILE__,__LINE__, tty->driver->name, local_read(&self->open_count) );
58c5fc13
MT
57104
57105 /* As far as I can see, we protect open_count - Jean II */
57106 spin_lock_irqsave(&self->spinlock, flags);
57107 if (!tty_hung_up_p(filp)) {
57108 extra_count = 1;
57109- self->open_count--;
c52201e0 57110+ local_dec(&self->open_count);
58c5fc13
MT
57111 }
57112 spin_unlock_irqrestore(&self->spinlock, flags);
57113- self->blocked_open++;
c52201e0 57114+ local_inc(&self->blocked_open);
58c5fc13
MT
57115
57116 while (1) {
57117 if (tty->termios->c_cflag & CBAUD) {
df50ba0c 57118@@ -330,7 +330,7 @@ static int ircomm_tty_block_til_ready(st
58c5fc13
MT
57119 }
57120
57121 IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
57122- __FILE__,__LINE__, tty->driver->name, self->open_count );
c52201e0 57123+ __FILE__,__LINE__, tty->driver->name, local_read(&self->open_count) );
58c5fc13
MT
57124
57125 schedule();
57126 }
df50ba0c 57127@@ -341,13 +341,13 @@ static int ircomm_tty_block_til_ready(st
58c5fc13
MT
57128 if (extra_count) {
57129 /* ++ is not atomic, so this should be protected - Jean II */
57130 spin_lock_irqsave(&self->spinlock, flags);
57131- self->open_count++;
c52201e0 57132+ local_inc(&self->open_count);
58c5fc13
MT
57133 spin_unlock_irqrestore(&self->spinlock, flags);
57134 }
57135- self->blocked_open--;
c52201e0 57136+ local_dec(&self->blocked_open);
58c5fc13
MT
57137
57138 IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
57139- __FILE__,__LINE__, tty->driver->name, self->open_count);
c52201e0 57140+ __FILE__,__LINE__, tty->driver->name, local_read(&self->open_count));
58c5fc13
MT
57141
57142 if (!retval)
57143 self->flags |= ASYNC_NORMAL_ACTIVE;
df50ba0c 57144@@ -416,14 +416,14 @@ static int ircomm_tty_open(struct tty_st
58c5fc13
MT
57145 }
57146 /* ++ is not atomic, so this should be protected - Jean II */
57147 spin_lock_irqsave(&self->spinlock, flags);
57148- self->open_count++;
c52201e0 57149+ local_inc(&self->open_count);
58c5fc13
MT
57150
57151 tty->driver_data = self;
57152 self->tty = tty;
57153 spin_unlock_irqrestore(&self->spinlock, flags);
57154
57155 IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
57156- self->line, self->open_count);
c52201e0 57157+ self->line, local_read(&self->open_count));
58c5fc13
MT
57158
57159 /* Not really used by us, but lets do it anyway */
57160 self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
df50ba0c 57161@@ -509,7 +509,7 @@ static void ircomm_tty_close(struct tty_
58c5fc13
MT
57162 return;
57163 }
57164
57165- if ((tty->count == 1) && (self->open_count != 1)) {
c52201e0 57166+ if ((tty->count == 1) && (local_read(&self->open_count) != 1)) {
58c5fc13
MT
57167 /*
57168 * Uh, oh. tty->count is 1, which means that the tty
57169 * structure will be freed. state->count should always
df50ba0c 57170@@ -519,16 +519,16 @@ static void ircomm_tty_close(struct tty_
58c5fc13
MT
57171 */
57172 IRDA_DEBUG(0, "%s(), bad serial port count; "
57173 "tty->count is 1, state->count is %d\n", __func__ ,
57174- self->open_count);
57175- self->open_count = 1;
c52201e0
MT
57176+ local_read(&self->open_count));
57177+ local_set(&self->open_count, 1);
58c5fc13
MT
57178 }
57179
57180- if (--self->open_count < 0) {
c52201e0 57181+ if (local_dec_return(&self->open_count) < 0) {
58c5fc13
MT
57182 IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
57183- __func__, self->line, self->open_count);
57184- self->open_count = 0;
c52201e0
MT
57185+ __func__, self->line, local_read(&self->open_count));
57186+ local_set(&self->open_count, 0);
58c5fc13
MT
57187 }
57188- if (self->open_count) {
c52201e0 57189+ if (local_read(&self->open_count)) {
58c5fc13
MT
57190 spin_unlock_irqrestore(&self->spinlock, flags);
57191
57192 IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
df50ba0c 57193@@ -560,7 +560,7 @@ static void ircomm_tty_close(struct tty_
58c5fc13
MT
57194 tty->closing = 0;
57195 self->tty = NULL;
57196
57197- if (self->blocked_open) {
c52201e0 57198+ if (local_read(&self->blocked_open)) {
58c5fc13
MT
57199 if (self->close_delay)
57200 schedule_timeout_interruptible(self->close_delay);
57201 wake_up_interruptible(&self->open_wait);
df50ba0c 57202@@ -1012,7 +1012,7 @@ static void ircomm_tty_hangup(struct tty
58c5fc13
MT
57203 spin_lock_irqsave(&self->spinlock, flags);
57204 self->flags &= ~ASYNC_NORMAL_ACTIVE;
57205 self->tty = NULL;
57206- self->open_count = 0;
c52201e0 57207+ local_set(&self->open_count, 0);
58c5fc13
MT
57208 spin_unlock_irqrestore(&self->spinlock, flags);
57209
57210 wake_up_interruptible(&self->open_wait);
df50ba0c 57211@@ -1364,7 +1364,7 @@ static void ircomm_tty_line_info(struct
58c5fc13
MT
57212 seq_putc(m, '\n');
57213
57214 seq_printf(m, "Role: %s\n", self->client ? "client" : "server");
57215- seq_printf(m, "Open count: %d\n", self->open_count);
c52201e0 57216+ seq_printf(m, "Open count: %d\n", local_read(&self->open_count));
58c5fc13
MT
57217 seq_printf(m, "Max data size: %d\n", self->max_data_size);
57218 seq_printf(m, "Max header size: %d\n", self->max_header_size);
57219
16454cff
MT
57220diff -urNp linux-2.6.38.1/net/key/af_key.c linux-2.6.38.1/net/key/af_key.c
57221--- linux-2.6.38.1/net/key/af_key.c 2011-03-14 21:20:32.000000000 -0400
57222+++ linux-2.6.38.1/net/key/af_key.c 2011-03-21 18:31:35.000000000 -0400
57199397
MT
57223@@ -3644,7 +3644,11 @@ static int pfkey_seq_show(struct seq_fil
57224 seq_printf(f ,"sk RefCnt Rmem Wmem User Inode\n");
57225 else
57226 seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n",
57227+#ifdef CONFIG_GRKERNSEC_HIDESYM
57228+ NULL,
57229+#else
57230 s,
57231+#endif
57232 atomic_read(&s->sk_refcnt),
57233 sk_rmem_alloc_get(s),
57234 sk_wmem_alloc_get(s),
16454cff
MT
57235diff -urNp linux-2.6.38.1/net/mac80211/ieee80211_i.h linux-2.6.38.1/net/mac80211/ieee80211_i.h
57236--- linux-2.6.38.1/net/mac80211/ieee80211_i.h 2011-03-14 21:20:32.000000000 -0400
57237+++ linux-2.6.38.1/net/mac80211/ieee80211_i.h 2011-03-21 18:31:35.000000000 -0400
57238@@ -27,6 +27,7 @@
c52201e0
MT
57239 #include <net/ieee80211_radiotap.h>
57240 #include <net/cfg80211.h>
57241 #include <net/mac80211.h>
57242+#include <asm/local.h>
57243 #include "key.h"
57244 #include "sta_info.h"
57245
16454cff 57246@@ -716,7 +717,7 @@ struct ieee80211_local {
ae4e228f 57247 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
58c5fc13
MT
57248 spinlock_t queue_stop_reason_lock;
57249
58c5fc13 57250- int open_count;
c52201e0 57251+ local_t open_count;
58c5fc13
MT
57252 int monitors, cooked_mntrs;
57253 /* number of interfaces with corresponding FIF_ flags */
bc901d79 57254 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
16454cff
MT
57255diff -urNp linux-2.6.38.1/net/mac80211/iface.c linux-2.6.38.1/net/mac80211/iface.c
57256--- linux-2.6.38.1/net/mac80211/iface.c 2011-03-14 21:20:32.000000000 -0400
57257+++ linux-2.6.38.1/net/mac80211/iface.c 2011-03-21 18:31:35.000000000 -0400
57258@@ -211,7 +211,7 @@ static int ieee80211_do_open(struct net_
58c5fc13
MT
57259 break;
57260 }
57261
57262- if (local->open_count == 0) {
c52201e0 57263+ if (local_read(&local->open_count) == 0) {
58c5fc13
MT
57264 res = drv_start(local);
57265 if (res)
57266 goto err_del_bss;
16454cff 57267@@ -235,7 +235,7 @@ static int ieee80211_do_open(struct net_
bc901d79
MT
57268 memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
57269
57270 if (!is_valid_ether_addr(dev->dev_addr)) {
57271- if (!local->open_count)
c52201e0 57272+ if (!local_read(&local->open_count))
bc901d79
MT
57273 drv_stop(local);
57274 return -EADDRNOTAVAIL;
57275 }
16454cff 57276@@ -327,7 +327,7 @@ static int ieee80211_do_open(struct net_
bc901d79 57277 mutex_unlock(&local->mtx);
58c5fc13 57278
bc901d79
MT
57279 if (coming_up)
57280- local->open_count++;
c52201e0 57281+ local_inc(&local->open_count);
58c5fc13 57282
58c5fc13
MT
57283 if (hw_reconf_flags) {
57284 ieee80211_hw_config(local, hw_reconf_flags);
16454cff 57285@@ -347,7 +347,7 @@ static int ieee80211_do_open(struct net_
58c5fc13 57286 err_del_interface:
df50ba0c 57287 drv_remove_interface(local, &sdata->vif);
58c5fc13
MT
57288 err_stop:
57289- if (!local->open_count)
c52201e0 57290+ if (!local_read(&local->open_count))
58c5fc13
MT
57291 drv_stop(local);
57292 err_del_bss:
57293 sdata->bss = NULL;
16454cff 57294@@ -473,7 +473,7 @@ static void ieee80211_do_stop(struct iee
58c5fc13
MT
57295 }
57296
bc901d79
MT
57297 if (going_down)
57298- local->open_count--;
c52201e0 57299+ local_dec(&local->open_count);
58c5fc13
MT
57300
57301 switch (sdata->vif.type) {
57302 case NL80211_IFTYPE_AP_VLAN:
16454cff 57303@@ -532,7 +532,7 @@ static void ieee80211_do_stop(struct iee
58c5fc13
MT
57304
57305 ieee80211_recalc_ps(local, -1);
57306
57307- if (local->open_count == 0) {
c52201e0 57308+ if (local_read(&local->open_count) == 0) {
bc901d79
MT
57309 if (local->ops->napi_poll)
57310 napi_disable(&local->napi);
ae4e228f 57311 ieee80211_clear_tx_pending(local);
16454cff
MT
57312diff -urNp linux-2.6.38.1/net/mac80211/main.c linux-2.6.38.1/net/mac80211/main.c
57313--- linux-2.6.38.1/net/mac80211/main.c 2011-03-14 21:20:32.000000000 -0400
57314+++ linux-2.6.38.1/net/mac80211/main.c 2011-03-21 18:31:35.000000000 -0400
57315@@ -161,7 +161,7 @@ int ieee80211_hw_config(struct ieee80211
58c5fc13
MT
57316 local->hw.conf.power_level = power;
57317 }
57318
57319- if (changed && local->open_count) {
c52201e0 57320+ if (changed && local_read(&local->open_count)) {
58c5fc13
MT
57321 ret = drv_config(local, changed);
57322 /*
57323 * Goal:
16454cff
MT
57324diff -urNp linux-2.6.38.1/net/mac80211/pm.c linux-2.6.38.1/net/mac80211/pm.c
57325--- linux-2.6.38.1/net/mac80211/pm.c 2011-03-14 21:20:32.000000000 -0400
57326+++ linux-2.6.38.1/net/mac80211/pm.c 2011-03-21 18:31:35.000000000 -0400
6892158b 57327@@ -95,7 +95,7 @@ int __ieee80211_suspend(struct ieee80211
58c5fc13
MT
57328 }
57329
57330 /* stop hardware - this must stop RX */
ae4e228f 57331- if (local->open_count)
c52201e0 57332+ if (local_read(&local->open_count))
ae4e228f
MT
57333 ieee80211_stop_device(local);
57334
57335 local->suspended = true;
16454cff
MT
57336diff -urNp linux-2.6.38.1/net/mac80211/rate.c linux-2.6.38.1/net/mac80211/rate.c
57337--- linux-2.6.38.1/net/mac80211/rate.c 2011-03-14 21:20:32.000000000 -0400
57338+++ linux-2.6.38.1/net/mac80211/rate.c 2011-03-21 18:31:35.000000000 -0400
57339@@ -371,7 +371,7 @@ int ieee80211_init_rate_ctrl_alg(struct
58c5fc13
MT
57340
57341 ASSERT_RTNL();
ae4e228f
MT
57342
57343- if (local->open_count)
c52201e0 57344+ if (local_read(&local->open_count))
58c5fc13
MT
57345 return -EBUSY;
57346
ae4e228f 57347 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) {
16454cff
MT
57348diff -urNp linux-2.6.38.1/net/mac80211/rc80211_pid_debugfs.c linux-2.6.38.1/net/mac80211/rc80211_pid_debugfs.c
57349--- linux-2.6.38.1/net/mac80211/rc80211_pid_debugfs.c 2011-03-14 21:20:32.000000000 -0400
57350+++ linux-2.6.38.1/net/mac80211/rc80211_pid_debugfs.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c 57351@@ -192,7 +192,7 @@ static ssize_t rate_control_pid_events_r
58c5fc13 57352
ae4e228f 57353 spin_unlock_irqrestore(&events->lock, status);
58c5fc13 57354
ae4e228f
MT
57355- if (copy_to_user(buf, pb, p))
57356+ if (p > sizeof(pb) || copy_to_user(buf, pb, p))
57357 return -EFAULT;
58c5fc13 57358
ae4e228f 57359 return p;
16454cff
MT
57360diff -urNp linux-2.6.38.1/net/mac80211/tx.c linux-2.6.38.1/net/mac80211/tx.c
57361--- linux-2.6.38.1/net/mac80211/tx.c 2011-03-14 21:20:32.000000000 -0400
57362+++ linux-2.6.38.1/net/mac80211/tx.c 2011-03-21 18:31:35.000000000 -0400
df50ba0c
MT
57363@@ -173,7 +173,7 @@ static __le16 ieee80211_duration(struct
57364 return cpu_to_le16(dur);
57365 }
57366
57367-static int inline is_ieee80211_device(struct ieee80211_local *local,
57368+static inline int is_ieee80211_device(struct ieee80211_local *local,
57369 struct net_device *dev)
57370 {
57371 return local == wdev_priv(dev->ieee80211_ptr);
16454cff
MT
57372diff -urNp linux-2.6.38.1/net/mac80211/util.c linux-2.6.38.1/net/mac80211/util.c
57373--- linux-2.6.38.1/net/mac80211/util.c 2011-03-14 21:20:32.000000000 -0400
57374+++ linux-2.6.38.1/net/mac80211/util.c 2011-03-21 18:31:35.000000000 -0400
57375@@ -1135,7 +1135,7 @@ int ieee80211_reconfig(struct ieee80211_
ae4e228f 57376 local->resuming = true;
58c5fc13
MT
57377
57378 /* restart hardware */
57379- if (local->open_count) {
c52201e0 57380+ if (local_read(&local->open_count)) {
ae4e228f
MT
57381 /*
57382 * Upon resume hardware can sometimes be goofy due to
57383 * various platform / driver / bus issues, so restarting
16454cff
MT
57384diff -urNp linux-2.6.38.1/net/netfilter/Kconfig linux-2.6.38.1/net/netfilter/Kconfig
57385--- linux-2.6.38.1/net/netfilter/Kconfig 2011-03-14 21:20:32.000000000 -0400
57386+++ linux-2.6.38.1/net/netfilter/Kconfig 2011-03-21 18:31:35.000000000 -0400
bc901d79 57387@@ -709,6 +709,16 @@ config NETFILTER_XT_MATCH_ESP
6892158b
MT
57388
57389 To compile it as a module, choose M here. If unsure, say N.
57390
57391+config NETFILTER_XT_MATCH_GRADM
57392+ tristate '"gradm" match support'
57393+ depends on NETFILTER_XTABLES && NETFILTER_ADVANCED
57394+ depends on GRKERNSEC && !GRKERNSEC_NO_RBAC
57395+ ---help---
57396+ The gradm match allows to match on grsecurity RBAC being enabled.
57397+ It is useful when iptables rules are applied early on bootup to
57398+ prevent connections to the machine (except from a trusted host)
57399+ while the RBAC system is disabled.
57400+
57401 config NETFILTER_XT_MATCH_HASHLIMIT
57402 tristate '"hashlimit" match support'
57403 depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
16454cff
MT
57404diff -urNp linux-2.6.38.1/net/netfilter/Makefile linux-2.6.38.1/net/netfilter/Makefile
57405--- linux-2.6.38.1/net/netfilter/Makefile 2011-03-14 21:20:32.000000000 -0400
57406+++ linux-2.6.38.1/net/netfilter/Makefile 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
57407@@ -74,6 +74,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CPU) +=
57408 obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
57409 obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
57410 obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
57411+obj-$(CONFIG_NETFILTER_XT_MATCH_GRADM) += xt_gradm.o
57412 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
57413 obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
57414 obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o
16454cff
MT
57415diff -urNp linux-2.6.38.1/net/netfilter/nf_conntrack_netlink.c linux-2.6.38.1/net/netfilter/nf_conntrack_netlink.c
57416--- linux-2.6.38.1/net/netfilter/nf_conntrack_netlink.c 2011-03-14 21:20:32.000000000 -0400
57417+++ linux-2.6.38.1/net/netfilter/nf_conntrack_netlink.c 2011-03-21 18:31:35.000000000 -0400
57418@@ -761,7 +761,7 @@ static const struct nla_policy tuple_nla
bc901d79
MT
57419 static int
57420 ctnetlink_parse_tuple(const struct nlattr * const cda[],
57421 struct nf_conntrack_tuple *tuple,
57422- enum ctattr_tuple type, u_int8_t l3num)
57423+ enum ctattr_type type, u_int8_t l3num)
57424 {
57425 struct nlattr *tb[CTA_TUPLE_MAX+1];
57426 int err;
16454cff
MT
57427diff -urNp linux-2.6.38.1/net/netfilter/xt_gradm.c linux-2.6.38.1/net/netfilter/xt_gradm.c
57428--- linux-2.6.38.1/net/netfilter/xt_gradm.c 1969-12-31 19:00:00.000000000 -0500
57429+++ linux-2.6.38.1/net/netfilter/xt_gradm.c 2011-03-21 18:31:35.000000000 -0400
6892158b
MT
57430@@ -0,0 +1,51 @@
57431+/*
57432+ * gradm match for netfilter
57433