]> git.ipfire.org Git - people/ms/ipfire-3.x.git/blob - pkgs/core/kernel/patches/grsecurity-2.2.0-2.6.36-201011062054.patch
naoki: Allow diff as a filename ending for patches.
[people/ms/ipfire-3.x.git] / pkgs / core / kernel / patches / grsecurity-2.2.0-2.6.36-201011062054.patch
1 diff -urNp linux-2.6.36/arch/alpha/include/asm/dma-mapping.h linux-2.6.36/arch/alpha/include/asm/dma-mapping.h
2 --- linux-2.6.36/arch/alpha/include/asm/dma-mapping.h 2010-10-20 16:30:22.000000000 -0400
3 +++ linux-2.6.36/arch/alpha/include/asm/dma-mapping.h 2010-11-06 18:58:15.000000000 -0400
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 }
16 diff -urNp linux-2.6.36/arch/alpha/include/asm/elf.h linux-2.6.36/arch/alpha/include/asm/elf.h
17 --- linux-2.6.36/arch/alpha/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
18 +++ linux-2.6.36/arch/alpha/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
19 @@ -90,6 +90,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
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
33 diff -urNp linux-2.6.36/arch/alpha/include/asm/pgtable.h linux-2.6.36/arch/alpha/include/asm/pgtable.h
34 --- linux-2.6.36/arch/alpha/include/asm/pgtable.h 2010-10-20 16:30:22.000000000 -0400
35 +++ linux-2.6.36/arch/alpha/include/asm/pgtable.h 2010-11-06 18:58:15.000000000 -0400
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))
54 diff -urNp linux-2.6.36/arch/alpha/kernel/module.c linux-2.6.36/arch/alpha/kernel/module.c
55 --- linux-2.6.36/arch/alpha/kernel/module.c 2010-10-20 16:30:22.000000000 -0400
56 +++ linux-2.6.36/arch/alpha/kernel/module.c 2010-11-06 18:58:15.000000000 -0400
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++) {
66 diff -urNp linux-2.6.36/arch/alpha/kernel/osf_sys.c linux-2.6.36/arch/alpha/kernel/osf_sys.c
67 --- linux-2.6.36/arch/alpha/kernel/osf_sys.c 2010-10-20 16:30:22.000000000 -0400
68 +++ linux-2.6.36/arch/alpha/kernel/osf_sys.c 2010-11-06 18:58:15.000000000 -0400
69 @@ -1165,7 +1165,7 @@ arch_get_unmapped_area_1(unsigned long a
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;
78 @@ -1201,6 +1201,10 @@ arch_get_unmapped_area(struct file *filp
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)
89 @@ -1208,8 +1212,8 @@ arch_get_unmapped_area(struct file *filp
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
100 diff -urNp linux-2.6.36/arch/alpha/kernel/pci_iommu.c linux-2.6.36/arch/alpha/kernel/pci_iommu.c
101 --- linux-2.6.36/arch/alpha/kernel/pci_iommu.c 2010-10-20 16:30:22.000000000 -0400
102 +++ linux-2.6.36/arch/alpha/kernel/pci_iommu.c 2010-11-06 18:58:15.000000000 -0400
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);
119 diff -urNp linux-2.6.36/arch/alpha/kernel/pci-noop.c linux-2.6.36/arch/alpha/kernel/pci-noop.c
120 --- linux-2.6.36/arch/alpha/kernel/pci-noop.c 2010-10-20 16:30:22.000000000 -0400
121 +++ linux-2.6.36/arch/alpha/kernel/pci-noop.c 2010-11-06 18:58:15.000000000 -0400
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)
140 diff -urNp linux-2.6.36/arch/alpha/mm/fault.c linux-2.6.36/arch/alpha/mm/fault.c
141 --- linux-2.6.36/arch/alpha/mm/fault.c 2010-10-20 16:30:22.000000000 -0400
142 +++ linux-2.6.36/arch/alpha/mm/fault.c 2010-11-06 18:58:15.000000000 -0400
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)))
299 diff -urNp linux-2.6.36/arch/arm/include/asm/elf.h linux-2.6.36/arch/arm/include/asm/elf.h
300 --- linux-2.6.36/arch/arm/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
301 +++ linux-2.6.36/arch/arm/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
302 @@ -113,7 +113,14 @@ int dump_task_regs(struct task_struct *t
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
318 diff -urNp linux-2.6.36/arch/arm/include/asm/kmap_types.h linux-2.6.36/arch/arm/include/asm/kmap_types.h
319 --- linux-2.6.36/arch/arm/include/asm/kmap_types.h 2010-10-20 16:30:22.000000000 -0400
320 +++ linux-2.6.36/arch/arm/include/asm/kmap_types.h 2010-11-06 18:58:15.000000000 -0400
321 @@ -21,6 +21,7 @@ enum km_type {
322 KM_L1_CACHE,
323 KM_L2_CACHE,
324 KM_KDB,
325 + KM_CLEARPAGE,
326 KM_TYPE_NR
327 };
328
329 diff -urNp linux-2.6.36/arch/arm/include/asm/uaccess.h linux-2.6.36/arch/arm/include/asm/uaccess.h
330 --- linux-2.6.36/arch/arm/include/asm/uaccess.h 2010-10-20 16:30:22.000000000 -0400
331 +++ linux-2.6.36/arch/arm/include/asm/uaccess.h 2010-11-06 18:58:15.000000000 -0400
332 @@ -403,6 +403,9 @@ extern unsigned long __must_check __strn
333
334 static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
335 {
336 + if ((long)n < 0)
337 + return n;
338 +
339 if (access_ok(VERIFY_READ, from, n))
340 n = __copy_from_user(to, from, n);
341 else /* security hole - plug it */
342 @@ -412,6 +415,9 @@ static inline unsigned long __must_check
343
344 static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
345 {
346 + if ((long)n < 0)
347 + return n;
348 +
349 if (access_ok(VERIFY_WRITE, to, n))
350 n = __copy_to_user(to, from, n);
351 return n;
352 diff -urNp linux-2.6.36/arch/arm/kernel/kgdb.c linux-2.6.36/arch/arm/kernel/kgdb.c
353 --- linux-2.6.36/arch/arm/kernel/kgdb.c 2010-10-20 16:30:22.000000000 -0400
354 +++ linux-2.6.36/arch/arm/kernel/kgdb.c 2010-11-06 18:58:15.000000000 -0400
355 @@ -246,7 +246,7 @@ void kgdb_arch_exit(void)
356 * and we handle the normal undef case within the do_undefinstr
357 * handler.
358 */
359 -struct kgdb_arch arch_kgdb_ops = {
360 +const struct kgdb_arch arch_kgdb_ops = {
361 #ifndef __ARMEB__
362 .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
363 #else /* ! __ARMEB__ */
364 diff -urNp linux-2.6.36/arch/arm/mach-at91/pm.c linux-2.6.36/arch/arm/mach-at91/pm.c
365 --- linux-2.6.36/arch/arm/mach-at91/pm.c 2010-10-20 16:30:22.000000000 -0400
366 +++ linux-2.6.36/arch/arm/mach-at91/pm.c 2010-11-06 18:58:15.000000000 -0400
367 @@ -294,7 +294,7 @@ static void at91_pm_end(void)
368 }
369
370
371 -static struct platform_suspend_ops at91_pm_ops ={
372 +static const struct platform_suspend_ops at91_pm_ops ={
373 .valid = at91_pm_valid_state,
374 .begin = at91_pm_begin,
375 .enter = at91_pm_enter,
376 diff -urNp linux-2.6.36/arch/arm/mach-davinci/pm.c linux-2.6.36/arch/arm/mach-davinci/pm.c
377 --- linux-2.6.36/arch/arm/mach-davinci/pm.c 2010-10-20 16:30:22.000000000 -0400
378 +++ linux-2.6.36/arch/arm/mach-davinci/pm.c 2010-11-06 18:58:15.000000000 -0400
379 @@ -110,7 +110,7 @@ static int davinci_pm_enter(suspend_stat
380 return ret;
381 }
382
383 -static struct platform_suspend_ops davinci_pm_ops = {
384 +static const struct platform_suspend_ops davinci_pm_ops = {
385 .enter = davinci_pm_enter,
386 .valid = suspend_valid_only_mem,
387 };
388 diff -urNp linux-2.6.36/arch/arm/mach-imx/pm-imx27.c linux-2.6.36/arch/arm/mach-imx/pm-imx27.c
389 --- linux-2.6.36/arch/arm/mach-imx/pm-imx27.c 2010-10-20 16:30:22.000000000 -0400
390 +++ linux-2.6.36/arch/arm/mach-imx/pm-imx27.c 2010-11-06 18:58:15.000000000 -0400
391 @@ -32,7 +32,7 @@ static int mx27_suspend_enter(suspend_st
392 return 0;
393 }
394
395 -static struct platform_suspend_ops mx27_suspend_ops = {
396 +static const struct platform_suspend_ops mx27_suspend_ops = {
397 .enter = mx27_suspend_enter,
398 .valid = suspend_valid_only_mem,
399 };
400 diff -urNp linux-2.6.36/arch/arm/mach-lpc32xx/pm.c linux-2.6.36/arch/arm/mach-lpc32xx/pm.c
401 --- linux-2.6.36/arch/arm/mach-lpc32xx/pm.c 2010-10-20 16:30:22.000000000 -0400
402 +++ linux-2.6.36/arch/arm/mach-lpc32xx/pm.c 2010-11-06 18:58:15.000000000 -0400
403 @@ -123,7 +123,7 @@ static int lpc32xx_pm_enter(suspend_stat
404 return 0;
405 }
406
407 -static struct platform_suspend_ops lpc32xx_pm_ops = {
408 +static const struct platform_suspend_ops lpc32xx_pm_ops = {
409 .valid = suspend_valid_only_mem,
410 .enter = lpc32xx_pm_enter,
411 };
412 diff -urNp linux-2.6.36/arch/arm/mach-msm/last_radio_log.c linux-2.6.36/arch/arm/mach-msm/last_radio_log.c
413 --- linux-2.6.36/arch/arm/mach-msm/last_radio_log.c 2010-10-20 16:30:22.000000000 -0400
414 +++ linux-2.6.36/arch/arm/mach-msm/last_radio_log.c 2010-11-06 18:58:15.000000000 -0400
415 @@ -47,6 +47,7 @@ static ssize_t last_radio_log_read(struc
416 return count;
417 }
418
419 +/* cannot be const, see msm_init_last_radio_log */
420 static struct file_operations last_radio_log_fops = {
421 .read = last_radio_log_read
422 };
423 diff -urNp linux-2.6.36/arch/arm/mach-omap1/pm.c linux-2.6.36/arch/arm/mach-omap1/pm.c
424 --- linux-2.6.36/arch/arm/mach-omap1/pm.c 2010-10-20 16:30:22.000000000 -0400
425 +++ linux-2.6.36/arch/arm/mach-omap1/pm.c 2010-11-06 18:58:15.000000000 -0400
426 @@ -647,7 +647,7 @@ static struct irqaction omap_wakeup_irq
427
428
429
430 -static struct platform_suspend_ops omap_pm_ops ={
431 +static const struct platform_suspend_ops omap_pm_ops ={
432 .prepare = omap_pm_prepare,
433 .enter = omap_pm_enter,
434 .finish = omap_pm_finish,
435 diff -urNp linux-2.6.36/arch/arm/mach-omap2/pm24xx.c linux-2.6.36/arch/arm/mach-omap2/pm24xx.c
436 --- linux-2.6.36/arch/arm/mach-omap2/pm24xx.c 2010-10-20 16:30:22.000000000 -0400
437 +++ linux-2.6.36/arch/arm/mach-omap2/pm24xx.c 2010-11-06 18:58:15.000000000 -0400
438 @@ -324,7 +324,7 @@ static void omap2_pm_finish(void)
439 enable_hlt();
440 }
441
442 -static struct platform_suspend_ops omap_pm_ops = {
443 +static const struct platform_suspend_ops omap_pm_ops = {
444 .prepare = omap2_pm_prepare,
445 .enter = omap2_pm_enter,
446 .finish = omap2_pm_finish,
447 diff -urNp linux-2.6.36/arch/arm/mach-omap2/pm34xx.c linux-2.6.36/arch/arm/mach-omap2/pm34xx.c
448 --- linux-2.6.36/arch/arm/mach-omap2/pm34xx.c 2010-10-20 16:30:22.000000000 -0400
449 +++ linux-2.6.36/arch/arm/mach-omap2/pm34xx.c 2010-11-06 18:58:15.000000000 -0400
450 @@ -672,7 +672,7 @@ static void omap3_pm_end(void)
451 return;
452 }
453
454 -static struct platform_suspend_ops omap_pm_ops = {
455 +static const struct platform_suspend_ops omap_pm_ops = {
456 .begin = omap3_pm_begin,
457 .end = omap3_pm_end,
458 .prepare = omap3_pm_prepare,
459 diff -urNp linux-2.6.36/arch/arm/mach-omap2/pm44xx.c linux-2.6.36/arch/arm/mach-omap2/pm44xx.c
460 --- linux-2.6.36/arch/arm/mach-omap2/pm44xx.c 2010-10-20 16:30:22.000000000 -0400
461 +++ linux-2.6.36/arch/arm/mach-omap2/pm44xx.c 2010-11-06 18:58:15.000000000 -0400
462 @@ -75,7 +75,7 @@ static void omap4_pm_end(void)
463 return;
464 }
465
466 -static struct platform_suspend_ops omap_pm_ops = {
467 +static const struct platform_suspend_ops omap_pm_ops = {
468 .begin = omap4_pm_begin,
469 .end = omap4_pm_end,
470 .prepare = omap4_pm_prepare,
471 diff -urNp linux-2.6.36/arch/arm/mach-pnx4008/pm.c linux-2.6.36/arch/arm/mach-pnx4008/pm.c
472 --- linux-2.6.36/arch/arm/mach-pnx4008/pm.c 2010-10-20 16:30:22.000000000 -0400
473 +++ linux-2.6.36/arch/arm/mach-pnx4008/pm.c 2010-11-06 18:58:15.000000000 -0400
474 @@ -119,7 +119,7 @@ static int pnx4008_pm_valid(suspend_stat
475 (state == PM_SUSPEND_MEM);
476 }
477
478 -static struct platform_suspend_ops pnx4008_pm_ops = {
479 +static const struct platform_suspend_ops pnx4008_pm_ops = {
480 .enter = pnx4008_pm_enter,
481 .valid = pnx4008_pm_valid,
482 };
483 diff -urNp linux-2.6.36/arch/arm/mach-pxa/pm.c linux-2.6.36/arch/arm/mach-pxa/pm.c
484 --- linux-2.6.36/arch/arm/mach-pxa/pm.c 2010-10-20 16:30:22.000000000 -0400
485 +++ linux-2.6.36/arch/arm/mach-pxa/pm.c 2010-11-06 18:58:15.000000000 -0400
486 @@ -96,7 +96,7 @@ void pxa_pm_finish(void)
487 pxa_cpu_pm_fns->finish();
488 }
489
490 -static struct platform_suspend_ops pxa_pm_ops = {
491 +static const struct platform_suspend_ops pxa_pm_ops = {
492 .valid = pxa_pm_valid,
493 .enter = pxa_pm_enter,
494 .prepare = pxa_pm_prepare,
495 diff -urNp linux-2.6.36/arch/arm/mach-pxa/sharpsl_pm.c linux-2.6.36/arch/arm/mach-pxa/sharpsl_pm.c
496 --- linux-2.6.36/arch/arm/mach-pxa/sharpsl_pm.c 2010-10-20 16:30:22.000000000 -0400
497 +++ linux-2.6.36/arch/arm/mach-pxa/sharpsl_pm.c 2010-11-06 18:58:15.000000000 -0400
498 @@ -868,7 +868,7 @@ static void sharpsl_apm_get_power_status
499 }
500
501 #ifdef CONFIG_PM
502 -static struct platform_suspend_ops sharpsl_pm_ops = {
503 +static const struct platform_suspend_ops sharpsl_pm_ops = {
504 .prepare = pxa_pm_prepare,
505 .finish = pxa_pm_finish,
506 .enter = corgi_pxa_pm_enter,
507 diff -urNp linux-2.6.36/arch/arm/mach-sa1100/pm.c linux-2.6.36/arch/arm/mach-sa1100/pm.c
508 --- linux-2.6.36/arch/arm/mach-sa1100/pm.c 2010-10-20 16:30:22.000000000 -0400
509 +++ linux-2.6.36/arch/arm/mach-sa1100/pm.c 2010-11-06 18:58:15.000000000 -0400
510 @@ -120,7 +120,7 @@ unsigned long sleep_phys_sp(void *sp)
511 return virt_to_phys(sp);
512 }
513
514 -static struct platform_suspend_ops sa11x0_pm_ops = {
515 +static const struct platform_suspend_ops sa11x0_pm_ops = {
516 .enter = sa11x0_pm_enter,
517 .valid = suspend_valid_only_mem,
518 };
519 diff -urNp linux-2.6.36/arch/arm/mm/fault.c linux-2.6.36/arch/arm/mm/fault.c
520 --- linux-2.6.36/arch/arm/mm/fault.c 2010-10-20 16:30:22.000000000 -0400
521 +++ linux-2.6.36/arch/arm/mm/fault.c 2010-11-06 18:58:15.000000000 -0400
522 @@ -167,6 +167,13 @@ __do_user_fault(struct task_struct *tsk,
523 }
524 #endif
525
526 +#ifdef CONFIG_PAX_PAGEEXEC
527 + if (fsr & FSR_LNX_PF) {
528 + pax_report_fault(regs, (void *)regs->ARM_pc, (void *)regs->ARM_sp);
529 + do_group_exit(SIGKILL);
530 + }
531 +#endif
532 +
533 tsk->thread.address = addr;
534 tsk->thread.error_code = fsr;
535 tsk->thread.trap_no = 14;
536 @@ -364,6 +371,33 @@ do_page_fault(unsigned long addr, unsign
537 }
538 #endif /* CONFIG_MMU */
539
540 +#ifdef CONFIG_PAX_PAGEEXEC
541 +void pax_report_insns(void *pc, void *sp)
542 +{
543 + long i;
544 +
545 + printk(KERN_ERR "PAX: bytes at PC: ");
546 + for (i = 0; i < 20; i++) {
547 + unsigned char c;
548 + if (get_user(c, (__force unsigned char __user *)pc+i))
549 + printk(KERN_CONT "?? ");
550 + else
551 + printk(KERN_CONT "%02x ", c);
552 + }
553 + printk("\n");
554 +
555 + printk(KERN_ERR "PAX: bytes at SP-4: ");
556 + for (i = -1; i < 20; i++) {
557 + unsigned long c;
558 + if (get_user(c, (__force unsigned long __user *)sp+i))
559 + printk(KERN_CONT "???????? ");
560 + else
561 + printk(KERN_CONT "%08lx ", c);
562 + }
563 + printk("\n");
564 +}
565 +#endif
566 +
567 /*
568 * First Level Translation Fault Handler
569 *
570 diff -urNp linux-2.6.36/arch/arm/mm/mmap.c linux-2.6.36/arch/arm/mm/mmap.c
571 --- linux-2.6.36/arch/arm/mm/mmap.c 2010-10-20 16:30:22.000000000 -0400
572 +++ linux-2.6.36/arch/arm/mm/mmap.c 2010-11-06 18:58:15.000000000 -0400
573 @@ -64,6 +64,10 @@ arch_get_unmapped_area(struct file *filp
574 if (len > TASK_SIZE)
575 return -ENOMEM;
576
577 +#ifdef CONFIG_PAX_RANDMMAP
578 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
579 +#endif
580 +
581 if (addr) {
582 if (do_align)
583 addr = COLOUR_ALIGN(addr, pgoff);
584 @@ -71,15 +75,14 @@ arch_get_unmapped_area(struct file *filp
585 addr = PAGE_ALIGN(addr);
586
587 vma = find_vma(mm, addr);
588 - if (TASK_SIZE - len >= addr &&
589 - (!vma || addr + len <= vma->vm_start))
590 + if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
591 return addr;
592 }
593 if (len > mm->cached_hole_size) {
594 - start_addr = addr = mm->free_area_cache;
595 + start_addr = addr = mm->free_area_cache;
596 } else {
597 - start_addr = addr = TASK_UNMAPPED_BASE;
598 - mm->cached_hole_size = 0;
599 + start_addr = addr = mm->mmap_base;
600 + mm->cached_hole_size = 0;
601 }
602 /* 8 bits of randomness in 20 address space bits */
603 if (current->flags & PF_RANDOMIZE)
604 @@ -98,14 +101,14 @@ full_search:
605 * Start a new search - just in case we missed
606 * some holes.
607 */
608 - if (start_addr != TASK_UNMAPPED_BASE) {
609 - start_addr = addr = TASK_UNMAPPED_BASE;
610 + if (start_addr != mm->mmap_base) {
611 + start_addr = addr = mm->mmap_base;
612 mm->cached_hole_size = 0;
613 goto full_search;
614 }
615 return -ENOMEM;
616 }
617 - if (!vma || addr + len <= vma->vm_start) {
618 + if (check_heap_stack_gap(vma, addr, len)) {
619 /*
620 * Remember the place where we stopped the search:
621 */
622 diff -urNp linux-2.6.36/arch/arm/plat-samsung/pm.c linux-2.6.36/arch/arm/plat-samsung/pm.c
623 --- linux-2.6.36/arch/arm/plat-samsung/pm.c 2010-10-20 16:30:22.000000000 -0400
624 +++ linux-2.6.36/arch/arm/plat-samsung/pm.c 2010-11-06 18:58:15.000000000 -0400
625 @@ -355,7 +355,7 @@ static void s3c_pm_finish(void)
626 s3c_pm_check_cleanup();
627 }
628
629 -static struct platform_suspend_ops s3c_pm_ops = {
630 +static const struct platform_suspend_ops s3c_pm_ops = {
631 .enter = s3c_pm_enter,
632 .prepare = s3c_pm_prepare,
633 .finish = s3c_pm_finish,
634 diff -urNp linux-2.6.36/arch/avr32/include/asm/elf.h linux-2.6.36/arch/avr32/include/asm/elf.h
635 --- linux-2.6.36/arch/avr32/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
636 +++ linux-2.6.36/arch/avr32/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
637 @@ -84,8 +84,14 @@ typedef struct user_fpu_struct elf_fpreg
638 the loader. We need to make sure that it is out of the way of the program
639 that it will "exec", and that there is sufficient room for the brk. */
640
641 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
642 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
643
644 +#ifdef CONFIG_PAX_ASLR
645 +#define PAX_ELF_ET_DYN_BASE 0x00001000UL
646 +
647 +#define PAX_DELTA_MMAP_LEN 15
648 +#define PAX_DELTA_STACK_LEN 15
649 +#endif
650
651 /* This yields a mask that user programs can use to figure out what
652 instruction set this CPU supports. This could be done in user space,
653 diff -urNp linux-2.6.36/arch/avr32/include/asm/kmap_types.h linux-2.6.36/arch/avr32/include/asm/kmap_types.h
654 --- linux-2.6.36/arch/avr32/include/asm/kmap_types.h 2010-10-20 16:30:22.000000000 -0400
655 +++ linux-2.6.36/arch/avr32/include/asm/kmap_types.h 2010-11-06 18:58:15.000000000 -0400
656 @@ -22,7 +22,8 @@ D(10) KM_IRQ0,
657 D(11) KM_IRQ1,
658 D(12) KM_SOFTIRQ0,
659 D(13) KM_SOFTIRQ1,
660 -D(14) KM_TYPE_NR
661 +D(14) KM_CLEARPAGE,
662 +D(15) KM_TYPE_NR
663 };
664
665 #undef D
666 diff -urNp linux-2.6.36/arch/avr32/mach-at32ap/pm.c linux-2.6.36/arch/avr32/mach-at32ap/pm.c
667 --- linux-2.6.36/arch/avr32/mach-at32ap/pm.c 2010-10-20 16:30:22.000000000 -0400
668 +++ linux-2.6.36/arch/avr32/mach-at32ap/pm.c 2010-11-06 18:58:15.000000000 -0400
669 @@ -176,7 +176,7 @@ out:
670 return 0;
671 }
672
673 -static struct platform_suspend_ops avr32_pm_ops = {
674 +static const struct platform_suspend_ops avr32_pm_ops = {
675 .valid = avr32_pm_valid_state,
676 .enter = avr32_pm_enter,
677 };
678 diff -urNp linux-2.6.36/arch/avr32/mm/fault.c linux-2.6.36/arch/avr32/mm/fault.c
679 --- linux-2.6.36/arch/avr32/mm/fault.c 2010-10-20 16:30:22.000000000 -0400
680 +++ linux-2.6.36/arch/avr32/mm/fault.c 2010-11-06 18:58:15.000000000 -0400
681 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
682
683 int exception_trace = 1;
684
685 +#ifdef CONFIG_PAX_PAGEEXEC
686 +void pax_report_insns(void *pc, void *sp)
687 +{
688 + unsigned long i;
689 +
690 + printk(KERN_ERR "PAX: bytes at PC: ");
691 + for (i = 0; i < 20; i++) {
692 + unsigned char c;
693 + if (get_user(c, (unsigned char *)pc+i))
694 + printk(KERN_CONT "???????? ");
695 + else
696 + printk(KERN_CONT "%02x ", c);
697 + }
698 + printk("\n");
699 +}
700 +#endif
701 +
702 /*
703 * This routine handles page faults. It determines the address and the
704 * problem, and then passes it off to one of the appropriate routines.
705 @@ -156,6 +173,16 @@ bad_area:
706 up_read(&mm->mmap_sem);
707
708 if (user_mode(regs)) {
709 +
710 +#ifdef CONFIG_PAX_PAGEEXEC
711 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
712 + if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
713 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
714 + do_group_exit(SIGKILL);
715 + }
716 + }
717 +#endif
718 +
719 if (exception_trace && printk_ratelimit())
720 printk("%s%s[%d]: segfault at %08lx pc %08lx "
721 "sp %08lx ecr %lu\n",
722 diff -urNp linux-2.6.36/arch/blackfin/kernel/kgdb.c linux-2.6.36/arch/blackfin/kernel/kgdb.c
723 --- linux-2.6.36/arch/blackfin/kernel/kgdb.c 2010-10-20 16:30:22.000000000 -0400
724 +++ linux-2.6.36/arch/blackfin/kernel/kgdb.c 2010-11-06 18:58:15.000000000 -0400
725 @@ -397,7 +397,7 @@ int kgdb_arch_handle_exception(int vecto
726 return -1; /* this means that we do not want to exit from the handler */
727 }
728
729 -struct kgdb_arch arch_kgdb_ops = {
730 +const struct kgdb_arch arch_kgdb_ops = {
731 .gdb_bpt_instr = {0xa1},
732 #ifdef CONFIG_SMP
733 .flags = KGDB_HW_BREAKPOINT|KGDB_THR_PROC_SWAP,
734 diff -urNp linux-2.6.36/arch/blackfin/mach-common/pm.c linux-2.6.36/arch/blackfin/mach-common/pm.c
735 --- linux-2.6.36/arch/blackfin/mach-common/pm.c 2010-10-20 16:30:22.000000000 -0400
736 +++ linux-2.6.36/arch/blackfin/mach-common/pm.c 2010-11-06 18:58:15.000000000 -0400
737 @@ -233,7 +233,7 @@ static int bfin_pm_enter(suspend_state_t
738 return 0;
739 }
740
741 -struct platform_suspend_ops bfin_pm_ops = {
742 +const struct platform_suspend_ops bfin_pm_ops = {
743 .enter = bfin_pm_enter,
744 .valid = bfin_pm_valid,
745 };
746 diff -urNp linux-2.6.36/arch/blackfin/mm/maccess.c linux-2.6.36/arch/blackfin/mm/maccess.c
747 --- linux-2.6.36/arch/blackfin/mm/maccess.c 2010-10-20 16:30:22.000000000 -0400
748 +++ linux-2.6.36/arch/blackfin/mm/maccess.c 2010-11-06 18:58:15.000000000 -0400
749 @@ -16,7 +16,7 @@ static int validate_memory_access_addres
750 return bfin_mem_access_type(addr, size);
751 }
752
753 -long probe_kernel_read(void *dst, void *src, size_t size)
754 +long probe_kernel_read(void *dst, const void *src, size_t size)
755 {
756 unsigned long lsrc = (unsigned long)src;
757 int mem_type;
758 @@ -55,7 +55,7 @@ long probe_kernel_read(void *dst, void *
759 return -EFAULT;
760 }
761
762 -long probe_kernel_write(void *dst, void *src, size_t size)
763 +long probe_kernel_write(void *dst, const void *src, size_t size)
764 {
765 unsigned long ldst = (unsigned long)dst;
766 int mem_type;
767 diff -urNp linux-2.6.36/arch/frv/include/asm/kmap_types.h linux-2.6.36/arch/frv/include/asm/kmap_types.h
768 --- linux-2.6.36/arch/frv/include/asm/kmap_types.h 2010-10-20 16:30:22.000000000 -0400
769 +++ linux-2.6.36/arch/frv/include/asm/kmap_types.h 2010-11-06 18:58:15.000000000 -0400
770 @@ -23,6 +23,7 @@ enum km_type {
771 KM_IRQ1,
772 KM_SOFTIRQ0,
773 KM_SOFTIRQ1,
774 + KM_CLEARPAGE,
775 KM_TYPE_NR
776 };
777
778 diff -urNp linux-2.6.36/arch/frv/mm/elf-fdpic.c linux-2.6.36/arch/frv/mm/elf-fdpic.c
779 --- linux-2.6.36/arch/frv/mm/elf-fdpic.c 2010-10-20 16:30:22.000000000 -0400
780 +++ linux-2.6.36/arch/frv/mm/elf-fdpic.c 2010-11-06 18:58:15.000000000 -0400
781 @@ -73,8 +73,7 @@ unsigned long arch_get_unmapped_area(str
782 if (addr) {
783 addr = PAGE_ALIGN(addr);
784 vma = find_vma(current->mm, addr);
785 - if (TASK_SIZE - len >= addr &&
786 - (!vma || addr + len <= vma->vm_start))
787 + if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
788 goto success;
789 }
790
791 @@ -89,7 +88,7 @@ unsigned long arch_get_unmapped_area(str
792 for (; vma; vma = vma->vm_next) {
793 if (addr > limit)
794 break;
795 - if (addr + len <= vma->vm_start)
796 + if (check_heap_stack_gap(vma, addr, len))
797 goto success;
798 addr = vma->vm_end;
799 }
800 @@ -104,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
801 for (; vma; vma = vma->vm_next) {
802 if (addr > limit)
803 break;
804 - if (addr + len <= vma->vm_start)
805 + if (check_heap_stack_gap(vma, addr, len))
806 goto success;
807 addr = vma->vm_end;
808 }
809 diff -urNp linux-2.6.36/arch/ia64/hp/common/hwsw_iommu.c linux-2.6.36/arch/ia64/hp/common/hwsw_iommu.c
810 --- linux-2.6.36/arch/ia64/hp/common/hwsw_iommu.c 2010-10-20 16:30:22.000000000 -0400
811 +++ linux-2.6.36/arch/ia64/hp/common/hwsw_iommu.c 2010-11-06 18:58:15.000000000 -0400
812 @@ -17,7 +17,7 @@
813 #include <linux/swiotlb.h>
814 #include <asm/machvec.h>
815
816 -extern struct dma_map_ops sba_dma_ops, swiotlb_dma_ops;
817 +extern const struct dma_map_ops sba_dma_ops, swiotlb_dma_ops;
818
819 /* swiotlb declarations & definitions: */
820 extern int swiotlb_late_init_with_default_size (size_t size);
821 @@ -33,7 +33,7 @@ static inline int use_swiotlb(struct dev
822 !sba_dma_ops.dma_supported(dev, *dev->dma_mask);
823 }
824
825 -struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
826 +const struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
827 {
828 if (use_swiotlb(dev))
829 return &swiotlb_dma_ops;
830 diff -urNp linux-2.6.36/arch/ia64/hp/common/sba_iommu.c linux-2.6.36/arch/ia64/hp/common/sba_iommu.c
831 --- linux-2.6.36/arch/ia64/hp/common/sba_iommu.c 2010-10-20 16:30:22.000000000 -0400
832 +++ linux-2.6.36/arch/ia64/hp/common/sba_iommu.c 2010-11-06 18:58:15.000000000 -0400
833 @@ -2097,7 +2097,7 @@ static struct acpi_driver acpi_sba_ioc_d
834 },
835 };
836
837 -extern struct dma_map_ops swiotlb_dma_ops;
838 +extern const struct dma_map_ops swiotlb_dma_ops;
839
840 static int __init
841 sba_init(void)
842 @@ -2211,7 +2211,7 @@ sba_page_override(char *str)
843
844 __setup("sbapagesize=",sba_page_override);
845
846 -struct dma_map_ops sba_dma_ops = {
847 +const struct dma_map_ops sba_dma_ops = {
848 .alloc_coherent = sba_alloc_coherent,
849 .free_coherent = sba_free_coherent,
850 .map_page = sba_map_page,
851 diff -urNp linux-2.6.36/arch/ia64/include/asm/dma-mapping.h linux-2.6.36/arch/ia64/include/asm/dma-mapping.h
852 --- linux-2.6.36/arch/ia64/include/asm/dma-mapping.h 2010-10-20 16:30:22.000000000 -0400
853 +++ linux-2.6.36/arch/ia64/include/asm/dma-mapping.h 2010-11-06 18:58:15.000000000 -0400
854 @@ -12,7 +12,7 @@
855
856 #define ARCH_HAS_DMA_GET_REQUIRED_MASK
857
858 -extern struct dma_map_ops *dma_ops;
859 +extern const struct dma_map_ops *dma_ops;
860 extern struct ia64_machine_vector ia64_mv;
861 extern void set_iommu_machvec(void);
862
863 @@ -24,7 +24,7 @@ extern void machvec_dma_sync_sg(struct d
864 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
865 dma_addr_t *daddr, gfp_t gfp)
866 {
867 - struct dma_map_ops *ops = platform_dma_get_ops(dev);
868 + const struct dma_map_ops *ops = platform_dma_get_ops(dev);
869 void *caddr;
870
871 caddr = ops->alloc_coherent(dev, size, daddr, gfp);
872 @@ -35,7 +35,7 @@ static inline void *dma_alloc_coherent(s
873 static inline void dma_free_coherent(struct device *dev, size_t size,
874 void *caddr, dma_addr_t daddr)
875 {
876 - struct dma_map_ops *ops = platform_dma_get_ops(dev);
877 + const struct dma_map_ops *ops = platform_dma_get_ops(dev);
878 debug_dma_free_coherent(dev, size, caddr, daddr);
879 ops->free_coherent(dev, size, caddr, daddr);
880 }
881 @@ -49,13 +49,13 @@ static inline void dma_free_coherent(str
882
883 static inline int dma_mapping_error(struct device *dev, dma_addr_t daddr)
884 {
885 - struct dma_map_ops *ops = platform_dma_get_ops(dev);
886 + const struct dma_map_ops *ops = platform_dma_get_ops(dev);
887 return ops->mapping_error(dev, daddr);
888 }
889
890 static inline int dma_supported(struct device *dev, u64 mask)
891 {
892 - struct dma_map_ops *ops = platform_dma_get_ops(dev);
893 + const struct dma_map_ops *ops = platform_dma_get_ops(dev);
894 return ops->dma_supported(dev, mask);
895 }
896
897 diff -urNp linux-2.6.36/arch/ia64/include/asm/elf.h linux-2.6.36/arch/ia64/include/asm/elf.h
898 --- linux-2.6.36/arch/ia64/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
899 +++ linux-2.6.36/arch/ia64/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
900 @@ -42,6 +42,13 @@
901 */
902 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
903
904 +#ifdef CONFIG_PAX_ASLR
905 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
906 +
907 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
908 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
909 +#endif
910 +
911 #define PT_IA_64_UNWIND 0x70000001
912
913 /* IA-64 relocations: */
914 diff -urNp linux-2.6.36/arch/ia64/include/asm/machvec.h linux-2.6.36/arch/ia64/include/asm/machvec.h
915 --- linux-2.6.36/arch/ia64/include/asm/machvec.h 2010-10-20 16:30:22.000000000 -0400
916 +++ linux-2.6.36/arch/ia64/include/asm/machvec.h 2010-11-06 18:58:15.000000000 -0400
917 @@ -45,7 +45,7 @@ typedef void ia64_mv_kernel_launch_event
918 /* DMA-mapping interface: */
919 typedef void ia64_mv_dma_init (void);
920 typedef u64 ia64_mv_dma_get_required_mask (struct device *);
921 -typedef struct dma_map_ops *ia64_mv_dma_get_ops(struct device *);
922 +typedef const struct dma_map_ops *ia64_mv_dma_get_ops(struct device *);
923
924 /*
925 * WARNING: The legacy I/O space is _architected_. Platforms are
926 @@ -251,7 +251,7 @@ extern void machvec_init_from_cmdline(co
927 # endif /* CONFIG_IA64_GENERIC */
928
929 extern void swiotlb_dma_init(void);
930 -extern struct dma_map_ops *dma_get_ops(struct device *);
931 +extern const struct dma_map_ops *dma_get_ops(struct device *);
932
933 /*
934 * Define default versions so we can extend machvec for new platforms without having
935 diff -urNp linux-2.6.36/arch/ia64/include/asm/pgtable.h linux-2.6.36/arch/ia64/include/asm/pgtable.h
936 --- linux-2.6.36/arch/ia64/include/asm/pgtable.h 2010-10-20 16:30:22.000000000 -0400
937 +++ linux-2.6.36/arch/ia64/include/asm/pgtable.h 2010-11-06 18:58:15.000000000 -0400
938 @@ -12,7 +12,7 @@
939 * David Mosberger-Tang <davidm@hpl.hp.com>
940 */
941
942 -
943 +#include <linux/const.h>
944 #include <asm/mman.h>
945 #include <asm/page.h>
946 #include <asm/processor.h>
947 @@ -143,6 +143,17 @@
948 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
949 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
950 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
951 +
952 +#ifdef CONFIG_PAX_PAGEEXEC
953 +# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
954 +# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
955 +# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
956 +#else
957 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
958 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
959 +# define PAGE_COPY_NOEXEC PAGE_COPY
960 +#endif
961 +
962 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
963 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
964 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
965 diff -urNp linux-2.6.36/arch/ia64/include/asm/uaccess.h linux-2.6.36/arch/ia64/include/asm/uaccess.h
966 --- linux-2.6.36/arch/ia64/include/asm/uaccess.h 2010-10-20 16:30:22.000000000 -0400
967 +++ linux-2.6.36/arch/ia64/include/asm/uaccess.h 2010-11-06 18:58:15.000000000 -0400
968 @@ -257,7 +257,7 @@ __copy_from_user (void *to, const void _
969 const void *__cu_from = (from); \
970 long __cu_len = (n); \
971 \
972 - if (__access_ok(__cu_to, __cu_len, get_fs())) \
973 + if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_to, __cu_len, get_fs())) \
974 __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
975 __cu_len; \
976 })
977 @@ -269,7 +269,7 @@ __copy_from_user (void *to, const void _
978 long __cu_len = (n); \
979 \
980 __chk_user_ptr(__cu_from); \
981 - if (__access_ok(__cu_from, __cu_len, get_fs())) \
982 + if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_from, __cu_len, get_fs())) \
983 __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \
984 __cu_len; \
985 })
986 diff -urNp linux-2.6.36/arch/ia64/kernel/dma-mapping.c linux-2.6.36/arch/ia64/kernel/dma-mapping.c
987 --- linux-2.6.36/arch/ia64/kernel/dma-mapping.c 2010-10-20 16:30:22.000000000 -0400
988 +++ linux-2.6.36/arch/ia64/kernel/dma-mapping.c 2010-11-06 18:58:15.000000000 -0400
989 @@ -3,7 +3,7 @@
990 /* Set this to 1 if there is a HW IOMMU in the system */
991 int iommu_detected __read_mostly;
992
993 -struct dma_map_ops *dma_ops;
994 +const struct dma_map_ops *dma_ops;
995 EXPORT_SYMBOL(dma_ops);
996
997 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
998 @@ -16,7 +16,7 @@ static int __init dma_init(void)
999 }
1000 fs_initcall(dma_init);
1001
1002 -struct dma_map_ops *dma_get_ops(struct device *dev)
1003 +const struct dma_map_ops *dma_get_ops(struct device *dev)
1004 {
1005 return dma_ops;
1006 }
1007 diff -urNp linux-2.6.36/arch/ia64/kernel/module.c linux-2.6.36/arch/ia64/kernel/module.c
1008 --- linux-2.6.36/arch/ia64/kernel/module.c 2010-10-20 16:30:22.000000000 -0400
1009 +++ linux-2.6.36/arch/ia64/kernel/module.c 2010-11-06 18:58:15.000000000 -0400
1010 @@ -315,8 +315,7 @@ module_alloc (unsigned long size)
1011 void
1012 module_free (struct module *mod, void *module_region)
1013 {
1014 - if (mod && mod->arch.init_unw_table &&
1015 - module_region == mod->module_init) {
1016 + if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
1017 unw_remove_unwind_table(mod->arch.init_unw_table);
1018 mod->arch.init_unw_table = NULL;
1019 }
1020 @@ -502,15 +501,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
1021 }
1022
1023 static inline int
1024 +in_init_rx (const struct module *mod, uint64_t addr)
1025 +{
1026 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
1027 +}
1028 +
1029 +static inline int
1030 +in_init_rw (const struct module *mod, uint64_t addr)
1031 +{
1032 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
1033 +}
1034 +
1035 +static inline int
1036 in_init (const struct module *mod, uint64_t addr)
1037 {
1038 - return addr - (uint64_t) mod->module_init < mod->init_size;
1039 + return in_init_rx(mod, addr) || in_init_rw(mod, addr);
1040 +}
1041 +
1042 +static inline int
1043 +in_core_rx (const struct module *mod, uint64_t addr)
1044 +{
1045 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
1046 +}
1047 +
1048 +static inline int
1049 +in_core_rw (const struct module *mod, uint64_t addr)
1050 +{
1051 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
1052 }
1053
1054 static inline int
1055 in_core (const struct module *mod, uint64_t addr)
1056 {
1057 - return addr - (uint64_t) mod->module_core < mod->core_size;
1058 + return in_core_rx(mod, addr) || in_core_rw(mod, addr);
1059 }
1060
1061 static inline int
1062 @@ -693,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_
1063 break;
1064
1065 case RV_BDREL:
1066 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
1067 + if (in_init_rx(mod, val))
1068 + val -= (uint64_t) mod->module_init_rx;
1069 + else if (in_init_rw(mod, val))
1070 + val -= (uint64_t) mod->module_init_rw;
1071 + else if (in_core_rx(mod, val))
1072 + val -= (uint64_t) mod->module_core_rx;
1073 + else if (in_core_rw(mod, val))
1074 + val -= (uint64_t) mod->module_core_rw;
1075 break;
1076
1077 case RV_LTV:
1078 @@ -828,15 +858,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
1079 * addresses have been selected...
1080 */
1081 uint64_t gp;
1082 - if (mod->core_size > MAX_LTOFF)
1083 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
1084 /*
1085 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
1086 * at the end of the module.
1087 */
1088 - gp = mod->core_size - MAX_LTOFF / 2;
1089 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
1090 else
1091 - gp = mod->core_size / 2;
1092 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
1093 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
1094 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
1095 mod->arch.gp = gp;
1096 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
1097 }
1098 diff -urNp linux-2.6.36/arch/ia64/kernel/pci-dma.c linux-2.6.36/arch/ia64/kernel/pci-dma.c
1099 --- linux-2.6.36/arch/ia64/kernel/pci-dma.c 2010-10-20 16:30:22.000000000 -0400
1100 +++ linux-2.6.36/arch/ia64/kernel/pci-dma.c 2010-11-06 18:58:15.000000000 -0400
1101 @@ -43,7 +43,7 @@ struct device fallback_dev = {
1102 .dma_mask = &fallback_dev.coherent_dma_mask,
1103 };
1104
1105 -extern struct dma_map_ops intel_dma_ops;
1106 +extern const struct dma_map_ops intel_dma_ops;
1107
1108 static int __init pci_iommu_init(void)
1109 {
1110 diff -urNp linux-2.6.36/arch/ia64/kernel/pci-swiotlb.c linux-2.6.36/arch/ia64/kernel/pci-swiotlb.c
1111 --- linux-2.6.36/arch/ia64/kernel/pci-swiotlb.c 2010-10-20 16:30:22.000000000 -0400
1112 +++ linux-2.6.36/arch/ia64/kernel/pci-swiotlb.c 2010-11-06 18:58:15.000000000 -0400
1113 @@ -22,7 +22,7 @@ static void *ia64_swiotlb_alloc_coherent
1114 return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
1115 }
1116
1117 -struct dma_map_ops swiotlb_dma_ops = {
1118 +const struct dma_map_ops swiotlb_dma_ops = {
1119 .alloc_coherent = ia64_swiotlb_alloc_coherent,
1120 .free_coherent = swiotlb_free_coherent,
1121 .map_page = swiotlb_map_page,
1122 diff -urNp linux-2.6.36/arch/ia64/kernel/sys_ia64.c linux-2.6.36/arch/ia64/kernel/sys_ia64.c
1123 --- linux-2.6.36/arch/ia64/kernel/sys_ia64.c 2010-10-20 16:30:22.000000000 -0400
1124 +++ linux-2.6.36/arch/ia64/kernel/sys_ia64.c 2010-11-06 18:58:15.000000000 -0400
1125 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
1126 if (REGION_NUMBER(addr) == RGN_HPAGE)
1127 addr = 0;
1128 #endif
1129 +
1130 +#ifdef CONFIG_PAX_RANDMMAP
1131 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1132 + addr = mm->free_area_cache;
1133 + else
1134 +#endif
1135 +
1136 if (!addr)
1137 addr = mm->free_area_cache;
1138
1139 @@ -61,14 +68,14 @@ arch_get_unmapped_area (struct file *fil
1140 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
1141 /* At this point: (!vma || addr < vma->vm_end). */
1142 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
1143 - if (start_addr != TASK_UNMAPPED_BASE) {
1144 + if (start_addr != mm->mmap_base) {
1145 /* Start a new search --- just in case we missed some holes. */
1146 - addr = TASK_UNMAPPED_BASE;
1147 + addr = mm->mmap_base;
1148 goto full_search;
1149 }
1150 return -ENOMEM;
1151 }
1152 - if (!vma || addr + len <= vma->vm_start) {
1153 + if (check_heap_stack_gap(vma, addr, len)) {
1154 /* Remember the address where we stopped this search: */
1155 mm->free_area_cache = addr + len;
1156 return addr;
1157 diff -urNp linux-2.6.36/arch/ia64/kernel/vmlinux.lds.S linux-2.6.36/arch/ia64/kernel/vmlinux.lds.S
1158 --- linux-2.6.36/arch/ia64/kernel/vmlinux.lds.S 2010-10-20 16:30:22.000000000 -0400
1159 +++ linux-2.6.36/arch/ia64/kernel/vmlinux.lds.S 2010-11-06 18:58:15.000000000 -0400
1160 @@ -199,7 +199,7 @@ SECTIONS {
1161 /* Per-cpu data: */
1162 . = ALIGN(PERCPU_PAGE_SIZE);
1163 PERCPU_VADDR(PERCPU_ADDR, :percpu)
1164 - __phys_per_cpu_start = __per_cpu_load;
1165 + __phys_per_cpu_start = per_cpu_load;
1166 /*
1167 * ensure percpu data fits
1168 * into percpu page size
1169 diff -urNp linux-2.6.36/arch/ia64/mm/fault.c linux-2.6.36/arch/ia64/mm/fault.c
1170 --- linux-2.6.36/arch/ia64/mm/fault.c 2010-10-20 16:30:22.000000000 -0400
1171 +++ linux-2.6.36/arch/ia64/mm/fault.c 2010-11-06 18:58:15.000000000 -0400
1172 @@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
1173 return pte_present(pte);
1174 }
1175
1176 +#ifdef CONFIG_PAX_PAGEEXEC
1177 +void pax_report_insns(void *pc, void *sp)
1178 +{
1179 + unsigned long i;
1180 +
1181 + printk(KERN_ERR "PAX: bytes at PC: ");
1182 + for (i = 0; i < 8; i++) {
1183 + unsigned int c;
1184 + if (get_user(c, (unsigned int *)pc+i))
1185 + printk(KERN_CONT "???????? ");
1186 + else
1187 + printk(KERN_CONT "%08x ", c);
1188 + }
1189 + printk("\n");
1190 +}
1191 +#endif
1192 +
1193 void __kprobes
1194 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
1195 {
1196 @@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
1197 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
1198 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
1199
1200 - if ((vma->vm_flags & mask) != mask)
1201 + if ((vma->vm_flags & mask) != mask) {
1202 +
1203 +#ifdef CONFIG_PAX_PAGEEXEC
1204 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
1205 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
1206 + goto bad_area;
1207 +
1208 + up_read(&mm->mmap_sem);
1209 + pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
1210 + do_group_exit(SIGKILL);
1211 + }
1212 +#endif
1213 +
1214 goto bad_area;
1215
1216 + }
1217 +
1218 /*
1219 * If for any reason at all we couldn't handle the fault, make
1220 * sure we exit gracefully rather than endlessly redo the
1221 diff -urNp linux-2.6.36/arch/ia64/mm/hugetlbpage.c linux-2.6.36/arch/ia64/mm/hugetlbpage.c
1222 --- linux-2.6.36/arch/ia64/mm/hugetlbpage.c 2010-10-20 16:30:22.000000000 -0400
1223 +++ linux-2.6.36/arch/ia64/mm/hugetlbpage.c 2010-11-06 18:58:15.000000000 -0400
1224 @@ -171,7 +171,7 @@ unsigned long hugetlb_get_unmapped_area(
1225 /* At this point: (!vmm || addr < vmm->vm_end). */
1226 if (REGION_OFFSET(addr) + len > RGN_MAP_LIMIT)
1227 return -ENOMEM;
1228 - if (!vmm || (addr + len) <= vmm->vm_start)
1229 + if (check_heap_stack_gap(vmm, addr, len))
1230 return addr;
1231 addr = ALIGN(vmm->vm_end, HPAGE_SIZE);
1232 }
1233 diff -urNp linux-2.6.36/arch/ia64/mm/init.c linux-2.6.36/arch/ia64/mm/init.c
1234 --- linux-2.6.36/arch/ia64/mm/init.c 2010-10-20 16:30:22.000000000 -0400
1235 +++ linux-2.6.36/arch/ia64/mm/init.c 2010-11-06 18:58:15.000000000 -0400
1236 @@ -122,6 +122,19 @@ ia64_init_addr_space (void)
1237 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
1238 vma->vm_end = vma->vm_start + PAGE_SIZE;
1239 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
1240 +
1241 +#ifdef CONFIG_PAX_PAGEEXEC
1242 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
1243 + vma->vm_flags &= ~VM_EXEC;
1244 +
1245 +#ifdef CONFIG_PAX_MPROTECT
1246 + if (current->mm->pax_flags & MF_PAX_MPROTECT)
1247 + vma->vm_flags &= ~VM_MAYEXEC;
1248 +#endif
1249 +
1250 + }
1251 +#endif
1252 +
1253 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1254 down_write(&current->mm->mmap_sem);
1255 if (insert_vm_struct(current->mm, vma)) {
1256 diff -urNp linux-2.6.36/arch/ia64/sn/pci/pci_dma.c linux-2.6.36/arch/ia64/sn/pci/pci_dma.c
1257 --- linux-2.6.36/arch/ia64/sn/pci/pci_dma.c 2010-10-20 16:30:22.000000000 -0400
1258 +++ linux-2.6.36/arch/ia64/sn/pci/pci_dma.c 2010-11-06 18:58:15.000000000 -0400
1259 @@ -465,7 +465,7 @@ int sn_pci_legacy_write(struct pci_bus *
1260 return ret;
1261 }
1262
1263 -static struct dma_map_ops sn_dma_ops = {
1264 +static const struct dma_map_ops sn_dma_ops = {
1265 .alloc_coherent = sn_dma_alloc_coherent,
1266 .free_coherent = sn_dma_free_coherent,
1267 .map_page = sn_dma_map_page,
1268 diff -urNp linux-2.6.36/arch/m32r/lib/usercopy.c linux-2.6.36/arch/m32r/lib/usercopy.c
1269 --- linux-2.6.36/arch/m32r/lib/usercopy.c 2010-10-20 16:30:22.000000000 -0400
1270 +++ linux-2.6.36/arch/m32r/lib/usercopy.c 2010-11-06 18:58:15.000000000 -0400
1271 @@ -14,6 +14,9 @@
1272 unsigned long
1273 __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
1274 {
1275 + if ((long)n < 0)
1276 + return n;
1277 +
1278 prefetch(from);
1279 if (access_ok(VERIFY_WRITE, to, n))
1280 __copy_user(to,from,n);
1281 @@ -23,6 +26,9 @@ __generic_copy_to_user(void __user *to,
1282 unsigned long
1283 __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
1284 {
1285 + if ((long)n < 0)
1286 + return n;
1287 +
1288 prefetchw(to);
1289 if (access_ok(VERIFY_READ, from, n))
1290 __copy_user_zeroing(to,from,n);
1291 diff -urNp linux-2.6.36/arch/microblaze/include/asm/device.h linux-2.6.36/arch/microblaze/include/asm/device.h
1292 --- linux-2.6.36/arch/microblaze/include/asm/device.h 2010-10-20 16:30:22.000000000 -0400
1293 +++ linux-2.6.36/arch/microblaze/include/asm/device.h 2010-11-06 18:58:15.000000000 -0400
1294 @@ -13,7 +13,7 @@ struct device_node;
1295
1296 struct dev_archdata {
1297 /* DMA operations on that device */
1298 - struct dma_map_ops *dma_ops;
1299 + const struct dma_map_ops *dma_ops;
1300 void *dma_data;
1301 };
1302
1303 diff -urNp linux-2.6.36/arch/microblaze/include/asm/dma-mapping.h linux-2.6.36/arch/microblaze/include/asm/dma-mapping.h
1304 --- linux-2.6.36/arch/microblaze/include/asm/dma-mapping.h 2010-10-20 16:30:22.000000000 -0400
1305 +++ linux-2.6.36/arch/microblaze/include/asm/dma-mapping.h 2010-11-06 18:58:15.000000000 -0400
1306 @@ -43,14 +43,14 @@ static inline unsigned long device_to_ma
1307 return 0xfffffffful;
1308 }
1309
1310 -extern struct dma_map_ops *dma_ops;
1311 +extern const struct dma_map_ops *dma_ops;
1312
1313 /*
1314 * Available generic sets of operations
1315 */
1316 -extern struct dma_map_ops dma_direct_ops;
1317 +extern const struct dma_map_ops dma_direct_ops;
1318
1319 -static inline struct dma_map_ops *get_dma_ops(struct device *dev)
1320 +static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
1321 {
1322 /* We don't handle the NULL dev case for ISA for now. We could
1323 * do it via an out of line call but it is not needed for now. The
1324 @@ -63,14 +63,14 @@ static inline struct dma_map_ops *get_dm
1325 return dev->archdata.dma_ops;
1326 }
1327
1328 -static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
1329 +static inline void set_dma_ops(struct device *dev, const struct dma_map_ops *ops)
1330 {
1331 dev->archdata.dma_ops = ops;
1332 }
1333
1334 static inline int dma_supported(struct device *dev, u64 mask)
1335 {
1336 - struct dma_map_ops *ops = get_dma_ops(dev);
1337 + const struct dma_map_ops *ops = get_dma_ops(dev);
1338
1339 if (unlikely(!ops))
1340 return 0;
1341 @@ -81,7 +81,7 @@ static inline int dma_supported(struct d
1342
1343 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
1344 {
1345 - struct dma_map_ops *ops = get_dma_ops(dev);
1346 + const struct dma_map_ops *ops = get_dma_ops(dev);
1347
1348 if (unlikely(ops == NULL))
1349 return -EIO;
1350 @@ -97,7 +97,7 @@ static inline int dma_set_mask(struct de
1351
1352 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
1353 {
1354 - struct dma_map_ops *ops = get_dma_ops(dev);
1355 + const struct dma_map_ops *ops = get_dma_ops(dev);
1356 if (ops->mapping_error)
1357 return ops->mapping_error(dev, dma_addr);
1358
1359 @@ -110,7 +110,7 @@ static inline int dma_mapping_error(stru
1360 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
1361 dma_addr_t *dma_handle, gfp_t flag)
1362 {
1363 - struct dma_map_ops *ops = get_dma_ops(dev);
1364 + const struct dma_map_ops *ops = get_dma_ops(dev);
1365 void *memory;
1366
1367 BUG_ON(!ops);
1368 @@ -124,7 +124,7 @@ static inline void *dma_alloc_coherent(s
1369 static inline void dma_free_coherent(struct device *dev, size_t size,
1370 void *cpu_addr, dma_addr_t dma_handle)
1371 {
1372 - struct dma_map_ops *ops = get_dma_ops(dev);
1373 + const struct dma_map_ops *ops = get_dma_ops(dev);
1374
1375 BUG_ON(!ops);
1376 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
1377 diff -urNp linux-2.6.36/arch/microblaze/include/asm/pci.h linux-2.6.36/arch/microblaze/include/asm/pci.h
1378 --- linux-2.6.36/arch/microblaze/include/asm/pci.h 2010-10-20 16:30:22.000000000 -0400
1379 +++ linux-2.6.36/arch/microblaze/include/asm/pci.h 2010-11-06 18:58:15.000000000 -0400
1380 @@ -54,8 +54,8 @@ static inline void pcibios_penalize_isa_
1381 }
1382
1383 #ifdef CONFIG_PCI
1384 -extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
1385 -extern struct dma_map_ops *get_pci_dma_ops(void);
1386 +extern void set_pci_dma_ops(const struct dma_map_ops *dma_ops);
1387 +extern const struct dma_map_ops *get_pci_dma_ops(void);
1388 #else /* CONFIG_PCI */
1389 #define set_pci_dma_ops(d)
1390 #define get_pci_dma_ops() NULL
1391 diff -urNp linux-2.6.36/arch/microblaze/kernel/dma.c linux-2.6.36/arch/microblaze/kernel/dma.c
1392 --- linux-2.6.36/arch/microblaze/kernel/dma.c 2010-10-20 16:30:22.000000000 -0400
1393 +++ linux-2.6.36/arch/microblaze/kernel/dma.c 2010-11-06 18:58:15.000000000 -0400
1394 @@ -133,7 +133,7 @@ static inline void dma_direct_unmap_page
1395 __dma_sync_page(dma_address, 0 , size, direction);
1396 }
1397
1398 -struct dma_map_ops dma_direct_ops = {
1399 +const struct dma_map_ops dma_direct_ops = {
1400 .alloc_coherent = dma_direct_alloc_coherent,
1401 .free_coherent = dma_direct_free_coherent,
1402 .map_sg = dma_direct_map_sg,
1403 diff -urNp linux-2.6.36/arch/microblaze/kernel/kgdb.c linux-2.6.36/arch/microblaze/kernel/kgdb.c
1404 --- linux-2.6.36/arch/microblaze/kernel/kgdb.c 2010-10-20 16:30:22.000000000 -0400
1405 +++ linux-2.6.36/arch/microblaze/kernel/kgdb.c 2010-11-06 18:58:15.000000000 -0400
1406 @@ -142,6 +142,6 @@ void kgdb_arch_exit(void)
1407 /*
1408 * Global data
1409 */
1410 -struct kgdb_arch arch_kgdb_ops = {
1411 +const struct kgdb_arch arch_kgdb_ops = {
1412 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
1413 };
1414 diff -urNp linux-2.6.36/arch/microblaze/pci/pci-common.c linux-2.6.36/arch/microblaze/pci/pci-common.c
1415 --- linux-2.6.36/arch/microblaze/pci/pci-common.c 2010-10-20 16:30:22.000000000 -0400
1416 +++ linux-2.6.36/arch/microblaze/pci/pci-common.c 2010-11-06 18:58:15.000000000 -0400
1417 @@ -47,14 +47,14 @@ resource_size_t isa_mem_base;
1418 /* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
1419 unsigned int pci_flags;
1420
1421 -static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
1422 +static const struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
1423
1424 -void set_pci_dma_ops(struct dma_map_ops *dma_ops)
1425 +void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
1426 {
1427 pci_dma_ops = dma_ops;
1428 }
1429
1430 -struct dma_map_ops *get_pci_dma_ops(void)
1431 +const struct dma_map_ops *get_pci_dma_ops(void)
1432 {
1433 return pci_dma_ops;
1434 }
1435 diff -urNp linux-2.6.36/arch/mips/alchemy/devboards/pm.c linux-2.6.36/arch/mips/alchemy/devboards/pm.c
1436 --- linux-2.6.36/arch/mips/alchemy/devboards/pm.c 2010-10-20 16:30:22.000000000 -0400
1437 +++ linux-2.6.36/arch/mips/alchemy/devboards/pm.c 2010-11-06 18:58:15.000000000 -0400
1438 @@ -110,7 +110,7 @@ static void db1x_pm_end(void)
1439
1440 }
1441
1442 -static struct platform_suspend_ops db1x_pm_ops = {
1443 +static const struct platform_suspend_ops db1x_pm_ops = {
1444 .valid = suspend_valid_only_mem,
1445 .begin = db1x_pm_begin,
1446 .enter = db1x_pm_enter,
1447 diff -urNp linux-2.6.36/arch/mips/include/asm/elf.h linux-2.6.36/arch/mips/include/asm/elf.h
1448 --- linux-2.6.36/arch/mips/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
1449 +++ linux-2.6.36/arch/mips/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
1450 @@ -368,6 +368,13 @@ extern const char *__elf_platform;
1451 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
1452 #endif
1453
1454 +#ifdef CONFIG_PAX_ASLR
1455 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1456 +
1457 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1458 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1459 +#endif
1460 +
1461 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
1462 struct linux_binprm;
1463 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
1464 diff -urNp linux-2.6.36/arch/mips/include/asm/page.h linux-2.6.36/arch/mips/include/asm/page.h
1465 --- linux-2.6.36/arch/mips/include/asm/page.h 2010-10-20 16:30:22.000000000 -0400
1466 +++ linux-2.6.36/arch/mips/include/asm/page.h 2010-11-06 18:58:15.000000000 -0400
1467 @@ -93,7 +93,7 @@ extern void copy_user_highpage(struct pa
1468 #ifdef CONFIG_CPU_MIPS32
1469 typedef struct { unsigned long pte_low, pte_high; } pte_t;
1470 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
1471 - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
1472 + #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
1473 #else
1474 typedef struct { unsigned long long pte; } pte_t;
1475 #define pte_val(x) ((x).pte)
1476 diff -urNp linux-2.6.36/arch/mips/include/asm/system.h linux-2.6.36/arch/mips/include/asm/system.h
1477 --- linux-2.6.36/arch/mips/include/asm/system.h 2010-10-20 16:30:22.000000000 -0400
1478 +++ linux-2.6.36/arch/mips/include/asm/system.h 2010-11-06 18:58:15.000000000 -0400
1479 @@ -234,6 +234,6 @@ extern void per_cpu_trap_init(void);
1480 */
1481 #define __ARCH_WANT_UNLOCKED_CTXSW
1482
1483 -extern unsigned long arch_align_stack(unsigned long sp);
1484 +#define arch_align_stack(x) ((x) & ALMASK)
1485
1486 #endif /* _ASM_SYSTEM_H */
1487 diff -urNp linux-2.6.36/arch/mips/jz4740/pm.c linux-2.6.36/arch/mips/jz4740/pm.c
1488 --- linux-2.6.36/arch/mips/jz4740/pm.c 2010-10-20 16:30:22.000000000 -0400
1489 +++ linux-2.6.36/arch/mips/jz4740/pm.c 2010-11-06 18:58:15.000000000 -0400
1490 @@ -42,7 +42,7 @@ static int jz4740_pm_enter(suspend_state
1491 return 0;
1492 }
1493
1494 -static struct platform_suspend_ops jz4740_pm_ops = {
1495 +static const struct platform_suspend_ops jz4740_pm_ops = {
1496 .valid = suspend_valid_only_mem,
1497 .enter = jz4740_pm_enter,
1498 };
1499 diff -urNp linux-2.6.36/arch/mips/kernel/binfmt_elfn32.c linux-2.6.36/arch/mips/kernel/binfmt_elfn32.c
1500 --- linux-2.6.36/arch/mips/kernel/binfmt_elfn32.c 2010-10-20 16:30:22.000000000 -0400
1501 +++ linux-2.6.36/arch/mips/kernel/binfmt_elfn32.c 2010-11-06 18:58:15.000000000 -0400
1502 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
1503 #undef ELF_ET_DYN_BASE
1504 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1505
1506 +#ifdef CONFIG_PAX_ASLR
1507 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1508 +
1509 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1510 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1511 +#endif
1512 +
1513 #include <asm/processor.h>
1514 #include <linux/module.h>
1515 #include <linux/elfcore.h>
1516 diff -urNp linux-2.6.36/arch/mips/kernel/binfmt_elfo32.c linux-2.6.36/arch/mips/kernel/binfmt_elfo32.c
1517 --- linux-2.6.36/arch/mips/kernel/binfmt_elfo32.c 2010-10-20 16:30:22.000000000 -0400
1518 +++ linux-2.6.36/arch/mips/kernel/binfmt_elfo32.c 2010-11-06 18:58:15.000000000 -0400
1519 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
1520 #undef ELF_ET_DYN_BASE
1521 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1522
1523 +#ifdef CONFIG_PAX_ASLR
1524 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1525 +
1526 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1527 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1528 +#endif
1529 +
1530 #include <asm/processor.h>
1531
1532 /*
1533 diff -urNp linux-2.6.36/arch/mips/kernel/kgdb.c linux-2.6.36/arch/mips/kernel/kgdb.c
1534 --- linux-2.6.36/arch/mips/kernel/kgdb.c 2010-10-20 16:30:22.000000000 -0400
1535 +++ linux-2.6.36/arch/mips/kernel/kgdb.c 2010-11-06 18:58:15.000000000 -0400
1536 @@ -351,6 +351,7 @@ int kgdb_arch_handle_exception(int vecto
1537 return -1;
1538 }
1539
1540 +/* cannot be const, see kgdb_arch_init */
1541 struct kgdb_arch arch_kgdb_ops;
1542
1543 /*
1544 diff -urNp linux-2.6.36/arch/mips/kernel/process.c linux-2.6.36/arch/mips/kernel/process.c
1545 --- linux-2.6.36/arch/mips/kernel/process.c 2010-10-20 16:30:22.000000000 -0400
1546 +++ linux-2.6.36/arch/mips/kernel/process.c 2010-11-06 18:58:15.000000000 -0400
1547 @@ -474,15 +474,3 @@ unsigned long get_wchan(struct task_stru
1548 out:
1549 return pc;
1550 }
1551 -
1552 -/*
1553 - * Don't forget that the stack pointer must be aligned on a 8 bytes
1554 - * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
1555 - */
1556 -unsigned long arch_align_stack(unsigned long sp)
1557 -{
1558 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
1559 - sp -= get_random_int() & ~PAGE_MASK;
1560 -
1561 - return sp & ALMASK;
1562 -}
1563 diff -urNp linux-2.6.36/arch/mips/kernel/syscall.c linux-2.6.36/arch/mips/kernel/syscall.c
1564 --- linux-2.6.36/arch/mips/kernel/syscall.c 2010-10-20 16:30:22.000000000 -0400
1565 +++ linux-2.6.36/arch/mips/kernel/syscall.c 2010-11-06 18:58:15.000000000 -0400
1566 @@ -108,14 +108,18 @@ unsigned long arch_get_unmapped_area(str
1567 do_color_align = 0;
1568 if (filp || (flags & MAP_SHARED))
1569 do_color_align = 1;
1570 +
1571 +#ifdef CONFIG_PAX_RANDMMAP
1572 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
1573 +#endif
1574 +
1575 if (addr) {
1576 if (do_color_align)
1577 addr = COLOUR_ALIGN(addr, pgoff);
1578 else
1579 addr = PAGE_ALIGN(addr);
1580 vmm = find_vma(current->mm, addr);
1581 - if (task_size - len >= addr &&
1582 - (!vmm || addr + len <= vmm->vm_start))
1583 + if (task_size - len >= addr && check_heap_stack_gap(vmm, addr, len))
1584 return addr;
1585 }
1586 addr = current->mm->mmap_base;
1587 @@ -128,7 +132,7 @@ unsigned long arch_get_unmapped_area(str
1588 /* At this point: (!vmm || addr < vmm->vm_end). */
1589 if (task_size - len < addr)
1590 return -ENOMEM;
1591 - if (!vmm || addr + len <= vmm->vm_start)
1592 + if (check_heap_stack_gap(vmm, addr, len))
1593 return addr;
1594 addr = vmm->vm_end;
1595 if (do_color_align)
1596 diff -urNp linux-2.6.36/arch/mips/loongson/common/pm.c linux-2.6.36/arch/mips/loongson/common/pm.c
1597 --- linux-2.6.36/arch/mips/loongson/common/pm.c 2010-10-20 16:30:22.000000000 -0400
1598 +++ linux-2.6.36/arch/mips/loongson/common/pm.c 2010-11-06 18:58:15.000000000 -0400
1599 @@ -147,7 +147,7 @@ static int loongson_pm_valid_state(suspe
1600 }
1601 }
1602
1603 -static struct platform_suspend_ops loongson_pm_ops = {
1604 +static const struct platform_suspend_ops loongson_pm_ops = {
1605 .valid = loongson_pm_valid_state,
1606 .enter = loongson_pm_enter,
1607 };
1608 diff -urNp linux-2.6.36/arch/mips/mm/fault.c linux-2.6.36/arch/mips/mm/fault.c
1609 --- linux-2.6.36/arch/mips/mm/fault.c 2010-10-20 16:30:22.000000000 -0400
1610 +++ linux-2.6.36/arch/mips/mm/fault.c 2010-11-06 18:58:15.000000000 -0400
1611 @@ -27,6 +27,23 @@
1612 #include <asm/highmem.h> /* For VMALLOC_END */
1613 #include <linux/kdebug.h>
1614
1615 +#ifdef CONFIG_PAX_PAGEEXEC
1616 +void pax_report_insns(void *pc, void *sp)
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
1635 diff -urNp linux-2.6.36/arch/parisc/include/asm/elf.h linux-2.6.36/arch/parisc/include/asm/elf.h
1636 --- linux-2.6.36/arch/parisc/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
1637 +++ linux-2.6.36/arch/parisc/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
1638 @@ -342,6 +342,13 @@ struct pt_regs; /* forward declaration..
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. */
1652 diff -urNp linux-2.6.36/arch/parisc/include/asm/pgtable.h linux-2.6.36/arch/parisc/include/asm/pgtable.h
1653 --- linux-2.6.36/arch/parisc/include/asm/pgtable.h 2010-10-20 16:30:22.000000000 -0400
1654 +++ linux-2.6.36/arch/parisc/include/asm/pgtable.h 2010-11-06 18:58:15.000000000 -0400
1655 @@ -207,6 +207,17 @@
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)
1673 diff -urNp linux-2.6.36/arch/parisc/kernel/module.c linux-2.6.36/arch/parisc/kernel/module.c
1674 --- linux-2.6.36/arch/parisc/kernel/module.c 2010-10-20 16:30:22.000000000 -0400
1675 +++ linux-2.6.36/arch/parisc/kernel/module.c 2010-11-06 18:58:15.000000000 -0400
1676 @@ -96,16 +96,38 @@
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)
1719 @@ -365,13 +387,13 @@ int module_frob_arch_sections(CONST Elf_
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;
1740 @@ -389,7 +411,7 @@ static Elf64_Word get_got(struct module
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;
1749 @@ -407,7 +429,7 @@ static Elf64_Word get_got(struct module
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);
1758 @@ -425,7 +447,7 @@ static Elf_Addr get_fdesc(struct module
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 */
1767 @@ -849,7 +871,7 @@ register_unwind_table(struct module *me,
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);
1776 diff -urNp linux-2.6.36/arch/parisc/kernel/sys_parisc.c linux-2.6.36/arch/parisc/kernel/sys_parisc.c
1777 --- linux-2.6.36/arch/parisc/kernel/sys_parisc.c 2010-10-20 16:30:22.000000000 -0400
1778 +++ linux-2.6.36/arch/parisc/kernel/sys_parisc.c 2010-11-06 18:58:15.000000000 -0400
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 */
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);
1806 diff -urNp linux-2.6.36/arch/parisc/kernel/traps.c linux-2.6.36/arch/parisc/kernel/traps.c
1807 --- linux-2.6.36/arch/parisc/kernel/traps.c 2010-10-20 16:30:22.000000000 -0400
1808 +++ linux-2.6.36/arch/parisc/kernel/traps.c 2010-11-06 18:58:15.000000000 -0400
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
1820 diff -urNp linux-2.6.36/arch/parisc/mm/fault.c linux-2.6.36/arch/parisc/mm/fault.c
1821 --- linux-2.6.36/arch/parisc/mm/fault.c 2010-10-20 16:30:22.000000000 -0400
1822 +++ linux-2.6.36/arch/parisc/mm/fault.c 2010-11-06 18:58:15.000000000 -0400
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
1992 diff -urNp linux-2.6.36/arch/powerpc/include/asm/device.h linux-2.6.36/arch/powerpc/include/asm/device.h
1993 --- linux-2.6.36/arch/powerpc/include/asm/device.h 2010-10-20 16:30:22.000000000 -0400
1994 +++ linux-2.6.36/arch/powerpc/include/asm/device.h 2010-11-06 18:58:15.000000000 -0400
1995 @@ -11,7 +11,7 @@ struct device_node;
1996
1997 struct dev_archdata {
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
2004 diff -urNp linux-2.6.36/arch/powerpc/include/asm/dma-mapping.h linux-2.6.36/arch/powerpc/include/asm/dma-mapping.h
2005 --- linux-2.6.36/arch/powerpc/include/asm/dma-mapping.h 2010-10-20 16:30:22.000000000 -0400
2006 +++ linux-2.6.36/arch/powerpc/include/asm/dma-mapping.h 2010-11-06 18:58:15.000000000 -0400
2007 @@ -66,12 +66,13 @@ static inline unsigned long device_to_ma
2008 /*
2009 * Available generic sets of operations
2010 */
2011 +/* cannot be const */
2012 #ifdef CONFIG_PPC64
2013 extern struct dma_map_ops dma_iommu_ops;
2014 #endif
2015 -extern struct dma_map_ops dma_direct_ops;
2016 +extern const struct dma_map_ops dma_direct_ops;
2017
2018 -static inline struct dma_map_ops *get_dma_ops(struct device *dev)
2019 +static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
2020 {
2021 /* We don't handle the NULL dev case for ISA for now. We could
2022 * do it via an out of line call but it is not needed for now. The
2023 @@ -84,7 +85,7 @@ static inline struct dma_map_ops *get_dm
2024 return dev->archdata.dma_ops;
2025 }
2026
2027 -static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
2028 +static inline void set_dma_ops(struct device *dev, const struct dma_map_ops *ops)
2029 {
2030 dev->archdata.dma_ops = ops;
2031 }
2032 @@ -118,7 +119,7 @@ static inline void set_dma_offset(struct
2033
2034 static inline int dma_supported(struct device *dev, u64 mask)
2035 {
2036 - struct dma_map_ops *dma_ops = get_dma_ops(dev);
2037 + const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2038
2039 if (unlikely(dma_ops == NULL))
2040 return 0;
2041 @@ -129,7 +130,7 @@ static inline int dma_supported(struct d
2042
2043 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
2044 {
2045 - struct dma_map_ops *dma_ops = get_dma_ops(dev);
2046 + const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2047
2048 if (unlikely(dma_ops == NULL))
2049 return -EIO;
2050 @@ -144,7 +145,7 @@ static inline int dma_set_mask(struct de
2051 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
2052 dma_addr_t *dma_handle, gfp_t flag)
2053 {
2054 - struct dma_map_ops *dma_ops = get_dma_ops(dev);
2055 + const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2056 void *cpu_addr;
2057
2058 BUG_ON(!dma_ops);
2059 @@ -159,7 +160,7 @@ static inline void *dma_alloc_coherent(s
2060 static inline void dma_free_coherent(struct device *dev, size_t size,
2061 void *cpu_addr, dma_addr_t dma_handle)
2062 {
2063 - struct dma_map_ops *dma_ops = get_dma_ops(dev);
2064 + const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2065
2066 BUG_ON(!dma_ops);
2067
2068 @@ -170,7 +171,7 @@ static inline void dma_free_coherent(str
2069
2070 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
2071 {
2072 - struct dma_map_ops *dma_ops = get_dma_ops(dev);
2073 + const struct dma_map_ops *dma_ops = get_dma_ops(dev);
2074
2075 if (dma_ops->mapping_error)
2076 return dma_ops->mapping_error(dev, dma_addr);
2077 diff -urNp linux-2.6.36/arch/powerpc/include/asm/elf.h linux-2.6.36/arch/powerpc/include/asm/elf.h
2078 --- linux-2.6.36/arch/powerpc/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
2079 +++ linux-2.6.36/arch/powerpc/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
2080 @@ -178,8 +178,19 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
2081 the loader. We need to make sure that it is out of the way of the program
2082 that it will "exec", and that there is sufficient room for the brk. */
2083
2084 -extern unsigned long randomize_et_dyn(unsigned long base);
2085 -#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000))
2086 +#define ELF_ET_DYN_BASE (0x20000000)
2087 +
2088 +#ifdef CONFIG_PAX_ASLR
2089 +#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
2090 +
2091 +#ifdef __powerpc64__
2092 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
2093 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
2094 +#else
2095 +#define PAX_DELTA_MMAP_LEN 15
2096 +#define PAX_DELTA_STACK_LEN 15
2097 +#endif
2098 +#endif
2099
2100 /*
2101 * Our registers are always unsigned longs, whether we're a 32 bit
2102 @@ -274,9 +285,6 @@ extern int arch_setup_additional_pages(s
2103 (0x7ff >> (PAGE_SHIFT - 12)) : \
2104 (0x3ffff >> (PAGE_SHIFT - 12)))
2105
2106 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
2107 -#define arch_randomize_brk arch_randomize_brk
2108 -
2109 #endif /* __KERNEL__ */
2110
2111 /*
2112 diff -urNp linux-2.6.36/arch/powerpc/include/asm/iommu.h linux-2.6.36/arch/powerpc/include/asm/iommu.h
2113 --- linux-2.6.36/arch/powerpc/include/asm/iommu.h 2010-10-20 16:30:22.000000000 -0400
2114 +++ linux-2.6.36/arch/powerpc/include/asm/iommu.h 2010-11-06 18:58:15.000000000 -0400
2115 @@ -116,6 +116,9 @@ extern void iommu_init_early_iSeries(voi
2116 extern void iommu_init_early_dart(void);
2117 extern void iommu_init_early_pasemi(void);
2118
2119 +/* dma-iommu.c */
2120 +extern int dma_iommu_dma_supported(struct device *dev, u64 mask);
2121 +
2122 #ifdef CONFIG_PCI
2123 extern void pci_iommu_init(void);
2124 extern void pci_direct_iommu_init(void);
2125 diff -urNp linux-2.6.36/arch/powerpc/include/asm/kmap_types.h linux-2.6.36/arch/powerpc/include/asm/kmap_types.h
2126 --- linux-2.6.36/arch/powerpc/include/asm/kmap_types.h 2010-10-20 16:30:22.000000000 -0400
2127 +++ linux-2.6.36/arch/powerpc/include/asm/kmap_types.h 2010-11-06 18:58:15.000000000 -0400
2128 @@ -27,6 +27,7 @@ enum km_type {
2129 KM_PPC_SYNC_PAGE,
2130 KM_PPC_SYNC_ICACHE,
2131 KM_KDB,
2132 + KM_CLEARPAGE,
2133 KM_TYPE_NR
2134 };
2135
2136 diff -urNp linux-2.6.36/arch/powerpc/include/asm/page_64.h linux-2.6.36/arch/powerpc/include/asm/page_64.h
2137 --- linux-2.6.36/arch/powerpc/include/asm/page_64.h 2010-10-20 16:30:22.000000000 -0400
2138 +++ linux-2.6.36/arch/powerpc/include/asm/page_64.h 2010-11-06 18:58:15.000000000 -0400
2139 @@ -172,15 +172,18 @@ do { \
2140 * stack by default, so in the absense of a PT_GNU_STACK program header
2141 * we turn execute permission off.
2142 */
2143 -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
2144 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2145 +#define VM_STACK_DEFAULT_FLAGS32 \
2146 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
2147 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2148
2149 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
2150 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2151
2152 +#ifndef CONFIG_PAX_PAGEEXEC
2153 #define VM_STACK_DEFAULT_FLAGS \
2154 (test_thread_flag(TIF_32BIT) ? \
2155 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
2156 +#endif
2157
2158 #include <asm-generic/getorder.h>
2159
2160 diff -urNp linux-2.6.36/arch/powerpc/include/asm/page.h linux-2.6.36/arch/powerpc/include/asm/page.h
2161 --- linux-2.6.36/arch/powerpc/include/asm/page.h 2010-10-20 16:30:22.000000000 -0400
2162 +++ linux-2.6.36/arch/powerpc/include/asm/page.h 2010-11-06 18:58:15.000000000 -0400
2163 @@ -129,8 +129,9 @@ extern phys_addr_t kernstart_addr;
2164 * and needs to be executable. This means the whole heap ends
2165 * up being executable.
2166 */
2167 -#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
2168 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2169 +#define VM_DATA_DEFAULT_FLAGS32 \
2170 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
2171 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2172
2173 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
2174 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2175 @@ -158,6 +159,9 @@ extern phys_addr_t kernstart_addr;
2176 #define is_kernel_addr(x) ((x) >= PAGE_OFFSET)
2177 #endif
2178
2179 +#define ktla_ktva(addr) (addr)
2180 +#define ktva_ktla(addr) (addr)
2181 +
2182 #ifndef __ASSEMBLY__
2183
2184 #undef STRICT_MM_TYPECHECKS
2185 diff -urNp linux-2.6.36/arch/powerpc/include/asm/pci.h linux-2.6.36/arch/powerpc/include/asm/pci.h
2186 --- linux-2.6.36/arch/powerpc/include/asm/pci.h 2010-10-20 16:30:22.000000000 -0400
2187 +++ linux-2.6.36/arch/powerpc/include/asm/pci.h 2010-11-06 18:58:15.000000000 -0400
2188 @@ -65,8 +65,8 @@ static inline int pci_get_legacy_ide_irq
2189 }
2190
2191 #ifdef CONFIG_PCI
2192 -extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
2193 -extern struct dma_map_ops *get_pci_dma_ops(void);
2194 +extern void set_pci_dma_ops(const struct dma_map_ops *dma_ops);
2195 +extern const struct dma_map_ops *get_pci_dma_ops(void);
2196 #else /* CONFIG_PCI */
2197 #define set_pci_dma_ops(d)
2198 #define get_pci_dma_ops() NULL
2199 diff -urNp linux-2.6.36/arch/powerpc/include/asm/pte-hash32.h linux-2.6.36/arch/powerpc/include/asm/pte-hash32.h
2200 --- linux-2.6.36/arch/powerpc/include/asm/pte-hash32.h 2010-10-20 16:30:22.000000000 -0400
2201 +++ linux-2.6.36/arch/powerpc/include/asm/pte-hash32.h 2010-11-06 18:58:15.000000000 -0400
2202 @@ -21,6 +21,7 @@
2203 #define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */
2204 #define _PAGE_USER 0x004 /* usermode access allowed */
2205 #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
2206 +#define _PAGE_EXEC _PAGE_GUARDED
2207 #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
2208 #define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
2209 #define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
2210 diff -urNp linux-2.6.36/arch/powerpc/include/asm/reg.h linux-2.6.36/arch/powerpc/include/asm/reg.h
2211 --- linux-2.6.36/arch/powerpc/include/asm/reg.h 2010-10-20 16:30:22.000000000 -0400
2212 +++ linux-2.6.36/arch/powerpc/include/asm/reg.h 2010-11-06 18:58:15.000000000 -0400
2213 @@ -191,6 +191,7 @@
2214 #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
2215 #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
2216 #define DSISR_NOHPTE 0x40000000 /* no translation found */
2217 +#define DSISR_GUARDED 0x10000000 /* fetch from guarded storage */
2218 #define DSISR_PROTFAULT 0x08000000 /* protection fault */
2219 #define DSISR_ISSTORE 0x02000000 /* access was a store */
2220 #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
2221 diff -urNp linux-2.6.36/arch/powerpc/include/asm/swiotlb.h linux-2.6.36/arch/powerpc/include/asm/swiotlb.h
2222 --- linux-2.6.36/arch/powerpc/include/asm/swiotlb.h 2010-10-20 16:30:22.000000000 -0400
2223 +++ linux-2.6.36/arch/powerpc/include/asm/swiotlb.h 2010-11-06 18:58:15.000000000 -0400
2224 @@ -13,7 +13,7 @@
2225
2226 #include <linux/swiotlb.h>
2227
2228 -extern struct dma_map_ops swiotlb_dma_ops;
2229 +extern const struct dma_map_ops swiotlb_dma_ops;
2230
2231 static inline void dma_mark_clean(void *addr, size_t size) {}
2232
2233 diff -urNp linux-2.6.36/arch/powerpc/include/asm/uaccess.h linux-2.6.36/arch/powerpc/include/asm/uaccess.h
2234 --- linux-2.6.36/arch/powerpc/include/asm/uaccess.h 2010-10-20 16:30:22.000000000 -0400
2235 +++ linux-2.6.36/arch/powerpc/include/asm/uaccess.h 2010-11-06 18:58:15.000000000 -0400
2236 @@ -13,6 +13,8 @@
2237 #define VERIFY_READ 0
2238 #define VERIFY_WRITE 1
2239
2240 +extern void check_object_size(const void *ptr, unsigned long n, bool to);
2241 +
2242 /*
2243 * The fs value determines whether argument validity checking should be
2244 * performed or not. If get_fs() == USER_DS, checking is performed, with
2245 @@ -327,52 +329,6 @@ do { \
2246 extern unsigned long __copy_tofrom_user(void __user *to,
2247 const void __user *from, unsigned long size);
2248
2249 -#ifndef __powerpc64__
2250 -
2251 -static inline unsigned long copy_from_user(void *to,
2252 - const void __user *from, unsigned long n)
2253 -{
2254 - unsigned long over;
2255 -
2256 - if (access_ok(VERIFY_READ, from, n))
2257 - return __copy_tofrom_user((__force void __user *)to, from, n);
2258 - if ((unsigned long)from < TASK_SIZE) {
2259 - over = (unsigned long)from + n - TASK_SIZE;
2260 - return __copy_tofrom_user((__force void __user *)to, from,
2261 - n - over) + over;
2262 - }
2263 - return n;
2264 -}
2265 -
2266 -static inline unsigned long copy_to_user(void __user *to,
2267 - const void *from, unsigned long n)
2268 -{
2269 - unsigned long over;
2270 -
2271 - if (access_ok(VERIFY_WRITE, to, n))
2272 - return __copy_tofrom_user(to, (__force void __user *)from, n);
2273 - if ((unsigned long)to < TASK_SIZE) {
2274 - over = (unsigned long)to + n - TASK_SIZE;
2275 - return __copy_tofrom_user(to, (__force void __user *)from,
2276 - n - over) + over;
2277 - }
2278 - return n;
2279 -}
2280 -
2281 -#else /* __powerpc64__ */
2282 -
2283 -#define __copy_in_user(to, from, size) \
2284 - __copy_tofrom_user((to), (from), (size))
2285 -
2286 -extern unsigned long copy_from_user(void *to, const void __user *from,
2287 - unsigned long n);
2288 -extern unsigned long copy_to_user(void __user *to, const void *from,
2289 - unsigned long n);
2290 -extern unsigned long copy_in_user(void __user *to, const void __user *from,
2291 - unsigned long n);
2292 -
2293 -#endif /* __powerpc64__ */
2294 -
2295 static inline unsigned long __copy_from_user_inatomic(void *to,
2296 const void __user *from, unsigned long n)
2297 {
2298 @@ -396,6 +352,10 @@ static inline unsigned long __copy_from_
2299 if (ret == 0)
2300 return 0;
2301 }
2302 +
2303 + if (!__builtin_constant_p(n))
2304 + check_object_size(to, n, false);
2305 +
2306 return __copy_tofrom_user((__force void __user *)to, from, n);
2307 }
2308
2309 @@ -422,6 +382,10 @@ static inline unsigned long __copy_to_us
2310 if (ret == 0)
2311 return 0;
2312 }
2313 +
2314 + if (!__builtin_constant_p(n))
2315 + check_object_size(from, n, true);
2316 +
2317 return __copy_tofrom_user(to, (__force const void __user *)from, n);
2318 }
2319
2320 @@ -439,6 +403,92 @@ static inline unsigned long __copy_to_us
2321 return __copy_to_user_inatomic(to, from, size);
2322 }
2323
2324 +#ifndef __powerpc64__
2325 +
2326 +static inline unsigned long __must_check copy_from_user(void *to,
2327 + const void __user *from, unsigned long n)
2328 +{
2329 + unsigned long over;
2330 +
2331 + if ((long)n < 0)
2332 + return n;
2333 +
2334 + if (access_ok(VERIFY_READ, from, n)) {
2335 + if (!__builtin_constant_p(n))
2336 + check_object_size(to, n, false);
2337 + return __copy_tofrom_user((__force void __user *)to, from, n);
2338 + }
2339 + if ((unsigned long)from < TASK_SIZE) {
2340 + over = (unsigned long)from + n - TASK_SIZE;
2341 + if (!__builtin_constant_p(n - over))
2342 + check_object_size(to, n - over, false);
2343 + return __copy_tofrom_user((__force void __user *)to, from,
2344 + n - over) + over;
2345 + }
2346 + return n;
2347 +}
2348 +
2349 +static inline unsigned long __must_check copy_to_user(void __user *to,
2350 + const void *from, unsigned long n)
2351 +{
2352 + unsigned long over;
2353 +
2354 + if ((long)n < 0)
2355 + return n;
2356 +
2357 + if (access_ok(VERIFY_WRITE, to, n)) {
2358 + if (!__builtin_constant_p(n))
2359 + check_object_size(from, n, true);
2360 + return __copy_tofrom_user(to, (__force void __user *)from, n);
2361 + }
2362 + if ((unsigned long)to < TASK_SIZE) {
2363 + over = (unsigned long)to + n - TASK_SIZE;
2364 + if (!__builtin_constant_p(n))
2365 + check_object_size(from, n - over, true);
2366 + return __copy_tofrom_user(to, (__force void __user *)from,
2367 + n - over) + over;
2368 + }
2369 + return n;
2370 +}
2371 +
2372 +#else /* __powerpc64__ */
2373 +
2374 +#define __copy_in_user(to, from, size) \
2375 + __copy_tofrom_user((to), (from), (size))
2376 +
2377 +static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
2378 +{
2379 + if ((long)n < 0 || n > INT_MAX)
2380 + return n;
2381 +
2382 + if (!__builtin_constant_p(n))
2383 + check_object_size(to, n, false);
2384 +
2385 + if (likely(access_ok(VERIFY_READ, from, n)))
2386 + n = __copy_from_user(to, from, n);
2387 + else
2388 + memset(to, 0, n);
2389 + return n;
2390 +}
2391 +
2392 +static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
2393 +{
2394 + if ((long)n < 0 || n > INT_MAX)
2395 + return n;
2396 +
2397 + if (likely(access_ok(VERIFY_WRITE, to, n))) {
2398 + if (!__builtin_constant_p(n))
2399 + check_object_size(from, n, true);
2400 + n = __copy_to_user(to, from, n);
2401 + }
2402 + return n;
2403 +}
2404 +
2405 +extern unsigned long copy_in_user(void __user *to, const void __user *from,
2406 + unsigned long n);
2407 +
2408 +#endif /* __powerpc64__ */
2409 +
2410 extern unsigned long __clear_user(void __user *addr, unsigned long size);
2411
2412 static inline unsigned long clear_user(void __user *addr, unsigned long size)
2413 diff -urNp linux-2.6.36/arch/powerpc/kernel/dma.c linux-2.6.36/arch/powerpc/kernel/dma.c
2414 --- linux-2.6.36/arch/powerpc/kernel/dma.c 2010-10-20 16:30:22.000000000 -0400
2415 +++ linux-2.6.36/arch/powerpc/kernel/dma.c 2010-11-06 18:58:15.000000000 -0400
2416 @@ -135,7 +135,7 @@ static inline void dma_direct_sync_singl
2417 }
2418 #endif
2419
2420 -struct dma_map_ops dma_direct_ops = {
2421 +const struct dma_map_ops dma_direct_ops = {
2422 .alloc_coherent = dma_direct_alloc_coherent,
2423 .free_coherent = dma_direct_free_coherent,
2424 .map_sg = dma_direct_map_sg,
2425 diff -urNp linux-2.6.36/arch/powerpc/kernel/dma-iommu.c linux-2.6.36/arch/powerpc/kernel/dma-iommu.c
2426 --- linux-2.6.36/arch/powerpc/kernel/dma-iommu.c 2010-10-20 16:30:22.000000000 -0400
2427 +++ linux-2.6.36/arch/powerpc/kernel/dma-iommu.c 2010-11-06 18:58:15.000000000 -0400
2428 @@ -70,7 +70,7 @@ static void dma_iommu_unmap_sg(struct de
2429 }
2430
2431 /* We support DMA to/from any memory page via the iommu */
2432 -static int dma_iommu_dma_supported(struct device *dev, u64 mask)
2433 +int dma_iommu_dma_supported(struct device *dev, u64 mask)
2434 {
2435 struct iommu_table *tbl = get_iommu_table_base(dev);
2436
2437 @@ -89,6 +89,7 @@ static int dma_iommu_dma_supported(struc
2438 return 1;
2439 }
2440
2441 +/* cannot be const, see arch/powerpc/platforms/cell/iommu.c */
2442 struct dma_map_ops dma_iommu_ops = {
2443 .alloc_coherent = dma_iommu_alloc_coherent,
2444 .free_coherent = dma_iommu_free_coherent,
2445 diff -urNp linux-2.6.36/arch/powerpc/kernel/dma-swiotlb.c linux-2.6.36/arch/powerpc/kernel/dma-swiotlb.c
2446 --- linux-2.6.36/arch/powerpc/kernel/dma-swiotlb.c 2010-10-20 16:30:22.000000000 -0400
2447 +++ linux-2.6.36/arch/powerpc/kernel/dma-swiotlb.c 2010-11-06 18:58:15.000000000 -0400
2448 @@ -31,7 +31,7 @@ unsigned int ppc_swiotlb_enable;
2449 * map_page, and unmap_page on highmem, use normal dma_ops
2450 * for everything else.
2451 */
2452 -struct dma_map_ops swiotlb_dma_ops = {
2453 +const struct dma_map_ops swiotlb_dma_ops = {
2454 .alloc_coherent = dma_direct_alloc_coherent,
2455 .free_coherent = dma_direct_free_coherent,
2456 .map_sg = swiotlb_map_sg_attrs,
2457 diff -urNp linux-2.6.36/arch/powerpc/kernel/exceptions-64e.S linux-2.6.36/arch/powerpc/kernel/exceptions-64e.S
2458 --- linux-2.6.36/arch/powerpc/kernel/exceptions-64e.S 2010-10-20 16:30:22.000000000 -0400
2459 +++ linux-2.6.36/arch/powerpc/kernel/exceptions-64e.S 2010-11-06 18:58:15.000000000 -0400
2460 @@ -495,6 +495,7 @@ storage_fault_common:
2461 std r14,_DAR(r1)
2462 std r15,_DSISR(r1)
2463 addi r3,r1,STACK_FRAME_OVERHEAD
2464 + bl .save_nvgprs
2465 mr r4,r14
2466 mr r5,r15
2467 ld r14,PACA_EXGEN+EX_R14(r13)
2468 @@ -504,8 +505,7 @@ storage_fault_common:
2469 cmpdi r3,0
2470 bne- 1f
2471 b .ret_from_except_lite
2472 -1: bl .save_nvgprs
2473 - mr r5,r3
2474 +1: mr r5,r3
2475 addi r3,r1,STACK_FRAME_OVERHEAD
2476 ld r4,_DAR(r1)
2477 bl .bad_page_fault
2478 diff -urNp linux-2.6.36/arch/powerpc/kernel/exceptions-64s.S linux-2.6.36/arch/powerpc/kernel/exceptions-64s.S
2479 --- linux-2.6.36/arch/powerpc/kernel/exceptions-64s.S 2010-10-20 16:30:22.000000000 -0400
2480 +++ linux-2.6.36/arch/powerpc/kernel/exceptions-64s.S 2010-11-06 18:58:15.000000000 -0400
2481 @@ -841,10 +841,10 @@ handle_page_fault:
2482 11: ld r4,_DAR(r1)
2483 ld r5,_DSISR(r1)
2484 addi r3,r1,STACK_FRAME_OVERHEAD
2485 + bl .save_nvgprs
2486 bl .do_page_fault
2487 cmpdi r3,0
2488 beq+ 13f
2489 - bl .save_nvgprs
2490 mr r5,r3
2491 addi r3,r1,STACK_FRAME_OVERHEAD
2492 lwz r4,_DAR(r1)
2493 diff -urNp linux-2.6.36/arch/powerpc/kernel/ibmebus.c linux-2.6.36/arch/powerpc/kernel/ibmebus.c
2494 --- linux-2.6.36/arch/powerpc/kernel/ibmebus.c 2010-10-20 16:30:22.000000000 -0400
2495 +++ linux-2.6.36/arch/powerpc/kernel/ibmebus.c 2010-11-06 18:58:15.000000000 -0400
2496 @@ -128,7 +128,7 @@ static int ibmebus_dma_supported(struct
2497 return 1;
2498 }
2499
2500 -static struct dma_map_ops ibmebus_dma_ops = {
2501 +static const struct dma_map_ops ibmebus_dma_ops = {
2502 .alloc_coherent = ibmebus_alloc_coherent,
2503 .free_coherent = ibmebus_free_coherent,
2504 .map_sg = ibmebus_map_sg,
2505 diff -urNp linux-2.6.36/arch/powerpc/kernel/kgdb.c linux-2.6.36/arch/powerpc/kernel/kgdb.c
2506 --- linux-2.6.36/arch/powerpc/kernel/kgdb.c 2010-10-20 16:30:22.000000000 -0400
2507 +++ linux-2.6.36/arch/powerpc/kernel/kgdb.c 2010-11-06 18:58:15.000000000 -0400
2508 @@ -360,7 +360,7 @@ int kgdb_arch_handle_exception(int vecto
2509 /*
2510 * Global data
2511 */
2512 -struct kgdb_arch arch_kgdb_ops = {
2513 +const struct kgdb_arch arch_kgdb_ops = {
2514 .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08},
2515 };
2516
2517 diff -urNp linux-2.6.36/arch/powerpc/kernel/module_32.c linux-2.6.36/arch/powerpc/kernel/module_32.c
2518 --- linux-2.6.36/arch/powerpc/kernel/module_32.c 2010-10-20 16:30:22.000000000 -0400
2519 +++ linux-2.6.36/arch/powerpc/kernel/module_32.c 2010-11-06 18:58:15.000000000 -0400
2520 @@ -162,7 +162,7 @@ int module_frob_arch_sections(Elf32_Ehdr
2521 me->arch.core_plt_section = i;
2522 }
2523 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
2524 - printk("Module doesn't contain .plt or .init.plt sections.\n");
2525 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
2526 return -ENOEXEC;
2527 }
2528
2529 @@ -203,11 +203,16 @@ static uint32_t do_plt_call(void *locati
2530
2531 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
2532 /* Init, or core PLT? */
2533 - if (location >= mod->module_core
2534 - && location < mod->module_core + mod->core_size)
2535 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
2536 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
2537 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
2538 - else
2539 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
2540 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
2541 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
2542 + else {
2543 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
2544 + return ~0UL;
2545 + }
2546
2547 /* Find this entry, or if that fails, the next avail. entry */
2548 while (entry->jump[0]) {
2549 diff -urNp linux-2.6.36/arch/powerpc/kernel/module.c linux-2.6.36/arch/powerpc/kernel/module.c
2550 --- linux-2.6.36/arch/powerpc/kernel/module.c 2010-10-20 16:30:22.000000000 -0400
2551 +++ linux-2.6.36/arch/powerpc/kernel/module.c 2010-11-06 18:58:15.000000000 -0400
2552 @@ -31,11 +31,24 @@
2553
2554 LIST_HEAD(module_bug_list);
2555
2556 +#ifdef CONFIG_PAX_KERNEXEC
2557 void *module_alloc(unsigned long size)
2558 {
2559 if (size == 0)
2560 return NULL;
2561
2562 + return vmalloc(size);
2563 +}
2564 +
2565 +void *module_alloc_exec(unsigned long size)
2566 +#else
2567 +void *module_alloc(unsigned long size)
2568 +#endif
2569 +
2570 +{
2571 + if (size == 0)
2572 + return NULL;
2573 +
2574 return vmalloc_exec(size);
2575 }
2576
2577 @@ -45,6 +58,13 @@ void module_free(struct module *mod, voi
2578 vfree(module_region);
2579 }
2580
2581 +#ifdef CONFIG_PAX_KERNEXEC
2582 +void module_free_exec(struct module *mod, void *module_region)
2583 +{
2584 + module_free(mod, module_region);
2585 +}
2586 +#endif
2587 +
2588 static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
2589 const Elf_Shdr *sechdrs,
2590 const char *name)
2591 diff -urNp linux-2.6.36/arch/powerpc/kernel/pci-common.c linux-2.6.36/arch/powerpc/kernel/pci-common.c
2592 --- linux-2.6.36/arch/powerpc/kernel/pci-common.c 2010-10-20 16:30:22.000000000 -0400
2593 +++ linux-2.6.36/arch/powerpc/kernel/pci-common.c 2010-11-06 18:58:15.000000000 -0400
2594 @@ -52,14 +52,14 @@ resource_size_t isa_mem_base;
2595 unsigned int ppc_pci_flags = 0;
2596
2597
2598 -static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
2599 +static const struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
2600
2601 -void set_pci_dma_ops(struct dma_map_ops *dma_ops)
2602 +void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
2603 {
2604 pci_dma_ops = dma_ops;
2605 }
2606
2607 -struct dma_map_ops *get_pci_dma_ops(void)
2608 +const struct dma_map_ops *get_pci_dma_ops(void)
2609 {
2610 return pci_dma_ops;
2611 }
2612 diff -urNp linux-2.6.36/arch/powerpc/kernel/process.c linux-2.6.36/arch/powerpc/kernel/process.c
2613 --- linux-2.6.36/arch/powerpc/kernel/process.c 2010-10-20 16:30:22.000000000 -0400
2614 +++ linux-2.6.36/arch/powerpc/kernel/process.c 2010-11-06 18:58:15.000000000 -0400
2615 @@ -1251,54 +1251,6 @@ unsigned long arch_align_stack(unsigned
2616 return sp & ~0xf;
2617 }
2618
2619 -static inline unsigned long brk_rnd(void)
2620 -{
2621 - unsigned long rnd = 0;
2622 -
2623 - /* 8MB for 32bit, 1GB for 64bit */
2624 - if (is_32bit_task())
2625 - rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
2626 - else
2627 - rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
2628 -
2629 - return rnd << PAGE_SHIFT;
2630 -}
2631 -
2632 -unsigned long arch_randomize_brk(struct mm_struct *mm)
2633 -{
2634 - unsigned long base = mm->brk;
2635 - unsigned long ret;
2636 -
2637 -#ifdef CONFIG_PPC_STD_MMU_64
2638 - /*
2639 - * If we are using 1TB segments and we are allowed to randomise
2640 - * the heap, we can put it above 1TB so it is backed by a 1TB
2641 - * segment. Otherwise the heap will be in the bottom 1TB
2642 - * which always uses 256MB segments and this may result in a
2643 - * performance penalty.
2644 - */
2645 - if (!is_32bit_task() && (mmu_highuser_ssize == MMU_SEGSIZE_1T))
2646 - base = max_t(unsigned long, mm->brk, 1UL << SID_SHIFT_1T);
2647 -#endif
2648 -
2649 - ret = PAGE_ALIGN(base + brk_rnd());
2650 -
2651 - if (ret < mm->brk)
2652 - return mm->brk;
2653 -
2654 - return ret;
2655 -}
2656 -
2657 -unsigned long randomize_et_dyn(unsigned long base)
2658 -{
2659 - unsigned long ret = PAGE_ALIGN(base + brk_rnd());
2660 -
2661 - if (ret < base)
2662 - return base;
2663 -
2664 - return ret;
2665 -}
2666 -
2667 #ifdef CONFIG_SMP
2668 int arch_sd_sibling_asym_packing(void)
2669 {
2670 diff -urNp linux-2.6.36/arch/powerpc/kernel/signal_32.c linux-2.6.36/arch/powerpc/kernel/signal_32.c
2671 --- linux-2.6.36/arch/powerpc/kernel/signal_32.c 2010-10-20 16:30:22.000000000 -0400
2672 +++ linux-2.6.36/arch/powerpc/kernel/signal_32.c 2010-11-06 18:58:15.000000000 -0400
2673 @@ -858,7 +858,7 @@ int handle_rt_signal32(unsigned long sig
2674 /* Save user registers on the stack */
2675 frame = &rt_sf->uc.uc_mcontext;
2676 addr = frame;
2677 - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
2678 + if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
2679 if (save_user_regs(regs, frame, 0, 1))
2680 goto badframe;
2681 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
2682 diff -urNp linux-2.6.36/arch/powerpc/kernel/signal_64.c linux-2.6.36/arch/powerpc/kernel/signal_64.c
2683 --- linux-2.6.36/arch/powerpc/kernel/signal_64.c 2010-10-20 16:30:22.000000000 -0400
2684 +++ linux-2.6.36/arch/powerpc/kernel/signal_64.c 2010-11-06 18:58:15.000000000 -0400
2685 @@ -429,7 +429,7 @@ int handle_rt_signal64(int signr, struct
2686 current->thread.fpscr.val = 0;
2687
2688 /* Set up to return from userspace. */
2689 - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
2690 + if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
2691 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
2692 } else {
2693 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
2694 diff -urNp linux-2.6.36/arch/powerpc/kernel/vdso.c linux-2.6.36/arch/powerpc/kernel/vdso.c
2695 --- linux-2.6.36/arch/powerpc/kernel/vdso.c 2010-10-20 16:30:22.000000000 -0400
2696 +++ linux-2.6.36/arch/powerpc/kernel/vdso.c 2010-11-06 18:58:15.000000000 -0400
2697 @@ -36,6 +36,7 @@
2698 #include <asm/firmware.h>
2699 #include <asm/vdso.h>
2700 #include <asm/vdso_datapage.h>
2701 +#include <asm/mman.h>
2702
2703 #include "setup.h"
2704
2705 @@ -220,7 +221,7 @@ int arch_setup_additional_pages(struct l
2706 vdso_base = VDSO32_MBASE;
2707 #endif
2708
2709 - current->mm->context.vdso_base = 0;
2710 + current->mm->context.vdso_base = ~0UL;
2711
2712 /* vDSO has a problem and was disabled, just don't "enable" it for the
2713 * process
2714 @@ -240,7 +241,7 @@ int arch_setup_additional_pages(struct l
2715 vdso_base = get_unmapped_area(NULL, vdso_base,
2716 (vdso_pages << PAGE_SHIFT) +
2717 ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
2718 - 0, 0);
2719 + 0, MAP_PRIVATE | MAP_EXECUTABLE);
2720 if (IS_ERR_VALUE(vdso_base)) {
2721 rc = vdso_base;
2722 goto fail_mmapsem;
2723 diff -urNp linux-2.6.36/arch/powerpc/kernel/vio.c linux-2.6.36/arch/powerpc/kernel/vio.c
2724 --- linux-2.6.36/arch/powerpc/kernel/vio.c 2010-10-20 16:30:22.000000000 -0400
2725 +++ linux-2.6.36/arch/powerpc/kernel/vio.c 2010-11-06 18:58:15.000000000 -0400
2726 @@ -602,11 +602,12 @@ static void vio_dma_iommu_unmap_sg(struc
2727 vio_cmo_dealloc(viodev, alloc_size);
2728 }
2729
2730 -struct dma_map_ops vio_dma_mapping_ops = {
2731 +static const struct dma_map_ops vio_dma_mapping_ops = {
2732 .alloc_coherent = vio_dma_iommu_alloc_coherent,
2733 .free_coherent = vio_dma_iommu_free_coherent,
2734 .map_sg = vio_dma_iommu_map_sg,
2735 .unmap_sg = vio_dma_iommu_unmap_sg,
2736 + .dma_supported = dma_iommu_dma_supported,
2737 .map_page = vio_dma_iommu_map_page,
2738 .unmap_page = vio_dma_iommu_unmap_page,
2739
2740 @@ -860,7 +861,6 @@ static void vio_cmo_bus_remove(struct vi
2741
2742 static void vio_cmo_set_dma_ops(struct vio_dev *viodev)
2743 {
2744 - vio_dma_mapping_ops.dma_supported = dma_iommu_ops.dma_supported;
2745 viodev->dev.archdata.dma_ops = &vio_dma_mapping_ops;
2746 }
2747
2748 diff -urNp linux-2.6.36/arch/powerpc/lib/usercopy_64.c linux-2.6.36/arch/powerpc/lib/usercopy_64.c
2749 --- linux-2.6.36/arch/powerpc/lib/usercopy_64.c 2010-10-20 16:30:22.000000000 -0400
2750 +++ linux-2.6.36/arch/powerpc/lib/usercopy_64.c 2010-11-06 18:58:15.000000000 -0400
2751 @@ -9,22 +9,6 @@
2752 #include <linux/module.h>
2753 #include <asm/uaccess.h>
2754
2755 -unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
2756 -{
2757 - if (likely(access_ok(VERIFY_READ, from, n)))
2758 - n = __copy_from_user(to, from, n);
2759 - else
2760 - memset(to, 0, n);
2761 - return n;
2762 -}
2763 -
2764 -unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
2765 -{
2766 - if (likely(access_ok(VERIFY_WRITE, to, n)))
2767 - n = __copy_to_user(to, from, n);
2768 - return n;
2769 -}
2770 -
2771 unsigned long copy_in_user(void __user *to, const void __user *from,
2772 unsigned long n)
2773 {
2774 @@ -35,7 +19,5 @@ unsigned long copy_in_user(void __user *
2775 return n;
2776 }
2777
2778 -EXPORT_SYMBOL(copy_from_user);
2779 -EXPORT_SYMBOL(copy_to_user);
2780 EXPORT_SYMBOL(copy_in_user);
2781
2782 diff -urNp linux-2.6.36/arch/powerpc/mm/fault.c linux-2.6.36/arch/powerpc/mm/fault.c
2783 --- linux-2.6.36/arch/powerpc/mm/fault.c 2010-10-20 16:30:22.000000000 -0400
2784 +++ linux-2.6.36/arch/powerpc/mm/fault.c 2010-11-06 18:58:15.000000000 -0400
2785 @@ -30,6 +30,10 @@
2786 #include <linux/kprobes.h>
2787 #include <linux/kdebug.h>
2788 #include <linux/perf_event.h>
2789 +#include <linux/slab.h>
2790 +#include <linux/pagemap.h>
2791 +#include <linux/compiler.h>
2792 +#include <linux/unistd.h>
2793
2794 #include <asm/firmware.h>
2795 #include <asm/page.h>
2796 @@ -41,6 +45,7 @@
2797 #include <asm/tlbflush.h>
2798 #include <asm/siginfo.h>
2799 #include <mm/mmu_decl.h>
2800 +#include <asm/ptrace.h>
2801
2802 #ifdef CONFIG_KPROBES
2803 static inline int notify_page_fault(struct pt_regs *regs)
2804 @@ -64,6 +69,33 @@ static inline int notify_page_fault(stru
2805 }
2806 #endif
2807
2808 +#ifdef CONFIG_PAX_PAGEEXEC
2809 +/*
2810 + * PaX: decide what to do with offenders (regs->nip = fault address)
2811 + *
2812 + * returns 1 when task should be killed
2813 + */
2814 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2815 +{
2816 + return 1;
2817 +}
2818 +
2819 +void pax_report_insns(void *pc, void *sp)
2820 +{
2821 + unsigned long i;
2822 +
2823 + printk(KERN_ERR "PAX: bytes at PC: ");
2824 + for (i = 0; i < 5; i++) {
2825 + unsigned int c;
2826 + if (get_user(c, (unsigned int __user *)pc+i))
2827 + printk(KERN_CONT "???????? ");
2828 + else
2829 + printk(KERN_CONT "%08x ", c);
2830 + }
2831 + printk("\n");
2832 +}
2833 +#endif
2834 +
2835 /*
2836 * Check whether the instruction at regs->nip is a store using
2837 * an update addressing form which will update r1.
2838 @@ -134,7 +166,7 @@ int __kprobes do_page_fault(struct pt_re
2839 * indicate errors in DSISR but can validly be set in SRR1.
2840 */
2841 if (trap == 0x400)
2842 - error_code &= 0x48200000;
2843 + error_code &= 0x58200000;
2844 else
2845 is_write = error_code & DSISR_ISSTORE;
2846 #else
2847 @@ -257,7 +289,7 @@ good_area:
2848 * "undefined". Of those that can be set, this is the only
2849 * one which seems bad.
2850 */
2851 - if (error_code & 0x10000000)
2852 + if (error_code & DSISR_GUARDED)
2853 /* Guarded storage error. */
2854 goto bad_area;
2855 #endif /* CONFIG_8xx */
2856 @@ -272,7 +304,7 @@ good_area:
2857 * processors use the same I/D cache coherency mechanism
2858 * as embedded.
2859 */
2860 - if (error_code & DSISR_PROTFAULT)
2861 + if (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))
2862 goto bad_area;
2863 #endif /* CONFIG_PPC_STD_MMU */
2864
2865 @@ -341,6 +373,23 @@ bad_area:
2866 bad_area_nosemaphore:
2867 /* User mode accesses cause a SIGSEGV */
2868 if (user_mode(regs)) {
2869 +
2870 +#ifdef CONFIG_PAX_PAGEEXEC
2871 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
2872 +#ifdef CONFIG_PPC_STD_MMU
2873 + if (is_exec && (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))) {
2874 +#else
2875 + if (is_exec && regs->nip == address) {
2876 +#endif
2877 + switch (pax_handle_fetch_fault(regs)) {
2878 + }
2879 +
2880 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
2881 + do_group_exit(SIGKILL);
2882 + }
2883 + }
2884 +#endif
2885 +
2886 _exception(SIGSEGV, regs, code, address);
2887 return 0;
2888 }
2889 diff -urNp linux-2.6.36/arch/powerpc/mm/mmap_64.c linux-2.6.36/arch/powerpc/mm/mmap_64.c
2890 --- linux-2.6.36/arch/powerpc/mm/mmap_64.c 2010-10-20 16:30:22.000000000 -0400
2891 +++ linux-2.6.36/arch/powerpc/mm/mmap_64.c 2010-11-06 18:58:15.000000000 -0400
2892 @@ -99,10 +99,22 @@ void arch_pick_mmap_layout(struct mm_str
2893 */
2894 if (mmap_is_legacy()) {
2895 mm->mmap_base = TASK_UNMAPPED_BASE;
2896 +
2897 +#ifdef CONFIG_PAX_RANDMMAP
2898 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2899 + mm->mmap_base += mm->delta_mmap;
2900 +#endif
2901 +
2902 mm->get_unmapped_area = arch_get_unmapped_area;
2903 mm->unmap_area = arch_unmap_area;
2904 } else {
2905 mm->mmap_base = mmap_base();
2906 +
2907 +#ifdef CONFIG_PAX_RANDMMAP
2908 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2909 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2910 +#endif
2911 +
2912 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2913 mm->unmap_area = arch_unmap_area_topdown;
2914 }
2915 diff -urNp linux-2.6.36/arch/powerpc/mm/slice.c linux-2.6.36/arch/powerpc/mm/slice.c
2916 --- linux-2.6.36/arch/powerpc/mm/slice.c 2010-10-20 16:30:22.000000000 -0400
2917 +++ linux-2.6.36/arch/powerpc/mm/slice.c 2010-11-06 18:58:15.000000000 -0400
2918 @@ -98,7 +98,7 @@ static int slice_area_is_free(struct mm_
2919 if ((mm->task_size - len) < addr)
2920 return 0;
2921 vma = find_vma(mm, addr);
2922 - return (!vma || (addr + len) <= vma->vm_start);
2923 + return check_heap_stack_gap(vma, addr, len);
2924 }
2925
2926 static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice)
2927 @@ -256,7 +256,7 @@ full_search:
2928 addr = _ALIGN_UP(addr + 1, 1ul << SLICE_HIGH_SHIFT);
2929 continue;
2930 }
2931 - if (!vma || addr + len <= vma->vm_start) {
2932 + if (check_heap_stack_gap(vma, addr, len)) {
2933 /*
2934 * Remember the place where we stopped the search:
2935 */
2936 @@ -336,7 +336,7 @@ static unsigned long slice_find_area_top
2937 * return with success:
2938 */
2939 vma = find_vma(mm, addr);
2940 - if (!vma || (addr + len) <= vma->vm_start) {
2941 + if (check_heap_stack_gap(vma, addr, len)) {
2942 /* remember the address as a hint for next time */
2943 if (use_cache)
2944 mm->free_area_cache = addr;
2945 @@ -426,6 +426,11 @@ unsigned long slice_get_unmapped_area(un
2946 if (fixed && addr > (mm->task_size - len))
2947 return -EINVAL;
2948
2949 +#ifdef CONFIG_PAX_RANDMMAP
2950 + if (!fixed && (mm->pax_flags & MF_PAX_RANDMMAP))
2951 + addr = 0;
2952 +#endif
2953 +
2954 /* If hint, make sure it matches our alignment restrictions */
2955 if (!fixed && addr) {
2956 addr = _ALIGN_UP(addr, 1ul << pshift);
2957 diff -urNp linux-2.6.36/arch/powerpc/platforms/52xx/lite5200_pm.c linux-2.6.36/arch/powerpc/platforms/52xx/lite5200_pm.c
2958 --- linux-2.6.36/arch/powerpc/platforms/52xx/lite5200_pm.c 2010-10-20 16:30:22.000000000 -0400
2959 +++ linux-2.6.36/arch/powerpc/platforms/52xx/lite5200_pm.c 2010-11-06 18:58:15.000000000 -0400
2960 @@ -232,7 +232,7 @@ static void lite5200_pm_end(void)
2961 lite5200_pm_target_state = PM_SUSPEND_ON;
2962 }
2963
2964 -static struct platform_suspend_ops lite5200_pm_ops = {
2965 +static const struct platform_suspend_ops lite5200_pm_ops = {
2966 .valid = lite5200_pm_valid,
2967 .begin = lite5200_pm_begin,
2968 .prepare = lite5200_pm_prepare,
2969 diff -urNp linux-2.6.36/arch/powerpc/platforms/52xx/mpc52xx_pm.c linux-2.6.36/arch/powerpc/platforms/52xx/mpc52xx_pm.c
2970 --- linux-2.6.36/arch/powerpc/platforms/52xx/mpc52xx_pm.c 2010-10-20 16:30:22.000000000 -0400
2971 +++ linux-2.6.36/arch/powerpc/platforms/52xx/mpc52xx_pm.c 2010-11-06 18:58:15.000000000 -0400
2972 @@ -186,7 +186,7 @@ void mpc52xx_pm_finish(void)
2973 iounmap(mbar);
2974 }
2975
2976 -static struct platform_suspend_ops mpc52xx_pm_ops = {
2977 +static const struct platform_suspend_ops mpc52xx_pm_ops = {
2978 .valid = mpc52xx_pm_valid,
2979 .prepare = mpc52xx_pm_prepare,
2980 .enter = mpc52xx_pm_enter,
2981 diff -urNp linux-2.6.36/arch/powerpc/platforms/83xx/suspend.c linux-2.6.36/arch/powerpc/platforms/83xx/suspend.c
2982 --- linux-2.6.36/arch/powerpc/platforms/83xx/suspend.c 2010-10-20 16:30:22.000000000 -0400
2983 +++ linux-2.6.36/arch/powerpc/platforms/83xx/suspend.c 2010-11-06 18:58:15.000000000 -0400
2984 @@ -311,7 +311,7 @@ static int mpc83xx_is_pci_agent(void)
2985 return ret;
2986 }
2987
2988 -static struct platform_suspend_ops mpc83xx_suspend_ops = {
2989 +static const struct platform_suspend_ops mpc83xx_suspend_ops = {
2990 .valid = mpc83xx_suspend_valid,
2991 .begin = mpc83xx_suspend_begin,
2992 .enter = mpc83xx_suspend_enter,
2993 diff -urNp linux-2.6.36/arch/powerpc/platforms/cell/iommu.c linux-2.6.36/arch/powerpc/platforms/cell/iommu.c
2994 --- linux-2.6.36/arch/powerpc/platforms/cell/iommu.c 2010-10-20 16:30:22.000000000 -0400
2995 +++ linux-2.6.36/arch/powerpc/platforms/cell/iommu.c 2010-11-06 18:58:15.000000000 -0400
2996 @@ -642,7 +642,7 @@ static int dma_fixed_dma_supported(struc
2997
2998 static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
2999
3000 -struct dma_map_ops dma_iommu_fixed_ops = {
3001 +const struct dma_map_ops dma_iommu_fixed_ops = {
3002 .alloc_coherent = dma_fixed_alloc_coherent,
3003 .free_coherent = dma_fixed_free_coherent,
3004 .map_sg = dma_fixed_map_sg,
3005 diff -urNp linux-2.6.36/arch/powerpc/platforms/ps3/system-bus.c linux-2.6.36/arch/powerpc/platforms/ps3/system-bus.c
3006 --- linux-2.6.36/arch/powerpc/platforms/ps3/system-bus.c 2010-10-20 16:30:22.000000000 -0400
3007 +++ linux-2.6.36/arch/powerpc/platforms/ps3/system-bus.c 2010-11-06 18:58:15.000000000 -0400
3008 @@ -695,7 +695,7 @@ static int ps3_dma_supported(struct devi
3009 return mask >= DMA_BIT_MASK(32);
3010 }
3011
3012 -static struct dma_map_ops ps3_sb_dma_ops = {
3013 +static const struct dma_map_ops ps3_sb_dma_ops = {
3014 .alloc_coherent = ps3_alloc_coherent,
3015 .free_coherent = ps3_free_coherent,
3016 .map_sg = ps3_sb_map_sg,
3017 @@ -705,7 +705,7 @@ static struct dma_map_ops ps3_sb_dma_ops
3018 .unmap_page = ps3_unmap_page,
3019 };
3020
3021 -static struct dma_map_ops ps3_ioc0_dma_ops = {
3022 +static const struct dma_map_ops ps3_ioc0_dma_ops = {
3023 .alloc_coherent = ps3_alloc_coherent,
3024 .free_coherent = ps3_free_coherent,
3025 .map_sg = ps3_ioc0_map_sg,
3026 diff -urNp linux-2.6.36/arch/powerpc/platforms/pseries/suspend.c linux-2.6.36/arch/powerpc/platforms/pseries/suspend.c
3027 --- linux-2.6.36/arch/powerpc/platforms/pseries/suspend.c 2010-10-20 16:30:22.000000000 -0400
3028 +++ linux-2.6.36/arch/powerpc/platforms/pseries/suspend.c 2010-11-06 18:58:15.000000000 -0400
3029 @@ -153,7 +153,7 @@ static struct sysdev_class suspend_sysde
3030 .name = "power",
3031 };
3032
3033 -static struct platform_suspend_ops pseries_suspend_ops = {
3034 +static const struct platform_suspend_ops pseries_suspend_ops = {
3035 .valid = suspend_valid_only_mem,
3036 .begin = pseries_suspend_begin,
3037 .prepare_late = pseries_prepare_late,
3038 diff -urNp linux-2.6.36/arch/powerpc/sysdev/fsl_pmc.c linux-2.6.36/arch/powerpc/sysdev/fsl_pmc.c
3039 --- linux-2.6.36/arch/powerpc/sysdev/fsl_pmc.c 2010-10-20 16:30:22.000000000 -0400
3040 +++ linux-2.6.36/arch/powerpc/sysdev/fsl_pmc.c 2010-11-06 18:58:15.000000000 -0400
3041 @@ -53,7 +53,7 @@ static int pmc_suspend_valid(suspend_sta
3042 return 1;
3043 }
3044
3045 -static struct platform_suspend_ops pmc_suspend_ops = {
3046 +static const struct platform_suspend_ops pmc_suspend_ops = {
3047 .valid = pmc_suspend_valid,
3048 .enter = pmc_suspend_enter,
3049 };
3050 diff -urNp linux-2.6.36/arch/s390/include/asm/elf.h linux-2.6.36/arch/s390/include/asm/elf.h
3051 --- linux-2.6.36/arch/s390/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
3052 +++ linux-2.6.36/arch/s390/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
3053 @@ -163,6 +163,13 @@ extern unsigned int vdso_enabled;
3054 that it will "exec", and that there is sufficient room for the brk. */
3055 #define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2)
3056
3057 +#ifdef CONFIG_PAX_ASLR
3058 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_31BIT) ? 0x10000UL : 0x80000000UL)
3059 +
3060 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_31BIT) ? 15 : 26 )
3061 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_31BIT) ? 15 : 26 )
3062 +#endif
3063 +
3064 /* This yields a mask that user programs can use to figure out what
3065 instruction set this CPU supports. */
3066
3067 diff -urNp linux-2.6.36/arch/s390/include/asm/uaccess.h linux-2.6.36/arch/s390/include/asm/uaccess.h
3068 --- linux-2.6.36/arch/s390/include/asm/uaccess.h 2010-10-20 16:30:22.000000000 -0400
3069 +++ linux-2.6.36/arch/s390/include/asm/uaccess.h 2010-11-06 18:58:15.000000000 -0400
3070 @@ -234,6 +234,10 @@ static inline unsigned long __must_check
3071 copy_to_user(void __user *to, const void *from, unsigned long n)
3072 {
3073 might_fault();
3074 +
3075 + if ((long)n < 0)
3076 + return n;
3077 +
3078 if (access_ok(VERIFY_WRITE, to, n))
3079 n = __copy_to_user(to, from, n);
3080 return n;
3081 @@ -259,6 +263,9 @@ copy_to_user(void __user *to, const void
3082 static inline unsigned long __must_check
3083 __copy_from_user(void *to, const void __user *from, unsigned long n)
3084 {
3085 + if ((long)n < 0)
3086 + return n;
3087 +
3088 if (__builtin_constant_p(n) && (n <= 256))
3089 return uaccess.copy_from_user_small(n, from, to);
3090 else
3091 @@ -293,6 +300,10 @@ copy_from_user(void *to, const void __us
3092 unsigned int sz = __compiletime_object_size(to);
3093
3094 might_fault();
3095 +
3096 + if ((long)n < 0)
3097 + return n;
3098 +
3099 if (unlikely(sz != -1 && sz < n)) {
3100 copy_from_user_overflow();
3101 return n;
3102 diff -urNp linux-2.6.36/arch/s390/Kconfig linux-2.6.36/arch/s390/Kconfig
3103 --- linux-2.6.36/arch/s390/Kconfig 2010-10-20 16:30:22.000000000 -0400
3104 +++ linux-2.6.36/arch/s390/Kconfig 2010-11-06 18:58:15.000000000 -0400
3105 @@ -227,13 +227,12 @@ config AUDIT_ARCH
3106
3107 config S390_EXEC_PROTECT
3108 bool "Data execute protection"
3109 + default y
3110 help
3111 This option allows to enable a buffer overflow protection for user
3112 - space programs and it also selects the addressing mode option above.
3113 - The kernel parameter noexec=on will enable this feature and also
3114 - switch the addressing modes, default is disabled. Enabling this (via
3115 - kernel parameter) on machines earlier than IBM System z9-109 EC/BC
3116 - will reduce system performance.
3117 + space programs.
3118 + Enabling this on machines earlier than IBM System z9-109 EC/BC will
3119 + reduce system performance.
3120
3121 comment "Code generation options"
3122
3123 diff -urNp linux-2.6.36/arch/s390/kernel/module.c linux-2.6.36/arch/s390/kernel/module.c
3124 --- linux-2.6.36/arch/s390/kernel/module.c 2010-10-20 16:30:22.000000000 -0400
3125 +++ linux-2.6.36/arch/s390/kernel/module.c 2010-11-06 18:58:15.000000000 -0400
3126 @@ -168,11 +168,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
3127
3128 /* Increase core size by size of got & plt and set start
3129 offsets for got and plt. */
3130 - me->core_size = ALIGN(me->core_size, 4);
3131 - me->arch.got_offset = me->core_size;
3132 - me->core_size += me->arch.got_size;
3133 - me->arch.plt_offset = me->core_size;
3134 - me->core_size += me->arch.plt_size;
3135 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
3136 + me->arch.got_offset = me->core_size_rw;
3137 + me->core_size_rw += me->arch.got_size;
3138 + me->arch.plt_offset = me->core_size_rx;
3139 + me->core_size_rx += me->arch.plt_size;
3140 return 0;
3141 }
3142
3143 @@ -258,7 +258,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
3144 if (info->got_initialized == 0) {
3145 Elf_Addr *gotent;
3146
3147 - gotent = me->module_core + me->arch.got_offset +
3148 + gotent = me->module_core_rw + me->arch.got_offset +
3149 info->got_offset;
3150 *gotent = val;
3151 info->got_initialized = 1;
3152 @@ -282,7 +282,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
3153 else if (r_type == R_390_GOTENT ||
3154 r_type == R_390_GOTPLTENT)
3155 *(unsigned int *) loc =
3156 - (val + (Elf_Addr) me->module_core - loc) >> 1;
3157 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
3158 else if (r_type == R_390_GOT64 ||
3159 r_type == R_390_GOTPLT64)
3160 *(unsigned long *) loc = val;
3161 @@ -296,7 +296,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
3162 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
3163 if (info->plt_initialized == 0) {
3164 unsigned int *ip;
3165 - ip = me->module_core + me->arch.plt_offset +
3166 + ip = me->module_core_rx + me->arch.plt_offset +
3167 info->plt_offset;
3168 #ifndef CONFIG_64BIT
3169 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
3170 @@ -321,7 +321,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
3171 val - loc + 0xffffUL < 0x1ffffeUL) ||
3172 (r_type == R_390_PLT32DBL &&
3173 val - loc + 0xffffffffULL < 0x1fffffffeULL)))
3174 - val = (Elf_Addr) me->module_core +
3175 + val = (Elf_Addr) me->module_core_rx +
3176 me->arch.plt_offset +
3177 info->plt_offset;
3178 val += rela->r_addend - loc;
3179 @@ -343,7 +343,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
3180 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
3181 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
3182 val = val + rela->r_addend -
3183 - ((Elf_Addr) me->module_core + me->arch.got_offset);
3184 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
3185 if (r_type == R_390_GOTOFF16)
3186 *(unsigned short *) loc = val;
3187 else if (r_type == R_390_GOTOFF32)
3188 @@ -353,7 +353,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
3189 break;
3190 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
3191 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
3192 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
3193 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
3194 rela->r_addend - loc;
3195 if (r_type == R_390_GOTPC)
3196 *(unsigned int *) loc = val;
3197 diff -urNp linux-2.6.36/arch/s390/kernel/setup.c linux-2.6.36/arch/s390/kernel/setup.c
3198 --- linux-2.6.36/arch/s390/kernel/setup.c 2010-10-20 16:30:22.000000000 -0400
3199 +++ linux-2.6.36/arch/s390/kernel/setup.c 2010-11-06 18:58:15.000000000 -0400
3200 @@ -281,7 +281,7 @@ static int __init early_parse_mem(char *
3201 }
3202 early_param("mem", early_parse_mem);
3203
3204 -unsigned int user_mode = HOME_SPACE_MODE;
3205 +unsigned int user_mode = SECONDARY_SPACE_MODE;
3206 EXPORT_SYMBOL_GPL(user_mode);
3207
3208 static int set_amode_and_uaccess(unsigned long user_amode,
3209 @@ -310,17 +310,6 @@ static int set_amode_and_uaccess(unsigne
3210 }
3211 }
3212
3213 -/*
3214 - * Switch kernel/user addressing modes?
3215 - */
3216 -static int __init early_parse_switch_amode(char *p)
3217 -{
3218 - if (user_mode != SECONDARY_SPACE_MODE)
3219 - user_mode = PRIMARY_SPACE_MODE;
3220 - return 0;
3221 -}
3222 -early_param("switch_amode", early_parse_switch_amode);
3223 -
3224 static int __init early_parse_user_mode(char *p)
3225 {
3226 if (p && strcmp(p, "primary") == 0)
3227 @@ -337,20 +326,6 @@ static int __init early_parse_user_mode(
3228 }
3229 early_param("user_mode", early_parse_user_mode);
3230
3231 -#ifdef CONFIG_S390_EXEC_PROTECT
3232 -/*
3233 - * Enable execute protection?
3234 - */
3235 -static int __init early_parse_noexec(char *p)
3236 -{
3237 - if (!strncmp(p, "off", 3))
3238 - return 0;
3239 - user_mode = SECONDARY_SPACE_MODE;
3240 - return 0;
3241 -}
3242 -early_param("noexec", early_parse_noexec);
3243 -#endif /* CONFIG_S390_EXEC_PROTECT */
3244 -
3245 static void setup_addressing_mode(void)
3246 {
3247 if (user_mode == SECONDARY_SPACE_MODE) {
3248 diff -urNp linux-2.6.36/arch/s390/mm/maccess.c linux-2.6.36/arch/s390/mm/maccess.c
3249 --- linux-2.6.36/arch/s390/mm/maccess.c 2010-10-20 16:30:22.000000000 -0400
3250 +++ linux-2.6.36/arch/s390/mm/maccess.c 2010-11-06 18:58:15.000000000 -0400
3251 @@ -45,7 +45,7 @@ static long probe_kernel_write_odd(void
3252 return rc ? rc : count;
3253 }
3254
3255 -long probe_kernel_write(void *dst, void *src, size_t size)
3256 +long probe_kernel_write(void *dst, const void *src, size_t size)
3257 {
3258 long copied = 0;
3259
3260 diff -urNp linux-2.6.36/arch/s390/mm/mmap.c linux-2.6.36/arch/s390/mm/mmap.c
3261 --- linux-2.6.36/arch/s390/mm/mmap.c 2010-10-20 16:30:22.000000000 -0400
3262 +++ linux-2.6.36/arch/s390/mm/mmap.c 2010-11-06 18:58:15.000000000 -0400
3263 @@ -78,10 +78,22 @@ void arch_pick_mmap_layout(struct mm_str
3264 */
3265 if (mmap_is_legacy()) {
3266 mm->mmap_base = TASK_UNMAPPED_BASE;
3267 +
3268 +#ifdef CONFIG_PAX_RANDMMAP
3269 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3270 + mm->mmap_base += mm->delta_mmap;
3271 +#endif
3272 +
3273 mm->get_unmapped_area = arch_get_unmapped_area;
3274 mm->unmap_area = arch_unmap_area;
3275 } else {
3276 mm->mmap_base = mmap_base();
3277 +
3278 +#ifdef CONFIG_PAX_RANDMMAP
3279 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3280 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3281 +#endif
3282 +
3283 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3284 mm->unmap_area = arch_unmap_area_topdown;
3285 }
3286 @@ -153,10 +165,22 @@ void arch_pick_mmap_layout(struct mm_str
3287 */
3288 if (mmap_is_legacy()) {
3289 mm->mmap_base = TASK_UNMAPPED_BASE;
3290 +
3291 +#ifdef CONFIG_PAX_RANDMMAP
3292 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3293 + mm->mmap_base += mm->delta_mmap;
3294 +#endif
3295 +
3296 mm->get_unmapped_area = s390_get_unmapped_area;
3297 mm->unmap_area = arch_unmap_area;
3298 } else {
3299 mm->mmap_base = mmap_base();
3300 +
3301 +#ifdef CONFIG_PAX_RANDMMAP
3302 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3303 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3304 +#endif
3305 +
3306 mm->get_unmapped_area = s390_get_unmapped_area_topdown;
3307 mm->unmap_area = arch_unmap_area_topdown;
3308 }
3309 diff -urNp linux-2.6.36/arch/sh/boards/mach-hp6xx/pm.c linux-2.6.36/arch/sh/boards/mach-hp6xx/pm.c
3310 --- linux-2.6.36/arch/sh/boards/mach-hp6xx/pm.c 2010-10-20 16:30:22.000000000 -0400
3311 +++ linux-2.6.36/arch/sh/boards/mach-hp6xx/pm.c 2010-11-06 18:58:15.000000000 -0400
3312 @@ -143,7 +143,7 @@ static int hp6x0_pm_enter(suspend_state_
3313 return 0;
3314 }
3315
3316 -static struct platform_suspend_ops hp6x0_pm_ops = {
3317 +static const struct platform_suspend_ops hp6x0_pm_ops = {
3318 .enter = hp6x0_pm_enter,
3319 .valid = suspend_valid_only_mem,
3320 };
3321 diff -urNp linux-2.6.36/arch/sh/include/asm/dma-mapping.h linux-2.6.36/arch/sh/include/asm/dma-mapping.h
3322 --- linux-2.6.36/arch/sh/include/asm/dma-mapping.h 2010-10-20 16:30:22.000000000 -0400
3323 +++ linux-2.6.36/arch/sh/include/asm/dma-mapping.h 2010-11-06 18:58:15.000000000 -0400
3324 @@ -1,10 +1,10 @@
3325 #ifndef __ASM_SH_DMA_MAPPING_H
3326 #define __ASM_SH_DMA_MAPPING_H
3327
3328 -extern struct dma_map_ops *dma_ops;
3329 +extern const struct dma_map_ops *dma_ops;
3330 extern void no_iommu_init(void);
3331
3332 -static inline struct dma_map_ops *get_dma_ops(struct device *dev)
3333 +static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
3334 {
3335 return dma_ops;
3336 }
3337 @@ -14,7 +14,7 @@ static inline struct dma_map_ops *get_dm
3338
3339 static inline int dma_supported(struct device *dev, u64 mask)
3340 {
3341 - struct dma_map_ops *ops = get_dma_ops(dev);
3342 + const struct dma_map_ops *ops = get_dma_ops(dev);
3343
3344 if (ops->dma_supported)
3345 return ops->dma_supported(dev, mask);
3346 @@ -24,7 +24,7 @@ static inline int dma_supported(struct d
3347
3348 static inline int dma_set_mask(struct device *dev, u64 mask)
3349 {
3350 - struct dma_map_ops *ops = get_dma_ops(dev);
3351 + const struct dma_map_ops *ops = get_dma_ops(dev);
3352
3353 if (!dev->dma_mask || !dma_supported(dev, mask))
3354 return -EIO;
3355 @@ -44,7 +44,7 @@ void dma_cache_sync(struct device *dev,
3356
3357 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
3358 {
3359 - struct dma_map_ops *ops = get_dma_ops(dev);
3360 + const struct dma_map_ops *ops = get_dma_ops(dev);
3361
3362 if (ops->mapping_error)
3363 return ops->mapping_error(dev, dma_addr);
3364 @@ -55,7 +55,7 @@ static inline int dma_mapping_error(stru
3365 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
3366 dma_addr_t *dma_handle, gfp_t gfp)
3367 {
3368 - struct dma_map_ops *ops = get_dma_ops(dev);
3369 + const struct dma_map_ops *ops = get_dma_ops(dev);
3370 void *memory;
3371
3372 if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
3373 @@ -72,7 +72,7 @@ static inline void *dma_alloc_coherent(s
3374 static inline void dma_free_coherent(struct device *dev, size_t size,
3375 void *vaddr, dma_addr_t dma_handle)
3376 {
3377 - struct dma_map_ops *ops = get_dma_ops(dev);
3378 + const struct dma_map_ops *ops = get_dma_ops(dev);
3379
3380 if (dma_release_from_coherent(dev, get_order(size), vaddr))
3381 return;
3382 diff -urNp linux-2.6.36/arch/sh/kernel/cpu/shmobile/pm.c linux-2.6.36/arch/sh/kernel/cpu/shmobile/pm.c
3383 --- linux-2.6.36/arch/sh/kernel/cpu/shmobile/pm.c 2010-10-20 16:30:22.000000000 -0400
3384 +++ linux-2.6.36/arch/sh/kernel/cpu/shmobile/pm.c 2010-11-06 18:58:15.000000000 -0400
3385 @@ -141,7 +141,7 @@ static int sh_pm_enter(suspend_state_t s
3386 return 0;
3387 }
3388
3389 -static struct platform_suspend_ops sh_pm_ops = {
3390 +static const struct platform_suspend_ops sh_pm_ops = {
3391 .enter = sh_pm_enter,
3392 .valid = suspend_valid_only_mem,
3393 };
3394 diff -urNp linux-2.6.36/arch/sh/kernel/dma-nommu.c linux-2.6.36/arch/sh/kernel/dma-nommu.c
3395 --- linux-2.6.36/arch/sh/kernel/dma-nommu.c 2010-10-20 16:30:22.000000000 -0400
3396 +++ linux-2.6.36/arch/sh/kernel/dma-nommu.c 2010-11-06 18:58:15.000000000 -0400
3397 @@ -62,7 +62,7 @@ static void nommu_sync_sg(struct device
3398 }
3399 #endif
3400
3401 -struct dma_map_ops nommu_dma_ops = {
3402 +const struct dma_map_ops nommu_dma_ops = {
3403 .alloc_coherent = dma_generic_alloc_coherent,
3404 .free_coherent = dma_generic_free_coherent,
3405 .map_page = nommu_map_page,
3406 diff -urNp linux-2.6.36/arch/sh/kernel/kgdb.c linux-2.6.36/arch/sh/kernel/kgdb.c
3407 --- linux-2.6.36/arch/sh/kernel/kgdb.c 2010-10-20 16:30:22.000000000 -0400
3408 +++ linux-2.6.36/arch/sh/kernel/kgdb.c 2010-11-06 18:58:15.000000000 -0400
3409 @@ -319,7 +319,7 @@ void kgdb_arch_exit(void)
3410 unregister_die_notifier(&kgdb_notifier);
3411 }
3412
3413 -struct kgdb_arch arch_kgdb_ops = {
3414 +const struct kgdb_arch arch_kgdb_ops = {
3415 /* Breakpoint instruction: trapa #0x3c */
3416 #ifdef CONFIG_CPU_LITTLE_ENDIAN
3417 .gdb_bpt_instr = { 0x3c, 0xc3 },
3418 diff -urNp linux-2.6.36/arch/sh/mm/consistent.c linux-2.6.36/arch/sh/mm/consistent.c
3419 --- linux-2.6.36/arch/sh/mm/consistent.c 2010-10-20 16:30:22.000000000 -0400
3420 +++ linux-2.6.36/arch/sh/mm/consistent.c 2010-11-06 18:58:15.000000000 -0400
3421 @@ -22,7 +22,7 @@
3422
3423 #define PREALLOC_DMA_DEBUG_ENTRIES 4096
3424
3425 -struct dma_map_ops *dma_ops;
3426 +const struct dma_map_ops *dma_ops;
3427 EXPORT_SYMBOL(dma_ops);
3428
3429 static int __init dma_init(void)
3430 diff -urNp linux-2.6.36/arch/sh/mm/mmap.c linux-2.6.36/arch/sh/mm/mmap.c
3431 --- linux-2.6.36/arch/sh/mm/mmap.c 2010-10-20 16:30:22.000000000 -0400
3432 +++ linux-2.6.36/arch/sh/mm/mmap.c 2010-11-06 18:58:15.000000000 -0400
3433 @@ -74,8 +74,7 @@ unsigned long arch_get_unmapped_area(str
3434 addr = PAGE_ALIGN(addr);
3435
3436 vma = find_vma(mm, addr);
3437 - if (TASK_SIZE - len >= addr &&
3438 - (!vma || addr + len <= vma->vm_start))
3439 + if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
3440 return addr;
3441 }
3442
3443 @@ -106,7 +105,7 @@ full_search:
3444 }
3445 return -ENOMEM;
3446 }
3447 - if (likely(!vma || addr + len <= vma->vm_start)) {
3448 + if (likely(check_heap_stack_gap(vma, addr, len))) {
3449 /*
3450 * Remember the place where we stopped the search:
3451 */
3452 @@ -157,8 +156,7 @@ arch_get_unmapped_area_topdown(struct fi
3453 addr = PAGE_ALIGN(addr);
3454
3455 vma = find_vma(mm, addr);
3456 - if (TASK_SIZE - len >= addr &&
3457 - (!vma || addr + len <= vma->vm_start))
3458 + if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
3459 return addr;
3460 }
3461
3462 @@ -179,7 +177,7 @@ arch_get_unmapped_area_topdown(struct fi
3463 /* make sure it can fit in the remaining address space */
3464 if (likely(addr > len)) {
3465 vma = find_vma(mm, addr-len);
3466 - if (!vma || addr <= vma->vm_start) {
3467 + if (check_heap_stack_gap(vma, addr - len, len)) {
3468 /* remember the address as a hint for next time */
3469 return (mm->free_area_cache = addr-len);
3470 }
3471 @@ -199,7 +197,7 @@ arch_get_unmapped_area_topdown(struct fi
3472 * return with success:
3473 */
3474 vma = find_vma(mm, addr);
3475 - if (likely(!vma || addr+len <= vma->vm_start)) {
3476 + if (likely(check_heap_stack_gap(vma, addr, len))) {
3477 /* remember the address as a hint for next time */
3478 return (mm->free_area_cache = addr);
3479 }
3480 diff -urNp linux-2.6.36/arch/sparc/include/asm/atomic_64.h linux-2.6.36/arch/sparc/include/asm/atomic_64.h
3481 --- linux-2.6.36/arch/sparc/include/asm/atomic_64.h 2010-10-20 16:30:22.000000000 -0400
3482 +++ linux-2.6.36/arch/sparc/include/asm/atomic_64.h 2010-11-06 18:58:15.000000000 -0400
3483 @@ -14,18 +14,40 @@
3484 #define ATOMIC64_INIT(i) { (i) }
3485
3486 #define atomic_read(v) (*(volatile int *)&(v)->counter)
3487 +static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
3488 +{
3489 + return v->counter;
3490 +}
3491 #define atomic64_read(v) (*(volatile long *)&(v)->counter)
3492 +static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
3493 +{
3494 + return v->counter;
3495 +}
3496
3497 #define atomic_set(v, i) (((v)->counter) = i)
3498 +static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
3499 +{
3500 + v->counter = i;
3501 +}
3502 #define atomic64_set(v, i) (((v)->counter) = i)
3503 +static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
3504 +{
3505 + v->counter = i;
3506 +}
3507
3508 extern void atomic_add(int, atomic_t *);
3509 +extern void atomic_add_unchecked(int, atomic_unchecked_t *);
3510 extern void atomic64_add(long, atomic64_t *);
3511 +extern void atomic64_add_unchecked(long, atomic64_unchecked_t *);
3512 extern void atomic_sub(int, atomic_t *);
3513 +extern void atomic_sub_unchecked(int, atomic_unchecked_t *);
3514 extern void atomic64_sub(long, atomic64_t *);
3515 +extern void atomic64_sub_unchecked(long, atomic64_unchecked_t *);
3516
3517 extern int atomic_add_ret(int, atomic_t *);
3518 +extern int atomic_add_ret_unchecked(int, atomic_unchecked_t *);
3519 extern long atomic64_add_ret(long, atomic64_t *);
3520 +extern long atomic64_add_ret_unchecked(long, atomic64_unchecked_t *);
3521 extern int atomic_sub_ret(int, atomic_t *);
3522 extern long atomic64_sub_ret(long, atomic64_t *);
3523
3524 @@ -33,12 +55,24 @@ extern long atomic64_sub_ret(long, atomi
3525 #define atomic64_dec_return(v) atomic64_sub_ret(1, v)
3526
3527 #define atomic_inc_return(v) atomic_add_ret(1, v)
3528 +static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
3529 +{
3530 + return atomic_add_ret_unchecked(1, v);
3531 +}
3532 #define atomic64_inc_return(v) atomic64_add_ret(1, v)
3533 +static inline long atomic64_inc_return_unchecked(atomic64_unchecked_t *v)
3534 +{
3535 + return atomic64_add_ret_unchecked(1, v);
3536 +}
3537
3538 #define atomic_sub_return(i, v) atomic_sub_ret(i, v)
3539 #define atomic64_sub_return(i, v) atomic64_sub_ret(i, v)
3540
3541 #define atomic_add_return(i, v) atomic_add_ret(i, v)
3542 +static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
3543 +{
3544 + return atomic_add_ret_unchecked(i, v);
3545 +}
3546 #define atomic64_add_return(i, v) atomic64_add_ret(i, v)
3547
3548 /*
3549 @@ -59,10 +93,26 @@ extern long atomic64_sub_ret(long, atomi
3550 #define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0)
3551
3552 #define atomic_inc(v) atomic_add(1, v)
3553 +static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
3554 +{
3555 + atomic_add_unchecked(1, v);
3556 +}
3557 #define atomic64_inc(v) atomic64_add(1, v)
3558 +static inline void atomic64_inc_unchecked(atomic64_unchecked_t *v)
3559 +{
3560 + atomic64_add_unchecked(1, v);
3561 +}
3562
3563 #define atomic_dec(v) atomic_sub(1, v)
3564 +static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
3565 +{
3566 + atomic_sub_unchecked(1, v);
3567 +}
3568 #define atomic64_dec(v) atomic64_sub(1, v)
3569 +static inline void atomic64_dec_unchecked(atomic64_unchecked_t *v)
3570 +{
3571 + atomic64_sub_unchecked(1, v);
3572 +}
3573
3574 #define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
3575 #define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
3576 @@ -72,17 +122,28 @@ extern long atomic64_sub_ret(long, atomi
3577
3578 static inline int atomic_add_unless(atomic_t *v, int a, int u)
3579 {
3580 - int c, old;
3581 + int c, old, new;
3582 c = atomic_read(v);
3583 for (;;) {
3584 - if (unlikely(c == (u)))
3585 + if (unlikely(c == u))
3586 break;
3587 - old = atomic_cmpxchg((v), c, c + (a));
3588 +
3589 + asm volatile("addcc %2, %0, %0\n"
3590 +
3591 +#ifdef CONFIG_PAX_REFCOUNT
3592 + "tvs %%icc, 6\n"
3593 +#endif
3594 +
3595 + : "=r" (new)
3596 + : "0" (c), "ir" (a)
3597 + : "cc");
3598 +
3599 + old = atomic_cmpxchg(v, c, new);
3600 if (likely(old == c))
3601 break;
3602 c = old;
3603 }
3604 - return c != (u);
3605 + return c != u;
3606 }
3607
3608 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
3609 @@ -93,17 +154,28 @@ static inline int atomic_add_unless(atom
3610
3611 static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
3612 {
3613 - long c, old;
3614 + long c, old, new;
3615 c = atomic64_read(v);
3616 for (;;) {
3617 - if (unlikely(c == (u)))
3618 + if (unlikely(c == u))
3619 break;
3620 - old = atomic64_cmpxchg((v), c, c + (a));
3621 +
3622 + asm volatile("addcc %2, %0, %0\n"
3623 +
3624 +#ifdef CONFIG_PAX_REFCOUNT
3625 + "tvs %%xcc, 6\n"
3626 +#endif
3627 +
3628 + : "=r" (new)
3629 + : "0" (c), "ir" (a)
3630 + : "cc");
3631 +
3632 + old = atomic64_cmpxchg(v, c, new);
3633 if (likely(old == c))
3634 break;
3635 c = old;
3636 }
3637 - return c != (u);
3638 + return c != u;
3639 }
3640
3641 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
3642 diff -urNp linux-2.6.36/arch/sparc/include/asm/dma-mapping.h linux-2.6.36/arch/sparc/include/asm/dma-mapping.h
3643 --- linux-2.6.36/arch/sparc/include/asm/dma-mapping.h 2010-10-20 16:30:22.000000000 -0400
3644 +++ linux-2.6.36/arch/sparc/include/asm/dma-mapping.h 2010-11-06 18:58:15.000000000 -0400
3645 @@ -12,10 +12,10 @@ extern int dma_supported(struct device *
3646 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
3647 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
3648
3649 -extern struct dma_map_ops *dma_ops, pci32_dma_ops;
3650 +extern const struct dma_map_ops *dma_ops, pci32_dma_ops;
3651 extern struct bus_type pci_bus_type;
3652
3653 -static inline struct dma_map_ops *get_dma_ops(struct device *dev)
3654 +static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
3655 {
3656 #if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
3657 if (dev->bus == &pci_bus_type)
3658 @@ -29,7 +29,7 @@ static inline struct dma_map_ops *get_dm
3659 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
3660 dma_addr_t *dma_handle, gfp_t flag)
3661 {
3662 - struct dma_map_ops *ops = get_dma_ops(dev);
3663 + const struct dma_map_ops *ops = get_dma_ops(dev);
3664 void *cpu_addr;
3665
3666 cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag);
3667 @@ -40,7 +40,7 @@ static inline void *dma_alloc_coherent(s
3668 static inline void dma_free_coherent(struct device *dev, size_t size,
3669 void *cpu_addr, dma_addr_t dma_handle)
3670 {
3671 - struct dma_map_ops *ops = get_dma_ops(dev);
3672 + const struct dma_map_ops *ops = get_dma_ops(dev);
3673
3674 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
3675 ops->free_coherent(dev, size, cpu_addr, dma_handle);
3676 diff -urNp linux-2.6.36/arch/sparc/include/asm/elf_32.h linux-2.6.36/arch/sparc/include/asm/elf_32.h
3677 --- linux-2.6.36/arch/sparc/include/asm/elf_32.h 2010-10-20 16:30:22.000000000 -0400
3678 +++ linux-2.6.36/arch/sparc/include/asm/elf_32.h 2010-11-06 18:58:15.000000000 -0400
3679 @@ -114,6 +114,13 @@ typedef struct {
3680
3681 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
3682
3683 +#ifdef CONFIG_PAX_ASLR
3684 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
3685 +
3686 +#define PAX_DELTA_MMAP_LEN 16
3687 +#define PAX_DELTA_STACK_LEN 16
3688 +#endif
3689 +
3690 /* This yields a mask that user programs can use to figure out what
3691 instruction set this cpu supports. This can NOT be done in userspace
3692 on Sparc. */
3693 diff -urNp linux-2.6.36/arch/sparc/include/asm/elf_64.h linux-2.6.36/arch/sparc/include/asm/elf_64.h
3694 --- linux-2.6.36/arch/sparc/include/asm/elf_64.h 2010-10-20 16:30:22.000000000 -0400
3695 +++ linux-2.6.36/arch/sparc/include/asm/elf_64.h 2010-11-06 18:58:15.000000000 -0400
3696 @@ -162,6 +162,12 @@ typedef struct {
3697 #define ELF_ET_DYN_BASE 0x0000010000000000UL
3698 #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
3699
3700 +#ifdef CONFIG_PAX_ASLR
3701 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
3702 +
3703 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28)
3704 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29)
3705 +#endif
3706
3707 /* This yields a mask that user programs can use to figure out what
3708 instruction set this cpu supports. */
3709 diff -urNp linux-2.6.36/arch/sparc/include/asm/pgtable_32.h linux-2.6.36/arch/sparc/include/asm/pgtable_32.h
3710 --- linux-2.6.36/arch/sparc/include/asm/pgtable_32.h 2010-10-20 16:30:22.000000000 -0400
3711 +++ linux-2.6.36/arch/sparc/include/asm/pgtable_32.h 2010-11-06 18:58:15.000000000 -0400
3712 @@ -43,6 +43,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
3713 BTFIXUPDEF_INT(page_none)
3714 BTFIXUPDEF_INT(page_copy)
3715 BTFIXUPDEF_INT(page_readonly)
3716 +
3717 +#ifdef CONFIG_PAX_PAGEEXEC
3718 +BTFIXUPDEF_INT(page_shared_noexec)
3719 +BTFIXUPDEF_INT(page_copy_noexec)
3720 +BTFIXUPDEF_INT(page_readonly_noexec)
3721 +#endif
3722 +
3723 BTFIXUPDEF_INT(page_kernel)
3724
3725 #define PMD_SHIFT SUN4C_PMD_SHIFT
3726 @@ -64,6 +71,16 @@ extern pgprot_t PAGE_SHARED;
3727 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
3728 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
3729
3730 +#ifdef CONFIG_PAX_PAGEEXEC
3731 +extern pgprot_t PAGE_SHARED_NOEXEC;
3732 +# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
3733 +# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
3734 +#else
3735 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
3736 +# define PAGE_COPY_NOEXEC PAGE_COPY
3737 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
3738 +#endif
3739 +
3740 extern unsigned long page_kernel;
3741
3742 #ifdef MODULE
3743 diff -urNp linux-2.6.36/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.36/arch/sparc/include/asm/pgtsrmmu.h
3744 --- linux-2.6.36/arch/sparc/include/asm/pgtsrmmu.h 2010-10-20 16:30:22.000000000 -0400
3745 +++ linux-2.6.36/arch/sparc/include/asm/pgtsrmmu.h 2010-11-06 18:58:15.000000000 -0400
3746 @@ -115,6 +115,13 @@
3747 SRMMU_EXEC | SRMMU_REF)
3748 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
3749 SRMMU_EXEC | SRMMU_REF)
3750 +
3751 +#ifdef CONFIG_PAX_PAGEEXEC
3752 +#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
3753 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
3754 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
3755 +#endif
3756 +
3757 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
3758 SRMMU_DIRTY | SRMMU_REF)
3759
3760 diff -urNp linux-2.6.36/arch/sparc/include/asm/spinlock_64.h linux-2.6.36/arch/sparc/include/asm/spinlock_64.h
3761 --- linux-2.6.36/arch/sparc/include/asm/spinlock_64.h 2010-10-20 16:30:22.000000000 -0400
3762 +++ linux-2.6.36/arch/sparc/include/asm/spinlock_64.h 2010-11-06 18:58:15.000000000 -0400
3763 @@ -99,7 +99,12 @@ static void inline arch_read_lock(arch_r
3764 __asm__ __volatile__ (
3765 "1: ldsw [%2], %0\n"
3766 " brlz,pn %0, 2f\n"
3767 -"4: add %0, 1, %1\n"
3768 +"4: addcc %0, 1, %1\n"
3769 +
3770 +#ifdef CONFIG_PAX_REFCOUNT
3771 +" tvs %%icc, 6\n"
3772 +#endif
3773 +
3774 " cas [%2], %0, %1\n"
3775 " cmp %0, %1\n"
3776 " bne,pn %%icc, 1b\n"
3777 @@ -112,7 +117,7 @@ static void inline arch_read_lock(arch_r
3778 " .previous"
3779 : "=&r" (tmp1), "=&r" (tmp2)
3780 : "r" (lock)
3781 - : "memory");
3782 + : "memory", "cc");
3783 }
3784
3785 static int inline arch_read_trylock(arch_rwlock_t *lock)
3786 @@ -123,7 +128,12 @@ static int inline arch_read_trylock(arch
3787 "1: ldsw [%2], %0\n"
3788 " brlz,a,pn %0, 2f\n"
3789 " mov 0, %0\n"
3790 -" add %0, 1, %1\n"
3791 +" addcc %0, 1, %1\n"
3792 +
3793 +#ifdef CONFIG_PAX_REFCOUNT
3794 +" tvs %%icc, 6\n"
3795 +#endif
3796 +
3797 " cas [%2], %0, %1\n"
3798 " cmp %0, %1\n"
3799 " bne,pn %%icc, 1b\n"
3800 @@ -142,7 +152,12 @@ static void inline arch_read_unlock(arch
3801
3802 __asm__ __volatile__(
3803 "1: lduw [%2], %0\n"
3804 -" sub %0, 1, %1\n"
3805 +" subcc %0, 1, %1\n"
3806 +
3807 +#ifdef CONFIG_PAX_REFCOUNT
3808 +" tvs %%icc, 6\n"
3809 +#endif
3810 +
3811 " cas [%2], %0, %1\n"
3812 " cmp %0, %1\n"
3813 " bne,pn %%xcc, 1b\n"
3814 diff -urNp linux-2.6.36/arch/sparc/include/asm/uaccess_32.h linux-2.6.36/arch/sparc/include/asm/uaccess_32.h
3815 --- linux-2.6.36/arch/sparc/include/asm/uaccess_32.h 2010-10-20 16:30:22.000000000 -0400
3816 +++ linux-2.6.36/arch/sparc/include/asm/uaccess_32.h 2010-11-06 18:58:15.000000000 -0400
3817 @@ -249,27 +249,46 @@ extern unsigned long __copy_user(void __
3818
3819 static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
3820 {
3821 - if (n && __access_ok((unsigned long) to, n))
3822 + if ((long)n < 0)
3823 + return n;
3824 +
3825 + if (n && __access_ok((unsigned long) to, n)) {
3826 + if (!__builtin_constant_p(n))
3827 + check_object_size(from, n, true);
3828 return __copy_user(to, (__force void __user *) from, n);
3829 - else
3830 + } else
3831 return n;
3832 }
3833
3834 static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
3835 {
3836 + if ((long)n < 0)
3837 + return n;
3838 +
3839 + if (!__builtin_constant_p(n))
3840 + check_object_size(from, n, true);
3841 +
3842 return __copy_user(to, (__force void __user *) from, n);
3843 }
3844
3845 static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
3846 {
3847 - if (n && __access_ok((unsigned long) from, n))
3848 + if ((long)n < 0)
3849 + return n;
3850 +
3851 + if (n && __access_ok((unsigned long) from, n)) {
3852 + if (!__builtin_constant_p(n))
3853 + check_object_size(to, n, false);
3854 return __copy_user((__force void __user *) to, from, n);
3855 - else
3856 + } else
3857 return n;
3858 }
3859
3860 static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
3861 {
3862 + if ((long)n < 0)
3863 + return n;
3864 +
3865 return __copy_user((__force void __user *) to, from, n);
3866 }
3867
3868 diff -urNp linux-2.6.36/arch/sparc/include/asm/uaccess_64.h linux-2.6.36/arch/sparc/include/asm/uaccess_64.h
3869 --- linux-2.6.36/arch/sparc/include/asm/uaccess_64.h 2010-10-20 16:30:22.000000000 -0400
3870 +++ linux-2.6.36/arch/sparc/include/asm/uaccess_64.h 2010-11-06 18:58:15.000000000 -0400
3871 @@ -10,6 +10,7 @@
3872 #include <linux/compiler.h>
3873 #include <linux/string.h>
3874 #include <linux/thread_info.h>
3875 +#include <linux/kernel.h>
3876 #include <asm/asi.h>
3877 #include <asm/system.h>
3878 #include <asm/spitfire.h>
3879 @@ -213,8 +214,15 @@ extern unsigned long copy_from_user_fixu
3880 static inline unsigned long __must_check
3881 copy_from_user(void *to, const void __user *from, unsigned long size)
3882 {
3883 - unsigned long ret = ___copy_from_user(to, from, size);
3884 + unsigned long ret;
3885
3886 + if ((long)size < 0 || size > INT_MAX)
3887 + return size;
3888 +
3889 + if (!__builtin_constant_p(size))
3890 + check_object_size(to, size, false);
3891 +
3892 + ret = ___copy_from_user(to, from, size);
3893 if (unlikely(ret))
3894 ret = copy_from_user_fixup(to, from, size);
3895
3896 @@ -230,8 +238,15 @@ extern unsigned long copy_to_user_fixup(
3897 static inline unsigned long __must_check
3898 copy_to_user(void __user *to, const void *from, unsigned long size)
3899 {
3900 - unsigned long ret = ___copy_to_user(to, from, size);
3901 + unsigned long ret;
3902 +
3903 + if ((long)size < 0 || size > INT_MAX)
3904 + return size;
3905 +
3906 + if (!__builtin_constant_p(size))
3907 + check_object_size(from, size, true);
3908
3909 + ret = ___copy_to_user(to, from, size);
3910 if (unlikely(ret))
3911 ret = copy_to_user_fixup(to, from, size);
3912 return ret;
3913 diff -urNp linux-2.6.36/arch/sparc/include/asm/uaccess.h linux-2.6.36/arch/sparc/include/asm/uaccess.h
3914 --- linux-2.6.36/arch/sparc/include/asm/uaccess.h 2010-10-20 16:30:22.000000000 -0400
3915 +++ linux-2.6.36/arch/sparc/include/asm/uaccess.h 2010-11-06 18:58:15.000000000 -0400
3916 @@ -1,5 +1,13 @@
3917 #ifndef ___ASM_SPARC_UACCESS_H
3918 #define ___ASM_SPARC_UACCESS_H
3919 +
3920 +#ifdef __KERNEL__
3921 +#ifndef __ASSEMBLY__
3922 +#include <linux/types.h>
3923 +extern void check_object_size(const void *ptr, unsigned long n, bool to);
3924 +#endif
3925 +#endif
3926 +
3927 #if defined(__sparc__) && defined(__arch64__)
3928 #include <asm/uaccess_64.h>
3929 #else
3930 diff -urNp linux-2.6.36/arch/sparc/kernel/iommu.c linux-2.6.36/arch/sparc/kernel/iommu.c
3931 --- linux-2.6.36/arch/sparc/kernel/iommu.c 2010-10-20 16:30:22.000000000 -0400
3932 +++ linux-2.6.36/arch/sparc/kernel/iommu.c 2010-11-06 18:58:15.000000000 -0400
3933 @@ -828,7 +828,7 @@ static void dma_4u_sync_sg_for_cpu(struc
3934 spin_unlock_irqrestore(&iommu->lock, flags);
3935 }
3936
3937 -static struct dma_map_ops sun4u_dma_ops = {
3938 +static const struct dma_map_ops sun4u_dma_ops = {
3939 .alloc_coherent = dma_4u_alloc_coherent,
3940 .free_coherent = dma_4u_free_coherent,
3941 .map_page = dma_4u_map_page,
3942 @@ -839,7 +839,7 @@ static struct dma_map_ops sun4u_dma_ops
3943 .sync_sg_for_cpu = dma_4u_sync_sg_for_cpu,
3944 };
3945
3946 -struct dma_map_ops *dma_ops = &sun4u_dma_ops;
3947 +const struct dma_map_ops *dma_ops = &sun4u_dma_ops;
3948 EXPORT_SYMBOL(dma_ops);
3949
3950 extern int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask);
3951 diff -urNp linux-2.6.36/arch/sparc/kernel/ioport.c linux-2.6.36/arch/sparc/kernel/ioport.c
3952 --- linux-2.6.36/arch/sparc/kernel/ioport.c 2010-10-20 16:30:22.000000000 -0400
3953 +++ linux-2.6.36/arch/sparc/kernel/ioport.c 2010-11-06 18:58:15.000000000 -0400
3954 @@ -397,7 +397,7 @@ static void sbus_sync_sg_for_device(stru
3955 BUG();
3956 }
3957
3958 -struct dma_map_ops sbus_dma_ops = {
3959 +const struct dma_map_ops sbus_dma_ops = {
3960 .alloc_coherent = sbus_alloc_coherent,
3961 .free_coherent = sbus_free_coherent,
3962 .map_page = sbus_map_page,
3963 @@ -408,7 +408,7 @@ struct dma_map_ops sbus_dma_ops = {
3964 .sync_sg_for_device = sbus_sync_sg_for_device,
3965 };
3966
3967 -struct dma_map_ops *dma_ops = &sbus_dma_ops;
3968 +const struct dma_map_ops *dma_ops = &sbus_dma_ops;
3969 EXPORT_SYMBOL(dma_ops);
3970
3971 static int __init sparc_register_ioport(void)
3972 @@ -645,7 +645,7 @@ static void pci32_sync_sg_for_device(str
3973 }
3974 }
3975
3976 -struct dma_map_ops pci32_dma_ops = {
3977 +const struct dma_map_ops pci32_dma_ops = {
3978 .alloc_coherent = pci32_alloc_coherent,
3979 .free_coherent = pci32_free_coherent,
3980 .map_page = pci32_map_page,
3981 diff -urNp linux-2.6.36/arch/sparc/kernel/kgdb_32.c linux-2.6.36/arch/sparc/kernel/kgdb_32.c
3982 --- linux-2.6.36/arch/sparc/kernel/kgdb_32.c 2010-10-20 16:30:22.000000000 -0400
3983 +++ linux-2.6.36/arch/sparc/kernel/kgdb_32.c 2010-11-06 18:58:15.000000000 -0400
3984 @@ -164,7 +164,7 @@ void kgdb_arch_set_pc(struct pt_regs *re
3985 regs->npc = regs->pc + 4;
3986 }
3987
3988 -struct kgdb_arch arch_kgdb_ops = {
3989 +const struct kgdb_arch arch_kgdb_ops = {
3990 /* Breakpoint instruction: ta 0x7d */
3991 .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x7d },
3992 };
3993 diff -urNp linux-2.6.36/arch/sparc/kernel/kgdb_64.c linux-2.6.36/arch/sparc/kernel/kgdb_64.c
3994 --- linux-2.6.36/arch/sparc/kernel/kgdb_64.c 2010-10-20 16:30:22.000000000 -0400
3995 +++ linux-2.6.36/arch/sparc/kernel/kgdb_64.c 2010-11-06 18:58:15.000000000 -0400
3996 @@ -187,7 +187,7 @@ void kgdb_arch_set_pc(struct pt_regs *re
3997 regs->tnpc = regs->tpc + 4;
3998 }
3999
4000 -struct kgdb_arch arch_kgdb_ops = {
4001 +const struct kgdb_arch arch_kgdb_ops = {
4002 /* Breakpoint instruction: ta 0x72 */
4003 .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x72 },
4004 };
4005 diff -urNp linux-2.6.36/arch/sparc/kernel/Makefile linux-2.6.36/arch/sparc/kernel/Makefile
4006 --- linux-2.6.36/arch/sparc/kernel/Makefile 2010-10-20 16:30:22.000000000 -0400
4007 +++ linux-2.6.36/arch/sparc/kernel/Makefile 2010-11-06 18:58:15.000000000 -0400
4008 @@ -3,7 +3,7 @@
4009 #
4010
4011 asflags-y := -ansi
4012 -ccflags-y := -Werror
4013 +#ccflags-y := -Werror
4014
4015 extra-y := head_$(BITS).o
4016 extra-y += init_task.o
4017 diff -urNp linux-2.6.36/arch/sparc/kernel/pci_sun4v.c linux-2.6.36/arch/sparc/kernel/pci_sun4v.c
4018 --- linux-2.6.36/arch/sparc/kernel/pci_sun4v.c 2010-10-20 16:30:22.000000000 -0400
4019 +++ linux-2.6.36/arch/sparc/kernel/pci_sun4v.c 2010-11-06 18:58:15.000000000 -0400
4020 @@ -525,7 +525,7 @@ static void dma_4v_unmap_sg(struct devic
4021 spin_unlock_irqrestore(&iommu->lock, flags);
4022 }
4023
4024 -static struct dma_map_ops sun4v_dma_ops = {
4025 +static const struct dma_map_ops sun4v_dma_ops = {
4026 .alloc_coherent = dma_4v_alloc_coherent,
4027 .free_coherent = dma_4v_free_coherent,
4028 .map_page = dma_4v_map_page,
4029 diff -urNp linux-2.6.36/arch/sparc/kernel/sys_sparc_32.c linux-2.6.36/arch/sparc/kernel/sys_sparc_32.c
4030 --- linux-2.6.36/arch/sparc/kernel/sys_sparc_32.c 2010-10-20 16:30:22.000000000 -0400
4031 +++ linux-2.6.36/arch/sparc/kernel/sys_sparc_32.c 2010-11-06 18:58:15.000000000 -0400
4032 @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
4033 if (ARCH_SUN4C && len > 0x20000000)
4034 return -ENOMEM;
4035 if (!addr)
4036 - addr = TASK_UNMAPPED_BASE;
4037 + addr = current->mm->mmap_base;
4038
4039 if (flags & MAP_SHARED)
4040 addr = COLOUR_ALIGN(addr);
4041 @@ -72,7 +72,7 @@ unsigned long arch_get_unmapped_area(str
4042 }
4043 if (TASK_SIZE - PAGE_SIZE - len < addr)
4044 return -ENOMEM;
4045 - if (!vmm || addr + len <= vmm->vm_start)
4046 + if (check_heap_stack_gap(vmm, addr, len))
4047 return addr;
4048 addr = vmm->vm_end;
4049 if (flags & MAP_SHARED)
4050 diff -urNp linux-2.6.36/arch/sparc/kernel/sys_sparc_64.c linux-2.6.36/arch/sparc/kernel/sys_sparc_64.c
4051 --- linux-2.6.36/arch/sparc/kernel/sys_sparc_64.c 2010-10-20 16:30:22.000000000 -0400
4052 +++ linux-2.6.36/arch/sparc/kernel/sys_sparc_64.c 2010-11-06 18:58:15.000000000 -0400
4053 @@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
4054 /* We do not accept a shared mapping if it would violate
4055 * cache aliasing constraints.
4056 */
4057 - if ((flags & MAP_SHARED) &&
4058 + if ((filp || (flags & MAP_SHARED)) &&
4059 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
4060 return -EINVAL;
4061 return addr;
4062 @@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
4063 if (filp || (flags & MAP_SHARED))
4064 do_color_align = 1;
4065
4066 +#ifdef CONFIG_PAX_RANDMMAP
4067 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
4068 +#endif
4069 +
4070 if (addr) {
4071 if (do_color_align)
4072 addr = COLOUR_ALIGN(addr, pgoff);
4073 @@ -146,15 +150,14 @@ unsigned long arch_get_unmapped_area(str
4074 addr = PAGE_ALIGN(addr);
4075
4076 vma = find_vma(mm, addr);
4077 - if (task_size - len >= addr &&
4078 - (!vma || addr + len <= vma->vm_start))
4079 + if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
4080 return addr;
4081 }
4082
4083 if (len > mm->cached_hole_size) {
4084 - start_addr = addr = mm->free_area_cache;
4085 + start_addr = addr = mm->free_area_cache;
4086 } else {
4087 - start_addr = addr = TASK_UNMAPPED_BASE;
4088 + start_addr = addr = mm->mmap_base;
4089 mm->cached_hole_size = 0;
4090 }
4091
4092 @@ -174,14 +177,14 @@ full_search:
4093 vma = find_vma(mm, VA_EXCLUDE_END);
4094 }
4095 if (unlikely(task_size < addr)) {
4096 - if (start_addr != TASK_UNMAPPED_BASE) {
4097 - start_addr = addr = TASK_UNMAPPED_BASE;
4098 + if (start_addr != mm->mmap_base) {
4099 + start_addr = addr = mm->mmap_base;
4100 mm->cached_hole_size = 0;
4101 goto full_search;
4102 }
4103 return -ENOMEM;
4104 }
4105 - if (likely(!vma || addr + len <= vma->vm_start)) {
4106 + if (likely(check_heap_stack_gap(vma, addr, len))) {
4107 /*
4108 * Remember the place where we stopped the search:
4109 */
4110 @@ -215,7 +218,7 @@ arch_get_unmapped_area_topdown(struct fi
4111 /* We do not accept a shared mapping if it would violate
4112 * cache aliasing constraints.
4113 */
4114 - if ((flags & MAP_SHARED) &&
4115 + if ((filp || (flags & MAP_SHARED)) &&
4116 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
4117 return -EINVAL;
4118 return addr;
4119 @@ -236,8 +239,7 @@ arch_get_unmapped_area_topdown(struct fi
4120 addr = PAGE_ALIGN(addr);
4121
4122 vma = find_vma(mm, addr);
4123 - if (task_size - len >= addr &&
4124 - (!vma || addr + len <= vma->vm_start))
4125 + if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
4126 return addr;
4127 }
4128
4129 @@ -258,7 +260,7 @@ arch_get_unmapped_area_topdown(struct fi
4130 /* make sure it can fit in the remaining address space */
4131 if (likely(addr > len)) {
4132 vma = find_vma(mm, addr-len);
4133 - if (!vma || addr <= vma->vm_start) {
4134 + if (check_heap_stack_gap(vma, addr - len, len)) {
4135 /* remember the address as a hint for next time */
4136 return (mm->free_area_cache = addr-len);
4137 }
4138 @@ -278,7 +280,7 @@ arch_get_unmapped_area_topdown(struct fi
4139 * return with success:
4140 */
4141 vma = find_vma(mm, addr);
4142 - if (likely(!vma || addr+len <= vma->vm_start)) {
4143 + if (likely(check_heap_stack_gap(vma, addr, len))) {
4144 /* remember the address as a hint for next time */
4145 return (mm->free_area_cache = addr);
4146 }
4147 @@ -385,6 +387,12 @@ void arch_pick_mmap_layout(struct mm_str
4148 gap == RLIM_INFINITY ||
4149 sysctl_legacy_va_layout) {
4150 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
4151 +
4152 +#ifdef CONFIG_PAX_RANDMMAP
4153 + if (mm->pax_flags & MF_PAX_RANDMMAP)
4154 + mm->mmap_base += mm->delta_mmap;
4155 +#endif
4156 +
4157 mm->get_unmapped_area = arch_get_unmapped_area;
4158 mm->unmap_area = arch_unmap_area;
4159 } else {
4160 @@ -397,6 +405,12 @@ void arch_pick_mmap_layout(struct mm_str
4161 gap = (task_size / 6 * 5);
4162
4163 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
4164 +
4165 +#ifdef CONFIG_PAX_RANDMMAP
4166 + if (mm->pax_flags & MF_PAX_RANDMMAP)
4167 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
4168 +#endif
4169 +
4170 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4171 mm->unmap_area = arch_unmap_area_topdown;
4172 }
4173 diff -urNp linux-2.6.36/arch/sparc/kernel/traps_64.c linux-2.6.36/arch/sparc/kernel/traps_64.c
4174 --- linux-2.6.36/arch/sparc/kernel/traps_64.c 2010-10-20 16:30:22.000000000 -0400
4175 +++ linux-2.6.36/arch/sparc/kernel/traps_64.c 2010-11-06 18:58:15.000000000 -0400
4176 @@ -95,6 +95,12 @@ void bad_trap(struct pt_regs *regs, long
4177
4178 lvl -= 0x100;
4179 if (regs->tstate & TSTATE_PRIV) {
4180 +
4181 +#ifdef CONFIG_PAX_REFCOUNT
4182 + if (lvl == 6)
4183 + pax_report_refcount_overflow(regs);
4184 +#endif
4185 +
4186 sprintf(buffer, "Kernel bad sw trap %lx", lvl);
4187 die_if_kernel(buffer, regs);
4188 }
4189 @@ -113,11 +119,16 @@ void bad_trap(struct pt_regs *regs, long
4190 void bad_trap_tl1(struct pt_regs *regs, long lvl)
4191 {
4192 char buffer[32];
4193 -
4194 +
4195 if (notify_die(DIE_TRAP_TL1, "bad trap tl1", regs,
4196 0, lvl, SIGTRAP) == NOTIFY_STOP)
4197 return;
4198
4199 +#ifdef CONFIG_PAX_REFCOUNT
4200 + if (lvl == 6)
4201 + pax_report_refcount_overflow(regs);
4202 +#endif
4203 +
4204 dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
4205
4206 sprintf (buffer, "Bad trap %lx at tl>0", lvl);
4207 diff -urNp linux-2.6.36/arch/sparc/lib/atomic_64.S linux-2.6.36/arch/sparc/lib/atomic_64.S
4208 --- linux-2.6.36/arch/sparc/lib/atomic_64.S 2010-10-20 16:30:22.000000000 -0400
4209 +++ linux-2.6.36/arch/sparc/lib/atomic_64.S 2010-11-06 18:58:15.000000000 -0400
4210 @@ -18,7 +18,12 @@
4211 atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
4212 BACKOFF_SETUP(%o2)
4213 1: lduw [%o1], %g1
4214 - add %g1, %o0, %g7
4215 + addcc %g1, %o0, %g7
4216 +
4217 +#ifdef CONFIG_PAX_REFCOUNT
4218 + tvs %icc, 6
4219 +#endif
4220 +
4221 cas [%o1], %g1, %g7
4222 cmp %g1, %g7
4223 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
4224 @@ -28,12 +33,32 @@ atomic_add: /* %o0 = increment, %o1 = at
4225 2: BACKOFF_SPIN(%o2, %o3, 1b)
4226 .size atomic_add, .-atomic_add
4227
4228 + .globl atomic_add_unchecked
4229 + .type atomic_add_unchecked,#function
4230 +atomic_add_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
4231 + BACKOFF_SETUP(%o2)
4232 +1: lduw [%o1], %g1
4233 + add %g1, %o0, %g7
4234 + cas [%o1], %g1, %g7
4235 + cmp %g1, %g7
4236 + bne,pn %icc, 2f
4237 + nop
4238 + retl
4239 + nop
4240 +2: BACKOFF_SPIN(%o2, %o3, 1b)
4241 + .size atomic_add_unchecked, .-atomic_add_unchecked
4242 +
4243 .globl atomic_sub
4244 .type atomic_sub,#function
4245 atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
4246 BACKOFF_SETUP(%o2)
4247 1: lduw [%o1], %g1
4248 - sub %g1, %o0, %g7
4249 + subcc %g1, %o0, %g7
4250 +
4251 +#ifdef CONFIG_PAX_REFCOUNT
4252 + tvs %icc, 6
4253 +#endif
4254 +
4255 cas [%o1], %g1, %g7
4256 cmp %g1, %g7
4257 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
4258 @@ -43,12 +68,32 @@ atomic_sub: /* %o0 = decrement, %o1 = at
4259 2: BACKOFF_SPIN(%o2, %o3, 1b)
4260 .size atomic_sub, .-atomic_sub
4261
4262 + .globl atomic_sub_unchecked
4263 + .type atomic_sub_unchecked,#function
4264 +atomic_sub_unchecked: /* %o0 = decrement, %o1 = atomic_ptr */
4265 + BACKOFF_SETUP(%o2)
4266 +1: lduw [%o1], %g1
4267 + sub %g1, %o0, %g7
4268 + cas [%o1], %g1, %g7
4269 + cmp %g1, %g7
4270 + bne,pn %icc, 2f
4271 + nop
4272 + retl
4273 + nop
4274 +2: BACKOFF_SPIN(%o2, %o3, 1b)
4275 + .size atomic_sub_unchecked, .-atomic_sub_unchecked
4276 +
4277 .globl atomic_add_ret
4278 .type atomic_add_ret,#function
4279 atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
4280 BACKOFF_SETUP(%o2)
4281 1: lduw [%o1], %g1
4282 - add %g1, %o0, %g7
4283 + addcc %g1, %o0, %g7
4284 +
4285 +#ifdef CONFIG_PAX_REFCOUNT
4286 + tvs %icc, 6
4287 +#endif
4288 +
4289 cas [%o1], %g1, %g7
4290 cmp %g1, %g7
4291 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
4292 @@ -58,12 +103,33 @@ atomic_add_ret: /* %o0 = increment, %o1
4293 2: BACKOFF_SPIN(%o2, %o3, 1b)
4294 .size atomic_add_ret, .-atomic_add_ret
4295
4296 + .globl atomic_add_ret_unchecked
4297 + .type atomic_add_ret_unchecked,#function
4298 +atomic_add_ret_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
4299 + BACKOFF_SETUP(%o2)
4300 +1: lduw [%o1], %g1
4301 + addcc %g1, %o0, %g7
4302 + cas [%o1], %g1, %g7
4303 + cmp %g1, %g7
4304 + bne,pn %icc, 2f
4305 + add %g7, %o0, %g7
4306 + sra %g7, 0, %o0
4307 + retl
4308 + nop
4309 +2: BACKOFF_SPIN(%o2, %o3, 1b)
4310 + .size atomic_add_ret_unchecked, .-atomic_add_ret_unchecked
4311 +
4312 .globl atomic_sub_ret
4313 .type atomic_sub_ret,#function
4314 atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
4315 BACKOFF_SETUP(%o2)
4316 1: lduw [%o1], %g1
4317 - sub %g1, %o0, %g7
4318 + subcc %g1, %o0, %g7
4319 +
4320 +#ifdef CONFIG_PAX_REFCOUNT
4321 + tvs %icc, 6
4322 +#endif
4323 +
4324 cas [%o1], %g1, %g7
4325 cmp %g1, %g7
4326 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
4327 @@ -78,7 +144,12 @@ atomic_sub_ret: /* %o0 = decrement, %o1
4328 atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
4329 BACKOFF_SETUP(%o2)
4330 1: ldx [%o1], %g1
4331 - add %g1, %o0, %g7
4332 + addcc %g1, %o0, %g7
4333 +
4334 +#ifdef CONFIG_PAX_REFCOUNT
4335 + tvs %xcc, 6
4336 +#endif
4337 +
4338 casx [%o1], %g1, %g7
4339 cmp %g1, %g7
4340 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
4341 @@ -88,12 +159,32 @@ atomic64_add: /* %o0 = increment, %o1 =
4342 2: BACKOFF_SPIN(%o2, %o3, 1b)
4343 .size atomic64_add, .-atomic64_add
4344
4345 + .globl atomic64_add_unchecked
4346 + .type atomic64_add_unchecked,#function
4347 +atomic64_add_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
4348 + BACKOFF_SETUP(%o2)
4349 +1: ldx [%o1], %g1
4350 + addcc %g1, %o0, %g7
4351 + casx [%o1], %g1, %g7
4352 + cmp %g1, %g7
4353 + bne,pn %xcc, 2f
4354 + nop
4355 + retl
4356 + nop
4357 +2: BACKOFF_SPIN(%o2, %o3, 1b)
4358 + .size atomic64_add_unchecked, .-atomic64_add_unchecked
4359 +
4360 .globl atomic64_sub
4361 .type atomic64_sub,#function
4362 atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
4363 BACKOFF_SETUP(%o2)
4364 1: ldx [%o1], %g1
4365 - sub %g1, %o0, %g7
4366 + subcc %g1, %o0, %g7
4367 +
4368 +#ifdef CONFIG_PAX_REFCOUNT
4369 + tvs %xcc, 6
4370 +#endif
4371 +
4372 casx [%o1], %g1, %g7
4373 cmp %g1, %g7
4374 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
4375 @@ -103,12 +194,32 @@ atomic64_sub: /* %o0 = decrement, %o1 =
4376 2: BACKOFF_SPIN(%o2, %o3, 1b)
4377 .size atomic64_sub, .-atomic64_sub
4378
4379 + .globl atomic64_sub_unchecked
4380 + .type atomic64_sub_unchecked,#function
4381 +atomic64_sub_unchecked: /* %o0 = decrement, %o1 = atomic_ptr */
4382 + BACKOFF_SETUP(%o2)
4383 +1: ldx [%o1], %g1
4384 + subcc %g1, %o0, %g7
4385 + casx [%o1], %g1, %g7
4386 + cmp %g1, %g7
4387 + bne,pn %xcc, 2f
4388 + nop
4389 + retl
4390 + nop
4391 +2: BACKOFF_SPIN(%o2, %o3, 1b)
4392 + .size atomic64_sub_unchecked, .-atomic64_sub_unchecked
4393 +
4394 .globl atomic64_add_ret
4395 .type atomic64_add_ret,#function
4396 atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
4397 BACKOFF_SETUP(%o2)
4398 1: ldx [%o1], %g1
4399 - add %g1, %o0, %g7
4400 + addcc %g1, %o0, %g7
4401 +
4402 +#ifdef CONFIG_PAX_REFCOUNT
4403 + tvs %xcc, 6
4404 +#endif
4405 +
4406 casx [%o1], %g1, %g7
4407 cmp %g1, %g7
4408 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
4409 @@ -118,12 +229,33 @@ atomic64_add_ret: /* %o0 = increment, %o
4410 2: BACKOFF_SPIN(%o2, %o3, 1b)
4411 .size atomic64_add_ret, .-atomic64_add_ret
4412
4413 + .globl atomic64_add_ret_unchecked
4414 + .type atomic64_add_ret_unchecked,#function
4415 +atomic64_add_ret_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
4416 + BACKOFF_SETUP(%o2)
4417 +1: ldx [%o1], %g1
4418 + addcc %g1, %o0, %g7
4419 + casx [%o1], %g1, %g7
4420 + cmp %g1, %g7
4421 + bne,pn %xcc, 2f
4422 + add %g7, %o0, %g7
4423 + mov %g7, %o0
4424 + retl
4425 + nop
4426 +2: BACKOFF_SPIN(%o2, %o3, 1b)
4427 + .size atomic64_add_ret_unchecked, .-atomic64_add_ret_unchecked
4428 +
4429 .globl atomic64_sub_ret
4430 .type atomic64_sub_ret,#function
4431 atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
4432 BACKOFF_SETUP(%o2)
4433 1: ldx [%o1], %g1
4434 - sub %g1, %o0, %g7
4435 + subcc %g1, %o0, %g7
4436 +
4437 +#ifdef CONFIG_PAX_REFCOUNT
4438 + tvs %xcc, 6
4439 +#endif
4440 +
4441 casx [%o1], %g1, %g7
4442 cmp %g1, %g7
4443 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
4444 diff -urNp linux-2.6.36/arch/sparc/lib/ksyms.c linux-2.6.36/arch/sparc/lib/ksyms.c
4445 --- linux-2.6.36/arch/sparc/lib/ksyms.c 2010-10-20 16:30:22.000000000 -0400
4446 +++ linux-2.6.36/arch/sparc/lib/ksyms.c 2010-11-06 18:58:15.000000000 -0400
4447 @@ -142,12 +142,17 @@ EXPORT_SYMBOL(__downgrade_write);
4448
4449 /* Atomic counter implementation. */
4450 EXPORT_SYMBOL(atomic_add);
4451 +EXPORT_SYMBOL(atomic_add_unchecked);
4452 EXPORT_SYMBOL(atomic_add_ret);
4453 EXPORT_SYMBOL(atomic_sub);
4454 +EXPORT_SYMBOL(atomic_sub_unchecked);
4455 EXPORT_SYMBOL(atomic_sub_ret);
4456 EXPORT_SYMBOL(atomic64_add);
4457 +EXPORT_SYMBOL(atomic64_add_unchecked);
4458 EXPORT_SYMBOL(atomic64_add_ret);
4459 +EXPORT_SYMBOL(atomic64_add_ret_unchecked);
4460 EXPORT_SYMBOL(atomic64_sub);
4461 +EXPORT_SYMBOL(atomic64_sub_unchecked);
4462 EXPORT_SYMBOL(atomic64_sub_ret);
4463
4464 /* Atomic bit operations. */
4465 diff -urNp linux-2.6.36/arch/sparc/Makefile linux-2.6.36/arch/sparc/Makefile
4466 --- linux-2.6.36/arch/sparc/Makefile 2010-10-20 16:30:22.000000000 -0400
4467 +++ linux-2.6.36/arch/sparc/Makefile 2010-11-06 18:58:50.000000000 -0400
4468 @@ -75,7 +75,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
4469 # Export what is needed by arch/sparc/boot/Makefile
4470 export VMLINUX_INIT VMLINUX_MAIN
4471 VMLINUX_INIT := $(head-y) $(init-y)
4472 -VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/
4473 +VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
4474 VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
4475 VMLINUX_MAIN += $(drivers-y) $(net-y)
4476
4477 diff -urNp linux-2.6.36/arch/sparc/mm/fault_32.c linux-2.6.36/arch/sparc/mm/fault_32.c
4478 --- linux-2.6.36/arch/sparc/mm/fault_32.c 2010-10-20 16:30:22.000000000 -0400
4479 +++ linux-2.6.36/arch/sparc/mm/fault_32.c 2010-11-06 18:58:15.000000000 -0400
4480 @@ -22,6 +22,9 @@
4481 #include <linux/interrupt.h>
4482 #include <linux/module.h>
4483 #include <linux/kdebug.h>
4484 +#include <linux/slab.h>
4485 +#include <linux/pagemap.h>
4486 +#include <linux/compiler.h>
4487
4488 #include <asm/system.h>
4489 #include <asm/page.h>
4490 @@ -209,6 +212,268 @@ static unsigned long compute_si_addr(str
4491 return safe_compute_effective_address(regs, insn);
4492 }
4493
4494 +#ifdef CONFIG_PAX_PAGEEXEC
4495 +#ifdef CONFIG_PAX_DLRESOLVE
4496 +static void pax_emuplt_close(struct vm_area_struct *vma)
4497 +{
4498 + vma->vm_mm->call_dl_resolve = 0UL;
4499 +}
4500 +
4501 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
4502 +{
4503 + unsigned int *kaddr;
4504 +
4505 + vmf->page = alloc_page(GFP_HIGHUSER);
4506 + if (!vmf->page)
4507 + return VM_FAULT_OOM;
4508 +
4509 + kaddr = kmap(vmf->page);
4510 + memset(kaddr, 0, PAGE_SIZE);
4511 + kaddr[0] = 0x9DE3BFA8U; /* save */
4512 + flush_dcache_page(vmf->page);
4513 + kunmap(vmf->page);
4514 + return VM_FAULT_MAJOR;
4515 +}
4516 +
4517 +static const struct vm_operations_struct pax_vm_ops = {
4518 + .close = pax_emuplt_close,
4519 + .fault = pax_emuplt_fault
4520 +};
4521 +
4522 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4523 +{
4524 + int ret;
4525 +
4526 + INIT_LIST_HEAD(&vma->anon_vma_chain);
4527 + vma->vm_mm = current->mm;
4528 + vma->vm_start = addr;
4529 + vma->vm_end = addr + PAGE_SIZE;
4530 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4531 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
4532 + vma->vm_ops = &pax_vm_ops;
4533 +
4534 + ret = insert_vm_struct(current->mm, vma);
4535 + if (ret)
4536 + return ret;
4537 +
4538 + ++current->mm->total_vm;
4539 + return 0;
4540 +}
4541 +#endif
4542 +
4543 +/*
4544 + * PaX: decide what to do with offenders (regs->pc = fault address)
4545 + *
4546 + * returns 1 when task should be killed
4547 + * 2 when patched PLT trampoline was detected
4548 + * 3 when unpatched PLT trampoline was detected
4549 + */
4550 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4551 +{
4552 +
4553 +#ifdef CONFIG_PAX_EMUPLT
4554 + int err;
4555 +
4556 + do { /* PaX: patched PLT emulation #1 */
4557 + unsigned int sethi1, sethi2, jmpl;
4558 +
4559 + err = get_user(sethi1, (unsigned int *)regs->pc);
4560 + err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
4561 + err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
4562 +
4563 + if (err)
4564 + break;
4565 +
4566 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4567 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
4568 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
4569 + {
4570 + unsigned int addr;
4571 +
4572 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4573 + addr = regs->u_regs[UREG_G1];
4574 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4575 + regs->pc = addr;
4576 + regs->npc = addr+4;
4577 + return 2;
4578 + }
4579 + } while (0);
4580 +
4581 + { /* PaX: patched PLT emulation #2 */
4582 + unsigned int ba;
4583 +
4584 + err = get_user(ba, (unsigned int *)regs->pc);
4585 +
4586 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4587 + unsigned int addr;
4588 +
4589 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4590 + regs->pc = addr;
4591 + regs->npc = addr+4;
4592 + return 2;
4593 + }
4594 + }
4595 +
4596 + do { /* PaX: patched PLT emulation #3 */
4597 + unsigned int sethi, jmpl, nop;
4598 +
4599 + err = get_user(sethi, (unsigned int *)regs->pc);
4600 + err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
4601 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
4602 +
4603 + if (err)
4604 + break;
4605 +
4606 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
4607 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4608 + nop == 0x01000000U)
4609 + {
4610 + unsigned int addr;
4611 +
4612 + addr = (sethi & 0x003FFFFFU) << 10;
4613 + regs->u_regs[UREG_G1] = addr;
4614 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4615 + regs->pc = addr;
4616 + regs->npc = addr+4;
4617 + return 2;
4618 + }
4619 + } while (0);
4620 +
4621 + do { /* PaX: unpatched PLT emulation step 1 */
4622 + unsigned int sethi, ba, nop;
4623 +
4624 + err = get_user(sethi, (unsigned int *)regs->pc);
4625 + err |= get_user(ba, (unsigned int *)(regs->pc+4));
4626 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
4627 +
4628 + if (err)
4629 + break;
4630 +
4631 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
4632 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4633 + nop == 0x01000000U)
4634 + {
4635 + unsigned int addr, save, call;
4636 +
4637 + if ((ba & 0xFFC00000U) == 0x30800000U)
4638 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4639 + else
4640 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
4641 +
4642 + err = get_user(save, (unsigned int *)addr);
4643 + err |= get_user(call, (unsigned int *)(addr+4));
4644 + err |= get_user(nop, (unsigned int *)(addr+8));
4645 + if (err)
4646 + break;
4647 +
4648 +#ifdef CONFIG_PAX_DLRESOLVE
4649 + if (save == 0x9DE3BFA8U &&
4650 + (call & 0xC0000000U) == 0x40000000U &&
4651 + nop == 0x01000000U)
4652 + {
4653 + struct vm_area_struct *vma;
4654 + unsigned long call_dl_resolve;
4655 +
4656 + down_read(&current->mm->mmap_sem);
4657 + call_dl_resolve = current->mm->call_dl_resolve;
4658 + up_read(&current->mm->mmap_sem);
4659 + if (likely(call_dl_resolve))
4660 + goto emulate;
4661 +
4662 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4663 +
4664 + down_write(&current->mm->mmap_sem);
4665 + if (current->mm->call_dl_resolve) {
4666 + call_dl_resolve = current->mm->call_dl_resolve;
4667 + up_write(&current->mm->mmap_sem);
4668 + if (vma)
4669 + kmem_cache_free(vm_area_cachep, vma);
4670 + goto emulate;
4671 + }
4672 +
4673 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4674 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4675 + up_write(&current->mm->mmap_sem);
4676 + if (vma)
4677 + kmem_cache_free(vm_area_cachep, vma);
4678 + return 1;
4679 + }
4680 +
4681 + if (pax_insert_vma(vma, call_dl_resolve)) {
4682 + up_write(&current->mm->mmap_sem);
4683 + kmem_cache_free(vm_area_cachep, vma);
4684 + return 1;
4685 + }
4686 +
4687 + current->mm->call_dl_resolve = call_dl_resolve;
4688 + up_write(&current->mm->mmap_sem);
4689 +
4690 +emulate:
4691 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4692 + regs->pc = call_dl_resolve;
4693 + regs->npc = addr+4;
4694 + return 3;
4695 + }
4696 +#endif
4697 +
4698 + /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */
4699 + if ((save & 0xFFC00000U) == 0x05000000U &&
4700 + (call & 0xFFFFE000U) == 0x85C0A000U &&
4701 + nop == 0x01000000U)
4702 + {
4703 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4704 + regs->u_regs[UREG_G2] = addr + 4;
4705 + addr = (save & 0x003FFFFFU) << 10;
4706 + addr += (((call | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4707 + regs->pc = addr;
4708 + regs->npc = addr+4;
4709 + return 3;
4710 + }
4711 + }
4712 + } while (0);
4713 +
4714 + do { /* PaX: unpatched PLT emulation step 2 */
4715 + unsigned int save, call, nop;
4716 +
4717 + err = get_user(save, (unsigned int *)(regs->pc-4));
4718 + err |= get_user(call, (unsigned int *)regs->pc);
4719 + err |= get_user(nop, (unsigned int *)(regs->pc+4));
4720 + if (err)
4721 + break;
4722 +
4723 + if (save == 0x9DE3BFA8U &&
4724 + (call & 0xC0000000U) == 0x40000000U &&
4725 + nop == 0x01000000U)
4726 + {
4727 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
4728 +
4729 + regs->u_regs[UREG_RETPC] = regs->pc;
4730 + regs->pc = dl_resolve;
4731 + regs->npc = dl_resolve+4;
4732 + return 3;
4733 + }
4734 + } while (0);
4735 +#endif
4736 +
4737 + return 1;
4738 +}
4739 +
4740 +void pax_report_insns(void *pc, void *sp)
4741 +{
4742 + unsigned long i;
4743 +
4744 + printk(KERN_ERR "PAX: bytes at PC: ");
4745 + for (i = 0; i < 8; i++) {
4746 + unsigned int c;
4747 + if (get_user(c, (unsigned int *)pc+i))
4748 + printk(KERN_CONT "???????? ");
4749 + else
4750 + printk(KERN_CONT "%08x ", c);
4751 + }
4752 + printk("\n");
4753 +}
4754 +#endif
4755 +
4756 static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
4757 int text_fault)
4758 {
4759 @@ -282,6 +547,24 @@ good_area:
4760 if(!(vma->vm_flags & VM_WRITE))
4761 goto bad_area;
4762 } else {
4763 +
4764 +#ifdef CONFIG_PAX_PAGEEXEC
4765 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
4766 + up_read(&mm->mmap_sem);
4767 + switch (pax_handle_fetch_fault(regs)) {
4768 +
4769 +#ifdef CONFIG_PAX_EMUPLT
4770 + case 2:
4771 + case 3:
4772 + return;
4773 +#endif
4774 +
4775 + }
4776 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
4777 + do_group_exit(SIGKILL);
4778 + }
4779 +#endif
4780 +
4781 /* Allow reads even for write-only mappings */
4782 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
4783 goto bad_area;
4784 diff -urNp linux-2.6.36/arch/sparc/mm/fault_64.c linux-2.6.36/arch/sparc/mm/fault_64.c
4785 --- linux-2.6.36/arch/sparc/mm/fault_64.c 2010-10-20 16:30:22.000000000 -0400
4786 +++ linux-2.6.36/arch/sparc/mm/fault_64.c 2010-11-06 18:58:15.000000000 -0400
4787 @@ -21,6 +21,9 @@
4788 #include <linux/kprobes.h>
4789 #include <linux/kdebug.h>
4790 #include <linux/percpu.h>
4791 +#include <linux/slab.h>
4792 +#include <linux/pagemap.h>
4793 +#include <linux/compiler.h>
4794
4795 #include <asm/page.h>
4796 #include <asm/pgtable.h>
4797 @@ -272,6 +275,457 @@ static void noinline __kprobes bogus_32b
4798 show_regs(regs);
4799 }
4800
4801 +#ifdef CONFIG_PAX_PAGEEXEC
4802 +#ifdef CONFIG_PAX_DLRESOLVE
4803 +static void pax_emuplt_close(struct vm_area_struct *vma)
4804 +{
4805 + vma->vm_mm->call_dl_resolve = 0UL;
4806 +}
4807 +
4808 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
4809 +{
4810 + unsigned int *kaddr;
4811 +
4812 + vmf->page = alloc_page(GFP_HIGHUSER);
4813 + if (!vmf->page)
4814 + return VM_FAULT_OOM;
4815 +
4816 + kaddr = kmap(vmf->page);
4817 + memset(kaddr, 0, PAGE_SIZE);
4818 + kaddr[0] = 0x9DE3BFA8U; /* save */
4819 + flush_dcache_page(vmf->page);
4820 + kunmap(vmf->page);
4821 + return VM_FAULT_MAJOR;
4822 +}
4823 +
4824 +static const struct vm_operations_struct pax_vm_ops = {
4825 + .close = pax_emuplt_close,
4826 + .fault = pax_emuplt_fault
4827 +};
4828 +
4829 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4830 +{
4831 + int ret;
4832 +
4833 + INIT_LIST_HEAD(&vma->anon_vma_chain);
4834 + vma->vm_mm = current->mm;
4835 + vma->vm_start = addr;
4836 + vma->vm_end = addr + PAGE_SIZE;
4837 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4838 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
4839 + vma->vm_ops = &pax_vm_ops;
4840 +
4841 + ret = insert_vm_struct(current->mm, vma);
4842 + if (ret)
4843 + return ret;
4844 +
4845 + ++current->mm->total_vm;
4846 + return 0;
4847 +}
4848 +#endif
4849 +
4850 +/*
4851 + * PaX: decide what to do with offenders (regs->tpc = fault address)
4852 + *
4853 + * returns 1 when task should be killed
4854 + * 2 when patched PLT trampoline was detected
4855 + * 3 when unpatched PLT trampoline was detected
4856 + */
4857 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4858 +{
4859 +
4860 +#ifdef CONFIG_PAX_EMUPLT
4861 + int err;
4862 +
4863 + do { /* PaX: patched PLT emulation #1 */
4864 + unsigned int sethi1, sethi2, jmpl;
4865 +
4866 + err = get_user(sethi1, (unsigned int *)regs->tpc);
4867 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4868 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
4869 +
4870 + if (err)
4871 + break;
4872 +
4873 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4874 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
4875 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
4876 + {
4877 + unsigned long addr;
4878 +
4879 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4880 + addr = regs->u_regs[UREG_G1];
4881 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4882 +
4883 + if (test_thread_flag(TIF_32BIT))
4884 + addr &= 0xFFFFFFFFUL;
4885 +
4886 + regs->tpc = addr;
4887 + regs->tnpc = addr+4;
4888 + return 2;
4889 + }
4890 + } while (0);
4891 +
4892 + { /* PaX: patched PLT emulation #2 */
4893 + unsigned int ba;
4894 +
4895 + err = get_user(ba, (unsigned int *)regs->tpc);
4896 +
4897 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4898 + unsigned long addr;
4899 +
4900 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4901 +
4902 + if (test_thread_flag(TIF_32BIT))
4903 + addr &= 0xFFFFFFFFUL;
4904 +
4905 + regs->tpc = addr;
4906 + regs->tnpc = addr+4;
4907 + return 2;
4908 + }
4909 + }
4910 +
4911 + do { /* PaX: patched PLT emulation #3 */
4912 + unsigned int sethi, jmpl, nop;
4913 +
4914 + err = get_user(sethi, (unsigned int *)regs->tpc);
4915 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
4916 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4917 +
4918 + if (err)
4919 + break;
4920 +
4921 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
4922 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4923 + nop == 0x01000000U)
4924 + {
4925 + unsigned long addr;
4926 +
4927 + addr = (sethi & 0x003FFFFFU) << 10;
4928 + regs->u_regs[UREG_G1] = addr;
4929 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4930 +
4931 + if (test_thread_flag(TIF_32BIT))
4932 + addr &= 0xFFFFFFFFUL;
4933 +
4934 + regs->tpc = addr;
4935 + regs->tnpc = addr+4;
4936 + return 2;
4937 + }
4938 + } while (0);
4939 +
4940 + do { /* PaX: patched PLT emulation #4 */
4941 + unsigned int sethi, mov1, call, mov2;
4942 +
4943 + err = get_user(sethi, (unsigned int *)regs->tpc);
4944 + err |= get_user(mov1, (unsigned int *)(regs->tpc+4));
4945 + err |= get_user(call, (unsigned int *)(regs->tpc+8));
4946 + err |= get_user(mov2, (unsigned int *)(regs->tpc+12));
4947 +
4948 + if (err)
4949 + break;
4950 +
4951 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
4952 + mov1 == 0x8210000FU &&
4953 + (call & 0xC0000000U) == 0x40000000U &&
4954 + mov2 == 0x9E100001U)
4955 + {
4956 + unsigned long addr;
4957 +
4958 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
4959 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4960 +
4961 + if (test_thread_flag(TIF_32BIT))
4962 + addr &= 0xFFFFFFFFUL;
4963 +
4964 + regs->tpc = addr;
4965 + regs->tnpc = addr+4;
4966 + return 2;
4967 + }
4968 + } while (0);
4969 +
4970 + do { /* PaX: patched PLT emulation #5 */
4971 + unsigned int sethi, sethi1, sethi2, or1, or2, sllx, jmpl, nop;
4972 +
4973 + err = get_user(sethi, (unsigned int *)regs->tpc);
4974 + err |= get_user(sethi1, (unsigned int *)(regs->tpc+4));
4975 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+8));
4976 + err |= get_user(or1, (unsigned int *)(regs->tpc+12));
4977 + err |= get_user(or2, (unsigned int *)(regs->tpc+16));
4978 + err |= get_user(sllx, (unsigned int *)(regs->tpc+20));
4979 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+24));
4980 + err |= get_user(nop, (unsigned int *)(regs->tpc+28));
4981 +
4982 + if (err)
4983 + break;
4984 +
4985 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
4986 + (sethi1 & 0xFFC00000U) == 0x03000000U &&
4987 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4988 + (or1 & 0xFFFFE000U) == 0x82106000U &&
4989 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
4990 + sllx == 0x83287020U &&
4991 + jmpl == 0x81C04005U &&
4992 + nop == 0x01000000U)
4993 + {
4994 + unsigned long addr;
4995 +
4996 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
4997 + regs->u_regs[UREG_G1] <<= 32;
4998 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
4999 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
5000 + regs->tpc = addr;
5001 + regs->tnpc = addr+4;
5002 + return 2;
5003 + }
5004 + } while (0);
5005 +
5006 + do { /* PaX: patched PLT emulation #6 */
5007 + unsigned int sethi, sethi1, sethi2, sllx, or, jmpl, nop;
5008 +
5009 + err = get_user(sethi, (unsigned int *)regs->tpc);
5010 + err |= get_user(sethi1, (unsigned int *)(regs->tpc+4));
5011 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+8));
5012 + err |= get_user(sllx, (unsigned int *)(regs->tpc+12));
5013 + err |= get_user(or, (unsigned int *)(regs->tpc+16));
5014 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
5015 + err |= get_user(nop, (unsigned int *)(regs->tpc+24));
5016 +
5017 + if (err)
5018 + break;
5019 +
5020 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
5021 + (sethi1 & 0xFFC00000U) == 0x03000000U &&
5022 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
5023 + sllx == 0x83287020U &&
5024 + (or & 0xFFFFE000U) == 0x8A116000U &&
5025 + jmpl == 0x81C04005U &&
5026 + nop == 0x01000000U)
5027 + {
5028 + unsigned long addr;
5029 +
5030 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
5031 + regs->u_regs[UREG_G1] <<= 32;
5032 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
5033 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
5034 + regs->tpc = addr;
5035 + regs->tnpc = addr+4;
5036 + return 2;
5037 + }
5038 + } while (0);
5039 +
5040 + do { /* PaX: unpatched PLT emulation step 1 */
5041 + unsigned int sethi, ba, nop;
5042 +
5043 + err = get_user(sethi, (unsigned int *)regs->tpc);
5044 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
5045 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
5046 +
5047 + if (err)
5048 + break;
5049 +
5050 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
5051 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
5052 + nop == 0x01000000U)
5053 + {
5054 + unsigned long addr;
5055 + unsigned int save, call;
5056 + unsigned int sethi1, sethi2, or1, or2, sllx, add, jmpl;
5057 +
5058 + if ((ba & 0xFFC00000U) == 0x30800000U)
5059 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
5060 + else
5061 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
5062 +
5063 + if (test_thread_flag(TIF_32BIT))
5064 + addr &= 0xFFFFFFFFUL;
5065 +
5066 + err = get_user(save, (unsigned int *)addr);
5067 + err |= get_user(call, (unsigned int *)(addr+4));
5068 + err |= get_user(nop, (unsigned int *)(addr+8));
5069 + if (err)
5070 + break;
5071 +
5072 +#ifdef CONFIG_PAX_DLRESOLVE
5073 + if (save == 0x9DE3BFA8U &&
5074 + (call & 0xC0000000U) == 0x40000000U &&
5075 + nop == 0x01000000U)
5076 + {
5077 + struct vm_area_struct *vma;
5078 + unsigned long call_dl_resolve;
5079 +
5080 + down_read(&current->mm->mmap_sem);
5081 + call_dl_resolve = current->mm->call_dl_resolve;
5082 + up_read(&current->mm->mmap_sem);
5083 + if (likely(call_dl_resolve))
5084 + goto emulate;
5085 +
5086 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
5087 +
5088 + down_write(&current->mm->mmap_sem);
5089 + if (current->mm->call_dl_resolve) {
5090 + call_dl_resolve = current->mm->call_dl_resolve;
5091 + up_write(&current->mm->mmap_sem);
5092 + if (vma)
5093 + kmem_cache_free(vm_area_cachep, vma);
5094 + goto emulate;
5095 + }
5096 +
5097 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5098 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
5099 + up_write(&current->mm->mmap_sem);
5100 + if (vma)
5101 + kmem_cache_free(vm_area_cachep, vma);
5102 + return 1;
5103 + }
5104 +
5105 + if (pax_insert_vma(vma, call_dl_resolve)) {
5106 + up_write(&current->mm->mmap_sem);
5107 + kmem_cache_free(vm_area_cachep, vma);
5108 + return 1;
5109 + }
5110 +
5111 + current->mm->call_dl_resolve = call_dl_resolve;
5112 + up_write(&current->mm->mmap_sem);
5113 +
5114 +emulate:
5115 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5116 + regs->tpc = call_dl_resolve;
5117 + regs->tnpc = addr+4;
5118 + return 3;
5119 + }
5120 +#endif
5121 +
5122 + /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */
5123 + if ((save & 0xFFC00000U) == 0x05000000U &&
5124 + (call & 0xFFFFE000U) == 0x85C0A000U &&
5125 + nop == 0x01000000U)
5126 + {
5127 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5128 + regs->u_regs[UREG_G2] = addr + 4;
5129 + addr = (save & 0x003FFFFFU) << 10;
5130 + addr += (((call | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
5131 +
5132 + if (test_thread_flag(TIF_32BIT))
5133 + addr &= 0xFFFFFFFFUL;
5134 +
5135 + regs->tpc = addr;
5136 + regs->tnpc = addr+4;
5137 + return 3;
5138 + }
5139 +
5140 + /* PaX: 64-bit PLT stub */
5141 + err = get_user(sethi1, (unsigned int *)addr);
5142 + err |= get_user(sethi2, (unsigned int *)(addr+4));
5143 + err |= get_user(or1, (unsigned int *)(addr+8));
5144 + err |= get_user(or2, (unsigned int *)(addr+12));
5145 + err |= get_user(sllx, (unsigned int *)(addr+16));
5146 + err |= get_user(add, (unsigned int *)(addr+20));
5147 + err |= get_user(jmpl, (unsigned int *)(addr+24));
5148 + err |= get_user(nop, (unsigned int *)(addr+28));
5149 + if (err)
5150 + break;
5151 +
5152 + if ((sethi1 & 0xFFC00000U) == 0x09000000U &&
5153 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
5154 + (or1 & 0xFFFFE000U) == 0x88112000U &&
5155 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
5156 + sllx == 0x89293020U &&
5157 + add == 0x8A010005U &&
5158 + jmpl == 0x89C14000U &&
5159 + nop == 0x01000000U)
5160 + {
5161 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5162 + regs->u_regs[UREG_G4] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
5163 + regs->u_regs[UREG_G4] <<= 32;
5164 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
5165 + regs->u_regs[UREG_G5] += regs->u_regs[UREG_G4];
5166 + regs->u_regs[UREG_G4] = addr + 24;
5167 + addr = regs->u_regs[UREG_G5];
5168 + regs->tpc = addr;
5169 + regs->tnpc = addr+4;
5170 + return 3;
5171 + }
5172 + }
5173 + } while (0);
5174 +
5175 +#ifdef CONFIG_PAX_DLRESOLVE
5176 + do { /* PaX: unpatched PLT emulation step 2 */
5177 + unsigned int save, call, nop;
5178 +
5179 + err = get_user(save, (unsigned int *)(regs->tpc-4));
5180 + err |= get_user(call, (unsigned int *)regs->tpc);
5181 + err |= get_user(nop, (unsigned int *)(regs->tpc+4));
5182 + if (err)
5183 + break;
5184 +
5185 + if (save == 0x9DE3BFA8U &&
5186 + (call & 0xC0000000U) == 0x40000000U &&
5187 + nop == 0x01000000U)
5188 + {
5189 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5190 +
5191 + if (test_thread_flag(TIF_32BIT))
5192 + dl_resolve &= 0xFFFFFFFFUL;
5193 +
5194 + regs->u_regs[UREG_RETPC] = regs->tpc;
5195 + regs->tpc = dl_resolve;
5196 + regs->tnpc = dl_resolve+4;
5197 + return 3;
5198 + }
5199 + } while (0);
5200 +#endif
5201 +
5202 + do { /* PaX: patched PLT emulation #7, must be AFTER the unpatched PLT emulation */
5203 + unsigned int sethi, ba, nop;
5204 +
5205 + err = get_user(sethi, (unsigned int *)regs->tpc);
5206 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
5207 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
5208 +
5209 + if (err)
5210 + break;
5211 +
5212 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
5213 + (ba & 0xFFF00000U) == 0x30600000U &&
5214 + nop == 0x01000000U)
5215 + {
5216 + unsigned long addr;
5217 +
5218 + addr = (sethi & 0x003FFFFFU) << 10;
5219 + regs->u_regs[UREG_G1] = addr;
5220 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
5221 +
5222 + if (test_thread_flag(TIF_32BIT))
5223 + addr &= 0xFFFFFFFFUL;
5224 +
5225 + regs->tpc = addr;
5226 + regs->tnpc = addr+4;
5227 + return 2;
5228 + }
5229 + } while (0);
5230 +
5231 +#endif
5232 +
5233 + return 1;
5234 +}
5235 +
5236 +void pax_report_insns(void *pc, void *sp)
5237 +{
5238 + unsigned long i;
5239 +
5240 + printk(KERN_ERR "PAX: bytes at PC: ");
5241 + for (i = 0; i < 8; i++) {
5242 + unsigned int c;
5243 + if (get_user(c, (unsigned int *)pc+i))
5244 + printk(KERN_CONT "???????? ");
5245 + else
5246 + printk(KERN_CONT "%08x ", c);
5247 + }
5248 + printk("\n");
5249 +}
5250 +#endif
5251 +
5252 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
5253 {
5254 struct mm_struct *mm = current->mm;
5255 @@ -340,6 +794,29 @@ asmlinkage void __kprobes do_sparc64_fau
5256 if (!vma)
5257 goto bad_area;
5258
5259 +#ifdef CONFIG_PAX_PAGEEXEC
5260 + /* PaX: detect ITLB misses on non-exec pages */
5261 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
5262 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
5263 + {
5264 + if (address != regs->tpc)
5265 + goto good_area;
5266 +
5267 + up_read(&mm->mmap_sem);
5268 + switch (pax_handle_fetch_fault(regs)) {
5269 +
5270 +#ifdef CONFIG_PAX_EMUPLT
5271 + case 2:
5272 + case 3:
5273 + return;
5274 +#endif
5275 +
5276 + }
5277 + pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
5278 + do_group_exit(SIGKILL);
5279 + }
5280 +#endif
5281 +
5282 /* Pure DTLB misses do not tell us whether the fault causing
5283 * load/store/atomic was a write or not, it only says that there
5284 * was no match. So in such a case we (carefully) read the
5285 diff -urNp linux-2.6.36/arch/sparc/mm/hugetlbpage.c linux-2.6.36/arch/sparc/mm/hugetlbpage.c
5286 --- linux-2.6.36/arch/sparc/mm/hugetlbpage.c 2010-10-20 16:30:22.000000000 -0400
5287 +++ linux-2.6.36/arch/sparc/mm/hugetlbpage.c 2010-11-06 18:58:15.000000000 -0400
5288 @@ -68,7 +68,7 @@ full_search:
5289 }
5290 return -ENOMEM;
5291 }
5292 - if (likely(!vma || addr + len <= vma->vm_start)) {
5293 + if (likely(check_heap_stack_gap(vma, addr, len))) {
5294 /*
5295 * Remember the place where we stopped the search:
5296 */
5297 @@ -107,7 +107,7 @@ hugetlb_get_unmapped_area_topdown(struct
5298 /* make sure it can fit in the remaining address space */
5299 if (likely(addr > len)) {
5300 vma = find_vma(mm, addr-len);
5301 - if (!vma || addr <= vma->vm_start) {
5302 + if (check_heap_stack_gap(vma, addr - len, len)) {
5303 /* remember the address as a hint for next time */
5304 return (mm->free_area_cache = addr-len);
5305 }
5306 @@ -125,7 +125,7 @@ hugetlb_get_unmapped_area_topdown(struct
5307 * return with success:
5308 */
5309 vma = find_vma(mm, addr);
5310 - if (likely(!vma || addr+len <= vma->vm_start)) {
5311 + if (likely(check_heap_stack_gap(vma, addr, len))) {
5312 /* remember the address as a hint for next time */
5313 return (mm->free_area_cache = addr);
5314 }
5315 @@ -182,8 +182,7 @@ hugetlb_get_unmapped_area(struct file *f
5316 if (addr) {
5317 addr = ALIGN(addr, HPAGE_SIZE);
5318 vma = find_vma(mm, addr);
5319 - if (task_size - len >= addr &&
5320 - (!vma || addr + len <= vma->vm_start))
5321 + if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
5322 return addr;
5323 }
5324 if (mm->get_unmapped_area == arch_get_unmapped_area)
5325 diff -urNp linux-2.6.36/arch/sparc/mm/init_32.c linux-2.6.36/arch/sparc/mm/init_32.c
5326 --- linux-2.6.36/arch/sparc/mm/init_32.c 2010-10-20 16:30:22.000000000 -0400
5327 +++ linux-2.6.36/arch/sparc/mm/init_32.c 2010-11-06 18:58:15.000000000 -0400
5328 @@ -318,6 +318,9 @@ extern void device_scan(void);
5329 pgprot_t PAGE_SHARED __read_mostly;
5330 EXPORT_SYMBOL(PAGE_SHARED);
5331
5332 +pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
5333 +EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
5334 +
5335 void __init paging_init(void)
5336 {
5337 switch(sparc_cpu_model) {
5338 @@ -346,17 +349,17 @@ void __init paging_init(void)
5339
5340 /* Initialize the protection map with non-constant, MMU dependent values. */
5341 protection_map[0] = PAGE_NONE;
5342 - protection_map[1] = PAGE_READONLY;
5343 - protection_map[2] = PAGE_COPY;
5344 - protection_map[3] = PAGE_COPY;
5345 + protection_map[1] = PAGE_READONLY_NOEXEC;
5346 + protection_map[2] = PAGE_COPY_NOEXEC;
5347 + protection_map[3] = PAGE_COPY_NOEXEC;
5348 protection_map[4] = PAGE_READONLY;
5349 protection_map[5] = PAGE_READONLY;
5350 protection_map[6] = PAGE_COPY;
5351 protection_map[7] = PAGE_COPY;
5352 protection_map[8] = PAGE_NONE;
5353 - protection_map[9] = PAGE_READONLY;
5354 - protection_map[10] = PAGE_SHARED;
5355 - protection_map[11] = PAGE_SHARED;
5356 + protection_map[9] = PAGE_READONLY_NOEXEC;
5357 + protection_map[10] = PAGE_SHARED_NOEXEC;
5358 + protection_map[11] = PAGE_SHARED_NOEXEC;
5359 protection_map[12] = PAGE_READONLY;
5360 protection_map[13] = PAGE_READONLY;
5361 protection_map[14] = PAGE_SHARED;
5362 diff -urNp linux-2.6.36/arch/sparc/mm/Makefile linux-2.6.36/arch/sparc/mm/Makefile
5363 --- linux-2.6.36/arch/sparc/mm/Makefile 2010-10-20 16:30:22.000000000 -0400
5364 +++ linux-2.6.36/arch/sparc/mm/Makefile 2010-11-06 18:58:15.000000000 -0400
5365 @@ -2,7 +2,7 @@
5366 #
5367
5368 asflags-y := -ansi
5369 -ccflags-y := -Werror
5370 +#ccflags-y := -Werror
5371
5372 obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o
5373 obj-y += fault_$(BITS).o
5374 diff -urNp linux-2.6.36/arch/sparc/mm/srmmu.c linux-2.6.36/arch/sparc/mm/srmmu.c
5375 --- linux-2.6.36/arch/sparc/mm/srmmu.c 2010-10-20 16:30:22.000000000 -0400
5376 +++ linux-2.6.36/arch/sparc/mm/srmmu.c 2010-11-06 18:58:15.000000000 -0400
5377 @@ -2198,6 +2198,13 @@ void __init ld_mmu_srmmu(void)
5378 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
5379 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
5380 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
5381 +
5382 +#ifdef CONFIG_PAX_PAGEEXEC
5383 + PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
5384 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
5385 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
5386 +#endif
5387 +
5388 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
5389 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
5390
5391 diff -urNp linux-2.6.36/arch/um/include/asm/kmap_types.h linux-2.6.36/arch/um/include/asm/kmap_types.h
5392 --- linux-2.6.36/arch/um/include/asm/kmap_types.h 2010-10-20 16:30:22.000000000 -0400
5393 +++ linux-2.6.36/arch/um/include/asm/kmap_types.h 2010-11-06 18:58:15.000000000 -0400
5394 @@ -23,6 +23,7 @@ enum km_type {
5395 KM_IRQ1,
5396 KM_SOFTIRQ0,
5397 KM_SOFTIRQ1,
5398 + KM_CLEARPAGE,
5399 KM_TYPE_NR
5400 };
5401
5402 diff -urNp linux-2.6.36/arch/um/include/asm/page.h linux-2.6.36/arch/um/include/asm/page.h
5403 --- linux-2.6.36/arch/um/include/asm/page.h 2010-10-20 16:30:22.000000000 -0400
5404 +++ linux-2.6.36/arch/um/include/asm/page.h 2010-11-06 18:58:15.000000000 -0400
5405 @@ -14,6 +14,9 @@
5406 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
5407 #define PAGE_MASK (~(PAGE_SIZE-1))
5408
5409 +#define ktla_ktva(addr) (addr)
5410 +#define ktva_ktla(addr) (addr)
5411 +
5412 #ifndef __ASSEMBLY__
5413
5414 struct page;
5415 diff -urNp linux-2.6.36/arch/um/sys-i386/syscalls.c linux-2.6.36/arch/um/sys-i386/syscalls.c
5416 --- linux-2.6.36/arch/um/sys-i386/syscalls.c 2010-10-20 16:30:22.000000000 -0400
5417 +++ linux-2.6.36/arch/um/sys-i386/syscalls.c 2010-11-06 18:58:15.000000000 -0400
5418 @@ -11,6 +11,21 @@
5419 #include "asm/uaccess.h"
5420 #include "asm/unistd.h"
5421
5422 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
5423 +{
5424 + unsigned long pax_task_size = TASK_SIZE;
5425 +
5426 +#ifdef CONFIG_PAX_SEGMEXEC
5427 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
5428 + pax_task_size = SEGMEXEC_TASK_SIZE;
5429 +#endif
5430 +
5431 + if (len > pax_task_size || addr > pax_task_size - len)
5432 + return -EINVAL;
5433 +
5434 + return 0;
5435 +}
5436 +
5437 /*
5438 * The prototype on i386 is:
5439 *
5440 diff -urNp linux-2.6.36/arch/x86/boot/bitops.h linux-2.6.36/arch/x86/boot/bitops.h
5441 --- linux-2.6.36/arch/x86/boot/bitops.h 2010-10-20 16:30:22.000000000 -0400
5442 +++ linux-2.6.36/arch/x86/boot/bitops.h 2010-11-06 18:58:15.000000000 -0400
5443 @@ -26,7 +26,7 @@ static inline int variable_test_bit(int
5444 u8 v;
5445 const u32 *p = (const u32 *)addr;
5446
5447 - asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
5448 + asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
5449 return v;
5450 }
5451
5452 @@ -37,7 +37,7 @@ static inline int variable_test_bit(int
5453
5454 static inline void set_bit(int nr, void *addr)
5455 {
5456 - asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
5457 + asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
5458 }
5459
5460 #endif /* BOOT_BITOPS_H */
5461 diff -urNp linux-2.6.36/arch/x86/boot/boot.h linux-2.6.36/arch/x86/boot/boot.h
5462 --- linux-2.6.36/arch/x86/boot/boot.h 2010-10-20 16:30:22.000000000 -0400
5463 +++ linux-2.6.36/arch/x86/boot/boot.h 2010-11-06 18:58:15.000000000 -0400
5464 @@ -85,7 +85,7 @@ static inline void io_delay(void)
5465 static inline u16 ds(void)
5466 {
5467 u16 seg;
5468 - asm("movw %%ds,%0" : "=rm" (seg));
5469 + asm volatile("movw %%ds,%0" : "=rm" (seg));
5470 return seg;
5471 }
5472
5473 @@ -181,7 +181,7 @@ static inline void wrgs32(u32 v, addr_t
5474 static inline int memcmp(const void *s1, const void *s2, size_t len)
5475 {
5476 u8 diff;
5477 - asm("repe; cmpsb; setnz %0"
5478 + asm volatile("repe; cmpsb; setnz %0"
5479 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
5480 return diff;
5481 }
5482 diff -urNp linux-2.6.36/arch/x86/boot/compressed/head_32.S linux-2.6.36/arch/x86/boot/compressed/head_32.S
5483 --- linux-2.6.36/arch/x86/boot/compressed/head_32.S 2010-10-20 16:30:22.000000000 -0400
5484 +++ linux-2.6.36/arch/x86/boot/compressed/head_32.S 2010-11-06 18:58:15.000000000 -0400
5485 @@ -76,7 +76,7 @@ ENTRY(startup_32)
5486 notl %eax
5487 andl %eax, %ebx
5488 #else
5489 - movl $LOAD_PHYSICAL_ADDR, %ebx
5490 + movl $____LOAD_PHYSICAL_ADDR, %ebx
5491 #endif
5492
5493 /* Target address to relocate to for decompression */
5494 @@ -162,7 +162,7 @@ relocated:
5495 * and where it was actually loaded.
5496 */
5497 movl %ebp, %ebx
5498 - subl $LOAD_PHYSICAL_ADDR, %ebx
5499 + subl $____LOAD_PHYSICAL_ADDR, %ebx
5500 jz 2f /* Nothing to be done if loaded at compiled addr. */
5501 /*
5502 * Process relocations.
5503 @@ -170,8 +170,7 @@ relocated:
5504
5505 1: subl $4, %edi
5506 movl (%edi), %ecx
5507 - testl %ecx, %ecx
5508 - jz 2f
5509 + jecxz 2f
5510 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
5511 jmp 1b
5512 2:
5513 diff -urNp linux-2.6.36/arch/x86/boot/compressed/head_64.S linux-2.6.36/arch/x86/boot/compressed/head_64.S
5514 --- linux-2.6.36/arch/x86/boot/compressed/head_64.S 2010-10-20 16:30:22.000000000 -0400
5515 +++ linux-2.6.36/arch/x86/boot/compressed/head_64.S 2010-11-06 18:58:15.000000000 -0400
5516 @@ -91,7 +91,7 @@ ENTRY(startup_32)
5517 notl %eax
5518 andl %eax, %ebx
5519 #else
5520 - movl $LOAD_PHYSICAL_ADDR, %ebx
5521 + movl $____LOAD_PHYSICAL_ADDR, %ebx
5522 #endif
5523
5524 /* Target address to relocate to for decompression */
5525 @@ -233,7 +233,7 @@ ENTRY(startup_64)
5526 notq %rax
5527 andq %rax, %rbp
5528 #else
5529 - movq $LOAD_PHYSICAL_ADDR, %rbp
5530 + movq $____LOAD_PHYSICAL_ADDR, %rbp
5531 #endif
5532
5533 /* Target address to relocate to for decompression */
5534 diff -urNp linux-2.6.36/arch/x86/boot/compressed/misc.c linux-2.6.36/arch/x86/boot/compressed/misc.c
5535 --- linux-2.6.36/arch/x86/boot/compressed/misc.c 2010-10-20 16:30:22.000000000 -0400
5536 +++ linux-2.6.36/arch/x86/boot/compressed/misc.c 2010-11-06 18:58:15.000000000 -0400
5537 @@ -289,7 +289,7 @@ static void parse_elf(void *output)
5538 case PT_LOAD:
5539 #ifdef CONFIG_RELOCATABLE
5540 dest = output;
5541 - dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
5542 + dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
5543 #else
5544 dest = (void *)(phdr->p_paddr);
5545 #endif
5546 @@ -342,7 +342,7 @@ asmlinkage void decompress_kernel(void *
5547 error("Destination address too large");
5548 #endif
5549 #ifndef CONFIG_RELOCATABLE
5550 - if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
5551 + if ((unsigned long)output != ____LOAD_PHYSICAL_ADDR)
5552 error("Wrong destination address");
5553 #endif
5554
5555 diff -urNp linux-2.6.36/arch/x86/boot/compressed/mkpiggy.c linux-2.6.36/arch/x86/boot/compressed/mkpiggy.c
5556 --- linux-2.6.36/arch/x86/boot/compressed/mkpiggy.c 2010-10-20 16:30:22.000000000 -0400
5557 +++ linux-2.6.36/arch/x86/boot/compressed/mkpiggy.c 2010-11-06 18:58:15.000000000 -0400
5558 @@ -74,7 +74,7 @@ int main(int argc, char *argv[])
5559
5560 offs = (olen > ilen) ? olen - ilen : 0;
5561 offs += olen >> 12; /* Add 8 bytes for each 32K block */
5562 - offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */
5563 + offs += 64*1024; /* Add 64K bytes slack */
5564 offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
5565
5566 printf(".section \".rodata..compressed\",\"a\",@progbits\n");
5567 diff -urNp linux-2.6.36/arch/x86/boot/compressed/relocs.c linux-2.6.36/arch/x86/boot/compressed/relocs.c
5568 --- linux-2.6.36/arch/x86/boot/compressed/relocs.c 2010-10-20 16:30:22.000000000 -0400
5569 +++ linux-2.6.36/arch/x86/boot/compressed/relocs.c 2010-11-06 18:58:15.000000000 -0400
5570 @@ -13,8 +13,11 @@
5571
5572 static void die(char *fmt, ...);
5573
5574 +#include "../../../../include/generated/autoconf.h"
5575 +
5576 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
5577 static Elf32_Ehdr ehdr;
5578 +static Elf32_Phdr *phdr;
5579 static unsigned long reloc_count, reloc_idx;
5580 static unsigned long *relocs;
5581
5582 @@ -270,9 +273,39 @@ static void read_ehdr(FILE *fp)
5583 }
5584 }
5585
5586 +static void read_phdrs(FILE *fp)
5587 +{
5588 + unsigned int i;
5589 +
5590 + phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
5591 + if (!phdr) {
5592 + die("Unable to allocate %d program headers\n",
5593 + ehdr.e_phnum);
5594 + }
5595 + if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
5596 + die("Seek to %d failed: %s\n",
5597 + ehdr.e_phoff, strerror(errno));
5598 + }
5599 + if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
5600 + die("Cannot read ELF program headers: %s\n",
5601 + strerror(errno));
5602 + }
5603 + for(i = 0; i < ehdr.e_phnum; i++) {
5604 + phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
5605 + phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
5606 + phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
5607 + phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
5608 + phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
5609 + phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
5610 + phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
5611 + phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
5612 + }
5613 +
5614 +}
5615 +
5616 static void read_shdrs(FILE *fp)
5617 {
5618 - int i;
5619 + unsigned int i;
5620 Elf32_Shdr shdr;
5621
5622 secs = calloc(ehdr.e_shnum, sizeof(struct section));
5623 @@ -307,7 +340,7 @@ static void read_shdrs(FILE *fp)
5624
5625 static void read_strtabs(FILE *fp)
5626 {
5627 - int i;
5628 + unsigned int i;
5629 for (i = 0; i < ehdr.e_shnum; i++) {
5630 struct section *sec = &secs[i];
5631 if (sec->shdr.sh_type != SHT_STRTAB) {
5632 @@ -332,7 +365,7 @@ static void read_strtabs(FILE *fp)
5633
5634 static void read_symtabs(FILE *fp)
5635 {
5636 - int i,j;
5637 + unsigned int i,j;
5638 for (i = 0; i < ehdr.e_shnum; i++) {
5639 struct section *sec = &secs[i];
5640 if (sec->shdr.sh_type != SHT_SYMTAB) {
5641 @@ -365,7 +398,9 @@ static void read_symtabs(FILE *fp)
5642
5643 static void read_relocs(FILE *fp)
5644 {
5645 - int i,j;
5646 + unsigned int i,j;
5647 + uint32_t base;
5648 +
5649 for (i = 0; i < ehdr.e_shnum; i++) {
5650 struct section *sec = &secs[i];
5651 if (sec->shdr.sh_type != SHT_REL) {
5652 @@ -385,9 +420,18 @@ static void read_relocs(FILE *fp)
5653 die("Cannot read symbol table: %s\n",
5654 strerror(errno));
5655 }
5656 + base = 0;
5657 + for (j = 0; j < ehdr.e_phnum; j++) {
5658 + if (phdr[j].p_type != PT_LOAD )
5659 + continue;
5660 + 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)
5661 + continue;
5662 + base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
5663 + break;
5664 + }
5665 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
5666 Elf32_Rel *rel = &sec->reltab[j];
5667 - rel->r_offset = elf32_to_cpu(rel->r_offset);
5668 + rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
5669 rel->r_info = elf32_to_cpu(rel->r_info);
5670 }
5671 }
5672 @@ -396,14 +440,14 @@ static void read_relocs(FILE *fp)
5673
5674 static void print_absolute_symbols(void)
5675 {
5676 - int i;
5677 + unsigned int i;
5678 printf("Absolute symbols\n");
5679 printf(" Num: Value Size Type Bind Visibility Name\n");
5680 for (i = 0; i < ehdr.e_shnum; i++) {
5681 struct section *sec = &secs[i];
5682 char *sym_strtab;
5683 Elf32_Sym *sh_symtab;
5684 - int j;
5685 + unsigned int j;
5686
5687 if (sec->shdr.sh_type != SHT_SYMTAB) {
5688 continue;
5689 @@ -431,14 +475,14 @@ static void print_absolute_symbols(void)
5690
5691 static void print_absolute_relocs(void)
5692 {
5693 - int i, printed = 0;
5694 + unsigned int i, printed = 0;
5695
5696 for (i = 0; i < ehdr.e_shnum; i++) {
5697 struct section *sec = &secs[i];
5698 struct section *sec_applies, *sec_symtab;
5699 char *sym_strtab;
5700 Elf32_Sym *sh_symtab;
5701 - int j;
5702 + unsigned int j;
5703 if (sec->shdr.sh_type != SHT_REL) {
5704 continue;
5705 }
5706 @@ -499,13 +543,13 @@ static void print_absolute_relocs(void)
5707
5708 static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
5709 {
5710 - int i;
5711 + unsigned int i;
5712 /* Walk through the relocations */
5713 for (i = 0; i < ehdr.e_shnum; i++) {
5714 char *sym_strtab;
5715 Elf32_Sym *sh_symtab;
5716 struct section *sec_applies, *sec_symtab;
5717 - int j;
5718 + unsigned int j;
5719 struct section *sec = &secs[i];
5720
5721 if (sec->shdr.sh_type != SHT_REL) {
5722 @@ -530,6 +574,22 @@ static void walk_relocs(void (*visit)(El
5723 !is_rel_reloc(sym_name(sym_strtab, sym))) {
5724 continue;
5725 }
5726 + /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
5727 + if (!strcmp(sec_name(sym->st_shndx), ".data..percpu") && strcmp(sym_name(sym_strtab, sym), "__per_cpu_load"))
5728 + continue;
5729 +
5730 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
5731 + /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
5732 + if (!strcmp(sec_name(sym->st_shndx), ".module.text") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
5733 + continue;
5734 + if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
5735 + continue;
5736 + if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
5737 + continue;
5738 + if (!strcmp(sec_name(sym->st_shndx), ".text") && strcmp(sym_name(sym_strtab, sym), "__LOAD_PHYSICAL_ADDR"))
5739 + continue;
5740 +#endif
5741 +
5742 switch (r_type) {
5743 case R_386_NONE:
5744 case R_386_PC32:
5745 @@ -571,7 +631,7 @@ static int cmp_relocs(const void *va, co
5746
5747 static void emit_relocs(int as_text)
5748 {
5749 - int i;
5750 + unsigned int i;
5751 /* Count how many relocations I have and allocate space for them. */
5752 reloc_count = 0;
5753 walk_relocs(count_reloc);
5754 @@ -665,6 +725,7 @@ int main(int argc, char **argv)
5755 fname, strerror(errno));
5756 }
5757 read_ehdr(fp);
5758 + read_phdrs(fp);
5759 read_shdrs(fp);
5760 read_strtabs(fp);
5761 read_symtabs(fp);
5762 diff -urNp linux-2.6.36/arch/x86/boot/cpucheck.c linux-2.6.36/arch/x86/boot/cpucheck.c
5763 --- linux-2.6.36/arch/x86/boot/cpucheck.c 2010-10-20 16:30:22.000000000 -0400
5764 +++ linux-2.6.36/arch/x86/boot/cpucheck.c 2010-11-06 18:58:15.000000000 -0400
5765 @@ -74,7 +74,7 @@ static int has_fpu(void)
5766 u16 fcw = -1, fsw = -1;
5767 u32 cr0;
5768
5769 - asm("movl %%cr0,%0" : "=r" (cr0));
5770 + asm volatile("movl %%cr0,%0" : "=r" (cr0));
5771 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
5772 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
5773 asm volatile("movl %0,%%cr0" : : "r" (cr0));
5774 @@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
5775 {
5776 u32 f0, f1;
5777
5778 - asm("pushfl ; "
5779 + asm volatile("pushfl ; "
5780 "pushfl ; "
5781 "popl %0 ; "
5782 "movl %0,%1 ; "
5783 @@ -115,7 +115,7 @@ static void get_flags(void)
5784 set_bit(X86_FEATURE_FPU, cpu.flags);
5785
5786 if (has_eflag(X86_EFLAGS_ID)) {
5787 - asm("cpuid"
5788 + asm volatile("cpuid"
5789 : "=a" (max_intel_level),
5790 "=b" (cpu_vendor[0]),
5791 "=d" (cpu_vendor[1]),
5792 @@ -124,7 +124,7 @@ static void get_flags(void)
5793
5794 if (max_intel_level >= 0x00000001 &&
5795 max_intel_level <= 0x0000ffff) {
5796 - asm("cpuid"
5797 + asm volatile("cpuid"
5798 : "=a" (tfms),
5799 "=c" (cpu.flags[4]),
5800 "=d" (cpu.flags[0])
5801 @@ -136,7 +136,7 @@ static void get_flags(void)
5802 cpu.model += ((tfms >> 16) & 0xf) << 4;
5803 }
5804
5805 - asm("cpuid"
5806 + asm volatile("cpuid"
5807 : "=a" (max_amd_level)
5808 : "a" (0x80000000)
5809 : "ebx", "ecx", "edx");
5810 @@ -144,7 +144,7 @@ static void get_flags(void)
5811 if (max_amd_level >= 0x80000001 &&
5812 max_amd_level <= 0x8000ffff) {
5813 u32 eax = 0x80000001;
5814 - asm("cpuid"
5815 + asm volatile("cpuid"
5816 : "+a" (eax),
5817 "=c" (cpu.flags[6]),
5818 "=d" (cpu.flags[1])
5819 @@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
5820 u32 ecx = MSR_K7_HWCR;
5821 u32 eax, edx;
5822
5823 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5824 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5825 eax &= ~(1 << 15);
5826 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5827 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5828
5829 get_flags(); /* Make sure it really did something */
5830 err = check_flags();
5831 @@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
5832 u32 ecx = MSR_VIA_FCR;
5833 u32 eax, edx;
5834
5835 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5836 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5837 eax |= (1<<1)|(1<<7);
5838 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5839 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5840
5841 set_bit(X86_FEATURE_CX8, cpu.flags);
5842 err = check_flags();
5843 @@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
5844 u32 eax, edx;
5845 u32 level = 1;
5846
5847 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5848 - asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
5849 - asm("cpuid"
5850 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5851 + asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
5852 + asm volatile("cpuid"
5853 : "+a" (level), "=d" (cpu.flags[0])
5854 : : "ecx", "ebx");
5855 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5856 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5857
5858 err = check_flags();
5859 }
5860 diff -urNp linux-2.6.36/arch/x86/boot/header.S linux-2.6.36/arch/x86/boot/header.S
5861 --- linux-2.6.36/arch/x86/boot/header.S 2010-10-20 16:30:22.000000000 -0400
5862 +++ linux-2.6.36/arch/x86/boot/header.S 2010-11-06 18:58:15.000000000 -0400
5863 @@ -224,7 +224,7 @@ setup_data: .quad 0 # 64-bit physical
5864 # single linked list of
5865 # struct setup_data
5866
5867 -pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
5868 +pref_address: .quad ____LOAD_PHYSICAL_ADDR # preferred load addr
5869
5870 #define ZO_INIT_SIZE (ZO__end - ZO_startup_32 + ZO_z_extract_offset)
5871 #define VO_INIT_SIZE (VO__end - VO__text)
5872 diff -urNp linux-2.6.36/arch/x86/boot/memory.c linux-2.6.36/arch/x86/boot/memory.c
5873 --- linux-2.6.36/arch/x86/boot/memory.c 2010-10-20 16:30:22.000000000 -0400
5874 +++ linux-2.6.36/arch/x86/boot/memory.c 2010-11-06 18:58:15.000000000 -0400
5875 @@ -19,7 +19,7 @@
5876
5877 static int detect_memory_e820(void)
5878 {
5879 - int count = 0;
5880 + unsigned int count = 0;
5881 struct biosregs ireg, oreg;
5882 struct e820entry *desc = boot_params.e820_map;
5883 static struct e820entry buf; /* static so it is zeroed */
5884 diff -urNp linux-2.6.36/arch/x86/boot/video.c linux-2.6.36/arch/x86/boot/video.c
5885 --- linux-2.6.36/arch/x86/boot/video.c 2010-10-20 16:30:22.000000000 -0400
5886 +++ linux-2.6.36/arch/x86/boot/video.c 2010-11-06 18:58:15.000000000 -0400
5887 @@ -96,7 +96,7 @@ static void store_mode_params(void)
5888 static unsigned int get_entry(void)
5889 {
5890 char entry_buf[4];
5891 - int i, len = 0;
5892 + unsigned int i, len = 0;
5893 int key;
5894 unsigned int v;
5895
5896 diff -urNp linux-2.6.36/arch/x86/boot/video-vesa.c linux-2.6.36/arch/x86/boot/video-vesa.c
5897 --- linux-2.6.36/arch/x86/boot/video-vesa.c 2010-10-20 16:30:22.000000000 -0400
5898 +++ linux-2.6.36/arch/x86/boot/video-vesa.c 2010-11-06 18:58:15.000000000 -0400
5899 @@ -200,6 +200,7 @@ static void vesa_store_pm_info(void)
5900
5901 boot_params.screen_info.vesapm_seg = oreg.es;
5902 boot_params.screen_info.vesapm_off = oreg.di;
5903 + boot_params.screen_info.vesapm_size = oreg.cx;
5904 }
5905
5906 /*
5907 diff -urNp linux-2.6.36/arch/x86/ia32/ia32_aout.c linux-2.6.36/arch/x86/ia32/ia32_aout.c
5908 --- linux-2.6.36/arch/x86/ia32/ia32_aout.c 2010-10-20 16:30:22.000000000 -0400
5909 +++ linux-2.6.36/arch/x86/ia32/ia32_aout.c 2010-11-06 18:58:50.000000000 -0400
5910 @@ -162,6 +162,8 @@ static int aout_core_dump(long signr, st
5911 unsigned long dump_start, dump_size;
5912 struct user32 dump;
5913
5914 + memset(&dump, 0, sizeof(dump));
5915 +
5916 fs = get_fs();
5917 set_fs(KERNEL_DS);
5918 has_dumped = 1;
5919 diff -urNp linux-2.6.36/arch/x86/ia32/ia32entry.S linux-2.6.36/arch/x86/ia32/ia32entry.S
5920 --- linux-2.6.36/arch/x86/ia32/ia32entry.S 2010-10-20 16:30:22.000000000 -0400
5921 +++ linux-2.6.36/arch/x86/ia32/ia32entry.S 2010-11-06 18:58:15.000000000 -0400
5922 @@ -13,6 +13,7 @@
5923 #include <asm/thread_info.h>
5924 #include <asm/segment.h>
5925 #include <asm/irqflags.h>
5926 +#include <asm/pgtable.h>
5927 #include <linux/linkage.h>
5928
5929 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
5930 @@ -120,6 +121,11 @@ ENTRY(ia32_sysenter_target)
5931 SWAPGS_UNSAFE_STACK
5932 movq PER_CPU_VAR(kernel_stack), %rsp
5933 addq $(KERNEL_STACK_OFFSET),%rsp
5934 +
5935 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5936 + call pax_enter_kernel_user
5937 +#endif
5938 +
5939 /*
5940 * No need to follow this irqs on/off section: the syscall
5941 * disabled irqs, here we enable it straight after entry:
5942 @@ -150,6 +156,12 @@ ENTRY(ia32_sysenter_target)
5943 SAVE_ARGS 0,0,1
5944 /* no need to do an access_ok check here because rbp has been
5945 32bit zero extended */
5946 +
5947 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5948 + mov $PAX_USER_SHADOW_BASE,%r10
5949 + add %r10,%rbp
5950 +#endif
5951 +
5952 1: movl (%rbp),%ebp
5953 .section __ex_table,"a"
5954 .quad 1b,ia32_badarg
5955 @@ -172,6 +184,11 @@ sysenter_dispatch:
5956 testl $_TIF_ALLWORK_MASK,TI_flags(%r10)
5957 jnz sysexit_audit
5958 sysexit_from_sys_call:
5959 +
5960 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5961 + call pax_exit_kernel_user
5962 +#endif
5963 +
5964 andl $~TS_COMPAT,TI_status(%r10)
5965 /* clear IF, that popfq doesn't enable interrupts early */
5966 andl $~0x200,EFLAGS-R11(%rsp)
5967 @@ -290,6 +307,11 @@ ENTRY(ia32_cstar_target)
5968 movl %esp,%r8d
5969 CFI_REGISTER rsp,r8
5970 movq PER_CPU_VAR(kernel_stack),%rsp
5971 +
5972 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5973 + call pax_enter_kernel_user
5974 +#endif
5975 +
5976 /*
5977 * No need to follow this irqs on/off section: the syscall
5978 * disabled irqs and here we enable it straight after entry:
5979 @@ -311,6 +333,12 @@ ENTRY(ia32_cstar_target)
5980 /* no need to do an access_ok check here because r8 has been
5981 32bit zero extended */
5982 /* hardware stack frame is complete now */
5983 +
5984 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5985 + mov $PAX_USER_SHADOW_BASE,%r10
5986 + add %r10,%r8
5987 +#endif
5988 +
5989 1: movl (%r8),%r9d
5990 .section __ex_table,"a"
5991 .quad 1b,ia32_badarg
5992 @@ -333,6 +361,11 @@ cstar_dispatch:
5993 testl $_TIF_ALLWORK_MASK,TI_flags(%r10)
5994 jnz sysretl_audit
5995 sysretl_from_sys_call:
5996 +
5997 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5998 + call pax_exit_kernel_user
5999 +#endif
6000 +
6001 andl $~TS_COMPAT,TI_status(%r10)
6002 RESTORE_ARGS 1,-ARG_SKIP,1,1,1
6003 movl RIP-ARGOFFSET(%rsp),%ecx
6004 @@ -415,6 +448,11 @@ ENTRY(ia32_syscall)
6005 CFI_REL_OFFSET rip,RIP-RIP
6006 PARAVIRT_ADJUST_EXCEPTION_FRAME
6007 SWAPGS
6008 +
6009 +#ifdef CONFIG_PAX_MEMORY_UDEREF
6010 + call pax_enter_kernel_user
6011 +#endif
6012 +
6013 /*
6014 * No need to follow this irqs on/off section: the syscall
6015 * disabled irqs and here we enable it straight after entry:
6016 diff -urNp linux-2.6.36/arch/x86/ia32/ia32_signal.c linux-2.6.36/arch/x86/ia32/ia32_signal.c
6017 --- linux-2.6.36/arch/x86/ia32/ia32_signal.c 2010-10-20 16:30:22.000000000 -0400
6018 +++ linux-2.6.36/arch/x86/ia32/ia32_signal.c 2010-11-06 18:58:15.000000000 -0400
6019 @@ -403,7 +403,7 @@ static void __user *get_sigframe(struct
6020 sp -= frame_size;
6021 /* Align the stack pointer according to the i386 ABI,
6022 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
6023 - sp = ((sp + 4) & -16ul) - 4;
6024 + sp = ((sp - 12) & -16ul) - 4;
6025 return (void __user *) sp;
6026 }
6027
6028 @@ -503,7 +503,7 @@ int ia32_setup_rt_frame(int sig, struct
6029 0xb8,
6030 __NR_ia32_rt_sigreturn,
6031 0x80cd,
6032 - 0,
6033 + 0
6034 };
6035
6036 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
6037 @@ -533,9 +533,11 @@ int ia32_setup_rt_frame(int sig, struct
6038
6039 if (ka->sa.sa_flags & SA_RESTORER)
6040 restorer = ka->sa.sa_restorer;
6041 + else if (current->mm->context.vdso)
6042 + /* Return stub is in 32bit vsyscall page */
6043 + restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6044 else
6045 - restorer = VDSO32_SYMBOL(current->mm->context.vdso,
6046 - rt_sigreturn);
6047 + restorer = &frame->retcode;
6048 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
6049
6050 /*
6051 diff -urNp linux-2.6.36/arch/x86/include/asm/alternative.h linux-2.6.36/arch/x86/include/asm/alternative.h
6052 --- linux-2.6.36/arch/x86/include/asm/alternative.h 2010-10-20 16:30:22.000000000 -0400
6053 +++ linux-2.6.36/arch/x86/include/asm/alternative.h 2010-11-06 18:58:15.000000000 -0400
6054 @@ -92,7 +92,7 @@ static inline int alternatives_text_rese
6055 ".section .discard,\"aw\",@progbits\n" \
6056 " .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */ \
6057 ".previous\n" \
6058 - ".section .altinstr_replacement, \"ax\"\n" \
6059 + ".section .altinstr_replacement, \"a\"\n" \
6060 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
6061 ".previous"
6062
6063 diff -urNp linux-2.6.36/arch/x86/include/asm/apm.h linux-2.6.36/arch/x86/include/asm/apm.h
6064 --- linux-2.6.36/arch/x86/include/asm/apm.h 2010-10-20 16:30:22.000000000 -0400
6065 +++ linux-2.6.36/arch/x86/include/asm/apm.h 2010-11-06 18:58:15.000000000 -0400
6066 @@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
6067 __asm__ __volatile__(APM_DO_ZERO_SEGS
6068 "pushl %%edi\n\t"
6069 "pushl %%ebp\n\t"
6070 - "lcall *%%cs:apm_bios_entry\n\t"
6071 + "lcall *%%ss:apm_bios_entry\n\t"
6072 "setc %%al\n\t"
6073 "popl %%ebp\n\t"
6074 "popl %%edi\n\t"
6075 @@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
6076 __asm__ __volatile__(APM_DO_ZERO_SEGS
6077 "pushl %%edi\n\t"
6078 "pushl %%ebp\n\t"
6079 - "lcall *%%cs:apm_bios_entry\n\t"
6080 + "lcall *%%ss:apm_bios_entry\n\t"
6081 "setc %%bl\n\t"
6082 "popl %%ebp\n\t"
6083 "popl %%edi\n\t"
6084 diff -urNp linux-2.6.36/arch/x86/include/asm/asm.h linux-2.6.36/arch/x86/include/asm/asm.h
6085 --- linux-2.6.36/arch/x86/include/asm/asm.h 2010-10-20 16:30:22.000000000 -0400
6086 +++ linux-2.6.36/arch/x86/include/asm/asm.h 2010-11-06 18:58:15.000000000 -0400
6087 @@ -37,6 +37,12 @@
6088 #define _ASM_SI __ASM_REG(si)
6089 #define _ASM_DI __ASM_REG(di)
6090
6091 +#ifdef CONFIG_X86_32
6092 +#define _ASM_INTO "into"
6093 +#else
6094 +#define _ASM_INTO "int $4"
6095 +#endif
6096 +
6097 /* Exception table entry */
6098 #ifdef __ASSEMBLY__
6099 # define _ASM_EXTABLE(from,to) \
6100 diff -urNp linux-2.6.36/arch/x86/include/asm/atomic64_32.h linux-2.6.36/arch/x86/include/asm/atomic64_32.h
6101 --- linux-2.6.36/arch/x86/include/asm/atomic64_32.h 2010-10-20 16:30:22.000000000 -0400
6102 +++ linux-2.6.36/arch/x86/include/asm/atomic64_32.h 2010-11-06 18:58:15.000000000 -0400
6103 @@ -12,6 +12,14 @@ typedef struct {
6104 u64 __aligned(8) counter;
6105 } atomic64_t;
6106
6107 +#ifdef CONFIG_PAX_REFCOUNT
6108 +typedef struct {
6109 + u64 __aligned(8) counter;
6110 +} atomic64_unchecked_t;
6111 +#else
6112 +typedef atomic64_t atomic64_unchecked_t;
6113 +#endif
6114 +
6115 #define ATOMIC64_INIT(val) { (val) }
6116
6117 #ifdef CONFIG_X86_CMPXCHG64
6118 diff -urNp linux-2.6.36/arch/x86/include/asm/atomic64_64.h linux-2.6.36/arch/x86/include/asm/atomic64_64.h
6119 --- linux-2.6.36/arch/x86/include/asm/atomic64_64.h 2010-10-20 16:30:22.000000000 -0400
6120 +++ linux-2.6.36/arch/x86/include/asm/atomic64_64.h 2010-11-06 18:58:15.000000000 -0400
6121 @@ -22,6 +22,18 @@ static inline long atomic64_read(const a
6122 }
6123
6124 /**
6125 + * atomic64_read_unchecked - read atomic64 variable
6126 + * @v: pointer of type atomic64_unchecked_t
6127 + *
6128 + * Atomically reads the value of @v.
6129 + * Doesn't imply a read memory barrier.
6130 + */
6131 +static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
6132 +{
6133 + return v->counter;
6134 +}
6135 +
6136 +/**
6137 * atomic64_set - set atomic64 variable
6138 * @v: pointer to type atomic64_t
6139 * @i: required value
6140 @@ -34,6 +46,18 @@ static inline void atomic64_set(atomic64
6141 }
6142
6143 /**
6144 + * atomic64_set_unchecked - set atomic64 variable
6145 + * @v: pointer to type atomic64_unchecked_t
6146 + * @i: required value
6147 + *
6148 + * Atomically sets the value of @v to @i.
6149 + */
6150 +static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
6151 +{
6152 + v->counter = i;
6153 +}
6154 +
6155 +/**
6156 * atomic64_add - add integer to atomic64 variable
6157 * @i: integer value to add
6158 * @v: pointer to type atomic64_t
6159 @@ -42,6 +66,28 @@ static inline void atomic64_set(atomic64
6160 */
6161 static inline void atomic64_add(long i, atomic64_t *v)
6162 {
6163 + asm volatile(LOCK_PREFIX "addq %1,%0\n"
6164 +
6165 +#ifdef CONFIG_PAX_REFCOUNT
6166 + "jno 0f\n"
6167 + LOCK_PREFIX "subq %1,%0\n"
6168 + "int $4\n0:\n"
6169 + _ASM_EXTABLE(0b, 0b)
6170 +#endif
6171 +
6172 + : "=m" (v->counter)
6173 + : "er" (i), "m" (v->counter));
6174 +}
6175 +
6176 +/**
6177 + * atomic64_add_unchecked - add integer to atomic64 variable
6178 + * @i: integer value to add
6179 + * @v: pointer to type atomic64_unchecked_t
6180 + *
6181 + * Atomically adds @i to @v.
6182 + */
6183 +static inline void atomic64_add_unchecked(long i, atomic64_unchecked_t *v)
6184 +{
6185 asm volatile(LOCK_PREFIX "addq %1,%0"
6186 : "=m" (v->counter)
6187 : "er" (i), "m" (v->counter));
6188 @@ -56,7 +102,29 @@ static inline void atomic64_add(long i,
6189 */
6190 static inline void atomic64_sub(long i, atomic64_t *v)
6191 {
6192 - asm volatile(LOCK_PREFIX "subq %1,%0"
6193 + asm volatile(LOCK_PREFIX "subq %1,%0\n"
6194 +
6195 +#ifdef CONFIG_PAX_REFCOUNT
6196 + "jno 0f\n"
6197 + LOCK_PREFIX "addq %1,%0\n"
6198 + "int $4\n0:\n"
6199 + _ASM_EXTABLE(0b, 0b)
6200 +#endif
6201 +
6202 + : "=m" (v->counter)
6203 + : "er" (i), "m" (v->counter));
6204 +}
6205 +
6206 +/**
6207 + * atomic64_sub_unchecked - subtract the atomic64 variable
6208 + * @i: integer value to subtract
6209 + * @v: pointer to type atomic64_unchecked_t
6210 + *
6211 + * Atomically subtracts @i from @v.
6212 + */
6213 +static inline void atomic64_sub_unchecked(long i, atomic64_unchecked_t *v)
6214 +{
6215 + asm volatile(LOCK_PREFIX "subq %1,%0\n"
6216 : "=m" (v->counter)
6217 : "er" (i), "m" (v->counter));
6218 }
6219 @@ -74,7 +142,16 @@ static inline int atomic64_sub_and_test(
6220 {
6221 unsigned char c;
6222
6223 - asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
6224 + asm volatile(LOCK_PREFIX "subq %2,%0\n"
6225 +
6226 +#ifdef CONFIG_PAX_REFCOUNT
6227 + "jno 0f\n"
6228 + LOCK_PREFIX "addq %2,%0\n"
6229 + "int $4\n0:\n"
6230 + _ASM_EXTABLE(0b, 0b)
6231 +#endif
6232 +
6233 + "sete %1\n"
6234 : "=m" (v->counter), "=qm" (c)
6235 : "er" (i), "m" (v->counter) : "memory");
6236 return c;
6237 @@ -88,6 +165,27 @@ static inline int atomic64_sub_and_test(
6238 */
6239 static inline void atomic64_inc(atomic64_t *v)
6240 {
6241 + asm volatile(LOCK_PREFIX "incq %0\n"
6242 +
6243 +#ifdef CONFIG_PAX_REFCOUNT
6244 + "jno 0f\n"
6245 + LOCK_PREFIX "decq %0\n"
6246 + "int $4\n0:\n"
6247 + _ASM_EXTABLE(0b, 0b)
6248 +#endif
6249 +
6250 + : "=m" (v->counter)
6251 + : "m" (v->counter));
6252 +}
6253 +
6254 +/**
6255 + * atomic64_inc_unchecked - increment atomic64 variable
6256 + * @v: pointer to type atomic64_unchecked_t
6257 + *
6258 + * Atomically increments @v by 1.
6259 + */
6260 +static inline void atomic64_inc_unchecked(atomic64_unchecked_t *v)
6261 +{
6262 asm volatile(LOCK_PREFIX "incq %0"
6263 : "=m" (v->counter)
6264 : "m" (v->counter));
6265 @@ -101,7 +199,28 @@ static inline void atomic64_inc(atomic64
6266 */
6267 static inline void atomic64_dec(atomic64_t *v)
6268 {
6269 - asm volatile(LOCK_PREFIX "decq %0"
6270 + asm volatile(LOCK_PREFIX "decq %0\n"
6271 +
6272 +#ifdef CONFIG_PAX_REFCOUNT
6273 + "jno 0f\n"
6274 + LOCK_PREFIX "incq %0\n"
6275 + "int $4\n0:\n"
6276 + _ASM_EXTABLE(0b, 0b)
6277 +#endif
6278 +
6279 + : "=m" (v->counter)
6280 + : "m" (v->counter));
6281 +}
6282 +
6283 +/**
6284 + * atomic64_dec_unchecked - decrement atomic64 variable
6285 + * @v: pointer to type atomic64_t
6286 + *
6287 + * Atomically decrements @v by 1.
6288 + */
6289 +static inline void atomic64_dec_unchecked(atomic64_unchecked_t *v)
6290 +{
6291 + asm volatile(LOCK_PREFIX "decq %0\n"
6292 : "=m" (v->counter)
6293 : "m" (v->counter));
6294 }
6295 @@ -118,7 +237,16 @@ static inline int atomic64_dec_and_test(
6296 {
6297 unsigned char c;
6298
6299 - asm volatile(LOCK_PREFIX "decq %0; sete %1"
6300 + asm volatile(LOCK_PREFIX "decq %0\n"
6301 +
6302 +#ifdef CONFIG_PAX_REFCOUNT
6303 + "jno 0f\n"
6304 + LOCK_PREFIX "incq %0\n"
6305 + "int $4\n0:\n"
6306 + _ASM_EXTABLE(0b, 0b)
6307 +#endif
6308 +
6309 + "sete %1\n"
6310 : "=m" (v->counter), "=qm" (c)
6311 : "m" (v->counter) : "memory");
6312 return c != 0;
6313 @@ -136,7 +264,16 @@ static inline int atomic64_inc_and_test(
6314 {
6315 unsigned char c;
6316
6317 - asm volatile(LOCK_PREFIX "incq %0; sete %1"
6318 + asm volatile(LOCK_PREFIX "incq %0\n"
6319 +
6320 +#ifdef CONFIG_PAX_REFCOUNT
6321 + "jno 0f\n"
6322 + LOCK_PREFIX "decq %0\n"
6323 + "int $4\n0:\n"
6324 + _ASM_EXTABLE(0b, 0b)
6325 +#endif
6326 +
6327 + "sete %1\n"
6328 : "=m" (v->counter), "=qm" (c)
6329 : "m" (v->counter) : "memory");
6330 return c != 0;
6331 @@ -155,7 +292,16 @@ static inline int atomic64_add_negative(
6332 {
6333 unsigned char c;
6334
6335 - asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
6336 + asm volatile(LOCK_PREFIX "addq %2,%0\n"
6337 +
6338 +#ifdef CONFIG_PAX_REFCOUNT
6339 + "jno 0f\n"
6340 + LOCK_PREFIX "subq %2,%0\n"
6341 + "int $4\n0:\n"
6342 + _ASM_EXTABLE(0b, 0b)
6343 +#endif
6344 +
6345 + "sets %1\n"
6346 : "=m" (v->counter), "=qm" (c)
6347 : "er" (i), "m" (v->counter) : "memory");
6348 return c;
6349 @@ -171,7 +317,31 @@ static inline int atomic64_add_negative(
6350 static inline long atomic64_add_return(long i, atomic64_t *v)
6351 {
6352 long __i = i;
6353 - asm volatile(LOCK_PREFIX "xaddq %0, %1;"
6354 + asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
6355 +
6356 +#ifdef CONFIG_PAX_REFCOUNT
6357 + "jno 0f\n"
6358 + "movq %0, %1\n"
6359 + "int $4\n0:\n"
6360 + _ASM_EXTABLE(0b, 0b)
6361 +#endif
6362 +
6363 + : "+r" (i), "+m" (v->counter)
6364 + : : "memory");
6365 + return i + __i;
6366 +}
6367 +
6368 +/**
6369 + * atomic64_add_return_unchecked - add and return
6370 + * @i: integer value to add
6371 + * @v: pointer to type atomic64_unchecked_t
6372 + *
6373 + * Atomically adds @i to @v and returns @i + @v
6374 + */
6375 +static inline long atomic64_add_return_unchecked(long i, atomic64_unchecked_t *v)
6376 +{
6377 + long __i = i;
6378 + asm volatile(LOCK_PREFIX "xaddq %0, %1"
6379 : "+r" (i), "+m" (v->counter)
6380 : : "memory");
6381 return i + __i;
6382 @@ -183,6 +353,10 @@ static inline long atomic64_sub_return(l
6383 }
6384
6385 #define atomic64_inc_return(v) (atomic64_add_return(1, (v)))
6386 +static inline long atomic64_inc_return_unchecked(atomic64_unchecked_t *v)
6387 +{
6388 + return atomic64_add_return_unchecked(1, v);
6389 +}
6390 #define atomic64_dec_return(v) (atomic64_sub_return(1, (v)))
6391
6392 static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
6393 @@ -206,17 +380,30 @@ static inline long atomic64_xchg(atomic6
6394 */
6395 static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
6396 {
6397 - long c, old;
6398 + long c, old, new;
6399 c = atomic64_read(v);
6400 for (;;) {
6401 - if (unlikely(c == (u)))
6402 + if (unlikely(c == u))
6403 break;
6404 - old = atomic64_cmpxchg((v), c, c + (a));
6405 +
6406 + asm volatile("add %2,%0\n"
6407 +
6408 +#ifdef CONFIG_PAX_REFCOUNT
6409 + "jno 0f\n"
6410 + "sub %2,%0\n"
6411 + "int $4\n0:\n"
6412 + _ASM_EXTABLE(0b, 0b)
6413 +#endif
6414 +
6415 + : "=r" (new)
6416 + : "0" (c), "ir" (a));
6417 +
6418 + old = atomic64_cmpxchg(v, c, new);
6419 if (likely(old == c))
6420 break;
6421 c = old;
6422 }
6423 - return c != (u);
6424 + return c != u;
6425 }
6426
6427 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
6428 diff -urNp linux-2.6.36/arch/x86/include/asm/atomic.h linux-2.6.36/arch/x86/include/asm/atomic.h
6429 --- linux-2.6.36/arch/x86/include/asm/atomic.h 2010-10-20 16:30:22.000000000 -0400
6430 +++ linux-2.6.36/arch/x86/include/asm/atomic.h 2010-11-06 18:58:15.000000000 -0400
6431 @@ -26,6 +26,17 @@ static inline int atomic_read(const atom
6432 }
6433
6434 /**
6435 + * atomic_read_unchecked - read atomic variable
6436 + * @v: pointer of type atomic_unchecked_t
6437 + *
6438 + * Atomically reads the value of @v.
6439 + */
6440 +static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
6441 +{
6442 + return v->counter;
6443 +}
6444 +
6445 +/**
6446 * atomic_set - set atomic variable
6447 * @v: pointer of type atomic_t
6448 * @i: required value
6449 @@ -38,6 +49,18 @@ static inline void atomic_set(atomic_t *
6450 }
6451
6452 /**
6453 + * atomic_set_unchecked - set atomic variable
6454 + * @v: pointer of type atomic_unchecked_t
6455 + * @i: required value
6456 + *
6457 + * Atomically sets the value of @v to @i.
6458 + */
6459 +static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
6460 +{
6461 + v->counter = i;
6462 +}
6463 +
6464 +/**
6465 * atomic_add - add integer to atomic variable
6466 * @i: integer value to add
6467 * @v: pointer of type atomic_t
6468 @@ -46,7 +69,29 @@ static inline void atomic_set(atomic_t *
6469 */
6470 static inline void atomic_add(int i, atomic_t *v)
6471 {
6472 - asm volatile(LOCK_PREFIX "addl %1,%0"
6473 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
6474 +
6475 +#ifdef CONFIG_PAX_REFCOUNT
6476 + "jno 0f\n"
6477 + LOCK_PREFIX "subl %1,%0\n"
6478 + _ASM_INTO "\n0:\n"
6479 + _ASM_EXTABLE(0b, 0b)
6480 +#endif
6481 +
6482 + : "+m" (v->counter)
6483 + : "ir" (i));
6484 +}
6485 +
6486 +/**
6487 + * atomic_add_unchecked - add integer to atomic variable
6488 + * @i: integer value to add
6489 + * @v: pointer of type atomic_unchecked_t
6490 + *
6491 + * Atomically adds @i to @v.
6492 + */
6493 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
6494 +{
6495 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
6496 : "+m" (v->counter)
6497 : "ir" (i));
6498 }
6499 @@ -60,7 +105,29 @@ static inline void atomic_add(int i, ato
6500 */
6501 static inline void atomic_sub(int i, atomic_t *v)
6502 {
6503 - asm volatile(LOCK_PREFIX "subl %1,%0"
6504 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
6505 +
6506 +#ifdef CONFIG_PAX_REFCOUNT
6507 + "jno 0f\n"
6508 + LOCK_PREFIX "addl %1,%0\n"
6509 + _ASM_INTO "\n0:\n"
6510 + _ASM_EXTABLE(0b, 0b)
6511 +#endif
6512 +
6513 + : "+m" (v->counter)
6514 + : "ir" (i));
6515 +}
6516 +
6517 +/**
6518 + * atomic_sub_unchecked - subtract integer from atomic variable
6519 + * @i: integer value to subtract
6520 + * @v: pointer of type atomic_t
6521 + *
6522 + * Atomically subtracts @i from @v.
6523 + */
6524 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
6525 +{
6526 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
6527 : "+m" (v->counter)
6528 : "ir" (i));
6529 }
6530 @@ -78,7 +145,16 @@ static inline int atomic_sub_and_test(in
6531 {
6532 unsigned char c;
6533
6534 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
6535 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
6536 +
6537 +#ifdef CONFIG_PAX_REFCOUNT
6538 + "jno 0f\n"
6539 + LOCK_PREFIX "addl %2,%0\n"
6540 + _ASM_INTO "\n0:\n"
6541 + _ASM_EXTABLE(0b, 0b)
6542 +#endif
6543 +
6544 + "sete %1\n"
6545 : "+m" (v->counter), "=qm" (c)
6546 : "ir" (i) : "memory");
6547 return c;
6548 @@ -92,7 +168,27 @@ static inline int atomic_sub_and_test(in
6549 */
6550 static inline void atomic_inc(atomic_t *v)
6551 {
6552 - asm volatile(LOCK_PREFIX "incl %0"
6553 + asm volatile(LOCK_PREFIX "incl %0\n"
6554 +
6555 +#ifdef CONFIG_PAX_REFCOUNT
6556 + "jno 0f\n"
6557 + LOCK_PREFIX "decl %0\n"
6558 + _ASM_INTO "\n0:\n"
6559 + _ASM_EXTABLE(0b, 0b)
6560 +#endif
6561 +
6562 + : "+m" (v->counter));
6563 +}
6564 +
6565 +/**
6566 + * atomic_inc_unchecked - increment atomic variable
6567 + * @v: pointer of type atomic_unchecked_t
6568 + *
6569 + * Atomically increments @v by 1.
6570 + */
6571 +static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
6572 +{
6573 + asm volatile(LOCK_PREFIX "incl %0\n"
6574 : "+m" (v->counter));
6575 }
6576
6577 @@ -104,7 +200,27 @@ static inline void atomic_inc(atomic_t *
6578 */
6579 static inline void atomic_dec(atomic_t *v)
6580 {
6581 - asm volatile(LOCK_PREFIX "decl %0"
6582 + asm volatile(LOCK_PREFIX "decl %0\n"
6583 +
6584 +#ifdef CONFIG_PAX_REFCOUNT
6585 + "jno 0f\n"
6586 + LOCK_PREFIX "incl %0\n"
6587 + _ASM_INTO "\n0:\n"
6588 + _ASM_EXTABLE(0b, 0b)
6589 +#endif
6590 +
6591 + : "+m" (v->counter));
6592 +}
6593 +
6594 +/**
6595 + * atomic_dec_unchecked - decrement atomic variable
6596 + * @v: pointer of type atomic_t
6597 + *
6598 + * Atomically decrements @v by 1.
6599 + */
6600 +static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
6601 +{
6602 + asm volatile(LOCK_PREFIX "decl %0\n"
6603 : "+m" (v->counter));
6604 }
6605
6606 @@ -120,7 +236,16 @@ static inline int atomic_dec_and_test(at
6607 {
6608 unsigned char c;
6609
6610 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
6611 + asm volatile(LOCK_PREFIX "decl %0\n"
6612 +
6613 +#ifdef CONFIG_PAX_REFCOUNT
6614 + "jno 0f\n"
6615 + LOCK_PREFIX "incl %0\n"
6616 + _ASM_INTO "\n0:\n"
6617 + _ASM_EXTABLE(0b, 0b)
6618 +#endif
6619 +
6620 + "sete %1\n"
6621 : "+m" (v->counter), "=qm" (c)
6622 : : "memory");
6623 return c != 0;
6624 @@ -138,7 +263,16 @@ static inline int atomic_inc_and_test(at
6625 {
6626 unsigned char c;
6627
6628 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
6629 + asm volatile(LOCK_PREFIX "incl %0\n"
6630 +
6631 +#ifdef CONFIG_PAX_REFCOUNT
6632 + "jno 0f\n"
6633 + LOCK_PREFIX "decl %0\n"
6634 + _ASM_INTO "\n0:\n"
6635 + _ASM_EXTABLE(0b, 0b)
6636 +#endif
6637 +
6638 + "sete %1\n"
6639 : "+m" (v->counter), "=qm" (c)
6640 : : "memory");
6641 return c != 0;
6642 @@ -157,7 +291,16 @@ static inline int atomic_add_negative(in
6643 {
6644 unsigned char c;
6645
6646 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
6647 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
6648 +
6649 +#ifdef CONFIG_PAX_REFCOUNT
6650 + "jno 0f\n"
6651 + LOCK_PREFIX "subl %2,%0\n"
6652 + _ASM_INTO "\n0:\n"
6653 + _ASM_EXTABLE(0b, 0b)
6654 +#endif
6655 +
6656 + "sets %1\n"
6657 : "+m" (v->counter), "=qm" (c)
6658 : "ir" (i) : "memory");
6659 return c;
6660 @@ -180,6 +323,46 @@ static inline int atomic_add_return(int
6661 #endif
6662 /* Modern 486+ processor */
6663 __i = i;
6664 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
6665 +
6666 +#ifdef CONFIG_PAX_REFCOUNT
6667 + "jno 0f\n"
6668 + "movl %0, %1\n"
6669 + _ASM_INTO "\n0:\n"
6670 + _ASM_EXTABLE(0b, 0b)
6671 +#endif
6672 +
6673 + : "+r" (i), "+m" (v->counter)
6674 + : : "memory");
6675 + return i + __i;
6676 +
6677 +#ifdef CONFIG_M386
6678 +no_xadd: /* Legacy 386 processor */
6679 + local_irq_save(flags);
6680 + __i = atomic_read(v);
6681 + atomic_set(v, i + __i);
6682 + local_irq_restore(flags);
6683 + return i + __i;
6684 +#endif
6685 +}
6686 +
6687 +/**
6688 + * atomic_add_return_unchecked - add integer and return
6689 + * @v: pointer of type atomic_unchecked_t
6690 + * @i: integer value to add
6691 + *
6692 + * Atomically adds @i to @v and returns @i + @v
6693 + */
6694 +static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
6695 +{
6696 + int __i;
6697 +#ifdef CONFIG_M386
6698 + unsigned long flags;
6699 + if (unlikely(boot_cpu_data.x86 <= 3))
6700 + goto no_xadd;
6701 +#endif
6702 + /* Modern 486+ processor */
6703 + __i = i;
6704 asm volatile(LOCK_PREFIX "xaddl %0, %1"
6705 : "+r" (i), "+m" (v->counter)
6706 : : "memory");
6707 @@ -208,6 +391,10 @@ static inline int atomic_sub_return(int
6708 }
6709
6710 #define atomic_inc_return(v) (atomic_add_return(1, v))
6711 +static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
6712 +{
6713 + return atomic_add_return_unchecked(1, v);
6714 +}
6715 #define atomic_dec_return(v) (atomic_sub_return(1, v))
6716
6717 static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
6718 @@ -231,17 +418,30 @@ static inline int atomic_xchg(atomic_t *
6719 */
6720 static inline int atomic_add_unless(atomic_t *v, int a, int u)
6721 {
6722 - int c, old;
6723 + int c, old, new;
6724 c = atomic_read(v);
6725 for (;;) {
6726 - if (unlikely(c == (u)))
6727 + if (unlikely(c == u))
6728 break;
6729 - old = atomic_cmpxchg((v), c, c + (a));
6730 +
6731 + asm volatile("addl %2,%0\n"
6732 +
6733 +#ifdef CONFIG_PAX_REFCOUNT
6734 + "jno 0f\n"
6735 + "subl %2,%0\n"
6736 + _ASM_INTO "\n0:\n"
6737 + _ASM_EXTABLE(0b, 0b)
6738 +#endif
6739 +
6740 + : "=r" (new)
6741 + : "0" (c), "ir" (a));
6742 +
6743 + old = atomic_cmpxchg(v, c, new);
6744 if (likely(old == c))
6745 break;
6746 c = old;
6747 }
6748 - return c != (u);
6749 + return c != u;
6750 }
6751
6752 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
6753 diff -urNp linux-2.6.36/arch/x86/include/asm/boot.h linux-2.6.36/arch/x86/include/asm/boot.h
6754 --- linux-2.6.36/arch/x86/include/asm/boot.h 2010-10-20 16:30:22.000000000 -0400
6755 +++ linux-2.6.36/arch/x86/include/asm/boot.h 2010-11-06 18:58:15.000000000 -0400
6756 @@ -11,10 +11,15 @@
6757 #include <asm/pgtable_types.h>
6758
6759 /* Physical address where kernel should be loaded. */
6760 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
6761 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
6762 + (CONFIG_PHYSICAL_ALIGN - 1)) \
6763 & ~(CONFIG_PHYSICAL_ALIGN - 1))
6764
6765 +#ifndef __ASSEMBLY__
6766 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
6767 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
6768 +#endif
6769 +
6770 /* Minimum kernel alignment, as a power of two */
6771 #ifdef CONFIG_X86_64
6772 #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT
6773 diff -urNp linux-2.6.36/arch/x86/include/asm/cacheflush.h linux-2.6.36/arch/x86/include/asm/cacheflush.h
6774 --- linux-2.6.36/arch/x86/include/asm/cacheflush.h 2010-10-20 16:30:22.000000000 -0400
6775 +++ linux-2.6.36/arch/x86/include/asm/cacheflush.h 2010-11-06 18:58:15.000000000 -0400
6776 @@ -66,7 +66,7 @@ static inline unsigned long get_page_mem
6777 unsigned long pg_flags = pg->flags & _PGMT_MASK;
6778
6779 if (pg_flags == _PGMT_DEFAULT)
6780 - return -1;
6781 + return ~0UL;
6782 else if (pg_flags == _PGMT_WC)
6783 return _PAGE_CACHE_WC;
6784 else if (pg_flags == _PGMT_UC_MINUS)
6785 diff -urNp linux-2.6.36/arch/x86/include/asm/cache.h linux-2.6.36/arch/x86/include/asm/cache.h
6786 --- linux-2.6.36/arch/x86/include/asm/cache.h 2010-10-20 16:30:22.000000000 -0400
6787 +++ linux-2.6.36/arch/x86/include/asm/cache.h 2010-11-06 18:58:15.000000000 -0400
6788 @@ -8,6 +8,7 @@
6789 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
6790
6791 #define __read_mostly __attribute__((__section__(".data..read_mostly")))
6792 +#define __read_only __attribute__((__section__(".data..read_only")))
6793
6794 #define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT
6795 #define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
6796 diff -urNp linux-2.6.36/arch/x86/include/asm/checksum_32.h linux-2.6.36/arch/x86/include/asm/checksum_32.h
6797 --- linux-2.6.36/arch/x86/include/asm/checksum_32.h 2010-10-20 16:30:22.000000000 -0400
6798 +++ linux-2.6.36/arch/x86/include/asm/checksum_32.h 2010-11-06 18:58:15.000000000 -0400
6799 @@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
6800 int len, __wsum sum,
6801 int *src_err_ptr, int *dst_err_ptr);
6802
6803 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
6804 + int len, __wsum sum,
6805 + int *src_err_ptr, int *dst_err_ptr);
6806 +
6807 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
6808 + int len, __wsum sum,
6809 + int *src_err_ptr, int *dst_err_ptr);
6810 +
6811 /*
6812 * Note: when you get a NULL pointer exception here this means someone
6813 * passed in an incorrect kernel address to one of these functions.
6814 @@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
6815 int *err_ptr)
6816 {
6817 might_sleep();
6818 - return csum_partial_copy_generic((__force void *)src, dst,
6819 + return csum_partial_copy_generic_from_user((__force void *)src, dst,
6820 len, sum, err_ptr, NULL);
6821 }
6822
6823 @@ -178,7 +186,7 @@ static inline __wsum csum_and_copy_to_us
6824 {
6825 might_sleep();
6826 if (access_ok(VERIFY_WRITE, dst, len))
6827 - return csum_partial_copy_generic(src, (__force void *)dst,
6828 + return csum_partial_copy_generic_to_user(src, (__force void *)dst,
6829 len, sum, NULL, err_ptr);
6830
6831 if (len)
6832 diff -urNp linux-2.6.36/arch/x86/include/asm/cpufeature.h linux-2.6.36/arch/x86/include/asm/cpufeature.h
6833 --- linux-2.6.36/arch/x86/include/asm/cpufeature.h 2010-10-20 16:30:22.000000000 -0400
6834 +++ linux-2.6.36/arch/x86/include/asm/cpufeature.h 2010-11-06 18:58:15.000000000 -0400
6835 @@ -338,7 +338,7 @@ static __always_inline __pure bool __sta
6836 ".section .discard,\"aw\",@progbits\n"
6837 " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
6838 ".previous\n"
6839 - ".section .altinstr_replacement,\"ax\"\n"
6840 + ".section .altinstr_replacement,\"a\"\n"
6841 "3: movb $1,%0\n"
6842 "4:\n"
6843 ".previous\n"
6844 diff -urNp linux-2.6.36/arch/x86/include/asm/desc.h linux-2.6.36/arch/x86/include/asm/desc.h
6845 --- linux-2.6.36/arch/x86/include/asm/desc.h 2010-10-20 16:30:22.000000000 -0400
6846 +++ linux-2.6.36/arch/x86/include/asm/desc.h 2010-11-06 18:58:15.000000000 -0400
6847 @@ -4,6 +4,7 @@
6848 #include <asm/desc_defs.h>
6849 #include <asm/ldt.h>
6850 #include <asm/mmu.h>
6851 +#include <asm/pgtable.h>
6852 #include <linux/smp.h>
6853
6854 static inline void fill_ldt(struct desc_struct *desc,
6855 @@ -15,6 +16,7 @@ static inline void fill_ldt(struct desc_
6856 desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
6857 desc->type = (info->read_exec_only ^ 1) << 1;
6858 desc->type |= info->contents << 2;
6859 + desc->type |= info->seg_not_present ^ 1;
6860 desc->s = 1;
6861 desc->dpl = 0x3;
6862 desc->p = info->seg_not_present ^ 1;
6863 @@ -31,16 +33,12 @@ static inline void fill_ldt(struct desc_
6864 }
6865
6866 extern struct desc_ptr idt_descr;
6867 -extern gate_desc idt_table[];
6868 -
6869 -struct gdt_page {
6870 - struct desc_struct gdt[GDT_ENTRIES];
6871 -} __attribute__((aligned(PAGE_SIZE)));
6872 -DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
6873 +extern gate_desc idt_table[256];
6874
6875 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
6876 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
6877 {
6878 - return per_cpu(gdt_page, cpu).gdt;
6879 + return cpu_gdt_table[cpu];
6880 }
6881
6882 #ifdef CONFIG_X86_64
6883 @@ -115,19 +113,24 @@ static inline void paravirt_free_ldt(str
6884 static inline void native_write_idt_entry(gate_desc *idt, int entry,
6885 const gate_desc *gate)
6886 {
6887 + pax_open_kernel();
6888 memcpy(&idt[entry], gate, sizeof(*gate));
6889 + pax_close_kernel();
6890 }
6891
6892 static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
6893 const void *desc)
6894 {
6895 + pax_open_kernel();
6896 memcpy(&ldt[entry], desc, 8);
6897 + pax_close_kernel();
6898 }
6899
6900 static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
6901 const void *desc, int type)
6902 {
6903 unsigned int size;
6904 +
6905 switch (type) {
6906 case DESC_TSS:
6907 size = sizeof(tss_desc);
6908 @@ -139,7 +142,10 @@ static inline void native_write_gdt_entr
6909 size = sizeof(struct desc_struct);
6910 break;
6911 }
6912 +
6913 + pax_open_kernel();
6914 memcpy(&gdt[entry], desc, size);
6915 + pax_close_kernel();
6916 }
6917
6918 static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
6919 @@ -211,7 +217,9 @@ static inline void native_set_ldt(const
6920
6921 static inline void native_load_tr_desc(void)
6922 {
6923 + pax_open_kernel();
6924 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
6925 + pax_close_kernel();
6926 }
6927
6928 static inline void native_load_gdt(const struct desc_ptr *dtr)
6929 @@ -246,8 +254,10 @@ static inline void native_load_tls(struc
6930 unsigned int i;
6931 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
6932
6933 + pax_open_kernel();
6934 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
6935 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
6936 + pax_close_kernel();
6937 }
6938
6939 #define _LDT_empty(info) \
6940 @@ -309,7 +319,7 @@ static inline void set_desc_limit(struct
6941 desc->limit = (limit >> 16) & 0xf;
6942 }
6943
6944 -static inline void _set_gate(int gate, unsigned type, void *addr,
6945 +static inline void _set_gate(int gate, unsigned type, const void *addr,
6946 unsigned dpl, unsigned ist, unsigned seg)
6947 {
6948 gate_desc s;
6949 @@ -327,7 +337,7 @@ static inline void _set_gate(int gate, u
6950 * Pentium F0 0F bugfix can have resulted in the mapped
6951 * IDT being write-protected.
6952 */
6953 -static inline void set_intr_gate(unsigned int n, void *addr)
6954 +static inline void set_intr_gate(unsigned int n, const void *addr)
6955 {
6956 BUG_ON((unsigned)n > 0xFF);
6957 _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
6958 @@ -356,19 +366,19 @@ static inline void alloc_intr_gate(unsig
6959 /*
6960 * This routine sets up an interrupt gate at directory privilege level 3.
6961 */
6962 -static inline void set_system_intr_gate(unsigned int n, void *addr)
6963 +static inline void set_system_intr_gate(unsigned int n, const void *addr)
6964 {
6965 BUG_ON((unsigned)n > 0xFF);
6966 _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
6967 }
6968
6969 -static inline void set_system_trap_gate(unsigned int n, void *addr)
6970 +static inline void set_system_trap_gate(unsigned int n, const void *addr)
6971 {
6972 BUG_ON((unsigned)n > 0xFF);
6973 _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS);
6974 }
6975
6976 -static inline void set_trap_gate(unsigned int n, void *addr)
6977 +static inline void set_trap_gate(unsigned int n, const void *addr)
6978 {
6979 BUG_ON((unsigned)n > 0xFF);
6980 _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS);
6981 @@ -377,19 +387,31 @@ static inline void set_trap_gate(unsigne
6982 static inline void set_task_gate(unsigned int n, unsigned int gdt_entry)
6983 {
6984 BUG_ON((unsigned)n > 0xFF);
6985 - _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3));
6986 + _set_gate(n, GATE_TASK, (const void *)0, 0, 0, (gdt_entry<<3));
6987 }
6988
6989 -static inline void set_intr_gate_ist(int n, void *addr, unsigned ist)
6990 +static inline void set_intr_gate_ist(int n, const void *addr, unsigned ist)
6991 {
6992 BUG_ON((unsigned)n > 0xFF);
6993 _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS);
6994 }
6995
6996 -static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist)
6997 +static inline void set_system_intr_gate_ist(int n, const void *addr, unsigned ist)
6998 {
6999 BUG_ON((unsigned)n > 0xFF);
7000 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
7001 }
7002
7003 +#ifdef CONFIG_X86_32
7004 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
7005 +{
7006 + struct desc_struct d;
7007 +
7008 + if (likely(limit))
7009 + limit = (limit - 1UL) >> PAGE_SHIFT;
7010 + pack_descriptor(&d, base, limit, 0xFB, 0xC);
7011 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
7012 +}
7013 +#endif
7014 +
7015 #endif /* _ASM_X86_DESC_H */
7016 diff -urNp linux-2.6.36/arch/x86/include/asm/device.h linux-2.6.36/arch/x86/include/asm/device.h
7017 --- linux-2.6.36/arch/x86/include/asm/device.h 2010-10-20 16:30:22.000000000 -0400
7018 +++ linux-2.6.36/arch/x86/include/asm/device.h 2010-11-06 18:58:15.000000000 -0400
7019 @@ -6,7 +6,7 @@ struct dev_archdata {
7020 void *acpi_handle;
7021 #endif
7022 #ifdef CONFIG_X86_64
7023 -struct dma_map_ops *dma_ops;
7024 + const struct dma_map_ops *dma_ops;
7025 #endif
7026 #if defined(CONFIG_DMAR) || defined(CONFIG_AMD_IOMMU)
7027 void *iommu; /* hook for IOMMU specific extension */
7028 diff -urNp linux-2.6.36/arch/x86/include/asm/dma-mapping.h linux-2.6.36/arch/x86/include/asm/dma-mapping.h
7029 --- linux-2.6.36/arch/x86/include/asm/dma-mapping.h 2010-10-20 16:30:22.000000000 -0400
7030 +++ linux-2.6.36/arch/x86/include/asm/dma-mapping.h 2010-11-06 18:58:15.000000000 -0400
7031 @@ -26,9 +26,9 @@ extern int iommu_merge;
7032 extern struct device x86_dma_fallback_dev;
7033 extern int panic_on_overflow;
7034
7035 -extern struct dma_map_ops *dma_ops;
7036 +extern const struct dma_map_ops *dma_ops;
7037
7038 -static inline struct dma_map_ops *get_dma_ops(struct device *dev)
7039 +static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
7040 {
7041 #ifdef CONFIG_X86_32
7042 return dma_ops;
7043 @@ -45,7 +45,7 @@ static inline struct dma_map_ops *get_dm
7044 /* Make sure we keep the same behaviour */
7045 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
7046 {
7047 - struct dma_map_ops *ops = get_dma_ops(dev);
7048 + const struct dma_map_ops *ops = get_dma_ops(dev);
7049 if (ops->mapping_error)
7050 return ops->mapping_error(dev, dma_addr);
7051
7052 @@ -115,7 +115,7 @@ static inline void *
7053 dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
7054 gfp_t gfp)
7055 {
7056 - struct dma_map_ops *ops = get_dma_ops(dev);
7057 + const struct dma_map_ops *ops = get_dma_ops(dev);
7058 void *memory;
7059
7060 gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
7061 @@ -142,7 +142,7 @@ dma_alloc_coherent(struct device *dev, s
7062 static inline void dma_free_coherent(struct device *dev, size_t size,
7063 void *vaddr, dma_addr_t bus)
7064 {
7065 - struct dma_map_ops *ops = get_dma_ops(dev);
7066 + const struct dma_map_ops *ops = get_dma_ops(dev);
7067
7068 WARN_ON(irqs_disabled()); /* for portability */
7069
7070 diff -urNp linux-2.6.36/arch/x86/include/asm/e820.h linux-2.6.36/arch/x86/include/asm/e820.h
7071 --- linux-2.6.36/arch/x86/include/asm/e820.h 2010-10-20 16:30:22.000000000 -0400
7072 +++ linux-2.6.36/arch/x86/include/asm/e820.h 2010-11-06 18:58:15.000000000 -0400
7073 @@ -69,7 +69,7 @@ struct e820map {
7074 #define ISA_START_ADDRESS 0xa0000
7075 #define ISA_END_ADDRESS 0x100000
7076
7077 -#define BIOS_BEGIN 0x000a0000
7078 +#define BIOS_BEGIN 0x000c0000
7079 #define BIOS_END 0x00100000
7080
7081 #ifdef __KERNEL__
7082 diff -urNp linux-2.6.36/arch/x86/include/asm/elf.h linux-2.6.36/arch/x86/include/asm/elf.h
7083 --- linux-2.6.36/arch/x86/include/asm/elf.h 2010-10-20 16:30:22.000000000 -0400
7084 +++ linux-2.6.36/arch/x86/include/asm/elf.h 2010-11-06 18:58:15.000000000 -0400
7085 @@ -237,7 +237,25 @@ extern int force_personality32;
7086 the loader. We need to make sure that it is out of the way of the program
7087 that it will "exec", and that there is sufficient room for the brk. */
7088
7089 +#ifdef CONFIG_PAX_SEGMEXEC
7090 +#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
7091 +#else
7092 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
7093 +#endif
7094 +
7095 +#ifdef CONFIG_PAX_ASLR
7096 +#ifdef CONFIG_X86_32
7097 +#define PAX_ELF_ET_DYN_BASE 0x10000000UL
7098 +
7099 +#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
7100 +#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
7101 +#else
7102 +#define PAX_ELF_ET_DYN_BASE 0x400000UL
7103 +
7104 +#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : TASK_SIZE_MAX_SHIFT - PAGE_SHIFT - 3)
7105 +#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : TASK_SIZE_MAX_SHIFT - PAGE_SHIFT - 3)
7106 +#endif
7107 +#endif
7108
7109 /* This yields a mask that user programs can use to figure out what
7110 instruction set this CPU supports. This could be done in user space,
7111 @@ -291,8 +309,7 @@ do { \
7112 #define ARCH_DLINFO \
7113 do { \
7114 if (vdso_enabled) \
7115 - NEW_AUX_ENT(AT_SYSINFO_EHDR, \
7116 - (unsigned long)current->mm->context.vdso); \
7117 + NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
7118 } while (0)
7119
7120 #define AT_SYSINFO 32
7121 @@ -303,7 +320,7 @@ do { \
7122
7123 #endif /* !CONFIG_X86_32 */
7124
7125 -#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
7126 +#define VDSO_CURRENT_BASE (current->mm->context.vdso)
7127
7128 #define VDSO_ENTRY \
7129 ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
7130 @@ -317,7 +334,4 @@ extern int arch_setup_additional_pages(s
7131 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
7132 #define compat_arch_setup_additional_pages syscall32_setup_pages
7133
7134 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
7135 -#define arch_randomize_brk arch_randomize_brk
7136 -
7137 #endif /* _ASM_X86_ELF_H */
7138 diff -urNp linux-2.6.36/arch/x86/include/asm/futex.h linux-2.6.36/arch/x86/include/asm/futex.h
7139 --- linux-2.6.36/arch/x86/include/asm/futex.h 2010-10-20 16:30:22.000000000 -0400
7140 +++ linux-2.6.36/arch/x86/include/asm/futex.h 2010-11-06 18:58:15.000000000 -0400
7141 @@ -11,17 +11,54 @@
7142 #include <asm/processor.h>
7143 #include <asm/system.h>
7144
7145 +#ifdef CONFIG_X86_32
7146 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
7147 + asm volatile( \
7148 + "movw\t%w6, %%ds\n" \
7149 + "1:\t" insn "\n" \
7150 + "2:\tpushl\t%%ss\n" \
7151 + "\tpopl\t%%ds\n" \
7152 + "\t.section .fixup,\"ax\"\n" \
7153 + "3:\tmov\t%3, %1\n" \
7154 + "\tjmp\t2b\n" \
7155 + "\t.previous\n" \
7156 + _ASM_EXTABLE(1b, 3b) \
7157 + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
7158 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
7159 +
7160 +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
7161 + asm volatile("movw\t%w7, %%es\n" \
7162 + "1:\tmovl\t%%es:%2, %0\n" \
7163 + "\tmovl\t%0, %3\n" \
7164 + "\t" insn "\n" \
7165 + "2:\t" LOCK_PREFIX "cmpxchgl %3, %%es:%2\n"\
7166 + "\tjnz\t1b\n" \
7167 + "3:\tpushl\t%%ss\n" \
7168 + "\tpopl\t%%es\n" \
7169 + "\t.section .fixup,\"ax\"\n" \
7170 + "4:\tmov\t%5, %1\n" \
7171 + "\tjmp\t3b\n" \
7172 + "\t.previous\n" \
7173 + _ASM_EXTABLE(1b, 4b) \
7174 + _ASM_EXTABLE(2b, 4b) \
7175 + : "=&a" (oldval), "=&r" (ret), \
7176 + "+m" (*uaddr), "=&r" (tem) \
7177 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
7178 +#else
7179 +#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
7180 + typecheck(u32 *, uaddr); \
7181 asm volatile("1:\t" insn "\n" \
7182 "2:\t.section .fixup,\"ax\"\n" \
7183 "3:\tmov\t%3, %1\n" \
7184 "\tjmp\t2b\n" \
7185 "\t.previous\n" \
7186 _ASM_EXTABLE(1b, 3b) \
7187 - : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
7188 + : "=r" (oldval), "=r" (ret), \
7189 + "+m" (*(uaddr + PAX_USER_SHADOW_BASE / 4))\
7190 : "i" (-EFAULT), "0" (oparg), "1" (0))
7191
7192 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
7193 + typecheck(u32 *, uaddr); \
7194 asm volatile("1:\tmovl %2, %0\n" \
7195 "\tmovl\t%0, %3\n" \
7196 "\t" insn "\n" \
7197 @@ -34,10 +71,12 @@
7198 _ASM_EXTABLE(1b, 4b) \
7199 _ASM_EXTABLE(2b, 4b) \
7200 : "=&a" (oldval), "=&r" (ret), \
7201 - "+m" (*uaddr), "=&r" (tem) \
7202 + "+m" (*(uaddr + PAX_USER_SHADOW_BASE / 4)),\
7203 + "=&r" (tem) \
7204 : "r" (oparg), "i" (-EFAULT), "1" (0))
7205 +#endif
7206
7207 -static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
7208 +static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
7209 {
7210 int op = (encoded_op >> 28) & 7;
7211 int cmp = (encoded_op >> 24) & 15;
7212 @@ -61,11 +100,20 @@ static inline int futex_atomic_op_inuser
7213
7214 switch (op) {
7215 case FUTEX_OP_SET:
7216 +#ifdef CONFIG_X86_32
7217 + __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
7218 +#else
7219 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
7220 +#endif
7221 break;
7222 case FUTEX_OP_ADD:
7223 +#ifdef CONFIG_X86_32
7224 + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret, oldval,
7225 + uaddr, oparg);
7226 +#else
7227 __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
7228 uaddr, oparg);
7229 +#endif
7230 break;
7231 case FUTEX_OP_OR:
7232 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
7233 @@ -109,7 +157,7 @@ static inline int futex_atomic_op_inuser
7234 return ret;
7235 }
7236
7237 -static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
7238 +static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
7239 int newval)
7240 {
7241
7242 @@ -119,17 +167,31 @@ static inline int futex_atomic_cmpxchg_i
7243 return -ENOSYS;
7244 #endif
7245
7246 - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
7247 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
7248 return -EFAULT;
7249
7250 - asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
7251 - "2:\t.section .fixup, \"ax\"\n"
7252 + asm volatile(
7253 +#ifdef CONFIG_X86_32
7254 + "\tmovw %w5, %%ds\n"
7255 + "1:\t" LOCK_PREFIX "cmpxchgl %3, %%ds:%1\n"
7256 + "2:\tpushl %%ss\n"
7257 + "\tpopl %%ds\n"
7258 +#else
7259 + "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
7260 + "2:\n"
7261 +#endif
7262 + "\t.section .fixup, \"ax\"\n"
7263 "3:\tmov %2, %0\n"
7264 "\tjmp 2b\n"
7265 "\t.previous\n"
7266 _ASM_EXTABLE(1b, 3b)
7267 +#ifdef CONFIG_X86_32
7268 : "=a" (oldval), "+m" (*uaddr)
7269 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
7270 +#else
7271 + : "=a" (oldval), "+m" (*(uaddr + PAX_USER_SHADOW_BASE / 4))
7272 : "i" (-EFAULT), "r" (newval), "0" (oldval)
7273 +#endif
7274 : "memory"
7275 );
7276
7277 diff -urNp linux-2.6.36/arch/x86/include/asm/i387.h linux-2.6.36/arch/x86/include/asm/i387.h
7278 --- linux-2.6.36/arch/x86/include/asm/i387.h 2010-10-20 16:30:22.000000000 -0400
7279 +++ linux-2.6.36/arch/x86/include/asm/i387.h 2010-11-06 18:58:15.000000000 -0400
7280 @@ -90,6 +90,11 @@ static inline int fxrstor_checking(struc
7281 {
7282 int err;
7283
7284 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
7285 + if ((unsigned long)fx < PAX_USER_SHADOW_BASE)
7286 + fx = (struct i387_fxsave_struct *)((void *)fx + PAX_USER_SHADOW_BASE);
7287 +#endif
7288 +
7289 asm volatile("1: rex64/fxrstor (%[fx])\n\t"
7290 "2:\n"
7291 ".section .fixup,\"ax\"\n"
7292 @@ -140,6 +145,11 @@ static inline int fxsave_user(struct i38
7293 {
7294 int err;
7295
7296 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
7297 + if ((unsigned long)fx < PAX_USER_SHADOW_BASE)
7298 + fx = (struct i387_fxsave_struct __user *)((void __user *)fx + PAX_USER_SHADOW_BASE);
7299 +#endif
7300 +
7301 /*
7302 * Clear the bytes not touched by the fxsave and reserved
7303 * for the SW usage.
7304 @@ -242,13 +252,8 @@ static inline int fxrstor_checking(struc
7305 }
7306
7307 /* We need a safe address that is cheap to find and that is already
7308 - in L1 during context switch. The best choices are unfortunately
7309 - different for UP and SMP */
7310 -#ifdef CONFIG_SMP
7311 -#define safe_address (__per_cpu_offset[0])
7312 -#else
7313 -#define safe_address (kstat_cpu(0).cpustat.user)
7314 -#endif
7315 + in L1 during context switch. */
7316 +#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
7317
7318 /*
7319 * These must be called with preempt disabled
7320 diff -urNp linux-2.6.36/arch/x86/include/asm/io.h linux-2.6.36/arch/x86/include/asm/io.h
7321 --- linux-2.6.36/arch/x86/include/asm/io.h 2010-10-20 16:30:22.000000000 -0400
7322 +++ linux-2.6.36/arch/x86/include/asm/io.h 2010-11-06 18:58:15.000000000 -0400
7323 @@ -213,6 +213,17 @@ extern void iounmap(volatile void __iome
7324
7325 #include <linux/vmalloc.h>
7326
7327 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
7328 +static inline int valid_phys_addr_range(unsigned long addr, size_t count)
7329 +{
7330 + return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
7331 +}
7332 +
7333 +static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t count)
7334 +{
7335 + return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
7336 +}
7337 +
7338 /*
7339 * Convert a virtual cached pointer to an uncached pointer
7340 */
7341 diff -urNp linux-2.6.36/arch/x86/include/asm/iommu.h linux-2.6.36/arch/x86/include/asm/iommu.h
7342 --- linux-2.6.36/arch/x86/include/asm/iommu.h 2010-10-20 16:30:22.000000000 -0400
7343 +++ linux-2.6.36/arch/x86/include/asm/iommu.h 2010-11-06 18:58:15.000000000 -0400
7344 @@ -1,7 +1,7 @@
7345 #ifndef _ASM_X86_IOMMU_H
7346 #define _ASM_X86_IOMMU_H
7347
7348 -extern struct dma_map_ops nommu_dma_ops;
7349 +extern const struct dma_map_ops nommu_dma_ops;
7350 extern int force_iommu, no_iommu;
7351 extern int iommu_detected;
7352 extern int iommu_pass_through;
7353 diff -urNp linux-2.6.36/arch/x86/include/asm/irqflags.h linux-2.6.36/arch/x86/include/asm/irqflags.h
7354 --- linux-2.6.36/arch/x86/include/asm/irqflags.h 2010-10-20 16:30:22.000000000 -0400
7355 +++ linux-2.6.36/arch/x86/include/asm/irqflags.h 2010-11-06 18:58:15.000000000 -0400
7356 @@ -142,6 +142,11 @@ static inline unsigned long __raw_local_
7357 sti; \
7358 sysexit
7359
7360 +#define GET_CR0_INTO_RDI mov %cr0, %rdi
7361 +#define SET_RDI_INTO_CR0 mov %rdi, %cr0
7362 +#define GET_CR3_INTO_RDI mov %cr3, %rdi
7363 +#define SET_RDI_INTO_CR3 mov %rdi, %cr3
7364 +
7365 #else
7366 #define INTERRUPT_RETURN iret
7367 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
7368 diff -urNp linux-2.6.36/arch/x86/include/asm/kvm_host.h linux-2.6.36/arch/x86/include/asm/kvm_host.h
7369 --- linux-2.6.36/arch/x86/include/asm/kvm_host.h 2010-10-20 16:30:22.000000000 -0400
7370 +++ linux-2.6.36/arch/x86/include/asm/kvm_host.h 2010-11-06 18:58:15.000000000 -0400
7371 @@ -525,7 +525,7 @@ struct kvm_x86_ops {
7372 const struct trace_print_flags *exit_reasons_str;
7373 };
7374
7375 -extern struct kvm_x86_ops *kvm_x86_ops;
7376 +extern const struct kvm_x86_ops *kvm_x86_ops;
7377
7378 int kvm_mmu_module_init(void);
7379 void kvm_mmu_module_exit(void);
7380 diff -urNp linux-2.6.36/arch/x86/include/asm/local.h linux-2.6.36/arch/x86/include/asm/local.h
7381 --- linux-2.6.36/arch/x86/include/asm/local.h 2010-10-20 16:30:22.000000000 -0400
7382 +++ linux-2.6.36/arch/x86/include/asm/local.h 2010-11-06 18:58:15.000000000 -0400
7383 @@ -18,26 +18,90 @@ typedef struct {
7384
7385 static inline void local_inc(local_t *l)
7386 {
7387 - asm volatile(_ASM_INC "%0"
7388 + asm volatile(_ASM_INC "%0\n"
7389 +
7390 +#ifdef CONFIG_PAX_REFCOUNT
7391 +#ifdef CONFIG_X86_32
7392 + "into\n0:\n"
7393 +#else
7394 + "jno 0f\n"
7395 + "int $4\n0:\n"
7396 +#endif
7397 + ".pushsection .fixup,\"ax\"\n"
7398 + "1:\n"
7399 + _ASM_DEC "%0\n"
7400 + "jmp 0b\n"
7401 + ".popsection\n"
7402 + _ASM_EXTABLE(0b, 1b)
7403 +#endif
7404 +
7405 : "+m" (l->a.counter));
7406 }
7407
7408 static inline void local_dec(local_t *l)
7409 {
7410 - asm volatile(_ASM_DEC "%0"
7411 + asm volatile(_ASM_DEC "%0\n"
7412 +
7413 +#ifdef CONFIG_PAX_REFCOUNT
7414 +#ifdef CONFIG_X86_32
7415 + "into\n0:\n"
7416 +#else
7417 + "jno 0f\n"
7418 + "int $4\n0:\n"
7419 +#endif
7420 + ".pushsection .fixup,\"ax\"\n"
7421 + "1:\n"
7422 + _ASM_INC "%0\n"
7423 + "jmp 0b\n"
7424 + ".popsection\n"
7425 + _ASM_EXTABLE(0b, 1b)
7426 +#endif
7427 +
7428 : "+m" (l->a.counter));
7429 }
7430
7431 static inline void local_add(long i, local_t *l)
7432 {
7433 - asm volatile(_ASM_ADD "%1,%0"
7434 + asm volatile(_ASM_ADD "%1,%0\n"
7435 +
7436 +#ifdef CONFIG_PAX_REFCOUNT
7437 +#ifdef CONFIG_X86_32
7438 + "into\n0:\n"
7439 +#else
7440 + "jno 0f\n"
7441 + "int $4\n0:\n"
7442 +#endif
7443 + ".pushsection .fixup,\"ax\"\n"
7444 + "1:\n"
7445 + _ASM_SUB "%1,%0\n"
7446 + "jmp 0b\n"
7447 + ".popsection\n"
7448 + _ASM_EXTABLE(0b, 1b)
7449 +#endif
7450 +
7451 : "+m" (l->a.counter)
7452 : "ir" (i));
7453 }
7454
7455 static inline void local_sub(long i, local_t *l)
7456 {
7457 - asm volatile(_ASM_SUB "%1,%0"
7458 + asm volatile(_ASM_SUB "%1,%0\n"
7459 +
7460 +#ifdef CONFIG_PAX_REFCOUNT
7461 +#ifdef CONFIG_X86_32
7462 + "into\n0:\n"
7463 +#else
7464 + "jno 0f\n"
7465 + "int $4\n0:\n"
7466 +#endif
7467 + ".pushsection .fixup,\"ax\"\n"
7468 + "1:\n"
7469 + _ASM_ADD "%1,%0\n"
7470 + "jmp 0b\n"
7471 + ".popsection\n"
7472 + _ASM_EXTABLE(0b, 1b)
7473 +#endif
7474 +
7475 : "+m" (l->a.counter)
7476 : "ir" (i));
7477 }
7478 @@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
7479 {
7480 unsigned char c;
7481
7482 - asm volatile(_ASM_SUB "%2,%0; sete %1"
7483 + asm volatile(_ASM_SUB "%2,%0\n"
7484 +
7485 +#ifdef CONFIG_PAX_REFCOUNT
7486 +#ifdef CONFIG_X86_32
7487 + "into\n0:\n"
7488 +#else
7489 + "jno 0f\n"
7490 + "int $4\n0:\n"
7491 +#endif
7492 + ".pushsection .fixup,\"ax\"\n"
7493 + "1:\n"
7494 + _ASM_ADD "%2,%0\n"
7495 + "jmp 0b\n"
7496 + ".popsection\n"
7497 + _ASM_EXTABLE(0b, 1b)
7498 +#endif
7499 +
7500 + "sete %1\n"
7501 : "+m" (l->a.counter), "=qm" (c)
7502 : "ir" (i) : "memory");
7503 return c;
7504 @@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
7505 {
7506 unsigned char c;
7507
7508 - asm volatile(_ASM_DEC "%0; sete %1"
7509 + asm volatile(_ASM_DEC "%0\n"
7510 +
7511 +#ifdef CONFIG_PAX_REFCOUNT
7512 +#ifdef CONFIG_X86_32
7513 + "into\n0:\n"
7514 +#else
7515 + "jno 0f\n"
7516 + "int $4\n0:\n"
7517 +#endif
7518 + ".pushsection .fixup,\"ax\"\n"
7519 + "1:\n"
7520 + _ASM_INC "%0\n"
7521 + "jmp 0b\n"
7522 + ".popsection\n"
7523 + _ASM_EXTABLE(0b, 1b)
7524 +#endif
7525 +
7526 + "sete %1\n"
7527 : "+m" (l->a.counter), "=qm" (c)
7528 : : "memory");
7529 return c != 0;
7530 @@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
7531 {
7532 unsigned char c;
7533
7534 - asm volatile(_ASM_INC "%0; sete %1"
7535 + asm volatile(_ASM_INC "%0\n"
7536 +
7537 +#ifdef CONFIG_PAX_REFCOUNT
7538 +#ifdef CONFIG_X86_32
7539 + "into\n0:\n"
7540 +#else
7541 + "jno 0f\n"
7542 + "int $4\n0:\n"
7543 +#endif
7544 + ".pushsection .fixup,\"ax\"\n"
7545 + "1:\n"
7546 + _ASM_DEC "%0\n"
7547 + "jmp 0b\n"
7548 + ".popsection\n"
7549 + _ASM_EXTABLE(0b, 1b)
7550 +#endif
7551 +
7552 + "sete %1\n"
7553 : "+m" (l->a.counter), "=qm" (c)
7554 : : "memory");
7555 return c != 0;
7556 @@ -110,7 +225,24 @@ static inline int local_add_negative(lon
7557 {
7558 unsigned char c;
7559
7560 - asm volatile(_ASM_ADD "%2,%0; sets %1"
7561 + asm volatile(_ASM_ADD "%2,%0\n"
7562 +
7563 +#ifdef CONFIG_PAX_REFCOUNT
7564 +#ifdef CONFIG_X86_32
7565 + "into\n0:\n"
7566 +#else
7567 + "jno 0f\n"
7568 + "int $4\n0:\n"
7569 +#endif
7570 + ".pushsection .fixup,\"ax\"\n"
7571 + "1:\n"
7572 + _ASM_SUB "%2,%0\n"
7573 + "jmp 0b\n"
7574 + ".popsection\n"
7575 + _ASM_EXTABLE(0b, 1b)
7576 +#endif
7577 +
7578 + "sets %1\n"
7579 : "+m" (l->a.counter), "=qm" (c)
7580 : "ir" (i) : "memory");
7581 return c;
7582 @@ -133,7 +265,23 @@ static inline long local_add_return(long
7583 #endif
7584 /* Modern 486+ processor */
7585 __i = i;
7586 - asm volatile(_ASM_XADD "%0, %1;"
7587 + asm volatile(_ASM_XADD "%0, %1\n"
7588 +
7589 +#ifdef CONFIG_PAX_REFCOUNT
7590 +#ifdef CONFIG_X86_32
7591 + "into\n0:\n"
7592 +#else
7593 + "jno 0f\n"
7594 + "int $4\n0:\n"
7595 +#endif
7596 + ".pushsection .fixup,\"ax\"\n"
7597 + "1:\n"
7598 + _ASM_MOV "%0,%1\n"
7599 + "jmp 0b\n"
7600 + ".popsection\n"
7601 + _ASM_EXTABLE(0b, 1b)
7602 +#endif
7603 +
7604 : "+r" (i), "+m" (l->a.counter)
7605 : : "memory");
7606 return i + __i;
7607 diff -urNp linux-2.6.36/arch/x86/include/asm/mc146818rtc.h linux-2.6.36/arch/x86/include/asm/mc146818rtc.h
7608 --- linux-2.6.36/arch/x86/include/asm/mc146818rtc.h 2010-10-20 16:30:22.000000000 -0400
7609 +++ linux-2.6.36/arch/x86/include/asm/mc146818rtc.h 2010-11-06 18:58:15.000000000 -0400
7610 @@ -81,8 +81,8 @@ static inline unsigned char current_lock
7611 #else
7612 #define lock_cmos_prefix(reg) do {} while (0)
7613 #define lock_cmos_suffix(reg) do {} while (0)
7614 -#define lock_cmos(reg)
7615 -#define unlock_cmos()
7616 +#define lock_cmos(reg) do {} while (0)
7617 +#define unlock_cmos() do {} while (0)
7618 #define do_i_have_lock_cmos() 0
7619 #define current_lock_cmos_reg() 0
7620 #endif
7621 diff -urNp linux-2.6.36/arch/x86/include/asm/microcode.h linux-2.6.36/arch/x86/include/asm/microcode.h
7622 --- linux-2.6.36/arch/x86/include/asm/microcode.h 2010-10-20 16:30:22.000000000 -0400
7623 +++ linux-2.6.36/arch/x86/include/asm/microcode.h 2010-11-06 18:58:15.000000000 -0400
7624 @@ -12,13 +12,13 @@ struct device;
7625 enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND };
7626
7627 struct microcode_ops {
7628 - enum ucode_state (*request_microcode_user) (int cpu,
7629 + enum ucode_state (* const request_microcode_user) (int cpu,
7630 const void __user *buf, size_t size);
7631
7632 - enum ucode_state (*request_microcode_fw) (int cpu,
7633 + enum ucode_state (* const request_microcode_fw) (int cpu,
7634 struct device *device);
7635
7636 - void (*microcode_fini_cpu) (int cpu);
7637 + void (* const microcode_fini_cpu) (int cpu);
7638
7639 /*
7640 * The generic 'microcode_core' part guarantees that
7641 @@ -38,18 +38,18 @@ struct ucode_cpu_info {
7642 extern struct ucode_cpu_info ucode_cpu_info[];
7643
7644 #ifdef CONFIG_MICROCODE_INTEL
7645 -extern struct microcode_ops * __init init_intel_microcode(void);
7646 +extern const struct microcode_ops * __init init_intel_microcode(void);
7647 #else
7648 -static inline struct microcode_ops * __init init_intel_microcode(void)
7649 +static inline const struct microcode_ops * __init init_intel_microcode(void)
7650 {
7651 return NULL;
7652 }
7653 #endif /* CONFIG_MICROCODE_INTEL */
7654
7655 #ifdef CONFIG_MICROCODE_AMD
7656 -extern struct microcode_ops * __init init_amd_microcode(void);
7657 +extern const struct microcode_ops * __init init_amd_microcode(void);
7658 #else
7659 -static inline struct microcode_ops * __init init_amd_microcode(void)
7660 +static inline const struct microcode_ops * __init init_amd_microcode(void)
7661 {
7662 return NULL;
7663 }
7664 diff -urNp linux-2.6.36/arch/x86/include/asm/mman.h linux-2.6.36/arch/x86/include/asm/mman.h
7665 --- linux-2.6.36/arch/x86/include/asm/mman.h 2010-10-20 16:30:22.000000000 -0400
7666 +++ linux-2.6.36/arch/x86/include/asm/mman.h 2010-11-06 18:58:15.000000000 -0400
7667 @@ -5,4 +5,14 @@
7668
7669 #include <asm-generic/mman.h>
7670
7671 +#ifdef __KERNEL__
7672 +#ifndef __ASSEMBLY__
7673 +#ifdef CONFIG_X86_32
7674 +#define arch_mmap_check i386_mmap_check
7675 +int i386_mmap_check(unsigned long addr, unsigned long len,
7676 + unsigned long flags);
7677 +#endif
7678 +#endif
7679 +#endif
7680 +
7681 #endif /* _ASM_X86_MMAN_H */
7682 diff -urNp linux-2.6.36/arch/x86/include/asm/mmu_context.h linux-2.6.36/arch/x86/include/asm/mmu_context.h
7683 --- linux-2.6.36/arch/x86/include/asm/mmu_context.h 2010-10-20 16:30:22.000000000 -0400
7684 +++ linux-2.6.36/arch/x86/include/asm/mmu_context.h 2010-11-06 18:58:15.000000000 -0400
7685 @@ -24,6 +24,21 @@ void destroy_context(struct mm_struct *m
7686
7687 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
7688 {
7689 +
7690 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
7691 + unsigned int i;
7692 + pgd_t *pgd;
7693 +
7694 + pax_open_kernel();
7695 + pgd = get_cpu_pgd(smp_processor_id());
7696 + for (i = USER_PGD_PTRS; i < 2 * USER_PGD_PTRS; ++i)
7697 + if (paravirt_enabled())
7698 + set_pgd(pgd+i, native_make_pgd(0));
7699 + else
7700 + pgd[i] = native_make_pgd(0);
7701 + pax_close_kernel();
7702 +#endif
7703 +
7704 #ifdef CONFIG_SMP
7705 if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
7706 percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
7707 @@ -34,27 +49,70 @@ static inline void switch_mm(struct mm_s
7708 struct task_struct *tsk)
7709 {
7710 unsigned cpu = smp_processor_id();
7711 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
7712 + int tlbstate = TLBSTATE_OK;
7713 +#endif
7714
7715 if (likely(prev != next)) {
7716 /* stop flush ipis for the previous mm */
7717 cpumask_clear_cpu(cpu, mm_cpumask(prev));
7718 #ifdef CONFIG_SMP
7719 +#ifdef CONFIG_X86_32
7720 + tlbstate = percpu_read(cpu_tlbstate.state);
7721 +#endif
7722 percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
7723 percpu_write(cpu_tlbstate.active_mm, next);
7724 #endif
7725 cpumask_set_cpu(cpu, mm_cpumask(next));
7726
7727 /* Re-load page tables */
7728 +#ifdef CONFIG_PAX_PER_CPU_PGD
7729 + pax_open_kernel();
7730 + __clone_user_pgds(get_cpu_pgd(cpu), next->pgd, USER_PGD_PTRS);
7731 + __shadow_user_pgds(get_cpu_pgd(cpu) + USER_PGD_PTRS, next->pgd, USER_PGD_PTRS);
7732 + pax_close_kernel();
7733 + load_cr3(get_cpu_pgd(cpu));
7734 +#else
7735 load_cr3(next->pgd);
7736 +#endif
7737
7738 /*
7739 * load the LDT, if the LDT is different:
7740 */
7741 if (unlikely(prev->context.ldt != next->context.ldt))
7742 load_LDT_nolock(&next->context);
7743 - }
7744 +
7745 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
7746 + if (!(__supported_pte_mask & _PAGE_NX)) {
7747 + smp_mb__before_clear_bit();
7748 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
7749 + smp_mb__after_clear_bit();
7750 + cpu_set(cpu, next->context.cpu_user_cs_mask);
7751 + }
7752 +#endif
7753 +
7754 +#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC))
7755 + if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
7756 + prev->context.user_cs_limit != next->context.user_cs_limit))
7757 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
7758 #ifdef CONFIG_SMP
7759 + else if (unlikely(tlbstate != TLBSTATE_OK))
7760 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
7761 +#endif
7762 +#endif
7763 +
7764 + }
7765 else {
7766 +
7767 +#ifdef CONFIG_PAX_PER_CPU_PGD
7768 + pax_open_kernel();
7769 + __clone_user_pgds(get_cpu_pgd(cpu), next->pgd, USER_PGD_PTRS);
7770 + __shadow_user_pgds(get_cpu_pgd(cpu) + USER_PGD_PTRS, next->pgd, USER_PGD_PTRS);
7771 + pax_close_kernel();
7772 + load_cr3(get_cpu_pgd(cpu));
7773 +#endif
7774 +
7775 +#ifdef CONFIG_SMP
7776 percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
7777 BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next);
7778
7779 @@ -63,11 +121,28 @@ static inline void switch_mm(struct mm_s
7780 * tlb flush IPI delivery. We must reload CR3
7781 * to make sure to use no freed page tables.
7782 */
7783 +
7784 +#ifndef CONFIG_PAX_PER_CPU_PGD
7785 load_cr3(next->pgd);
7786 +#endif
7787 +
7788 load_LDT_nolock(&next->context);
7789 +
7790 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
7791 + if (!(__supported_pte_mask & _PAGE_NX))
7792 + cpu_set(cpu, next->context.cpu_user_cs_mask);
7793 +#endif
7794 +
7795 +#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC))
7796 +#ifdef CONFIG_PAX_PAGEEXEC
7797 + if (!((next->pax_flags & MF_PAX_PAGEEXEC) && (__supported_pte_mask & _PAGE_NX)))
7798 +#endif
7799 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
7800 +#endif
7801 +
7802 }
7803 - }
7804 #endif
7805 + }
7806 }
7807
7808 #define activate_mm(prev, next) \
7809 diff -urNp linux-2.6.36/arch/x86/include/asm/mmu.h linux-2.6.36/arch/x86/include/asm/mmu.h
7810 --- linux-2.6.36/arch/x86/include/asm/mmu.h 2010-10-20 16:30:22.000000000 -0400
7811 +++ linux-2.6.36/arch/x86/include/asm/mmu.h 2010-11-06 18:58:15.000000000 -0400
7812 @@ -9,10 +9,23 @@
7813 * we put the segment information here.
7814 */
7815 typedef struct {
7816 - void *ldt;
7817 + struct desc_struct *ldt;
7818 int size;
7819 struct mutex lock;
7820 - void *vdso;
7821 + unsigned long vdso;
7822 +
7823 +#ifdef CONFIG_X86_32
7824 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7825 + unsigned long user_cs_base;
7826 + unsigned long user_cs_limit;
7827 +
7828 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
7829 + cpumask_t cpu_user_cs_mask;
7830 +#endif
7831 +
7832 +#endif
7833 +#endif
7834 +
7835 } mm_context_t;
7836
7837 #ifdef CONFIG_SMP
7838 diff -urNp linux-2.6.36/arch/x86/include/asm/module.h linux-2.6.36/arch/x86/include/asm/module.h
7839 --- linux-2.6.36/arch/x86/include/asm/module.h 2010-10-20 16:30:22.000000000 -0400
7840 +++ linux-2.6.36/arch/x86/include/asm/module.h 2010-11-06 18:58:50.000000000 -0400
7841 @@ -59,13 +59,31 @@
7842 #error unknown processor family
7843 #endif
7844
7845 +#ifdef CONFIG_PAX_MEMORY_UDEREF
7846 +#define MODULE_PAX_UDEREF "UDEREF "
7847 +#else
7848 +#define MODULE_PAX_UDEREF ""
7849 +#endif
7850 +
7851 #ifdef CONFIG_X86_32
7852 # ifdef CONFIG_4KSTACKS
7853 # define MODULE_STACKSIZE "4KSTACKS "
7854 # else
7855 # define MODULE_STACKSIZE ""
7856 # endif
7857 -# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
7858 +# ifdef CONFIG_PAX_KERNEXEC
7859 +# define MODULE_PAX_KERNEXEC "KERNEXEC "
7860 +# else
7861 +# define MODULE_PAX_KERNEXEC ""
7862 +# endif
7863 +# ifdef CONFIG_GRKERNSEC
7864 +# define MODULE_GRSEC "GRSECURITY "
7865 +# else
7866 +# define MODULE_GRSEC ""
7867 +# endif
7868 +# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC MODULE_PAX_KERNEXEC MODULE_PAX_UDEREF
7869 +#else
7870 +# define MODULE_ARCH_VERMAGIC MODULE_PAX_UDEREF
7871 #endif
7872
7873 #endif /* _ASM_X86_MODULE_H */
7874 diff -urNp linux-2.6.36/arch/x86/include/asm/page_32_types.h linux-2.6.36/arch/x86/include/asm/page_32_types.h
7875 --- linux-2.6.36/arch/x86/include/asm/page_32_types.h 2010-10-20 16:30:22.000000000 -0400
7876 +++ linux-2.6.36/arch/x86/include/asm/page_32_types.h 2010-11-06 18:58:15.000000000 -0400
7877 @@ -15,6 +15,10 @@
7878 */
7879 #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
7880
7881 +#ifdef CONFIG_PAX_PAGEEXEC
7882 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
7883 +#endif
7884 +
7885 #ifdef CONFIG_4KSTACKS
7886 #define THREAD_ORDER 0
7887 #else
7888 diff -urNp linux-2.6.36/arch/x86/include/asm/paravirt.h linux-2.6.36/arch/x86/include/asm/paravirt.h
7889 --- linux-2.6.36/arch/x86/include/asm/paravirt.h 2010-10-20 16:30:22.000000000 -0400
7890 +++ linux-2.6.36/arch/x86/include/asm/paravirt.h 2010-11-06 18:58:15.000000000 -0400
7891 @@ -720,6 +720,21 @@ static inline void __set_fixmap(unsigned
7892 pv_mmu_ops.set_fixmap(idx, phys, flags);
7893 }
7894
7895 +#ifdef CONFIG_PAX_KERNEXEC
7896 +static inline unsigned long pax_open_kernel(void)
7897 +{
7898 + return PVOP_CALL0(unsigned long, pv_mmu_ops.pax_open_kernel);
7899 +}
7900 +
7901 +static inline unsigned long pax_close_kernel(void)
7902 +{
7903 + return PVOP_CALL0(unsigned long, pv_mmu_ops.pax_close_kernel);
7904 +}
7905 +#else
7906 +static inline unsigned long pax_open_kernel(void) { return 0; }
7907 +static inline unsigned long pax_close_kernel(void) { return 0; }
7908 +#endif
7909 +
7910 #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
7911
7912 static inline int arch_spin_is_locked(struct arch_spinlock *lock)
7913 @@ -936,7 +951,7 @@ extern void default_banner(void);
7914
7915 #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
7916 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
7917 -#define PARA_INDIRECT(addr) *%cs:addr
7918 +#define PARA_INDIRECT(addr) *%ss:addr
7919 #endif
7920
7921 #define INTERRUPT_RETURN \
7922 @@ -1013,6 +1028,21 @@ extern void default_banner(void);
7923 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \
7924 CLBR_NONE, \
7925 jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit))
7926 +
7927 +#define GET_CR0_INTO_RDI \
7928 + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \
7929 + mov %rax,%rdi
7930 +
7931 +#define SET_RDI_INTO_CR0 \
7932 + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0)
7933 +
7934 +#define GET_CR3_INTO_RDI \
7935 + call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr3); \
7936 + mov %rax,%rdi
7937 +
7938 +#define SET_RDI_INTO_CR3 \
7939 + call PARA_INDIRECT(pv_mmu_ops+PV_MMU_write_cr3)
7940 +
7941 #endif /* CONFIG_X86_32 */
7942
7943 #endif /* __ASSEMBLY__ */
7944 diff -urNp linux-2.6.36/arch/x86/include/asm/paravirt_types.h linux-2.6.36/arch/x86/include/asm/paravirt_types.h
7945 --- linux-2.6.36/arch/x86/include/asm/paravirt_types.h 2010-10-20 16:30:22.000000000 -0400
7946 +++ linux-2.6.36/arch/x86/include/asm/paravirt_types.h 2010-11-06 18:58:15.000000000 -0400
7947 @@ -312,6 +312,12 @@ struct pv_mmu_ops {
7948 an mfn. We can tell which is which from the index. */
7949 void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
7950 phys_addr_t phys, pgprot_t flags);
7951 +
7952 +#ifdef CONFIG_PAX_KERNEXEC
7953 + unsigned long (*pax_open_kernel)(void);
7954 + unsigned long (*pax_close_kernel)(void);
7955 +#endif
7956 +
7957 };
7958
7959 struct arch_spinlock;
7960 diff -urNp linux-2.6.36/arch/x86/include/asm/pci_x86.h linux-2.6.36/arch/x86/include/asm/pci_x86.h
7961 --- linux-2.6.36/arch/x86/include/asm/pci_x86.h 2010-10-20 16:30:22.000000000 -0400
7962 +++ linux-2.6.36/arch/x86/include/asm/pci_x86.h 2010-11-06 18:58:15.000000000 -0400
7963 @@ -92,16 +92,16 @@ extern int (*pcibios_enable_irq)(struct
7964 extern void (*pcibios_disable_irq)(struct pci_dev *dev);
7965
7966 struct pci_raw_ops {
7967 - int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
7968 + int (* const read)(unsigned int domain, unsigned int bus, unsigned int devfn,
7969 int reg, int len, u32 *val);
7970 - int (*write)(unsigned int domain, unsigned int bus, unsigned int devfn,
7971 + int (* const write)(unsigned int domain, unsigned int bus, unsigned int devfn,
7972 int reg, int len, u32 val);
7973 };
7974
7975 -extern struct pci_raw_ops *raw_pci_ops;
7976 -extern struct pci_raw_ops *raw_pci_ext_ops;
7977 +extern const struct pci_raw_ops *raw_pci_ops;
7978 +extern const struct pci_raw_ops *raw_pci_ext_ops;
7979
7980 -extern struct pci_raw_ops pci_direct_conf1;
7981 +extern const struct pci_raw_ops pci_direct_conf1;
7982 extern bool port_cf9_safe;
7983
7984 /* arch_initcall level */
7985 diff -urNp linux-2.6.36/arch/x86/include/asm/pgalloc.h linux-2.6.36/arch/x86/include/asm/pgalloc.h
7986 --- linux-2.6.36/arch/x86/include/asm/pgalloc.h 2010-10-20 16:30:22.000000000 -0400
7987 +++ linux-2.6.36/arch/x86/include/asm/pgalloc.h 2010-11-06 18:58:15.000000000 -0400
7988 @@ -63,6 +63,13 @@ static inline void pmd_populate_kernel(s
7989 pmd_t *pmd, pte_t *pte)
7990 {
7991 paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
7992 + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
7993 +}
7994 +
7995 +static inline void pmd_populate_user(struct mm_struct *mm,
7996 + pmd_t *pmd, pte_t *pte)
7997 +{
7998 + paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
7999 set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
8000 }
8001
8002 diff -urNp linux-2.6.36/arch/x86/include/asm/pgtable-2level.h linux-2.6.36/arch/x86/include/asm/pgtable-2level.h
8003 --- linux-2.6.36/arch/x86/include/asm/pgtable-2level.h 2010-10-20 16:30:22.000000000 -0400
8004 +++ linux-2.6.36/arch/x86/include/asm/pgtable-2level.h 2010-11-06 18:58:15.000000000 -0400
8005 @@ -18,7 +18,9 @@ static inline void native_set_pte(pte_t
8006
8007 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
8008 {
8009 + pax_open_kernel();
8010 *pmdp = pmd;
8011 + pax_close_kernel();
8012 }
8013
8014 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
8015 diff -urNp linux-2.6.36/arch/x86/include/asm/pgtable_32.h linux-2.6.36/arch/x86/include/asm/pgtable_32.h
8016 --- linux-2.6.36/arch/x86/include/asm/pgtable_32.h 2010-10-20 16:30:22.000000000 -0400
8017 +++ linux-2.6.36/arch/x86/include/asm/pgtable_32.h 2010-11-06 18:58:15.000000000 -0400
8018 @@ -25,9 +25,6 @@
8019 struct mm_struct;
8020 struct vm_area_struct;
8021
8022 -extern pgd_t swapper_pg_dir[1024];
8023 -extern pgd_t trampoline_pg_dir[1024];
8024 -
8025 static inline void pgtable_cache_init(void) { }
8026 static inline void check_pgt_cache(void) { }
8027 void paging_init(void);
8028 @@ -48,6 +45,12 @@ extern void set_pmd_pfn(unsigned long, u
8029 # include <asm/pgtable-2level.h>
8030 #endif
8031
8032 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
8033 +extern pgd_t trampoline_pg_dir[PTRS_PER_PGD];
8034 +#ifdef CONFIG_X86_PAE
8035 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
8036 +#endif
8037 +
8038 #if defined(CONFIG_HIGHPTE)
8039 #define __KM_PTE \
8040 (in_nmi() ? KM_NMI_PTE : \
8041 @@ -72,7 +75,9 @@ extern void set_pmd_pfn(unsigned long, u
8042 /* Clear a kernel PTE and flush it from the TLB */
8043 #define kpte_clear_flush(ptep, vaddr) \
8044 do { \
8045 + pax_open_kernel(); \
8046 pte_clear(&init_mm, (vaddr), (ptep)); \
8047 + pax_close_kernel(); \
8048 __flush_tlb_one((vaddr)); \
8049 } while (0)
8050
8051 @@ -84,6 +89,9 @@ do { \
8052
8053 #endif /* !__ASSEMBLY__ */
8054
8055 +#define HAVE_ARCH_UNMAPPED_AREA
8056 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
8057 +
8058 /*
8059 * kern_addr_valid() is (1) for FLATMEM and (0) for
8060 * SPARSEMEM and DISCONTIGMEM
8061 diff -urNp linux-2.6.36/arch/x86/include/asm/pgtable_32_types.h linux-2.6.36/arch/x86/include/asm/pgtable_32_types.h
8062 --- linux-2.6.36/arch/x86/include/asm/pgtable_32_types.h 2010-10-20 16:30:22.000000000 -0400
8063 +++ linux-2.6.36/arch/x86/include/asm/pgtable_32_types.h 2010-11-06 18:58:15.000000000 -0400
8064 @@ -8,7 +8,7 @@
8065 */
8066 #ifdef CONFIG_X86_PAE
8067 # include <asm/pgtable-3level_types.h>
8068 -# define PMD_SIZE (1UL << PMD_SHIFT)
8069 +# define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
8070 # define PMD_MASK (~(PMD_SIZE - 1))
8071 #else
8072 # include <asm/pgtable-2level_types.h>
8073 @@ -46,6 +46,19 @@ extern bool __vmalloc_start_set; /* set
8074 # define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE)
8075 #endif
8076
8077 +#ifdef CONFIG_PAX_KERNEXEC
8078 +#ifndef __ASSEMBLY__
8079 +extern unsigned char MODULES_EXEC_VADDR[];
8080 +extern unsigned char MODULES_EXEC_END[];
8081 +#endif
8082 +#include <asm/boot.h>
8083 +#define ktla_ktva(addr) (addr + LOAD_PHYSICAL_ADDR + PAGE_OFFSET)
8084 +#define ktva_ktla(addr) (addr - LOAD_PHYSICAL_ADDR - PAGE_OFFSET)
8085 +#else
8086 +#define ktla_ktva(addr) (addr)
8087 +#define ktva_ktla(addr) (addr)
8088 +#endif
8089 +
8090 #define MODULES_VADDR VMALLOC_START
8091 #define MODULES_END VMALLOC_END
8092 #define MODULES_LEN (MODULES_VADDR - MODULES_END)
8093 diff -urNp linux-2.6.36/arch/x86/include/asm/pgtable-3level.h linux-2.6.36/arch/x86/include/asm/pgtable-3level.h
8094 --- linux-2.6.36/arch/x86/include/asm/pgtable-3level.h 2010-10-20 16:30:22.000000000 -0400
8095 +++ linux-2.6.36/arch/x86/include/asm/pgtable-3level.h 2010-11-06 18:58:15.000000000 -0400
8096 @@ -38,12 +38,16 @@ static inline void native_set_pte_atomic
8097
8098 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
8099 {
8100 + pax_open_kernel();
8101 set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
8102 + pax_close_kernel();
8103 }
8104
8105 static inline void native_set_pud(pud_t *pudp, pud_t pud)
8106 {
8107 + pax_open_kernel();
8108 set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
8109 + pax_close_kernel();
8110 }
8111
8112 /*
8113 diff -urNp linux-2.6.36/arch/x86/include/asm/pgtable_64.h linux-2.6.36/arch/x86/include/asm/pgtable_64.h
8114 --- linux-2.6.36/arch/x86/include/asm/pgtable_64.h 2010-10-20 16:30:22.000000000 -0400
8115 +++ linux-2.6.36/arch/x86/include/asm/pgtable_64.h 2010-11-06 18:58:15.000000000 -0400
8116 @@ -16,10 +16,13 @@
8117
8118 extern pud_t level3_kernel_pgt[512];
8119 extern pud_t level3_ident_pgt[512];
8120 +extern pud_t level3_vmalloc_pgt[512];
8121 +extern pud_t level3_vmemmap_pgt[512];
8122 +extern pud_t level2_vmemmap_pgt[512];
8123 extern pmd_t level2_kernel_pgt[512];
8124 extern pmd_t level2_fixmap_pgt[512];
8125 -extern pmd_t level2_ident_pgt[512];
8126 -extern pgd_t init_level4_pgt[];
8127 +extern pmd_t level2_ident_pgt[512*2];
8128 +extern pgd_t init_level4_pgt[512];
8129
8130 #define swapper_pg_dir init_level4_pgt
8131
8132 @@ -74,7 +77,9 @@ static inline pte_t native_ptep_get_and_
8133
8134 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
8135 {
8136 + pax_open_kernel();
8137 *pmdp = pmd;
8138 + pax_close_kernel();
8139 }
8140
8141 static inline void native_pmd_clear(pmd_t *pmd)
8142 @@ -94,7 +99,9 @@ static inline void native_pud_clear(pud_
8143
8144 static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd)
8145 {
8146 + pax_open_kernel();
8147 *pgdp = pgd;
8148 + pax_close_kernel();
8149 }
8150
8151 static inline void native_pgd_clear(pgd_t *pgd)
8152 diff -urNp linux-2.6.36/arch/x86/include/asm/pgtable_64_types.h linux-2.6.36/arch/x86/include/asm/pgtable_64_types.h
8153 --- linux-2.6.36/arch/x86/include/asm/pgtable_64_types.h 2010-10-20 16:30:22.000000000 -0400
8154 +++ linux-2.6.36/arch/x86/include/asm/pgtable_64_types.h 2010-11-06 18:58:15.000000000 -0400
8155 @@ -59,5 +59,10 @@ typedef struct { pteval_t pte; } pte_t;
8156 #define MODULES_VADDR _AC(0xffffffffa0000000, UL)
8157 #define MODULES_END _AC(0xffffffffff000000, UL)
8158 #define MODULES_LEN (MODULES_END - MODULES_VADDR)
8159 +#define MODULES_EXEC_VADDR MODULES_VADDR
8160 +#define MODULES_EXEC_END MODULES_END
8161 +
8162 +#define ktla_ktva(addr) (addr)
8163 +#define ktva_ktla(addr) (addr)
8164
8165 #endif /* _ASM_X86_PGTABLE_64_DEFS_H */
8166 diff -urNp linux-2.6.36/arch/x86/include/asm/pgtable.h linux-2.6.36/arch/x86/include/asm/pgtable.h
8167 --- linux-2.6.36/arch/x86/include/asm/pgtable.h 2010-10-20 16:30:22.000000000 -0400
8168 +++ linux-2.6.36/arch/x86/include/asm/pgtable.h 2010-11-06 18:58:15.000000000 -0400
8169 @@ -76,12 +76,51 @@ extern struct list_head pgd_list;
8170
8171 #define arch_end_context_switch(prev) do {} while(0)
8172
8173 +#define pax_open_kernel() native_pax_open_kernel()
8174 +#define pax_close_kernel() native_pax_close_kernel()
8175 #endif /* CONFIG_PARAVIRT */
8176
8177 +#define __HAVE_ARCH_PAX_OPEN_KERNEL
8178 +#define __HAVE_ARCH_PAX_CLOSE_KERNEL
8179 +
8180 +#ifdef CONFIG_PAX_KERNEXEC
8181 +static inline unsigned long native_pax_open_kernel(void)
8182 +{
8183 + unsigned long cr0;
8184 +
8185 + preempt_disable();
8186 + barrier();
8187 + cr0 = read_cr0() ^ X86_CR0_WP;
8188 + BUG_ON(unlikely(cr0 & X86_CR0_WP));
8189 + write_cr0(cr0);
8190 + return cr0 ^ X86_CR0_WP;
8191 +}
8192 +
8193 +static inline unsigned long native_pax_close_kernel(void)
8194 +{
8195 + unsigned long cr0;
8196 +
8197 + cr0 = read_cr0() ^ X86_CR0_WP;
8198 + BUG_ON(unlikely(!(cr0 & X86_CR0_WP)));
8199 + write_cr0(cr0);
8200 + barrier();
8201 + preempt_enable_no_resched();
8202 + return cr0 ^ X86_CR0_WP;
8203 +}
8204 +#else
8205 +static inline unsigned long native_pax_open_kernel(void) { return 0; }
8206 +static inline unsigned long native_pax_close_kernel(void) { return 0; }
8207 +#endif
8208 +
8209 /*
8210 * The following only work if pte_present() is true.
8211 * Undefined behaviour if not..
8212 */
8213 +static inline int pte_user(pte_t pte)
8214 +{
8215 + return pte_val(pte) & _PAGE_USER;
8216 +}
8217 +
8218 static inline int pte_dirty(pte_t pte)
8219 {
8220 return pte_flags(pte) & _PAGE_DIRTY;
8221 @@ -169,9 +208,29 @@ static inline pte_t pte_wrprotect(pte_t
8222 return pte_clear_flags(pte, _PAGE_RW);
8223 }
8224
8225 +static inline pte_t pte_mkread(pte_t pte)
8226 +{
8227 + return __pte(pte_val(pte) | _PAGE_USER);
8228 +}
8229 +
8230 static inline pte_t pte_mkexec(pte_t pte)
8231 {
8232 - return pte_clear_flags(pte, _PAGE_NX);
8233 +#ifdef CONFIG_X86_PAE
8234 + if (__supported_pte_mask & _PAGE_NX)
8235 + return pte_clear_flags(pte, _PAGE_NX);
8236 + else
8237 +#endif
8238 + return pte_set_flags(pte, _PAGE_USER);
8239 +}
8240 +
8241 +static inline pte_t pte_exprotect(pte_t pte)
8242 +{
8243 +#ifdef CONFIG_X86_PAE
8244 + if (__supported_pte_mask & _PAGE_NX)
8245 + return pte_set_flags(pte, _PAGE_NX);
8246 + else
8247 +#endif
8248 + return pte_clear_flags(pte, _PAGE_USER);
8249 }
8250
8251 static inline pte_t pte_mkdirty(pte_t pte)
8252 @@ -304,6 +363,15 @@ pte_t *populate_extra_pte(unsigned long
8253 #endif
8254
8255 #ifndef __ASSEMBLY__
8256 +
8257 +#ifdef CONFIG_PAX_PER_CPU_PGD
8258 +extern pgd_t cpu_pgd[NR_CPUS][PTRS_PER_PGD];
8259 +static inline pgd_t *get_cpu_pgd(unsigned int cpu)
8260 +{
8261 + return cpu_pgd[cpu];
8262 +}
8263 +#endif
8264 +
8265 #include <linux/mm_types.h>
8266
8267 static inline int pte_none(pte_t pte)
8268 @@ -474,7 +542,7 @@ static inline pud_t *pud_offset(pgd_t *p
8269
8270 static inline int pgd_bad(pgd_t pgd)
8271 {
8272 - return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
8273 + return (pgd_flags(pgd) & ~(_PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
8274 }
8275
8276 static inline int pgd_none(pgd_t pgd)
8277 @@ -497,7 +565,12 @@ static inline int pgd_none(pgd_t pgd)
8278 * pgd_offset() returns a (pgd_t *)
8279 * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
8280 */
8281 -#define pgd_offset(mm, address) ((mm)->pgd + pgd_index((address)))
8282 +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
8283 +
8284 +#ifdef CONFIG_PAX_PER_CPU_PGD
8285 +#define pgd_offset_cpu(cpu, address) (get_cpu_pgd(cpu) + pgd_index(address))
8286 +#endif
8287 +
8288 /*
8289 * a shortcut which implies the use of the kernel's pgd, instead
8290 * of a process's
8291 @@ -508,6 +581,20 @@ static inline int pgd_none(pgd_t pgd)
8292 #define KERNEL_PGD_BOUNDARY pgd_index(PAGE_OFFSET)
8293 #define KERNEL_PGD_PTRS (PTRS_PER_PGD - KERNEL_PGD_BOUNDARY)
8294
8295 +#ifdef CONFIG_X86_32
8296 +#define USER_PGD_PTRS KERNEL_PGD_BOUNDARY
8297 +#else
8298 +#define TASK_SIZE_MAX_SHIFT CONFIG_TASK_SIZE_MAX_SHIFT
8299 +#define USER_PGD_PTRS (_AC(1,UL) << (TASK_SIZE_MAX_SHIFT - PGDIR_SHIFT))
8300 +
8301 +#ifdef CONFIG_PAX_MEMORY_UDEREF
8302 +#define PAX_USER_SHADOW_BASE (_AC(1,UL) << TASK_SIZE_MAX_SHIFT)
8303 +#else
8304 +#define PAX_USER_SHADOW_BASE (_AC(0,UL))
8305 +#endif
8306 +
8307 +#endif
8308 +
8309 #ifndef __ASSEMBLY__
8310
8311 extern int direct_gbpages;
8312 @@ -613,11 +700,23 @@ static inline void ptep_set_wrprotect(st
8313 * dst and src can be on the same page, but the range must not overlap,
8314 * and must not cross a page boundary.
8315 */
8316 -static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
8317 +static inline void clone_pgd_range(pgd_t *dst, const pgd_t *src, int count)
8318 {
8319 - memcpy(dst, src, count * sizeof(pgd_t));
8320 + pax_open_kernel();
8321 + while (count--)
8322 + *dst++ = *src++;
8323 + pax_close_kernel();
8324 }
8325
8326 +#ifdef CONFIG_PAX_PER_CPU_PGD
8327 +extern void __clone_user_pgds(pgd_t *dst, const pgd_t *src, int count);
8328 +#endif
8329 +
8330 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
8331 +extern void __shadow_user_pgds(pgd_t *dst, const pgd_t *src, int count);
8332 +#else
8333 +static inline void __shadow_user_pgds(pgd_t *dst, const pgd_t *src, int count) {}
8334 +#endif
8335
8336 #include <asm-generic/pgtable.h>
8337 #endif /* __ASSEMBLY__ */
8338 diff -urNp linux-2.6.36/arch/x86/include/asm/pgtable_types.h linux-2.6.36/arch/x86/include/asm/pgtable_types.h
8339 --- linux-2.6.36/arch/x86/include/asm/pgtable_types.h 2010-10-20 16:30:22.000000000 -0400
8340 +++ linux-2.6.36/arch/x86/include/asm/pgtable_types.h 2010-11-06 18:58:15.000000000 -0400
8341 @@ -16,12 +16,11 @@
8342 #define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
8343 #define _PAGE_BIT_PAT 7 /* on 4KB pages */
8344 #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
8345 -#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
8346 +#define _PAGE_BIT_SPECIAL 9 /* special mappings, no associated struct page */
8347 #define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
8348 #define _PAGE_BIT_HIDDEN 11 /* hidden by kmemcheck */
8349 #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
8350 -#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
8351 -#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1
8352 +#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SPECIAL
8353 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
8354
8355 /* If _PAGE_BIT_PRESENT is clear, we use these: */
8356 @@ -39,7 +38,6 @@
8357 #define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
8358 #define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
8359 #define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
8360 -#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
8361 #define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
8362 #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
8363 #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
8364 @@ -55,8 +53,10 @@
8365
8366 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
8367 #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
8368 -#else
8369 +#elif defined(CONFIG_KMEMCHECK)
8370 #define _PAGE_NX (_AT(pteval_t, 0))
8371 +#else
8372 +#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN)
8373 #endif
8374
8375 #define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE)
8376 @@ -93,6 +93,9 @@
8377 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
8378 _PAGE_ACCESSED)
8379
8380 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
8381 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
8382 +
8383 #define __PAGE_KERNEL_EXEC \
8384 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
8385 #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
8386 @@ -103,8 +106,8 @@
8387 #define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC)
8388 #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
8389 #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
8390 -#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
8391 -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
8392 +#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RO | _PAGE_USER)
8393 +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
8394 #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
8395 #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
8396 #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
8397 @@ -163,8 +166,8 @@
8398 * bits are combined, this will alow user to access the high address mapped
8399 * VDSO in the presence of CONFIG_COMPAT_VDSO
8400 */
8401 -#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
8402 -#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
8403 +#define PTE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
8404 +#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
8405 #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
8406 #endif
8407
8408 @@ -202,7 +205,17 @@ static inline pgdval_t pgd_flags(pgd_t p
8409 {
8410 return native_pgd_val(pgd) & PTE_FLAGS_MASK;
8411 }
8412 +#endif
8413
8414 +#if PAGETABLE_LEVELS == 3
8415 +#include <asm-generic/pgtable-nopud.h>
8416 +#endif
8417 +
8418 +#if PAGETABLE_LEVELS == 2
8419 +#include <asm-generic/pgtable-nopmd.h>
8420 +#endif
8421 +
8422 +#ifndef __ASSEMBLY__
8423 #if PAGETABLE_LEVELS > 3
8424 typedef struct { pudval_t pud; } pud_t;
8425
8426 @@ -216,8 +229,6 @@ static inline pudval_t native_pud_val(pu
8427 return pud.pud;
8428 }
8429 #else
8430 -#include <asm-generic/pgtable-nopud.h>
8431 -
8432 static inline pudval_t native_pud_val(pud_t pud)
8433 {
8434 return native_pgd_val(pud.pgd);
8435 @@ -237,8 +248,6 @@ static inline pmdval_t native_pmd_val(pm
8436 return pmd.pmd;
8437 }
8438 #else
8439 -#include <asm-generic/pgtable-nopmd.h>
8440 -
8441 static inline pmdval_t native_pmd_val(pmd_t pmd)
8442 {
8443 return native_pgd_val(pmd.pud.pgd);
8444 @@ -278,7 +287,6 @@ typedef struct page *pgtable_t;
8445
8446 extern pteval_t __supported_pte_mask;
8447 extern void set_nx(void);
8448 -extern int nx_enabled;
8449
8450 #define pgprot_writecombine pgprot_writecombine
8451 extern pgprot_t pgprot_writecombine(pgprot_t prot);
8452 diff -urNp linux-2.6.36/arch/x86/include/asm/processor.h linux-2.6.36/arch/x86/include/asm/processor.h
8453 --- linux-2.6.36/arch/x86/include/asm/processor.h 2010-10-20 16:30:22.000000000 -0400
8454 +++ linux-2.6.36/arch/x86/include/asm/processor.h 2010-11-06 18:58:15.000000000 -0400
8455 @@ -269,7 +269,7 @@ struct tss_struct {
8456
8457 } ____cacheline_aligned;
8458
8459 -DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);
8460 +extern struct tss_struct init_tss[NR_CPUS];
8461
8462 /*
8463 * Save the original ist values for checking stack pointers during debugging
8464 @@ -885,8 +885,15 @@ static inline void spin_lock_prefetch(co
8465 */
8466 #define TASK_SIZE PAGE_OFFSET
8467 #define TASK_SIZE_MAX TASK_SIZE
8468 +
8469 +#ifdef CONFIG_PAX_SEGMEXEC
8470 +#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
8471 +#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
8472 +#else
8473 #define STACK_TOP TASK_SIZE
8474 -#define STACK_TOP_MAX STACK_TOP
8475 +#endif
8476 +
8477 +#define STACK_TOP_MAX TASK_SIZE
8478
8479 #define INIT_THREAD { \
8480 .sp0 = sizeof(init_stack) + (long)&init_stack, \
8481 @@ -903,7 +910,7 @@ static inline void spin_lock_prefetch(co
8482 */
8483 #define INIT_TSS { \
8484 .x86_tss = { \
8485 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
8486 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
8487 .ss0 = __KERNEL_DS, \
8488 .ss1 = __KERNEL_CS, \
8489 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
8490 @@ -914,11 +921,7 @@ static inline void spin_lock_prefetch(co
8491 extern unsigned long thread_saved_pc(struct task_struct *tsk);
8492
8493 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
8494 -#define KSTK_TOP(info) \
8495 -({ \
8496 - unsigned long *__ptr = (unsigned long *)(info); \
8497 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
8498 -})
8499 +#define KSTK_TOP(info) ((info)->task.thread.sp0)
8500
8501 /*
8502 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
8503 @@ -933,7 +936,7 @@ extern unsigned long thread_saved_pc(str
8504 #define task_pt_regs(task) \
8505 ({ \
8506 struct pt_regs *__regs__; \
8507 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
8508 + __regs__ = (struct pt_regs *)((task)->thread.sp0); \
8509 __regs__ - 1; \
8510 })
8511
8512 @@ -943,13 +946,13 @@ extern unsigned long thread_saved_pc(str
8513 /*
8514 * User space process size. 47bits minus one guard page.
8515 */
8516 -#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
8517 +#define TASK_SIZE_MAX ((1UL << TASK_SIZE_MAX_SHIFT) - PAGE_SIZE)
8518
8519 /* This decides where the kernel will search for a free chunk of vm
8520 * space during mmap's.
8521 */
8522 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
8523 - 0xc0000000 : 0xFFFFe000)
8524 + 0xc0000000 : 0xFFFFf000)
8525
8526 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
8527 IA32_PAGE_OFFSET : TASK_SIZE_MAX)
8528 @@ -986,6 +989,10 @@ extern void start_thread(struct pt_regs
8529 */
8530 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
8531
8532 +#ifdef CONFIG_PAX_SEGMEXEC
8533 +#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
8534 +#endif
8535 +
8536 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
8537
8538 /* Get/set a process' ability to use the timestamp counter instruction */
8539 diff -urNp linux-2.6.36/arch/x86/include/asm/ptrace.h linux-2.6.36/arch/x86/include/asm/ptrace.h
8540 --- linux-2.6.36/arch/x86/include/asm/ptrace.h 2010-10-20 16:30:22.000000000 -0400
8541 +++ linux-2.6.36/arch/x86/include/asm/ptrace.h 2010-11-06 18:58:15.000000000 -0400
8542 @@ -152,28 +152,29 @@ static inline unsigned long regs_return_
8543 }
8544
8545 /*
8546 - * user_mode_vm(regs) determines whether a register set came from user mode.
8547 + * user_mode(regs) determines whether a register set came from user mode.
8548 * This is true if V8086 mode was enabled OR if the register set was from
8549 * protected mode with RPL-3 CS value. This tricky test checks that with
8550 * one comparison. Many places in the kernel can bypass this full check
8551 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
8552 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
8553 + * be used.
8554 */
8555 -static inline int user_mode(struct pt_regs *regs)
8556 +static inline int user_mode_novm(struct pt_regs *regs)
8557 {
8558 #ifdef CONFIG_X86_32
8559 return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
8560 #else
8561 - return !!(regs->cs & 3);
8562 + return !!(regs->cs & SEGMENT_RPL_MASK);
8563 #endif
8564 }
8565
8566 -static inline int user_mode_vm(struct pt_regs *regs)
8567 +static inline int user_mode(struct pt_regs *regs)
8568 {
8569 #ifdef CONFIG_X86_32
8570 return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
8571 USER_RPL;
8572 #else
8573 - return user_mode(regs);
8574 + return user_mode_novm(regs);
8575 #endif
8576 }
8577
8578 diff -urNp linux-2.6.36/arch/x86/include/asm/reboot.h linux-2.6.36/arch/x86/include/asm/reboot.h
8579 --- linux-2.6.36/arch/x86/include/asm/reboot.h 2010-10-20 16:30:22.000000000 -0400
8580 +++ linux-2.6.36/arch/x86/include/asm/reboot.h 2010-11-06 18:58:15.000000000 -0400
8581 @@ -18,7 +18,7 @@ extern struct machine_ops machine_ops;
8582
8583 void native_machine_crash_shutdown(struct pt_regs *regs);
8584 void native_machine_shutdown(void);
8585 -void machine_real_restart(const unsigned char *code, int length);
8586 +void machine_real_restart(const unsigned char *code, unsigned int length);
8587
8588 typedef void (*nmi_shootdown_cb)(int, struct die_args*);
8589 void nmi_shootdown_cpus(nmi_shootdown_cb callback);
8590 diff -urNp linux-2.6.36/arch/x86/include/asm/rwsem.h linux-2.6.36/arch/x86/include/asm/rwsem.h
8591 --- linux-2.6.36/arch/x86/include/asm/rwsem.h 2010-10-20 16:30:22.000000000 -0400
8592 +++ linux-2.6.36/arch/x86/include/asm/rwsem.h 2010-11-06 18:58:15.000000000 -0400
8593 @@ -118,10 +118,26 @@ static inline void __down_read(struct rw
8594 {
8595 asm volatile("# beginning down_read\n\t"
8596 LOCK_PREFIX _ASM_INC "(%1)\n\t"
8597 +
8598 +#ifdef CONFIG_PAX_REFCOUNT
8599 +#ifdef CONFIG_X86_32
8600 + "into\n0:\n"
8601 +#else
8602 + "jno 0f\n"
8603 + "int $4\n0:\n"
8604 +#endif
8605 + ".pushsection .fixup,\"ax\"\n"
8606 + "1:\n"
8607 + LOCK_PREFIX _ASM_DEC "(%1)\n"
8608 + "jmp 0b\n"
8609 + ".popsection\n"
8610 + _ASM_EXTABLE(0b, 1b)
8611 +#endif
8612 +
8613 /* adds 0x00000001 */
8614 - " jns 1f\n"
8615 + " jns 2f\n"
8616 " call call_rwsem_down_read_failed\n"
8617 - "1:\n\t"
8618 + "2:\n\t"
8619 "# ending down_read\n\t"
8620 : "+m" (sem->count)
8621 : "a" (sem)
8622 @@ -136,13 +152,29 @@ static inline int __down_read_trylock(st
8623 rwsem_count_t result, tmp;
8624 asm volatile("# beginning __down_read_trylock\n\t"
8625 " mov %0,%1\n\t"
8626 - "1:\n\t"
8627 + "2:\n\t"
8628 " mov %1,%2\n\t"
8629 " add %3,%2\n\t"
8630 - " jle 2f\n\t"
8631 +
8632 +#ifdef CONFIG_PAX_REFCOUNT
8633 +#ifdef CONFIG_X86_32
8634 + "into\n0:\n"
8635 +#else
8636 + "jno 0f\n"
8637 + "int $4\n0:\n"
8638 +#endif
8639 + ".pushsection .fixup,\"ax\"\n"
8640 + "1:\n"
8641 + "sub %3,%2\n"
8642 + "jmp 0b\n"
8643 + ".popsection\n"
8644 + _ASM_EXTABLE(0b, 1b)
8645 +#endif
8646 +
8647 + " jle 3f\n\t"
8648 LOCK_PREFIX " cmpxchg %2,%0\n\t"
8649 - " jnz 1b\n\t"
8650 - "2:\n\t"
8651 + " jnz 2b\n\t"
8652 + "3:\n\t"
8653 "# ending __down_read_trylock\n\t"
8654 : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
8655 : "i" (RWSEM_ACTIVE_READ_BIAS)
8656 @@ -158,12 +190,28 @@ static inline void __down_write_nested(s
8657 rwsem_count_t tmp;
8658 asm volatile("# beginning down_write\n\t"
8659 LOCK_PREFIX " xadd %1,(%2)\n\t"
8660 +
8661 +#ifdef CONFIG_PAX_REFCOUNT
8662 +#ifdef CONFIG_X86_32
8663 + "into\n0:\n"
8664 +#else
8665 + "jno 0f\n"
8666 + "int $4\n0:\n"
8667 +#endif
8668 + ".pushsection .fixup,\"ax\"\n"
8669 + "1:\n"
8670 + "mov %1,(%2)\n"
8671 + "jmp 0b\n"
8672 + ".popsection\n"
8673 + _ASM_EXTABLE(0b, 1b)
8674 +#endif
8675 +
8676 /* adds 0xffff0001, returns the old value */
8677 " test %1,%1\n\t"
8678 /* was the count 0 before? */
8679 - " jz 1f\n"
8680 + " jz 2f\n"
8681 " call call_rwsem_down_write_failed\n"
8682 - "1:\n"
8683 + "2:\n"
8684 "# ending down_write"
8685 : "+m" (sem->count), "=d" (tmp)
8686 : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS)
8687 @@ -196,10 +244,26 @@ static inline void __up_read(struct rw_s
8688 rwsem_count_t tmp;
8689 asm volatile("# beginning __up_read\n\t"
8690 LOCK_PREFIX " xadd %1,(%2)\n\t"
8691 +
8692 +#ifdef CONFIG_PAX_REFCOUNT
8693 +#ifdef CONFIG_X86_32
8694 + "into\n0:\n"
8695 +#else
8696 + "jno 0f\n"
8697 + "int $4\n0:\n"
8698 +#endif
8699 + ".pushsection .fixup,\"ax\"\n"
8700 + "1:\n"
8701 + "mov %1,(%2)\n"
8702 + "jmp 0b\n"
8703 + ".popsection\n"
8704 + _ASM_EXTABLE(0b, 1b)
8705 +#endif
8706 +
8707 /* subtracts 1, returns the old value */
8708 - " jns 1f\n\t"
8709 + " jns 2f\n\t"
8710 " call call_rwsem_wake\n" /* expects old value in %edx */
8711 - "1:\n"
8712 + "2:\n"
8713 "# ending __up_read\n"
8714 : "+m" (sem->count), "=d" (tmp)
8715 : "a" (sem), "1" (-RWSEM_ACTIVE_READ_BIAS)
8716 @@ -214,10 +278,26 @@ static inline void __up_write(struct rw_
8717 rwsem_count_t tmp;
8718 asm volatile("# beginning __up_write\n\t"
8719 LOCK_PREFIX " xadd %1,(%2)\n\t"
8720 +
8721 +#ifdef CONFIG_PAX_REFCOUNT
8722 +#ifdef CONFIG_X86_32
8723 + "into\n0:\n"
8724 +#else
8725 + "jno 0f\n"
8726 + "int $4\n0:\n"
8727 +#endif
8728 + ".pushsection .fixup,\"ax\"\n"
8729 + "1:\n"
8730 + "mov %1,(%2)\n"
8731 + "jmp 0b\n"
8732 + ".popsection\n"
8733 + _ASM_EXTABLE(0b, 1b)
8734 +#endif
8735 +
8736 /* subtracts 0xffff0001, returns the old value */
8737 - " jns 1f\n\t"
8738 + " jns 2f\n\t"
8739 " call call_rwsem_wake\n" /* expects old value in %edx */
8740 - "1:\n\t"
8741 + "2:\n\t"
8742 "# ending __up_write\n"
8743 : "+m" (sem->count), "=d" (tmp)
8744 : "a" (sem), "1" (-RWSEM_ACTIVE_WRITE_BIAS)
8745 @@ -231,13 +311,29 @@ static inline void __downgrade_write(str
8746 {
8747 asm volatile("# beginning __downgrade_write\n\t"
8748 LOCK_PREFIX _ASM_ADD "%2,(%1)\n\t"
8749 +
8750 +#ifdef CONFIG_PAX_REFCOUNT
8751 +#ifdef CONFIG_X86_32
8752 + "into\n0:\n"
8753 +#else
8754 + "jno 0f\n"
8755 + "int $4\n0:\n"
8756 +#endif
8757 + ".pushsection .fixup,\"ax\"\n"
8758 + "1:\n"
8759 + LOCK_PREFIX _ASM_SUB "%2,(%1)\n"
8760 + "jmp 0b\n"
8761 + ".popsection\n"
8762 + _ASM_EXTABLE(0b, 1b)
8763 +#endif
8764 +
8765 /*
8766 * transitions 0xZZZZ0001 -> 0xYYYY0001 (i386)
8767 * 0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 (x86_64)
8768 */
8769 - " jns 1f\n\t"
8770 + " jns 2f\n\t"
8771 " call call_rwsem_downgrade_wake\n"
8772 - "1:\n\t"
8773 + "2:\n\t"
8774 "# ending __downgrade_write\n"
8775 : "+m" (sem->count)
8776 : "a" (sem), "er" (-RWSEM_WAITING_BIAS)
8777 @@ -250,7 +346,23 @@ static inline void __downgrade_write(str
8778 static inline void rwsem_atomic_add(rwsem_count_t delta,
8779 struct rw_semaphore *sem)
8780 {
8781 - asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0"
8782 + asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0\n"
8783 +
8784 +#ifdef CONFIG_PAX_REFCOUNT
8785 +#ifdef CONFIG_X86_32
8786 + "into\n0:\n"
8787 +#else
8788 + "jno 0f\n"
8789 + "int $4\n0:\n"
8790 +#endif
8791 + ".pushsection .fixup,\"ax\"\n"
8792 + "1:\n"
8793 + LOCK_PREFIX _ASM_SUB "%1,%0\n"
8794 + "jmp 0b\n"
8795 + ".popsection\n"
8796 + _ASM_EXTABLE(0b, 1b)
8797 +#endif
8798 +
8799 : "+m" (sem->count)
8800 : "er" (delta));
8801 }
8802 @@ -263,7 +375,23 @@ static inline rwsem_count_t rwsem_atomic
8803 {
8804 rwsem_count_t tmp = delta;
8805
8806 - asm volatile(LOCK_PREFIX "xadd %0,%1"
8807 + asm volatile(LOCK_PREFIX "xadd %0,%1\n"
8808 +
8809 +#ifdef CONFIG_PAX_REFCOUNT
8810 +#ifdef CONFIG_X86_32
8811 + "into\n0:\n"
8812 +#else
8813 + "jno 0f\n"
8814 + "int $4\n0:\n"
8815 +#endif
8816 + ".pushsection .fixup,\"ax\"\n"
8817 + "1:\n"
8818 + "mov %0,%1\n"
8819 + "jmp 0b\n"
8820 + ".popsection\n"
8821 + _ASM_EXTABLE(0b, 1b)
8822 +#endif
8823 +
8824 : "+r" (tmp), "+m" (sem->count)
8825 : : "memory");
8826
8827 diff -urNp linux-2.6.36/arch/x86/include/asm/segment.h linux-2.6.36/arch/x86/include/asm/segment.h
8828 --- linux-2.6.36/arch/x86/include/asm/segment.h 2010-10-20 16:30:22.000000000 -0400
8829 +++ linux-2.6.36/arch/x86/include/asm/segment.h 2010-11-06 18:58:15.000000000 -0400
8830 @@ -62,8 +62,8 @@
8831 * 26 - ESPFIX small SS
8832 * 27 - per-cpu [ offset to per-cpu data area ]
8833 * 28 - stack_canary-20 [ for stack protector ]
8834 - * 29 - unused
8835 - * 30 - unused
8836 + * 29 - PCI BIOS CS
8837 + * 30 - PCI BIOS DS
8838 * 31 - TSS for double fault handler
8839 */
8840 #define GDT_ENTRY_TLS_MIN 6
8841 @@ -77,6 +77,8 @@
8842
8843 #define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE + 0)
8844
8845 +#define GDT_ENTRY_KERNEXEC_KERNEL_CS (4)
8846 +
8847 #define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE + 1)
8848
8849 #define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE + 4)
8850 @@ -88,7 +90,7 @@
8851 #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
8852 #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
8853
8854 -#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
8855 +#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
8856 #ifdef CONFIG_SMP
8857 #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
8858 #else
8859 @@ -102,6 +104,12 @@
8860 #define __KERNEL_STACK_CANARY 0
8861 #endif
8862
8863 +#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 17)
8864 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
8865 +
8866 +#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 18)
8867 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
8868 +
8869 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
8870
8871 /*
8872 @@ -139,7 +147,7 @@
8873 */
8874
8875 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
8876 -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
8877 +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
8878
8879
8880 #else
8881 @@ -163,6 +171,8 @@
8882 #define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS * 8 + 3)
8883 #define __USER32_DS __USER_DS
8884
8885 +#define GDT_ENTRY_KERNEXEC_KERNEL_CS 7
8886 +
8887 #define GDT_ENTRY_TSS 8 /* needs two entries */
8888 #define GDT_ENTRY_LDT 10 /* needs two entries */
8889 #define GDT_ENTRY_TLS_MIN 12
8890 @@ -183,6 +193,7 @@
8891 #endif
8892
8893 #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS * 8)
8894 +#define __KERNEXEC_KERNEL_CS (GDT_ENTRY_KERNEXEC_KERNEL_CS * 8)
8895 #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8)
8896 #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS* 8 + 3)
8897 #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS* 8 + 3)
8898 diff -urNp linux-2.6.36/arch/x86/include/asm/smp.h linux-2.6.36/arch/x86/include/asm/smp.h
8899 --- linux-2.6.36/arch/x86/include/asm/smp.h 2010-10-20 16:30:22.000000000 -0400
8900 +++ linux-2.6.36/arch/x86/include/asm/smp.h 2010-11-06 18:58:15.000000000 -0400
8901 @@ -24,7 +24,7 @@ extern unsigned int num_processors;
8902 DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
8903 DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
8904 DECLARE_PER_CPU(u16, cpu_llc_id);
8905 -DECLARE_PER_CPU(int, cpu_number);
8906 +DECLARE_PER_CPU(unsigned int, cpu_number);
8907
8908 static inline struct cpumask *cpu_sibling_mask(int cpu)
8909 {
8910 diff -urNp linux-2.6.36/arch/x86/include/asm/spinlock.h linux-2.6.36/arch/x86/include/asm/spinlock.h
8911 --- linux-2.6.36/arch/x86/include/asm/spinlock.h 2010-10-20 16:30:22.000000000 -0400
8912 +++ linux-2.6.36/arch/x86/include/asm/spinlock.h 2010-11-06 18:58:15.000000000 -0400
8913 @@ -249,18 +249,50 @@ static inline int arch_write_can_lock(ar
8914 static inline void arch_read_lock(arch_rwlock_t *rw)
8915 {
8916 asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
8917 - "jns 1f\n"
8918 - "call __read_lock_failed\n\t"
8919 +
8920 +#ifdef CONFIG_PAX_REFCOUNT
8921 +#ifdef CONFIG_X86_32
8922 + "into\n0:\n"
8923 +#else
8924 + "jno 0f\n"
8925 + "int $4\n0:\n"
8926 +#endif
8927 + ".pushsection .fixup,\"ax\"\n"
8928 "1:\n"
8929 + LOCK_PREFIX " addl $1,(%0)\n"
8930 + "jmp 0b\n"
8931 + ".popsection\n"
8932 + _ASM_EXTABLE(0b, 1b)
8933 +#endif
8934 +
8935 + "jns 2f\n"
8936 + "call __read_lock_failed\n\t"
8937 + "2:\n"
8938 ::LOCK_PTR_REG (rw) : "memory");
8939 }
8940
8941 static inline void arch_write_lock(arch_rwlock_t *rw)
8942 {
8943 asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
8944 - "jz 1f\n"
8945 - "call __write_lock_failed\n\t"
8946 +
8947 +#ifdef CONFIG_PAX_REFCOUNT
8948 +#ifdef CONFIG_X86_32
8949 + "into\n0:\n"
8950 +#else
8951 + "jno 0f\n"
8952 + "int $4\n0:\n"
8953 +#endif
8954 + ".pushsection .fixup,\"ax\"\n"
8955 "1:\n"
8956 + LOCK_PREFIX " addl %1,(%0)\n"
8957 + "jmp 0b\n"
8958 + ".popsection\n"
8959 + _ASM_EXTABLE(0b, 1b)
8960 +#endif
8961 +
8962 + "jz 2f\n"
8963 + "call __write_lock_failed\n\t"
8964 + "2:\n"
8965 ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
8966 }
8967
8968 @@ -286,12 +318,45 @@ static inline int arch_write_trylock(arc
8969
8970 static inline void arch_read_unlock(arch_rwlock_t *rw)
8971 {
8972 - asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
8973 + asm volatile(LOCK_PREFIX "incl %0\n"
8974 +
8975 +#ifdef CONFIG_PAX_REFCOUNT
8976 +#ifdef CONFIG_X86_32
8977 + "into\n0:\n"
8978 +#else
8979 + "jno 0f\n"
8980 + "int $4\n0:\n"
8981 +#endif
8982 + ".pushsection .fixup,\"ax\"\n"
8983 + "1:\n"
8984 + LOCK_PREFIX "decl %0\n"
8985 + "jmp 0b\n"
8986 + ".popsection\n"
8987 + _ASM_EXTABLE(0b, 1b)
8988 +#endif
8989 +
8990 + :"+m" (rw->lock) : : "memory");
8991 }
8992
8993 static inline void arch_write_unlock(arch_rwlock_t *rw)
8994 {
8995 - asm volatile(LOCK_PREFIX "addl %1, %0"
8996 + asm volatile(LOCK_PREFIX "addl %1, %0\n"
8997 +
8998 +#ifdef CONFIG_PAX_REFCOUNT
8999 +#ifdef CONFIG_X86_32
9000 + "into\n0:\n"
9001 +#else
9002 + "jno 0f\n"
9003 + "int $4\n0:\n"
9004 +#endif
9005 + ".pushsection .fixup,\"ax\"\n"
9006 + "1:\n"
9007 + LOCK_PREFIX "subl %1,%0\n"
9008 + "jmp 0b\n"
9009 + ".popsection\n"
9010 + _ASM_EXTABLE(0b, 1b)
9011 +#endif
9012 +
9013 : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
9014 }
9015
9016 diff -urNp linux-2.6.36/arch/x86/include/asm/system.h linux-2.6.36/arch/x86/include/asm/system.h
9017 --- linux-2.6.36/arch/x86/include/asm/system.h 2010-10-20 16:30:22.000000000 -0400
9018 +++ linux-2.6.36/arch/x86/include/asm/system.h 2010-11-06 18:58:15.000000000 -0400
9019 @@ -202,7 +202,7 @@ static inline unsigned long get_limit(un
9020 {
9021 unsigned long __limit;
9022 asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
9023 - return __limit + 1;
9024 + return __limit;
9025 }
9026
9027 static inline void native_clts(void)
9028 @@ -342,7 +342,7 @@ void enable_hlt(void);
9029
9030 void cpu_idle_wait(void);
9031
9032 -extern unsigned long arch_align_stack(unsigned long sp);
9033 +#define arch_align_stack(x) ((x) & ~0xfUL)
9034 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
9035
9036 void default_idle(void);
9037 diff -urNp linux-2.6.36/arch/x86/include/asm/uaccess_32.h linux-2.6.36/arch/x86/include/asm/uaccess_32.h
9038 --- linux-2.6.36/arch/x86/include/asm/uaccess_32.h 2010-10-20 16:30:22.000000000 -0400
9039 +++ linux-2.6.36/arch/x86/include/asm/uaccess_32.h 2010-11-06 18:58:15.000000000 -0400
9040 @@ -44,6 +44,9 @@ unsigned long __must_check __copy_from_u
9041 static __always_inline unsigned long __must_check
9042 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
9043 {
9044 + if ((long)n < 0)
9045 + return n;
9046 +
9047 if (__builtin_constant_p(n)) {
9048 unsigned long ret;
9049
9050 @@ -62,6 +65,8 @@ __copy_to_user_inatomic(void __user *to,
9051 return ret;
9052 }
9053 }
9054 + if (!__builtin_constant_p(n))
9055 + check_object_size(from, n, true);
9056 return __copy_to_user_ll(to, from, n);
9057 }
9058
9059 @@ -89,6 +94,9 @@ __copy_to_user(void __user *to, const vo
9060 static __always_inline unsigned long
9061 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
9062 {
9063 + if ((long)n < 0)
9064 + return n;
9065 +
9066 /* Avoid zeroing the tail if the copy fails..
9067 * If 'n' is constant and 1, 2, or 4, we do still zero on a failure,
9068 * but as the zeroing behaviour is only significant when n is not
9069 @@ -138,6 +146,10 @@ static __always_inline unsigned long
9070 __copy_from_user(void *to, const void __user *from, unsigned long n)
9071 {
9072 might_fault();
9073 +
9074 + if ((long)n < 0)
9075 + return n;
9076 +
9077 if (__builtin_constant_p(n)) {
9078 unsigned long ret;
9079
9080 @@ -153,6 +165,8 @@ __copy_from_user(void *to, const void __
9081 return ret;
9082 }
9083 }
9084 + if (!__builtin_constant_p(n))
9085 + check_object_size(to, n, false);
9086 return __copy_from_user_ll(to, from, n);
9087 }
9088
9089 @@ -160,6 +174,10 @@ static __always_inline unsigned long __c
9090 const void __user *from, unsigned long n)
9091 {
9092 might_fault();
9093 +
9094 + if ((long)n < 0)
9095 + return n;
9096 +
9097 if (__builtin_constant_p(n)) {
9098 unsigned long ret;
9099
9100 @@ -182,15 +200,19 @@ static __always_inline unsigned long
9101 __copy_from_user_inatomic_nocache(void *to, const void __user *from,
9102 unsigned long n)
9103 {
9104 - return __copy_from_user_ll_nocache_nozero(to, from, n);
9105 -}
9106 + if ((long)n < 0)
9107 + return n;
9108
9109 -unsigned long __must_check copy_to_user(void __user *to,
9110 - const void *from, unsigned long n);
9111 -unsigned long __must_check _copy_from_user(void *to,
9112 - const void __user *from,
9113 - unsigned long n);
9114 + return __copy_from_user_ll_nocache_nozero(to, from, n);
9115 +}
9116
9117 +extern void copy_to_user_overflow(void)
9118 +#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
9119 + __compiletime_error("copy_to_user() buffer size is not provably correct")
9120 +#else
9121 + __compiletime_warning("copy_to_user() buffer size is not provably correct")
9122 +#endif
9123 +;
9124
9125 extern void copy_from_user_overflow(void)
9126 #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
9127 @@ -200,17 +222,61 @@ extern void copy_from_user_overflow(void
9128 #endif
9129 ;
9130
9131 -static inline unsigned long __must_check copy_from_user(void *to,
9132 - const void __user *from,
9133 - unsigned long n)
9134 +/**
9135 + * copy_to_user: - Copy a block of data into user space.
9136 + * @to: Destination address, in user space.
9137 + * @from: Source address, in kernel space.
9138 + * @n: Number of bytes to copy.
9139 + *
9140 + * Context: User context only. This function may sleep.
9141 + *
9142 + * Copy data from kernel space to user space.
9143 + *
9144 + * Returns number of bytes that could not be copied.
9145 + * On success, this will be zero.
9146 + */
9147 +static inline unsigned long __must_check
9148 +copy_to_user(void __user *to, const void *from, unsigned long n)
9149 +{
9150 + int sz = __compiletime_object_size(from);
9151 +
9152 + if (unlikely(sz != -1 && sz < n))
9153 + copy_to_user_overflow();
9154 + else if (access_ok(VERIFY_WRITE, to, n))
9155 + n = __copy_to_user(to, from, n);
9156 + return n;
9157 +}
9158 +
9159 +/**
9160 + * copy_from_user: - Copy a block of data from user space.
9161 + * @to: Destination address, in kernel space.
9162 + * @from: Source address, in user space.
9163 + * @n: Number of bytes to copy.
9164 + *
9165 + * Context: User context only. This function may sleep.
9166 + *
9167 + * Copy data from user space to kernel space.
9168 + *
9169 + * Returns number of bytes that could not be copied.
9170 + * On success, this will be zero.
9171 + *
9172 + * If some data could not be copied, this function will pad the copied
9173 + * data to the requested size using zero bytes.
9174 + */
9175 +static inline unsigned long __must_check
9176 +copy_from_user(void *to, const void __user *from, unsigned long n)
9177 {
9178 int sz = __compiletime_object_size(to);
9179
9180 - if (likely(sz == -1 || sz >= n))
9181 - n = _copy_from_user(to, from, n);
9182 - else
9183 + if (unlikely(sz != -1 && sz < n))
9184 copy_from_user_overflow();
9185 -
9186 + else if (access_ok(VERIFY_READ, from, n))
9187 + n = __copy_from_user(to, from, n);
9188 + else if ((long)n > 0) {
9189 + if (!__builtin_constant_p(n))
9190 + check_object_size(to, n, false);
9191 + memset(to, 0, n);
9192 + }
9193 return n;
9194 }
9195
9196 diff -urNp linux-2.6.36/arch/x86/include/asm/uaccess_64.h linux-2.6.36/arch/x86/include/asm/uaccess_64.h
9197 --- linux-2.6.36/arch/x86/include/asm/uaccess_64.h 2010-10-20 16:30:22.000000000 -0400
9198 +++ linux-2.6.36/arch/x86/include/asm/uaccess_64.h 2010-11-06 18:58:15.000000000 -0400
9199 @@ -11,6 +11,9 @@
9200 #include <asm/alternative.h>
9201 #include <asm/cpufeature.h>
9202 #include <asm/page.h>
9203 +#include <asm/pgtable.h>
9204 +
9205 +#define set_fs(x) (current_thread_info()->addr_limit = (x))
9206
9207 /*
9208 * Copy To/From Userspace
9209 @@ -37,26 +40,26 @@ copy_user_generic(void *to, const void *
9210 return ret;
9211 }
9212
9213 -__must_check unsigned long
9214 -_copy_to_user(void __user *to, const void *from, unsigned len);
9215 -__must_check unsigned long
9216 -_copy_from_user(void *to, const void __user *from, unsigned len);
9217 +static __always_inline __must_check unsigned long
9218 +__copy_to_user(void __user *to, const void *from, unsigned len);
9219 +static __always_inline __must_check unsigned long
9220 +__copy_from_user(void *to, const void __user *from, unsigned len);
9221 __must_check unsigned long
9222 copy_in_user(void __user *to, const void __user *from, unsigned len);
9223
9224 static inline unsigned long __must_check copy_from_user(void *to,
9225 const void __user *from,
9226 - unsigned long n)
9227 + unsigned n)
9228 {
9229 - int sz = __compiletime_object_size(to);
9230 -
9231 might_fault();
9232 - if (likely(sz == -1 || sz >= n))
9233 - n = _copy_from_user(to, from, n);
9234 -#ifdef CONFIG_DEBUG_VM
9235 - else
9236 - WARN(1, "Buffer overflow detected!\n");
9237 -#endif
9238 +
9239 + if (access_ok(VERIFY_READ, from, n))
9240 + n = __copy_from_user(to, from, n);
9241 + else if ((int)n > 0) {
9242 + if (!__builtin_constant_p(n))
9243 + check_object_size(to, n, false);
9244 + memset(to, 0, n);
9245 + }
9246 return n;
9247 }
9248
9249 @@ -65,17 +68,35 @@ int copy_to_user(void __user *dst, const
9250 {
9251 might_fault();
9252
9253 - return _copy_to_user(dst, src, size);
9254 + if (access_ok(VERIFY_WRITE, dst, size))
9255 + size = __copy_to_user(dst, src, size);
9256 + return size;
9257 }
9258
9259 static __always_inline __must_check
9260 -int __copy_from_user(void *dst, const void __user *src, unsigned size)
9261 +unsigned long __copy_from_user(void *dst, const void __user *src, unsigned size)
9262 {
9263 - int ret = 0;
9264 + int sz = __compiletime_object_size(dst);
9265 + unsigned ret = 0;
9266
9267 might_fault();
9268 - if (!__builtin_constant_p(size))
9269 +
9270 + if ((int)size < 0)
9271 + return size;
9272 +
9273 + if (unlikely(sz != -1 && sz < size)) {
9274 +#ifdef CONFIG_DEBUG_VM
9275 + WARN(1, "Buffer overflow detected!\n");
9276 +#endif
9277 + return size;
9278 + }
9279 +
9280 + if (!__builtin_constant_p(size)) {
9281 + check_object_size(dst, size, false);
9282 + if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9283 + src += PAX_USER_SHADOW_BASE;
9284 return copy_user_generic(dst, (__force void *)src, size);
9285 + }
9286 switch (size) {
9287 case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
9288 ret, "b", "b", "=q", 1);
9289 @@ -108,18 +129,36 @@ int __copy_from_user(void *dst, const vo
9290 ret, "q", "", "=r", 8);
9291 return ret;
9292 default:
9293 + if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9294 + src += PAX_USER_SHADOW_BASE;
9295 return copy_user_generic(dst, (__force void *)src, size);
9296 }
9297 }
9298
9299 static __always_inline __must_check
9300 -int __copy_to_user(void __user *dst, const void *src, unsigned size)
9301 +unsigned long __copy_to_user(void __user *dst, const void *src, unsigned size)
9302 {
9303 - int ret = 0;
9304 + int sz = __compiletime_object_size(src);
9305 + unsigned ret = 0;
9306
9307 might_fault();
9308 - if (!__builtin_constant_p(size))
9309 +
9310 + if ((int)size < 0)
9311 + return size;
9312 +
9313 + if (unlikely(sz != -1 && sz < size)) {
9314 +#ifdef CONFIG_DEBUG_VM
9315 + WARN(1, "Buffer overflow detected!\n");
9316 +#endif
9317 + return size;
9318 + }
9319 +
9320 + if (!__builtin_constant_p(size)) {
9321 + check_object_size(src, size, true);
9322 + if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9323 + dst += PAX_USER_SHADOW_BASE;
9324 return copy_user_generic((__force void *)dst, src, size);
9325 + }
9326 switch (size) {
9327 case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
9328 ret, "b", "b", "iq", 1);
9329 @@ -152,19 +191,30 @@ int __copy_to_user(void __user *dst, con
9330 ret, "q", "", "er", 8);
9331 return ret;
9332 default:
9333 + if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9334 + dst += PAX_USER_SHADOW_BASE;
9335 return copy_user_generic((__force void *)dst, src, size);
9336 }
9337 }
9338
9339 static __always_inline __must_check
9340 -int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
9341 +unsigned long __copy_in_user(void __user *dst, const void __user *src, unsigned size)
9342 {
9343 - int ret = 0;
9344 + unsigned ret = 0;
9345
9346 might_fault();
9347 - if (!__builtin_constant_p(size))
9348 +
9349 + if ((int)size < 0)
9350 + return size;
9351 +
9352 + if (!__builtin_constant_p(size)) {
9353 + if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9354 + src += PAX_USER_SHADOW_BASE;
9355 + if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9356 + dst += PAX_USER_SHADOW_BASE;
9357 return copy_user_generic((__force void *)dst,
9358 (__force void *)src, size);
9359 + }
9360 switch (size) {
9361 case 1: {
9362 u8 tmp;
9363 @@ -204,6 +254,10 @@ int __copy_in_user(void __user *dst, con
9364 return ret;
9365 }
9366 default:
9367 + if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9368 + src += PAX_USER_SHADOW_BASE;
9369 + if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9370 + dst += PAX_USER_SHADOW_BASE;
9371 return copy_user_generic((__force void *)dst,
9372 (__force void *)src, size);
9373 }
9374 @@ -222,33 +276,45 @@ __must_check unsigned long __clear_user(
9375 static __must_check __always_inline int
9376 __copy_from_user_inatomic(void *dst, const void __user *src, unsigned size)
9377 {
9378 + if ((unsigned long)src < PAX_USER_SHADOW_BASE)
9379 + src += PAX_USER_SHADOW_BASE;
9380 return copy_user_generic(dst, (__force const void *)src, size);
9381 }
9382
9383 -static __must_check __always_inline int
9384 +static __must_check __always_inline unsigned long
9385 __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
9386 {
9387 + if ((int)size < 0)
9388 + return size;
9389 +
9390 + if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
9391 + dst += PAX_USER_SHADOW_BASE;
9392 return copy_user_generic((__force void *)dst, src, size);
9393 }
9394
9395 -extern long __copy_user_nocache(void *dst, const void __user *src,
9396 +extern unsigned long __copy_user_nocache(void *dst, const void __user *src,
9397 unsigned size, int zerorest);
9398
9399 -static inline int
9400 -__copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
9401 +static inline unsigned long __copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
9402 {
9403 might_sleep();
9404 +
9405 + if ((int)size < 0)
9406 + return size;
9407 +
9408 return __copy_user_nocache(dst, src, size, 1);
9409 }
9410
9411 -static inline int
9412 -__copy_from_user_inatomic_nocache(void *dst, const void __user *src,
9413 +static inline unsigned long __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
9414 unsigned size)
9415 {
9416 + if ((int)size < 0)
9417 + return size;
9418 +
9419 return __copy_user_nocache(dst, src, size, 0);
9420 }
9421
9422 -unsigned long
9423 +extern unsigned long
9424 copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest);
9425
9426 #endif /* _ASM_X86_UACCESS_64_H */
9427 diff -urNp linux-2.6.36/arch/x86/include/asm/uaccess.h linux-2.6.36/arch/x86/include/asm/uaccess.h
9428 --- linux-2.6.36/arch/x86/include/asm/uaccess.h 2010-10-20 16:30:22.000000000 -0400
9429 +++ linux-2.6.36/arch/x86/include/asm/uaccess.h 2010-11-06 18:58:15.000000000 -0400
9430 @@ -8,12 +8,15 @@
9431 #include <linux/thread_info.h>
9432 #include <linux/prefetch.h>
9433 #include <linux/string.h>
9434 +#include <linux/sched.h>
9435 #include <asm/asm.h>
9436 #include <asm/page.h>
9437
9438 #define VERIFY_READ 0
9439 #define VERIFY_WRITE 1
9440
9441 +extern void check_object_size(const void *ptr, unsigned long n, bool to);
9442 +
9443 /*
9444 * The fs value determines whether argument validity checking should be
9445 * performed or not. If get_fs() == USER_DS, checking is performed, with
9446 @@ -29,7 +32,12 @@
9447
9448 #define get_ds() (KERNEL_DS)
9449 #define get_fs() (current_thread_info()->addr_limit)
9450 +#ifdef CONFIG_X86_32
9451 +void __set_fs(mm_segment_t x, int cpu);
9452 +void set_fs(mm_segment_t x);
9453 +#else
9454 #define set_fs(x) (current_thread_info()->addr_limit = (x))
9455 +#endif
9456
9457 #define segment_eq(a, b) ((a).seg == (b).seg)
9458
9459 @@ -77,7 +85,33 @@
9460 * checks that the pointer is in the user space range - after calling
9461 * this function, memory access functions may still return -EFAULT.
9462 */
9463 -#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0))
9464 +#define __access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0))
9465 +#define access_ok(type, addr, size) \
9466 +({ \
9467 + long __size = size; \
9468 + unsigned long __addr = (unsigned long)addr; \
9469 + unsigned long __addr_ao = __addr & PAGE_MASK; \
9470 + unsigned long __end_ao = __addr + __size - 1; \
9471 + bool __ret_ao = __range_not_ok(__addr, __size) == 0; \
9472 + if (__ret_ao && unlikely((__end_ao ^ __addr_ao) & PAGE_MASK)) { \
9473 + while(__addr_ao <= __end_ao) { \
9474 + char __c_ao; \
9475 + __addr_ao += PAGE_SIZE; \
9476 + if (__size > PAGE_SIZE) \
9477 + cond_resched(); \
9478 + if (__get_user(__c_ao, (char __user *)__addr)) \
9479 + break; \
9480 + if (type != VERIFY_WRITE) { \
9481 + __addr = __addr_ao; \
9482 + continue; \
9483 + } \
9484 + if (__put_user(__c_ao, (char __user *)__addr)) \
9485 + break; \
9486 + __addr = __addr_ao; \
9487 + } \
9488 + } \
9489 + __ret_ao; \
9490 +})
9491
9492 /*
9493 * The exception table consists of pairs of addresses: the first is the
9494 @@ -183,13 +217,21 @@ extern int __get_user_bad(void);
9495 asm volatile("call __put_user_" #size : "=a" (__ret_pu) \
9496 : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
9497
9498 -
9499 +#ifdef CONFIG_X86_32
9500 +#define _ASM_LOAD_USER_DS(ds) "movw %w" #ds ",%%ds\n"
9501 +#define _ASM_LOAD_KERNEL_DS "pushl %%ss; popl %%ds\n"
9502 +#else
9503 +#define _ASM_LOAD_USER_DS(ds)
9504 +#define _ASM_LOAD_KERNEL_DS
9505 +#endif
9506
9507 #ifdef CONFIG_X86_32
9508 #define __put_user_asm_u64(x, addr, err, errret) \
9509 - asm volatile("1: movl %%eax,0(%2)\n" \
9510 - "2: movl %%edx,4(%2)\n" \
9511 + asm volatile(_ASM_LOAD_USER_DS(5) \
9512 + "1: movl %%eax,%%ds:0(%2)\n" \
9513 + "2: movl %%edx,%%ds:4(%2)\n" \
9514 "3:\n" \
9515 + _ASM_LOAD_KERNEL_DS \
9516 ".section .fixup,\"ax\"\n" \
9517 "4: movl %3,%0\n" \
9518 " jmp 3b\n" \
9519 @@ -197,15 +239,18 @@ extern int __get_user_bad(void);
9520 _ASM_EXTABLE(1b, 4b) \
9521 _ASM_EXTABLE(2b, 4b) \
9522 : "=r" (err) \
9523 - : "A" (x), "r" (addr), "i" (errret), "0" (err))
9524 + : "A" (x), "r" (addr), "i" (errret), "0" (err), \
9525 + "r"(__USER_DS))
9526
9527 #define __put_user_asm_ex_u64(x, addr) \
9528 - asm volatile("1: movl %%eax,0(%1)\n" \
9529 - "2: movl %%edx,4(%1)\n" \
9530 + asm volatile(_ASM_LOAD_USER_DS(2) \
9531 + "1: movl %%eax,%%ds:0(%1)\n" \
9532 + "2: movl %%edx,%%ds:4(%1)\n" \
9533 "3:\n" \
9534 + _ASM_LOAD_KERNEL_DS \
9535 _ASM_EXTABLE(1b, 2b - 1b) \
9536 _ASM_EXTABLE(2b, 3b - 2b) \
9537 - : : "A" (x), "r" (addr))
9538 + : : "A" (x), "r" (addr), "r"(__USER_DS))
9539
9540 #define __put_user_x8(x, ptr, __ret_pu) \
9541 asm volatile("call __put_user_8" : "=a" (__ret_pu) \
9542 @@ -374,16 +419,18 @@ do { \
9543 } while (0)
9544
9545 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
9546 - asm volatile("1: mov"itype" %2,%"rtype"1\n" \
9547 + asm volatile(_ASM_LOAD_USER_DS(5) \
9548 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
9549 "2:\n" \
9550 + _ASM_LOAD_KERNEL_DS \
9551 ".section .fixup,\"ax\"\n" \
9552 "3: mov %3,%0\n" \
9553 " xor"itype" %"rtype"1,%"rtype"1\n" \
9554 " jmp 2b\n" \
9555 ".previous\n" \
9556 _ASM_EXTABLE(1b, 3b) \
9557 - : "=r" (err), ltype(x) \
9558 - : "m" (__m(addr)), "i" (errret), "0" (err))
9559 + : "=r" (err), ltype (x) \
9560 + : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
9561
9562 #define __get_user_size_ex(x, ptr, size) \
9563 do { \
9564 @@ -407,10 +454,12 @@ do { \
9565 } while (0)
9566
9567 #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
9568 - asm volatile("1: mov"itype" %1,%"rtype"0\n" \
9569 + asm volatile(_ASM_LOAD_USER_DS(2) \
9570 + "1: mov"itype" %%ds:%1,%"rtype"0\n" \
9571 "2:\n" \
9572 + _ASM_LOAD_KERNEL_DS \
9573 _ASM_EXTABLE(1b, 2b - 1b) \
9574 - : ltype(x) : "m" (__m(addr)))
9575 + : ltype(x) : "m" (__m(addr)), "r"(__USER_DS))
9576
9577 #define __put_user_nocheck(x, ptr, size) \
9578 ({ \
9579 @@ -424,13 +473,24 @@ do { \
9580 int __gu_err; \
9581 unsigned long __gu_val; \
9582 __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
9583 - (x) = (__force __typeof__(*(ptr)))__gu_val; \
9584 + (x) = (__typeof__(*(ptr)))__gu_val; \
9585 __gu_err; \
9586 })
9587
9588 /* FIXME: this hack is definitely wrong -AK */
9589 struct __large_struct { unsigned long buf[100]; };
9590 -#define __m(x) (*(struct __large_struct __user *)(x))
9591 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
9592 +#define ____m(x) \
9593 +({ \
9594 + unsigned long ____x = (unsigned long)(x); \
9595 + if (____x < PAX_USER_SHADOW_BASE) \
9596 + ____x += PAX_USER_SHADOW_BASE; \
9597 + (void __user *)____x; \
9598 +})
9599 +#else
9600 +#define ____m(x) (x)
9601 +#endif
9602 +#define __m(x) (*(struct __large_struct __user *)____m(x))
9603
9604 /*
9605 * Tell gcc we read from memory instead of writing: this is because
9606 @@ -438,21 +498,26 @@ struct __large_struct { unsigned long bu
9607 * aliasing issues.
9608 */
9609 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
9610 - asm volatile("1: mov"itype" %"rtype"1,%2\n" \
9611 + asm volatile(_ASM_LOAD_USER_DS(5) \
9612 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
9613 "2:\n" \
9614 + _ASM_LOAD_KERNEL_DS \
9615 ".section .fixup,\"ax\"\n" \
9616 "3: mov %3,%0\n" \
9617 " jmp 2b\n" \
9618 ".previous\n" \
9619 _ASM_EXTABLE(1b, 3b) \
9620 : "=r"(err) \
9621 - : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
9622 + : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
9623 + "r"(__USER_DS))
9624
9625 #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
9626 - asm volatile("1: mov"itype" %"rtype"0,%1\n" \
9627 + asm volatile(_ASM_LOAD_USER_DS(2) \
9628 + "1: mov"itype" %"rtype"0,%%ds:%1\n" \
9629 "2:\n" \
9630 + _ASM_LOAD_KERNEL_DS \
9631 _ASM_EXTABLE(1b, 2b - 1b) \
9632 - : : ltype(x), "m" (__m(addr)))
9633 + : : ltype(x), "m" (__m(addr)), "r"(__USER_DS))
9634
9635 /*
9636 * uaccess_try and catch
9637 @@ -530,7 +595,7 @@ struct __large_struct { unsigned long bu
9638 #define get_user_ex(x, ptr) do { \
9639 unsigned long __gue_val; \
9640 __get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr)))); \
9641 - (x) = (__force __typeof__(*(ptr)))__gue_val; \
9642 + (x) = (__typeof__(*(ptr)))__gue_val; \
9643 } while (0)
9644
9645 #ifdef CONFIG_X86_WP_WORKS_OK
9646 @@ -567,6 +632,7 @@ extern struct movsl_mask {
9647
9648 #define ARCH_HAS_NOCACHE_UACCESS 1
9649
9650 +#define ARCH_HAS_SORT_EXTABLE
9651 #ifdef CONFIG_X86_32
9652 # include "uaccess_32.h"
9653 #else
9654 diff -urNp linux-2.6.36/arch/x86/include/asm/vgtod.h linux-2.6.36/arch/x86/include/asm/vgtod.h
9655 --- linux-2.6.36/arch/x86/include/asm/vgtod.h 2010-10-20 16:30:22.000000000 -0400
9656 +++ linux-2.6.36/arch/x86/include/asm/vgtod.h 2010-11-06 18:58:15.000000000 -0400
9657 @@ -14,6 +14,7 @@ struct vsyscall_gtod_data {
9658 int sysctl_enabled;
9659 struct timezone sys_tz;
9660 struct { /* extract of a clocksource struct */
9661 + char name[8];
9662 cycle_t (*vread)(void);
9663 cycle_t cycle_last;
9664 cycle_t mask;
9665 diff -urNp linux-2.6.36/arch/x86/include/asm/vmi.h linux-2.6.36/arch/x86/include/asm/vmi.h
9666 --- linux-2.6.36/arch/x86/include/asm/vmi.h 2010-10-20 16:30:22.000000000 -0400
9667 +++ linux-2.6.36/arch/x86/include/asm/vmi.h 2010-11-06 18:58:15.000000000 -0400
9668 @@ -191,6 +191,7 @@ struct vrom_header {
9669 u8 reserved[96]; /* Reserved for headers */
9670 char vmi_init[8]; /* VMI_Init jump point */
9671 char get_reloc[8]; /* VMI_GetRelocationInfo jump point */
9672 + char rom_data[8048]; /* rest of the option ROM */
9673 } __attribute__((packed));
9674
9675 struct pnp_header {
9676 diff -urNp linux-2.6.36/arch/x86/include/asm/vsyscall.h linux-2.6.36/arch/x86/include/asm/vsyscall.h
9677 --- linux-2.6.36/arch/x86/include/asm/vsyscall.h 2010-10-20 16:30:22.000000000 -0400
9678 +++ linux-2.6.36/arch/x86/include/asm/vsyscall.h 2010-11-06 18:58:15.000000000 -0400
9679 @@ -15,9 +15,10 @@ enum vsyscall_num {
9680
9681 #ifdef __KERNEL__
9682 #include <linux/seqlock.h>
9683 +#include <linux/getcpu.h>
9684 +#include <linux/time.h>
9685
9686 #define __section_vgetcpu_mode __attribute__ ((unused, __section__ (".vgetcpu_mode"), aligned(16)))
9687 -#define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16)))
9688
9689 /* Definitions for CONFIG_GENERIC_TIME definitions */
9690 #define __section_vsyscall_gtod_data __attribute__ \
9691 @@ -31,7 +32,6 @@ enum vsyscall_num {
9692 #define VGETCPU_LSL 2
9693
9694 extern int __vgetcpu_mode;
9695 -extern volatile unsigned long __jiffies;
9696
9697 /* kernel space (writeable) */
9698 extern int vgetcpu_mode;
9699 @@ -39,6 +39,9 @@ extern struct timezone sys_tz;
9700
9701 extern void map_vsyscall(void);
9702
9703 +extern int vgettimeofday(struct timeval * tv, struct timezone * tz);
9704 +extern time_t vtime(time_t *t);
9705 +extern long vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache);
9706 #endif /* __KERNEL__ */
9707
9708 #endif /* _ASM_X86_VSYSCALL_H */
9709 diff -urNp linux-2.6.36/arch/x86/include/asm/xsave.h linux-2.6.36/arch/x86/include/asm/xsave.h
9710 --- linux-2.6.36/arch/x86/include/asm/xsave.h 2010-10-20 16:30:22.000000000 -0400
9711 +++ linux-2.6.36/arch/x86/include/asm/xsave.h 2010-11-06 18:58:15.000000000 -0400
9712 @@ -65,6 +65,11 @@ static inline int xsave_user(struct xsav
9713 {
9714 int err;
9715
9716 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
9717 + if ((unsigned long)buf < PAX_USER_SHADOW_BASE)
9718 + buf = (struct xsave_struct __user *)((void __user*)buf + PAX_USER_SHADOW_BASE);
9719 +#endif
9720 +
9721 /*
9722 * Clear the xsave header first, so that reserved fields are
9723 * initialized to zero.
9724 @@ -100,6 +105,11 @@ static inline int xrestore_user(struct x
9725 u32 lmask = mask;
9726 u32 hmask = mask >> 32;
9727
9728 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
9729 + if ((unsigned long)xstate < PAX_USER_SHADOW_BASE)
9730 + xstate = (struct xsave_struct *)((void *)xstate + PAX_USER_SHADOW_BASE);
9731 +#endif
9732 +
9733 __asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n"
9734 "2:\n"
9735 ".section .fixup,\"ax\"\n"
9736 diff -urNp linux-2.6.36/arch/x86/Kconfig linux-2.6.36/arch/x86/Kconfig
9737 --- linux-2.6.36/arch/x86/Kconfig 2010-10-20 16:30:22.000000000 -0400
9738 +++ linux-2.6.36/arch/x86/Kconfig 2010-11-06 18:58:50.000000000 -0400
9739 @@ -1036,7 +1036,7 @@ choice
9740
9741 config NOHIGHMEM
9742 bool "off"
9743 - depends on !X86_NUMAQ
9744 + depends on !X86_NUMAQ && !(PAX_PAGEEXEC && PAX_ENABLE_PAE)
9745 ---help---
9746 Linux can use up to 64 Gigabytes of physical memory on x86 systems.
9747 However, the address space of 32-bit x86 processors is only 4
9748 @@ -1073,7 +1073,7 @@ config NOHIGHMEM
9749
9750 config HIGHMEM4G
9751 bool "4GB"
9752 - depends on !X86_NUMAQ
9753 + depends on !X86_NUMAQ && !(PAX_PAGEEXEC && PAX_ENABLE_PAE)
9754 ---help---
9755 Select this if you have a 32-bit processor and between 1 and 4
9756 gigabytes of physical RAM.
9757 @@ -1127,7 +1127,7 @@ config PAGE_OFFSET
9758 hex
9759 default 0xB0000000 if VMSPLIT_3G_OPT
9760 default 0x80000000 if VMSPLIT_2G
9761 - default 0x78000000 if VMSPLIT_2G_OPT
9762 + default 0x70000000 if VMSPLIT_2G_OPT
9763 default 0x40000000 if VMSPLIT_1G
9764 default 0xC0000000
9765 depends on X86_32
9766 @@ -1459,7 +1459,7 @@ config ARCH_USES_PG_UNCACHED
9767
9768 config EFI
9769 bool "EFI runtime service support"
9770 - depends on ACPI
9771 + depends on ACPI && !PAX_KERNEXEC
9772 ---help---
9773 This enables the kernel to use EFI runtime services that are
9774 available (such as the EFI variable services).
9775 @@ -1546,6 +1546,7 @@ config KEXEC_JUMP
9776 config PHYSICAL_START
9777 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
9778 default "0x1000000"
9779 + range 0x400000 0x40000000
9780 ---help---
9781 This gives the physical address where the kernel is loaded.
9782
9783 @@ -1609,6 +1610,7 @@ config X86_NEED_RELOCS
9784 config PHYSICAL_ALIGN
9785 hex "Alignment value to which kernel should be aligned" if X86_32
9786 default "0x1000000"
9787 + range 0x400000 0x1000000 if PAX_KERNEXEC
9788 range 0x2000 0x1000000
9789 ---help---
9790 This value puts the alignment restrictions on physical address
9791 @@ -1640,9 +1642,10 @@ config HOTPLUG_CPU
9792 Say N if you want to disable CPU hotplug.
9793
9794 config COMPAT_VDSO
9795 - def_bool y
9796 + def_bool n
9797 prompt "Compat VDSO support"
9798 depends on X86_32 || IA32_EMULATION
9799 + depends on !PAX_NOEXEC && !PAX_MEMORY_UDEREF
9800 ---help---
9801 Map the 32-bit VDSO to the predictable old-style address too.
9802
9803 diff -urNp linux-2.6.36/arch/x86/Kconfig.cpu linux-2.6.36/arch/x86/Kconfig.cpu
9804 --- linux-2.6.36/arch/x86/Kconfig.cpu 2010-10-20 16:30:22.000000000 -0400
9805 +++ linux-2.6.36/arch/x86/Kconfig.cpu 2010-11-06 18:58:15.000000000 -0400
9806 @@ -336,7 +336,7 @@ config X86_PPRO_FENCE
9807
9808 config X86_F00F_BUG
9809 def_bool y
9810 - depends on M586MMX || M586TSC || M586 || M486 || M386
9811 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
9812
9813 config X86_INVD_BUG
9814 def_bool y
9815 @@ -360,7 +360,7 @@ config X86_POPAD_OK
9816
9817 config X86_ALIGNMENT_16
9818 def_bool y
9819 - depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
9820 + depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
9821
9822 config X86_INTEL_USERCOPY
9823 def_bool y
9824 @@ -406,7 +406,7 @@ config X86_CMPXCHG64
9825 # generates cmov.
9826 config X86_CMOV
9827 def_bool y
9828 - depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
9829 + depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
9830
9831 config X86_MINIMUM_CPU_FAMILY
9832 int
9833 diff -urNp linux-2.6.36/arch/x86/Kconfig.debug linux-2.6.36/arch/x86/Kconfig.debug
9834 --- linux-2.6.36/arch/x86/Kconfig.debug 2010-10-20 16:30:22.000000000 -0400
9835 +++ linux-2.6.36/arch/x86/Kconfig.debug 2010-11-06 18:58:15.000000000 -0400
9836 @@ -97,7 +97,7 @@ config X86_PTDUMP
9837 config DEBUG_RODATA
9838 bool "Write protect kernel read-only data structures"
9839 default y
9840 - depends on DEBUG_KERNEL
9841 + depends on DEBUG_KERNEL && BROKEN
9842 ---help---
9843 Mark the kernel read-only data as write-protected in the pagetables,
9844 in order to catch accidental (and incorrect) writes to such const
9845 diff -urNp linux-2.6.36/arch/x86/kernel/acpi/boot.c linux-2.6.36/arch/x86/kernel/acpi/boot.c
9846 --- linux-2.6.36/arch/x86/kernel/acpi/boot.c 2010-10-20 16:30:22.000000000 -0400
9847 +++ linux-2.6.36/arch/x86/kernel/acpi/boot.c 2010-11-06 18:58:15.000000000 -0400
9848 @@ -1472,7 +1472,7 @@ static struct dmi_system_id __initdata a
9849 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
9850 },
9851 },
9852 - {}
9853 + { NULL, NULL, {{0, {0}}}, NULL}
9854 };
9855
9856 /*
9857 diff -urNp linux-2.6.36/arch/x86/kernel/acpi/sleep.c linux-2.6.36/arch/x86/kernel/acpi/sleep.c
9858 --- linux-2.6.36/arch/x86/kernel/acpi/sleep.c 2010-10-20 16:30:22.000000000 -0400
9859 +++ linux-2.6.36/arch/x86/kernel/acpi/sleep.c 2010-11-06 18:58:15.000000000 -0400
9860 @@ -11,11 +11,12 @@
9861 #include <linux/cpumask.h>
9862 #include <asm/segment.h>
9863 #include <asm/desc.h>
9864 +#include <asm/e820.h>
9865
9866 #include "realmode/wakeup.h"
9867 #include "sleep.h"
9868
9869 -unsigned long acpi_wakeup_address;
9870 +unsigned long acpi_wakeup_address = 0x2000;
9871 unsigned long acpi_realmode_flags;
9872
9873 /* address in low memory of the wakeup routine. */
9874 @@ -96,8 +97,12 @@ int acpi_save_state_mem(void)
9875 header->trampoline_segment = setup_trampoline() >> 4;
9876 #ifdef CONFIG_SMP
9877 stack_start.sp = temp_stack + sizeof(temp_stack);
9878 +
9879 + pax_open_kernel();
9880 early_gdt_descr.address =
9881 (unsigned long)get_cpu_gdt_table(smp_processor_id());
9882 + pax_close_kernel();
9883 +
9884 initial_gs = per_cpu_offset(smp_processor_id());
9885 #endif
9886 initial_code = (unsigned long)wakeup_long64;
9887 diff -urNp linux-2.6.36/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.36/arch/x86/kernel/acpi/wakeup_32.S
9888 --- linux-2.6.36/arch/x86/kernel/acpi/wakeup_32.S 2010-10-20 16:30:22.000000000 -0400
9889 +++ linux-2.6.36/arch/x86/kernel/acpi/wakeup_32.S 2010-11-06 18:58:15.000000000 -0400
9890 @@ -30,13 +30,11 @@ wakeup_pmode_return:
9891 # and restore the stack ... but you need gdt for this to work
9892 movl saved_context_esp, %esp
9893
9894 - movl %cs:saved_magic, %eax
9895 - cmpl $0x12345678, %eax
9896 + cmpl $0x12345678, saved_magic
9897 jne bogus_magic
9898
9899 # jump to place where we left off
9900 - movl saved_eip, %eax
9901 - jmp *%eax
9902 + jmp *(saved_eip)
9903
9904 bogus_magic:
9905 jmp bogus_magic
9906 diff -urNp linux-2.6.36/arch/x86/kernel/alternative.c linux-2.6.36/arch/x86/kernel/alternative.c
9907 --- linux-2.6.36/arch/x86/kernel/alternative.c 2010-10-20 16:30:22.000000000 -0400
9908 +++ linux-2.6.36/arch/x86/kernel/alternative.c 2010-11-06 18:58:15.000000000 -0400
9909 @@ -248,7 +248,7 @@ static void alternatives_smp_lock(const
9910 if (!*poff || ptr < text || ptr >= text_end)
9911 continue;
9912 /* turn DS segment override prefix into lock prefix */
9913 - if (*ptr == 0x3e)
9914 + if (*ktla_ktva(ptr) == 0x3e)
9915 text_poke(ptr, ((unsigned char []){0xf0}), 1);
9916 };
9917 mutex_unlock(&text_mutex);
9918 @@ -269,7 +269,7 @@ static void alternatives_smp_unlock(cons
9919 if (!*poff || ptr < text || ptr >= text_end)
9920 continue;
9921 /* turn lock prefix into DS segment override prefix */
9922 - if (*ptr == 0xf0)
9923 + if (*ktla_ktva(ptr) == 0xf0)
9924 text_poke(ptr, ((unsigned char []){0x3E}), 1);
9925 };
9926 mutex_unlock(&text_mutex);
9927 @@ -437,7 +437,7 @@ void __init_or_module apply_paravirt(str
9928
9929 BUG_ON(p->len > MAX_PATCH_LEN);
9930 /* prep the buffer with the original instructions */
9931 - memcpy(insnbuf, p->instr, p->len);
9932 + memcpy(insnbuf, ktla_ktva(p->instr), p->len);
9933 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
9934 (unsigned long)p->instr, p->len);
9935
9936 @@ -505,7 +505,7 @@ void __init alternative_instructions(voi
9937 if (smp_alt_once)
9938 free_init_pages("SMP alternatives",
9939 (unsigned long)__smp_locks,
9940 - (unsigned long)__smp_locks_end);
9941 + PAGE_ALIGN((unsigned long)__smp_locks_end));
9942
9943 restart_nmi();
9944 }
9945 @@ -522,13 +522,17 @@ void __init alternative_instructions(voi
9946 * instructions. And on the local CPU you need to be protected again NMI or MCE
9947 * handlers seeing an inconsistent instruction while you patch.
9948 */
9949 -static void *__init_or_module text_poke_early(void *addr, const void *opcode,
9950 +static void *__kprobes text_poke_early(void *addr, const void *opcode,
9951 size_t len)
9952 {
9953 unsigned long flags;
9954 local_irq_save(flags);
9955 - memcpy(addr, opcode, len);
9956 +
9957 + pax_open_kernel();
9958 + memcpy(ktla_ktva(addr), opcode, len);
9959 sync_core();
9960 + pax_close_kernel();
9961 +
9962 local_irq_restore(flags);
9963 /* Could also do a CLFLUSH here to speed up CPU recovery; but
9964 that causes hangs on some VIA CPUs. */
9965 @@ -550,36 +554,22 @@ static void *__init_or_module text_poke_
9966 */
9967 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
9968 {
9969 - unsigned long flags;
9970 - char *vaddr;
9971 + unsigned char *vaddr = ktla_ktva(addr);
9972 struct page *pages[2];
9973 - int i;
9974 + size_t i;
9975
9976 if (!core_kernel_text((unsigned long)addr)) {
9977 - pages[0] = vmalloc_to_page(addr);
9978 - pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
9979 + pages[0] = vmalloc_to_page(vaddr);
9980 + pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
9981 } else {
9982 - pages[0] = virt_to_page(addr);
9983 + pages[0] = virt_to_page(vaddr);
9984 WARN_ON(!PageReserved(pages[0]));
9985 - pages[1] = virt_to_page(addr + PAGE_SIZE);
9986 + pages[1] = virt_to_page(vaddr + PAGE_SIZE);
9987 }
9988 BUG_ON(!pages[0]);
9989 - local_irq_save(flags);
9990 - set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0]));
9991 - if (pages[1])
9992 - set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1]));
9993 - vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0);
9994 - memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
9995 - clear_fixmap(FIX_TEXT_POKE0);
9996 - if (pages[1])
9997 - clear_fixmap(FIX_TEXT_POKE1);
9998 - local_flush_tlb();
9999 - sync_core();
10000 - /* Could also do a CLFLUSH here to speed up CPU recovery; but
10001 - that causes hangs on some VIA CPUs. */
10002 + text_poke_early(addr, opcode, len);
10003 for (i = 0; i < len; i++)
10004 - BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
10005 - local_irq_restore(flags);
10006 + BUG_ON(((char *)vaddr)[i] != ((char *)opcode)[i]);
10007 return addr;
10008 }
10009
10010 diff -urNp linux-2.6.36/arch/x86/kernel/amd_iommu.c linux-2.6.36/arch/x86/kernel/amd_iommu.c
10011 --- linux-2.6.36/arch/x86/kernel/amd_iommu.c 2010-10-20 16:30:22.000000000 -0400
10012 +++ linux-2.6.36/arch/x86/kernel/amd_iommu.c 2010-11-06 18:58:15.000000000 -0400
10013 @@ -2286,7 +2286,7 @@ static void prealloc_protection_domains(
10014 }
10015 }
10016
10017 -static struct dma_map_ops amd_iommu_dma_ops = {
10018 +static const struct dma_map_ops amd_iommu_dma_ops = {
10019 .alloc_coherent = alloc_coherent,
10020 .free_coherent = free_coherent,
10021 .map_page = map_page,
10022 diff -urNp linux-2.6.36/arch/x86/kernel/apic/io_apic.c linux-2.6.36/arch/x86/kernel/apic/io_apic.c
10023 --- linux-2.6.36/arch/x86/kernel/apic/io_apic.c 2010-10-20 16:30:22.000000000 -0400
10024 +++ linux-2.6.36/arch/x86/kernel/apic/io_apic.c 2010-11-06 18:58:15.000000000 -0400
10025 @@ -696,7 +696,7 @@ struct IO_APIC_route_entry **alloc_ioapi
10026 ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
10027 GFP_ATOMIC);
10028 if (!ioapic_entries)
10029 - return 0;
10030 + return NULL;
10031
10032 for (apic = 0; apic < nr_ioapics; apic++) {
10033 ioapic_entries[apic] =
10034 @@ -713,7 +713,7 @@ nomem:
10035 kfree(ioapic_entries[apic]);
10036 kfree(ioapic_entries);
10037
10038 - return 0;
10039 + return NULL;
10040 }
10041
10042 /*
10043 @@ -1123,7 +1123,7 @@ int IO_APIC_get_PCI_irq_vector(int bus,
10044 }
10045 EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
10046
10047 -void lock_vector_lock(void)
10048 +void lock_vector_lock(void) __acquires(vector_lock)
10049 {
10050 /* Used to the online set of cpus does not change
10051 * during assign_irq_vector.
10052 @@ -1131,7 +1131,7 @@ void lock_vector_lock(void)
10053 raw_spin_lock(&vector_lock);
10054 }
10055
10056 -void unlock_vector_lock(void)
10057 +void unlock_vector_lock(void) __releases(vector_lock)
10058 {
10059 raw_spin_unlock(&vector_lock);
10060 }
10061 diff -urNp linux-2.6.36/arch/x86/kernel/apm_32.c linux-2.6.36/arch/x86/kernel/apm_32.c
10062 --- linux-2.6.36/arch/x86/kernel/apm_32.c 2010-10-20 16:30:22.000000000 -0400
10063 +++ linux-2.6.36/arch/x86/kernel/apm_32.c 2010-11-06 18:58:15.000000000 -0400
10064 @@ -410,7 +410,7 @@ static DEFINE_MUTEX(apm_mutex);
10065 * This is for buggy BIOS's that refer to (real mode) segment 0x40
10066 * even though they are called in protected mode.
10067 */
10068 -static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
10069 +static const struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4093,
10070 (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
10071
10072 static const char driver_version[] = "1.16ac"; /* no spaces */
10073 @@ -588,7 +588,10 @@ static long __apm_bios_call(void *_call)
10074 BUG_ON(cpu != 0);
10075 gdt = get_cpu_gdt_table(cpu);
10076 save_desc_40 = gdt[0x40 / 8];
10077 +
10078 + pax_open_kernel();
10079 gdt[0x40 / 8] = bad_bios_desc;
10080 + pax_close_kernel();
10081
10082 apm_irq_save(flags);
10083 APM_DO_SAVE_SEGS;
10084 @@ -597,7 +600,11 @@ static long __apm_bios_call(void *_call)
10085 &call->esi);
10086 APM_DO_RESTORE_SEGS;
10087 apm_irq_restore(flags);
10088 +
10089 + pax_open_kernel();
10090 gdt[0x40 / 8] = save_desc_40;
10091 + pax_close_kernel();
10092 +
10093 put_cpu();
10094
10095 return call->eax & 0xff;
10096 @@ -664,7 +671,10 @@ static long __apm_bios_call_simple(void
10097 BUG_ON(cpu != 0);
10098 gdt = get_cpu_gdt_table(cpu);
10099 save_desc_40 = gdt[0x40 / 8];
10100 +
10101 + pax_open_kernel();
10102 gdt[0x40 / 8] = bad_bios_desc;
10103 + pax_close_kernel();
10104
10105 apm_irq_save(flags);
10106 APM_DO_SAVE_SEGS;
10107 @@ -672,7 +682,11 @@ static long __apm_bios_call_simple(void
10108 &call->eax);
10109 APM_DO_RESTORE_SEGS;
10110 apm_irq_restore(flags);
10111 +
10112 + pax_open_kernel();
10113 gdt[0x40 / 8] = save_desc_40;
10114 + pax_close_kernel();
10115 +
10116 put_cpu();
10117 return error;
10118 }
10119 @@ -975,7 +989,7 @@ recalc:
10120
10121 static void apm_power_off(void)
10122 {
10123 - unsigned char po_bios_call[] = {
10124 + const unsigned char po_bios_call[] = {
10125 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
10126 0x8e, 0xd0, /* movw ax,ss */
10127 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
10128 @@ -1931,7 +1945,10 @@ static const struct file_operations apm_
10129 static struct miscdevice apm_device = {
10130 APM_MINOR_DEV,
10131 "apm_bios",
10132 - &apm_bios_fops
10133 + &apm_bios_fops,
10134 + {NULL, NULL},
10135 + NULL,
10136 + NULL
10137 };
10138
10139
10140 @@ -2252,7 +2269,7 @@ static struct dmi_system_id __initdata a
10141 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
10142 },
10143
10144 - { }
10145 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
10146 };
10147
10148 /*
10149 @@ -2355,12 +2372,15 @@ static int __init apm_init(void)
10150 * code to that CPU.
10151 */
10152 gdt = get_cpu_gdt_table(0);
10153 +
10154 + pax_open_kernel();
10155 set_desc_base(&gdt[APM_CS >> 3],
10156 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
10157 set_desc_base(&gdt[APM_CS_16 >> 3],
10158 (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
10159 set_desc_base(&gdt[APM_DS >> 3],
10160 (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
10161 + pax_close_kernel();
10162
10163 proc_create("apm", 0, NULL, &apm_file_ops);
10164
10165 diff -urNp linux-2.6.36/arch/x86/kernel/asm-offsets_32.c linux-2.6.36/arch/x86/kernel/asm-offsets_32.c
10166 --- linux-2.6.36/arch/x86/kernel/asm-offsets_32.c 2010-10-20 16:30:22.000000000 -0400
10167 +++ linux-2.6.36/arch/x86/kernel/asm-offsets_32.c 2010-11-06 18:58:15.000000000 -0400
10168 @@ -115,6 +115,11 @@ void foo(void)
10169 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
10170 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
10171 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
10172 +
10173 +#ifdef CONFIG_PAX_KERNEXEC
10174 + OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
10175 +#endif
10176 +
10177 #endif
10178
10179 #ifdef CONFIG_XEN
10180 diff -urNp linux-2.6.36/arch/x86/kernel/asm-offsets_64.c linux-2.6.36/arch/x86/kernel/asm-offsets_64.c
10181 --- linux-2.6.36/arch/x86/kernel/asm-offsets_64.c 2010-10-20 16:30:22.000000000 -0400
10182 +++ linux-2.6.36/arch/x86/kernel/asm-offsets_64.c 2010-11-06 18:58:15.000000000 -0400
10183 @@ -63,6 +63,18 @@ int main(void)
10184 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
10185 OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs);
10186 OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
10187 +
10188 +#ifdef CONFIG_PAX_KERNEXEC
10189 + OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
10190 + OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
10191 +#endif
10192 +
10193 +#ifdef CONFIG_PAX_MEMORY_UDEREF
10194 + OFFSET(PV_MMU_read_cr3, pv_mmu_ops, read_cr3);
10195 + OFFSET(PV_MMU_write_cr3, pv_mmu_ops, write_cr3);
10196 + OFFSET(PV_MMU_set_pgd, pv_mmu_ops, set_pgd);
10197 +#endif
10198 +
10199 #endif
10200
10201
10202 @@ -115,6 +127,7 @@ int main(void)
10203 ENTRY(cr8);
10204 BLANK();
10205 #undef ENTRY
10206 + DEFINE(TSS_size, sizeof(struct tss_struct));
10207 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
10208 BLANK();
10209 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
10210 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/common.c linux-2.6.36/arch/x86/kernel/cpu/common.c
10211 --- linux-2.6.36/arch/x86/kernel/cpu/common.c 2010-10-20 16:30:22.000000000 -0400
10212 +++ linux-2.6.36/arch/x86/kernel/cpu/common.c 2010-11-06 18:58:15.000000000 -0400
10213 @@ -83,60 +83,6 @@ static const struct cpu_dev __cpuinitcon
10214
10215 static const struct cpu_dev *this_cpu __cpuinitdata = &default_cpu;
10216
10217 -DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
10218 -#ifdef CONFIG_X86_64
10219 - /*
10220 - * We need valid kernel segments for data and code in long mode too
10221 - * IRET will check the segment types kkeil 2000/10/28
10222 - * Also sysret mandates a special GDT layout
10223 - *
10224 - * TLS descriptors are currently at a different place compared to i386.
10225 - * Hopefully nobody expects them at a fixed place (Wine?)
10226 - */
10227 - [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
10228 - [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
10229 - [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
10230 - [GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),
10231 - [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
10232 - [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
10233 -#else
10234 - [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff),
10235 - [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
10236 - [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff),
10237 - [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff),
10238 - /*
10239 - * Segments used for calling PnP BIOS have byte granularity.
10240 - * They code segments and data segments have fixed 64k limits,
10241 - * the transfer segment sizes are set at run time.
10242 - */
10243 - /* 32-bit code */
10244 - [GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
10245 - /* 16-bit code */
10246 - [GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
10247 - /* 16-bit data */
10248 - [GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff),
10249 - /* 16-bit data */
10250 - [GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0),
10251 - /* 16-bit data */
10252 - [GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0),
10253 - /*
10254 - * The APM segments have byte granularity and their bases
10255 - * are set at run time. All have 64k limits.
10256 - */
10257 - /* 32-bit code */
10258 - [GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
10259 - /* 16-bit code */
10260 - [GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
10261 - /* data */
10262 - [GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff),
10263 -
10264 - [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
10265 - [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
10266 - GDT_STACK_CANARY_INIT
10267 -#endif
10268 -} };
10269 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
10270 -
10271 static int __init x86_xsave_setup(char *s)
10272 {
10273 setup_clear_cpu_cap(X86_FEATURE_XSAVE);
10274 @@ -352,7 +298,7 @@ void switch_to_new_gdt(int cpu)
10275 {
10276 struct desc_ptr gdt_descr;
10277
10278 - gdt_descr.address = (long)get_cpu_gdt_table(cpu);
10279 + gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
10280 gdt_descr.size = GDT_SIZE - 1;
10281 load_gdt(&gdt_descr);
10282 /* Reload the per-cpu base */
10283 @@ -820,6 +766,10 @@ static void __cpuinit identify_cpu(struc
10284 /* Filter out anything that depends on CPUID levels we don't have */
10285 filter_cpuid_features(c, true);
10286
10287 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || (defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32))
10288 + setup_clear_cpu_cap(X86_FEATURE_SEP);
10289 +#endif
10290 +
10291 /* If the model name is still unset, do table lookup. */
10292 if (!c->x86_model_id[0]) {
10293 const char *p;
10294 @@ -1135,7 +1085,7 @@ void __cpuinit cpu_init(void)
10295 int i;
10296
10297 cpu = stack_smp_processor_id();
10298 - t = &per_cpu(init_tss, cpu);
10299 + t = init_tss + cpu;
10300 oist = &per_cpu(orig_ist, cpu);
10301
10302 #ifdef CONFIG_NUMA
10303 @@ -1161,7 +1111,7 @@ void __cpuinit cpu_init(void)
10304 switch_to_new_gdt(cpu);
10305 loadsegment(fs, 0);
10306
10307 - load_idt((const struct desc_ptr *)&idt_descr);
10308 + load_idt(&idt_descr);
10309
10310 memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
10311 syscall_init();
10312 @@ -1224,7 +1174,7 @@ void __cpuinit cpu_init(void)
10313 {
10314 int cpu = smp_processor_id();
10315 struct task_struct *curr = current;
10316 - struct tss_struct *t = &per_cpu(init_tss, cpu);
10317 + struct tss_struct *t = init_tss + cpu;
10318 struct thread_struct *thread = &curr->thread;
10319
10320 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
10321 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.36/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
10322 --- linux-2.6.36/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2010-10-20 16:30:22.000000000 -0400
10323 +++ linux-2.6.36/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2010-11-06 18:58:15.000000000 -0400
10324 @@ -481,7 +481,7 @@ static const struct dmi_system_id sw_any
10325 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
10326 },
10327 },
10328 - { }
10329 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
10330 };
10331
10332 static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
10333 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.36/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
10334 --- linux-2.6.36/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2010-10-20 16:30:22.000000000 -0400
10335 +++ linux-2.6.36/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2010-11-06 18:58:15.000000000 -0400
10336 @@ -226,7 +226,7 @@ static struct cpu_model models[] =
10337 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
10338 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
10339
10340 - { NULL, }
10341 + { NULL, NULL, 0, NULL}
10342 };
10343 #undef _BANIAS
10344 #undef BANIAS
10345 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/intel.c linux-2.6.36/arch/x86/kernel/cpu/intel.c
10346 --- linux-2.6.36/arch/x86/kernel/cpu/intel.c 2010-10-20 16:30:22.000000000 -0400
10347 +++ linux-2.6.36/arch/x86/kernel/cpu/intel.c 2010-11-06 18:58:15.000000000 -0400
10348 @@ -161,7 +161,7 @@ static void __cpuinit trap_init_f00f_bug
10349 * Update the IDT descriptor and reload the IDT so that
10350 * it uses the read-only mapped virtual address.
10351 */
10352 - idt_descr.address = fix_to_virt(FIX_F00F_IDT);
10353 + idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
10354 load_idt(&idt_descr);
10355 }
10356 #endif
10357 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/Makefile linux-2.6.36/arch/x86/kernel/cpu/Makefile
10358 --- linux-2.6.36/arch/x86/kernel/cpu/Makefile 2010-10-20 16:30:22.000000000 -0400
10359 +++ linux-2.6.36/arch/x86/kernel/cpu/Makefile 2010-11-06 18:58:15.000000000 -0400
10360 @@ -8,10 +8,6 @@ CFLAGS_REMOVE_common.o = -pg
10361 CFLAGS_REMOVE_perf_event.o = -pg
10362 endif
10363
10364 -# Make sure load_percpu_segment has no stackprotector
10365 -nostackp := $(call cc-option, -fno-stack-protector)
10366 -CFLAGS_common.o := $(nostackp)
10367 -
10368 obj-y := intel_cacheinfo.o scattered.o topology.o
10369 obj-y += proc.o capflags.o powerflags.o common.o
10370 obj-y += vmware.o hypervisor.o sched.o mshyperv.o
10371 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/mcheck/mce.c linux-2.6.36/arch/x86/kernel/cpu/mcheck/mce.c
10372 --- linux-2.6.36/arch/x86/kernel/cpu/mcheck/mce.c 2010-10-20 16:30:22.000000000 -0400
10373 +++ linux-2.6.36/arch/x86/kernel/cpu/mcheck/mce.c 2010-11-06 18:58:15.000000000 -0400
10374 @@ -219,7 +219,7 @@ static void print_mce(struct mce *m)
10375 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
10376 m->cs, m->ip);
10377
10378 - if (m->cs == __KERNEL_CS)
10379 + if (m->cs == __KERNEL_CS || m->cs == __KERNEXEC_KERNEL_CS)
10380 print_symbol("{%s}", m->ip);
10381 pr_cont("\n");
10382 }
10383 @@ -1460,14 +1460,14 @@ void __cpuinit mcheck_cpu_init(struct cp
10384 */
10385
10386 static DEFINE_SPINLOCK(mce_state_lock);
10387 -static int open_count; /* #times opened */
10388 +static atomic_t open_count; /* #times opened */
10389 static int open_exclu; /* already open exclusive? */
10390
10391 static int mce_open(struct inode *inode, struct file *file)
10392 {
10393 spin_lock(&mce_state_lock);
10394
10395 - if (open_exclu || (open_count && (file->f_flags & O_EXCL))) {
10396 + if (open_exclu || (atomic_read(&open_count) && (file->f_flags & O_EXCL))) {
10397 spin_unlock(&mce_state_lock);
10398
10399 return -EBUSY;
10400 @@ -1475,7 +1475,7 @@ static int mce_open(struct inode *inode,
10401
10402 if (file->f_flags & O_EXCL)
10403 open_exclu = 1;
10404 - open_count++;
10405 + atomic_inc(&open_count);
10406
10407 spin_unlock(&mce_state_lock);
10408
10409 @@ -1486,7 +1486,7 @@ static int mce_release(struct inode *ino
10410 {
10411 spin_lock(&mce_state_lock);
10412
10413 - open_count--;
10414 + atomic_dec(&open_count);
10415 open_exclu = 0;
10416
10417 spin_unlock(&mce_state_lock);
10418 @@ -1672,6 +1672,7 @@ static struct miscdevice mce_log_device
10419 MISC_MCELOG_MINOR,
10420 "mcelog",
10421 &mce_chrdev_ops,
10422 + {NULL, NULL}, NULL, NULL
10423 };
10424
10425 /*
10426 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.36/arch/x86/kernel/cpu/mtrr/generic.c
10427 --- linux-2.6.36/arch/x86/kernel/cpu/mtrr/generic.c 2010-10-20 16:30:22.000000000 -0400
10428 +++ linux-2.6.36/arch/x86/kernel/cpu/mtrr/generic.c 2010-11-06 18:58:15.000000000 -0400
10429 @@ -28,7 +28,7 @@ static struct fixed_range_block fixed_ra
10430 { MSR_MTRRfix64K_00000, 1 }, /* one 64k MTRR */
10431 { MSR_MTRRfix16K_80000, 2 }, /* two 16k MTRRs */
10432 { MSR_MTRRfix4K_C0000, 8 }, /* eight 4k MTRRs */
10433 - {}
10434 + { 0, 0 }
10435 };
10436
10437 static unsigned long smp_changes_mask;
10438 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/mtrr/main.c linux-2.6.36/arch/x86/kernel/cpu/mtrr/main.c
10439 --- linux-2.6.36/arch/x86/kernel/cpu/mtrr/main.c 2010-10-20 16:30:22.000000000 -0400
10440 +++ linux-2.6.36/arch/x86/kernel/cpu/mtrr/main.c 2010-11-06 18:58:15.000000000 -0400
10441 @@ -61,7 +61,7 @@ static DEFINE_MUTEX(mtrr_mutex);
10442 u64 size_or_mask, size_and_mask;
10443 static bool mtrr_aps_delayed_init;
10444
10445 -static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
10446 +static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM] __read_only;
10447
10448 const struct mtrr_ops *mtrr_if;
10449
10450 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/mtrr/mtrr.h linux-2.6.36/arch/x86/kernel/cpu/mtrr/mtrr.h
10451 --- linux-2.6.36/arch/x86/kernel/cpu/mtrr/mtrr.h 2010-10-20 16:30:22.000000000 -0400
10452 +++ linux-2.6.36/arch/x86/kernel/cpu/mtrr/mtrr.h 2010-11-06 18:58:15.000000000 -0400
10453 @@ -12,19 +12,19 @@
10454 extern unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
10455
10456 struct mtrr_ops {
10457 - u32 vendor;
10458 - u32 use_intel_if;
10459 - void (*set)(unsigned int reg, unsigned long base,
10460 + const u32 vendor;
10461 + const u32 use_intel_if;
10462 + void (* const set)(unsigned int reg, unsigned long base,
10463 unsigned long size, mtrr_type type);
10464 - void (*set_all)(void);
10465 + void (* const set_all)(void);
10466
10467 - void (*get)(unsigned int reg, unsigned long *base,
10468 + void (* const get)(unsigned int reg, unsigned long *base,
10469 unsigned long *size, mtrr_type *type);
10470 - int (*get_free_region)(unsigned long base, unsigned long size,
10471 + int (* const get_free_region)(unsigned long base, unsigned long size,
10472 int replace_reg);
10473 - int (*validate_add_page)(unsigned long base, unsigned long size,
10474 + int (* const validate_add_page)(unsigned long base, unsigned long size,
10475 unsigned int type);
10476 - int (*have_wrcomb)(void);
10477 + int (* const have_wrcomb)(void);
10478 };
10479
10480 extern int generic_get_free_region(unsigned long base, unsigned long size,
10481 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/perfctr-watchdog.c linux-2.6.36/arch/x86/kernel/cpu/perfctr-watchdog.c
10482 --- linux-2.6.36/arch/x86/kernel/cpu/perfctr-watchdog.c 2010-10-20 16:30:22.000000000 -0400
10483 +++ linux-2.6.36/arch/x86/kernel/cpu/perfctr-watchdog.c 2010-11-06 18:58:15.000000000 -0400
10484 @@ -30,11 +30,11 @@ struct nmi_watchdog_ctlblk {
10485
10486 /* Interface defining a CPU specific perfctr watchdog */
10487 struct wd_ops {
10488 - int (*reserve)(void);
10489 - void (*unreserve)(void);
10490 - int (*setup)(unsigned nmi_hz);
10491 - void (*rearm)(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz);
10492 - void (*stop)(void);
10493 + int (* const reserve)(void);
10494 + void (* const unreserve)(void);
10495 + int (* const setup)(unsigned nmi_hz);
10496 + void (* const rearm)(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz);
10497 + void (* const stop)(void);
10498 unsigned perfctr;
10499 unsigned evntsel;
10500 u64 checkbit;
10501 @@ -634,6 +634,7 @@ static const struct wd_ops p4_wd_ops = {
10502 #define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
10503 #define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK
10504
10505 +/* cannot be const, see probe_nmi_watchdog */
10506 static struct wd_ops intel_arch_wd_ops;
10507
10508 static int setup_intel_arch_watchdog(unsigned nmi_hz)
10509 @@ -686,6 +687,7 @@ static int setup_intel_arch_watchdog(uns
10510 return 1;
10511 }
10512
10513 +/* cannot be const */
10514 static struct wd_ops intel_arch_wd_ops __read_mostly = {
10515 .reserve = single_msr_reserve,
10516 .unreserve = single_msr_unreserve,
10517 diff -urNp linux-2.6.36/arch/x86/kernel/cpu/perf_event.c linux-2.6.36/arch/x86/kernel/cpu/perf_event.c
10518 --- linux-2.6.36/arch/x86/kernel/cpu/perf_event.c 2010-10-20 16:30:22.000000000 -0400
10519 +++ linux-2.6.36/arch/x86/kernel/cpu/perf_event.c 2010-11-06 18:58:15.000000000 -0400
10520 @@ -1732,7 +1732,7 @@ perf_callchain_user(struct pt_regs *regs
10521 break;
10522
10523 callchain_store(entry, frame.return_address);
10524 - fp = frame.next_frame;
10525 + fp = (__force const void __user *)frame.next_frame;
10526 }
10527 }
10528
10529 diff -urNp linux-2.6.36/arch/x86/kernel/crash.c linux-2.6.36/arch/x86/kernel/crash.c
10530 --- linux-2.6.36/arch/x86/kernel/crash.c 2010-10-20 16:30:22.000000000 -0400
10531 +++ linux-2.6.36/arch/x86/kernel/crash.c 2010-11-06 18:58:15.000000000 -0400
10532 @@ -42,7 +42,7 @@ static void kdump_nmi_callback(int cpu,
10533 regs = args->regs;
10534
10535 #ifdef CONFIG_X86_32
10536 - if (!user_mode_vm(regs)) {
10537 + if (!user_mode(regs)) {
10538 crash_fixup_ss_esp(&fixed_regs, regs);
10539 regs = &fixed_regs;
10540 }
10541 diff -urNp linux-2.6.36/arch/x86/kernel/doublefault_32.c linux-2.6.36/arch/x86/kernel/doublefault_32.c
10542 --- linux-2.6.36/arch/x86/kernel/doublefault_32.c 2010-10-20 16:30:22.000000000 -0400
10543 +++ linux-2.6.36/arch/x86/kernel/doublefault_32.c 2010-11-06 18:58:15.000000000 -0400
10544 @@ -11,7 +11,7 @@
10545
10546 #define DOUBLEFAULT_STACKSIZE (1024)
10547 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
10548 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
10549 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
10550
10551 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
10552
10553 @@ -21,7 +21,7 @@ static void doublefault_fn(void)
10554 unsigned long gdt, tss;
10555
10556 store_gdt(&gdt_desc);
10557 - gdt = gdt_desc.address;
10558 + gdt = (unsigned long)gdt_desc.address;
10559
10560 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
10561
10562 @@ -58,10 +58,10 @@ struct tss_struct doublefault_tss __cach
10563 /* 0x2 bit is always set */
10564 .flags = X86_EFLAGS_SF | 0x2,
10565 .sp = STACK_START,
10566 - .es = __USER_DS,
10567 + .es = __KERNEL_DS,
10568 .cs = __KERNEL_CS,
10569 .ss = __KERNEL_DS,
10570 - .ds = __USER_DS,
10571 + .ds = __KERNEL_DS,
10572 .fs = __KERNEL_PERCPU,
10573
10574 .__cr3 = __pa_nodebug(swapper_pg_dir),
10575 diff -urNp linux-2.6.36/arch/x86/kernel/dumpstack_32.c linux-2.6.36/arch/x86/kernel/dumpstack_32.c
10576 --- linux-2.6.36/arch/x86/kernel/dumpstack_32.c 2010-10-20 16:30:22.000000000 -0400
10577 +++ linux-2.6.36/arch/x86/kernel/dumpstack_32.c 2010-11-06 18:58:15.000000000 -0400
10578 @@ -105,11 +105,12 @@ void show_registers(struct pt_regs *regs
10579 * When in-kernel, we also print out the stack and code at the
10580 * time of the fault..
10581 */
10582 - if (!user_mode_vm(regs)) {
10583 + if (!user_mode(regs)) {
10584 unsigned int code_prologue = code_bytes * 43 / 64;
10585 unsigned int code_len = code_bytes;
10586 unsigned char c;
10587 u8 *ip;
10588 + unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
10589
10590 printk(KERN_EMERG "Stack:\n");
10591 show_stack_log_lvl(NULL, regs, &regs->sp,
10592 @@ -117,10 +118,10 @@ void show_registers(struct pt_regs *regs
10593
10594 printk(KERN_EMERG "Code: ");
10595
10596 - ip = (u8 *)regs->ip - code_prologue;
10597 + ip = (u8 *)regs->ip - code_prologue + cs_base;
10598 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
10599 /* try starting at IP */
10600 - ip = (u8 *)regs->ip;
10601 + ip = (u8 *)regs->ip + cs_base;
10602 code_len = code_len - code_prologue + 1;
10603 }
10604 for (i = 0; i < code_len; i++, ip++) {
10605 @@ -129,7 +130,7 @@ void show_registers(struct pt_regs *regs
10606 printk(" Bad EIP value.");
10607 break;
10608 }
10609 - if (ip == (u8 *)regs->ip)
10610 + if (ip == (u8 *)regs->ip + cs_base)
10611 printk("<%02x> ", c);
10612 else
10613 printk("%02x ", c);
10614 @@ -142,6 +143,7 @@ int is_valid_bugaddr(unsigned long ip)
10615 {
10616 unsigned short ud2;
10617
10618 + ip = ktla_ktva(ip);
10619 if (ip < PAGE_OFFSET)
10620 return 0;
10621 if (probe_kernel_address((unsigned short *)ip, ud2))
10622 diff -urNp linux-2.6.36/arch/x86/kernel/dumpstack.c linux-2.6.36/arch/x86/kernel/dumpstack.c
10623 --- linux-2.6.36/arch/x86/kernel/dumpstack.c 2010-10-20 16:30:22.000000000 -0400
10624 +++ linux-2.6.36/arch/x86/kernel/dumpstack.c 2010-11-06 18:58:15.000000000 -0400
10625 @@ -206,7 +206,7 @@ void dump_stack(void)
10626 #endif
10627
10628 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
10629 - current->pid, current->comm, print_tainted(),
10630 + task_pid_nr(current), current->comm, print_tainted(),
10631 init_utsname()->release,
10632 (int)strcspn(init_utsname()->version, " "),
10633 init_utsname()->version);
10634 @@ -262,7 +262,7 @@ void __kprobes oops_end(unsigned long fl
10635 panic("Fatal exception in interrupt");
10636 if (panic_on_oops)
10637 panic("Fatal exception");
10638 - do_exit(signr);
10639 + do_group_exit(signr);
10640 }
10641
10642 int __kprobes __die(const char *str, struct pt_regs *regs, long err)
10643 @@ -289,7 +289,7 @@ int __kprobes __die(const char *str, str
10644
10645 show_registers(regs);
10646 #ifdef CONFIG_X86_32
10647 - if (user_mode_vm(regs)) {
10648 + if (user_mode(regs)) {
10649 sp = regs->sp;
10650 ss = regs->ss & 0xffff;
10651 } else {
10652 @@ -317,7 +317,7 @@ void die(const char *str, struct pt_regs
10653 unsigned long flags = oops_begin();
10654 int sig = SIGSEGV;
10655
10656 - if (!user_mode_vm(regs))
10657 + if (!user_mode(regs))
10658 report_bug(regs->ip, regs);
10659
10660 if (__die(str, regs, err))
10661 diff -urNp linux-2.6.36/arch/x86/kernel/efi_32.c linux-2.6.36/arch/x86/kernel/efi_32.c
10662 --- linux-2.6.36/arch/x86/kernel/efi_32.c 2010-10-20 16:30:22.000000000 -0400
10663 +++ linux-2.6.36/arch/x86/kernel/efi_32.c 2010-11-06 18:58:15.000000000 -0400
10664 @@ -38,70 +38,38 @@
10665 */
10666
10667 static unsigned long efi_rt_eflags;
10668 -static pgd_t efi_bak_pg_dir_pointer[2];
10669 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
10670
10671 -void efi_call_phys_prelog(void)
10672 +void __init efi_call_phys_prelog(void)
10673 {
10674 - unsigned long cr4;
10675 - unsigned long temp;
10676 struct desc_ptr gdt_descr;
10677
10678 local_irq_save(efi_rt_eflags);
10679
10680 - /*
10681 - * If I don't have PAE, I should just duplicate two entries in page
10682 - * directory. If I have PAE, I just need to duplicate one entry in
10683 - * page directory.
10684 - */
10685 - cr4 = read_cr4_safe();
10686
10687 - if (cr4 & X86_CR4_PAE) {
10688 - efi_bak_pg_dir_pointer[0].pgd =
10689 - swapper_pg_dir[pgd_index(0)].pgd;
10690 - swapper_pg_dir[0].pgd =
10691 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
10692 - } else {
10693 - efi_bak_pg_dir_pointer[0].pgd =
10694 - swapper_pg_dir[pgd_index(0)].pgd;
10695 - efi_bak_pg_dir_pointer[1].pgd =
10696 - swapper_pg_dir[pgd_index(0x400000)].pgd;
10697 - swapper_pg_dir[pgd_index(0)].pgd =
10698 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
10699 - temp = PAGE_OFFSET + 0x400000;
10700 - swapper_pg_dir[pgd_index(0x400000)].pgd =
10701 - swapper_pg_dir[pgd_index(temp)].pgd;
10702 - }
10703 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
10704 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
10705 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
10706
10707 /*
10708 * After the lock is released, the original page table is restored.
10709 */
10710 __flush_tlb_all();
10711
10712 - gdt_descr.address = __pa(get_cpu_gdt_table(0));
10713 + gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
10714 gdt_descr.size = GDT_SIZE - 1;
10715 load_gdt(&gdt_descr);
10716 }
10717
10718 -void efi_call_phys_epilog(void)
10719 +void __init efi_call_phys_epilog(void)
10720 {
10721 - unsigned long cr4;
10722 struct desc_ptr gdt_descr;
10723
10724 - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
10725 + gdt_descr.address = get_cpu_gdt_table(0);
10726 gdt_descr.size = GDT_SIZE - 1;
10727 load_gdt(&gdt_descr);
10728
10729 - cr4 = read_cr4_safe();
10730 -
10731 - if (cr4 & X86_CR4_PAE) {
10732 - swapper_pg_dir[pgd_index(0)].pgd =
10733 - efi_bak_pg_dir_pointer[0].pgd;
10734 - } else {
10735 - swapper_pg_dir[pgd_index(0)].pgd =
10736 - efi_bak_pg_dir_pointer[0].pgd;
10737 - swapper_pg_dir[pgd_index(0x400000)].pgd =
10738 - efi_bak_pg_dir_pointer[1].pgd;
10739 - }
10740 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
10741
10742 /*
10743 * After the lock is released, the original page table is restored.
10744 diff -urNp linux-2.6.36/arch/x86/kernel/efi_stub_32.S linux-2.6.36/arch/x86/kernel/efi_stub_32.S
10745 --- linux-2.6.36/arch/x86/kernel/efi_stub_32.S 2010-10-20 16:30:22.000000000 -0400
10746 +++ linux-2.6.36/arch/x86/kernel/efi_stub_32.S 2010-11-06 18:58:15.000000000 -0400
10747 @@ -6,6 +6,7 @@
10748 */
10749
10750 #include <linux/linkage.h>
10751 +#include <linux/init.h>
10752 #include <asm/page_types.h>
10753
10754 /*
10755 @@ -20,7 +21,7 @@
10756 * service functions will comply with gcc calling convention, too.
10757 */
10758
10759 -.text
10760 +__INIT
10761 ENTRY(efi_call_phys)
10762 /*
10763 * 0. The function can only be called in Linux kernel. So CS has been
10764 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
10765 * The mapping of lower virtual memory has been created in prelog and
10766 * epilog.
10767 */
10768 - movl $1f, %edx
10769 - subl $__PAGE_OFFSET, %edx
10770 - jmp *%edx
10771 + jmp 1f-__PAGE_OFFSET
10772 1:
10773
10774 /*
10775 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
10776 * parameter 2, ..., param n. To make things easy, we save the return
10777 * address of efi_call_phys in a global variable.
10778 */
10779 - popl %edx
10780 - movl %edx, saved_return_addr
10781 - /* get the function pointer into ECX*/
10782 - popl %ecx
10783 - movl %ecx, efi_rt_function_ptr
10784 - movl $2f, %edx
10785 - subl $__PAGE_OFFSET, %edx
10786 - pushl %edx
10787 + popl (saved_return_addr)
10788 + popl (efi_rt_function_ptr)
10789
10790 /*
10791 * 3. Clear PG bit in %CR0.
10792 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
10793 /*
10794 * 5. Call the physical function.
10795 */
10796 - jmp *%ecx
10797 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
10798
10799 -2:
10800 /*
10801 * 6. After EFI runtime service returns, control will return to
10802 * following instruction. We'd better readjust stack pointer first.
10803 @@ -88,35 +80,28 @@ ENTRY(efi_call_phys)
10804 movl %cr0, %edx
10805 orl $0x80000000, %edx
10806 movl %edx, %cr0
10807 - jmp 1f
10808 -1:
10809 +
10810 /*
10811 * 8. Now restore the virtual mode from flat mode by
10812 * adding EIP with PAGE_OFFSET.
10813 */
10814 - movl $1f, %edx
10815 - jmp *%edx
10816 + jmp 1f+__PAGE_OFFSET
10817 1:
10818
10819 /*
10820 * 9. Balance the stack. And because EAX contain the return value,
10821 * we'd better not clobber it.
10822 */
10823 - leal efi_rt_function_ptr, %edx
10824 - movl (%edx), %ecx
10825 - pushl %ecx
10826 + pushl (efi_rt_function_ptr)
10827
10828 /*
10829 - * 10. Push the saved return address onto the stack and return.
10830 + * 10. Return to the saved return address.
10831 */
10832 - leal saved_return_addr, %edx
10833 - movl (%edx), %ecx
10834 - pushl %ecx
10835 - ret
10836 + jmpl *(saved_return_addr)
10837 ENDPROC(efi_call_phys)
10838 .previous
10839
10840 -.data
10841 +__INITDATA
10842 saved_return_addr:
10843 .long 0
10844 efi_rt_function_ptr:
10845 diff -urNp linux-2.6.36/arch/x86/kernel/entry_32.S linux-2.6.36/arch/x86/kernel/entry_32.S
10846 --- linux-2.6.36/arch/x86/kernel/entry_32.S 2010-10-20 16:30:22.000000000 -0400
10847 +++ linux-2.6.36/arch/x86/kernel/entry_32.S 2010-11-06 18:58:15.000000000 -0400
10848 @@ -192,7 +192,67 @@
10849
10850 #endif /* CONFIG_X86_32_LAZY_GS */
10851
10852 -.macro SAVE_ALL
10853 +.macro PAX_EXIT_KERNEL
10854 +#ifdef CONFIG_PAX_KERNEXEC
10855 +#ifdef CONFIG_PARAVIRT
10856 + push %eax; push %ecx;
10857 +#endif
10858 + mov %cs, %esi
10859 + cmp $__KERNEXEC_KERNEL_CS, %esi
10860 + jnz 2f
10861 +#ifdef CONFIG_PARAVIRT
10862 + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0);
10863 + mov %eax, %esi
10864 +#else
10865 + mov %cr0, %esi
10866 +#endif
10867 + btr $16, %esi
10868 + ljmp $__KERNEL_CS, $1f
10869 +1:
10870 +#ifdef CONFIG_PARAVIRT
10871 + mov %esi, %eax
10872 + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0);
10873 +#else
10874 + mov %esi, %cr0
10875 +#endif
10876 +2:
10877 +#ifdef CONFIG_PARAVIRT
10878 + pop %ecx; pop %eax
10879 +#endif
10880 +#endif
10881 +.endm
10882 +
10883 +.macro PAX_ENTER_KERNEL
10884 +#ifdef CONFIG_PAX_KERNEXEC
10885 +#ifdef CONFIG_PARAVIRT
10886 + push %eax; push %ecx;
10887 + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0)
10888 + mov %eax, %esi
10889 +#else
10890 + mov %cr0, %esi
10891 +#endif
10892 + bts $16, %esi
10893 + jnc 1f
10894 + mov %cs, %esi
10895 + cmp $__KERNEL_CS, %esi
10896 + jz 3f
10897 + ljmp $__KERNEL_CS, $3f
10898 +1: ljmp $__KERNEXEC_KERNEL_CS, $2f
10899 +2:
10900 +#ifdef CONFIG_PARAVIRT
10901 + mov %esi, %eax
10902 + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0)
10903 +#else
10904 + mov %esi, %cr0
10905 +#endif
10906 +3:
10907 +#ifdef CONFIG_PARAVIRT
10908 + pop %ecx; pop %eax
10909 +#endif
10910 +#endif
10911 +.endm
10912 +
10913 +.macro __SAVE_ALL _DS
10914 cld
10915 PUSH_GS
10916 pushl %fs
10917 @@ -225,7 +285,7 @@
10918 pushl %ebx
10919 CFI_ADJUST_CFA_OFFSET 4
10920 CFI_REL_OFFSET ebx, 0
10921 - movl $(__USER_DS), %edx
10922 + movl $\_DS, %edx
10923 movl %edx, %ds
10924 movl %edx, %es
10925 movl $(__KERNEL_PERCPU), %edx
10926 @@ -233,6 +293,15 @@
10927 SET_KERNEL_GS %edx
10928 .endm
10929
10930 +.macro SAVE_ALL
10931 +#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
10932 + __SAVE_ALL __KERNEL_DS
10933 + PAX_ENTER_KERNEL
10934 +#else
10935 + __SAVE_ALL __USER_DS
10936 +#endif
10937 +.endm
10938 +
10939 .macro RESTORE_INT_REGS
10940 popl %ebx
10941 CFI_ADJUST_CFA_OFFSET -4
10942 @@ -357,7 +426,15 @@ check_userspace:
10943 movb PT_CS(%esp), %al
10944 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
10945 cmpl $USER_RPL, %eax
10946 +
10947 +#ifdef CONFIG_PAX_KERNEXEC
10948 + jae resume_userspace
10949 +
10950 + PAX_EXIT_KERNEL
10951 + jmp resume_kernel
10952 +#else
10953 jb resume_kernel # not returning to v8086 or userspace
10954 +#endif
10955
10956 ENTRY(resume_userspace)
10957 LOCKDEP_SYS_EXIT
10958 @@ -423,10 +500,9 @@ sysenter_past_esp:
10959 /*CFI_REL_OFFSET cs, 0*/
10960 /*
10961 * Push current_thread_info()->sysenter_return to the stack.
10962 - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
10963 - * pushed above; +8 corresponds to copy_thread's esp0 setting.
10964 */
10965 - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
10966 + GET_THREAD_INFO(%ebp)
10967 + pushl TI_sysenter_return(%ebp)
10968 CFI_ADJUST_CFA_OFFSET 4
10969 CFI_REL_OFFSET eip, 0
10970
10971 @@ -439,9 +515,19 @@ sysenter_past_esp:
10972 * Load the potential sixth argument from user stack.
10973 * Careful about security.
10974 */
10975 + movl PT_OLDESP(%esp),%ebp
10976 +
10977 +#ifdef CONFIG_PAX_MEMORY_UDEREF
10978 + mov PT_OLDSS(%esp),%ds
10979 +1: movl %ds:(%ebp),%ebp
10980 + push %ss
10981 + pop %ds
10982 +#else
10983 cmpl $__PAGE_OFFSET-3,%ebp
10984 jae syscall_fault
10985 1: movl (%ebp),%ebp
10986 +#endif
10987 +
10988 movl %ebp,PT_EBP(%esp)
10989 .section __ex_table,"a"
10990 .align 4
10991 @@ -464,12 +550,23 @@ sysenter_do_call:
10992 testl $_TIF_ALLWORK_MASK, %ecx
10993 jne sysexit_audit
10994 sysenter_exit:
10995 +
10996 +#ifdef CONFIG_PAX_RANDKSTACK
10997 + pushl %eax
10998 + CFI_ADJUST_CFA_OFFSET 4
10999 + call pax_randomize_kstack
11000 + popl %eax
11001 + CFI_ADJUST_CFA_OFFSET -4
11002 +#endif
11003 +
11004 /* if something modifies registers it must also disable sysexit */
11005 movl PT_EIP(%esp), %edx
11006 movl PT_OLDESP(%esp), %ecx
11007 xorl %ebp,%ebp
11008 TRACE_IRQS_ON
11009 1: mov PT_FS(%esp), %fs
11010 +2: mov PT_DS(%esp), %ds
11011 +3: mov PT_ES(%esp), %es
11012 PTGS_TO_GS
11013 ENABLE_INTERRUPTS_SYSEXIT
11014
11015 @@ -513,11 +610,17 @@ sysexit_audit:
11016
11017 CFI_ENDPROC
11018 .pushsection .fixup,"ax"
11019 -2: movl $0,PT_FS(%esp)
11020 +4: movl $0,PT_FS(%esp)
11021 + jmp 1b
11022 +5: movl $0,PT_DS(%esp)
11023 + jmp 1b
11024 +6: movl $0,PT_ES(%esp)
11025 jmp 1b
11026 .section __ex_table,"a"
11027 .align 4
11028 - .long 1b,2b
11029 + .long 1b,4b
11030 + .long 2b,5b
11031 + .long 3b,6b
11032 .popsection
11033 PTGS_TO_GS_EX
11034 ENDPROC(ia32_sysenter_target)
11035 @@ -551,6 +654,10 @@ syscall_exit:
11036 testl $_TIF_ALLWORK_MASK, %ecx # current->work
11037 jne syscall_exit_work
11038
11039 +#ifdef CONFIG_PAX_RANDKSTACK
11040 + call pax_randomize_kstack
11041 +#endif
11042 +
11043 restore_all:
11044 TRACE_IRQS_IRET
11045 restore_all_notrace:
11046 @@ -611,14 +718,21 @@ ldt_ss:
11047 * compensating for the offset by changing to the ESPFIX segment with
11048 * a base address that matches for the difference.
11049 */
11050 -#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
11051 +#define GDT_ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)(%ebx)
11052 mov %esp, %edx /* load kernel esp */
11053 mov PT_OLDESP(%esp), %eax /* load userspace esp */
11054 mov %dx, %ax /* eax: new kernel esp */
11055 sub %eax, %edx /* offset (low word is 0) */
11056 +#ifdef CONFIG_SMP
11057 + movl PER_CPU_VAR(cpu_number), %ebx
11058 + shll $PAGE_SHIFT_asm, %ebx
11059 + addl $cpu_gdt_table, %ebx
11060 +#else
11061 + movl $cpu_gdt_table, %ebx
11062 +#endif
11063 shr $16, %edx
11064 - mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
11065 - mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
11066 + mov %dl, 4 + GDT_ESPFIX_SS /* bits 16..23 */
11067 + mov %dh, 7 + GDT_ESPFIX_SS /* bits 24..31 */
11068 pushl $__ESPFIX_SS
11069 CFI_ADJUST_CFA_OFFSET 4
11070 push %eax /* new kernel esp */
11071 @@ -655,25 +769,19 @@ work_resched:
11072
11073 work_notifysig: # deal with pending signals and
11074 # notify-resume requests
11075 + movl %esp, %eax
11076 #ifdef CONFIG_VM86
11077 testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
11078 - movl %esp, %eax
11079 - jne work_notifysig_v86 # returning to kernel-space or
11080 + jz 1f # returning to kernel-space or
11081 # vm86-space
11082 - xorl %edx, %edx
11083 - call do_notify_resume
11084 - jmp resume_userspace_sig
11085
11086 - ALIGN
11087 -work_notifysig_v86:
11088 pushl %ecx # save ti_flags for do_notify_resume
11089 CFI_ADJUST_CFA_OFFSET 4
11090 call save_v86_state # %eax contains pt_regs pointer
11091 popl %ecx
11092 CFI_ADJUST_CFA_OFFSET -4
11093 movl %eax, %esp
11094 -#else
11095 - movl %esp, %eax
11096 +1:
11097 #endif
11098 xorl %edx, %edx
11099 call do_notify_resume
11100 @@ -708,6 +816,10 @@ END(syscall_exit_work)
11101
11102 RING0_INT_FRAME # can't unwind into user space anyway
11103 syscall_fault:
11104 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11105 + push %ss
11106 + pop %ds
11107 +#endif
11108 GET_THREAD_INFO(%ebp)
11109 movl $-EFAULT,PT_EAX(%esp)
11110 jmp resume_userspace
11111 @@ -791,8 +903,15 @@ ptregs_clone:
11112 * normal stack and adjusts ESP with the matching offset.
11113 */
11114 /* fixup the stack */
11115 - mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
11116 - mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
11117 +#ifdef CONFIG_SMP
11118 + movl PER_CPU_VAR(cpu_number), %ebx
11119 + shll $PAGE_SHIFT_asm, %ebx
11120 + addl $cpu_gdt_table, %ebx
11121 +#else
11122 + movl $cpu_gdt_table, %ebx
11123 +#endif
11124 + mov 4 + GDT_ESPFIX_SS, %al /* bits 16..23 */
11125 + mov 7 + GDT_ESPFIX_SS, %ah /* bits 24..31 */
11126 shl $16, %eax
11127 addl %esp, %eax /* the adjusted stack pointer */
11128 pushl $__KERNEL_DS
11129 @@ -1275,7 +1394,6 @@ return_to_handler:
11130 jmp *%ecx
11131 #endif
11132
11133 -.section .rodata,"a"
11134 #include "syscall_table_32.S"
11135
11136 syscall_table_size=(.-sys_call_table)
11137 @@ -1332,9 +1450,12 @@ error_code:
11138 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
11139 REG_TO_PTGS %ecx
11140 SET_KERNEL_GS %ecx
11141 - movl $(__USER_DS), %ecx
11142 + movl $(__KERNEL_DS), %ecx
11143 movl %ecx, %ds
11144 movl %ecx, %es
11145 +
11146 + PAX_ENTER_KERNEL
11147 +
11148 TRACE_IRQS_OFF
11149 movl %esp,%eax # pt_regs pointer
11150 call *%edi
11151 @@ -1428,6 +1549,9 @@ nmi_stack_correct:
11152 xorl %edx,%edx # zero error code
11153 movl %esp,%eax # pt_regs pointer
11154 call do_nmi
11155 +
11156 + PAX_EXIT_KERNEL
11157 +
11158 jmp restore_all_notrace
11159 CFI_ENDPROC
11160
11161 @@ -1468,6 +1592,9 @@ nmi_espfix_stack:
11162 FIXUP_ESPFIX_STACK # %eax == %esp
11163 xorl %edx,%edx # zero error code
11164 call do_nmi
11165 +
11166 + PAX_EXIT_KERNEL
11167 +
11168 RESTORE_REGS
11169 lss 12+4(%esp), %esp # back to espfix stack
11170 CFI_ADJUST_CFA_OFFSET -24
11171 diff -urNp linux-2.6.36/arch/x86/kernel/entry_64.S linux-2.6.36/arch/x86/kernel/entry_64.S
11172 --- linux-2.6.36/arch/x86/kernel/entry_64.S 2010-10-20 16:30:22.000000000 -0400
11173 +++ linux-2.6.36/arch/x86/kernel/entry_64.S 2010-11-06 18:58:15.000000000 -0400
11174 @@ -53,6 +53,7 @@
11175 #include <asm/paravirt.h>
11176 #include <asm/ftrace.h>
11177 #include <asm/percpu.h>
11178 +#include <asm/pgtable.h>
11179
11180 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
11181 #include <linux/elf-em.h>
11182 @@ -174,6 +175,189 @@ ENTRY(native_usergs_sysret64)
11183 ENDPROC(native_usergs_sysret64)
11184 #endif /* CONFIG_PARAVIRT */
11185
11186 + .macro ljmpq sel, off
11187 +#if defined(CONFIG_MCORE2) || defined (CONFIG_MATOM)
11188 + .byte 0x48; ljmp *1234f(%rip)
11189 + .pushsection .rodata
11190 + .align 16
11191 + 1234: .quad \off; .word \sel
11192 + .popsection
11193 +#else
11194 + push $\sel
11195 + push $\off
11196 + lretq
11197 +#endif
11198 + .endm
11199 +
11200 +ENTRY(pax_enter_kernel)
11201 +
11202 +#ifdef CONFIG_PAX_KERNEXEC
11203 + push %rdi
11204 +
11205 +#ifdef CONFIG_PARAVIRT
11206 + PV_SAVE_REGS(CLBR_RDI)
11207 +#endif
11208 +
11209 + GET_CR0_INTO_RDI
11210 + bts $16,%rdi
11211 + jnc 1f
11212 + mov %cs,%edi
11213 + cmp $__KERNEL_CS,%edi
11214 + jz 3f
11215 + ljmpq __KERNEL_CS,3f
11216 +1: ljmpq __KERNEXEC_KERNEL_CS,2f
11217 +2: SET_RDI_INTO_CR0
11218 +3:
11219 +
11220 +#ifdef CONFIG_PARAVIRT
11221 + PV_RESTORE_REGS(CLBR_RDI)
11222 +#endif
11223 +
11224 + pop %rdi
11225 +#endif
11226 +
11227 + retq
11228 +ENDPROC(pax_enter_kernel)
11229 +
11230 +ENTRY(pax_exit_kernel)
11231 +
11232 +#ifdef CONFIG_PAX_KERNEXEC
11233 + push %rdi
11234 +
11235 +#ifdef CONFIG_PARAVIRT
11236 + PV_SAVE_REGS(CLBR_RDI)
11237 +#endif
11238 +
11239 + mov %cs,%rdi
11240 + cmp $__KERNEXEC_KERNEL_CS,%edi
11241 + jnz 2f
11242 + GET_CR0_INTO_RDI
11243 + btr $16,%rdi
11244 + ljmpq __KERNEL_CS,1f
11245 +1: SET_RDI_INTO_CR0
11246 +2:
11247 +
11248 +#ifdef CONFIG_PARAVIRT
11249 + PV_RESTORE_REGS(CLBR_RDI);
11250 +#endif
11251 +
11252 + pop %rdi
11253 +#endif
11254 +
11255 + retq
11256 +ENDPROC(pax_exit_kernel)
11257 +
11258 +ENTRY(pax_enter_kernel_user)
11259 +
11260 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11261 + push %rdi
11262 + push %rbx
11263 +
11264 +#ifdef CONFIG_PARAVIRT
11265 + PV_SAVE_REGS(CLBR_RDI)
11266 +#endif
11267 +
11268 + GET_CR3_INTO_RDI
11269 + mov %rdi,%rbx
11270 + add $__START_KERNEL_map,%rbx
11271 + sub phys_base(%rip),%rbx
11272 +
11273 +#ifdef CONFIG_PARAVIRT
11274 + push %rdi
11275 + cmpl $0, pv_info+PARAVIRT_enabled
11276 + jz 1f
11277 + i = 0
11278 + .rept USER_PGD_PTRS
11279 + mov i*8(%rbx),%rsi
11280 + mov $0,%sil
11281 + lea i*8(%rbx),%rdi
11282 + call PARA_INDIRECT(pv_mmu_ops+PV_MMU_set_pgd)
11283 + i = i + 1
11284 + .endr
11285 + jmp 2f
11286 +1:
11287 +#endif
11288 +
11289 + i = 0
11290 + .rept USER_PGD_PTRS
11291 + movb $0,i*8(%rbx)
11292 + i = i + 1
11293 + .endr
11294 +
11295 +#ifdef CONFIG_PARAVIRT
11296 +2: pop %rdi
11297 +#endif
11298 + SET_RDI_INTO_CR3
11299 +
11300 +#ifdef CONFIG_PAX_KERNEXEC
11301 + GET_CR0_INTO_RDI
11302 + bts $16,%rdi
11303 + SET_RDI_INTO_CR0
11304 +#endif
11305 +
11306 +#ifdef CONFIG_PARAVIRT
11307 + PV_RESTORE_REGS(CLBR_RDI)
11308 +#endif
11309 +
11310 + pop %rbx
11311 + pop %rdi
11312 +#endif
11313 +
11314 + retq
11315 +ENDPROC(pax_enter_kernel_user)
11316 +
11317 +ENTRY(pax_exit_kernel_user)
11318 +
11319 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11320 + push %rdi
11321 +
11322 +#ifdef CONFIG_PARAVIRT
11323 + push %rbx
11324 + PV_SAVE_REGS(CLBR_RDI)
11325 +#endif
11326 +
11327 +#ifdef CONFIG_PAX_KERNEXEC
11328 + GET_CR0_INTO_RDI
11329 + btr $16,%rdi
11330 + SET_RDI_INTO_CR0
11331 +#endif
11332 +
11333 + GET_CR3_INTO_RDI
11334 + add $__START_KERNEL_map,%rdi
11335 + sub phys_base(%rip),%rdi
11336 +
11337 +#ifdef CONFIG_PARAVIRT
11338 + cmpl $0, pv_info+PARAVIRT_enabled
11339 + jz 1f
11340 + mov %rdi,%rbx
11341 + i = 0
11342 + .rept USER_PGD_PTRS
11343 + mov i*8(%rbx),%rsi
11344 + mov $0x67,%sil
11345 + lea i*8(%rbx),%rdi
11346 + call PARA_INDIRECT(pv_mmu_ops+PV_MMU_set_pgd)
11347 + i = i + 1
11348 + .endr
11349 + jmp 2f
11350 +1:
11351 +#endif
11352 +
11353 + i = 0
11354 + .rept USER_PGD_PTRS
11355 + movb $0x67,i*8(%rdi)
11356 + i = i + 1
11357 + .endr
11358 +
11359 +#ifdef CONFIG_PARAVIRT
11360 +2: PV_RESTORE_REGS(CLBR_RDI)
11361 + pop %rbx
11362 +#endif
11363 +
11364 + pop %rdi
11365 +#endif
11366 +
11367 + retq
11368 +ENDPROC(pax_exit_kernel_user)
11369
11370 .macro TRACE_IRQS_IRETQ offset=ARGOFFSET
11371 #ifdef CONFIG_TRACE_IRQFLAGS
11372 @@ -317,7 +501,7 @@ ENTRY(save_args)
11373 leaq -ARGOFFSET+16(%rsp),%rdi /* arg1 for handler */
11374 movq_cfi rbp, 8 /* push %rbp */
11375 leaq 8(%rsp), %rbp /* mov %rsp, %ebp */
11376 - testl $3, CS(%rdi)
11377 + testb $3, CS(%rdi)
11378 je 1f
11379 SWAPGS
11380 /*
11381 @@ -409,7 +593,7 @@ ENTRY(ret_from_fork)
11382
11383 RESTORE_REST
11384
11385 - testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread?
11386 + testb $3, CS-ARGOFFSET(%rsp) # from kernel_thread?
11387 je int_ret_from_sys_call
11388
11389 testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET
11390 @@ -468,6 +652,11 @@ ENTRY(system_call_after_swapgs)
11391
11392 movq %rsp,PER_CPU_VAR(old_rsp)
11393 movq PER_CPU_VAR(kernel_stack),%rsp
11394 +
11395 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11396 + call pax_enter_kernel_user
11397 +#endif
11398 +
11399 /*
11400 * No need to follow this irqs off/on section - it's straight
11401 * and short:
11402 @@ -502,6 +691,11 @@ sysret_check:
11403 andl %edi,%edx
11404 jnz sysret_careful
11405 CFI_REMEMBER_STATE
11406 +
11407 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11408 + call pax_exit_kernel_user
11409 +#endif
11410 +
11411 /*
11412 * sysretq will re-enable interrupts:
11413 */
11414 @@ -613,7 +807,7 @@ tracesys:
11415 GLOBAL(int_ret_from_sys_call)
11416 DISABLE_INTERRUPTS(CLBR_NONE)
11417 TRACE_IRQS_OFF
11418 - testl $3,CS-ARGOFFSET(%rsp)
11419 + testb $3,CS-ARGOFFSET(%rsp)
11420 je retint_restore_args
11421 movl $_TIF_ALLWORK_MASK,%edi
11422 /* edi: mask to check */
11423 @@ -800,6 +994,16 @@ END(interrupt)
11424 CFI_ADJUST_CFA_OFFSET 10*8
11425 call save_args
11426 PARTIAL_FRAME 0
11427 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11428 + testb $3, CS(%rdi)
11429 + jnz 1f
11430 + call pax_enter_kernel
11431 + jmp 2f
11432 +1: call pax_enter_kernel_user
11433 +2:
11434 +#else
11435 + call pax_enter_kernel
11436 +#endif
11437 call \func
11438 .endm
11439
11440 @@ -826,7 +1030,7 @@ ret_from_intr:
11441 CFI_ADJUST_CFA_OFFSET -8
11442 exit_intr:
11443 GET_THREAD_INFO(%rcx)
11444 - testl $3,CS-ARGOFFSET(%rsp)
11445 + testb $3,CS-ARGOFFSET(%rsp)
11446 je retint_kernel
11447
11448 /* Interrupt came from user space */
11449 @@ -848,12 +1052,18 @@ retint_swapgs: /* return to user-space
11450 * The iretq could re-enable interrupts:
11451 */
11452 DISABLE_INTERRUPTS(CLBR_ANY)
11453 +
11454 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11455 + call pax_exit_kernel_user
11456 +#endif
11457 +
11458 TRACE_IRQS_IRETQ
11459 SWAPGS
11460 jmp restore_args
11461
11462 retint_restore_args: /* return to kernel space */
11463 DISABLE_INTERRUPTS(CLBR_ANY)
11464 + call pax_exit_kernel
11465 /*
11466 * The iretq could re-enable interrupts:
11467 */
11468 @@ -1040,6 +1250,16 @@ ENTRY(\sym)
11469 CFI_ADJUST_CFA_OFFSET 15*8
11470 call error_entry
11471 DEFAULT_FRAME 0
11472 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11473 + testb $3, CS(%rsp)
11474 + jnz 1f
11475 + call pax_enter_kernel
11476 + jmp 2f
11477 +1: call pax_enter_kernel_user
11478 +2:
11479 +#else
11480 + call pax_enter_kernel
11481 +#endif
11482 movq %rsp,%rdi /* pt_regs pointer */
11483 xorl %esi,%esi /* no error code */
11484 call \do_sym
11485 @@ -1057,6 +1277,16 @@ ENTRY(\sym)
11486 subq $15*8, %rsp
11487 call save_paranoid
11488 TRACE_IRQS_OFF
11489 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11490 + testb $3, CS(%rsp)
11491 + jnz 1f
11492 + call pax_enter_kernel
11493 + jmp 2f
11494 +1: call pax_enter_kernel_user
11495 +2:
11496 +#else
11497 + call pax_enter_kernel
11498 +#endif
11499 movq %rsp,%rdi /* pt_regs pointer */
11500 xorl %esi,%esi /* no error code */
11501 call \do_sym
11502 @@ -1065,7 +1295,7 @@ ENTRY(\sym)
11503 END(\sym)
11504 .endm
11505
11506 -#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
11507 +#define INIT_TSS_IST(x) (TSS_ist + ((x) - 1) * 8)(%r12)
11508 .macro paranoidzeroentry_ist sym do_sym ist
11509 ENTRY(\sym)
11510 INTR_FRAME
11511 @@ -1075,8 +1305,24 @@ ENTRY(\sym)
11512 subq $15*8, %rsp
11513 call save_paranoid
11514 TRACE_IRQS_OFF
11515 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11516 + testb $3, CS(%rsp)
11517 + jnz 1f
11518 + call pax_enter_kernel
11519 + jmp 2f
11520 +1: call pax_enter_kernel_user
11521 +2:
11522 +#else
11523 + call pax_enter_kernel
11524 +#endif
11525 movq %rsp,%rdi /* pt_regs pointer */
11526 xorl %esi,%esi /* no error code */
11527 +#ifdef CONFIG_SMP
11528 + imul $TSS_size, PER_CPU_VAR(cpu_number), %r12d
11529 + lea init_tss(%r12), %r12
11530 +#else
11531 + lea init_tss(%rip), %r12
11532 +#endif
11533 subq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
11534 call \do_sym
11535 addq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
11536 @@ -1093,6 +1339,16 @@ ENTRY(\sym)
11537 CFI_ADJUST_CFA_OFFSET 15*8
11538 call error_entry
11539 DEFAULT_FRAME 0
11540 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11541 + testb $3, CS(%rsp)
11542 + jnz 1f
11543 + call pax_enter_kernel
11544 + jmp 2f
11545 +1: call pax_enter_kernel_user
11546 +2:
11547 +#else
11548 + call pax_enter_kernel
11549 +#endif
11550 movq %rsp,%rdi /* pt_regs pointer */
11551 movq ORIG_RAX(%rsp),%rsi /* get error code */
11552 movq $-1,ORIG_RAX(%rsp) /* no syscall to restart */
11553 @@ -1112,6 +1368,16 @@ ENTRY(\sym)
11554 call save_paranoid
11555 DEFAULT_FRAME 0
11556 TRACE_IRQS_OFF
11557 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11558 + testb $3, CS(%rsp)
11559 + jnz 1f
11560 + call pax_enter_kernel
11561 + jmp 2f
11562 +1: call pax_enter_kernel_user
11563 +2:
11564 +#else
11565 + call pax_enter_kernel
11566 +#endif
11567 movq %rsp,%rdi /* pt_regs pointer */
11568 movq ORIG_RAX(%rsp),%rsi /* get error code */
11569 movq $-1,ORIG_RAX(%rsp) /* no syscall to restart */
11570 @@ -1373,14 +1639,27 @@ ENTRY(paranoid_exit)
11571 TRACE_IRQS_OFF
11572 testl %ebx,%ebx /* swapgs needed? */
11573 jnz paranoid_restore
11574 - testl $3,CS(%rsp)
11575 + testb $3,CS(%rsp)
11576 jnz paranoid_userspace
11577 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11578 + call pax_exit_kernel
11579 + TRACE_IRQS_IRETQ 0
11580 + SWAPGS_UNSAFE_STACK
11581 + RESTORE_ALL 8
11582 + jmp irq_return
11583 +#endif
11584 paranoid_swapgs:
11585 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11586 + call pax_exit_kernel_user
11587 +#else
11588 + call pax_exit_kernel
11589 +#endif
11590 TRACE_IRQS_IRETQ 0
11591 SWAPGS_UNSAFE_STACK
11592 RESTORE_ALL 8
11593 jmp irq_return
11594 paranoid_restore:
11595 + call pax_exit_kernel
11596 TRACE_IRQS_IRETQ 0
11597 RESTORE_ALL 8
11598 jmp irq_return
11599 @@ -1438,7 +1717,7 @@ ENTRY(error_entry)
11600 movq_cfi r14, R14+8
11601 movq_cfi r15, R15+8
11602 xorl %ebx,%ebx
11603 - testl $3,CS+8(%rsp)
11604 + testb $3,CS+8(%rsp)
11605 je error_kernelspace
11606 error_swapgs:
11607 SWAPGS
11608 @@ -1502,6 +1781,16 @@ ENTRY(nmi)
11609 CFI_ADJUST_CFA_OFFSET 15*8
11610 call save_paranoid
11611 DEFAULT_FRAME 0
11612 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11613 + testb $3, CS(%rsp)
11614 + jnz 1f
11615 + call pax_enter_kernel
11616 + jmp 2f
11617 +1: call pax_enter_kernel_user
11618 +2:
11619 +#else
11620 + call pax_enter_kernel
11621 +#endif
11622 /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
11623 movq %rsp,%rdi
11624 movq $-1,%rsi
11625 @@ -1512,11 +1801,12 @@ ENTRY(nmi)
11626 DISABLE_INTERRUPTS(CLBR_NONE)
11627 testl %ebx,%ebx /* swapgs needed? */
11628 jnz nmi_restore
11629 - testl $3,CS(%rsp)
11630 + testb $3,CS(%rsp)
11631 jnz nmi_userspace
11632 nmi_swapgs:
11633 SWAPGS_UNSAFE_STACK
11634 nmi_restore:
11635 + call pax_exit_kernel
11636 RESTORE_ALL 8
11637 jmp irq_return
11638 nmi_userspace:
11639 diff -urNp linux-2.6.36/arch/x86/kernel/ftrace.c linux-2.6.36/arch/x86/kernel/ftrace.c
11640 --- linux-2.6.36/arch/x86/kernel/ftrace.c 2010-10-20 16:30:22.000000000 -0400
11641 +++ linux-2.6.36/arch/x86/kernel/ftrace.c 2010-11-06 18:58:15.000000000 -0400
11642 @@ -174,7 +174,9 @@ void ftrace_nmi_enter(void)
11643
11644 if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
11645 smp_rmb();
11646 + pax_open_kernel();
11647 ftrace_mod_code();
11648 + pax_close_kernel();
11649 atomic_inc(&nmi_update_count);
11650 }
11651 /* Must have previous changes seen before executions */
11652 @@ -260,7 +262,7 @@ do_ftrace_mod_code(unsigned long ip, voi
11653
11654
11655
11656 -static unsigned char ftrace_nop[MCOUNT_INSN_SIZE];
11657 +static unsigned char ftrace_nop[MCOUNT_INSN_SIZE] __read_only;
11658
11659 static unsigned char *ftrace_nop_replace(void)
11660 {
11661 @@ -273,6 +275,8 @@ ftrace_modify_code(unsigned long ip, uns
11662 {
11663 unsigned char replaced[MCOUNT_INSN_SIZE];
11664
11665 + ip = ktla_ktva(ip);
11666 +
11667 /*
11668 * Note: Due to modules and __init, code can
11669 * disappear and change, we need to protect against faulting
11670 @@ -329,7 +333,7 @@ int ftrace_update_ftrace_func(ftrace_fun
11671 unsigned char old[MCOUNT_INSN_SIZE], *new;
11672 int ret;
11673
11674 - memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
11675 + memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
11676 new = ftrace_call_replace(ip, (unsigned long)func);
11677 ret = ftrace_modify_code(ip, old, new);
11678
11679 @@ -382,15 +386,15 @@ int __init ftrace_dyn_arch_init(void *da
11680 switch (faulted) {
11681 case 0:
11682 pr_info("converting mcount calls to 0f 1f 44 00 00\n");
11683 - memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE);
11684 + memcpy(ftrace_nop, ktla_ktva(ftrace_test_p6nop), MCOUNT_INSN_SIZE);
11685 break;
11686 case 1:
11687 pr_info("converting mcount calls to 66 66 66 66 90\n");
11688 - memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE);
11689 + memcpy(ftrace_nop, ktla_ktva(ftrace_test_nop5), MCOUNT_INSN_SIZE);
11690 break;
11691 case 2:
11692 pr_info("converting mcount calls to jmp . + 5\n");
11693 - memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE);
11694 + memcpy(ftrace_nop, ktla_ktva(ftrace_test_jmp), MCOUNT_INSN_SIZE);
11695 break;
11696 }
11697
11698 @@ -411,6 +415,8 @@ static int ftrace_mod_jmp(unsigned long
11699 {
11700 unsigned char code[MCOUNT_INSN_SIZE];
11701
11702 + ip = ktla_ktva(ip);
11703 +
11704 if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
11705 return -EFAULT;
11706
11707 diff -urNp linux-2.6.36/arch/x86/kernel/head32.c linux-2.6.36/arch/x86/kernel/head32.c
11708 --- linux-2.6.36/arch/x86/kernel/head32.c 2010-10-20 16:30:22.000000000 -0400
11709 +++ linux-2.6.36/arch/x86/kernel/head32.c 2010-11-06 18:58:15.000000000 -0400
11710 @@ -17,6 +17,7 @@
11711 #include <asm/apic.h>
11712 #include <asm/io_apic.h>
11713 #include <asm/bios_ebda.h>
11714 +#include <asm/boot.h>
11715
11716 static void __init i386_default_early_setup(void)
11717 {
11718 @@ -40,7 +41,7 @@ void __init i386_start_kernel(void)
11719 "EX TRAMPOLINE");
11720 #endif
11721
11722 - reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
11723 + reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&__bss_stop), "TEXT DATA BSS");
11724
11725 #ifdef CONFIG_BLK_DEV_INITRD
11726 /* Reserve INITRD */
11727 diff -urNp linux-2.6.36/arch/x86/kernel/head_32.S linux-2.6.36/arch/x86/kernel/head_32.S
11728 --- linux-2.6.36/arch/x86/kernel/head_32.S 2010-10-20 16:30:22.000000000 -0400
11729 +++ linux-2.6.36/arch/x86/kernel/head_32.S 2010-11-06 18:58:15.000000000 -0400
11730 @@ -25,6 +25,12 @@
11731 /* Physical address */
11732 #define pa(X) ((X) - __PAGE_OFFSET)
11733
11734 +#ifdef CONFIG_PAX_KERNEXEC
11735 +#define ta(X) (X)
11736 +#else
11737 +#define ta(X) ((X) - __PAGE_OFFSET)
11738 +#endif
11739 +
11740 /*
11741 * References to members of the new_cpu_data structure.
11742 */
11743 @@ -54,11 +60,7 @@
11744 * and small than max_low_pfn, otherwise will waste some page table entries
11745 */
11746
11747 -#if PTRS_PER_PMD > 1
11748 -#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
11749 -#else
11750 -#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
11751 -#endif
11752 +#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PTE)
11753
11754 /* Enough space to fit pagetables for the low memory linear map */
11755 MAPPING_BEYOND_END = \
11756 @@ -75,6 +77,12 @@ INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_P
11757 RESERVE_BRK(pagetables, INIT_MAP_SIZE)
11758
11759 /*
11760 + * Real beginning of normal "text" segment
11761 + */
11762 +ENTRY(stext)
11763 +ENTRY(_stext)
11764 +
11765 +/*
11766 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
11767 * %esi points to the real-mode code as a 32-bit pointer.
11768 * CS and DS must be 4 GB flat segments, but we don't depend on
11769 @@ -82,6 +90,13 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE)
11770 * can.
11771 */
11772 __HEAD
11773 +
11774 +#ifdef CONFIG_PAX_KERNEXEC
11775 + jmp startup_32
11776 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
11777 +.fill PAGE_SIZE-5,1,0xcc
11778 +#endif
11779 +
11780 ENTRY(startup_32)
11781 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
11782 us to not reload segments */
11783 @@ -99,6 +114,55 @@ ENTRY(startup_32)
11784 movl %eax,%gs
11785 2:
11786
11787 +#ifdef CONFIG_SMP
11788 + movl $pa(cpu_gdt_table),%edi
11789 + movl $__per_cpu_load,%eax
11790 + movw %ax,__KERNEL_PERCPU + 2(%edi)
11791 + rorl $16,%eax
11792 + movb %al,__KERNEL_PERCPU + 4(%edi)
11793 + movb %ah,__KERNEL_PERCPU + 7(%edi)
11794 + movl $__per_cpu_end - 1,%eax
11795 + subl $__per_cpu_start,%eax
11796 + movw %ax,__KERNEL_PERCPU + 0(%edi)
11797 +#endif
11798 +
11799 +#ifdef CONFIG_PAX_MEMORY_UDEREF
11800 + movl $NR_CPUS,%ecx
11801 + movl $pa(cpu_gdt_table),%edi
11802 +1:
11803 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
11804 + addl $PAGE_SIZE_asm,%edi
11805 + loop 1b
11806 +#endif
11807 +
11808 +#ifdef CONFIG_PAX_KERNEXEC
11809 + movl $pa(boot_gdt),%edi
11810 + movl $__LOAD_PHYSICAL_ADDR,%eax
11811 + movw %ax,__BOOT_CS + 2(%edi)
11812 + rorl $16,%eax
11813 + movb %al,__BOOT_CS + 4(%edi)
11814 + movb %ah,__BOOT_CS + 7(%edi)
11815 + rorl $16,%eax
11816 +
11817 + ljmp $(__BOOT_CS),$1f
11818 +1:
11819 +
11820 + movl $NR_CPUS,%ecx
11821 + movl $pa(cpu_gdt_table),%edi
11822 + addl $__PAGE_OFFSET,%eax
11823 +1:
11824 + movw %ax,__KERNEL_CS + 2(%edi)
11825 + movw %ax,__KERNEXEC_KERNEL_CS + 2(%edi)
11826 + rorl $16,%eax
11827 + movb %al,__KERNEL_CS + 4(%edi)
11828 + movb %al,__KERNEXEC_KERNEL_CS + 4(%edi)
11829 + movb %ah,__KERNEL_CS + 7(%edi)
11830 + movb %ah,__KERNEXEC_KERNEL_CS + 7(%edi)
11831 + rorl $16,%eax
11832 + addl $PAGE_SIZE_asm,%edi
11833 + loop 1b
11834 +#endif
11835 +
11836 /*
11837 * Clear BSS first so that there are no surprises...
11838 */
11839 @@ -148,9 +212,7 @@ ENTRY(startup_32)
11840 cmpl $num_subarch_entries, %eax
11841 jae bad_subarch
11842
11843 - movl pa(subarch_entries)(,%eax,4), %eax
11844 - subl $__PAGE_OFFSET, %eax
11845 - jmp *%eax
11846 + jmp *pa(subarch_entries)(,%eax,4)
11847
11848 bad_subarch:
11849 WEAK(lguest_entry)
11850 @@ -162,10 +224,10 @@ WEAK(xen_entry)
11851 __INITDATA
11852
11853 subarch_entries:
11854 - .long default_entry /* normal x86/PC */
11855 - .long lguest_entry /* lguest hypervisor */
11856 - .long xen_entry /* Xen hypervisor */
11857 - .long default_entry /* Moorestown MID */
11858 + .long ta(default_entry) /* normal x86/PC */
11859 + .long ta(lguest_entry) /* lguest hypervisor */
11860 + .long ta(xen_entry) /* Xen hypervisor */
11861 + .long ta(default_entry) /* Moorestown MID */
11862 num_subarch_entries = (. - subarch_entries) / 4
11863 .previous
11864 #endif /* CONFIG_PARAVIRT */
11865 @@ -226,8 +288,11 @@ default_entry:
11866 movl %eax, pa(max_pfn_mapped)
11867
11868 /* Do early initialization of the fixmap area */
11869 - movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
11870 - movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
11871 +#ifdef CONFIG_COMPAT_VDSO
11872 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(swapper_pg_pmd+0x1000*KPMDS-8)
11873 +#else
11874 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
11875 +#endif
11876 #else /* Not PAE */
11877
11878 page_pde_offset = (__PAGE_OFFSET >> 20);
11879 @@ -257,8 +322,11 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
11880 movl %eax, pa(max_pfn_mapped)
11881
11882 /* Do early initialization of the fixmap area */
11883 - movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
11884 - movl %eax,pa(swapper_pg_dir+0xffc)
11885 +#ifdef CONFIG_COMPAT_VDSO
11886 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(swapper_pg_dir+0xffc)
11887 +#else
11888 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xffc)
11889 +#endif
11890 #endif
11891 jmp 3f
11892 /*
11893 @@ -305,6 +373,7 @@ ENTRY(startup_32_smp)
11894 orl %edx,%eax
11895 movl %eax,%cr4
11896
11897 +#ifdef CONFIG_X86_PAE
11898 testb $X86_CR4_PAE, %al # check if PAE is enabled
11899 jz 6f
11900
11901 @@ -329,6 +398,9 @@ ENTRY(startup_32_smp)
11902 /* Make changes effective */
11903 wrmsr
11904
11905 + btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4)
11906 +#endif
11907 +
11908 6:
11909
11910 /*
11911 @@ -354,9 +426,7 @@ ENTRY(startup_32_smp)
11912
11913 #ifdef CONFIG_SMP
11914 cmpb $0, ready
11915 - jz 1f /* Initial CPU cleans BSS */
11916 - jmp checkCPUtype
11917 -1:
11918 + jnz checkCPUtype /* Initial CPU cleans BSS */
11919 #endif /* CONFIG_SMP */
11920
11921 /*
11922 @@ -434,7 +504,7 @@ is386: movl $2,%ecx # set MP
11923 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
11924 movl %eax,%ss # after changing gdt.
11925
11926 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
11927 +# movl $(__KERNEL_DS),%eax # DS/ES contains default KERNEL segment
11928 movl %eax,%ds
11929 movl %eax,%es
11930
11931 @@ -448,8 +518,11 @@ is386: movl $2,%ecx # set MP
11932 */
11933 cmpb $0,ready
11934 jne 1f
11935 - movl $gdt_page,%eax
11936 + movl $cpu_gdt_table,%eax
11937 movl $stack_canary,%ecx
11938 +#ifdef CONFIG_SMP
11939 + addl $__per_cpu_load,%ecx
11940 +#endif
11941 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
11942 shrl $16, %ecx
11943 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
11944 @@ -467,10 +540,6 @@ is386: movl $2,%ecx # set MP
11945 #ifdef CONFIG_SMP
11946 movb ready, %cl
11947 movb $1, ready
11948 - cmpb $0,%cl # the first CPU calls start_kernel
11949 - je 1f
11950 - movl (stack_start), %esp
11951 -1:
11952 #endif /* CONFIG_SMP */
11953 jmp *(initial_code)
11954
11955 @@ -556,22 +625,22 @@ early_page_fault:
11956 jmp early_fault
11957
11958 early_fault:
11959 - cld
11960 #ifdef CONFIG_PRINTK
11961 + cmpl $1,%ss:early_recursion_flag
11962 + je hlt_loop
11963 + incl %ss:early_recursion_flag
11964 + cld
11965 pusha
11966 movl $(__KERNEL_DS),%eax
11967 movl %eax,%ds
11968 movl %eax,%es
11969 - cmpl $2,early_recursion_flag
11970 - je hlt_loop
11971 - incl early_recursion_flag
11972 movl %cr2,%eax
11973 pushl %eax
11974 pushl %edx /* trapno */
11975 pushl $fault_msg
11976 call printk
11977 +; call dump_stack
11978 #endif
11979 - call dump_stack
11980 hlt_loop:
11981 hlt
11982 jmp hlt_loop
11983 @@ -579,8 +648,11 @@ hlt_loop:
11984 /* This is the default interrupt "handler" :-) */
11985 ALIGN
11986 ignore_int:
11987 - cld
11988 #ifdef CONFIG_PRINTK
11989 + cmpl $2,%ss:early_recursion_flag
11990 + je hlt_loop
11991 + incl %ss:early_recursion_flag
11992 + cld
11993 pushl %eax
11994 pushl %ecx
11995 pushl %edx
11996 @@ -589,9 +661,6 @@ ignore_int:
11997 movl $(__KERNEL_DS),%eax
11998 movl %eax,%ds
11999 movl %eax,%es
12000 - cmpl $2,early_recursion_flag
12001 - je hlt_loop
12002 - incl early_recursion_flag
12003 pushl 16(%esp)
12004 pushl 24(%esp)
12005 pushl 32(%esp)
12006 @@ -620,31 +689,47 @@ ENTRY(initial_page_table)
12007 /*
12008 * BSS section
12009 */
12010 -__PAGE_ALIGNED_BSS
12011 - .align PAGE_SIZE_asm
12012 #ifdef CONFIG_X86_PAE
12013 +.section .swapper_pg_pmd,"a",@progbits
12014 swapper_pg_pmd:
12015 .fill 1024*KPMDS,4,0
12016 #else
12017 +.section .swapper_pg_dir,"a",@progbits
12018 ENTRY(swapper_pg_dir)
12019 .fill 1024,4,0
12020 #endif
12021 +.section .swapper_pg_fixmap,"a",@progbits
12022 swapper_pg_fixmap:
12023 .fill 1024,4,0
12024 #ifdef CONFIG_X86_TRAMPOLINE
12025 +.section .trampoline_pg_dir,"a",@progbits
12026 ENTRY(trampoline_pg_dir)
12027 +#ifdef CONFIG_X86_PAE
12028 + .fill 4,8,0
12029 +#else
12030 .fill 1024,4,0
12031 #endif
12032 +#endif
12033 +
12034 +.section .empty_zero_page,"a",@progbits
12035 ENTRY(empty_zero_page)
12036 .fill 4096,1,0
12037
12038 /*
12039 + * The IDT has to be page-aligned to simplify the Pentium
12040 + * F0 0F bug workaround.. We have a special link segment
12041 + * for this.
12042 + */
12043 +.section .idt,"a",@progbits
12044 +ENTRY(idt_table)
12045 + .fill 256,8,0
12046 +
12047 +/*
12048 * This starts the data section.
12049 */
12050 #ifdef CONFIG_X86_PAE
12051 -__PAGE_ALIGNED_DATA
12052 - /* Page-aligned for the benefit of paravirt? */
12053 - .align PAGE_SIZE_asm
12054 +.section .swapper_pg_dir,"a",@progbits
12055 +
12056 ENTRY(swapper_pg_dir)
12057 .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
12058 # if KPMDS == 3
12059 @@ -663,15 +748,24 @@ ENTRY(swapper_pg_dir)
12060 # error "Kernel PMDs should be 1, 2 or 3"
12061 # endif
12062 .align PAGE_SIZE_asm /* needs to be page-sized too */
12063 +
12064 +#ifdef CONFIG_PAX_PER_CPU_PGD
12065 +ENTRY(cpu_pgd)
12066 + .rept NR_CPUS
12067 + .fill 4,8,0
12068 + .endr
12069 +#endif
12070 +
12071 #endif
12072
12073 .data
12074 ENTRY(stack_start)
12075 - .long init_thread_union+THREAD_SIZE
12076 + .long init_thread_union+THREAD_SIZE-8
12077 .long __BOOT_DS
12078
12079 ready: .byte 0
12080
12081 +.section .rodata,"a",@progbits
12082 early_recursion_flag:
12083 .long 0
12084
12085 @@ -707,7 +801,7 @@ fault_msg:
12086 .word 0 # 32 bit align gdt_desc.address
12087 boot_gdt_descr:
12088 .word __BOOT_DS+7
12089 - .long boot_gdt - __PAGE_OFFSET
12090 + .long pa(boot_gdt)
12091
12092 .word 0 # 32-bit align idt_desc.address
12093 idt_descr:
12094 @@ -718,7 +812,7 @@ idt_descr:
12095 .word 0 # 32 bit align gdt_desc.address
12096 ENTRY(early_gdt_descr)
12097 .word GDT_ENTRIES*8-1
12098 - .long gdt_page /* Overwritten for secondary CPUs */
12099 + .long cpu_gdt_table /* Overwritten for secondary CPUs */
12100
12101 /*
12102 * The boot_gdt must mirror the equivalent in setup.S and is
12103 @@ -727,5 +821,65 @@ ENTRY(early_gdt_descr)
12104 .align L1_CACHE_BYTES
12105 ENTRY(boot_gdt)
12106 .fill GDT_ENTRY_BOOT_CS,8,0
12107 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
12108 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
12109 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
12110 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
12111 +
12112 + .align PAGE_SIZE_asm
12113 +ENTRY(cpu_gdt_table)
12114 + .rept NR_CPUS
12115 + .quad 0x0000000000000000 /* NULL descriptor */
12116 + .quad 0x0000000000000000 /* 0x0b reserved */
12117 + .quad 0x0000000000000000 /* 0x13 reserved */
12118 + .quad 0x0000000000000000 /* 0x1b reserved */
12119 +
12120 +#ifdef CONFIG_PAX_KERNEXEC
12121 + .quad 0x00cf9b000000ffff /* 0x20 alternate kernel 4GB code at 0x00000000 */
12122 +#else
12123 + .quad 0x0000000000000000 /* 0x20 unused */
12124 +#endif
12125 +
12126 + .quad 0x0000000000000000 /* 0x28 unused */
12127 + .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
12128 + .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
12129 + .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
12130 + .quad 0x0000000000000000 /* 0x4b reserved */
12131 + .quad 0x0000000000000000 /* 0x53 reserved */
12132 + .quad 0x0000000000000000 /* 0x5b reserved */
12133 +
12134 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
12135 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
12136 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
12137 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
12138 +
12139 + .quad 0x0000000000000000 /* 0x80 TSS descriptor */
12140 + .quad 0x0000000000000000 /* 0x88 LDT descriptor */
12141 +
12142 + /*
12143 + * Segments used for calling PnP BIOS have byte granularity.
12144 + * The code segments and data segments have fixed 64k limits,
12145 + * the transfer segment sizes are set at run time.
12146 + */
12147 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
12148 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
12149 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
12150 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
12151 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
12152 +
12153 + /*
12154 + * The APM segments have byte granularity and their bases
12155 + * are set at run time. All have 64k limits.
12156 + */
12157 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
12158 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
12159 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
12160 +
12161 + .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
12162 + .quad 0x0040930000000000 /* 0xd8 - PERCPU */
12163 + .quad 0x0040910000000018 /* 0xe0 - STACK_CANARY */
12164 + .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_CS */
12165 + .quad 0x0000000000000000 /* 0xf0 - PCIBIOS_DS */
12166 + .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
12167 +
12168 + /* Be sure this is zeroed to avoid false validations in Xen */
12169 + .fill PAGE_SIZE_asm - GDT_SIZE,1,0
12170 + .endr
12171 diff -urNp linux-2.6.36/arch/x86/kernel/head_64.S linux-2.6.36/arch/x86/kernel/head_64.S
12172 --- linux-2.6.36/arch/x86/kernel/head_64.S 2010-10-20 16:30:22.000000000 -0400
12173 +++ linux-2.6.36/arch/x86/kernel/head_64.S 2010-11-06 18:58:15.000000000 -0400
12174 @@ -19,6 +19,7 @@
12175 #include <asm/cache.h>
12176 #include <asm/processor-flags.h>
12177 #include <asm/percpu.h>
12178 +#include <asm/cpufeature.h>
12179
12180 #ifdef CONFIG_PARAVIRT
12181 #include <asm/asm-offsets.h>
12182 @@ -38,6 +39,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
12183 L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
12184 L4_START_KERNEL = pgd_index(__START_KERNEL_map)
12185 L3_START_KERNEL = pud_index(__START_KERNEL_map)
12186 +L4_VMALLOC_START = pgd_index(VMALLOC_START)
12187 +L3_VMALLOC_START = pud_index(VMALLOC_START)
12188 +L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
12189 +L3_VMEMMAP_START = pud_index(VMEMMAP_START)
12190
12191 .text
12192 __HEAD
12193 @@ -85,35 +90,22 @@ startup_64:
12194 */
12195 addq %rbp, init_level4_pgt + 0(%rip)
12196 addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
12197 + addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
12198 + addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
12199 addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
12200
12201 addq %rbp, level3_ident_pgt + 0(%rip)
12202 +#ifndef CONFIG_XEN
12203 + addq %rbp, level3_ident_pgt + 8(%rip)
12204 +#endif
12205
12206 - addq %rbp, level3_kernel_pgt + (510*8)(%rip)
12207 - addq %rbp, level3_kernel_pgt + (511*8)(%rip)
12208 + addq %rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip)
12209
12210 - addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
12211 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
12212 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
12213
12214 - /* Add an Identity mapping if I am above 1G */
12215 - leaq _text(%rip), %rdi
12216 - andq $PMD_PAGE_MASK, %rdi
12217 -
12218 - movq %rdi, %rax
12219 - shrq $PUD_SHIFT, %rax
12220 - andq $(PTRS_PER_PUD - 1), %rax
12221 - jz ident_complete
12222 -
12223 - leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
12224 - leaq level3_ident_pgt(%rip), %rbx
12225 - movq %rdx, 0(%rbx, %rax, 8)
12226 -
12227 - movq %rdi, %rax
12228 - shrq $PMD_SHIFT, %rax
12229 - andq $(PTRS_PER_PMD - 1), %rax
12230 - leaq __PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx
12231 - leaq level2_spare_pgt(%rip), %rbx
12232 - movq %rdx, 0(%rbx, %rax, 8)
12233 -ident_complete:
12234 + addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
12235 + addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
12236
12237 /*
12238 * Fixup the kernel text+data virtual addresses. Note that
12239 @@ -161,8 +153,8 @@ ENTRY(secondary_startup_64)
12240 * after the boot processor executes this code.
12241 */
12242
12243 - /* Enable PAE mode and PGE */
12244 - movl $(X86_CR4_PAE | X86_CR4_PGE), %eax
12245 + /* Enable PAE mode and PSE/PGE */
12246 + movl $(X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE), %eax
12247 movq %rax, %cr4
12248
12249 /* Setup early boot stage 4 level pagetables. */
12250 @@ -184,9 +176,14 @@ ENTRY(secondary_startup_64)
12251 movl $MSR_EFER, %ecx
12252 rdmsr
12253 btsl $_EFER_SCE, %eax /* Enable System Call */
12254 - btl $20,%edi /* No Execute supported? */
12255 + btl $(X86_FEATURE_NX & 31),%edi /* No Execute supported? */
12256 jnc 1f
12257 btsl $_EFER_NX, %eax
12258 + leaq init_level4_pgt(%rip), %rdi
12259 + btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
12260 + btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
12261 + btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
12262 + btsq $_PAGE_BIT_NX, __supported_pte_mask(%rip)
12263 1: wrmsr /* Make changes effective */
12264
12265 /* Setup cr0 */
12266 @@ -270,7 +267,7 @@ ENTRY(secondary_startup_64)
12267 bad_address:
12268 jmp bad_address
12269
12270 - .section ".init.text","ax"
12271 + __INIT
12272 #ifdef CONFIG_EARLY_PRINTK
12273 .globl early_idt_handlers
12274 early_idt_handlers:
12275 @@ -315,18 +312,23 @@ ENTRY(early_idt_handler)
12276 #endif /* EARLY_PRINTK */
12277 1: hlt
12278 jmp 1b
12279 + .previous
12280
12281 #ifdef CONFIG_EARLY_PRINTK
12282 + __INITDATA
12283 early_recursion_flag:
12284 .long 0
12285 + .previous
12286
12287 + .section .rodata,"a",@progbits
12288 early_idt_msg:
12289 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
12290 early_idt_ripmsg:
12291 .asciz "RIP %s\n"
12292 -#endif /* CONFIG_EARLY_PRINTK */
12293 .previous
12294 +#endif /* CONFIG_EARLY_PRINTK */
12295
12296 + .section .rodata,"a",@progbits
12297 #define NEXT_PAGE(name) \
12298 .balign PAGE_SIZE; \
12299 ENTRY(name)
12300 @@ -350,13 +352,36 @@ NEXT_PAGE(init_level4_pgt)
12301 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
12302 .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
12303 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
12304 + .org init_level4_pgt + L4_VMALLOC_START*8, 0
12305 + .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
12306 + .org init_level4_pgt + L4_VMEMMAP_START*8, 0
12307 + .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
12308 .org init_level4_pgt + L4_START_KERNEL*8, 0
12309 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
12310 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
12311
12312 +#ifdef CONFIG_PAX_PER_CPU_PGD
12313 +NEXT_PAGE(cpu_pgd)
12314 + .rept NR_CPUS
12315 + .fill 512,8,0
12316 + .endr
12317 +#endif
12318 +
12319 NEXT_PAGE(level3_ident_pgt)
12320 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
12321 +#ifdef CONFIG_XEN
12322 .fill 511,8,0
12323 +#else
12324 + .quad level2_ident_pgt + PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
12325 + .fill 510,8,0
12326 +#endif
12327 +
12328 +NEXT_PAGE(level3_vmalloc_pgt)
12329 + .fill 512,8,0
12330 +
12331 +NEXT_PAGE(level3_vmemmap_pgt)
12332 + .fill L3_VMEMMAP_START,8,0
12333 + .quad level2_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
12334
12335 NEXT_PAGE(level3_kernel_pgt)
12336 .fill L3_START_KERNEL,8,0
12337 @@ -364,20 +389,23 @@ NEXT_PAGE(level3_kernel_pgt)
12338 .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
12339 .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
12340
12341 +NEXT_PAGE(level2_vmemmap_pgt)
12342 + .fill 512,8,0
12343 +
12344 NEXT_PAGE(level2_fixmap_pgt)
12345 - .fill 506,8,0
12346 - .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
12347 - /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
12348 - .fill 5,8,0
12349 + .fill 507,8,0
12350 + .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
12351 + /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
12352 + .fill 4,8,0
12353
12354 -NEXT_PAGE(level1_fixmap_pgt)
12355 +NEXT_PAGE(level1_vsyscall_pgt)
12356 .fill 512,8,0
12357
12358 -NEXT_PAGE(level2_ident_pgt)
12359 - /* Since I easily can, map the first 1G.
12360 + /* Since I easily can, map the first 2G.
12361 * Don't set NX because code runs from these pages.
12362 */
12363 - PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
12364 +NEXT_PAGE(level2_ident_pgt)
12365 + PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 2*PTRS_PER_PMD)
12366
12367 NEXT_PAGE(level2_kernel_pgt)
12368 /*
12369 @@ -390,33 +418,55 @@ NEXT_PAGE(level2_kernel_pgt)
12370 * If you want to increase this then increase MODULES_VADDR
12371 * too.)
12372 */
12373 - PMDS(0, __PAGE_KERNEL_LARGE_EXEC,
12374 - KERNEL_IMAGE_SIZE/PMD_SIZE)
12375 -
12376 -NEXT_PAGE(level2_spare_pgt)
12377 - .fill 512, 8, 0
12378 + PMDS(0, __PAGE_KERNEL_LARGE_EXEC, KERNEL_IMAGE_SIZE/PMD_SIZE)
12379
12380 #undef PMDS
12381 #undef NEXT_PAGE
12382
12383 - .data
12384 + .align PAGE_SIZE
12385 +ENTRY(cpu_gdt_table)
12386 + .rept NR_CPUS
12387 + .quad 0x0000000000000000 /* NULL descriptor */
12388 + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
12389 + .quad 0x00af9b000000ffff /* __KERNEL_CS */
12390 + .quad 0x00cf93000000ffff /* __KERNEL_DS */
12391 + .quad 0x00cffb000000ffff /* __USER32_CS */
12392 + .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
12393 + .quad 0x00affb000000ffff /* __USER_CS */
12394 +
12395 +#ifdef CONFIG_PAX_KERNEXEC
12396 + .quad 0x00af9b000000ffff /* __KERNEXEC_KERNEL_CS */
12397 +#else
12398 + .quad 0x0 /* unused */
12399 +#endif
12400 +
12401 + .quad 0,0 /* TSS */
12402 + .quad 0,0 /* LDT */
12403 + .quad 0,0,0 /* three TLS descriptors */
12404 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
12405 + /* asm/segment.h:GDT_ENTRIES must match this */
12406 +
12407 + /* zero the remaining page */
12408 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
12409 + .endr
12410 +
12411 .align 16
12412 .globl early_gdt_descr
12413 early_gdt_descr:
12414 .word GDT_ENTRIES*8-1
12415 early_gdt_descr_base:
12416 - .quad INIT_PER_CPU_VAR(gdt_page)
12417 + .quad cpu_gdt_table
12418
12419 ENTRY(phys_base)
12420 /* This must match the first entry in level2_kernel_pgt */
12421 .quad 0x0000000000000000
12422
12423 #include "../../x86/xen/xen-head.S"
12424 -
12425 - .section .bss, "aw", @nobits
12426 +
12427 + .section .rodata,"a",@progbits
12428 .align L1_CACHE_BYTES
12429 ENTRY(idt_table)
12430 - .skip IDT_ENTRIES * 16
12431 + .fill 512,8,0
12432
12433 __PAGE_ALIGNED_BSS
12434 .align PAGE_SIZE
12435 diff -urNp linux-2.6.36/arch/x86/kernel/i386_ksyms_32.c linux-2.6.36/arch/x86/kernel/i386_ksyms_32.c
12436 --- linux-2.6.36/arch/x86/kernel/i386_ksyms_32.c 2010-10-20 16:30:22.000000000 -0400
12437 +++ linux-2.6.36/arch/x86/kernel/i386_ksyms_32.c 2010-11-06 18:58:15.000000000 -0400
12438 @@ -20,8 +20,12 @@ extern void cmpxchg8b_emu(void);
12439 EXPORT_SYMBOL(cmpxchg8b_emu);
12440 #endif
12441
12442 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
12443 +
12444 /* Networking helper routines. */
12445 EXPORT_SYMBOL(csum_partial_copy_generic);
12446 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
12447 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
12448
12449 EXPORT_SYMBOL(__get_user_1);
12450 EXPORT_SYMBOL(__get_user_2);
12451 @@ -36,3 +40,7 @@ EXPORT_SYMBOL(strstr);
12452
12453 EXPORT_SYMBOL(csum_partial);
12454 EXPORT_SYMBOL(empty_zero_page);
12455 +
12456 +#ifdef CONFIG_PAX_KERNEXEC
12457 +EXPORT_SYMBOL(__LOAD_PHYSICAL_ADDR);
12458 +#endif
12459 diff -urNp linux-2.6.36/arch/x86/kernel/init_task.c linux-2.6.36/arch/x86/kernel/init_task.c
12460 --- linux-2.6.36/arch/x86/kernel/init_task.c 2010-10-20 16:30:22.000000000 -0400
12461 +++ linux-2.6.36/arch/x86/kernel/init_task.c 2010-11-06 18:58:15.000000000 -0400
12462 @@ -38,5 +38,5 @@ EXPORT_SYMBOL(init_task);
12463 * section. Since TSS's are completely CPU-local, we want them
12464 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
12465 */
12466 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
12467 -
12468 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
12469 +EXPORT_SYMBOL(init_tss);
12470 diff -urNp linux-2.6.36/arch/x86/kernel/ioport.c linux-2.6.36/arch/x86/kernel/ioport.c
12471 --- linux-2.6.36/arch/x86/kernel/ioport.c 2010-10-20 16:30:22.000000000 -0400
12472 +++ linux-2.6.36/arch/x86/kernel/ioport.c 2010-11-06 18:58:50.000000000 -0400
12473 @@ -6,6 +6,7 @@
12474 #include <linux/sched.h>
12475 #include <linux/kernel.h>
12476 #include <linux/capability.h>
12477 +#include <linux/security.h>
12478 #include <linux/errno.h>
12479 #include <linux/types.h>
12480 #include <linux/ioport.h>
12481 @@ -41,6 +42,12 @@ asmlinkage long sys_ioperm(unsigned long
12482
12483 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
12484 return -EINVAL;
12485 +#ifdef CONFIG_GRKERNSEC_IO
12486 + if (turn_on && grsec_disable_privio) {
12487 + gr_handle_ioperm();
12488 + return -EPERM;
12489 + }
12490 +#endif
12491 if (turn_on && !capable(CAP_SYS_RAWIO))
12492 return -EPERM;
12493
12494 @@ -67,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long
12495 * because the ->io_bitmap_max value must match the bitmap
12496 * contents:
12497 */
12498 - tss = &per_cpu(init_tss, get_cpu());
12499 + tss = init_tss + get_cpu();
12500
12501 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
12502
12503 @@ -112,6 +119,12 @@ long sys_iopl(unsigned int level, struct
12504 return -EINVAL;
12505 /* Trying to gain more privileges? */
12506 if (level > old) {
12507 +#ifdef CONFIG_GRKERNSEC_IO
12508 + if (grsec_disable_privio) {
12509 + gr_handle_iopl();
12510 + return -EPERM;
12511 + }
12512 +#endif
12513 if (!capable(CAP_SYS_RAWIO))
12514 return -EPERM;
12515 }
12516 diff -urNp linux-2.6.36/arch/x86/kernel/irq_32.c linux-2.6.36/arch/x86/kernel/irq_32.c
12517 --- linux-2.6.36/arch/x86/kernel/irq_32.c 2010-10-20 16:30:22.000000000 -0400
12518 +++ linux-2.6.36/arch/x86/kernel/irq_32.c 2010-11-06 18:58:15.000000000 -0400
12519 @@ -94,7 +94,7 @@ execute_on_irq_stack(int overflow, struc
12520 return 0;
12521
12522 /* build the stack frame on the IRQ stack */
12523 - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
12524 + isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
12525 irqctx->tinfo.task = curctx->tinfo.task;
12526 irqctx->tinfo.previous_esp = current_stack_pointer;
12527
12528 @@ -175,7 +175,7 @@ asmlinkage void do_softirq(void)
12529 irqctx->tinfo.previous_esp = current_stack_pointer;
12530
12531 /* build the stack frame on the softirq stack */
12532 - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
12533 + isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
12534
12535 call_on_stack(__do_softirq, isp);
12536 /*
12537 diff -urNp linux-2.6.36/arch/x86/kernel/kgdb.c linux-2.6.36/arch/x86/kernel/kgdb.c
12538 --- linux-2.6.36/arch/x86/kernel/kgdb.c 2010-10-20 16:30:22.000000000 -0400
12539 +++ linux-2.6.36/arch/x86/kernel/kgdb.c 2010-11-06 18:58:15.000000000 -0400
12540 @@ -123,11 +123,11 @@ char *dbg_get_reg(int regno, void *mem,
12541 switch (regno) {
12542 #ifdef CONFIG_X86_32
12543 case GDB_SS:
12544 - if (!user_mode_vm(regs))
12545 + if (!user_mode(regs))
12546 *(unsigned long *)mem = __KERNEL_DS;
12547 break;
12548 case GDB_SP:
12549 - if (!user_mode_vm(regs))
12550 + if (!user_mode(regs))
12551 *(unsigned long *)mem = kernel_stack_pointer(regs);
12552 break;
12553 case GDB_GS:
12554 @@ -715,7 +715,7 @@ void kgdb_arch_set_pc(struct pt_regs *re
12555 regs->ip = ip;
12556 }
12557
12558 -struct kgdb_arch arch_kgdb_ops = {
12559 +const struct kgdb_arch arch_kgdb_ops = {
12560 /* Breakpoint instruction: */
12561 .gdb_bpt_instr = { 0xcc },
12562 .flags = KGDB_HW_BREAKPOINT,
12563 diff -urNp linux-2.6.36/arch/x86/kernel/kprobes.c linux-2.6.36/arch/x86/kernel/kprobes.c
12564 --- linux-2.6.36/arch/x86/kernel/kprobes.c 2010-10-20 16:30:22.000000000 -0400
12565 +++ linux-2.6.36/arch/x86/kernel/kprobes.c 2010-11-06 18:58:15.000000000 -0400
12566 @@ -114,9 +114,12 @@ static void __kprobes __synthesize_relat
12567 s32 raddr;
12568 } __attribute__((packed)) *insn;
12569
12570 - insn = (struct __arch_relative_insn *)from;
12571 + insn = (struct __arch_relative_insn *)(ktla_ktva(from));
12572 +
12573 + pax_open_kernel();
12574 insn->raddr = (s32)((long)(to) - ((long)(from) + 5));
12575 insn->op = op;
12576 + pax_close_kernel();
12577 }
12578
12579 /* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
12580 @@ -317,7 +320,9 @@ static int __kprobes __copy_instruction(
12581 }
12582 }
12583 insn_get_length(&insn);
12584 + pax_open_kernel();
12585 memcpy(dest, insn.kaddr, insn.length);
12586 + pax_close_kernel();
12587
12588 #ifdef CONFIG_X86_64
12589 if (insn_rip_relative(&insn)) {
12590 @@ -341,7 +346,9 @@ static int __kprobes __copy_instruction(
12591 (u8 *) dest;
12592 BUG_ON((s64) (s32) newdisp != newdisp); /* Sanity check. */
12593 disp = (u8 *) dest + insn_offset_displacement(&insn);
12594 + pax_open_kernel();
12595 *(s32 *) disp = (s32) newdisp;
12596 + pax_close_kernel();
12597 }
12598 #endif
12599 return insn.length;
12600 @@ -355,12 +362,12 @@ static void __kprobes arch_copy_kprobe(s
12601 */
12602 __copy_instruction(p->ainsn.insn, p->addr, 0);
12603
12604 - if (can_boost(p->addr))
12605 + if (can_boost(ktla_ktva(p->addr)))
12606 p->ainsn.boostable = 0;
12607 else
12608 p->ainsn.boostable = -1;
12609
12610 - p->opcode = *p->addr;
12611 + p->opcode = *(ktla_ktva(p->addr));
12612 }
12613
12614 int __kprobes arch_prepare_kprobe(struct kprobe *p)
12615 @@ -477,7 +484,7 @@ static void __kprobes setup_singlestep(s
12616 * nor set current_kprobe, because it doesn't use single
12617 * stepping.
12618 */
12619 - regs->ip = (unsigned long)p->ainsn.insn;
12620 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
12621 preempt_enable_no_resched();
12622 return;
12623 }
12624 @@ -496,7 +503,7 @@ static void __kprobes setup_singlestep(s
12625 if (p->opcode == BREAKPOINT_INSTRUCTION)
12626 regs->ip = (unsigned long)p->addr;
12627 else
12628 - regs->ip = (unsigned long)p->ainsn.insn;
12629 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
12630 }
12631
12632 /*
12633 @@ -575,7 +582,7 @@ static int __kprobes kprobe_handler(stru
12634 setup_singlestep(p, regs, kcb, 0);
12635 return 1;
12636 }
12637 - } else if (*addr != BREAKPOINT_INSTRUCTION) {
12638 + } else if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
12639 /*
12640 * The breakpoint instruction was removed right
12641 * after we hit it. Another cpu has removed
12642 @@ -820,7 +827,7 @@ static void __kprobes resume_execution(s
12643 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
12644 {
12645 unsigned long *tos = stack_addr(regs);
12646 - unsigned long copy_ip = (unsigned long)p->ainsn.insn;
12647 + unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
12648 unsigned long orig_ip = (unsigned long)p->addr;
12649 kprobe_opcode_t *insn = p->ainsn.insn;
12650
12651 @@ -1002,7 +1009,7 @@ int __kprobes kprobe_exceptions_notify(s
12652 struct die_args *args = data;
12653 int ret = NOTIFY_DONE;
12654
12655 - if (args->regs && user_mode_vm(args->regs))
12656 + if (args->regs && user_mode(args->regs))
12657 return ret;
12658
12659 switch (val) {
12660 diff -urNp linux-2.6.36/arch/x86/kernel/ldt.c linux-2.6.36/arch/x86/kernel/ldt.c
12661 --- linux-2.6.36/arch/x86/kernel/ldt.c 2010-10-20 16:30:22.000000000 -0400
12662 +++ linux-2.6.36/arch/x86/kernel/ldt.c 2010-11-06 18:58:15.000000000 -0400
12663 @@ -67,13 +67,13 @@ static int alloc_ldt(mm_context_t *pc, i
12664 if (reload) {
12665 #ifdef CONFIG_SMP
12666 preempt_disable();
12667 - load_LDT(pc);
12668 + load_LDT_nolock(pc);
12669 if (!cpumask_equal(mm_cpumask(current->mm),
12670 cpumask_of(smp_processor_id())))
12671 smp_call_function(flush_ldt, current->mm, 1);
12672 preempt_enable();
12673 #else
12674 - load_LDT(pc);
12675 + load_LDT_nolock(pc);
12676 #endif
12677 }
12678 if (oldsize) {
12679 @@ -95,7 +95,7 @@ static inline int copy_ldt(mm_context_t
12680 return err;
12681
12682 for (i = 0; i < old->size; i++)
12683 - write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
12684 + write_ldt_entry(new->ldt, i, old->ldt + i);
12685 return 0;
12686 }
12687
12688 @@ -116,6 +116,24 @@ int init_new_context(struct task_struct
12689 retval = copy_ldt(&mm->context, &old_mm->context);
12690 mutex_unlock(&old_mm->context.lock);
12691 }
12692 +
12693 + if (tsk == current) {
12694 + mm->context.vdso = 0;
12695 +
12696 +#ifdef CONFIG_X86_32
12697 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12698 + mm->context.user_cs_base = 0UL;
12699 + mm->context.user_cs_limit = ~0UL;
12700 +
12701 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
12702 + cpus_clear(mm->context.cpu_user_cs_mask);
12703 +#endif
12704 +
12705 +#endif
12706 +#endif
12707 +
12708 + }
12709 +
12710 return retval;
12711 }
12712
12713 @@ -230,6 +248,13 @@ static int write_ldt(void __user *ptr, u
12714 }
12715 }
12716
12717 +#ifdef CONFIG_PAX_SEGMEXEC
12718 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
12719 + error = -EINVAL;
12720 + goto out_unlock;
12721 + }
12722 +#endif
12723 +
12724 fill_ldt(&ldt, &ldt_info);
12725 if (oldmode)
12726 ldt.avl = 0;
12727 diff -urNp linux-2.6.36/arch/x86/kernel/machine_kexec_32.c linux-2.6.36/arch/x86/kernel/machine_kexec_32.c
12728 --- linux-2.6.36/arch/x86/kernel/machine_kexec_32.c 2010-10-20 16:30:22.000000000 -0400
12729 +++ linux-2.6.36/arch/x86/kernel/machine_kexec_32.c 2010-11-06 18:58:15.000000000 -0400
12730 @@ -27,7 +27,7 @@
12731 #include <asm/cacheflush.h>
12732 #include <asm/debugreg.h>
12733
12734 -static void set_idt(void *newidt, __u16 limit)
12735 +static void set_idt(struct desc_struct *newidt, __u16 limit)
12736 {
12737 struct desc_ptr curidt;
12738
12739 @@ -39,7 +39,7 @@ static void set_idt(void *newidt, __u16
12740 }
12741
12742
12743 -static void set_gdt(void *newgdt, __u16 limit)
12744 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
12745 {
12746 struct desc_ptr curgdt;
12747
12748 @@ -217,7 +217,7 @@ void machine_kexec(struct kimage *image)
12749 }
12750
12751 control_page = page_address(image->control_code_page);
12752 - memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
12753 + memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
12754
12755 relocate_kernel_ptr = control_page;
12756 page_list[PA_CONTROL_PAGE] = __pa(control_page);
12757 diff -urNp linux-2.6.36/arch/x86/kernel/microcode_amd.c linux-2.6.36/arch/x86/kernel/microcode_amd.c
12758 --- linux-2.6.36/arch/x86/kernel/microcode_amd.c 2010-10-20 16:30:22.000000000 -0400
12759 +++ linux-2.6.36/arch/x86/kernel/microcode_amd.c 2010-11-06 18:58:15.000000000 -0400
12760 @@ -331,7 +331,7 @@ static void microcode_fini_cpu_amd(int c
12761 uci->mc = NULL;
12762 }
12763
12764 -static struct microcode_ops microcode_amd_ops = {
12765 +static const struct microcode_ops microcode_amd_ops = {
12766 .request_microcode_user = request_microcode_user,
12767 .request_microcode_fw = request_microcode_fw,
12768 .collect_cpu_info = collect_cpu_info_amd,
12769 @@ -339,7 +339,7 @@ static struct microcode_ops microcode_am
12770 .microcode_fini_cpu = microcode_fini_cpu_amd,
12771 };
12772
12773 -struct microcode_ops * __init init_amd_microcode(void)
12774 +const struct microcode_ops * __init init_amd_microcode(void)
12775 {
12776 return &microcode_amd_ops;
12777 }
12778 diff -urNp linux-2.6.36/arch/x86/kernel/microcode_core.c linux-2.6.36/arch/x86/kernel/microcode_core.c
12779 --- linux-2.6.36/arch/x86/kernel/microcode_core.c 2010-10-20 16:30:22.000000000 -0400
12780 +++ linux-2.6.36/arch/x86/kernel/microcode_core.c 2010-11-06 18:58:15.000000000 -0400
12781 @@ -92,7 +92,7 @@ MODULE_LICENSE("GPL");
12782
12783 #define MICROCODE_VERSION "2.00"
12784
12785 -static struct microcode_ops *microcode_ops;
12786 +static const struct microcode_ops *microcode_ops;
12787
12788 /*
12789 * Synchronization.
12790 diff -urNp linux-2.6.36/arch/x86/kernel/microcode_intel.c linux-2.6.36/arch/x86/kernel/microcode_intel.c
12791 --- linux-2.6.36/arch/x86/kernel/microcode_intel.c 2010-10-20 16:30:22.000000000 -0400
12792 +++ linux-2.6.36/arch/x86/kernel/microcode_intel.c 2010-11-06 18:58:15.000000000 -0400
12793 @@ -446,13 +446,13 @@ static enum ucode_state request_microcod
12794
12795 static int get_ucode_user(void *to, const void *from, size_t n)
12796 {
12797 - return copy_from_user(to, from, n);
12798 + return copy_from_user(to, (__force const void __user *)from, n);
12799 }
12800
12801 static enum ucode_state
12802 request_microcode_user(int cpu, const void __user *buf, size_t size)
12803 {
12804 - return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
12805 + return generic_load_microcode(cpu, (__force void *)buf, size, &get_ucode_user);
12806 }
12807
12808 static void microcode_fini_cpu(int cpu)
12809 @@ -463,7 +463,7 @@ static void microcode_fini_cpu(int cpu)
12810 uci->mc = NULL;
12811 }
12812
12813 -static struct microcode_ops microcode_intel_ops = {
12814 +static const struct microcode_ops microcode_intel_ops = {
12815 .request_microcode_user = request_microcode_user,
12816 .request_microcode_fw = request_microcode_fw,
12817 .collect_cpu_info = collect_cpu_info,
12818 @@ -471,7 +471,7 @@ static struct microcode_ops microcode_in
12819 .microcode_fini_cpu = microcode_fini_cpu,
12820 };
12821
12822 -struct microcode_ops * __init init_intel_microcode(void)
12823 +const struct microcode_ops * __init init_intel_microcode(void)
12824 {
12825 return &microcode_intel_ops;
12826 }
12827 diff -urNp linux-2.6.36/arch/x86/kernel/module.c linux-2.6.36/arch/x86/kernel/module.c
12828 --- linux-2.6.36/arch/x86/kernel/module.c 2010-10-20 16:30:22.000000000 -0400
12829 +++ linux-2.6.36/arch/x86/kernel/module.c 2010-11-06 18:58:15.000000000 -0400
12830 @@ -35,7 +35,7 @@
12831 #define DEBUGP(fmt...)
12832 #endif
12833
12834 -void *module_alloc(unsigned long size)
12835 +static void *__module_alloc(unsigned long size, pgprot_t prot)
12836 {
12837 struct vm_struct *area;
12838
12839 @@ -49,8 +49,18 @@ void *module_alloc(unsigned long size)
12840 if (!area)
12841 return NULL;
12842
12843 - return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM,
12844 - PAGE_KERNEL_EXEC);
12845 + return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, prot);
12846 +}
12847 +
12848 +void *module_alloc(unsigned long size)
12849 +{
12850 +
12851 +#ifdef CONFIG_PAX_KERNEXEC
12852 + return __module_alloc(size, PAGE_KERNEL);
12853 +#else
12854 + return __module_alloc(size, PAGE_KERNEL_EXEC);
12855 +#endif
12856 +
12857 }
12858
12859 /* Free memory returned from module_alloc */
12860 @@ -59,6 +69,40 @@ void module_free(struct module *mod, voi
12861 vfree(module_region);
12862 }
12863
12864 +#ifdef CONFIG_PAX_KERNEXEC
12865 +#ifdef CONFIG_X86_32
12866 +void *module_alloc_exec(unsigned long size)
12867 +{
12868 + struct vm_struct *area;
12869 +
12870 + if (size == 0)
12871 + return NULL;
12872 +
12873 + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_EXEC_VADDR, (unsigned long)&MODULES_EXEC_END);
12874 + return area ? area->addr : NULL;
12875 +}
12876 +EXPORT_SYMBOL(module_alloc_exec);
12877 +
12878 +void module_free_exec(struct module *mod, void *module_region)
12879 +{
12880 + vunmap(module_region);
12881 +}
12882 +EXPORT_SYMBOL(module_free_exec);
12883 +#else
12884 +void module_free_exec(struct module *mod, void *module_region)
12885 +{
12886 + module_free(mod, module_region);
12887 +}
12888 +EXPORT_SYMBOL(module_free_exec);
12889 +
12890 +void *module_alloc_exec(unsigned long size)
12891 +{
12892 + return __module_alloc(size, PAGE_KERNEL_RX);
12893 +}
12894 +EXPORT_SYMBOL(module_alloc_exec);
12895 +#endif
12896 +#endif
12897 +
12898 /* We don't need anything special. */
12899 int module_frob_arch_sections(Elf_Ehdr *hdr,
12900 Elf_Shdr *sechdrs,
12901 @@ -78,14 +122,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
12902 unsigned int i;
12903 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
12904 Elf32_Sym *sym;
12905 - uint32_t *location;
12906 + uint32_t *plocation, location;
12907
12908 DEBUGP("Applying relocate section %u to %u\n", relsec,
12909 sechdrs[relsec].sh_info);
12910 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
12911 /* This is where to make the change */
12912 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
12913 - + rel[i].r_offset;
12914 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
12915 + location = (uint32_t)plocation;
12916 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
12917 + plocation = ktla_ktva((void *)plocation);
12918 /* This is the symbol it is referring to. Note that all
12919 undefined symbols have been resolved. */
12920 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
12921 @@ -94,11 +140,15 @@ int apply_relocate(Elf32_Shdr *sechdrs,
12922 switch (ELF32_R_TYPE(rel[i].r_info)) {
12923 case R_386_32:
12924 /* We add the value into the location given */
12925 - *location += sym->st_value;
12926 + pax_open_kernel();
12927 + *plocation += sym->st_value;
12928 + pax_close_kernel();
12929 break;
12930 case R_386_PC32:
12931 /* Add the value, subtract its postition */
12932 - *location += sym->st_value - (uint32_t)location;
12933 + pax_open_kernel();
12934 + *plocation += sym->st_value - location;
12935 + pax_close_kernel();
12936 break;
12937 default:
12938 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
12939 @@ -154,21 +204,30 @@ int apply_relocate_add(Elf64_Shdr *sechd
12940 case R_X86_64_NONE:
12941 break;
12942 case R_X86_64_64:
12943 + pax_open_kernel();
12944 *(u64 *)loc = val;
12945 + pax_close_kernel();
12946 break;
12947 case R_X86_64_32:
12948 + pax_open_kernel();
12949 *(u32 *)loc = val;
12950 + pax_close_kernel();
12951 if (val != *(u32 *)loc)
12952 goto overflow;
12953 break;
12954 case R_X86_64_32S:
12955 + pax_open_kernel();
12956 *(s32 *)loc = val;
12957 + pax_close_kernel();
12958 if ((s64)val != *(s32 *)loc)
12959 goto overflow;
12960 break;
12961 case R_X86_64_PC32:
12962 val -= (u64)loc;
12963 + pax_open_kernel();
12964 *(u32 *)loc = val;
12965 + pax_close_kernel();
12966 +
12967 #if 0
12968 if ((s64)val != *(s32 *)loc)
12969 goto overflow;
12970 diff -urNp linux-2.6.36/arch/x86/kernel/paravirt.c linux-2.6.36/arch/x86/kernel/paravirt.c
12971 --- linux-2.6.36/arch/x86/kernel/paravirt.c 2010-10-20 16:30:22.000000000 -0400
12972 +++ linux-2.6.36/arch/x86/kernel/paravirt.c 2010-11-06 18:58:15.000000000 -0400
12973 @@ -122,7 +122,7 @@ unsigned paravirt_patch_jmp(void *insnbu
12974 * corresponding structure. */
12975 static void *get_call_destination(u8 type)
12976 {
12977 - struct paravirt_patch_template tmpl = {
12978 + const struct paravirt_patch_template tmpl = {
12979 .pv_init_ops = pv_init_ops,
12980 .pv_time_ops = pv_time_ops,
12981 .pv_cpu_ops = pv_cpu_ops,
12982 @@ -145,14 +145,14 @@ unsigned paravirt_patch_default(u8 type,
12983 if (opfunc == NULL)
12984 /* If there's no function, patch it with a ud2a (BUG) */
12985 ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a));
12986 - else if (opfunc == _paravirt_nop)
12987 + else if (opfunc == (void *)_paravirt_nop)
12988 /* If the operation is a nop, then nop the callsite */
12989 ret = paravirt_patch_nop();
12990
12991 /* identity functions just return their single argument */
12992 - else if (opfunc == _paravirt_ident_32)
12993 + else if (opfunc == (void *)_paravirt_ident_32)
12994 ret = paravirt_patch_ident_32(insnbuf, len);
12995 - else if (opfunc == _paravirt_ident_64)
12996 + else if (opfunc == (void *)_paravirt_ident_64)
12997 ret = paravirt_patch_ident_64(insnbuf, len);
12998
12999 else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
13000 @@ -178,7 +178,7 @@ unsigned paravirt_patch_insns(void *insn
13001 if (insn_len > len || start == NULL)
13002 insn_len = len;
13003 else
13004 - memcpy(insnbuf, start, insn_len);
13005 + memcpy(insnbuf, ktla_ktva(start), insn_len);
13006
13007 return insn_len;
13008 }
13009 @@ -294,22 +294,22 @@ void arch_flush_lazy_mmu_mode(void)
13010 preempt_enable();
13011 }
13012
13013 -struct pv_info pv_info = {
13014 +struct pv_info pv_info __read_only = {
13015 .name = "bare hardware",
13016 .paravirt_enabled = 0,
13017 .kernel_rpl = 0,
13018 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
13019 };
13020
13021 -struct pv_init_ops pv_init_ops = {
13022 +struct pv_init_ops pv_init_ops __read_only = {
13023 .patch = native_patch,
13024 };
13025
13026 -struct pv_time_ops pv_time_ops = {
13027 +struct pv_time_ops pv_time_ops __read_only = {
13028 .sched_clock = native_sched_clock,
13029 };
13030
13031 -struct pv_irq_ops pv_irq_ops = {
13032 +struct pv_irq_ops pv_irq_ops __read_only = {
13033 .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
13034 .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
13035 .irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable),
13036 @@ -321,7 +321,7 @@ struct pv_irq_ops pv_irq_ops = {
13037 #endif
13038 };
13039
13040 -struct pv_cpu_ops pv_cpu_ops = {
13041 +struct pv_cpu_ops pv_cpu_ops __read_only = {
13042 .cpuid = native_cpuid,
13043 .get_debugreg = native_get_debugreg,
13044 .set_debugreg = native_set_debugreg,
13045 @@ -382,7 +382,7 @@ struct pv_cpu_ops pv_cpu_ops = {
13046 .end_context_switch = paravirt_nop,
13047 };
13048
13049 -struct pv_apic_ops pv_apic_ops = {
13050 +struct pv_apic_ops pv_apic_ops __read_only = {
13051 #ifdef CONFIG_X86_LOCAL_APIC
13052 .startup_ipi_hook = paravirt_nop,
13053 #endif
13054 @@ -396,7 +396,7 @@ struct pv_apic_ops pv_apic_ops = {
13055 #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64)
13056 #endif
13057
13058 -struct pv_mmu_ops pv_mmu_ops = {
13059 +struct pv_mmu_ops pv_mmu_ops __read_only = {
13060
13061 .read_cr2 = native_read_cr2,
13062 .write_cr2 = native_write_cr2,
13063 @@ -463,6 +463,12 @@ struct pv_mmu_ops pv_mmu_ops = {
13064 },
13065
13066 .set_fixmap = native_set_fixmap,
13067 +
13068 +#ifdef CONFIG_PAX_KERNEXEC
13069 + .pax_open_kernel = native_pax_open_kernel,
13070 + .pax_close_kernel = native_pax_close_kernel,
13071 +#endif
13072 +
13073 };
13074
13075 EXPORT_SYMBOL_GPL(pv_time_ops);
13076 diff -urNp linux-2.6.36/arch/x86/kernel/paravirt-spinlocks.c linux-2.6.36/arch/x86/kernel/paravirt-spinlocks.c
13077 --- linux-2.6.36/arch/x86/kernel/paravirt-spinlocks.c 2010-10-20 16:30:22.000000000 -0400
13078 +++ linux-2.6.36/arch/x86/kernel/paravirt-spinlocks.c 2010-11-06 18:58:15.000000000 -0400
13079 @@ -13,7 +13,7 @@ default_spin_lock_flags(arch_spinlock_t
13080 arch_spin_lock(lock);
13081 }
13082
13083 -struct pv_lock_ops pv_lock_ops = {
13084 +struct pv_lock_ops pv_lock_ops __read_only = {
13085 #ifdef CONFIG_SMP
13086 .spin_is_locked = __ticket_spin_is_locked,
13087 .spin_is_contended = __ticket_spin_is_contended,
13088 diff -urNp linux-2.6.36/arch/x86/kernel/pci-calgary_64.c linux-2.6.36/arch/x86/kernel/pci-calgary_64.c
13089 --- linux-2.6.36/arch/x86/kernel/pci-calgary_64.c 2010-10-20 16:30:22.000000000 -0400
13090 +++ linux-2.6.36/arch/x86/kernel/pci-calgary_64.c 2010-11-06 18:58:15.000000000 -0400
13091 @@ -475,7 +475,7 @@ static void calgary_free_coherent(struct
13092 free_pages((unsigned long)vaddr, get_order(size));
13093 }
13094
13095 -static struct dma_map_ops calgary_dma_ops = {
13096 +static const struct dma_map_ops calgary_dma_ops = {
13097 .alloc_coherent = calgary_alloc_coherent,
13098 .free_coherent = calgary_free_coherent,
13099 .map_sg = calgary_map_sg,
13100 diff -urNp linux-2.6.36/arch/x86/kernel/pci-dma.c linux-2.6.36/arch/x86/kernel/pci-dma.c
13101 --- linux-2.6.36/arch/x86/kernel/pci-dma.c 2010-10-20 16:30:22.000000000 -0400
13102 +++ linux-2.6.36/arch/x86/kernel/pci-dma.c 2010-11-06 18:58:15.000000000 -0400
13103 @@ -17,7 +17,7 @@
13104
13105 static int forbid_dac __read_mostly;
13106
13107 -struct dma_map_ops *dma_ops = &nommu_dma_ops;
13108 +const struct dma_map_ops *dma_ops = &nommu_dma_ops;
13109 EXPORT_SYMBOL(dma_ops);
13110
13111 static int iommu_sac_force __read_mostly;
13112 @@ -251,7 +251,7 @@ early_param("iommu", iommu_setup);
13113
13114 int dma_supported(struct device *dev, u64 mask)
13115 {
13116 - struct dma_map_ops *ops = get_dma_ops(dev);
13117 + const struct dma_map_ops *ops = get_dma_ops(dev);
13118
13119 #ifdef CONFIG_PCI
13120 if (mask > 0xffffffff && forbid_dac > 0) {
13121 diff -urNp linux-2.6.36/arch/x86/kernel/pci-gart_64.c linux-2.6.36/arch/x86/kernel/pci-gart_64.c
13122 --- linux-2.6.36/arch/x86/kernel/pci-gart_64.c 2010-10-20 16:30:22.000000000 -0400
13123 +++ linux-2.6.36/arch/x86/kernel/pci-gart_64.c 2010-11-06 18:58:15.000000000 -0400
13124 @@ -699,7 +699,7 @@ static __init int init_k8_gatt(struct ag
13125 return -1;
13126 }
13127
13128 -static struct dma_map_ops gart_dma_ops = {
13129 +static const struct dma_map_ops gart_dma_ops = {
13130 .map_sg = gart_map_sg,
13131 .unmap_sg = gart_unmap_sg,
13132 .map_page = gart_map_page,
13133 diff -urNp linux-2.6.36/arch/x86/kernel/pci-nommu.c linux-2.6.36/arch/x86/kernel/pci-nommu.c
13134 --- linux-2.6.36/arch/x86/kernel/pci-nommu.c 2010-10-20 16:30:22.000000000 -0400
13135 +++ linux-2.6.36/arch/x86/kernel/pci-nommu.c 2010-11-06 18:58:15.000000000 -0400
13136 @@ -95,7 +95,7 @@ static void nommu_sync_sg_for_device(str
13137 flush_write_buffers();
13138 }
13139
13140 -struct dma_map_ops nommu_dma_ops = {
13141 +const struct dma_map_ops nommu_dma_ops = {
13142 .alloc_coherent = dma_generic_alloc_coherent,
13143 .free_coherent = nommu_free_coherent,
13144 .map_sg = nommu_map_sg,
13145 diff -urNp linux-2.6.36/arch/x86/kernel/pci-swiotlb.c linux-2.6.36/arch/x86/kernel/pci-swiotlb.c
13146 --- linux-2.6.36/arch/x86/kernel/pci-swiotlb.c 2010-10-20 16:30:22.000000000 -0400
13147 +++ linux-2.6.36/arch/x86/kernel/pci-swiotlb.c 2010-11-06 18:58:15.000000000 -0400
13148 @@ -25,7 +25,7 @@ static void *x86_swiotlb_alloc_coherent(
13149 return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
13150 }
13151
13152 -static struct dma_map_ops swiotlb_dma_ops = {
13153 +static const struct dma_map_ops swiotlb_dma_ops = {
13154 .mapping_error = swiotlb_dma_mapping_error,
13155 .alloc_coherent = x86_swiotlb_alloc_coherent,
13156 .free_coherent = swiotlb_free_coherent,
13157 diff -urNp linux-2.6.36/arch/x86/kernel/process_32.c linux-2.6.36/arch/x86/kernel/process_32.c
13158 --- linux-2.6.36/arch/x86/kernel/process_32.c 2010-10-20 16:30:22.000000000 -0400
13159 +++ linux-2.6.36/arch/x86/kernel/process_32.c 2010-11-06 18:58:15.000000000 -0400
13160 @@ -67,6 +67,7 @@ asmlinkage void ret_from_fork(void) __as
13161 unsigned long thread_saved_pc(struct task_struct *tsk)
13162 {
13163 return ((unsigned long *)tsk->thread.sp)[3];
13164 +//XXX return tsk->thread.eip;
13165 }
13166
13167 #ifndef CONFIG_SMP
13168 @@ -130,7 +131,7 @@ void __show_regs(struct pt_regs *regs, i
13169 unsigned long sp;
13170 unsigned short ss, gs;
13171
13172 - if (user_mode_vm(regs)) {
13173 + if (user_mode(regs)) {
13174 sp = regs->sp;
13175 ss = regs->ss & 0xffff;
13176 gs = get_user_gs(regs);
13177 @@ -200,7 +201,7 @@ int copy_thread(unsigned long clone_flag
13178 struct task_struct *tsk;
13179 int err;
13180
13181 - childregs = task_pt_regs(p);
13182 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
13183 *childregs = *regs;
13184 childregs->ax = 0;
13185 childregs->sp = sp;
13186 @@ -234,6 +235,7 @@ int copy_thread(unsigned long clone_flag
13187 * Set a new TLS for the child thread?
13188 */
13189 if (clone_flags & CLONE_SETTLS)
13190 +//XXX needs set_fs()?
13191 err = do_set_thread_area(p, -1,
13192 (struct user_desc __user *)childregs->si, 0);
13193
13194 @@ -297,7 +299,7 @@ __switch_to(struct task_struct *prev_p,
13195 struct thread_struct *prev = &prev_p->thread,
13196 *next = &next_p->thread;
13197 int cpu = smp_processor_id();
13198 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
13199 + struct tss_struct *tss = init_tss + cpu;
13200 bool preload_fpu;
13201
13202 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
13203 @@ -332,6 +334,11 @@ __switch_to(struct task_struct *prev_p,
13204 */
13205 lazy_save_gs(prev->gs);
13206
13207 +#ifdef CONFIG_PAX_MEMORY_UDEREF
13208 + if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
13209 + __set_fs(task_thread_info(next_p)->addr_limit, cpu);
13210 +#endif
13211 +
13212 /*
13213 * Load the per-thread Thread-Local Storage descriptor.
13214 */
13215 @@ -408,3 +415,27 @@ unsigned long get_wchan(struct task_stru
13216 return 0;
13217 }
13218
13219 +#ifdef CONFIG_PAX_RANDKSTACK
13220 +asmlinkage void pax_randomize_kstack(void)
13221 +{
13222 + struct thread_struct *thread = &current->thread;
13223 + unsigned long time;
13224 +
13225 + if (!randomize_va_space)
13226 + return;
13227 +
13228 + rdtscl(time);
13229 +
13230 + /* P4 seems to return a 0 LSB, ignore it */
13231 +#ifdef CONFIG_MPENTIUM4
13232 + time &= 0x1EUL;
13233 + time <<= 2;
13234 +#else
13235 + time &= 0xFUL;
13236 + time <<= 3;
13237 +#endif
13238 +
13239 + thread->sp0 ^= time;
13240 + load_sp0(init_tss + smp_processor_id(), thread);
13241 +}
13242 +#endif
13243 diff -urNp linux-2.6.36/arch/x86/kernel/process_64.c linux-2.6.36/arch/x86/kernel/process_64.c
13244 --- linux-2.6.36/arch/x86/kernel/process_64.c 2010-10-20 16:30:22.000000000 -0400
13245 +++ linux-2.6.36/arch/x86/kernel/process_64.c 2010-11-06 18:58:15.000000000 -0400
13246 @@ -89,7 +89,7 @@ static void __exit_idle(void)
13247 void exit_idle(void)
13248 {
13249 /* idle loop has pid 0 */
13250 - if (current->pid)
13251 + if (task_pid_nr(current))
13252 return;
13253 __exit_idle();
13254 }
13255 @@ -380,7 +380,7 @@ __switch_to(struct task_struct *prev_p,
13256 struct thread_struct *prev = &prev_p->thread;
13257 struct thread_struct *next = &next_p->thread;
13258 int cpu = smp_processor_id();
13259 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
13260 + struct tss_struct *tss = init_tss + cpu;
13261 unsigned fsindex, gsindex;
13262 bool preload_fpu;
13263
13264 @@ -533,12 +533,11 @@ unsigned long get_wchan(struct task_stru
13265 if (!p || p == current || p->state == TASK_RUNNING)
13266 return 0;
13267 stack = (unsigned long)task_stack_page(p);
13268 - if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
13269 + if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
13270 return 0;
13271 fp = *(u64 *)(p->thread.sp);
13272 do {
13273 - if (fp < (unsigned long)stack ||
13274 - fp >= (unsigned long)stack+THREAD_SIZE)
13275 + if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
13276 return 0;
13277 ip = *(u64 *)(fp+8);
13278 if (!in_sched_functions(ip))
13279 diff -urNp linux-2.6.36/arch/x86/kernel/process.c linux-2.6.36/arch/x86/kernel/process.c
13280 --- linux-2.6.36/arch/x86/kernel/process.c 2010-10-20 16:30:22.000000000 -0400
13281 +++ linux-2.6.36/arch/x86/kernel/process.c 2010-11-06 18:58:15.000000000 -0400
13282 @@ -74,7 +74,7 @@ void exit_thread(void)
13283 unsigned long *bp = t->io_bitmap_ptr;
13284
13285 if (bp) {
13286 - struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
13287 + struct tss_struct *tss = init_tss + get_cpu();
13288
13289 t->io_bitmap_ptr = NULL;
13290 clear_thread_flag(TIF_IO_BITMAP);
13291 @@ -108,7 +108,7 @@ void show_regs_common(void)
13292
13293 printk(KERN_CONT "\n");
13294 printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n",
13295 - current->pid, current->comm, print_tainted(),
13296 + task_pid_nr(current), current->comm, print_tainted(),
13297 init_utsname()->release,
13298 (int)strcspn(init_utsname()->version, " "),
13299 init_utsname()->version, board, product);
13300 @@ -118,6 +118,9 @@ void flush_thread(void)
13301 {
13302 struct task_struct *tsk = current;
13303
13304 +#if defined(CONFIG_X86_32) && !defined(CONFIG_CC_STACKPROTECTOR)
13305 + loadsegment(gs, 0);
13306 +#endif
13307 flush_ptrace_hw_breakpoint(tsk);
13308 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
13309 /*
13310 @@ -280,8 +283,8 @@ int kernel_thread(int (*fn)(void *), voi
13311 regs.di = (unsigned long) arg;
13312
13313 #ifdef CONFIG_X86_32
13314 - regs.ds = __USER_DS;
13315 - regs.es = __USER_DS;
13316 + regs.ds = __KERNEL_DS;
13317 + regs.es = __KERNEL_DS;
13318 regs.fs = __KERNEL_PERCPU;
13319 regs.gs = __KERNEL_STACK_CANARY;
13320 #else
13321 @@ -658,17 +661,3 @@ static int __init idle_setup(char *str)
13322 return 0;
13323 }
13324 early_param("idle", idle_setup);
13325 -
13326 -unsigned long arch_align_stack(unsigned long sp)
13327 -{
13328 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
13329 - sp -= get_random_int() % 8192;
13330 - return sp & ~0xf;
13331 -}
13332 -
13333 -unsigned long arch_randomize_brk(struct mm_struct *mm)
13334 -{
13335 - unsigned long range_end = mm->brk + 0x02000000;
13336 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
13337 -}
13338 -
13339 diff -urNp linux-2.6.36/arch/x86/kernel/ptrace.c linux-2.6.36/arch/x86/kernel/ptrace.c
13340 --- linux-2.6.36/arch/x86/kernel/ptrace.c 2010-10-20 16:30:22.000000000 -0400
13341 +++ linux-2.6.36/arch/x86/kernel/ptrace.c 2010-11-06 18:58:15.000000000 -0400
13342 @@ -804,7 +804,7 @@ static const struct user_regset_view use
13343 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
13344 {
13345 int ret;
13346 - unsigned long __user *datap = (unsigned long __user *)data;
13347 + unsigned long __user *datap = (__force unsigned long __user *)data;
13348
13349 switch (request) {
13350 /* read the word at location addr in the USER area. */
13351 @@ -891,14 +891,14 @@ long arch_ptrace(struct task_struct *chi
13352 if (addr < 0)
13353 return -EIO;
13354 ret = do_get_thread_area(child, addr,
13355 - (struct user_desc __user *) data);
13356 + (__force struct user_desc __user *) data);
13357 break;
13358
13359 case PTRACE_SET_THREAD_AREA:
13360 if (addr < 0)
13361 return -EIO;
13362 ret = do_set_thread_area(child, addr,
13363 - (struct user_desc __user *) data, 0);
13364 + (__force struct user_desc __user *) data, 0);
13365 break;
13366 #endif
13367
13368 @@ -1315,7 +1315,7 @@ static void fill_sigtrap_info(struct tas
13369 memset(info, 0, sizeof(*info));
13370 info->si_signo = SIGTRAP;
13371 info->si_code = si_code;
13372 - info->si_addr = user_mode_vm(regs) ? (void __user *)regs->ip : NULL;
13373 + info->si_addr = user_mode(regs) ? (__force void __user *)regs->ip : NULL;
13374 }
13375
13376 void user_single_step_siginfo(struct task_struct *tsk,
13377 diff -urNp linux-2.6.36/arch/x86/kernel/reboot.c linux-2.6.36/arch/x86/kernel/reboot.c
13378 --- linux-2.6.36/arch/x86/kernel/reboot.c 2010-10-20 16:30:22.000000000 -0400
13379 +++ linux-2.6.36/arch/x86/kernel/reboot.c 2010-11-06 18:58:15.000000000 -0400
13380 @@ -33,7 +33,7 @@ void (*pm_power_off)(void);
13381 EXPORT_SYMBOL(pm_power_off);
13382
13383 static const struct desc_ptr no_idt = {};
13384 -static int reboot_mode;
13385 +static unsigned short reboot_mode;
13386 enum reboot_type reboot_type = BOOT_KBD;
13387 int reboot_force;
13388
13389 @@ -284,7 +284,7 @@ static struct dmi_system_id __initdata r
13390 DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
13391 },
13392 },
13393 - { }
13394 + { NULL, NULL, {{0, {0}}}, NULL}
13395 };
13396
13397 static int __init reboot_init(void)
13398 @@ -300,12 +300,12 @@ core_initcall(reboot_init);
13399 controller to pulse the CPU reset line, which is more thorough, but
13400 doesn't work with at least one type of 486 motherboard. It is easy
13401 to stop this code working; hence the copious comments. */
13402 -static const unsigned long long
13403 -real_mode_gdt_entries [3] =
13404 +static struct desc_struct
13405 +real_mode_gdt_entries [3] __read_only =
13406 {
13407 - 0x0000000000000000ULL, /* Null descriptor */
13408 - 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
13409 - 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
13410 + GDT_ENTRY_INIT(0, 0, 0), /* Null descriptor */
13411 + GDT_ENTRY_INIT(0x9b, 0, 0xffff), /* 16-bit real-mode 64k code at 0x00000000 */
13412 + GDT_ENTRY_INIT(0x93, 0x100, 0xffff) /* 16-bit real-mode 64k data at 0x00000100 */
13413 };
13414
13415 static const struct desc_ptr
13416 @@ -354,7 +354,7 @@ static const unsigned char jump_to_bios
13417 * specified by the code and length parameters.
13418 * We assume that length will aways be less that 100!
13419 */
13420 -void machine_real_restart(const unsigned char *code, int length)
13421 +void machine_real_restart(const unsigned char *code, unsigned int length)
13422 {
13423 local_irq_disable();
13424
13425 @@ -374,8 +374,8 @@ void machine_real_restart(const unsigned
13426 /* Remap the kernel at virtual address zero, as well as offset zero
13427 from the kernel segment. This assumes the kernel segment starts at
13428 virtual address PAGE_OFFSET. */
13429 - memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
13430 - sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
13431 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
13432 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
13433
13434 /*
13435 * Use `swapper_pg_dir' as our page directory.
13436 @@ -387,16 +387,15 @@ void machine_real_restart(const unsigned
13437 boot)". This seems like a fairly standard thing that gets set by
13438 REBOOT.COM programs, and the previous reset routine did this
13439 too. */
13440 - *((unsigned short *)0x472) = reboot_mode;
13441 + *(unsigned short *)(__va(0x472)) = reboot_mode;
13442
13443 /* For the switch to real mode, copy some code to low memory. It has
13444 to be in the first 64k because it is running in 16-bit mode, and it
13445 has to have the same physical and virtual address, because it turns
13446 off paging. Copy it near the end of the first page, out of the way
13447 of BIOS variables. */
13448 - memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
13449 - real_mode_switch, sizeof (real_mode_switch));
13450 - memcpy((void *)(0x1000 - 100), code, length);
13451 + memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
13452 + memcpy(__va(0x1000 - 100), code, length);
13453
13454 /* Set up the IDT for real mode. */
13455 load_idt(&real_mode_idt);
13456 diff -urNp linux-2.6.36/arch/x86/kernel/setup.c linux-2.6.36/arch/x86/kernel/setup.c
13457 --- linux-2.6.36/arch/x86/kernel/setup.c 2010-10-20 16:30:22.000000000 -0400
13458 +++ linux-2.6.36/arch/x86/kernel/setup.c 2010-11-06 18:58:15.000000000 -0400
13459 @@ -705,7 +705,7 @@ static void __init trim_bios_range(void)
13460 * area (640->1Mb) as ram even though it is not.
13461 * take them out.
13462 */
13463 - e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1);
13464 + e820_remove_range(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_RAM, 1);
13465 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
13466 }
13467
13468 @@ -797,14 +797,14 @@ void __init setup_arch(char **cmdline_p)
13469
13470 if (!boot_params.hdr.root_flags)
13471 root_mountflags &= ~MS_RDONLY;
13472 - init_mm.start_code = (unsigned long) _text;
13473 - init_mm.end_code = (unsigned long) _etext;
13474 + init_mm.start_code = ktla_ktva((unsigned long) _text);
13475 + init_mm.end_code = ktla_ktva((unsigned long) _etext);
13476 init_mm.end_data = (unsigned long) _edata;
13477 init_mm.brk = _brk_end;
13478
13479 - code_resource.start = virt_to_phys(_text);
13480 - code_resource.end = virt_to_phys(_etext)-1;
13481 - data_resource.start = virt_to_phys(_etext);
13482 + code_resource.start = virt_to_phys(ktla_ktva(_text));
13483 + code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
13484 + data_resource.start = virt_to_phys(_sdata);
13485 data_resource.end = virt_to_phys(_edata)-1;
13486 bss_resource.start = virt_to_phys(&__bss_start);
13487 bss_resource.end = virt_to_phys(&__bss_stop)-1;
13488 diff -urNp linux-2.6.36/arch/x86/kernel/setup_percpu.c linux-2.6.36/arch/x86/kernel/setup_percpu.c
13489 --- linux-2.6.36/arch/x86/kernel/setup_percpu.c 2010-10-20 16:30:22.000000000 -0400
13490 +++ linux-2.6.36/arch/x86/kernel/setup_percpu.c 2010-11-06 18:58:15.000000000 -0400
13491 @@ -21,19 +21,17 @@
13492 #include <asm/cpu.h>
13493 #include <asm/stackprotector.h>
13494
13495 -DEFINE_PER_CPU(int, cpu_number);
13496 +#ifdef CONFIG_SMP
13497 +DEFINE_PER_CPU(unsigned int, cpu_number);
13498 EXPORT_PER_CPU_SYMBOL(cpu_number);
13499 +#endif
13500
13501 -#ifdef CONFIG_X86_64
13502 #define BOOT_PERCPU_OFFSET ((unsigned long)__per_cpu_load)
13503 -#else
13504 -#define BOOT_PERCPU_OFFSET 0
13505 -#endif
13506
13507 DEFINE_PER_CPU(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;
13508 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
13509
13510 -unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
13511 +unsigned long __per_cpu_offset[NR_CPUS] __read_only = {
13512 [0 ... NR_CPUS-1] = BOOT_PERCPU_OFFSET,
13513 };
13514 EXPORT_SYMBOL(__per_cpu_offset);
13515 @@ -161,10 +159,10 @@ static inline void setup_percpu_segment(
13516 {
13517 #ifdef CONFIG_X86_32
13518 struct desc_struct gdt;
13519 + unsigned long base = per_cpu_offset(cpu);
13520
13521 - pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
13522 - 0x2 | DESCTYPE_S, 0x8);
13523 - gdt.s = 1;
13524 + pack_descriptor(&gdt, base, (VMALLOC_END - base - 1) >> PAGE_SHIFT,
13525 + 0x83 | DESCTYPE_S, 0xC);
13526 write_gdt_entry(get_cpu_gdt_table(cpu),
13527 GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
13528 #endif
13529 @@ -213,6 +211,11 @@ void __init setup_per_cpu_areas(void)
13530 /* alrighty, percpu areas up and running */
13531 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
13532 for_each_possible_cpu(cpu) {
13533 +#ifdef CONFIG_CC_STACKPROTECTOR
13534 +#ifdef CONFIG_x86_32
13535 + unsigned long canary = per_cpu(stack_canary, cpu);
13536 +#endif
13537 +#endif
13538 per_cpu_offset(cpu) = delta + pcpu_unit_offsets[cpu];
13539 per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
13540 per_cpu(cpu_number, cpu) = cpu;
13541 @@ -249,6 +252,12 @@ void __init setup_per_cpu_areas(void)
13542 set_cpu_numa_node(cpu, early_cpu_to_node(cpu));
13543 #endif
13544 #endif
13545 +#ifdef CONFIG_CC_STACKPROTECTOR
13546 +#ifdef CONFIG_x86_32
13547 + if (cpu == boot_cpu_id)
13548 + per_cpu(stack_canary, cpu) = canary;
13549 +#endif
13550 +#endif
13551 /*
13552 * Up to this point, the boot CPU has been using .init.data
13553 * area. Reload any changed state for the boot CPU.
13554 diff -urNp linux-2.6.36/arch/x86/kernel/signal.c linux-2.6.36/arch/x86/kernel/signal.c
13555 --- linux-2.6.36/arch/x86/kernel/signal.c 2010-10-20 16:30:22.000000000 -0400
13556 +++ linux-2.6.36/arch/x86/kernel/signal.c 2010-11-06 18:58:15.000000000 -0400
13557 @@ -198,7 +198,7 @@ static unsigned long align_sigframe(unsi
13558 * Align the stack pointer according to the i386 ABI,
13559 * i.e. so that on function entry ((sp + 4) & 15) == 0.
13560 */
13561 - sp = ((sp + 4) & -16ul) - 4;
13562 + sp = ((sp - 12) & -16ul) - 4;
13563 #else /* !CONFIG_X86_32 */
13564 sp = round_down(sp, 16) - 8;
13565 #endif
13566 @@ -249,11 +249,11 @@ get_sigframe(struct k_sigaction *ka, str
13567 * Return an always-bogus address instead so we will die with SIGSEGV.
13568 */
13569 if (onsigstack && !likely(on_sig_stack(sp)))
13570 - return (void __user *)-1L;
13571 + return (__force void __user *)-1L;
13572
13573 /* save i387 state */
13574 if (used_math() && save_i387_xstate(*fpstate) < 0)
13575 - return (void __user *)-1L;
13576 + return (__force void __user *)-1L;
13577
13578 return (void __user *)sp;
13579 }
13580 @@ -308,9 +308,9 @@ __setup_frame(int sig, struct k_sigactio
13581 }
13582
13583 if (current->mm->context.vdso)
13584 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
13585 + restorer = (__force void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
13586 else
13587 - restorer = &frame->retcode;
13588 + restorer = (void __user *)&frame->retcode;
13589 if (ka->sa.sa_flags & SA_RESTORER)
13590 restorer = ka->sa.sa_restorer;
13591
13592 @@ -324,7 +324,7 @@ __setup_frame(int sig, struct k_sigactio
13593 * reasons and because gdb uses it as a signature to notice
13594 * signal handler stack frames.
13595 */
13596 - err |= __put_user(*((u64 *)&retcode), (u64 *)frame->retcode);
13597 + err |= __put_user(*((u64 *)&retcode), (u64 __user *)frame->retcode);
13598
13599 if (err)
13600 return -EFAULT;
13601 @@ -378,7 +378,10 @@ static int __setup_rt_frame(int sig, str
13602 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
13603
13604 /* Set up to return from userspace. */
13605 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
13606 + if (current->mm->context.vdso)
13607 + restorer = (__force void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
13608 + else
13609 + restorer = (void __user *)&frame->retcode;
13610 if (ka->sa.sa_flags & SA_RESTORER)
13611 restorer = ka->sa.sa_restorer;
13612 put_user_ex(restorer, &frame->pretcode);
13613 @@ -390,7 +393,7 @@ static int __setup_rt_frame(int sig, str
13614 * reasons and because gdb uses it as a signature to notice
13615 * signal handler stack frames.
13616 */
13617 - put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
13618 + put_user_ex(*((u64 *)&rt_retcode), (u64 __user *)frame->retcode);
13619 } put_user_catch(err);
13620
13621 if (err)
13622 @@ -780,7 +783,7 @@ static void do_signal(struct pt_regs *re
13623 * X86_32: vm86 regs switched out by assembly code before reaching
13624 * here, so testing against kernel CS suffices.
13625 */
13626 - if (!user_mode(regs))
13627 + if (!user_mode_novm(regs))
13628 return;
13629
13630 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
13631 diff -urNp linux-2.6.36/arch/x86/kernel/smpboot.c linux-2.6.36/arch/x86/kernel/smpboot.c
13632 --- linux-2.6.36/arch/x86/kernel/smpboot.c 2010-10-20 16:30:22.000000000 -0400
13633 +++ linux-2.6.36/arch/x86/kernel/smpboot.c 2010-11-06 18:58:15.000000000 -0400
13634 @@ -782,7 +782,11 @@ do_rest:
13635 (unsigned long)task_stack_page(c_idle.idle) -
13636 KERNEL_STACK_OFFSET + THREAD_SIZE;
13637 #endif
13638 +
13639 + pax_open_kernel();
13640 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
13641 + pax_close_kernel();
13642 +
13643 initial_code = (unsigned long)start_secondary;
13644 stack_start.sp = (void *) c_idle.idle->thread.sp;
13645
13646 @@ -922,6 +926,12 @@ int __cpuinit native_cpu_up(unsigned int
13647
13648 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
13649
13650 +#ifdef CONFIG_PAX_PER_CPU_PGD
13651 + clone_pgd_range(get_cpu_pgd(cpu) + KERNEL_PGD_BOUNDARY,
13652 + swapper_pg_dir + KERNEL_PGD_BOUNDARY,
13653 + KERNEL_PGD_PTRS);
13654 +#endif
13655 +
13656 err = do_boot_cpu(apicid, cpu);
13657
13658 if (err) {
13659 diff -urNp linux-2.6.36/arch/x86/kernel/step.c linux-2.6.36/arch/x86/kernel/step.c
13660 --- linux-2.6.36/arch/x86/kernel/step.c 2010-10-20 16:30:22.000000000 -0400
13661 +++ linux-2.6.36/arch/x86/kernel/step.c 2010-11-06 18:58:15.000000000 -0400
13662 @@ -27,10 +27,10 @@ unsigned long convert_ip_to_linear(struc
13663 struct desc_struct *desc;
13664 unsigned long base;
13665
13666 - seg &= ~7UL;
13667 + seg >>= 3;
13668
13669 mutex_lock(&child->mm->context.lock);
13670 - if (unlikely((seg >> 3) >= child->mm->context.size))
13671 + if (unlikely(seg >= child->mm->context.size))
13672 addr = -1L; /* bogus selector, access would fault */
13673 else {
13674 desc = child->mm->context.ldt + seg;
13675 @@ -53,6 +53,9 @@ static int is_setting_trap_flag(struct t
13676 unsigned char opcode[15];
13677 unsigned long addr = convert_ip_to_linear(child, regs);
13678
13679 + if (addr == -EINVAL)
13680 + return 0;
13681 +
13682 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
13683 for (i = 0; i < copied; i++) {
13684 switch (opcode[i]) {
13685 @@ -74,7 +77,7 @@ static int is_setting_trap_flag(struct t
13686
13687 #ifdef CONFIG_X86_64
13688 case 0x40 ... 0x4f:
13689 - if (regs->cs != __USER_CS)
13690 + if ((regs->cs & 0xffff) != __USER_CS)
13691 /* 32-bit mode: register increment */
13692 return 0;
13693 /* 64-bit mode: REX prefix */
13694 diff -urNp linux-2.6.36/arch/x86/kernel/syscall_table_32.S linux-2.6.36/arch/x86/kernel/syscall_table_32.S
13695 --- linux-2.6.36/arch/x86/kernel/syscall_table_32.S 2010-10-20 16:30:22.000000000 -0400
13696 +++ linux-2.6.36/arch/x86/kernel/syscall_table_32.S 2010-11-06 18:58:15.000000000 -0400
13697 @@ -1,3 +1,4 @@
13698 +.section .rodata,"a",@progbits
13699 ENTRY(sys_call_table)
13700 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
13701 .long sys_exit
13702 diff -urNp linux-2.6.36/arch/x86/kernel/sys_i386_32.c linux-2.6.36/arch/x86/kernel/sys_i386_32.c
13703 --- linux-2.6.36/arch/x86/kernel/sys_i386_32.c 2010-10-20 16:30:22.000000000 -0400
13704 +++ linux-2.6.36/arch/x86/kernel/sys_i386_32.c 2010-11-06 18:58:15.000000000 -0400
13705 @@ -24,6 +24,228 @@
13706
13707 #include <asm/syscalls.h>
13708
13709 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
13710 +{
13711 + unsigned long pax_task_size = TASK_SIZE;
13712 +
13713 +#ifdef CONFIG_PAX_SEGMEXEC
13714 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
13715 + pax_task_size = SEGMEXEC_TASK_SIZE;
13716 +#endif
13717 +
13718 + if (len > pax_task_size || addr > pax_task_size - len)
13719 + return -EINVAL;
13720 +
13721 + return 0;
13722 +}
13723 +
13724 +unsigned long
13725 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
13726 + unsigned long len, unsigned long pgoff, unsigned long flags)
13727 +{
13728 + struct mm_struct *mm = current->mm;
13729 + struct vm_area_struct *vma;
13730 + unsigned long start_addr, pax_task_size = TASK_SIZE;
13731 +
13732 +#ifdef CONFIG_PAX_SEGMEXEC
13733 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
13734 + pax_task_size = SEGMEXEC_TASK_SIZE;
13735 +#endif
13736 +
13737 + pax_task_size -= PAGE_SIZE;
13738 +
13739 + if (len > pax_task_size)
13740 + return -ENOMEM;
13741 +
13742 + if (flags & MAP_FIXED)
13743 + return addr;
13744 +
13745 +#ifdef CONFIG_PAX_RANDMMAP
13746 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
13747 +#endif
13748 +
13749 + if (addr) {
13750 + addr = PAGE_ALIGN(addr);
13751 + if (pax_task_size - len >= addr) {
13752 + vma = find_vma(mm, addr);
13753 + if (check_heap_stack_gap(vma, addr, len))
13754 + return addr;
13755 + }
13756 + }
13757 + if (len > mm->cached_hole_size) {
13758 + start_addr = addr = mm->free_area_cache;
13759 + } else {
13760 + start_addr = addr = mm->mmap_base;
13761 + mm->cached_hole_size = 0;
13762 + }
13763 +
13764 +#ifdef CONFIG_PAX_PAGEEXEC
13765 + if (!(__supported_pte_mask & _PAGE_NX) && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
13766 + start_addr = 0x00110000UL;
13767 +
13768 +#ifdef CONFIG_PAX_RANDMMAP
13769 + if (mm->pax_flags & MF_PAX_RANDMMAP)
13770 + start_addr += mm->delta_mmap & 0x03FFF000UL;
13771 +#endif
13772 +
13773 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
13774 + start_addr = addr = mm->mmap_base;
13775 + else
13776 + addr = start_addr;
13777 + }
13778 +#endif
13779 +
13780 +full_search:
13781 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
13782 + /* At this point: (!vma || addr < vma->vm_end). */
13783 + if (pax_task_size - len < addr) {
13784 + /*
13785 + * Start a new search - just in case we missed
13786 + * some holes.
13787 + */
13788 + if (start_addr != mm->mmap_base) {
13789 + start_addr = addr = mm->mmap_base;
13790 + mm->cached_hole_size = 0;
13791 + goto full_search;
13792 + }
13793 + return -ENOMEM;
13794 + }
13795 + if (check_heap_stack_gap(vma, addr, len))
13796 + break;
13797 + if (addr + mm->cached_hole_size < vma->vm_start)
13798 + mm->cached_hole_size = vma->vm_start - addr;
13799 + addr = vma->vm_end;
13800 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
13801 + start_addr = addr = mm->mmap_base;
13802 + mm->cached_hole_size = 0;
13803 + goto full_search;
13804 + }
13805 + }
13806 +
13807 + /*
13808 + * Remember the place where we stopped the search:
13809 + */
13810 + mm->free_area_cache = addr + len;
13811 + return addr;
13812 +}
13813 +
13814 +unsigned long
13815 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
13816 + const unsigned long len, const unsigned long pgoff,
13817 + const unsigned long flags)
13818 +{
13819 + struct vm_area_struct *vma;
13820 + struct mm_struct *mm = current->mm;
13821 + unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
13822 +
13823 +#ifdef CONFIG_PAX_SEGMEXEC
13824 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
13825 + pax_task_size = SEGMEXEC_TASK_SIZE;
13826 +#endif
13827 +
13828 + pax_task_size -= PAGE_SIZE;
13829 +
13830 + /* requested length too big for entire address space */
13831 + if (len > pax_task_size)
13832 + return -ENOMEM;
13833 +
13834 + if (flags & MAP_FIXED)
13835 + return addr;
13836 +
13837 +#ifdef CONFIG_PAX_PAGEEXEC
13838 + if (!(__supported_pte_mask & _PAGE_NX) && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
13839 + goto bottomup;
13840 +#endif
13841 +
13842 +#ifdef CONFIG_PAX_RANDMMAP
13843 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
13844 +#endif
13845 +
13846 + /* requesting a specific address */
13847 + if (addr) {
13848 + addr = PAGE_ALIGN(addr);
13849 + if (pax_task_size - len >= addr) {
13850 + vma = find_vma(mm, addr);
13851 + if (check_heap_stack_gap(vma, addr, len))
13852 + return addr;
13853 + }
13854 + }
13855 +
13856 + /* check if free_area_cache is useful for us */
13857 + if (len <= mm->cached_hole_size) {
13858 + mm->cached_hole_size = 0;
13859 + mm->free_area_cache = mm->mmap_base;
13860 + }
13861 +
13862 + /* either no address requested or can't fit in requested address hole */
13863 + addr = mm->free_area_cache;
13864 +
13865 + /* make sure it can fit in the remaining address space */
13866 + if (addr > len) {
13867 + vma = find_vma(mm, addr-len);
13868 + if (check_heap_stack_gap(vma, addr - len, len))
13869 + /* remember the address as a hint for next time */
13870 + return (mm->free_area_cache = addr-len);
13871 + }
13872 +
13873 + if (mm->mmap_base < len)
13874 + goto bottomup;
13875 +
13876 + addr = mm->mmap_base-len;
13877 +
13878 + do {
13879 + /*
13880 + * Lookup failure means no vma is above this address,
13881 + * else if new region fits below vma->vm_start,
13882 + * return with success:
13883 + */
13884 + vma = find_vma(mm, addr);
13885 + if (check_heap_stack_gap(vma, addr, len))
13886 + /* remember the address as a hint for next time */
13887 + return (mm->free_area_cache = addr);
13888 +
13889 + /* remember the largest hole we saw so far */
13890 + if (addr + mm->cached_hole_size < vma->vm_start)
13891 + mm->cached_hole_size = vma->vm_start - addr;
13892 +
13893 + /* try just below the current vma->vm_start */
13894 + addr = vma->vm_start-len;
13895 + } while (len < vma->vm_start);
13896 +
13897 +bottomup:
13898 + /*
13899 + * A failed mmap() very likely causes application failure,
13900 + * so fall back to the bottom-up function here. This scenario
13901 + * can happen with large stack limits and large mmap()
13902 + * allocations.
13903 + */
13904 +
13905 +#ifdef CONFIG_PAX_SEGMEXEC
13906 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
13907 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
13908 + else
13909 +#endif
13910 +
13911 + mm->mmap_base = TASK_UNMAPPED_BASE;
13912 +
13913 +#ifdef CONFIG_PAX_RANDMMAP
13914 + if (mm->pax_flags & MF_PAX_RANDMMAP)
13915 + mm->mmap_base += mm->delta_mmap;
13916 +#endif
13917 +
13918 + mm->free_area_cache = mm->mmap_base;
13919 + mm->cached_hole_size = ~0UL;
13920 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
13921 + /*
13922 + * Restore the topdown base:
13923 + */
13924 + mm->mmap_base = base;
13925 + mm->free_area_cache = base;
13926 + mm->cached_hole_size = ~0UL;
13927 +
13928 + return addr;
13929 +}
13930 +
13931 /*
13932 * Do a system call from kernel instead of calling sys_execve so we
13933 * end up with proper pt_regs.
13934 diff -urNp linux-2.6.36/arch/x86/kernel/sys_x86_64.c linux-2.6.36/arch/x86/kernel/sys_x86_64.c
13935 --- linux-2.6.36/arch/x86/kernel/sys_x86_64.c 2010-10-20 16:30:22.000000000 -0400
13936 +++ linux-2.6.36/arch/x86/kernel/sys_x86_64.c 2010-11-06 18:58:15.000000000 -0400
13937 @@ -32,8 +32,8 @@ out:
13938 return error;
13939 }
13940
13941 -static void find_start_end(unsigned long flags, unsigned long *begin,
13942 - unsigned long *end)
13943 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
13944 + unsigned long *begin, unsigned long *end)
13945 {
13946 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
13947 unsigned long new_begin;
13948 @@ -52,7 +52,7 @@ static void find_start_end(unsigned long
13949 *begin = new_begin;
13950 }
13951 } else {
13952 - *begin = TASK_UNMAPPED_BASE;
13953 + *begin = mm->mmap_base;
13954 *end = TASK_SIZE;
13955 }
13956 }
13957 @@ -69,16 +69,19 @@ arch_get_unmapped_area(struct file *filp
13958 if (flags & MAP_FIXED)
13959 return addr;
13960
13961 - find_start_end(flags, &begin, &end);
13962 + find_start_end(mm, flags, &begin, &end);
13963
13964 if (len > end)
13965 return -ENOMEM;
13966
13967 +#ifdef CONFIG_PAX_RANDMMAP
13968 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
13969 +#endif
13970 +
13971 if (addr) {
13972 addr = PAGE_ALIGN(addr);
13973 vma = find_vma(mm, addr);
13974 - if (end - len >= addr &&
13975 - (!vma || addr + len <= vma->vm_start))
13976 + if (end - len >= addr && check_heap_stack_gap(vma, addr, len))
13977 return addr;
13978 }
13979 if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
13980 @@ -106,7 +109,7 @@ full_search:
13981 }
13982 return -ENOMEM;
13983 }
13984 - if (!vma || addr + len <= vma->vm_start) {
13985 + if (check_heap_stack_gap(vma, addr, len)) {
13986 /*
13987 * Remember the place where we stopped the search:
13988 */
13989 @@ -128,7 +131,7 @@ arch_get_unmapped_area_topdown(struct fi
13990 {
13991 struct vm_area_struct *vma;
13992 struct mm_struct *mm = current->mm;
13993 - unsigned long addr = addr0;
13994 + unsigned long base = mm->mmap_base, addr = addr0;
13995
13996 /* requested length too big for entire address space */
13997 if (len > TASK_SIZE)
13998 @@ -141,12 +144,15 @@ arch_get_unmapped_area_topdown(struct fi
13999 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
14000 goto bottomup;
14001
14002 +#ifdef CONFIG_PAX_RANDMMAP
14003 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
14004 +#endif
14005 +
14006 /* requesting a specific address */
14007 if (addr) {
14008 addr = PAGE_ALIGN(addr);
14009 vma = find_vma(mm, addr);
14010 - if (TASK_SIZE - len >= addr &&
14011 - (!vma || addr + len <= vma->vm_start))
14012 + if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
14013 return addr;
14014 }
14015
14016 @@ -162,7 +168,7 @@ arch_get_unmapped_area_topdown(struct fi
14017 /* make sure it can fit in the remaining address space */
14018 if (addr > len) {
14019 vma = find_vma(mm, addr-len);
14020 - if (!vma || addr <= vma->vm_start)
14021 + if (check_heap_stack_gap(vma, addr - len, len))
14022 /* remember the address as a hint for next time */
14023 return mm->free_area_cache = addr-len;
14024 }
14025 @@ -179,7 +185,7 @@ arch_get_unmapped_area_topdown(struct fi
14026 * return with success:
14027 */
14028 vma = find_vma(mm, addr);
14029 - if (!vma || addr+len <= vma->vm_start)
14030 + if (check_heap_stack_gap(vma, addr, len))
14031 /* remember the address as a hint for next time */
14032 return mm->free_area_cache = addr;
14033
14034 @@ -198,13 +204,21 @@ bottomup:
14035 * can happen with large stack limits and large mmap()
14036 * allocations.
14037 */
14038 + mm->mmap_base = TASK_UNMAPPED_BASE;
14039 +
14040 +#ifdef CONFIG_PAX_RANDMMAP
14041 + if (mm->pax_flags & MF_PAX_RANDMMAP)
14042 + mm->mmap_base += mm->delta_mmap;
14043 +#endif
14044 +
14045 + mm->free_area_cache = mm->mmap_base;
14046 mm->cached_hole_size = ~0UL;
14047 - mm->free_area_cache = TASK_UNMAPPED_BASE;
14048 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
14049 /*
14050 * Restore the topdown base:
14051 */
14052 - mm->free_area_cache = mm->mmap_base;
14053 + mm->mmap_base = base;
14054 + mm->free_area_cache = base;
14055 mm->cached_hole_size = ~0UL;
14056
14057 return addr;
14058 diff -urNp linux-2.6.36/arch/x86/kernel/time.c linux-2.6.36/arch/x86/kernel/time.c
14059 --- linux-2.6.36/arch/x86/kernel/time.c 2010-10-20 16:30:22.000000000 -0400
14060 +++ linux-2.6.36/arch/x86/kernel/time.c 2010-11-06 18:58:15.000000000 -0400
14061 @@ -26,17 +26,13 @@
14062 int timer_ack;
14063 #endif
14064
14065 -#ifdef CONFIG_X86_64
14066 -volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
14067 -#endif
14068 -
14069 unsigned long profile_pc(struct pt_regs *regs)
14070 {
14071 unsigned long pc = instruction_pointer(regs);
14072
14073 - if (!user_mode_vm(regs) && in_lock_functions(pc)) {
14074 + if (!user_mode(regs) && in_lock_functions(pc)) {
14075 #ifdef CONFIG_FRAME_POINTER
14076 - return *(unsigned long *)(regs->bp + sizeof(long));
14077 + return ktla_ktva(*(unsigned long *)(regs->bp + sizeof(long)));
14078 #else
14079 unsigned long *sp =
14080 (unsigned long *)kernel_stack_pointer(regs);
14081 @@ -45,11 +41,17 @@ unsigned long profile_pc(struct pt_regs
14082 * or above a saved flags. Eflags has bits 22-31 zero,
14083 * kernel addresses don't.
14084 */
14085 +
14086 +#ifdef CONFIG_PAX_KERNEXEC
14087 + return ktla_ktva(sp[0]);
14088 +#else
14089 if (sp[0] >> 22)
14090 return sp[0];
14091 if (sp[1] >> 22)
14092 return sp[1];
14093 #endif
14094 +
14095 +#endif
14096 }
14097 return pc;
14098 }
14099 diff -urNp linux-2.6.36/arch/x86/kernel/tls.c linux-2.6.36/arch/x86/kernel/tls.c
14100 --- linux-2.6.36/arch/x86/kernel/tls.c 2010-10-20 16:30:22.000000000 -0400
14101 +++ linux-2.6.36/arch/x86/kernel/tls.c 2010-11-06 18:58:15.000000000 -0400
14102 @@ -85,6 +85,11 @@ int do_set_thread_area(struct task_struc
14103 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
14104 return -EINVAL;
14105
14106 +#ifdef CONFIG_PAX_SEGMEXEC
14107 + if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
14108 + return -EINVAL;
14109 +#endif
14110 +
14111 set_tls_desc(p, idx, &info, 1);
14112
14113 return 0;
14114 diff -urNp linux-2.6.36/arch/x86/kernel/trampoline_32.S linux-2.6.36/arch/x86/kernel/trampoline_32.S
14115 --- linux-2.6.36/arch/x86/kernel/trampoline_32.S 2010-10-20 16:30:22.000000000 -0400
14116 +++ linux-2.6.36/arch/x86/kernel/trampoline_32.S 2010-11-06 18:58:15.000000000 -0400
14117 @@ -32,6 +32,12 @@
14118 #include <asm/segment.h>
14119 #include <asm/page_types.h>
14120
14121 +#ifdef CONFIG_PAX_KERNEXEC
14122 +#define ta(X) (X)
14123 +#else
14124 +#define ta(X) ((X) - __PAGE_OFFSET)
14125 +#endif
14126 +
14127 /* We can free up trampoline after bootup if cpu hotplug is not supported. */
14128 __CPUINITRODATA
14129 .code16
14130 @@ -60,7 +66,7 @@ r_base = .
14131 inc %ax # protected mode (PE) bit
14132 lmsw %ax # into protected mode
14133 # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S
14134 - ljmpl $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET)
14135 + ljmpl $__BOOT_CS, $ta(startup_32_smp)
14136
14137 # These need to be in the same 64K segment as the above;
14138 # hence we don't use the boot_gdt_descr defined in head.S
14139 diff -urNp linux-2.6.36/arch/x86/kernel/trampoline_64.S linux-2.6.36/arch/x86/kernel/trampoline_64.S
14140 --- linux-2.6.36/arch/x86/kernel/trampoline_64.S 2010-10-20 16:30:22.000000000 -0400
14141 +++ linux-2.6.36/arch/x86/kernel/trampoline_64.S 2010-11-06 18:58:15.000000000 -0400
14142 @@ -91,7 +91,7 @@ startup_32:
14143 movl $__KERNEL_DS, %eax # Initialize the %ds segment register
14144 movl %eax, %ds
14145
14146 - movl $X86_CR4_PAE, %eax
14147 + movl $(X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE), %eax
14148 movl %eax, %cr4 # Enable PAE mode
14149
14150 # Setup trampoline 4 level pagetables
14151 @@ -138,7 +138,7 @@ tidt:
14152 # so the kernel can live anywhere
14153 .balign 4
14154 tgdt:
14155 - .short tgdt_end - tgdt # gdt limit
14156 + .short tgdt_end - tgdt - 1 # gdt limit
14157 .long tgdt - r_base
14158 .short 0
14159 .quad 0x00cf9b000000ffff # __KERNEL32_CS
14160 diff -urNp linux-2.6.36/arch/x86/kernel/traps.c linux-2.6.36/arch/x86/kernel/traps.c
14161 --- linux-2.6.36/arch/x86/kernel/traps.c 2010-10-20 16:30:22.000000000 -0400
14162 +++ linux-2.6.36/arch/x86/kernel/traps.c 2010-11-06 18:58:15.000000000 -0400
14163 @@ -70,12 +70,6 @@ asmlinkage int system_call(void);
14164
14165 /* Do we ignore FPU interrupts ? */
14166 char ignore_fpu_irq;
14167 -
14168 -/*
14169 - * The IDT has to be page-aligned to simplify the Pentium
14170 - * F0 0F bug workaround.
14171 - */
14172 -gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, };
14173 #endif
14174
14175 DECLARE_BITMAP(used_vectors, NR_VECTORS);
14176 @@ -110,13 +104,13 @@ static inline void preempt_conditional_c
14177 }
14178
14179 static void __kprobes
14180 -do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
14181 +do_trap(int trapnr, int signr, const char *str, struct pt_regs *regs,
14182 long error_code, siginfo_t *info)
14183 {
14184 struct task_struct *tsk = current;
14185
14186 #ifdef CONFIG_X86_32
14187 - if (regs->flags & X86_VM_MASK) {
14188 + if (v8086_mode(regs)) {
14189 /*
14190 * traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
14191 * On nmi (interrupt 2), do_trap should not be called.
14192 @@ -127,7 +121,7 @@ do_trap(int trapnr, int signr, char *str
14193 }
14194 #endif
14195
14196 - if (!user_mode(regs))
14197 + if (!user_mode_novm(regs))
14198 goto kernel_trap;
14199
14200 #ifdef CONFIG_X86_32
14201 @@ -150,7 +144,7 @@ trap_signal:
14202 printk_ratelimit()) {
14203 printk(KERN_INFO
14204 "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
14205 - tsk->comm, tsk->pid, str,
14206 + tsk->comm, task_pid_nr(tsk), str,
14207 regs->ip, regs->sp, error_code);
14208 print_vma_addr(" in ", regs->ip);
14209 printk("\n");
14210 @@ -167,8 +161,20 @@ kernel_trap:
14211 if (!fixup_exception(regs)) {
14212 tsk->thread.error_code = error_code;
14213 tsk->thread.trap_no = trapnr;
14214 +
14215 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
14216 + if (trapnr == 12 && ((regs->cs & 0xFFFF) == __KERNEL_CS || (regs->cs & 0xFFFF) == __KERNEXEC_KERNEL_CS))
14217 + str = "PAX: suspicious stack segment fault";
14218 +#endif
14219 +
14220 die(str, regs, error_code);
14221 }
14222 +
14223 +#ifdef CONFIG_PAX_REFCOUNT
14224 + if (trapnr == 4)
14225 + pax_report_refcount_overflow(regs);
14226 +#endif
14227 +
14228 return;
14229
14230 #ifdef CONFIG_X86_32
14231 @@ -257,14 +263,30 @@ do_general_protection(struct pt_regs *re
14232 conditional_sti(regs);
14233
14234 #ifdef CONFIG_X86_32
14235 - if (regs->flags & X86_VM_MASK)
14236 + if (v8086_mode(regs))
14237 goto gp_in_vm86;
14238 #endif
14239
14240 tsk = current;
14241 - if (!user_mode(regs))
14242 + if (!user_mode_novm(regs))
14243 goto gp_in_kernel;
14244
14245 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
14246 + if (!(__supported_pte_mask & _PAGE_NX) && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
14247 + struct mm_struct *mm = tsk->mm;
14248 + unsigned long limit;
14249 +
14250 + down_write(&mm->mmap_sem);
14251 + limit = mm->context.user_cs_limit;
14252 + if (limit < TASK_SIZE) {
14253 + track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
14254 + up_write(&mm->mmap_sem);
14255 + return;
14256 + }
14257 + up_write(&mm->mmap_sem);
14258 + }
14259 +#endif
14260 +
14261 tsk->thread.error_code = error_code;
14262 tsk->thread.trap_no = 13;
14263
14264 @@ -297,6 +319,13 @@ gp_in_kernel:
14265 if (notify_die(DIE_GPF, "general protection fault", regs,
14266 error_code, 13, SIGSEGV) == NOTIFY_STOP)
14267 return;
14268 +
14269 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
14270 + if ((regs->cs & 0xFFFF) == __KERNEL_CS || (regs->cs & 0xFFFF) == __KERNEXEC_KERNEL_CS)
14271 + die("PAX: suspicious general protection fault", regs, error_code);
14272 + else
14273 +#endif
14274 +
14275 die("general protection fault", regs, error_code);
14276 }
14277
14278 @@ -572,7 +601,7 @@ dotraplinkage void __kprobes do_debug(st
14279 /* It's safe to allow irq's after DR6 has been saved */
14280 preempt_conditional_sti(regs);
14281
14282 - if (regs->flags & X86_VM_MASK) {
14283 + if (v8086_mode(regs)) {
14284 handle_vm86_trap((struct kernel_vm86_regs *) regs,
14285 error_code, 1);
14286 return;
14287 @@ -585,7 +614,7 @@ dotraplinkage void __kprobes do_debug(st
14288 * We already checked v86 mode above, so we can check for kernel mode
14289 * by just checking the CPL of CS.
14290 */
14291 - if ((dr6 & DR_STEP) && !user_mode(regs)) {
14292 + if ((dr6 & DR_STEP) && !user_mode_novm(regs)) {
14293 tsk->thread.debugreg6 &= ~DR_STEP;
14294 set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
14295 regs->flags &= ~X86_EFLAGS_TF;
14296 @@ -614,7 +643,7 @@ void math_error(struct pt_regs *regs, in
14297 return;
14298 conditional_sti(regs);
14299
14300 - if (!user_mode_vm(regs))
14301 + if (!user_mode(regs))
14302 {
14303 if (!fixup_exception(regs)) {
14304 task->thread.error_code = error_code;
14305 diff -urNp linux-2.6.36/arch/x86/kernel/tsc.c linux-2.6.36/arch/x86/kernel/tsc.c
14306 --- linux-2.6.36/arch/x86/kernel/tsc.c 2010-10-20 16:30:22.000000000 -0400
14307 +++ linux-2.6.36/arch/x86/kernel/tsc.c 2010-11-06 18:58:15.000000000 -0400
14308 @@ -832,7 +832,7 @@ static struct dmi_system_id __initdata b
14309 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
14310 },
14311 },
14312 - {}
14313 + { NULL, NULL, {{0, {0}}}, NULL}
14314 };
14315
14316 static void __init check_system_tsc_reliable(void)
14317 diff -urNp linux-2.6.36/arch/x86/kernel/vm86_32.c linux-2.6.36/arch/x86/kernel/vm86_32.c
14318 --- linux-2.6.36/arch/x86/kernel/vm86_32.c 2010-10-20 16:30:22.000000000 -0400
14319 +++ linux-2.6.36/arch/x86/kernel/vm86_32.c 2010-11-06 18:58:50.000000000 -0400
14320 @@ -41,6 +41,7 @@
14321 #include <linux/ptrace.h>
14322 #include <linux/audit.h>
14323 #include <linux/stddef.h>
14324 +#include <linux/grsecurity.h>
14325
14326 #include <asm/uaccess.h>
14327 #include <asm/io.h>
14328 @@ -148,7 +149,7 @@ struct pt_regs *save_v86_state(struct ke
14329 do_exit(SIGSEGV);
14330 }
14331
14332 - tss = &per_cpu(init_tss, get_cpu());
14333 + tss = init_tss + get_cpu();
14334 current->thread.sp0 = current->thread.saved_sp0;
14335 current->thread.sysenter_cs = __KERNEL_CS;
14336 load_sp0(tss, &current->thread);
14337 @@ -207,6 +208,13 @@ int sys_vm86old(struct vm86_struct __use
14338 struct task_struct *tsk;
14339 int tmp, ret = -EPERM;
14340
14341 +#ifdef CONFIG_GRKERNSEC_VM86
14342 + if (!capable(CAP_SYS_RAWIO)) {
14343 + gr_handle_vm86();
14344 + goto out;
14345 + }
14346 +#endif
14347 +
14348 tsk = current;
14349 if (tsk->thread.saved_sp0)
14350 goto out;
14351 @@ -237,6 +245,14 @@ int sys_vm86(unsigned long cmd, unsigned
14352 int tmp, ret;
14353 struct vm86plus_struct __user *v86;
14354
14355 +#ifdef CONFIG_GRKERNSEC_VM86
14356 + if (!capable(CAP_SYS_RAWIO)) {
14357 + gr_handle_vm86();
14358 + ret = -EPERM;
14359 + goto out;
14360 + }
14361 +#endif
14362 +
14363 tsk = current;
14364 switch (cmd) {
14365 case VM86_REQUEST_IRQ:
14366 @@ -323,7 +339,7 @@ static void do_sys_vm86(struct kernel_vm
14367 tsk->thread.saved_fs = info->regs32->fs;
14368 tsk->thread.saved_gs = get_user_gs(info->regs32);
14369
14370 - tss = &per_cpu(init_tss, get_cpu());
14371 + tss = init_tss + get_cpu();
14372 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
14373 if (cpu_has_sep)
14374 tsk->thread.sysenter_cs = 0;
14375 @@ -528,7 +544,7 @@ static void do_int(struct kernel_vm86_re
14376 goto cannot_handle;
14377 if (i == 0x21 && is_revectored(AH(regs), &KVM86->int21_revectored))
14378 goto cannot_handle;
14379 - intr_ptr = (unsigned long __user *) (i << 2);
14380 + intr_ptr = (__force unsigned long __user *) (i << 2);
14381 if (get_user(segoffs, intr_ptr))
14382 goto cannot_handle;
14383 if ((segoffs >> 16) == BIOSSEG)
14384 diff -urNp linux-2.6.36/arch/x86/kernel/vmi_32.c linux-2.6.36/arch/x86/kernel/vmi_32.c
14385 --- linux-2.6.36/arch/x86/kernel/vmi_32.c 2010-10-20 16:30:22.000000000 -0400
14386 +++ linux-2.6.36/arch/x86/kernel/vmi_32.c 2010-11-06 18:58:15.000000000 -0400
14387 @@ -46,12 +46,17 @@ typedef u32 __attribute__((regparm(1)))
14388 typedef u64 __attribute__((regparm(2))) (VROMLONGFUNC)(int);
14389
14390 #define call_vrom_func(rom,func) \
14391 - (((VROMFUNC *)(rom->func))())
14392 + (((VROMFUNC *)(ktva_ktla(rom.func)))())
14393
14394 #define call_vrom_long_func(rom,func,arg) \
14395 - (((VROMLONGFUNC *)(rom->func)) (arg))
14396 +({\
14397 + u64 __reloc = ((VROMLONGFUNC *)(ktva_ktla(rom.func))) (arg);\
14398 + struct vmi_relocation_info *const __rel = (struct vmi_relocation_info *)&__reloc;\
14399 + __rel->eip = (unsigned char *)ktva_ktla((unsigned long)__rel->eip);\
14400 + __reloc;\
14401 +})
14402
14403 -static struct vrom_header *vmi_rom;
14404 +static struct vrom_header vmi_rom __attribute((__section__(".vmi.rom"), __aligned__(PAGE_SIZE)));
14405 static int disable_pge;
14406 static int disable_pse;
14407 static int disable_sep;
14408 @@ -78,10 +83,10 @@ static struct {
14409 void (*set_initial_ap_state)(int, int);
14410 void (*halt)(void);
14411 void (*set_lazy_mode)(int mode);
14412 -} vmi_ops;
14413 +} vmi_ops __read_only;
14414
14415 /* Cached VMI operations */
14416 -struct vmi_timer_ops vmi_timer_ops;
14417 +struct vmi_timer_ops vmi_timer_ops __read_only;
14418
14419 /*
14420 * VMI patching routines.
14421 @@ -96,7 +101,7 @@ struct vmi_timer_ops vmi_timer_ops;
14422 static inline void patch_offset(void *insnbuf,
14423 unsigned long ip, unsigned long dest)
14424 {
14425 - *(unsigned long *)(insnbuf+1) = dest-ip-5;
14426 + *(unsigned long *)(insnbuf+1) = dest-ip-5;
14427 }
14428
14429 static unsigned patch_internal(int call, unsigned len, void *insnbuf,
14430 @@ -104,6 +109,7 @@ static unsigned patch_internal(int call,
14431 {
14432 u64 reloc;
14433 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
14434 +
14435 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
14436 switch(rel->type) {
14437 case VMI_RELOCATION_CALL_REL:
14438 @@ -382,13 +388,13 @@ static void vmi_set_pud(pud_t *pudp, pud
14439
14440 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
14441 {
14442 - const pte_t pte = { .pte = 0 };
14443 + const pte_t pte = __pte(0ULL);
14444 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
14445 }
14446
14447 static void vmi_pmd_clear(pmd_t *pmd)
14448 {
14449 - const pte_t pte = { .pte = 0 };
14450 + const pte_t pte = __pte(0ULL);
14451 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
14452 }
14453 #endif
14454 @@ -416,8 +422,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
14455 ap.ss = __KERNEL_DS;
14456 ap.esp = (unsigned long) start_esp;
14457
14458 - ap.ds = __USER_DS;
14459 - ap.es = __USER_DS;
14460 + ap.ds = __KERNEL_DS;
14461 + ap.es = __KERNEL_DS;
14462 ap.fs = __KERNEL_PERCPU;
14463 ap.gs = __KERNEL_STACK_CANARY;
14464
14465 @@ -464,6 +470,18 @@ static void vmi_leave_lazy_mmu(void)
14466 paravirt_leave_lazy_mmu();
14467 }
14468
14469 +#ifdef CONFIG_PAX_KERNEXEC
14470 +static unsigned long vmi_pax_open_kernel(void)
14471 +{
14472 + return 0;
14473 +}
14474 +
14475 +static unsigned long vmi_pax_close_kernel(void)
14476 +{
14477 + return 0;
14478 +}
14479 +#endif
14480 +
14481 static inline int __init check_vmi_rom(struct vrom_header *rom)
14482 {
14483 struct pci_header *pci;
14484 @@ -476,6 +494,10 @@ static inline int __init check_vmi_rom(s
14485 return 0;
14486 if (rom->vrom_signature != VMI_SIGNATURE)
14487 return 0;
14488 + if (rom->rom_length * 512 > sizeof(*rom)) {
14489 + printk(KERN_WARNING "PAX: VMI: ROM size too big: %x\n", rom->rom_length * 512);
14490 + return 0;
14491 + }
14492 if (rom->api_version_maj != VMI_API_REV_MAJOR ||
14493 rom->api_version_min+1 < VMI_API_REV_MINOR+1) {
14494 printk(KERN_WARNING "VMI: Found mismatched rom version %d.%d\n",
14495 @@ -540,7 +562,7 @@ static inline int __init probe_vmi_rom(v
14496 struct vrom_header *romstart;
14497 romstart = (struct vrom_header *)isa_bus_to_virt(base);
14498 if (check_vmi_rom(romstart)) {
14499 - vmi_rom = romstart;
14500 + vmi_rom = *romstart;
14501 return 1;
14502 }
14503 }
14504 @@ -816,6 +838,11 @@ static inline int __init activate_vmi(vo
14505
14506 para_fill(pv_irq_ops.safe_halt, Halt);
14507
14508 +#ifdef CONFIG_PAX_KERNEXEC
14509 + pv_mmu_ops.pax_open_kernel = vmi_pax_open_kernel;
14510 + pv_mmu_ops.pax_close_kernel = vmi_pax_close_kernel;
14511 +#endif
14512 +
14513 /*
14514 * Alternative instruction rewriting doesn't happen soon enough
14515 * to convert VMI_IRET to a call instead of a jump; so we have
14516 @@ -833,16 +860,16 @@ static inline int __init activate_vmi(vo
14517
14518 void __init vmi_init(void)
14519 {
14520 - if (!vmi_rom)
14521 + if (!vmi_rom.rom_signature)
14522 probe_vmi_rom();
14523 else
14524 - check_vmi_rom(vmi_rom);
14525 + check_vmi_rom(&vmi_rom);
14526
14527 /* In case probing for or validating the ROM failed, basil */
14528 - if (!vmi_rom)
14529 + if (!vmi_rom.rom_signature)
14530 return;
14531
14532 - reserve_top_address(-vmi_rom->virtual_top);
14533 + reserve_top_address(-vmi_rom.virtual_top);
14534
14535 #ifdef CONFIG_X86_IO_APIC
14536 /* This is virtual hardware; timer routing is wired correctly */
14537 @@ -854,7 +881,7 @@ void __init vmi_activate(void)
14538 {
14539 unsigned long flags;
14540
14541 - if (!vmi_rom)
14542 + if (!vmi_rom.rom_signature)
14543 return;
14544
14545 local_irq_save(flags);
14546 diff -urNp linux-2.6.36/arch/x86/kernel/vmlinux.lds.S linux-2.6.36/arch/x86/kernel/vmlinux.lds.S
14547 --- linux-2.6.36/arch/x86/kernel/vmlinux.lds.S 2010-10-20 16:30:22.000000000 -0400
14548 +++ linux-2.6.36/arch/x86/kernel/vmlinux.lds.S 2010-11-06 18:58:15.000000000 -0400
14549 @@ -26,6 +26,13 @@
14550 #include <asm/page_types.h>
14551 #include <asm/cache.h>
14552 #include <asm/boot.h>
14553 +#include <asm/segment.h>
14554 +
14555 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
14556 +#define __KERNEL_TEXT_OFFSET (LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR)
14557 +#else
14558 +#define __KERNEL_TEXT_OFFSET 0
14559 +#endif
14560
14561 #undef i386 /* in case the preprocessor is a 32bit one */
14562
14563 @@ -34,13 +41,13 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONF
14564 #ifdef CONFIG_X86_32
14565 OUTPUT_ARCH(i386)
14566 ENTRY(phys_startup_32)
14567 -jiffies = jiffies_64;
14568 #else
14569 OUTPUT_ARCH(i386:x86-64)
14570 ENTRY(phys_startup_64)
14571 -jiffies_64 = jiffies;
14572 #endif
14573
14574 +jiffies = jiffies_64;
14575 +
14576 #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
14577 /*
14578 * On 64-bit, align RODATA to 2MB so that even with CONFIG_DEBUG_RODATA
14579 @@ -69,31 +76,46 @@ jiffies_64 = jiffies;
14580
14581 PHDRS {
14582 text PT_LOAD FLAGS(5); /* R_E */
14583 - data PT_LOAD FLAGS(7); /* RWE */
14584 +#ifdef CONFIG_X86_32
14585 + module PT_LOAD FLAGS(5); /* R_E */
14586 +#endif
14587 +#ifdef CONFIG_XEN
14588 + rodata PT_LOAD FLAGS(5); /* R_E */
14589 +#else
14590 + rodata PT_LOAD FLAGS(4); /* R__ */
14591 +#endif
14592 + data PT_LOAD FLAGS(6); /* RW_ */
14593 #ifdef CONFIG_X86_64
14594 user PT_LOAD FLAGS(5); /* R_E */
14595 +#endif
14596 + init.begin PT_LOAD FLAGS(6); /* RW_ */
14597 #ifdef CONFIG_SMP
14598 percpu PT_LOAD FLAGS(6); /* RW_ */
14599 #endif
14600 + text.init PT_LOAD FLAGS(5); /* R_E */
14601 + text.exit PT_LOAD FLAGS(5); /* R_E */
14602 init PT_LOAD FLAGS(7); /* RWE */
14603 -#endif
14604 note PT_NOTE FLAGS(0); /* ___ */
14605 }
14606
14607 SECTIONS
14608 {
14609 #ifdef CONFIG_X86_32
14610 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
14611 - phys_startup_32 = startup_32 - LOAD_OFFSET;
14612 + . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
14613 #else
14614 - . = __START_KERNEL;
14615 - phys_startup_64 = startup_64 - LOAD_OFFSET;
14616 + . = __START_KERNEL;
14617 #endif
14618
14619 /* Text and read-only data */
14620 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
14621 - _text = .;
14622 + .text (. - __KERNEL_TEXT_OFFSET): AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
14623 /* bootstrapping code */
14624 +#ifdef CONFIG_X86_32
14625 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
14626 +#else
14627 + phys_startup_64 = startup_64 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
14628 +#endif
14629 + __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
14630 + _text = .;
14631 HEAD_TEXT
14632 #ifdef CONFIG_X86_32
14633 . = ALIGN(PAGE_SIZE);
14634 @@ -108,13 +130,52 @@ SECTIONS
14635 IRQENTRY_TEXT
14636 *(.fixup)
14637 *(.gnu.warning)
14638 - /* End of text section */
14639 - _etext = .;
14640 } :text = 0x9090
14641
14642 - NOTES :text :note
14643 + . += __KERNEL_TEXT_OFFSET;
14644 +
14645 +#ifdef CONFIG_X86_32
14646 + . = ALIGN(PAGE_SIZE);
14647 + .vmi.rom : AT(ADDR(.vmi.rom) - LOAD_OFFSET) {
14648 + *(.vmi.rom)
14649 + } :module
14650 +
14651 + . = ALIGN(PAGE_SIZE);
14652 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
14653 +
14654 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
14655 + MODULES_EXEC_VADDR = .;
14656 + BYTE(0)
14657 + . += (CONFIG_PAX_KERNEXEC_MODULE_TEXT * 1024 * 1024);
14658 + . = ALIGN(HPAGE_SIZE);
14659 + MODULES_EXEC_END = . - 1;
14660 +#endif
14661 +
14662 + } :module
14663 +#endif
14664 +
14665 + .text.end : AT(ADDR(.text.end) - LOAD_OFFSET) {
14666 + /* End of text section */
14667 + _etext = . - __KERNEL_TEXT_OFFSET;
14668 + }
14669 +
14670 +#ifdef CONFIG_X86_32
14671 + . = ALIGN(PAGE_SIZE);
14672 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
14673 + *(.idt)
14674 + . = ALIGN(PAGE_SIZE);
14675 + *(.empty_zero_page)
14676 + *(.swapper_pg_fixmap)
14677 + *(.swapper_pg_pmd)
14678 + *(.swapper_pg_dir)
14679 + *(.trampoline_pg_dir)
14680 + } :rodata
14681 +#endif
14682 +
14683 + . = ALIGN(PAGE_SIZE);
14684 + NOTES :rodata :note
14685
14686 - EXCEPTION_TABLE(16) :text = 0x9090
14687 + EXCEPTION_TABLE(16) :rodata
14688
14689 X64_ALIGN_DEBUG_RODATA_BEGIN
14690 RO_DATA(PAGE_SIZE)
14691 @@ -122,16 +183,20 @@ SECTIONS
14692
14693 /* Data */
14694 .data : AT(ADDR(.data) - LOAD_OFFSET) {
14695 +
14696 +#ifdef CONFIG_PAX_KERNEXEC
14697 + . = ALIGN(HPAGE_SIZE);
14698 +#else
14699 + . = ALIGN(PAGE_SIZE);
14700 +#endif
14701 +
14702 /* Start of data section */
14703 _sdata = .;
14704
14705 /* init_task */
14706 INIT_TASK_DATA(THREAD_SIZE)
14707
14708 -#ifdef CONFIG_X86_32
14709 - /* 32 bit has nosave before _edata */
14710 NOSAVE_DATA
14711 -#endif
14712
14713 PAGE_ALIGNED_DATA(PAGE_SIZE)
14714
14715 @@ -194,12 +259,6 @@ SECTIONS
14716 }
14717 vgetcpu_mode = VVIRT(.vgetcpu_mode);
14718
14719 - . = ALIGN(L1_CACHE_BYTES);
14720 - .jiffies : AT(VLOAD(.jiffies)) {
14721 - *(.jiffies)
14722 - }
14723 - jiffies = VVIRT(.jiffies);
14724 -
14725 .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
14726 *(.vsyscall_3)
14727 }
14728 @@ -215,12 +274,19 @@ SECTIONS
14729 #endif /* CONFIG_X86_64 */
14730
14731 /* Init code and data - will be freed after init */
14732 - . = ALIGN(PAGE_SIZE);
14733 .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
14734 + BYTE(0)
14735 +
14736 +#ifdef CONFIG_PAX_KERNEXEC
14737 + . = ALIGN(HPAGE_SIZE);
14738 +#else
14739 + . = ALIGN(PAGE_SIZE);
14740 +#endif
14741 +
14742 __init_begin = .; /* paired with __init_end */
14743 - }
14744 + } :init.begin
14745
14746 -#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
14747 +#ifdef CONFIG_SMP
14748 /*
14749 * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
14750 * output PHDR, so the next output section - .init.text - should
14751 @@ -229,12 +295,27 @@ SECTIONS
14752 PERCPU_VADDR(0, :percpu)
14753 #endif
14754
14755 - INIT_TEXT_SECTION(PAGE_SIZE)
14756 -#ifdef CONFIG_X86_64
14757 - :init
14758 -#endif
14759 + . = ALIGN(PAGE_SIZE);
14760 + init_begin = .;
14761 + .init.text (. - __KERNEL_TEXT_OFFSET): AT(init_begin - LOAD_OFFSET) {
14762 + VMLINUX_SYMBOL(_sinittext) = .;
14763 + INIT_TEXT
14764 + VMLINUX_SYMBOL(_einittext) = .;
14765 + . = ALIGN(PAGE_SIZE);
14766 + } :text.init
14767 +
14768 + /*
14769 + * .exit.text is discard at runtime, not link time, to deal with
14770 + * references from .altinstructions and .eh_frame
14771 + */
14772 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
14773 + EXIT_TEXT
14774 + . = ALIGN(16);
14775 + } :text.exit
14776 + . = init_begin + SIZEOF(.init.text) + SIZEOF(.exit.text);
14777
14778 - INIT_DATA_SECTION(16)
14779 + . = ALIGN(PAGE_SIZE);
14780 + INIT_DATA_SECTION(16) :init
14781
14782 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
14783 __x86_cpu_dev_start = .;
14784 @@ -260,19 +341,11 @@ SECTIONS
14785 *(.altinstr_replacement)
14786 }
14787
14788 - /*
14789 - * .exit.text is discard at runtime, not link time, to deal with
14790 - * references from .altinstructions and .eh_frame
14791 - */
14792 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
14793 - EXIT_TEXT
14794 - }
14795 -
14796 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
14797 EXIT_DATA
14798 }
14799
14800 -#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
14801 +#ifndef CONFIG_SMP
14802 PERCPU(PAGE_SIZE)
14803 #endif
14804
14805 @@ -291,16 +364,10 @@ SECTIONS
14806 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
14807 __smp_locks = .;
14808 *(.smp_locks)
14809 - . = ALIGN(PAGE_SIZE);
14810 __smp_locks_end = .;
14811 + . = ALIGN(PAGE_SIZE);
14812 }
14813
14814 -#ifdef CONFIG_X86_64
14815 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
14816 - NOSAVE_DATA
14817 - }
14818 -#endif
14819 -
14820 /* BSS */
14821 . = ALIGN(PAGE_SIZE);
14822 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
14823 @@ -316,6 +383,7 @@ SECTIONS
14824 __brk_base = .;
14825 . += 64 * 1024; /* 64k alignment slop space */
14826 *(.brk_reservation) /* areas brk users have reserved */
14827 + . = ALIGN(HPAGE_SIZE);
14828 __brk_limit = .;
14829 }
14830
14831 @@ -342,13 +410,12 @@ SECTIONS
14832 * for the boot processor.
14833 */
14834 #define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load
14835 -INIT_PER_CPU(gdt_page);
14836 INIT_PER_CPU(irq_stack_union);
14837
14838 /*
14839 * Build-time check on the image size:
14840 */
14841 -. = ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
14842 +. = ASSERT((_end - _text - __KERNEL_TEXT_OFFSET <= KERNEL_IMAGE_SIZE),
14843 "kernel image bigger than KERNEL_IMAGE_SIZE");
14844
14845 #ifdef CONFIG_SMP
14846 diff -urNp linux-2.6.36/arch/x86/kernel/vsyscall_64.c linux-2.6.36/arch/x86/kernel/vsyscall_64.c
14847 --- linux-2.6.36/arch/x86/kernel/vsyscall_64.c 2010-10-20 16:30:22.000000000 -0400
14848 +++ linux-2.6.36/arch/x86/kernel/vsyscall_64.c 2010-11-06 18:58:15.000000000 -0400
14849 @@ -80,6 +80,7 @@ void update_vsyscall(struct timespec *wa
14850
14851 write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags);
14852 /* copy vsyscall data */
14853 + strlcpy(vsyscall_gtod_data.clock.name, clock->name, sizeof vsyscall_gtod_data.clock.name);
14854 vsyscall_gtod_data.clock.vread = clock->vread;
14855 vsyscall_gtod_data.clock.cycle_last = clock->cycle_last;
14856 vsyscall_gtod_data.clock.mask = clock->mask;
14857 @@ -208,7 +209,7 @@ vgetcpu(unsigned *cpu, unsigned *node, s
14858 We do this here because otherwise user space would do it on
14859 its own in a likely inferior way (no access to jiffies).
14860 If you don't like it pass NULL. */
14861 - if (tcache && tcache->blob[0] == (j = __jiffies)) {
14862 + if (tcache && tcache->blob[0] == (j = jiffies)) {
14863 p = tcache->blob[1];
14864 } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
14865 /* Load per CPU data from RDTSCP */
14866 diff -urNp linux-2.6.36/arch/x86/kernel/x8664_ksyms_64.c linux-2.6.36/arch/x86/kernel/x8664_ksyms_64.c
14867 --- linux-2.6.36/arch/x86/kernel/x8664_ksyms_64.c 2010-10-20 16:30:22.000000000 -0400
14868 +++ linux-2.6.36/arch/x86/kernel/x8664_ksyms_64.c 2010-11-06 18:58:15.000000000 -0400
14869 @@ -29,8 +29,6 @@ EXPORT_SYMBOL(__put_user_8);
14870 EXPORT_SYMBOL(copy_user_generic_string);
14871 EXPORT_SYMBOL(copy_user_generic_unrolled);
14872 EXPORT_SYMBOL(__copy_user_nocache);
14873 -EXPORT_SYMBOL(_copy_from_user);
14874 -EXPORT_SYMBOL(_copy_to_user);
14875
14876 EXPORT_SYMBOL(copy_page);
14877 EXPORT_SYMBOL(clear_page);
14878 diff -urNp linux-2.6.36/arch/x86/kernel/xsave.c linux-2.6.36/arch/x86/kernel/xsave.c
14879 --- linux-2.6.36/arch/x86/kernel/xsave.c 2010-10-20 16:30:22.000000000 -0400
14880 +++ linux-2.6.36/arch/x86/kernel/xsave.c 2010-11-06 18:58:15.000000000 -0400
14881 @@ -130,7 +130,7 @@ int check_for_xstate(struct i387_fxsave_
14882 fx_sw_user->xstate_size > fx_sw_user->extended_size)
14883 return -EINVAL;
14884
14885 - err = __get_user(magic2, (__u32 *) (((void *)fpstate) +
14886 + err = __get_user(magic2, (__u32 __user *) (((void __user *)fpstate) +
14887 fx_sw_user->extended_size -
14888 FP_XSTATE_MAGIC2_SIZE));
14889 if (err)
14890 @@ -267,7 +267,7 @@ fx_only:
14891 * the other extended state.
14892 */
14893 xrstor_state(init_xstate_buf, pcntxt_mask & ~XSTATE_FPSSE);
14894 - return fxrstor_checking((__force struct i387_fxsave_struct *)buf);
14895 + return fxrstor_checking((struct i387_fxsave_struct __user *)buf);
14896 }
14897
14898 /*
14899 @@ -299,7 +299,7 @@ int restore_i387_xstate(void __user *buf
14900 if (use_xsave())
14901 err = restore_user_xstate(buf);
14902 else
14903 - err = fxrstor_checking((__force struct i387_fxsave_struct *)
14904 + err = fxrstor_checking((struct i387_fxsave_struct __user *)
14905 buf);
14906 if (unlikely(err)) {
14907 /*
14908 diff -urNp linux-2.6.36/arch/x86/kvm/emulate.c linux-2.6.36/arch/x86/kvm/emulate.c
14909 --- linux-2.6.36/arch/x86/kvm/emulate.c 2010-10-20 16:30:22.000000000 -0400
14910 +++ linux-2.6.36/arch/x86/kvm/emulate.c 2010-11-06 18:58:15.000000000 -0400
14911 @@ -92,7 +92,7 @@
14912 #define Src2CL (1<<29)
14913 #define Src2ImmByte (2<<29)
14914 #define Src2One (3<<29)
14915 -#define Src2Mask (7<<29)
14916 +#define Src2Mask (7U<<29)
14917
14918 enum {
14919 Group1_80, Group1_81, Group1_82, Group1_83,
14920 @@ -446,6 +446,7 @@ static u32 group2_table[] = {
14921
14922 #define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix) \
14923 do { \
14924 + unsigned long _tmp; \
14925 __asm__ __volatile__ ( \
14926 _PRE_EFLAGS("0", "4", "2") \
14927 _op _suffix " %"_x"3,%1; " \
14928 @@ -459,8 +460,6 @@ static u32 group2_table[] = {
14929 /* Raw emulation: instruction has two explicit operands. */
14930 #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
14931 do { \
14932 - unsigned long _tmp; \
14933 - \
14934 switch ((_dst).bytes) { \
14935 case 2: \
14936 ____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \
14937 @@ -476,7 +475,6 @@ static u32 group2_table[] = {
14938
14939 #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \
14940 do { \
14941 - unsigned long _tmp; \
14942 switch ((_dst).bytes) { \
14943 case 1: \
14944 ____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b"); \
14945 diff -urNp linux-2.6.36/arch/x86/kvm/lapic.c linux-2.6.36/arch/x86/kvm/lapic.c
14946 --- linux-2.6.36/arch/x86/kvm/lapic.c 2010-10-20 16:30:22.000000000 -0400
14947 +++ linux-2.6.36/arch/x86/kvm/lapic.c 2010-11-06 18:58:15.000000000 -0400
14948 @@ -53,7 +53,7 @@
14949 #define APIC_BUS_CYCLE_NS 1
14950
14951 /* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
14952 -#define apic_debug(fmt, arg...)
14953 +#define apic_debug(fmt, arg...) do {} while (0)
14954
14955 #define APIC_LVT_NUM 6
14956 /* 14 is the version for Xeon and Pentium 8.4.8*/
14957 diff -urNp linux-2.6.36/arch/x86/kvm/svm.c linux-2.6.36/arch/x86/kvm/svm.c
14958 --- linux-2.6.36/arch/x86/kvm/svm.c 2010-10-20 16:30:22.000000000 -0400
14959 +++ linux-2.6.36/arch/x86/kvm/svm.c 2010-11-06 18:58:15.000000000 -0400
14960 @@ -2892,7 +2892,11 @@ static void reload_tss(struct kvm_vcpu *
14961 int cpu = raw_smp_processor_id();
14962
14963 struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
14964 +
14965 + pax_open_kernel();
14966 sd->tss_desc->type = 9; /* available 32/64-bit TSS */
14967 + pax_close_kernel();
14968 +
14969 load_TR_desc();
14970 }
14971
14972 @@ -3443,7 +3447,7 @@ static void svm_fpu_deactivate(struct kv
14973 update_cr0_intercept(svm);
14974 }
14975
14976 -static struct kvm_x86_ops svm_x86_ops = {
14977 +static const struct kvm_x86_ops svm_x86_ops = {
14978 .cpu_has_kvm_support = has_svm,
14979 .disabled_by_bios = is_disabled,
14980 .hardware_setup = svm_hardware_setup,
14981 diff -urNp linux-2.6.36/arch/x86/kvm/vmx.c linux-2.6.36/arch/x86/kvm/vmx.c
14982 --- linux-2.6.36/arch/x86/kvm/vmx.c 2010-10-20 16:30:22.000000000 -0400
14983 +++ linux-2.6.36/arch/x86/kvm/vmx.c 2010-11-06 18:58:15.000000000 -0400
14984 @@ -711,7 +711,11 @@ static void reload_tss(void)
14985
14986 native_store_gdt(&gdt);
14987 descs = (void *)gdt.address;
14988 +
14989 + pax_open_kernel();
14990 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
14991 + pax_close_kernel();
14992 +
14993 load_TR_desc();
14994 }
14995
14996 @@ -1616,8 +1620,11 @@ static __init int hardware_setup(void)
14997 if (!cpu_has_vmx_flexpriority())
14998 flexpriority_enabled = 0;
14999
15000 - if (!cpu_has_vmx_tpr_shadow())
15001 - kvm_x86_ops->update_cr8_intercept = NULL;
15002 + if (!cpu_has_vmx_tpr_shadow()) {
15003 + pax_open_kernel();
15004 + *(void **)&kvm_x86_ops->update_cr8_intercept = NULL;
15005 + pax_close_kernel();
15006 + }
15007
15008 if (enable_ept && !cpu_has_vmx_ept_2m_page())
15009 kvm_disable_largepages();
15010 @@ -2602,7 +2609,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
15011 vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */
15012
15013 asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return));
15014 - vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */
15015 + vmcs_writel(HOST_RIP, ktla_ktva(kvm_vmx_return)); /* 22.2.5 */
15016 vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0);
15017 vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0);
15018 vmcs_write64(VM_EXIT_MSR_LOAD_ADDR, __pa(vmx->msr_autoload.host));
15019 @@ -3985,6 +3992,12 @@ static void vmx_vcpu_run(struct kvm_vcpu
15020 "jmp .Lkvm_vmx_return \n\t"
15021 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
15022 ".Lkvm_vmx_return: "
15023 +
15024 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
15025 + "ljmp %[cs],$.Lkvm_vmx_return2\n\t"
15026 + ".Lkvm_vmx_return2: "
15027 +#endif
15028 +
15029 /* Save guest registers, load host registers, keep flags */
15030 "xchg %0, (%%"R"sp) \n\t"
15031 "mov %%"R"ax, %c[rax](%0) \n\t"
15032 @@ -4031,8 +4044,13 @@ static void vmx_vcpu_run(struct kvm_vcpu
15033 [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
15034 #endif
15035 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
15036 +
15037 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
15038 + ,[cs]"i"(__KERNEL_CS)
15039 +#endif
15040 +
15041 : "cc", "memory"
15042 - , R"bx", R"di", R"si"
15043 + , R"ax", R"bx", R"di", R"si"
15044 #ifdef CONFIG_X86_64
15045 , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
15046 #endif
15047 @@ -4046,7 +4064,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
15048 if (vmx->rmode.irq.pending)
15049 fixup_rmode_irq(vmx);
15050
15051 - asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
15052 + asm("mov %0, %%ds; mov %0, %%es; mov %0, %%ss" : : "r"(__KERNEL_DS));
15053 vmx->launched = 1;
15054
15055 vmx_complete_interrupts(vmx);
15056 @@ -4280,7 +4298,7 @@ static void vmx_set_supported_cpuid(u32
15057 {
15058 }
15059
15060 -static struct kvm_x86_ops vmx_x86_ops = {
15061 +static const struct kvm_x86_ops vmx_x86_ops = {
15062 .cpu_has_kvm_support = cpu_has_kvm_support,
15063 .disabled_by_bios = vmx_disabled_by_bios,
15064 .hardware_setup = hardware_setup,
15065 diff -urNp linux-2.6.36/arch/x86/kvm/x86.c linux-2.6.36/arch/x86/kvm/x86.c
15066 --- linux-2.6.36/arch/x86/kvm/x86.c 2010-10-20 16:30:22.000000000 -0400
15067 +++ linux-2.6.36/arch/x86/kvm/x86.c 2010-11-06 18:58:15.000000000 -0400
15068 @@ -90,7 +90,7 @@ static void update_cr8_intercept(struct
15069 static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
15070 struct kvm_cpuid_entry2 __user *entries);
15071
15072 -struct kvm_x86_ops *kvm_x86_ops;
15073 +const struct kvm_x86_ops *kvm_x86_ops;
15074 EXPORT_SYMBOL_GPL(kvm_x86_ops);
15075
15076 int ignore_msrs = 0;
15077 @@ -116,38 +116,38 @@ static struct kvm_shared_msrs_global __r
15078 static DEFINE_PER_CPU(struct kvm_shared_msrs, shared_msrs);
15079
15080 struct kvm_stats_debugfs_item debugfs_entries[] = {
15081 - { "pf_fixed", VCPU_STAT(pf_fixed) },
15082 - { "pf_guest", VCPU_STAT(pf_guest) },
15083 - { "tlb_flush", VCPU_STAT(tlb_flush) },
15084 - { "invlpg", VCPU_STAT(invlpg) },
15085 - { "exits", VCPU_STAT(exits) },
15086 - { "io_exits", VCPU_STAT(io_exits) },
15087 - { "mmio_exits", VCPU_STAT(mmio_exits) },
15088 - { "signal_exits", VCPU_STAT(signal_exits) },
15089 - { "irq_window", VCPU_STAT(irq_window_exits) },
15090 - { "nmi_window", VCPU_STAT(nmi_window_exits) },
15091 - { "halt_exits", VCPU_STAT(halt_exits) },
15092 - { "halt_wakeup", VCPU_STAT(halt_wakeup) },
15093 - { "hypercalls", VCPU_STAT(hypercalls) },
15094 - { "request_irq", VCPU_STAT(request_irq_exits) },
15095 - { "irq_exits", VCPU_STAT(irq_exits) },
15096 - { "host_state_reload", VCPU_STAT(host_state_reload) },
15097 - { "efer_reload", VCPU_STAT(efer_reload) },
15098 - { "fpu_reload", VCPU_STAT(fpu_reload) },
15099 - { "insn_emulation", VCPU_STAT(insn_emulation) },
15100 - { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
15101 - { "irq_injections", VCPU_STAT(irq_injections) },
15102 - { "nmi_injections", VCPU_STAT(nmi_injections) },
15103 - { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
15104 - { "mmu_pte_write", VM_STAT(mmu_pte_write) },
15105 - { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
15106 - { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
15107 - { "mmu_flooded", VM_STAT(mmu_flooded) },
15108 - { "mmu_recycled", VM_STAT(mmu_recycled) },
15109 - { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
15110 - { "mmu_unsync", VM_STAT(mmu_unsync) },
15111 - { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
15112 - { "largepages", VM_STAT(lpages) },
15113 + { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
15114 + { "pf_guest", VCPU_STAT(pf_guest), NULL },
15115 + { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
15116 + { "invlpg", VCPU_STAT(invlpg), NULL },
15117 + { "exits", VCPU_STAT(exits), NULL },
15118 + { "io_exits", VCPU_STAT(io_exits), NULL },
15119 + { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
15120 + { "signal_exits", VCPU_STAT(signal_exits), NULL },
15121 + { "irq_window", VCPU_STAT(irq_window_exits), NULL },
15122 + { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
15123 + { "halt_exits", VCPU_STAT(halt_exits), NULL },
15124 + { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
15125 + { "hypercalls", VCPU_STAT(hypercalls), NULL },
15126 + { "request_irq", VCPU_STAT(request_irq_exits), NULL },
15127 + { "irq_exits", VCPU_STAT(irq_exits), NULL },
15128 + { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
15129 + { "efer_reload", VCPU_STAT(efer_reload), NULL },
15130 + { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
15131 + { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
15132 + { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
15133 + { "irq_injections", VCPU_STAT(irq_injections), NULL },
15134 + { "nmi_injections", VCPU_STAT(nmi_injections), NULL },
15135 + { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
15136 + { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
15137 + { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
15138 + { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
15139 + { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
15140 + { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
15141 + { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
15142 + { "mmu_unsync", VM_STAT(mmu_unsync), NULL },
15143 + { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
15144 + { "largepages", VM_STAT(lpages), NULL },
15145 { NULL }
15146 };
15147
15148 @@ -1740,6 +1740,8 @@ long kvm_arch_dev_ioctl(struct file *fil
15149 if (n < msr_list.nmsrs)
15150 goto out;
15151 r = -EFAULT;
15152 + if (num_msrs_to_save > ARRAY_SIZE(msrs_to_save))
15153 + goto out;
15154 if (copy_to_user(user_msr_list->indices, &msrs_to_save,
15155 num_msrs_to_save * sizeof(u32)))
15156 goto out;
15157 @@ -2197,7 +2199,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
15158 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
15159 struct kvm_interrupt *irq)
15160 {
15161 - if (irq->irq < 0 || irq->irq >= 256)
15162 + if (irq->irq >= 256)
15163 return -EINVAL;
15164 if (irqchip_in_kernel(vcpu->kvm))
15165 return -ENXIO;
15166 @@ -4214,10 +4216,10 @@ void kvm_after_handle_nmi(struct kvm_vcp
15167 }
15168 EXPORT_SYMBOL_GPL(kvm_after_handle_nmi);
15169
15170 -int kvm_arch_init(void *opaque)
15171 +int kvm_arch_init(const void *opaque)
15172 {
15173 int r;
15174 - struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
15175 + const struct kvm_x86_ops *ops = (const struct kvm_x86_ops *)opaque;
15176
15177 if (kvm_x86_ops) {
15178 printk(KERN_ERR "kvm: already loaded the other module\n");
15179 diff -urNp linux-2.6.36/arch/x86/lib/atomic64_cx8_32.S linux-2.6.36/arch/x86/lib/atomic64_cx8_32.S
15180 --- linux-2.6.36/arch/x86/lib/atomic64_cx8_32.S 2010-10-20 16:30:22.000000000 -0400
15181 +++ linux-2.6.36/arch/x86/lib/atomic64_cx8_32.S 2010-11-06 18:58:15.000000000 -0400
15182 @@ -86,13 +86,23 @@ ENTRY(atomic64_\func\()_return_cx8)
15183 movl %edx, %ecx
15184 \ins\()l %esi, %ebx
15185 \insc\()l %edi, %ecx
15186 +
15187 +#ifdef CONFIG_PAX_REFCOUNT
15188 + into
15189 +2:
15190 + _ASM_EXTABLE(2b, 3f)
15191 +#endif
15192 +
15193 LOCK_PREFIX
15194 cmpxchg8b (%ebp)
15195 jne 1b
15196 -
15197 -10:
15198 movl %ebx, %eax
15199 movl %ecx, %edx
15200 +
15201 +#ifdef CONFIG_PAX_REFCOUNT
15202 +3:
15203 +#endif
15204 +
15205 RESTORE edi
15206 RESTORE esi
15207 RESTORE ebx
15208 @@ -116,13 +126,24 @@ ENTRY(atomic64_\func\()_return_cx8)
15209 movl %edx, %ecx
15210 \ins\()l $1, %ebx
15211 \insc\()l $0, %ecx
15212 +
15213 +#ifdef CONFIG_PAX_REFCOUNT
15214 + into
15215 +2:
15216 + _ASM_EXTABLE(2b, 3f)
15217 +#endif
15218 +
15219 LOCK_PREFIX
15220 cmpxchg8b (%esi)
15221 jne 1b
15222
15223 -10:
15224 movl %ebx, %eax
15225 movl %ecx, %edx
15226 +
15227 +#ifdef CONFIG_PAX_REFCOUNT
15228 +3:
15229 +#endif
15230 +
15231 RESTORE ebx
15232 ret
15233 CFI_ENDPROC
15234 @@ -176,6 +197,13 @@ ENTRY(atomic64_add_unless_cx8)
15235 movl %edx, %ecx
15236 addl %esi, %ebx
15237 adcl %edi, %ecx
15238 +
15239 +#ifdef CONFIG_PAX_REFCOUNT
15240 + into
15241 +1234:
15242 + _ASM_EXTABLE(1234b, 1234b)
15243 +#endif
15244 +
15245 LOCK_PREFIX
15246 cmpxchg8b (%ebp)
15247 jne 1b
15248 @@ -208,6 +236,13 @@ ENTRY(atomic64_inc_not_zero_cx8)
15249 movl %edx, %ecx
15250 addl $1, %ebx
15251 adcl $0, %ecx
15252 +
15253 +#ifdef CONFIG_PAX_REFCOUNT
15254 + into
15255 +1234:
15256 + _ASM_EXTABLE(1234b, 1234b)
15257 +#endif
15258 +
15259 LOCK_PREFIX
15260 cmpxchg8b (%esi)
15261 jne 1b
15262 diff -urNp linux-2.6.36/arch/x86/lib/checksum_32.S linux-2.6.36/arch/x86/lib/checksum_32.S
15263 --- linux-2.6.36/arch/x86/lib/checksum_32.S 2010-10-20 16:30:22.000000000 -0400
15264 +++ linux-2.6.36/arch/x86/lib/checksum_32.S 2010-11-06 18:58:15.000000000 -0400
15265 @@ -28,7 +28,8 @@
15266 #include <linux/linkage.h>
15267 #include <asm/dwarf2.h>
15268 #include <asm/errno.h>
15269 -
15270 +#include <asm/segment.h>
15271 +
15272 /*
15273 * computes a partial checksum, e.g. for TCP/UDP fragments
15274 */
15275 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
15276
15277 #define ARGBASE 16
15278 #define FP 12
15279 -
15280 -ENTRY(csum_partial_copy_generic)
15281 +
15282 +ENTRY(csum_partial_copy_generic_to_user)
15283 CFI_STARTPROC
15284 + pushl $(__USER_DS)
15285 + CFI_ADJUST_CFA_OFFSET 4
15286 + popl %es
15287 + CFI_ADJUST_CFA_OFFSET -4
15288 + jmp csum_partial_copy_generic
15289 +
15290 +ENTRY(csum_partial_copy_generic_from_user)
15291 + pushl $(__USER_DS)
15292 + CFI_ADJUST_CFA_OFFSET 4
15293 + popl %ds
15294 + CFI_ADJUST_CFA_OFFSET -4
15295 +
15296 +ENTRY(csum_partial_copy_generic)
15297 subl $4,%esp
15298 CFI_ADJUST_CFA_OFFSET 4
15299 pushl %edi
15300 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
15301 jmp 4f
15302 SRC(1: movw (%esi), %bx )
15303 addl $2, %esi
15304 -DST( movw %bx, (%edi) )
15305 +DST( movw %bx, %es:(%edi) )
15306 addl $2, %edi
15307 addw %bx, %ax
15308 adcl $0, %eax
15309 @@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
15310 SRC(1: movl (%esi), %ebx )
15311 SRC( movl 4(%esi), %edx )
15312 adcl %ebx, %eax
15313 -DST( movl %ebx, (%edi) )
15314 +DST( movl %ebx, %es:(%edi) )
15315 adcl %edx, %eax
15316 -DST( movl %edx, 4(%edi) )
15317 +DST( movl %edx, %es:4(%edi) )
15318
15319 SRC( movl 8(%esi), %ebx )
15320 SRC( movl 12(%esi), %edx )
15321 adcl %ebx, %eax
15322 -DST( movl %ebx, 8(%edi) )
15323 +DST( movl %ebx, %es:8(%edi) )
15324 adcl %edx, %eax
15325 -DST( movl %edx, 12(%edi) )
15326 +DST( movl %edx, %es:12(%edi) )
15327
15328 SRC( movl 16(%esi), %ebx )
15329 SRC( movl 20(%esi), %edx )
15330 adcl %ebx, %eax
15331 -DST( movl %ebx, 16(%edi) )
15332 +DST( movl %ebx, %es:16(%edi) )
15333 adcl %edx, %eax
15334 -DST( movl %edx, 20(%edi) )
15335 +DST( movl %edx, %es:20(%edi) )
15336
15337 SRC( movl 24(%esi), %ebx )
15338 SRC( movl 28(%esi), %edx )
15339 adcl %ebx, %eax
15340 -DST( movl %ebx, 24(%edi) )
15341 +DST( movl %ebx, %es:24(%edi) )
15342 adcl %edx, %eax
15343 -DST( movl %edx, 28(%edi) )
15344 +DST( movl %edx, %es:28(%edi) )
15345
15346 lea 32(%esi), %esi
15347 lea 32(%edi), %edi
15348 @@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
15349 shrl $2, %edx # This clears CF
15350 SRC(3: movl (%esi), %ebx )
15351 adcl %ebx, %eax
15352 -DST( movl %ebx, (%edi) )
15353 +DST( movl %ebx, %es:(%edi) )
15354 lea 4(%esi), %esi
15355 lea 4(%edi), %edi
15356 dec %edx
15357 @@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
15358 jb 5f
15359 SRC( movw (%esi), %cx )
15360 leal 2(%esi), %esi
15361 -DST( movw %cx, (%edi) )
15362 +DST( movw %cx, %es:(%edi) )
15363 leal 2(%edi), %edi
15364 je 6f
15365 shll $16,%ecx
15366 SRC(5: movb (%esi), %cl )
15367 -DST( movb %cl, (%edi) )
15368 +DST( movb %cl, %es:(%edi) )
15369 6: addl %ecx, %eax
15370 adcl $0, %eax
15371 7:
15372 @@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
15373
15374 6001:
15375 movl ARGBASE+20(%esp), %ebx # src_err_ptr
15376 - movl $-EFAULT, (%ebx)
15377 + movl $-EFAULT, %ss:(%ebx)
15378
15379 # zero the complete destination - computing the rest
15380 # is too much work
15381 @@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
15382
15383 6002:
15384 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
15385 - movl $-EFAULT,(%ebx)
15386 + movl $-EFAULT,%ss:(%ebx)
15387 jmp 5000b
15388
15389 .previous
15390
15391 + pushl %ss
15392 + CFI_ADJUST_CFA_OFFSET 4
15393 + popl %ds
15394 + CFI_ADJUST_CFA_OFFSET -4
15395 + pushl %ss
15396 + CFI_ADJUST_CFA_OFFSET 4
15397 + popl %es
15398 + CFI_ADJUST_CFA_OFFSET -4
15399 popl %ebx
15400 CFI_ADJUST_CFA_OFFSET -4
15401 CFI_RESTORE ebx
15402 @@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
15403 CFI_ADJUST_CFA_OFFSET -4
15404 ret
15405 CFI_ENDPROC
15406 -ENDPROC(csum_partial_copy_generic)
15407 +ENDPROC(csum_partial_copy_generic_to_user)
15408
15409 #else
15410
15411 /* Version for PentiumII/PPro */
15412
15413 #define ROUND1(x) \
15414 + nop; nop; nop; \
15415 SRC(movl x(%esi), %ebx ) ; \
15416 addl %ebx, %eax ; \
15417 - DST(movl %ebx, x(%edi) ) ;
15418 + DST(movl %ebx, %es:x(%edi)) ;
15419
15420 #define ROUND(x) \
15421 + nop; nop; nop; \
15422 SRC(movl x(%esi), %ebx ) ; \
15423 adcl %ebx, %eax ; \
15424 - DST(movl %ebx, x(%edi) ) ;
15425 + DST(movl %ebx, %es:x(%edi)) ;
15426
15427 #define ARGBASE 12
15428 -
15429 -ENTRY(csum_partial_copy_generic)
15430 +
15431 +ENTRY(csum_partial_copy_generic_to_user)
15432 CFI_STARTPROC
15433 + pushl $(__USER_DS)
15434 + CFI_ADJUST_CFA_OFFSET 4
15435 + popl %es
15436 + CFI_ADJUST_CFA_OFFSET -4
15437 + jmp csum_partial_copy_generic
15438 +
15439 +ENTRY(csum_partial_copy_generic_from_user)
15440 + pushl $(__USER_DS)
15441 + CFI_ADJUST_CFA_OFFSET 4
15442 + popl %ds
15443 + CFI_ADJUST_CFA_OFFSET -4
15444 +
15445 +ENTRY(csum_partial_copy_generic)
15446 pushl %ebx
15447 CFI_ADJUST_CFA_OFFSET 4
15448 CFI_REL_OFFSET ebx, 0
15449 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
15450 subl %ebx, %edi
15451 lea -1(%esi),%edx
15452 andl $-32,%edx
15453 - lea 3f(%ebx,%ebx), %ebx
15454 + lea 3f(%ebx,%ebx,2), %ebx
15455 testl %esi, %esi
15456 jmp *%ebx
15457 1: addl $64,%esi
15458 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
15459 jb 5f
15460 SRC( movw (%esi), %dx )
15461 leal 2(%esi), %esi
15462 -DST( movw %dx, (%edi) )
15463 +DST( movw %dx, %es:(%edi) )
15464 leal 2(%edi), %edi
15465 je 6f
15466 shll $16,%edx
15467 5:
15468 SRC( movb (%esi), %dl )
15469 -DST( movb %dl, (%edi) )
15470 +DST( movb %dl, %es:(%edi) )
15471 6: addl %edx, %eax
15472 adcl $0, %eax
15473 7:
15474 .section .fixup, "ax"
15475 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
15476 - movl $-EFAULT, (%ebx)
15477 + movl $-EFAULT, %ss:(%ebx)
15478 # zero the complete destination (computing the rest is too much work)
15479 movl ARGBASE+8(%esp),%edi # dst
15480 movl ARGBASE+12(%esp),%ecx # len
15481 @@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
15482 rep; stosb
15483 jmp 7b
15484 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
15485 - movl $-EFAULT, (%ebx)
15486 + movl $-EFAULT, %ss:(%ebx)
15487 jmp 7b
15488 .previous
15489
15490 + pushl %ss
15491 + CFI_ADJUST_CFA_OFFSET 4
15492 + popl %ds
15493 + CFI_ADJUST_CFA_OFFSET -4
15494 + pushl %ss
15495 + CFI_ADJUST_CFA_OFFSET 4
15496 + popl %es
15497 + CFI_ADJUST_CFA_OFFSET -4
15498 popl %esi
15499 CFI_ADJUST_CFA_OFFSET -4
15500 CFI_RESTORE esi
15501 @@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
15502 CFI_RESTORE ebx
15503 ret
15504 CFI_ENDPROC
15505 -ENDPROC(csum_partial_copy_generic)
15506 +ENDPROC(csum_partial_copy_generic_to_user)
15507
15508 #undef ROUND
15509 #undef ROUND1
15510 diff -urNp linux-2.6.36/arch/x86/lib/clear_page_64.S linux-2.6.36/arch/x86/lib/clear_page_64.S
15511 --- linux-2.6.36/arch/x86/lib/clear_page_64.S 2010-10-20 16:30:22.000000000 -0400
15512 +++ linux-2.6.36/arch/x86/lib/clear_page_64.S 2010-11-06 18:58:15.000000000 -0400
15513 @@ -43,7 +43,7 @@ ENDPROC(clear_page)
15514
15515 #include <asm/cpufeature.h>
15516
15517 - .section .altinstr_replacement,"ax"
15518 + .section .altinstr_replacement,"a"
15519 1: .byte 0xeb /* jmp <disp8> */
15520 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
15521 2:
15522 diff -urNp linux-2.6.36/arch/x86/lib/copy_page_64.S linux-2.6.36/arch/x86/lib/copy_page_64.S
15523 --- linux-2.6.36/arch/x86/lib/copy_page_64.S 2010-10-20 16:30:22.000000000 -0400
15524 +++ linux-2.6.36/arch/x86/lib/copy_page_64.S 2010-11-06 18:58:15.000000000 -0400
15525 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
15526
15527 #include <asm/cpufeature.h>
15528
15529 - .section .altinstr_replacement,"ax"
15530 + .section .altinstr_replacement,"a"
15531 1: .byte 0xeb /* jmp <disp8> */
15532 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
15533 2:
15534 diff -urNp linux-2.6.36/arch/x86/lib/copy_user_64.S linux-2.6.36/arch/x86/lib/copy_user_64.S
15535 --- linux-2.6.36/arch/x86/lib/copy_user_64.S 2010-10-20 16:30:22.000000000 -0400
15536 +++ linux-2.6.36/arch/x86/lib/copy_user_64.S 2010-11-06 18:58:15.000000000 -0400
15537 @@ -15,13 +15,14 @@
15538 #include <asm/asm-offsets.h>
15539 #include <asm/thread_info.h>
15540 #include <asm/cpufeature.h>
15541 +#include <asm/pgtable.h>
15542
15543 .macro ALTERNATIVE_JUMP feature,orig,alt
15544 0:
15545 .byte 0xe9 /* 32bit jump */
15546 .long \orig-1f /* by default jump to orig */
15547 1:
15548 - .section .altinstr_replacement,"ax"
15549 + .section .altinstr_replacement,"a"
15550 2: .byte 0xe9 /* near jump with 32bit immediate */
15551 .long \alt-1b /* offset */ /* or alternatively to alt */
15552 .previous
15553 @@ -64,37 +65,13 @@
15554 #endif
15555 .endm
15556
15557 -/* Standard copy_to_user with segment limit checking */
15558 -ENTRY(_copy_to_user)
15559 - CFI_STARTPROC
15560 - GET_THREAD_INFO(%rax)
15561 - movq %rdi,%rcx
15562 - addq %rdx,%rcx
15563 - jc bad_to_user
15564 - cmpq TI_addr_limit(%rax),%rcx
15565 - jae bad_to_user
15566 - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
15567 - CFI_ENDPROC
15568 -ENDPROC(_copy_to_user)
15569 -
15570 -/* Standard copy_from_user with segment limit checking */
15571 -ENTRY(_copy_from_user)
15572 - CFI_STARTPROC
15573 - GET_THREAD_INFO(%rax)
15574 - movq %rsi,%rcx
15575 - addq %rdx,%rcx
15576 - jc bad_from_user
15577 - cmpq TI_addr_limit(%rax),%rcx
15578 - jae bad_from_user
15579 - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
15580 - CFI_ENDPROC
15581 -ENDPROC(_copy_from_user)
15582 -
15583 .section .fixup,"ax"
15584 /* must zero dest */
15585 ENTRY(bad_from_user)
15586 bad_from_user:
15587 CFI_STARTPROC
15588 + testl %edx,%edx
15589 + js bad_to_user
15590 movl %edx,%ecx
15591 xorl %eax,%eax
15592 rep
15593 diff -urNp linux-2.6.36/arch/x86/lib/copy_user_nocache_64.S linux-2.6.36/arch/x86/lib/copy_user_nocache_64.S
15594 --- linux-2.6.36/arch/x86/lib/copy_user_nocache_64.S 2010-10-20 16:30:22.000000000 -0400
15595 +++ linux-2.6.36/arch/x86/lib/copy_user_nocache_64.S 2010-11-06 18:58:15.000000000 -0400
15596 @@ -14,6 +14,7 @@
15597 #include <asm/current.h>
15598 #include <asm/asm-offsets.h>
15599 #include <asm/thread_info.h>
15600 +#include <asm/pgtable.h>
15601
15602 .macro ALIGN_DESTINATION
15603 #ifdef FIX_ALIGNMENT
15604 @@ -50,6 +51,15 @@
15605 */
15606 ENTRY(__copy_user_nocache)
15607 CFI_STARTPROC
15608 +
15609 +#ifdef CONFIG_PAX_MEMORY_UDEREF
15610 + mov $PAX_USER_SHADOW_BASE,%rcx
15611 + cmp %rcx,%rsi
15612 + jae 1f
15613 + add %rcx,%rsi
15614 +1:
15615 +#endif
15616 +
15617 cmpl $8,%edx
15618 jb 20f /* less then 8 bytes, go to byte copy loop */
15619 ALIGN_DESTINATION
15620 diff -urNp linux-2.6.36/arch/x86/lib/csum-wrappers_64.c linux-2.6.36/arch/x86/lib/csum-wrappers_64.c
15621 --- linux-2.6.36/arch/x86/lib/csum-wrappers_64.c 2010-10-20 16:30:22.000000000 -0400
15622 +++ linux-2.6.36/arch/x86/lib/csum-wrappers_64.c 2010-11-06 18:58:15.000000000 -0400
15623 @@ -52,6 +52,8 @@ csum_partial_copy_from_user(const void _
15624 len -= 2;
15625 }
15626 }
15627 + if ((unsigned long)src < PAX_USER_SHADOW_BASE)
15628 + src += PAX_USER_SHADOW_BASE;
15629 isum = csum_partial_copy_generic((__force const void *)src,
15630 dst, len, isum, errp, NULL);
15631 if (unlikely(*errp))
15632 @@ -105,6 +107,8 @@ csum_partial_copy_to_user(const void *sr
15633 }
15634
15635 *errp = 0;
15636 + if ((unsigned long)dst < PAX_USER_SHADOW_BASE)
15637 + dst += PAX_USER_SHADOW_BASE;
15638 return csum_partial_copy_generic(src, (void __force *)dst,
15639 len, isum, NULL, errp);
15640 }
15641 diff -urNp linux-2.6.36/arch/x86/lib/getuser.S linux-2.6.36/arch/x86/lib/getuser.S
15642 --- linux-2.6.36/arch/x86/lib/getuser.S 2010-10-20 16:30:22.000000000 -0400
15643 +++ linux-2.6.36/arch/x86/lib/getuser.S 2010-11-06 18:58:15.000000000 -0400
15644 @@ -33,14 +33,38 @@
15645 #include <asm/asm-offsets.h>
15646 #include <asm/thread_info.h>
15647 #include <asm/asm.h>
15648 +#include <asm/segment.h>
15649 +#include <asm/pgtable.h>
15650
15651 .text
15652 ENTRY(__get_user_1)
15653 CFI_STARTPROC
15654 +
15655 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
15656 + pushl $(__USER_DS)
15657 + popl %ds
15658 +#else
15659 GET_THREAD_INFO(%_ASM_DX)
15660 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
15661 jae bad_get_user
15662 +
15663 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
15664 + mov $PAX_USER_SHADOW_BASE,%_ASM_DX
15665 + cmp %_ASM_DX,%_ASM_AX
15666 + jae 1234f
15667 + add %_ASM_DX,%_ASM_AX
15668 +1234:
15669 +#endif
15670 +
15671 +#endif
15672 +
15673 1: movzb (%_ASM_AX),%edx
15674 +
15675 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
15676 + pushl %ss
15677 + pop %ds
15678 +#endif
15679 +
15680 xor %eax,%eax
15681 ret
15682 CFI_ENDPROC
15683 @@ -49,11 +73,33 @@ ENDPROC(__get_user_1)
15684 ENTRY(__get_user_2)
15685 CFI_STARTPROC
15686 add $1,%_ASM_AX
15687 +
15688 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
15689 + pushl $(__USER_DS)
15690 + popl %ds
15691 +#else
15692 jc bad_get_user
15693 GET_THREAD_INFO(%_ASM_DX)
15694 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
15695 jae bad_get_user
15696 +
15697 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
15698 + mov $PAX_USER_SHADOW_BASE,%_ASM_DX
15699 + cmp %_ASM_DX,%_ASM_AX
15700 + jae 1234f
15701 + add %_ASM_DX,%_ASM_AX
15702 +1234:
15703 +#endif
15704 +
15705 +#endif
15706 +
15707 2: movzwl -1(%_ASM_AX),%edx
15708 +
15709 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
15710 + pushl %ss
15711 + pop %ds
15712 +#endif
15713 +
15714 xor %eax,%eax
15715 ret
15716 CFI_ENDPROC
15717 @@ -62,11 +108,33 @@ ENDPROC(__get_user_2)
15718 ENTRY(__get_user_4)
15719 CFI_STARTPROC
15720 add $3,%_ASM_AX
15721 +
15722 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
15723 + pushl $(__USER_DS)
15724 + popl %ds
15725 +#else
15726 jc bad_get_user
15727 GET_THREAD_INFO(%_ASM_DX)
15728 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
15729 jae bad_get_user
15730 +
15731 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
15732 + mov $PAX_USER_SHADOW_BASE,%_ASM_DX
15733 + cmp %_ASM_DX,%_ASM_AX
15734 + jae 1234f
15735 + add %_ASM_DX,%_ASM_AX
15736 +1234:
15737 +#endif
15738 +
15739 +#endif
15740 +
15741 3: mov -3(%_ASM_AX),%edx
15742 +
15743 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
15744 + pushl %ss
15745 + pop %ds
15746 +#endif
15747 +
15748 xor %eax,%eax
15749 ret
15750 CFI_ENDPROC
15751 @@ -80,6 +148,15 @@ ENTRY(__get_user_8)
15752 GET_THREAD_INFO(%_ASM_DX)
15753 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
15754 jae bad_get_user
15755 +
15756 +#ifdef CONFIG_PAX_MEMORY_UDEREF
15757 + mov $PAX_USER_SHADOW_BASE,%_ASM_DX
15758 + cmp %_ASM_DX,%_ASM_AX
15759 + jae 1234f
15760 + add %_ASM_DX,%_ASM_AX
15761 +1234:
15762 +#endif
15763 +
15764 4: movq -7(%_ASM_AX),%_ASM_DX
15765 xor %eax,%eax
15766 ret
15767 @@ -89,6 +166,12 @@ ENDPROC(__get_user_8)
15768
15769 bad_get_user:
15770 CFI_STARTPROC
15771 +
15772 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
15773 + pushl %ss
15774 + pop %ds
15775 +#endif
15776 +
15777 xor %edx,%edx
15778 mov $(-EFAULT),%_ASM_AX
15779 ret
15780 diff -urNp linux-2.6.36/arch/x86/lib/insn.c linux-2.6.36/arch/x86/lib/insn.c
15781 --- linux-2.6.36/arch/x86/lib/insn.c 2010-10-20 16:30:22.000000000 -0400
15782 +++ linux-2.6.36/arch/x86/lib/insn.c 2010-11-06 18:58:15.000000000 -0400
15783 @@ -21,6 +21,7 @@
15784 #include <linux/string.h>
15785 #include <asm/inat.h>
15786 #include <asm/insn.h>
15787 +#include <asm/pgtable_types.h>
15788
15789 #define get_next(t, insn) \
15790 ({t r; r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
15791 @@ -40,8 +41,8 @@
15792 void insn_init(struct insn *insn, const void *kaddr, int x86_64)
15793 {
15794 memset(insn, 0, sizeof(*insn));
15795 - insn->kaddr = kaddr;
15796 - insn->next_byte = kaddr;
15797 + insn->kaddr = ktla_ktva(kaddr);
15798 + insn->next_byte = ktla_ktva(kaddr);
15799 insn->x86_64 = x86_64 ? 1 : 0;
15800 insn->opnd_bytes = 4;
15801 if (x86_64)
15802 diff -urNp linux-2.6.36/arch/x86/lib/mmx_32.c linux-2.6.36/arch/x86/lib/mmx_32.c
15803 --- linux-2.6.36/arch/x86/lib/mmx_32.c 2010-10-20 16:30:22.000000000 -0400
15804 +++ linux-2.6.36/arch/x86/lib/mmx_32.c 2010-11-06 18:58:15.000000000 -0400
15805 @@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
15806 {
15807 void *p;
15808 int i;
15809 + unsigned long cr0;
15810
15811 if (unlikely(in_interrupt()))
15812 return __memcpy(to, from, len);
15813 @@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
15814 kernel_fpu_begin();
15815
15816 __asm__ __volatile__ (
15817 - "1: prefetch (%0)\n" /* This set is 28 bytes */
15818 - " prefetch 64(%0)\n"
15819 - " prefetch 128(%0)\n"
15820 - " prefetch 192(%0)\n"
15821 - " prefetch 256(%0)\n"
15822 + "1: prefetch (%1)\n" /* This set is 28 bytes */
15823 + " prefetch 64(%1)\n"
15824 + " prefetch 128(%1)\n"
15825 + " prefetch 192(%1)\n"
15826 + " prefetch 256(%1)\n"
15827 "2: \n"
15828 ".section .fixup, \"ax\"\n"
15829 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
15830 + "3: \n"
15831 +
15832 +#ifdef CONFIG_PAX_KERNEXEC
15833 + " movl %%cr0, %0\n"
15834 + " movl %0, %%eax\n"
15835 + " andl $0xFFFEFFFF, %%eax\n"
15836 + " movl %%eax, %%cr0\n"
15837 +#endif
15838 +
15839 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
15840 +
15841 +#ifdef CONFIG_PAX_KERNEXEC
15842 + " movl %0, %%cr0\n"
15843 +#endif
15844 +
15845 " jmp 2b\n"
15846 ".previous\n"
15847 _ASM_EXTABLE(1b, 3b)
15848 - : : "r" (from));
15849 + : "=&r" (cr0) : "r" (from) : "ax");
15850
15851 for ( ; i > 5; i--) {
15852 __asm__ __volatile__ (
15853 - "1: prefetch 320(%0)\n"
15854 - "2: movq (%0), %%mm0\n"
15855 - " movq 8(%0), %%mm1\n"
15856 - " movq 16(%0), %%mm2\n"
15857 - " movq 24(%0), %%mm3\n"
15858 - " movq %%mm0, (%1)\n"
15859 - " movq %%mm1, 8(%1)\n"
15860 - " movq %%mm2, 16(%1)\n"
15861 - " movq %%mm3, 24(%1)\n"
15862 - " movq 32(%0), %%mm0\n"
15863 - " movq 40(%0), %%mm1\n"
15864 - " movq 48(%0), %%mm2\n"
15865 - " movq 56(%0), %%mm3\n"
15866 - " movq %%mm0, 32(%1)\n"
15867 - " movq %%mm1, 40(%1)\n"
15868 - " movq %%mm2, 48(%1)\n"
15869 - " movq %%mm3, 56(%1)\n"
15870 + "1: prefetch 320(%1)\n"
15871 + "2: movq (%1), %%mm0\n"
15872 + " movq 8(%1), %%mm1\n"
15873 + " movq 16(%1), %%mm2\n"
15874 + " movq 24(%1), %%mm3\n"
15875 + " movq %%mm0, (%2)\n"
15876 + " movq %%mm1, 8(%2)\n"
15877 + " movq %%mm2, 16(%2)\n"
15878 + " movq %%mm3, 24(%2)\n"
15879 + " movq 32(%1), %%mm0\n"
15880 + " movq 40(%1), %%mm1\n"
15881 + " movq 48(%1), %%mm2\n"
15882 + " movq 56(%1), %%mm3\n"
15883 + " movq %%mm0, 32(%2)\n"
15884 + " movq %%mm1, 40(%2)\n"
15885 + " movq %%mm2, 48(%2)\n"
15886 + " movq %%mm3, 56(%2)\n"
15887 ".section .fixup, \"ax\"\n"
15888 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
15889 + "3:\n"
15890 +
15891 +#ifdef CONFIG_PAX_KERNEXEC
15892 + " movl %%cr0, %0\n"
15893 + " movl %0, %%eax\n"
15894 + " andl $0xFFFEFFFF, %%eax\n"
15895 + " movl %%eax, %%cr0\n"
15896 +#endif
15897 +
15898 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
15899 +
15900 +#ifdef CONFIG_PAX_KERNEXEC
15901 + " movl %0, %%cr0\n"
15902 +#endif
15903 +
15904 " jmp 2b\n"
15905 ".previous\n"
15906 _ASM_EXTABLE(1b, 3b)
15907 - : : "r" (from), "r" (to) : "memory");
15908 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
15909
15910 from += 64;
15911 to += 64;
15912 @@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
15913 static void fast_copy_page(void *to, void *from)
15914 {
15915 int i;
15916 + unsigned long cr0;
15917
15918 kernel_fpu_begin();
15919
15920 @@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
15921 * but that is for later. -AV
15922 */
15923 __asm__ __volatile__(
15924 - "1: prefetch (%0)\n"
15925 - " prefetch 64(%0)\n"
15926 - " prefetch 128(%0)\n"
15927 - " prefetch 192(%0)\n"
15928 - " prefetch 256(%0)\n"
15929 + "1: prefetch (%1)\n"
15930 + " prefetch 64(%1)\n"
15931 + " prefetch 128(%1)\n"
15932 + " prefetch 192(%1)\n"
15933 + " prefetch 256(%1)\n"
15934 "2: \n"
15935 ".section .fixup, \"ax\"\n"
15936 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
15937 + "3: \n"
15938 +
15939 +#ifdef CONFIG_PAX_KERNEXEC
15940 + " movl %%cr0, %0\n"
15941 + " movl %0, %%eax\n"
15942 + " andl $0xFFFEFFFF, %%eax\n"
15943 + " movl %%eax, %%cr0\n"
15944 +#endif
15945 +
15946 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
15947 +
15948 +#ifdef CONFIG_PAX_KERNEXEC
15949 + " movl %0, %%cr0\n"
15950 +#endif
15951 +
15952 " jmp 2b\n"
15953 ".previous\n"
15954 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
15955 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
15956
15957 for (i = 0; i < (4096-320)/64; i++) {
15958 __asm__ __volatile__ (
15959 - "1: prefetch 320(%0)\n"
15960 - "2: movq (%0), %%mm0\n"
15961 - " movntq %%mm0, (%1)\n"
15962 - " movq 8(%0), %%mm1\n"
15963 - " movntq %%mm1, 8(%1)\n"
15964 - " movq 16(%0), %%mm2\n"
15965 - " movntq %%mm2, 16(%1)\n"
15966 - " movq 24(%0), %%mm3\n"
15967 - " movntq %%mm3, 24(%1)\n"
15968 - " movq 32(%0), %%mm4\n"
15969 - " movntq %%mm4, 32(%1)\n"
15970 - " movq 40(%0), %%mm5\n"
15971 - " movntq %%mm5, 40(%1)\n"
15972 - " movq 48(%0), %%mm6\n"
15973 - " movntq %%mm6, 48(%1)\n"
15974 - " movq 56(%0), %%mm7\n"
15975 - " movntq %%mm7, 56(%1)\n"
15976 + "1: prefetch 320(%1)\n"
15977 + "2: movq (%1), %%mm0\n"
15978 + " movntq %%mm0, (%2)\n"
15979 + " movq 8(%1), %%mm1\n"
15980 + " movntq %%mm1, 8(%2)\n"
15981 + " movq 16(%1), %%mm2\n"
15982 + " movntq %%mm2, 16(%2)\n"
15983 + " movq 24(%1), %%mm3\n"
15984 + " movntq %%mm3, 24(%2)\n"
15985 + " movq 32(%1), %%mm4\n"
15986 + " movntq %%mm4, 32(%2)\n"
15987 + " movq 40(%1), %%mm5\n"
15988 + " movntq %%mm5, 40(%2)\n"
15989 + " movq 48(%1), %%mm6\n"
15990 + " movntq %%mm6, 48(%2)\n"
15991 + " movq 56(%1), %%mm7\n"
15992 + " movntq %%mm7, 56(%2)\n"
15993 ".section .fixup, \"ax\"\n"
15994 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
15995 + "3:\n"
15996 +
15997 +#ifdef CONFIG_PAX_KERNEXEC
15998 + " movl %%cr0, %0\n"
15999 + " movl %0, %%eax\n"
16000 + " andl $0xFFFEFFFF, %%eax\n"
16001 + " movl %%eax, %%cr0\n"
16002 +#endif
16003 +
16004 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16005 +
16006 +#ifdef CONFIG_PAX_KERNEXEC
16007 + " movl %0, %%cr0\n"
16008 +#endif
16009 +
16010 " jmp 2b\n"
16011 ".previous\n"
16012 - _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
16013 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
16014
16015 from += 64;
16016 to += 64;
16017 @@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
16018 static void fast_copy_page(void *to, void *from)
16019 {
16020 int i;
16021 + unsigned long cr0;
16022
16023 kernel_fpu_begin();
16024
16025 __asm__ __volatile__ (
16026 - "1: prefetch (%0)\n"
16027 - " prefetch 64(%0)\n"
16028 - " prefetch 128(%0)\n"
16029 - " prefetch 192(%0)\n"
16030 - " prefetch 256(%0)\n"
16031 + "1: prefetch (%1)\n"
16032 + " prefetch 64(%1)\n"
16033 + " prefetch 128(%1)\n"
16034 + " prefetch 192(%1)\n"
16035 + " prefetch 256(%1)\n"
16036 "2: \n"
16037 ".section .fixup, \"ax\"\n"
16038 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
16039 + "3: \n"
16040 +
16041 +#ifdef CONFIG_PAX_KERNEXEC
16042 + " movl %%cr0, %0\n"
16043 + " movl %0, %%eax\n"
16044 + " andl $0xFFFEFFFF, %%eax\n"
16045 + " movl %%eax, %%cr0\n"
16046 +#endif
16047 +
16048 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
16049 +
16050 +#ifdef CONFIG_PAX_KERNEXEC
16051 + " movl %0, %%cr0\n"
16052 +#endif
16053 +
16054 " jmp 2b\n"
16055 ".previous\n"
16056 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
16057 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
16058
16059 for (i = 0; i < 4096/64; i++) {
16060 __asm__ __volatile__ (
16061 - "1: prefetch 320(%0)\n"
16062 - "2: movq (%0), %%mm0\n"
16063 - " movq 8(%0), %%mm1\n"
16064 - " movq 16(%0), %%mm2\n"
16065 - " movq 24(%0), %%mm3\n"
16066 - " movq %%mm0, (%1)\n"
16067 - " movq %%mm1, 8(%1)\n"
16068 - " movq %%mm2, 16(%1)\n"
16069 - " movq %%mm3, 24(%1)\n"
16070 - " movq 32(%0), %%mm0\n"
16071 - " movq 40(%0), %%mm1\n"
16072 - " movq 48(%0), %%mm2\n"
16073 - " movq 56(%0), %%mm3\n"
16074 - " movq %%mm0, 32(%1)\n"
16075 - " movq %%mm1, 40(%1)\n"
16076 - " movq %%mm2, 48(%1)\n"
16077 - " movq %%mm3, 56(%1)\n"
16078 + "1: prefetch 320(%1)\n"
16079 + "2: movq (%1), %%mm0\n"
16080 + " movq 8(%1), %%mm1\n"
16081 + " movq 16(%1), %%mm2\n"
16082 + " movq 24(%1), %%mm3\n"
16083 + " movq %%mm0, (%2)\n"
16084 + " movq %%mm1, 8(%2)\n"
16085 + " movq %%mm2, 16(%2)\n"
16086 + " movq %%mm3, 24(%2)\n"
16087 + " movq 32(%1), %%mm0\n"
16088 + " movq 40(%1), %%mm1\n"
16089 + " movq 48(%1), %%mm2\n"
16090 + " movq 56(%1), %%mm3\n"
16091 + " movq %%mm0, 32(%2)\n"
16092 + " movq %%mm1, 40(%2)\n"
16093 + " movq %%mm2, 48(%2)\n"
16094 + " movq %%mm3, 56(%2)\n"
16095 ".section .fixup, \"ax\"\n"
16096 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16097 + "3:\n"
16098 +
16099 +#ifdef CONFIG_PAX_KERNEXEC
16100 + " movl %%cr0, %0\n"
16101 + " movl %0, %%eax\n"
16102 + " andl $0xFFFEFFFF, %%eax\n"
16103 + " movl %%eax, %%cr0\n"
16104 +#endif
16105 +
16106 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
16107 +
16108 +#ifdef CONFIG_PAX_KERNEXEC
16109 + " movl %0, %%cr0\n"
16110 +#endif
16111 +
16112 " jmp 2b\n"
16113 ".previous\n"
16114 _ASM_EXTABLE(1b, 3b)
16115 - : : "r" (from), "r" (to) : "memory");
16116 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
16117
16118 from += 64;
16119 to += 64;
16120 diff -urNp linux-2.6.36/arch/x86/lib/putuser.S linux-2.6.36/arch/x86/lib/putuser.S
16121 --- linux-2.6.36/arch/x86/lib/putuser.S 2010-10-20 16:30:22.000000000 -0400
16122 +++ linux-2.6.36/arch/x86/lib/putuser.S 2010-11-06 18:58:15.000000000 -0400
16123 @@ -15,7 +15,8 @@
16124 #include <asm/thread_info.h>
16125 #include <asm/errno.h>
16126 #include <asm/asm.h>
16127 -
16128 +#include <asm/segment.h>
16129 +#include <asm/pgtable.h>
16130
16131 /*
16132 * __put_user_X
16133 @@ -29,59 +30,162 @@
16134 * as they get called from within inline assembly.
16135 */
16136
16137 -#define ENTER CFI_STARTPROC ; \
16138 - GET_THREAD_INFO(%_ASM_BX)
16139 +#define ENTER CFI_STARTPROC
16140 #define EXIT ret ; \
16141 CFI_ENDPROC
16142
16143 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16144 +#define _DEST %_ASM_CX,%_ASM_BX
16145 +#else
16146 +#define _DEST %_ASM_CX
16147 +#endif
16148 +
16149 .text
16150 ENTRY(__put_user_1)
16151 ENTER
16152 +
16153 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16154 + pushl $(__USER_DS)
16155 + popl %ds
16156 +#else
16157 + GET_THREAD_INFO(%_ASM_BX)
16158 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
16159 jae bad_put_user
16160 -1: movb %al,(%_ASM_CX)
16161 +
16162 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16163 + mov $PAX_USER_SHADOW_BASE,%_ASM_BX
16164 + cmp %_ASM_BX,%_ASM_CX
16165 + jb 1234f
16166 + xor %ebx,%ebx
16167 +1234:
16168 +#endif
16169 +
16170 +#endif
16171 +
16172 +1: movb %al,(_DEST)
16173 +
16174 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16175 + pushl %ss
16176 + popl %ds
16177 +#endif
16178 +
16179 xor %eax,%eax
16180 EXIT
16181 ENDPROC(__put_user_1)
16182
16183 ENTRY(__put_user_2)
16184 ENTER
16185 +
16186 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16187 + pushl $(__USER_DS)
16188 + popl %ds
16189 +#else
16190 + GET_THREAD_INFO(%_ASM_BX)
16191 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
16192 sub $1,%_ASM_BX
16193 cmp %_ASM_BX,%_ASM_CX
16194 jae bad_put_user
16195 -2: movw %ax,(%_ASM_CX)
16196 +
16197 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16198 + mov $PAX_USER_SHADOW_BASE,%_ASM_BX
16199 + cmp %_ASM_BX,%_ASM_CX
16200 + jb 1234f
16201 + xor %ebx,%ebx
16202 +1234:
16203 +#endif
16204 +
16205 +#endif
16206 +
16207 +2: movw %ax,(_DEST)
16208 +
16209 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16210 + pushl %ss
16211 + popl %ds
16212 +#endif
16213 +
16214 xor %eax,%eax
16215 EXIT
16216 ENDPROC(__put_user_2)
16217
16218 ENTRY(__put_user_4)
16219 ENTER
16220 +
16221 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16222 + pushl $(__USER_DS)
16223 + popl %ds
16224 +#else
16225 + GET_THREAD_INFO(%_ASM_BX)
16226 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
16227 sub $3,%_ASM_BX
16228 cmp %_ASM_BX,%_ASM_CX
16229 jae bad_put_user
16230 -3: movl %eax,(%_ASM_CX)
16231 +
16232 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16233 + mov $PAX_USER_SHADOW_BASE,%_ASM_BX
16234 + cmp %_ASM_BX,%_ASM_CX
16235 + jb 1234f
16236 + xor %ebx,%ebx
16237 +1234:
16238 +#endif
16239 +
16240 +#endif
16241 +
16242 +3: movl %eax,(_DEST)
16243 +
16244 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16245 + pushl %ss
16246 + popl %ds
16247 +#endif
16248 +
16249 xor %eax,%eax
16250 EXIT
16251 ENDPROC(__put_user_4)
16252
16253 ENTRY(__put_user_8)
16254 ENTER
16255 +
16256 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16257 + pushl $(__USER_DS)
16258 + popl %ds
16259 +#else
16260 + GET_THREAD_INFO(%_ASM_BX)
16261 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
16262 sub $7,%_ASM_BX
16263 cmp %_ASM_BX,%_ASM_CX
16264 jae bad_put_user
16265 -4: mov %_ASM_AX,(%_ASM_CX)
16266 +
16267 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
16268 + mov $PAX_USER_SHADOW_BASE,%_ASM_BX
16269 + cmp %_ASM_BX,%_ASM_CX
16270 + jb 1234f
16271 + xor %ebx,%ebx
16272 +1234:
16273 +#endif
16274 +
16275 +#endif
16276 +
16277 +4: mov %_ASM_AX,(_DEST)
16278 #ifdef CONFIG_X86_32
16279 -5: movl %edx,4(%_ASM_CX)
16280 +5: movl %edx,4(_DEST)
16281 #endif
16282 +
16283 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16284 + pushl %ss
16285 + popl %ds
16286 +#endif
16287 +
16288 xor %eax,%eax
16289 EXIT
16290 ENDPROC(__put_user_8)
16291
16292 bad_put_user:
16293 CFI_STARTPROC
16294 +
16295 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
16296 + pushl %ss
16297 + popl %ds
16298 +#endif
16299 +
16300 movl $-EFAULT,%eax
16301 EXIT
16302 END(bad_put_user)
16303 diff -urNp linux-2.6.36/arch/x86/lib/usercopy_32.c linux-2.6.36/arch/x86/lib/usercopy_32.c
16304 --- linux-2.6.36/arch/x86/lib/usercopy_32.c 2010-10-20 16:30:22.000000000 -0400
16305 +++ linux-2.6.36/arch/x86/lib/usercopy_32.c 2010-11-06 18:58:15.000000000 -0400
16306 @@ -36,31 +36,38 @@ static inline int __movsl_is_ok(unsigned
16307 * Copy a null terminated string from userspace.
16308 */
16309
16310 -#define __do_strncpy_from_user(dst, src, count, res) \
16311 -do { \
16312 - int __d0, __d1, __d2; \
16313 - might_fault(); \
16314 - __asm__ __volatile__( \
16315 - " testl %1,%1\n" \
16316 - " jz 2f\n" \
16317 - "0: lodsb\n" \
16318 - " stosb\n" \
16319 - " testb %%al,%%al\n" \
16320 - " jz 1f\n" \
16321 - " decl %1\n" \
16322 - " jnz 0b\n" \
16323 - "1: subl %1,%0\n" \
16324 - "2:\n" \
16325 - ".section .fixup,\"ax\"\n" \
16326 - "3: movl %5,%0\n" \
16327 - " jmp 2b\n" \
16328 - ".previous\n" \
16329 - _ASM_EXTABLE(0b,3b) \
16330 - : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \
16331 - "=&D" (__d2) \
16332 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
16333 - : "memory"); \
16334 -} while (0)
16335 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
16336 +{
16337 + int __d0, __d1, __d2;
16338 + long res = -EFAULT;
16339 +
16340 + might_fault();
16341 + __asm__ __volatile__(
16342 + " movw %w10,%%ds\n"
16343 + " testl %1,%1\n"
16344 + " jz 2f\n"
16345 + "0: lodsb\n"
16346 + " stosb\n"
16347 + " testb %%al,%%al\n"
16348 + " jz 1f\n"
16349 + " decl %1\n"
16350 + " jnz 0b\n"
16351 + "1: subl %1,%0\n"
16352 + "2:\n"
16353 + " pushl %%ss\n"
16354 + " popl %%ds\n"
16355 + ".section .fixup,\"ax\"\n"
16356 + "3: movl %5,%0\n"
16357 + " jmp 2b\n"
16358 + ".previous\n"
16359 + _ASM_EXTABLE(0b,3b)
16360 + : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),
16361 + "=&D" (__d2)
16362 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
16363 + "r"(__USER_DS)
16364 + : "memory");
16365 + return res;
16366 +}
16367
16368 /**
16369 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
16370 @@ -85,9 +92,7 @@ do { \
16371 long
16372 __strncpy_from_user(char *dst, const char __user *src, long count)
16373 {
16374 - long res;
16375 - __do_strncpy_from_user(dst, src, count, res);
16376 - return res;
16377 + return __do_strncpy_from_user(dst, src, count);
16378 }
16379 EXPORT_SYMBOL(__strncpy_from_user);
16380
16381 @@ -114,7 +119,7 @@ strncpy_from_user(char *dst, const char
16382 {
16383 long res = -EFAULT;
16384 if (access_ok(VERIFY_READ, src, 1))
16385 - __do_strncpy_from_user(dst, src, count, res);
16386 + res = __do_strncpy_from_user(dst, src, count);
16387 return res;
16388 }
16389 EXPORT_SYMBOL(strncpy_from_user);
16390 @@ -123,24 +128,30 @@ EXPORT_SYMBOL(strncpy_from_user);
16391 * Zero Userspace
16392 */
16393
16394 -#define __do_clear_user(addr,size) \
16395 -do { \
16396 - int __d0; \
16397 - might_fault(); \
16398 - __asm__ __volatile__( \
16399 - "0: rep; stosl\n" \
16400 - " movl %2,%0\n" \
16401 - "1: rep; stosb\n" \
16402 - "2:\n" \
16403 - ".section .fixup,\"ax\"\n" \
16404 - "3: lea 0(%2,%0,4),%0\n" \
16405 - " jmp 2b\n" \
16406 - ".previous\n" \
16407 - _ASM_EXTABLE(0b,3b) \
16408 - _ASM_EXTABLE(1b,2b) \
16409 - : "=&c"(size), "=&D" (__d0) \
16410 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
16411 -} while (0)
16412 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
16413 +{
16414 + int __d0;
16415 +
16416 + might_fault();
16417 + __asm__ __volatile__(
16418 + " movw %w6,%%es\n"
16419 + "0: rep; stosl\n"
16420 + " movl %2,%0\n"
16421 + "1: rep; stosb\n"
16422 + "2:\n"
16423 + " pushl %%ss\n"
16424 + " popl %%es\n"
16425 + ".section .fixup,\"ax\"\n"
16426 + "3: lea 0(%2,%0,4),%0\n"
16427 + " jmp 2b\n"
16428 + ".previous\n"
16429 + _ASM_EXTABLE(0b,3b)
16430 + _ASM_EXTABLE(1b,2b)
16431 + : "=&c"(size), "=&D" (__d0)
16432 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
16433 + "r"(__USER_DS));
16434 + return size;
16435 +}
16436
16437 /**
16438 * clear_user: - Zero a block of memory in user space.
16439 @@ -157,7 +168,7 @@ clear_user(void __user *to, unsigned lon
16440 {
16441 might_fault();
16442 if (access_ok(VERIFY_WRITE, to, n))
16443 - __do_clear_user(to, n);
16444 + n = __do_clear_user(to, n);
16445 return n;
16446 }
16447 EXPORT_SYMBOL(clear_user);
16448 @@ -176,8 +187,7 @@ EXPORT_SYMBOL(clear_user);
16449 unsigned long
16450 __clear_user(void __user *to, unsigned long n)
16451 {
16452 - __do_clear_user(to, n);
16453 - return n;
16454 + return __do_clear_user(to, n);
16455 }
16456 EXPORT_SYMBOL(__clear_user);
16457
16458 @@ -200,14 +210,17 @@ long strnlen_user(const char __user *s,
16459 might_fault();
16460
16461 __asm__ __volatile__(
16462 + " movw %w8,%%es\n"
16463 " testl %0, %0\n"
16464 " jz 3f\n"
16465 - " andl %0,%%ecx\n"
16466 + " movl %0,%%ecx\n"
16467 "0: repne; scasb\n"
16468 " setne %%al\n"
16469 " subl %%ecx,%0\n"
16470 " addl %0,%%eax\n"
16471 "1:\n"
16472 + " pushl %%ss\n"
16473 + " popl %%es\n"
16474 ".section .fixup,\"ax\"\n"
16475 "2: xorl %%eax,%%eax\n"
16476 " jmp 1b\n"
16477 @@ -219,7 +232,7 @@ long strnlen_user(const char __user *s,
16478 " .long 0b,2b\n"
16479 ".previous"
16480 :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
16481 - :"0" (n), "1" (s), "2" (0), "3" (mask)
16482 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
16483 :"cc");
16484 return res & mask;
16485 }
16486 @@ -227,10 +240,121 @@ EXPORT_SYMBOL(strnlen_user);
16487
16488 #ifdef CONFIG_X86_INTEL_USERCOPY
16489 static unsigned long
16490 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
16491 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
16492 +{
16493 + int d0, d1;
16494 + __asm__ __volatile__(
16495 + " movw %w6, %%es\n"
16496 + " .align 2,0x90\n"
16497 + "1: movl 32(%4), %%eax\n"
16498 + " cmpl $67, %0\n"
16499 + " jbe 3f\n"
16500 + "2: movl 64(%4), %%eax\n"
16501 + " .align 2,0x90\n"
16502 + "3: movl 0(%4), %%eax\n"
16503 + "4: movl 4(%4), %%edx\n"
16504 + "5: movl %%eax, %%es:0(%3)\n"
16505 + "6: movl %%edx, %%es:4(%3)\n"
16506 + "7: movl 8(%4), %%eax\n"
16507 + "8: movl 12(%4),%%edx\n"
16508 + "9: movl %%eax, %%es:8(%3)\n"
16509 + "10: movl %%edx, %%es:12(%3)\n"
16510 + "11: movl 16(%4), %%eax\n"
16511 + "12: movl 20(%4), %%edx\n"
16512 + "13: movl %%eax, %%es:16(%3)\n"
16513 + "14: movl %%edx, %%es:20(%3)\n"
16514 + "15: movl 24(%4), %%eax\n"
16515 + "16: movl 28(%4), %%edx\n"
16516 + "17: movl %%eax, %%es:24(%3)\n"
16517 + "18: movl %%edx, %%es:28(%3)\n"
16518 + "19: movl 32(%4), %%eax\n"
16519 + "20: movl 36(%4), %%edx\n"
16520 + "21: movl %%eax, %%es:32(%3)\n"
16521 + "22: movl %%edx, %%es:36(%3)\n"
16522 + "23: movl 40(%4), %%eax\n"
16523 + "24: movl 44(%4), %%edx\n"
16524 + "25: movl %%eax, %%es:40(%3)\n"
16525 + "26: movl %%edx, %%es:44(%3)\n"
16526 + "27: movl 48(%4), %%eax\n"
16527 + "28: movl 52(%4), %%edx\n"
16528 + "29: movl %%eax, %%es:48(%3)\n"
16529 + "30: movl %%edx, %%es:52(%3)\n"
16530 + "31: movl 56(%4), %%eax\n"
16531 + "32: movl 60(%4), %%edx\n"
16532 + "33: movl %%eax, %%es:56(%3)\n"
16533 + "34: movl %%edx, %%es:60(%3)\n"
16534 + " addl $-64, %0\n"
16535 + " addl $64, %4\n"
16536 + " addl $64, %3\n"
16537 + " cmpl $63, %0\n"
16538 + " ja 1b\n"
16539 + "35: movl %0, %%eax\n"
16540 + " shrl $2, %0\n"
16541 + " andl $3, %%eax\n"
16542 + " cld\n"
16543 + "99: rep; movsl\n"
16544 + "36: movl %%eax, %0\n"
16545 + "37: rep; movsb\n"
16546 + "100:\n"
16547 + " pushl %%ss\n"
16548 + " popl %%es\n"
16549 + ".section .fixup,\"ax\"\n"
16550 + "101: lea 0(%%eax,%0,4),%0\n"
16551 + " jmp 100b\n"
16552 + ".previous\n"
16553 + ".section __ex_table,\"a\"\n"
16554 + " .align 4\n"
16555 + " .long 1b,100b\n"
16556 + " .long 2b,100b\n"
16557 + " .long 3b,100b\n"
16558 + " .long 4b,100b\n"
16559 + " .long 5b,100b\n"
16560 + " .long 6b,100b\n"
16561 + " .long 7b,100b\n"
16562 + " .long 8b,100b\n"
16563 + " .long 9b,100b\n"
16564 + " .long 10b,100b\n"
16565 + " .long 11b,100b\n"
16566 + " .long 12b,100b\n"
16567 + " .long 13b,100b\n"
16568 + " .long 14b,100b\n"
16569 + " .long 15b,100b\n"
16570 + " .long 16b,100b\n"
16571 + " .long 17b,100b\n"
16572 + " .long 18b,100b\n"
16573 + " .long 19b,100b\n"
16574 + " .long 20b,100b\n"
16575 + " .long 21b,100b\n"
16576 + " .long 22b,100b\n"
16577 + " .long 23b,100b\n"
16578 + " .long 24b,100b\n"
16579 + " .long 25b,100b\n"
16580 + " .long 26b,100b\n"
16581 + " .long 27b,100b\n"
16582 + " .long 28b,100b\n"
16583 + " .long 29b,100b\n"
16584 + " .long 30b,100b\n"
16585 + " .long 31b,100b\n"
16586 + " .long 32b,100b\n"
16587 + " .long 33b,100b\n"
16588 + " .long 34b,100b\n"
16589 + " .long 35b,100b\n"
16590 + " .long 36b,100b\n"
16591 + " .long 37b,100b\n"
16592 + " .long 99b,101b\n"
16593 + ".previous"
16594 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
16595 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
16596 + : "eax", "edx", "memory");
16597 + return size;
16598 +}
16599 +
16600 +static unsigned long
16601 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
16602 {
16603 int d0, d1;
16604 __asm__ __volatile__(
16605 + " movw %w6, %%ds\n"
16606 " .align 2,0x90\n"
16607 "1: movl 32(%4), %%eax\n"
16608 " cmpl $67, %0\n"
16609 @@ -239,36 +363,36 @@ __copy_user_intel(void __user *to, const
16610 " .align 2,0x90\n"
16611 "3: movl 0(%4), %%eax\n"
16612 "4: movl 4(%4), %%edx\n"
16613 - "5: movl %%eax, 0(%3)\n"
16614 - "6: movl %%edx, 4(%3)\n"
16615 + "5: movl %%eax, %%es:0(%3)\n"
16616 + "6: movl %%edx, %%es:4(%3)\n"
16617 "7: movl 8(%4), %%eax\n"
16618 "8: movl 12(%4),%%edx\n"
16619 - "9: movl %%eax, 8(%3)\n"
16620 - "10: movl %%edx, 12(%3)\n"
16621 + "9: movl %%eax, %%es:8(%3)\n"
16622 + "10: movl %%edx, %%es:12(%3)\n"
16623 "11: movl 16(%4), %%eax\n"
16624 "12: movl 20(%4), %%edx\n"
16625 - "13: movl %%eax, 16(%3)\n"
16626 - "14: movl %%edx, 20(%3)\n"
16627 + "13: movl %%eax, %%es:16(%3)\n"
16628 + "14: movl %%edx, %%es:20(%3)\n"
16629 "15: movl 24(%4), %%eax\n"
16630 "16: movl 28(%4), %%edx\n"
16631 - "17: movl %%eax, 24(%3)\n"
16632 - "18: movl %%edx, 28(%3)\n"
16633 + "17: movl %%eax, %%es:24(%3)\n"
16634 + "18: movl %%edx, %%es:28(%3)\n"
16635 "19: movl 32(%4), %%eax\n"
16636 "20: movl 36(%4), %%edx\n"
16637 - "21: movl %%eax, 32(%3)\n"
16638 - "22: movl %%edx, 36(%3)\n"
16639 + "21: movl %%eax, %%es:32(%3)\n"
16640 + "22: movl %%edx, %%es:36(%3)\n"
16641 "23: movl 40(%4), %%eax\n"
16642 "24: movl 44(%4), %%edx\n"
16643 - "25: movl %%eax, 40(%3)\n"
16644 - "26: movl %%edx, 44(%3)\n"
16645 + "25: movl %%eax, %%es:40(%3)\n"
16646 + "26: movl %%edx, %%es:44(%3)\n"
16647 "27: movl 48(%4), %%eax\n"
16648 "28: movl 52(%4), %%edx\n"
16649 - "29: movl %%eax, 48(%3)\n"
16650 - "30: movl %%edx, 52(%3)\n"
16651 + "29: movl %%eax, %%es:48(%3)\n"
16652 + "30: movl %%edx, %%es:52(%3)\n"
16653 "31: movl 56(%4), %%eax\n"
16654 "32: movl 60(%4), %%edx\n"
16655 - "33: movl %%eax, 56(%3)\n"
16656 - "34: movl %%edx, 60(%3)\n"
16657 + "33: movl %%eax, %%es:56(%3)\n"
16658 + "34: movl %%edx, %%es:60(%3)\n"
16659 " addl $-64, %0\n"
16660 " addl $64, %4\n"
16661 " addl $64, %3\n"
16662 @@ -282,6 +406,8 @@ __copy_user_intel(void __user *to, const
16663 "36: movl %%eax, %0\n"
16664 "37: rep; movsb\n"
16665 "100:\n"
16666 + " pushl %%ss\n"
16667 + " popl %%ds\n"
16668 ".section .fixup,\"ax\"\n"
16669 "101: lea 0(%%eax,%0,4),%0\n"
16670 " jmp 100b\n"
16671 @@ -328,7 +454,7 @@ __copy_user_intel(void __user *to, const
16672 " .long 99b,101b\n"
16673 ".previous"
16674 : "=&c"(size), "=&D" (d0), "=&S" (d1)
16675 - : "1"(to), "2"(from), "0"(size)
16676 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
16677 : "eax", "edx", "memory");
16678 return size;
16679 }
16680 @@ -338,6 +464,7 @@ __copy_user_zeroing_intel(void *to, cons
16681 {
16682 int d0, d1;
16683 __asm__ __volatile__(
16684 + " movw %w6, %%ds\n"
16685 " .align 2,0x90\n"
16686 "0: movl 32(%4), %%eax\n"
16687 " cmpl $67, %0\n"
16688 @@ -346,36 +473,36 @@ __copy_user_zeroing_intel(void *to, cons
16689 " .align 2,0x90\n"
16690 "2: movl 0(%4), %%eax\n"
16691 "21: movl 4(%4), %%edx\n"
16692 - " movl %%eax, 0(%3)\n"
16693 - " movl %%edx, 4(%3)\n"
16694 + " movl %%eax, %%es:0(%3)\n"
16695 + " movl %%edx, %%es:4(%3)\n"
16696 "3: movl 8(%4), %%eax\n"
16697 "31: movl 12(%4),%%edx\n"
16698 - " movl %%eax, 8(%3)\n"
16699 - " movl %%edx, 12(%3)\n"
16700 + " movl %%eax, %%es:8(%3)\n"
16701 + " movl %%edx, %%es:12(%3)\n"
16702 "4: movl 16(%4), %%eax\n"
16703 "41: movl 20(%4), %%edx\n"
16704 - " movl %%eax, 16(%3)\n"
16705 - " movl %%edx, 20(%3)\n"
16706 + " movl %%eax, %%es:16(%3)\n"
16707 + " movl %%edx, %%es:20(%3)\n"
16708 "10: movl 24(%4), %%eax\n"
16709 "51: movl 28(%4), %%edx\n"
16710 - " movl %%eax, 24(%3)\n"
16711 - " movl %%edx, 28(%3)\n"
16712 + " movl %%eax, %%es:24(%3)\n"
16713 + " movl %%edx, %%es:28(%3)\n"
16714 "11: movl 32(%4), %%eax\n"
16715 "61: movl 36(%4), %%edx\n"
16716 - " movl %%eax, 32(%3)\n"
16717 - " movl %%edx, 36(%3)\n"
16718 + " movl %%eax, %%es:32(%3)\n"
16719 + " movl %%edx, %%es:36(%3)\n"
16720 "12: movl 40(%4), %%eax\n"
16721 "71: movl 44(%4), %%edx\n"
16722 - " movl %%eax, 40(%3)\n"
16723 - " movl %%edx, 44(%3)\n"
16724 + " movl %%eax, %%es:40(%3)\n"
16725 + " movl %%edx, %%es:44(%3)\n"
16726 "13: movl 48(%4), %%eax\n"
16727 "81: movl 52(%4), %%edx\n"
16728 - " movl %%eax, 48(%3)\n"
16729 - " movl %%edx, 52(%3)\n"
16730 + " movl %%eax, %%es:48(%3)\n"
16731 + " movl %%edx, %%es:52(%3)\n"
16732 "14: movl 56(%4), %%eax\n"
16733 "91: movl 60(%4), %%edx\n"
16734 - " movl %%eax, 56(%3)\n"
16735 - " movl %%edx, 60(%3)\n"
16736 + " movl %%eax, %%es:56(%3)\n"
16737 + " movl %%edx, %%es:60(%3)\n"
16738 " addl $-64, %0\n"
16739 " addl $64, %4\n"
16740 " addl $64, %3\n"
16741 @@ -389,6 +516,8 @@ __copy_user_zeroing_intel(void *to, cons
16742 " movl %%eax,%0\n"
16743 "7: rep; movsb\n"
16744 "8:\n"
16745 + " pushl %%ss\n"
16746 + " popl %%ds\n"
16747 ".section .fixup,\"ax\"\n"
16748 "9: lea 0(%%eax,%0,4),%0\n"
16749 "16: pushl %0\n"
16750 @@ -423,7 +552,7 @@ __copy_user_zeroing_intel(void *to, cons
16751 " .long 7b,16b\n"
16752 ".previous"
16753 : "=&c"(size), "=&D" (d0), "=&S" (d1)
16754 - : "1"(to), "2"(from), "0"(size)
16755 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
16756 : "eax", "edx", "memory");
16757 return size;
16758 }
16759 @@ -439,6 +568,7 @@ static unsigned long __copy_user_zeroing
16760 int d0, d1;
16761
16762 __asm__ __volatile__(
16763 + " movw %w6, %%ds\n"
16764 " .align 2,0x90\n"
16765 "0: movl 32(%4), %%eax\n"
16766 " cmpl $67, %0\n"
16767 @@ -447,36 +577,36 @@ static unsigned long __copy_user_zeroing
16768 " .align 2,0x90\n"
16769 "2: movl 0(%4), %%eax\n"
16770 "21: movl 4(%4), %%edx\n"
16771 - " movnti %%eax, 0(%3)\n"
16772 - " movnti %%edx, 4(%3)\n"
16773 + " movnti %%eax, %%es:0(%3)\n"
16774 + " movnti %%edx, %%es:4(%3)\n"
16775 "3: movl 8(%4), %%eax\n"
16776 "31: movl 12(%4),%%edx\n"
16777 - " movnti %%eax, 8(%3)\n"
16778 - " movnti %%edx, 12(%3)\n"
16779 + " movnti %%eax, %%es:8(%3)\n"
16780 + " movnti %%edx, %%es:12(%3)\n"
16781 "4: movl 16(%4), %%eax\n"
16782 "41: movl 20(%4), %%edx\n"
16783 - " movnti %%eax, 16(%3)\n"
16784 - " movnti %%edx, 20(%3)\n"
16785 + " movnti %%eax, %%es:16(%3)\n"
16786 + " movnti %%edx, %%es:20(%3)\n"
16787 "10: movl 24(%4), %%eax\n"
16788 "51: movl 28(%4), %%edx\n"
16789 - " movnti %%eax, 24(%3)\n"
16790 - " movnti %%edx, 28(%3)\n"
16791 + " movnti %%eax, %%es:24(%3)\n"
16792 + " movnti %%edx, %%es:28(%3)\n"
16793 "11: movl 32(%4), %%eax\n"
16794 "61: movl 36(%4), %%edx\n"
16795 - " movnti %%eax, 32(%3)\n"
16796 - " movnti %%edx, 36(%3)\n"
16797 + " movnti %%eax, %%es:32(%3)\n"
16798 + " movnti %%edx, %%es:36(%3)\n"
16799 "12: movl 40(%4), %%eax\n"
16800 "71: movl 44(%4), %%edx\n"
16801 - " movnti %%eax, 40(%3)\n"
16802 - " movnti %%edx, 44(%3)\n"
16803 + " movnti %%eax, %%es:40(%3)\n"
16804 + " movnti %%edx, %%es:44(%3)\n"
16805 "13: movl 48(%4), %%eax\n"
16806 "81: movl 52(%4), %%edx\n"
16807 - " movnti %%eax, 48(%3)\n"
16808 - " movnti %%edx, 52(%3)\n"
16809 + " movnti %%eax, %%es:48(%3)\n"
16810 + " movnti %%edx, %%es:52(%3)\n"
16811 "14: movl 56(%4), %%eax\n"
16812 "91: movl 60(%4), %%edx\n"
16813 - " movnti %%eax, 56(%3)\n"
16814 - " movnti %%edx, 60(%3)\n"
16815 + " movnti %%eax, %%es:56(%3)\n"
16816 + " movnti %%edx, %%es:60(%3)\n"
16817 " addl $-64, %0\n"
16818 " addl $64, %4\n"
16819 " addl $64, %3\n"
16820 @@ -491,6 +621,8 @@ static unsigned long __copy_user_zeroing
16821 " movl %%eax,%0\n"
16822 "7: rep; movsb\n"
16823 "8:\n"
16824 + " pushl %%ss\n"
16825 + " popl %%ds\n"
16826 ".section .fixup,\"ax\"\n"
16827 "9: lea 0(%%eax,%0,4),%0\n"
16828 "16: pushl %0\n"
16829 @@ -525,7 +657,7 @@ static unsigned long __copy_user_zeroing
16830 " .long 7b,16b\n"
16831 ".previous"
16832 : "=&c"(size), "=&D" (d0), "=&S" (d1)
16833 - : "1"(to), "2"(from), "0"(size)
16834 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
16835 : "eax", "edx", "memory");
16836 return size;
16837 }
16838 @@ -536,6 +668,7 @@ static unsigned long __copy_user_intel_n
16839 int d0, d1;
16840
16841 __asm__ __volatile__(
16842 + " movw %w6, %%ds\n"
16843 " .align 2,0x90\n"
16844 "0: movl 32(%4), %%eax\n"
16845 " cmpl $67, %0\n"
16846 @@ -544,36 +677,36 @@ static unsigned long __copy_user_intel_n
16847 " .align 2,0x90\n"
16848 "2: movl 0(%4), %%eax\n"
16849 "21: movl 4(%4), %%edx\n"
16850 - " movnti %%eax, 0(%3)\n"
16851 - " movnti %%edx, 4(%3)\n"
16852 + " movnti %%eax, %%es:0(%3)\n"
16853 + " movnti %%edx, %%es:4(%3)\n"
16854 "3: movl 8(%4), %%eax\n"
16855 "31: movl 12(%4),%%edx\n"
16856 - " movnti %%eax, 8(%3)\n"
16857 - " movnti %%edx, 12(%3)\n"
16858 + " movnti %%eax, %%es:8(%3)\n"
16859 + " movnti %%edx, %%es:12(%3)\n"
16860 "4: movl 16(%4), %%eax\n"
16861 "41: movl 20(%4), %%edx\n"
16862 - " movnti %%eax, 16(%3)\n"
16863 - " movnti %%edx, 20(%3)\n"
16864 + " movnti %%eax, %%es:16(%3)\n"
16865 + " movnti %%edx, %%es:20(%3)\n"
16866 "10: movl 24(%4), %%eax\n"
16867 "51: movl 28(%4), %%edx\n"
16868 - " movnti %%eax, 24(%3)\n"
16869 - " movnti %%edx, 28(%3)\n"
16870 + " movnti %%eax, %%es:24(%3)\n"
16871 + " movnti %%edx, %%es:28(%3)\n"
16872 "11: movl 32(%4), %%eax\n"
16873 "61: movl 36(%4), %%edx\n"
16874 - " movnti %%eax, 32(%3)\n"
16875 - " movnti %%edx, 36(%3)\n"
16876 + " movnti %%eax, %%es:32(%3)\n"
16877 + " movnti %%edx, %%es:36(%3)\n"
16878 "12: movl 40(%4), %%eax\n"
16879 "71: movl 44(%4), %%edx\n"
16880 - " movnti %%eax, 40(%3)\n"
16881 - " movnti %%edx, 44(%3)\n"
16882 + " movnti %%eax, %%es:40(%3)\n"
16883 + " movnti %%edx, %%es:44(%3)\n"
16884 "13: movl 48(%4), %%eax\n"
16885 "81: movl 52(%4), %%edx\n"
16886 - " movnti %%eax, 48(%3)\n"
16887 - " movnti %%edx, 52(%3)\n"
16888 + " movnti %%eax, %%es:48(%3)\n"
16889 + " movnti %%edx, %%es:52(%3)\n"
16890 "14: movl 56(%4), %%eax\n"
16891 "91: movl 60(%4), %%edx\n"
16892 - " movnti %%eax, 56(%3)\n"
16893 - " movnti %%edx, 60(%3)\n"
16894 + " movnti %%eax, %%es:56(%3)\n"
16895 + " movnti %%edx, %%es:60(%3)\n"
16896 " addl $-64, %0\n"
16897 " addl $64, %4\n"
16898 " addl $64, %3\n"
16899 @@ -588,6 +721,8 @@ static unsigned long __copy_user_intel_n
16900 " movl %%eax,%0\n"
16901 "7: rep; movsb\n"
16902 "8:\n"
16903 + " pushl %%ss\n"
16904 + " popl %%ds\n"
16905 ".section .fixup,\"ax\"\n"
16906 "9: lea 0(%%eax,%0,4),%0\n"
16907 "16: jmp 8b\n"
16908 @@ -616,7 +751,7 @@ static unsigned long __copy_user_intel_n
16909 " .long 7b,16b\n"
16910 ".previous"
16911 : "=&c"(size), "=&D" (d0), "=&S" (d1)
16912 - : "1"(to), "2"(from), "0"(size)
16913 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
16914 : "eax", "edx", "memory");
16915 return size;
16916 }
16917 @@ -629,90 +764,146 @@ static unsigned long __copy_user_intel_n
16918 */
16919 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
16920 unsigned long size);
16921 -unsigned long __copy_user_intel(void __user *to, const void *from,
16922 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
16923 + unsigned long size);
16924 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
16925 unsigned long size);
16926 unsigned long __copy_user_zeroing_intel_nocache(void *to,
16927 const void __user *from, unsigned long size);
16928 #endif /* CONFIG_X86_INTEL_USERCOPY */
16929
16930 /* Generic arbitrary sized copy. */
16931 -#define __copy_user(to, from, size) \
16932 -do { \
16933 - int __d0, __d1, __d2; \
16934 - __asm__ __volatile__( \
16935 - " cmp $7,%0\n" \
16936 - " jbe 1f\n" \
16937 - " movl %1,%0\n" \
16938 - " negl %0\n" \
16939 - " andl $7,%0\n" \
16940 - " subl %0,%3\n" \
16941 - "4: rep; movsb\n" \
16942 - " movl %3,%0\n" \
16943 - " shrl $2,%0\n" \
16944 - " andl $3,%3\n" \
16945 - " .align 2,0x90\n" \
16946 - "0: rep; movsl\n" \
16947 - " movl %3,%0\n" \
16948 - "1: rep; movsb\n" \
16949 - "2:\n" \
16950 - ".section .fixup,\"ax\"\n" \
16951 - "5: addl %3,%0\n" \
16952 - " jmp 2b\n" \
16953 - "3: lea 0(%3,%0,4),%0\n" \
16954 - " jmp 2b\n" \
16955 - ".previous\n" \
16956 - ".section __ex_table,\"a\"\n" \
16957 - " .align 4\n" \
16958 - " .long 4b,5b\n" \
16959 - " .long 0b,3b\n" \
16960 - " .long 1b,2b\n" \
16961 - ".previous" \
16962 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
16963 - : "3"(size), "0"(size), "1"(to), "2"(from) \
16964 - : "memory"); \
16965 -} while (0)
16966 -
16967 -#define __copy_user_zeroing(to, from, size) \
16968 -do { \
16969 - int __d0, __d1, __d2; \
16970 - __asm__ __volatile__( \
16971 - " cmp $7,%0\n" \
16972 - " jbe 1f\n" \
16973 - " movl %1,%0\n" \
16974 - " negl %0\n" \
16975 - " andl $7,%0\n" \
16976 - " subl %0,%3\n" \
16977 - "4: rep; movsb\n" \
16978 - " movl %3,%0\n" \
16979 - " shrl $2,%0\n" \
16980 - " andl $3,%3\n" \
16981 - " .align 2,0x90\n" \
16982 - "0: rep; movsl\n" \
16983 - " movl %3,%0\n" \
16984 - "1: rep; movsb\n" \
16985 - "2:\n" \
16986 - ".section .fixup,\"ax\"\n" \
16987 - "5: addl %3,%0\n" \
16988 - " jmp 6f\n" \
16989 - "3: lea 0(%3,%0,4),%0\n" \
16990 - "6: pushl %0\n" \
16991 - " pushl %%eax\n" \
16992 - " xorl %%eax,%%eax\n" \
16993 - " rep; stosb\n" \
16994 - " popl %%eax\n" \
16995 - " popl %0\n" \
16996 - " jmp 2b\n" \
16997 - ".previous\n" \
16998 - ".section __ex_table,\"a\"\n" \
16999 - " .align 4\n" \
17000 - " .long 4b,5b\n" \
17001 - " .long 0b,3b\n" \
17002 - " .long 1b,6b\n" \
17003 - ".previous" \
17004 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
17005 - : "3"(size), "0"(size), "1"(to), "2"(from) \
17006 - : "memory"); \
17007 -} while (0)
17008 +static unsigned long
17009 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
17010 +{
17011 + int __d0, __d1, __d2;
17012 +
17013 + __asm__ __volatile__(
17014 + " movw %w8,%%es\n"
17015 + " cmp $7,%0\n"
17016 + " jbe 1f\n"
17017 + " movl %1,%0\n"
17018 + " negl %0\n"
17019 + " andl $7,%0\n"
17020 + " subl %0,%3\n"
17021 + "4: rep; movsb\n"
17022 + " movl %3,%0\n"
17023 + " shrl $2,%0\n"
17024 + " andl $3,%3\n"
17025 + " .align 2,0x90\n"
17026 + "0: rep; movsl\n"
17027 + " movl %3,%0\n"
17028 + "1: rep; movsb\n"
17029 + "2:\n"
17030 + " pushl %%ss\n"
17031 + " popl %%es\n"
17032 + ".section .fixup,\"ax\"\n"
17033 + "5: addl %3,%0\n"
17034 + " jmp 2b\n"
17035 + "3: lea 0(%3,%0,4),%0\n"
17036 + " jmp 2b\n"
17037 + ".previous\n"
17038 + ".section __ex_table,\"a\"\n"
17039 + " .align 4\n"
17040 + " .long 4b,5b\n"
17041 + " .long 0b,3b\n"
17042 + " .long 1b,2b\n"
17043 + ".previous"
17044 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
17045 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
17046 + : "memory");
17047 + return size;
17048 +}
17049 +
17050 +static unsigned long
17051 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
17052 +{
17053 + int __d0, __d1, __d2;
17054 +
17055 + __asm__ __volatile__(
17056 + " movw %w8,%%ds\n"
17057 + " cmp $7,%0\n"
17058 + " jbe 1f\n"
17059 + " movl %1,%0\n"
17060 + " negl %0\n"
17061 + " andl $7,%0\n"
17062 + " subl %0,%3\n"
17063 + "4: rep; movsb\n"
17064 + " movl %3,%0\n"
17065 + " shrl $2,%0\n"
17066 + " andl $3,%3\n"
17067 + " .align 2,0x90\n"
17068 + "0: rep; movsl\n"
17069 + " movl %3,%0\n"
17070 + "1: rep; movsb\n"
17071 + "2:\n"
17072 + " pushl %%ss\n"
17073 + " popl %%ds\n"
17074 + ".section .fixup,\"ax\"\n"
17075 + "5: addl %3,%0\n"
17076 + " jmp 2b\n"
17077 + "3: lea 0(%3,%0,4),%0\n"
17078 + " jmp 2b\n"
17079 + ".previous\n"
17080 + ".section __ex_table,\"a\"\n"
17081 + " .align 4\n"
17082 + " .long 4b,5b\n"
17083 + " .long 0b,3b\n"
17084 + " .long 1b,2b\n"
17085 + ".previous"
17086 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
17087 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
17088 + : "memory");
17089 + return size;
17090 +}
17091 +
17092 +static unsigned long
17093 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
17094 +{
17095 + int __d0, __d1, __d2;
17096 +
17097 + __asm__ __volatile__(
17098 + " movw %w8,%%ds\n"
17099 + " cmp $7,%0\n"
17100 + " jbe 1f\n"
17101 + " movl %1,%0\n"
17102 + " negl %0\n"
17103 + " andl $7,%0\n"
17104 + " subl %0,%3\n"
17105 + "4: rep; movsb\n"
17106 + " movl %3,%0\n"
17107 + " shrl $2,%0\n"
17108 + " andl $3,%3\n"
17109 + " .align 2,0x90\n"
17110 + "0: rep; movsl\n"
17111 + " movl %3,%0\n"
17112 + "1: rep; movsb\n"
17113 + "2:\n"
17114 + " pushl %%ss\n"
17115 + " popl %%ds\n"
17116 + ".section .fixup,\"ax\"\n"
17117 + "5: addl %3,%0\n"
17118 + " jmp 6f\n"
17119 + "3: lea 0(%3,%0,4),%0\n"
17120 + "6: pushl %0\n"
17121 + " pushl %%eax\n"
17122 + " xorl %%eax,%%eax\n"
17123 + " rep; stosb\n"
17124 + " popl %%eax\n"
17125 + " popl %0\n"
17126 + " jmp 2b\n"
17127 + ".previous\n"
17128 + ".section __ex_table,\"a\"\n"
17129 + " .align 4\n"
17130 + " .long 4b,5b\n"
17131 + " .long 0b,3b\n"
17132 + " .long 1b,6b\n"
17133 + ".previous"
17134 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
17135 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
17136 + : "memory");
17137 + return size;
17138 +}
17139
17140 unsigned long __copy_to_user_ll(void __user *to, const void *from,
17141 unsigned long n)
17142 @@ -775,9 +966,9 @@ survive:
17143 }
17144 #endif
17145 if (movsl_is_ok(to, from, n))
17146 - __copy_user(to, from, n);
17147 + n = __generic_copy_to_user(to, from, n);
17148 else
17149 - n = __copy_user_intel(to, from, n);
17150 + n = __generic_copy_to_user_intel(to, from, n);
17151 return n;
17152 }
17153 EXPORT_SYMBOL(__copy_to_user_ll);
17154 @@ -786,7 +977,7 @@ unsigned long __copy_from_user_ll(void *
17155 unsigned long n)
17156 {
17157 if (movsl_is_ok(to, from, n))
17158 - __copy_user_zeroing(to, from, n);
17159 + n = __copy_user_zeroing(to, from, n);
17160 else
17161 n = __copy_user_zeroing_intel(to, from, n);
17162 return n;
17163 @@ -797,10 +988,9 @@ unsigned long __copy_from_user_ll_nozero
17164 unsigned long n)
17165 {
17166 if (movsl_is_ok(to, from, n))
17167 - __copy_user(to, from, n);
17168 + n = __generic_copy_from_user(to, from, n);
17169 else
17170 - n = __copy_user_intel((void __user *)to,
17171 - (const void *)from, n);
17172 + n = __generic_copy_from_user_intel(to, from, n);
17173 return n;
17174 }
17175 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
17176 @@ -812,9 +1002,9 @@ unsigned long __copy_from_user_ll_nocach
17177 if (n > 64 && cpu_has_xmm2)
17178 n = __copy_user_zeroing_intel_nocache(to, from, n);
17179 else
17180 - __copy_user_zeroing(to, from, n);
17181 + n = __copy_user_zeroing(to, from, n);
17182 #else
17183 - __copy_user_zeroing(to, from, n);
17184 + n = __copy_user_zeroing(to, from, n);
17185 #endif
17186 return n;
17187 }
17188 @@ -827,65 +1017,53 @@ unsigned long __copy_from_user_ll_nocach
17189 if (n > 64 && cpu_has_xmm2)
17190 n = __copy_user_intel_nocache(to, from, n);
17191 else
17192 - __copy_user(to, from, n);
17193 + n = __generic_copy_from_user(to, from, n);
17194 #else
17195 - __copy_user(to, from, n);
17196 + n = __generic_copy_from_user(to, from, n);
17197 #endif
17198 return n;
17199 }
17200 EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero);
17201
17202 -/**
17203 - * copy_to_user: - Copy a block of data into user space.
17204 - * @to: Destination address, in user space.
17205 - * @from: Source address, in kernel space.
17206 - * @n: Number of bytes to copy.
17207 - *
17208 - * Context: User context only. This function may sleep.
17209 - *
17210 - * Copy data from kernel space to user space.
17211 - *
17212 - * Returns number of bytes that could not be copied.
17213 - * On success, this will be zero.
17214 - */
17215 -unsigned long
17216 -copy_to_user(void __user *to, const void *from, unsigned long n)
17217 +void copy_from_user_overflow(void)
17218 {
17219 - if (access_ok(VERIFY_WRITE, to, n))
17220 - n = __copy_to_user(to, from, n);
17221 - return n;
17222 + WARN(1, "Buffer overflow detected!\n");
17223 }
17224 -EXPORT_SYMBOL(copy_to_user);
17225 +EXPORT_SYMBOL(copy_from_user_overflow);
17226
17227 -/**
17228 - * copy_from_user: - Copy a block of data from user space.
17229 - * @to: Destination address, in kernel space.
17230 - * @from: Source address, in user space.
17231 - * @n: Number of bytes to copy.
17232 - *
17233 - * Context: User context only. This function may sleep.
17234 - *
17235 - * Copy data from user space to kernel space.
17236 - *
17237 - * Returns number of bytes that could not be copied.
17238 - * On success, this will be zero.
17239 - *
17240 - * If some data could not be copied, this function will pad the copied
17241 - * data to the requested size using zero bytes.
17242 - */
17243 -unsigned long
17244 -_copy_from_user(void *to, const void __user *from, unsigned long n)
17245 +void copy_to_user_overflow(void)
17246 {
17247 - if (access_ok(VERIFY_READ, from, n))
17248 - n = __copy_from_user(to, from, n);
17249 - else
17250 - memset(to, 0, n);
17251 - return n;
17252 + WARN(1, "Buffer overflow detected!\n");
17253 }
17254 -EXPORT_SYMBOL(_copy_from_user);
17255 +EXPORT_SYMBOL(copy_to_user_overflow);
17256
17257 -void copy_from_user_overflow(void)
17258 +#ifdef CONFIG_PAX_MEMORY_UDEREF
17259 +void __set_fs(mm_segment_t x, int cpu)
17260 {
17261 - WARN(1, "Buffer overflow detected!\n");
17262 + unsigned long limit = x.seg;
17263 + struct desc_struct d;
17264 +
17265 + current_thread_info()->addr_limit = x;
17266 + if (unlikely(paravirt_enabled()))
17267 + return;
17268 +
17269 + if (likely(limit))
17270 + limit = (limit - 1UL) >> PAGE_SHIFT;
17271 + pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
17272 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
17273 }
17274 -EXPORT_SYMBOL(copy_from_user_overflow);
17275 +
17276 +void set_fs(mm_segment_t x)
17277 +{
17278 + __set_fs(x, get_cpu());
17279 + put_cpu();
17280 +}
17281 +EXPORT_SYMBOL(copy_from_user);
17282 +#else
17283 +void set_fs(mm_segment_t x)
17284 +{
17285 + current_thread_info()->addr_limit = x;
17286 +}
17287 +#endif
17288 +
17289 +EXPORT_SYMBOL(set_fs);
17290 diff -urNp linux-2.6.36/arch/x86/lib/usercopy_64.c linux-2.6.36/arch/x86/lib/usercopy_64.c
17291 --- linux-2.6.36/arch/x86/lib/usercopy_64.c 2010-10-20 16:30:22.000000000 -0400
17292 +++ linux-2.6.36/arch/x86/lib/usercopy_64.c 2010-11-06 18:58:15.000000000 -0400
17293 @@ -42,6 +42,8 @@ long
17294 __strncpy_from_user(char *dst, const char __user *src, long count)
17295 {
17296 long res;
17297 + if ((unsigned long)src < PAX_USER_SHADOW_BASE)
17298 + src += PAX_USER_SHADOW_BASE;
17299 __do_strncpy_from_user(dst, src, count, res);
17300 return res;
17301 }
17302 @@ -65,6 +67,8 @@ unsigned long __clear_user(void __user *
17303 {
17304 long __d0;
17305 might_fault();
17306 + if ((unsigned long)addr < PAX_USER_SHADOW_BASE)
17307 + addr += PAX_USER_SHADOW_BASE;
17308 /* no memory constraint because it doesn't change any memory gcc knows
17309 about */
17310 asm volatile(
17311 @@ -151,10 +155,14 @@ EXPORT_SYMBOL(strlen_user);
17312
17313 unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
17314 {
17315 - if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {
17316 + if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {
17317 + if ((unsigned long)to < PAX_USER_SHADOW_BASE)
17318 + to += PAX_USER_SHADOW_BASE;
17319 + if ((unsigned long)from < PAX_USER_SHADOW_BASE)
17320 + from += PAX_USER_SHADOW_BASE;
17321 return copy_user_generic((__force void *)to, (__force void *)from, len);
17322 - }
17323 - return len;
17324 + }
17325 + return len;
17326 }
17327 EXPORT_SYMBOL(copy_in_user);
17328
17329 diff -urNp linux-2.6.36/arch/x86/Makefile linux-2.6.36/arch/x86/Makefile
17330 --- linux-2.6.36/arch/x86/Makefile 2010-10-20 16:30:22.000000000 -0400
17331 +++ linux-2.6.36/arch/x86/Makefile 2010-11-06 18:58:15.000000000 -0400
17332 @@ -191,3 +191,12 @@ define archhelp
17333 echo ' FDARGS="..." arguments for the booted kernel'
17334 echo ' FDINITRD=file initrd for the booted kernel'
17335 endef
17336 +
17337 +define OLD_LD
17338 +
17339 +*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
17340 +*** Please upgrade your binutils to 2.18 or newer
17341 +endef
17342 +
17343 +archprepare:
17344 + $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
17345 diff -urNp linux-2.6.36/arch/x86/mm/extable.c linux-2.6.36/arch/x86/mm/extable.c
17346 --- linux-2.6.36/arch/x86/mm/extable.c 2010-10-20 16:30:22.000000000 -0400
17347 +++ linux-2.6.36/arch/x86/mm/extable.c 2010-11-06 18:58:15.000000000 -0400
17348 @@ -1,14 +1,71 @@
17349 #include <linux/module.h>
17350 #include <linux/spinlock.h>
17351 +#include <linux/sort.h>
17352 #include <asm/uaccess.h>
17353 +#include <asm/pgtable.h>
17354
17355 +/*
17356 + * The exception table needs to be sorted so that the binary
17357 + * search that we use to find entries in it works properly.
17358 + * This is used both for the kernel exception table and for
17359 + * the exception tables of modules that get loaded.
17360 + */
17361 +static int cmp_ex(const void *a, const void *b)
17362 +{
17363 + const struct exception_table_entry *x = a, *y = b;
17364 +
17365 + /* avoid overflow */
17366 + if (x->insn > y->insn)
17367 + return 1;
17368 + if (x->insn < y->insn)
17369 + return -1;
17370 + return 0;
17371 +}
17372 +
17373 +static void swap_ex(void *a, void *b, int size)
17374 +{
17375 + struct exception_table_entry t, *x = a, *y = b;
17376 +
17377 + t = *x;
17378 +
17379 + pax_open_kernel();
17380 + *x = *y;
17381 + *y = t;
17382 + pax_close_kernel();
17383 +}
17384 +
17385 +void sort_extable(struct exception_table_entry *start,
17386 + struct exception_table_entry *finish)
17387 +{
17388 + sort(start, finish - start, sizeof(struct exception_table_entry),
17389 + cmp_ex, swap_ex);
17390 +}
17391 +
17392 +#ifdef CONFIG_MODULES
17393 +/*
17394 + * If the exception table is sorted, any referring to the module init
17395 + * will be at the beginning or the end.
17396 + */
17397 +void trim_init_extable(struct module *m)
17398 +{
17399 + /*trim the beginning*/
17400 + while (m->num_exentries && within_module_init(m->extable[0].insn, m)) {
17401 + m->extable++;
17402 + m->num_exentries--;
17403 + }
17404 + /*trim the end*/
17405 + while (m->num_exentries &&
17406 + within_module_init(m->extable[m->num_exentries-1].insn, m))
17407 + m->num_exentries--;
17408 +}
17409 +#endif /* CONFIG_MODULES */
17410
17411 int fixup_exception(struct pt_regs *regs)
17412 {
17413 const struct exception_table_entry *fixup;
17414
17415 #ifdef CONFIG_PNPBIOS
17416 - if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
17417 + if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
17418 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
17419 extern u32 pnp_bios_is_utter_crap;
17420 pnp_bios_is_utter_crap = 1;
17421 diff -urNp linux-2.6.36/arch/x86/mm/fault.c linux-2.6.36/arch/x86/mm/fault.c
17422 --- linux-2.6.36/arch/x86/mm/fault.c 2010-10-20 16:30:22.000000000 -0400
17423 +++ linux-2.6.36/arch/x86/mm/fault.c 2010-11-06 18:58:50.000000000 -0400
17424 @@ -11,10 +11,18 @@
17425 #include <linux/kprobes.h> /* __kprobes, ... */
17426 #include <linux/mmiotrace.h> /* kmmio_handler, ... */
17427 #include <linux/perf_event.h> /* perf_sw_event */
17428 +#include <linux/unistd.h>
17429 +#include <linux/compiler.h>
17430
17431 #include <asm/traps.h> /* dotraplinkage, ... */
17432 #include <asm/pgalloc.h> /* pgd_*(), ... */
17433 #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
17434 +#include <asm/vsyscall.h>
17435 +#include <asm/tlbflush.h>
17436 +
17437 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
17438 +#include <asm/stacktrace.h>
17439 +#endif
17440
17441 /*
17442 * Page fault error code bits:
17443 @@ -52,7 +60,7 @@ static inline int __kprobes notify_page_
17444 int ret = 0;
17445
17446 /* kprobe_running() needs smp_processor_id() */
17447 - if (kprobes_built_in() && !user_mode_vm(regs)) {
17448 + if (kprobes_built_in() && !user_mode(regs)) {
17449 preempt_disable();
17450 if (kprobe_running() && kprobe_fault_handler(regs, 14))
17451 ret = 1;
17452 @@ -173,6 +181,30 @@ force_sig_info_fault(int si_signo, int s
17453 force_sig_info(si_signo, &info, tsk);
17454 }
17455
17456 +#ifdef CONFIG_PAX_EMUTRAMP
17457 +static int pax_handle_fetch_fault(struct pt_regs *regs);
17458 +#endif
17459 +
17460 +#ifdef CONFIG_PAX_PAGEEXEC
17461 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
17462 +{
17463 + pgd_t *pgd;
17464 + pud_t *pud;
17465 + pmd_t *pmd;
17466 +
17467 + pgd = pgd_offset(mm, address);
17468 + if (!pgd_present(*pgd))
17469 + return NULL;
17470 + pud = pud_offset(pgd, address);
17471 + if (!pud_present(*pud))
17472 + return NULL;
17473 + pmd = pmd_offset(pud, address);
17474 + if (!pmd_present(*pmd))
17475 + return NULL;
17476 + return pmd;
17477 +}
17478 +#endif
17479 +
17480 DEFINE_SPINLOCK(pgd_lock);
17481 LIST_HEAD(pgd_list);
17482
17483 @@ -225,11 +257,24 @@ void vmalloc_sync_all(void)
17484 address += PMD_SIZE) {
17485
17486 unsigned long flags;
17487 +
17488 +#ifdef CONFIG_PAX_PER_CPU_PGD
17489 + unsigned long cpu;
17490 +#else
17491 struct page *page;
17492 +#endif
17493
17494 spin_lock_irqsave(&pgd_lock, flags);
17495 +
17496 +#ifdef CONFIG_PAX_PER_CPU_PGD
17497 + for (cpu = 0; cpu < NR_CPUS; ++cpu) {
17498 + pgd_t *pgd = get_cpu_pgd(cpu);
17499 +#else
17500 list_for_each_entry(page, &pgd_list, lru) {
17501 - if (!vmalloc_sync_one(page_address(page), address))
17502 + pgd_t *pgd = page_address(page);
17503 +#endif
17504 +
17505 + if (!vmalloc_sync_one(pgd, address))
17506 break;
17507 }
17508 spin_unlock_irqrestore(&pgd_lock, flags);
17509 @@ -259,6 +304,11 @@ static noinline __kprobes int vmalloc_fa
17510 * an interrupt in the middle of a task switch..
17511 */
17512 pgd_paddr = read_cr3();
17513 +
17514 +#ifdef CONFIG_PAX_PER_CPU_PGD
17515 + BUG_ON(__pa(get_cpu_pgd(smp_processor_id())) != (pgd_paddr & PHYSICAL_PAGE_MASK));
17516 +#endif
17517 +
17518 pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
17519 if (!pmd_k)
17520 return -1;
17521 @@ -333,15 +383,27 @@ void vmalloc_sync_all(void)
17522
17523 const pgd_t *pgd_ref = pgd_offset_k(address);
17524 unsigned long flags;
17525 +
17526 +#ifdef CONFIG_PAX_PER_CPU_PGD
17527 + unsigned long cpu;
17528 +#else
17529 struct page *page;
17530 +#endif
17531
17532 if (pgd_none(*pgd_ref))
17533 continue;
17534
17535 spin_lock_irqsave(&pgd_lock, flags);
17536 +
17537 +#ifdef CONFIG_PAX_PER_CPU_PGD
17538 + for (cpu = 0; cpu < NR_CPUS; ++cpu) {
17539 + pgd_t *pgd = pgd_offset_cpu(cpu, address);
17540 +#else
17541 list_for_each_entry(page, &pgd_list, lru) {
17542 pgd_t *pgd;
17543 pgd = (pgd_t *)page_address(page) + pgd_index(address);
17544 +#endif
17545 +
17546 if (pgd_none(*pgd))
17547 set_pgd(pgd, *pgd_ref);
17548 else
17549 @@ -374,7 +436,14 @@ static noinline __kprobes int vmalloc_fa
17550 * happen within a race in page table update. In the later
17551 * case just flush:
17552 */
17553 +
17554 +#ifdef CONFIG_PAX_PER_CPU_PGD
17555 + BUG_ON(__pa(get_cpu_pgd(smp_processor_id())) != (read_cr3() & PHYSICAL_PAGE_MASK));
17556 + pgd = pgd_offset_cpu(smp_processor_id(), address);
17557 +#else
17558 pgd = pgd_offset(current->active_mm, address);
17559 +#endif
17560 +
17561 pgd_ref = pgd_offset_k(address);
17562 if (pgd_none(*pgd_ref))
17563 return -1;
17564 @@ -536,7 +605,7 @@ static int is_errata93(struct pt_regs *r
17565 static int is_errata100(struct pt_regs *regs, unsigned long address)
17566 {
17567 #ifdef CONFIG_X86_64
17568 - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32))
17569 + if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) && (address >> 32))
17570 return 1;
17571 #endif
17572 return 0;
17573 @@ -563,7 +632,7 @@ static int is_f00f_bug(struct pt_regs *r
17574 }
17575
17576 static const char nx_warning[] = KERN_CRIT
17577 -"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n";
17578 +"kernel tried to execute NX-protected page - exploit attempt? (uid: %d, task: %s, pid: %d)\n";
17579
17580 static void
17581 show_fault_oops(struct pt_regs *regs, unsigned long error_code,
17582 @@ -572,15 +641,26 @@ show_fault_oops(struct pt_regs *regs, un
17583 if (!oops_may_print())
17584 return;
17585
17586 - if (error_code & PF_INSTR) {
17587 + if ((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR)) {
17588 unsigned int level;
17589
17590 pte_t *pte = lookup_address(address, &level);
17591
17592 if (pte && pte_present(*pte) && !pte_exec(*pte))
17593 - printk(nx_warning, current_uid());
17594 + printk(nx_warning, current_uid(), current->comm, task_pid_nr(current));
17595 }
17596
17597 +#ifdef CONFIG_PAX_KERNEXEC
17598 + if (init_mm.start_code <= address && address < init_mm.end_code) {
17599 + if (current->signal->curr_ip)
17600 + printk(KERN_ERR "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
17601 + &current->signal->curr_ip, current->comm, task_pid_nr(current), current_uid(), current_euid());
17602 + else
17603 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
17604 + current->comm, task_pid_nr(current), current_uid(), current_euid());
17605 + }
17606 +#endif
17607 +
17608 printk(KERN_ALERT "BUG: unable to handle kernel ");
17609 if (address < PAGE_SIZE)
17610 printk(KERN_CONT "NULL pointer dereference");
17611 @@ -705,6 +785,68 @@ __bad_area_nosemaphore(struct pt_regs *r
17612 unsigned long address, int si_code)
17613 {
17614 struct task_struct *tsk = current;
17615 + struct mm_struct *mm = tsk->mm;
17616 +
17617 +#ifdef CONFIG_X86_64
17618 + if (mm && (error_code & PF_INSTR) && mm->context.vdso) {
17619 + if (regs->ip == (unsigned long)vgettimeofday) {
17620 + regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_gettimeofday);
17621 + return;
17622 + } else if (regs->ip == (unsigned long)vtime) {
17623 + regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_time);
17624 + return;
17625 + } else if (regs->ip == (unsigned long)vgetcpu) {
17626 + regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, getcpu);
17627 + return;
17628 + }
17629 + }
17630 +#endif
17631 +
17632 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17633 + if (mm && (error_code & PF_USER)) {
17634 + unsigned long ip = regs->ip;
17635 +
17636 + if (v8086_mode(regs))
17637 + ip = ((regs->cs & 0xffff) << 4) + (ip & 0xffff);
17638 +
17639 + /*
17640 + * It's possible to have interrupts off here:
17641 + */
17642 + local_irq_enable();
17643 +
17644 +#ifdef CONFIG_PAX_PAGEEXEC
17645 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
17646 + (((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && ip == address))) {
17647 +
17648 +#ifdef CONFIG_PAX_EMUTRAMP
17649 + switch (pax_handle_fetch_fault(regs)) {
17650 + case 2:
17651 + return;
17652 + }
17653 +#endif
17654 +
17655 + pax_report_fault(regs, (void *)ip, (void *)regs->sp);
17656 + do_group_exit(SIGKILL);
17657 + }
17658 +#endif
17659 +
17660 +#ifdef CONFIG_PAX_SEGMEXEC
17661 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (ip + SEGMEXEC_TASK_SIZE == address)) {
17662 +
17663 +#ifdef CONFIG_PAX_EMUTRAMP
17664 + switch (pax_handle_fetch_fault(regs)) {
17665 + case 2:
17666 + return;
17667 + }
17668 +#endif
17669 +
17670 + pax_report_fault(regs, (void *)ip, (void *)regs->sp);
17671 + do_group_exit(SIGKILL);
17672 + }
17673 +#endif
17674 +
17675 + }
17676 +#endif
17677
17678 /* User mode accesses just cause a SIGSEGV */
17679 if (error_code & PF_USER) {
17680 @@ -851,6 +993,106 @@ static int spurious_fault_check(unsigned
17681 return 1;
17682 }
17683
17684 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
17685 +static int pax_handle_pageexec_fault(struct pt_regs *regs, struct mm_struct *mm, unsigned long address, unsigned long error_code)
17686 +{
17687 + pte_t *pte;
17688 + pmd_t *pmd;
17689 + spinlock_t *ptl;
17690 + unsigned char pte_mask;
17691 +
17692 + if ((__supported_pte_mask & _PAGE_NX) || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
17693 + !(mm->pax_flags & MF_PAX_PAGEEXEC))
17694 + return 0;
17695 +
17696 + /* PaX: it's our fault, let's handle it if we can */
17697 +
17698 + /* PaX: take a look at read faults before acquiring any locks */
17699 + if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
17700 + /* instruction fetch attempt from a protected page in user mode */
17701 + up_read(&mm->mmap_sem);
17702 +
17703 +#ifdef CONFIG_PAX_EMUTRAMP
17704 + switch (pax_handle_fetch_fault(regs)) {
17705 + case 2:
17706 + return 1;
17707 + }
17708 +#endif
17709 +
17710 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
17711 + do_group_exit(SIGKILL);
17712 + }
17713 +
17714 + pmd = pax_get_pmd(mm, address);
17715 + if (unlikely(!pmd))
17716 + return 0;
17717 +
17718 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
17719 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
17720 + pte_unmap_unlock(pte, ptl);
17721 + return 0;
17722 + }
17723 +
17724 + if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
17725 + /* write attempt to a protected page in user mode */
17726 + pte_unmap_unlock(pte, ptl);
17727 + return 0;
17728 + }
17729 +
17730 +#ifdef CONFIG_SMP
17731 + if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
17732 +#else
17733 + if (likely(address > get_limit(regs->cs)))
17734 +#endif
17735 + {
17736 + set_pte(pte, pte_mkread(*pte));
17737 + __flush_tlb_one(address);
17738 + pte_unmap_unlock(pte, ptl);
17739 + up_read(&mm->mmap_sem);
17740 + return 1;
17741 + }
17742 +
17743 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
17744 +
17745 + /*
17746 + * PaX: fill DTLB with user rights and retry
17747 + */
17748 + __asm__ __volatile__ (
17749 +#ifdef CONFIG_PAX_MEMORY_UDEREF
17750 + "movw %w4,%%es\n"
17751 +#endif
17752 + "orb %2,(%1)\n"
17753 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
17754 +/*
17755 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
17756 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
17757 + * page fault when examined during a TLB load attempt. this is true not only
17758 + * for PTEs holding a non-present entry but also present entries that will
17759 + * raise a page fault (such as those set up by PaX, or the copy-on-write
17760 + * mechanism). in effect it means that we do *not* need to flush the TLBs
17761 + * for our target pages since their PTEs are simply not in the TLBs at all.
17762 +
17763 + * the best thing in omitting it is that we gain around 15-20% speed in the
17764 + * fast path of the page fault handler and can get rid of tracing since we
17765 + * can no longer flush unintended entries.
17766 + */
17767 + "invlpg (%0)\n"
17768 +#endif
17769 + "testb $0,%%es:(%0)\n"
17770 + "xorb %3,(%1)\n"
17771 +#ifdef CONFIG_PAX_MEMORY_UDEREF
17772 + "pushl %%ss\n"
17773 + "popl %%es\n"
17774 +#endif
17775 + :
17776 + : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
17777 + : "memory", "cc");
17778 + pte_unmap_unlock(pte, ptl);
17779 + up_read(&mm->mmap_sem);
17780 + return 1;
17781 +}
17782 +#endif
17783 +
17784 /*
17785 * Handle a spurious fault caused by a stale TLB entry.
17786 *
17787 @@ -917,6 +1159,9 @@ int show_unhandled_signals = 1;
17788 static inline int
17789 access_error(unsigned long error_code, int write, struct vm_area_struct *vma)
17790 {
17791 + if ((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
17792 + return 1;
17793 +
17794 if (write) {
17795 /* write, present and write, not present: */
17796 if (unlikely(!(vma->vm_flags & VM_WRITE)))
17797 @@ -950,17 +1195,31 @@ do_page_fault(struct pt_regs *regs, unsi
17798 {
17799 struct vm_area_struct *vma;
17800 struct task_struct *tsk;
17801 - unsigned long address;
17802 struct mm_struct *mm;
17803 int write;
17804 int fault;
17805
17806 + /* Get the faulting address: */
17807 + unsigned long address = read_cr2();
17808 +
17809 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
17810 + if (!user_mode(regs) && address < 2 * PAX_USER_SHADOW_BASE) {
17811 + if (!search_exception_tables(regs->ip)) {
17812 + bad_area_nosemaphore(regs, error_code, address);
17813 + return;
17814 + }
17815 + if (address < PAX_USER_SHADOW_BASE) {
17816 + printk(KERN_ERR "PAX: please report this to pageexec@freemail.hu\n");
17817 + printk(KERN_ERR "PAX: faulting IP: %pS\n", (void *)regs->ip);
17818 + show_trace_log_lvl(NULL, NULL, (void *)regs->sp, regs->bp, KERN_ERR);
17819 + } else
17820 + address -= PAX_USER_SHADOW_BASE;
17821 + }
17822 +#endif
17823 +
17824 tsk = current;
17825 mm = tsk->mm;
17826
17827 - /* Get the faulting address: */
17828 - address = read_cr2();
17829 -
17830 /*
17831 * Detect and handle instructions that would cause a page fault for
17832 * both a tracked kernel page and a userspace page.
17833 @@ -1020,7 +1279,7 @@ do_page_fault(struct pt_regs *regs, unsi
17834 * User-mode registers count as a user access even for any
17835 * potential system fault or CPU buglet:
17836 */
17837 - if (user_mode_vm(regs)) {
17838 + if (user_mode(regs)) {
17839 local_irq_enable();
17840 error_code |= PF_USER;
17841 } else {
17842 @@ -1074,6 +1333,11 @@ do_page_fault(struct pt_regs *regs, unsi
17843 might_sleep();
17844 }
17845
17846 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
17847 + if (pax_handle_pageexec_fault(regs, mm, address, error_code))
17848 + return;
17849 +#endif
17850 +
17851 vma = find_vma(mm, address);
17852 if (unlikely(!vma)) {
17853 bad_area(regs, error_code, address);
17854 @@ -1085,18 +1349,24 @@ do_page_fault(struct pt_regs *regs, unsi
17855 bad_area(regs, error_code, address);
17856 return;
17857 }
17858 - if (error_code & PF_USER) {
17859 - /*
17860 - * Accessing the stack below %sp is always a bug.
17861 - * The large cushion allows instructions like enter
17862 - * and pusha to work. ("enter $65535, $31" pushes
17863 - * 32 pointers and then decrements %sp by 65535.)
17864 - */
17865 - if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
17866 - bad_area(regs, error_code, address);
17867 - return;
17868 - }
17869 + /*
17870 + * Accessing the stack below %sp is always a bug.
17871 + * The large cushion allows instructions like enter
17872 + * and pusha to work. ("enter $65535, $31" pushes
17873 + * 32 pointers and then decrements %sp by 65535.)
17874 + */
17875 + if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < task_pt_regs(tsk)->sp)) {
17876 + bad_area(regs, error_code, address);
17877 + return;
17878 }
17879 +
17880 +#ifdef CONFIG_PAX_SEGMEXEC
17881 + if (unlikely((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)) {
17882 + bad_area(regs, error_code, address);
17883 + return;
17884 + }
17885 +#endif
17886 +
17887 if (unlikely(expand_stack(vma, address))) {
17888 bad_area(regs, error_code, address);
17889 return;
17890 @@ -1140,3 +1410,199 @@ good_area:
17891
17892 up_read(&mm->mmap_sem);
17893 }
17894 +
17895 +#ifdef CONFIG_PAX_EMUTRAMP
17896 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
17897 +{
17898 + int err;
17899 +
17900 + do { /* PaX: gcc trampoline emulation #1 */
17901 + unsigned char mov1, mov2;
17902 + unsigned short jmp;
17903 + unsigned int addr1, addr2;
17904 +
17905 +#ifdef CONFIG_X86_64
17906 + if ((regs->ip + 11) >> 32)
17907 + break;
17908 +#endif
17909 +
17910 + err = get_user(mov1, (unsigned char __user *)regs->ip);
17911 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
17912 + err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
17913 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
17914 + err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
17915 +
17916 + if (err)
17917 + break;
17918 +
17919 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
17920 + regs->cx = addr1;
17921 + regs->ax = addr2;
17922 + regs->ip = addr2;
17923 + return 2;
17924 + }
17925 + } while (0);
17926 +
17927 + do { /* PaX: gcc trampoline emulation #2 */
17928 + unsigned char mov, jmp;
17929 + unsigned int addr1, addr2;
17930 +
17931 +#ifdef CONFIG_X86_64
17932 + if ((regs->ip + 9) >> 32)
17933 + break;
17934 +#endif
17935 +
17936 + err = get_user(mov, (unsigned char __user *)regs->ip);
17937 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
17938 + err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
17939 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
17940 +
17941 + if (err)
17942 + break;
17943 +
17944 + if (mov == 0xB9 && jmp == 0xE9) {
17945 + regs->cx = addr1;
17946 + regs->ip = (unsigned int)(regs->ip + addr2 + 10);
17947 + return 2;
17948 + }
17949 + } while (0);
17950 +
17951 + return 1; /* PaX in action */
17952 +}
17953 +
17954 +#ifdef CONFIG_X86_64
17955 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
17956 +{
17957 + int err;
17958 +
17959 + do { /* PaX: gcc trampoline emulation #1 */
17960 + unsigned short mov1, mov2, jmp1;
17961 + unsigned char jmp2;
17962 + unsigned int addr1;
17963 + unsigned long addr2;
17964 +
17965 + err = get_user(mov1, (unsigned short __user *)regs->ip);
17966 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
17967 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
17968 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
17969 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
17970 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
17971 +
17972 + if (err)
17973 + break;
17974 +
17975 + if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
17976 + regs->r11 = addr1;
17977 + regs->r10 = addr2;
17978 + regs->ip = addr1;
17979 + return 2;
17980 + }
17981 + } while (0);
17982 +
17983 + do { /* PaX: gcc trampoline emulation #2 */
17984 + unsigned short mov1, mov2, jmp1;
17985 + unsigned char jmp2;
17986 + unsigned long addr1, addr2;
17987 +
17988 + err = get_user(mov1, (unsigned short __user *)regs->ip);
17989 + err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
17990 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
17991 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
17992 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
17993 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
17994 +
17995 + if (err)
17996 + break;
17997 +
17998 + if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
17999 + regs->r11 = addr1;
18000 + regs->r10 = addr2;
18001 + regs->ip = addr1;
18002 + return 2;
18003 + }
18004 + } while (0);
18005 +
18006 + return 1; /* PaX in action */
18007 +}
18008 +#endif
18009 +
18010 +/*
18011 + * PaX: decide what to do with offenders (regs->ip = fault address)
18012 + *
18013 + * returns 1 when task should be killed
18014 + * 2 when gcc trampoline was detected
18015 + */
18016 +static int pax_handle_fetch_fault(struct pt_regs *regs)
18017 +{
18018 + if (v8086_mode(regs))
18019 + return 1;
18020 +
18021 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
18022 + return 1;
18023 +
18024 +#ifdef CONFIG_X86_32
18025 + return pax_handle_fetch_fault_32(regs);
18026 +#else
18027 + if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
18028 + return pax_handle_fetch_fault_32(regs);
18029 + else
18030 + return pax_handle_fetch_fault_64(regs);
18031 +#endif
18032 +}
18033 +#endif
18034 +
18035 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18036 +void pax_report_insns(void *pc, void *sp)
18037 +{
18038 + long i;
18039 +
18040 + printk(KERN_ERR "PAX: bytes at PC: ");
18041 + for (i = 0; i < 20; i++) {
18042 + unsigned char c;
18043 + if (get_user(c, (__force unsigned char __user *)pc+i))
18044 + printk(KERN_CONT "?? ");
18045 + else
18046 + printk(KERN_CONT "%02x ", c);
18047 + }
18048 + printk("\n");
18049 +
18050 + printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
18051 + for (i = -1; i < 80 / (long)sizeof(long); i++) {
18052 + unsigned long c;
18053 + if (get_user(c, (__force unsigned long __user *)sp+i))
18054 +#ifdef CONFIG_X86_32
18055 + printk(KERN_CONT "???????? ");
18056 +#else
18057 + printk(KERN_CONT "???????????????? ");
18058 +#endif
18059 + else
18060 + printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
18061 + }
18062 + printk("\n");
18063 +}
18064 +#endif
18065 +
18066 +/**
18067 + * probe_kernel_write(): safely attempt to write to a location
18068 + * @dst: address to write to
18069 + * @src: pointer to the data that shall be written
18070 + * @size: size of the data chunk
18071 + *
18072 + * Safely write to address @dst from the buffer at @src. If a kernel fault
18073 + * happens, handle that and return -EFAULT.
18074 + */
18075 +long notrace probe_kernel_write(void *dst, const void *src, size_t size)
18076 +{
18077 + long ret;
18078 + mm_segment_t old_fs = get_fs();
18079 +
18080 + set_fs(KERNEL_DS);
18081 + pagefault_disable();
18082 + pax_open_kernel();
18083 + ret = __copy_to_user_inatomic((__force void __user *)dst, src, size);
18084 + pax_close_kernel();
18085 + pagefault_enable();
18086 + set_fs(old_fs);
18087 +
18088 + return ret ? -EFAULT : 0;
18089 +}
18090 diff -urNp linux-2.6.36/arch/x86/mm/gup.c linux-2.6.36/arch/x86/mm/gup.c
18091 --- linux-2.6.36/arch/x86/mm/gup.c 2010-10-20 16:30:22.000000000 -0400
18092 +++ linux-2.6.36/arch/x86/mm/gup.c 2010-11-06 18:58:15.000000000 -0400
18093 @@ -237,7 +237,7 @@ int __get_user_pages_fast(unsigned long
18094 addr = start;
18095 len = (unsigned long) nr_pages << PAGE_SHIFT;
18096 end = start + len;
18097 - if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
18098 + if (unlikely(!__access_ok(write ? VERIFY_WRITE : VERIFY_READ,
18099 (void __user *)start, len)))
18100 return 0;
18101
18102 diff -urNp linux-2.6.36/arch/x86/mm/highmem_32.c linux-2.6.36/arch/x86/mm/highmem_32.c
18103 --- linux-2.6.36/arch/x86/mm/highmem_32.c 2010-10-20 16:30:22.000000000 -0400
18104 +++ linux-2.6.36/arch/x86/mm/highmem_32.c 2010-11-06 18:58:15.000000000 -0400
18105 @@ -43,7 +43,10 @@ void *kmap_atomic_prot(struct page *page
18106 idx = type + KM_TYPE_NR*smp_processor_id();
18107 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
18108 BUG_ON(!pte_none(*(kmap_pte-idx)));
18109 +
18110 + pax_open_kernel();
18111 set_pte(kmap_pte-idx, mk_pte(page, prot));
18112 + pax_close_kernel();
18113
18114 return (void *)vaddr;
18115 }
18116 diff -urNp linux-2.6.36/arch/x86/mm/hugetlbpage.c linux-2.6.36/arch/x86/mm/hugetlbpage.c
18117 --- linux-2.6.36/arch/x86/mm/hugetlbpage.c 2010-10-20 16:30:22.000000000 -0400
18118 +++ linux-2.6.36/arch/x86/mm/hugetlbpage.c 2010-11-06 18:58:15.000000000 -0400
18119 @@ -266,13 +266,20 @@ static unsigned long hugetlb_get_unmappe
18120 struct hstate *h = hstate_file(file);
18121 struct mm_struct *mm = current->mm;
18122 struct vm_area_struct *vma;
18123 - unsigned long start_addr;
18124 + unsigned long start_addr, pax_task_size = TASK_SIZE;
18125 +
18126 +#ifdef CONFIG_PAX_SEGMEXEC
18127 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
18128 + pax_task_size = SEGMEXEC_TASK_SIZE;
18129 +#endif
18130 +
18131 + pax_task_size -= PAGE_SIZE;
18132
18133 if (len > mm->cached_hole_size) {
18134 - start_addr = mm->free_area_cache;
18135 + start_addr = mm->free_area_cache;
18136 } else {
18137 - start_addr = TASK_UNMAPPED_BASE;
18138 - mm->cached_hole_size = 0;
18139 + start_addr = mm->mmap_base;
18140 + mm->cached_hole_size = 0;
18141 }
18142
18143 full_search:
18144 @@ -280,26 +287,27 @@ full_search:
18145
18146 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
18147 /* At this point: (!vma || addr < vma->vm_end). */
18148 - if (TASK_SIZE - len < addr) {
18149 + if (pax_task_size - len < addr) {
18150 /*
18151 * Start a new search - just in case we missed
18152 * some holes.
18153 */
18154 - if (start_addr != TASK_UNMAPPED_BASE) {
18155 - start_addr = TASK_UNMAPPED_BASE;
18156 + if (start_addr != mm->mmap_base) {
18157 + start_addr = mm->mmap_base;
18158 mm->cached_hole_size = 0;
18159 goto full_search;
18160 }
18161 return -ENOMEM;
18162 }
18163 - if (!vma || addr + len <= vma->vm_start) {
18164 - mm->free_area_cache = addr + len;
18165 - return addr;
18166 - }
18167 + if (check_heap_stack_gap(vma, addr, len))
18168 + break;
18169 if (addr + mm->cached_hole_size < vma->vm_start)
18170 mm->cached_hole_size = vma->vm_start - addr;
18171 addr = ALIGN(vma->vm_end, huge_page_size(h));
18172 }
18173 +
18174 + mm->free_area_cache = addr + len;
18175 + return addr;
18176 }
18177
18178 static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
18179 @@ -308,10 +316,9 @@ static unsigned long hugetlb_get_unmappe
18180 {
18181 struct hstate *h = hstate_file(file);
18182 struct mm_struct *mm = current->mm;
18183 - struct vm_area_struct *vma, *prev_vma;
18184 - unsigned long base = mm->mmap_base, addr = addr0;
18185 + struct vm_area_struct *vma;
18186 + unsigned long base = mm->mmap_base, addr;
18187 unsigned long largest_hole = mm->cached_hole_size;
18188 - int first_time = 1;
18189
18190 /* don't allow allocations above current base */
18191 if (mm->free_area_cache > base)
18192 @@ -321,7 +328,7 @@ static unsigned long hugetlb_get_unmappe
18193 largest_hole = 0;
18194 mm->free_area_cache = base;
18195 }
18196 -try_again:
18197 +
18198 /* make sure it can fit in the remaining address space */
18199 if (mm->free_area_cache < len)
18200 goto fail;
18201 @@ -329,33 +336,27 @@ try_again:
18202 /* either no address requested or cant fit in requested address hole */
18203 addr = (mm->free_area_cache - len) & huge_page_mask(h);
18204 do {
18205 + vma = find_vma(mm, addr);
18206 /*
18207 * Lookup failure means no vma is above this address,
18208 * i.e. return with success:
18209 - */
18210 - if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
18211 - return addr;
18212 -
18213 - /*
18214 * new region fits between prev_vma->vm_end and
18215 * vma->vm_start, use it:
18216 */
18217 - if (addr + len <= vma->vm_start &&
18218 - (!prev_vma || (addr >= prev_vma->vm_end))) {
18219 + if (check_heap_stack_gap(vma, addr, len)) {
18220 /* remember the address as a hint for next time */
18221 - mm->cached_hole_size = largest_hole;
18222 - return (mm->free_area_cache = addr);
18223 - } else {
18224 - /* pull free_area_cache down to the first hole */
18225 - if (mm->free_area_cache == vma->vm_end) {
18226 - mm->free_area_cache = vma->vm_start;
18227 - mm->cached_hole_size = largest_hole;
18228 - }
18229 + mm->cached_hole_size = largest_hole;
18230 + return (mm->free_area_cache = addr);
18231 + }
18232 + /* pull free_area_cache down to the first hole */
18233 + if (mm->free_area_cache == vma->vm_end) {
18234 + mm->free_area_cache = vma->vm_start;
18235 + mm->cached_hole_size = largest_hole;
18236 }
18237
18238 /* remember the largest hole we saw so far */
18239 if (addr + largest_hole < vma->vm_start)
18240 - largest_hole = vma->vm_start - addr;
18241 + largest_hole = vma->vm_start - addr;
18242
18243 /* try just below the current vma->vm_start */
18244 addr = (vma->vm_start - len) & huge_page_mask(h);
18245 @@ -363,22 +364,26 @@ try_again:
18246
18247 fail:
18248 /*
18249 - * if hint left us with no space for the requested
18250 - * mapping then try again:
18251 - */
18252 - if (first_time) {
18253 - mm->free_area_cache = base;
18254 - largest_hole = 0;
18255 - first_time = 0;
18256 - goto try_again;
18257 - }
18258 - /*
18259 * A failed mmap() very likely causes application failure,
18260 * so fall back to the bottom-up function here. This scenario
18261 * can happen with large stack limits and large mmap()
18262 * allocations.
18263 */
18264 - mm->free_area_cache = TASK_UNMAPPED_BASE;
18265 +
18266 +#ifdef CONFIG_PAX_SEGMEXEC
18267 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
18268 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
18269 + else
18270 +#endif
18271 +
18272 + mm->mmap_base = TASK_UNMAPPED_BASE;
18273 +
18274 +#ifdef CONFIG_PAX_RANDMMAP
18275 + if (mm->pax_flags & MF_PAX_RANDMMAP)
18276 + mm->mmap_base += mm->delta_mmap;
18277 +#endif
18278 +
18279 + mm->free_area_cache = mm->mmap_base;
18280 mm->cached_hole_size = ~0UL;
18281 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
18282 len, pgoff, flags);
18283 @@ -386,6 +391,7 @@ fail:
18284 /*
18285 * Restore the topdown base:
18286 */
18287 + mm->mmap_base = base;
18288 mm->free_area_cache = base;
18289 mm->cached_hole_size = ~0UL;
18290
18291 @@ -399,10 +405,19 @@ hugetlb_get_unmapped_area(struct file *f
18292 struct hstate *h = hstate_file(file);
18293 struct mm_struct *mm = current->mm;
18294 struct vm_area_struct *vma;
18295 + unsigned long pax_task_size = TASK_SIZE;
18296
18297 if (len & ~huge_page_mask(h))
18298 return -EINVAL;
18299 - if (len > TASK_SIZE)
18300 +
18301 +#ifdef CONFIG_PAX_SEGMEXEC
18302 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
18303 + pax_task_size = SEGMEXEC_TASK_SIZE;
18304 +#endif
18305 +
18306 + pax_task_size -= PAGE_SIZE;
18307 +
18308 + if (len > pax_task_size)
18309 return -ENOMEM;
18310
18311 if (flags & MAP_FIXED) {
18312 @@ -414,8 +429,7 @@ hugetlb_get_unmapped_area(struct file *f
18313 if (addr) {
18314 addr = ALIGN(addr, huge_page_size(h));
18315 vma = find_vma(mm, addr);
18316 - if (TASK_SIZE - len >= addr &&
18317 - (!vma || addr + len <= vma->vm_start))
18318 + if (pax_task_size - len >= addr && check_heap_stack_gap(vma, addr, len))
18319 return addr;
18320 }
18321 if (mm->get_unmapped_area == arch_get_unmapped_area)
18322 diff -urNp linux-2.6.36/arch/x86/mm/init_32.c linux-2.6.36/arch/x86/mm/init_32.c
18323 --- linux-2.6.36/arch/x86/mm/init_32.c 2010-10-20 16:30:22.000000000 -0400
18324 +++ linux-2.6.36/arch/x86/mm/init_32.c 2010-11-06 18:58:15.000000000 -0400
18325 @@ -72,36 +72,6 @@ static __init void *alloc_low_page(void)
18326 }
18327
18328 /*
18329 - * Creates a middle page table and puts a pointer to it in the
18330 - * given global directory entry. This only returns the gd entry
18331 - * in non-PAE compilation mode, since the middle layer is folded.
18332 - */
18333 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
18334 -{
18335 - pud_t *pud;
18336 - pmd_t *pmd_table;
18337 -
18338 -#ifdef CONFIG_X86_PAE
18339 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
18340 - if (after_bootmem)
18341 - pmd_table = (pmd_t *)alloc_bootmem_pages(PAGE_SIZE);
18342 - else
18343 - pmd_table = (pmd_t *)alloc_low_page();
18344 - paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
18345 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
18346 - pud = pud_offset(pgd, 0);
18347 - BUG_ON(pmd_table != pmd_offset(pud, 0));
18348 -
18349 - return pmd_table;
18350 - }
18351 -#endif
18352 - pud = pud_offset(pgd, 0);
18353 - pmd_table = pmd_offset(pud, 0);
18354 -
18355 - return pmd_table;
18356 -}
18357 -
18358 -/*
18359 * Create a page table and place a pointer to it in a middle page
18360 * directory entry:
18361 */
18362 @@ -121,13 +91,28 @@ static pte_t * __init one_page_table_ini
18363 page_table = (pte_t *)alloc_low_page();
18364
18365 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
18366 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18367 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
18368 +#else
18369 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
18370 +#endif
18371 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
18372 }
18373
18374 return pte_offset_kernel(pmd, 0);
18375 }
18376
18377 +static pmd_t * __init one_md_table_init(pgd_t *pgd)
18378 +{
18379 + pud_t *pud;
18380 + pmd_t *pmd_table;
18381 +
18382 + pud = pud_offset(pgd, 0);
18383 + pmd_table = pmd_offset(pud, 0);
18384 +
18385 + return pmd_table;
18386 +}
18387 +
18388 pmd_t * __init populate_extra_pmd(unsigned long vaddr)
18389 {
18390 int pgd_idx = pgd_index(vaddr);
18391 @@ -201,6 +186,7 @@ page_table_range_init(unsigned long star
18392 int pgd_idx, pmd_idx;
18393 unsigned long vaddr;
18394 pgd_t *pgd;
18395 + pud_t *pud;
18396 pmd_t *pmd;
18397 pte_t *pte = NULL;
18398
18399 @@ -210,8 +196,13 @@ page_table_range_init(unsigned long star
18400 pgd = pgd_base + pgd_idx;
18401
18402 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
18403 - pmd = one_md_table_init(pgd);
18404 - pmd = pmd + pmd_index(vaddr);
18405 + pud = pud_offset(pgd, vaddr);
18406 + pmd = pmd_offset(pud, vaddr);
18407 +
18408 +#ifdef CONFIG_X86_PAE
18409 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
18410 +#endif
18411 +
18412 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
18413 pmd++, pmd_idx++) {
18414 pte = page_table_kmap_check(one_page_table_init(pmd),
18415 @@ -223,11 +214,20 @@ page_table_range_init(unsigned long star
18416 }
18417 }
18418
18419 -static inline int is_kernel_text(unsigned long addr)
18420 +static inline int is_kernel_text(unsigned long start, unsigned long end)
18421 {
18422 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
18423 - return 1;
18424 - return 0;
18425 + if ((start > ktla_ktva((unsigned long)_etext) ||
18426 + end <= ktla_ktva((unsigned long)_stext)) &&
18427 + (start > ktla_ktva((unsigned long)_einittext) ||
18428 + end <= ktla_ktva((unsigned long)_sinittext)) &&
18429 +
18430 +#ifdef CONFIG_ACPI_SLEEP
18431 + (start > (unsigned long)__va(acpi_wakeup_address) + 0x4000 || end <= (unsigned long)__va(acpi_wakeup_address)) &&
18432 +#endif
18433 +
18434 + (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
18435 + return 0;
18436 + return 1;
18437 }
18438
18439 /*
18440 @@ -244,9 +244,10 @@ kernel_physical_mapping_init(unsigned lo
18441 unsigned long last_map_addr = end;
18442 unsigned long start_pfn, end_pfn;
18443 pgd_t *pgd_base = swapper_pg_dir;
18444 - int pgd_idx, pmd_idx, pte_ofs;
18445 + unsigned int pgd_idx, pmd_idx, pte_ofs;
18446 unsigned long pfn;
18447 pgd_t *pgd;
18448 + pud_t *pud;
18449 pmd_t *pmd;
18450 pte_t *pte;
18451 unsigned pages_2m, pages_4k;
18452 @@ -279,8 +280,13 @@ repeat:
18453 pfn = start_pfn;
18454 pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
18455 pgd = pgd_base + pgd_idx;
18456 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
18457 - pmd = one_md_table_init(pgd);
18458 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
18459 + pud = pud_offset(pgd, 0);
18460 + pmd = pmd_offset(pud, 0);
18461 +
18462 +#ifdef CONFIG_X86_PAE
18463 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
18464 +#endif
18465
18466 if (pfn >= end_pfn)
18467 continue;
18468 @@ -292,14 +298,13 @@ repeat:
18469 #endif
18470 for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
18471 pmd++, pmd_idx++) {
18472 - unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
18473 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
18474
18475 /*
18476 * Map with big pages if possible, otherwise
18477 * create normal page tables:
18478 */
18479 if (use_pse) {
18480 - unsigned int addr2;
18481 pgprot_t prot = PAGE_KERNEL_LARGE;
18482 /*
18483 * first pass will use the same initial
18484 @@ -309,11 +314,7 @@ repeat:
18485 __pgprot(PTE_IDENT_ATTR |
18486 _PAGE_PSE);
18487
18488 - addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
18489 - PAGE_OFFSET + PAGE_SIZE-1;
18490 -
18491 - if (is_kernel_text(addr) ||
18492 - is_kernel_text(addr2))
18493 + if (is_kernel_text(address, address + PMD_SIZE))
18494 prot = PAGE_KERNEL_LARGE_EXEC;
18495
18496 pages_2m++;
18497 @@ -330,7 +331,7 @@ repeat:
18498 pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
18499 pte += pte_ofs;
18500 for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
18501 - pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
18502 + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
18503 pgprot_t prot = PAGE_KERNEL;
18504 /*
18505 * first pass will use the same initial
18506 @@ -338,7 +339,7 @@ repeat:
18507 */
18508 pgprot_t init_prot = __pgprot(PTE_IDENT_ATTR);
18509
18510 - if (is_kernel_text(addr))
18511 + if (is_kernel_text(address, address + PAGE_SIZE))
18512 prot = PAGE_KERNEL_EXEC;
18513
18514 pages_4k++;
18515 @@ -491,7 +492,7 @@ void __init native_pagetable_setup_start
18516
18517 pud = pud_offset(pgd, va);
18518 pmd = pmd_offset(pud, va);
18519 - if (!pmd_present(*pmd))
18520 + if (!pmd_present(*pmd) || pmd_huge(*pmd))
18521 break;
18522
18523 pte = pte_offset_kernel(pmd, va);
18524 @@ -543,9 +544,7 @@ void __init early_ioremap_page_table_ran
18525
18526 static void __init pagetable_init(void)
18527 {
18528 - pgd_t *pgd_base = swapper_pg_dir;
18529 -
18530 - permanent_kmaps_init(pgd_base);
18531 + permanent_kmaps_init(swapper_pg_dir);
18532 }
18533
18534 #ifdef CONFIG_ACPI_SLEEP
18535 @@ -553,12 +552,12 @@ static void __init pagetable_init(void)
18536 * ACPI suspend needs this for resume, because things like the intel-agp
18537 * driver might have split up a kernel 4MB mapping.
18538 */
18539 -char swsusp_pg_dir[PAGE_SIZE]
18540 +pgd_t swsusp_pg_dir[PTRS_PER_PGD]
18541 __attribute__ ((aligned(PAGE_SIZE)));
18542
18543 static inline void save_pg_dir(void)
18544 {
18545 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
18546 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
18547 }
18548 #else /* !CONFIG_ACPI_SLEEP */
18549 static inline void save_pg_dir(void)
18550 @@ -590,7 +589,7 @@ void zap_low_mappings(bool early)
18551 flush_tlb_all();
18552 }
18553
18554 -pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
18555 +pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
18556 EXPORT_SYMBOL_GPL(__supported_pte_mask);
18557
18558 /* user-defined highmem size */
18559 @@ -781,7 +780,7 @@ void __init setup_bootmem_allocator(void
18560 * Initialize the boot-time allocator (with low memory only):
18561 */
18562 bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT;
18563 - bootmap = find_e820_area(0, max_pfn_mapped<<PAGE_SHIFT, bootmap_size,
18564 + bootmap = find_e820_area(0x100000, max_pfn_mapped<<PAGE_SHIFT, bootmap_size,
18565 PAGE_SIZE);
18566 if (bootmap == -1L)
18567 panic("Cannot find bootmem map of size %ld\n", bootmap_size);
18568 @@ -871,6 +870,12 @@ void __init mem_init(void)
18569
18570 pci_iommu_alloc();
18571
18572 +#ifdef CONFIG_PAX_PER_CPU_PGD
18573 + clone_pgd_range(get_cpu_pgd(0) + KERNEL_PGD_BOUNDARY,
18574 + swapper_pg_dir + KERNEL_PGD_BOUNDARY,
18575 + KERNEL_PGD_PTRS);
18576 +#endif
18577 +
18578 #ifdef CONFIG_FLATMEM
18579 BUG_ON(!mem_map);
18580 #endif
18581 @@ -888,7 +893,7 @@ void __init mem_init(void)
18582 set_highmem_pages_init();
18583
18584 codesize = (unsigned long) &_etext - (unsigned long) &_text;
18585 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
18586 + datasize = (unsigned long) &_edata - (unsigned long) &_sdata;
18587 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
18588
18589 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
18590 @@ -929,10 +934,10 @@ void __init mem_init(void)
18591 ((unsigned long)&__init_end -
18592 (unsigned long)&__init_begin) >> 10,
18593
18594 - (unsigned long)&_etext, (unsigned long)&_edata,
18595 - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
18596 + (unsigned long)&_sdata, (unsigned long)&_edata,
18597 + ((unsigned long)&_edata - (unsigned long)&_sdata) >> 10,
18598
18599 - (unsigned long)&_text, (unsigned long)&_etext,
18600 + ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
18601 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
18602
18603 /*
18604 @@ -1013,6 +1018,7 @@ void set_kernel_text_rw(void)
18605 if (!kernel_set_to_readonly)
18606 return;
18607
18608 + start = ktla_ktva(start);
18609 pr_debug("Set kernel text: %lx - %lx for read write\n",
18610 start, start+size);
18611
18612 @@ -1027,6 +1033,7 @@ void set_kernel_text_ro(void)
18613 if (!kernel_set_to_readonly)
18614 return;
18615
18616 + start = ktla_ktva(start);
18617 pr_debug("Set kernel text: %lx - %lx for read only\n",
18618 start, start+size);
18619
18620 @@ -1038,6 +1045,7 @@ void mark_rodata_ro(void)
18621 unsigned long start = PFN_ALIGN(_text);
18622 unsigned long size = PFN_ALIGN(_etext) - start;
18623
18624 + start = ktla_ktva(start);
18625 set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
18626 printk(KERN_INFO "Write protecting the kernel text: %luk\n",
18627 size >> 10);
18628 diff -urNp linux-2.6.36/arch/x86/mm/init_64.c linux-2.6.36/arch/x86/mm/init_64.c
18629 --- linux-2.6.36/arch/x86/mm/init_64.c 2010-10-20 16:30:22.000000000 -0400
18630 +++ linux-2.6.36/arch/x86/mm/init_64.c 2010-11-06 18:58:15.000000000 -0400
18631 @@ -50,7 +50,6 @@
18632 #include <asm/numa.h>
18633 #include <asm/cacheflush.h>
18634 #include <asm/init.h>
18635 -#include <linux/bootmem.h>
18636
18637 static unsigned long dma_reserve __initdata;
18638
18639 @@ -74,7 +73,7 @@ early_param("gbpages", parse_direct_gbpa
18640 * around without checking the pgd every time.
18641 */
18642
18643 -pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
18644 +pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_IOMAP);
18645 EXPORT_SYMBOL_GPL(__supported_pte_mask);
18646
18647 int force_personality32;
18648 @@ -165,7 +164,9 @@ void set_pte_vaddr_pud(pud_t *pud_page,
18649 pmd = fill_pmd(pud, vaddr);
18650 pte = fill_pte(pmd, vaddr);
18651
18652 + pax_open_kernel();
18653 set_pte(pte, new_pte);
18654 + pax_close_kernel();
18655
18656 /*
18657 * It's enough to flush this one mapping.
18658 @@ -224,14 +225,12 @@ static void __init __init_extra_mapping(
18659 pgd = pgd_offset_k((unsigned long)__va(phys));
18660 if (pgd_none(*pgd)) {
18661 pud = (pud_t *) spp_getpage();
18662 - set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
18663 - _PAGE_USER));
18664 + set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
18665 }
18666 pud = pud_offset(pgd, (unsigned long)__va(phys));
18667 if (pud_none(*pud)) {
18668 pmd = (pmd_t *) spp_getpage();
18669 - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
18670 - _PAGE_USER));
18671 + set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
18672 }
18673 pmd = pmd_offset(pud, phys);
18674 BUG_ON(!pmd_none(*pmd));
18675 @@ -680,6 +679,12 @@ void __init mem_init(void)
18676
18677 pci_iommu_alloc();
18678
18679 +#ifdef CONFIG_PAX_PER_CPU_PGD
18680 + clone_pgd_range(get_cpu_pgd(0) + KERNEL_PGD_BOUNDARY,
18681 + swapper_pg_dir + KERNEL_PGD_BOUNDARY,
18682 + KERNEL_PGD_PTRS);
18683 +#endif
18684 +
18685 /* clear_bss() already clear the empty_zero_page */
18686
18687 reservedpages = 0;
18688 @@ -886,8 +891,8 @@ int kern_addr_valid(unsigned long addr)
18689 static struct vm_area_struct gate_vma = {
18690 .vm_start = VSYSCALL_START,
18691 .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
18692 - .vm_page_prot = PAGE_READONLY_EXEC,
18693 - .vm_flags = VM_READ | VM_EXEC
18694 + .vm_page_prot = PAGE_READONLY,
18695 + .vm_flags = VM_READ
18696 };
18697
18698 struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
18699 @@ -921,7 +926,7 @@ int in_gate_area_no_task(unsigned long a
18700
18701 const char *arch_vma_name(struct vm_area_struct *vma)
18702 {
18703 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
18704 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
18705 return "[vdso]";
18706 if (vma == &gate_vma)
18707 return "[vsyscall]";
18708 diff -urNp linux-2.6.36/arch/x86/mm/init.c linux-2.6.36/arch/x86/mm/init.c
18709 --- linux-2.6.36/arch/x86/mm/init.c 2010-10-20 16:30:22.000000000 -0400
18710 +++ linux-2.6.36/arch/x86/mm/init.c 2010-11-06 18:58:15.000000000 -0400
18711 @@ -70,11 +70,7 @@ static void __init find_early_table_spac
18712 * cause a hotspot and fill up ZONE_DMA. The page tables
18713 * need roughly 0.5KB per GB.
18714 */
18715 -#ifdef CONFIG_X86_32
18716 - start = 0x7000;
18717 -#else
18718 - start = 0x8000;
18719 -#endif
18720 + start = 0x100000;
18721 e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
18722 tables, PAGE_SIZE);
18723 if (e820_table_start == -1UL)
18724 @@ -321,7 +317,13 @@ unsigned long __init_refok init_memory_m
18725 */
18726 int devmem_is_allowed(unsigned long pagenr)
18727 {
18728 - if (pagenr <= 256)
18729 + if (!pagenr)
18730 + return 1;
18731 +#ifdef CONFIG_VM86
18732 + if (pagenr < (ISA_START_ADDRESS >> PAGE_SHIFT))
18733 + return 1;
18734 +#endif
18735 + if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
18736 return 1;
18737 if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
18738 return 0;
18739 @@ -380,6 +382,88 @@ void free_init_pages(char *what, unsigne
18740
18741 void free_initmem(void)
18742 {
18743 +
18744 +#ifdef CONFIG_PAX_KERNEXEC
18745 +#ifdef CONFIG_X86_32
18746 + /* PaX: limit KERNEL_CS to actual size */
18747 + unsigned long addr, limit;
18748 + struct desc_struct d;
18749 + int cpu;
18750 +
18751 + limit = paravirt_enabled() ? ktva_ktla(0xffffffff) : (unsigned long)&_etext;
18752 + limit = (limit - 1UL) >> PAGE_SHIFT;
18753 +
18754 + memset(__LOAD_PHYSICAL_ADDR + PAGE_OFFSET, POISON_FREE_INITMEM, PAGE_SIZE);
18755 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
18756 + pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
18757 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
18758 + }
18759 +
18760 + /* PaX: make KERNEL_CS read-only */
18761 + addr = PFN_ALIGN(ktla_ktva((unsigned long)&_text));
18762 + if (!paravirt_enabled())
18763 + set_memory_ro(addr, (PFN_ALIGN(_sdata) - addr) >> PAGE_SHIFT);
18764 +/*
18765 + for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_sdata; addr += PMD_SIZE) {
18766 + pgd = pgd_offset_k(addr);
18767 + pud = pud_offset(pgd, addr);
18768 + pmd = pmd_offset(pud, addr);
18769 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
18770 + }
18771 +*/
18772 +#ifdef CONFIG_X86_PAE
18773 + set_memory_nx(PFN_ALIGN(__init_begin), (PFN_ALIGN(__init_end) - PFN_ALIGN(__init_begin)) >> PAGE_SHIFT);
18774 +/*
18775 + for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
18776 + pgd = pgd_offset_k(addr);
18777 + pud = pud_offset(pgd, addr);
18778 + pmd = pmd_offset(pud, addr);
18779 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
18780 + }
18781 +*/
18782 +#endif
18783 +
18784 +#ifdef CONFIG_MODULES
18785 + set_memory_4k((unsigned long)MODULES_EXEC_VADDR, (MODULES_EXEC_END - MODULES_EXEC_VADDR) >> PAGE_SHIFT);
18786 +#endif
18787 +
18788 +#else
18789 + pgd_t *pgd;
18790 + pud_t *pud;
18791 + pmd_t *pmd;
18792 + unsigned long addr, end;
18793 +
18794 + /* PaX: make kernel code/rodata read-only, rest non-executable */
18795 + for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
18796 + pgd = pgd_offset_k(addr);
18797 + pud = pud_offset(pgd, addr);
18798 + pmd = pmd_offset(pud, addr);
18799 + if (!pmd_present(*pmd))
18800 + continue;
18801 + if ((unsigned long)_text <= addr && addr < (unsigned long)_sdata)
18802 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
18803 + else
18804 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
18805 + }
18806 +
18807 + addr = (unsigned long)__va(__pa(__START_KERNEL_map));
18808 + end = addr + KERNEL_IMAGE_SIZE;
18809 + for (; addr < end; addr += PMD_SIZE) {
18810 + pgd = pgd_offset_k(addr);
18811 + pud = pud_offset(pgd, addr);
18812 + pmd = pmd_offset(pud, addr);
18813 + if (!pmd_present(*pmd))
18814 + continue;
18815 + if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_sdata)))
18816 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
18817 + else
18818 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
18819 + }
18820 +#endif
18821 +
18822 + flush_tlb_all();
18823 +#endif
18824 +
18825 free_init_pages("unused kernel memory",
18826 (unsigned long)(&__init_begin),
18827 (unsigned long)(&__init_end));
18828 diff -urNp linux-2.6.36/arch/x86/mm/iomap_32.c linux-2.6.36/arch/x86/mm/iomap_32.c
18829 --- linux-2.6.36/arch/x86/mm/iomap_32.c 2010-10-20 16:30:22.000000000 -0400
18830 +++ linux-2.6.36/arch/x86/mm/iomap_32.c 2010-11-06 18:58:15.000000000 -0400
18831 @@ -65,7 +65,11 @@ void *kmap_atomic_prot_pfn(unsigned long
18832 debug_kmap_atomic(type);
18833 idx = type + KM_TYPE_NR * smp_processor_id();
18834 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
18835 +
18836 + pax_open_kernel();
18837 set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
18838 + pax_close_kernel();
18839 +
18840 arch_flush_lazy_mmu_mode();
18841
18842 return (void *)vaddr;
18843 diff -urNp linux-2.6.36/arch/x86/mm/ioremap.c linux-2.6.36/arch/x86/mm/ioremap.c
18844 --- linux-2.6.36/arch/x86/mm/ioremap.c 2010-10-20 16:30:22.000000000 -0400
18845 +++ linux-2.6.36/arch/x86/mm/ioremap.c 2010-11-06 18:58:15.000000000 -0400
18846 @@ -104,7 +104,7 @@ static void __iomem *__ioremap_caller(re
18847 for (pfn = phys_addr >> PAGE_SHIFT; pfn <= last_pfn; pfn++) {
18848 int is_ram = page_is_ram(pfn);
18849
18850 - if (is_ram && pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
18851 + if (is_ram && pfn_valid(pfn) && (pfn >= 0x100 || !PageReserved(pfn_to_page(pfn))))
18852 return NULL;
18853 WARN_ON_ONCE(is_ram);
18854 }
18855 @@ -344,7 +344,7 @@ static int __init early_ioremap_debug_se
18856 early_param("early_ioremap_debug", early_ioremap_debug_setup);
18857
18858 static __initdata int after_paging_init;
18859 -static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
18860 +static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __read_only __aligned(PAGE_SIZE);
18861
18862 static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
18863 {
18864 @@ -376,8 +376,7 @@ void __init early_ioremap_init(void)
18865 slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
18866
18867 pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
18868 - memset(bm_pte, 0, sizeof(bm_pte));
18869 - pmd_populate_kernel(&init_mm, pmd, bm_pte);
18870 + pmd_populate_user(&init_mm, pmd, bm_pte);
18871
18872 /*
18873 * The boot-ioremap range spans multiple pmds, for which
18874 diff -urNp linux-2.6.36/arch/x86/mm/kmemcheck/kmemcheck.c linux-2.6.36/arch/x86/mm/kmemcheck/kmemcheck.c
18875 --- linux-2.6.36/arch/x86/mm/kmemcheck/kmemcheck.c 2010-10-20 16:30:22.000000000 -0400
18876 +++ linux-2.6.36/arch/x86/mm/kmemcheck/kmemcheck.c 2010-11-06 18:58:15.000000000 -0400
18877 @@ -622,9 +622,9 @@ bool kmemcheck_fault(struct pt_regs *reg
18878 * memory (e.g. tracked pages)? For now, we need this to avoid
18879 * invoking kmemcheck for PnP BIOS calls.
18880 */
18881 - if (regs->flags & X86_VM_MASK)
18882 + if (v8086_mode(regs))
18883 return false;
18884 - if (regs->cs != __KERNEL_CS)
18885 + if (regs->cs != __KERNEL_CS && regs->cs != __KERNEXEC_KERNEL_CS)
18886 return false;
18887
18888 pte = kmemcheck_pte_lookup(address);
18889 diff -urNp linux-2.6.36/arch/x86/mm/mmap.c linux-2.6.36/arch/x86/mm/mmap.c
18890 --- linux-2.6.36/arch/x86/mm/mmap.c 2010-10-20 16:30:22.000000000 -0400
18891 +++ linux-2.6.36/arch/x86/mm/mmap.c 2010-11-06 18:58:15.000000000 -0400
18892 @@ -49,7 +49,7 @@ static unsigned int stack_maxrandom_size
18893 * Leave an at least ~128 MB hole with possible stack randomization.
18894 */
18895 #define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())
18896 -#define MAX_GAP (TASK_SIZE/6*5)
18897 +#define MAX_GAP (pax_task_size/6*5)
18898
18899 /*
18900 * True on X86_32 or when emulating IA32 on X86_64
18901 @@ -94,27 +94,40 @@ static unsigned long mmap_rnd(void)
18902 return rnd << PAGE_SHIFT;
18903 }
18904
18905 -static unsigned long mmap_base(void)
18906 +static unsigned long mmap_base(struct mm_struct *mm)
18907 {
18908 unsigned long gap = rlimit(RLIMIT_STACK);
18909 + unsigned long pax_task_size = TASK_SIZE;
18910 +
18911 +#ifdef CONFIG_PAX_SEGMEXEC
18912 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
18913 + pax_task_size = SEGMEXEC_TASK_SIZE;
18914 +#endif
18915
18916 if (gap < MIN_GAP)
18917 gap = MIN_GAP;
18918 else if (gap > MAX_GAP)
18919 gap = MAX_GAP;
18920
18921 - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
18922 + return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
18923 }
18924
18925 /*
18926 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
18927 * does, but not when emulating X86_32
18928 */
18929 -static unsigned long mmap_legacy_base(void)
18930 +static unsigned long mmap_legacy_base(struct mm_struct *mm)
18931 {
18932 - if (mmap_is_ia32())
18933 + if (mmap_is_ia32()) {
18934 +
18935 +#ifdef CONFIG_PAX_SEGMEXEC
18936 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
18937 + return SEGMEXEC_TASK_UNMAPPED_BASE;
18938 + else
18939 +#endif
18940 +
18941 return TASK_UNMAPPED_BASE;
18942 - else
18943 + } else
18944 return TASK_UNMAPPED_BASE + mmap_rnd();
18945 }
18946
18947 @@ -125,11 +138,23 @@ static unsigned long mmap_legacy_base(vo
18948 void arch_pick_mmap_layout(struct mm_struct *mm)
18949 {
18950 if (mmap_is_legacy()) {
18951 - mm->mmap_base = mmap_legacy_base();
18952 + mm->mmap_base = mmap_legacy_base(mm);
18953 +
18954 +#ifdef CONFIG_PAX_RANDMMAP
18955 + if (mm->pax_flags & MF_PAX_RANDMMAP)
18956 + mm->mmap_base += mm->delta_mmap;
18957 +#endif
18958 +
18959 mm->get_unmapped_area = arch_get_unmapped_area;
18960 mm->unmap_area = arch_unmap_area;
18961 } else {
18962 - mm->mmap_base = mmap_base();
18963 + mm->mmap_base = mmap_base(mm);
18964 +
18965 +#ifdef CONFIG_PAX_RANDMMAP
18966 + if (mm->pax_flags & MF_PAX_RANDMMAP)
18967 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
18968 +#endif
18969 +
18970 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
18971 mm->unmap_area = arch_unmap_area_topdown;
18972 }
18973 diff -urNp linux-2.6.36/arch/x86/mm/numa_32.c linux-2.6.36/arch/x86/mm/numa_32.c
18974 --- linux-2.6.36/arch/x86/mm/numa_32.c 2010-10-20 16:30:22.000000000 -0400
18975 +++ linux-2.6.36/arch/x86/mm/numa_32.c 2010-11-06 18:58:15.000000000 -0400
18976 @@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
18977 }
18978 #endif
18979
18980 -extern unsigned long find_max_low_pfn(void);
18981 extern unsigned long highend_pfn, highstart_pfn;
18982
18983 #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
18984 diff -urNp linux-2.6.36/arch/x86/mm/pageattr.c linux-2.6.36/arch/x86/mm/pageattr.c
18985 --- linux-2.6.36/arch/x86/mm/pageattr.c 2010-10-20 16:30:22.000000000 -0400
18986 +++ linux-2.6.36/arch/x86/mm/pageattr.c 2010-11-06 18:58:15.000000000 -0400
18987 @@ -261,16 +261,17 @@ static inline pgprot_t static_protection
18988 * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support.
18989 */
18990 if (within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT))
18991 - pgprot_val(forbidden) |= _PAGE_NX;
18992 + pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
18993
18994 /*
18995 * The kernel text needs to be executable for obvious reasons
18996 * Does not cover __inittext since that is gone later on. On
18997 * 64bit we do not enforce !NX on the low mapping
18998 */
18999 - if (within(address, (unsigned long)_text, (unsigned long)_etext))
19000 - pgprot_val(forbidden) |= _PAGE_NX;
19001 + if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
19002 + pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
19003
19004 +#ifdef CONFIG_DEBUG_RODATA
19005 /*
19006 * The .rodata section needs to be read-only. Using the pfn
19007 * catches all aliases.
19008 @@ -278,6 +279,7 @@ static inline pgprot_t static_protection
19009 if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
19010 __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
19011 pgprot_val(forbidden) |= _PAGE_RW;
19012 +#endif
19013
19014 #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
19015 /*
19016 @@ -316,6 +318,13 @@ static inline pgprot_t static_protection
19017 }
19018 #endif
19019
19020 +#ifdef CONFIG_PAX_KERNEXEC
19021 + if (within(pfn, __pa((unsigned long)&_text), __pa((unsigned long)&_sdata))) {
19022 + pgprot_val(forbidden) |= _PAGE_RW;
19023 + pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
19024 + }
19025 +#endif
19026 +
19027 prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
19028
19029 return prot;
19030 @@ -368,23 +377,37 @@ EXPORT_SYMBOL_GPL(lookup_address);
19031 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
19032 {
19033 /* change init_mm */
19034 + pax_open_kernel();
19035 set_pte_atomic(kpte, pte);
19036 +
19037 #ifdef CONFIG_X86_32
19038 if (!SHARED_KERNEL_PMD) {
19039 +
19040 +#ifdef CONFIG_PAX_PER_CPU_PGD
19041 + unsigned long cpu;
19042 +#else
19043 struct page *page;
19044 +#endif
19045
19046 +#ifdef CONFIG_PAX_PER_CPU_PGD
19047 + for (cpu = 0; cpu < NR_CPUS; ++cpu) {
19048 + pgd_t *pgd = get_cpu_pgd(cpu);
19049 +#else
19050 list_for_each_entry(page, &pgd_list, lru) {
19051 - pgd_t *pgd;
19052 + pgd_t *pgd = (pgd_t *)page_address(page);
19053 +#endif
19054 +
19055 pud_t *pud;
19056 pmd_t *pmd;
19057
19058 - pgd = (pgd_t *)page_address(page) + pgd_index(address);
19059 + pgd += pgd_index(address);
19060 pud = pud_offset(pgd, address);
19061 pmd = pmd_offset(pud, address);
19062 set_pte_atomic((pte_t *)pmd, pte);
19063 }
19064 }
19065 #endif
19066 + pax_close_kernel();
19067 }
19068
19069 static int
19070 diff -urNp linux-2.6.36/arch/x86/mm/pageattr-test.c linux-2.6.36/arch/x86/mm/pageattr-test.c
19071 --- linux-2.6.36/arch/x86/mm/pageattr-test.c 2010-10-20 16:30:22.000000000 -0400
19072 +++ linux-2.6.36/arch/x86/mm/pageattr-test.c 2010-11-06 18:58:15.000000000 -0400
19073 @@ -36,7 +36,7 @@ enum {
19074
19075 static int pte_testbit(pte_t pte)
19076 {
19077 - return pte_flags(pte) & _PAGE_UNUSED1;
19078 + return pte_flags(pte) & _PAGE_CPA_TEST;
19079 }
19080
19081 struct split_state {
19082 diff -urNp linux-2.6.36/arch/x86/mm/pat.c linux-2.6.36/arch/x86/mm/pat.c
19083 --- linux-2.6.36/arch/x86/mm/pat.c 2010-10-20 16:30:22.000000000 -0400
19084 +++ linux-2.6.36/arch/x86/mm/pat.c 2010-11-06 18:58:15.000000000 -0400
19085 @@ -361,7 +361,7 @@ int free_memtype(u64 start, u64 end)
19086
19087 if (!entry) {
19088 printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n",
19089 - current->comm, current->pid, start, end);
19090 + current->comm, task_pid_nr(current), start, end);
19091 return -EINVAL;
19092 }
19093
19094 @@ -492,8 +492,8 @@ static inline int range_is_allowed(unsig
19095 while (cursor < to) {
19096 if (!devmem_is_allowed(pfn)) {
19097 printk(KERN_INFO
19098 - "Program %s tried to access /dev/mem between %Lx->%Lx.\n",
19099 - current->comm, from, to);
19100 + "Program %s tried to access /dev/mem between %Lx->%Lx (%Lx).\n",
19101 + current->comm, from, to, cursor);
19102 return 0;
19103 }
19104 cursor += PAGE_SIZE;
19105 @@ -557,7 +557,7 @@ int kernel_map_sync_memtype(u64 base, un
19106 printk(KERN_INFO
19107 "%s:%d ioremap_change_attr failed %s "
19108 "for %Lx-%Lx\n",
19109 - current->comm, current->pid,
19110 + current->comm, task_pid_nr(current),
19111 cattr_name(flags),
19112 base, (unsigned long long)(base + size));
19113 return -EINVAL;
19114 @@ -593,7 +593,7 @@ static int reserve_pfn_range(u64 paddr,
19115 if (want_flags != flags) {
19116 printk(KERN_WARNING
19117 "%s:%d map pfn RAM range req %s for %Lx-%Lx, got %s\n",
19118 - current->comm, current->pid,
19119 + current->comm, task_pid_nr(current),
19120 cattr_name(want_flags),
19121 (unsigned long long)paddr,
19122 (unsigned long long)(paddr + size),
19123 @@ -615,7 +615,7 @@ static int reserve_pfn_range(u64 paddr,
19124 free_memtype(paddr, paddr + size);
19125 printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
19126 " for %Lx-%Lx, got %s\n",
19127 - current->comm, current->pid,
19128 + current->comm, task_pid_nr(current),
19129 cattr_name(want_flags),
19130 (unsigned long long)paddr,
19131 (unsigned long long)(paddr + size),
19132 diff -urNp linux-2.6.36/arch/x86/mm/pgtable_32.c linux-2.6.36/arch/x86/mm/pgtable_32.c
19133 --- linux-2.6.36/arch/x86/mm/pgtable_32.c 2010-10-20 16:30:22.000000000 -0400
19134 +++ linux-2.6.36/arch/x86/mm/pgtable_32.c 2010-11-06 18:58:15.000000000 -0400
19135 @@ -48,10 +48,13 @@ void set_pte_vaddr(unsigned long vaddr,
19136 return;
19137 }
19138 pte = pte_offset_kernel(pmd, vaddr);
19139 +
19140 + pax_open_kernel();
19141 if (pte_val(pteval))
19142 set_pte_at(&init_mm, vaddr, pte, pteval);
19143 else
19144 pte_clear(&init_mm, vaddr, pte);
19145 + pax_close_kernel();
19146
19147 /*
19148 * It's enough to flush this one mapping.
19149 diff -urNp linux-2.6.36/arch/x86/mm/pgtable.c linux-2.6.36/arch/x86/mm/pgtable.c
19150 --- linux-2.6.36/arch/x86/mm/pgtable.c 2010-10-20 16:30:22.000000000 -0400
19151 +++ linux-2.6.36/arch/x86/mm/pgtable.c 2010-11-06 18:58:15.000000000 -0400
19152 @@ -84,8 +84,58 @@ static inline void pgd_list_del(pgd_t *p
19153 list_del(&page->lru);
19154 }
19155
19156 -#define UNSHARED_PTRS_PER_PGD \
19157 - (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
19158 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
19159 +pgdval_t clone_pgd_mask __read_only = ~_PAGE_PRESENT;
19160 +
19161 +void __shadow_user_pgds(pgd_t *dst, const pgd_t *src, int count)
19162 +{
19163 + while (count--)
19164 + *dst++ = __pgd((pgd_val(*src++) | _PAGE_NX) & ~_PAGE_USER);
19165 +}
19166 +#endif
19167 +
19168 +#ifdef CONFIG_PAX_PER_CPU_PGD
19169 +void __clone_user_pgds(pgd_t *dst, const pgd_t *src, int count)
19170 +{
19171 + while (count--)
19172 +
19173 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
19174 + *dst++ = __pgd(pgd_val(*src++) & clone_pgd_mask);
19175 +#else
19176 + *dst++ = *src++;
19177 +#endif
19178 +
19179 +}
19180 +#endif
19181 +
19182 +#ifdef CONFIG_PAX_PER_CPU_PGD
19183 +static inline void pgd_ctor(pgd_t *pgd) {}
19184 +static inline void pgd_dtor(pgd_t *pgd) {}
19185 +#ifdef CONFIG_X86_64
19186 +#define pxd_t pud_t
19187 +#define pyd_t pgd_t
19188 +#define paravirt_release_pxd(pfn) paravirt_release_pud(pfn)
19189 +#define pxd_free(mm, pud) pud_free((mm), (pud))
19190 +#define pyd_populate(mm, pgd, pud) pgd_populate((mm), (pgd), (pud))
19191 +#define pyd_offset(mm ,address) pgd_offset((mm), (address))
19192 +#define PYD_SIZE PGDIR_SIZE
19193 +#else
19194 +#define pxd_t pmd_t
19195 +#define pyd_t pud_t
19196 +#define paravirt_release_pxd(pfn) paravirt_release_pmd(pfn)
19197 +#define pxd_free(mm, pud) pmd_free((mm), (pud))
19198 +#define pyd_populate(mm, pgd, pud) pud_populate((mm), (pgd), (pud))
19199 +#define pyd_offset(mm ,address) pud_offset((mm), (address))
19200 +#define PYD_SIZE PUD_SIZE
19201 +#endif
19202 +#else
19203 +#define pxd_t pmd_t
19204 +#define pyd_t pud_t
19205 +#define paravirt_release_pxd(pfn) paravirt_release_pmd(pfn)
19206 +#define pxd_free(mm, pmd) pmd_free((mm), (pmd))
19207 +#define pyd_populate(mm, pud, pmd) pud_populate((mm), (pud), (pmd))
19208 +#define pyd_offset(mm ,address) pud_offset((mm), (address))
19209 +#define PYD_SIZE PUD_SIZE
19210
19211 static void pgd_ctor(pgd_t *pgd)
19212 {
19213 @@ -120,6 +170,7 @@ static void pgd_dtor(pgd_t *pgd)
19214 pgd_list_del(pgd);
19215 spin_unlock_irqrestore(&pgd_lock, flags);
19216 }
19217 +#endif
19218
19219 /*
19220 * List of all pgd's needed for non-PAE so it can invalidate entries
19221 @@ -132,7 +183,7 @@ static void pgd_dtor(pgd_t *pgd)
19222 * -- wli
19223 */
19224
19225 -#ifdef CONFIG_X86_PAE
19226 +#if defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
19227 /*
19228 * In PAE mode, we need to do a cr3 reload (=tlb flush) when
19229 * updating the top-level pagetable entries to guarantee the
19230 @@ -144,7 +195,7 @@ static void pgd_dtor(pgd_t *pgd)
19231 * not shared between pagetables (!SHARED_KERNEL_PMDS), we allocate
19232 * and initialize the kernel pmds here.
19233 */
19234 -#define PREALLOCATED_PMDS UNSHARED_PTRS_PER_PGD
19235 +#define PREALLOCATED_PXDS (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
19236
19237 void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
19238 {
19239 @@ -163,36 +214,38 @@ void pud_populate(struct mm_struct *mm,
19240 if (mm == current->active_mm)
19241 write_cr3(read_cr3());
19242 }
19243 +#elif defined(CONFIG_X86_64) && defined(CONFIG_PAX_PER_CPU_PGD)
19244 +#define PREALLOCATED_PXDS USER_PGD_PTRS
19245 #else /* !CONFIG_X86_PAE */
19246
19247 /* No need to prepopulate any pagetable entries in non-PAE modes. */
19248 -#define PREALLOCATED_PMDS 0
19249 +#define PREALLOCATED_PXDS 0
19250
19251 #endif /* CONFIG_X86_PAE */
19252
19253 -static void free_pmds(pmd_t *pmds[])
19254 +static void free_pxds(pxd_t *pxds[])
19255 {
19256 int i;
19257
19258 - for(i = 0; i < PREALLOCATED_PMDS; i++)
19259 - if (pmds[i])
19260 - free_page((unsigned long)pmds[i]);
19261 + for(i = 0; i < PREALLOCATED_PXDS; i++)
19262 + if (pxds[i])
19263 + free_page((unsigned long)pxds[i]);
19264 }
19265
19266 -static int preallocate_pmds(pmd_t *pmds[])
19267 +static int preallocate_pxds(pxd_t *pxds[])
19268 {
19269 int i;
19270 bool failed = false;
19271
19272 - for(i = 0; i < PREALLOCATED_PMDS; i++) {
19273 - pmd_t *pmd = (pmd_t *)__get_free_page(PGALLOC_GFP);
19274 - if (pmd == NULL)
19275 + for(i = 0; i < PREALLOCATED_PXDS; i++) {
19276 + pxd_t *pxd = (pxd_t *)__get_free_page(PGALLOC_GFP);
19277 + if (pxd == NULL)
19278 failed = true;
19279 - pmds[i] = pmd;
19280 + pxds[i] = pxd;
19281 }
19282
19283 if (failed) {
19284 - free_pmds(pmds);
19285 + free_pxds(pxds);
19286 return -ENOMEM;
19287 }
19288
19289 @@ -205,51 +258,56 @@ static int preallocate_pmds(pmd_t *pmds[
19290 * preallocate which never got a corresponding vma will need to be
19291 * freed manually.
19292 */
19293 -static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
19294 +static void pgd_mop_up_pxds(struct mm_struct *mm, pgd_t *pgdp)
19295 {
19296 int i;
19297
19298 - for(i = 0; i < PREALLOCATED_PMDS; i++) {
19299 + for(i = 0; i < PREALLOCATED_PXDS; i++) {
19300 pgd_t pgd = pgdp[i];
19301
19302 if (pgd_val(pgd) != 0) {
19303 - pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
19304 + pxd_t *pxd = (pxd_t *)pgd_page_vaddr(pgd);
19305
19306 - pgdp[i] = native_make_pgd(0);
19307 + set_pgd(pgdp + i, native_make_pgd(0));
19308
19309 - paravirt_release_pmd(pgd_val(pgd) >> PAGE_SHIFT);
19310 - pmd_free(mm, pmd);
19311 + paravirt_release_pxd(pgd_val(pgd) >> PAGE_SHIFT);
19312 + pxd_free(mm, pxd);
19313 }
19314 }
19315 }
19316
19317 -static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
19318 +static void pgd_prepopulate_pxd(struct mm_struct *mm, pgd_t *pgd, pxd_t *pxds[])
19319 {
19320 - pud_t *pud;
19321 + pyd_t *pyd;
19322 unsigned long addr;
19323 int i;
19324
19325 - if (PREALLOCATED_PMDS == 0) /* Work around gcc-3.4.x bug */
19326 + if (PREALLOCATED_PXDS == 0) /* Work around gcc-3.4.x bug */
19327 return;
19328
19329 - pud = pud_offset(pgd, 0);
19330 +#ifdef CONFIG_X86_64
19331 + pyd = pyd_offset(mm, 0L);
19332 +#else
19333 + pyd = pyd_offset(pgd, 0L);
19334 +#endif
19335
19336 - for (addr = i = 0; i < PREALLOCATED_PMDS;
19337 - i++, pud++, addr += PUD_SIZE) {
19338 - pmd_t *pmd = pmds[i];
19339 + for (addr = i = 0; i < PREALLOCATED_PXDS;
19340 + i++, pyd++, addr += PYD_SIZE) {
19341 + pxd_t *pxd = pxds[i];
19342
19343 if (i >= KERNEL_PGD_BOUNDARY)
19344 - memcpy(pmd, (pmd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
19345 - sizeof(pmd_t) * PTRS_PER_PMD);
19346 + memcpy(pxd, (pxd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
19347 + sizeof(pxd_t) * PTRS_PER_PMD);
19348
19349 - pud_populate(mm, pud, pmd);
19350 + pyd_populate(mm, pyd, pxd);
19351 }
19352 }
19353
19354 pgd_t *pgd_alloc(struct mm_struct *mm)
19355 {
19356 pgd_t *pgd;
19357 - pmd_t *pmds[PREALLOCATED_PMDS];
19358 + pxd_t *pxds[PREALLOCATED_PXDS];
19359 +
19360 unsigned long flags;
19361
19362 pgd = (pgd_t *)__get_free_page(PGALLOC_GFP);
19363 @@ -259,11 +317,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
19364
19365 mm->pgd = pgd;
19366
19367 - if (preallocate_pmds(pmds) != 0)
19368 + if (preallocate_pxds(pxds) != 0)
19369 goto out_free_pgd;
19370
19371 if (paravirt_pgd_alloc(mm) != 0)
19372 - goto out_free_pmds;
19373 + goto out_free_pxds;
19374
19375 /*
19376 * Make sure that pre-populating the pmds is atomic with
19377 @@ -273,14 +331,14 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
19378 spin_lock_irqsave(&pgd_lock, flags);
19379
19380 pgd_ctor(pgd);
19381 - pgd_prepopulate_pmd(mm, pgd, pmds);
19382 + pgd_prepopulate_pxd(mm, pgd, pxds);
19383
19384 spin_unlock_irqrestore(&pgd_lock, flags);
19385
19386 return pgd;
19387
19388 -out_free_pmds:
19389 - free_pmds(pmds);
19390 +out_free_pxds:
19391 + free_pxds(pxds);
19392 out_free_pgd:
19393 free_page((unsigned long)pgd);
19394 out:
19395 @@ -289,7 +347,7 @@ out:
19396
19397 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
19398 {
19399 - pgd_mop_up_pmds(mm, pgd);
19400 + pgd_mop_up_pxds(mm, pgd);
19401 pgd_dtor(pgd);
19402 paravirt_pgd_free(mm, pgd);
19403 free_page((unsigned long)pgd);
19404 diff -urNp linux-2.6.36/arch/x86/mm/setup_nx.c linux-2.6.36/arch/x86/mm/setup_nx.c
19405 --- linux-2.6.36/arch/x86/mm/setup_nx.c 2010-10-20 16:30:22.000000000 -0400
19406 +++ linux-2.6.36/arch/x86/mm/setup_nx.c 2010-11-06 18:58:15.000000000 -0400
19407 @@ -5,8 +5,10 @@
19408 #include <asm/pgtable.h>
19409 #include <asm/proto.h>
19410
19411 +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
19412 static int disable_nx __cpuinitdata;
19413
19414 +#ifndef CONFIG_PAX_PAGEEXEC
19415 /*
19416 * noexec = on|off
19417 *
19418 @@ -28,12 +30,17 @@ static int __init noexec_setup(char *str
19419 return 0;
19420 }
19421 early_param("noexec", noexec_setup);
19422 +#endif
19423 +
19424 +#endif
19425
19426 void __cpuinit x86_configure_nx(void)
19427 {
19428 +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
19429 if (cpu_has_nx && !disable_nx)
19430 __supported_pte_mask |= _PAGE_NX;
19431 else
19432 +#endif
19433 __supported_pte_mask &= ~_PAGE_NX;
19434 }
19435
19436 diff -urNp linux-2.6.36/arch/x86/mm/tlb.c linux-2.6.36/arch/x86/mm/tlb.c
19437 --- linux-2.6.36/arch/x86/mm/tlb.c 2010-10-20 16:30:22.000000000 -0400
19438 +++ linux-2.6.36/arch/x86/mm/tlb.c 2010-11-06 18:58:15.000000000 -0400
19439 @@ -13,7 +13,7 @@
19440 #include <asm/uv/uv.h>
19441
19442 DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
19443 - = { &init_mm, 0, };
19444 + = { &init_mm, 0 };
19445
19446 /*
19447 * Smarter SMP flushing macros.
19448 @@ -62,7 +62,11 @@ void leave_mm(int cpu)
19449 BUG();
19450 cpumask_clear_cpu(cpu,
19451 mm_cpumask(percpu_read(cpu_tlbstate.active_mm)));
19452 +
19453 +#ifndef CONFIG_PAX_PER_CPU_PGD
19454 load_cr3(swapper_pg_dir);
19455 +#endif
19456 +
19457 }
19458 EXPORT_SYMBOL_GPL(leave_mm);
19459
19460 diff -urNp linux-2.6.36/arch/x86/oprofile/backtrace.c linux-2.6.36/arch/x86/oprofile/backtrace.c
19461 --- linux-2.6.36/arch/x86/oprofile/backtrace.c 2010-10-20 16:30:22.000000000 -0400
19462 +++ linux-2.6.36/arch/x86/oprofile/backtrace.c 2010-11-06 18:58:15.000000000 -0400
19463 @@ -58,7 +58,7 @@ static struct frame_head *dump_user_back
19464 struct frame_head bufhead[2];
19465
19466 /* Also check accessibility of one struct frame_head beyond */
19467 - if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
19468 + if (!__access_ok(VERIFY_READ, head, sizeof(bufhead)))
19469 return NULL;
19470 if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
19471 return NULL;
19472 @@ -78,7 +78,7 @@ x86_backtrace(struct pt_regs * const reg
19473 {
19474 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
19475
19476 - if (!user_mode_vm(regs)) {
19477 + if (!user_mode(regs)) {
19478 unsigned long stack = kernel_stack_pointer(regs);
19479 if (depth)
19480 dump_trace(NULL, regs, (unsigned long *)stack, 0,
19481 diff -urNp linux-2.6.36/arch/x86/oprofile/op_model_p4.c linux-2.6.36/arch/x86/oprofile/op_model_p4.c
19482 --- linux-2.6.36/arch/x86/oprofile/op_model_p4.c 2010-10-20 16:30:22.000000000 -0400
19483 +++ linux-2.6.36/arch/x86/oprofile/op_model_p4.c 2010-11-06 18:58:15.000000000 -0400
19484 @@ -50,7 +50,7 @@ static inline void setup_num_counters(vo
19485 #endif
19486 }
19487
19488 -static int inline addr_increment(void)
19489 +static inline int addr_increment(void)
19490 {
19491 #ifdef CONFIG_SMP
19492 return smp_num_siblings == 2 ? 2 : 1;
19493 diff -urNp linux-2.6.36/arch/x86/pci/common.c linux-2.6.36/arch/x86/pci/common.c
19494 --- linux-2.6.36/arch/x86/pci/common.c 2010-10-20 16:30:22.000000000 -0400
19495 +++ linux-2.6.36/arch/x86/pci/common.c 2010-11-06 18:58:15.000000000 -0400
19496 @@ -32,8 +32,8 @@ int noioapicreroute = 1;
19497 int pcibios_last_bus = -1;
19498 unsigned long pirq_table_addr;
19499 struct pci_bus *pci_root_bus;
19500 -struct pci_raw_ops *raw_pci_ops;
19501 -struct pci_raw_ops *raw_pci_ext_ops;
19502 +const struct pci_raw_ops *raw_pci_ops;
19503 +const struct pci_raw_ops *raw_pci_ext_ops;
19504
19505 int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
19506 int reg, int len, u32 *val)
19507 @@ -382,7 +382,7 @@ static const struct dmi_system_id __devi
19508 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
19509 },
19510 },
19511 - {}
19512 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
19513 };
19514
19515 void __init dmi_check_pciprobe(void)
19516 diff -urNp linux-2.6.36/arch/x86/pci/direct.c linux-2.6.36/arch/x86/pci/direct.c
19517 --- linux-2.6.36/arch/x86/pci/direct.c 2010-10-20 16:30:22.000000000 -0400
19518 +++ linux-2.6.36/arch/x86/pci/direct.c 2010-11-06 18:58:15.000000000 -0400
19519 @@ -79,7 +79,7 @@ static int pci_conf1_write(unsigned int
19520
19521 #undef PCI_CONF1_ADDRESS
19522
19523 -struct pci_raw_ops pci_direct_conf1 = {
19524 +const struct pci_raw_ops pci_direct_conf1 = {
19525 .read = pci_conf1_read,
19526 .write = pci_conf1_write,
19527 };
19528 @@ -173,7 +173,7 @@ static int pci_conf2_write(unsigned int
19529
19530 #undef PCI_CONF2_ADDRESS
19531
19532 -struct pci_raw_ops pci_direct_conf2 = {
19533 +const struct pci_raw_ops pci_direct_conf2 = {
19534 .read = pci_conf2_read,
19535 .write = pci_conf2_write,
19536 };
19537 @@ -189,7 +189,7 @@ struct pci_raw_ops pci_direct_conf2 = {
19538 * This should be close to trivial, but it isn't, because there are buggy
19539 * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
19540 */
19541 -static int __init pci_sanity_check(struct pci_raw_ops *o)
19542 +static int __init pci_sanity_check(const struct pci_raw_ops *o)
19543 {
19544 u32 x = 0;
19545 int year, devfn;
19546 diff -urNp linux-2.6.36/arch/x86/pci/fixup.c linux-2.6.36/arch/x86/pci/fixup.c
19547 --- linux-2.6.36/arch/x86/pci/fixup.c 2010-10-20 16:30:22.000000000 -0400
19548 +++ linux-2.6.36/arch/x86/pci/fixup.c 2010-11-06 18:58:15.000000000 -0400
19549 @@ -364,7 +364,7 @@ static const struct dmi_system_id __devi
19550 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
19551 },
19552 },
19553 - {}
19554 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19555 };
19556
19557 /*
19558 @@ -435,7 +435,7 @@ static const struct dmi_system_id __devi
19559 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
19560 },
19561 },
19562 - { }
19563 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19564 };
19565
19566 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
19567 diff -urNp linux-2.6.36/arch/x86/pci/irq.c linux-2.6.36/arch/x86/pci/irq.c
19568 --- linux-2.6.36/arch/x86/pci/irq.c 2010-10-20 16:30:22.000000000 -0400
19569 +++ linux-2.6.36/arch/x86/pci/irq.c 2010-11-06 18:58:15.000000000 -0400
19570 @@ -542,7 +542,7 @@ static __init int intel_router_probe(str
19571 static struct pci_device_id __initdata pirq_440gx[] = {
19572 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
19573 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
19574 - { },
19575 + { PCI_DEVICE(0, 0) }
19576 };
19577
19578 /* 440GX has a proprietary PIRQ router -- don't use it */
19579 @@ -1113,7 +1113,7 @@ static struct dmi_system_id __initdata p
19580 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
19581 },
19582 },
19583 - { }
19584 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19585 };
19586
19587 void __init pcibios_irq_init(void)
19588 diff -urNp linux-2.6.36/arch/x86/pci/mmconfig_32.c linux-2.6.36/arch/x86/pci/mmconfig_32.c
19589 --- linux-2.6.36/arch/x86/pci/mmconfig_32.c 2010-10-20 16:30:22.000000000 -0400
19590 +++ linux-2.6.36/arch/x86/pci/mmconfig_32.c 2010-11-06 18:58:15.000000000 -0400
19591 @@ -117,7 +117,7 @@ static int pci_mmcfg_write(unsigned int
19592 return 0;
19593 }
19594
19595 -static struct pci_raw_ops pci_mmcfg = {
19596 +static const struct pci_raw_ops pci_mmcfg = {
19597 .read = pci_mmcfg_read,
19598 .write = pci_mmcfg_write,
19599 };
19600 diff -urNp linux-2.6.36/arch/x86/pci/mmconfig_64.c linux-2.6.36/arch/x86/pci/mmconfig_64.c
19601 --- linux-2.6.36/arch/x86/pci/mmconfig_64.c 2010-10-20 16:30:22.000000000 -0400
19602 +++ linux-2.6.36/arch/x86/pci/mmconfig_64.c 2010-11-06 18:58:15.000000000 -0400
19603 @@ -81,7 +81,7 @@ static int pci_mmcfg_write(unsigned int
19604 return 0;
19605 }
19606
19607 -static struct pci_raw_ops pci_mmcfg = {
19608 +static const struct pci_raw_ops pci_mmcfg = {
19609 .read = pci_mmcfg_read,
19610 .write = pci_mmcfg_write,
19611 };
19612 diff -urNp linux-2.6.36/arch/x86/pci/numaq_32.c linux-2.6.36/arch/x86/pci/numaq_32.c
19613 --- linux-2.6.36/arch/x86/pci/numaq_32.c 2010-10-20 16:30:22.000000000 -0400
19614 +++ linux-2.6.36/arch/x86/pci/numaq_32.c 2010-11-06 18:58:15.000000000 -0400
19615 @@ -108,7 +108,7 @@ static int pci_conf1_mq_write(unsigned i
19616
19617 #undef PCI_CONF1_MQ_ADDRESS
19618
19619 -static struct pci_raw_ops pci_direct_conf1_mq = {
19620 +static const struct pci_raw_ops pci_direct_conf1_mq = {
19621 .read = pci_conf1_mq_read,
19622 .write = pci_conf1_mq_write
19623 };
19624 diff -urNp linux-2.6.36/arch/x86/pci/olpc.c linux-2.6.36/arch/x86/pci/olpc.c
19625 --- linux-2.6.36/arch/x86/pci/olpc.c 2010-10-20 16:30:22.000000000 -0400
19626 +++ linux-2.6.36/arch/x86/pci/olpc.c 2010-11-06 18:58:15.000000000 -0400
19627 @@ -297,7 +297,7 @@ static int pci_olpc_write(unsigned int s
19628 return 0;
19629 }
19630
19631 -static struct pci_raw_ops pci_olpc_conf = {
19632 +static const struct pci_raw_ops pci_olpc_conf = {
19633 .read = pci_olpc_read,
19634 .write = pci_olpc_write,
19635 };
19636 diff -urNp linux-2.6.36/arch/x86/pci/pcbios.c linux-2.6.36/arch/x86/pci/pcbios.c
19637 --- linux-2.6.36/arch/x86/pci/pcbios.c 2010-10-20 16:30:22.000000000 -0400
19638 +++ linux-2.6.36/arch/x86/pci/pcbios.c 2010-11-06 18:58:15.000000000 -0400
19639 @@ -57,50 +57,93 @@ union bios32 {
19640 static struct {
19641 unsigned long address;
19642 unsigned short segment;
19643 -} bios32_indirect = { 0, __KERNEL_CS };
19644 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
19645
19646 /*
19647 * Returns the entry point for the given service, NULL on error
19648 */
19649
19650 -static unsigned long bios32_service(unsigned long service)
19651 +static unsigned long __devinit bios32_service(unsigned long service)
19652 {
19653 unsigned char return_code; /* %al */
19654 unsigned long address; /* %ebx */
19655 unsigned long length; /* %ecx */
19656 unsigned long entry; /* %edx */
19657 unsigned long flags;
19658 + struct desc_struct d, *gdt;
19659
19660 local_irq_save(flags);
19661 - __asm__("lcall *(%%edi); cld"
19662 +
19663 + gdt = get_cpu_gdt_table(smp_processor_id());
19664 +
19665 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
19666 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
19667 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
19668 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
19669 +
19670 + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
19671 : "=a" (return_code),
19672 "=b" (address),
19673 "=c" (length),
19674 "=d" (entry)
19675 : "0" (service),
19676 "1" (0),
19677 - "D" (&bios32_indirect));
19678 + "D" (&bios32_indirect),
19679 + "r"(__PCIBIOS_DS)
19680 + : "memory");
19681 +
19682 + pax_open_kernel();
19683 + gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
19684 + gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
19685 + gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
19686 + gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
19687 + pax_close_kernel();
19688 +
19689 local_irq_restore(flags);
19690
19691 switch (return_code) {
19692 - case 0:
19693 - return address + entry;
19694 - case 0x80: /* Not present */
19695 - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
19696 - return 0;
19697 - default: /* Shouldn't happen */
19698 - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
19699 - service, return_code);
19700 + case 0: {
19701 + int cpu;
19702 + unsigned char flags;
19703 +
19704 + printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
19705 + if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
19706 + printk(KERN_WARNING "bios32_service: not valid\n");
19707 return 0;
19708 + }
19709 + address = address + PAGE_OFFSET;
19710 + length += 16UL; /* some BIOSs underreport this... */
19711 + flags = 4;
19712 + if (length >= 64*1024*1024) {
19713 + length >>= PAGE_SHIFT;
19714 + flags |= 8;
19715 + }
19716 +
19717 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
19718 + gdt = get_cpu_gdt_table(cpu);
19719 + pack_descriptor(&d, address, length, 0x9b, flags);
19720 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
19721 + pack_descriptor(&d, address, length, 0x93, flags);
19722 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
19723 + }
19724 + return entry;
19725 + }
19726 + case 0x80: /* Not present */
19727 + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
19728 + return 0;
19729 + default: /* Shouldn't happen */
19730 + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
19731 + service, return_code);
19732 + return 0;
19733 }
19734 }
19735
19736 static struct {
19737 unsigned long address;
19738 unsigned short segment;
19739 -} pci_indirect = { 0, __KERNEL_CS };
19740 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
19741
19742 -static int pci_bios_present;
19743 +static int pci_bios_present __read_only;
19744
19745 static int __devinit check_pcibios(void)
19746 {
19747 @@ -109,11 +152,13 @@ static int __devinit check_pcibios(void)
19748 unsigned long flags, pcibios_entry;
19749
19750 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
19751 - pci_indirect.address = pcibios_entry + PAGE_OFFSET;
19752 + pci_indirect.address = pcibios_entry;
19753
19754 local_irq_save(flags);
19755 - __asm__(
19756 - "lcall *(%%edi); cld\n\t"
19757 + __asm__("movw %w6, %%ds\n\t"
19758 + "lcall *%%ss:(%%edi); cld\n\t"
19759 + "push %%ss\n\t"
19760 + "pop %%ds\n\t"
19761 "jc 1f\n\t"
19762 "xor %%ah, %%ah\n"
19763 "1:"
19764 @@ -122,7 +167,8 @@ static int __devinit check_pcibios(void)
19765 "=b" (ebx),
19766 "=c" (ecx)
19767 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
19768 - "D" (&pci_indirect)
19769 + "D" (&pci_indirect),
19770 + "r" (__PCIBIOS_DS)
19771 : "memory");
19772 local_irq_restore(flags);
19773
19774 @@ -166,7 +212,10 @@ static int pci_bios_read(unsigned int se
19775
19776 switch (len) {
19777 case 1:
19778 - __asm__("lcall *(%%esi); cld\n\t"
19779 + __asm__("movw %w6, %%ds\n\t"
19780 + "lcall *%%ss:(%%esi); cld\n\t"
19781 + "push %%ss\n\t"
19782 + "pop %%ds\n\t"
19783 "jc 1f\n\t"
19784 "xor %%ah, %%ah\n"
19785 "1:"
19786 @@ -175,7 +224,8 @@ static int pci_bios_read(unsigned int se
19787 : "1" (PCIBIOS_READ_CONFIG_BYTE),
19788 "b" (bx),
19789 "D" ((long)reg),
19790 - "S" (&pci_indirect));
19791 + "S" (&pci_indirect),
19792 + "r" (__PCIBIOS_DS));
19793 /*
19794 * Zero-extend the result beyond 8 bits, do not trust the
19795 * BIOS having done it:
19796 @@ -183,7 +233,10 @@ static int pci_bios_read(unsigned int se
19797 *value &= 0xff;
19798 break;
19799 case 2:
19800 - __asm__("lcall *(%%esi); cld\n\t"
19801 + __asm__("movw %w6, %%ds\n\t"
19802 + "lcall *%%ss:(%%esi); cld\n\t"
19803 + "push %%ss\n\t"
19804 + "pop %%ds\n\t"
19805 "jc 1f\n\t"
19806 "xor %%ah, %%ah\n"
19807 "1:"
19808 @@ -192,7 +245,8 @@ static int pci_bios_read(unsigned int se
19809 : "1" (PCIBIOS_READ_CONFIG_WORD),
19810 "b" (bx),
19811 "D" ((long)reg),
19812 - "S" (&pci_indirect));
19813 + "S" (&pci_indirect),
19814 + "r" (__PCIBIOS_DS));
19815 /*
19816 * Zero-extend the result beyond 16 bits, do not trust the
19817 * BIOS having done it:
19818 @@ -200,7 +254,10 @@ static int pci_bios_read(unsigned int se
19819 *value &= 0xffff;
19820 break;
19821 case 4:
19822 - __asm__("lcall *(%%esi); cld\n\t"
19823 + __asm__("movw %w6, %%ds\n\t"
19824 + "lcall *%%ss:(%%esi); cld\n\t"
19825 + "push %%ss\n\t"
19826 + "pop %%ds\n\t"
19827 "jc 1f\n\t"
19828 "xor %%ah, %%ah\n"
19829 "1:"
19830 @@ -209,7 +266,8 @@ static int pci_bios_read(unsigned int se
19831 : "1" (PCIBIOS_READ_CONFIG_DWORD),
19832 "b" (bx),
19833 "D" ((long)reg),
19834 - "S" (&pci_indirect));
19835 + "S" (&pci_indirect),
19836 + "r" (__PCIBIOS_DS));
19837 break;
19838 }
19839
19840 @@ -232,7 +290,10 @@ static int pci_bios_write(unsigned int s
19841
19842 switch (len) {
19843 case 1:
19844 - __asm__("lcall *(%%esi); cld\n\t"
19845 + __asm__("movw %w6, %%ds\n\t"
19846 + "lcall *%%ss:(%%esi); cld\n\t"
19847 + "push %%ss\n\t"
19848 + "pop %%ds\n\t"
19849 "jc 1f\n\t"
19850 "xor %%ah, %%ah\n"
19851 "1:"
19852 @@ -241,10 +302,14 @@ static int pci_bios_write(unsigned int s
19853 "c" (value),
19854 "b" (bx),
19855 "D" ((long)reg),
19856 - "S" (&pci_indirect));
19857 + "S" (&pci_indirect),
19858 + "r" (__PCIBIOS_DS));
19859 break;
19860 case 2:
19861 - __asm__("lcall *(%%esi); cld\n\t"
19862 + __asm__("movw %w6, %%ds\n\t"
19863 + "lcall *%%ss:(%%esi); cld\n\t"
19864 + "push %%ss\n\t"
19865 + "pop %%ds\n\t"
19866 "jc 1f\n\t"
19867 "xor %%ah, %%ah\n"
19868 "1:"
19869 @@ -253,10 +318,14 @@ static int pci_bios_write(unsigned int s
19870 "c" (value),
19871 "b" (bx),
19872 "D" ((long)reg),
19873 - "S" (&pci_indirect));
19874 + "S" (&pci_indirect),
19875 + "r" (__PCIBIOS_DS));
19876 break;
19877 case 4:
19878 - __asm__("lcall *(%%esi); cld\n\t"
19879 + __asm__("movw %w6, %%ds\n\t"
19880 + "lcall *%%ss:(%%esi); cld\n\t"
19881 + "push %%ss\n\t"
19882 + "pop %%ds\n\t"
19883 "jc 1f\n\t"
19884 "xor %%ah, %%ah\n"
19885 "1:"
19886 @@ -265,7 +334,8 @@ static int pci_bios_write(unsigned int s
19887 "c" (value),
19888 "b" (bx),
19889 "D" ((long)reg),
19890 - "S" (&pci_indirect));
19891 + "S" (&pci_indirect),
19892 + "r" (__PCIBIOS_DS));
19893 break;
19894 }
19895
19896 @@ -279,7 +349,7 @@ static int pci_bios_write(unsigned int s
19897 * Function table for BIOS32 access
19898 */
19899
19900 -static struct pci_raw_ops pci_bios_access = {
19901 +static const struct pci_raw_ops pci_bios_access = {
19902 .read = pci_bios_read,
19903 .write = pci_bios_write
19904 };
19905 @@ -288,7 +358,7 @@ static struct pci_raw_ops pci_bios_acces
19906 * Try to find PCI BIOS.
19907 */
19908
19909 -static struct pci_raw_ops * __devinit pci_find_bios(void)
19910 +static const struct pci_raw_ops * __devinit pci_find_bios(void)
19911 {
19912 union bios32 *check;
19913 unsigned char sum;
19914 @@ -369,10 +439,13 @@ struct irq_routing_table * pcibios_get_i
19915
19916 DBG("PCI: Fetching IRQ routing table... ");
19917 __asm__("push %%es\n\t"
19918 + "movw %w8, %%ds\n\t"
19919 "push %%ds\n\t"
19920 "pop %%es\n\t"
19921 - "lcall *(%%esi); cld\n\t"
19922 + "lcall *%%ss:(%%esi); cld\n\t"
19923 "pop %%es\n\t"
19924 + "push %%ss\n\t"
19925 + "pop %%ds\n"
19926 "jc 1f\n\t"
19927 "xor %%ah, %%ah\n"
19928 "1:"
19929 @@ -383,7 +456,8 @@ struct irq_routing_table * pcibios_get_i
19930 "1" (0),
19931 "D" ((long) &opt),
19932 "S" (&pci_indirect),
19933 - "m" (opt)
19934 + "m" (opt),
19935 + "r" (__PCIBIOS_DS)
19936 : "memory");
19937 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
19938 if (ret & 0xff00)
19939 @@ -407,7 +481,10 @@ int pcibios_set_irq_routing(struct pci_d
19940 {
19941 int ret;
19942
19943 - __asm__("lcall *(%%esi); cld\n\t"
19944 + __asm__("movw %w5, %%ds\n\t"
19945 + "lcall *%%ss:(%%esi); cld\n\t"
19946 + "push %%ss\n\t"
19947 + "pop %%ds\n"
19948 "jc 1f\n\t"
19949 "xor %%ah, %%ah\n"
19950 "1:"
19951 @@ -415,7 +492,8 @@ int pcibios_set_irq_routing(struct pci_d
19952 : "0" (PCIBIOS_SET_PCI_HW_INT),
19953 "b" ((dev->bus->number << 8) | dev->devfn),
19954 "c" ((irq << 8) | (pin + 10)),
19955 - "S" (&pci_indirect));
19956 + "S" (&pci_indirect),
19957 + "r" (__PCIBIOS_DS));
19958 return !(ret & 0xff00);
19959 }
19960 EXPORT_SYMBOL(pcibios_set_irq_routing);
19961 diff -urNp linux-2.6.36/arch/x86/power/cpu.c linux-2.6.36/arch/x86/power/cpu.c
19962 --- linux-2.6.36/arch/x86/power/cpu.c 2010-10-20 16:30:22.000000000 -0400
19963 +++ linux-2.6.36/arch/x86/power/cpu.c 2010-11-06 18:58:15.000000000 -0400
19964 @@ -130,7 +130,7 @@ static void do_fpu_end(void)
19965 static void fix_processor_context(void)
19966 {
19967 int cpu = smp_processor_id();
19968 - struct tss_struct *t = &per_cpu(init_tss, cpu);
19969 + struct tss_struct *t = init_tss + cpu;
19970
19971 set_tss_desc(cpu, t); /*
19972 * This just modifies memory; should not be
19973 @@ -140,7 +140,9 @@ static void fix_processor_context(void)
19974 */
19975
19976 #ifdef CONFIG_X86_64
19977 + pax_open_kernel();
19978 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
19979 + pax_close_kernel();
19980
19981 syscall_init(); /* This sets MSR_*STAR and related */
19982 #endif
19983 diff -urNp linux-2.6.36/arch/x86/vdso/Makefile linux-2.6.36/arch/x86/vdso/Makefile
19984 --- linux-2.6.36/arch/x86/vdso/Makefile 2010-10-20 16:30:22.000000000 -0400
19985 +++ linux-2.6.36/arch/x86/vdso/Makefile 2010-11-06 18:58:15.000000000 -0400
19986 @@ -123,7 +123,7 @@ quiet_cmd_vdso = VDSO $@
19987 -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
19988 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
19989
19990 -VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
19991 +VDSO_LDFLAGS = -fPIC -shared --no-undefined $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
19992 GCOV_PROFILE := n
19993
19994 #
19995 diff -urNp linux-2.6.36/arch/x86/vdso/vclock_gettime.c linux-2.6.36/arch/x86/vdso/vclock_gettime.c
19996 --- linux-2.6.36/arch/x86/vdso/vclock_gettime.c 2010-10-20 16:30:22.000000000 -0400
19997 +++ linux-2.6.36/arch/x86/vdso/vclock_gettime.c 2010-11-06 18:58:15.000000000 -0400
19998 @@ -22,24 +22,48 @@
19999 #include <asm/hpet.h>
20000 #include <asm/unistd.h>
20001 #include <asm/io.h>
20002 +#include <asm/fixmap.h>
20003 #include "vextern.h"
20004
20005 #define gtod vdso_vsyscall_gtod_data
20006
20007 +notrace noinline long __vdso_fallback_time(long *t)
20008 +{
20009 + long secs;
20010 + asm volatile("syscall"
20011 + : "=a" (secs)
20012 + : "0" (__NR_time),"D" (t) : "r11", "cx", "memory");
20013 + return secs;
20014 +}
20015 +
20016 notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
20017 {
20018 long ret;
20019 asm("syscall" : "=a" (ret) :
20020 - "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "memory");
20021 + "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "r11", "cx", "memory");
20022 return ret;
20023 }
20024
20025 +notrace static inline cycle_t __vdso_vread_hpet(void)
20026 +{
20027 + return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0);
20028 +}
20029 +
20030 +notrace static inline cycle_t __vdso_vread_tsc(void)
20031 +{
20032 + cycle_t ret = (cycle_t)vget_cycles();
20033 +
20034 + return ret >= gtod->clock.cycle_last ? ret : gtod->clock.cycle_last;
20035 +}
20036 +
20037 notrace static inline long vgetns(void)
20038 {
20039 long v;
20040 - cycles_t (*vread)(void);
20041 - vread = gtod->clock.vread;
20042 - v = (vread() - gtod->clock.cycle_last) & gtod->clock.mask;
20043 + if (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3])
20044 + v = __vdso_vread_tsc();
20045 + else
20046 + v = __vdso_vread_hpet();
20047 + v = (v - gtod->clock.cycle_last) & gtod->clock.mask;
20048 return (v * gtod->clock.mult) >> gtod->clock.shift;
20049 }
20050
20051 @@ -113,7 +137,9 @@ notrace static noinline int do_monotonic
20052
20053 notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
20054 {
20055 - if (likely(gtod->sysctl_enabled))
20056 + if (likely(gtod->sysctl_enabled &&
20057 + ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) ||
20058 + (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]))))
20059 switch (clock) {
20060 case CLOCK_REALTIME:
20061 if (likely(gtod->clock.vread))
20062 @@ -133,10 +159,20 @@ notrace int __vdso_clock_gettime(clockid
20063 int clock_gettime(clockid_t, struct timespec *)
20064 __attribute__((weak, alias("__vdso_clock_gettime")));
20065
20066 -notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
20067 +notrace noinline int __vdso_fallback_gettimeofday(struct timeval *tv, struct timezone *tz)
20068 {
20069 long ret;
20070 - if (likely(gtod->sysctl_enabled && gtod->clock.vread)) {
20071 + asm("syscall" : "=a" (ret) :
20072 + "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "r11", "cx", "memory");
20073 + return ret;
20074 +}
20075 +
20076 +notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
20077 +{
20078 + if (likely(gtod->sysctl_enabled &&
20079 + ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) ||
20080 + (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]))))
20081 + {
20082 if (likely(tv != NULL)) {
20083 BUILD_BUG_ON(offsetof(struct timeval, tv_usec) !=
20084 offsetof(struct timespec, tv_nsec) ||
20085 @@ -151,9 +187,7 @@ notrace int __vdso_gettimeofday(struct t
20086 }
20087 return 0;
20088 }
20089 - asm("syscall" : "=a" (ret) :
20090 - "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
20091 - return ret;
20092 + return __vdso_fallback_gettimeofday(tv, tz);
20093 }
20094 int gettimeofday(struct timeval *, struct timezone *)
20095 __attribute__((weak, alias("__vdso_gettimeofday")));
20096 diff -urNp linux-2.6.36/arch/x86/vdso/vdso32-setup.c linux-2.6.36/arch/x86/vdso/vdso32-setup.c
20097 --- linux-2.6.36/arch/x86/vdso/vdso32-setup.c 2010-10-20 16:30:22.000000000 -0400
20098 +++ linux-2.6.36/arch/x86/vdso/vdso32-setup.c 2010-11-06 18:58:15.000000000 -0400
20099 @@ -25,6 +25,7 @@
20100 #include <asm/tlbflush.h>
20101 #include <asm/vdso.h>
20102 #include <asm/proto.h>
20103 +#include <asm/mman.h>
20104
20105 enum {
20106 VDSO_DISABLED = 0,
20107 @@ -226,7 +227,7 @@ static inline void map_compat_vdso(int m
20108 void enable_sep_cpu(void)
20109 {
20110 int cpu = get_cpu();
20111 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
20112 + struct tss_struct *tss = init_tss + cpu;
20113
20114 if (!boot_cpu_has(X86_FEATURE_SEP)) {
20115 put_cpu();
20116 @@ -249,7 +250,7 @@ static int __init gate_vma_init(void)
20117 gate_vma.vm_start = FIXADDR_USER_START;
20118 gate_vma.vm_end = FIXADDR_USER_END;
20119 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
20120 - gate_vma.vm_page_prot = __P101;
20121 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
20122 /*
20123 * Make sure the vDSO gets into every core dump.
20124 * Dumping its contents makes post-mortem fully interpretable later
20125 @@ -331,14 +332,14 @@ int arch_setup_additional_pages(struct l
20126 if (compat)
20127 addr = VDSO_HIGH_BASE;
20128 else {
20129 - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
20130 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
20131 if (IS_ERR_VALUE(addr)) {
20132 ret = addr;
20133 goto up_fail;
20134 }
20135 }
20136
20137 - current->mm->context.vdso = (void *)addr;
20138 + current->mm->context.vdso = addr;
20139
20140 if (compat_uses_vma || !compat) {
20141 /*
20142 @@ -361,11 +362,11 @@ int arch_setup_additional_pages(struct l
20143 }
20144
20145 current_thread_info()->sysenter_return =
20146 - VDSO32_SYMBOL(addr, SYSENTER_RETURN);
20147 + (__force void __user *)VDSO32_SYMBOL(addr, SYSENTER_RETURN);
20148
20149 up_fail:
20150 if (ret)
20151 - current->mm->context.vdso = NULL;
20152 + current->mm->context.vdso = 0;
20153
20154 up_write(&mm->mmap_sem);
20155
20156 @@ -412,8 +413,14 @@ __initcall(ia32_binfmt_init);
20157
20158 const char *arch_vma_name(struct vm_area_struct *vma)
20159 {
20160 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
20161 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
20162 return "[vdso]";
20163 +
20164 +#ifdef CONFIG_PAX_SEGMEXEC
20165 + if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
20166 + return "[vdso]";
20167 +#endif
20168 +
20169 return NULL;
20170 }
20171
20172 @@ -422,7 +429,7 @@ struct vm_area_struct *get_gate_vma(stru
20173 struct mm_struct *mm = tsk->mm;
20174
20175 /* Check to see if this task was created in compat vdso mode */
20176 - if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
20177 + if (mm && mm->context.vdso == VDSO_HIGH_BASE)
20178 return &gate_vma;
20179 return NULL;
20180 }
20181 diff -urNp linux-2.6.36/arch/x86/vdso/vdso.lds.S linux-2.6.36/arch/x86/vdso/vdso.lds.S
20182 --- linux-2.6.36/arch/x86/vdso/vdso.lds.S 2010-10-20 16:30:22.000000000 -0400
20183 +++ linux-2.6.36/arch/x86/vdso/vdso.lds.S 2010-11-06 18:58:15.000000000 -0400
20184 @@ -35,3 +35,9 @@ VDSO64_PRELINK = VDSO_PRELINK;
20185 #define VEXTERN(x) VDSO64_ ## x = vdso_ ## x;
20186 #include "vextern.h"
20187 #undef VEXTERN
20188 +
20189 +#define VEXTERN(x) VDSO64_ ## x = __vdso_ ## x;
20190 +VEXTERN(fallback_gettimeofday)
20191 +VEXTERN(fallback_time)
20192 +VEXTERN(getcpu)
20193 +#undef VEXTERN
20194 diff -urNp linux-2.6.36/arch/x86/vdso/vextern.h linux-2.6.36/arch/x86/vdso/vextern.h
20195 --- linux-2.6.36/arch/x86/vdso/vextern.h 2010-10-20 16:30:22.000000000 -0400
20196 +++ linux-2.6.36/arch/x86/vdso/vextern.h 2010-11-06 18:58:15.000000000 -0400
20197 @@ -11,6 +11,5 @@
20198 put into vextern.h and be referenced as a pointer with vdso prefix.
20199 The main kernel later fills in the values. */
20200
20201 -VEXTERN(jiffies)
20202 VEXTERN(vgetcpu_mode)
20203 VEXTERN(vsyscall_gtod_data)
20204 diff -urNp linux-2.6.36/arch/x86/vdso/vma.c linux-2.6.36/arch/x86/vdso/vma.c
20205 --- linux-2.6.36/arch/x86/vdso/vma.c 2010-10-20 16:30:22.000000000 -0400
20206 +++ linux-2.6.36/arch/x86/vdso/vma.c 2010-11-06 18:58:15.000000000 -0400
20207 @@ -58,7 +58,7 @@ static int __init init_vdso_vars(void)
20208 if (!vbase)
20209 goto oom;
20210
20211 - if (memcmp(vbase, "\177ELF", 4)) {
20212 + if (memcmp(vbase, ELFMAG, SELFMAG)) {
20213 printk("VDSO: I'm broken; not ELF\n");
20214 vdso_enabled = 0;
20215 }
20216 @@ -118,7 +118,7 @@ int arch_setup_additional_pages(struct l
20217 goto up_fail;
20218 }
20219
20220 - current->mm->context.vdso = (void *)addr;
20221 + current->mm->context.vdso = addr;
20222
20223 ret = install_special_mapping(mm, addr, vdso_size,
20224 VM_READ|VM_EXEC|
20225 @@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l
20226 VM_ALWAYSDUMP,
20227 vdso_pages);
20228 if (ret) {
20229 - current->mm->context.vdso = NULL;
20230 + current->mm->context.vdso = 0;
20231 goto up_fail;
20232 }
20233
20234 @@ -134,10 +134,3 @@ up_fail:
20235 up_write(&mm->mmap_sem);
20236 return ret;
20237 }
20238 -
20239 -static __init int vdso_setup(char *s)
20240 -{
20241 - vdso_enabled = simple_strtoul(s, NULL, 0);
20242 - return 0;
20243 -}
20244 -__setup("vdso=", vdso_setup);
20245 diff -urNp linux-2.6.36/arch/x86/xen/enlighten.c linux-2.6.36/arch/x86/xen/enlighten.c
20246 --- linux-2.6.36/arch/x86/xen/enlighten.c 2010-10-20 16:30:22.000000000 -0400
20247 +++ linux-2.6.36/arch/x86/xen/enlighten.c 2010-11-06 18:58:15.000000000 -0400
20248 @@ -79,8 +79,6 @@ EXPORT_SYMBOL_GPL(xen_start_info);
20249
20250 struct shared_info xen_dummy_shared_info;
20251
20252 -void *xen_initial_gdt;
20253 -
20254 RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
20255 __read_mostly int xen_have_vector_callback;
20256 EXPORT_SYMBOL_GPL(xen_have_vector_callback);
20257 @@ -573,7 +571,7 @@ static void xen_write_idt_entry(gate_des
20258
20259 preempt_disable();
20260
20261 - start = __get_cpu_var(idt_desc).address;
20262 + start = (unsigned long)__get_cpu_var(idt_desc).address;
20263 end = start + __get_cpu_var(idt_desc).size + 1;
20264
20265 xen_mc_flush();
20266 @@ -1130,7 +1128,17 @@ asmlinkage void __init xen_start_kernel(
20267 __userpte_alloc_gfp &= ~__GFP_HIGHMEM;
20268
20269 /* Work out if we support NX */
20270 - x86_configure_nx();
20271 +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
20272 + if ((cpuid_eax(0x80000000) & 0xffff0000) == 0x80000000 &&
20273 + (cpuid_edx(0x80000001) & (1U << (X86_FEATURE_NX & 31)))) {
20274 + unsigned l, h;
20275 +
20276 + __supported_pte_mask |= _PAGE_NX;
20277 + rdmsr(MSR_EFER, l, h);
20278 + l |= EFER_NX;
20279 + wrmsr(MSR_EFER, l, h);
20280 + }
20281 +#endif
20282
20283 xen_setup_features();
20284
20285 @@ -1161,13 +1169,6 @@ asmlinkage void __init xen_start_kernel(
20286
20287 machine_ops = xen_machine_ops;
20288
20289 - /*
20290 - * The only reliable way to retain the initial address of the
20291 - * percpu gdt_page is to remember it here, so we can go and
20292 - * mark it RW later, when the initial percpu area is freed.
20293 - */
20294 - xen_initial_gdt = &per_cpu(gdt_page, 0);
20295 -
20296 xen_smp_init();
20297
20298 pgd = (pgd_t *)xen_start_info->pt_base;
20299 diff -urNp linux-2.6.36/arch/x86/xen/mmu.c linux-2.6.36/arch/x86/xen/mmu.c
20300 --- linux-2.6.36/arch/x86/xen/mmu.c 2010-10-20 16:30:22.000000000 -0400
20301 +++ linux-2.6.36/arch/x86/xen/mmu.c 2010-11-06 18:58:15.000000000 -0400
20302 @@ -1773,6 +1773,8 @@ __init pgd_t *xen_setup_kernel_pagetable
20303 convert_pfn_mfn(init_level4_pgt);
20304 convert_pfn_mfn(level3_ident_pgt);
20305 convert_pfn_mfn(level3_kernel_pgt);
20306 + convert_pfn_mfn(level3_vmalloc_pgt);
20307 + convert_pfn_mfn(level3_vmemmap_pgt);
20308
20309 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
20310 l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
20311 @@ -1791,7 +1793,10 @@ __init pgd_t *xen_setup_kernel_pagetable
20312 set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
20313 set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
20314 set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
20315 + set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
20316 + set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
20317 set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
20318 + set_page_prot(level2_vmemmap_pgt, PAGE_KERNEL_RO);
20319 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
20320 set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
20321
20322 diff -urNp linux-2.6.36/arch/x86/xen/pci-swiotlb-xen.c linux-2.6.36/arch/x86/xen/pci-swiotlb-xen.c
20323 --- linux-2.6.36/arch/x86/xen/pci-swiotlb-xen.c 2010-10-20 16:30:22.000000000 -0400
20324 +++ linux-2.6.36/arch/x86/xen/pci-swiotlb-xen.c 2010-11-06 18:58:15.000000000 -0400
20325 @@ -8,7 +8,7 @@
20326
20327 int xen_swiotlb __read_mostly;
20328
20329 -static struct dma_map_ops xen_swiotlb_dma_ops = {
20330 +static const struct dma_map_ops xen_swiotlb_dma_ops = {
20331 .mapping_error = xen_swiotlb_dma_mapping_error,
20332 .alloc_coherent = xen_swiotlb_alloc_coherent,
20333 .free_coherent = xen_swiotlb_free_coherent,
20334 diff -urNp linux-2.6.36/arch/x86/xen/smp.c linux-2.6.36/arch/x86/xen/smp.c
20335 --- linux-2.6.36/arch/x86/xen/smp.c 2010-10-20 16:30:22.000000000 -0400
20336 +++ linux-2.6.36/arch/x86/xen/smp.c 2010-11-06 18:58:15.000000000 -0400
20337 @@ -169,11 +169,6 @@ static void __init xen_smp_prepare_boot_
20338 {
20339 BUG_ON(smp_processor_id() != 0);
20340 native_smp_prepare_boot_cpu();
20341 -
20342 - /* We've switched to the "real" per-cpu gdt, so make sure the
20343 - old memory can be recycled */
20344 - make_lowmem_page_readwrite(xen_initial_gdt);
20345 -
20346 xen_setup_vcpu_info_placement();
20347 }
20348
20349 @@ -233,8 +228,8 @@ cpu_initialize_context(unsigned int cpu,
20350 gdt = get_cpu_gdt_table(cpu);
20351
20352 ctxt->flags = VGCF_IN_KERNEL;
20353 - ctxt->user_regs.ds = __USER_DS;
20354 - ctxt->user_regs.es = __USER_DS;
20355 + ctxt->user_regs.ds = __KERNEL_DS;
20356 + ctxt->user_regs.es = __KERNEL_DS;
20357 ctxt->user_regs.ss = __KERNEL_DS;
20358 #ifdef CONFIG_X86_32
20359 ctxt->user_regs.fs = __KERNEL_PERCPU;
20360 diff -urNp linux-2.6.36/arch/x86/xen/xen-head.S linux-2.6.36/arch/x86/xen/xen-head.S
20361 --- linux-2.6.36/arch/x86/xen/xen-head.S 2010-10-20 16:30:22.000000000 -0400
20362 +++ linux-2.6.36/arch/x86/xen/xen-head.S 2010-11-06 18:58:15.000000000 -0400
20363 @@ -19,6 +19,17 @@ ENTRY(startup_xen)
20364 #ifdef CONFIG_X86_32
20365 mov %esi,xen_start_info
20366 mov $init_thread_union+THREAD_SIZE,%esp
20367 +#ifdef CONFIG_SMP
20368 + movl $cpu_gdt_table,%edi
20369 + movl $__per_cpu_load,%eax
20370 + movw %ax,__KERNEL_PERCPU + 2(%edi)
20371 + rorl $16,%eax
20372 + movb %al,__KERNEL_PERCPU + 4(%edi)
20373 + movb %ah,__KERNEL_PERCPU + 7(%edi)
20374 + movl $__per_cpu_end - 1,%eax
20375 + subl $__per_cpu_start,%eax
20376 + movw %ax,__KERNEL_PERCPU + 0(%edi)
20377 +#endif
20378 #else
20379 mov %rsi,xen_start_info
20380 mov $init_thread_union+THREAD_SIZE,%rsp
20381 diff -urNp linux-2.6.36/arch/x86/xen/xen-ops.h linux-2.6.36/arch/x86/xen/xen-ops.h
20382 --- linux-2.6.36/arch/x86/xen/xen-ops.h 2010-10-20 16:30:22.000000000 -0400
20383 +++ linux-2.6.36/arch/x86/xen/xen-ops.h 2010-11-06 18:58:15.000000000 -0400
20384 @@ -10,8 +10,6 @@
20385 extern const char xen_hypervisor_callback[];
20386 extern const char xen_failsafe_callback[];
20387
20388 -extern void *xen_initial_gdt;
20389 -
20390 struct trap_info;
20391 void xen_copy_trap_info(struct trap_info *traps);
20392
20393 diff -urNp linux-2.6.36/block/blk-iopoll.c linux-2.6.36/block/blk-iopoll.c
20394 --- linux-2.6.36/block/blk-iopoll.c 2010-10-20 16:30:22.000000000 -0400
20395 +++ linux-2.6.36/block/blk-iopoll.c 2010-11-06 18:58:15.000000000 -0400
20396 @@ -77,7 +77,7 @@ void blk_iopoll_complete(struct blk_iopo
20397 }
20398 EXPORT_SYMBOL(blk_iopoll_complete);
20399
20400 -static void blk_iopoll_softirq(struct softirq_action *h)
20401 +static void blk_iopoll_softirq(void)
20402 {
20403 struct list_head *list = &__get_cpu_var(blk_cpu_iopoll);
20404 int rearm = 0, budget = blk_iopoll_budget;
20405 diff -urNp linux-2.6.36/block/blk-map.c linux-2.6.36/block/blk-map.c
20406 --- linux-2.6.36/block/blk-map.c 2010-10-20 16:30:22.000000000 -0400
20407 +++ linux-2.6.36/block/blk-map.c 2010-11-06 18:58:15.000000000 -0400
20408 @@ -54,7 +54,7 @@ static int __blk_rq_map_user(struct requ
20409 * direct dma. else, set up kernel bounce buffers
20410 */
20411 uaddr = (unsigned long) ubuf;
20412 - if (blk_rq_aligned(q, ubuf, len) && !map_data)
20413 + if (blk_rq_aligned(q, (__force void *)ubuf, len) && !map_data)
20414 bio = bio_map_user(q, NULL, uaddr, len, reading, gfp_mask);
20415 else
20416 bio = bio_copy_user(q, map_data, uaddr, len, reading, gfp_mask);
20417 @@ -297,7 +297,7 @@ int blk_rq_map_kern(struct request_queue
20418 if (!len || !kbuf)
20419 return -EINVAL;
20420
20421 - do_copy = !blk_rq_aligned(q, kbuf, len) || object_is_on_stack(kbuf);
20422 + do_copy = !blk_rq_aligned(q, kbuf, len) || object_starts_on_stack(kbuf);
20423 if (do_copy)
20424 bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading);
20425 else
20426 diff -urNp linux-2.6.36/block/blk-softirq.c linux-2.6.36/block/blk-softirq.c
20427 --- linux-2.6.36/block/blk-softirq.c 2010-10-20 16:30:22.000000000 -0400
20428 +++ linux-2.6.36/block/blk-softirq.c 2010-11-06 18:58:15.000000000 -0400
20429 @@ -17,7 +17,7 @@ static DEFINE_PER_CPU(struct list_head,
20430 * Softirq action handler - move entries to local list and loop over them
20431 * while passing them to the queue registered handler.
20432 */
20433 -static void blk_done_softirq(struct softirq_action *h)
20434 +static void blk_done_softirq(void)
20435 {
20436 struct list_head *cpu_list, local_list;
20437
20438 diff -urNp linux-2.6.36/crypto/lrw.c linux-2.6.36/crypto/lrw.c
20439 --- linux-2.6.36/crypto/lrw.c 2010-10-20 16:30:22.000000000 -0400
20440 +++ linux-2.6.36/crypto/lrw.c 2010-11-06 18:58:15.000000000 -0400
20441 @@ -60,7 +60,7 @@ static int setkey(struct crypto_tfm *par
20442 struct priv *ctx = crypto_tfm_ctx(parent);
20443 struct crypto_cipher *child = ctx->child;
20444 int err, i;
20445 - be128 tmp = { 0 };
20446 + be128 tmp = { 0, 0 };
20447 int bsize = crypto_cipher_blocksize(child);
20448
20449 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
20450 diff -urNp linux-2.6.36/Documentation/dontdiff linux-2.6.36/Documentation/dontdiff
20451 --- linux-2.6.36/Documentation/dontdiff 2010-10-20 16:30:22.000000000 -0400
20452 +++ linux-2.6.36/Documentation/dontdiff 2010-11-06 18:58:15.000000000 -0400
20453 @@ -3,6 +3,7 @@
20454 *.bin
20455 *.cpio
20456 *.csp
20457 +*.dbg
20458 *.dsp
20459 *.dvi
20460 *.elf
20461 @@ -38,8 +39,10 @@
20462 *.tab.h
20463 *.tex
20464 *.ver
20465 +*.vim
20466 *.xml
20467 *_MODULES
20468 +*_reg_safe.h
20469 *_vga16.c
20470 *~
20471 *.9
20472 @@ -49,11 +52,16 @@
20473 53c700_d.h
20474 CVS
20475 ChangeSet
20476 +GPATH
20477 +GRTAGS
20478 +GSYMS
20479 +GTAGS
20480 Image
20481 Kerntypes
20482 Module.markers
20483 Module.symvers
20484 PENDING
20485 +PERF*
20486 SCCS
20487 System.map*
20488 TAGS
20489 @@ -76,7 +84,10 @@ btfixupprep
20490 build
20491 bvmlinux
20492 bzImage*
20493 +capflags.c
20494 classlist.h*
20495 +clut_vga16.c
20496 +common-cmds.h
20497 comp*.log
20498 compile.h*
20499 conf
20500 @@ -100,19 +111,22 @@ fore200e_mkfirm
20501 fore200e_pca_fw.c*
20502 gconf
20503 gen-devlist
20504 +gen-kdb_cmds.c
20505 gen_crc32table
20506 gen_init_cpio
20507 generated
20508 genheaders
20509 genksyms
20510 *_gray256.c
20511 +hash
20512 ihex2fw
20513 ikconfig.h*
20514 +inat-tables.c
20515 initramfs_data.cpio
20516 +initramfs_data.cpio.bz2
20517 initramfs_data.cpio.gz
20518 initramfs_list
20519 kallsyms
20520 -kconfig
20521 keywords.c
20522 ksym.c*
20523 ksym.h*
20524 @@ -136,10 +150,13 @@ mkboot
20525 mkbugboot
20526 mkcpustr
20527 mkdep
20528 +mkpiggy
20529 mkprep
20530 +mkregtable
20531 mktables
20532 mktree
20533 modpost
20534 +modules.builtin
20535 modules.order
20536 modversions.h*
20537 ncscope.*
20538 @@ -151,7 +168,9 @@ parse.h
20539 patches*
20540 pca200e.bin
20541 pca200e_ecd.bin2
20542 +perf-archive
20543 piggy.gz
20544 +piggy.S
20545 piggyback
20546 pnmtologo
20547 ppc_defs.h*
20548 @@ -160,12 +179,14 @@ qconf
20549 raid6altivec*.c
20550 raid6int*.c
20551 raid6tables.c
20552 +regdb.c
20553 relocs
20554 series
20555 setup
20556 setup.bin
20557 setup.elf
20558 sImage
20559 +slabinfo
20560 sm_tbl*
20561 split-include
20562 syscalltab.h
20563 @@ -189,14 +210,20 @@ version.h*
20564 vmlinux
20565 vmlinux-*
20566 vmlinux.aout
20567 +vmlinux.bin.all
20568 +vmlinux.bin.bz2
20569 vmlinux.lds
20570 +vmlinux.relocs
20571 +voffset.h
20572 vsyscall.lds
20573 vsyscall_32.lds
20574 wanxlfw.inc
20575 uImage
20576 unifdef
20577 +utsrelease.h
20578 wakeup.bin
20579 wakeup.elf
20580 wakeup.lds
20581 zImage*
20582 zconf.hash.c
20583 +zoffset.h
20584 diff -urNp linux-2.6.36/Documentation/filesystems/sysfs.txt linux-2.6.36/Documentation/filesystems/sysfs.txt
20585 --- linux-2.6.36/Documentation/filesystems/sysfs.txt 2010-10-20 16:30:22.000000000 -0400
20586 +++ linux-2.6.36/Documentation/filesystems/sysfs.txt 2010-11-06 18:58:15.000000000 -0400
20587 @@ -123,8 +123,8 @@ set of sysfs operations for forwarding r
20588 show and store methods of the attribute owners.
20589
20590 struct sysfs_ops {
20591 - ssize_t (*show)(struct kobject *, struct attribute *, char *);
20592 - ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
20593 + ssize_t (* const show)(struct kobject *, struct attribute *, char *);
20594 + ssize_t (* const store)(struct kobject *, struct attribute *, const char *, size_t);
20595 };
20596
20597 [ Subsystems should have already defined a struct kobj_type as a
20598 diff -urNp linux-2.6.36/Documentation/kernel-parameters.txt linux-2.6.36/Documentation/kernel-parameters.txt
20599 --- linux-2.6.36/Documentation/kernel-parameters.txt 2010-10-20 16:30:22.000000000 -0400
20600 +++ linux-2.6.36/Documentation/kernel-parameters.txt 2010-11-06 18:58:15.000000000 -0400
20601 @@ -1835,6 +1835,12 @@ and is between 256 and 4096 characters.
20602 the specified number of seconds. This is to be used if
20603 your oopses keep scrolling off the screen.
20604
20605 + pax_nouderef [X86-32] disables UDEREF. Most likely needed under certain
20606 + virtualization environments that don't cope well with the
20607 + expand down segment used by UDEREF on X86-32.
20608 +
20609 + pax_softmode= [X86-32] 0/1 to disable/enable PaX softmode on boot already.
20610 +
20611 pcbit= [HW,ISDN]
20612
20613 pcd. [PARIDE]
20614 diff -urNp linux-2.6.36/drivers/acpi/battery.c linux-2.6.36/drivers/acpi/battery.c
20615 --- linux-2.6.36/drivers/acpi/battery.c 2010-10-20 16:30:22.000000000 -0400
20616 +++ linux-2.6.36/drivers/acpi/battery.c 2010-11-06 18:58:15.000000000 -0400
20617 @@ -809,7 +809,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
20618 }
20619
20620 static struct battery_file {
20621 - struct file_operations ops;
20622 + const struct file_operations ops;
20623 mode_t mode;
20624 const char *name;
20625 } acpi_battery_file[] = {
20626 diff -urNp linux-2.6.36/drivers/acpi/blacklist.c linux-2.6.36/drivers/acpi/blacklist.c
20627 --- linux-2.6.36/drivers/acpi/blacklist.c 2010-10-20 16:30:22.000000000 -0400
20628 +++ linux-2.6.36/drivers/acpi/blacklist.c 2010-11-06 18:58:15.000000000 -0400
20629 @@ -73,7 +73,7 @@ static struct acpi_blacklist_item acpi_b
20630 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
20631 "Incorrect _ADR", 1},
20632
20633 - {""}
20634 + {"", "", 0, NULL, all_versions, NULL, 0}
20635 };
20636
20637 #if CONFIG_ACPI_BLACKLIST_YEAR
20638 diff -urNp linux-2.6.36/drivers/acpi/dock.c linux-2.6.36/drivers/acpi/dock.c
20639 --- linux-2.6.36/drivers/acpi/dock.c 2010-10-20 16:30:22.000000000 -0400
20640 +++ linux-2.6.36/drivers/acpi/dock.c 2010-11-06 18:58:15.000000000 -0400
20641 @@ -77,7 +77,7 @@ struct dock_dependent_device {
20642 struct list_head list;
20643 struct list_head hotplug_list;
20644 acpi_handle handle;
20645 - struct acpi_dock_ops *ops;
20646 + const struct acpi_dock_ops *ops;
20647 void *context;
20648 };
20649
20650 @@ -589,7 +589,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifi
20651 * the dock driver after _DCK is executed.
20652 */
20653 int
20654 -register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
20655 +register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops,
20656 void *context)
20657 {
20658 struct dock_dependent_device *dd;
20659 diff -urNp linux-2.6.36/drivers/acpi/osl.c linux-2.6.36/drivers/acpi/osl.c
20660 --- linux-2.6.36/drivers/acpi/osl.c 2010-10-20 16:30:22.000000000 -0400
20661 +++ linux-2.6.36/drivers/acpi/osl.c 2010-11-06 18:58:15.000000000 -0400
20662 @@ -497,6 +497,8 @@ acpi_os_read_memory(acpi_physical_addres
20663 void __iomem *virt_addr;
20664
20665 virt_addr = ioremap(phys_addr, width);
20666 + if (!virt_addr)
20667 + return AE_NO_MEMORY;
20668 if (!value)
20669 value = &dummy;
20670
20671 @@ -525,6 +527,8 @@ acpi_os_write_memory(acpi_physical_addre
20672 void __iomem *virt_addr;
20673
20674 virt_addr = ioremap(phys_addr, width);
20675 + if (!virt_addr)
20676 + return AE_NO_MEMORY;
20677
20678 switch (width) {
20679 case 8:
20680 diff -urNp linux-2.6.36/drivers/acpi/power_meter.c linux-2.6.36/drivers/acpi/power_meter.c
20681 --- linux-2.6.36/drivers/acpi/power_meter.c 2010-10-20 16:30:22.000000000 -0400
20682 +++ linux-2.6.36/drivers/acpi/power_meter.c 2010-11-06 18:58:15.000000000 -0400
20683 @@ -316,8 +316,6 @@ static ssize_t set_trip(struct device *d
20684 return res;
20685
20686 temp /= 1000;
20687 - if (temp < 0)
20688 - return -EINVAL;
20689
20690 mutex_lock(&resource->lock);
20691 resource->trip[attr->index - 7] = temp;
20692 diff -urNp linux-2.6.36/drivers/acpi/proc.c linux-2.6.36/drivers/acpi/proc.c
20693 --- linux-2.6.36/drivers/acpi/proc.c 2010-10-20 16:30:22.000000000 -0400
20694 +++ linux-2.6.36/drivers/acpi/proc.c 2010-11-06 18:58:15.000000000 -0400
20695 @@ -338,20 +338,15 @@ acpi_system_write_wakeup_device(struct f
20696 size_t count, loff_t * ppos)
20697 {
20698 struct list_head *node, *next;
20699 - char strbuf[5];
20700 - char str[5] = "";
20701 - unsigned int len = count;
20702 + char strbuf[5] = {0};
20703 struct acpi_device *found_dev = NULL;
20704
20705 - if (len > 4)
20706 - len = 4;
20707 - if (len < 0)
20708 - return -EFAULT;
20709 + if (count > 4)
20710 + count = 4;
20711
20712 - if (copy_from_user(strbuf, buffer, len))
20713 + if (copy_from_user(strbuf, buffer, count))
20714 return -EFAULT;
20715 - strbuf[len] = '\0';
20716 - sscanf(strbuf, "%s", str);
20717 + strbuf[count] = '\0';
20718
20719 mutex_lock(&acpi_device_lock);
20720 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
20721 @@ -360,7 +355,7 @@ acpi_system_write_wakeup_device(struct f
20722 if (!dev->wakeup.flags.valid)
20723 continue;
20724
20725 - if (!strncmp(dev->pnp.bus_id, str, 4)) {
20726 + if (!strncmp(dev->pnp.bus_id, strbuf, 4)) {
20727 dev->wakeup.state.enabled =
20728 dev->wakeup.state.enabled ? 0 : 1;
20729 found_dev = dev;
20730 diff -urNp linux-2.6.36/drivers/acpi/processor_driver.c linux-2.6.36/drivers/acpi/processor_driver.c
20731 --- linux-2.6.36/drivers/acpi/processor_driver.c 2010-10-20 16:30:22.000000000 -0400
20732 +++ linux-2.6.36/drivers/acpi/processor_driver.c 2010-11-06 18:58:15.000000000 -0400
20733 @@ -507,7 +507,7 @@ static int __cpuinit acpi_processor_add(
20734 return 0;
20735 #endif
20736
20737 - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
20738 + BUG_ON(pr->id >= nr_cpu_ids);
20739
20740 /*
20741 * Buggy BIOS check
20742 diff -urNp linux-2.6.36/drivers/acpi/processor_idle.c linux-2.6.36/drivers/acpi/processor_idle.c
20743 --- linux-2.6.36/drivers/acpi/processor_idle.c 2010-10-20 16:30:22.000000000 -0400
20744 +++ linux-2.6.36/drivers/acpi/processor_idle.c 2010-11-06 18:58:15.000000000 -0400
20745 @@ -115,7 +115,7 @@ static struct dmi_system_id __cpuinitdat
20746 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
20747 DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
20748 (void *)1},
20749 - {},
20750 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL},
20751 };
20752
20753
20754 diff -urNp linux-2.6.36/drivers/acpi/sleep.c linux-2.6.36/drivers/acpi/sleep.c
20755 --- linux-2.6.36/drivers/acpi/sleep.c 2010-10-20 16:30:22.000000000 -0400
20756 +++ linux-2.6.36/drivers/acpi/sleep.c 2010-11-06 18:58:15.000000000 -0400
20757 @@ -319,7 +319,7 @@ static int acpi_suspend_state_valid(susp
20758 }
20759 }
20760
20761 -static struct platform_suspend_ops acpi_suspend_ops = {
20762 +static const struct platform_suspend_ops acpi_suspend_ops = {
20763 .valid = acpi_suspend_state_valid,
20764 .begin = acpi_suspend_begin,
20765 .prepare_late = acpi_pm_prepare,
20766 @@ -347,7 +347,7 @@ static int acpi_suspend_begin_old(suspen
20767 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
20768 * been requested.
20769 */
20770 -static struct platform_suspend_ops acpi_suspend_ops_old = {
20771 +static const struct platform_suspend_ops acpi_suspend_ops_old = {
20772 .valid = acpi_suspend_state_valid,
20773 .begin = acpi_suspend_begin_old,
20774 .prepare_late = acpi_pm_pre_suspend,
20775 @@ -490,7 +490,7 @@ static void acpi_pm_thaw(void)
20776 acpi_enable_all_runtime_gpes();
20777 }
20778
20779 -static struct platform_hibernation_ops acpi_hibernation_ops = {
20780 +static const struct platform_hibernation_ops acpi_hibernation_ops = {
20781 .begin = acpi_hibernation_begin,
20782 .end = acpi_pm_end,
20783 .pre_snapshot = acpi_pm_prepare,
20784 @@ -533,7 +533,7 @@ static int acpi_hibernation_begin_old(vo
20785 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
20786 * been requested.
20787 */
20788 -static struct platform_hibernation_ops acpi_hibernation_ops_old = {
20789 +static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
20790 .begin = acpi_hibernation_begin_old,
20791 .end = acpi_pm_end,
20792 .pre_snapshot = acpi_pm_pre_suspend,
20793 diff -urNp linux-2.6.36/drivers/acpi/video.c linux-2.6.36/drivers/acpi/video.c
20794 --- linux-2.6.36/drivers/acpi/video.c 2010-10-20 16:30:22.000000000 -0400
20795 +++ linux-2.6.36/drivers/acpi/video.c 2010-11-06 18:58:15.000000000 -0400
20796 @@ -367,7 +367,7 @@ static int acpi_video_set_brightness(str
20797 vd->brightness->levels[request_level]);
20798 }
20799
20800 -static struct backlight_ops acpi_backlight_ops = {
20801 +static const struct backlight_ops acpi_backlight_ops = {
20802 .get_brightness = acpi_video_get_brightness,
20803 .update_status = acpi_video_set_brightness,
20804 };
20805 diff -urNp linux-2.6.36/drivers/ata/ahci.c linux-2.6.36/drivers/ata/ahci.c
20806 --- linux-2.6.36/drivers/ata/ahci.c 2010-10-20 16:30:22.000000000 -0400
20807 +++ linux-2.6.36/drivers/ata/ahci.c 2010-11-06 18:58:15.000000000 -0400
20808 @@ -94,17 +94,17 @@ static struct scsi_host_template ahci_sh
20809 AHCI_SHT("ahci"),
20810 };
20811
20812 -static struct ata_port_operations ahci_vt8251_ops = {
20813 +static const struct ata_port_operations ahci_vt8251_ops = {
20814 .inherits = &ahci_ops,
20815 .hardreset = ahci_vt8251_hardreset,
20816 };
20817
20818 -static struct ata_port_operations ahci_p5wdh_ops = {
20819 +static const struct ata_port_operations ahci_p5wdh_ops = {
20820 .inherits = &ahci_ops,
20821 .hardreset = ahci_p5wdh_hardreset,
20822 };
20823
20824 -static struct ata_port_operations ahci_sb600_ops = {
20825 +static const struct ata_port_operations ahci_sb600_ops = {
20826 .inherits = &ahci_ops,
20827 .softreset = ahci_sb600_softreset,
20828 .pmp_softreset = ahci_sb600_softreset,
20829 @@ -388,7 +388,7 @@ static const struct pci_device_id ahci_p
20830 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
20831 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
20832
20833 - { } /* terminate list */
20834 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
20835 };
20836
20837
20838 diff -urNp linux-2.6.36/drivers/ata/ahci.h linux-2.6.36/drivers/ata/ahci.h
20839 --- linux-2.6.36/drivers/ata/ahci.h 2010-10-20 16:30:22.000000000 -0400
20840 +++ linux-2.6.36/drivers/ata/ahci.h 2010-11-06 18:58:15.000000000 -0400
20841 @@ -309,7 +309,7 @@ extern struct device_attribute *ahci_sde
20842 .shost_attrs = ahci_shost_attrs, \
20843 .sdev_attrs = ahci_sdev_attrs
20844
20845 -extern struct ata_port_operations ahci_ops;
20846 +extern const struct ata_port_operations ahci_ops;
20847
20848 void ahci_save_initial_config(struct device *dev,
20849 struct ahci_host_priv *hpriv,
20850 diff -urNp linux-2.6.36/drivers/ata/ata_generic.c linux-2.6.36/drivers/ata/ata_generic.c
20851 --- linux-2.6.36/drivers/ata/ata_generic.c 2010-10-20 16:30:22.000000000 -0400
20852 +++ linux-2.6.36/drivers/ata/ata_generic.c 2010-11-06 18:58:15.000000000 -0400
20853 @@ -100,7 +100,7 @@ static struct scsi_host_template generic
20854 ATA_BMDMA_SHT(DRV_NAME),
20855 };
20856
20857 -static struct ata_port_operations generic_port_ops = {
20858 +static const struct ata_port_operations generic_port_ops = {
20859 .inherits = &ata_bmdma_port_ops,
20860 .cable_detect = ata_cable_unknown,
20861 .set_mode = generic_set_mode,
20862 diff -urNp linux-2.6.36/drivers/ata/ata_piix.c linux-2.6.36/drivers/ata/ata_piix.c
20863 --- linux-2.6.36/drivers/ata/ata_piix.c 2010-10-20 16:30:22.000000000 -0400
20864 +++ linux-2.6.36/drivers/ata/ata_piix.c 2010-11-06 18:58:15.000000000 -0400
20865 @@ -306,7 +306,7 @@ static const struct pci_device_id piix_p
20866 { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
20867 /* SATA Controller IDE (PBG) */
20868 { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
20869 - { } /* terminate list */
20870 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
20871 };
20872
20873 static struct pci_driver piix_pci_driver = {
20874 @@ -324,12 +324,12 @@ static struct scsi_host_template piix_sh
20875 ATA_BMDMA_SHT(DRV_NAME),
20876 };
20877
20878 -static struct ata_port_operations piix_sata_ops = {
20879 +static const struct ata_port_operations piix_sata_ops = {
20880 .inherits = &ata_bmdma32_port_ops,
20881 .sff_irq_check = piix_irq_check,
20882 };
20883
20884 -static struct ata_port_operations piix_pata_ops = {
20885 +static const struct ata_port_operations piix_pata_ops = {
20886 .inherits = &piix_sata_ops,
20887 .cable_detect = ata_cable_40wire,
20888 .set_piomode = piix_set_piomode,
20889 @@ -337,18 +337,18 @@ static struct ata_port_operations piix_p
20890 .prereset = piix_pata_prereset,
20891 };
20892
20893 -static struct ata_port_operations piix_vmw_ops = {
20894 +static const struct ata_port_operations piix_vmw_ops = {
20895 .inherits = &piix_pata_ops,
20896 .bmdma_status = piix_vmw_bmdma_status,
20897 };
20898
20899 -static struct ata_port_operations ich_pata_ops = {
20900 +static const struct ata_port_operations ich_pata_ops = {
20901 .inherits = &piix_pata_ops,
20902 .cable_detect = ich_pata_cable_detect,
20903 .set_dmamode = ich_set_dmamode,
20904 };
20905
20906 -static struct ata_port_operations piix_sidpr_sata_ops = {
20907 +static const struct ata_port_operations piix_sidpr_sata_ops = {
20908 .inherits = &piix_sata_ops,
20909 .hardreset = sata_std_hardreset,
20910 .scr_read = piix_sidpr_scr_read,
20911 @@ -624,7 +624,7 @@ static const struct ich_laptop ich_lapto
20912 { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
20913 { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */
20914 /* end marker */
20915 - { 0, }
20916 + { 0, 0, 0 }
20917 };
20918
20919 /**
20920 @@ -1116,7 +1116,7 @@ static int piix_broken_suspend(void)
20921 },
20922 },
20923
20924 - { } /* terminate list */
20925 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } /* terminate list */
20926 };
20927 static const char *oemstrs[] = {
20928 "Tecra M3,",
20929 diff -urNp linux-2.6.36/drivers/ata/libahci.c linux-2.6.36/drivers/ata/libahci.c
20930 --- linux-2.6.36/drivers/ata/libahci.c 2010-10-20 16:30:22.000000000 -0400
20931 +++ linux-2.6.36/drivers/ata/libahci.c 2010-11-06 18:58:15.000000000 -0400
20932 @@ -141,7 +141,7 @@ struct device_attribute *ahci_sdev_attrs
20933 };
20934 EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
20935
20936 -struct ata_port_operations ahci_ops = {
20937 +const struct ata_port_operations ahci_ops = {
20938 .inherits = &sata_pmp_port_ops,
20939
20940 .qc_defer = ahci_pmp_qc_defer,
20941 diff -urNp linux-2.6.36/drivers/ata/libata-acpi.c linux-2.6.36/drivers/ata/libata-acpi.c
20942 --- linux-2.6.36/drivers/ata/libata-acpi.c 2010-10-20 16:30:22.000000000 -0400
20943 +++ linux-2.6.36/drivers/ata/libata-acpi.c 2010-11-06 18:58:15.000000000 -0400
20944 @@ -218,12 +218,12 @@ static void ata_acpi_dev_uevent(acpi_han
20945 ata_acpi_uevent(dev->link->ap, dev, event);
20946 }
20947
20948 -static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
20949 +static const struct acpi_dock_ops ata_acpi_dev_dock_ops = {
20950 .handler = ata_acpi_dev_notify_dock,
20951 .uevent = ata_acpi_dev_uevent,
20952 };
20953
20954 -static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
20955 +static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
20956 .handler = ata_acpi_ap_notify_dock,
20957 .uevent = ata_acpi_ap_uevent,
20958 };
20959 diff -urNp linux-2.6.36/drivers/ata/libata-core.c linux-2.6.36/drivers/ata/libata-core.c
20960 --- linux-2.6.36/drivers/ata/libata-core.c 2010-10-20 16:30:22.000000000 -0400
20961 +++ linux-2.6.36/drivers/ata/libata-core.c 2010-11-06 18:58:15.000000000 -0400
20962 @@ -899,7 +899,7 @@ static const struct ata_xfer_ent {
20963 { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
20964 { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
20965 { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
20966 - { -1, },
20967 + { -1, 0, 0 }
20968 };
20969
20970 /**
20971 @@ -3071,7 +3071,7 @@ static const struct ata_timing ata_timin
20972 { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 },
20973 { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 },
20974
20975 - { 0xFF }
20976 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
20977 };
20978
20979 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
20980 @@ -4260,7 +4260,7 @@ static const struct ata_blacklist_entry
20981 { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER },
20982
20983 /* End Marker */
20984 - { }
20985 + { NULL, NULL, 0 }
20986 };
20987
20988 /**
20989 @@ -4865,7 +4865,7 @@ void ata_qc_free(struct ata_queued_cmd *
20990 struct ata_port *ap;
20991 unsigned int tag;
20992
20993 - WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
20994 + BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
20995 ap = qc->ap;
20996
20997 qc->flags = 0;
20998 @@ -4881,7 +4881,7 @@ void __ata_qc_complete(struct ata_queued
20999 struct ata_port *ap;
21000 struct ata_link *link;
21001
21002 - WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
21003 + BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
21004 WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE));
21005 ap = qc->ap;
21006 link = qc->dev->link;
21007 @@ -5866,7 +5866,7 @@ static void ata_host_stop(struct device
21008 * LOCKING:
21009 * None.
21010 */
21011 -static void ata_finalize_port_ops(struct ata_port_operations *ops)
21012 +static void ata_finalize_port_ops(const struct ata_port_operations *ops)
21013 {
21014 static DEFINE_SPINLOCK(lock);
21015 const struct ata_port_operations *cur;
21016 @@ -5878,6 +5878,7 @@ static void ata_finalize_port_ops(struct
21017 return;
21018
21019 spin_lock(&lock);
21020 + pax_open_kernel();
21021
21022 for (cur = ops->inherits; cur; cur = cur->inherits) {
21023 void **inherit = (void **)cur;
21024 @@ -5891,8 +5892,9 @@ static void ata_finalize_port_ops(struct
21025 if (IS_ERR(*pp))
21026 *pp = NULL;
21027
21028 - ops->inherits = NULL;
21029 + ((struct ata_port_operations *)ops)->inherits = NULL;
21030
21031 + pax_close_kernel();
21032 spin_unlock(&lock);
21033 }
21034
21035 @@ -5989,7 +5991,7 @@ int ata_host_start(struct ata_host *host
21036 */
21037 /* KILLME - the only user left is ipr */
21038 void ata_host_init(struct ata_host *host, struct device *dev,
21039 - unsigned long flags, struct ata_port_operations *ops)
21040 + unsigned long flags, const struct ata_port_operations *ops)
21041 {
21042 spin_lock_init(&host->lock);
21043 host->dev = dev;
21044 @@ -6630,7 +6632,7 @@ static void ata_dummy_error_handler(stru
21045 /* truly dummy */
21046 }
21047
21048 -struct ata_port_operations ata_dummy_port_ops = {
21049 +const struct ata_port_operations ata_dummy_port_ops = {
21050 .qc_prep = ata_noop_qc_prep,
21051 .qc_issue = ata_dummy_qc_issue,
21052 .error_handler = ata_dummy_error_handler,
21053 diff -urNp linux-2.6.36/drivers/ata/libata-eh.c linux-2.6.36/drivers/ata/libata-eh.c
21054 --- linux-2.6.36/drivers/ata/libata-eh.c 2010-10-20 16:30:22.000000000 -0400
21055 +++ linux-2.6.36/drivers/ata/libata-eh.c 2010-11-06 18:58:15.000000000 -0400
21056 @@ -3685,7 +3685,7 @@ void ata_do_eh(struct ata_port *ap, ata_
21057 */
21058 void ata_std_error_handler(struct ata_port *ap)
21059 {
21060 - struct ata_port_operations *ops = ap->ops;
21061 + const struct ata_port_operations *ops = ap->ops;
21062 ata_reset_fn_t hardreset = ops->hardreset;
21063
21064 /* ignore built-in hardreset if SCR access is not available */
21065 diff -urNp linux-2.6.36/drivers/ata/libata-pmp.c linux-2.6.36/drivers/ata/libata-pmp.c
21066 --- linux-2.6.36/drivers/ata/libata-pmp.c 2010-10-20 16:30:22.000000000 -0400
21067 +++ linux-2.6.36/drivers/ata/libata-pmp.c 2010-11-06 18:58:15.000000000 -0400
21068 @@ -868,7 +868,7 @@ static int sata_pmp_handle_link_fail(str
21069 */
21070 static int sata_pmp_eh_recover(struct ata_port *ap)
21071 {
21072 - struct ata_port_operations *ops = ap->ops;
21073 + const struct ata_port_operations *ops = ap->ops;
21074 int pmp_tries, link_tries[SATA_PMP_MAX_PORTS];
21075 struct ata_link *pmp_link = &ap->link;
21076 struct ata_device *pmp_dev = pmp_link->device;
21077 diff -urNp linux-2.6.36/drivers/ata/pata_acpi.c linux-2.6.36/drivers/ata/pata_acpi.c
21078 --- linux-2.6.36/drivers/ata/pata_acpi.c 2010-10-20 16:30:22.000000000 -0400
21079 +++ linux-2.6.36/drivers/ata/pata_acpi.c 2010-11-06 18:58:15.000000000 -0400
21080 @@ -216,7 +216,7 @@ static struct scsi_host_template pacpi_s
21081 ATA_BMDMA_SHT(DRV_NAME),
21082 };
21083
21084 -static struct ata_port_operations pacpi_ops = {
21085 +static const struct ata_port_operations pacpi_ops = {
21086 .inherits = &ata_bmdma_port_ops,
21087 .qc_issue = pacpi_qc_issue,
21088 .cable_detect = pacpi_cable_detect,
21089 diff -urNp linux-2.6.36/drivers/ata/pata_ali.c linux-2.6.36/drivers/ata/pata_ali.c
21090 --- linux-2.6.36/drivers/ata/pata_ali.c 2010-10-20 16:30:22.000000000 -0400
21091 +++ linux-2.6.36/drivers/ata/pata_ali.c 2010-11-06 18:58:15.000000000 -0400
21092 @@ -363,7 +363,7 @@ static struct scsi_host_template ali_sht
21093 * Port operations for PIO only ALi
21094 */
21095
21096 -static struct ata_port_operations ali_early_port_ops = {
21097 +static const struct ata_port_operations ali_early_port_ops = {
21098 .inherits = &ata_sff_port_ops,
21099 .cable_detect = ata_cable_40wire,
21100 .set_piomode = ali_set_piomode,
21101 @@ -380,7 +380,7 @@ static const struct ata_port_operations
21102 * Port operations for DMA capable ALi without cable
21103 * detect
21104 */
21105 -static struct ata_port_operations ali_20_port_ops = {
21106 +static const struct ata_port_operations ali_20_port_ops = {
21107 .inherits = &ali_dma_base_ops,
21108 .cable_detect = ata_cable_40wire,
21109 .mode_filter = ali_20_filter,
21110 @@ -391,7 +391,7 @@ static struct ata_port_operations ali_20
21111 /*
21112 * Port operations for DMA capable ALi with cable detect
21113 */
21114 -static struct ata_port_operations ali_c2_port_ops = {
21115 +static const struct ata_port_operations ali_c2_port_ops = {
21116 .inherits = &ali_dma_base_ops,
21117 .check_atapi_dma = ali_check_atapi_dma,
21118 .cable_detect = ali_c2_cable_detect,
21119 @@ -402,7 +402,7 @@ static struct ata_port_operations ali_c2
21120 /*
21121 * Port operations for DMA capable ALi with cable detect
21122 */
21123 -static struct ata_port_operations ali_c4_port_ops = {
21124 +static const struct ata_port_operations ali_c4_port_ops = {
21125 .inherits = &ali_dma_base_ops,
21126 .check_atapi_dma = ali_check_atapi_dma,
21127 .cable_detect = ali_c2_cable_detect,
21128 @@ -412,7 +412,7 @@ static struct ata_port_operations ali_c4
21129 /*
21130 * Port operations for DMA capable ALi with cable detect and LBA48
21131 */
21132 -static struct ata_port_operations ali_c5_port_ops = {
21133 +static const struct ata_port_operations ali_c5_port_ops = {
21134 .inherits = &ali_dma_base_ops,
21135 .check_atapi_dma = ali_check_atapi_dma,
21136 .dev_config = ali_warn_atapi_dma,
21137 diff -urNp linux-2.6.36/drivers/ata/pata_amd.c linux-2.6.36/drivers/ata/pata_amd.c
21138 --- linux-2.6.36/drivers/ata/pata_amd.c 2010-10-20 16:30:22.000000000 -0400
21139 +++ linux-2.6.36/drivers/ata/pata_amd.c 2010-11-06 18:58:15.000000000 -0400
21140 @@ -397,28 +397,28 @@ static const struct ata_port_operations
21141 .prereset = amd_pre_reset,
21142 };
21143
21144 -static struct ata_port_operations amd33_port_ops = {
21145 +static const struct ata_port_operations amd33_port_ops = {
21146 .inherits = &amd_base_port_ops,
21147 .cable_detect = ata_cable_40wire,
21148 .set_piomode = amd33_set_piomode,
21149 .set_dmamode = amd33_set_dmamode,
21150 };
21151
21152 -static struct ata_port_operations amd66_port_ops = {
21153 +static const struct ata_port_operations amd66_port_ops = {
21154 .inherits = &amd_base_port_ops,
21155 .cable_detect = ata_cable_unknown,
21156 .set_piomode = amd66_set_piomode,
21157 .set_dmamode = amd66_set_dmamode,
21158 };
21159
21160 -static struct ata_port_operations amd100_port_ops = {
21161 +static const struct ata_port_operations amd100_port_ops = {
21162 .inherits = &amd_base_port_ops,
21163 .cable_detect = ata_cable_unknown,
21164 .set_piomode = amd100_set_piomode,
21165 .set_dmamode = amd100_set_dmamode,
21166 };
21167
21168 -static struct ata_port_operations amd133_port_ops = {
21169 +static const struct ata_port_operations amd133_port_ops = {
21170 .inherits = &amd_base_port_ops,
21171 .cable_detect = amd_cable_detect,
21172 .set_piomode = amd133_set_piomode,
21173 @@ -433,13 +433,13 @@ static const struct ata_port_operations
21174 .host_stop = nv_host_stop,
21175 };
21176
21177 -static struct ata_port_operations nv100_port_ops = {
21178 +static const struct ata_port_operations nv100_port_ops = {
21179 .inherits = &nv_base_port_ops,
21180 .set_piomode = nv100_set_piomode,
21181 .set_dmamode = nv100_set_dmamode,
21182 };
21183
21184 -static struct ata_port_operations nv133_port_ops = {
21185 +static const struct ata_port_operations nv133_port_ops = {
21186 .inherits = &nv_base_port_ops,
21187 .set_piomode = nv133_set_piomode,
21188 .set_dmamode = nv133_set_dmamode,
21189 diff -urNp linux-2.6.36/drivers/ata/pata_artop.c linux-2.6.36/drivers/ata/pata_artop.c
21190 --- linux-2.6.36/drivers/ata/pata_artop.c 2010-10-20 16:30:22.000000000 -0400
21191 +++ linux-2.6.36/drivers/ata/pata_artop.c 2010-11-06 18:58:15.000000000 -0400
21192 @@ -312,7 +312,7 @@ static struct scsi_host_template artop_s
21193 ATA_BMDMA_SHT(DRV_NAME),
21194 };
21195
21196 -static struct ata_port_operations artop6210_ops = {
21197 +static const struct ata_port_operations artop6210_ops = {
21198 .inherits = &ata_bmdma_port_ops,
21199 .cable_detect = ata_cable_40wire,
21200 .set_piomode = artop6210_set_piomode,
21201 @@ -321,7 +321,7 @@ static struct ata_port_operations artop6
21202 .qc_defer = artop6210_qc_defer,
21203 };
21204
21205 -static struct ata_port_operations artop6260_ops = {
21206 +static const struct ata_port_operations artop6260_ops = {
21207 .inherits = &ata_bmdma_port_ops,
21208 .cable_detect = artop6260_cable_detect,
21209 .set_piomode = artop6260_set_piomode,
21210 diff -urNp linux-2.6.36/drivers/ata/pata_at32.c linux-2.6.36/drivers/ata/pata_at32.c
21211 --- linux-2.6.36/drivers/ata/pata_at32.c 2010-10-20 16:30:22.000000000 -0400
21212 +++ linux-2.6.36/drivers/ata/pata_at32.c 2010-11-06 18:58:15.000000000 -0400
21213 @@ -173,7 +173,7 @@ static struct scsi_host_template at32_sh
21214 ATA_PIO_SHT(DRV_NAME),
21215 };
21216
21217 -static struct ata_port_operations at32_port_ops = {
21218 +static const struct ata_port_operations at32_port_ops = {
21219 .inherits = &ata_sff_port_ops,
21220 .cable_detect = ata_cable_40wire,
21221 .set_piomode = pata_at32_set_piomode,
21222 diff -urNp linux-2.6.36/drivers/ata/pata_at91.c linux-2.6.36/drivers/ata/pata_at91.c
21223 --- linux-2.6.36/drivers/ata/pata_at91.c 2010-10-20 16:30:22.000000000 -0400
21224 +++ linux-2.6.36/drivers/ata/pata_at91.c 2010-11-06 18:58:15.000000000 -0400
21225 @@ -196,7 +196,7 @@ static struct scsi_host_template pata_at
21226 ATA_PIO_SHT(DRV_NAME),
21227 };
21228
21229 -static struct ata_port_operations pata_at91_port_ops = {
21230 +static const struct ata_port_operations pata_at91_port_ops = {
21231 .inherits = &ata_sff_port_ops,
21232
21233 .sff_data_xfer = pata_at91_data_xfer_noirq,
21234 diff -urNp linux-2.6.36/drivers/ata/pata_atiixp.c linux-2.6.36/drivers/ata/pata_atiixp.c
21235 --- linux-2.6.36/drivers/ata/pata_atiixp.c 2010-10-20 16:30:22.000000000 -0400
21236 +++ linux-2.6.36/drivers/ata/pata_atiixp.c 2010-11-06 18:58:15.000000000 -0400
21237 @@ -214,7 +214,7 @@ static struct scsi_host_template atiixp_
21238 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
21239 };
21240
21241 -static struct ata_port_operations atiixp_port_ops = {
21242 +static const struct ata_port_operations atiixp_port_ops = {
21243 .inherits = &ata_bmdma_port_ops,
21244
21245 .qc_prep = ata_bmdma_dumb_qc_prep,
21246 diff -urNp linux-2.6.36/drivers/ata/pata_atp867x.c linux-2.6.36/drivers/ata/pata_atp867x.c
21247 --- linux-2.6.36/drivers/ata/pata_atp867x.c 2010-10-20 16:30:22.000000000 -0400
21248 +++ linux-2.6.36/drivers/ata/pata_atp867x.c 2010-11-06 18:58:15.000000000 -0400
21249 @@ -275,7 +275,7 @@ static struct scsi_host_template atp867x
21250 ATA_BMDMA_SHT(DRV_NAME),
21251 };
21252
21253 -static struct ata_port_operations atp867x_ops = {
21254 +static const struct ata_port_operations atp867x_ops = {
21255 .inherits = &ata_bmdma_port_ops,
21256 .cable_detect = atp867x_cable_detect,
21257 .set_piomode = atp867x_set_piomode,
21258 diff -urNp linux-2.6.36/drivers/ata/pata_bf54x.c linux-2.6.36/drivers/ata/pata_bf54x.c
21259 --- linux-2.6.36/drivers/ata/pata_bf54x.c 2010-10-20 16:30:22.000000000 -0400
21260 +++ linux-2.6.36/drivers/ata/pata_bf54x.c 2010-11-06 18:58:15.000000000 -0400
21261 @@ -1420,7 +1420,7 @@ static struct scsi_host_template bfin_sh
21262 .dma_boundary = ATA_DMA_BOUNDARY,
21263 };
21264
21265 -static struct ata_port_operations bfin_pata_ops = {
21266 +static const struct ata_port_operations bfin_pata_ops = {
21267 .inherits = &ata_bmdma_port_ops,
21268
21269 .set_piomode = bfin_set_piomode,
21270 diff -urNp linux-2.6.36/drivers/ata/pata_cmd640.c linux-2.6.36/drivers/ata/pata_cmd640.c
21271 --- linux-2.6.36/drivers/ata/pata_cmd640.c 2010-10-20 16:30:22.000000000 -0400
21272 +++ linux-2.6.36/drivers/ata/pata_cmd640.c 2010-11-06 18:58:15.000000000 -0400
21273 @@ -165,7 +165,7 @@ static struct scsi_host_template cmd640_
21274 ATA_PIO_SHT(DRV_NAME),
21275 };
21276
21277 -static struct ata_port_operations cmd640_port_ops = {
21278 +static const struct ata_port_operations cmd640_port_ops = {
21279 .inherits = &ata_sff_port_ops,
21280 /* In theory xfer_noirq is not needed once we kill the prefetcher */
21281 .sff_data_xfer = ata_sff_data_xfer_noirq,
21282 diff -urNp linux-2.6.36/drivers/ata/pata_cmd64x.c linux-2.6.36/drivers/ata/pata_cmd64x.c
21283 --- linux-2.6.36/drivers/ata/pata_cmd64x.c 2010-10-20 16:30:22.000000000 -0400
21284 +++ linux-2.6.36/drivers/ata/pata_cmd64x.c 2010-11-06 18:58:15.000000000 -0400
21285 @@ -268,18 +268,18 @@ static const struct ata_port_operations
21286 .set_dmamode = cmd64x_set_dmamode,
21287 };
21288
21289 -static struct ata_port_operations cmd64x_port_ops = {
21290 +static const struct ata_port_operations cmd64x_port_ops = {
21291 .inherits = &cmd64x_base_ops,
21292 .cable_detect = ata_cable_40wire,
21293 };
21294
21295 -static struct ata_port_operations cmd646r1_port_ops = {
21296 +static const struct ata_port_operations cmd646r1_port_ops = {
21297 .inherits = &cmd64x_base_ops,
21298 .bmdma_stop = cmd646r1_bmdma_stop,
21299 .cable_detect = ata_cable_40wire,
21300 };
21301
21302 -static struct ata_port_operations cmd648_port_ops = {
21303 +static const struct ata_port_operations cmd648_port_ops = {
21304 .inherits = &cmd64x_base_ops,
21305 .bmdma_stop = cmd648_bmdma_stop,
21306 .cable_detect = cmd648_cable_detect,
21307 diff -urNp linux-2.6.36/drivers/ata/pata_cs5520.c linux-2.6.36/drivers/ata/pata_cs5520.c
21308 --- linux-2.6.36/drivers/ata/pata_cs5520.c 2010-10-20 16:30:22.000000000 -0400
21309 +++ linux-2.6.36/drivers/ata/pata_cs5520.c 2010-11-06 18:58:15.000000000 -0400
21310 @@ -108,7 +108,7 @@ static struct scsi_host_template cs5520_
21311 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
21312 };
21313
21314 -static struct ata_port_operations cs5520_port_ops = {
21315 +static const struct ata_port_operations cs5520_port_ops = {
21316 .inherits = &ata_bmdma_port_ops,
21317 .qc_prep = ata_bmdma_dumb_qc_prep,
21318 .cable_detect = ata_cable_40wire,
21319 diff -urNp linux-2.6.36/drivers/ata/pata_cs5530.c linux-2.6.36/drivers/ata/pata_cs5530.c
21320 --- linux-2.6.36/drivers/ata/pata_cs5530.c 2010-10-20 16:30:22.000000000 -0400
21321 +++ linux-2.6.36/drivers/ata/pata_cs5530.c 2010-11-06 18:58:15.000000000 -0400
21322 @@ -164,7 +164,7 @@ static struct scsi_host_template cs5530_
21323 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
21324 };
21325
21326 -static struct ata_port_operations cs5530_port_ops = {
21327 +static const struct ata_port_operations cs5530_port_ops = {
21328 .inherits = &ata_bmdma_port_ops,
21329
21330 .qc_prep = ata_bmdma_dumb_qc_prep,
21331 diff -urNp linux-2.6.36/drivers/ata/pata_cs5535.c linux-2.6.36/drivers/ata/pata_cs5535.c
21332 --- linux-2.6.36/drivers/ata/pata_cs5535.c 2010-10-20 16:30:22.000000000 -0400
21333 +++ linux-2.6.36/drivers/ata/pata_cs5535.c 2010-11-06 18:58:15.000000000 -0400
21334 @@ -160,7 +160,7 @@ static struct scsi_host_template cs5535_
21335 ATA_BMDMA_SHT(DRV_NAME),
21336 };
21337
21338 -static struct ata_port_operations cs5535_port_ops = {
21339 +static const struct ata_port_operations cs5535_port_ops = {
21340 .inherits = &ata_bmdma_port_ops,
21341 .cable_detect = cs5535_cable_detect,
21342 .set_piomode = cs5535_set_piomode,
21343 diff -urNp linux-2.6.36/drivers/ata/pata_cs5536.c linux-2.6.36/drivers/ata/pata_cs5536.c
21344 --- linux-2.6.36/drivers/ata/pata_cs5536.c 2010-10-20 16:30:22.000000000 -0400
21345 +++ linux-2.6.36/drivers/ata/pata_cs5536.c 2010-11-06 18:58:15.000000000 -0400
21346 @@ -223,7 +223,7 @@ static struct scsi_host_template cs5536_
21347 ATA_BMDMA_SHT(DRV_NAME),
21348 };
21349
21350 -static struct ata_port_operations cs5536_port_ops = {
21351 +static const struct ata_port_operations cs5536_port_ops = {
21352 .inherits = &ata_bmdma32_port_ops,
21353 .cable_detect = cs5536_cable_detect,
21354 .set_piomode = cs5536_set_piomode,
21355 diff -urNp linux-2.6.36/drivers/ata/pata_cypress.c linux-2.6.36/drivers/ata/pata_cypress.c
21356 --- linux-2.6.36/drivers/ata/pata_cypress.c 2010-10-20 16:30:22.000000000 -0400
21357 +++ linux-2.6.36/drivers/ata/pata_cypress.c 2010-11-06 18:58:15.000000000 -0400
21358 @@ -115,7 +115,7 @@ static struct scsi_host_template cy82c69
21359 ATA_BMDMA_SHT(DRV_NAME),
21360 };
21361
21362 -static struct ata_port_operations cy82c693_port_ops = {
21363 +static const struct ata_port_operations cy82c693_port_ops = {
21364 .inherits = &ata_bmdma_port_ops,
21365 .cable_detect = ata_cable_40wire,
21366 .set_piomode = cy82c693_set_piomode,
21367 diff -urNp linux-2.6.36/drivers/ata/pata_efar.c linux-2.6.36/drivers/ata/pata_efar.c
21368 --- linux-2.6.36/drivers/ata/pata_efar.c 2010-10-20 16:30:22.000000000 -0400
21369 +++ linux-2.6.36/drivers/ata/pata_efar.c 2010-11-06 18:58:15.000000000 -0400
21370 @@ -238,7 +238,7 @@ static struct scsi_host_template efar_sh
21371 ATA_BMDMA_SHT(DRV_NAME),
21372 };
21373
21374 -static struct ata_port_operations efar_ops = {
21375 +static const struct ata_port_operations efar_ops = {
21376 .inherits = &ata_bmdma_port_ops,
21377 .cable_detect = efar_cable_detect,
21378 .set_piomode = efar_set_piomode,
21379 diff -urNp linux-2.6.36/drivers/ata/pata_hpt366.c linux-2.6.36/drivers/ata/pata_hpt366.c
21380 --- linux-2.6.36/drivers/ata/pata_hpt366.c 2010-10-20 16:30:22.000000000 -0400
21381 +++ linux-2.6.36/drivers/ata/pata_hpt366.c 2010-11-06 18:58:15.000000000 -0400
21382 @@ -269,7 +269,7 @@ static struct scsi_host_template hpt36x_
21383 * Configuration for HPT366/68
21384 */
21385
21386 -static struct ata_port_operations hpt366_port_ops = {
21387 +static const struct ata_port_operations hpt366_port_ops = {
21388 .inherits = &ata_bmdma_port_ops,
21389 .cable_detect = hpt36x_cable_detect,
21390 .mode_filter = hpt366_filter,
21391 diff -urNp linux-2.6.36/drivers/ata/pata_hpt37x.c linux-2.6.36/drivers/ata/pata_hpt37x.c
21392 --- linux-2.6.36/drivers/ata/pata_hpt37x.c 2010-10-20 16:30:22.000000000 -0400
21393 +++ linux-2.6.36/drivers/ata/pata_hpt37x.c 2010-11-06 18:58:15.000000000 -0400
21394 @@ -564,7 +564,7 @@ static struct scsi_host_template hpt37x_
21395 * Configuration for HPT370
21396 */
21397
21398 -static struct ata_port_operations hpt370_port_ops = {
21399 +static const struct ata_port_operations hpt370_port_ops = {
21400 .inherits = &ata_bmdma_port_ops,
21401
21402 .bmdma_stop = hpt370_bmdma_stop,
21403 @@ -580,7 +580,7 @@ static struct ata_port_operations hpt370
21404 * Configuration for HPT370A. Close to 370 but less filters
21405 */
21406
21407 -static struct ata_port_operations hpt370a_port_ops = {
21408 +static const struct ata_port_operations hpt370a_port_ops = {
21409 .inherits = &hpt370_port_ops,
21410 .mode_filter = hpt370a_filter,
21411 };
21412 @@ -590,7 +590,7 @@ static struct ata_port_operations hpt370
21413 * and DMA mode setting functionality.
21414 */
21415
21416 -static struct ata_port_operations hpt372_port_ops = {
21417 +static const struct ata_port_operations hpt372_port_ops = {
21418 .inherits = &ata_bmdma_port_ops,
21419
21420 .bmdma_stop = hpt37x_bmdma_stop,
21421 @@ -606,7 +606,7 @@ static struct ata_port_operations hpt372
21422 * but we have a different cable detection procedure for function 1.
21423 */
21424
21425 -static struct ata_port_operations hpt374_fn1_port_ops = {
21426 +static const struct ata_port_operations hpt374_fn1_port_ops = {
21427 .inherits = &hpt372_port_ops,
21428 .cable_detect = hpt374_fn1_cable_detect,
21429 .prereset = hpt37x_pre_reset,
21430 diff -urNp linux-2.6.36/drivers/ata/pata_hpt3x2n.c linux-2.6.36/drivers/ata/pata_hpt3x2n.c
21431 --- linux-2.6.36/drivers/ata/pata_hpt3x2n.c 2010-10-20 16:30:22.000000000 -0400
21432 +++ linux-2.6.36/drivers/ata/pata_hpt3x2n.c 2010-11-06 18:58:15.000000000 -0400
21433 @@ -331,7 +331,7 @@ static struct scsi_host_template hpt3x2n
21434 * Configuration for HPT3x2n.
21435 */
21436
21437 -static struct ata_port_operations hpt3x2n_port_ops = {
21438 +static const struct ata_port_operations hpt3x2n_port_ops = {
21439 .inherits = &ata_bmdma_port_ops,
21440
21441 .bmdma_stop = hpt3x2n_bmdma_stop,
21442 diff -urNp linux-2.6.36/drivers/ata/pata_hpt3x3.c linux-2.6.36/drivers/ata/pata_hpt3x3.c
21443 --- linux-2.6.36/drivers/ata/pata_hpt3x3.c 2010-10-20 16:30:22.000000000 -0400
21444 +++ linux-2.6.36/drivers/ata/pata_hpt3x3.c 2010-11-06 18:58:15.000000000 -0400
21445 @@ -141,7 +141,7 @@ static struct scsi_host_template hpt3x3_
21446 ATA_BMDMA_SHT(DRV_NAME),
21447 };
21448
21449 -static struct ata_port_operations hpt3x3_port_ops = {
21450 +static const struct ata_port_operations hpt3x3_port_ops = {
21451 .inherits = &ata_bmdma_port_ops,
21452 .cable_detect = ata_cable_40wire,
21453 .set_piomode = hpt3x3_set_piomode,
21454 diff -urNp linux-2.6.36/drivers/ata/pata_icside.c linux-2.6.36/drivers/ata/pata_icside.c
21455 --- linux-2.6.36/drivers/ata/pata_icside.c 2010-10-20 16:30:22.000000000 -0400
21456 +++ linux-2.6.36/drivers/ata/pata_icside.c 2010-11-06 18:58:15.000000000 -0400
21457 @@ -320,7 +320,7 @@ static void pata_icside_postreset(struct
21458 }
21459 }
21460
21461 -static struct ata_port_operations pata_icside_port_ops = {
21462 +static const struct ata_port_operations pata_icside_port_ops = {
21463 .inherits = &ata_bmdma_port_ops,
21464 /* no need to build any PRD tables for DMA */
21465 .qc_prep = ata_noop_qc_prep,
21466 diff -urNp linux-2.6.36/drivers/ata/pata_isapnp.c linux-2.6.36/drivers/ata/pata_isapnp.c
21467 --- linux-2.6.36/drivers/ata/pata_isapnp.c 2010-10-20 16:30:22.000000000 -0400
21468 +++ linux-2.6.36/drivers/ata/pata_isapnp.c 2010-11-06 18:58:15.000000000 -0400
21469 @@ -23,12 +23,12 @@ static struct scsi_host_template isapnp_
21470 ATA_PIO_SHT(DRV_NAME),
21471 };
21472
21473 -static struct ata_port_operations isapnp_port_ops = {
21474 +static const struct ata_port_operations isapnp_port_ops = {
21475 .inherits = &ata_sff_port_ops,
21476 .cable_detect = ata_cable_40wire,
21477 };
21478
21479 -static struct ata_port_operations isapnp_noalt_port_ops = {
21480 +static const struct ata_port_operations isapnp_noalt_port_ops = {
21481 .inherits = &ata_sff_port_ops,
21482 .cable_detect = ata_cable_40wire,
21483 /* No altstatus so we don't want to use the lost interrupt poll */
21484 diff -urNp linux-2.6.36/drivers/ata/pata_it8213.c linux-2.6.36/drivers/ata/pata_it8213.c
21485 --- linux-2.6.36/drivers/ata/pata_it8213.c 2010-10-20 16:30:22.000000000 -0400
21486 +++ linux-2.6.36/drivers/ata/pata_it8213.c 2010-11-06 18:58:15.000000000 -0400
21487 @@ -233,7 +233,7 @@ static struct scsi_host_template it8213_
21488 };
21489
21490
21491 -static struct ata_port_operations it8213_ops = {
21492 +static const struct ata_port_operations it8213_ops = {
21493 .inherits = &ata_bmdma_port_ops,
21494 .cable_detect = it8213_cable_detect,
21495 .set_piomode = it8213_set_piomode,
21496 diff -urNp linux-2.6.36/drivers/ata/pata_it821x.c linux-2.6.36/drivers/ata/pata_it821x.c
21497 --- linux-2.6.36/drivers/ata/pata_it821x.c 2010-10-20 16:30:22.000000000 -0400
21498 +++ linux-2.6.36/drivers/ata/pata_it821x.c 2010-11-06 18:58:15.000000000 -0400
21499 @@ -801,7 +801,7 @@ static struct scsi_host_template it821x_
21500 ATA_BMDMA_SHT(DRV_NAME),
21501 };
21502
21503 -static struct ata_port_operations it821x_smart_port_ops = {
21504 +static const struct ata_port_operations it821x_smart_port_ops = {
21505 .inherits = &ata_bmdma_port_ops,
21506
21507 .check_atapi_dma= it821x_check_atapi_dma,
21508 @@ -815,7 +815,7 @@ static struct ata_port_operations it821x
21509 .port_start = it821x_port_start,
21510 };
21511
21512 -static struct ata_port_operations it821x_passthru_port_ops = {
21513 +static const struct ata_port_operations it821x_passthru_port_ops = {
21514 .inherits = &ata_bmdma_port_ops,
21515
21516 .check_atapi_dma= it821x_check_atapi_dma,
21517 @@ -831,7 +831,7 @@ static struct ata_port_operations it821x
21518 .port_start = it821x_port_start,
21519 };
21520
21521 -static struct ata_port_operations it821x_rdc_port_ops = {
21522 +static const struct ata_port_operations it821x_rdc_port_ops = {
21523 .inherits = &ata_bmdma_port_ops,
21524
21525 .check_atapi_dma= it821x_check_atapi_dma,
21526 diff -urNp linux-2.6.36/drivers/ata/pata_ixp4xx_cf.c linux-2.6.36/drivers/ata/pata_ixp4xx_cf.c
21527 --- linux-2.6.36/drivers/ata/pata_ixp4xx_cf.c 2010-10-20 16:30:22.000000000 -0400
21528 +++ linux-2.6.36/drivers/ata/pata_ixp4xx_cf.c 2010-11-06 18:58:15.000000000 -0400
21529 @@ -89,7 +89,7 @@ static struct scsi_host_template ixp4xx_
21530 ATA_PIO_SHT(DRV_NAME),
21531 };
21532
21533 -static struct ata_port_operations ixp4xx_port_ops = {
21534 +static const struct ata_port_operations ixp4xx_port_ops = {
21535 .inherits = &ata_sff_port_ops,
21536 .sff_data_xfer = ixp4xx_mmio_data_xfer,
21537 .cable_detect = ata_cable_40wire,
21538 diff -urNp linux-2.6.36/drivers/ata/pata_jmicron.c linux-2.6.36/drivers/ata/pata_jmicron.c
21539 --- linux-2.6.36/drivers/ata/pata_jmicron.c 2010-10-20 16:30:22.000000000 -0400
21540 +++ linux-2.6.36/drivers/ata/pata_jmicron.c 2010-11-06 18:58:15.000000000 -0400
21541 @@ -111,7 +111,7 @@ static struct scsi_host_template jmicron
21542 ATA_BMDMA_SHT(DRV_NAME),
21543 };
21544
21545 -static struct ata_port_operations jmicron_ops = {
21546 +static const struct ata_port_operations jmicron_ops = {
21547 .inherits = &ata_bmdma_port_ops,
21548 .prereset = jmicron_pre_reset,
21549 };
21550 diff -urNp linux-2.6.36/drivers/ata/pata_legacy.c linux-2.6.36/drivers/ata/pata_legacy.c
21551 --- linux-2.6.36/drivers/ata/pata_legacy.c 2010-10-20 16:30:22.000000000 -0400
21552 +++ linux-2.6.36/drivers/ata/pata_legacy.c 2010-11-06 18:58:15.000000000 -0400
21553 @@ -116,7 +116,7 @@ struct legacy_probe {
21554
21555 struct legacy_controller {
21556 const char *name;
21557 - struct ata_port_operations *ops;
21558 + const struct ata_port_operations *ops;
21559 unsigned int pio_mask;
21560 unsigned int flags;
21561 unsigned int pflags;
21562 @@ -239,12 +239,12 @@ static const struct ata_port_operations
21563 * pio_mask as well.
21564 */
21565
21566 -static struct ata_port_operations simple_port_ops = {
21567 +static const struct ata_port_operations simple_port_ops = {
21568 .inherits = &legacy_base_port_ops,
21569 .sff_data_xfer = ata_sff_data_xfer_noirq,
21570 };
21571
21572 -static struct ata_port_operations legacy_port_ops = {
21573 +static const struct ata_port_operations legacy_port_ops = {
21574 .inherits = &legacy_base_port_ops,
21575 .sff_data_xfer = ata_sff_data_xfer_noirq,
21576 .set_mode = legacy_set_mode,
21577 @@ -340,7 +340,7 @@ static unsigned int pdc_data_xfer_vlb(st
21578 return buflen;
21579 }
21580
21581 -static struct ata_port_operations pdc20230_port_ops = {
21582 +static const struct ata_port_operations pdc20230_port_ops = {
21583 .inherits = &legacy_base_port_ops,
21584 .set_piomode = pdc20230_set_piomode,
21585 .sff_data_xfer = pdc_data_xfer_vlb,
21586 @@ -373,7 +373,7 @@ static void ht6560a_set_piomode(struct a
21587 ioread8(ap->ioaddr.status_addr);
21588 }
21589
21590 -static struct ata_port_operations ht6560a_port_ops = {
21591 +static const struct ata_port_operations ht6560a_port_ops = {
21592 .inherits = &legacy_base_port_ops,
21593 .set_piomode = ht6560a_set_piomode,
21594 };
21595 @@ -416,7 +416,7 @@ static void ht6560b_set_piomode(struct a
21596 ioread8(ap->ioaddr.status_addr);
21597 }
21598
21599 -static struct ata_port_operations ht6560b_port_ops = {
21600 +static const struct ata_port_operations ht6560b_port_ops = {
21601 .inherits = &legacy_base_port_ops,
21602 .set_piomode = ht6560b_set_piomode,
21603 };
21604 @@ -515,7 +515,7 @@ static void opti82c611a_set_piomode(stru
21605 }
21606
21607
21608 -static struct ata_port_operations opti82c611a_port_ops = {
21609 +static const struct ata_port_operations opti82c611a_port_ops = {
21610 .inherits = &legacy_base_port_ops,
21611 .set_piomode = opti82c611a_set_piomode,
21612 };
21613 @@ -625,7 +625,7 @@ static unsigned int opti82c46x_qc_issue(
21614 return ata_sff_qc_issue(qc);
21615 }
21616
21617 -static struct ata_port_operations opti82c46x_port_ops = {
21618 +static const struct ata_port_operations opti82c46x_port_ops = {
21619 .inherits = &legacy_base_port_ops,
21620 .set_piomode = opti82c46x_set_piomode,
21621 .qc_issue = opti82c46x_qc_issue,
21622 @@ -787,20 +787,20 @@ static int qdi_port(struct platform_devi
21623 return 0;
21624 }
21625
21626 -static struct ata_port_operations qdi6500_port_ops = {
21627 +static const struct ata_port_operations qdi6500_port_ops = {
21628 .inherits = &legacy_base_port_ops,
21629 .set_piomode = qdi6500_set_piomode,
21630 .qc_issue = qdi_qc_issue,
21631 .sff_data_xfer = vlb32_data_xfer,
21632 };
21633
21634 -static struct ata_port_operations qdi6580_port_ops = {
21635 +static const struct ata_port_operations qdi6580_port_ops = {
21636 .inherits = &legacy_base_port_ops,
21637 .set_piomode = qdi6580_set_piomode,
21638 .sff_data_xfer = vlb32_data_xfer,
21639 };
21640
21641 -static struct ata_port_operations qdi6580dp_port_ops = {
21642 +static const struct ata_port_operations qdi6580dp_port_ops = {
21643 .inherits = &legacy_base_port_ops,
21644 .set_piomode = qdi6580dp_set_piomode,
21645 .qc_issue = qdi_qc_issue,
21646 @@ -872,7 +872,7 @@ static int winbond_port(struct platform_
21647 return 0;
21648 }
21649
21650 -static struct ata_port_operations winbond_port_ops = {
21651 +static const struct ata_port_operations winbond_port_ops = {
21652 .inherits = &legacy_base_port_ops,
21653 .set_piomode = winbond_set_piomode,
21654 .sff_data_xfer = vlb32_data_xfer,
21655 @@ -995,7 +995,7 @@ static __init int legacy_init_one(struct
21656 int pio_modes = controller->pio_mask;
21657 unsigned long io = probe->port;
21658 u32 mask = (1 << probe->slot);
21659 - struct ata_port_operations *ops = controller->ops;
21660 + const struct ata_port_operations *ops = controller->ops;
21661 struct legacy_data *ld = &legacy_data[probe->slot];
21662 struct ata_host *host = NULL;
21663 struct ata_port *ap;
21664 diff -urNp linux-2.6.36/drivers/ata/pata_macio.c linux-2.6.36/drivers/ata/pata_macio.c
21665 --- linux-2.6.36/drivers/ata/pata_macio.c 2010-10-20 16:30:22.000000000 -0400
21666 +++ linux-2.6.36/drivers/ata/pata_macio.c 2010-11-06 18:58:15.000000000 -0400
21667 @@ -918,9 +918,8 @@ static struct scsi_host_template pata_ma
21668 .slave_configure = pata_macio_slave_config,
21669 };
21670
21671 -static struct ata_port_operations pata_macio_ops = {
21672 +static const struct ata_port_operations pata_macio_ops = {
21673 .inherits = &ata_bmdma_port_ops,
21674 -
21675 .freeze = pata_macio_freeze,
21676 .set_piomode = pata_macio_set_timings,
21677 .set_dmamode = pata_macio_set_timings,
21678 diff -urNp linux-2.6.36/drivers/ata/pata_marvell.c linux-2.6.36/drivers/ata/pata_marvell.c
21679 --- linux-2.6.36/drivers/ata/pata_marvell.c 2010-10-20 16:30:22.000000000 -0400
21680 +++ linux-2.6.36/drivers/ata/pata_marvell.c 2010-11-06 18:58:15.000000000 -0400
21681 @@ -100,7 +100,7 @@ static struct scsi_host_template marvell
21682 ATA_BMDMA_SHT(DRV_NAME),
21683 };
21684
21685 -static struct ata_port_operations marvell_ops = {
21686 +static const struct ata_port_operations marvell_ops = {
21687 .inherits = &ata_bmdma_port_ops,
21688 .cable_detect = marvell_cable_detect,
21689 .prereset = marvell_pre_reset,
21690 diff -urNp linux-2.6.36/drivers/ata/pata_mpc52xx.c linux-2.6.36/drivers/ata/pata_mpc52xx.c
21691 --- linux-2.6.36/drivers/ata/pata_mpc52xx.c 2010-10-20 16:30:22.000000000 -0400
21692 +++ linux-2.6.36/drivers/ata/pata_mpc52xx.c 2010-11-06 18:58:15.000000000 -0400
21693 @@ -609,7 +609,7 @@ static struct scsi_host_template mpc52xx
21694 ATA_PIO_SHT(DRV_NAME),
21695 };
21696
21697 -static struct ata_port_operations mpc52xx_ata_port_ops = {
21698 +static const struct ata_port_operations mpc52xx_ata_port_ops = {
21699 .inherits = &ata_sff_port_ops,
21700 .sff_dev_select = mpc52xx_ata_dev_select,
21701 .set_piomode = mpc52xx_ata_set_piomode,
21702 diff -urNp linux-2.6.36/drivers/ata/pata_mpiix.c linux-2.6.36/drivers/ata/pata_mpiix.c
21703 --- linux-2.6.36/drivers/ata/pata_mpiix.c 2010-10-20 16:30:22.000000000 -0400
21704 +++ linux-2.6.36/drivers/ata/pata_mpiix.c 2010-11-06 18:58:15.000000000 -0400
21705 @@ -140,7 +140,7 @@ static struct scsi_host_template mpiix_s
21706 ATA_PIO_SHT(DRV_NAME),
21707 };
21708
21709 -static struct ata_port_operations mpiix_port_ops = {
21710 +static const struct ata_port_operations mpiix_port_ops = {
21711 .inherits = &ata_sff_port_ops,
21712 .qc_issue = mpiix_qc_issue,
21713 .cable_detect = ata_cable_40wire,
21714 diff -urNp linux-2.6.36/drivers/ata/pata_netcell.c linux-2.6.36/drivers/ata/pata_netcell.c
21715 --- linux-2.6.36/drivers/ata/pata_netcell.c 2010-10-20 16:30:22.000000000 -0400
21716 +++ linux-2.6.36/drivers/ata/pata_netcell.c 2010-11-06 18:58:15.000000000 -0400
21717 @@ -34,7 +34,7 @@ static struct scsi_host_template netcell
21718 ATA_BMDMA_SHT(DRV_NAME),
21719 };
21720
21721 -static struct ata_port_operations netcell_ops = {
21722 +static const struct ata_port_operations netcell_ops = {
21723 .inherits = &ata_bmdma_port_ops,
21724 .cable_detect = ata_cable_80wire,
21725 .read_id = netcell_read_id,
21726 diff -urNp linux-2.6.36/drivers/ata/pata_ninja32.c linux-2.6.36/drivers/ata/pata_ninja32.c
21727 --- linux-2.6.36/drivers/ata/pata_ninja32.c 2010-10-20 16:30:22.000000000 -0400
21728 +++ linux-2.6.36/drivers/ata/pata_ninja32.c 2010-11-06 18:58:15.000000000 -0400
21729 @@ -81,7 +81,7 @@ static struct scsi_host_template ninja32
21730 ATA_BMDMA_SHT(DRV_NAME),
21731 };
21732
21733 -static struct ata_port_operations ninja32_port_ops = {
21734 +static const struct ata_port_operations ninja32_port_ops = {
21735 .inherits = &ata_bmdma_port_ops,
21736 .sff_dev_select = ninja32_dev_select,
21737 .cable_detect = ata_cable_40wire,
21738 diff -urNp linux-2.6.36/drivers/ata/pata_ns87410.c linux-2.6.36/drivers/ata/pata_ns87410.c
21739 --- linux-2.6.36/drivers/ata/pata_ns87410.c 2010-10-20 16:30:22.000000000 -0400
21740 +++ linux-2.6.36/drivers/ata/pata_ns87410.c 2010-11-06 18:58:15.000000000 -0400
21741 @@ -132,7 +132,7 @@ static struct scsi_host_template ns87410
21742 ATA_PIO_SHT(DRV_NAME),
21743 };
21744
21745 -static struct ata_port_operations ns87410_port_ops = {
21746 +static const struct ata_port_operations ns87410_port_ops = {
21747 .inherits = &ata_sff_port_ops,
21748 .qc_issue = ns87410_qc_issue,
21749 .cable_detect = ata_cable_40wire,
21750 diff -urNp linux-2.6.36/drivers/ata/pata_ns87415.c linux-2.6.36/drivers/ata/pata_ns87415.c
21751 --- linux-2.6.36/drivers/ata/pata_ns87415.c 2010-10-20 16:30:22.000000000 -0400
21752 +++ linux-2.6.36/drivers/ata/pata_ns87415.c 2010-11-06 18:58:15.000000000 -0400
21753 @@ -299,7 +299,7 @@ static u8 ns87560_bmdma_status(struct at
21754 }
21755 #endif /* 87560 SuperIO Support */
21756
21757 -static struct ata_port_operations ns87415_pata_ops = {
21758 +static const struct ata_port_operations ns87415_pata_ops = {
21759 .inherits = &ata_bmdma_port_ops,
21760
21761 .check_atapi_dma = ns87415_check_atapi_dma,
21762 @@ -313,7 +313,7 @@ static struct ata_port_operations ns8741
21763 };
21764
21765 #if defined(CONFIG_SUPERIO)
21766 -static struct ata_port_operations ns87560_pata_ops = {
21767 +static const struct ata_port_operations ns87560_pata_ops = {
21768 .inherits = &ns87415_pata_ops,
21769 .sff_tf_read = ns87560_tf_read,
21770 .sff_check_status = ns87560_check_status,
21771 diff -urNp linux-2.6.36/drivers/ata/pata_octeon_cf.c linux-2.6.36/drivers/ata/pata_octeon_cf.c
21772 --- linux-2.6.36/drivers/ata/pata_octeon_cf.c 2010-10-20 16:30:22.000000000 -0400
21773 +++ linux-2.6.36/drivers/ata/pata_octeon_cf.c 2010-11-06 18:58:15.000000000 -0400
21774 @@ -782,6 +782,7 @@ static unsigned int octeon_cf_qc_issue(s
21775 return 0;
21776 }
21777
21778 +/* cannot be const */
21779 static struct ata_port_operations octeon_cf_ops = {
21780 .inherits = &ata_sff_port_ops,
21781 .check_atapi_dma = octeon_cf_check_atapi_dma,
21782 diff -urNp linux-2.6.36/drivers/ata/pata_oldpiix.c linux-2.6.36/drivers/ata/pata_oldpiix.c
21783 --- linux-2.6.36/drivers/ata/pata_oldpiix.c 2010-10-20 16:30:22.000000000 -0400
21784 +++ linux-2.6.36/drivers/ata/pata_oldpiix.c 2010-11-06 18:58:15.000000000 -0400
21785 @@ -208,7 +208,7 @@ static struct scsi_host_template oldpiix
21786 ATA_BMDMA_SHT(DRV_NAME),
21787 };
21788
21789 -static struct ata_port_operations oldpiix_pata_ops = {
21790 +static const struct ata_port_operations oldpiix_pata_ops = {
21791 .inherits = &ata_bmdma_port_ops,
21792 .qc_issue = oldpiix_qc_issue,
21793 .cable_detect = ata_cable_40wire,
21794 diff -urNp linux-2.6.36/drivers/ata/pata_opti.c linux-2.6.36/drivers/ata/pata_opti.c
21795 --- linux-2.6.36/drivers/ata/pata_opti.c 2010-10-20 16:30:22.000000000 -0400
21796 +++ linux-2.6.36/drivers/ata/pata_opti.c 2010-11-06 18:58:15.000000000 -0400
21797 @@ -152,7 +152,7 @@ static struct scsi_host_template opti_sh
21798 ATA_PIO_SHT(DRV_NAME),
21799 };
21800
21801 -static struct ata_port_operations opti_port_ops = {
21802 +static const struct ata_port_operations opti_port_ops = {
21803 .inherits = &ata_sff_port_ops,
21804 .cable_detect = ata_cable_40wire,
21805 .set_piomode = opti_set_piomode,
21806 diff -urNp linux-2.6.36/drivers/ata/pata_optidma.c linux-2.6.36/drivers/ata/pata_optidma.c
21807 --- linux-2.6.36/drivers/ata/pata_optidma.c 2010-10-20 16:30:22.000000000 -0400
21808 +++ linux-2.6.36/drivers/ata/pata_optidma.c 2010-11-06 18:58:15.000000000 -0400
21809 @@ -337,7 +337,7 @@ static struct scsi_host_template optidma
21810 ATA_BMDMA_SHT(DRV_NAME),
21811 };
21812
21813 -static struct ata_port_operations optidma_port_ops = {
21814 +static const struct ata_port_operations optidma_port_ops = {
21815 .inherits = &ata_bmdma_port_ops,
21816 .cable_detect = ata_cable_40wire,
21817 .set_piomode = optidma_set_pio_mode,
21818 @@ -346,7 +346,7 @@ static struct ata_port_operations optidm
21819 .prereset = optidma_pre_reset,
21820 };
21821
21822 -static struct ata_port_operations optiplus_port_ops = {
21823 +static const struct ata_port_operations optiplus_port_ops = {
21824 .inherits = &optidma_port_ops,
21825 .set_piomode = optiplus_set_pio_mode,
21826 .set_dmamode = optiplus_set_dma_mode,
21827 diff -urNp linux-2.6.36/drivers/ata/pata_palmld.c linux-2.6.36/drivers/ata/pata_palmld.c
21828 --- linux-2.6.36/drivers/ata/pata_palmld.c 2010-10-20 16:30:22.000000000 -0400
21829 +++ linux-2.6.36/drivers/ata/pata_palmld.c 2010-11-06 18:58:15.000000000 -0400
21830 @@ -37,7 +37,7 @@ static struct scsi_host_template palmld_
21831 ATA_PIO_SHT(DRV_NAME),
21832 };
21833
21834 -static struct ata_port_operations palmld_port_ops = {
21835 +static const struct ata_port_operations palmld_port_ops = {
21836 .inherits = &ata_sff_port_ops,
21837 .sff_data_xfer = ata_sff_data_xfer_noirq,
21838 .cable_detect = ata_cable_40wire,
21839 diff -urNp linux-2.6.36/drivers/ata/pata_pcmcia.c linux-2.6.36/drivers/ata/pata_pcmcia.c
21840 --- linux-2.6.36/drivers/ata/pata_pcmcia.c 2010-10-20 16:30:22.000000000 -0400
21841 +++ linux-2.6.36/drivers/ata/pata_pcmcia.c 2010-11-06 18:58:15.000000000 -0400
21842 @@ -152,14 +152,14 @@ static struct scsi_host_template pcmcia_
21843 ATA_PIO_SHT(DRV_NAME),
21844 };
21845
21846 -static struct ata_port_operations pcmcia_port_ops = {
21847 +static const struct ata_port_operations pcmcia_port_ops = {
21848 .inherits = &ata_sff_port_ops,
21849 .sff_data_xfer = ata_sff_data_xfer_noirq,
21850 .cable_detect = ata_cable_40wire,
21851 .set_mode = pcmcia_set_mode,
21852 };
21853
21854 -static struct ata_port_operations pcmcia_8bit_port_ops = {
21855 +static const struct ata_port_operations pcmcia_8bit_port_ops = {
21856 .inherits = &ata_sff_port_ops,
21857 .sff_data_xfer = ata_data_xfer_8bit,
21858 .cable_detect = ata_cable_40wire,
21859 @@ -244,7 +244,7 @@ static int pcmcia_init_one(struct pcmcia
21860 unsigned long io_base, ctl_base;
21861 void __iomem *io_addr, *ctl_addr;
21862 int n_ports = 1;
21863 - struct ata_port_operations *ops = &pcmcia_port_ops;
21864 + const struct ata_port_operations *ops = &pcmcia_port_ops;
21865
21866 /* Set up attributes in order to probe card and get resources */
21867 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
21868 diff -urNp linux-2.6.36/drivers/ata/pata_pdc2027x.c linux-2.6.36/drivers/ata/pata_pdc2027x.c
21869 --- linux-2.6.36/drivers/ata/pata_pdc2027x.c 2010-10-20 16:30:22.000000000 -0400
21870 +++ linux-2.6.36/drivers/ata/pata_pdc2027x.c 2010-11-06 18:58:15.000000000 -0400
21871 @@ -132,14 +132,14 @@ static struct scsi_host_template pdc2027
21872 ATA_BMDMA_SHT(DRV_NAME),
21873 };
21874
21875 -static struct ata_port_operations pdc2027x_pata100_ops = {
21876 +static const struct ata_port_operations pdc2027x_pata100_ops = {
21877 .inherits = &ata_bmdma_port_ops,
21878 .check_atapi_dma = pdc2027x_check_atapi_dma,
21879 .cable_detect = pdc2027x_cable_detect,
21880 .prereset = pdc2027x_prereset,
21881 };
21882
21883 -static struct ata_port_operations pdc2027x_pata133_ops = {
21884 +static const struct ata_port_operations pdc2027x_pata133_ops = {
21885 .inherits = &pdc2027x_pata100_ops,
21886 .mode_filter = pdc2027x_mode_filter,
21887 .set_piomode = pdc2027x_set_piomode,
21888 diff -urNp linux-2.6.36/drivers/ata/pata_pdc202xx_old.c linux-2.6.36/drivers/ata/pata_pdc202xx_old.c
21889 --- linux-2.6.36/drivers/ata/pata_pdc202xx_old.c 2010-10-20 16:30:22.000000000 -0400
21890 +++ linux-2.6.36/drivers/ata/pata_pdc202xx_old.c 2010-11-06 18:58:15.000000000 -0400
21891 @@ -274,7 +274,7 @@ static struct scsi_host_template pdc202x
21892 ATA_BMDMA_SHT(DRV_NAME),
21893 };
21894
21895 -static struct ata_port_operations pdc2024x_port_ops = {
21896 +static const struct ata_port_operations pdc2024x_port_ops = {
21897 .inherits = &ata_bmdma_port_ops,
21898
21899 .cable_detect = ata_cable_40wire,
21900 @@ -284,7 +284,7 @@ static struct ata_port_operations pdc202
21901 .sff_exec_command = pdc202xx_exec_command,
21902 };
21903
21904 -static struct ata_port_operations pdc2026x_port_ops = {
21905 +static const struct ata_port_operations pdc2026x_port_ops = {
21906 .inherits = &pdc2024x_port_ops,
21907
21908 .check_atapi_dma = pdc2026x_check_atapi_dma,
21909 diff -urNp linux-2.6.36/drivers/ata/pata_piccolo.c linux-2.6.36/drivers/ata/pata_piccolo.c
21910 --- linux-2.6.36/drivers/ata/pata_piccolo.c 2010-10-20 16:30:22.000000000 -0400
21911 +++ linux-2.6.36/drivers/ata/pata_piccolo.c 2010-11-06 18:58:15.000000000 -0400
21912 @@ -67,7 +67,7 @@ static struct scsi_host_template tosh_sh
21913 ATA_BMDMA_SHT(DRV_NAME),
21914 };
21915
21916 -static struct ata_port_operations tosh_port_ops = {
21917 +static const struct ata_port_operations tosh_port_ops = {
21918 .inherits = &ata_bmdma_port_ops,
21919 .cable_detect = ata_cable_unknown,
21920 .set_piomode = tosh_set_piomode,
21921 diff -urNp linux-2.6.36/drivers/ata/pata_platform.c linux-2.6.36/drivers/ata/pata_platform.c
21922 --- linux-2.6.36/drivers/ata/pata_platform.c 2010-10-20 16:30:22.000000000 -0400
21923 +++ linux-2.6.36/drivers/ata/pata_platform.c 2010-11-06 18:58:15.000000000 -0400
21924 @@ -48,7 +48,7 @@ static struct scsi_host_template pata_pl
21925 ATA_PIO_SHT(DRV_NAME),
21926 };
21927
21928 -static struct ata_port_operations pata_platform_port_ops = {
21929 +static const struct ata_port_operations pata_platform_port_ops = {
21930 .inherits = &ata_sff_port_ops,
21931 .sff_data_xfer = ata_sff_data_xfer_noirq,
21932 .cable_detect = ata_cable_unknown,
21933 diff -urNp linux-2.6.36/drivers/ata/pata_pxa.c linux-2.6.36/drivers/ata/pata_pxa.c
21934 --- linux-2.6.36/drivers/ata/pata_pxa.c 2010-10-20 16:30:22.000000000 -0400
21935 +++ linux-2.6.36/drivers/ata/pata_pxa.c 2010-11-06 18:58:15.000000000 -0400
21936 @@ -198,7 +198,7 @@ static struct scsi_host_template pxa_ata
21937 ATA_BMDMA_SHT(DRV_NAME),
21938 };
21939
21940 -static struct ata_port_operations pxa_ata_port_ops = {
21941 +static const struct ata_port_operations pxa_ata_port_ops = {
21942 .inherits = &ata_bmdma_port_ops,
21943 .cable_detect = ata_cable_40wire,
21944
21945 diff -urNp linux-2.6.36/drivers/ata/pata_qdi.c linux-2.6.36/drivers/ata/pata_qdi.c
21946 --- linux-2.6.36/drivers/ata/pata_qdi.c 2010-10-20 16:30:22.000000000 -0400
21947 +++ linux-2.6.36/drivers/ata/pata_qdi.c 2010-11-06 18:58:15.000000000 -0400
21948 @@ -157,7 +157,7 @@ static struct scsi_host_template qdi_sht
21949 ATA_PIO_SHT(DRV_NAME),
21950 };
21951
21952 -static struct ata_port_operations qdi6500_port_ops = {
21953 +static const struct ata_port_operations qdi6500_port_ops = {
21954 .inherits = &ata_sff_port_ops,
21955 .qc_issue = qdi_qc_issue,
21956 .sff_data_xfer = qdi_data_xfer,
21957 @@ -165,7 +165,7 @@ static struct ata_port_operations qdi650
21958 .set_piomode = qdi6500_set_piomode,
21959 };
21960
21961 -static struct ata_port_operations qdi6580_port_ops = {
21962 +static const struct ata_port_operations qdi6580_port_ops = {
21963 .inherits = &qdi6500_port_ops,
21964 .set_piomode = qdi6580_set_piomode,
21965 };
21966 diff -urNp linux-2.6.36/drivers/ata/pata_radisys.c linux-2.6.36/drivers/ata/pata_radisys.c
21967 --- linux-2.6.36/drivers/ata/pata_radisys.c 2010-10-20 16:30:22.000000000 -0400
21968 +++ linux-2.6.36/drivers/ata/pata_radisys.c 2010-11-06 18:58:15.000000000 -0400
21969 @@ -187,7 +187,7 @@ static struct scsi_host_template radisys
21970 ATA_BMDMA_SHT(DRV_NAME),
21971 };
21972
21973 -static struct ata_port_operations radisys_pata_ops = {
21974 +static const struct ata_port_operations radisys_pata_ops = {
21975 .inherits = &ata_bmdma_port_ops,
21976 .qc_issue = radisys_qc_issue,
21977 .cable_detect = ata_cable_unknown,
21978 diff -urNp linux-2.6.36/drivers/ata/pata_rb532_cf.c linux-2.6.36/drivers/ata/pata_rb532_cf.c
21979 --- linux-2.6.36/drivers/ata/pata_rb532_cf.c 2010-10-20 16:30:22.000000000 -0400
21980 +++ linux-2.6.36/drivers/ata/pata_rb532_cf.c 2010-11-06 18:58:15.000000000 -0400
21981 @@ -69,7 +69,7 @@ static irqreturn_t rb532_pata_irq_handle
21982 return IRQ_HANDLED;
21983 }
21984
21985 -static struct ata_port_operations rb532_pata_port_ops = {
21986 +static const struct ata_port_operations rb532_pata_port_ops = {
21987 .inherits = &ata_sff_port_ops,
21988 .sff_data_xfer = ata_sff_data_xfer32,
21989 };
21990 diff -urNp linux-2.6.36/drivers/ata/pata_rdc.c linux-2.6.36/drivers/ata/pata_rdc.c
21991 --- linux-2.6.36/drivers/ata/pata_rdc.c 2010-10-20 16:30:22.000000000 -0400
21992 +++ linux-2.6.36/drivers/ata/pata_rdc.c 2010-11-06 18:58:15.000000000 -0400
21993 @@ -273,7 +273,7 @@ static void rdc_set_dmamode(struct ata_p
21994 pci_write_config_byte(dev, 0x48, udma_enable);
21995 }
21996
21997 -static struct ata_port_operations rdc_pata_ops = {
21998 +static const struct ata_port_operations rdc_pata_ops = {
21999 .inherits = &ata_bmdma32_port_ops,
22000 .cable_detect = rdc_pata_cable_detect,
22001 .set_piomode = rdc_set_piomode,
22002 diff -urNp linux-2.6.36/drivers/ata/pata_rz1000.c linux-2.6.36/drivers/ata/pata_rz1000.c
22003 --- linux-2.6.36/drivers/ata/pata_rz1000.c 2010-10-20 16:30:22.000000000 -0400
22004 +++ linux-2.6.36/drivers/ata/pata_rz1000.c 2010-11-06 18:58:15.000000000 -0400
22005 @@ -54,7 +54,7 @@ static struct scsi_host_template rz1000_
22006 ATA_PIO_SHT(DRV_NAME),
22007 };
22008
22009 -static struct ata_port_operations rz1000_port_ops = {
22010 +static const struct ata_port_operations rz1000_port_ops = {
22011 .inherits = &ata_sff_port_ops,
22012 .cable_detect = ata_cable_40wire,
22013 .set_mode = rz1000_set_mode,
22014 diff -urNp linux-2.6.36/drivers/ata/pata_samsung_cf.c linux-2.6.36/drivers/ata/pata_samsung_cf.c
22015 --- linux-2.6.36/drivers/ata/pata_samsung_cf.c 2010-10-20 16:30:22.000000000 -0400
22016 +++ linux-2.6.36/drivers/ata/pata_samsung_cf.c 2010-11-06 18:58:15.000000000 -0400
22017 @@ -399,7 +399,7 @@ static struct scsi_host_template pata_s3
22018 ATA_PIO_SHT(DRV_NAME),
22019 };
22020
22021 -static struct ata_port_operations pata_s3c_port_ops = {
22022 +static const struct ata_port_operations pata_s3c_port_ops = {
22023 .inherits = &ata_sff_port_ops,
22024 .sff_check_status = pata_s3c_check_status,
22025 .sff_check_altstatus = pata_s3c_check_altstatus,
22026 @@ -413,7 +413,7 @@ static struct ata_port_operations pata_s
22027 .set_piomode = pata_s3c_set_piomode,
22028 };
22029
22030 -static struct ata_port_operations pata_s5p_port_ops = {
22031 +static const struct ata_port_operations pata_s5p_port_ops = {
22032 .inherits = &ata_sff_port_ops,
22033 .set_piomode = pata_s3c_set_piomode,
22034 };
22035 diff -urNp linux-2.6.36/drivers/ata/pata_sc1200.c linux-2.6.36/drivers/ata/pata_sc1200.c
22036 --- linux-2.6.36/drivers/ata/pata_sc1200.c 2010-10-20 16:30:22.000000000 -0400
22037 +++ linux-2.6.36/drivers/ata/pata_sc1200.c 2010-11-06 18:58:15.000000000 -0400
22038 @@ -207,7 +207,7 @@ static struct scsi_host_template sc1200_
22039 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
22040 };
22041
22042 -static struct ata_port_operations sc1200_port_ops = {
22043 +static const struct ata_port_operations sc1200_port_ops = {
22044 .inherits = &ata_bmdma_port_ops,
22045 .qc_prep = ata_bmdma_dumb_qc_prep,
22046 .qc_issue = sc1200_qc_issue,
22047 diff -urNp linux-2.6.36/drivers/ata/pata_scc.c linux-2.6.36/drivers/ata/pata_scc.c
22048 --- linux-2.6.36/drivers/ata/pata_scc.c 2010-10-20 16:30:22.000000000 -0400
22049 +++ linux-2.6.36/drivers/ata/pata_scc.c 2010-11-06 18:58:15.000000000 -0400
22050 @@ -926,7 +926,7 @@ static struct scsi_host_template scc_sht
22051 ATA_BMDMA_SHT(DRV_NAME),
22052 };
22053
22054 -static struct ata_port_operations scc_pata_ops = {
22055 +static const struct ata_port_operations scc_pata_ops = {
22056 .inherits = &ata_bmdma_port_ops,
22057
22058 .set_piomode = scc_set_piomode,
22059 diff -urNp linux-2.6.36/drivers/ata/pata_sch.c linux-2.6.36/drivers/ata/pata_sch.c
22060 --- linux-2.6.36/drivers/ata/pata_sch.c 2010-10-20 16:30:22.000000000 -0400
22061 +++ linux-2.6.36/drivers/ata/pata_sch.c 2010-11-06 18:58:15.000000000 -0400
22062 @@ -75,7 +75,7 @@ static struct scsi_host_template sch_sht
22063 ATA_BMDMA_SHT(DRV_NAME),
22064 };
22065
22066 -static struct ata_port_operations sch_pata_ops = {
22067 +static const struct ata_port_operations sch_pata_ops = {
22068 .inherits = &ata_bmdma_port_ops,
22069 .cable_detect = ata_cable_unknown,
22070 .set_piomode = sch_set_piomode,
22071 diff -urNp linux-2.6.36/drivers/ata/pata_serverworks.c linux-2.6.36/drivers/ata/pata_serverworks.c
22072 --- linux-2.6.36/drivers/ata/pata_serverworks.c 2010-10-20 16:30:22.000000000 -0400
22073 +++ linux-2.6.36/drivers/ata/pata_serverworks.c 2010-11-06 18:58:15.000000000 -0400
22074 @@ -300,7 +300,7 @@ static struct scsi_host_template serverw
22075 ATA_BMDMA_SHT(DRV_NAME),
22076 };
22077
22078 -static struct ata_port_operations serverworks_osb4_port_ops = {
22079 +static const struct ata_port_operations serverworks_osb4_port_ops = {
22080 .inherits = &ata_bmdma_port_ops,
22081 .cable_detect = serverworks_cable_detect,
22082 .mode_filter = serverworks_osb4_filter,
22083 @@ -308,7 +308,7 @@ static struct ata_port_operations server
22084 .set_dmamode = serverworks_set_dmamode,
22085 };
22086
22087 -static struct ata_port_operations serverworks_csb_port_ops = {
22088 +static const struct ata_port_operations serverworks_csb_port_ops = {
22089 .inherits = &serverworks_osb4_port_ops,
22090 .mode_filter = serverworks_csb_filter,
22091 };
22092 diff -urNp linux-2.6.36/drivers/ata/pata_sil680.c linux-2.6.36/drivers/ata/pata_sil680.c
22093 --- linux-2.6.36/drivers/ata/pata_sil680.c 2010-10-20 16:30:22.000000000 -0400
22094 +++ linux-2.6.36/drivers/ata/pata_sil680.c 2010-11-06 18:58:15.000000000 -0400
22095 @@ -214,8 +214,7 @@ static struct scsi_host_template sil680_
22096 ATA_BMDMA_SHT(DRV_NAME),
22097 };
22098
22099 -
22100 -static struct ata_port_operations sil680_port_ops = {
22101 +static const struct ata_port_operations sil680_port_ops = {
22102 .inherits = &ata_bmdma32_port_ops,
22103 .sff_exec_command = sil680_sff_exec_command,
22104 .cable_detect = sil680_cable_detect,
22105 diff -urNp linux-2.6.36/drivers/ata/pata_sis.c linux-2.6.36/drivers/ata/pata_sis.c
22106 --- linux-2.6.36/drivers/ata/pata_sis.c 2010-10-20 16:30:22.000000000 -0400
22107 +++ linux-2.6.36/drivers/ata/pata_sis.c 2010-11-06 18:58:15.000000000 -0400
22108 @@ -503,47 +503,47 @@ static struct scsi_host_template sis_sht
22109 ATA_BMDMA_SHT(DRV_NAME),
22110 };
22111
22112 -static struct ata_port_operations sis_133_for_sata_ops = {
22113 +static const struct ata_port_operations sis_133_for_sata_ops = {
22114 .inherits = &ata_bmdma_port_ops,
22115 .set_piomode = sis_133_set_piomode,
22116 .set_dmamode = sis_133_set_dmamode,
22117 .cable_detect = sis_133_cable_detect,
22118 };
22119
22120 -static struct ata_port_operations sis_base_ops = {
22121 +static const struct ata_port_operations sis_base_ops = {
22122 .inherits = &ata_bmdma_port_ops,
22123 .prereset = sis_pre_reset,
22124 };
22125
22126 -static struct ata_port_operations sis_133_ops = {
22127 +static const struct ata_port_operations sis_133_ops = {
22128 .inherits = &sis_base_ops,
22129 .set_piomode = sis_133_set_piomode,
22130 .set_dmamode = sis_133_set_dmamode,
22131 .cable_detect = sis_133_cable_detect,
22132 };
22133
22134 -static struct ata_port_operations sis_133_early_ops = {
22135 +static const struct ata_port_operations sis_133_early_ops = {
22136 .inherits = &sis_base_ops,
22137 .set_piomode = sis_100_set_piomode,
22138 .set_dmamode = sis_133_early_set_dmamode,
22139 .cable_detect = sis_66_cable_detect,
22140 };
22141
22142 -static struct ata_port_operations sis_100_ops = {
22143 +static const struct ata_port_operations sis_100_ops = {
22144 .inherits = &sis_base_ops,
22145 .set_piomode = sis_100_set_piomode,
22146 .set_dmamode = sis_100_set_dmamode,
22147 .cable_detect = sis_66_cable_detect,
22148 };
22149
22150 -static struct ata_port_operations sis_66_ops = {
22151 +static const struct ata_port_operations sis_66_ops = {
22152 .inherits = &sis_base_ops,
22153 .set_piomode = sis_old_set_piomode,
22154 .set_dmamode = sis_66_set_dmamode,
22155 .cable_detect = sis_66_cable_detect,
22156 };
22157
22158 -static struct ata_port_operations sis_old_ops = {
22159 +static const struct ata_port_operations sis_old_ops = {
22160 .inherits = &sis_base_ops,
22161 .set_piomode = sis_old_set_piomode,
22162 .set_dmamode = sis_old_set_dmamode,
22163 diff -urNp linux-2.6.36/drivers/ata/pata_sl82c105.c linux-2.6.36/drivers/ata/pata_sl82c105.c
22164 --- linux-2.6.36/drivers/ata/pata_sl82c105.c 2010-10-20 16:30:22.000000000 -0400
22165 +++ linux-2.6.36/drivers/ata/pata_sl82c105.c 2010-11-06 18:58:15.000000000 -0400
22166 @@ -231,7 +231,7 @@ static struct scsi_host_template sl82c10
22167 ATA_BMDMA_SHT(DRV_NAME),
22168 };
22169
22170 -static struct ata_port_operations sl82c105_port_ops = {
22171 +static const struct ata_port_operations sl82c105_port_ops = {
22172 .inherits = &ata_bmdma_port_ops,
22173 .qc_defer = sl82c105_qc_defer,
22174 .bmdma_start = sl82c105_bmdma_start,
22175 diff -urNp linux-2.6.36/drivers/ata/pata_triflex.c linux-2.6.36/drivers/ata/pata_triflex.c
22176 --- linux-2.6.36/drivers/ata/pata_triflex.c 2010-10-20 16:30:22.000000000 -0400
22177 +++ linux-2.6.36/drivers/ata/pata_triflex.c 2010-11-06 18:58:15.000000000 -0400
22178 @@ -178,7 +178,7 @@ static struct scsi_host_template triflex
22179 ATA_BMDMA_SHT(DRV_NAME),
22180 };
22181
22182 -static struct ata_port_operations triflex_port_ops = {
22183 +static const struct ata_port_operations triflex_port_ops = {
22184 .inherits = &ata_bmdma_port_ops,
22185 .bmdma_start = triflex_bmdma_start,
22186 .bmdma_stop = triflex_bmdma_stop,
22187 diff -urNp linux-2.6.36/drivers/ata/pata_via.c linux-2.6.36/drivers/ata/pata_via.c
22188 --- linux-2.6.36/drivers/ata/pata_via.c 2010-10-20 16:30:22.000000000 -0400
22189 +++ linux-2.6.36/drivers/ata/pata_via.c 2010-11-06 18:58:15.000000000 -0400
22190 @@ -441,7 +441,7 @@ static struct scsi_host_template via_sht
22191 ATA_BMDMA_SHT(DRV_NAME),
22192 };
22193
22194 -static struct ata_port_operations via_port_ops = {
22195 +static const struct ata_port_operations via_port_ops = {
22196 .inherits = &ata_bmdma_port_ops,
22197 .cable_detect = via_cable_detect,
22198 .set_piomode = via_set_piomode,
22199 @@ -452,7 +452,7 @@ static struct ata_port_operations via_po
22200 .mode_filter = via_mode_filter,
22201 };
22202
22203 -static struct ata_port_operations via_port_ops_noirq = {
22204 +static const struct ata_port_operations via_port_ops_noirq = {
22205 .inherits = &via_port_ops,
22206 .sff_data_xfer = ata_sff_data_xfer_noirq,
22207 };
22208 diff -urNp linux-2.6.36/drivers/ata/pdc_adma.c linux-2.6.36/drivers/ata/pdc_adma.c
22209 --- linux-2.6.36/drivers/ata/pdc_adma.c 2010-10-20 16:30:22.000000000 -0400
22210 +++ linux-2.6.36/drivers/ata/pdc_adma.c 2010-11-06 18:58:15.000000000 -0400
22211 @@ -146,7 +146,7 @@ static struct scsi_host_template adma_at
22212 .dma_boundary = ADMA_DMA_BOUNDARY,
22213 };
22214
22215 -static struct ata_port_operations adma_ata_ops = {
22216 +static const struct ata_port_operations adma_ata_ops = {
22217 .inherits = &ata_sff_port_ops,
22218
22219 .lost_interrupt = ATA_OP_NULL,
22220 diff -urNp linux-2.6.36/drivers/ata/sata_dwc_460ex.c linux-2.6.36/drivers/ata/sata_dwc_460ex.c
22221 --- linux-2.6.36/drivers/ata/sata_dwc_460ex.c 2010-10-20 16:30:22.000000000 -0400
22222 +++ linux-2.6.36/drivers/ata/sata_dwc_460ex.c 2010-11-06 18:58:15.000000000 -0400
22223 @@ -1560,7 +1560,7 @@ static struct scsi_host_template sata_dw
22224 .dma_boundary = ATA_DMA_BOUNDARY,
22225 };
22226
22227 -static struct ata_port_operations sata_dwc_ops = {
22228 +static const struct ata_port_operations sata_dwc_ops = {
22229 .inherits = &ata_sff_port_ops,
22230
22231 .error_handler = sata_dwc_error_handler,
22232 diff -urNp linux-2.6.36/drivers/ata/sata_fsl.c linux-2.6.36/drivers/ata/sata_fsl.c
22233 --- linux-2.6.36/drivers/ata/sata_fsl.c 2010-10-20 16:30:22.000000000 -0400
22234 +++ linux-2.6.36/drivers/ata/sata_fsl.c 2010-11-06 18:58:15.000000000 -0400
22235 @@ -1261,7 +1261,7 @@ static struct scsi_host_template sata_fs
22236 .dma_boundary = ATA_DMA_BOUNDARY,
22237 };
22238
22239 -static struct ata_port_operations sata_fsl_ops = {
22240 +static const struct ata_port_operations sata_fsl_ops = {
22241 .inherits = &sata_pmp_port_ops,
22242
22243 .qc_defer = ata_std_qc_defer,
22244 diff -urNp linux-2.6.36/drivers/ata/sata_inic162x.c linux-2.6.36/drivers/ata/sata_inic162x.c
22245 --- linux-2.6.36/drivers/ata/sata_inic162x.c 2010-10-20 16:30:22.000000000 -0400
22246 +++ linux-2.6.36/drivers/ata/sata_inic162x.c 2010-11-06 18:58:15.000000000 -0400
22247 @@ -705,7 +705,7 @@ static int inic_port_start(struct ata_po
22248 return 0;
22249 }
22250
22251 -static struct ata_port_operations inic_port_ops = {
22252 +static const struct ata_port_operations inic_port_ops = {
22253 .inherits = &sata_port_ops,
22254
22255 .check_atapi_dma = inic_check_atapi_dma,
22256 diff -urNp linux-2.6.36/drivers/ata/sata_mv.c linux-2.6.36/drivers/ata/sata_mv.c
22257 --- linux-2.6.36/drivers/ata/sata_mv.c 2010-10-20 16:30:22.000000000 -0400
22258 +++ linux-2.6.36/drivers/ata/sata_mv.c 2010-11-06 18:58:15.000000000 -0400
22259 @@ -663,7 +663,7 @@ static struct scsi_host_template mv6_sht
22260 .dma_boundary = MV_DMA_BOUNDARY,
22261 };
22262
22263 -static struct ata_port_operations mv5_ops = {
22264 +static const struct ata_port_operations mv5_ops = {
22265 .inherits = &ata_sff_port_ops,
22266
22267 .lost_interrupt = ATA_OP_NULL,
22268 @@ -683,7 +683,7 @@ static struct ata_port_operations mv5_op
22269 .port_stop = mv_port_stop,
22270 };
22271
22272 -static struct ata_port_operations mv6_ops = {
22273 +static const struct ata_port_operations mv6_ops = {
22274 .inherits = &ata_bmdma_port_ops,
22275
22276 .lost_interrupt = ATA_OP_NULL,
22277 @@ -717,7 +717,7 @@ static struct ata_port_operations mv6_op
22278 .port_stop = mv_port_stop,
22279 };
22280
22281 -static struct ata_port_operations mv_iie_ops = {
22282 +static const struct ata_port_operations mv_iie_ops = {
22283 .inherits = &mv6_ops,
22284 .dev_config = ATA_OP_NULL,
22285 .qc_prep = mv_qc_prep_iie,
22286 diff -urNp linux-2.6.36/drivers/ata/sata_nv.c linux-2.6.36/drivers/ata/sata_nv.c
22287 --- linux-2.6.36/drivers/ata/sata_nv.c 2010-10-20 16:30:22.000000000 -0400
22288 +++ linux-2.6.36/drivers/ata/sata_nv.c 2010-11-06 18:58:15.000000000 -0400
22289 @@ -465,7 +465,7 @@ static struct scsi_host_template nv_swnc
22290 * cases. Define nv_hardreset() which only kicks in for post-boot
22291 * probing and use it for all variants.
22292 */
22293 -static struct ata_port_operations nv_generic_ops = {
22294 +static const struct ata_port_operations nv_generic_ops = {
22295 .inherits = &ata_bmdma_port_ops,
22296 .lost_interrupt = ATA_OP_NULL,
22297 .scr_read = nv_scr_read,
22298 @@ -473,20 +473,20 @@ static struct ata_port_operations nv_gen
22299 .hardreset = nv_hardreset,
22300 };
22301
22302 -static struct ata_port_operations nv_nf2_ops = {
22303 +static const struct ata_port_operations nv_nf2_ops = {
22304 .inherits = &nv_generic_ops,
22305 .freeze = nv_nf2_freeze,
22306 .thaw = nv_nf2_thaw,
22307 };
22308
22309 -static struct ata_port_operations nv_ck804_ops = {
22310 +static const struct ata_port_operations nv_ck804_ops = {
22311 .inherits = &nv_generic_ops,
22312 .freeze = nv_ck804_freeze,
22313 .thaw = nv_ck804_thaw,
22314 .host_stop = nv_ck804_host_stop,
22315 };
22316
22317 -static struct ata_port_operations nv_adma_ops = {
22318 +static const struct ata_port_operations nv_adma_ops = {
22319 .inherits = &nv_ck804_ops,
22320
22321 .check_atapi_dma = nv_adma_check_atapi_dma,
22322 @@ -510,7 +510,7 @@ static struct ata_port_operations nv_adm
22323 .host_stop = nv_adma_host_stop,
22324 };
22325
22326 -static struct ata_port_operations nv_swncq_ops = {
22327 +static const struct ata_port_operations nv_swncq_ops = {
22328 .inherits = &nv_generic_ops,
22329
22330 .qc_defer = ata_std_qc_defer,
22331 diff -urNp linux-2.6.36/drivers/ata/sata_promise.c linux-2.6.36/drivers/ata/sata_promise.c
22332 --- linux-2.6.36/drivers/ata/sata_promise.c 2010-10-20 16:30:22.000000000 -0400
22333 +++ linux-2.6.36/drivers/ata/sata_promise.c 2010-11-06 18:58:15.000000000 -0400
22334 @@ -196,7 +196,7 @@ static const struct ata_port_operations
22335 .error_handler = pdc_error_handler,
22336 };
22337
22338 -static struct ata_port_operations pdc_sata_ops = {
22339 +static const struct ata_port_operations pdc_sata_ops = {
22340 .inherits = &pdc_common_ops,
22341 .cable_detect = pdc_sata_cable_detect,
22342 .freeze = pdc_sata_freeze,
22343 @@ -209,14 +209,14 @@ static struct ata_port_operations pdc_sa
22344
22345 /* First-generation chips need a more restrictive ->check_atapi_dma op,
22346 and ->freeze/thaw that ignore the hotplug controls. */
22347 -static struct ata_port_operations pdc_old_sata_ops = {
22348 +static const struct ata_port_operations pdc_old_sata_ops = {
22349 .inherits = &pdc_sata_ops,
22350 .freeze = pdc_freeze,
22351 .thaw = pdc_thaw,
22352 .check_atapi_dma = pdc_old_sata_check_atapi_dma,
22353 };
22354
22355 -static struct ata_port_operations pdc_pata_ops = {
22356 +static const struct ata_port_operations pdc_pata_ops = {
22357 .inherits = &pdc_common_ops,
22358 .cable_detect = pdc_pata_cable_detect,
22359 .freeze = pdc_freeze,
22360 diff -urNp linux-2.6.36/drivers/ata/sata_qstor.c linux-2.6.36/drivers/ata/sata_qstor.c
22361 --- linux-2.6.36/drivers/ata/sata_qstor.c 2010-10-20 16:30:22.000000000 -0400
22362 +++ linux-2.6.36/drivers/ata/sata_qstor.c 2010-11-06 18:58:15.000000000 -0400
22363 @@ -131,7 +131,7 @@ static struct scsi_host_template qs_ata_
22364 .dma_boundary = QS_DMA_BOUNDARY,
22365 };
22366
22367 -static struct ata_port_operations qs_ata_ops = {
22368 +static const struct ata_port_operations qs_ata_ops = {
22369 .inherits = &ata_sff_port_ops,
22370
22371 .check_atapi_dma = qs_check_atapi_dma,
22372 diff -urNp linux-2.6.36/drivers/ata/sata_sil24.c linux-2.6.36/drivers/ata/sata_sil24.c
22373 --- linux-2.6.36/drivers/ata/sata_sil24.c 2010-10-20 16:30:22.000000000 -0400
22374 +++ linux-2.6.36/drivers/ata/sata_sil24.c 2010-11-06 18:58:15.000000000 -0400
22375 @@ -389,7 +389,7 @@ static struct scsi_host_template sil24_s
22376 .dma_boundary = ATA_DMA_BOUNDARY,
22377 };
22378
22379 -static struct ata_port_operations sil24_ops = {
22380 +static const struct ata_port_operations sil24_ops = {
22381 .inherits = &sata_pmp_port_ops,
22382
22383 .qc_defer = sil24_qc_defer,
22384 diff -urNp linux-2.6.36/drivers/ata/sata_sil.c linux-2.6.36/drivers/ata/sata_sil.c
22385 --- linux-2.6.36/drivers/ata/sata_sil.c 2010-10-20 16:30:22.000000000 -0400
22386 +++ linux-2.6.36/drivers/ata/sata_sil.c 2010-11-06 18:58:15.000000000 -0400
22387 @@ -182,7 +182,7 @@ static struct scsi_host_template sil_sht
22388 .sg_tablesize = ATA_MAX_PRD
22389 };
22390
22391 -static struct ata_port_operations sil_ops = {
22392 +static const struct ata_port_operations sil_ops = {
22393 .inherits = &ata_bmdma32_port_ops,
22394 .dev_config = sil_dev_config,
22395 .set_mode = sil_set_mode,
22396 diff -urNp linux-2.6.36/drivers/ata/sata_sis.c linux-2.6.36/drivers/ata/sata_sis.c
22397 --- linux-2.6.36/drivers/ata/sata_sis.c 2010-10-20 16:30:22.000000000 -0400
22398 +++ linux-2.6.36/drivers/ata/sata_sis.c 2010-11-06 18:58:15.000000000 -0400
22399 @@ -89,7 +89,7 @@ static struct scsi_host_template sis_sht
22400 ATA_BMDMA_SHT(DRV_NAME),
22401 };
22402
22403 -static struct ata_port_operations sis_ops = {
22404 +static const struct ata_port_operations sis_ops = {
22405 .inherits = &ata_bmdma_port_ops,
22406 .scr_read = sis_scr_read,
22407 .scr_write = sis_scr_write,
22408 diff -urNp linux-2.6.36/drivers/ata/sata_svw.c linux-2.6.36/drivers/ata/sata_svw.c
22409 --- linux-2.6.36/drivers/ata/sata_svw.c 2010-10-20 16:30:22.000000000 -0400
22410 +++ linux-2.6.36/drivers/ata/sata_svw.c 2010-11-06 18:58:15.000000000 -0400
22411 @@ -344,7 +344,7 @@ static struct scsi_host_template k2_sata
22412 };
22413
22414
22415 -static struct ata_port_operations k2_sata_ops = {
22416 +static const struct ata_port_operations k2_sata_ops = {
22417 .inherits = &ata_bmdma_port_ops,
22418 .sff_tf_load = k2_sata_tf_load,
22419 .sff_tf_read = k2_sata_tf_read,
22420 diff -urNp linux-2.6.36/drivers/ata/sata_sx4.c linux-2.6.36/drivers/ata/sata_sx4.c
22421 --- linux-2.6.36/drivers/ata/sata_sx4.c 2010-10-20 16:30:22.000000000 -0400
22422 +++ linux-2.6.36/drivers/ata/sata_sx4.c 2010-11-06 18:58:15.000000000 -0400
22423 @@ -249,7 +249,7 @@ static struct scsi_host_template pdc_sat
22424 };
22425
22426 /* TODO: inherit from base port_ops after converting to new EH */
22427 -static struct ata_port_operations pdc_20621_ops = {
22428 +static const struct ata_port_operations pdc_20621_ops = {
22429 .inherits = &ata_sff_port_ops,
22430
22431 .check_atapi_dma = pdc_check_atapi_dma,
22432 diff -urNp linux-2.6.36/drivers/ata/sata_uli.c linux-2.6.36/drivers/ata/sata_uli.c
22433 --- linux-2.6.36/drivers/ata/sata_uli.c 2010-10-20 16:30:22.000000000 -0400
22434 +++ linux-2.6.36/drivers/ata/sata_uli.c 2010-11-06 18:58:15.000000000 -0400
22435 @@ -80,7 +80,7 @@ static struct scsi_host_template uli_sht
22436 ATA_BMDMA_SHT(DRV_NAME),
22437 };
22438
22439 -static struct ata_port_operations uli_ops = {
22440 +static const struct ata_port_operations uli_ops = {
22441 .inherits = &ata_bmdma_port_ops,
22442 .scr_read = uli_scr_read,
22443 .scr_write = uli_scr_write,
22444 diff -urNp linux-2.6.36/drivers/ata/sata_via.c linux-2.6.36/drivers/ata/sata_via.c
22445 --- linux-2.6.36/drivers/ata/sata_via.c 2010-10-20 16:30:22.000000000 -0400
22446 +++ linux-2.6.36/drivers/ata/sata_via.c 2010-11-06 18:58:15.000000000 -0400
22447 @@ -115,32 +115,32 @@ static struct scsi_host_template svia_sh
22448 ATA_BMDMA_SHT(DRV_NAME),
22449 };
22450
22451 -static struct ata_port_operations svia_base_ops = {
22452 +static const struct ata_port_operations svia_base_ops = {
22453 .inherits = &ata_bmdma_port_ops,
22454 .sff_tf_load = svia_tf_load,
22455 };
22456
22457 -static struct ata_port_operations vt6420_sata_ops = {
22458 +static const struct ata_port_operations vt6420_sata_ops = {
22459 .inherits = &svia_base_ops,
22460 .freeze = svia_noop_freeze,
22461 .prereset = vt6420_prereset,
22462 .bmdma_start = vt6420_bmdma_start,
22463 };
22464
22465 -static struct ata_port_operations vt6421_pata_ops = {
22466 +static const struct ata_port_operations vt6421_pata_ops = {
22467 .inherits = &svia_base_ops,
22468 .cable_detect = vt6421_pata_cable_detect,
22469 .set_piomode = vt6421_set_pio_mode,
22470 .set_dmamode = vt6421_set_dma_mode,
22471 };
22472
22473 -static struct ata_port_operations vt6421_sata_ops = {
22474 +static const struct ata_port_operations vt6421_sata_ops = {
22475 .inherits = &svia_base_ops,
22476 .scr_read = svia_scr_read,
22477 .scr_write = svia_scr_write,
22478 };
22479
22480 -static struct ata_port_operations vt8251_ops = {
22481 +static const struct ata_port_operations vt8251_ops = {
22482 .inherits = &svia_base_ops,
22483 .hardreset = sata_std_hardreset,
22484 .scr_read = vt8251_scr_read,
22485 diff -urNp linux-2.6.36/drivers/ata/sata_vsc.c linux-2.6.36/drivers/ata/sata_vsc.c
22486 --- linux-2.6.36/drivers/ata/sata_vsc.c 2010-10-20 16:30:22.000000000 -0400
22487 +++ linux-2.6.36/drivers/ata/sata_vsc.c 2010-11-06 18:58:15.000000000 -0400
22488 @@ -300,7 +300,7 @@ static struct scsi_host_template vsc_sat
22489 };
22490
22491
22492 -static struct ata_port_operations vsc_sata_ops = {
22493 +static const struct ata_port_operations vsc_sata_ops = {
22494 .inherits = &ata_bmdma_port_ops,
22495 /* The IRQ handling is not quite standard SFF behaviour so we
22496 cannot use the default lost interrupt handler */
22497 diff -urNp linux-2.6.36/drivers/atm/adummy.c linux-2.6.36/drivers/atm/adummy.c
22498 --- linux-2.6.36/drivers/atm/adummy.c 2010-10-20 16:30:22.000000000 -0400
22499 +++ linux-2.6.36/drivers/atm/adummy.c 2010-11-06 18:58:15.000000000 -0400
22500 @@ -114,7 +114,7 @@ adummy_send(struct atm_vcc *vcc, struct
22501 vcc->pop(vcc, skb);
22502 else
22503 dev_kfree_skb_any(skb);
22504 - atomic_inc(&vcc->stats->tx);
22505 + atomic_inc_unchecked(&vcc->stats->tx);
22506
22507 return 0;
22508 }
22509 diff -urNp linux-2.6.36/drivers/atm/ambassador.c linux-2.6.36/drivers/atm/ambassador.c
22510 --- linux-2.6.36/drivers/atm/ambassador.c 2010-10-20 16:30:22.000000000 -0400
22511 +++ linux-2.6.36/drivers/atm/ambassador.c 2010-11-06 18:58:15.000000000 -0400
22512 @@ -454,7 +454,7 @@ static void tx_complete (amb_dev * dev,
22513 PRINTD (DBG_FLOW|DBG_TX, "tx_complete %p %p", dev, tx);
22514
22515 // VC layer stats
22516 - atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
22517 + atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
22518
22519 // free the descriptor
22520 kfree (tx_descr);
22521 @@ -495,7 +495,7 @@ static void rx_complete (amb_dev * dev,
22522 dump_skb ("<<<", vc, skb);
22523
22524 // VC layer stats
22525 - atomic_inc(&atm_vcc->stats->rx);
22526 + atomic_inc_unchecked(&atm_vcc->stats->rx);
22527 __net_timestamp(skb);
22528 // end of our responsability
22529 atm_vcc->push (atm_vcc, skb);
22530 @@ -510,7 +510,7 @@ static void rx_complete (amb_dev * dev,
22531 } else {
22532 PRINTK (KERN_INFO, "dropped over-size frame");
22533 // should we count this?
22534 - atomic_inc(&atm_vcc->stats->rx_drop);
22535 + atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
22536 }
22537
22538 } else {
22539 @@ -1342,7 +1342,7 @@ static int amb_send (struct atm_vcc * at
22540 }
22541
22542 if (check_area (skb->data, skb->len)) {
22543 - atomic_inc(&atm_vcc->stats->tx_err);
22544 + atomic_inc_unchecked(&atm_vcc->stats->tx_err);
22545 return -ENOMEM; // ?
22546 }
22547
22548 diff -urNp linux-2.6.36/drivers/atm/atmtcp.c linux-2.6.36/drivers/atm/atmtcp.c
22549 --- linux-2.6.36/drivers/atm/atmtcp.c 2010-10-20 16:30:22.000000000 -0400
22550 +++ linux-2.6.36/drivers/atm/atmtcp.c 2010-11-06 18:58:15.000000000 -0400
22551 @@ -207,7 +207,7 @@ static int atmtcp_v_send(struct atm_vcc
22552 if (vcc->pop) vcc->pop(vcc,skb);
22553 else dev_kfree_skb(skb);
22554 if (dev_data) return 0;
22555 - atomic_inc(&vcc->stats->tx_err);
22556 + atomic_inc_unchecked(&vcc->stats->tx_err);
22557 return -ENOLINK;
22558 }
22559 size = skb->len+sizeof(struct atmtcp_hdr);
22560 @@ -215,7 +215,7 @@ static int atmtcp_v_send(struct atm_vcc
22561 if (!new_skb) {
22562 if (vcc->pop) vcc->pop(vcc,skb);
22563 else dev_kfree_skb(skb);
22564 - atomic_inc(&vcc->stats->tx_err);
22565 + atomic_inc_unchecked(&vcc->stats->tx_err);
22566 return -ENOBUFS;
22567 }
22568 hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
22569 @@ -226,8 +226,8 @@ static int atmtcp_v_send(struct atm_vcc
22570 if (vcc->pop) vcc->pop(vcc,skb);
22571 else dev_kfree_skb(skb);
22572 out_vcc->push(out_vcc,new_skb);
22573 - atomic_inc(&vcc->stats->tx);
22574 - atomic_inc(&out_vcc->stats->rx);
22575 + atomic_inc_unchecked(&vcc->stats->tx);
22576 + atomic_inc_unchecked(&out_vcc->stats->rx);
22577 return 0;
22578 }
22579
22580 @@ -301,7 +301,7 @@ static int atmtcp_c_send(struct atm_vcc
22581 out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
22582 read_unlock(&vcc_sklist_lock);
22583 if (!out_vcc) {
22584 - atomic_inc(&vcc->stats->tx_err);
22585 + atomic_inc_unchecked(&vcc->stats->tx_err);
22586 goto done;
22587 }
22588 skb_pull(skb,sizeof(struct atmtcp_hdr));
22589 @@ -313,8 +313,8 @@ static int atmtcp_c_send(struct atm_vcc
22590 __net_timestamp(new_skb);
22591 skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
22592 out_vcc->push(out_vcc,new_skb);
22593 - atomic_inc(&vcc->stats->tx);
22594 - atomic_inc(&out_vcc->stats->rx);
22595 + atomic_inc_unchecked(&vcc->stats->tx);
22596 + atomic_inc_unchecked(&out_vcc->stats->rx);
22597 done:
22598 if (vcc->pop) vcc->pop(vcc,skb);
22599 else dev_kfree_skb(skb);
22600 diff -urNp linux-2.6.36/drivers/atm/eni.c linux-2.6.36/drivers/atm/eni.c
22601 --- linux-2.6.36/drivers/atm/eni.c 2010-10-20 16:30:22.000000000 -0400
22602 +++ linux-2.6.36/drivers/atm/eni.c 2010-11-06 18:58:15.000000000 -0400
22603 @@ -526,7 +526,7 @@ static int rx_aal0(struct atm_vcc *vcc)
22604 DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
22605 vcc->dev->number);
22606 length = 0;
22607 - atomic_inc(&vcc->stats->rx_err);
22608 + atomic_inc_unchecked(&vcc->stats->rx_err);
22609 }
22610 else {
22611 length = ATM_CELL_SIZE-1; /* no HEC */
22612 @@ -581,7 +581,7 @@ static int rx_aal5(struct atm_vcc *vcc)
22613 size);
22614 }
22615 eff = length = 0;
22616 - atomic_inc(&vcc->stats->rx_err);
22617 + atomic_inc_unchecked(&vcc->stats->rx_err);
22618 }
22619 else {
22620 size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
22621 @@ -598,7 +598,7 @@ static int rx_aal5(struct atm_vcc *vcc)
22622 "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n",
22623 vcc->dev->number,vcc->vci,length,size << 2,descr);
22624 length = eff = 0;
22625 - atomic_inc(&vcc->stats->rx_err);
22626 + atomic_inc_unchecked(&vcc->stats->rx_err);
22627 }
22628 }
22629 skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL;
22630 @@ -771,7 +771,7 @@ rx_dequeued++;
22631 vcc->push(vcc,skb);
22632 pushed++;
22633 }
22634 - atomic_inc(&vcc->stats->rx);
22635 + atomic_inc_unchecked(&vcc->stats->rx);
22636 }
22637 wake_up(&eni_dev->rx_wait);
22638 }
22639 @@ -1228,7 +1228,7 @@ static void dequeue_tx(struct atm_dev *d
22640 PCI_DMA_TODEVICE);
22641 if (vcc->pop) vcc->pop(vcc,skb);
22642 else dev_kfree_skb_irq(skb);
22643 - atomic_inc(&vcc->stats->tx);
22644 + atomic_inc_unchecked(&vcc->stats->tx);
22645 wake_up(&eni_dev->tx_wait);
22646 dma_complete++;
22647 }
22648 diff -urNp linux-2.6.36/drivers/atm/firestream.c linux-2.6.36/drivers/atm/firestream.c
22649 --- linux-2.6.36/drivers/atm/firestream.c 2010-10-20 16:30:22.000000000 -0400
22650 +++ linux-2.6.36/drivers/atm/firestream.c 2010-11-06 18:58:15.000000000 -0400
22651 @@ -749,7 +749,7 @@ static void process_txdone_queue (struct
22652 }
22653 }
22654
22655 - atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
22656 + atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
22657
22658 fs_dprintk (FS_DEBUG_TXMEM, "i");
22659 fs_dprintk (FS_DEBUG_ALLOC, "Free t-skb: %p\n", skb);
22660 @@ -816,7 +816,7 @@ static void process_incoming (struct fs_
22661 #endif
22662 skb_put (skb, qe->p1 & 0xffff);
22663 ATM_SKB(skb)->vcc = atm_vcc;
22664 - atomic_inc(&atm_vcc->stats->rx);
22665 + atomic_inc_unchecked(&atm_vcc->stats->rx);
22666 __net_timestamp(skb);
22667 fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
22668 atm_vcc->push (atm_vcc, skb);
22669 @@ -837,12 +837,12 @@ static void process_incoming (struct fs_
22670 kfree (pe);
22671 }
22672 if (atm_vcc)
22673 - atomic_inc(&atm_vcc->stats->rx_drop);
22674 + atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
22675 break;
22676 case 0x1f: /* Reassembly abort: no buffers. */
22677 /* Silently increment error counter. */
22678 if (atm_vcc)
22679 - atomic_inc(&atm_vcc->stats->rx_drop);
22680 + atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
22681 break;
22682 default: /* Hmm. Haven't written the code to handle the others yet... -- REW */
22683 printk (KERN_WARNING "Don't know what to do with RX status %x: %s.\n",
22684 diff -urNp linux-2.6.36/drivers/atm/fore200e.c linux-2.6.36/drivers/atm/fore200e.c
22685 --- linux-2.6.36/drivers/atm/fore200e.c 2010-10-20 16:30:22.000000000 -0400
22686 +++ linux-2.6.36/drivers/atm/fore200e.c 2010-11-06 18:58:15.000000000 -0400
22687 @@ -933,9 +933,9 @@ fore200e_tx_irq(struct fore200e* fore200
22688 #endif
22689 /* check error condition */
22690 if (*entry->status & STATUS_ERROR)
22691 - atomic_inc(&vcc->stats->tx_err);
22692 + atomic_inc_unchecked(&vcc->stats->tx_err);
22693 else
22694 - atomic_inc(&vcc->stats->tx);
22695 + atomic_inc_unchecked(&vcc->stats->tx);
22696 }
22697 }
22698
22699 @@ -1084,7 +1084,7 @@ fore200e_push_rpd(struct fore200e* fore2
22700 if (skb == NULL) {
22701 DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
22702
22703 - atomic_inc(&vcc->stats->rx_drop);
22704 + atomic_inc_unchecked(&vcc->stats->rx_drop);
22705 return -ENOMEM;
22706 }
22707
22708 @@ -1127,14 +1127,14 @@ fore200e_push_rpd(struct fore200e* fore2
22709
22710 dev_kfree_skb_any(skb);
22711
22712 - atomic_inc(&vcc->stats->rx_drop);
22713 + atomic_inc_unchecked(&vcc->stats->rx_drop);
22714 return -ENOMEM;
22715 }
22716
22717 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
22718
22719 vcc->push(vcc, skb);
22720 - atomic_inc(&vcc->stats->rx);
22721 + atomic_inc_unchecked(&vcc->stats->rx);
22722
22723 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
22724
22725 @@ -1212,7 +1212,7 @@ fore200e_rx_irq(struct fore200e* fore200
22726 DPRINTK(2, "damaged PDU on %d.%d.%d\n",
22727 fore200e->atm_dev->number,
22728 entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
22729 - atomic_inc(&vcc->stats->rx_err);
22730 + atomic_inc_unchecked(&vcc->stats->rx_err);
22731 }
22732 }
22733
22734 @@ -1657,7 +1657,7 @@ fore200e_send(struct atm_vcc *vcc, struc
22735 goto retry_here;
22736 }
22737
22738 - atomic_inc(&vcc->stats->tx_err);
22739 + atomic_inc_unchecked(&vcc->stats->tx_err);
22740
22741 fore200e->tx_sat++;
22742 DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
22743 diff -urNp linux-2.6.36/drivers/atm/he.c linux-2.6.36/drivers/atm/he.c
22744 --- linux-2.6.36/drivers/atm/he.c 2010-10-20 16:30:22.000000000 -0400
22745 +++ linux-2.6.36/drivers/atm/he.c 2010-11-06 18:58:15.000000000 -0400
22746 @@ -1709,7 +1709,7 @@ he_service_rbrq(struct he_dev *he_dev, i
22747
22748 if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
22749 hprintk("HBUF_ERR! (cid 0x%x)\n", cid);
22750 - atomic_inc(&vcc->stats->rx_drop);
22751 + atomic_inc_unchecked(&vcc->stats->rx_drop);
22752 goto return_host_buffers;
22753 }
22754
22755 @@ -1736,7 +1736,7 @@ he_service_rbrq(struct he_dev *he_dev, i
22756 RBRQ_LEN_ERR(he_dev->rbrq_head)
22757 ? "LEN_ERR" : "",
22758 vcc->vpi, vcc->vci);
22759 - atomic_inc(&vcc->stats->rx_err);
22760 + atomic_inc_unchecked(&vcc->stats->rx_err);
22761 goto return_host_buffers;
22762 }
22763
22764 @@ -1788,7 +1788,7 @@ he_service_rbrq(struct he_dev *he_dev, i
22765 vcc->push(vcc, skb);
22766 spin_lock(&he_dev->global_lock);
22767
22768 - atomic_inc(&vcc->stats->rx);
22769 + atomic_inc_unchecked(&vcc->stats->rx);
22770
22771 return_host_buffers:
22772 ++pdus_assembled;
22773 @@ -2114,7 +2114,7 @@ __enqueue_tpd(struct he_dev *he_dev, str
22774 tpd->vcc->pop(tpd->vcc, tpd->skb);
22775 else
22776 dev_kfree_skb_any(tpd->skb);
22777 - atomic_inc(&tpd->vcc->stats->tx_err);
22778 + atomic_inc_unchecked(&tpd->vcc->stats->tx_err);
22779 }
22780 pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
22781 return;
22782 @@ -2526,7 +2526,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
22783 vcc->pop(vcc, skb);
22784 else
22785 dev_kfree_skb_any(skb);
22786 - atomic_inc(&vcc->stats->tx_err);
22787 + atomic_inc_unchecked(&vcc->stats->tx_err);
22788 return -EINVAL;
22789 }
22790
22791 @@ -2537,7 +2537,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
22792 vcc->pop(vcc, skb);
22793 else
22794 dev_kfree_skb_any(skb);
22795 - atomic_inc(&vcc->stats->tx_err);
22796 + atomic_inc_unchecked(&vcc->stats->tx_err);
22797 return -EINVAL;
22798 }
22799 #endif
22800 @@ -2549,7 +2549,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
22801 vcc->pop(vcc, skb);
22802 else
22803 dev_kfree_skb_any(skb);
22804 - atomic_inc(&vcc->stats->tx_err);
22805 + atomic_inc_unchecked(&vcc->stats->tx_err);
22806 spin_unlock_irqrestore(&he_dev->global_lock, flags);
22807 return -ENOMEM;
22808 }
22809 @@ -2591,7 +2591,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
22810 vcc->pop(vcc, skb);
22811 else
22812 dev_kfree_skb_any(skb);
22813 - atomic_inc(&vcc->stats->tx_err);
22814 + atomic_inc_unchecked(&vcc->stats->tx_err);
22815 spin_unlock_irqrestore(&he_dev->global_lock, flags);
22816 return -ENOMEM;
22817 }
22818 @@ -2622,7 +2622,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
22819 __enqueue_tpd(he_dev, tpd, cid);
22820 spin_unlock_irqrestore(&he_dev->global_lock, flags);
22821
22822 - atomic_inc(&vcc->stats->tx);
22823 + atomic_inc_unchecked(&vcc->stats->tx);
22824
22825 return 0;
22826 }
22827 diff -urNp linux-2.6.36/drivers/atm/horizon.c linux-2.6.36/drivers/atm/horizon.c
22828 --- linux-2.6.36/drivers/atm/horizon.c 2010-10-20 16:30:22.000000000 -0400
22829 +++ linux-2.6.36/drivers/atm/horizon.c 2010-11-06 18:58:15.000000000 -0400
22830 @@ -1034,7 +1034,7 @@ static void rx_schedule (hrz_dev * dev,
22831 {
22832 struct atm_vcc * vcc = ATM_SKB(skb)->vcc;
22833 // VC layer stats
22834 - atomic_inc(&vcc->stats->rx);
22835 + atomic_inc_unchecked(&vcc->stats->rx);
22836 __net_timestamp(skb);
22837 // end of our responsability
22838 vcc->push (vcc, skb);
22839 @@ -1186,7 +1186,7 @@ static void tx_schedule (hrz_dev * const
22840 dev->tx_iovec = NULL;
22841
22842 // VC layer stats
22843 - atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
22844 + atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
22845
22846 // free the skb
22847 hrz_kfree_skb (skb);
22848 diff -urNp linux-2.6.36/drivers/atm/idt77252.c linux-2.6.36/drivers/atm/idt77252.c
22849 --- linux-2.6.36/drivers/atm/idt77252.c 2010-10-20 16:30:22.000000000 -0400
22850 +++ linux-2.6.36/drivers/atm/idt77252.c 2010-11-06 18:58:15.000000000 -0400
22851 @@ -811,7 +811,7 @@ drain_scq(struct idt77252_dev *card, str
22852 else
22853 dev_kfree_skb(skb);
22854
22855 - atomic_inc(&vcc->stats->tx);
22856 + atomic_inc_unchecked(&vcc->stats->tx);
22857 }
22858
22859 atomic_dec(&scq->used);
22860 @@ -1074,13 +1074,13 @@ dequeue_rx(struct idt77252_dev *card, st
22861 if ((sb = dev_alloc_skb(64)) == NULL) {
22862 printk("%s: Can't allocate buffers for aal0.\n",
22863 card->name);
22864 - atomic_add(i, &vcc->stats->rx_drop);
22865 + atomic_add_unchecked(i, &vcc->stats->rx_drop);
22866 break;
22867 }
22868 if (!atm_charge(vcc, sb->truesize)) {
22869 RXPRINTK("%s: atm_charge() dropped aal0 packets.\n",
22870 card->name);
22871 - atomic_add(i - 1, &vcc->stats->rx_drop);
22872 + atomic_add_unchecked(i - 1, &vcc->stats->rx_drop);
22873 dev_kfree_skb(sb);
22874 break;
22875 }
22876 @@ -1097,7 +1097,7 @@ dequeue_rx(struct idt77252_dev *card, st
22877 ATM_SKB(sb)->vcc = vcc;
22878 __net_timestamp(sb);
22879 vcc->push(vcc, sb);
22880 - atomic_inc(&vcc->stats->rx);
22881 + atomic_inc_unchecked(&vcc->stats->rx);
22882
22883 cell += ATM_CELL_PAYLOAD;
22884 }
22885 @@ -1134,13 +1134,13 @@ dequeue_rx(struct idt77252_dev *card, st
22886 "(CDC: %08x)\n",
22887 card->name, len, rpp->len, readl(SAR_REG_CDC));
22888 recycle_rx_pool_skb(card, rpp);
22889 - atomic_inc(&vcc->stats->rx_err);
22890 + atomic_inc_unchecked(&vcc->stats->rx_err);
22891 return;
22892 }
22893 if (stat & SAR_RSQE_CRC) {
22894 RXPRINTK("%s: AAL5 CRC error.\n", card->name);
22895 recycle_rx_pool_skb(card, rpp);
22896 - atomic_inc(&vcc->stats->rx_err);
22897 + atomic_inc_unchecked(&vcc->stats->rx_err);
22898 return;
22899 }
22900 if (skb_queue_len(&rpp->queue) > 1) {
22901 @@ -1151,7 +1151,7 @@ dequeue_rx(struct idt77252_dev *card, st
22902 RXPRINTK("%s: Can't alloc RX skb.\n",
22903 card->name);
22904 recycle_rx_pool_skb(card, rpp);
22905 - atomic_inc(&vcc->stats->rx_err);
22906 + atomic_inc_unchecked(&vcc->stats->rx_err);
22907 return;
22908 }
22909 if (!atm_charge(vcc, skb->truesize)) {
22910 @@ -1170,7 +1170,7 @@ dequeue_rx(struct idt77252_dev *card, st
22911 __net_timestamp(skb);
22912
22913 vcc->push(vcc, skb);
22914 - atomic_inc(&vcc->stats->rx);
22915 + atomic_inc_unchecked(&vcc->stats->rx);
22916
22917 return;
22918 }
22919 @@ -1192,7 +1192,7 @@ dequeue_rx(struct idt77252_dev *card, st
22920 __net_timestamp(skb);
22921
22922 vcc->push(vcc, skb);
22923 - atomic_inc(&vcc->stats->rx);
22924 + atomic_inc_unchecked(&vcc->stats->rx);
22925
22926 if (skb->truesize > SAR_FB_SIZE_3)
22927 add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
22928 @@ -1304,14 +1304,14 @@ idt77252_rx_raw(struct idt77252_dev *car
22929 if (vcc->qos.aal != ATM_AAL0) {
22930 RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n",
22931 card->name, vpi, vci);
22932 - atomic_inc(&vcc->stats->rx_drop);
22933 + atomic_inc_unchecked(&vcc->stats->rx_drop);
22934 goto drop;
22935 }
22936
22937 if ((sb = dev_alloc_skb(64)) == NULL) {
22938 printk("%s: Can't allocate buffers for AAL0.\n",
22939 card->name);
22940 - atomic_inc(&vcc->stats->rx_err);
22941 + atomic_inc_unchecked(&vcc->stats->rx_err);
22942 goto drop;
22943 }
22944
22945 @@ -1330,7 +1330,7 @@ idt77252_rx_raw(struct idt77252_dev *car
22946 ATM_SKB(sb)->vcc = vcc;
22947 __net_timestamp(sb);
22948 vcc->push(vcc, sb);
22949 - atomic_inc(&vcc->stats->rx);
22950 + atomic_inc_unchecked(&vcc->stats->rx);
22951
22952 drop:
22953 skb_pull(queue, 64);
22954 @@ -1955,13 +1955,13 @@ idt77252_send_skb(struct atm_vcc *vcc, s
22955
22956 if (vc == NULL) {
22957 printk("%s: NULL connection in send().\n", card->name);
22958 - atomic_inc(&vcc->stats->tx_err);
22959 + atomic_inc_unchecked(&vcc->stats->tx_err);
22960 dev_kfree_skb(skb);
22961 return -EINVAL;
22962 }
22963 if (!test_bit(VCF_TX, &vc->flags)) {
22964 printk("%s: Trying to transmit on a non-tx VC.\n", card->name);
22965 - atomic_inc(&vcc->stats->tx_err);
22966 + atomic_inc_unchecked(&vcc->stats->tx_err);
22967 dev_kfree_skb(skb);
22968 return -EINVAL;
22969 }
22970 @@ -1973,14 +1973,14 @@ idt77252_send_skb(struct atm_vcc *vcc, s
22971 break;
22972 default:
22973 printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
22974 - atomic_inc(&vcc->stats->tx_err);
22975 + atomic_inc_unchecked(&vcc->stats->tx_err);
22976 dev_kfree_skb(skb);
22977 return -EINVAL;
22978 }
22979
22980 if (skb_shinfo(skb)->nr_frags != 0) {
22981 printk("%s: No scatter-gather yet.\n", card->name);
22982 - atomic_inc(&vcc->stats->tx_err);
22983 + atomic_inc_unchecked(&vcc->stats->tx_err);
22984 dev_kfree_skb(skb);
22985 return -EINVAL;
22986 }
22987 @@ -1988,7 +1988,7 @@ idt77252_send_skb(struct atm_vcc *vcc, s
22988
22989 err = queue_skb(card, vc, skb, oam);
22990 if (err) {
22991 - atomic_inc(&vcc->stats->tx_err);
22992 + atomic_inc_unchecked(&vcc->stats->tx_err);
22993 dev_kfree_skb(skb);
22994 return err;
22995 }
22996 @@ -2011,7 +2011,7 @@ idt77252_send_oam(struct atm_vcc *vcc, v
22997 skb = dev_alloc_skb(64);
22998 if (!skb) {
22999 printk("%s: Out of memory in send_oam().\n", card->name);
23000 - atomic_inc(&vcc->stats->tx_err);
23001 + atomic_inc_unchecked(&vcc->stats->tx_err);
23002 return -ENOMEM;
23003 }
23004 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
23005 diff -urNp linux-2.6.36/drivers/atm/iphase.c linux-2.6.36/drivers/atm/iphase.c
23006 --- linux-2.6.36/drivers/atm/iphase.c 2010-10-20 16:30:22.000000000 -0400
23007 +++ linux-2.6.36/drivers/atm/iphase.c 2010-11-06 18:58:15.000000000 -0400
23008 @@ -1124,7 +1124,7 @@ static int rx_pkt(struct atm_dev *dev)
23009 status = (u_short) (buf_desc_ptr->desc_mode);
23010 if (status & (RX_CER | RX_PTE | RX_OFL))
23011 {
23012 - atomic_inc(&vcc->stats->rx_err);
23013 + atomic_inc_unchecked(&vcc->stats->rx_err);
23014 IF_ERR(printk("IA: bad packet, dropping it");)
23015 if (status & RX_CER) {
23016 IF_ERR(printk(" cause: packet CRC error\n");)
23017 @@ -1147,7 +1147,7 @@ static int rx_pkt(struct atm_dev *dev)
23018 len = dma_addr - buf_addr;
23019 if (len > iadev->rx_buf_sz) {
23020 printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz);
23021 - atomic_inc(&vcc->stats->rx_err);
23022 + atomic_inc_unchecked(&vcc->stats->rx_err);
23023 goto out_free_desc;
23024 }
23025
23026 @@ -1297,7 +1297,7 @@ static void rx_dle_intr(struct atm_dev *
23027 ia_vcc = INPH_IA_VCC(vcc);
23028 if (ia_vcc == NULL)
23029 {
23030 - atomic_inc(&vcc->stats->rx_err);
23031 + atomic_inc_unchecked(&vcc->stats->rx_err);
23032 dev_kfree_skb_any(skb);
23033 atm_return(vcc, atm_guess_pdu2truesize(len));
23034 goto INCR_DLE;
23035 @@ -1309,7 +1309,7 @@ static void rx_dle_intr(struct atm_dev *
23036 if ((length > iadev->rx_buf_sz) || (length >
23037 (skb->len - sizeof(struct cpcs_trailer))))
23038 {
23039 - atomic_inc(&vcc->stats->rx_err);
23040 + atomic_inc_unchecked(&vcc->stats->rx_err);
23041 IF_ERR(printk("rx_dle_intr: Bad AAL5 trailer %d (skb len %d)",
23042 length, skb->len);)
23043 dev_kfree_skb_any(skb);
23044 @@ -1325,7 +1325,7 @@ static void rx_dle_intr(struct atm_dev *
23045
23046 IF_RX(printk("rx_dle_intr: skb push");)
23047 vcc->push(vcc,skb);
23048 - atomic_inc(&vcc->stats->rx);
23049 + atomic_inc_unchecked(&vcc->stats->rx);
23050 iadev->rx_pkt_cnt++;
23051 }
23052 INCR_DLE:
23053 @@ -2807,15 +2807,15 @@ static int ia_ioctl(struct atm_dev *dev,
23054 {
23055 struct k_sonet_stats *stats;
23056 stats = &PRIV(_ia_dev[board])->sonet_stats;
23057 - printk("section_bip: %d\n", atomic_read(&stats->section_bip));
23058 - printk("line_bip : %d\n", atomic_read(&stats->line_bip));
23059 - printk("path_bip : %d\n", atomic_read(&stats->path_bip));
23060 - printk("line_febe : %d\n", atomic_read(&stats->line_febe));
23061 - printk("path_febe : %d\n", atomic_read(&stats->path_febe));
23062 - printk("corr_hcs : %d\n", atomic_read(&stats->corr_hcs));
23063 - printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs));
23064 - printk("tx_cells : %d\n", atomic_read(&stats->tx_cells));
23065 - printk("rx_cells : %d\n", atomic_read(&stats->rx_cells));
23066 + printk("section_bip: %d\n", atomic_read_unchecked(&stats->section_bip));
23067 + printk("line_bip : %d\n", atomic_read_unchecked(&stats->line_bip));
23068 + printk("path_bip : %d\n", atomic_read_unchecked(&stats->path_bip));
23069 + printk("line_febe : %d\n", atomic_read_unchecked(&stats->line_febe));
23070 + printk("path_febe : %d\n", atomic_read_unchecked(&stats->path_febe));
23071 + printk("corr_hcs : %d\n", atomic_read_unchecked(&stats->corr_hcs));
23072 + printk("uncorr_hcs : %d\n", atomic_read_unchecked(&stats->uncorr_hcs));
23073 + printk("tx_cells : %d\n", atomic_read_unchecked(&stats->tx_cells));
23074 + printk("rx_cells : %d\n", atomic_read_unchecked(&stats->rx_cells));
23075 }
23076 ia_cmds.status = 0;
23077 break;
23078 @@ -2920,7 +2920,7 @@ static int ia_pkt_tx (struct atm_vcc *vc
23079 if ((desc == 0) || (desc > iadev->num_tx_desc))
23080 {
23081 IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);)
23082 - atomic_inc(&vcc->stats->tx);
23083 + atomic_inc_unchecked(&vcc->stats->tx);
23084 if (vcc->pop)
23085 vcc->pop(vcc, skb);
23086 else
23087 @@ -3025,14 +3025,14 @@ static int ia_pkt_tx (struct atm_vcc *vc
23088 ATM_DESC(skb) = vcc->vci;
23089 skb_queue_tail(&iadev->tx_dma_q, skb);
23090
23091 - atomic_inc(&vcc->stats->tx);
23092 + atomic_inc_unchecked(&vcc->stats->tx);
23093 iadev->tx_pkt_cnt++;
23094 /* Increment transaction counter */
23095 writel(2, iadev->dma+IPHASE5575_TX_COUNTER);
23096
23097 #if 0
23098 /* add flow control logic */
23099 - if (atomic_read(&vcc->stats->tx) % 20 == 0) {
23100 + if (atomic_read_unchecked(&vcc->stats->tx) % 20 == 0) {
23101 if (iavcc->vc_desc_cnt > 10) {
23102 vcc->tx_quota = vcc->tx_quota * 3 / 4;
23103 printk("Tx1: vcc->tx_quota = %d \n", (u32)vcc->tx_quota );
23104 diff -urNp linux-2.6.36/drivers/atm/lanai.c linux-2.6.36/drivers/atm/lanai.c
23105 --- linux-2.6.36/drivers/atm/lanai.c 2010-10-20 16:30:22.000000000 -0400
23106 +++ linux-2.6.36/drivers/atm/lanai.c 2010-11-06 18:58:15.000000000 -0400
23107 @@ -1303,7 +1303,7 @@ static void lanai_send_one_aal5(struct l
23108 vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
23109 lanai_endtx(lanai, lvcc);
23110 lanai_free_skb(lvcc->tx.atmvcc, skb);
23111 - atomic_inc(&lvcc->tx.atmvcc->stats->tx);
23112 + atomic_inc_unchecked(&lvcc->tx.atmvcc->stats->tx);
23113 }
23114
23115 /* Try to fill the buffer - don't call unless there is backlog */
23116 @@ -1426,7 +1426,7 @@ static void vcc_rx_aal5(struct lanai_vcc
23117 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
23118 __net_timestamp(skb);
23119 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
23120 - atomic_inc(&lvcc->rx.atmvcc->stats->rx);
23121 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx);
23122 out:
23123 lvcc->rx.buf.ptr = end;
23124 cardvcc_write(lvcc, endptr, vcc_rxreadptr);
23125 @@ -1668,7 +1668,7 @@ static int handle_service(struct lanai_d
23126 DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
23127 "vcc %d\n", lanai->number, (unsigned int) s, vci);
23128 lanai->stats.service_rxnotaal5++;
23129 - atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
23130 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
23131 return 0;
23132 }
23133 if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {
23134 @@ -1680,7 +1680,7 @@ static int handle_service(struct lanai_d
23135 int bytes;
23136 read_unlock(&vcc_sklist_lock);
23137 DPRINTK("got trashed rx pdu on vci %d\n", vci);
23138 - atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
23139 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
23140 lvcc->stats.x.aal5.service_trash++;
23141 bytes = (SERVICE_GET_END(s) * 16) -
23142 (((unsigned long) lvcc->rx.buf.ptr) -
23143 @@ -1692,7 +1692,7 @@ static int handle_service(struct lanai_d
23144 }
23145 if (s & SERVICE_STREAM) {
23146 read_unlock(&vcc_sklist_lock);
23147 - atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
23148 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
23149 lvcc->stats.x.aal5.service_stream++;
23150 printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
23151 "PDU on VCI %d!\n", lanai->number, vci);
23152 @@ -1700,7 +1700,7 @@ static int handle_service(struct lanai_d
23153 return 0;
23154 }
23155 DPRINTK("got rx crc error on vci %d\n", vci);
23156 - atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
23157 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
23158 lvcc->stats.x.aal5.service_rxcrc++;
23159 lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
23160 cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
23161 diff -urNp linux-2.6.36/drivers/atm/nicstar.c linux-2.6.36/drivers/atm/nicstar.c
23162 --- linux-2.6.36/drivers/atm/nicstar.c 2010-10-20 16:30:22.000000000 -0400
23163 +++ linux-2.6.36/drivers/atm/nicstar.c 2010-11-06 18:58:15.000000000 -0400
23164 @@ -1653,7 +1653,7 @@ static int ns_send(struct atm_vcc *vcc,
23165 if ((vc = (vc_map *) vcc->dev_data) == NULL) {
23166 printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n",
23167 card->index);
23168 - atomic_inc(&vcc->stats->tx_err);
23169 + atomic_inc_unchecked(&vcc->stats->tx_err);
23170 dev_kfree_skb_any(skb);
23171 return -EINVAL;
23172 }
23173 @@ -1661,7 +1661,7 @@ static int ns_send(struct atm_vcc *vcc,
23174 if (!vc->tx) {
23175 printk("nicstar%d: Trying to transmit on a non-tx VC.\n",
23176 card->index);
23177 - atomic_inc(&vcc->stats->tx_err);
23178 + atomic_inc_unchecked(&vcc->stats->tx_err);
23179 dev_kfree_skb_any(skb);
23180 return -EINVAL;
23181 }
23182 @@ -1669,14 +1669,14 @@ static int ns_send(struct atm_vcc *vcc,
23183 if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {
23184 printk("nicstar%d: Only AAL0 and AAL5 are supported.\n",
23185 card->index);
23186 - atomic_inc(&vcc->stats->tx_err);
23187 + atomic_inc_unchecked(&vcc->stats->tx_err);
23188 dev_kfree_skb_any(skb);
23189 return -EINVAL;
23190 }
23191
23192 if (skb_shinfo(skb)->nr_frags != 0) {
23193 printk("nicstar%d: No scatter-gather yet.\n", card->index);
23194 - atomic_inc(&vcc->stats->tx_err);
23195 + atomic_inc_unchecked(&vcc->stats->tx_err);
23196 dev_kfree_skb_any(skb);
23197 return -EINVAL;
23198 }
23199 @@ -1724,11 +1724,11 @@ static int ns_send(struct atm_vcc *vcc,
23200 }
23201
23202 if (push_scqe(card, vc, scq, &scqe, skb) != 0) {
23203 - atomic_inc(&vcc->stats->tx_err);
23204 + atomic_inc_unchecked(&vcc->stats->tx_err);
23205 dev_kfree_skb_any(skb);
23206 return -EIO;
23207 }
23208 - atomic_inc(&vcc->stats->tx);
23209 + atomic_inc_unchecked(&vcc->stats->tx);
23210
23211 return 0;
23212 }
23213 @@ -2045,14 +2045,14 @@ static void dequeue_rx(ns_dev * card, ns
23214 printk
23215 ("nicstar%d: Can't allocate buffers for aal0.\n",
23216 card->index);
23217 - atomic_add(i, &vcc->stats->rx_drop);
23218 + atomic_add_unchecked(i, &vcc->stats->rx_drop);
23219 break;
23220 }
23221 if (!atm_charge(vcc, sb->truesize)) {
23222 RXPRINTK
23223 ("nicstar%d: atm_charge() dropped aal0 packets.\n",
23224 card->index);
23225 - atomic_add(i - 1, &vcc->stats->rx_drop); /* already increased by 1 */
23226 + atomic_add_unchecked(i - 1, &vcc->stats->rx_drop); /* already increased by 1 */
23227 dev_kfree_skb_any(sb);
23228 break;
23229 }
23230 @@ -2067,7 +2067,7 @@ static void dequeue_rx(ns_dev * card, ns
23231 ATM_SKB(sb)->vcc = vcc;
23232 __net_timestamp(sb);
23233 vcc->push(vcc, sb);
23234 - atomic_inc(&vcc->stats->rx);
23235 + atomic_inc_unchecked(&vcc->stats->rx);
23236 cell += ATM_CELL_PAYLOAD;
23237 }
23238
23239 @@ -2084,7 +2084,7 @@ static void dequeue_rx(ns_dev * card, ns
23240 if (iovb == NULL) {
23241 printk("nicstar%d: Out of iovec buffers.\n",
23242 card->index);
23243 - atomic_inc(&vcc->stats->rx_drop);
23244 + atomic_inc_unchecked(&vcc->stats->rx_drop);
23245 recycle_rx_buf(card, skb);
23246 return;
23247 }
23248 @@ -2108,7 +2108,7 @@ static void dequeue_rx(ns_dev * card, ns
23249 small or large buffer itself. */
23250 } else if (NS_PRV_IOVCNT(iovb) >= NS_MAX_IOVECS) {
23251 printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
23252 - atomic_inc(&vcc->stats->rx_err);
23253 + atomic_inc_unchecked(&vcc->stats->rx_err);
23254 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
23255 NS_MAX_IOVECS);
23256 NS_PRV_IOVCNT(iovb) = 0;
23257 @@ -2128,7 +2128,7 @@ static void dequeue_rx(ns_dev * card, ns
23258 ("nicstar%d: Expected a small buffer, and this is not one.\n",
23259 card->index);
23260 which_list(card, skb);
23261 - atomic_inc(&vcc->stats->rx_err);
23262 + atomic_inc_unchecked(&vcc->stats->rx_err);
23263 recycle_rx_buf(card, skb);
23264 vc->rx_iov = NULL;
23265 recycle_iov_buf(card, iovb);
23266 @@ -2141,7 +2141,7 @@ static void dequeue_rx(ns_dev * card, ns
23267 ("nicstar%d: Expected a large buffer, and this is not one.\n",
23268 card->index);
23269 which_list(card, skb);
23270 - atomic_inc(&vcc->stats->rx_err);
23271 + atomic_inc_unchecked(&vcc->stats->rx_err);
23272 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
23273 NS_PRV_IOVCNT(iovb));
23274 vc->rx_iov = NULL;
23275 @@ -2164,7 +2164,7 @@ static void dequeue_rx(ns_dev * card, ns
23276 printk(" - PDU size mismatch.\n");
23277 else
23278 printk(".\n");
23279 - atomic_inc(&vcc->stats->rx_err);
23280 + atomic_inc_unchecked(&vcc->stats->rx_err);
23281 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
23282 NS_PRV_IOVCNT(iovb));
23283 vc->rx_iov = NULL;
23284 @@ -2178,7 +2178,7 @@ static void dequeue_rx(ns_dev * card, ns
23285 /* skb points to a small buffer */
23286 if (!atm_charge(vcc, skb->truesize)) {
23287 push_rxbufs(card, skb);
23288 - atomic_inc(&vcc->stats->rx_drop);
23289 + atomic_inc_unchecked(&vcc->stats->rx_drop);
23290 } else {
23291 skb_put(skb, len);
23292 dequeue_sm_buf(card, skb);
23293 @@ -2188,7 +2188,7 @@ static void dequeue_rx(ns_dev * card, ns
23294 ATM_SKB(skb)->vcc = vcc;
23295 __net_timestamp(skb);
23296 vcc->push(vcc, skb);
23297 - atomic_inc(&vcc->stats->rx);
23298 + atomic_inc_unchecked(&vcc->stats->rx);
23299 }
23300 } else if (NS_PRV_IOVCNT(iovb) == 2) { /* One small plus one large buffer */
23301 struct sk_buff *sb;
23302 @@ -2199,7 +2199,7 @@ static void dequeue_rx(ns_dev * card, ns
23303 if (len <= NS_SMBUFSIZE) {
23304 if (!atm_charge(vcc, sb->truesize)) {
23305 push_rxbufs(card, sb);
23306 - atomic_inc(&vcc->stats->rx_drop);
23307 + atomic_inc_unchecked(&vcc->stats->rx_drop);
23308 } else {
23309 skb_put(sb, len);
23310 dequeue_sm_buf(card, sb);
23311 @@ -2209,7 +2209,7 @@ static void dequeue_rx(ns_dev * card, ns
23312 ATM_SKB(sb)->vcc = vcc;
23313 __net_timestamp(sb);
23314 vcc->push(vcc, sb);
23315 - atomic_inc(&vcc->stats->rx);
23316 + atomic_inc_unchecked(&vcc->stats->rx);
23317 }
23318
23319 push_rxbufs(card, skb);
23320 @@ -2218,7 +2218,7 @@ static void dequeue_rx(ns_dev * card, ns
23321
23322 if (!atm_charge(vcc, skb->truesize)) {
23323 push_rxbufs(card, skb);
23324 - atomic_inc(&vcc->stats->rx_drop);
23325 + atomic_inc_unchecked(&vcc->stats->rx_drop);
23326 } else {
23327 dequeue_lg_buf(card, skb);
23328 #ifdef NS_USE_DESTRUCTORS
23329 @@ -2231,7 +2231,7 @@ static void dequeue_rx(ns_dev * card, ns
23330 ATM_SKB(skb)->vcc = vcc;
23331 __net_timestamp(skb);
23332 vcc->push(vcc, skb);
23333 - atomic_inc(&vcc->stats->rx);
23334 + atomic_inc_unchecked(&vcc->stats->rx);
23335 }
23336
23337 push_rxbufs(card, sb);
23338 @@ -2252,7 +2252,7 @@ static void dequeue_rx(ns_dev * card, ns
23339 printk
23340 ("nicstar%d: Out of huge buffers.\n",
23341 card->index);
23342 - atomic_inc(&vcc->stats->rx_drop);
23343 + atomic_inc_unchecked(&vcc->stats->rx_drop);
23344 recycle_iovec_rx_bufs(card,
23345 (struct iovec *)
23346 iovb->data,
23347 @@ -2303,7 +2303,7 @@ static void dequeue_rx(ns_dev * card, ns
23348 card->hbpool.count++;
23349 } else
23350 dev_kfree_skb_any(hb);
23351 - atomic_inc(&vcc->stats->rx_drop);
23352 + atomic_inc_unchecked(&vcc->stats->rx_drop);
23353 } else {
23354 /* Copy the small buffer to the huge buffer */
23355 sb = (struct sk_buff *)iov->iov_base;
23356 @@ -2340,7 +2340,7 @@ static void dequeue_rx(ns_dev * card, ns
23357 #endif /* NS_USE_DESTRUCTORS */
23358 __net_timestamp(hb);
23359 vcc->push(vcc, hb);
23360 - atomic_inc(&vcc->stats->rx);
23361 + atomic_inc_unchecked(&vcc->stats->rx);
23362 }
23363 }
23364
23365 diff -urNp linux-2.6.36/drivers/atm/solos-pci.c linux-2.6.36/drivers/atm/solos-pci.c
23366 --- linux-2.6.36/drivers/atm/solos-pci.c 2010-10-20 16:30:22.000000000 -0400
23367 +++ linux-2.6.36/drivers/atm/solos-pci.c 2010-11-06 18:58:15.000000000 -0400
23368 @@ -717,7 +717,7 @@ void solos_bh(unsigned long card_arg)
23369 }
23370 atm_charge(vcc, skb->truesize);
23371 vcc->push(vcc, skb);
23372 - atomic_inc(&vcc->stats->rx);
23373 + atomic_inc_unchecked(&vcc->stats->rx);
23374 break;
23375
23376 case PKT_STATUS:
23377 @@ -1025,7 +1025,7 @@ static uint32_t fpga_tx(struct solos_car
23378 vcc = SKB_CB(oldskb)->vcc;
23379
23380 if (vcc) {
23381 - atomic_inc(&vcc->stats->tx);
23382 + atomic_inc_unchecked(&vcc->stats->tx);
23383 solos_pop(vcc, oldskb);
23384 } else
23385 dev_kfree_skb_irq(oldskb);
23386 diff -urNp linux-2.6.36/drivers/atm/suni.c linux-2.6.36/drivers/atm/suni.c
23387 --- linux-2.6.36/drivers/atm/suni.c 2010-10-20 16:30:22.000000000 -0400
23388 +++ linux-2.6.36/drivers/atm/suni.c 2010-11-06 18:58:15.000000000 -0400
23389 @@ -50,8 +50,8 @@ static DEFINE_SPINLOCK(sunis_lock);
23390
23391
23392 #define ADD_LIMITED(s,v) \
23393 - atomic_add((v),&stats->s); \
23394 - if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX);
23395 + atomic_add_unchecked((v),&stats->s); \
23396 + if (atomic_read_unchecked(&stats->s) < 0) atomic_set_unchecked(&stats->s,INT_MAX);
23397
23398
23399 static void suni_hz(unsigned long from_timer)
23400 diff -urNp linux-2.6.36/drivers/atm/uPD98402.c linux-2.6.36/drivers/atm/uPD98402.c
23401 --- linux-2.6.36/drivers/atm/uPD98402.c 2010-10-20 16:30:22.000000000 -0400
23402 +++ linux-2.6.36/drivers/atm/uPD98402.c 2010-11-06 18:58:15.000000000 -0400
23403 @@ -42,7 +42,7 @@ static int fetch_stats(struct atm_dev *d
23404 struct sonet_stats tmp;
23405 int error = 0;
23406
23407 - atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
23408 + atomic_add_unchecked(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
23409 sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
23410 if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
23411 if (zero && !error) {
23412 @@ -161,9 +161,9 @@ static int uPD98402_ioctl(struct atm_dev
23413
23414
23415 #define ADD_LIMITED(s,v) \
23416 - { atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \
23417 - if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \
23418 - atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); }
23419 + { atomic_add_unchecked(GET(v),&PRIV(dev)->sonet_stats.s); \
23420 + if (atomic_read_unchecked(&PRIV(dev)->sonet_stats.s) < 0) \
23421 + atomic_set_unchecked(&PRIV(dev)->sonet_stats.s,INT_MAX); }
23422
23423
23424 static void stat_event(struct atm_dev *dev)
23425 @@ -194,7 +194,7 @@ static void uPD98402_int(struct atm_dev
23426 if (reason & uPD98402_INT_PFM) stat_event(dev);
23427 if (reason & uPD98402_INT_PCO) {
23428 (void) GET(PCOCR); /* clear interrupt cause */
23429 - atomic_add(GET(HECCT),
23430 + atomic_add_unchecked(GET(HECCT),
23431 &PRIV(dev)->sonet_stats.uncorr_hcs);
23432 }
23433 if ((reason & uPD98402_INT_RFO) &&
23434 @@ -222,9 +222,9 @@ static int uPD98402_start(struct atm_dev
23435 PUT(~(uPD98402_INT_PFM | uPD98402_INT_ALM | uPD98402_INT_RFO |
23436 uPD98402_INT_LOS),PIMR); /* enable them */
23437 (void) fetch_stats(dev,NULL,1); /* clear kernel counters */
23438 - atomic_set(&PRIV(dev)->sonet_stats.corr_hcs,-1);
23439 - atomic_set(&PRIV(dev)->sonet_stats.tx_cells,-1);
23440 - atomic_set(&PRIV(dev)->sonet_stats.rx_cells,-1);
23441 + atomic_set_unchecked(&PRIV(dev)->sonet_stats.corr_hcs,-1);
23442 + atomic_set_unchecked(&PRIV(dev)->sonet_stats.tx_cells,-1);
23443 + atomic_set_unchecked(&PRIV(dev)->sonet_stats.rx_cells,-1);
23444 return 0;
23445 }
23446
23447 diff -urNp linux-2.6.36/drivers/atm/zatm.c linux-2.6.36/drivers/atm/zatm.c
23448 --- linux-2.6.36/drivers/atm/zatm.c 2010-10-20 16:30:22.000000000 -0400
23449 +++ linux-2.6.36/drivers/atm/zatm.c 2010-11-06 18:58:15.000000000 -0400
23450 @@ -459,7 +459,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
23451 }
23452 if (!size) {
23453 dev_kfree_skb_irq(skb);
23454 - if (vcc) atomic_inc(&vcc->stats->rx_err);
23455 + if (vcc) atomic_inc_unchecked(&vcc->stats->rx_err);
23456 continue;
23457 }
23458 if (!atm_charge(vcc,skb->truesize)) {
23459 @@ -469,7 +469,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
23460 skb->len = size;
23461 ATM_SKB(skb)->vcc = vcc;
23462 vcc->push(vcc,skb);
23463 - atomic_inc(&vcc->stats->rx);
23464 + atomic_inc_unchecked(&vcc->stats->rx);
23465 }
23466 zout(pos & 0xffff,MTA(mbx));
23467 #if 0 /* probably a stupid idea */
23468 @@ -733,7 +733,7 @@ if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD
23469 skb_queue_head(&zatm_vcc->backlog,skb);
23470 break;
23471 }
23472 - atomic_inc(&vcc->stats->tx);
23473 + atomic_inc_unchecked(&vcc->stats->tx);
23474 wake_up(&zatm_vcc->tx_wait);
23475 }
23476
23477 diff -urNp linux-2.6.36/drivers/char/agp/frontend.c linux-2.6.36/drivers/char/agp/frontend.c
23478 --- linux-2.6.36/drivers/char/agp/frontend.c 2010-10-20 16:30:22.000000000 -0400
23479 +++ linux-2.6.36/drivers/char/agp/frontend.c 2010-11-06 18:58:15.000000000 -0400
23480 @@ -818,7 +818,7 @@ static int agpioc_reserve_wrap(struct ag
23481 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
23482 return -EFAULT;
23483
23484 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
23485 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
23486 return -EFAULT;
23487
23488 client = agp_find_client_by_pid(reserve.pid);
23489 diff -urNp linux-2.6.36/drivers/char/agp/intel-agp.c linux-2.6.36/drivers/char/agp/intel-agp.c
23490 --- linux-2.6.36/drivers/char/agp/intel-agp.c 2010-10-20 16:30:22.000000000 -0400
23491 +++ linux-2.6.36/drivers/char/agp/intel-agp.c 2010-11-06 18:58:15.000000000 -0400
23492 @@ -1056,7 +1056,7 @@ static struct pci_device_id agp_intel_pc
23493 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
23494 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
23495 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
23496 - { }
23497 + { 0, 0, 0, 0, 0, 0, 0 }
23498 };
23499
23500 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
23501 diff -urNp linux-2.6.36/drivers/char/hpet.c linux-2.6.36/drivers/char/hpet.c
23502 --- linux-2.6.36/drivers/char/hpet.c 2010-10-20 16:30:22.000000000 -0400
23503 +++ linux-2.6.36/drivers/char/hpet.c 2010-11-06 18:58:50.000000000 -0400
23504 @@ -429,7 +429,7 @@ static int hpet_release(struct inode *in
23505 return 0;
23506 }
23507
23508 -static int hpet_ioctl_common(struct hpet_dev *, int, unsigned long, int);
23509 +static int hpet_ioctl_common(struct hpet_dev *, unsigned int, unsigned long, int);
23510
23511 static long hpet_ioctl(struct file *file, unsigned int cmd,
23512 unsigned long arg)
23513 @@ -553,7 +553,7 @@ static inline unsigned long hpet_time_di
23514 }
23515
23516 static int
23517 -hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
23518 +hpet_ioctl_common(struct hpet_dev *devp, unsigned int cmd, unsigned long arg, int kernel)
23519 {
23520 struct hpet_timer __iomem *timer;
23521 struct hpet __iomem *hpet;
23522 @@ -596,11 +596,11 @@ hpet_ioctl_common(struct hpet_dev *devp,
23523 {
23524 struct hpet_info info;
23525
23526 + memset(&info, 0, sizeof(info));
23527 +
23528 if (devp->hd_ireqfreq)
23529 info.hi_ireqfreq =
23530 hpet_time_div(hpetp, devp->hd_ireqfreq);
23531 - else
23532 - info.hi_ireqfreq = 0;
23533 info.hi_flags =
23534 readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK;
23535 info.hi_hpet = hpetp->hp_which;
23536 @@ -998,7 +998,7 @@ static struct acpi_driver hpet_acpi_driv
23537 },
23538 };
23539
23540 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
23541 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
23542
23543 static int __init hpet_init(void)
23544 {
23545 diff -urNp linux-2.6.36/drivers/char/hvc_console.h linux-2.6.36/drivers/char/hvc_console.h
23546 --- linux-2.6.36/drivers/char/hvc_console.h 2010-10-20 16:30:22.000000000 -0400
23547 +++ linux-2.6.36/drivers/char/hvc_console.h 2010-11-06 18:58:15.000000000 -0400
23548 @@ -82,6 +82,7 @@ extern int hvc_instantiate(uint32_t vter
23549 /* register a vterm for hvc tty operation (module_init or hotplug add) */
23550 extern struct hvc_struct * hvc_alloc(uint32_t vtermno, int data,
23551 const struct hv_ops *ops, int outbuf_size);
23552 +
23553 /* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
23554 extern int hvc_remove(struct hvc_struct *hp);
23555
23556 diff -urNp linux-2.6.36/drivers/char/hvcs.c linux-2.6.36/drivers/char/hvcs.c
23557 --- linux-2.6.36/drivers/char/hvcs.c 2010-10-20 16:30:22.000000000 -0400
23558 +++ linux-2.6.36/drivers/char/hvcs.c 2010-11-06 18:58:15.000000000 -0400
23559 @@ -270,7 +270,7 @@ struct hvcs_struct {
23560 unsigned int index;
23561
23562 struct tty_struct *tty;
23563 - int open_count;
23564 + atomic_t open_count;
23565
23566 /*
23567 * Used to tell the driver kernel_thread what operations need to take
23568 @@ -420,7 +420,7 @@ static ssize_t hvcs_vterm_state_store(st
23569
23570 spin_lock_irqsave(&hvcsd->lock, flags);
23571
23572 - if (hvcsd->open_count > 0) {
23573 + if (atomic_read(&hvcsd->open_count) > 0) {
23574 spin_unlock_irqrestore(&hvcsd->lock, flags);
23575 printk(KERN_INFO "HVCS: vterm state unchanged. "
23576 "The hvcs device node is still in use.\n");
23577 @@ -1136,7 +1136,7 @@ static int hvcs_open(struct tty_struct *
23578 if ((retval = hvcs_partner_connect(hvcsd)))
23579 goto error_release;
23580
23581 - hvcsd->open_count = 1;
23582 + atomic_set(&hvcsd->open_count, 1);
23583 hvcsd->tty = tty;
23584 tty->driver_data = hvcsd;
23585
23586 @@ -1170,7 +1170,7 @@ fast_open:
23587
23588 spin_lock_irqsave(&hvcsd->lock, flags);
23589 kref_get(&hvcsd->kref);
23590 - hvcsd->open_count++;
23591 + atomic_inc(&hvcsd->open_count);
23592 hvcsd->todo_mask |= HVCS_SCHED_READ;
23593 spin_unlock_irqrestore(&hvcsd->lock, flags);
23594
23595 @@ -1214,7 +1214,7 @@ static void hvcs_close(struct tty_struct
23596 hvcsd = tty->driver_data;
23597
23598 spin_lock_irqsave(&hvcsd->lock, flags);
23599 - if (--hvcsd->open_count == 0) {
23600 + if (atomic_dec_and_test(&hvcsd->open_count)) {
23601
23602 vio_disable_interrupts(hvcsd->vdev);
23603
23604 @@ -1240,10 +1240,10 @@ static void hvcs_close(struct tty_struct
23605 free_irq(irq, hvcsd);
23606 kref_put(&hvcsd->kref, destroy_hvcs_struct);
23607 return;
23608 - } else if (hvcsd->open_count < 0) {
23609 + } else if (atomic_read(&hvcsd->open_count) < 0) {
23610 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
23611 " is missmanaged.\n",
23612 - hvcsd->vdev->unit_address, hvcsd->open_count);
23613 + hvcsd->vdev->unit_address, atomic_read(&hvcsd->open_count));
23614 }
23615
23616 spin_unlock_irqrestore(&hvcsd->lock, flags);
23617 @@ -1259,7 +1259,7 @@ static void hvcs_hangup(struct tty_struc
23618
23619 spin_lock_irqsave(&hvcsd->lock, flags);
23620 /* Preserve this so that we know how many kref refs to put */
23621 - temp_open_count = hvcsd->open_count;
23622 + temp_open_count = atomic_read(&hvcsd->open_count);
23623
23624 /*
23625 * Don't kref put inside the spinlock because the destruction
23626 @@ -1274,7 +1274,7 @@ static void hvcs_hangup(struct tty_struc
23627 hvcsd->tty->driver_data = NULL;
23628 hvcsd->tty = NULL;
23629
23630 - hvcsd->open_count = 0;
23631 + atomic_set(&hvcsd->open_count, 0);
23632
23633 /* This will drop any buffered data on the floor which is OK in a hangup
23634 * scenario. */
23635 @@ -1345,7 +1345,7 @@ static int hvcs_write(struct tty_struct
23636 * the middle of a write operation? This is a crummy place to do this
23637 * but we want to keep it all in the spinlock.
23638 */
23639 - if (hvcsd->open_count <= 0) {
23640 + if (atomic_read(&hvcsd->open_count) <= 0) {
23641 spin_unlock_irqrestore(&hvcsd->lock, flags);
23642 return -ENODEV;
23643 }
23644 @@ -1419,7 +1419,7 @@ static int hvcs_write_room(struct tty_st
23645 {
23646 struct hvcs_struct *hvcsd = tty->driver_data;
23647
23648 - if (!hvcsd || hvcsd->open_count <= 0)
23649 + if (!hvcsd || atomic_read(&hvcsd->open_count) <= 0)
23650 return 0;
23651
23652 return HVCS_BUFF_LEN - hvcsd->chars_in_buffer;
23653 diff -urNp linux-2.6.36/drivers/char/ipmi/ipmi_msghandler.c linux-2.6.36/drivers/char/ipmi/ipmi_msghandler.c
23654 --- linux-2.6.36/drivers/char/ipmi/ipmi_msghandler.c 2010-10-20 16:30:22.000000000 -0400
23655 +++ linux-2.6.36/drivers/char/ipmi/ipmi_msghandler.c 2010-11-06 18:58:15.000000000 -0400
23656 @@ -414,7 +414,7 @@ struct ipmi_smi {
23657 struct proc_dir_entry *proc_dir;
23658 char proc_dir_name[10];
23659
23660 - atomic_t stats[IPMI_NUM_STATS];
23661 + atomic_unchecked_t stats[IPMI_NUM_STATS];
23662
23663 /*
23664 * run_to_completion duplicate of smb_info, smi_info
23665 @@ -447,9 +447,9 @@ static DEFINE_MUTEX(smi_watchers_mutex);
23666
23667
23668 #define ipmi_inc_stat(intf, stat) \
23669 - atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
23670 + atomic_inc_unchecked(&(intf)->stats[IPMI_STAT_ ## stat])
23671 #define ipmi_get_stat(intf, stat) \
23672 - ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
23673 + ((unsigned int) atomic_read_unchecked(&(intf)->stats[IPMI_STAT_ ## stat]))
23674
23675 static int is_lan_addr(struct ipmi_addr *addr)
23676 {
23677 @@ -2817,7 +2817,7 @@ int ipmi_register_smi(struct ipmi_smi_ha
23678 INIT_LIST_HEAD(&intf->cmd_rcvrs);
23679 init_waitqueue_head(&intf->waitq);
23680 for (i = 0; i < IPMI_NUM_STATS; i++)
23681 - atomic_set(&intf->stats[i], 0);
23682 + atomic_set_unchecked(&intf->stats[i], 0);
23683
23684 intf->proc_dir = NULL;
23685
23686 diff -urNp linux-2.6.36/drivers/char/ipmi/ipmi_si_intf.c linux-2.6.36/drivers/char/ipmi/ipmi_si_intf.c
23687 --- linux-2.6.36/drivers/char/ipmi/ipmi_si_intf.c 2010-10-20 16:30:22.000000000 -0400
23688 +++ linux-2.6.36/drivers/char/ipmi/ipmi_si_intf.c 2010-11-06 18:58:15.000000000 -0400
23689 @@ -286,7 +286,7 @@ struct smi_info {
23690 unsigned char slave_addr;
23691
23692 /* Counters and things for the proc filesystem. */
23693 - atomic_t stats[SI_NUM_STATS];
23694 + atomic_unchecked_t stats[SI_NUM_STATS];
23695
23696 struct task_struct *thread;
23697
23698 @@ -294,9 +294,9 @@ struct smi_info {
23699 };
23700
23701 #define smi_inc_stat(smi, stat) \
23702 - atomic_inc(&(smi)->stats[SI_STAT_ ## stat])
23703 + atomic_inc_unchecked(&(smi)->stats[SI_STAT_ ## stat])
23704 #define smi_get_stat(smi, stat) \
23705 - ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat]))
23706 + ((unsigned int) atomic_read_unchecked(&(smi)->stats[SI_STAT_ ## stat]))
23707
23708 #define SI_MAX_PARMS 4
23709
23710 @@ -3171,7 +3171,7 @@ static int try_smi_init(struct smi_info
23711 atomic_set(&new_smi->req_events, 0);
23712 new_smi->run_to_completion = 0;
23713 for (i = 0; i < SI_NUM_STATS; i++)
23714 - atomic_set(&new_smi->stats[i], 0);
23715 + atomic_set_unchecked(&new_smi->stats[i], 0);
23716
23717 new_smi->interrupt_disabled = 1;
23718 atomic_set(&new_smi->stop_operation, 0);
23719 diff -urNp linux-2.6.36/drivers/char/keyboard.c linux-2.6.36/drivers/char/keyboard.c
23720 --- linux-2.6.36/drivers/char/keyboard.c 2010-10-20 16:30:22.000000000 -0400
23721 +++ linux-2.6.36/drivers/char/keyboard.c 2010-11-06 18:58:50.000000000 -0400
23722 @@ -640,6 +640,16 @@ static void k_spec(struct vc_data *vc, u
23723 kbd->kbdmode == VC_MEDIUMRAW) &&
23724 value != KVAL(K_SAK))
23725 return; /* SAK is allowed even in raw mode */
23726 +
23727 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
23728 + {
23729 + void *func = fn_handler[value];
23730 + if (func == fn_show_state || func == fn_show_ptregs ||
23731 + func == fn_show_mem)
23732 + return;
23733 + }
23734 +#endif
23735 +
23736 fn_handler[value](vc);
23737 }
23738
23739 @@ -1396,7 +1406,7 @@ static const struct input_device_id kbd_
23740 .evbit = { BIT_MASK(EV_SND) },
23741 },
23742
23743 - { }, /* Terminating entry */
23744 + { 0 }, /* Terminating entry */
23745 };
23746
23747 MODULE_DEVICE_TABLE(input, kbd_ids);
23748 diff -urNp linux-2.6.36/drivers/char/mem.c linux-2.6.36/drivers/char/mem.c
23749 --- linux-2.6.36/drivers/char/mem.c 2010-10-20 16:30:22.000000000 -0400
23750 +++ linux-2.6.36/drivers/char/mem.c 2010-11-06 18:58:50.000000000 -0400
23751 @@ -18,6 +18,7 @@
23752 #include <linux/raw.h>
23753 #include <linux/tty.h>
23754 #include <linux/capability.h>
23755 +#include <linux/security.h>
23756 #include <linux/ptrace.h>
23757 #include <linux/device.h>
23758 #include <linux/highmem.h>
23759 @@ -34,6 +35,10 @@
23760 # include <linux/efi.h>
23761 #endif
23762
23763 +#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
23764 +extern struct file_operations grsec_fops;
23765 +#endif
23766 +
23767 static inline unsigned long size_inside_page(unsigned long start,
23768 unsigned long size)
23769 {
23770 @@ -120,6 +125,7 @@ static ssize_t read_mem(struct file *fil
23771
23772 while (count > 0) {
23773 unsigned long remaining;
23774 + char *temp;
23775
23776 sz = size_inside_page(p, count);
23777
23778 @@ -135,7 +141,23 @@ static ssize_t read_mem(struct file *fil
23779 if (!ptr)
23780 return -EFAULT;
23781
23782 - remaining = copy_to_user(buf, ptr, sz);
23783 +#ifdef CONFIG_PAX_USERCOPY
23784 + temp = kmalloc(sz, GFP_KERNEL);
23785 + if (!temp) {
23786 + unxlate_dev_mem_ptr(p, ptr);
23787 + return -ENOMEM;
23788 + }
23789 + memcpy(temp, ptr, sz);
23790 +#else
23791 + temp = ptr;
23792 +#endif
23793 +
23794 + remaining = copy_to_user(buf, temp, sz);
23795 +
23796 +#ifdef CONFIG_PAX_USERCOPY
23797 + kfree(temp);
23798 +#endif
23799 +
23800 unxlate_dev_mem_ptr(p, ptr);
23801 if (remaining)
23802 return -EFAULT;
23803 @@ -161,6 +183,11 @@ static ssize_t write_mem(struct file *fi
23804 if (!valid_phys_addr_range(p, count))
23805 return -EFAULT;
23806
23807 +#ifdef CONFIG_GRKERNSEC_KMEM
23808 + gr_handle_mem_write();
23809 + return -EPERM;
23810 +#endif
23811 +
23812 written = 0;
23813
23814 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
23815 @@ -316,6 +343,11 @@ static int mmap_mem(struct file *file, s
23816 &vma->vm_page_prot))
23817 return -EINVAL;
23818
23819 +#ifdef CONFIG_GRKERNSEC_KMEM
23820 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
23821 + return -EPERM;
23822 +#endif
23823 +
23824 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
23825 size,
23826 vma->vm_page_prot);
23827 @@ -398,9 +430,8 @@ static ssize_t read_kmem(struct file *fi
23828 size_t count, loff_t *ppos)
23829 {
23830 unsigned long p = *ppos;
23831 - ssize_t low_count, read, sz;
23832 + ssize_t low_count, read, sz, err = 0;
23833 char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
23834 - int err = 0;
23835
23836 read = 0;
23837 if (p < (unsigned long) high_memory) {
23838 @@ -422,6 +453,8 @@ static ssize_t read_kmem(struct file *fi
23839 }
23840 #endif
23841 while (low_count > 0) {
23842 + char *temp;
23843 +
23844 sz = size_inside_page(p, low_count);
23845
23846 /*
23847 @@ -431,7 +464,22 @@ static ssize_t read_kmem(struct file *fi
23848 */
23849 kbuf = xlate_dev_kmem_ptr((char *)p);
23850
23851 - if (copy_to_user(buf, kbuf, sz))
23852 +#ifdef CONFIG_PAX_USERCOPY
23853 + temp = kmalloc(sz, GFP_KERNEL);
23854 + if (!temp)
23855 + return -ENOMEM;
23856 + memcpy(temp, kbuf, sz);
23857 +#else
23858 + temp = kbuf;
23859 +#endif
23860 +
23861 + err = copy_to_user(buf, temp, sz);
23862 +
23863 +#ifdef CONFIG_PAX_USERCOPY
23864 + kfree(temp);
23865 +#endif
23866 +
23867 + if (err)
23868 return -EFAULT;
23869 buf += sz;
23870 p += sz;
23871 @@ -530,6 +578,11 @@ static ssize_t write_kmem(struct file *f
23872 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
23873 int err = 0;
23874
23875 +#ifdef CONFIG_GRKERNSEC_KMEM
23876 + gr_handle_kmem_write();
23877 + return -EPERM;
23878 +#endif
23879 +
23880 if (p < (unsigned long) high_memory) {
23881 unsigned long to_write = min_t(unsigned long, count,
23882 (unsigned long)high_memory - p);
23883 @@ -731,6 +784,16 @@ static loff_t memory_lseek(struct file *
23884
23885 static int open_port(struct inode * inode, struct file * filp)
23886 {
23887 +#ifdef CONFIG_GRKERNSEC_KMEM
23888 + gr_handle_open_port();
23889 + return -EPERM;
23890 +#endif
23891 +
23892 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
23893 +}
23894 +
23895 +static int open_mem(struct inode * inode, struct file * filp)
23896 +{
23897 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
23898 }
23899
23900 @@ -738,7 +801,6 @@ static int open_port(struct inode * inod
23901 #define full_lseek null_lseek
23902 #define write_zero write_null
23903 #define read_full read_zero
23904 -#define open_mem open_port
23905 #define open_kmem open_mem
23906 #define open_oldmem open_mem
23907
23908 @@ -855,6 +917,9 @@ static const struct memdev {
23909 #ifdef CONFIG_CRASH_DUMP
23910 [12] = { "oldmem", 0, &oldmem_fops, NULL },
23911 #endif
23912 +#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
23913 + [13] = { "grsec",S_IRUSR | S_IWUGO, &grsec_fops, NULL },
23914 +#endif
23915 };
23916
23917 static int memory_open(struct inode *inode, struct file *filp)
23918 diff -urNp linux-2.6.36/drivers/char/n_gsm.c linux-2.6.36/drivers/char/n_gsm.c
23919 --- linux-2.6.36/drivers/char/n_gsm.c 2010-10-20 16:30:22.000000000 -0400
23920 +++ linux-2.6.36/drivers/char/n_gsm.c 2010-11-06 18:58:15.000000000 -0400
23921 @@ -1577,7 +1577,7 @@ static struct gsm_dlci *gsm_dlci_alloc(s
23922 return NULL;
23923 spin_lock_init(&dlci->lock);
23924 dlci->fifo = &dlci->_fifo;
23925 - if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) {
23926 + if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL)) {
23927 kfree(dlci);
23928 return NULL;
23929 }
23930 diff -urNp linux-2.6.36/drivers/char/n_tty.c linux-2.6.36/drivers/char/n_tty.c
23931 --- linux-2.6.36/drivers/char/n_tty.c 2010-10-20 16:30:22.000000000 -0400
23932 +++ linux-2.6.36/drivers/char/n_tty.c 2010-11-06 18:58:15.000000000 -0400
23933 @@ -2116,6 +2116,7 @@ void n_tty_inherit_ops(struct tty_ldisc_
23934 {
23935 *ops = tty_ldisc_N_TTY;
23936 ops->owner = NULL;
23937 - ops->refcount = ops->flags = 0;
23938 + atomic_set(&ops->refcount, 0);
23939 + ops->flags = 0;
23940 }
23941 EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
23942 diff -urNp linux-2.6.36/drivers/char/nvram.c linux-2.6.36/drivers/char/nvram.c
23943 --- linux-2.6.36/drivers/char/nvram.c 2010-10-20 16:30:22.000000000 -0400
23944 +++ linux-2.6.36/drivers/char/nvram.c 2010-11-06 18:58:15.000000000 -0400
23945 @@ -245,7 +245,7 @@ static ssize_t nvram_read(struct file *f
23946
23947 spin_unlock_irq(&rtc_lock);
23948
23949 - if (copy_to_user(buf, contents, tmp - contents))
23950 + if (tmp - contents > sizeof(contents) || copy_to_user(buf, contents, tmp - contents))
23951 return -EFAULT;
23952
23953 *ppos = i;
23954 @@ -434,7 +434,10 @@ static const struct file_operations nvra
23955 static struct miscdevice nvram_dev = {
23956 NVRAM_MINOR,
23957 "nvram",
23958 - &nvram_fops
23959 + &nvram_fops,
23960 + {NULL, NULL},
23961 + NULL,
23962 + NULL
23963 };
23964
23965 static int __init nvram_init(void)
23966 diff -urNp linux-2.6.36/drivers/char/pcmcia/ipwireless/tty.c linux-2.6.36/drivers/char/pcmcia/ipwireless/tty.c
23967 --- linux-2.6.36/drivers/char/pcmcia/ipwireless/tty.c 2010-10-20 16:30:22.000000000 -0400
23968 +++ linux-2.6.36/drivers/char/pcmcia/ipwireless/tty.c 2010-11-06 18:58:15.000000000 -0400
23969 @@ -51,7 +51,7 @@ struct ipw_tty {
23970 int tty_type;
23971 struct ipw_network *network;
23972 struct tty_struct *linux_tty;
23973 - int open_count;
23974 + atomic_t open_count;
23975 unsigned int control_lines;
23976 struct mutex ipw_tty_mutex;
23977 int tx_bytes_queued;
23978 @@ -127,10 +127,10 @@ static int ipw_open(struct tty_struct *l
23979 mutex_unlock(&tty->ipw_tty_mutex);
23980 return -ENODEV;
23981 }
23982 - if (tty->open_count == 0)
23983 + if (atomic_read(&tty->open_count) == 0)
23984 tty->tx_bytes_queued = 0;
23985
23986 - tty->open_count++;
23987 + atomic_inc(&tty->open_count);
23988
23989 tty->linux_tty = linux_tty;
23990 linux_tty->driver_data = tty;
23991 @@ -146,9 +146,7 @@ static int ipw_open(struct tty_struct *l
23992
23993 static void do_ipw_close(struct ipw_tty *tty)
23994 {
23995 - tty->open_count--;
23996 -
23997 - if (tty->open_count == 0) {
23998 + if (atomic_dec_return(&tty->open_count) == 0) {
23999 struct tty_struct *linux_tty = tty->linux_tty;
24000
24001 if (linux_tty != NULL) {
24002 @@ -169,7 +167,7 @@ static void ipw_hangup(struct tty_struct
24003 return;
24004
24005 mutex_lock(&tty->ipw_tty_mutex);
24006 - if (tty->open_count == 0) {
24007 + if (atomic_read(&tty->open_count) == 0) {
24008 mutex_unlock(&tty->ipw_tty_mutex);
24009 return;
24010 }
24011 @@ -198,7 +196,7 @@ void ipwireless_tty_received(struct ipw_
24012 return;
24013 }
24014
24015 - if (!tty->open_count) {
24016 + if (!atomic_read(&tty->open_count)) {
24017 mutex_unlock(&tty->ipw_tty_mutex);
24018 return;
24019 }
24020 @@ -240,7 +238,7 @@ static int ipw_write(struct tty_struct *
24021 return -ENODEV;
24022
24023 mutex_lock(&tty->ipw_tty_mutex);
24024 - if (!tty->open_count) {
24025 + if (!atomic_read(&tty->open_count)) {
24026 mutex_unlock(&tty->ipw_tty_mutex);
24027 return -EINVAL;
24028 }
24029 @@ -280,7 +278,7 @@ static int ipw_write_room(struct tty_str
24030 if (!tty)
24031 return -ENODEV;
24032
24033 - if (!tty->open_count)
24034 + if (!atomic_read(&tty->open_count))
24035 return -EINVAL;
24036
24037 room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
24038 @@ -322,7 +320,7 @@ static int ipw_chars_in_buffer(struct tt
24039 if (!tty)
24040 return 0;
24041
24042 - if (!tty->open_count)
24043 + if (!atomic_read(&tty->open_count))
24044 return 0;
24045
24046 return tty->tx_bytes_queued;
24047 @@ -403,7 +401,7 @@ static int ipw_tiocmget(struct tty_struc
24048 if (!tty)
24049 return -ENODEV;
24050
24051 - if (!tty->open_count)
24052 + if (!atomic_read(&tty->open_count))
24053 return -EINVAL;
24054
24055 return get_control_lines(tty);
24056 @@ -419,7 +417,7 @@ ipw_tiocmset(struct tty_struct *linux_tt
24057 if (!tty)
24058 return -ENODEV;
24059
24060 - if (!tty->open_count)
24061 + if (!atomic_read(&tty->open_count))
24062 return -EINVAL;
24063
24064 return set_control_lines(tty, set, clear);
24065 @@ -433,7 +431,7 @@ static int ipw_ioctl(struct tty_struct *
24066 if (!tty)
24067 return -ENODEV;
24068
24069 - if (!tty->open_count)
24070 + if (!atomic_read(&tty->open_count))
24071 return -EINVAL;
24072
24073 /* FIXME: Exactly how is the tty object locked here .. */
24074 @@ -582,7 +580,7 @@ void ipwireless_tty_free(struct ipw_tty
24075 against a parallel ioctl etc */
24076 mutex_lock(&ttyj->ipw_tty_mutex);
24077 }
24078 - while (ttyj->open_count)
24079 + while (atomic_read(&ttyj->open_count))
24080 do_ipw_close(ttyj);
24081 ipwireless_disassociate_network_ttys(network,
24082 ttyj->channel_idx);
24083 diff -urNp linux-2.6.36/drivers/char/pty.c linux-2.6.36/drivers/char/pty.c
24084 --- linux-2.6.36/drivers/char/pty.c 2010-10-20 16:30:22.000000000 -0400
24085 +++ linux-2.6.36/drivers/char/pty.c 2010-11-06 18:58:15.000000000 -0400
24086 @@ -698,7 +698,18 @@ out:
24087 return retval;
24088 }
24089
24090 -static struct file_operations ptmx_fops;
24091 +static const struct file_operations ptmx_fops = {
24092 + .llseek = no_llseek,
24093 + .read = tty_read,
24094 + .write = tty_write,
24095 + .poll = tty_poll,
24096 + .unlocked_ioctl = tty_ioctl,
24097 + .compat_ioctl = tty_compat_ioctl,
24098 + .open = ptmx_open,
24099 + .release = tty_release,
24100 + .fasync = tty_fasync,
24101 +};
24102 +
24103
24104 static void __init unix98_pty_init(void)
24105 {
24106 @@ -752,9 +763,6 @@ static void __init unix98_pty_init(void)
24107 register_sysctl_table(pty_root_table);
24108
24109 /* Now create the /dev/ptmx special device */
24110 - tty_default_fops(&ptmx_fops);
24111 - ptmx_fops.open = ptmx_open;
24112 -
24113 cdev_init(&ptmx_cdev, &ptmx_fops);
24114 if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
24115 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
24116 diff -urNp linux-2.6.36/drivers/char/random.c linux-2.6.36/drivers/char/random.c
24117 --- linux-2.6.36/drivers/char/random.c 2010-10-20 16:30:22.000000000 -0400
24118 +++ linux-2.6.36/drivers/char/random.c 2010-11-06 18:58:50.000000000 -0400
24119 @@ -254,8 +254,13 @@
24120 /*
24121 * Configuration information
24122 */
24123 +#ifdef CONFIG_GRKERNSEC_RANDNET
24124 +#define INPUT_POOL_WORDS 512
24125 +#define OUTPUT_POOL_WORDS 128
24126 +#else
24127 #define INPUT_POOL_WORDS 128
24128 #define OUTPUT_POOL_WORDS 32
24129 +#endif
24130 #define SEC_XFER_SIZE 512
24131 #define EXTRACT_SIZE 10
24132
24133 @@ -293,10 +298,17 @@ static struct poolinfo {
24134 int poolwords;
24135 int tap1, tap2, tap3, tap4, tap5;
24136 } poolinfo_table[] = {
24137 +#ifdef CONFIG_GRKERNSEC_RANDNET
24138 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
24139 + { 512, 411, 308, 208, 104, 1 },
24140 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
24141 + { 128, 103, 76, 51, 25, 1 },
24142 +#else
24143 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
24144 { 128, 103, 76, 51, 25, 1 },
24145 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
24146 { 32, 26, 20, 14, 7, 1 },
24147 +#endif
24148 #if 0
24149 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
24150 { 2048, 1638, 1231, 819, 411, 1 },
24151 @@ -902,7 +914,7 @@ static ssize_t extract_entropy_user(stru
24152
24153 extract_buf(r, tmp);
24154 i = min_t(int, nbytes, EXTRACT_SIZE);
24155 - if (copy_to_user(buf, tmp, i)) {
24156 + if (i > sizeof(tmp) || copy_to_user(buf, tmp, i)) {
24157 ret = -EFAULT;
24158 break;
24159 }
24160 @@ -1205,7 +1217,7 @@ EXPORT_SYMBOL(generate_random_uuid);
24161 #include <linux/sysctl.h>
24162
24163 static int min_read_thresh = 8, min_write_thresh;
24164 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
24165 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
24166 static int max_write_thresh = INPUT_POOL_WORDS * 32;
24167 static char sysctl_bootid[16];
24168
24169 diff -urNp linux-2.6.36/drivers/char/sonypi.c linux-2.6.36/drivers/char/sonypi.c
24170 --- linux-2.6.36/drivers/char/sonypi.c 2010-10-20 16:30:22.000000000 -0400
24171 +++ linux-2.6.36/drivers/char/sonypi.c 2010-11-06 18:58:15.000000000 -0400
24172 @@ -491,7 +491,7 @@ static struct sonypi_device {
24173 spinlock_t fifo_lock;
24174 wait_queue_head_t fifo_proc_list;
24175 struct fasync_struct *fifo_async;
24176 - int open_count;
24177 + atomic_t open_count;
24178 int model;
24179 struct input_dev *input_jog_dev;
24180 struct input_dev *input_key_dev;
24181 @@ -898,7 +898,7 @@ static int sonypi_misc_fasync(int fd, st
24182 static int sonypi_misc_release(struct inode *inode, struct file *file)
24183 {
24184 mutex_lock(&sonypi_device.lock);
24185 - sonypi_device.open_count--;
24186 + atomic_dec(&sonypi_device.open_count);
24187 mutex_unlock(&sonypi_device.lock);
24188 return 0;
24189 }
24190 @@ -907,9 +907,9 @@ static int sonypi_misc_open(struct inode
24191 {
24192 mutex_lock(&sonypi_device.lock);
24193 /* Flush input queue on first open */
24194 - if (!sonypi_device.open_count)
24195 + if (!atomic_read(&sonypi_device.open_count))
24196 kfifo_reset(&sonypi_device.fifo);
24197 - sonypi_device.open_count++;
24198 + atomic_inc(&sonypi_device.open_count);
24199 mutex_unlock(&sonypi_device.lock);
24200
24201 return 0;
24202 diff -urNp linux-2.6.36/drivers/char/tpm/tpm_bios.c linux-2.6.36/drivers/char/tpm/tpm_bios.c
24203 --- linux-2.6.36/drivers/char/tpm/tpm_bios.c 2010-10-20 16:30:22.000000000 -0400
24204 +++ linux-2.6.36/drivers/char/tpm/tpm_bios.c 2010-11-06 18:58:15.000000000 -0400
24205 @@ -173,7 +173,7 @@ static void *tpm_bios_measurements_start
24206 event = addr;
24207
24208 if ((event->event_type == 0 && event->event_size == 0) ||
24209 - ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
24210 + (event->event_size >= limit - addr - sizeof(struct tcpa_event)))
24211 return NULL;
24212
24213 return addr;
24214 @@ -198,7 +198,7 @@ static void *tpm_bios_measurements_next(
24215 return NULL;
24216
24217 if ((event->event_type == 0 && event->event_size == 0) ||
24218 - ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
24219 + (event->event_size >= limit - v - sizeof(struct tcpa_event)))
24220 return NULL;
24221
24222 (*pos)++;
24223 @@ -291,7 +291,8 @@ static int tpm_binary_bios_measurements_
24224 int i;
24225
24226 for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
24227 - seq_putc(m, data[i]);
24228 + if (!seq_putc(m, data[i]))
24229 + return -EFAULT;
24230
24231 return 0;
24232 }
24233 @@ -410,6 +411,11 @@ static int read_log(struct tpm_bios_log
24234 log->bios_event_log_end = log->bios_event_log + len;
24235
24236 virt = acpi_os_map_memory(start, len);
24237 + if (!virt) {
24238 + kfree(log->bios_event_log);
24239 + log->bios_event_log = NULL;
24240 + return -EFAULT;
24241 + }
24242
24243 memcpy(log->bios_event_log, virt, len);
24244
24245 diff -urNp linux-2.6.36/drivers/char/tty_io.c linux-2.6.36/drivers/char/tty_io.c
24246 --- linux-2.6.36/drivers/char/tty_io.c 2010-10-20 16:30:22.000000000 -0400
24247 +++ linux-2.6.36/drivers/char/tty_io.c 2010-11-06 18:58:15.000000000 -0400
24248 @@ -139,21 +139,11 @@ EXPORT_SYMBOL(tty_mutex);
24249 /* Spinlock to protect the tty->tty_files list */
24250 DEFINE_SPINLOCK(tty_files_lock);
24251
24252 -static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
24253 -static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
24254 ssize_t redirected_tty_write(struct file *, const char __user *,
24255 size_t, loff_t *);
24256 -static unsigned int tty_poll(struct file *, poll_table *);
24257 static int tty_open(struct inode *, struct file *);
24258 long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
24259 -#ifdef CONFIG_COMPAT
24260 -static long tty_compat_ioctl(struct file *file, unsigned int cmd,
24261 - unsigned long arg);
24262 -#else
24263 -#define tty_compat_ioctl NULL
24264 -#endif
24265 static int __tty_fasync(int fd, struct file *filp, int on);
24266 -static int tty_fasync(int fd, struct file *filp, int on);
24267 static void release_tty(struct tty_struct *tty, int idx);
24268 static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
24269 static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
24270 @@ -925,7 +915,7 @@ EXPORT_SYMBOL(start_tty);
24271 * read calls may be outstanding in parallel.
24272 */
24273
24274 -static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
24275 +ssize_t tty_read(struct file *file, char __user *buf, size_t count,
24276 loff_t *ppos)
24277 {
24278 int i;
24279 @@ -951,6 +941,8 @@ static ssize_t tty_read(struct file *fil
24280 return i;
24281 }
24282
24283 +EXPORT_SYMBOL(tty_read);
24284 +
24285 void tty_write_unlock(struct tty_struct *tty)
24286 {
24287 mutex_unlock(&tty->atomic_write_lock);
24288 @@ -1100,7 +1092,7 @@ void tty_write_message(struct tty_struct
24289 * write method will not be invoked in parallel for each device.
24290 */
24291
24292 -static ssize_t tty_write(struct file *file, const char __user *buf,
24293 +ssize_t tty_write(struct file *file, const char __user *buf,
24294 size_t count, loff_t *ppos)
24295 {
24296 struct inode *inode = file->f_path.dentry->d_inode;
24297 @@ -1126,6 +1118,8 @@ static ssize_t tty_write(struct file *fi
24298 return ret;
24299 }
24300
24301 +EXPORT_SYMBOL(tty_write);
24302 +
24303 ssize_t redirected_tty_write(struct file *file, const char __user *buf,
24304 size_t count, loff_t *ppos)
24305 {
24306 @@ -1938,6 +1932,8 @@ got_driver:
24307
24308
24309
24310 +EXPORT_SYMBOL(tty_release);
24311 +
24312 /**
24313 * tty_poll - check tty status
24314 * @filp: file being polled
24315 @@ -1950,7 +1946,7 @@ got_driver:
24316 * may be re-entered freely by other callers.
24317 */
24318
24319 -static unsigned int tty_poll(struct file *filp, poll_table *wait)
24320 +unsigned int tty_poll(struct file *filp, poll_table *wait)
24321 {
24322 struct tty_struct *tty = file_tty(filp);
24323 struct tty_ldisc *ld;
24324 @@ -2007,7 +2003,9 @@ out:
24325 return retval;
24326 }
24327
24328 -static int tty_fasync(int fd, struct file *filp, int on)
24329 +EXPORT_SYMBOL(tty_poll);
24330 +
24331 +int tty_fasync(int fd, struct file *filp, int on)
24332 {
24333 int retval;
24334 tty_lock();
24335 @@ -2016,6 +2014,8 @@ static int tty_fasync(int fd, struct fil
24336 return retval;
24337 }
24338
24339 +EXPORT_SYMBOL(tty_fasync);
24340 +
24341 /**
24342 * tiocsti - fake input character
24343 * @tty: tty to fake input into
24344 @@ -2648,8 +2648,10 @@ long tty_ioctl(struct file *file, unsign
24345 return retval;
24346 }
24347
24348 +EXPORT_SYMBOL(tty_ioctl);
24349 +
24350 #ifdef CONFIG_COMPAT
24351 -static long tty_compat_ioctl(struct file *file, unsigned int cmd,
24352 +long tty_compat_ioctl(struct file *file, unsigned int cmd,
24353 unsigned long arg)
24354 {
24355 struct inode *inode = file->f_dentry->d_inode;
24356 @@ -2673,6 +2675,9 @@ static long tty_compat_ioctl(struct file
24357
24358 return retval;
24359 }
24360 +
24361 +EXPORT_SYMBOL(tty_compat_ioctl);
24362 +
24363 #endif
24364
24365 /*
24366 @@ -3116,11 +3121,6 @@ struct tty_struct *get_current_tty(void)
24367 }
24368 EXPORT_SYMBOL_GPL(get_current_tty);
24369
24370 -void tty_default_fops(struct file_operations *fops)
24371 -{
24372 - *fops = tty_fops;
24373 -}
24374 -
24375 /*
24376 * Initialize the console device. This is called *early*, so
24377 * we can't necessarily depend on lots of kernel help here.
24378 diff -urNp linux-2.6.36/drivers/char/tty_ldisc.c linux-2.6.36/drivers/char/tty_ldisc.c
24379 --- linux-2.6.36/drivers/char/tty_ldisc.c 2010-10-20 16:30:22.000000000 -0400
24380 +++ linux-2.6.36/drivers/char/tty_ldisc.c 2010-11-06 18:58:15.000000000 -0400
24381 @@ -75,7 +75,7 @@ static void put_ldisc(struct tty_ldisc *
24382 if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) {
24383 struct tty_ldisc_ops *ldo = ld->ops;
24384
24385 - ldo->refcount--;
24386 + atomic_dec(&ldo->refcount);
24387 module_put(ldo->owner);
24388 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
24389
24390 @@ -109,7 +109,7 @@ int tty_register_ldisc(int disc, struct
24391 spin_lock_irqsave(&tty_ldisc_lock, flags);
24392 tty_ldiscs[disc] = new_ldisc;
24393 new_ldisc->num = disc;
24394 - new_ldisc->refcount = 0;
24395 + atomic_set(&new_ldisc->refcount, 0);
24396 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
24397
24398 return ret;
24399 @@ -137,7 +137,7 @@ int tty_unregister_ldisc(int disc)
24400 return -EINVAL;
24401
24402 spin_lock_irqsave(&tty_ldisc_lock, flags);
24403 - if (tty_ldiscs[disc]->refcount)
24404 + if (atomic_read(&tty_ldiscs[disc]->refcount))
24405 ret = -EBUSY;
24406 else
24407 tty_ldiscs[disc] = NULL;
24408 @@ -158,7 +158,7 @@ static struct tty_ldisc_ops *get_ldops(i
24409 if (ldops) {
24410 ret = ERR_PTR(-EAGAIN);
24411 if (try_module_get(ldops->owner)) {
24412 - ldops->refcount++;
24413 + atomic_inc(&ldops->refcount);
24414 ret = ldops;
24415 }
24416 }
24417 @@ -171,7 +171,7 @@ static void put_ldops(struct tty_ldisc_o
24418 unsigned long flags;
24419
24420 spin_lock_irqsave(&tty_ldisc_lock, flags);
24421 - ldops->refcount--;
24422 + atomic_dec(&ldops->refcount);
24423 module_put(ldops->owner);
24424 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
24425 }
24426 diff -urNp linux-2.6.36/drivers/char/vt_ioctl.c linux-2.6.36/drivers/char/vt_ioctl.c
24427 --- linux-2.6.36/drivers/char/vt_ioctl.c 2010-10-20 16:30:22.000000000 -0400
24428 +++ linux-2.6.36/drivers/char/vt_ioctl.c 2010-11-06 18:58:50.000000000 -0400
24429 @@ -210,9 +210,6 @@ do_kdsk_ioctl(int cmd, struct kbentry __
24430 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
24431 return -EFAULT;
24432
24433 - if (!capable(CAP_SYS_TTY_CONFIG))
24434 - perm = 0;
24435 -
24436 switch (cmd) {
24437 case KDGKBENT:
24438 key_map = key_maps[s];
24439 @@ -224,8 +221,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
24440 val = (i ? K_HOLE : K_NOSUCHMAP);
24441 return put_user(val, &user_kbe->kb_value);
24442 case KDSKBENT:
24443 + if (!capable(CAP_SYS_TTY_CONFIG))
24444 + perm = 0;
24445 +
24446 if (!perm)
24447 return -EPERM;
24448 +
24449 if (!i && v == K_NOSUCHMAP) {
24450 /* deallocate map */
24451 key_map = key_maps[s];
24452 @@ -325,9 +326,6 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
24453 int i, j, k;
24454 int ret;
24455
24456 - if (!capable(CAP_SYS_TTY_CONFIG))
24457 - perm = 0;
24458 -
24459 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
24460 if (!kbs) {
24461 ret = -ENOMEM;
24462 @@ -361,6 +359,9 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
24463 kfree(kbs);
24464 return ((p && *p) ? -EOVERFLOW : 0);
24465 case KDSKBSENT:
24466 + if (!capable(CAP_SYS_TTY_CONFIG))
24467 + perm = 0;
24468 +
24469 if (!perm) {
24470 ret = -EPERM;
24471 goto reterr;
24472 diff -urNp linux-2.6.36/drivers/cpuidle/sysfs.c linux-2.6.36/drivers/cpuidle/sysfs.c
24473 --- linux-2.6.36/drivers/cpuidle/sysfs.c 2010-10-20 16:30:22.000000000 -0400
24474 +++ linux-2.6.36/drivers/cpuidle/sysfs.c 2010-11-06 18:58:15.000000000 -0400
24475 @@ -300,7 +300,7 @@ static struct kobj_type ktype_state_cpui
24476 .release = cpuidle_state_sysfs_release,
24477 };
24478
24479 -static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
24480 +static inline void cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
24481 {
24482 kobject_put(&device->kobjs[i]->kobj);
24483 wait_for_completion(&device->kobjs[i]->kobj_unregister);
24484 diff -urNp linux-2.6.36/drivers/edac/edac_core.h linux-2.6.36/drivers/edac/edac_core.h
24485 --- linux-2.6.36/drivers/edac/edac_core.h 2010-10-20 16:30:22.000000000 -0400
24486 +++ linux-2.6.36/drivers/edac/edac_core.h 2010-11-06 18:58:15.000000000 -0400
24487 @@ -85,11 +85,11 @@ extern const char *edac_mem_types[];
24488
24489 #else /* !CONFIG_EDAC_DEBUG */
24490
24491 -#define debugf0( ... )
24492 -#define debugf1( ... )
24493 -#define debugf2( ... )
24494 -#define debugf3( ... )
24495 -#define debugf4( ... )
24496 +#define debugf0( ... ) do {} while (0)
24497 +#define debugf1( ... ) do {} while (0)
24498 +#define debugf2( ... ) do {} while (0)
24499 +#define debugf3( ... ) do {} while (0)
24500 +#define debugf4( ... ) do {} while (0)
24501
24502 #endif /* !CONFIG_EDAC_DEBUG */
24503
24504 diff -urNp linux-2.6.36/drivers/edac/edac_mc_sysfs.c linux-2.6.36/drivers/edac/edac_mc_sysfs.c
24505 --- linux-2.6.36/drivers/edac/edac_mc_sysfs.c 2010-10-20 16:30:22.000000000 -0400
24506 +++ linux-2.6.36/drivers/edac/edac_mc_sysfs.c 2010-11-06 18:58:15.000000000 -0400
24507 @@ -764,7 +764,7 @@ static void edac_inst_grp_release(struct
24508 }
24509
24510 /* Intermediate show/store table */
24511 -static struct sysfs_ops inst_grp_ops = {
24512 +static const struct sysfs_ops inst_grp_ops = {
24513 .show = inst_grp_show,
24514 .store = inst_grp_store
24515 };
24516 diff -urNp linux-2.6.36/drivers/firewire/core-cdev.c linux-2.6.36/drivers/firewire/core-cdev.c
24517 --- linux-2.6.36/drivers/firewire/core-cdev.c 2010-10-20 16:30:22.000000000 -0400
24518 +++ linux-2.6.36/drivers/firewire/core-cdev.c 2010-11-06 18:58:15.000000000 -0400
24519 @@ -1329,8 +1329,7 @@ static int init_iso_resource(struct clie
24520 int ret;
24521
24522 if ((request->channels == 0 && request->bandwidth == 0) ||
24523 - request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL ||
24524 - request->bandwidth < 0)
24525 + request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL)
24526 return -EINVAL;
24527
24528 r = kmalloc(sizeof(*r), GFP_KERNEL);
24529 diff -urNp linux-2.6.36/drivers/firmware/dmi_scan.c linux-2.6.36/drivers/firmware/dmi_scan.c
24530 --- linux-2.6.36/drivers/firmware/dmi_scan.c 2010-10-20 16:30:22.000000000 -0400
24531 +++ linux-2.6.36/drivers/firmware/dmi_scan.c 2010-11-06 18:58:15.000000000 -0400
24532 @@ -412,11 +412,6 @@ void __init dmi_scan_machine(void)
24533 }
24534 }
24535 else {
24536 - /*
24537 - * no iounmap() for that ioremap(); it would be a no-op, but
24538 - * it's so early in setup that sucker gets confused into doing
24539 - * what it shouldn't if we actually call it.
24540 - */
24541 p = dmi_ioremap(0xF0000, 0x10000);
24542 if (p == NULL)
24543 goto error;
24544 diff -urNp linux-2.6.36/drivers/gpu/drm/drm_crtc_helper.c linux-2.6.36/drivers/gpu/drm/drm_crtc_helper.c
24545 --- linux-2.6.36/drivers/gpu/drm/drm_crtc_helper.c 2010-10-20 16:30:22.000000000 -0400
24546 +++ linux-2.6.36/drivers/gpu/drm/drm_crtc_helper.c 2010-11-06 18:58:15.000000000 -0400
24547 @@ -276,7 +276,7 @@ static bool drm_encoder_crtc_ok(struct d
24548 struct drm_crtc *tmp;
24549 int crtc_mask = 1;
24550
24551 - WARN(!crtc, "checking null crtc?");
24552 + BUG_ON(!crtc);
24553
24554 dev = crtc->dev;
24555
24556 diff -urNp linux-2.6.36/drivers/gpu/drm/drm_drv.c linux-2.6.36/drivers/gpu/drm/drm_drv.c
24557 --- linux-2.6.36/drivers/gpu/drm/drm_drv.c 2010-10-20 16:30:22.000000000 -0400
24558 +++ linux-2.6.36/drivers/gpu/drm/drm_drv.c 2010-11-06 18:58:15.000000000 -0400
24559 @@ -428,7 +428,7 @@ long drm_ioctl(struct file *filp,
24560
24561 dev = file_priv->minor->dev;
24562 atomic_inc(&dev->ioctl_count);
24563 - atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
24564 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_IOCTLS]);
24565 ++file_priv->ioctl_count;
24566
24567 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
24568 diff -urNp linux-2.6.36/drivers/gpu/drm/drm_fops.c linux-2.6.36/drivers/gpu/drm/drm_fops.c
24569 --- linux-2.6.36/drivers/gpu/drm/drm_fops.c 2010-10-20 16:30:22.000000000 -0400
24570 +++ linux-2.6.36/drivers/gpu/drm/drm_fops.c 2010-11-06 18:58:15.000000000 -0400
24571 @@ -71,7 +71,7 @@ static int drm_setup(struct drm_device *
24572 }
24573
24574 for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
24575 - atomic_set(&dev->counts[i], 0);
24576 + atomic_set_unchecked(&dev->counts[i], 0);
24577
24578 dev->sigdata.lock = NULL;
24579
24580 @@ -135,8 +135,8 @@ int drm_open(struct inode *inode, struct
24581
24582 retcode = drm_open_helper(inode, filp, dev);
24583 if (!retcode) {
24584 - atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
24585 - if (!dev->open_count++)
24586 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]);
24587 + if (atomic_inc_return(&dev->open_count) == 1)
24588 retcode = drm_setup(dev);
24589 }
24590 if (!retcode) {
24591 @@ -471,7 +471,7 @@ int drm_release(struct inode *inode, str
24592
24593 mutex_lock(&drm_global_mutex);
24594
24595 - DRM_DEBUG("open_count = %d\n", dev->open_count);
24596 + DRM_DEBUG("open_count = %d\n", atomic_read(&dev->open_count));
24597
24598 if (dev->driver->preclose)
24599 dev->driver->preclose(dev, file_priv);
24600 @@ -483,7 +483,7 @@ int drm_release(struct inode *inode, str
24601 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
24602 task_pid_nr(current),
24603 (long)old_encode_dev(file_priv->minor->device),
24604 - dev->open_count);
24605 + atomic_read(&dev->open_count));
24606
24607 /* if the master has gone away we can't do anything with the lock */
24608 if (file_priv->minor->master)
24609 @@ -564,8 +564,8 @@ int drm_release(struct inode *inode, str
24610 * End inline drm_release
24611 */
24612
24613 - atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
24614 - if (!--dev->open_count) {
24615 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_CLOSES]);
24616 + if (atomic_dec_and_test(&dev->open_count)) {
24617 if (atomic_read(&dev->ioctl_count)) {
24618 DRM_ERROR("Device busy: %d\n",
24619 atomic_read(&dev->ioctl_count));
24620 diff -urNp linux-2.6.36/drivers/gpu/drm/drm_global.c linux-2.6.36/drivers/gpu/drm/drm_global.c
24621 --- linux-2.6.36/drivers/gpu/drm/drm_global.c 2010-10-20 16:30:22.000000000 -0400
24622 +++ linux-2.6.36/drivers/gpu/drm/drm_global.c 2010-11-06 18:58:15.000000000 -0400
24623 @@ -36,7 +36,7 @@
24624 struct drm_global_item {
24625 struct mutex mutex;
24626 void *object;
24627 - int refcount;
24628 + atomic_t refcount;
24629 };
24630
24631 static struct drm_global_item glob[DRM_GLOBAL_NUM];
24632 @@ -49,7 +49,7 @@ void drm_global_init(void)
24633 struct drm_global_item *item = &glob[i];
24634 mutex_init(&item->mutex);
24635 item->object = NULL;
24636 - item->refcount = 0;
24637 + atomic_set(&item->refcount, 0);
24638 }
24639 }
24640
24641 @@ -59,7 +59,7 @@ void drm_global_release(void)
24642 for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
24643 struct drm_global_item *item = &glob[i];
24644 BUG_ON(item->object != NULL);
24645 - BUG_ON(item->refcount != 0);
24646 + BUG_ON(atomic_read(&item->refcount) != 0);
24647 }
24648 }
24649
24650 @@ -70,7 +70,7 @@ int drm_global_item_ref(struct drm_globa
24651 void *object;
24652
24653 mutex_lock(&item->mutex);
24654 - if (item->refcount == 0) {
24655 + if (atomic_read(&item->refcount) == 0) {
24656 item->object = kzalloc(ref->size, GFP_KERNEL);
24657 if (unlikely(item->object == NULL)) {
24658 ret = -ENOMEM;
24659 @@ -83,7 +83,7 @@ int drm_global_item_ref(struct drm_globa
24660 goto out_err;
24661
24662 }
24663 - ++item->refcount;
24664 + atomic_inc(&item->refcount);
24665 ref->object = item->object;
24666 object = item->object;
24667 mutex_unlock(&item->mutex);
24668 @@ -100,9 +100,9 @@ void drm_global_item_unref(struct drm_gl
24669 struct drm_global_item *item = &glob[ref->global_type];
24670
24671 mutex_lock(&item->mutex);
24672 - BUG_ON(item->refcount == 0);
24673 + BUG_ON(atomic_read(&item->refcount) == 0);
24674 BUG_ON(ref->object != item->object);
24675 - if (--item->refcount == 0) {
24676 + if (atomic_dec_and_test(&item->refcount)) {
24677 ref->release(ref);
24678 item->object = NULL;
24679 }
24680 diff -urNp linux-2.6.36/drivers/gpu/drm/drm_info.c linux-2.6.36/drivers/gpu/drm/drm_info.c
24681 --- linux-2.6.36/drivers/gpu/drm/drm_info.c 2010-10-20 16:30:22.000000000 -0400
24682 +++ linux-2.6.36/drivers/gpu/drm/drm_info.c 2010-11-06 18:58:15.000000000 -0400
24683 @@ -86,10 +86,14 @@ int drm_vm_info(struct seq_file *m, void
24684 struct drm_local_map *map;
24685 struct drm_map_list *r_list;
24686
24687 - /* Hardcoded from _DRM_FRAME_BUFFER,
24688 - _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
24689 - _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
24690 - const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
24691 + static const char * const types[] = {
24692 + [_DRM_FRAME_BUFFER] = "FB",
24693 + [_DRM_REGISTERS] = "REG",
24694 + [_DRM_SHM] = "SHM",
24695 + [_DRM_AGP] = "AGP",
24696 + [_DRM_SCATTER_GATHER] = "SG",
24697 + [_DRM_CONSISTENT] = "PCI",
24698 + [_DRM_GEM] = "GEM" };
24699 const char *type;
24700 int i;
24701
24702 @@ -100,7 +104,7 @@ int drm_vm_info(struct seq_file *m, void
24703 map = r_list->map;
24704 if (!map)
24705 continue;
24706 - if (map->type < 0 || map->type > 5)
24707 + if (map->type >= ARRAY_SIZE(types))
24708 type = "??";
24709 else
24710 type = types[map->type];
24711 diff -urNp linux-2.6.36/drivers/gpu/drm/drm_ioctl.c linux-2.6.36/drivers/gpu/drm/drm_ioctl.c
24712 --- linux-2.6.36/drivers/gpu/drm/drm_ioctl.c 2010-10-20 16:30:22.000000000 -0400
24713 +++ linux-2.6.36/drivers/gpu/drm/drm_ioctl.c 2010-11-06 18:58:15.000000000 -0400
24714 @@ -353,7 +353,7 @@ int drm_getstats(struct drm_device *dev,
24715 stats->data[i].value =
24716 (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0);
24717 else
24718 - stats->data[i].value = atomic_read(&dev->counts[i]);
24719 + stats->data[i].value = atomic_read_unchecked(&dev->counts[i]);
24720 stats->data[i].type = dev->types[i];
24721 }
24722
24723 diff -urNp linux-2.6.36/drivers/gpu/drm/drm_lock.c linux-2.6.36/drivers/gpu/drm/drm_lock.c
24724 --- linux-2.6.36/drivers/gpu/drm/drm_lock.c 2010-10-20 16:30:22.000000000 -0400
24725 +++ linux-2.6.36/drivers/gpu/drm/drm_lock.c 2010-11-06 18:58:15.000000000 -0400
24726 @@ -87,7 +87,7 @@ int drm_lock(struct drm_device *dev, voi
24727 if (drm_lock_take(&master->lock, lock->context)) {
24728 master->lock.file_priv = file_priv;
24729 master->lock.lock_time = jiffies;
24730 - atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
24731 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_LOCKS]);
24732 break; /* Got lock */
24733 }
24734
24735 @@ -167,7 +167,7 @@ int drm_unlock(struct drm_device *dev, v
24736 return -EINVAL;
24737 }
24738
24739 - atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
24740 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_UNLOCKS]);
24741
24742 /* kernel_context_switch isn't used by any of the x86 drm
24743 * modules but is required by the Sparc driver.
24744 diff -urNp linux-2.6.36/drivers/gpu/drm/i810/i810_dma.c linux-2.6.36/drivers/gpu/drm/i810/i810_dma.c
24745 --- linux-2.6.36/drivers/gpu/drm/i810/i810_dma.c 2010-10-20 16:30:22.000000000 -0400
24746 +++ linux-2.6.36/drivers/gpu/drm/i810/i810_dma.c 2010-11-06 18:58:15.000000000 -0400
24747 @@ -952,8 +952,8 @@ static int i810_dma_vertex(struct drm_de
24748 dma->buflist[vertex->idx],
24749 vertex->discard, vertex->used);
24750
24751 - atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
24752 - atomic_inc(&dev->counts[_DRM_STAT_DMA]);
24753 + atomic_add_unchecked(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
24754 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
24755 sarea_priv->last_enqueue = dev_priv->counter - 1;
24756 sarea_priv->last_dispatch = (int)hw_status[5];
24757
24758 @@ -1113,8 +1113,8 @@ static int i810_dma_mc(struct drm_device
24759 i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used,
24760 mc->last_render);
24761
24762 - atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
24763 - atomic_inc(&dev->counts[_DRM_STAT_DMA]);
24764 + atomic_add_unchecked(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
24765 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
24766 sarea_priv->last_enqueue = dev_priv->counter - 1;
24767 sarea_priv->last_dispatch = (int)hw_status[5];
24768
24769 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/dvo_ch7017.c linux-2.6.36/drivers/gpu/drm/i915/dvo_ch7017.c
24770 --- linux-2.6.36/drivers/gpu/drm/i915/dvo_ch7017.c 2010-10-20 16:30:22.000000000 -0400
24771 +++ linux-2.6.36/drivers/gpu/drm/i915/dvo_ch7017.c 2010-11-06 18:58:15.000000000 -0400
24772 @@ -402,7 +402,7 @@ static void ch7017_destroy(struct intel_
24773 }
24774 }
24775
24776 -struct intel_dvo_dev_ops ch7017_ops = {
24777 +const struct intel_dvo_dev_ops ch7017_ops = {
24778 .init = ch7017_init,
24779 .detect = ch7017_detect,
24780 .mode_valid = ch7017_mode_valid,
24781 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/dvo_ch7xxx.c linux-2.6.36/drivers/gpu/drm/i915/dvo_ch7xxx.c
24782 --- linux-2.6.36/drivers/gpu/drm/i915/dvo_ch7xxx.c 2010-10-20 16:30:22.000000000 -0400
24783 +++ linux-2.6.36/drivers/gpu/drm/i915/dvo_ch7xxx.c 2010-11-06 18:58:15.000000000 -0400
24784 @@ -322,7 +322,7 @@ static void ch7xxx_destroy(struct intel_
24785 }
24786 }
24787
24788 -struct intel_dvo_dev_ops ch7xxx_ops = {
24789 +const struct intel_dvo_dev_ops ch7xxx_ops = {
24790 .init = ch7xxx_init,
24791 .detect = ch7xxx_detect,
24792 .mode_valid = ch7xxx_mode_valid,
24793 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/dvo.h linux-2.6.36/drivers/gpu/drm/i915/dvo.h
24794 --- linux-2.6.36/drivers/gpu/drm/i915/dvo.h 2010-10-20 16:30:22.000000000 -0400
24795 +++ linux-2.6.36/drivers/gpu/drm/i915/dvo.h 2010-11-06 18:58:15.000000000 -0400
24796 @@ -122,23 +122,23 @@ struct intel_dvo_dev_ops {
24797 *
24798 * \return singly-linked list of modes or NULL if no modes found.
24799 */
24800 - struct drm_display_mode *(*get_modes)(struct intel_dvo_device *dvo);
24801 + struct drm_display_mode *(* const get_modes)(struct intel_dvo_device *dvo);
24802
24803 /**
24804 * Clean up driver-specific bits of the output
24805 */
24806 - void (*destroy) (struct intel_dvo_device *dvo);
24807 + void (* const destroy) (struct intel_dvo_device *dvo);
24808
24809 /**
24810 * Debugging hook to dump device registers to log file
24811 */
24812 - void (*dump_regs)(struct intel_dvo_device *dvo);
24813 + void (* const dump_regs)(struct intel_dvo_device *dvo);
24814 };
24815
24816 -extern struct intel_dvo_dev_ops sil164_ops;
24817 -extern struct intel_dvo_dev_ops ch7xxx_ops;
24818 -extern struct intel_dvo_dev_ops ivch_ops;
24819 -extern struct intel_dvo_dev_ops tfp410_ops;
24820 -extern struct intel_dvo_dev_ops ch7017_ops;
24821 +extern const struct intel_dvo_dev_ops sil164_ops;
24822 +extern const struct intel_dvo_dev_ops ch7xxx_ops;
24823 +extern const struct intel_dvo_dev_ops ivch_ops;
24824 +extern const struct intel_dvo_dev_ops tfp410_ops;
24825 +extern const struct intel_dvo_dev_ops ch7017_ops;
24826
24827 #endif /* _INTEL_DVO_H */
24828 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/dvo_ivch.c linux-2.6.36/drivers/gpu/drm/i915/dvo_ivch.c
24829 --- linux-2.6.36/drivers/gpu/drm/i915/dvo_ivch.c 2010-10-20 16:30:22.000000000 -0400
24830 +++ linux-2.6.36/drivers/gpu/drm/i915/dvo_ivch.c 2010-11-06 18:58:15.000000000 -0400
24831 @@ -412,7 +412,7 @@ static void ivch_destroy(struct intel_dv
24832 }
24833 }
24834
24835 -struct intel_dvo_dev_ops ivch_ops= {
24836 +const struct intel_dvo_dev_ops ivch_ops= {
24837 .init = ivch_init,
24838 .dpms = ivch_dpms,
24839 .mode_valid = ivch_mode_valid,
24840 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/dvo_sil164.c linux-2.6.36/drivers/gpu/drm/i915/dvo_sil164.c
24841 --- linux-2.6.36/drivers/gpu/drm/i915/dvo_sil164.c 2010-10-20 16:30:22.000000000 -0400
24842 +++ linux-2.6.36/drivers/gpu/drm/i915/dvo_sil164.c 2010-11-06 18:58:15.000000000 -0400
24843 @@ -254,7 +254,7 @@ static void sil164_destroy(struct intel_
24844 }
24845 }
24846
24847 -struct intel_dvo_dev_ops sil164_ops = {
24848 +const struct intel_dvo_dev_ops sil164_ops = {
24849 .init = sil164_init,
24850 .detect = sil164_detect,
24851 .mode_valid = sil164_mode_valid,
24852 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/dvo_tfp410.c linux-2.6.36/drivers/gpu/drm/i915/dvo_tfp410.c
24853 --- linux-2.6.36/drivers/gpu/drm/i915/dvo_tfp410.c 2010-10-20 16:30:22.000000000 -0400
24854 +++ linux-2.6.36/drivers/gpu/drm/i915/dvo_tfp410.c 2010-11-06 18:58:15.000000000 -0400
24855 @@ -295,7 +295,7 @@ static void tfp410_destroy(struct intel_
24856 }
24857 }
24858
24859 -struct intel_dvo_dev_ops tfp410_ops = {
24860 +const struct intel_dvo_dev_ops tfp410_ops = {
24861 .init = tfp410_init,
24862 .detect = tfp410_detect,
24863 .mode_valid = tfp410_mode_valid,
24864 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/i915_dma.c linux-2.6.36/drivers/gpu/drm/i915/i915_dma.c
24865 --- linux-2.6.36/drivers/gpu/drm/i915/i915_dma.c 2010-10-20 16:30:22.000000000 -0400
24866 +++ linux-2.6.36/drivers/gpu/drm/i915/i915_dma.c 2010-11-06 18:58:15.000000000 -0400
24867 @@ -1357,7 +1357,7 @@ static bool i915_switcheroo_can_switch(s
24868 bool can_switch;
24869
24870 spin_lock(&dev->count_lock);
24871 - can_switch = (dev->open_count == 0);
24872 + can_switch = (atomic_read(&dev->open_count) == 0);
24873 spin_unlock(&dev->count_lock);
24874 return can_switch;
24875 }
24876 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/i915_drv.c linux-2.6.36/drivers/gpu/drm/i915/i915_drv.c
24877 --- linux-2.6.36/drivers/gpu/drm/i915/i915_drv.c 2010-10-20 16:30:22.000000000 -0400
24878 +++ linux-2.6.36/drivers/gpu/drm/i915/i915_drv.c 2010-11-06 18:58:15.000000000 -0400
24879 @@ -492,7 +492,7 @@ static const struct dev_pm_ops i915_pm_o
24880 .restore = i915_pm_resume,
24881 };
24882
24883 -static struct vm_operations_struct i915_gem_vm_ops = {
24884 +static const struct vm_operations_struct i915_gem_vm_ops = {
24885 .fault = i915_gem_fault,
24886 .open = drm_gem_vm_open,
24887 .close = drm_gem_vm_close,
24888 diff -urNp linux-2.6.36/drivers/gpu/drm/i915/i915_gem.c linux-2.6.36/drivers/gpu/drm/i915/i915_gem.c
24889 --- linux-2.6.36/drivers/gpu/drm/i915/i915_gem.c 2010-10-20 16:30:22.000000000 -0400
24890 +++ linux-2.6.36/drivers/gpu/drm/i915/i915_gem.c 2010-11-06 18:58:50.000000000 -0400
24891 @@ -476,12 +476,17 @@ i915_gem_pread_ioctl(struct drm_device *
24892 }
24893
24894 if (!access_ok(VERIFY_WRITE,
24895 - (char __user *)(uintptr_t)args->data_ptr,
24896 + (char __user *) (uintptr_t)args->data_ptr,
24897 args->size)) {
24898 ret = -EFAULT;
24899 goto err;
24900 }
24901
24902 + if (!access_ok(VERIFY_WRITE, (char __user *) (uintptr_t)args->data_ptr, args->size)) {
24903 + drm_gem_object_unreference_unlocked(obj);
24904 + return -EFAULT;
24905 + }
24906 +
24907 if (i915_gem_object_needs_bit17_swizzle(obj)) {
24908 ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv);
24909 } else {
24910 @@ -940,12 +945,17 @@ i915_gem_pwrite_ioctl(struct drm_device
24911 }
24912
24913 if (!access_ok(VERIFY_READ,
24914 - (char __user *)(uintptr_t)args->data_ptr,
24915 + (char __user *) (uintptr_t)args->data_ptr,
24916 args->size)) {
24917 ret = -EFAULT;
24918 goto err;
24919 }
24920
24921 + if (!access_ok(VERIFY_READ, (char __user *) (uintptr_t)args->data_ptr, args->size)) {
24922 + drm_gem_object_unreference_unlocked(obj);
24923 + return -EFAULT;
24924 + }
24925 +
24926 /* We can only do the GTT pwrite on untiled buffers, as otherwise
24927 * it would end up going through the fenced access, and we'll get
24928 * different detiling behavior between reading and writing.
24929 diff -urNp linux-2.6.36/drivers/gpu/drm/nouveau/nouveau_backlight.c linux-2.6.36/drivers/gpu/drm/nouveau/nouveau_backlight.c
24930 --- linux-2.6.36/drivers/gpu/drm/nouveau/nouveau_backlight.c 2010-10-20 16:30:22.000000000 -0400
24931 +++ linux-2.6.36/drivers/gpu/drm/nouveau/nouveau_backlight.c 2010-11-06 18:58:15.000000000 -0400
24932 @@ -58,7 +58,7 @@ static int nv40_set_intensity(struct bac
24933 return 0;
24934 }
24935
24936 -static struct backlight_ops nv40_bl_ops = {
24937 +static const struct backlight_ops nv40_bl_ops = {
24938 .options = BL_CORE_SUSPENDRESUME,
24939 .get_brightness = nv40_get_intensity,
24940 .update_status = nv40_set_intensity,
24941 @@ -81,7 +81,7 @@ static int nv50_set_intensity(struct bac
24942 return 0;
24943 }
24944
24945 -static struct backlight_ops nv50_bl_ops = {
24946 +static const struct backlight_ops nv50_bl_ops = {
24947 .options = BL_CORE_SUSPENDRESUME,
24948 .get_brightness = nv50_get_intensity,
24949 .update_status = nv50_set_intensity,
24950 diff -urNp linux-2.6.36/drivers/gpu/drm/nouveau/nouveau_state.c linux-2.6.36/drivers/gpu/drm/nouveau/nouveau_state.c
24951 --- linux-2.6.36/drivers/gpu/drm/nouveau/nouveau_state.c 2010-10-20 16:30:22.000000000 -0400
24952 +++ linux-2.6.36/drivers/gpu/drm/nouveau/nouveau_state.c 2010-11-06 18:58:15.000000000 -0400
24953 @@ -501,7 +501,7 @@ static bool nouveau_switcheroo_can_switc
24954 bool can_switch;
24955
24956 spin_lock(&dev->count_lock);
24957 - can_switch = (dev->open_count == 0);
24958 + can_switch = (atomic_read(&dev->open_count) == 0);
24959 spin_unlock(&dev->count_lock);
24960 return can_switch;
24961 }
24962 diff -urNp linux-2.6.36/drivers/gpu/drm/radeon/mkregtable.c linux-2.6.36/drivers/gpu/drm/radeon/mkregtable.c
24963 --- linux-2.6.36/drivers/gpu/drm/radeon/mkregtable.c 2010-10-20 16:30:22.000000000 -0400
24964 +++ linux-2.6.36/drivers/gpu/drm/radeon/mkregtable.c 2010-11-06 18:58:15.000000000 -0400
24965 @@ -637,14 +637,14 @@ static int parser_auth(struct table *t,
24966 regex_t mask_rex;
24967 regmatch_t match[4];
24968 char buf[1024];
24969 - size_t end;
24970 + long end;
24971 int len;
24972 int done = 0;
24973 int r;
24974 unsigned o;
24975 struct offset *offset;
24976 char last_reg_s[10];
24977 - int last_reg;
24978 + unsigned long last_reg;
24979
24980 if (regcomp
24981 (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
24982 diff -urNp linux-2.6.36/drivers/gpu/drm/radeon/radeon_device.c linux-2.6.36/drivers/gpu/drm/radeon/radeon_device.c
24983 --- linux-2.6.36/drivers/gpu/drm/radeon/radeon_device.c 2010-10-20 16:30:22.000000000 -0400
24984 +++ linux-2.6.36/drivers/gpu/drm/radeon/radeon_device.c 2010-11-06 18:58:15.000000000 -0400
24985 @@ -578,7 +578,7 @@ static bool radeon_switcheroo_can_switch
24986 bool can_switch;
24987
24988 spin_lock(&dev->count_lock);
24989 - can_switch = (dev->open_count == 0);
24990 + can_switch = (atomic_read(&dev->open_count) == 0);
24991 spin_unlock(&dev->count_lock);
24992 return can_switch;
24993 }
24994 diff -urNp linux-2.6.36/drivers/gpu/drm/radeon/radeon_state.c linux-2.6.36/drivers/gpu/drm/radeon/radeon_state.c
24995 --- linux-2.6.36/drivers/gpu/drm/radeon/radeon_state.c 2010-10-20 16:30:22.000000000 -0400
24996 +++ linux-2.6.36/drivers/gpu/drm/radeon/radeon_state.c 2010-11-06 18:58:15.000000000 -0400
24997 @@ -2168,7 +2168,7 @@ static int radeon_cp_clear(struct drm_de
24998 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
24999 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
25000
25001 - if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes,
25002 + if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS || DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes,
25003 sarea_priv->nbox * sizeof(depth_boxes[0])))
25004 return -EFAULT;
25005
25006 @@ -3031,7 +3031,7 @@ static int radeon_cp_getparam(struct drm
25007 {
25008 drm_radeon_private_t *dev_priv = dev->dev_private;
25009 drm_radeon_getparam_t *param = data;
25010 - int value;
25011 + int value = 0;
25012
25013 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
25014
25015 diff -urNp linux-2.6.36/drivers/gpu/drm/radeon/radeon_ttm.c linux-2.6.36/drivers/gpu/drm/radeon/radeon_ttm.c
25016 --- linux-2.6.36/drivers/gpu/drm/radeon/radeon_ttm.c 2010-10-20 16:30:22.000000000 -0400
25017 +++ linux-2.6.36/drivers/gpu/drm/radeon/radeon_ttm.c 2010-11-06 18:58:15.000000000 -0400
25018 @@ -601,8 +601,9 @@ void radeon_ttm_fini(struct radeon_devic
25019 DRM_INFO("radeon: ttm finalized\n");
25020 }
25021
25022 -static struct vm_operations_struct radeon_ttm_vm_ops;
25023 -static const struct vm_operations_struct *ttm_vm_ops = NULL;
25024 +extern int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
25025 +extern void ttm_bo_vm_open(struct vm_area_struct *vma);
25026 +extern void ttm_bo_vm_close(struct vm_area_struct *vma);
25027
25028 static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
25029 {
25030 @@ -610,17 +611,22 @@ static int radeon_ttm_fault(struct vm_ar
25031 struct radeon_device *rdev;
25032 int r;
25033
25034 - bo = (struct ttm_buffer_object *)vma->vm_private_data;
25035 - if (bo == NULL) {
25036 + bo = (struct ttm_buffer_object *)vma->vm_private_data;
25037 + if (!bo)
25038 return VM_FAULT_NOPAGE;
25039 - }
25040 rdev = radeon_get_rdev(bo->bdev);
25041 mutex_lock(&rdev->vram_mutex);
25042 - r = ttm_vm_ops->fault(vma, vmf);
25043 + r = ttm_bo_vm_fault(vma, vmf);
25044 mutex_unlock(&rdev->vram_mutex);
25045 return r;
25046 }
25047
25048 +static const struct vm_operations_struct radeon_ttm_vm_ops = {
25049 + .fault = radeon_ttm_fault,
25050 + .open = ttm_bo_vm_open,
25051 + .close = ttm_bo_vm_close
25052 +};
25053 +
25054 int radeon_mmap(struct file *filp, struct vm_area_struct *vma)
25055 {
25056 struct drm_file *file_priv;
25057 @@ -633,18 +639,11 @@ int radeon_mmap(struct file *filp, struc
25058
25059 file_priv = (struct drm_file *)filp->private_data;
25060 rdev = file_priv->minor->dev->dev_private;
25061 - if (rdev == NULL) {
25062 + if (!rdev)
25063 return -EINVAL;
25064 - }
25065 r = ttm_bo_mmap(filp, vma, &rdev->mman.bdev);
25066 - if (unlikely(r != 0)) {
25067 + if (r)
25068 return r;
25069 - }
25070 - if (unlikely(ttm_vm_ops == NULL)) {
25071 - ttm_vm_ops = vma->vm_ops;
25072 - radeon_ttm_vm_ops = *ttm_vm_ops;
25073 - radeon_ttm_vm_ops.fault = &radeon_ttm_fault;
25074 - }
25075 vma->vm_ops = &radeon_ttm_vm_ops;
25076 return 0;
25077 }
25078 diff -urNp linux-2.6.36/drivers/gpu/drm/ttm/ttm_bo.c linux-2.6.36/drivers/gpu/drm/ttm/ttm_bo.c
25079 --- linux-2.6.36/drivers/gpu/drm/ttm/ttm_bo.c 2010-10-20 16:30:22.000000000 -0400
25080 +++ linux-2.6.36/drivers/gpu/drm/ttm/ttm_bo.c 2010-11-06 18:58:15.000000000 -0400
25081 @@ -47,7 +47,7 @@
25082 #include <linux/module.h>
25083
25084 #define TTM_ASSERT_LOCKED(param)
25085 -#define TTM_DEBUG(fmt, arg...)
25086 +#define TTM_DEBUG(fmt, arg...) do {} while (0)
25087 #define TTM_BO_HASH_ORDER 13
25088
25089 static int ttm_bo_setup_vm(struct ttm_buffer_object *bo);
25090 diff -urNp linux-2.6.36/drivers/gpu/drm/ttm/ttm_bo_vm.c linux-2.6.36/drivers/gpu/drm/ttm/ttm_bo_vm.c
25091 --- linux-2.6.36/drivers/gpu/drm/ttm/ttm_bo_vm.c 2010-10-20 16:30:22.000000000 -0400
25092 +++ linux-2.6.36/drivers/gpu/drm/ttm/ttm_bo_vm.c 2010-11-06 18:58:15.000000000 -0400
25093 @@ -69,11 +69,11 @@ static struct ttm_buffer_object *ttm_bo_
25094 return best_bo;
25095 }
25096
25097 -static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
25098 +int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
25099 {
25100 struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
25101 vma->vm_private_data;
25102 - struct ttm_bo_device *bdev = bo->bdev;
25103 + struct ttm_bo_device *bdev;
25104 unsigned long page_offset;
25105 unsigned long page_last;
25106 unsigned long pfn;
25107 @@ -84,6 +84,10 @@ static int ttm_bo_vm_fault(struct vm_are
25108 unsigned long address = (unsigned long)vmf->virtual_address;
25109 int retval = VM_FAULT_NOPAGE;
25110
25111 + if (!bo)
25112 + return VM_FAULT_NOPAGE;
25113 + bdev = bo->bdev;
25114 +
25115 /*
25116 * Work around locking order reversal in fault / nopfn
25117 * between mmap_sem and bo_reserve: Perform a trylock operation
25118 @@ -212,22 +216,25 @@ out_unlock:
25119 ttm_bo_unreserve(bo);
25120 return retval;
25121 }
25122 +EXPORT_SYMBOL(ttm_bo_vm_fault);
25123
25124 -static void ttm_bo_vm_open(struct vm_area_struct *vma)
25125 +void ttm_bo_vm_open(struct vm_area_struct *vma)
25126 {
25127 struct ttm_buffer_object *bo =
25128 (struct ttm_buffer_object *)vma->vm_private_data;
25129
25130 (void)ttm_bo_reference(bo);
25131 }
25132 +EXPORT_SYMBOL(ttm_bo_vm_open);
25133
25134 -static void ttm_bo_vm_close(struct vm_area_struct *vma)
25135 +void ttm_bo_vm_close(struct vm_area_struct *vma)
25136 {
25137 struct ttm_buffer_object *bo = (struct ttm_buffer_object *)vma->vm_private_data;
25138
25139 ttm_bo_unref(&bo);
25140 vma->vm_private_data = NULL;
25141 }
25142 +EXPORT_SYMBOL(ttm_bo_vm_close);
25143
25144 static const struct vm_operations_struct ttm_bo_vm_ops = {
25145 .fault = ttm_bo_vm_fault,
25146 diff -urNp linux-2.6.36/drivers/hid/hidraw.c linux-2.6.36/drivers/hid/hidraw.c
25147 --- linux-2.6.36/drivers/hid/hidraw.c 2010-10-20 16:30:22.000000000 -0400
25148 +++ linux-2.6.36/drivers/hid/hidraw.c 2010-11-06 18:58:50.000000000 -0400
25149 @@ -250,7 +250,7 @@ static long hidraw_ioctl(struct file *fi
25150
25151 mutex_lock(&minors_lock);
25152 dev = hidraw_table[minor];
25153 - if (!dev) {
25154 + if (dev == NULL) {
25155 ret = -ENODEV;
25156 goto out;
25157 }
25158 diff -urNp linux-2.6.36/drivers/hid/usbhid/hiddev.c linux-2.6.36/drivers/hid/usbhid/hiddev.c
25159 --- linux-2.6.36/drivers/hid/usbhid/hiddev.c 2010-10-20 16:30:22.000000000 -0400
25160 +++ linux-2.6.36/drivers/hid/usbhid/hiddev.c 2010-11-06 18:58:15.000000000 -0400
25161 @@ -614,7 +614,7 @@ static long hiddev_ioctl(struct file *fi
25162 return put_user(HID_VERSION, (int __user *)arg);
25163
25164 case HIDIOCAPPLICATION:
25165 - if (arg < 0 || arg >= hid->maxapplication)
25166 + if (arg >= hid->maxapplication)
25167 return -EINVAL;
25168
25169 for (i = 0; i < hid->maxcollection; i++)
25170 diff -urNp linux-2.6.36/drivers/hwmon/k8temp.c linux-2.6.36/drivers/hwmon/k8temp.c
25171 --- linux-2.6.36/drivers/hwmon/k8temp.c 2010-10-20 16:30:22.000000000 -0400
25172 +++ linux-2.6.36/drivers/hwmon/k8temp.c 2010-11-06 18:58:15.000000000 -0400
25173 @@ -138,7 +138,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
25174
25175 static const struct pci_device_id k8temp_ids[] = {
25176 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
25177 - { 0 },
25178 + { 0, 0, 0, 0, 0, 0, 0 },
25179 };
25180
25181 MODULE_DEVICE_TABLE(pci, k8temp_ids);
25182 diff -urNp linux-2.6.36/drivers/hwmon/sis5595.c linux-2.6.36/drivers/hwmon/sis5595.c
25183 --- linux-2.6.36/drivers/hwmon/sis5595.c 2010-10-20 16:30:22.000000000 -0400
25184 +++ linux-2.6.36/drivers/hwmon/sis5595.c 2010-11-06 18:58:15.000000000 -0400
25185 @@ -699,7 +699,7 @@ static struct sis5595_data *sis5595_upda
25186
25187 static const struct pci_device_id sis5595_pci_ids[] = {
25188 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
25189 - { 0, }
25190 + { 0, 0, 0, 0, 0, 0, 0 }
25191 };
25192
25193 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
25194 diff -urNp linux-2.6.36/drivers/hwmon/via686a.c linux-2.6.36/drivers/hwmon/via686a.c
25195 --- linux-2.6.36/drivers/hwmon/via686a.c 2010-10-20 16:30:22.000000000 -0400
25196 +++ linux-2.6.36/drivers/hwmon/via686a.c 2010-11-06 18:58:15.000000000 -0400
25197 @@ -769,7 +769,7 @@ static struct via686a_data *via686a_upda
25198
25199 static const struct pci_device_id via686a_pci_ids[] = {
25200 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
25201 - { 0, }
25202 + { 0, 0, 0, 0, 0, 0, 0 }
25203 };
25204
25205 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
25206 diff -urNp linux-2.6.36/drivers/hwmon/vt8231.c linux-2.6.36/drivers/hwmon/vt8231.c
25207 --- linux-2.6.36/drivers/hwmon/vt8231.c 2010-10-20 16:30:22.000000000 -0400
25208 +++ linux-2.6.36/drivers/hwmon/vt8231.c 2010-11-06 18:58:15.000000000 -0400
25209 @@ -699,7 +699,7 @@ static struct platform_driver vt8231_dri
25210
25211 static const struct pci_device_id vt8231_pci_ids[] = {
25212 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
25213 - { 0, }
25214 + { 0, 0, 0, 0, 0, 0, 0 }
25215 };
25216
25217 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
25218 diff -urNp linux-2.6.36/drivers/hwmon/w83791d.c linux-2.6.36/drivers/hwmon/w83791d.c
25219 --- linux-2.6.36/drivers/hwmon/w83791d.c 2010-10-20 16:30:22.000000000 -0400
25220 +++ linux-2.6.36/drivers/hwmon/w83791d.c 2010-11-06 18:58:15.000000000 -0400
25221 @@ -329,8 +329,8 @@ static int w83791d_detect(struct i2c_cli
25222 struct i2c_board_info *info);
25223 static int w83791d_remove(struct i2c_client *client);
25224
25225 -static int w83791d_read(struct i2c_client *client, u8 register);
25226 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
25227 +static int w83791d_read(struct i2c_client *client, u8 reg);
25228 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
25229 static struct w83791d_data *w83791d_update_device(struct device *dev);
25230
25231 #ifdef DEBUG
25232 diff -urNp linux-2.6.36/drivers/i2c/busses/i2c-i801.c linux-2.6.36/drivers/i2c/busses/i2c-i801.c
25233 --- linux-2.6.36/drivers/i2c/busses/i2c-i801.c 2010-10-20 16:30:22.000000000 -0400
25234 +++ linux-2.6.36/drivers/i2c/busses/i2c-i801.c 2010-11-06 18:58:15.000000000 -0400
25235 @@ -592,7 +592,7 @@ static const struct pci_device_id i801_i
25236 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
25237 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) },
25238 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CPT_SMBUS) },
25239 - { 0, }
25240 + { 0, 0, 0, 0, 0, 0, 0 }
25241 };
25242
25243 MODULE_DEVICE_TABLE(pci, i801_ids);
25244 diff -urNp linux-2.6.36/drivers/i2c/busses/i2c-piix4.c linux-2.6.36/drivers/i2c/busses/i2c-piix4.c
25245 --- linux-2.6.36/drivers/i2c/busses/i2c-piix4.c 2010-10-20 16:30:22.000000000 -0400
25246 +++ linux-2.6.36/drivers/i2c/busses/i2c-piix4.c 2010-11-06 18:58:15.000000000 -0400
25247 @@ -124,7 +124,7 @@ static struct dmi_system_id __devinitdat
25248 .ident = "IBM",
25249 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
25250 },
25251 - { },
25252 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25253 };
25254
25255 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
25256 @@ -491,7 +491,7 @@ static const struct pci_device_id piix4_
25257 PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
25258 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
25259 PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
25260 - { 0, }
25261 + { 0, 0, 0, 0, 0, 0, 0 }
25262 };
25263
25264 MODULE_DEVICE_TABLE (pci, piix4_ids);
25265 diff -urNp linux-2.6.36/drivers/i2c/busses/i2c-sis630.c linux-2.6.36/drivers/i2c/busses/i2c-sis630.c
25266 --- linux-2.6.36/drivers/i2c/busses/i2c-sis630.c 2010-10-20 16:30:22.000000000 -0400
25267 +++ linux-2.6.36/drivers/i2c/busses/i2c-sis630.c 2010-11-06 18:58:15.000000000 -0400
25268 @@ -471,7 +471,7 @@ static struct i2c_adapter sis630_adapter
25269 static const struct pci_device_id sis630_ids[] __devinitconst = {
25270 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
25271 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
25272 - { 0, }
25273 + { 0, 0, 0, 0, 0, 0, 0 }
25274 };
25275
25276 MODULE_DEVICE_TABLE (pci, sis630_ids);
25277 diff -urNp linux-2.6.36/drivers/i2c/busses/i2c-sis96x.c linux-2.6.36/drivers/i2c/busses/i2c-sis96x.c
25278 --- linux-2.6.36/drivers/i2c/busses/i2c-sis96x.c 2010-10-20 16:30:22.000000000 -0400
25279 +++ linux-2.6.36/drivers/i2c/busses/i2c-sis96x.c 2010-11-06 18:58:15.000000000 -0400
25280 @@ -247,7 +247,7 @@ static struct i2c_adapter sis96x_adapter
25281
25282 static const struct pci_device_id sis96x_ids[] = {
25283 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
25284 - { 0, }
25285 + { 0, 0, 0, 0, 0, 0, 0 }
25286 };
25287
25288 MODULE_DEVICE_TABLE (pci, sis96x_ids);
25289 diff -urNp linux-2.6.36/drivers/ide/ide-cd.c linux-2.6.36/drivers/ide/ide-cd.c
25290 --- linux-2.6.36/drivers/ide/ide-cd.c 2010-10-20 16:30:22.000000000 -0400
25291 +++ linux-2.6.36/drivers/ide/ide-cd.c 2010-11-06 18:58:15.000000000 -0400
25292 @@ -776,7 +776,7 @@ static void cdrom_do_block_pc(ide_drive_
25293 alignment = queue_dma_alignment(q) | q->dma_pad_mask;
25294 if ((unsigned long)buf & alignment
25295 || blk_rq_bytes(rq) & q->dma_pad_mask
25296 - || object_is_on_stack(buf))
25297 + || object_starts_on_stack(buf))
25298 drive->dma = 0;
25299 }
25300 }
25301 diff -urNp linux-2.6.36/drivers/ieee1394/dv1394.c linux-2.6.36/drivers/ieee1394/dv1394.c
25302 --- linux-2.6.36/drivers/ieee1394/dv1394.c 2010-10-20 16:30:22.000000000 -0400
25303 +++ linux-2.6.36/drivers/ieee1394/dv1394.c 2010-11-06 18:58:15.000000000 -0400
25304 @@ -738,7 +738,7 @@ static void frame_prepare(struct video_c
25305 based upon DIF section and sequence
25306 */
25307
25308 -static void inline
25309 +static inline void
25310 frame_put_packet (struct frame *f, struct packet *p)
25311 {
25312 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
25313 @@ -2173,7 +2173,7 @@ static const struct ieee1394_device_id d
25314 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
25315 .version = AVC_SW_VERSION_ENTRY & 0xffffff
25316 },
25317 - { }
25318 + { 0, 0, 0, 0, 0, 0 }
25319 };
25320
25321 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
25322 diff -urNp linux-2.6.36/drivers/ieee1394/eth1394.c linux-2.6.36/drivers/ieee1394/eth1394.c
25323 --- linux-2.6.36/drivers/ieee1394/eth1394.c 2010-10-20 16:30:22.000000000 -0400
25324 +++ linux-2.6.36/drivers/ieee1394/eth1394.c 2010-11-06 18:58:15.000000000 -0400
25325 @@ -446,7 +446,7 @@ static const struct ieee1394_device_id e
25326 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
25327 .version = ETHER1394_GASP_VERSION,
25328 },
25329 - {}
25330 + { 0, 0, 0, 0, 0, 0 }
25331 };
25332
25333 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
25334 diff -urNp linux-2.6.36/drivers/ieee1394/hosts.c linux-2.6.36/drivers/ieee1394/hosts.c
25335 --- linux-2.6.36/drivers/ieee1394/hosts.c 2010-10-20 16:30:22.000000000 -0400
25336 +++ linux-2.6.36/drivers/ieee1394/hosts.c 2010-11-06 18:58:15.000000000 -0400
25337 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
25338 }
25339
25340 static struct hpsb_host_driver dummy_driver = {
25341 + .name = "dummy",
25342 .transmit_packet = dummy_transmit_packet,
25343 .devctl = dummy_devctl,
25344 .isoctl = dummy_isoctl
25345 diff -urNp linux-2.6.36/drivers/ieee1394/ohci1394.c linux-2.6.36/drivers/ieee1394/ohci1394.c
25346 --- linux-2.6.36/drivers/ieee1394/ohci1394.c 2010-10-20 16:30:22.000000000 -0400
25347 +++ linux-2.6.36/drivers/ieee1394/ohci1394.c 2010-11-06 18:58:15.000000000 -0400
25348 @@ -148,9 +148,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
25349 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
25350
25351 /* Module Parameters */
25352 -static int phys_dma = 1;
25353 +static int phys_dma;
25354 module_param(phys_dma, int, 0444);
25355 -MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
25356 +MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
25357
25358 static void dma_trm_tasklet(unsigned long data);
25359 static void dma_trm_reset(struct dma_trm_ctx *d);
25360 @@ -3445,7 +3445,7 @@ static struct pci_device_id ohci1394_pci
25361 .subvendor = PCI_ANY_ID,
25362 .subdevice = PCI_ANY_ID,
25363 },
25364 - { 0, },
25365 + { 0, 0, 0, 0, 0, 0, 0 },
25366 };
25367
25368 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
25369 diff -urNp linux-2.6.36/drivers/ieee1394/raw1394.c linux-2.6.36/drivers/ieee1394/raw1394.c
25370 --- linux-2.6.36/drivers/ieee1394/raw1394.c 2010-10-20 16:30:22.000000000 -0400
25371 +++ linux-2.6.36/drivers/ieee1394/raw1394.c 2010-11-06 18:58:15.000000000 -0400
25372 @@ -3001,7 +3001,7 @@ static const struct ieee1394_device_id r
25373 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
25374 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
25375 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
25376 - {}
25377 + { 0, 0, 0, 0, 0, 0 }
25378 };
25379
25380 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
25381 diff -urNp linux-2.6.36/drivers/ieee1394/sbp2.c linux-2.6.36/drivers/ieee1394/sbp2.c
25382 --- linux-2.6.36/drivers/ieee1394/sbp2.c 2010-10-20 16:30:22.000000000 -0400
25383 +++ linux-2.6.36/drivers/ieee1394/sbp2.c 2010-11-06 18:58:15.000000000 -0400
25384 @@ -289,7 +289,7 @@ static const struct ieee1394_device_id s
25385 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
25386 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
25387 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
25388 - {}
25389 + { 0, 0, 0, 0, 0, 0 }
25390 };
25391 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
25392
25393 @@ -2107,7 +2107,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
25394 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
25395 MODULE_LICENSE("GPL");
25396
25397 -static int sbp2_module_init(void)
25398 +static int __init sbp2_module_init(void)
25399 {
25400 int ret;
25401
25402 diff -urNp linux-2.6.36/drivers/ieee1394/video1394.c linux-2.6.36/drivers/ieee1394/video1394.c
25403 --- linux-2.6.36/drivers/ieee1394/video1394.c 2010-10-20 16:30:22.000000000 -0400
25404 +++ linux-2.6.36/drivers/ieee1394/video1394.c 2010-11-06 18:58:15.000000000 -0400
25405 @@ -1307,7 +1307,7 @@ static const struct ieee1394_device_id v
25406 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
25407 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
25408 },
25409 - { }
25410 + { 0, 0, 0, 0, 0, 0 }
25411 };
25412
25413 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
25414 diff -urNp linux-2.6.36/drivers/infiniband/core/cm.c linux-2.6.36/drivers/infiniband/core/cm.c
25415 --- linux-2.6.36/drivers/infiniband/core/cm.c 2010-10-20 16:30:22.000000000 -0400
25416 +++ linux-2.6.36/drivers/infiniband/core/cm.c 2010-11-06 18:58:15.000000000 -0400
25417 @@ -113,7 +113,7 @@ static char const counter_group_names[CM
25418
25419 struct cm_counter_group {
25420 struct kobject obj;
25421 - atomic_long_t counter[CM_ATTR_COUNT];
25422 + atomic_long_unchecked_t counter[CM_ATTR_COUNT];
25423 };
25424
25425 struct cm_counter_attribute {
25426 @@ -1387,7 +1387,7 @@ static void cm_dup_req_handler(struct cm
25427 struct ib_mad_send_buf *msg = NULL;
25428 int ret;
25429
25430 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25431 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25432 counter[CM_REQ_COUNTER]);
25433
25434 /* Quick state check to discard duplicate REQs. */
25435 @@ -1765,7 +1765,7 @@ static void cm_dup_rep_handler(struct cm
25436 if (!cm_id_priv)
25437 return;
25438
25439 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25440 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25441 counter[CM_REP_COUNTER]);
25442 ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg);
25443 if (ret)
25444 @@ -1932,7 +1932,7 @@ static int cm_rtu_handler(struct cm_work
25445 if (cm_id_priv->id.state != IB_CM_REP_SENT &&
25446 cm_id_priv->id.state != IB_CM_MRA_REP_RCVD) {
25447 spin_unlock_irq(&cm_id_priv->lock);
25448 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25449 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25450 counter[CM_RTU_COUNTER]);
25451 goto out;
25452 }
25453 @@ -2111,7 +2111,7 @@ static int cm_dreq_handler(struct cm_wor
25454 cm_id_priv = cm_acquire_id(dreq_msg->remote_comm_id,
25455 dreq_msg->local_comm_id);
25456 if (!cm_id_priv) {
25457 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25458 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25459 counter[CM_DREQ_COUNTER]);
25460 cm_issue_drep(work->port, work->mad_recv_wc);
25461 return -EINVAL;
25462 @@ -2132,7 +2132,7 @@ static int cm_dreq_handler(struct cm_wor
25463 case IB_CM_MRA_REP_RCVD:
25464 break;
25465 case IB_CM_TIMEWAIT:
25466 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25467 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25468 counter[CM_DREQ_COUNTER]);
25469 if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))
25470 goto unlock;
25471 @@ -2146,7 +2146,7 @@ static int cm_dreq_handler(struct cm_wor
25472 cm_free_msg(msg);
25473 goto deref;
25474 case IB_CM_DREQ_RCVD:
25475 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25476 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25477 counter[CM_DREQ_COUNTER]);
25478 goto unlock;
25479 default:
25480 @@ -2504,7 +2504,7 @@ static int cm_mra_handler(struct cm_work
25481 ib_modify_mad(cm_id_priv->av.port->mad_agent,
25482 cm_id_priv->msg, timeout)) {
25483 if (cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD)
25484 - atomic_long_inc(&work->port->
25485 + atomic_long_inc_unchecked(&work->port->
25486 counter_group[CM_RECV_DUPLICATES].
25487 counter[CM_MRA_COUNTER]);
25488 goto out;
25489 @@ -2513,7 +2513,7 @@ static int cm_mra_handler(struct cm_work
25490 break;
25491 case IB_CM_MRA_REQ_RCVD:
25492 case IB_CM_MRA_REP_RCVD:
25493 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25494 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25495 counter[CM_MRA_COUNTER]);
25496 /* fall through */
25497 default:
25498 @@ -2675,7 +2675,7 @@ static int cm_lap_handler(struct cm_work
25499 case IB_CM_LAP_IDLE:
25500 break;
25501 case IB_CM_MRA_LAP_SENT:
25502 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25503 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25504 counter[CM_LAP_COUNTER]);
25505 if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))
25506 goto unlock;
25507 @@ -2691,7 +2691,7 @@ static int cm_lap_handler(struct cm_work
25508 cm_free_msg(msg);
25509 goto deref;
25510 case IB_CM_LAP_RCVD:
25511 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25512 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25513 counter[CM_LAP_COUNTER]);
25514 goto unlock;
25515 default:
25516 @@ -2975,7 +2975,7 @@ static int cm_sidr_req_handler(struct cm
25517 cur_cm_id_priv = cm_insert_remote_sidr(cm_id_priv);
25518 if (cur_cm_id_priv) {
25519 spin_unlock_irq(&cm.lock);
25520 - atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
25521 + atomic_long_inc_unchecked(&work->port->counter_group[CM_RECV_DUPLICATES].
25522 counter[CM_SIDR_REQ_COUNTER]);
25523 goto out; /* Duplicate message. */
25524 }
25525 @@ -3186,10 +3186,10 @@ static void cm_send_handler(struct ib_ma
25526 if (!msg->context[0] && (attr_index != CM_REJ_COUNTER))
25527 msg->retries = 1;
25528
25529 - atomic_long_add(1 + msg->retries,
25530 + atomic_long_add_unchecked(1 + msg->retries,
25531 &port->counter_group[CM_XMIT].counter[attr_index]);
25532 if (msg->retries)
25533 - atomic_long_add(msg->retries,
25534 + atomic_long_add_unchecked(msg->retries,
25535 &port->counter_group[CM_XMIT_RETRIES].
25536 counter[attr_index]);
25537
25538 @@ -3399,7 +3399,7 @@ static void cm_recv_handler(struct ib_ma
25539 }
25540
25541 attr_id = be16_to_cpu(mad_recv_wc->recv_buf.mad->mad_hdr.attr_id);
25542 - atomic_long_inc(&port->counter_group[CM_RECV].
25543 + atomic_long_inc_unchecked(&port->counter_group[CM_RECV].
25544 counter[attr_id - CM_ATTR_ID_OFFSET]);
25545
25546 work = kmalloc(sizeof *work + sizeof(struct ib_sa_path_rec) * paths,
25547 @@ -3597,7 +3597,7 @@ static ssize_t cm_show_counter(struct ko
25548 cm_attr = container_of(attr, struct cm_counter_attribute, attr);
25549
25550 return sprintf(buf, "%ld\n",
25551 - atomic_long_read(&group->counter[cm_attr->index]));
25552 + atomic_long_read_unchecked(&group->counter[cm_attr->index]));
25553 }
25554
25555 static const struct sysfs_ops cm_counter_ops = {
25556 diff -urNp linux-2.6.36/drivers/infiniband/hw/qib/qib.h linux-2.6.36/drivers/infiniband/hw/qib/qib.h
25557 --- linux-2.6.36/drivers/infiniband/hw/qib/qib.h 2010-10-20 16:30:22.000000000 -0400
25558 +++ linux-2.6.36/drivers/infiniband/hw/qib/qib.h 2010-11-06 18:58:15.000000000 -0400
25559 @@ -51,6 +51,7 @@
25560 #include <linux/completion.h>
25561 #include <linux/kref.h>
25562 #include <linux/sched.h>
25563 +#include <linux/slab.h>
25564
25565 #include "qib_common.h"
25566 #include "qib_verbs.h"
25567 diff -urNp linux-2.6.36/drivers/input/keyboard/atkbd.c linux-2.6.36/drivers/input/keyboard/atkbd.c
25568 --- linux-2.6.36/drivers/input/keyboard/atkbd.c 2010-10-20 16:30:22.000000000 -0400
25569 +++ linux-2.6.36/drivers/input/keyboard/atkbd.c 2010-11-06 18:58:15.000000000 -0400
25570 @@ -1240,7 +1240,7 @@ static struct serio_device_id atkbd_seri
25571 .id = SERIO_ANY,
25572 .extra = SERIO_ANY,
25573 },
25574 - { 0 }
25575 + { 0, 0, 0, 0 }
25576 };
25577
25578 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
25579 diff -urNp linux-2.6.36/drivers/input/mouse/lifebook.c linux-2.6.36/drivers/input/mouse/lifebook.c
25580 --- linux-2.6.36/drivers/input/mouse/lifebook.c 2010-10-20 16:30:22.000000000 -0400
25581 +++ linux-2.6.36/drivers/input/mouse/lifebook.c 2010-11-06 18:58:15.000000000 -0400
25582 @@ -123,7 +123,7 @@ static const struct dmi_system_id __init
25583 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
25584 },
25585 },
25586 - { }
25587 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
25588 };
25589
25590 void __init lifebook_module_init(void)
25591 diff -urNp linux-2.6.36/drivers/input/mouse/psmouse-base.c linux-2.6.36/drivers/input/mouse/psmouse-base.c
25592 --- linux-2.6.36/drivers/input/mouse/psmouse-base.c 2010-10-20 16:30:22.000000000 -0400
25593 +++ linux-2.6.36/drivers/input/mouse/psmouse-base.c 2010-11-06 18:58:15.000000000 -0400
25594 @@ -1462,7 +1462,7 @@ static struct serio_device_id psmouse_se
25595 .id = SERIO_ANY,
25596 .extra = SERIO_ANY,
25597 },
25598 - { 0 }
25599 + { 0, 0, 0, 0 }
25600 };
25601
25602 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
25603 diff -urNp linux-2.6.36/drivers/input/mouse/synaptics.c linux-2.6.36/drivers/input/mouse/synaptics.c
25604 --- linux-2.6.36/drivers/input/mouse/synaptics.c 2010-10-20 16:30:22.000000000 -0400
25605 +++ linux-2.6.36/drivers/input/mouse/synaptics.c 2010-11-06 18:58:15.000000000 -0400
25606 @@ -476,7 +476,7 @@ static void synaptics_process_packet(str
25607 break;
25608 case 2:
25609 if (SYN_MODEL_PEN(priv->model_id))
25610 - ; /* Nothing, treat a pen as a single finger */
25611 + break; /* Nothing, treat a pen as a single finger */
25612 break;
25613 case 4 ... 15:
25614 if (SYN_CAP_PALMDETECT(priv->capabilities))
25615 @@ -705,7 +705,6 @@ static const struct dmi_system_id __init
25616 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
25617 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
25618 },
25619 -
25620 },
25621 {
25622 /* Toshiba Portege M300 */
25623 @@ -714,9 +713,8 @@ static const struct dmi_system_id __init
25624 DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
25625 DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
25626 },
25627 -
25628 },
25629 - { }
25630 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25631 #endif
25632 };
25633
25634 diff -urNp linux-2.6.36/drivers/input/mousedev.c linux-2.6.36/drivers/input/mousedev.c
25635 --- linux-2.6.36/drivers/input/mousedev.c 2010-10-20 16:30:22.000000000 -0400
25636 +++ linux-2.6.36/drivers/input/mousedev.c 2010-11-06 18:58:15.000000000 -0400
25637 @@ -762,7 +762,7 @@ static ssize_t mousedev_read(struct file
25638
25639 spin_unlock_irq(&client->packet_lock);
25640
25641 - if (copy_to_user(buffer, data, count))
25642 + if (count > sizeof(data) || copy_to_user(buffer, data, count))
25643 return -EFAULT;
25644
25645 return count;
25646 @@ -1064,7 +1064,7 @@ static struct input_handler mousedev_han
25647
25648 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
25649 static struct miscdevice psaux_mouse = {
25650 - PSMOUSE_MINOR, "psaux", &mousedev_fops
25651 + PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
25652 };
25653 static int psaux_registered;
25654 #endif
25655 diff -urNp linux-2.6.36/drivers/input/serio/i8042-x86ia64io.h linux-2.6.36/drivers/input/serio/i8042-x86ia64io.h
25656 --- linux-2.6.36/drivers/input/serio/i8042-x86ia64io.h 2010-10-20 16:30:22.000000000 -0400
25657 +++ linux-2.6.36/drivers/input/serio/i8042-x86ia64io.h 2010-11-06 18:58:15.000000000 -0400
25658 @@ -183,7 +183,7 @@ static const struct dmi_system_id __init
25659 DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
25660 },
25661 },
25662 - { }
25663 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25664 };
25665
25666 /*
25667 @@ -413,7 +413,7 @@ static const struct dmi_system_id __init
25668 DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
25669 },
25670 },
25671 - { }
25672 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25673 };
25674
25675 static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
25676 @@ -487,7 +487,7 @@ static const struct dmi_system_id __init
25677 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
25678 },
25679 },
25680 - { }
25681 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25682 };
25683
25684 #ifdef CONFIG_PNP
25685 @@ -506,7 +506,7 @@ static const struct dmi_system_id __init
25686 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
25687 },
25688 },
25689 - { }
25690 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25691 };
25692
25693 static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
25694 @@ -530,7 +530,7 @@ static const struct dmi_system_id __init
25695 DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
25696 },
25697 },
25698 - { }
25699 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25700 };
25701 #endif
25702
25703 @@ -604,7 +604,7 @@ static const struct dmi_system_id __init
25704 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
25705 },
25706 },
25707 - { }
25708 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
25709 };
25710
25711 #endif /* CONFIG_X86 */
25712 diff -urNp linux-2.6.36/drivers/input/serio/serio_raw.c linux-2.6.36/drivers/input/serio/serio_raw.c
25713 --- linux-2.6.36/drivers/input/serio/serio_raw.c 2010-10-20 16:30:22.000000000 -0400
25714 +++ linux-2.6.36/drivers/input/serio/serio_raw.c 2010-11-06 18:58:15.000000000 -0400
25715 @@ -376,7 +376,7 @@ static struct serio_device_id serio_raw_
25716 .id = SERIO_ANY,
25717 .extra = SERIO_ANY,
25718 },
25719 - { 0 }
25720 + { 0, 0, 0, 0 }
25721 };
25722
25723 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
25724 diff -urNp linux-2.6.36/drivers/isdn/gigaset/common.c linux-2.6.36/drivers/isdn/gigaset/common.c
25725 --- linux-2.6.36/drivers/isdn/gigaset/common.c 2010-10-20 16:30:22.000000000 -0400
25726 +++ linux-2.6.36/drivers/isdn/gigaset/common.c 2010-11-06 18:58:15.000000000 -0400
25727 @@ -723,7 +723,7 @@ struct cardstate *gigaset_initcs(struct
25728 cs->commands_pending = 0;
25729 cs->cur_at_seq = 0;
25730 cs->gotfwver = -1;
25731 - cs->open_count = 0;
25732 + atomic_set(&cs->open_count, 0);
25733 cs->dev = NULL;
25734 cs->tty = NULL;
25735 cs->tty_dev = NULL;
25736 diff -urNp linux-2.6.36/drivers/isdn/gigaset/gigaset.h linux-2.6.36/drivers/isdn/gigaset/gigaset.h
25737 --- linux-2.6.36/drivers/isdn/gigaset/gigaset.h 2010-10-20 16:30:22.000000000 -0400
25738 +++ linux-2.6.36/drivers/isdn/gigaset/gigaset.h 2010-11-06 18:58:15.000000000 -0400
25739 @@ -434,7 +434,7 @@ struct cardstate {
25740 spinlock_t cmdlock;
25741 unsigned curlen, cmdbytes;
25742
25743 - unsigned open_count;
25744 + atomic_t open_count;
25745 struct tty_struct *tty;
25746 struct tasklet_struct if_wake_tasklet;
25747 unsigned control_state;
25748 diff -urNp linux-2.6.36/drivers/isdn/gigaset/interface.c linux-2.6.36/drivers/isdn/gigaset/interface.c
25749 --- linux-2.6.36/drivers/isdn/gigaset/interface.c 2010-10-20 16:30:22.000000000 -0400
25750 +++ linux-2.6.36/drivers/isdn/gigaset/interface.c 2010-11-06 18:58:15.000000000 -0400
25751 @@ -160,9 +160,7 @@ static int if_open(struct tty_struct *tt
25752 return -ERESTARTSYS;
25753 tty->driver_data = cs;
25754
25755 - ++cs->open_count;
25756 -
25757 - if (cs->open_count == 1) {
25758 + if (atomic_inc_return(&cs->open_count) == 1) {
25759 spin_lock_irqsave(&cs->lock, flags);
25760 cs->tty = tty;
25761 spin_unlock_irqrestore(&cs->lock, flags);
25762 @@ -190,10 +188,10 @@ static void if_close(struct tty_struct *
25763
25764 if (!cs->connected)
25765 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
25766 - else if (!cs->open_count)
25767 + else if (!atomic_read(&cs->open_count))
25768 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25769 else {
25770 - if (!--cs->open_count) {
25771 + if (!atomic_dec_return(&cs->open_count)) {
25772 spin_lock_irqsave(&cs->lock, flags);
25773 cs->tty = NULL;
25774 spin_unlock_irqrestore(&cs->lock, flags);
25775 @@ -228,7 +226,7 @@ static int if_ioctl(struct tty_struct *t
25776 if (!cs->connected) {
25777 gig_dbg(DEBUG_IF, "not connected");
25778 retval = -ENODEV;
25779 - } else if (!cs->open_count)
25780 + } else if (!atomic_read(&cs->open_count))
25781 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25782 else {
25783 retval = 0;
25784 @@ -358,7 +356,7 @@ static int if_write(struct tty_struct *t
25785 retval = -ENODEV;
25786 goto done;
25787 }
25788 - if (!cs->open_count) {
25789 + if (!atomic_read(&cs->open_count)) {
25790 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25791 retval = -ENODEV;
25792 goto done;
25793 @@ -411,7 +409,7 @@ static int if_write_room(struct tty_stru
25794 if (!cs->connected) {
25795 gig_dbg(DEBUG_IF, "not connected");
25796 retval = -ENODEV;
25797 - } else if (!cs->open_count)
25798 + } else if (!atomic_read(&cs->open_count))
25799 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25800 else if (cs->mstate != MS_LOCKED) {
25801 dev_warn(cs->dev, "can't write to unlocked device\n");
25802 @@ -441,7 +439,7 @@ static int if_chars_in_buffer(struct tty
25803
25804 if (!cs->connected)
25805 gig_dbg(DEBUG_IF, "not connected");
25806 - else if (!cs->open_count)
25807 + else if (!atomic_read(&cs->open_count))
25808 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25809 else if (cs->mstate != MS_LOCKED)
25810 dev_warn(cs->dev, "can't write to unlocked device\n");
25811 @@ -469,7 +467,7 @@ static void if_throttle(struct tty_struc
25812
25813 if (!cs->connected)
25814 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
25815 - else if (!cs->open_count)
25816 + else if (!atomic_read(&cs->open_count))
25817 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25818 else
25819 gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
25820 @@ -493,7 +491,7 @@ static void if_unthrottle(struct tty_str
25821
25822 if (!cs->connected)
25823 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
25824 - else if (!cs->open_count)
25825 + else if (!atomic_read(&cs->open_count))
25826 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25827 else
25828 gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
25829 @@ -524,7 +522,7 @@ static void if_set_termios(struct tty_st
25830 goto out;
25831 }
25832
25833 - if (!cs->open_count) {
25834 + if (!atomic_read(&cs->open_count)) {
25835 dev_warn(cs->dev, "%s: device not opened\n", __func__);
25836 goto out;
25837 }
25838 diff -urNp linux-2.6.36/drivers/isdn/hardware/avm/b1.c linux-2.6.36/drivers/isdn/hardware/avm/b1.c
25839 --- linux-2.6.36/drivers/isdn/hardware/avm/b1.c 2010-10-20 16:30:22.000000000 -0400
25840 +++ linux-2.6.36/drivers/isdn/hardware/avm/b1.c 2010-11-06 18:58:50.000000000 -0400
25841 @@ -176,7 +176,7 @@ int b1_load_t4file(avmcard *card, capilo
25842 }
25843 if (left) {
25844 if (t4file->user) {
25845 - if (copy_from_user(buf, dp, left))
25846 + if (left > sizeof(buf) || copy_from_user(buf, dp, left))
25847 return -EFAULT;
25848 } else {
25849 memcpy(buf, dp, left);
25850 @@ -224,7 +224,7 @@ int b1_load_config(avmcard *card, capilo
25851 }
25852 if (left) {
25853 if (config->user) {
25854 - if (copy_from_user(buf, dp, left))
25855 + if (left > sizeof(buf) || copy_from_user(buf, dp, left))
25856 return -EFAULT;
25857 } else {
25858 memcpy(buf, dp, left);
25859 diff -urNp linux-2.6.36/drivers/isdn/icn/icn.c linux-2.6.36/drivers/isdn/icn/icn.c
25860 --- linux-2.6.36/drivers/isdn/icn/icn.c 2010-10-20 16:30:22.000000000 -0400
25861 +++ linux-2.6.36/drivers/isdn/icn/icn.c 2010-11-06 18:58:50.000000000 -0400
25862 @@ -1045,7 +1045,7 @@ icn_writecmd(const u_char * buf, int len
25863 if (count > len)
25864 count = len;
25865 if (user) {
25866 - if (copy_from_user(msg, buf, count))
25867 + if (count > sizeof(msg) || copy_from_user(msg, buf, count))
25868 return -EFAULT;
25869 } else
25870 memcpy(msg, buf, count);
25871 diff -urNp linux-2.6.36/drivers/lguest/core.c linux-2.6.36/drivers/lguest/core.c
25872 --- linux-2.6.36/drivers/lguest/core.c 2010-10-20 16:30:22.000000000 -0400
25873 +++ linux-2.6.36/drivers/lguest/core.c 2010-11-06 18:58:15.000000000 -0400
25874 @@ -92,9 +92,17 @@ static __init int map_switcher(void)
25875 * it's worked so far. The end address needs +1 because __get_vm_area
25876 * allocates an extra guard page, so we need space for that.
25877 */
25878 +
25879 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
25880 + switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
25881 + VM_ALLOC | VM_KERNEXEC, SWITCHER_ADDR, SWITCHER_ADDR
25882 + + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
25883 +#else
25884 switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
25885 VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR
25886 + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
25887 +#endif
25888 +
25889 if (!switcher_vma) {
25890 err = -ENOMEM;
25891 printk("lguest: could not map switcher pages high\n");
25892 diff -urNp linux-2.6.36/drivers/macintosh/via-pmu-backlight.c linux-2.6.36/drivers/macintosh/via-pmu-backlight.c
25893 --- linux-2.6.36/drivers/macintosh/via-pmu-backlight.c 2010-10-20 16:30:22.000000000 -0400
25894 +++ linux-2.6.36/drivers/macintosh/via-pmu-backlight.c 2010-11-06 18:58:15.000000000 -0400
25895 @@ -15,7 +15,7 @@
25896
25897 #define MAX_PMU_LEVEL 0xFF
25898
25899 -static struct backlight_ops pmu_backlight_data;
25900 +static const struct backlight_ops pmu_backlight_data;
25901 static DEFINE_SPINLOCK(pmu_backlight_lock);
25902 static int sleeping, uses_pmu_bl;
25903 static u8 bl_curve[FB_BACKLIGHT_LEVELS];
25904 @@ -115,7 +115,7 @@ static int pmu_backlight_get_brightness(
25905 return bd->props.brightness;
25906 }
25907
25908 -static struct backlight_ops pmu_backlight_data = {
25909 +static const struct backlight_ops pmu_backlight_data = {
25910 .get_brightness = pmu_backlight_get_brightness,
25911 .update_status = pmu_backlight_update_status,
25912
25913 diff -urNp linux-2.6.36/drivers/macintosh/via-pmu.c linux-2.6.36/drivers/macintosh/via-pmu.c
25914 --- linux-2.6.36/drivers/macintosh/via-pmu.c 2010-10-20 16:30:22.000000000 -0400
25915 +++ linux-2.6.36/drivers/macintosh/via-pmu.c 2010-11-06 18:58:15.000000000 -0400
25916 @@ -2256,7 +2256,7 @@ static int pmu_sleep_valid(suspend_state
25917 && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0);
25918 }
25919
25920 -static struct platform_suspend_ops pmu_pm_ops = {
25921 +static const struct platform_suspend_ops pmu_pm_ops = {
25922 .enter = powerbook_sleep,
25923 .valid = pmu_sleep_valid,
25924 };
25925 diff -urNp linux-2.6.36/drivers/md/bitmap.c linux-2.6.36/drivers/md/bitmap.c
25926 --- linux-2.6.36/drivers/md/bitmap.c 2010-10-20 16:30:22.000000000 -0400
25927 +++ linux-2.6.36/drivers/md/bitmap.c 2010-11-06 18:58:15.000000000 -0400
25928 @@ -55,7 +55,7 @@
25929 # if DEBUG > 0
25930 # define PRINTK(x...) printk(KERN_DEBUG x)
25931 # else
25932 -# define PRINTK(x...)
25933 +# define PRINTK(x...) do {} while (0)
25934 # endif
25935 #endif
25936
25937 diff -urNp linux-2.6.36/drivers/md/dm-table.c linux-2.6.36/drivers/md/dm-table.c
25938 --- linux-2.6.36/drivers/md/dm-table.c 2010-10-20 16:30:22.000000000 -0400
25939 +++ linux-2.6.36/drivers/md/dm-table.c 2010-11-06 18:58:15.000000000 -0400
25940 @@ -366,7 +366,7 @@ static int device_area_is_invalid(struct
25941 if (!dev_size)
25942 return 0;
25943
25944 - if ((start >= dev_size) || (start + len > dev_size)) {
25945 + if ((start >= dev_size) || (len > dev_size - start)) {
25946 DMWARN("%s: %s too small for target: "
25947 "start=%llu, len=%llu, dev_size=%llu",
25948 dm_device_name(ti->table->md), bdevname(bdev, b),
25949 diff -urNp linux-2.6.36/drivers/md/md.c linux-2.6.36/drivers/md/md.c
25950 --- linux-2.6.36/drivers/md/md.c 2010-10-20 16:30:22.000000000 -0400
25951 +++ linux-2.6.36/drivers/md/md.c 2010-11-06 18:58:15.000000000 -0400
25952 @@ -6403,7 +6403,7 @@ static int md_seq_show(struct seq_file *
25953 chunk_kb ? "KB" : "B");
25954 if (bitmap->file) {
25955 seq_printf(seq, ", file: ");
25956 - seq_path(seq, &bitmap->file->f_path, " \t\n");
25957 + seq_path(seq, &bitmap->file->f_path, " \t\n\\");
25958 }
25959
25960 seq_printf(seq, "\n");
25961 @@ -6497,7 +6497,7 @@ static int is_mddev_idle(mddev_t *mddev,
25962 struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
25963 curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
25964 (int)part_stat_read(&disk->part0, sectors[1]) -
25965 - atomic_read(&disk->sync_io);
25966 + atomic_read_unchecked(&disk->sync_io);
25967 /* sync IO will cause sync_io to increase before the disk_stats
25968 * as sync_io is counted when a request starts, and
25969 * disk_stats is counted when it completes.
25970 diff -urNp linux-2.6.36/drivers/md/md.h linux-2.6.36/drivers/md/md.h
25971 --- linux-2.6.36/drivers/md/md.h 2010-10-20 16:30:22.000000000 -0400
25972 +++ linux-2.6.36/drivers/md/md.h 2010-11-06 18:58:15.000000000 -0400
25973 @@ -362,7 +362,7 @@ static inline void rdev_dec_pending(mdk_
25974
25975 static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
25976 {
25977 - atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
25978 + atomic_add_unchecked(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
25979 }
25980
25981 struct mdk_personality
25982 diff -urNp linux-2.6.36/drivers/media/dvb/dvb-core/dvbdev.c linux-2.6.36/drivers/media/dvb/dvb-core/dvbdev.c
25983 --- linux-2.6.36/drivers/media/dvb/dvb-core/dvbdev.c 2010-10-20 16:30:22.000000000 -0400
25984 +++ linux-2.6.36/drivers/media/dvb/dvb-core/dvbdev.c 2010-11-06 18:58:15.000000000 -0400
25985 @@ -196,6 +196,7 @@ int dvb_register_device(struct dvb_adapt
25986 const struct dvb_device *template, void *priv, int type)
25987 {
25988 struct dvb_device *dvbdev;
25989 + /* cannot be const, see this function */
25990 struct file_operations *dvbdevfops;
25991 struct device *clsdev;
25992 int minor;
25993 diff -urNp linux-2.6.36/drivers/media/IR/lirc_dev.c linux-2.6.36/drivers/media/IR/lirc_dev.c
25994 --- linux-2.6.36/drivers/media/IR/lirc_dev.c 2010-10-20 16:30:22.000000000 -0400
25995 +++ linux-2.6.36/drivers/media/IR/lirc_dev.c 2010-11-06 18:58:15.000000000 -0400
25996 @@ -155,7 +155,7 @@ static int lirc_thread(void *irctl)
25997 }
25998
25999
26000 -static struct file_operations fops = {
26001 +static const struct file_operations fops = {
26002 .owner = THIS_MODULE,
26003 .read = lirc_dev_fop_read,
26004 .write = lirc_dev_fop_write,
26005 diff -urNp linux-2.6.36/drivers/media/radio/radio-cadet.c linux-2.6.36/drivers/media/radio/radio-cadet.c
26006 --- linux-2.6.36/drivers/media/radio/radio-cadet.c 2010-10-20 16:30:22.000000000 -0400
26007 +++ linux-2.6.36/drivers/media/radio/radio-cadet.c 2010-11-06 18:58:50.000000000 -0400
26008 @@ -347,7 +347,7 @@ static ssize_t cadet_read(struct file *f
26009 while (i < count && dev->rdsin != dev->rdsout)
26010 readbuf[i++] = dev->rdsbuf[dev->rdsout++];
26011
26012 - if (copy_to_user(data, readbuf, i))
26013 + if (i > sizeof(readbuf) || copy_to_user(data, readbuf, i))
26014 return -EFAULT;
26015 return i;
26016 }
26017 diff -urNp linux-2.6.36/drivers/message/fusion/mptbase.c linux-2.6.36/drivers/message/fusion/mptbase.c
26018 --- linux-2.6.36/drivers/message/fusion/mptbase.c 2010-10-20 16:30:22.000000000 -0400
26019 +++ linux-2.6.36/drivers/message/fusion/mptbase.c 2010-11-06 19:06:37.000000000 -0400
26020 @@ -6681,8 +6681,13 @@ static int mpt_iocinfo_proc_show(struct
26021 seq_printf(m, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
26022 seq_printf(m, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
26023
26024 +#ifdef CONFIG_GRKERNSEC_HIDESYM
26025 + seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n", NULL, NULL);
26026 +#else
26027 seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
26028 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
26029 +#endif
26030 +
26031 /*
26032 * Rounding UP to nearest 4-kB boundary here...
26033 */
26034 diff -urNp linux-2.6.36/drivers/message/fusion/mptdebug.h linux-2.6.36/drivers/message/fusion/mptdebug.h
26035 --- linux-2.6.36/drivers/message/fusion/mptdebug.h 2010-10-20 16:30:22.000000000 -0400
26036 +++ linux-2.6.36/drivers/message/fusion/mptdebug.h 2010-11-06 18:58:15.000000000 -0400
26037 @@ -71,7 +71,7 @@
26038 CMD; \
26039 }
26040 #else
26041 -#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
26042 +#define MPT_CHECK_LOGGING(IOC, CMD, BITS) do {} while (0)
26043 #endif
26044
26045
26046 diff -urNp linux-2.6.36/drivers/message/fusion/mptsas.c linux-2.6.36/drivers/message/fusion/mptsas.c
26047 --- linux-2.6.36/drivers/message/fusion/mptsas.c 2010-10-20 16:30:22.000000000 -0400
26048 +++ linux-2.6.36/drivers/message/fusion/mptsas.c 2010-11-06 18:58:15.000000000 -0400
26049 @@ -439,6 +439,23 @@ mptsas_is_end_device(struct mptsas_devin
26050 return 0;
26051 }
26052
26053 +static inline void
26054 +mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
26055 +{
26056 + if (phy_info->port_details) {
26057 + phy_info->port_details->rphy = rphy;
26058 + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
26059 + ioc->name, rphy));
26060 + }
26061 +
26062 + if (rphy) {
26063 + dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
26064 + &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
26065 + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
26066 + ioc->name, rphy, rphy->dev.release));
26067 + }
26068 +}
26069 +
26070 /* no mutex */
26071 static void
26072 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
26073 @@ -477,23 +494,6 @@ mptsas_get_rphy(struct mptsas_phyinfo *p
26074 return NULL;
26075 }
26076
26077 -static inline void
26078 -mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
26079 -{
26080 - if (phy_info->port_details) {
26081 - phy_info->port_details->rphy = rphy;
26082 - dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
26083 - ioc->name, rphy));
26084 - }
26085 -
26086 - if (rphy) {
26087 - dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
26088 - &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
26089 - dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
26090 - ioc->name, rphy, rphy->dev.release));
26091 - }
26092 -}
26093 -
26094 static inline struct sas_port *
26095 mptsas_get_port(struct mptsas_phyinfo *phy_info)
26096 {
26097 diff -urNp linux-2.6.36/drivers/message/fusion/mptscsih.c linux-2.6.36/drivers/message/fusion/mptscsih.c
26098 --- linux-2.6.36/drivers/message/fusion/mptscsih.c 2010-10-20 16:30:22.000000000 -0400
26099 +++ linux-2.6.36/drivers/message/fusion/mptscsih.c 2010-11-06 18:58:15.000000000 -0400
26100 @@ -1268,15 +1268,16 @@ mptscsih_info(struct Scsi_Host *SChost)
26101
26102 h = shost_priv(SChost);
26103
26104 - if (h) {
26105 - if (h->info_kbuf == NULL)
26106 - if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
26107 - return h->info_kbuf;
26108 - h->info_kbuf[0] = '\0';
26109 + if (!h)
26110 + return NULL;
26111
26112 - mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
26113 - h->info_kbuf[size-1] = '\0';
26114 - }
26115 + if (h->info_kbuf == NULL)
26116 + if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
26117 + return h->info_kbuf;
26118 + h->info_kbuf[0] = '\0';
26119 +
26120 + mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
26121 + h->info_kbuf[size-1] = '\0';
26122
26123 return h->info_kbuf;
26124 }
26125 diff -urNp linux-2.6.36/drivers/message/i2o/i2o_proc.c linux-2.6.36/drivers/message/i2o/i2o_proc.c
26126 --- linux-2.6.36/drivers/message/i2o/i2o_proc.c 2010-10-20 16:30:22.000000000 -0400
26127 +++ linux-2.6.36/drivers/message/i2o/i2o_proc.c 2010-11-06 18:58:15.000000000 -0400
26128 @@ -255,13 +255,6 @@ static char *scsi_devices[] = {
26129 "Array Controller Device"
26130 };
26131
26132 -static char *chtostr(u8 * chars, int n)
26133 -{
26134 - char tmp[256];
26135 - tmp[0] = 0;
26136 - return strncat(tmp, (char *)chars, n);
26137 -}
26138 -
26139 static int i2o_report_query_status(struct seq_file *seq, int block_status,
26140 char *group)
26141 {
26142 @@ -838,8 +831,7 @@ static int i2o_seq_show_ddm_table(struct
26143
26144 seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id);
26145 seq_printf(seq, "%-#8x", ddm_table.module_id);
26146 - seq_printf(seq, "%-29s",
26147 - chtostr(ddm_table.module_name_version, 28));
26148 + seq_printf(seq, "%-.28s", ddm_table.module_name_version);
26149 seq_printf(seq, "%9d ", ddm_table.data_size);
26150 seq_printf(seq, "%8d", ddm_table.code_size);
26151
26152 @@ -940,8 +932,8 @@ static int i2o_seq_show_drivers_stored(s
26153
26154 seq_printf(seq, "%-#7x", dst->i2o_vendor_id);
26155 seq_printf(seq, "%-#8x", dst->module_id);
26156 - seq_printf(seq, "%-29s", chtostr(dst->module_name_version, 28));
26157 - seq_printf(seq, "%-9s", chtostr(dst->date, 8));
26158 + seq_printf(seq, "%-.28s", dst->module_name_version);
26159 + seq_printf(seq, "%-.8s", dst->date);
26160 seq_printf(seq, "%8d ", dst->module_size);
26161 seq_printf(seq, "%8d ", dst->mpb_size);
26162 seq_printf(seq, "0x%04x", dst->module_flags);
26163 @@ -1272,14 +1264,10 @@ static int i2o_seq_show_dev_identity(str
26164 seq_printf(seq, "Device Class : %s\n", i2o_get_class_name(work16[0]));
26165 seq_printf(seq, "Owner TID : %0#5x\n", work16[2]);
26166 seq_printf(seq, "Parent TID : %0#5x\n", work16[3]);
26167 - seq_printf(seq, "Vendor info : %s\n",
26168 - chtostr((u8 *) (work32 + 2), 16));
26169 - seq_printf(seq, "Product info : %s\n",
26170 - chtostr((u8 *) (work32 + 6), 16));
26171 - seq_printf(seq, "Description : %s\n",
26172 - chtostr((u8 *) (work32 + 10), 16));
26173 - seq_printf(seq, "Product rev. : %s\n",
26174 - chtostr((u8 *) (work32 + 14), 8));
26175 + seq_printf(seq, "Vendor info : %.16s\n", (u8 *) (work32 + 2));
26176 + seq_printf(seq, "Product info : %.16s\n", (u8 *) (work32 + 6));
26177 + seq_printf(seq, "Description : %.16s\n", (u8 *) (work32 + 10));
26178 + seq_printf(seq, "Product rev. : %.8s\n", (u8 *) (work32 + 14));
26179
26180 seq_printf(seq, "Serial number : ");
26181 print_serial_number(seq, (u8 *) (work32 + 16),
26182 @@ -1324,10 +1312,8 @@ static int i2o_seq_show_ddm_identity(str
26183 }
26184
26185 seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid);
26186 - seq_printf(seq, "Module name : %s\n",
26187 - chtostr(result.module_name, 24));
26188 - seq_printf(seq, "Module revision : %s\n",
26189 - chtostr(result.module_rev, 8));
26190 + seq_printf(seq, "Module name : %.24s\n", result.module_name);
26191 + seq_printf(seq, "Module revision : %.8s\n", result.module_rev);
26192
26193 seq_printf(seq, "Serial number : ");
26194 print_serial_number(seq, result.serial_number, sizeof(result) - 36);
26195 @@ -1358,14 +1344,10 @@ static int i2o_seq_show_uinfo(struct seq
26196 return 0;
26197 }
26198
26199 - seq_printf(seq, "Device name : %s\n",
26200 - chtostr(result.device_name, 64));
26201 - seq_printf(seq, "Service name : %s\n",
26202 - chtostr(result.service_name, 64));
26203 - seq_printf(seq, "Physical name : %s\n",
26204 - chtostr(result.physical_location, 64));
26205 - seq_printf(seq, "Instance number : %s\n",
26206 - chtostr(result.instance_number, 4));
26207 + seq_printf(seq, "Device name : %.64s\n", result.device_name);
26208 + seq_printf(seq, "Service name : %.64s\n", result.service_name);
26209 + seq_printf(seq, "Physical name : %.64s\n", result.physical_location);
26210 + seq_printf(seq, "Instance number : %.4s\n", result.instance_number);
26211
26212 return 0;
26213 }
26214 diff -urNp linux-2.6.36/drivers/mfd/janz-cmodio.c linux-2.6.36/drivers/mfd/janz-cmodio.c
26215 --- linux-2.6.36/drivers/mfd/janz-cmodio.c 2010-10-20 16:30:22.000000000 -0400
26216 +++ linux-2.6.36/drivers/mfd/janz-cmodio.c 2010-11-06 18:58:15.000000000 -0400
26217 @@ -13,6 +13,7 @@
26218
26219 #include <linux/kernel.h>
26220 #include <linux/module.h>
26221 +#include <linux/slab.h>
26222 #include <linux/init.h>
26223 #include <linux/pci.h>
26224 #include <linux/interrupt.h>
26225 diff -urNp linux-2.6.36/drivers/misc/kgdbts.c linux-2.6.36/drivers/misc/kgdbts.c
26226 --- linux-2.6.36/drivers/misc/kgdbts.c 2010-10-20 16:30:22.000000000 -0400
26227 +++ linux-2.6.36/drivers/misc/kgdbts.c 2010-11-06 18:58:15.000000000 -0400
26228 @@ -118,7 +118,7 @@
26229 } while (0)
26230 #define MAX_CONFIG_LEN 40
26231
26232 -static struct kgdb_io kgdbts_io_ops;
26233 +static const struct kgdb_io kgdbts_io_ops;
26234 static char get_buf[BUFMAX];
26235 static int get_buf_cnt;
26236 static char put_buf[BUFMAX];
26237 @@ -1114,7 +1114,7 @@ static void kgdbts_post_exp_handler(void
26238 module_put(THIS_MODULE);
26239 }
26240
26241 -static struct kgdb_io kgdbts_io_ops = {
26242 +static const struct kgdb_io kgdbts_io_ops = {
26243 .name = "kgdbts",
26244 .read_char = kgdbts_get_char,
26245 .write_char = kgdbts_put_char,
26246 diff -urNp linux-2.6.36/drivers/misc/sgi-gru/gruhandles.c linux-2.6.36/drivers/misc/sgi-gru/gruhandles.c
26247 --- linux-2.6.36/drivers/misc/sgi-gru/gruhandles.c 2010-10-20 16:30:22.000000000 -0400
26248 +++ linux-2.6.36/drivers/misc/sgi-gru/gruhandles.c 2010-11-06 18:58:15.000000000 -0400
26249 @@ -44,8 +44,8 @@ static void update_mcs_stats(enum mcs_op
26250 unsigned long nsec;
26251
26252 nsec = CLKS2NSEC(clks);
26253 - atomic_long_inc(&mcs_op_statistics[op].count);
26254 - atomic_long_add(nsec, &mcs_op_statistics[op].total);
26255 + atomic_long_inc_unchecked(&mcs_op_statistics[op].count);
26256 + atomic_long_add_unchecked(nsec, &mcs_op_statistics[op].total);
26257 if (mcs_op_statistics[op].max < nsec)
26258 mcs_op_statistics[op].max = nsec;
26259 }
26260 diff -urNp linux-2.6.36/drivers/misc/sgi-gru/gruprocfs.c linux-2.6.36/drivers/misc/sgi-gru/gruprocfs.c
26261 --- linux-2.6.36/drivers/misc/sgi-gru/gruprocfs.c 2010-10-20 16:30:22.000000000 -0400
26262 +++ linux-2.6.36/drivers/misc/sgi-gru/gruprocfs.c 2010-11-06 18:58:15.000000000 -0400
26263 @@ -32,9 +32,9 @@
26264
26265 #define printstat(s, f) printstat_val(s, &gru_stats.f, #f)
26266
26267 -static void printstat_val(struct seq_file *s, atomic_long_t *v, char *id)
26268 +static void printstat_val(struct seq_file *s, atomic_long_unchecked_t *v, char *id)
26269 {
26270 - unsigned long val = atomic_long_read(v);
26271 + unsigned long val = atomic_long_read_unchecked(v);
26272
26273 seq_printf(s, "%16lu %s\n", val, id);
26274 }
26275 @@ -134,8 +134,8 @@ static int mcs_statistics_show(struct se
26276
26277 seq_printf(s, "%-20s%12s%12s%12s\n", "#id", "count", "aver-clks", "max-clks");
26278 for (op = 0; op < mcsop_last; op++) {
26279 - count = atomic_long_read(&mcs_op_statistics[op].count);
26280 - total = atomic_long_read(&mcs_op_statistics[op].total);
26281 + count = atomic_long_read_unchecked(&mcs_op_statistics[op].count);
26282 + total = atomic_long_read_unchecked(&mcs_op_statistics[op].total);
26283 max = mcs_op_statistics[op].max;
26284 seq_printf(s, "%-20s%12ld%12ld%12ld\n", id[op], count,
26285 count ? total / count : 0, max);
26286 diff -urNp linux-2.6.36/drivers/misc/sgi-gru/grutables.h linux-2.6.36/drivers/misc/sgi-gru/grutables.h
26287 --- linux-2.6.36/drivers/misc/sgi-gru/grutables.h 2010-10-20 16:30:22.000000000 -0400
26288 +++ linux-2.6.36/drivers/misc/sgi-gru/grutables.h 2010-11-06 18:58:15.000000000 -0400
26289 @@ -167,82 +167,82 @@ extern unsigned int gru_max_gids;
26290 * GRU statistics.
26291 */
26292 struct gru_stats_s {
26293 - atomic_long_t vdata_alloc;
26294 - atomic_long_t vdata_free;
26295 - atomic_long_t gts_alloc;
26296 - atomic_long_t gts_free;
26297 - atomic_long_t gms_alloc;
26298 - atomic_long_t gms_free;
26299 - atomic_long_t gts_double_allocate;
26300 - atomic_long_t assign_context;
26301 - atomic_long_t assign_context_failed;
26302 - atomic_long_t free_context;
26303 - atomic_long_t load_user_context;
26304 - atomic_long_t load_kernel_context;
26305 - atomic_long_t lock_kernel_context;
26306 - atomic_long_t unlock_kernel_context;
26307 - atomic_long_t steal_user_context;
26308 - atomic_long_t steal_kernel_context;
26309 - atomic_long_t steal_context_failed;
26310 - atomic_long_t nopfn;
26311 - atomic_long_t asid_new;
26312 - atomic_long_t asid_next;
26313 - atomic_long_t asid_wrap;
26314 - atomic_long_t asid_reuse;
26315 - atomic_long_t intr;
26316 - atomic_long_t intr_cbr;
26317 - atomic_long_t intr_tfh;
26318 - atomic_long_t intr_spurious;
26319 - atomic_long_t intr_mm_lock_failed;
26320 - atomic_long_t call_os;
26321 - atomic_long_t call_os_wait_queue;
26322 - atomic_long_t user_flush_tlb;
26323 - atomic_long_t user_unload_context;
26324 - atomic_long_t user_exception;
26325 - atomic_long_t set_context_option;
26326 - atomic_long_t check_context_retarget_intr;
26327 - atomic_long_t check_context_unload;
26328 - atomic_long_t tlb_dropin;
26329 - atomic_long_t tlb_preload_page;
26330 - atomic_long_t tlb_dropin_fail_no_asid;
26331 - atomic_long_t tlb_dropin_fail_upm;
26332 - atomic_long_t tlb_dropin_fail_invalid;
26333 - atomic_long_t tlb_dropin_fail_range_active;
26334 - atomic_long_t tlb_dropin_fail_idle;
26335 - atomic_long_t tlb_dropin_fail_fmm;
26336 - atomic_long_t tlb_dropin_fail_no_exception;
26337 - atomic_long_t tfh_stale_on_fault;
26338 - atomic_long_t mmu_invalidate_range;
26339 - atomic_long_t mmu_invalidate_page;
26340 - atomic_long_t flush_tlb;
26341 - atomic_long_t flush_tlb_gru;
26342 - atomic_long_t flush_tlb_gru_tgh;
26343 - atomic_long_t flush_tlb_gru_zero_asid;
26344 -
26345 - atomic_long_t copy_gpa;
26346 - atomic_long_t read_gpa;
26347 -
26348 - atomic_long_t mesq_receive;
26349 - atomic_long_t mesq_receive_none;
26350 - atomic_long_t mesq_send;
26351 - atomic_long_t mesq_send_failed;
26352 - atomic_long_t mesq_noop;
26353 - atomic_long_t mesq_send_unexpected_error;
26354 - atomic_long_t mesq_send_lb_overflow;
26355 - atomic_long_t mesq_send_qlimit_reached;
26356 - atomic_long_t mesq_send_amo_nacked;
26357 - atomic_long_t mesq_send_put_nacked;
26358 - atomic_long_t mesq_page_overflow;
26359 - atomic_long_t mesq_qf_locked;
26360 - atomic_long_t mesq_qf_noop_not_full;
26361 - atomic_long_t mesq_qf_switch_head_failed;
26362 - atomic_long_t mesq_qf_unexpected_error;
26363 - atomic_long_t mesq_noop_unexpected_error;
26364 - atomic_long_t mesq_noop_lb_overflow;
26365 - atomic_long_t mesq_noop_qlimit_reached;
26366 - atomic_long_t mesq_noop_amo_nacked;
26367 - atomic_long_t mesq_noop_put_nacked;
26368 - atomic_long_t mesq_noop_page_overflow;
26369 + atomic_long_unchecked_t vdata_alloc;
26370 + atomic_long_unchecked_t vdata_free;
26371 + atomic_long_unchecked_t gts_alloc;
26372 + atomic_long_unchecked_t gts_free;
26373 + atomic_long_unchecked_t gms_alloc;
26374 + atomic_long_unchecked_t gms_free;
26375 + atomic_long_unchecked_t gts_double_allocate;
26376 + atomic_long_unchecked_t assign_context;
26377 + atomic_long_unchecked_t assign_context_failed;
26378 + atomic_long_unchecked_t free_context;
26379 + atomic_long_unchecked_t load_user_context;
26380 + atomic_long_unchecked_t load_kernel_context;
26381 + atomic_long_unchecked_t lock_kernel_context;
26382 + atomic_long_unchecked_t unlock_kernel_context;
26383 + atomic_long_unchecked_t steal_user_context;
26384 + atomic_long_unchecked_t steal_kernel_context;
26385 + atomic_long_unchecked_t steal_context_failed;
26386 + atomic_long_unchecked_t nopfn;
26387 + atomic_long_unchecked_t asid_new;
26388 + atomic_long_unchecked_t asid_next;
26389 + atomic_long_unchecked_t asid_wrap;
26390 + atomic_long_unchecked_t asid_reuse;
26391 + atomic_long_unchecked_t intr;
26392 + atomic_long_unchecked_t intr_cbr;
26393 + atomic_long_unchecked_t intr_tfh;
26394 + atomic_long_unchecked_t intr_spurious;
26395 + atomic_long_unchecked_t intr_mm_lock_failed;
26396 + atomic_long_unchecked_t call_os;
26397 + atomic_long_unchecked_t call_os_wait_queue;
26398 + atomic_long_unchecked_t user_flush_tlb;
26399 + atomic_long_unchecked_t user_unload_context;
26400 + atomic_long_unchecked_t user_exception;
26401 + atomic_long_unchecked_t set_context_option;
26402 + atomic_long_unchecked_t check_context_retarget_intr;
26403 + atomic_long_unchecked_t check_context_unload;
26404 + atomic_long_unchecked_t tlb_dropin;
26405 + atomic_long_unchecked_t tlb_preload_page;
26406 + atomic_long_unchecked_t tlb_dropin_fail_no_asid;
26407 + atomic_long_unchecked_t tlb_dropin_fail_upm;
26408 + atomic_long_unchecked_t tlb_dropin_fail_invalid;
26409 + atomic_long_unchecked_t tlb_dropin_fail_range_active;
26410 + atomic_long_unchecked_t tlb_dropin_fail_idle;
26411 + atomic_long_unchecked_t tlb_dropin_fail_fmm;
26412 + atomic_long_unchecked_t tlb_dropin_fail_no_exception;
26413 + atomic_long_unchecked_t tfh_stale_on_fault;
26414 + atomic_long_unchecked_t mmu_invalidate_range;
26415 + atomic_long_unchecked_t mmu_invalidate_page;
26416 + atomic_long_unchecked_t flush_tlb;
26417 + atomic_long_unchecked_t flush_tlb_gru;
26418 + atomic_long_unchecked_t flush_tlb_gru_tgh;
26419 + atomic_long_unchecked_t flush_tlb_gru_zero_asid;
26420 +
26421 + atomic_long_unchecked_t copy_gpa;
26422 + atomic_long_unchecked_t read_gpa;
26423 +
26424 + atomic_long_unchecked_t mesq_receive;
26425 + atomic_long_unchecked_t mesq_receive_none;
26426 + atomic_long_unchecked_t mesq_send;
26427 + atomic_long_unchecked_t mesq_send_failed;
26428 + atomic_long_unchecked_t mesq_noop;
26429 + atomic_long_unchecked_t mesq_send_unexpected_error;
26430 + atomic_long_unchecked_t mesq_send_lb_overflow;
26431 + atomic_long_unchecked_t mesq_send_qlimit_reached;
26432 + atomic_long_unchecked_t mesq_send_amo_nacked;
26433 + atomic_long_unchecked_t mesq_send_put_nacked;
26434 + atomic_long_unchecked_t mesq_page_overflow;
26435 + atomic_long_unchecked_t mesq_qf_locked;
26436 + atomic_long_unchecked_t mesq_qf_noop_not_full;
26437 + atomic_long_unchecked_t mesq_qf_switch_head_failed;
26438 + atomic_long_unchecked_t mesq_qf_unexpected_error;
26439 + atomic_long_unchecked_t mesq_noop_unexpected_error;
26440 + atomic_long_unchecked_t mesq_noop_lb_overflow;
26441 + atomic_long_unchecked_t mesq_noop_qlimit_reached;
26442 + atomic_long_unchecked_t mesq_noop_amo_nacked;
26443 + atomic_long_unchecked_t mesq_noop_put_nacked;
26444 + atomic_long_unchecked_t mesq_noop_page_overflow;
26445
26446 };
26447
26448 @@ -251,8 +251,8 @@ enum mcs_op {cchop_allocate, cchop_start
26449 tghop_invalidate, mcsop_last};
26450
26451 struct mcs_op_statistic {
26452 - atomic_long_t count;
26453 - atomic_long_t total;
26454 + atomic_long_unchecked_t count;
26455 + atomic_long_unchecked_t total;
26456 unsigned long max;
26457 };
26458
26459 @@ -275,7 +275,7 @@ extern struct mcs_op_statistic mcs_op_st
26460
26461 #define STAT(id) do { \
26462 if (gru_options & OPT_STATS) \
26463 - atomic_long_inc(&gru_stats.id); \
26464 + atomic_long_inc_unchecked(&gru_stats.id); \
26465 } while (0)
26466
26467 #ifdef CONFIG_SGI_GRU_DEBUG
26468 diff -urNp linux-2.6.36/drivers/mtd/devices/doc2000.c linux-2.6.36/drivers/mtd/devices/doc2000.c
26469 --- linux-2.6.36/drivers/mtd/devices/doc2000.c 2010-10-20 16:30:22.000000000 -0400
26470 +++ linux-2.6.36/drivers/mtd/devices/doc2000.c 2010-11-06 18:58:15.000000000 -0400
26471 @@ -776,7 +776,7 @@ static int doc_write(struct mtd_info *mt
26472
26473 /* The ECC will not be calculated correctly if less than 512 is written */
26474 /* DBB-
26475 - if (len != 0x200 && eccbuf)
26476 + if (len != 0x200)
26477 printk(KERN_WARNING
26478 "ECC needs a full sector write (adr: %lx size %lx)\n",
26479 (long) to, (long) len);
26480 diff -urNp linux-2.6.36/drivers/mtd/devices/doc2001.c linux-2.6.36/drivers/mtd/devices/doc2001.c
26481 --- linux-2.6.36/drivers/mtd/devices/doc2001.c 2010-10-20 16:30:22.000000000 -0400
26482 +++ linux-2.6.36/drivers/mtd/devices/doc2001.c 2010-11-06 18:58:15.000000000 -0400
26483 @@ -393,7 +393,7 @@ static int doc_read (struct mtd_info *mt
26484 struct Nand *mychip = &this->chips[from >> (this->chipshift)];
26485
26486 /* Don't allow read past end of device */
26487 - if (from >= this->totlen)
26488 + if (from >= this->totlen || !len)
26489 return -EINVAL;
26490
26491 /* Don't allow a single read to cross a 512-byte block boundary */
26492 diff -urNp linux-2.6.36/drivers/mtd/nand/denali.c linux-2.6.36/drivers/mtd/nand/denali.c
26493 --- linux-2.6.36/drivers/mtd/nand/denali.c 2010-10-20 16:30:22.000000000 -0400
26494 +++ linux-2.6.36/drivers/mtd/nand/denali.c 2010-11-06 18:58:15.000000000 -0400
26495 @@ -25,6 +25,7 @@
26496 #include <linux/pci.h>
26497 #include <linux/mtd/mtd.h>
26498 #include <linux/module.h>
26499 +#include <linux/slab.h>
26500
26501 #include "denali.h"
26502
26503 diff -urNp linux-2.6.36/drivers/mtd/ubi/build.c linux-2.6.36/drivers/mtd/ubi/build.c
26504 --- linux-2.6.36/drivers/mtd/ubi/build.c 2010-10-20 16:30:22.000000000 -0400
26505 +++ linux-2.6.36/drivers/mtd/ubi/build.c 2010-11-06 18:58:15.000000000 -0400
26506 @@ -1283,7 +1283,7 @@ module_exit(ubi_exit);
26507 static int __init bytes_str_to_int(const char *str)
26508 {
26509 char *endp;
26510 - unsigned long result;
26511 + unsigned long result, scale = 1;
26512
26513 result = simple_strtoul(str, &endp, 0);
26514 if (str == endp || result >= INT_MAX) {
26515 @@ -1294,11 +1294,11 @@ static int __init bytes_str_to_int(const
26516
26517 switch (*endp) {
26518 case 'G':
26519 - result *= 1024;
26520 + scale *= 1024;
26521 case 'M':
26522 - result *= 1024;
26523 + scale *= 1024;
26524 case 'K':
26525 - result *= 1024;
26526 + scale *= 1024;
26527 if (endp[1] == 'i' && endp[2] == 'B')
26528 endp += 2;
26529 case '\0':
26530 @@ -1309,7 +1309,13 @@ static int __init bytes_str_to_int(const
26531 return -EINVAL;
26532 }
26533
26534 - return result;
26535 + if ((intoverflow_t)result*scale >= INT_MAX) {
26536 + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
26537 + str);
26538 + return -EINVAL;
26539 + }
26540 +
26541 + return result*scale;
26542 }
26543
26544 /**
26545 diff -urNp linux-2.6.36/drivers/net/cxgb3/cxgb3_main.c linux-2.6.36/drivers/net/cxgb3/cxgb3_main.c
26546 --- linux-2.6.36/drivers/net/cxgb3/cxgb3_main.c 2010-10-20 16:30:22.000000000 -0400
26547 +++ linux-2.6.36/drivers/net/cxgb3/cxgb3_main.c 2010-11-06 18:58:50.000000000 -0400
26548 @@ -2296,7 +2296,7 @@ static int cxgb_extension_ioctl(struct n
26549 case CHELSIO_GET_QSET_NUM:{
26550 struct ch_reg edata;
26551
26552 - memset(&edata, 0, sizeof(struct ch_reg));
26553 + memset(&edata, 0, sizeof(edata));
26554
26555 edata.cmd = CHELSIO_GET_QSET_NUM;
26556 edata.val = pi->nqsets;
26557 diff -urNp linux-2.6.36/drivers/net/e1000e/82571.c linux-2.6.36/drivers/net/e1000e/82571.c
26558 --- linux-2.6.36/drivers/net/e1000e/82571.c 2010-10-20 16:30:22.000000000 -0400
26559 +++ linux-2.6.36/drivers/net/e1000e/82571.c 2010-11-06 18:58:15.000000000 -0400
26560 @@ -207,6 +207,7 @@ static s32 e1000_init_mac_params_82571(s
26561 {
26562 struct e1000_hw *hw = &adapter->hw;
26563 struct e1000_mac_info *mac = &hw->mac;
26564 + /* cannot be const */
26565 struct e1000_mac_operations *func = &mac->ops;
26566 u32 swsm = 0;
26567 u32 swsm2 = 0;
26568 @@ -1703,7 +1704,7 @@ static void e1000_clear_hw_cntrs_82571(s
26569 er32(ICRXDMTC);
26570 }
26571
26572 -static struct e1000_mac_operations e82571_mac_ops = {
26573 +static const struct e1000_mac_operations e82571_mac_ops = {
26574 /* .check_mng_mode: mac type dependent */
26575 /* .check_for_link: media type dependent */
26576 .id_led_init = e1000e_id_led_init,
26577 @@ -1725,7 +1726,7 @@ static struct e1000_mac_operations e8257
26578 .read_mac_addr = e1000_read_mac_addr_82571,
26579 };
26580
26581 -static struct e1000_phy_operations e82_phy_ops_igp = {
26582 +static const struct e1000_phy_operations e82_phy_ops_igp = {
26583 .acquire = e1000_get_hw_semaphore_82571,
26584 .check_polarity = e1000_check_polarity_igp,
26585 .check_reset_block = e1000e_check_reset_block_generic,
26586 @@ -1743,7 +1744,7 @@ static struct e1000_phy_operations e82_p
26587 .cfg_on_link_up = NULL,
26588 };
26589
26590 -static struct e1000_phy_operations e82_phy_ops_m88 = {
26591 +static const struct e1000_phy_operations e82_phy_ops_m88 = {
26592 .acquire = e1000_get_hw_semaphore_82571,
26593 .check_polarity = e1000_check_polarity_m88,
26594 .check_reset_block = e1000e_check_reset_block_generic,
26595 @@ -1761,7 +1762,7 @@ static struct e1000_phy_operations e82_p
26596 .cfg_on_link_up = NULL,
26597 };
26598
26599 -static struct e1000_phy_operations e82_phy_ops_bm = {
26600 +static const struct e1000_phy_operations e82_phy_ops_bm = {
26601 .acquire = e1000_get_hw_semaphore_82571,
26602 .check_polarity = e1000_check_polarity_m88,
26603 .check_reset_block = e1000e_check_reset_block_generic,
26604 @@ -1779,7 +1780,7 @@ static struct e1000_phy_operations e82_p
26605 .cfg_on_link_up = NULL,
26606 };
26607
26608 -static struct e1000_nvm_operations e82571_nvm_ops = {
26609 +static const struct e1000_nvm_operations e82571_nvm_ops = {
26610 .acquire = e1000_acquire_nvm_82571,
26611 .read = e1000e_read_nvm_eerd,
26612 .release = e1000_release_nvm_82571,
26613 diff -urNp linux-2.6.36/drivers/net/e1000e/e1000.h linux-2.6.36/drivers/net/e1000e/e1000.h
26614 --- linux-2.6.36/drivers/net/e1000e/e1000.h 2010-10-20 16:30:22.000000000 -0400
26615 +++ linux-2.6.36/drivers/net/e1000e/e1000.h 2010-11-06 18:58:15.000000000 -0400
26616 @@ -379,9 +379,9 @@ struct e1000_info {
26617 u32 pba;
26618 u32 max_hw_frame_size;
26619 s32 (*get_variants)(struct e1000_adapter *);
26620 - struct e1000_mac_operations *mac_ops;
26621 - struct e1000_phy_operations *phy_ops;
26622 - struct e1000_nvm_operations *nvm_ops;
26623 + const struct e1000_mac_operations *mac_ops;
26624 + const struct e1000_phy_operations *phy_ops;
26625 + const struct e1000_nvm_operations *nvm_ops;
26626 };
26627
26628 /* hardware capability, feature, and workaround flags */
26629 diff -urNp linux-2.6.36/drivers/net/e1000e/es2lan.c linux-2.6.36/drivers/net/e1000e/es2lan.c
26630 --- linux-2.6.36/drivers/net/e1000e/es2lan.c 2010-10-20 16:30:22.000000000 -0400
26631 +++ linux-2.6.36/drivers/net/e1000e/es2lan.c 2010-11-06 18:58:15.000000000 -0400
26632 @@ -205,6 +205,7 @@ static s32 e1000_init_mac_params_80003es
26633 {
26634 struct e1000_hw *hw = &adapter->hw;
26635 struct e1000_mac_info *mac = &hw->mac;
26636 + /* cannot be const */
26637 struct e1000_mac_operations *func = &mac->ops;
26638
26639 /* Set media type */
26640 @@ -1431,7 +1432,7 @@ static void e1000_clear_hw_cntrs_80003es
26641 er32(ICRXDMTC);
26642 }
26643
26644 -static struct e1000_mac_operations es2_mac_ops = {
26645 +static const struct e1000_mac_operations es2_mac_ops = {
26646 .read_mac_addr = e1000_read_mac_addr_80003es2lan,
26647 .id_led_init = e1000e_id_led_init,
26648 .check_mng_mode = e1000e_check_mng_mode_generic,
26649 @@ -1453,7 +1454,7 @@ static struct e1000_mac_operations es2_m
26650 .setup_led = e1000e_setup_led_generic,
26651 };
26652
26653 -static struct e1000_phy_operations es2_phy_ops = {
26654 +static const struct e1000_phy_operations es2_phy_ops = {
26655 .acquire = e1000_acquire_phy_80003es2lan,
26656 .check_polarity = e1000_check_polarity_m88,
26657 .check_reset_block = e1000e_check_reset_block_generic,
26658 @@ -1471,7 +1472,7 @@ static struct e1000_phy_operations es2_p
26659 .cfg_on_link_up = e1000_cfg_on_link_up_80003es2lan,
26660 };
26661
26662 -static struct e1000_nvm_operations es2_nvm_ops = {
26663 +static const struct e1000_nvm_operations es2_nvm_ops = {
26664 .acquire = e1000_acquire_nvm_80003es2lan,
26665 .read = e1000e_read_nvm_eerd,
26666 .release = e1000_release_nvm_80003es2lan,
26667 diff -urNp linux-2.6.36/drivers/net/e1000e/hw.h linux-2.6.36/drivers/net/e1000e/hw.h
26668 --- linux-2.6.36/drivers/net/e1000e/hw.h 2010-10-20 16:30:22.000000000 -0400
26669 +++ linux-2.6.36/drivers/net/e1000e/hw.h 2010-11-06 18:58:15.000000000 -0400
26670 @@ -800,13 +800,13 @@ struct e1000_phy_operations {
26671
26672 /* Function pointers for the NVM. */
26673 struct e1000_nvm_operations {
26674 - s32 (*acquire)(struct e1000_hw *);
26675 - s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
26676 - void (*release)(struct e1000_hw *);
26677 - s32 (*update)(struct e1000_hw *);
26678 - s32 (*valid_led_default)(struct e1000_hw *, u16 *);
26679 - s32 (*validate)(struct e1000_hw *);
26680 - s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
26681 + s32 (* const acquire)(struct e1000_hw *);
26682 + s32 (* const read)(struct e1000_hw *, u16, u16, u16 *);
26683 + void (* const release)(struct e1000_hw *);
26684 + s32 (* const update)(struct e1000_hw *);
26685 + s32 (* const valid_led_default)(struct e1000_hw *, u16 *);
26686 + s32 (* const validate)(struct e1000_hw *);
26687 + s32 (* const write)(struct e1000_hw *, u16, u16, u16 *);
26688 };
26689
26690 struct e1000_mac_info {
26691 @@ -886,6 +886,7 @@ struct e1000_phy_info {
26692 };
26693
26694 struct e1000_nvm_info {
26695 + /* cannot be const */
26696 struct e1000_nvm_operations ops;
26697
26698 enum e1000_nvm_type type;
26699 diff -urNp linux-2.6.36/drivers/net/e1000e/ich8lan.c linux-2.6.36/drivers/net/e1000e/ich8lan.c
26700 --- linux-2.6.36/drivers/net/e1000e/ich8lan.c 2010-10-20 16:30:22.000000000 -0400
26701 +++ linux-2.6.36/drivers/net/e1000e/ich8lan.c 2010-11-06 18:58:15.000000000 -0400
26702 @@ -3856,7 +3856,7 @@ static void e1000_clear_hw_cntrs_ich8lan
26703 }
26704 }
26705
26706 -static struct e1000_mac_operations ich8_mac_ops = {
26707 +static const struct e1000_mac_operations ich8_mac_ops = {
26708 .id_led_init = e1000e_id_led_init,
26709 /* check_mng_mode dependent on mac type */
26710 .check_for_link = e1000_check_for_copper_link_ich8lan,
26711 @@ -3875,7 +3875,7 @@ static struct e1000_mac_operations ich8_
26712 /* id_led_init dependent on mac type */
26713 };
26714
26715 -static struct e1000_phy_operations ich8_phy_ops = {
26716 +static const struct e1000_phy_operations ich8_phy_ops = {
26717 .acquire = e1000_acquire_swflag_ich8lan,
26718 .check_reset_block = e1000_check_reset_block_ich8lan,
26719 .commit = NULL,
26720 @@ -3889,7 +3889,7 @@ static struct e1000_phy_operations ich8_
26721 .write_reg = e1000e_write_phy_reg_igp,
26722 };
26723
26724 -static struct e1000_nvm_operations ich8_nvm_ops = {
26725 +static const struct e1000_nvm_operations ich8_nvm_ops = {
26726 .acquire = e1000_acquire_nvm_ich8lan,
26727 .read = e1000_read_nvm_ich8lan,
26728 .release = e1000_release_nvm_ich8lan,
26729 diff -urNp linux-2.6.36/drivers/net/eql.c linux-2.6.36/drivers/net/eql.c
26730 --- linux-2.6.36/drivers/net/eql.c 2010-10-20 16:30:22.000000000 -0400
26731 +++ linux-2.6.36/drivers/net/eql.c 2010-11-06 18:58:50.000000000 -0400
26732 @@ -555,7 +555,7 @@ static int eql_g_master_cfg(struct net_d
26733 equalizer_t *eql;
26734 master_config_t mc;
26735
26736 - memset(&mc, 0, sizeof(master_config_t));
26737 + memset(&mc, 0, sizeof(mc));
26738
26739 if (eql_is_master(dev)) {
26740 eql = netdev_priv(dev);
26741 diff -urNp linux-2.6.36/drivers/net/igb/e1000_82575.c linux-2.6.36/drivers/net/igb/e1000_82575.c
26742 --- linux-2.6.36/drivers/net/igb/e1000_82575.c 2010-10-20 16:30:22.000000000 -0400
26743 +++ linux-2.6.36/drivers/net/igb/e1000_82575.c 2010-11-06 18:58:15.000000000 -0400
26744 @@ -1698,7 +1698,7 @@ u16 igb_rxpbs_adjust_82580(u32 data)
26745 return ret_val;
26746 }
26747
26748 -static struct e1000_mac_operations e1000_mac_ops_82575 = {
26749 +static const struct e1000_mac_operations e1000_mac_ops_82575 = {
26750 .init_hw = igb_init_hw_82575,
26751 .check_for_link = igb_check_for_link_82575,
26752 .rar_set = igb_rar_set,
26753 @@ -1706,13 +1706,13 @@ static struct e1000_mac_operations e1000
26754 .get_speed_and_duplex = igb_get_speed_and_duplex_copper,
26755 };
26756
26757 -static struct e1000_phy_operations e1000_phy_ops_82575 = {
26758 +static const struct e1000_phy_operations e1000_phy_ops_82575 = {
26759 .acquire = igb_acquire_phy_82575,
26760 .get_cfg_done = igb_get_cfg_done_82575,
26761 .release = igb_release_phy_82575,
26762 };
26763
26764 -static struct e1000_nvm_operations e1000_nvm_ops_82575 = {
26765 +static const struct e1000_nvm_operations e1000_nvm_ops_82575 = {
26766 .acquire = igb_acquire_nvm_82575,
26767 .read = igb_read_nvm_eerd,
26768 .release = igb_release_nvm_82575,
26769 diff -urNp linux-2.6.36/drivers/net/igb/e1000_hw.h linux-2.6.36/drivers/net/igb/e1000_hw.h
26770 --- linux-2.6.36/drivers/net/igb/e1000_hw.h 2010-10-20 16:30:22.000000000 -0400
26771 +++ linux-2.6.36/drivers/net/igb/e1000_hw.h 2010-11-06 18:58:15.000000000 -0400
26772 @@ -323,17 +323,17 @@ struct e1000_phy_operations {
26773 };
26774
26775 struct e1000_nvm_operations {
26776 - s32 (*acquire)(struct e1000_hw *);
26777 - s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
26778 - void (*release)(struct e1000_hw *);
26779 - s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
26780 + s32 (* const acquire)(struct e1000_hw *);
26781 + s32 (* const read)(struct e1000_hw *, u16, u16, u16 *);
26782 + void (* const release)(struct e1000_hw *);
26783 + s32 (* const write)(struct e1000_hw *, u16, u16, u16 *);
26784 };
26785
26786 struct e1000_info {
26787 s32 (*get_invariants)(struct e1000_hw *);
26788 - struct e1000_mac_operations *mac_ops;
26789 - struct e1000_phy_operations *phy_ops;
26790 - struct e1000_nvm_operations *nvm_ops;
26791 + const struct e1000_mac_operations *mac_ops;
26792 + const struct e1000_phy_operations *phy_ops;
26793 + const struct e1000_nvm_operations *nvm_ops;
26794 };
26795
26796 extern const struct e1000_info e1000_82575_info;
26797 @@ -412,6 +412,7 @@ struct e1000_phy_info {
26798 };
26799
26800 struct e1000_nvm_info {
26801 + /* cannot be const */
26802 struct e1000_nvm_operations ops;
26803
26804 enum e1000_nvm_type type;
26805 diff -urNp linux-2.6.36/drivers/net/irda/vlsi_ir.c linux-2.6.36/drivers/net/irda/vlsi_ir.c
26806 --- linux-2.6.36/drivers/net/irda/vlsi_ir.c 2010-10-20 16:30:22.000000000 -0400
26807 +++ linux-2.6.36/drivers/net/irda/vlsi_ir.c 2010-11-06 18:58:15.000000000 -0400
26808 @@ -907,13 +907,12 @@ static netdev_tx_t vlsi_hard_start_xmit(
26809 /* no race - tx-ring already empty */
26810 vlsi_set_baud(idev, iobase);
26811 netif_wake_queue(ndev);
26812 - }
26813 - else
26814 - ;
26815 + } else {
26816 /* keep the speed change pending like it would
26817 * for any len>0 packet. tx completion interrupt
26818 * will apply it when the tx ring becomes empty.
26819 */
26820 + }
26821 spin_unlock_irqrestore(&idev->lock, flags);
26822 dev_kfree_skb_any(skb);
26823 return NETDEV_TX_OK;
26824 diff -urNp linux-2.6.36/drivers/net/pcnet32.c linux-2.6.36/drivers/net/pcnet32.c
26825 --- linux-2.6.36/drivers/net/pcnet32.c 2010-10-20 16:30:22.000000000 -0400
26826 +++ linux-2.6.36/drivers/net/pcnet32.c 2010-11-06 18:58:15.000000000 -0400
26827 @@ -82,7 +82,7 @@ static int cards_found;
26828 /*
26829 * VLB I/O addresses
26830 */
26831 -static unsigned int pcnet32_portlist[] __initdata =
26832 +static unsigned int pcnet32_portlist[] __devinitdata =
26833 { 0x300, 0x320, 0x340, 0x360, 0 };
26834
26835 static int pcnet32_debug;
26836 diff -urNp linux-2.6.36/drivers/net/ppp_generic.c linux-2.6.36/drivers/net/ppp_generic.c
26837 --- linux-2.6.36/drivers/net/ppp_generic.c 2010-10-20 16:30:22.000000000 -0400
26838 +++ linux-2.6.36/drivers/net/ppp_generic.c 2010-11-06 18:58:15.000000000 -0400
26839 @@ -985,7 +985,6 @@ ppp_net_ioctl(struct net_device *dev, st
26840 void __user *addr = (void __user *) ifr->ifr_ifru.ifru_data;
26841 struct ppp_stats stats;
26842 struct ppp_comp_stats cstats;
26843 - char *vers;
26844
26845 switch (cmd) {
26846 case SIOCGPPPSTATS:
26847 @@ -1007,8 +1006,7 @@ ppp_net_ioctl(struct net_device *dev, st
26848 break;
26849
26850 case SIOCGPPPVER:
26851 - vers = PPP_VERSION;
26852 - if (copy_to_user(addr, vers, strlen(vers) + 1))
26853 + if (copy_to_user(addr, PPP_VERSION, sizeof(PPP_VERSION)))
26854 break;
26855 err = 0;
26856 break;
26857 diff -urNp linux-2.6.36/drivers/net/tg3.c linux-2.6.36/drivers/net/tg3.c
26858 --- linux-2.6.36/drivers/net/tg3.c 2010-10-20 16:30:22.000000000 -0400
26859 +++ linux-2.6.36/drivers/net/tg3.c 2010-11-06 18:58:15.000000000 -0400
26860 @@ -12433,7 +12433,7 @@ static void __devinit tg3_read_vpd(struc
26861 cnt = pci_read_vpd(tp->pdev, pos,
26862 TG3_NVM_VPD_LEN - pos,
26863 &vpd_data[pos]);
26864 - if (cnt == -ETIMEDOUT || -EINTR)
26865 + if (cnt == -ETIMEDOUT || cnt == -EINTR)
26866 cnt = 0;
26867 else if (cnt < 0)
26868 goto out_not_found;
26869 diff -urNp linux-2.6.36/drivers/net/tg3.h linux-2.6.36/drivers/net/tg3.h
26870 --- linux-2.6.36/drivers/net/tg3.h 2010-10-20 16:30:22.000000000 -0400
26871 +++ linux-2.6.36/drivers/net/tg3.h 2010-11-06 18:58:15.000000000 -0400
26872 @@ -131,6 +131,7 @@
26873 #define CHIPREV_ID_5750_A0 0x4000
26874 #define CHIPREV_ID_5750_A1 0x4001
26875 #define CHIPREV_ID_5750_A3 0x4003
26876 +#define CHIPREV_ID_5750_C1 0x4201
26877 #define CHIPREV_ID_5750_C2 0x4202
26878 #define CHIPREV_ID_5752_A0_HW 0x5000
26879 #define CHIPREV_ID_5752_A0 0x6000
26880 diff -urNp linux-2.6.36/drivers/net/tulip/de4x5.c linux-2.6.36/drivers/net/tulip/de4x5.c
26881 --- linux-2.6.36/drivers/net/tulip/de4x5.c 2010-10-20 16:30:22.000000000 -0400
26882 +++ linux-2.6.36/drivers/net/tulip/de4x5.c 2010-11-06 18:58:50.000000000 -0400
26883 @@ -5401,7 +5401,7 @@ de4x5_ioctl(struct net_device *dev, stru
26884 for (i=0; i<ETH_ALEN; i++) {
26885 tmp.addr[i] = dev->dev_addr[i];
26886 }
26887 - if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
26888 + if (ioc->len > sizeof(tmp.addr) || copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
26889 break;
26890
26891 case DE4X5_SET_HWADDR: /* Set the hardware address */
26892 @@ -5441,7 +5441,7 @@ de4x5_ioctl(struct net_device *dev, stru
26893 spin_lock_irqsave(&lp->lock, flags);
26894 memcpy(&statbuf, &lp->pktStats, ioc->len);
26895 spin_unlock_irqrestore(&lp->lock, flags);
26896 - if (copy_to_user(ioc->data, &statbuf, ioc->len))
26897 + if (ioc->len > sizeof(statbuf) || copy_to_user(ioc->data, &statbuf, ioc->len))
26898 return -EFAULT;
26899 break;
26900 }
26901 @@ -5474,7 +5474,7 @@ de4x5_ioctl(struct net_device *dev, stru
26902 tmp.lval[6] = inl(DE4X5_STRR); j+=4;
26903 tmp.lval[7] = inl(DE4X5_SIGR); j+=4;
26904 ioc->len = j;
26905 - if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
26906 + if (copy_to_user(ioc->data, tmp.lval, ioc->len)) return -EFAULT;
26907 break;
26908
26909 #define DE4X5_DUMP 0x0f /* Dump the DE4X5 Status */
26910 diff -urNp linux-2.6.36/drivers/net/usb/hso.c linux-2.6.36/drivers/net/usb/hso.c
26911 --- linux-2.6.36/drivers/net/usb/hso.c 2010-10-20 16:30:22.000000000 -0400
26912 +++ linux-2.6.36/drivers/net/usb/hso.c 2010-11-06 18:58:50.000000000 -0400
26913 @@ -257,7 +257,7 @@ struct hso_serial {
26914
26915 /* from usb_serial_port */
26916 struct tty_struct *tty;
26917 - int open_count;
26918 + atomic_t open_count;
26919 spinlock_t serial_lock;
26920
26921 int (*write_data) (struct hso_serial *serial);
26922 @@ -1200,7 +1200,7 @@ static void put_rxbuf_data_and_resubmit_
26923 struct urb *urb;
26924
26925 urb = serial->rx_urb[0];
26926 - if (serial->open_count > 0) {
26927 + if (atomic_read(&serial->open_count) > 0) {
26928 count = put_rxbuf_data(urb, serial);
26929 if (count == -1)
26930 return;
26931 @@ -1236,7 +1236,7 @@ static void hso_std_serial_read_bulk_cal
26932 DUMP1(urb->transfer_buffer, urb->actual_length);
26933
26934 /* Anyone listening? */
26935 - if (serial->open_count == 0)
26936 + if (atomic_read(&serial->open_count) == 0)
26937 return;
26938
26939 if (status == 0) {
26940 @@ -1331,8 +1331,7 @@ static int hso_serial_open(struct tty_st
26941 spin_unlock_irq(&serial->serial_lock);
26942
26943 /* check for port already opened, if not set the termios */
26944 - serial->open_count++;
26945 - if (serial->open_count == 1) {
26946 + if (atomic_inc_return(&serial->open_count) == 1) {
26947 serial->rx_state = RX_IDLE;
26948 /* Force default termio settings */
26949 _hso_serial_set_termios(tty, NULL);
26950 @@ -1344,7 +1343,7 @@ static int hso_serial_open(struct tty_st
26951 result = hso_start_serial_device(serial->parent, GFP_KERNEL);
26952 if (result) {
26953 hso_stop_serial_device(serial->parent);
26954 - serial->open_count--;
26955 + atomic_dec(&serial->open_count);
26956 kref_put(&serial->parent->ref, hso_serial_ref_free);
26957 }
26958 } else {
26959 @@ -1381,10 +1380,10 @@ static void hso_serial_close(struct tty_
26960
26961 /* reset the rts and dtr */
26962 /* do the actual close */
26963 - serial->open_count--;
26964 + atomic_dec(&serial->open_count);
26965
26966 - if (serial->open_count <= 0) {
26967 - serial->open_count = 0;
26968 + if (atomic_read(&serial->open_count) <= 0) {
26969 + atomic_set(&serial->open_count, 0);
26970 spin_lock_irq(&serial->serial_lock);
26971 if (serial->tty == tty) {
26972 serial->tty->driver_data = NULL;
26973 @@ -1466,7 +1465,7 @@ static void hso_serial_set_termios(struc
26974
26975 /* the actual setup */
26976 spin_lock_irqsave(&serial->serial_lock, flags);
26977 - if (serial->open_count)
26978 + if (atomic_read(&serial->open_count))
26979 _hso_serial_set_termios(tty, old);
26980 else
26981 tty->termios = old;
26982 @@ -1652,10 +1651,11 @@ static int hso_get_count(struct hso_seri
26983 struct uart_icount cnow;
26984 struct hso_tiocmget *tiocmget = serial->tiocmget;
26985
26986 - memset(&icount, 0, sizeof(struct serial_icounter_struct));
26987 -
26988 if (!tiocmget)
26989 return -ENOENT;
26990 +
26991 + memset(&icount, 0, sizeof(icount));
26992 +
26993 spin_lock_irq(&serial->serial_lock);
26994 memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount));
26995 spin_unlock_irq(&serial->serial_lock);
26996 @@ -1930,7 +1930,7 @@ static void intr_callback(struct urb *ur
26997 D1("Pending read interrupt on port %d\n", i);
26998 spin_lock(&serial->serial_lock);
26999 if (serial->rx_state == RX_IDLE &&
27000 - serial->open_count > 0) {
27001 + atomic_read(&serial->open_count) > 0) {
27002 /* Setup and send a ctrl req read on
27003 * port i */
27004 if (!serial->rx_urb_filled[0]) {
27005 @@ -3120,7 +3120,7 @@ static int hso_resume(struct usb_interfa
27006 /* Start all serial ports */
27007 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
27008 if (serial_table[i] && (serial_table[i]->interface == iface)) {
27009 - if (dev2ser(serial_table[i])->open_count) {
27010 + if (atomic_read(&dev2ser(serial_table[i])->open_count)) {
27011 result =
27012 hso_start_serial_device(serial_table[i], GFP_NOIO);
27013 hso_kick_transmit(dev2ser(serial_table[i]));
27014 diff -urNp linux-2.6.36/drivers/net/wireless/b43/debugfs.c linux-2.6.36/drivers/net/wireless/b43/debugfs.c
27015 --- linux-2.6.36/drivers/net/wireless/b43/debugfs.c 2010-10-20 16:30:22.000000000 -0400
27016 +++ linux-2.6.36/drivers/net/wireless/b43/debugfs.c 2010-11-06 18:58:15.000000000 -0400
27017 @@ -43,7 +43,7 @@ static struct dentry *rootdir;
27018 struct b43_debugfs_fops {
27019 ssize_t (*read)(struct b43_wldev *dev, char *buf, size_t bufsize);
27020 int (*write)(struct b43_wldev *dev, const char *buf, size_t count);
27021 - struct file_operations fops;
27022 + const struct file_operations fops;
27023 /* Offset of struct b43_dfs_file in struct b43_dfsentry */
27024 size_t file_struct_offset;
27025 };
27026 diff -urNp linux-2.6.36/drivers/net/wireless/b43legacy/debugfs.c linux-2.6.36/drivers/net/wireless/b43legacy/debugfs.c
27027 --- linux-2.6.36/drivers/net/wireless/b43legacy/debugfs.c 2010-10-20 16:30:22.000000000 -0400
27028 +++ linux-2.6.36/drivers/net/wireless/b43legacy/debugfs.c 2010-11-06 18:58:15.000000000 -0400
27029 @@ -44,7 +44,7 @@ static struct dentry *rootdir;
27030 struct b43legacy_debugfs_fops {
27031 ssize_t (*read)(struct b43legacy_wldev *dev, char *buf, size_t bufsize);
27032 int (*write)(struct b43legacy_wldev *dev, const char *buf, size_t count);
27033 - struct file_operations fops;
27034 + const struct file_operations fops;
27035 /* Offset of struct b43legacy_dfs_file in struct b43legacy_dfsentry */
27036 size_t file_struct_offset;
27037 /* Take wl->irq_lock before calling read/write? */
27038 diff -urNp linux-2.6.36/drivers/net/wireless/iwlwifi/iwl-debug.h linux-2.6.36/drivers/net/wireless/iwlwifi/iwl-debug.h
27039 --- linux-2.6.36/drivers/net/wireless/iwlwifi/iwl-debug.h 2010-10-20 16:30:22.000000000 -0400
27040 +++ linux-2.6.36/drivers/net/wireless/iwlwifi/iwl-debug.h 2010-11-06 18:58:15.000000000 -0400
27041 @@ -68,8 +68,8 @@ do {
27042 } while (0)
27043
27044 #else
27045 -#define IWL_DEBUG(__priv, level, fmt, args...)
27046 -#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
27047 +#define IWL_DEBUG(__priv, level, fmt, args...) do {} while (0)
27048 +#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) do {} while (0)
27049 static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
27050 const void *p, u32 len)
27051 {}
27052 diff -urNp linux-2.6.36/drivers/net/wireless/libertas/debugfs.c linux-2.6.36/drivers/net/wireless/libertas/debugfs.c
27053 --- linux-2.6.36/drivers/net/wireless/libertas/debugfs.c 2010-10-20 16:30:22.000000000 -0400
27054 +++ linux-2.6.36/drivers/net/wireless/libertas/debugfs.c 2010-11-06 18:58:15.000000000 -0400
27055 @@ -701,7 +701,7 @@ out_unlock:
27056 struct lbs_debugfs_files {
27057 const char *name;
27058 int perm;
27059 - struct file_operations fops;
27060 + const struct file_operations fops;
27061 };
27062
27063 static const struct lbs_debugfs_files debugfs_files[] = {
27064 diff -urNp linux-2.6.36/drivers/net/wireless/rndis_wlan.c linux-2.6.36/drivers/net/wireless/rndis_wlan.c
27065 --- linux-2.6.36/drivers/net/wireless/rndis_wlan.c 2010-10-20 16:30:22.000000000 -0400
27066 +++ linux-2.6.36/drivers/net/wireless/rndis_wlan.c 2010-11-06 18:58:15.000000000 -0400
27067 @@ -1236,7 +1236,7 @@ static int set_rts_threshold(struct usbn
27068
27069 netdev_dbg(usbdev->net, "%s(): %i\n", __func__, rts_threshold);
27070
27071 - if (rts_threshold < 0 || rts_threshold > 2347)
27072 + if (rts_threshold > 2347)
27073 rts_threshold = 2347;
27074
27075 tmp = cpu_to_le32(rts_threshold);
27076 diff -urNp linux-2.6.36/drivers/oprofile/buffer_sync.c linux-2.6.36/drivers/oprofile/buffer_sync.c
27077 --- linux-2.6.36/drivers/oprofile/buffer_sync.c 2010-10-20 16:30:22.000000000 -0400
27078 +++ linux-2.6.36/drivers/oprofile/buffer_sync.c 2010-11-06 18:58:15.000000000 -0400
27079 @@ -342,7 +342,7 @@ static void add_data(struct op_entry *en
27080 if (cookie == NO_COOKIE)
27081 offset = pc;
27082 if (cookie == INVALID_COOKIE) {
27083 - atomic_inc(&oprofile_stats.sample_lost_no_mapping);
27084 + atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
27085 offset = pc;
27086 }
27087 if (cookie != last_cookie) {
27088 @@ -386,14 +386,14 @@ add_sample(struct mm_struct *mm, struct
27089 /* add userspace sample */
27090
27091 if (!mm) {
27092 - atomic_inc(&oprofile_stats.sample_lost_no_mm);
27093 + atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mm);
27094 return 0;
27095 }
27096
27097 cookie = lookup_dcookie(mm, s->eip, &offset);
27098
27099 if (cookie == INVALID_COOKIE) {
27100 - atomic_inc(&oprofile_stats.sample_lost_no_mapping);
27101 + atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
27102 return 0;
27103 }
27104
27105 @@ -562,7 +562,7 @@ void sync_buffer(int cpu)
27106 /* ignore backtraces if failed to add a sample */
27107 if (state == sb_bt_start) {
27108 state = sb_bt_ignore;
27109 - atomic_inc(&oprofile_stats.bt_lost_no_mapping);
27110 + atomic_inc_unchecked(&oprofile_stats.bt_lost_no_mapping);
27111 }
27112 }
27113 release_mm(mm);
27114 diff -urNp linux-2.6.36/drivers/oprofile/event_buffer.c linux-2.6.36/drivers/oprofile/event_buffer.c
27115 --- linux-2.6.36/drivers/oprofile/event_buffer.c 2010-10-20 16:30:22.000000000 -0400
27116 +++ linux-2.6.36/drivers/oprofile/event_buffer.c 2010-11-06 18:58:15.000000000 -0400
27117 @@ -53,7 +53,7 @@ void add_event_entry(unsigned long value
27118 }
27119
27120 if (buffer_pos == buffer_size) {
27121 - atomic_inc(&oprofile_stats.event_lost_overflow);
27122 + atomic_inc_unchecked(&oprofile_stats.event_lost_overflow);
27123 return;
27124 }
27125
27126 diff -urNp linux-2.6.36/drivers/oprofile/oprof.c linux-2.6.36/drivers/oprofile/oprof.c
27127 --- linux-2.6.36/drivers/oprofile/oprof.c 2010-10-20 16:30:22.000000000 -0400
27128 +++ linux-2.6.36/drivers/oprofile/oprof.c 2010-11-06 18:58:15.000000000 -0400
27129 @@ -110,7 +110,7 @@ static void switch_worker(struct work_st
27130 if (oprofile_ops.switch_events())
27131 return;
27132
27133 - atomic_inc(&oprofile_stats.multiplex_counter);
27134 + atomic_inc_unchecked(&oprofile_stats.multiplex_counter);
27135 start_switch_worker();
27136 }
27137
27138 diff -urNp linux-2.6.36/drivers/oprofile/oprofilefs.c linux-2.6.36/drivers/oprofile/oprofilefs.c
27139 --- linux-2.6.36/drivers/oprofile/oprofilefs.c 2010-10-20 16:30:22.000000000 -0400
27140 +++ linux-2.6.36/drivers/oprofile/oprofilefs.c 2010-11-06 18:58:15.000000000 -0400
27141 @@ -187,7 +187,7 @@ static const struct file_operations atom
27142
27143
27144 int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root,
27145 - char const *name, atomic_t *val)
27146 + char const *name, atomic_unchecked_t *val)
27147 {
27148 struct dentry *d = __oprofilefs_create_file(sb, root, name,
27149 &atomic_ro_fops, 0444);
27150 diff -urNp linux-2.6.36/drivers/oprofile/oprofile_stats.c linux-2.6.36/drivers/oprofile/oprofile_stats.c
27151 --- linux-2.6.36/drivers/oprofile/oprofile_stats.c 2010-10-20 16:30:22.000000000 -0400
27152 +++ linux-2.6.36/drivers/oprofile/oprofile_stats.c 2010-11-06 18:58:15.000000000 -0400
27153 @@ -30,11 +30,11 @@ void oprofile_reset_stats(void)
27154 cpu_buf->sample_invalid_eip = 0;
27155 }
27156
27157 - atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
27158 - atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
27159 - atomic_set(&oprofile_stats.event_lost_overflow, 0);
27160 - atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
27161 - atomic_set(&oprofile_stats.multiplex_counter, 0);
27162 + atomic_set_unchecked(&oprofile_stats.sample_lost_no_mm, 0);
27163 + atomic_set_unchecked(&oprofile_stats.sample_lost_no_mapping, 0);
27164 + atomic_set_unchecked(&oprofile_stats.event_lost_overflow, 0);
27165 + atomic_set_unchecked(&oprofile_stats.bt_lost_no_mapping, 0);
27166 + atomic_set_unchecked(&oprofile_stats.multiplex_counter, 0);
27167 }
27168
27169
27170 diff -urNp linux-2.6.36/drivers/oprofile/oprofile_stats.h linux-2.6.36/drivers/oprofile/oprofile_stats.h
27171 --- linux-2.6.36/drivers/oprofile/oprofile_stats.h 2010-10-20 16:30:22.000000000 -0400
27172 +++ linux-2.6.36/drivers/oprofile/oprofile_stats.h 2010-11-06 18:58:15.000000000 -0400
27173 @@ -13,11 +13,11 @@
27174 #include <asm/atomic.h>
27175
27176 struct oprofile_stat_struct {
27177 - atomic_t sample_lost_no_mm;
27178 - atomic_t sample_lost_no_mapping;
27179 - atomic_t bt_lost_no_mapping;
27180 - atomic_t event_lost_overflow;
27181 - atomic_t multiplex_counter;
27182 + atomic_unchecked_t sample_lost_no_mm;
27183 + atomic_unchecked_t sample_lost_no_mapping;
27184 + atomic_unchecked_t bt_lost_no_mapping;
27185 + atomic_unchecked_t event_lost_overflow;
27186 + atomic_unchecked_t multiplex_counter;
27187 };
27188
27189 extern struct oprofile_stat_struct oprofile_stats;
27190 diff -urNp linux-2.6.36/drivers/parport/procfs.c linux-2.6.36/drivers/parport/procfs.c
27191 --- linux-2.6.36/drivers/parport/procfs.c 2010-10-20 16:30:22.000000000 -0400
27192 +++ linux-2.6.36/drivers/parport/procfs.c 2010-11-06 18:58:50.000000000 -0400
27193 @@ -64,7 +64,7 @@ static int do_active_device(ctl_table *t
27194
27195 *ppos += len;
27196
27197 - return copy_to_user(result, buffer, len) ? -EFAULT : 0;
27198 + return (len > sizeof(buffer) || copy_to_user(result, buffer, len)) ? -EFAULT : 0;
27199 }
27200
27201 #ifdef CONFIG_PARPORT_1284
27202 @@ -106,7 +106,7 @@ static int do_autoprobe(ctl_table *table
27203
27204 *ppos += len;
27205
27206 - return copy_to_user (result, buffer, len) ? -EFAULT : 0;
27207 + return (len > sizeof(buffer) || copy_to_user (result, buffer, len)) ? -EFAULT : 0;
27208 }
27209 #endif /* IEEE1284.3 support. */
27210
27211 diff -urNp linux-2.6.36/drivers/pci/hotplug/acpiphp_glue.c linux-2.6.36/drivers/pci/hotplug/acpiphp_glue.c
27212 --- linux-2.6.36/drivers/pci/hotplug/acpiphp_glue.c 2010-10-20 16:30:22.000000000 -0400
27213 +++ linux-2.6.36/drivers/pci/hotplug/acpiphp_glue.c 2010-11-06 18:58:15.000000000 -0400
27214 @@ -110,7 +110,7 @@ static int post_dock_fixups(struct notif
27215 }
27216
27217
27218 -static struct acpi_dock_ops acpiphp_dock_ops = {
27219 +static const struct acpi_dock_ops acpiphp_dock_ops = {
27220 .handler = handle_hotplug_event_func,
27221 };
27222
27223 diff -urNp linux-2.6.36/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.36/drivers/pci/hotplug/cpqphp_nvram.c
27224 --- linux-2.6.36/drivers/pci/hotplug/cpqphp_nvram.c 2010-10-20 16:30:22.000000000 -0400
27225 +++ linux-2.6.36/drivers/pci/hotplug/cpqphp_nvram.c 2010-11-06 18:58:15.000000000 -0400
27226 @@ -428,9 +428,13 @@ static u32 store_HRT (void __iomem *rom_
27227
27228 void compaq_nvram_init (void __iomem *rom_start)
27229 {
27230 +
27231 +#ifndef CONFIG_PAX_KERNEXEC
27232 if (rom_start) {
27233 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
27234 }
27235 +#endif
27236 +
27237 dbg("int15 entry = %p\n", compaq_int15_entry_point);
27238
27239 /* initialize our int15 lock */
27240 diff -urNp linux-2.6.36/drivers/pci/intel-iommu.c linux-2.6.36/drivers/pci/intel-iommu.c
27241 --- linux-2.6.36/drivers/pci/intel-iommu.c 2010-10-20 16:30:22.000000000 -0400
27242 +++ linux-2.6.36/drivers/pci/intel-iommu.c 2010-11-06 18:58:15.000000000 -0400
27243 @@ -2934,7 +2934,7 @@ static int intel_mapping_error(struct de
27244 return !dma_addr;
27245 }
27246
27247 -struct dma_map_ops intel_dma_ops = {
27248 +const struct dma_map_ops intel_dma_ops = {
27249 .alloc_coherent = intel_alloc_coherent,
27250 .free_coherent = intel_free_coherent,
27251 .map_sg = intel_map_sg,
27252 diff -urNp linux-2.6.36/drivers/pci/pcie/portdrv_pci.c linux-2.6.36/drivers/pci/pcie/portdrv_pci.c
27253 --- linux-2.6.36/drivers/pci/pcie/portdrv_pci.c 2010-10-20 16:30:22.000000000 -0400
27254 +++ linux-2.6.36/drivers/pci/pcie/portdrv_pci.c 2010-11-06 18:58:15.000000000 -0400
27255 @@ -276,7 +276,7 @@ static void pcie_portdrv_err_resume(stru
27256 static const struct pci_device_id port_pci_ids[] = { {
27257 /* handle any PCI-Express port */
27258 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
27259 - }, { /* end: all zeroes */ }
27260 + }, { 0, 0, 0, 0, 0, 0, 0 }
27261 };
27262 MODULE_DEVICE_TABLE(pci, port_pci_ids);
27263
27264 diff -urNp linux-2.6.36/drivers/pci/probe.c linux-2.6.36/drivers/pci/probe.c
27265 --- linux-2.6.36/drivers/pci/probe.c 2010-10-20 16:30:22.000000000 -0400
27266 +++ linux-2.6.36/drivers/pci/probe.c 2010-11-06 18:58:15.000000000 -0400
27267 @@ -62,14 +62,14 @@ static ssize_t pci_bus_show_cpuaffinity(
27268 return ret;
27269 }
27270
27271 -static ssize_t inline pci_bus_show_cpumaskaffinity(struct device *dev,
27272 +static inline ssize_t pci_bus_show_cpumaskaffinity(struct device *dev,
27273 struct device_attribute *attr,
27274 char *buf)
27275 {
27276 return pci_bus_show_cpuaffinity(dev, 0, attr, buf);
27277 }
27278
27279 -static ssize_t inline pci_bus_show_cpulistaffinity(struct device *dev,
27280 +static inline ssize_t pci_bus_show_cpulistaffinity(struct device *dev,
27281 struct device_attribute *attr,
27282 char *buf)
27283 {
27284 diff -urNp linux-2.6.36/drivers/pci/proc.c linux-2.6.36/drivers/pci/proc.c
27285 --- linux-2.6.36/drivers/pci/proc.c 2010-10-20 16:30:22.000000000 -0400
27286 +++ linux-2.6.36/drivers/pci/proc.c 2010-11-06 18:58:50.000000000 -0400
27287 @@ -479,7 +479,16 @@ static const struct file_operations proc
27288 static int __init pci_proc_init(void)
27289 {
27290 struct pci_dev *dev = NULL;
27291 +
27292 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
27293 +#ifdef CONFIG_GRKERNSEC_PROC_USER
27294 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
27295 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
27296 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
27297 +#endif
27298 +#else
27299 proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
27300 +#endif
27301 proc_create("devices", 0, proc_bus_pci_dir,
27302 &proc_bus_pci_dev_operations);
27303 proc_initialized = 1;
27304 diff -urNp linux-2.6.36/drivers/pcmcia/ti113x.h linux-2.6.36/drivers/pcmcia/ti113x.h
27305 --- linux-2.6.36/drivers/pcmcia/ti113x.h 2010-10-20 16:30:22.000000000 -0400
27306 +++ linux-2.6.36/drivers/pcmcia/ti113x.h 2010-11-06 18:58:15.000000000 -0400
27307 @@ -936,7 +936,7 @@ static struct pci_device_id ene_tune_tbl
27308 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
27309 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
27310
27311 - {}
27312 + { 0, 0, 0, 0, 0, 0, 0 }
27313 };
27314
27315 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
27316 diff -urNp linux-2.6.36/drivers/pcmcia/yenta_socket.c linux-2.6.36/drivers/pcmcia/yenta_socket.c
27317 --- linux-2.6.36/drivers/pcmcia/yenta_socket.c 2010-10-20 16:30:22.000000000 -0400
27318 +++ linux-2.6.36/drivers/pcmcia/yenta_socket.c 2010-11-06 18:58:15.000000000 -0400
27319 @@ -1427,7 +1427,7 @@ static struct pci_device_id yenta_table[
27320
27321 /* match any cardbus bridge */
27322 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
27323 - { /* all zeroes */ }
27324 + { 0, 0, 0, 0, 0, 0, 0 }
27325 };
27326 MODULE_DEVICE_TABLE(pci, yenta_table);
27327
27328 diff -urNp linux-2.6.36/drivers/platform/x86/acer-wmi.c linux-2.6.36/drivers/platform/x86/acer-wmi.c
27329 --- linux-2.6.36/drivers/platform/x86/acer-wmi.c 2010-10-20 16:30:22.000000000 -0400
27330 +++ linux-2.6.36/drivers/platform/x86/acer-wmi.c 2010-11-06 18:58:15.000000000 -0400
27331 @@ -915,7 +915,7 @@ static int update_bl_status(struct backl
27332 return 0;
27333 }
27334
27335 -static struct backlight_ops acer_bl_ops = {
27336 +static const struct backlight_ops acer_bl_ops = {
27337 .get_brightness = read_brightness,
27338 .update_status = update_bl_status,
27339 };
27340 diff -urNp linux-2.6.36/drivers/platform/x86/asus_acpi.c linux-2.6.36/drivers/platform/x86/asus_acpi.c
27341 --- linux-2.6.36/drivers/platform/x86/asus_acpi.c 2010-10-20 16:30:22.000000000 -0400
27342 +++ linux-2.6.36/drivers/platform/x86/asus_acpi.c 2010-11-06 18:58:15.000000000 -0400
27343 @@ -1467,7 +1467,7 @@ static int asus_hotk_remove(struct acpi_
27344 return 0;
27345 }
27346
27347 -static struct backlight_ops asus_backlight_data = {
27348 +static const struct backlight_ops asus_backlight_data = {
27349 .get_brightness = read_brightness,
27350 .update_status = set_brightness_status,
27351 };
27352 diff -urNp linux-2.6.36/drivers/platform/x86/asus-laptop.c linux-2.6.36/drivers/platform/x86/asus-laptop.c
27353 --- linux-2.6.36/drivers/platform/x86/asus-laptop.c 2010-10-20 16:30:22.000000000 -0400
27354 +++ linux-2.6.36/drivers/platform/x86/asus-laptop.c 2010-11-06 18:58:15.000000000 -0400
27355 @@ -224,7 +224,6 @@ struct asus_laptop {
27356 struct asus_led gled;
27357 struct asus_led kled;
27358 struct workqueue_struct *led_workqueue;
27359 -
27360 int wireless_status;
27361 bool have_rsts;
27362 int lcd_state;
27363 @@ -621,7 +620,7 @@ static int update_bl_status(struct backl
27364 return asus_lcd_set(asus, value);
27365 }
27366
27367 -static struct backlight_ops asusbl_ops = {
27368 +static const struct backlight_ops asusbl_ops = {
27369 .get_brightness = asus_read_brightness,
27370 .update_status = update_bl_status,
27371 };
27372 diff -urNp linux-2.6.36/drivers/platform/x86/dell-laptop.c linux-2.6.36/drivers/platform/x86/dell-laptop.c
27373 --- linux-2.6.36/drivers/platform/x86/dell-laptop.c 2010-10-20 16:30:22.000000000 -0400
27374 +++ linux-2.6.36/drivers/platform/x86/dell-laptop.c 2010-11-06 18:58:15.000000000 -0400
27375 @@ -475,7 +475,7 @@ out:
27376 return buffer->output[1];
27377 }
27378
27379 -static struct backlight_ops dell_ops = {
27380 +static const struct backlight_ops dell_ops = {
27381 .get_brightness = dell_get_intensity,
27382 .update_status = dell_send_intensity,
27383 };
27384 diff -urNp linux-2.6.36/drivers/platform/x86/eeepc-laptop.c linux-2.6.36/drivers/platform/x86/eeepc-laptop.c
27385 --- linux-2.6.36/drivers/platform/x86/eeepc-laptop.c 2010-10-20 16:30:22.000000000 -0400
27386 +++ linux-2.6.36/drivers/platform/x86/eeepc-laptop.c 2010-11-06 18:58:15.000000000 -0400
27387 @@ -1114,7 +1114,7 @@ static int update_bl_status(struct backl
27388 return set_brightness(bd, bd->props.brightness);
27389 }
27390
27391 -static struct backlight_ops eeepcbl_ops = {
27392 +static const struct backlight_ops eeepcbl_ops = {
27393 .get_brightness = read_brightness,
27394 .update_status = update_bl_status,
27395 };
27396 diff -urNp linux-2.6.36/drivers/platform/x86/fujitsu-laptop.c linux-2.6.36/drivers/platform/x86/fujitsu-laptop.c
27397 --- linux-2.6.36/drivers/platform/x86/fujitsu-laptop.c 2010-10-20 16:30:22.000000000 -0400
27398 +++ linux-2.6.36/drivers/platform/x86/fujitsu-laptop.c 2010-11-06 18:58:15.000000000 -0400
27399 @@ -437,7 +437,7 @@ static int bl_update_status(struct backl
27400 return ret;
27401 }
27402
27403 -static struct backlight_ops fujitsubl_ops = {
27404 +static const struct backlight_ops fujitsubl_ops = {
27405 .get_brightness = bl_get_brightness,
27406 .update_status = bl_update_status,
27407 };
27408 diff -urNp linux-2.6.36/drivers/platform/x86/sony-laptop.c linux-2.6.36/drivers/platform/x86/sony-laptop.c
27409 --- linux-2.6.36/drivers/platform/x86/sony-laptop.c 2010-10-20 16:30:22.000000000 -0400
27410 +++ linux-2.6.36/drivers/platform/x86/sony-laptop.c 2010-11-06 18:58:15.000000000 -0400
27411 @@ -856,7 +856,7 @@ static int sony_backlight_get_brightness
27412 }
27413
27414 static struct backlight_device *sony_backlight_device;
27415 -static struct backlight_ops sony_backlight_ops = {
27416 +static const struct backlight_ops sony_backlight_ops = {
27417 .update_status = sony_backlight_update_status,
27418 .get_brightness = sony_backlight_get_brightness,
27419 };
27420 diff -urNp linux-2.6.36/drivers/platform/x86/thinkpad_acpi.c linux-2.6.36/drivers/platform/x86/thinkpad_acpi.c
27421 --- linux-2.6.36/drivers/platform/x86/thinkpad_acpi.c 2010-10-20 16:30:22.000000000 -0400
27422 +++ linux-2.6.36/drivers/platform/x86/thinkpad_acpi.c 2010-11-06 18:58:15.000000000 -0400
27423 @@ -6109,7 +6109,7 @@ static void tpacpi_brightness_notify_cha
27424 BACKLIGHT_UPDATE_HOTKEY);
27425 }
27426
27427 -static struct backlight_ops ibm_backlight_data = {
27428 +static const struct backlight_ops ibm_backlight_data = {
27429 .get_brightness = brightness_get,
27430 .update_status = brightness_update_status,
27431 };
27432 diff -urNp linux-2.6.36/drivers/platform/x86/toshiba_acpi.c linux-2.6.36/drivers/platform/x86/toshiba_acpi.c
27433 --- linux-2.6.36/drivers/platform/x86/toshiba_acpi.c 2010-10-20 16:30:22.000000000 -0400
27434 +++ linux-2.6.36/drivers/platform/x86/toshiba_acpi.c 2010-11-06 18:58:15.000000000 -0400
27435 @@ -847,7 +847,7 @@ static void remove_toshiba_proc_entries(
27436 remove_proc_entry("version", toshiba_proc_dir);
27437 }
27438
27439 -static struct backlight_ops toshiba_backlight_data = {
27440 +static const struct backlight_ops toshiba_backlight_data = {
27441 .get_brightness = get_lcd,
27442 .update_status = set_lcd_status,
27443 };
27444 diff -urNp linux-2.6.36/drivers/pnp/pnpbios/bioscalls.c linux-2.6.36/drivers/pnp/pnpbios/bioscalls.c
27445 --- linux-2.6.36/drivers/pnp/pnpbios/bioscalls.c 2010-10-20 16:30:22.000000000 -0400
27446 +++ linux-2.6.36/drivers/pnp/pnpbios/bioscalls.c 2010-11-06 18:58:15.000000000 -0400
27447 @@ -59,7 +59,7 @@ do { \
27448 set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
27449 } while(0)
27450
27451 -static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
27452 +static const struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4093,
27453 (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
27454
27455 /*
27456 @@ -96,7 +96,10 @@ static inline u16 call_pnp_bios(u16 func
27457
27458 cpu = get_cpu();
27459 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
27460 +
27461 + pax_open_kernel();
27462 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
27463 + pax_close_kernel();
27464
27465 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
27466 spin_lock_irqsave(&pnp_bios_lock, flags);
27467 @@ -134,7 +137,10 @@ static inline u16 call_pnp_bios(u16 func
27468 :"memory");
27469 spin_unlock_irqrestore(&pnp_bios_lock, flags);
27470
27471 + pax_open_kernel();
27472 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
27473 + pax_close_kernel();
27474 +
27475 put_cpu();
27476
27477 /* If we get here and this is set then the PnP BIOS faulted on us. */
27478 @@ -468,7 +474,7 @@ int pnp_bios_read_escd(char *data, u32 n
27479 return status;
27480 }
27481
27482 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
27483 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
27484 {
27485 int i;
27486
27487 @@ -476,6 +482,8 @@ void pnpbios_calls_init(union pnp_bios_i
27488 pnp_bios_callpoint.offset = header->fields.pm16offset;
27489 pnp_bios_callpoint.segment = PNP_CS16;
27490
27491 + pax_open_kernel();
27492 +
27493 for_each_possible_cpu(i) {
27494 struct desc_struct *gdt = get_cpu_gdt_table(i);
27495 if (!gdt)
27496 @@ -487,4 +495,6 @@ void pnpbios_calls_init(union pnp_bios_i
27497 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_DS],
27498 (unsigned long)__va(header->fields.pm16dseg));
27499 }
27500 +
27501 + pax_close_kernel();
27502 }
27503 diff -urNp linux-2.6.36/drivers/pnp/quirks.c linux-2.6.36/drivers/pnp/quirks.c
27504 --- linux-2.6.36/drivers/pnp/quirks.c 2010-10-20 16:30:22.000000000 -0400
27505 +++ linux-2.6.36/drivers/pnp/quirks.c 2010-11-06 18:58:15.000000000 -0400
27506 @@ -322,7 +322,7 @@ static struct pnp_fixup pnp_fixups[] = {
27507 /* PnP resources that might overlap PCI BARs */
27508 {"PNP0c01", quirk_system_pci_resources},
27509 {"PNP0c02", quirk_system_pci_resources},
27510 - {""}
27511 + {"", NULL}
27512 };
27513
27514 void pnp_fixup_device(struct pnp_dev *dev)
27515 diff -urNp linux-2.6.36/drivers/pnp/resource.c linux-2.6.36/drivers/pnp/resource.c
27516 --- linux-2.6.36/drivers/pnp/resource.c 2010-10-20 16:30:22.000000000 -0400
27517 +++ linux-2.6.36/drivers/pnp/resource.c 2010-11-06 18:58:15.000000000 -0400
27518 @@ -360,7 +360,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
27519 return 1;
27520
27521 /* check if the resource is valid */
27522 - if (*irq < 0 || *irq > 15)
27523 + if (*irq > 15)
27524 return 0;
27525
27526 /* check if the resource is reserved */
27527 @@ -424,7 +424,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
27528 return 1;
27529
27530 /* check if the resource is valid */
27531 - if (*dma < 0 || *dma == 4 || *dma > 7)
27532 + if (*dma == 4 || *dma > 7)
27533 return 0;
27534
27535 /* check if the resource is reserved */
27536 diff -urNp linux-2.6.36/drivers/s390/cio/qdio_debug.c linux-2.6.36/drivers/s390/cio/qdio_debug.c
27537 --- linux-2.6.36/drivers/s390/cio/qdio_debug.c 2010-10-20 16:30:22.000000000 -0400
27538 +++ linux-2.6.36/drivers/s390/cio/qdio_debug.c 2010-11-06 18:58:15.000000000 -0400
27539 @@ -233,7 +233,7 @@ static int qperf_seq_open(struct inode *
27540 filp->f_path.dentry->d_inode->i_private);
27541 }
27542
27543 -static struct file_operations debugfs_perf_fops = {
27544 +static const struct file_operations debugfs_perf_fops = {
27545 .owner = THIS_MODULE,
27546 .open = qperf_seq_open,
27547 .read = seq_read,
27548 diff -urNp linux-2.6.36/drivers/scsi/ipr.c linux-2.6.36/drivers/scsi/ipr.c
27549 --- linux-2.6.36/drivers/scsi/ipr.c 2010-10-20 16:30:22.000000000 -0400
27550 +++ linux-2.6.36/drivers/scsi/ipr.c 2010-11-06 18:58:15.000000000 -0400
27551 @@ -6156,7 +6156,7 @@ static bool ipr_qc_fill_rtf(struct ata_q
27552 return true;
27553 }
27554
27555 -static struct ata_port_operations ipr_sata_ops = {
27556 +static const struct ata_port_operations ipr_sata_ops = {
27557 .phy_reset = ipr_ata_phy_reset,
27558 .hardreset = ipr_sata_reset,
27559 .post_internal_cmd = ipr_ata_post_internal,
27560 diff -urNp linux-2.6.36/drivers/scsi/libfc/fc_exch.c linux-2.6.36/drivers/scsi/libfc/fc_exch.c
27561 --- linux-2.6.36/drivers/scsi/libfc/fc_exch.c 2010-10-20 16:30:22.000000000 -0400
27562 +++ linux-2.6.36/drivers/scsi/libfc/fc_exch.c 2010-11-06 18:58:15.000000000 -0400
27563 @@ -100,12 +100,12 @@ struct fc_exch_mgr {
27564 * all together if not used XXX
27565 */
27566 struct {
27567 - atomic_t no_free_exch;
27568 - atomic_t no_free_exch_xid;
27569 - atomic_t xid_not_found;
27570 - atomic_t xid_busy;
27571 - atomic_t seq_not_found;
27572 - atomic_t non_bls_resp;
27573 + atomic_unchecked_t no_free_exch;
27574 + atomic_unchecked_t no_free_exch_xid;
27575 + atomic_unchecked_t xid_not_found;
27576 + atomic_unchecked_t xid_busy;
27577 + atomic_unchecked_t seq_not_found;
27578 + atomic_unchecked_t non_bls_resp;
27579 } stats;
27580 };
27581 #define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
27582 @@ -670,7 +670,7 @@ static struct fc_exch *fc_exch_em_alloc(
27583 /* allocate memory for exchange */
27584 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
27585 if (!ep) {
27586 - atomic_inc(&mp->stats.no_free_exch);
27587 + atomic_inc_unchecked(&mp->stats.no_free_exch);
27588 goto out;
27589 }
27590 memset(ep, 0, sizeof(*ep));
27591 @@ -718,7 +718,7 @@ out:
27592 return ep;
27593 err:
27594 spin_unlock_bh(&pool->lock);
27595 - atomic_inc(&mp->stats.no_free_exch_xid);
27596 + atomic_inc_unchecked(&mp->stats.no_free_exch_xid);
27597 mempool_free(ep, mp->ep_pool);
27598 return NULL;
27599 }
27600 @@ -863,7 +863,7 @@ static enum fc_pf_rjt_reason fc_seq_look
27601 xid = ntohs(fh->fh_ox_id); /* we originated exch */
27602 ep = fc_exch_find(mp, xid);
27603 if (!ep) {
27604 - atomic_inc(&mp->stats.xid_not_found);
27605 + atomic_inc_unchecked(&mp->stats.xid_not_found);
27606 reject = FC_RJT_OX_ID;
27607 goto out;
27608 }
27609 @@ -893,7 +893,7 @@ static enum fc_pf_rjt_reason fc_seq_look
27610 ep = fc_exch_find(mp, xid);
27611 if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
27612 if (ep) {
27613 - atomic_inc(&mp->stats.xid_busy);
27614 + atomic_inc_unchecked(&mp->stats.xid_busy);
27615 reject = FC_RJT_RX_ID;
27616 goto rel;
27617 }
27618 @@ -904,7 +904,7 @@ static enum fc_pf_rjt_reason fc_seq_look
27619 }
27620 xid = ep->xid; /* get our XID */
27621 } else if (!ep) {
27622 - atomic_inc(&mp->stats.xid_not_found);
27623 + atomic_inc_unchecked(&mp->stats.xid_not_found);
27624 reject = FC_RJT_RX_ID; /* XID not found */
27625 goto out;
27626 }
27627 @@ -921,7 +921,7 @@ static enum fc_pf_rjt_reason fc_seq_look
27628 } else {
27629 sp = &ep->seq;
27630 if (sp->id != fh->fh_seq_id) {
27631 - atomic_inc(&mp->stats.seq_not_found);
27632 + atomic_inc_unchecked(&mp->stats.seq_not_found);
27633 reject = FC_RJT_SEQ_ID; /* sequence/exch should exist */
27634 goto rel;
27635 }
27636 @@ -1338,22 +1338,22 @@ static void fc_exch_recv_seq_resp(struct
27637
27638 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
27639 if (!ep) {
27640 - atomic_inc(&mp->stats.xid_not_found);
27641 + atomic_inc_unchecked(&mp->stats.xid_not_found);
27642 goto out;
27643 }
27644 if (ep->esb_stat & ESB_ST_COMPLETE) {
27645 - atomic_inc(&mp->stats.xid_not_found);
27646 + atomic_inc_unchecked(&mp->stats.xid_not_found);
27647 goto out;
27648 }
27649 if (ep->rxid == FC_XID_UNKNOWN)
27650 ep->rxid = ntohs(fh->fh_rx_id);
27651 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
27652 - atomic_inc(&mp->stats.xid_not_found);
27653 + atomic_inc_unchecked(&mp->stats.xid_not_found);
27654 goto rel;
27655 }
27656 if (ep->did != ntoh24(fh->fh_s_id) &&
27657 ep->did != FC_FID_FLOGI) {
27658 - atomic_inc(&mp->stats.xid_not_found);
27659 + atomic_inc_unchecked(&mp->stats.xid_not_found);
27660 goto rel;
27661 }
27662 sof = fr_sof(fp);
27663 @@ -1362,7 +1362,7 @@ static void fc_exch_recv_seq_resp(struct
27664 sp->ssb_stat |= SSB_ST_RESP;
27665 sp->id = fh->fh_seq_id;
27666 } else if (sp->id != fh->fh_seq_id) {
27667 - atomic_inc(&mp->stats.seq_not_found);
27668 + atomic_inc_unchecked(&mp->stats.seq_not_found);
27669 goto rel;
27670 }
27671
27672 @@ -1425,9 +1425,9 @@ static void fc_exch_recv_resp(struct fc_
27673 sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */
27674
27675 if (!sp)
27676 - atomic_inc(&mp->stats.xid_not_found);
27677 + atomic_inc_unchecked(&mp->stats.xid_not_found);
27678 else
27679 - atomic_inc(&mp->stats.non_bls_resp);
27680 + atomic_inc_unchecked(&mp->stats.non_bls_resp);
27681
27682 fc_frame_free(fp);
27683 }
27684 diff -urNp linux-2.6.36/drivers/scsi/libsas/sas_ata.c linux-2.6.36/drivers/scsi/libsas/sas_ata.c
27685 --- linux-2.6.36/drivers/scsi/libsas/sas_ata.c 2010-10-20 16:30:22.000000000 -0400
27686 +++ linux-2.6.36/drivers/scsi/libsas/sas_ata.c 2010-11-06 18:58:15.000000000 -0400
27687 @@ -344,7 +344,7 @@ static int sas_ata_scr_read(struct ata_l
27688 }
27689 }
27690
27691 -static struct ata_port_operations sas_sata_ops = {
27692 +static const struct ata_port_operations sas_sata_ops = {
27693 .phy_reset = sas_ata_phy_reset,
27694 .post_internal_cmd = sas_ata_post_internal,
27695 .qc_prep = ata_noop_qc_prep,
27696 diff -urNp linux-2.6.36/drivers/scsi/mpt2sas/mpt2sas_debug.h linux-2.6.36/drivers/scsi/mpt2sas/mpt2sas_debug.h
27697 --- linux-2.6.36/drivers/scsi/mpt2sas/mpt2sas_debug.h 2010-10-20 16:30:22.000000000 -0400
27698 +++ linux-2.6.36/drivers/scsi/mpt2sas/mpt2sas_debug.h 2010-11-06 18:58:15.000000000 -0400
27699 @@ -79,7 +79,7 @@
27700 CMD; \
27701 }
27702 #else
27703 -#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
27704 +#define MPT_CHECK_LOGGING(IOC, CMD, BITS) do {} while (0)
27705 #endif /* CONFIG_SCSI_MPT2SAS_LOGGING */
27706
27707
27708 diff -urNp linux-2.6.36/drivers/scsi/qla2xxx/qla_os.c linux-2.6.36/drivers/scsi/qla2xxx/qla_os.c
27709 --- linux-2.6.36/drivers/scsi/qla2xxx/qla_os.c 2010-10-20 16:30:22.000000000 -0400
27710 +++ linux-2.6.36/drivers/scsi/qla2xxx/qla_os.c 2010-11-06 18:58:15.000000000 -0400
27711 @@ -3946,7 +3946,7 @@ static struct pci_driver qla2xxx_pci_dri
27712 .err_handler = &qla2xxx_err_handler,
27713 };
27714
27715 -static struct file_operations apidev_fops = {
27716 +static const struct file_operations apidev_fops = {
27717 .owner = THIS_MODULE,
27718 };
27719
27720 diff -urNp linux-2.6.36/drivers/scsi/scsi_logging.h linux-2.6.36/drivers/scsi/scsi_logging.h
27721 --- linux-2.6.36/drivers/scsi/scsi_logging.h 2010-10-20 16:30:22.000000000 -0400
27722 +++ linux-2.6.36/drivers/scsi/scsi_logging.h 2010-11-06 18:58:15.000000000 -0400
27723 @@ -51,7 +51,7 @@ do { \
27724 } while (0); \
27725 } while (0)
27726 #else
27727 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
27728 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
27729 #endif /* CONFIG_SCSI_LOGGING */
27730
27731 /*
27732 diff -urNp linux-2.6.36/drivers/scsi/sg.c linux-2.6.36/drivers/scsi/sg.c
27733 --- linux-2.6.36/drivers/scsi/sg.c 2010-10-20 16:30:22.000000000 -0400
27734 +++ linux-2.6.36/drivers/scsi/sg.c 2010-11-06 18:58:15.000000000 -0400
27735 @@ -2307,7 +2307,7 @@ struct sg_proc_leaf {
27736 const struct file_operations * fops;
27737 };
27738
27739 -static struct sg_proc_leaf sg_proc_leaf_arr[] = {
27740 +static const struct sg_proc_leaf sg_proc_leaf_arr[] = {
27741 {"allow_dio", &adio_fops},
27742 {"debug", &debug_fops},
27743 {"def_reserved_size", &dressz_fops},
27744 @@ -2322,7 +2322,7 @@ sg_proc_init(void)
27745 {
27746 int k, mask;
27747 int num_leaves = ARRAY_SIZE(sg_proc_leaf_arr);
27748 - struct sg_proc_leaf * leaf;
27749 + const struct sg_proc_leaf * leaf;
27750
27751 sg_proc_sgp = proc_mkdir(sg_proc_sg_dirname, NULL);
27752 if (!sg_proc_sgp)
27753 diff -urNp linux-2.6.36/drivers/serial/8250_pci.c linux-2.6.36/drivers/serial/8250_pci.c
27754 --- linux-2.6.36/drivers/serial/8250_pci.c 2010-10-20 16:30:22.000000000 -0400
27755 +++ linux-2.6.36/drivers/serial/8250_pci.c 2010-11-06 18:58:15.000000000 -0400
27756 @@ -3777,7 +3777,7 @@ static struct pci_device_id serial_pci_t
27757 PCI_ANY_ID, PCI_ANY_ID,
27758 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
27759 0xffff00, pbn_default },
27760 - { 0, }
27761 + { 0, 0, 0, 0, 0, 0, 0 }
27762 };
27763
27764 static struct pci_driver serial_pci_driver = {
27765 diff -urNp linux-2.6.36/drivers/serial/kgdboc.c linux-2.6.36/drivers/serial/kgdboc.c
27766 --- linux-2.6.36/drivers/serial/kgdboc.c 2010-10-20 16:30:22.000000000 -0400
27767 +++ linux-2.6.36/drivers/serial/kgdboc.c 2010-11-06 18:58:15.000000000 -0400
27768 @@ -21,7 +21,8 @@
27769
27770 #define MAX_CONFIG_LEN 40
27771
27772 -static struct kgdb_io kgdboc_io_ops;
27773 +/* cannot be const, see configure_kgdboc() */
27774 +static struct kgdb_io kgdboc_io_ops;
27775
27776 /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
27777 static int configured = -1;
27778 @@ -233,6 +234,7 @@ static void kgdboc_post_exp_handler(void
27779 }
27780 }
27781
27782 +/* cannot be const, see configure_kgdboc() */
27783 static struct kgdb_io kgdboc_io_ops = {
27784 .name = "kgdboc",
27785 .read_char = kgdboc_get_char,
27786 diff -urNp linux-2.6.36/drivers/staging/comedi/comedi_fops.c linux-2.6.36/drivers/staging/comedi/comedi_fops.c
27787 --- linux-2.6.36/drivers/staging/comedi/comedi_fops.c 2010-10-20 16:30:22.000000000 -0400
27788 +++ linux-2.6.36/drivers/staging/comedi/comedi_fops.c 2010-11-06 18:58:15.000000000 -0400
27789 @@ -1425,7 +1425,7 @@ static void comedi_unmap(struct vm_area_
27790 mutex_unlock(&dev->mutex);
27791 }
27792
27793 -static struct vm_operations_struct comedi_vm_ops = {
27794 +static const struct vm_operations_struct comedi_vm_ops = {
27795 .close = comedi_unmap,
27796 };
27797
27798 diff -urNp linux-2.6.36/drivers/staging/dream/pmem.c linux-2.6.36/drivers/staging/dream/pmem.c
27799 --- linux-2.6.36/drivers/staging/dream/pmem.c 2010-10-20 16:30:22.000000000 -0400
27800 +++ linux-2.6.36/drivers/staging/dream/pmem.c 2010-11-06 18:58:15.000000000 -0400
27801 @@ -1201,7 +1201,7 @@ static ssize_t debug_read(struct file *f
27802 return simple_read_from_buffer(buf, count, ppos, buffer, n);
27803 }
27804
27805 -static struct file_operations debug_fops = {
27806 +static const struct file_operations debug_fops = {
27807 .read = debug_read,
27808 .open = debug_open,
27809 };
27810 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/adsp_driver.c linux-2.6.36/drivers/staging/dream/qdsp5/adsp_driver.c
27811 --- linux-2.6.36/drivers/staging/dream/qdsp5/adsp_driver.c 2010-10-20 16:30:22.000000000 -0400
27812 +++ linux-2.6.36/drivers/staging/dream/qdsp5/adsp_driver.c 2010-11-06 18:58:15.000000000 -0400
27813 @@ -577,7 +577,7 @@ static struct adsp_device *inode_to_devi
27814 static dev_t adsp_devno;
27815 static struct class *adsp_class;
27816
27817 -static struct file_operations adsp_fops = {
27818 +static const struct file_operations adsp_fops = {
27819 .owner = THIS_MODULE,
27820 .open = adsp_open,
27821 .unlocked_ioctl = adsp_ioctl,
27822 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/audio_aac.c linux-2.6.36/drivers/staging/dream/qdsp5/audio_aac.c
27823 --- linux-2.6.36/drivers/staging/dream/qdsp5/audio_aac.c 2010-10-20 16:30:22.000000000 -0400
27824 +++ linux-2.6.36/drivers/staging/dream/qdsp5/audio_aac.c 2010-11-06 18:58:15.000000000 -0400
27825 @@ -1023,7 +1023,7 @@ done:
27826 return rc;
27827 }
27828
27829 -static struct file_operations audio_aac_fops = {
27830 +static const struct file_operations audio_aac_fops = {
27831 .owner = THIS_MODULE,
27832 .open = audio_open,
27833 .release = audio_release,
27834 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/audio_amrnb.c linux-2.6.36/drivers/staging/dream/qdsp5/audio_amrnb.c
27835 --- linux-2.6.36/drivers/staging/dream/qdsp5/audio_amrnb.c 2010-10-20 16:30:22.000000000 -0400
27836 +++ linux-2.6.36/drivers/staging/dream/qdsp5/audio_amrnb.c 2010-11-06 18:58:15.000000000 -0400
27837 @@ -834,7 +834,7 @@ done:
27838 return rc;
27839 }
27840
27841 -static struct file_operations audio_amrnb_fops = {
27842 +static const struct file_operations audio_amrnb_fops = {
27843 .owner = THIS_MODULE,
27844 .open = audamrnb_open,
27845 .release = audamrnb_release,
27846 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/audio_evrc.c linux-2.6.36/drivers/staging/dream/qdsp5/audio_evrc.c
27847 --- linux-2.6.36/drivers/staging/dream/qdsp5/audio_evrc.c 2010-10-20 16:30:22.000000000 -0400
27848 +++ linux-2.6.36/drivers/staging/dream/qdsp5/audio_evrc.c 2010-11-06 18:58:15.000000000 -0400
27849 @@ -806,7 +806,7 @@ dma_fail:
27850 return rc;
27851 }
27852
27853 -static struct file_operations audio_evrc_fops = {
27854 +static const struct file_operations audio_evrc_fops = {
27855 .owner = THIS_MODULE,
27856 .open = audevrc_open,
27857 .release = audevrc_release,
27858 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/audio_in.c linux-2.6.36/drivers/staging/dream/qdsp5/audio_in.c
27859 --- linux-2.6.36/drivers/staging/dream/qdsp5/audio_in.c 2010-10-20 16:30:22.000000000 -0400
27860 +++ linux-2.6.36/drivers/staging/dream/qdsp5/audio_in.c 2010-11-06 18:58:15.000000000 -0400
27861 @@ -914,7 +914,7 @@ static int audpre_open(struct inode *ino
27862 return 0;
27863 }
27864
27865 -static struct file_operations audio_fops = {
27866 +static const struct file_operations audio_fops = {
27867 .owner = THIS_MODULE,
27868 .open = audio_in_open,
27869 .release = audio_in_release,
27870 @@ -923,7 +923,7 @@ static struct file_operations audio_fops
27871 .unlocked_ioctl = audio_in_ioctl,
27872 };
27873
27874 -static struct file_operations audpre_fops = {
27875 +static const struct file_operations audpre_fops = {
27876 .owner = THIS_MODULE,
27877 .open = audpre_open,
27878 .unlocked_ioctl = audpre_ioctl,
27879 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/audio_mp3.c linux-2.6.36/drivers/staging/dream/qdsp5/audio_mp3.c
27880 --- linux-2.6.36/drivers/staging/dream/qdsp5/audio_mp3.c 2010-10-20 16:30:22.000000000 -0400
27881 +++ linux-2.6.36/drivers/staging/dream/qdsp5/audio_mp3.c 2010-11-06 18:58:15.000000000 -0400
27882 @@ -941,7 +941,7 @@ done:
27883 return rc;
27884 }
27885
27886 -static struct file_operations audio_mp3_fops = {
27887 +static const struct file_operations audio_mp3_fops = {
27888 .owner = THIS_MODULE,
27889 .open = audio_open,
27890 .release = audio_release,
27891 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/audio_out.c linux-2.6.36/drivers/staging/dream/qdsp5/audio_out.c
27892 --- linux-2.6.36/drivers/staging/dream/qdsp5/audio_out.c 2010-10-20 16:30:22.000000000 -0400
27893 +++ linux-2.6.36/drivers/staging/dream/qdsp5/audio_out.c 2010-11-06 18:58:15.000000000 -0400
27894 @@ -800,7 +800,7 @@ static int audpp_open(struct inode *inod
27895 return 0;
27896 }
27897
27898 -static struct file_operations audio_fops = {
27899 +static const struct file_operations audio_fops = {
27900 .owner = THIS_MODULE,
27901 .open = audio_open,
27902 .release = audio_release,
27903 @@ -809,7 +809,7 @@ static struct file_operations audio_fops
27904 .unlocked_ioctl = audio_ioctl,
27905 };
27906
27907 -static struct file_operations audpp_fops = {
27908 +static const struct file_operations audpp_fops = {
27909 .owner = THIS_MODULE,
27910 .open = audpp_open,
27911 .unlocked_ioctl = audpp_ioctl,
27912 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/audio_qcelp.c linux-2.6.36/drivers/staging/dream/qdsp5/audio_qcelp.c
27913 --- linux-2.6.36/drivers/staging/dream/qdsp5/audio_qcelp.c 2010-10-20 16:30:22.000000000 -0400
27914 +++ linux-2.6.36/drivers/staging/dream/qdsp5/audio_qcelp.c 2010-11-06 18:58:15.000000000 -0400
27915 @@ -817,7 +817,7 @@ err:
27916 return rc;
27917 }
27918
27919 -static struct file_operations audio_qcelp_fops = {
27920 +static const struct file_operations audio_qcelp_fops = {
27921 .owner = THIS_MODULE,
27922 .open = audqcelp_open,
27923 .release = audqcelp_release,
27924 diff -urNp linux-2.6.36/drivers/staging/dream/qdsp5/snd.c linux-2.6.36/drivers/staging/dream/qdsp5/snd.c
27925 --- linux-2.6.36/drivers/staging/dream/qdsp5/snd.c 2010-10-20 16:30:22.000000000 -0400
27926 +++ linux-2.6.36/drivers/staging/dream/qdsp5/snd.c 2010-11-06 18:58:15.000000000 -0400
27927 @@ -242,7 +242,7 @@ err:
27928 return rc;
27929 }
27930
27931 -static struct file_operations snd_fops = {
27932 +static const struct file_operations snd_fops = {
27933 .owner = THIS_MODULE,
27934 .open = snd_open,
27935 .release = snd_release,
27936 diff -urNp linux-2.6.36/drivers/staging/go7007/go7007-v4l2.c linux-2.6.36/drivers/staging/go7007/go7007-v4l2.c
27937 --- linux-2.6.36/drivers/staging/go7007/go7007-v4l2.c 2010-10-20 16:30:22.000000000 -0400
27938 +++ linux-2.6.36/drivers/staging/go7007/go7007-v4l2.c 2010-11-06 18:58:15.000000000 -0400
27939 @@ -1673,7 +1673,7 @@ static int go7007_vm_fault(struct vm_are
27940 return 0;
27941 }
27942
27943 -static struct vm_operations_struct go7007_vm_ops = {
27944 +static const struct vm_operations_struct go7007_vm_ops = {
27945 .open = go7007_vm_open,
27946 .close = go7007_vm_close,
27947 .fault = go7007_vm_fault,
27948 diff -urNp linux-2.6.36/drivers/staging/hv/hv.c linux-2.6.36/drivers/staging/hv/hv.c
27949 --- linux-2.6.36/drivers/staging/hv/hv.c 2010-10-20 16:30:22.000000000 -0400
27950 +++ linux-2.6.36/drivers/staging/hv/hv.c 2010-11-06 18:58:15.000000000 -0400
27951 @@ -162,7 +162,7 @@ static u64 HvDoHypercall(u64 Control, vo
27952 u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
27953 u32 outputAddressHi = outputAddress >> 32;
27954 u32 outputAddressLo = outputAddress & 0xFFFFFFFF;
27955 - volatile void *hypercallPage = gHvContext.HypercallPage;
27956 + volatile void *hypercallPage = ktva_ktla(gHvContext.HypercallPage);
27957
27958 DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
27959 Control, Input, Output);
27960 diff -urNp linux-2.6.36/drivers/staging/msm/msm_fb_bl.c linux-2.6.36/drivers/staging/msm/msm_fb_bl.c
27961 --- linux-2.6.36/drivers/staging/msm/msm_fb_bl.c 2010-10-20 16:30:22.000000000 -0400
27962 +++ linux-2.6.36/drivers/staging/msm/msm_fb_bl.c 2010-11-06 18:58:15.000000000 -0400
27963 @@ -42,7 +42,7 @@ static int msm_fb_bl_update_status(struc
27964 return 0;
27965 }
27966
27967 -static struct backlight_ops msm_fb_bl_ops = {
27968 +static const struct backlight_ops msm_fb_bl_ops = {
27969 .get_brightness = msm_fb_bl_get_brightness,
27970 .update_status = msm_fb_bl_update_status,
27971 };
27972 diff -urNp linux-2.6.36/drivers/staging/phison/phison.c linux-2.6.36/drivers/staging/phison/phison.c
27973 --- linux-2.6.36/drivers/staging/phison/phison.c 2010-10-20 16:30:22.000000000 -0400
27974 +++ linux-2.6.36/drivers/staging/phison/phison.c 2010-11-06 18:58:15.000000000 -0400
27975 @@ -43,7 +43,7 @@ static struct scsi_host_template phison_
27976 ATA_BMDMA_SHT(DRV_NAME),
27977 };
27978
27979 -static struct ata_port_operations phison_ops = {
27980 +static const struct ata_port_operations phison_ops = {
27981 .inherits = &ata_bmdma_port_ops,
27982 .prereset = phison_pre_reset,
27983 };
27984 diff -urNp linux-2.6.36/drivers/staging/pohmelfs/inode.c linux-2.6.36/drivers/staging/pohmelfs/inode.c
27985 --- linux-2.6.36/drivers/staging/pohmelfs/inode.c 2010-10-20 16:30:22.000000000 -0400
27986 +++ linux-2.6.36/drivers/staging/pohmelfs/inode.c 2010-11-06 18:58:15.000000000 -0400
27987 @@ -1852,7 +1852,7 @@ static int pohmelfs_fill_super(struct su
27988 mutex_init(&psb->mcache_lock);
27989 psb->mcache_root = RB_ROOT;
27990 psb->mcache_timeout = msecs_to_jiffies(5000);
27991 - atomic_long_set(&psb->mcache_gen, 0);
27992 + atomic_long_set_unchecked(&psb->mcache_gen, 0);
27993
27994 psb->trans_max_pages = 100;
27995
27996 diff -urNp linux-2.6.36/drivers/staging/pohmelfs/mcache.c linux-2.6.36/drivers/staging/pohmelfs/mcache.c
27997 --- linux-2.6.36/drivers/staging/pohmelfs/mcache.c 2010-10-20 16:30:22.000000000 -0400
27998 +++ linux-2.6.36/drivers/staging/pohmelfs/mcache.c 2010-11-06 18:58:15.000000000 -0400
27999 @@ -121,7 +121,7 @@ struct pohmelfs_mcache *pohmelfs_mcache_
28000 m->data = data;
28001 m->start = start;
28002 m->size = size;
28003 - m->gen = atomic_long_inc_return(&psb->mcache_gen);
28004 + m->gen = atomic_long_inc_return_unchecked(&psb->mcache_gen);
28005
28006 mutex_lock(&psb->mcache_lock);
28007 err = pohmelfs_mcache_insert(psb, m);
28008 diff -urNp linux-2.6.36/drivers/staging/pohmelfs/netfs.h linux-2.6.36/drivers/staging/pohmelfs/netfs.h
28009 --- linux-2.6.36/drivers/staging/pohmelfs/netfs.h 2010-10-20 16:30:22.000000000 -0400
28010 +++ linux-2.6.36/drivers/staging/pohmelfs/netfs.h 2010-11-06 18:58:15.000000000 -0400
28011 @@ -571,7 +571,7 @@ struct pohmelfs_config;
28012 struct pohmelfs_sb {
28013 struct rb_root mcache_root;
28014 struct mutex mcache_lock;
28015 - atomic_long_t mcache_gen;
28016 + atomic_long_unchecked_t mcache_gen;
28017 unsigned long mcache_timeout;
28018
28019 unsigned int idx;
28020 diff -urNp linux-2.6.36/drivers/staging/rtl8192u/ieee80211/proc.c linux-2.6.36/drivers/staging/rtl8192u/ieee80211/proc.c
28021 --- linux-2.6.36/drivers/staging/rtl8192u/ieee80211/proc.c 2010-10-20 16:30:22.000000000 -0400
28022 +++ linux-2.6.36/drivers/staging/rtl8192u/ieee80211/proc.c 2010-11-06 18:58:15.000000000 -0400
28023 @@ -99,7 +99,7 @@ static int crypto_info_open(struct inode
28024 return seq_open(file, &crypto_seq_ops);
28025 }
28026
28027 -static struct file_operations proc_crypto_ops = {
28028 +static const struct file_operations proc_crypto_ops = {
28029 .open = crypto_info_open,
28030 .read = seq_read,
28031 .llseek = seq_lseek,
28032 diff -urNp linux-2.6.36/drivers/staging/samsung-laptop/samsung-laptop.c linux-2.6.36/drivers/staging/samsung-laptop/samsung-laptop.c
28033 --- linux-2.6.36/drivers/staging/samsung-laptop/samsung-laptop.c 2010-10-20 16:30:22.000000000 -0400
28034 +++ linux-2.6.36/drivers/staging/samsung-laptop/samsung-laptop.c 2010-11-06 18:58:15.000000000 -0400
28035 @@ -269,7 +269,7 @@ static int update_status(struct backligh
28036 return 0;
28037 }
28038
28039 -static struct backlight_ops backlight_ops = {
28040 +static const struct backlight_ops backlight_ops = {
28041 .get_brightness = get_brightness,
28042 .update_status = update_status,
28043 };
28044 diff -urNp linux-2.6.36/drivers/staging/spectra/ffsport.c linux-2.6.36/drivers/staging/spectra/ffsport.c
28045 --- linux-2.6.36/drivers/staging/spectra/ffsport.c 2010-10-20 16:30:22.000000000 -0400
28046 +++ linux-2.6.36/drivers/staging/spectra/ffsport.c 2010-11-06 18:58:15.000000000 -0400
28047 @@ -602,7 +602,7 @@ int GLOB_SBD_unlocked_ioctl(struct block
28048 return ret;
28049 }
28050
28051 -static struct block_device_operations GLOB_SBD_ops = {
28052 +static const struct block_device_operations GLOB_SBD_ops = {
28053 .owner = THIS_MODULE,
28054 .open = GLOB_SBD_open,
28055 .release = GLOB_SBD_release,
28056 diff -urNp linux-2.6.36/drivers/staging/vme/devices/vme_user.c linux-2.6.36/drivers/staging/vme/devices/vme_user.c
28057 --- linux-2.6.36/drivers/staging/vme/devices/vme_user.c 2010-10-20 16:30:22.000000000 -0400
28058 +++ linux-2.6.36/drivers/staging/vme/devices/vme_user.c 2010-11-06 18:58:15.000000000 -0400
28059 @@ -137,7 +137,7 @@ static long vme_user_unlocked_ioctl(stru
28060 static int __init vme_user_probe(struct device *, int, int);
28061 static int __exit vme_user_remove(struct device *, int, int);
28062
28063 -static struct file_operations vme_user_fops = {
28064 +static const struct file_operations vme_user_fops = {
28065 .open = vme_user_open,
28066 .release = vme_user_release,
28067 .read = vme_user_read,
28068 diff -urNp linux-2.6.36/drivers/usb/atm/cxacru.c linux-2.6.36/drivers/usb/atm/cxacru.c
28069 --- linux-2.6.36/drivers/usb/atm/cxacru.c 2010-10-20 16:30:22.000000000 -0400
28070 +++ linux-2.6.36/drivers/usb/atm/cxacru.c 2010-11-06 18:58:15.000000000 -0400
28071 @@ -473,7 +473,7 @@ static ssize_t cxacru_sysfs_store_adsl_c
28072 ret = sscanf(buf + pos, "%x=%x%n", &index, &value, &tmp);
28073 if (ret < 2)
28074 return -EINVAL;
28075 - if (index < 0 || index > 0x7f)
28076 + if (index > 0x7f)
28077 return -EINVAL;
28078 pos += tmp;
28079
28080 diff -urNp linux-2.6.36/drivers/usb/atm/usbatm.c linux-2.6.36/drivers/usb/atm/usbatm.c
28081 --- linux-2.6.36/drivers/usb/atm/usbatm.c 2010-10-20 16:30:22.000000000 -0400
28082 +++ linux-2.6.36/drivers/usb/atm/usbatm.c 2010-11-06 18:58:15.000000000 -0400
28083 @@ -332,7 +332,7 @@ static void usbatm_extract_one_cell(stru
28084 if (printk_ratelimit())
28085 atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n",
28086 __func__, vpi, vci);
28087 - atomic_inc(&vcc->stats->rx_err);
28088 + atomic_inc_unchecked(&vcc->stats->rx_err);
28089 return;
28090 }
28091
28092 @@ -360,7 +360,7 @@ static void usbatm_extract_one_cell(stru
28093 if (length > ATM_MAX_AAL5_PDU) {
28094 atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n",
28095 __func__, length, vcc);
28096 - atomic_inc(&vcc->stats->rx_err);
28097 + atomic_inc_unchecked(&vcc->stats->rx_err);
28098 goto out;
28099 }
28100
28101 @@ -369,14 +369,14 @@ static void usbatm_extract_one_cell(stru
28102 if (sarb->len < pdu_length) {
28103 atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n",
28104 __func__, pdu_length, sarb->len, vcc);
28105 - atomic_inc(&vcc->stats->rx_err);
28106 + atomic_inc_unchecked(&vcc->stats->rx_err);
28107 goto out;
28108 }
28109
28110 if (crc32_be(~0, skb_tail_pointer(sarb) - pdu_length, pdu_length) != 0xc704dd7b) {
28111 atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n",
28112 __func__, vcc);
28113 - atomic_inc(&vcc->stats->rx_err);
28114 + atomic_inc_unchecked(&vcc->stats->rx_err);
28115 goto out;
28116 }
28117
28118 @@ -386,7 +386,7 @@ static void usbatm_extract_one_cell(stru
28119 if (printk_ratelimit())
28120 atm_err(instance, "%s: no memory for skb (length: %u)!\n",
28121 __func__, length);
28122 - atomic_inc(&vcc->stats->rx_drop);
28123 + atomic_inc_unchecked(&vcc->stats->rx_drop);
28124 goto out;
28125 }
28126
28127 @@ -411,7 +411,7 @@ static void usbatm_extract_one_cell(stru
28128
28129 vcc->push(vcc, skb);
28130
28131 - atomic_inc(&vcc->stats->rx);
28132 + atomic_inc_unchecked(&vcc->stats->rx);
28133 out:
28134 skb_trim(sarb, 0);
28135 }
28136 @@ -614,7 +614,7 @@ static void usbatm_tx_process(unsigned l
28137 struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc;
28138
28139 usbatm_pop(vcc, skb);
28140 - atomic_inc(&vcc->stats->tx);
28141 + atomic_inc_unchecked(&vcc->stats->tx);
28142
28143 skb = skb_dequeue(&instance->sndqueue);
28144 }
28145 @@ -773,11 +773,11 @@ static int usbatm_atm_proc_read(struct a
28146 if (!left--)
28147 return sprintf(page,
28148 "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
28149 - atomic_read(&atm_dev->stats.aal5.tx),
28150 - atomic_read(&atm_dev->stats.aal5.tx_err),
28151 - atomic_read(&atm_dev->stats.aal5.rx),
28152 - atomic_read(&atm_dev->stats.aal5.rx_err),
28153 - atomic_read(&atm_dev->stats.aal5.rx_drop));
28154 + atomic_read_unchecked(&atm_dev->stats.aal5.tx),
28155 + atomic_read_unchecked(&atm_dev->stats.aal5.tx_err),
28156 + atomic_read_unchecked(&atm_dev->stats.aal5.rx),
28157 + atomic_read_unchecked(&atm_dev->stats.aal5.rx_err),
28158 + atomic_read_unchecked(&atm_dev->stats.aal5.rx_drop));
28159
28160 if (!left--) {
28161 if (instance->disconnected)
28162 diff -urNp linux-2.6.36/drivers/usb/class/cdc-acm.c linux-2.6.36/drivers/usb/class/cdc-acm.c
28163 --- linux-2.6.36/drivers/usb/class/cdc-acm.c 2010-10-20 16:30:22.000000000 -0400
28164 +++ linux-2.6.36/drivers/usb/class/cdc-acm.c 2010-11-06 18:58:15.000000000 -0400
28165 @@ -1634,7 +1634,7 @@ static const struct usb_device_id acm_id
28166 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
28167 USB_CDC_ACM_PROTO_AT_CDMA) },
28168
28169 - { }
28170 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
28171 };
28172
28173 MODULE_DEVICE_TABLE(usb, acm_ids);
28174 diff -urNp linux-2.6.36/drivers/usb/class/cdc-wdm.c linux-2.6.36/drivers/usb/class/cdc-wdm.c
28175 --- linux-2.6.36/drivers/usb/class/cdc-wdm.c 2010-10-20 16:30:22.000000000 -0400
28176 +++ linux-2.6.36/drivers/usb/class/cdc-wdm.c 2010-11-06 18:58:15.000000000 -0400
28177 @@ -342,7 +342,7 @@ static ssize_t wdm_write
28178 goto outnp;
28179 }
28180
28181 - if (!file->f_flags && O_NONBLOCK)
28182 + if (!(file->f_flags & O_NONBLOCK))
28183 r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
28184 &desc->flags));
28185 else
28186 diff -urNp linux-2.6.36/drivers/usb/class/usblp.c linux-2.6.36/drivers/usb/class/usblp.c
28187 --- linux-2.6.36/drivers/usb/class/usblp.c 2010-10-20 16:30:22.000000000 -0400
28188 +++ linux-2.6.36/drivers/usb/class/usblp.c 2010-11-06 18:58:15.000000000 -0400
28189 @@ -227,7 +227,7 @@ static const struct quirk_printer_struct
28190 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
28191 { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
28192 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
28193 - { 0, 0 }
28194 + { 0, 0, 0 }
28195 };
28196
28197 static int usblp_wwait(struct usblp *usblp, int nonblock);
28198 @@ -1397,7 +1397,7 @@ static const struct usb_device_id usblp_
28199 { USB_INTERFACE_INFO(7, 1, 2) },
28200 { USB_INTERFACE_INFO(7, 1, 3) },
28201 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
28202 - { } /* Terminating entry */
28203 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
28204 };
28205
28206 MODULE_DEVICE_TABLE(usb, usblp_ids);
28207 diff -urNp linux-2.6.36/drivers/usb/core/hcd.c linux-2.6.36/drivers/usb/core/hcd.c
28208 --- linux-2.6.36/drivers/usb/core/hcd.c 2010-10-20 16:30:22.000000000 -0400
28209 +++ linux-2.6.36/drivers/usb/core/hcd.c 2010-11-06 18:58:15.000000000 -0400
28210 @@ -2420,7 +2420,7 @@ EXPORT_SYMBOL_GPL(usb_hcd_platform_shutd
28211
28212 #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
28213
28214 -struct usb_mon_operations *mon_ops;
28215 +const struct usb_mon_operations *mon_ops;
28216
28217 /*
28218 * The registration is unlocked.
28219 @@ -2430,7 +2430,7 @@ struct usb_mon_operations *mon_ops;
28220 * symbols from usbcore, usbcore gets referenced and cannot be unloaded first.
28221 */
28222
28223 -int usb_mon_register (struct usb_mon_operations *ops)
28224 +int usb_mon_register (const struct usb_mon_operations *ops)
28225 {
28226
28227 if (mon_ops)
28228 diff -urNp linux-2.6.36/drivers/usb/core/hub.c linux-2.6.36/drivers/usb/core/hub.c
28229 --- linux-2.6.36/drivers/usb/core/hub.c 2010-10-20 16:30:22.000000000 -0400
28230 +++ linux-2.6.36/drivers/usb/core/hub.c 2010-11-06 18:58:15.000000000 -0400
28231 @@ -3456,7 +3456,7 @@ static const struct usb_device_id hub_id
28232 .bDeviceClass = USB_CLASS_HUB},
28233 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
28234 .bInterfaceClass = USB_CLASS_HUB},
28235 - { } /* Terminating entry */
28236 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
28237 };
28238
28239 MODULE_DEVICE_TABLE (usb, hub_id_table);
28240 diff -urNp linux-2.6.36/drivers/usb/core/message.c linux-2.6.36/drivers/usb/core/message.c
28241 --- linux-2.6.36/drivers/usb/core/message.c 2010-10-20 16:30:22.000000000 -0400
28242 +++ linux-2.6.36/drivers/usb/core/message.c 2010-11-06 18:58:15.000000000 -0400
28243 @@ -869,8 +869,8 @@ char *usb_cache_string(struct usb_device
28244 buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
28245 if (buf) {
28246 len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
28247 - if (len > 0) {
28248 - smallbuf = kmalloc(++len, GFP_NOIO);
28249 + if (len++ > 0) {
28250 + smallbuf = kmalloc(len, GFP_NOIO);
28251 if (!smallbuf)
28252 return buf;
28253 memcpy(smallbuf, buf, len);
28254 diff -urNp linux-2.6.36/drivers/usb/early/ehci-dbgp.c linux-2.6.36/drivers/usb/early/ehci-dbgp.c
28255 --- linux-2.6.36/drivers/usb/early/ehci-dbgp.c 2010-10-20 16:30:22.000000000 -0400
28256 +++ linux-2.6.36/drivers/usb/early/ehci-dbgp.c 2010-11-06 18:58:15.000000000 -0400
28257 @@ -96,6 +96,7 @@ static inline u32 dbgp_len_update(u32 x,
28258 }
28259
28260 #ifdef CONFIG_KGDB
28261 +/* cannot be const, see kgdbdbgp_parse_config */
28262 static struct kgdb_io kgdbdbgp_io_ops;
28263 #define dbgp_kgdb_mode (dbg_io_ops == &kgdbdbgp_io_ops)
28264 #else
28265 @@ -1026,6 +1027,7 @@ static void kgdbdbgp_write_char(u8 chr)
28266 early_dbgp_write(NULL, &chr, 1);
28267 }
28268
28269 +/* cannot be const, see kgdbdbgp_parse_config() */
28270 static struct kgdb_io kgdbdbgp_io_ops = {
28271 .name = "kgdbdbgp",
28272 .read_char = kgdbdbgp_read_char,
28273 diff -urNp linux-2.6.36/drivers/usb/host/ehci-pci.c linux-2.6.36/drivers/usb/host/ehci-pci.c
28274 --- linux-2.6.36/drivers/usb/host/ehci-pci.c 2010-10-20 16:30:22.000000000 -0400
28275 +++ linux-2.6.36/drivers/usb/host/ehci-pci.c 2010-11-06 18:58:15.000000000 -0400
28276 @@ -445,7 +445,7 @@ static const struct pci_device_id pci_id
28277 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
28278 .driver_data = (unsigned long) &ehci_pci_hc_driver,
28279 },
28280 - { /* end: all zeroes */ }
28281 + { 0, 0, 0, 0, 0, 0, 0 }
28282 };
28283 MODULE_DEVICE_TABLE(pci, pci_ids);
28284
28285 diff -urNp linux-2.6.36/drivers/usb/host/uhci-hcd.c linux-2.6.36/drivers/usb/host/uhci-hcd.c
28286 --- linux-2.6.36/drivers/usb/host/uhci-hcd.c 2010-10-20 16:30:22.000000000 -0400
28287 +++ linux-2.6.36/drivers/usb/host/uhci-hcd.c 2010-11-06 18:58:15.000000000 -0400
28288 @@ -948,7 +948,7 @@ static const struct pci_device_id uhci_p
28289 /* handle any USB UHCI controller */
28290 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
28291 .driver_data = (unsigned long) &uhci_driver,
28292 - }, { /* end: all zeroes */ }
28293 + }, { 0, 0, 0, 0, 0, 0, 0 }
28294 };
28295
28296 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
28297 diff -urNp linux-2.6.36/drivers/usb/mon/mon_main.c linux-2.6.36/drivers/usb/mon/mon_main.c
28298 --- linux-2.6.36/drivers/usb/mon/mon_main.c 2010-10-20 16:30:22.000000000 -0400
28299 +++ linux-2.6.36/drivers/usb/mon/mon_main.c 2010-11-06 18:58:15.000000000 -0400
28300 @@ -240,7 +240,7 @@ static struct notifier_block mon_nb = {
28301 /*
28302 * Ops
28303 */
28304 -static struct usb_mon_operations mon_ops_0 = {
28305 +static const struct usb_mon_operations mon_ops_0 = {
28306 .urb_submit = mon_submit,
28307 .urb_submit_error = mon_submit_error,
28308 .urb_complete = mon_complete,
28309 diff -urNp linux-2.6.36/drivers/usb/storage/debug.h linux-2.6.36/drivers/usb/storage/debug.h
28310 --- linux-2.6.36/drivers/usb/storage/debug.h 2010-10-20 16:30:22.000000000 -0400
28311 +++ linux-2.6.36/drivers/usb/storage/debug.h 2010-11-06 18:58:15.000000000 -0400
28312 @@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
28313 #define US_DEBUGPX(x...) printk( x )
28314 #define US_DEBUG(x) x
28315 #else
28316 -#define US_DEBUGP(x...)
28317 -#define US_DEBUGPX(x...)
28318 -#define US_DEBUG(x)
28319 +#define US_DEBUGP(x...) do {} while (0)
28320 +#define US_DEBUGPX(x...) do {} while (0)
28321 +#define US_DEBUG(x) do {} while (0)
28322 #endif
28323
28324 #endif
28325 diff -urNp linux-2.6.36/drivers/usb/storage/usb.c linux-2.6.36/drivers/usb/storage/usb.c
28326 --- linux-2.6.36/drivers/usb/storage/usb.c 2010-10-20 16:30:22.000000000 -0400
28327 +++ linux-2.6.36/drivers/usb/storage/usb.c 2010-11-06 18:58:15.000000000 -0400
28328 @@ -122,7 +122,7 @@ MODULE_PARM_DESC(quirks, "supplemental l
28329
28330 static struct us_unusual_dev us_unusual_dev_list[] = {
28331 # include "unusual_devs.h"
28332 - { } /* Terminating entry */
28333 + { NULL, NULL, 0, 0, NULL } /* Terminating entry */
28334 };
28335
28336 #undef UNUSUAL_DEV
28337 diff -urNp linux-2.6.36/drivers/usb/storage/usual-tables.c linux-2.6.36/drivers/usb/storage/usual-tables.c
28338 --- linux-2.6.36/drivers/usb/storage/usual-tables.c 2010-10-20 16:30:22.000000000 -0400
28339 +++ linux-2.6.36/drivers/usb/storage/usual-tables.c 2010-11-06 18:58:15.000000000 -0400
28340 @@ -48,7 +48,7 @@
28341
28342 struct usb_device_id usb_storage_usb_ids[] = {
28343 # include "unusual_devs.h"
28344 - { } /* Terminating entry */
28345 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
28346 };
28347 EXPORT_SYMBOL_GPL(usb_storage_usb_ids);
28348
28349 diff -urNp linux-2.6.36/drivers/uwb/wlp/messages.c linux-2.6.36/drivers/uwb/wlp/messages.c
28350 --- linux-2.6.36/drivers/uwb/wlp/messages.c 2010-10-20 16:30:22.000000000 -0400
28351 +++ linux-2.6.36/drivers/uwb/wlp/messages.c 2010-11-06 18:58:15.000000000 -0400
28352 @@ -920,7 +920,7 @@ int wlp_parse_f0(struct wlp *wlp, struct
28353 size_t len = skb->len;
28354 size_t used;
28355 ssize_t result;
28356 - struct wlp_nonce enonce, rnonce;
28357 + struct wlp_nonce enonce = {{0}}, rnonce = {{0}};
28358 enum wlp_assc_error assc_err;
28359 char enonce_buf[WLP_WSS_NONCE_STRSIZE];
28360 char rnonce_buf[WLP_WSS_NONCE_STRSIZE];
28361 diff -urNp linux-2.6.36/drivers/vhost/vhost.c linux-2.6.36/drivers/vhost/vhost.c
28362 --- linux-2.6.36/drivers/vhost/vhost.c 2010-10-20 16:30:22.000000000 -0400
28363 +++ linux-2.6.36/drivers/vhost/vhost.c 2010-11-06 18:58:15.000000000 -0400
28364 @@ -503,7 +503,7 @@ static int init_used(struct vhost_virtqu
28365 return get_user(vq->last_used_idx, &used->idx);
28366 }
28367
28368 -static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
28369 +static long vhost_set_vring(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
28370 {
28371 struct file *eventfp, *filep = NULL,
28372 *pollstart = NULL, *pollstop = NULL;
28373 diff -urNp linux-2.6.36/drivers/video/atmel_lcdfb.c linux-2.6.36/drivers/video/atmel_lcdfb.c
28374 --- linux-2.6.36/drivers/video/atmel_lcdfb.c 2010-10-20 16:30:22.000000000 -0400
28375 +++ linux-2.6.36/drivers/video/atmel_lcdfb.c 2010-11-06 18:58:15.000000000 -0400
28376 @@ -111,7 +111,7 @@ static int atmel_bl_get_brightness(struc
28377 return lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
28378 }
28379
28380 -static struct backlight_ops atmel_lcdc_bl_ops = {
28381 +static const struct backlight_ops atmel_lcdc_bl_ops = {
28382 .update_status = atmel_bl_update_status,
28383 .get_brightness = atmel_bl_get_brightness,
28384 };
28385 diff -urNp linux-2.6.36/drivers/video/aty/aty128fb.c linux-2.6.36/drivers/video/aty/aty128fb.c
28386 --- linux-2.6.36/drivers/video/aty/aty128fb.c 2010-10-20 16:30:22.000000000 -0400
28387 +++ linux-2.6.36/drivers/video/aty/aty128fb.c 2010-11-06 18:58:15.000000000 -0400
28388 @@ -1786,7 +1786,7 @@ static int aty128_bl_get_brightness(stru
28389 return bd->props.brightness;
28390 }
28391
28392 -static struct backlight_ops aty128_bl_data = {
28393 +static const struct backlight_ops aty128_bl_data = {
28394 .get_brightness = aty128_bl_get_brightness,
28395 .update_status = aty128_bl_update_status,
28396 };
28397 diff -urNp linux-2.6.36/drivers/video/aty/atyfb_base.c linux-2.6.36/drivers/video/aty/atyfb_base.c
28398 --- linux-2.6.36/drivers/video/aty/atyfb_base.c 2010-10-20 16:30:22.000000000 -0400
28399 +++ linux-2.6.36/drivers/video/aty/atyfb_base.c 2010-11-06 18:58:15.000000000 -0400
28400 @@ -2221,7 +2221,7 @@ static int aty_bl_get_brightness(struct
28401 return bd->props.brightness;
28402 }
28403
28404 -static struct backlight_ops aty_bl_data = {
28405 +static const struct backlight_ops aty_bl_data = {
28406 .get_brightness = aty_bl_get_brightness,
28407 .update_status = aty_bl_update_status,
28408 };
28409 diff -urNp linux-2.6.36/drivers/video/aty/radeon_backlight.c linux-2.6.36/drivers/video/aty/radeon_backlight.c
28410 --- linux-2.6.36/drivers/video/aty/radeon_backlight.c 2010-10-20 16:30:22.000000000 -0400
28411 +++ linux-2.6.36/drivers/video/aty/radeon_backlight.c 2010-11-06 18:58:15.000000000 -0400
28412 @@ -128,7 +128,7 @@ static int radeon_bl_get_brightness(stru
28413 return bd->props.brightness;
28414 }
28415
28416 -static struct backlight_ops radeon_bl_data = {
28417 +static const struct backlight_ops radeon_bl_data = {
28418 .get_brightness = radeon_bl_get_brightness,
28419 .update_status = radeon_bl_update_status,
28420 };
28421 diff -urNp linux-2.6.36/drivers/video/backlight/88pm860x_bl.c linux-2.6.36/drivers/video/backlight/88pm860x_bl.c
28422 --- linux-2.6.36/drivers/video/backlight/88pm860x_bl.c 2010-10-20 16:30:22.000000000 -0400
28423 +++ linux-2.6.36/drivers/video/backlight/88pm860x_bl.c 2010-11-06 18:58:15.000000000 -0400
28424 @@ -155,7 +155,7 @@ out:
28425 return -EINVAL;
28426 }
28427
28428 -static struct backlight_ops pm860x_backlight_ops = {
28429 +static const struct backlight_ops pm860x_backlight_ops = {
28430 .options = BL_CORE_SUSPENDRESUME,
28431 .update_status = pm860x_backlight_update_status,
28432 .get_brightness = pm860x_backlight_get_brightness,
28433 diff -urNp linux-2.6.36/drivers/video/backlight/max8925_bl.c linux-2.6.36/drivers/video/backlight/max8925_bl.c
28434 --- linux-2.6.36/drivers/video/backlight/max8925_bl.c 2010-10-20 16:30:22.000000000 -0400
28435 +++ linux-2.6.36/drivers/video/backlight/max8925_bl.c 2010-11-06 18:58:15.000000000 -0400
28436 @@ -92,7 +92,7 @@ static int max8925_backlight_get_brightn
28437 return ret;
28438 }
28439
28440 -static struct backlight_ops max8925_backlight_ops = {
28441 +static const struct backlight_ops max8925_backlight_ops = {
28442 .options = BL_CORE_SUSPENDRESUME,
28443 .update_status = max8925_backlight_update_status,
28444 .get_brightness = max8925_backlight_get_brightness,
28445 diff -urNp linux-2.6.36/drivers/video/fbcmap.c linux-2.6.36/drivers/video/fbcmap.c
28446 --- linux-2.6.36/drivers/video/fbcmap.c 2010-10-20 16:30:22.000000000 -0400
28447 +++ linux-2.6.36/drivers/video/fbcmap.c 2010-11-06 18:58:15.000000000 -0400
28448 @@ -266,8 +266,7 @@ int fb_set_user_cmap(struct fb_cmap_user
28449 rc = -ENODEV;
28450 goto out;
28451 }
28452 - if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
28453 - !info->fbops->fb_setcmap)) {
28454 + if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap) {
28455 rc = -EINVAL;
28456 goto out1;
28457 }
28458 diff -urNp linux-2.6.36/drivers/video/fbmem.c linux-2.6.36/drivers/video/fbmem.c
28459 --- linux-2.6.36/drivers/video/fbmem.c 2010-10-20 16:30:22.000000000 -0400
28460 +++ linux-2.6.36/drivers/video/fbmem.c 2010-11-06 18:58:15.000000000 -0400
28461 @@ -403,7 +403,7 @@ static void fb_do_show_logo(struct fb_in
28462 image->dx += image->width + 8;
28463 }
28464 } else if (rotate == FB_ROTATE_UD) {
28465 - for (x = 0; x < num && image->dx >= 0; x++) {
28466 + for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
28467 info->fbops->fb_imageblit(info, image);
28468 image->dx -= image->width + 8;
28469 }
28470 @@ -415,7 +415,7 @@ static void fb_do_show_logo(struct fb_in
28471 image->dy += image->height + 8;
28472 }
28473 } else if (rotate == FB_ROTATE_CCW) {
28474 - for (x = 0; x < num && image->dy >= 0; x++) {
28475 + for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
28476 info->fbops->fb_imageblit(info, image);
28477 image->dy -= image->height + 8;
28478 }
28479 @@ -1119,7 +1119,7 @@ static long do_fb_ioctl(struct fb_info *
28480 return -EFAULT;
28481 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
28482 return -EINVAL;
28483 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
28484 + if (con2fb.framebuffer >= FB_MAX)
28485 return -EINVAL;
28486 if (!registered_fb[con2fb.framebuffer])
28487 request_module("fb%d", con2fb.framebuffer);
28488 diff -urNp linux-2.6.36/drivers/video/fbmon.c linux-2.6.36/drivers/video/fbmon.c
28489 --- linux-2.6.36/drivers/video/fbmon.c 2010-10-20 16:30:22.000000000 -0400
28490 +++ linux-2.6.36/drivers/video/fbmon.c 2010-11-06 18:58:15.000000000 -0400
28491 @@ -46,7 +46,7 @@
28492 #ifdef DEBUG
28493 #define DPRINTK(fmt, args...) printk(fmt,## args)
28494 #else
28495 -#define DPRINTK(fmt, args...)
28496 +#define DPRINTK(fmt, args...) do {} while (0)
28497 #endif
28498
28499 #define FBMON_FIX_HEADER 1
28500 diff -urNp linux-2.6.36/drivers/video/i810/i810_accel.c linux-2.6.36/drivers/video/i810/i810_accel.c
28501 --- linux-2.6.36/drivers/video/i810/i810_accel.c 2010-10-20 16:30:22.000000000 -0400
28502 +++ linux-2.6.36/drivers/video/i810/i810_accel.c 2010-11-06 18:58:15.000000000 -0400
28503 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
28504 }
28505 }
28506 printk("ringbuffer lockup!!!\n");
28507 + printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
28508 i810_report_error(mmio);
28509 par->dev_flags |= LOCKUP;
28510 info->pixmap.scan_align = 1;
28511 diff -urNp linux-2.6.36/drivers/video/i810/i810_main.c linux-2.6.36/drivers/video/i810/i810_main.c
28512 --- linux-2.6.36/drivers/video/i810/i810_main.c 2010-10-20 16:30:22.000000000 -0400
28513 +++ linux-2.6.36/drivers/video/i810/i810_main.c 2010-11-06 18:58:15.000000000 -0400
28514 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
28515 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
28516 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
28517 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
28518 - { 0 },
28519 + { 0, 0, 0, 0, 0, 0, 0 },
28520 };
28521
28522 static struct pci_driver i810fb_driver = {
28523 diff -urNp linux-2.6.36/drivers/video/modedb.c linux-2.6.36/drivers/video/modedb.c
28524 --- linux-2.6.36/drivers/video/modedb.c 2010-10-20 16:30:22.000000000 -0400
28525 +++ linux-2.6.36/drivers/video/modedb.c 2010-11-06 18:58:15.000000000 -0400
28526 @@ -40,240 +40,240 @@ static const struct fb_videomode modedb[
28527 {
28528 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
28529 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
28530 - 0, FB_VMODE_NONINTERLACED
28531 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28532 }, {
28533 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
28534 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
28535 - 0, FB_VMODE_NONINTERLACED
28536 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28537 }, {
28538 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
28539 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
28540 - 0, FB_VMODE_NONINTERLACED
28541 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28542 }, {
28543 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
28544 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
28545 - 0, FB_VMODE_INTERLACED
28546 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
28547 }, {
28548 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
28549 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
28550 - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28551 + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28552 }, {
28553 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
28554 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
28555 - 0, FB_VMODE_NONINTERLACED
28556 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28557 }, {
28558 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
28559 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
28560 - 0, FB_VMODE_NONINTERLACED
28561 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28562 }, {
28563 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
28564 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
28565 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28566 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28567 }, {
28568 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
28569 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
28570 - 0, FB_VMODE_NONINTERLACED
28571 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28572 }, {
28573 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
28574 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
28575 - 0, FB_VMODE_INTERLACED
28576 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
28577 }, {
28578 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
28579 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
28580 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28581 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28582 }, {
28583 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
28584 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
28585 - 0, FB_VMODE_NONINTERLACED
28586 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28587 }, {
28588 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
28589 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
28590 - 0, FB_VMODE_NONINTERLACED
28591 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28592 }, {
28593 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
28594 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
28595 - 0, FB_VMODE_NONINTERLACED
28596 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28597 }, {
28598 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
28599 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
28600 - 0, FB_VMODE_NONINTERLACED
28601 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28602 }, {
28603 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
28604 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
28605 - 0, FB_VMODE_NONINTERLACED
28606 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28607 }, {
28608 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
28609 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
28610 - 0, FB_VMODE_INTERLACED
28611 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
28612 }, {
28613 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
28614 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
28615 - 0, FB_VMODE_NONINTERLACED
28616 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28617 }, {
28618 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
28619 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
28620 - 0, FB_VMODE_NONINTERLACED
28621 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28622 }, {
28623 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
28624 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
28625 - 0, FB_VMODE_NONINTERLACED
28626 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28627 }, {
28628 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
28629 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
28630 - 0, FB_VMODE_NONINTERLACED
28631 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28632 }, {
28633 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
28634 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
28635 - 0, FB_VMODE_NONINTERLACED
28636 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28637 }, {
28638 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
28639 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
28640 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28641 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28642 }, {
28643 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
28644 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
28645 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28646 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28647 }, {
28648 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
28649 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
28650 - 0, FB_VMODE_NONINTERLACED
28651 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28652 }, {
28653 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
28654 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
28655 - 0, FB_VMODE_NONINTERLACED
28656 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28657 }, {
28658 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
28659 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
28660 - 0, FB_VMODE_NONINTERLACED
28661 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28662 }, {
28663 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
28664 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
28665 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28666 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28667 }, {
28668 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
28669 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
28670 - 0, FB_VMODE_NONINTERLACED
28671 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28672 }, {
28673 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
28674 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
28675 - 0, FB_VMODE_NONINTERLACED
28676 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28677 }, {
28678 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
28679 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
28680 - 0, FB_VMODE_NONINTERLACED
28681 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28682 }, {
28683 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
28684 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
28685 - 0, FB_VMODE_NONINTERLACED
28686 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28687 }, {
28688 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
28689 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
28690 - 0, FB_VMODE_NONINTERLACED
28691 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28692 }, {
28693 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
28694 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
28695 - 0, FB_VMODE_NONINTERLACED
28696 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28697 }, {
28698 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
28699 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
28700 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28701 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28702 }, {
28703 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
28704 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
28705 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28706 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28707 }, {
28708 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
28709 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
28710 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28711 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28712 }, {
28713 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
28714 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
28715 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28716 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28717 }, {
28718 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
28719 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
28720 - 0, FB_VMODE_NONINTERLACED
28721 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28722 }, {
28723 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
28724 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
28725 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28726 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28727 }, {
28728 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
28729 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
28730 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28731 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28732 }, {
28733 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
28734 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
28735 - 0, FB_VMODE_NONINTERLACED
28736 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28737 }, {
28738 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
28739 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
28740 - 0, FB_VMODE_NONINTERLACED
28741 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28742 }, {
28743 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
28744 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
28745 - 0, FB_VMODE_DOUBLE
28746 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28747 }, {
28748 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
28749 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
28750 - 0, FB_VMODE_DOUBLE
28751 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28752 }, {
28753 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
28754 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
28755 - 0, FB_VMODE_DOUBLE
28756 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28757 }, {
28758 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
28759 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
28760 - 0, FB_VMODE_DOUBLE
28761 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28762 }, {
28763 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
28764 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
28765 - 0, FB_VMODE_DOUBLE
28766 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28767 }, {
28768 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
28769 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
28770 - 0, FB_VMODE_DOUBLE
28771 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28772 }, {
28773 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
28774 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
28775 - 0, FB_VMODE_DOUBLE
28776 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28777 }, {
28778 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
28779 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
28780 - 0, FB_VMODE_DOUBLE
28781 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28782 }, {
28783 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
28784 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
28785 - 0, FB_VMODE_DOUBLE
28786 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28787 }, {
28788 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
28789 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
28790 - 0, FB_VMODE_DOUBLE
28791 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
28792 }, {
28793 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
28794 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
28795 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
28796 - FB_VMODE_NONINTERLACED
28797 + FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28798 }, {
28799 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
28800 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
28801 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
28802 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28803 }, {
28804 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
28805 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
28806 - 0, FB_VMODE_NONINTERLACED
28807 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28808 }, {
28809 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
28810 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
28811 - 0, FB_VMODE_NONINTERLACED
28812 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
28813 }, {
28814 /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
28815 NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5,
28816 - 0, FB_VMODE_INTERLACED
28817 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
28818 }, {
28819 /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
28820 NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5,
28821 - 0, FB_VMODE_INTERLACED
28822 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
28823 },
28824 };
28825
28826 diff -urNp linux-2.6.36/drivers/video/nvidia/nv_backlight.c linux-2.6.36/drivers/video/nvidia/nv_backlight.c
28827 --- linux-2.6.36/drivers/video/nvidia/nv_backlight.c 2010-10-20 16:30:22.000000000 -0400
28828 +++ linux-2.6.36/drivers/video/nvidia/nv_backlight.c 2010-11-06 18:58:15.000000000 -0400
28829 @@ -87,7 +87,7 @@ static int nvidia_bl_get_brightness(stru
28830 return bd->props.brightness;
28831 }
28832
28833 -static struct backlight_ops nvidia_bl_ops = {
28834 +static const struct backlight_ops nvidia_bl_ops = {
28835 .get_brightness = nvidia_bl_get_brightness,
28836 .update_status = nvidia_bl_update_status,
28837 };
28838 diff -urNp linux-2.6.36/drivers/video/omap2/displays/panel-taal.c linux-2.6.36/drivers/video/omap2/displays/panel-taal.c
28839 --- linux-2.6.36/drivers/video/omap2/displays/panel-taal.c 2010-10-20 16:30:22.000000000 -0400
28840 +++ linux-2.6.36/drivers/video/omap2/displays/panel-taal.c 2010-11-06 18:58:15.000000000 -0400
28841 @@ -465,7 +465,7 @@ static int taal_bl_get_intensity(struct
28842 return 0;
28843 }
28844
28845 -static struct backlight_ops taal_bl_ops = {
28846 +static const struct backlight_ops taal_bl_ops = {
28847 .get_brightness = taal_bl_get_intensity,
28848 .update_status = taal_bl_update_status,
28849 };
28850 diff -urNp linux-2.6.36/drivers/video/riva/fbdev.c linux-2.6.36/drivers/video/riva/fbdev.c
28851 --- linux-2.6.36/drivers/video/riva/fbdev.c 2010-10-20 16:30:22.000000000 -0400
28852 +++ linux-2.6.36/drivers/video/riva/fbdev.c 2010-11-06 18:58:15.000000000 -0400
28853 @@ -331,7 +331,7 @@ static int riva_bl_get_brightness(struct
28854 return bd->props.brightness;
28855 }
28856
28857 -static struct backlight_ops riva_bl_ops = {
28858 +static const struct backlight_ops riva_bl_ops = {
28859 .get_brightness = riva_bl_get_brightness,
28860 .update_status = riva_bl_update_status,
28861 };
28862 diff -urNp linux-2.6.36/drivers/video/uvesafb.c linux-2.6.36/drivers/video/uvesafb.c
28863 --- linux-2.6.36/drivers/video/uvesafb.c 2010-10-20 16:30:22.000000000 -0400
28864 +++ linux-2.6.36/drivers/video/uvesafb.c 2010-11-06 18:58:15.000000000 -0400
28865 @@ -19,6 +19,7 @@
28866 #include <linux/io.h>
28867 #include <linux/mutex.h>
28868 #include <linux/slab.h>
28869 +#include <linux/moduleloader.h>
28870 #include <video/edid.h>
28871 #include <video/uvesafb.h>
28872 #ifdef CONFIG_X86
28873 @@ -121,7 +122,7 @@ static int uvesafb_helper_start(void)
28874 NULL,
28875 };
28876
28877 - return call_usermodehelper(v86d_path, argv, envp, 1);
28878 + return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
28879 }
28880
28881 /*
28882 @@ -569,10 +570,32 @@ static int __devinit uvesafb_vbe_getpmi(
28883 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
28884 par->pmi_setpal = par->ypan = 0;
28885 } else {
28886 +
28887 +#ifdef CONFIG_PAX_KERNEXEC
28888 +#ifdef CONFIG_MODULES
28889 + par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
28890 +#endif
28891 + if (!par->pmi_code) {
28892 + par->pmi_setpal = par->ypan = 0;
28893 + return 0;
28894 + }
28895 +#endif
28896 +
28897 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
28898 + task->t.regs.edi);
28899 +
28900 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
28901 + pax_open_kernel();
28902 + memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
28903 + pax_close_kernel();
28904 +
28905 + par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
28906 + par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
28907 +#else
28908 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
28909 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
28910 +#endif
28911 +
28912 printk(KERN_INFO "uvesafb: protected mode interface info at "
28913 "%04x:%04x\n",
28914 (u16)task->t.regs.es, (u16)task->t.regs.edi);
28915 @@ -1800,6 +1823,11 @@ out:
28916 if (par->vbe_modes)
28917 kfree(par->vbe_modes);
28918
28919 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
28920 + if (par->pmi_code)
28921 + module_free_exec(NULL, par->pmi_code);
28922 +#endif
28923 +
28924 framebuffer_release(info);
28925 return err;
28926 }
28927 @@ -1826,6 +1854,12 @@ static int uvesafb_remove(struct platfor
28928 kfree(par->vbe_state_orig);
28929 if (par->vbe_state_saved)
28930 kfree(par->vbe_state_saved);
28931 +
28932 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
28933 + if (par->pmi_code)
28934 + module_free_exec(NULL, par->pmi_code);
28935 +#endif
28936 +
28937 }
28938
28939 framebuffer_release(info);
28940 diff -urNp linux-2.6.36/drivers/video/vesafb.c linux-2.6.36/drivers/video/vesafb.c
28941 --- linux-2.6.36/drivers/video/vesafb.c 2010-10-20 16:30:22.000000000 -0400
28942 +++ linux-2.6.36/drivers/video/vesafb.c 2010-11-06 18:58:15.000000000 -0400
28943 @@ -9,6 +9,7 @@
28944 */
28945
28946 #include <linux/module.h>
28947 +#include <linux/moduleloader.h>
28948 #include <linux/kernel.h>
28949 #include <linux/errno.h>
28950 #include <linux/string.h>
28951 @@ -52,8 +53,8 @@ static int vram_remap __initdata; /*
28952 static int vram_total __initdata; /* Set total amount of memory */
28953 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
28954 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
28955 -static void (*pmi_start)(void) __read_mostly;
28956 -static void (*pmi_pal) (void) __read_mostly;
28957 +static void (*pmi_start)(void) __read_only;
28958 +static void (*pmi_pal) (void) __read_only;
28959 static int depth __read_mostly;
28960 static int vga_compat __read_mostly;
28961 /* --------------------------------------------------------------------- */
28962 @@ -232,6 +233,7 @@ static int __init vesafb_probe(struct pl
28963 unsigned int size_vmode;
28964 unsigned int size_remap;
28965 unsigned int size_total;
28966 + void *pmi_code = NULL;
28967
28968 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
28969 return -ENODEV;
28970 @@ -274,10 +276,6 @@ static int __init vesafb_probe(struct pl
28971 size_remap = size_total;
28972 vesafb_fix.smem_len = size_remap;
28973
28974 -#ifndef __i386__
28975 - screen_info.vesapm_seg = 0;
28976 -#endif
28977 -
28978 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
28979 printk(KERN_WARNING
28980 "vesafb: cannot reserve video memory at 0x%lx\n",
28981 @@ -319,9 +317,21 @@ static int __init vesafb_probe(struct pl
28982 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
28983 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
28984
28985 +#ifdef __i386__
28986 +
28987 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
28988 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
28989 + if (!pmi_code)
28990 +#elif !defined(CONFIG_PAX_KERNEXEC)
28991 + if (0)
28992 +#endif
28993 +
28994 +#endif
28995 + screen_info.vesapm_seg = 0;
28996 +
28997 if (screen_info.vesapm_seg) {
28998 - printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
28999 - screen_info.vesapm_seg,screen_info.vesapm_off);
29000 + printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
29001 + screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
29002 }
29003
29004 if (screen_info.vesapm_seg < 0xc000)
29005 @@ -329,9 +339,25 @@ static int __init vesafb_probe(struct pl
29006
29007 if (ypan || pmi_setpal) {
29008 unsigned short *pmi_base;
29009 - pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
29010 - pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
29011 - pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
29012 +
29013 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
29014 +
29015 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
29016 + pax_open_kernel();
29017 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
29018 +#else
29019 + pmi_code = pmi_base;
29020 +#endif
29021 +
29022 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
29023 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
29024 +
29025 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
29026 + pmi_start = ktva_ktla(pmi_start);
29027 + pmi_pal = ktva_ktla(pmi_pal);
29028 + pax_close_kernel();
29029 +#endif
29030 +
29031 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
29032 if (pmi_base[3]) {
29033 printk(KERN_INFO "vesafb: pmi: ports = ");
29034 @@ -473,6 +499,11 @@ static int __init vesafb_probe(struct pl
29035 info->node, info->fix.id);
29036 return 0;
29037 err:
29038 +
29039 +#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
29040 + module_free_exec(NULL, pmi_code);
29041 +#endif
29042 +
29043 if (info->screen_base)
29044 iounmap(info->screen_base);
29045 framebuffer_release(info);
29046 diff -urNp linux-2.6.36/fs/9p/vfs_inode.c linux-2.6.36/fs/9p/vfs_inode.c
29047 --- linux-2.6.36/fs/9p/vfs_inode.c 2010-10-20 16:30:22.000000000 -0400
29048 +++ linux-2.6.36/fs/9p/vfs_inode.c 2010-11-06 18:58:15.000000000 -0400
29049 @@ -1539,7 +1539,7 @@ static void *v9fs_vfs_follow_link(struct
29050 static void
29051 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
29052 {
29053 - char *s = nd_get_link(nd);
29054 + const char *s = nd_get_link(nd);
29055
29056 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name,
29057 IS_ERR(s) ? "<error>" : s);
29058 diff -urNp linux-2.6.36/fs/aio.c linux-2.6.36/fs/aio.c
29059 --- linux-2.6.36/fs/aio.c 2010-10-20 16:30:22.000000000 -0400
29060 +++ linux-2.6.36/fs/aio.c 2010-11-06 18:58:15.000000000 -0400
29061 @@ -130,7 +130,7 @@ static int aio_setup_ring(struct kioctx
29062 size += sizeof(struct io_event) * nr_events;
29063 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
29064
29065 - if (nr_pages < 0)
29066 + if (nr_pages <= 0)
29067 return -EINVAL;
29068
29069 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
29070 diff -urNp linux-2.6.36/fs/attr.c linux-2.6.36/fs/attr.c
29071 --- linux-2.6.36/fs/attr.c 2010-10-20 16:30:22.000000000 -0400
29072 +++ linux-2.6.36/fs/attr.c 2010-11-06 18:58:50.000000000 -0400
29073 @@ -98,6 +98,7 @@ int inode_newsize_ok(const struct inode
29074 unsigned long limit;
29075
29076 limit = rlimit(RLIMIT_FSIZE);
29077 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long)offset, 1);
29078 if (limit != RLIM_INFINITY && offset > limit)
29079 goto out_sig;
29080 if (offset > inode->i_sb->s_maxbytes)
29081 diff -urNp linux-2.6.36/fs/autofs/root.c linux-2.6.36/fs/autofs/root.c
29082 --- linux-2.6.36/fs/autofs/root.c 2010-10-20 16:30:22.000000000 -0400
29083 +++ linux-2.6.36/fs/autofs/root.c 2010-11-06 19:50:37.000000000 -0400
29084 @@ -27,7 +27,9 @@ static int autofs_root_unlink(struct ino
29085 static int autofs_root_rmdir(struct inode *,struct dentry *);
29086 static int autofs_root_mkdir(struct inode *,struct dentry *,int);
29087 static long autofs_root_ioctl(struct file *,unsigned int,unsigned long);
29088 +#ifdef CONFIG_COMPAT
29089 static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long);
29090 +#endif
29091
29092 const struct file_operations autofs_root_operations = {
29093 .llseek = generic_file_llseek,
29094 @@ -306,7 +308,8 @@ static int autofs_root_symlink(struct in
29095 set_bit(n,sbi->symlink_bitmap);
29096 sl = &sbi->symlink[n];
29097 sl->len = strlen(symname);
29098 - sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
29099 + slsize = sl->len+1;
29100 + sl->data = kmalloc(slsize, GFP_KERNEL);
29101 if (!sl->data) {
29102 clear_bit(n,sbi->symlink_bitmap);
29103 unlock_kernel();
29104 diff -urNp linux-2.6.36/fs/autofs4/root.c linux-2.6.36/fs/autofs4/root.c
29105 --- linux-2.6.36/fs/autofs4/root.c 2010-10-20 16:30:22.000000000 -0400
29106 +++ linux-2.6.36/fs/autofs4/root.c 2010-11-06 19:50:56.000000000 -0400
29107 @@ -28,7 +28,9 @@ static int autofs4_dir_unlink(struct ino
29108 static int autofs4_dir_rmdir(struct inode *,struct dentry *);
29109 static int autofs4_dir_mkdir(struct inode *,struct dentry *,int);
29110 static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long);
29111 +#ifdef CONFIG_COMPAT
29112 static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long);
29113 +#endif
29114 static int autofs4_dir_open(struct inode *inode, struct file *file);
29115 static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
29116 static void *autofs4_follow_link(struct dentry *, struct nameidata *);
29117 diff -urNp linux-2.6.36/fs/autofs4/symlink.c linux-2.6.36/fs/autofs4/symlink.c
29118 --- linux-2.6.36/fs/autofs4/symlink.c 2010-10-20 16:30:22.000000000 -0400
29119 +++ linux-2.6.36/fs/autofs4/symlink.c 2010-11-06 18:58:15.000000000 -0400
29120 @@ -15,7 +15,7 @@
29121 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
29122 {
29123 struct autofs_info *ino = autofs4_dentry_ino(dentry);
29124 - nd_set_link(nd, (char *)ino->u.symlink);
29125 + nd_set_link(nd, ino->u.symlink);
29126 return NULL;
29127 }
29128
29129 diff -urNp linux-2.6.36/fs/befs/linuxvfs.c linux-2.6.36/fs/befs/linuxvfs.c
29130 --- linux-2.6.36/fs/befs/linuxvfs.c 2010-10-20 16:30:22.000000000 -0400
29131 +++ linux-2.6.36/fs/befs/linuxvfs.c 2010-11-06 18:58:15.000000000 -0400
29132 @@ -493,7 +493,7 @@ static void befs_put_link(struct dentry
29133 {
29134 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
29135 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
29136 - char *link = nd_get_link(nd);
29137 + const char *link = nd_get_link(nd);
29138 if (!IS_ERR(link))
29139 kfree(link);
29140 }
29141 diff -urNp linux-2.6.36/fs/binfmt_aout.c linux-2.6.36/fs/binfmt_aout.c
29142 --- linux-2.6.36/fs/binfmt_aout.c 2010-10-20 16:30:22.000000000 -0400
29143 +++ linux-2.6.36/fs/binfmt_aout.c 2010-11-06 18:58:50.000000000 -0400
29144 @@ -16,6 +16,7 @@
29145 #include <linux/string.h>
29146 #include <linux/fs.h>
29147 #include <linux/file.h>
29148 +#include <linux/security.h>
29149 #include <linux/stat.h>
29150 #include <linux/fcntl.h>
29151 #include <linux/ptrace.h>
29152 @@ -86,6 +87,8 @@ static int aout_core_dump(struct coredum
29153 #endif
29154 # define START_STACK(u) ((void __user *)u.start_stack)
29155
29156 + memset(&dump, 0, sizeof(dump));
29157 +
29158 fs = get_fs();
29159 set_fs(KERNEL_DS);
29160 has_dumped = 1;
29161 @@ -97,10 +100,12 @@ static int aout_core_dump(struct coredum
29162
29163 /* If the size of the dump file exceeds the rlimit, then see what would happen
29164 if we wrote the stack, but not the data area. */
29165 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
29166 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > cprm->limit)
29167 dump.u_dsize = 0;
29168
29169 /* Make sure we have enough room to write the stack and data areas. */
29170 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
29171 if ((dump.u_ssize + 1) * PAGE_SIZE > cprm->limit)
29172 dump.u_ssize = 0;
29173
29174 @@ -234,6 +239,8 @@ static int load_aout_binary(struct linux
29175 rlim = rlimit(RLIMIT_DATA);
29176 if (rlim >= RLIM_INFINITY)
29177 rlim = ~0;
29178 +
29179 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
29180 if (ex.a_data + ex.a_bss > rlim)
29181 return -ENOMEM;
29182
29183 @@ -262,6 +269,27 @@ static int load_aout_binary(struct linux
29184 install_exec_creds(bprm);
29185 current->flags &= ~PF_FORKNOEXEC;
29186
29187 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29188 + current->mm->pax_flags = 0UL;
29189 +#endif
29190 +
29191 +#ifdef CONFIG_PAX_PAGEEXEC
29192 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
29193 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
29194 +
29195 +#ifdef CONFIG_PAX_EMUTRAMP
29196 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
29197 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
29198 +#endif
29199 +
29200 +#ifdef CONFIG_PAX_MPROTECT
29201 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
29202 + current->mm->pax_flags |= MF_PAX_MPROTECT;
29203 +#endif
29204 +
29205 + }
29206 +#endif
29207 +
29208 if (N_MAGIC(ex) == OMAGIC) {
29209 unsigned long text_addr, map_size;
29210 loff_t pos;
29211 @@ -334,7 +362,7 @@ static int load_aout_binary(struct linux
29212
29213 down_write(&current->mm->mmap_sem);
29214 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
29215 - PROT_READ | PROT_WRITE | PROT_EXEC,
29216 + PROT_READ | PROT_WRITE,
29217 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
29218 fd_offset + ex.a_text);
29219 up_write(&current->mm->mmap_sem);
29220 diff -urNp linux-2.6.36/fs/binfmt_elf.c linux-2.6.36/fs/binfmt_elf.c
29221 --- linux-2.6.36/fs/binfmt_elf.c 2010-10-20 16:30:22.000000000 -0400
29222 +++ linux-2.6.36/fs/binfmt_elf.c 2010-11-06 18:58:50.000000000 -0400
29223 @@ -51,6 +51,10 @@ static int elf_core_dump(struct coredump
29224 #define elf_core_dump NULL
29225 #endif
29226
29227 +#ifdef CONFIG_PAX_MPROTECT
29228 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags);
29229 +#endif
29230 +
29231 #if ELF_EXEC_PAGESIZE > PAGE_SIZE
29232 #define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
29233 #else
29234 @@ -70,6 +74,11 @@ static struct linux_binfmt elf_format =
29235 .load_binary = load_elf_binary,
29236 .load_shlib = load_elf_library,
29237 .core_dump = elf_core_dump,
29238 +
29239 +#ifdef CONFIG_PAX_MPROTECT
29240 + .handle_mprotect= elf_handle_mprotect,
29241 +#endif
29242 +
29243 .min_coredump = ELF_EXEC_PAGESIZE,
29244 .hasvdso = 1
29245 };
29246 @@ -78,6 +87,8 @@ static struct linux_binfmt elf_format =
29247
29248 static int set_brk(unsigned long start, unsigned long end)
29249 {
29250 + unsigned long e = end;
29251 +
29252 start = ELF_PAGEALIGN(start);
29253 end = ELF_PAGEALIGN(end);
29254 if (end > start) {
29255 @@ -88,7 +99,7 @@ static int set_brk(unsigned long start,
29256 if (BAD_ADDR(addr))
29257 return addr;
29258 }
29259 - current->mm->start_brk = current->mm->brk = end;
29260 + current->mm->start_brk = current->mm->brk = e;
29261 return 0;
29262 }
29263
29264 @@ -149,7 +160,7 @@ create_elf_tables(struct linux_binprm *b
29265 elf_addr_t __user *u_rand_bytes;
29266 const char *k_platform = ELF_PLATFORM;
29267 const char *k_base_platform = ELF_BASE_PLATFORM;
29268 - unsigned char k_rand_bytes[16];
29269 + u32 k_rand_bytes[4];
29270 int items;
29271 elf_addr_t *elf_info;
29272 int ei_index = 0;
29273 @@ -196,8 +207,12 @@ create_elf_tables(struct linux_binprm *b
29274 * Generate 16 random bytes for userspace PRNG seeding.
29275 */
29276 get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));
29277 - u_rand_bytes = (elf_addr_t __user *)
29278 - STACK_ALLOC(p, sizeof(k_rand_bytes));
29279 + srandom32(k_rand_bytes[0] ^ random32());
29280 + srandom32(k_rand_bytes[1] ^ random32());
29281 + srandom32(k_rand_bytes[2] ^ random32());
29282 + srandom32(k_rand_bytes[3] ^ random32());
29283 + p = STACK_ROUND(p, sizeof(k_rand_bytes));
29284 + u_rand_bytes = (elf_addr_t __user *) p;
29285 if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
29286 return -EFAULT;
29287
29288 @@ -386,10 +401,10 @@ static unsigned long load_elf_interp(str
29289 {
29290 struct elf_phdr *elf_phdata;
29291 struct elf_phdr *eppnt;
29292 - unsigned long load_addr = 0;
29293 + unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
29294 int load_addr_set = 0;
29295 unsigned long last_bss = 0, elf_bss = 0;
29296 - unsigned long error = ~0UL;
29297 + unsigned long error = -EINVAL;
29298 unsigned long total_size;
29299 int retval, i, size;
29300
29301 @@ -435,6 +450,11 @@ static unsigned long load_elf_interp(str
29302 goto out_close;
29303 }
29304
29305 +#ifdef CONFIG_PAX_SEGMEXEC
29306 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
29307 + pax_task_size = SEGMEXEC_TASK_SIZE;
29308 +#endif
29309 +
29310 eppnt = elf_phdata;
29311 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
29312 if (eppnt->p_type == PT_LOAD) {
29313 @@ -478,8 +498,8 @@ static unsigned long load_elf_interp(str
29314 k = load_addr + eppnt->p_vaddr;
29315 if (BAD_ADDR(k) ||
29316 eppnt->p_filesz > eppnt->p_memsz ||
29317 - eppnt->p_memsz > TASK_SIZE ||
29318 - TASK_SIZE - eppnt->p_memsz < k) {
29319 + eppnt->p_memsz > pax_task_size ||
29320 + pax_task_size - eppnt->p_memsz < k) {
29321 error = -ENOMEM;
29322 goto out_close;
29323 }
29324 @@ -533,6 +553,177 @@ out:
29325 return error;
29326 }
29327
29328 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
29329 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
29330 +{
29331 + unsigned long pax_flags = 0UL;
29332 +
29333 +#ifdef CONFIG_PAX_PAGEEXEC
29334 + if (elf_phdata->p_flags & PF_PAGEEXEC)
29335 + pax_flags |= MF_PAX_PAGEEXEC;
29336 +#endif
29337 +
29338 +#ifdef CONFIG_PAX_SEGMEXEC
29339 + if (elf_phdata->p_flags & PF_SEGMEXEC)
29340 + pax_flags |= MF_PAX_SEGMEXEC;
29341 +#endif
29342 +
29343 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
29344 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29345 + if ((__supported_pte_mask & _PAGE_NX))
29346 + pax_flags &= ~MF_PAX_SEGMEXEC;
29347 + else
29348 + pax_flags &= ~MF_PAX_PAGEEXEC;
29349 + }
29350 +#endif
29351 +
29352 +#ifdef CONFIG_PAX_EMUTRAMP
29353 + if (elf_phdata->p_flags & PF_EMUTRAMP)
29354 + pax_flags |= MF_PAX_EMUTRAMP;
29355 +#endif
29356 +
29357 +#ifdef CONFIG_PAX_MPROTECT
29358 + if (elf_phdata->p_flags & PF_MPROTECT)
29359 + pax_flags |= MF_PAX_MPROTECT;
29360 +#endif
29361 +
29362 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
29363 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
29364 + pax_flags |= MF_PAX_RANDMMAP;
29365 +#endif
29366 +
29367 + return pax_flags;
29368 +}
29369 +#endif
29370 +
29371 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
29372 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
29373 +{
29374 + unsigned long pax_flags = 0UL;
29375 +
29376 +#ifdef CONFIG_PAX_PAGEEXEC
29377 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
29378 + pax_flags |= MF_PAX_PAGEEXEC;
29379 +#endif
29380 +
29381 +#ifdef CONFIG_PAX_SEGMEXEC
29382 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
29383 + pax_flags |= MF_PAX_SEGMEXEC;
29384 +#endif
29385 +
29386 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
29387 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29388 + if ((__supported_pte_mask & _PAGE_NX))
29389 + pax_flags &= ~MF_PAX_SEGMEXEC;
29390 + else
29391 + pax_flags &= ~MF_PAX_PAGEEXEC;
29392 + }
29393 +#endif
29394 +
29395 +#ifdef CONFIG_PAX_EMUTRAMP
29396 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
29397 + pax_flags |= MF_PAX_EMUTRAMP;
29398 +#endif
29399 +
29400 +#ifdef CONFIG_PAX_MPROTECT
29401 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
29402 + pax_flags |= MF_PAX_MPROTECT;
29403 +#endif
29404 +
29405 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
29406 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
29407 + pax_flags |= MF_PAX_RANDMMAP;
29408 +#endif
29409 +
29410 + return pax_flags;
29411 +}
29412 +#endif
29413 +
29414 +#ifdef CONFIG_PAX_EI_PAX
29415 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
29416 +{
29417 + unsigned long pax_flags = 0UL;
29418 +
29419 +#ifdef CONFIG_PAX_PAGEEXEC
29420 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
29421 + pax_flags |= MF_PAX_PAGEEXEC;
29422 +#endif
29423 +
29424 +#ifdef CONFIG_PAX_SEGMEXEC
29425 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
29426 + pax_flags |= MF_PAX_SEGMEXEC;
29427 +#endif
29428 +
29429 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
29430 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29431 + if ((__supported_pte_mask & _PAGE_NX))
29432 + pax_flags &= ~MF_PAX_SEGMEXEC;
29433 + else
29434 + pax_flags &= ~MF_PAX_PAGEEXEC;
29435 + }
29436 +#endif
29437 +
29438 +#ifdef CONFIG_PAX_EMUTRAMP
29439 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
29440 + pax_flags |= MF_PAX_EMUTRAMP;
29441 +#endif
29442 +
29443 +#ifdef CONFIG_PAX_MPROTECT
29444 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
29445 + pax_flags |= MF_PAX_MPROTECT;
29446 +#endif
29447 +
29448 +#ifdef CONFIG_PAX_ASLR
29449 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
29450 + pax_flags |= MF_PAX_RANDMMAP;
29451 +#endif
29452 +
29453 + return pax_flags;
29454 +}
29455 +#endif
29456 +
29457 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
29458 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
29459 +{
29460 + unsigned long pax_flags = 0UL;
29461 +
29462 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
29463 + unsigned long i;
29464 +#endif
29465 +
29466 +#ifdef CONFIG_PAX_EI_PAX
29467 + pax_flags = pax_parse_ei_pax(elf_ex);
29468 +#endif
29469 +
29470 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
29471 + for (i = 0UL; i < elf_ex->e_phnum; i++)
29472 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
29473 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
29474 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
29475 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
29476 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
29477 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
29478 + return -EINVAL;
29479 +
29480 +#ifdef CONFIG_PAX_SOFTMODE
29481 + if (pax_softmode)
29482 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
29483 + else
29484 +#endif
29485 +
29486 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
29487 + break;
29488 + }
29489 +#endif
29490 +
29491 + if (0 > pax_check_flags(&pax_flags))
29492 + return -EINVAL;
29493 +
29494 + current->mm->pax_flags = pax_flags;
29495 + return 0;
29496 +}
29497 +#endif
29498 +
29499 /*
29500 * These are the functions used to load ELF style executables and shared
29501 * libraries. There is no binary dependent code anywhere else.
29502 @@ -549,6 +740,11 @@ static unsigned long randomize_stack_top
29503 {
29504 unsigned int random_variable = 0;
29505
29506 +#ifdef CONFIG_PAX_RANDUSTACK
29507 + if (randomize_va_space)
29508 + return stack_top - current->mm->delta_stack;
29509 +#endif
29510 +
29511 if ((current->flags & PF_RANDOMIZE) &&
29512 !(current->personality & ADDR_NO_RANDOMIZE)) {
29513 random_variable = get_random_int() & STACK_RND_MASK;
29514 @@ -567,7 +763,7 @@ static int load_elf_binary(struct linux_
29515 unsigned long load_addr = 0, load_bias = 0;
29516 int load_addr_set = 0;
29517 char * elf_interpreter = NULL;
29518 - unsigned long error;
29519 + unsigned long error = 0;
29520 struct elf_phdr *elf_ppnt, *elf_phdata;
29521 unsigned long elf_bss, elf_brk;
29522 int retval, i;
29523 @@ -577,11 +773,11 @@ static int load_elf_binary(struct linux_
29524 unsigned long start_code, end_code, start_data, end_data;
29525 unsigned long reloc_func_desc = 0;
29526 int executable_stack = EXSTACK_DEFAULT;
29527 - unsigned long def_flags = 0;
29528 struct {
29529 struct elfhdr elf_ex;
29530 struct elfhdr interp_elf_ex;
29531 } *loc;
29532 + unsigned long pax_task_size = TASK_SIZE;
29533
29534 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
29535 if (!loc) {
29536 @@ -719,11 +915,80 @@ static int load_elf_binary(struct linux_
29537
29538 /* OK, This is the point of no return */
29539 current->flags &= ~PF_FORKNOEXEC;
29540 - current->mm->def_flags = def_flags;
29541 +
29542 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29543 + current->mm->pax_flags = 0UL;
29544 +#endif
29545 +
29546 +#ifdef CONFIG_PAX_DLRESOLVE
29547 + current->mm->call_dl_resolve = 0UL;
29548 +#endif
29549 +
29550 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
29551 + current->mm->call_syscall = 0UL;
29552 +#endif
29553 +
29554 +#ifdef CONFIG_PAX_ASLR
29555 + current->mm->delta_mmap = 0UL;
29556 + current->mm->delta_stack = 0UL;
29557 +#endif
29558 +
29559 + current->mm->def_flags = 0;
29560 +
29561 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
29562 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
29563 + send_sig(SIGKILL, current, 0);
29564 + goto out_free_dentry;
29565 + }
29566 +#endif
29567 +
29568 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
29569 + pax_set_initial_flags(bprm);
29570 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
29571 + if (pax_set_initial_flags_func)
29572 + (pax_set_initial_flags_func)(bprm);
29573 +#endif
29574 +
29575 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
29576 + if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !(__supported_pte_mask & _PAGE_NX)) {
29577 + current->mm->context.user_cs_limit = PAGE_SIZE;
29578 + current->mm->def_flags |= VM_PAGEEXEC;
29579 + }
29580 +#endif
29581 +
29582 +#ifdef CONFIG_PAX_SEGMEXEC
29583 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
29584 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
29585 + current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
29586 + pax_task_size = SEGMEXEC_TASK_SIZE;
29587 + }
29588 +#endif
29589 +
29590 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
29591 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29592 + set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
29593 + put_cpu();
29594 + }
29595 +#endif
29596
29597 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
29598 may depend on the personality. */
29599 SET_PERSONALITY(loc->elf_ex);
29600 +
29601 +#ifdef CONFIG_PAX_ASLR
29602 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
29603 + current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
29604 + current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
29605 + }
29606 +#endif
29607 +
29608 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
29609 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29610 + executable_stack = EXSTACK_DISABLE_X;
29611 + current->personality &= ~READ_IMPLIES_EXEC;
29612 + } else
29613 +#endif
29614 +
29615 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
29616 current->personality |= READ_IMPLIES_EXEC;
29617
29618 @@ -805,6 +1070,20 @@ static int load_elf_binary(struct linux_
29619 #else
29620 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
29621 #endif
29622 +
29623 +#ifdef CONFIG_PAX_RANDMMAP
29624 + /* PaX: randomize base address at the default exe base if requested */
29625 + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
29626 +#ifdef CONFIG_SPARC64
29627 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
29628 +#else
29629 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
29630 +#endif
29631 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
29632 + elf_flags |= MAP_FIXED;
29633 + }
29634 +#endif
29635 +
29636 }
29637
29638 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
29639 @@ -837,9 +1116,9 @@ static int load_elf_binary(struct linux_
29640 * allowed task size. Note that p_filesz must always be
29641 * <= p_memsz so it is only necessary to check p_memsz.
29642 */
29643 - if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
29644 - elf_ppnt->p_memsz > TASK_SIZE ||
29645 - TASK_SIZE - elf_ppnt->p_memsz < k) {
29646 + if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
29647 + elf_ppnt->p_memsz > pax_task_size ||
29648 + pax_task_size - elf_ppnt->p_memsz < k) {
29649 /* set_brk can never work. Avoid overflows. */
29650 send_sig(SIGKILL, current, 0);
29651 retval = -EINVAL;
29652 @@ -867,6 +1146,11 @@ static int load_elf_binary(struct linux_
29653 start_data += load_bias;
29654 end_data += load_bias;
29655
29656 +#ifdef CONFIG_PAX_RANDMMAP
29657 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
29658 + elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
29659 +#endif
29660 +
29661 /* Calling set_brk effectively mmaps the pages that we need
29662 * for the bss and break sections. We must do this before
29663 * mapping in the interpreter, to make sure it doesn't wind
29664 @@ -878,9 +1162,11 @@ static int load_elf_binary(struct linux_
29665 goto out_free_dentry;
29666 }
29667 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
29668 - send_sig(SIGSEGV, current, 0);
29669 - retval = -EFAULT; /* Nobody gets to see this, but.. */
29670 - goto out_free_dentry;
29671 + /*
29672 + * This bss-zeroing can fail if the ELF
29673 + * file specifies odd protections. So
29674 + * we don't check the return value
29675 + */
29676 }
29677
29678 if (elf_interpreter) {
29679 @@ -1091,7 +1377,7 @@ out:
29680 * Decide what to dump of a segment, part, all or none.
29681 */
29682 static unsigned long vma_dump_size(struct vm_area_struct *vma,
29683 - unsigned long mm_flags)
29684 + unsigned long mm_flags, long signr)
29685 {
29686 #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
29687
29688 @@ -1125,7 +1411,7 @@ static unsigned long vma_dump_size(struc
29689 if (vma->vm_file == NULL)
29690 return 0;
29691
29692 - if (FILTER(MAPPED_PRIVATE))
29693 + if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
29694 goto whole;
29695
29696 /*
29697 @@ -1347,9 +1633,9 @@ static void fill_auxv_note(struct memelf
29698 {
29699 elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv;
29700 int i = 0;
29701 - do
29702 + do {
29703 i += 2;
29704 - while (auxv[i - 2] != AT_NULL);
29705 + } while (auxv[i - 2] != AT_NULL);
29706 fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
29707 }
29708
29709 @@ -1855,14 +2141,14 @@ static void fill_extnum_info(struct elfh
29710 }
29711
29712 static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
29713 - unsigned long mm_flags)
29714 + struct coredump_params *cprm)
29715 {
29716 struct vm_area_struct *vma;
29717 size_t size = 0;
29718
29719 for (vma = first_vma(current, gate_vma); vma != NULL;
29720 vma = next_vma(vma, gate_vma))
29721 - size += vma_dump_size(vma, mm_flags);
29722 + size += vma_dump_size(vma, cprm->mm_flags, cprm->signr);
29723 return size;
29724 }
29725
29726 @@ -1956,7 +2242,7 @@ static int elf_core_dump(struct coredump
29727
29728 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
29729
29730 - offset += elf_core_vma_data_size(gate_vma, cprm->mm_flags);
29731 + offset += elf_core_vma_data_size(gate_vma, cprm);
29732 offset += elf_core_extra_data_size();
29733 e_shoff = offset;
29734
29735 @@ -1970,10 +2256,12 @@ static int elf_core_dump(struct coredump
29736 offset = dataoff;
29737
29738 size += sizeof(*elf);
29739 + gr_learn_resource(current, RLIMIT_CORE, size, 1);
29740 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
29741 goto end_coredump;
29742
29743 size += sizeof(*phdr4note);
29744 + gr_learn_resource(current, RLIMIT_CORE, size, 1);
29745 if (size > cprm->limit
29746 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
29747 goto end_coredump;
29748 @@ -1987,7 +2275,7 @@ static int elf_core_dump(struct coredump
29749 phdr.p_offset = offset;
29750 phdr.p_vaddr = vma->vm_start;
29751 phdr.p_paddr = 0;
29752 - phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags);
29753 + phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags, cprm->signr);
29754 phdr.p_memsz = vma->vm_end - vma->vm_start;
29755 offset += phdr.p_filesz;
29756 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
29757 @@ -1998,6 +2286,7 @@ static int elf_core_dump(struct coredump
29758 phdr.p_align = ELF_EXEC_PAGESIZE;
29759
29760 size += sizeof(phdr);
29761 + gr_learn_resource(current, RLIMIT_CORE, size, 1);
29762 if (size > cprm->limit
29763 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
29764 goto end_coredump;
29765 @@ -2022,7 +2311,7 @@ static int elf_core_dump(struct coredump
29766 unsigned long addr;
29767 unsigned long end;
29768
29769 - end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags);
29770 + end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags, cprm->signr);
29771
29772 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
29773 struct page *page;
29774 @@ -2031,6 +2320,7 @@ static int elf_core_dump(struct coredump
29775 page = get_dump_page(addr);
29776 if (page) {
29777 void *kaddr = kmap(page);
29778 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
29779 stop = ((size += PAGE_SIZE) > cprm->limit) ||
29780 !dump_write(cprm->file, kaddr,
29781 PAGE_SIZE);
29782 @@ -2048,6 +2338,7 @@ static int elf_core_dump(struct coredump
29783
29784 if (e_phnum == PN_XNUM) {
29785 size += sizeof(*shdr4extnum);
29786 + gr_learn_resource(current, RLIMIT_CORE, size, 1);
29787 if (size > cprm->limit
29788 || !dump_write(cprm->file, shdr4extnum,
29789 sizeof(*shdr4extnum)))
29790 @@ -2068,6 +2359,97 @@ out:
29791
29792 #endif /* CONFIG_ELF_CORE */
29793
29794 +#ifdef CONFIG_PAX_MPROTECT
29795 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
29796 + * therefore we'll grant them VM_MAYWRITE once during their life. Similarly
29797 + * we'll remove VM_MAYWRITE for good on RELRO segments.
29798 + *
29799 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
29800 + * basis because we want to allow the common case and not the special ones.
29801 + */
29802 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags)
29803 +{
29804 + struct elfhdr elf_h;
29805 + struct elf_phdr elf_p;
29806 + unsigned long i;
29807 + unsigned long oldflags;
29808 + bool is_textrel_rw, is_textrel_rx, is_relro;
29809 +
29810 + if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT))
29811 + return;
29812 +
29813 + oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ);
29814 + newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ;
29815 +
29816 +#ifdef CONFIG_PAX_ELFRELOCS
29817 + /* possible TEXTREL */
29818 + is_textrel_rw = vma->vm_file && !vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ);
29819 + 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);
29820 +#else
29821 + is_textrel_rw = false;
29822 + is_textrel_rx = false;
29823 +#endif
29824 +
29825 + /* possible RELRO */
29826 + is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ);
29827 +
29828 + if (!is_textrel_rw && !is_textrel_rx && !is_relro)
29829 + return;
29830 +
29831 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
29832 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
29833 +
29834 +#ifdef CONFIG_PAX_ETEXECRELOCS
29835 + ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
29836 +#else
29837 + ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) ||
29838 +#endif
29839 +
29840 + (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
29841 + !elf_check_arch(&elf_h) ||
29842 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
29843 + elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr))
29844 + return;
29845 +
29846 + for (i = 0UL; i < elf_h.e_phnum; i++) {
29847 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
29848 + return;
29849 + switch (elf_p.p_type) {
29850 + case PT_DYNAMIC:
29851 + if (!is_textrel_rw && !is_textrel_rx)
29852 + continue;
29853 + i = 0UL;
29854 + while ((i+1) * sizeof(elf_dyn) <= elf_p.p_filesz) {
29855 + elf_dyn dyn;
29856 +
29857 + if (sizeof(dyn) != kernel_read(vma->vm_file, elf_p.p_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
29858 + return;
29859 + if (dyn.d_tag == DT_NULL)
29860 + return;
29861 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
29862 + gr_log_textrel(vma);
29863 + if (is_textrel_rw)
29864 + vma->vm_flags |= VM_MAYWRITE;
29865 + else
29866 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
29867 + vma->vm_flags &= ~VM_MAYWRITE;
29868 + return;
29869 + }
29870 + i++;
29871 + }
29872 + return;
29873 +
29874 + case PT_GNU_RELRO:
29875 + if (!is_relro)
29876 + continue;
29877 + if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start)
29878 + vma->vm_flags &= ~VM_MAYWRITE;
29879 + return;
29880 + }
29881 + }
29882 +}
29883 +#endif
29884 +
29885 static int __init init_elf_binfmt(void)
29886 {
29887 return register_binfmt(&elf_format);
29888 diff -urNp linux-2.6.36/fs/binfmt_flat.c linux-2.6.36/fs/binfmt_flat.c
29889 --- linux-2.6.36/fs/binfmt_flat.c 2010-10-20 16:30:22.000000000 -0400
29890 +++ linux-2.6.36/fs/binfmt_flat.c 2010-11-06 18:58:15.000000000 -0400
29891 @@ -567,7 +567,9 @@ static int load_flat_file(struct linux_b
29892 realdatastart = (unsigned long) -ENOMEM;
29893 printk("Unable to allocate RAM for process data, errno %d\n",
29894 (int)-realdatastart);
29895 + down_write(&current->mm->mmap_sem);
29896 do_munmap(current->mm, textpos, text_len);
29897 + up_write(&current->mm->mmap_sem);
29898 ret = realdatastart;
29899 goto err;
29900 }
29901 @@ -591,8 +593,10 @@ static int load_flat_file(struct linux_b
29902 }
29903 if (IS_ERR_VALUE(result)) {
29904 printk("Unable to read data+bss, errno %d\n", (int)-result);
29905 + down_write(&current->mm->mmap_sem);
29906 do_munmap(current->mm, textpos, text_len);
29907 do_munmap(current->mm, realdatastart, len);
29908 + up_write(&current->mm->mmap_sem);
29909 ret = result;
29910 goto err;
29911 }
29912 @@ -661,8 +665,10 @@ static int load_flat_file(struct linux_b
29913 }
29914 if (IS_ERR_VALUE(result)) {
29915 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
29916 + down_write(&current->mm->mmap_sem);
29917 do_munmap(current->mm, textpos, text_len + data_len + extra +
29918 MAX_SHARED_LIBS * sizeof(unsigned long));
29919 + up_write(&current->mm->mmap_sem);
29920 ret = result;
29921 goto err;
29922 }
29923 diff -urNp linux-2.6.36/fs/binfmt_misc.c linux-2.6.36/fs/binfmt_misc.c
29924 --- linux-2.6.36/fs/binfmt_misc.c 2010-10-20 16:30:22.000000000 -0400
29925 +++ linux-2.6.36/fs/binfmt_misc.c 2010-11-06 18:58:15.000000000 -0400
29926 @@ -694,7 +694,7 @@ static int bm_fill_super(struct super_bl
29927 static struct tree_descr bm_files[] = {
29928 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
29929 [3] = {"register", &bm_register_operations, S_IWUSR},
29930 - /* last one */ {""}
29931 + /* last one */ {"", NULL, 0}
29932 };
29933 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
29934 if (!err)
29935 diff -urNp linux-2.6.36/fs/bio.c linux-2.6.36/fs/bio.c
29936 --- linux-2.6.36/fs/bio.c 2010-10-20 16:30:22.000000000 -0400
29937 +++ linux-2.6.36/fs/bio.c 2010-11-06 18:58:15.000000000 -0400
29938 @@ -1214,7 +1214,7 @@ static void bio_copy_kern_endio(struct b
29939 const int read = bio_data_dir(bio) == READ;
29940 struct bio_map_data *bmd = bio->bi_private;
29941 int i;
29942 - char *p = bmd->sgvecs[0].iov_base;
29943 + char *p = (__force char *)bmd->sgvecs[0].iov_base;
29944
29945 __bio_for_each_segment(bvec, bio, i, 0) {
29946 char *addr = page_address(bvec->bv_page);
29947 diff -urNp linux-2.6.36/fs/block_dev.c linux-2.6.36/fs/block_dev.c
29948 --- linux-2.6.36/fs/block_dev.c 2010-10-20 16:30:22.000000000 -0400
29949 +++ linux-2.6.36/fs/block_dev.c 2010-11-06 18:58:15.000000000 -0400
29950 @@ -648,7 +648,7 @@ static bool bd_may_claim(struct block_de
29951 else if (bdev->bd_contains == bdev)
29952 return true; /* is a whole device which isn't held */
29953
29954 - else if (whole->bd_holder == bd_claim)
29955 + else if (whole->bd_holder == (void *)bd_claim)
29956 return true; /* is a partition of a device that is being partitioned */
29957 else if (whole->bd_holder != NULL)
29958 return false; /* is a partition of a held device */
29959 diff -urNp linux-2.6.36/fs/btrfs/ctree.c linux-2.6.36/fs/btrfs/ctree.c
29960 --- linux-2.6.36/fs/btrfs/ctree.c 2010-10-20 16:30:22.000000000 -0400
29961 +++ linux-2.6.36/fs/btrfs/ctree.c 2010-11-06 18:58:15.000000000 -0400
29962 @@ -468,9 +468,12 @@ static noinline int __btrfs_cow_block(st
29963 free_extent_buffer(buf);
29964 add_root_to_dirty_list(root);
29965 } else {
29966 - if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID)
29967 - parent_start = parent->start;
29968 - else
29969 + if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
29970 + if (parent)
29971 + parent_start = parent->start;
29972 + else
29973 + parent_start = 0;
29974 + } else
29975 parent_start = 0;
29976
29977 WARN_ON(trans->transid != btrfs_header_generation(parent));
29978 @@ -3763,7 +3766,6 @@ setup_items_for_insert(struct btrfs_tran
29979
29980 ret = 0;
29981 if (slot == 0) {
29982 - struct btrfs_disk_key disk_key;
29983 btrfs_cpu_key_to_disk(&disk_key, cpu_key);
29984 ret = fixup_low_keys(trans, root, path, &disk_key, 1);
29985 }
29986 diff -urNp linux-2.6.36/fs/btrfs/disk-io.c linux-2.6.36/fs/btrfs/disk-io.c
29987 --- linux-2.6.36/fs/btrfs/disk-io.c 2010-10-20 16:30:22.000000000 -0400
29988 +++ linux-2.6.36/fs/btrfs/disk-io.c 2010-11-06 18:58:15.000000000 -0400
29989 @@ -40,7 +40,7 @@
29990 #include "tree-log.h"
29991 #include "free-space-cache.h"
29992
29993 -static struct extent_io_ops btree_extent_io_ops;
29994 +static const struct extent_io_ops btree_extent_io_ops;
29995 static void end_workqueue_fn(struct btrfs_work *work);
29996 static void free_fs_root(struct btrfs_root *root);
29997
29998 @@ -2597,7 +2597,7 @@ out:
29999 return 0;
30000 }
30001
30002 -static struct extent_io_ops btree_extent_io_ops = {
30003 +static const struct extent_io_ops btree_extent_io_ops = {
30004 .write_cache_pages_lock_hook = btree_lock_page_hook,
30005 .readpage_end_io_hook = btree_readpage_end_io_hook,
30006 .submit_bio_hook = btree_submit_bio_hook,
30007 diff -urNp linux-2.6.36/fs/btrfs/extent_io.h linux-2.6.36/fs/btrfs/extent_io.h
30008 --- linux-2.6.36/fs/btrfs/extent_io.h 2010-10-20 16:30:22.000000000 -0400
30009 +++ linux-2.6.36/fs/btrfs/extent_io.h 2010-11-06 18:58:15.000000000 -0400
30010 @@ -51,36 +51,36 @@ typedef int (extent_submit_bio_hook_t)(s
30011 struct bio *bio, int mirror_num,
30012 unsigned long bio_flags, u64 bio_offset);
30013 struct extent_io_ops {
30014 - int (*fill_delalloc)(struct inode *inode, struct page *locked_page,
30015 + int (* const fill_delalloc)(struct inode *inode, struct page *locked_page,
30016 u64 start, u64 end, int *page_started,
30017 unsigned long *nr_written);
30018 - int (*writepage_start_hook)(struct page *page, u64 start, u64 end);
30019 - int (*writepage_io_hook)(struct page *page, u64 start, u64 end);
30020 + int (* const writepage_start_hook)(struct page *page, u64 start, u64 end);
30021 + int (* const writepage_io_hook)(struct page *page, u64 start, u64 end);
30022 extent_submit_bio_hook_t *submit_bio_hook;
30023 - int (*merge_bio_hook)(struct page *page, unsigned long offset,
30024 + int (* const merge_bio_hook)(struct page *page, unsigned long offset,
30025 size_t size, struct bio *bio,
30026 unsigned long bio_flags);
30027 - int (*readpage_io_hook)(struct page *page, u64 start, u64 end);
30028 - int (*readpage_io_failed_hook)(struct bio *bio, struct page *page,
30029 + int (* const readpage_io_hook)(struct page *page, u64 start, u64 end);
30030 + int (* const readpage_io_failed_hook)(struct bio *bio, struct page *page,
30031 u64 start, u64 end,
30032 struct extent_state *state);
30033 - int (*writepage_io_failed_hook)(struct bio *bio, struct page *page,
30034 + int (* const writepage_io_failed_hook)(struct bio *bio, struct page *page,
30035 u64 start, u64 end,
30036 struct extent_state *state);
30037 - int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end,
30038 + int (* const readpage_end_io_hook)(struct page *page, u64 start, u64 end,
30039 struct extent_state *state);
30040 - int (*writepage_end_io_hook)(struct page *page, u64 start, u64 end,
30041 + int (* const writepage_end_io_hook)(struct page *page, u64 start, u64 end,
30042 struct extent_state *state, int uptodate);
30043 - int (*set_bit_hook)(struct inode *inode, struct extent_state *state,
30044 + int (* const set_bit_hook)(struct inode *inode, struct extent_state *state,
30045 int *bits);
30046 - int (*clear_bit_hook)(struct inode *inode, struct extent_state *state,
30047 + int (* const clear_bit_hook)(struct inode *inode, struct extent_state *state,
30048 int *bits);
30049 - int (*merge_extent_hook)(struct inode *inode,
30050 + int (* const merge_extent_hook)(struct inode *inode,
30051 struct extent_state *new,
30052 struct extent_state *other);
30053 - int (*split_extent_hook)(struct inode *inode,
30054 + int (* const split_extent_hook)(struct inode *inode,
30055 struct extent_state *orig, u64 split);
30056 - int (*write_cache_pages_lock_hook)(struct page *page);
30057 + int (* const write_cache_pages_lock_hook)(struct page *page);
30058 };
30059
30060 struct extent_io_tree {
30061 @@ -90,7 +90,7 @@ struct extent_io_tree {
30062 u64 dirty_bytes;
30063 spinlock_t lock;
30064 spinlock_t buffer_lock;
30065 - struct extent_io_ops *ops;
30066 + const struct extent_io_ops *ops;
30067 };
30068
30069 struct extent_state {
30070 diff -urNp linux-2.6.36/fs/btrfs/free-space-cache.c linux-2.6.36/fs/btrfs/free-space-cache.c
30071 --- linux-2.6.36/fs/btrfs/free-space-cache.c 2010-10-20 16:30:22.000000000 -0400
30072 +++ linux-2.6.36/fs/btrfs/free-space-cache.c 2010-11-06 18:58:15.000000000 -0400
30073 @@ -1075,8 +1075,6 @@ u64 btrfs_alloc_from_cluster(struct btrf
30074
30075 while(1) {
30076 if (entry->bytes < bytes || entry->offset < min_start) {
30077 - struct rb_node *node;
30078 -
30079 node = rb_next(&entry->offset_index);
30080 if (!node)
30081 break;
30082 @@ -1227,7 +1225,7 @@ again:
30083 */
30084 while (entry->bitmap || found_bitmap ||
30085 (!entry->bitmap && entry->bytes < min_bytes)) {
30086 - struct rb_node *node = rb_next(&entry->offset_index);
30087 + node = rb_next(&entry->offset_index);
30088
30089 if (entry->bitmap && entry->bytes > bytes + empty_size) {
30090 ret = btrfs_bitmap_cluster(block_group, entry, cluster,
30091 diff -urNp linux-2.6.36/fs/btrfs/inode.c linux-2.6.36/fs/btrfs/inode.c
30092 --- linux-2.6.36/fs/btrfs/inode.c 2010-10-20 16:30:22.000000000 -0400
30093 +++ linux-2.6.36/fs/btrfs/inode.c 2010-11-06 18:58:15.000000000 -0400
30094 @@ -64,7 +64,7 @@ static const struct inode_operations btr
30095 static const struct address_space_operations btrfs_aops;
30096 static const struct address_space_operations btrfs_symlink_aops;
30097 static const struct file_operations btrfs_dir_file_operations;
30098 -static struct extent_io_ops btrfs_extent_io_ops;
30099 +static const struct extent_io_ops btrfs_extent_io_ops;
30100
30101 static struct kmem_cache *btrfs_inode_cachep;
30102 struct kmem_cache *btrfs_trans_handle_cachep;
30103 @@ -6964,7 +6964,7 @@ static const struct file_operations btrf
30104 .fsync = btrfs_sync_file,
30105 };
30106
30107 -static struct extent_io_ops btrfs_extent_io_ops = {
30108 +static const struct extent_io_ops btrfs_extent_io_ops = {
30109 .fill_delalloc = run_delalloc_range,
30110 .submit_bio_hook = btrfs_submit_bio_hook,
30111 .merge_bio_hook = btrfs_merge_bio_hook,
30112 diff -urNp linux-2.6.36/fs/btrfs/relocation.c linux-2.6.36/fs/btrfs/relocation.c
30113 --- linux-2.6.36/fs/btrfs/relocation.c 2010-10-20 16:30:22.000000000 -0400
30114 +++ linux-2.6.36/fs/btrfs/relocation.c 2010-11-06 18:58:15.000000000 -0400
30115 @@ -1239,7 +1239,7 @@ static int __update_reloc_root(struct bt
30116 }
30117 spin_unlock(&rc->reloc_root_tree.lock);
30118
30119 - BUG_ON((struct btrfs_root *)node->data != root);
30120 + BUG_ON(!node || (struct btrfs_root *)node->data != root);
30121
30122 if (!del) {
30123 spin_lock(&rc->reloc_root_tree.lock);
30124 diff -urNp linux-2.6.36/fs/cachefiles/bind.c linux-2.6.36/fs/cachefiles/bind.c
30125 --- linux-2.6.36/fs/cachefiles/bind.c 2010-10-20 16:30:22.000000000 -0400
30126 +++ linux-2.6.36/fs/cachefiles/bind.c 2010-11-06 18:58:15.000000000 -0400
30127 @@ -39,13 +39,11 @@ int cachefiles_daemon_bind(struct cachef
30128 args);
30129
30130 /* start by checking things over */
30131 - ASSERT(cache->fstop_percent >= 0 &&
30132 - cache->fstop_percent < cache->fcull_percent &&
30133 + ASSERT(cache->fstop_percent < cache->fcull_percent &&
30134 cache->fcull_percent < cache->frun_percent &&
30135 cache->frun_percent < 100);
30136
30137 - ASSERT(cache->bstop_percent >= 0 &&
30138 - cache->bstop_percent < cache->bcull_percent &&
30139 + ASSERT(cache->bstop_percent < cache->bcull_percent &&
30140 cache->bcull_percent < cache->brun_percent &&
30141 cache->brun_percent < 100);
30142
30143 diff -urNp linux-2.6.36/fs/cachefiles/daemon.c linux-2.6.36/fs/cachefiles/daemon.c
30144 --- linux-2.6.36/fs/cachefiles/daemon.c 2010-10-20 16:30:22.000000000 -0400
30145 +++ linux-2.6.36/fs/cachefiles/daemon.c 2010-11-06 18:58:15.000000000 -0400
30146 @@ -195,7 +195,7 @@ static ssize_t cachefiles_daemon_read(st
30147 if (n > buflen)
30148 return -EMSGSIZE;
30149
30150 - if (copy_to_user(_buffer, buffer, n) != 0)
30151 + if (n > sizeof(buffer) || copy_to_user(_buffer, buffer, n) != 0)
30152 return -EFAULT;
30153
30154 return n;
30155 @@ -221,7 +221,7 @@ static ssize_t cachefiles_daemon_write(s
30156 if (test_bit(CACHEFILES_DEAD, &cache->flags))
30157 return -EIO;
30158
30159 - if (datalen < 0 || datalen > PAGE_SIZE - 1)
30160 + if (datalen > PAGE_SIZE - 1)
30161 return -EOPNOTSUPP;
30162
30163 /* drag the command string into the kernel so we can parse it */
30164 @@ -385,7 +385,7 @@ static int cachefiles_daemon_fstop(struc
30165 if (args[0] != '%' || args[1] != '\0')
30166 return -EINVAL;
30167
30168 - if (fstop < 0 || fstop >= cache->fcull_percent)
30169 + if (fstop >= cache->fcull_percent)
30170 return cachefiles_daemon_range_error(cache, args);
30171
30172 cache->fstop_percent = fstop;
30173 @@ -457,7 +457,7 @@ static int cachefiles_daemon_bstop(struc
30174 if (args[0] != '%' || args[1] != '\0')
30175 return -EINVAL;
30176
30177 - if (bstop < 0 || bstop >= cache->bcull_percent)
30178 + if (bstop >= cache->bcull_percent)
30179 return cachefiles_daemon_range_error(cache, args);
30180
30181 cache->bstop_percent = bstop;
30182 diff -urNp linux-2.6.36/fs/cachefiles/rdwr.c linux-2.6.36/fs/cachefiles/rdwr.c
30183 --- linux-2.6.36/fs/cachefiles/rdwr.c 2010-10-20 16:30:22.000000000 -0400
30184 +++ linux-2.6.36/fs/cachefiles/rdwr.c 2010-11-06 18:58:15.000000000 -0400
30185 @@ -945,7 +945,7 @@ int cachefiles_write_page(struct fscache
30186 old_fs = get_fs();
30187 set_fs(KERNEL_DS);
30188 ret = file->f_op->write(
30189 - file, (const void __user *) data, len, &pos);
30190 + file, (__force const void __user *) data, len, &pos);
30191 set_fs(old_fs);
30192 kunmap(page);
30193 if (ret != len)
30194 diff -urNp linux-2.6.36/fs/ceph/dir.c linux-2.6.36/fs/ceph/dir.c
30195 --- linux-2.6.36/fs/ceph/dir.c 2010-10-20 16:30:22.000000000 -0400
30196 +++ linux-2.6.36/fs/ceph/dir.c 2010-11-06 18:58:15.000000000 -0400
30197 @@ -230,7 +230,7 @@ static int ceph_readdir(struct file *fil
30198 struct ceph_client *client = ceph_inode_to_client(inode);
30199 struct ceph_mds_client *mdsc = &client->mdsc;
30200 unsigned frag = fpos_frag(filp->f_pos);
30201 - int off = fpos_off(filp->f_pos);
30202 + unsigned int off = fpos_off(filp->f_pos);
30203 int err;
30204 u32 ftype;
30205 struct ceph_mds_reply_info_parsed *rinfo;
30206 @@ -359,7 +359,7 @@ more:
30207 rinfo = &fi->last_readdir->r_reply_info;
30208 dout("readdir frag %x num %d off %d chunkoff %d\n", frag,
30209 rinfo->dir_nr, off, fi->offset);
30210 - while (off - fi->offset >= 0 && off - fi->offset < rinfo->dir_nr) {
30211 + while (off >= fi->offset && off - fi->offset < rinfo->dir_nr) {
30212 u64 pos = ceph_make_fpos(frag, off);
30213 struct ceph_mds_reply_inode *in =
30214 rinfo->dir_in[off - fi->offset].in;
30215 diff -urNp linux-2.6.36/fs/cifs/cifs_uniupr.h linux-2.6.36/fs/cifs/cifs_uniupr.h
30216 --- linux-2.6.36/fs/cifs/cifs_uniupr.h 2010-10-20 16:30:22.000000000 -0400
30217 +++ linux-2.6.36/fs/cifs/cifs_uniupr.h 2010-11-06 18:58:15.000000000 -0400
30218 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
30219 {0x0490, 0x04cc, UniCaseRangeU0490},
30220 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
30221 {0xff40, 0xff5a, UniCaseRangeUff40},
30222 - {0}
30223 + {0, 0, NULL}
30224 };
30225 #endif
30226
30227 diff -urNp linux-2.6.36/fs/cifs/link.c linux-2.6.36/fs/cifs/link.c
30228 --- linux-2.6.36/fs/cifs/link.c 2010-10-20 16:30:22.000000000 -0400
30229 +++ linux-2.6.36/fs/cifs/link.c 2010-11-06 18:58:15.000000000 -0400
30230 @@ -216,7 +216,7 @@ cifs_symlink(struct inode *inode, struct
30231
30232 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
30233 {
30234 - char *p = nd_get_link(nd);
30235 + const char *p = nd_get_link(nd);
30236 if (!IS_ERR(p))
30237 kfree(p);
30238 }
30239 diff -urNp linux-2.6.36/fs/compat_binfmt_elf.c linux-2.6.36/fs/compat_binfmt_elf.c
30240 --- linux-2.6.36/fs/compat_binfmt_elf.c 2010-10-20 16:30:22.000000000 -0400
30241 +++ linux-2.6.36/fs/compat_binfmt_elf.c 2010-11-06 18:58:15.000000000 -0400
30242 @@ -30,11 +30,13 @@
30243 #undef elf_phdr
30244 #undef elf_shdr
30245 #undef elf_note
30246 +#undef elf_dyn
30247 #undef elf_addr_t
30248 #define elfhdr elf32_hdr
30249 #define elf_phdr elf32_phdr
30250 #define elf_shdr elf32_shdr
30251 #define elf_note elf32_note
30252 +#define elf_dyn Elf32_Dyn
30253 #define elf_addr_t Elf32_Addr
30254
30255 /*
30256 diff -urNp linux-2.6.36/fs/compat.c linux-2.6.36/fs/compat.c
30257 --- linux-2.6.36/fs/compat.c 2010-10-20 16:30:22.000000000 -0400
30258 +++ linux-2.6.36/fs/compat.c 2010-11-06 18:58:50.000000000 -0400
30259 @@ -593,7 +593,7 @@ ssize_t compat_rw_copy_check_uvector(int
30260 goto out;
30261
30262 ret = -EINVAL;
30263 - if (nr_segs > UIO_MAXIOV || nr_segs < 0)
30264 + if (nr_segs > UIO_MAXIOV)
30265 goto out;
30266 if (nr_segs > fast_segs) {
30267 ret = -ENOMEM;
30268 @@ -1435,14 +1435,12 @@ static int compat_copy_strings(int argc,
30269 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
30270 struct page *page;
30271
30272 -#ifdef CONFIG_STACK_GROWSUP
30273 ret = expand_stack_downwards(bprm->vma, pos);
30274 if (ret < 0) {
30275 /* We've exceed the stack rlimit. */
30276 ret = -E2BIG;
30277 goto out;
30278 }
30279 -#endif
30280 ret = get_user_pages(current, bprm->mm, pos,
30281 1, 1, 1, &page, NULL);
30282 if (ret <= 0) {
30283 @@ -1488,6 +1486,11 @@ int compat_do_execve(char * filename,
30284 compat_uptr_t __user *envp,
30285 struct pt_regs * regs)
30286 {
30287 +#ifdef CONFIG_GRKERNSEC
30288 + struct file *old_exec_file;
30289 + struct acl_subject_label *old_acl;
30290 + struct rlimit old_rlim[RLIM_NLIMITS];
30291 +#endif
30292 struct linux_binprm *bprm;
30293 struct file *file;
30294 struct files_struct *displaced;
30295 @@ -1524,6 +1527,14 @@ int compat_do_execve(char * filename,
30296 bprm->filename = filename;
30297 bprm->interp = filename;
30298
30299 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->cred->user->processes), 1);
30300 + retval = -EAGAIN;
30301 + if (gr_handle_nproc())
30302 + goto out_file;
30303 + retval = -EACCES;
30304 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
30305 + goto out_file;
30306 +
30307 retval = bprm_mm_init(bprm);
30308 if (retval)
30309 goto out_file;
30310 @@ -1553,9 +1564,40 @@ int compat_do_execve(char * filename,
30311 if (retval < 0)
30312 goto out;
30313
30314 + if (!gr_tpe_allow(file)) {
30315 + retval = -EACCES;
30316 + goto out;
30317 + }
30318 +
30319 + if (gr_check_crash_exec(file)) {
30320 + retval = -EACCES;
30321 + goto out;
30322 + }
30323 +
30324 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
30325 +
30326 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
30327 +
30328 +#ifdef CONFIG_GRKERNSEC
30329 + old_acl = current->acl;
30330 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
30331 + old_exec_file = current->exec_file;
30332 + get_file(file);
30333 + current->exec_file = file;
30334 +#endif
30335 +
30336 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
30337 + bprm->unsafe & LSM_UNSAFE_SHARE);
30338 + if (retval < 0)
30339 + goto out_fail;
30340 +
30341 retval = search_binary_handler(bprm, regs);
30342 if (retval < 0)
30343 - goto out;
30344 + goto out_fail;
30345 +#ifdef CONFIG_GRKERNSEC
30346 + if (old_exec_file)
30347 + fput(old_exec_file);
30348 +#endif
30349
30350 /* execve succeeded */
30351 current->fs->in_exec = 0;
30352 @@ -1566,6 +1608,14 @@ int compat_do_execve(char * filename,
30353 put_files_struct(displaced);
30354 return retval;
30355
30356 +out_fail:
30357 +#ifdef CONFIG_GRKERNSEC
30358 + current->acl = old_acl;
30359 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
30360 + fput(current->exec_file);
30361 + current->exec_file = old_exec_file;
30362 +#endif
30363 +
30364 out:
30365 if (bprm->mm)
30366 mmput(bprm->mm);
30367 diff -urNp linux-2.6.36/fs/compat_ioctl.c linux-2.6.36/fs/compat_ioctl.c
30368 --- linux-2.6.36/fs/compat_ioctl.c 2010-10-20 16:30:22.000000000 -0400
30369 +++ linux-2.6.36/fs/compat_ioctl.c 2010-11-06 18:58:15.000000000 -0400
30370 @@ -210,6 +210,8 @@ static int do_video_set_spu_palette(unsi
30371
30372 err = get_user(palp, &up->palette);
30373 err |= get_user(length, &up->length);
30374 + if (err)
30375 + return -EFAULT;
30376
30377 up_native = compat_alloc_user_space(sizeof(struct video_spu_palette));
30378 err = put_user(compat_ptr(palp), &up_native->palette);
30379 diff -urNp linux-2.6.36/fs/debugfs/inode.c linux-2.6.36/fs/debugfs/inode.c
30380 --- linux-2.6.36/fs/debugfs/inode.c 2010-10-20 16:30:22.000000000 -0400
30381 +++ linux-2.6.36/fs/debugfs/inode.c 2010-11-06 18:58:15.000000000 -0400
30382 @@ -129,7 +129,7 @@ static inline int debugfs_positive(struc
30383
30384 static int debug_fill_super(struct super_block *sb, void *data, int silent)
30385 {
30386 - static struct tree_descr debug_files[] = {{""}};
30387 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
30388
30389 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
30390 }
30391 diff -urNp linux-2.6.36/fs/dlm/lockspace.c linux-2.6.36/fs/dlm/lockspace.c
30392 --- linux-2.6.36/fs/dlm/lockspace.c 2010-10-20 16:30:22.000000000 -0400
30393 +++ linux-2.6.36/fs/dlm/lockspace.c 2010-11-06 18:58:15.000000000 -0400
30394 @@ -200,7 +200,7 @@ static int dlm_uevent(struct kset *kset,
30395 return 0;
30396 }
30397
30398 -static struct kset_uevent_ops dlm_uevent_ops = {
30399 +static const struct kset_uevent_ops dlm_uevent_ops = {
30400 .uevent = dlm_uevent,
30401 };
30402
30403 diff -urNp linux-2.6.36/fs/ecryptfs/inode.c linux-2.6.36/fs/ecryptfs/inode.c
30404 --- linux-2.6.36/fs/ecryptfs/inode.c 2010-10-20 16:30:22.000000000 -0400
30405 +++ linux-2.6.36/fs/ecryptfs/inode.c 2010-11-06 18:58:15.000000000 -0400
30406 @@ -740,7 +740,7 @@ static int ecryptfs_readlink_lower(struc
30407 old_fs = get_fs();
30408 set_fs(get_ds());
30409 rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
30410 - (char __user *)lower_buf,
30411 + (__force char __user *)lower_buf,
30412 lower_bufsiz);
30413 set_fs(old_fs);
30414 if (rc < 0)
30415 @@ -786,7 +786,7 @@ static void *ecryptfs_follow_link(struct
30416 }
30417 old_fs = get_fs();
30418 set_fs(get_ds());
30419 - rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
30420 + rc = dentry->d_inode->i_op->readlink(dentry, (__force char __user *)buf, len);
30421 set_fs(old_fs);
30422 if (rc < 0) {
30423 kfree(buf);
30424 @@ -801,7 +801,7 @@ out:
30425 static void
30426 ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
30427 {
30428 - char *buf = nd_get_link(nd);
30429 + const char *buf = nd_get_link(nd);
30430 if (!IS_ERR(buf)) {
30431 /* Free the char* */
30432 kfree(buf);
30433 diff -urNp linux-2.6.36/fs/ecryptfs/miscdev.c linux-2.6.36/fs/ecryptfs/miscdev.c
30434 --- linux-2.6.36/fs/ecryptfs/miscdev.c 2010-10-20 16:30:22.000000000 -0400
30435 +++ linux-2.6.36/fs/ecryptfs/miscdev.c 2010-11-06 18:58:15.000000000 -0400
30436 @@ -328,7 +328,7 @@ check_list:
30437 goto out_unlock_msg_ctx;
30438 i = 5;
30439 if (msg_ctx->msg) {
30440 - if (copy_to_user(&buf[i], packet_length, packet_length_size))
30441 + if (packet_length_size > sizeof(packet_length) || copy_to_user(&buf[i], packet_length, packet_length_size))
30442 goto out_unlock_msg_ctx;
30443 i += packet_length_size;
30444 if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
30445 diff -urNp linux-2.6.36/fs/exec.c linux-2.6.36/fs/exec.c
30446 --- linux-2.6.36/fs/exec.c 2010-10-20 16:30:22.000000000 -0400
30447 +++ linux-2.6.36/fs/exec.c 2010-11-06 19:14:10.000000000 -0400
30448 @@ -54,12 +54,24 @@
30449 #include <linux/fsnotify.h>
30450 #include <linux/fs_struct.h>
30451 #include <linux/pipe_fs_i.h>
30452 +#include <linux/random.h>
30453 +#include <linux/seq_file.h>
30454 +
30455 +#ifdef CONFIG_PAX_REFCOUNT
30456 +#include <linux/kallsyms.h>
30457 +#include <linux/kdebug.h>
30458 +#endif
30459
30460 #include <asm/uaccess.h>
30461 #include <asm/mmu_context.h>
30462 #include <asm/tlb.h>
30463 #include "internal.h"
30464
30465 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
30466 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
30467 +EXPORT_SYMBOL(pax_set_initial_flags_func);
30468 +#endif
30469 +
30470 int core_uses_pid;
30471 char core_pattern[CORENAME_MAX_SIZE] = "core";
30472 unsigned int core_pipe_limit;
30473 @@ -113,7 +125,7 @@ SYSCALL_DEFINE1(uselib, const char __use
30474 goto out;
30475
30476 file = do_filp_open(AT_FDCWD, tmp,
30477 - O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
30478 + O_LARGEFILE | O_RDONLY | FMODE_EXEC | FMODE_GREXEC, 0,
30479 MAY_READ | MAY_EXEC | MAY_OPEN);
30480 putname(tmp);
30481 error = PTR_ERR(file);
30482 @@ -161,18 +173,10 @@ static struct page *get_arg_page(struct
30483 int write)
30484 {
30485 struct page *page;
30486 - int ret;
30487
30488 -#ifdef CONFIG_STACK_GROWSUP
30489 - if (write) {
30490 - ret = expand_stack_downwards(bprm->vma, pos);
30491 - if (ret < 0)
30492 - return NULL;
30493 - }
30494 -#endif
30495 - ret = get_user_pages(current, bprm->mm, pos,
30496 - 1, write, 1, &page, NULL);
30497 - if (ret <= 0)
30498 + if (0 > expand_stack_downwards(bprm->vma, pos))
30499 + return NULL;
30500 + if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
30501 return NULL;
30502
30503 if (write) {
30504 @@ -245,6 +249,11 @@ static int __bprm_mm_init(struct linux_b
30505 vma->vm_end = STACK_TOP_MAX;
30506 vma->vm_start = vma->vm_end - PAGE_SIZE;
30507 vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
30508 +
30509 +#ifdef CONFIG_PAX_SEGMEXEC
30510 + vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
30511 +#endif
30512 +
30513 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
30514 INIT_LIST_HEAD(&vma->anon_vma_chain);
30515 err = insert_vm_struct(mm, vma);
30516 @@ -254,6 +263,12 @@ static int __bprm_mm_init(struct linux_b
30517 mm->stack_vm = mm->total_vm = 1;
30518 up_write(&mm->mmap_sem);
30519 bprm->p = vma->vm_end - sizeof(void *);
30520 +
30521 +#ifdef CONFIG_PAX_RANDUSTACK
30522 + if (randomize_va_space)
30523 + bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
30524 +#endif
30525 +
30526 return 0;
30527 err:
30528 up_write(&mm->mmap_sem);
30529 @@ -485,7 +500,7 @@ int copy_strings_kernel(int argc, const
30530 int r;
30531 mm_segment_t oldfs = get_fs();
30532 set_fs(KERNEL_DS);
30533 - r = copy_strings(argc, (const char __user *const __user *)argv, bprm);
30534 + r = copy_strings(argc, (__force const char __user *const __user *)argv, bprm);
30535 set_fs(oldfs);
30536 return r;
30537 }
30538 @@ -515,7 +530,8 @@ static int shift_arg_pages(struct vm_are
30539 unsigned long new_end = old_end - shift;
30540 struct mmu_gather *tlb;
30541
30542 - BUG_ON(new_start > new_end);
30543 + if (new_start >= new_end || new_start < mmap_min_addr)
30544 + return -EFAULT;
30545
30546 /*
30547 * ensure there are no vmas between where we want to go
30548 @@ -524,6 +540,10 @@ static int shift_arg_pages(struct vm_are
30549 if (vma != find_vma(mm, new_start))
30550 return -EFAULT;
30551
30552 +#ifdef CONFIG_PAX_SEGMEXEC
30553 + BUG_ON(pax_find_mirror_vma(vma));
30554 +#endif
30555 +
30556 /*
30557 * cover the whole range: [new_start, old_end)
30558 */
30559 @@ -619,8 +639,28 @@ int setup_arg_pages(struct linux_binprm
30560 bprm->exec -= stack_shift;
30561
30562 down_write(&mm->mmap_sem);
30563 +
30564 + /* Move stack pages down in memory. */
30565 + if (stack_shift) {
30566 + ret = shift_arg_pages(vma, stack_shift);
30567 + if (ret)
30568 + goto out_unlock;
30569 + }
30570 +
30571 vm_flags = VM_STACK_FLAGS;
30572
30573 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30574 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
30575 + vm_flags &= ~VM_EXEC;
30576 +
30577 +#ifdef CONFIG_PAX_MPROTECT
30578 + if (mm->pax_flags & MF_PAX_MPROTECT)
30579 + vm_flags &= ~VM_MAYEXEC;
30580 +#endif
30581 +
30582 + }
30583 +#endif
30584 +
30585 /*
30586 * Adjust stack execute permissions; explicitly enable for
30587 * EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X and leave alone
30588 @@ -639,13 +679,6 @@ int setup_arg_pages(struct linux_binprm
30589 goto out_unlock;
30590 BUG_ON(prev != vma);
30591
30592 - /* Move stack pages down in memory. */
30593 - if (stack_shift) {
30594 - ret = shift_arg_pages(vma, stack_shift);
30595 - if (ret)
30596 - goto out_unlock;
30597 - }
30598 -
30599 /* mprotect_fixup is overkill to remove the temporary stack flags */
30600 vma->vm_flags &= ~VM_STACK_INCOMPLETE_SETUP;
30601
30602 @@ -686,7 +719,7 @@ struct file *open_exec(const char *name)
30603 int err;
30604
30605 file = do_filp_open(AT_FDCWD, name,
30606 - O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
30607 + O_LARGEFILE | O_RDONLY | FMODE_EXEC | FMODE_GREXEC, 0,
30608 MAY_EXEC | MAY_OPEN);
30609 if (IS_ERR(file))
30610 goto out;
30611 @@ -723,7 +756,7 @@ int kernel_read(struct file *file, loff_
30612 old_fs = get_fs();
30613 set_fs(get_ds());
30614 /* The cast to a user pointer is valid due to the set_fs() */
30615 - result = vfs_read(file, (void __user *)addr, count, &pos);
30616 + result = vfs_read(file, (__force void __user *)addr, count, &pos);
30617 set_fs(old_fs);
30618 return result;
30619 }
30620 @@ -1140,7 +1173,7 @@ int check_unsafe_exec(struct linux_binpr
30621 }
30622 rcu_read_unlock();
30623
30624 - if (p->fs->users > n_fs) {
30625 + if (atomic_read(&p->fs->users) > n_fs) {
30626 bprm->unsafe |= LSM_UNSAFE_SHARE;
30627 } else {
30628 res = -EAGAIN;
30629 @@ -1336,6 +1369,11 @@ int do_execve(const char * filename,
30630 const char __user *const __user *envp,
30631 struct pt_regs * regs)
30632 {
30633 +#ifdef CONFIG_GRKERNSEC
30634 + struct file *old_exec_file;
30635 + struct acl_subject_label *old_acl;
30636 + struct rlimit old_rlim[RLIM_NLIMITS];
30637 +#endif
30638 struct linux_binprm *bprm;
30639 struct file *file;
30640 struct files_struct *displaced;
30641 @@ -1372,6 +1410,18 @@ int do_execve(const char * filename,
30642 bprm->filename = filename;
30643 bprm->interp = filename;
30644
30645 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->cred->user->processes), 1);
30646 +
30647 + if (gr_handle_nproc()) {
30648 + retval = -EAGAIN;
30649 + goto out_file;
30650 + }
30651 +
30652 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
30653 + retval = -EACCES;
30654 + goto out_file;
30655 + }
30656 +
30657 retval = bprm_mm_init(bprm);
30658 if (retval)
30659 goto out_file;
30660 @@ -1401,10 +1451,41 @@ int do_execve(const char * filename,
30661 if (retval < 0)
30662 goto out;
30663
30664 + if (!gr_tpe_allow(file)) {
30665 + retval = -EACCES;
30666 + goto out;
30667 + }
30668 +
30669 + if (gr_check_crash_exec(file)) {
30670 + retval = -EACCES;
30671 + goto out;
30672 + }
30673 +
30674 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
30675 +
30676 + gr_handle_exec_args(bprm, argv);
30677 +
30678 +#ifdef CONFIG_GRKERNSEC
30679 + old_acl = current->acl;
30680 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
30681 + old_exec_file = current->exec_file;
30682 + get_file(file);
30683 + current->exec_file = file;
30684 +#endif
30685 +
30686 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
30687 + bprm->unsafe & LSM_UNSAFE_SHARE);
30688 + if (retval < 0)
30689 + goto out_fail;
30690 +
30691 current->flags &= ~PF_KTHREAD;
30692 retval = search_binary_handler(bprm,regs);
30693 if (retval < 0)
30694 - goto out;
30695 + goto out_fail;
30696 +#ifdef CONFIG_GRKERNSEC
30697 + if (old_exec_file)
30698 + fput(old_exec_file);
30699 +#endif
30700
30701 /* execve succeeded */
30702 current->fs->in_exec = 0;
30703 @@ -1415,6 +1496,14 @@ int do_execve(const char * filename,
30704 put_files_struct(displaced);
30705 return retval;
30706
30707 +out_fail:
30708 +#ifdef CONFIG_GRKERNSEC
30709 + current->acl = old_acl;
30710 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
30711 + fput(current->exec_file);
30712 + current->exec_file = old_exec_file;
30713 +#endif
30714 +
30715 out:
30716 if (bprm->mm)
30717 mmput (bprm->mm);
30718 @@ -1578,6 +1667,217 @@ out:
30719 return ispipe;
30720 }
30721
30722 +int pax_check_flags(unsigned long *flags)
30723 +{
30724 + int retval = 0;
30725 +
30726 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
30727 + if (*flags & MF_PAX_SEGMEXEC)
30728 + {
30729 + *flags &= ~MF_PAX_SEGMEXEC;
30730 + retval = -EINVAL;
30731 + }
30732 +#endif
30733 +
30734 + if ((*flags & MF_PAX_PAGEEXEC)
30735 +
30736 +#ifdef CONFIG_PAX_PAGEEXEC
30737 + && (*flags & MF_PAX_SEGMEXEC)
30738 +#endif
30739 +
30740 + )
30741 + {
30742 + *flags &= ~MF_PAX_PAGEEXEC;
30743 + retval = -EINVAL;
30744 + }
30745 +
30746 + if ((*flags & MF_PAX_MPROTECT)
30747 +
30748 +#ifdef CONFIG_PAX_MPROTECT
30749 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
30750 +#endif
30751 +
30752 + )
30753 + {
30754 + *flags &= ~MF_PAX_MPROTECT;
30755 + retval = -EINVAL;
30756 + }
30757 +
30758 + if ((*flags & MF_PAX_EMUTRAMP)
30759 +
30760 +#ifdef CONFIG_PAX_EMUTRAMP
30761 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
30762 +#endif
30763 +
30764 + )
30765 + {
30766 + *flags &= ~MF_PAX_EMUTRAMP;
30767 + retval = -EINVAL;
30768 + }
30769 +
30770 + return retval;
30771 +}
30772 +
30773 +EXPORT_SYMBOL(pax_check_flags);
30774 +
30775 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30776 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
30777 +{
30778 + struct task_struct *tsk = current;
30779 + struct mm_struct *mm = current->mm;
30780 + char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
30781 + char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
30782 + char *path_exec = NULL;
30783 + char *path_fault = NULL;
30784 + unsigned long start = 0UL, end = 0UL, offset = 0UL;
30785 +
30786 + if (buffer_exec && buffer_fault) {
30787 + struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
30788 +
30789 + down_read(&mm->mmap_sem);
30790 + vma = mm->mmap;
30791 + while (vma && (!vma_exec || !vma_fault)) {
30792 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
30793 + vma_exec = vma;
30794 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
30795 + vma_fault = vma;
30796 + vma = vma->vm_next;
30797 + }
30798 + if (vma_exec) {
30799 + path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
30800 + if (IS_ERR(path_exec))
30801 + path_exec = "<path too long>";
30802 + else {
30803 + path_exec = mangle_path(buffer_exec, path_exec, "\t\n\\");
30804 + if (path_exec) {
30805 + *path_exec = 0;
30806 + path_exec = buffer_exec;
30807 + } else
30808 + path_exec = "<path too long>";
30809 + }
30810 + }
30811 + if (vma_fault) {
30812 + start = vma_fault->vm_start;
30813 + end = vma_fault->vm_end;
30814 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
30815 + if (vma_fault->vm_file) {
30816 + path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
30817 + if (IS_ERR(path_fault))
30818 + path_fault = "<path too long>";
30819 + else {
30820 + path_fault = mangle_path(buffer_fault, path_fault, "\t\n\\");
30821 + if (path_fault) {
30822 + *path_fault = 0;
30823 + path_fault = buffer_fault;
30824 + } else
30825 + path_fault = "<path too long>";
30826 + }
30827 + } else
30828 + path_fault = "<anonymous mapping>";
30829 + }
30830 + up_read(&mm->mmap_sem);
30831 + }
30832 + if (tsk->signal->curr_ip)
30833 + printk(KERN_ERR "PAX: From %pI4: execution attempt in: %s, %08lx-%08lx %08lx\n", &tsk->signal->curr_ip, path_fault, start, end, offset);
30834 + else
30835 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
30836 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
30837 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
30838 + task_uid(tsk), task_euid(tsk), pc, sp);
30839 + free_page((unsigned long)buffer_exec);
30840 + free_page((unsigned long)buffer_fault);
30841 + pax_report_insns(pc, sp);
30842 + do_coredump(SIGKILL, SIGKILL, regs);
30843 +}
30844 +#endif
30845 +
30846 +#ifdef CONFIG_PAX_REFCOUNT
30847 +void pax_report_refcount_overflow(struct pt_regs *regs)
30848 +{
30849 + if (current->signal->curr_ip)
30850 + printk(KERN_ERR "PAX: From %pI4: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
30851 + &current->signal->curr_ip, current->comm, task_pid_nr(current), current_uid(), current_euid());
30852 + else
30853 + printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
30854 + current->comm, task_pid_nr(current), current_uid(), current_euid());
30855 + print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
30856 + show_regs(regs);
30857 + force_sig_info(SIGKILL, SEND_SIG_FORCED, current);
30858 +}
30859 +#endif
30860 +
30861 +#ifdef CONFIG_PAX_USERCOPY
30862 +/* 0: not at all, 1: fully, 2: fully inside frame, -1: partially (implies an error) */
30863 +int object_is_on_stack(const void *obj, unsigned long len)
30864 +{
30865 + const void * const stack = task_stack_page(current);
30866 + const void * const stackend = stack + THREAD_SIZE;
30867 +
30868 +#if defined(CONFIG_FRAME_POINTER) && defined(CONFIG_X86)
30869 + const void *frame = NULL;
30870 + const void *oldframe;
30871 +#endif
30872 +
30873 + if (obj + len < obj)
30874 + return -1;
30875 +
30876 + if (obj + len <= stack || stackend <= obj)
30877 + return 0;
30878 +
30879 + if (obj < stack || stackend < obj + len)
30880 + return -1;
30881 +
30882 +#if defined(CONFIG_FRAME_POINTER) && defined(CONFIG_X86)
30883 + oldframe = __builtin_frame_address(1);
30884 + if (oldframe)
30885 + frame = __builtin_frame_address(2);
30886 + /*
30887 + low ----------------------------------------------> high
30888 + [saved bp][saved ip][args][local vars][saved bp][saved ip]
30889 + ^----------------^
30890 + allow copies only within here
30891 + */
30892 + while (stack <= frame && frame < stackend) {
30893 + /* if obj + len extends past the last frame, this
30894 + check won't pass and the next frame will be 0,
30895 + causing us to bail out and correctly report
30896 + the copy as invalid
30897 + */
30898 + if (obj + len <= frame)
30899 + return obj >= oldframe + 2 * sizeof(void *) ? 2 : -1;
30900 + oldframe = frame;
30901 + frame = *(const void * const *)frame;
30902 + }
30903 + return -1;
30904 +#else
30905 + return 1;
30906 +#endif
30907 +}
30908 +
30909 +
30910 +void pax_report_leak_to_user(const void *ptr, unsigned long len)
30911 +{
30912 + if (current->signal->curr_ip)
30913 + printk(KERN_ERR "PAX: From %pI4: kernel memory leak attempt detected from %p (%lu bytes)\n",
30914 + &current->signal->curr_ip, ptr, len);
30915 + else
30916 + printk(KERN_ERR "PAX: kernel memory leak attempt detected from %p (%lu bytes)\n", ptr, len);
30917 + dump_stack();
30918 + do_group_exit(SIGKILL);
30919 +}
30920 +
30921 +void pax_report_overflow_from_user(const void *ptr, unsigned long len)
30922 +{
30923 + if (current->signal->curr_ip)
30924 + printk(KERN_ERR "PAX: From %pI4: kernel memory overflow attempt detected to %p (%lu bytes)\n",
30925 + &current->signal->curr_ip, ptr, len);
30926 + else
30927 + printk(KERN_ERR "PAX: kernel memory overflow attempt detected to %p (%lu bytes)\n", ptr, len);
30928 + dump_stack();
30929 + do_group_exit(SIGKILL);
30930 +}
30931 +#endif
30932 +
30933 static int zap_process(struct task_struct *start, int exit_code)
30934 {
30935 struct task_struct *t;
30936 @@ -1788,17 +2088,17 @@ static void wait_for_dump_helpers(struct
30937 pipe = file->f_path.dentry->d_inode->i_pipe;
30938
30939 pipe_lock(pipe);
30940 - pipe->readers++;
30941 - pipe->writers--;
30942 + atomic_inc(&pipe->readers);
30943 + atomic_dec(&pipe->writers);
30944
30945 - while ((pipe->readers > 1) && (!signal_pending(current))) {
30946 + while ((atomic_read(&pipe->readers) > 1) && (!signal_pending(current))) {
30947 wake_up_interruptible_sync(&pipe->wait);
30948 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
30949 pipe_wait(pipe);
30950 }
30951
30952 - pipe->readers--;
30953 - pipe->writers++;
30954 + atomic_dec(&pipe->readers);
30955 + atomic_inc(&pipe->writers);
30956 pipe_unlock(pipe);
30957
30958 }
30959 @@ -1906,6 +2206,10 @@ void do_coredump(long signr, int exit_co
30960 */
30961 clear_thread_flag(TIF_SIGPENDING);
30962
30963 + if (signr == SIGKILL || signr == SIGILL)
30964 + gr_handle_brute_attach(current);
30965 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
30966 +
30967 ispipe = format_corename(corename, signr);
30968
30969 if (ispipe) {
30970 diff -urNp linux-2.6.36/fs/ext2/balloc.c linux-2.6.36/fs/ext2/balloc.c
30971 --- linux-2.6.36/fs/ext2/balloc.c 2010-10-20 16:30:22.000000000 -0400
30972 +++ linux-2.6.36/fs/ext2/balloc.c 2010-11-06 18:58:50.000000000 -0400
30973 @@ -1193,7 +1193,7 @@ static int ext2_has_free_blocks(struct e
30974
30975 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
30976 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
30977 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
30978 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
30979 sbi->s_resuid != current_fsuid() &&
30980 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
30981 return 0;
30982 diff -urNp linux-2.6.36/fs/ext2/xattr.c linux-2.6.36/fs/ext2/xattr.c
30983 --- linux-2.6.36/fs/ext2/xattr.c 2010-10-20 16:30:22.000000000 -0400
30984 +++ linux-2.6.36/fs/ext2/xattr.c 2010-11-06 18:58:15.000000000 -0400
30985 @@ -86,8 +86,8 @@
30986 printk("\n"); \
30987 } while (0)
30988 #else
30989 -# define ea_idebug(f...)
30990 -# define ea_bdebug(f...)
30991 +# define ea_idebug(inode, f...) do {} while (0)
30992 +# define ea_bdebug(bh, f...) do {} while (0)
30993 #endif
30994
30995 static int ext2_xattr_set2(struct inode *, struct buffer_head *,
30996 diff -urNp linux-2.6.36/fs/ext3/balloc.c linux-2.6.36/fs/ext3/balloc.c
30997 --- linux-2.6.36/fs/ext3/balloc.c 2010-10-20 16:30:22.000000000 -0400
30998 +++ linux-2.6.36/fs/ext3/balloc.c 2010-11-06 18:58:50.000000000 -0400
30999 @@ -1422,7 +1422,7 @@ static int ext3_has_free_blocks(struct e
31000
31001 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
31002 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
31003 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
31004 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
31005 sbi->s_resuid != current_fsuid() &&
31006 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
31007 return 0;
31008 diff -urNp linux-2.6.36/fs/ext3/namei.c linux-2.6.36/fs/ext3/namei.c
31009 --- linux-2.6.36/fs/ext3/namei.c 2010-10-20 16:30:22.000000000 -0400
31010 +++ linux-2.6.36/fs/ext3/namei.c 2010-11-06 18:58:15.000000000 -0400
31011 @@ -1168,7 +1168,7 @@ static struct ext3_dir_entry_2 *do_split
31012 char *data1 = (*bh)->b_data, *data2;
31013 unsigned split, move, size;
31014 struct ext3_dir_entry_2 *de = NULL, *de2;
31015 - int err = 0, i;
31016 + int i, err = 0;
31017
31018 bh2 = ext3_append (handle, dir, &newblock, &err);
31019 if (!(bh2)) {
31020 diff -urNp linux-2.6.36/fs/ext3/xattr.c linux-2.6.36/fs/ext3/xattr.c
31021 --- linux-2.6.36/fs/ext3/xattr.c 2010-10-20 16:30:22.000000000 -0400
31022 +++ linux-2.6.36/fs/ext3/xattr.c 2010-11-06 18:58:15.000000000 -0400
31023 @@ -89,8 +89,8 @@
31024 printk("\n"); \
31025 } while (0)
31026 #else
31027 -# define ea_idebug(f...)
31028 -# define ea_bdebug(f...)
31029 +# define ea_idebug(f...) do {} while (0)
31030 +# define ea_bdebug(f...) do {} while (0)
31031 #endif
31032
31033 static void ext3_xattr_cache_insert(struct buffer_head *);
31034 diff -urNp linux-2.6.36/fs/ext4/balloc.c linux-2.6.36/fs/ext4/balloc.c
31035 --- linux-2.6.36/fs/ext4/balloc.c 2010-10-20 16:30:22.000000000 -0400
31036 +++ linux-2.6.36/fs/ext4/balloc.c 2010-11-06 18:58:50.000000000 -0400
31037 @@ -518,7 +518,7 @@ int ext4_has_free_blocks(struct ext4_sb_
31038 /* Hm, nope. Are (enough) root reserved blocks available? */
31039 if (sbi->s_resuid == current_fsuid() ||
31040 ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
31041 - capable(CAP_SYS_RESOURCE)) {
31042 + capable_nolog(CAP_SYS_RESOURCE)) {
31043 if (free_blocks >= (nblocks + dirty_blocks))
31044 return 1;
31045 }
31046 diff -urNp linux-2.6.36/fs/ext4/namei.c linux-2.6.36/fs/ext4/namei.c
31047 --- linux-2.6.36/fs/ext4/namei.c 2010-10-20 16:30:22.000000000 -0400
31048 +++ linux-2.6.36/fs/ext4/namei.c 2010-11-06 18:58:15.000000000 -0400
31049 @@ -1170,7 +1170,7 @@ static struct ext4_dir_entry_2 *do_split
31050 char *data1 = (*bh)->b_data, *data2;
31051 unsigned split, move, size;
31052 struct ext4_dir_entry_2 *de = NULL, *de2;
31053 - int err = 0, i;
31054 + int i, err = 0;
31055
31056 bh2 = ext4_append (handle, dir, &newblock, &err);
31057 if (!(bh2)) {
31058 diff -urNp linux-2.6.36/fs/ext4/xattr.c linux-2.6.36/fs/ext4/xattr.c
31059 --- linux-2.6.36/fs/ext4/xattr.c 2010-10-20 16:30:22.000000000 -0400
31060 +++ linux-2.6.36/fs/ext4/xattr.c 2010-11-06 18:58:15.000000000 -0400
31061 @@ -82,8 +82,8 @@
31062 printk("\n"); \
31063 } while (0)
31064 #else
31065 -# define ea_idebug(f...)
31066 -# define ea_bdebug(f...)
31067 +# define ea_idebug(inode, f...) do {} while (0)
31068 +# define ea_bdebug(bh, f...) do {} while (0)
31069 #endif
31070
31071 static void ext4_xattr_cache_insert(struct buffer_head *);
31072 diff -urNp linux-2.6.36/fs/fcntl.c linux-2.6.36/fs/fcntl.c
31073 --- linux-2.6.36/fs/fcntl.c 2010-10-20 16:30:22.000000000 -0400
31074 +++ linux-2.6.36/fs/fcntl.c 2010-11-06 18:58:50.000000000 -0400
31075 @@ -224,6 +224,11 @@ int __f_setown(struct file *filp, struct
31076 if (err)
31077 return err;
31078
31079 + if (gr_handle_chroot_fowner(pid, type))
31080 + return -ENOENT;
31081 + if (gr_check_protected_task_fowner(pid, type))
31082 + return -EACCES;
31083 +
31084 f_modown(filp, pid, type, force);
31085 return 0;
31086 }
31087 @@ -348,6 +353,7 @@ static long do_fcntl(int fd, unsigned in
31088 switch (cmd) {
31089 case F_DUPFD:
31090 case F_DUPFD_CLOEXEC:
31091 + gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
31092 if (arg >= rlimit(RLIMIT_NOFILE))
31093 break;
31094 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
31095 diff -urNp linux-2.6.36/fs/fifo.c linux-2.6.36/fs/fifo.c
31096 --- linux-2.6.36/fs/fifo.c 2010-10-20 16:30:22.000000000 -0400
31097 +++ linux-2.6.36/fs/fifo.c 2010-11-06 18:58:15.000000000 -0400
31098 @@ -58,10 +58,10 @@ static int fifo_open(struct inode *inode
31099 */
31100 filp->f_op = &read_pipefifo_fops;
31101 pipe->r_counter++;
31102 - if (pipe->readers++ == 0)
31103 + if (atomic_inc_return(&pipe->readers) == 1)
31104 wake_up_partner(inode);
31105
31106 - if (!pipe->writers) {
31107 + if (!atomic_read(&pipe->writers)) {
31108 if ((filp->f_flags & O_NONBLOCK)) {
31109 /* suppress POLLHUP until we have
31110 * seen a writer */
31111 @@ -82,15 +82,15 @@ static int fifo_open(struct inode *inode
31112 * errno=ENXIO when there is no process reading the FIFO.
31113 */
31114 ret = -ENXIO;
31115 - if ((filp->f_flags & O_NONBLOCK) && !pipe->readers)
31116 + if ((filp->f_flags & O_NONBLOCK) && !atomic_read(&pipe->readers))
31117 goto err;
31118
31119 filp->f_op = &write_pipefifo_fops;
31120 pipe->w_counter++;
31121 - if (!pipe->writers++)
31122 + if (atomic_inc_return(&pipe->writers) == 1)
31123 wake_up_partner(inode);
31124
31125 - if (!pipe->readers) {
31126 + if (!atomic_read(&pipe->readers)) {
31127 wait_for_partner(inode, &pipe->r_counter);
31128 if (signal_pending(current))
31129 goto err_wr;
31130 @@ -106,11 +106,11 @@ static int fifo_open(struct inode *inode
31131 */
31132 filp->f_op = &rdwr_pipefifo_fops;
31133
31134 - pipe->readers++;
31135 - pipe->writers++;
31136 + atomic_inc(&pipe->readers);
31137 + atomic_inc(&pipe->writers);
31138 pipe->r_counter++;
31139 pipe->w_counter++;
31140 - if (pipe->readers == 1 || pipe->writers == 1)
31141 + if (atomic_read(&pipe->readers) == 1 || atomic_read(&pipe->writers) == 1)
31142 wake_up_partner(inode);
31143 break;
31144
31145 @@ -124,19 +124,19 @@ static int fifo_open(struct inode *inode
31146 return 0;
31147
31148 err_rd:
31149 - if (!--pipe->readers)
31150 + if (atomic_dec_and_test(&pipe->readers))
31151 wake_up_interruptible(&pipe->wait);
31152 ret = -ERESTARTSYS;
31153 goto err;
31154
31155 err_wr:
31156 - if (!--pipe->writers)
31157 + if (atomic_dec_and_test(&pipe->writers))
31158 wake_up_interruptible(&pipe->wait);
31159 ret = -ERESTARTSYS;
31160 goto err;
31161
31162 err:
31163 - if (!pipe->readers && !pipe->writers)
31164 + if (!atomic_read(&pipe->readers) && !atomic_read(&pipe->writers))
31165 free_pipe_info(inode);
31166
31167 err_nocleanup:
31168 diff -urNp linux-2.6.36/fs/file.c linux-2.6.36/fs/file.c
31169 --- linux-2.6.36/fs/file.c 2010-10-20 16:30:22.000000000 -0400
31170 +++ linux-2.6.36/fs/file.c 2010-11-06 18:58:50.000000000 -0400
31171 @@ -14,6 +14,7 @@
31172 #include <linux/slab.h>
31173 #include <linux/vmalloc.h>
31174 #include <linux/file.h>
31175 +#include <linux/security.h>
31176 #include <linux/fdtable.h>
31177 #include <linux/bitops.h>
31178 #include <linux/interrupt.h>
31179 @@ -250,6 +251,7 @@ int expand_files(struct files_struct *fi
31180 * N.B. For clone tasks sharing a files structure, this test
31181 * will limit the total number of files that can be opened.
31182 */
31183 + gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
31184 if (nr >= rlimit(RLIMIT_NOFILE))
31185 return -EMFILE;
31186
31187 diff -urNp linux-2.6.36/fs/fs_struct.c linux-2.6.36/fs/fs_struct.c
31188 --- linux-2.6.36/fs/fs_struct.c 2010-10-20 16:30:22.000000000 -0400
31189 +++ linux-2.6.36/fs/fs_struct.c 2010-11-06 19:16:06.000000000 -0400
31190 @@ -4,6 +4,7 @@
31191 #include <linux/path.h>
31192 #include <linux/slab.h>
31193 #include <linux/fs_struct.h>
31194 +#include <linux/grsecurity.h>
31195
31196 /*
31197 * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
31198 @@ -17,6 +18,7 @@ void set_fs_root(struct fs_struct *fs, s
31199 old_root = fs->root;
31200 fs->root = *path;
31201 path_get(path);
31202 + gr_set_chroot_entries(current, path);
31203 spin_unlock(&fs->lock);
31204 if (old_root.dentry)
31205 path_put(&old_root);
31206 @@ -56,6 +58,7 @@ void chroot_fs_refs(struct path *old_roo
31207 && fs->root.mnt == old_root->mnt) {
31208 path_get(new_root);
31209 fs->root = *new_root;
31210 + gr_set_chroot_entries(p, new_root);
31211 count++;
31212 }
31213 if (fs->pwd.dentry == old_root->dentry
31214 @@ -89,7 +92,8 @@ void exit_fs(struct task_struct *tsk)
31215 task_lock(tsk);
31216 spin_lock(&fs->lock);
31217 tsk->fs = NULL;
31218 - kill = !--fs->users;
31219 + gr_clear_chroot_entries(tsk);
31220 + kill = !atomic_dec_return(&fs->users);
31221 spin_unlock(&fs->lock);
31222 task_unlock(tsk);
31223 if (kill)
31224 @@ -102,7 +106,7 @@ struct fs_struct *copy_fs_struct(struct
31225 struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
31226 /* We don't need to lock fs - think why ;-) */
31227 if (fs) {
31228 - fs->users = 1;
31229 + atomic_set(&fs->users, 1);
31230 fs->in_exec = 0;
31231 spin_lock_init(&fs->lock);
31232 fs->umask = old->umask;
31233 @@ -122,8 +126,9 @@ int unshare_fs_struct(void)
31234
31235 task_lock(current);
31236 spin_lock(&fs->lock);
31237 - kill = !--fs->users;
31238 + kill = !atomic_dec_return(&fs->users);
31239 current->fs = new_fs;
31240 + gr_set_chroot_entries(current, &new_fs->root);
31241 spin_unlock(&fs->lock);
31242 task_unlock(current);
31243
31244 @@ -142,7 +147,7 @@ EXPORT_SYMBOL(current_umask);
31245
31246 /* to be mentioned only in INIT_TASK */
31247 struct fs_struct init_fs = {
31248 - .users = 1,
31249 + .users = ATOMIC_INIT(1),
31250 .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock),
31251 .umask = 0022,
31252 };
31253 @@ -157,12 +162,13 @@ void daemonize_fs_struct(void)
31254 task_lock(current);
31255
31256 spin_lock(&init_fs.lock);
31257 - init_fs.users++;
31258 + atomic_inc(&init_fs.users);
31259 spin_unlock(&init_fs.lock);
31260
31261 spin_lock(&fs->lock);
31262 current->fs = &init_fs;
31263 - kill = !--fs->users;
31264 + gr_set_chroot_entries(current, &current->fs->root);
31265 + kill = !atomic_dec_return(&fs->users);
31266 spin_unlock(&fs->lock);
31267
31268 task_unlock(current);
31269 diff -urNp linux-2.6.36/fs/fuse/control.c linux-2.6.36/fs/fuse/control.c
31270 --- linux-2.6.36/fs/fuse/control.c 2010-10-20 16:30:22.000000000 -0400
31271 +++ linux-2.6.36/fs/fuse/control.c 2010-11-06 18:58:15.000000000 -0400
31272 @@ -293,7 +293,7 @@ void fuse_ctl_remove_conn(struct fuse_co
31273
31274 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
31275 {
31276 - struct tree_descr empty_descr = {""};
31277 + struct tree_descr empty_descr = {"", NULL, 0};
31278 struct fuse_conn *fc;
31279 int err;
31280
31281 diff -urNp linux-2.6.36/fs/fuse/cuse.c linux-2.6.36/fs/fuse/cuse.c
31282 --- linux-2.6.36/fs/fuse/cuse.c 2010-10-20 16:30:22.000000000 -0400
31283 +++ linux-2.6.36/fs/fuse/cuse.c 2010-11-06 18:58:15.000000000 -0400
31284 @@ -529,8 +529,18 @@ static int cuse_channel_release(struct i
31285 return rc;
31286 }
31287
31288 -static struct file_operations cuse_channel_fops; /* initialized during init */
31289 -
31290 +static const struct file_operations cuse_channel_fops = { /* initialized during init */
31291 + .owner = THIS_MODULE,
31292 + .llseek = no_llseek,
31293 + .read = do_sync_read,
31294 + .aio_read = fuse_dev_read,
31295 + .write = do_sync_write,
31296 + .aio_write = fuse_dev_write,
31297 + .poll = fuse_dev_poll,
31298 + .open = cuse_channel_open,
31299 + .release = cuse_channel_release,
31300 + .fasync = fuse_dev_fasync,
31301 +};
31302
31303 /**************************************************************************
31304 * Misc stuff and module initializatiion
31305 @@ -576,12 +586,6 @@ static int __init cuse_init(void)
31306 for (i = 0; i < CUSE_CONNTBL_LEN; i++)
31307 INIT_LIST_HEAD(&cuse_conntbl[i]);
31308
31309 - /* inherit and extend fuse_dev_operations */
31310 - cuse_channel_fops = fuse_dev_operations;
31311 - cuse_channel_fops.owner = THIS_MODULE;
31312 - cuse_channel_fops.open = cuse_channel_open;
31313 - cuse_channel_fops.release = cuse_channel_release;
31314 -
31315 cuse_class = class_create(THIS_MODULE, "cuse");
31316 if (IS_ERR(cuse_class))
31317 return PTR_ERR(cuse_class);
31318 diff -urNp linux-2.6.36/fs/fuse/dev.c linux-2.6.36/fs/fuse/dev.c
31319 --- linux-2.6.36/fs/fuse/dev.c 2010-10-20 16:30:22.000000000 -0400
31320 +++ linux-2.6.36/fs/fuse/dev.c 2010-11-06 18:58:15.000000000 -0400
31321 @@ -1049,7 +1049,7 @@ static ssize_t fuse_dev_do_read(struct f
31322 return err;
31323 }
31324
31325 -static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
31326 +ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
31327 unsigned long nr_segs, loff_t pos)
31328 {
31329 struct fuse_copy_state cs;
31330 @@ -1063,6 +1063,8 @@ static ssize_t fuse_dev_read(struct kioc
31331 return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs));
31332 }
31333
31334 +EXPORT_SYMBOL_GPL(fuse_dev_read);
31335 +
31336 static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe,
31337 struct pipe_buffer *buf)
31338 {
31339 @@ -1106,7 +1108,7 @@ static ssize_t fuse_dev_splice_read(stru
31340 ret = 0;
31341 pipe_lock(pipe);
31342
31343 - if (!pipe->readers) {
31344 + if (!atomic_read(&pipe->readers)) {
31345 send_sig(SIGPIPE, current, 0);
31346 if (!ret)
31347 ret = -EPIPE;
31348 @@ -1604,7 +1606,7 @@ static ssize_t fuse_dev_do_write(struct
31349 return err;
31350 }
31351
31352 -static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
31353 +ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
31354 unsigned long nr_segs, loff_t pos)
31355 {
31356 struct fuse_copy_state cs;
31357 @@ -1617,6 +1619,8 @@ static ssize_t fuse_dev_write(struct kio
31358 return fuse_dev_do_write(fc, &cs, iov_length(iov, nr_segs));
31359 }
31360
31361 +EXPORT_SYMBOL_GPL(fuse_dev_write);
31362 +
31363 static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
31364 struct file *out, loff_t *ppos,
31365 size_t len, unsigned int flags)
31366 @@ -1695,7 +1699,7 @@ out:
31367 return ret;
31368 }
31369
31370 -static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
31371 +unsigned fuse_dev_poll(struct file *file, poll_table *wait)
31372 {
31373 unsigned mask = POLLOUT | POLLWRNORM;
31374 struct fuse_conn *fc = fuse_get_conn(file);
31375 @@ -1714,6 +1718,8 @@ static unsigned fuse_dev_poll(struct fil
31376 return mask;
31377 }
31378
31379 +EXPORT_SYMBOL_GPL(fuse_dev_poll);
31380 +
31381 /*
31382 * Abort all requests on the given list (pending or processing)
31383 *
31384 @@ -1831,7 +1837,7 @@ int fuse_dev_release(struct inode *inode
31385 }
31386 EXPORT_SYMBOL_GPL(fuse_dev_release);
31387
31388 -static int fuse_dev_fasync(int fd, struct file *file, int on)
31389 +int fuse_dev_fasync(int fd, struct file *file, int on)
31390 {
31391 struct fuse_conn *fc = fuse_get_conn(file);
31392 if (!fc)
31393 @@ -1841,6 +1847,8 @@ static int fuse_dev_fasync(int fd, struc
31394 return fasync_helper(fd, file, on, &fc->fasync);
31395 }
31396
31397 +EXPORT_SYMBOL_GPL(fuse_dev_fasync);
31398 +
31399 const struct file_operations fuse_dev_operations = {
31400 .owner = THIS_MODULE,
31401 .llseek = no_llseek,
31402 diff -urNp linux-2.6.36/fs/fuse/dir.c linux-2.6.36/fs/fuse/dir.c
31403 --- linux-2.6.36/fs/fuse/dir.c 2010-10-20 16:30:22.000000000 -0400
31404 +++ linux-2.6.36/fs/fuse/dir.c 2010-11-06 18:58:15.000000000 -0400
31405 @@ -1127,7 +1127,7 @@ static char *read_link(struct dentry *de
31406 return link;
31407 }
31408
31409 -static void free_link(char *link)
31410 +static void free_link(const char *link)
31411 {
31412 if (!IS_ERR(link))
31413 free_page((unsigned long) link);
31414 diff -urNp linux-2.6.36/fs/fuse/fuse_i.h linux-2.6.36/fs/fuse/fuse_i.h
31415 --- linux-2.6.36/fs/fuse/fuse_i.h 2010-10-20 16:30:22.000000000 -0400
31416 +++ linux-2.6.36/fs/fuse/fuse_i.h 2010-11-06 18:58:15.000000000 -0400
31417 @@ -525,6 +525,16 @@ extern const struct file_operations fuse
31418
31419 extern const struct dentry_operations fuse_dentry_operations;
31420
31421 +extern ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
31422 + unsigned long nr_segs, loff_t pos);
31423 +
31424 +extern ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
31425 + unsigned long nr_segs, loff_t pos);
31426 +
31427 +extern unsigned fuse_dev_poll(struct file *file, poll_table *wait);
31428 +
31429 +extern int fuse_dev_fasync(int fd, struct file *file, int on);
31430 +
31431 /**
31432 * Inode to nodeid comparison.
31433 */
31434 diff -urNp linux-2.6.36/fs/hfs/inode.c linux-2.6.36/fs/hfs/inode.c
31435 --- linux-2.6.36/fs/hfs/inode.c 2010-10-20 16:30:22.000000000 -0400
31436 +++ linux-2.6.36/fs/hfs/inode.c 2010-11-06 18:58:15.000000000 -0400
31437 @@ -447,7 +447,7 @@ int hfs_write_inode(struct inode *inode,
31438
31439 if (S_ISDIR(main_inode->i_mode)) {
31440 if (fd.entrylength < sizeof(struct hfs_cat_dir))
31441 - /* panic? */;
31442 + {/* panic? */}
31443 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
31444 sizeof(struct hfs_cat_dir));
31445 if (rec.type != HFS_CDR_DIR ||
31446 @@ -468,7 +468,7 @@ int hfs_write_inode(struct inode *inode,
31447 sizeof(struct hfs_cat_file));
31448 } else {
31449 if (fd.entrylength < sizeof(struct hfs_cat_file))
31450 - /* panic? */;
31451 + {/* panic? */}
31452 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
31453 sizeof(struct hfs_cat_file));
31454 if (rec.type != HFS_CDR_FIL ||
31455 diff -urNp linux-2.6.36/fs/hfsplus/inode.c linux-2.6.36/fs/hfsplus/inode.c
31456 --- linux-2.6.36/fs/hfsplus/inode.c 2010-10-20 16:30:22.000000000 -0400
31457 +++ linux-2.6.36/fs/hfsplus/inode.c 2010-11-06 18:58:15.000000000 -0400
31458 @@ -477,7 +477,7 @@ int hfsplus_cat_read_inode(struct inode
31459 struct hfsplus_cat_folder *folder = &entry.folder;
31460
31461 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
31462 - /* panic? */;
31463 + {/* panic? */}
31464 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
31465 sizeof(struct hfsplus_cat_folder));
31466 hfsplus_get_perms(inode, &folder->permissions, 1);
31467 @@ -494,7 +494,7 @@ int hfsplus_cat_read_inode(struct inode
31468 struct hfsplus_cat_file *file = &entry.file;
31469
31470 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
31471 - /* panic? */;
31472 + {/* panic? */}
31473 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
31474 sizeof(struct hfsplus_cat_file));
31475
31476 @@ -550,7 +550,7 @@ int hfsplus_cat_write_inode(struct inode
31477 struct hfsplus_cat_folder *folder = &entry.folder;
31478
31479 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
31480 - /* panic? */;
31481 + {/* panic? */}
31482 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
31483 sizeof(struct hfsplus_cat_folder));
31484 /* simple node checks? */
31485 @@ -572,7 +572,7 @@ int hfsplus_cat_write_inode(struct inode
31486 struct hfsplus_cat_file *file = &entry.file;
31487
31488 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
31489 - /* panic? */;
31490 + {/* panic? */}
31491 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
31492 sizeof(struct hfsplus_cat_file));
31493 hfsplus_inode_write_fork(inode, &file->data_fork);
31494 diff -urNp linux-2.6.36/fs/hugetlbfs/inode.c linux-2.6.36/fs/hugetlbfs/inode.c
31495 --- linux-2.6.36/fs/hugetlbfs/inode.c 2010-10-20 16:30:22.000000000 -0400
31496 +++ linux-2.6.36/fs/hugetlbfs/inode.c 2010-11-06 18:58:50.000000000 -0400
31497 @@ -891,7 +891,7 @@ static struct file_system_type hugetlbfs
31498 .kill_sb = kill_litter_super,
31499 };
31500
31501 -static struct vfsmount *hugetlbfs_vfsmount;
31502 +struct vfsmount *hugetlbfs_vfsmount;
31503
31504 static int can_do_hugetlb_shm(void)
31505 {
31506 diff -urNp linux-2.6.36/fs/ioctl.c linux-2.6.36/fs/ioctl.c
31507 --- linux-2.6.36/fs/ioctl.c 2010-10-20 16:30:22.000000000 -0400
31508 +++ linux-2.6.36/fs/ioctl.c 2010-11-06 18:58:15.000000000 -0400
31509 @@ -87,7 +87,7 @@ int fiemap_fill_next_extent(struct fiema
31510 u64 phys, u64 len, u32 flags)
31511 {
31512 struct fiemap_extent extent;
31513 - struct fiemap_extent *dest = fieinfo->fi_extents_start;
31514 + struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
31515
31516 /* only count the extents */
31517 if (fieinfo->fi_extents_max == 0) {
31518 @@ -197,7 +197,7 @@ static int ioctl_fiemap(struct file *fil
31519
31520 fieinfo.fi_flags = fiemap.fm_flags;
31521 fieinfo.fi_extents_max = fiemap.fm_extent_count;
31522 - fieinfo.fi_extents_start = (struct fiemap_extent *)(arg + sizeof(fiemap));
31523 + fieinfo.fi_extents_start = (struct fiemap_extent __user *)(arg + sizeof(fiemap));
31524
31525 if (fiemap.fm_extent_count != 0 &&
31526 !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
31527 @@ -210,7 +210,7 @@ static int ioctl_fiemap(struct file *fil
31528 error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start, len);
31529 fiemap.fm_flags = fieinfo.fi_flags;
31530 fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
31531 - if (copy_to_user((char *)arg, &fiemap, sizeof(fiemap)))
31532 + if (copy_to_user((__force char __user *)arg, &fiemap, sizeof(fiemap)))
31533 error = -EFAULT;
31534
31535 return error;
31536 diff -urNp linux-2.6.36/fs/jffs2/debug.h linux-2.6.36/fs/jffs2/debug.h
31537 --- linux-2.6.36/fs/jffs2/debug.h 2010-10-20 16:30:22.000000000 -0400
31538 +++ linux-2.6.36/fs/jffs2/debug.h 2010-11-06 18:58:15.000000000 -0400
31539 @@ -53,13 +53,13 @@
31540 #if CONFIG_JFFS2_FS_DEBUG > 0
31541 #define D1(x) x
31542 #else
31543 -#define D1(x)
31544 +#define D1(x) do {} while (0);
31545 #endif
31546
31547 #if CONFIG_JFFS2_FS_DEBUG > 1
31548 #define D2(x) x
31549 #else
31550 -#define D2(x)
31551 +#define D2(x) do {} while (0);
31552 #endif
31553
31554 /* The prefixes of JFFS2 messages */
31555 @@ -115,73 +115,73 @@
31556 #ifdef JFFS2_DBG_READINODE_MESSAGES
31557 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31558 #else
31559 -#define dbg_readinode(fmt, ...)
31560 +#define dbg_readinode(fmt, ...) do {} while (0)
31561 #endif
31562 #ifdef JFFS2_DBG_READINODE2_MESSAGES
31563 #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31564 #else
31565 -#define dbg_readinode2(fmt, ...)
31566 +#define dbg_readinode2(fmt, ...) do {} while (0)
31567 #endif
31568
31569 /* Fragtree build debugging messages */
31570 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
31571 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31572 #else
31573 -#define dbg_fragtree(fmt, ...)
31574 +#define dbg_fragtree(fmt, ...) do {} while (0)
31575 #endif
31576 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
31577 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31578 #else
31579 -#define dbg_fragtree2(fmt, ...)
31580 +#define dbg_fragtree2(fmt, ...) do {} while (0)
31581 #endif
31582
31583 /* Directory entry list manilulation debugging messages */
31584 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
31585 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31586 #else
31587 -#define dbg_dentlist(fmt, ...)
31588 +#define dbg_dentlist(fmt, ...) do {} while (0)
31589 #endif
31590
31591 /* Print the messages about manipulating node_refs */
31592 #ifdef JFFS2_DBG_NODEREF_MESSAGES
31593 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31594 #else
31595 -#define dbg_noderef(fmt, ...)
31596 +#define dbg_noderef(fmt, ...) do {} while (0)
31597 #endif
31598
31599 /* Manipulations with the list of inodes (JFFS2 inocache) */
31600 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
31601 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31602 #else
31603 -#define dbg_inocache(fmt, ...)
31604 +#define dbg_inocache(fmt, ...) do {} while (0)
31605 #endif
31606
31607 /* Summary debugging messages */
31608 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
31609 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31610 #else
31611 -#define dbg_summary(fmt, ...)
31612 +#define dbg_summary(fmt, ...) do {} while (0)
31613 #endif
31614
31615 /* File system build messages */
31616 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
31617 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31618 #else
31619 -#define dbg_fsbuild(fmt, ...)
31620 +#define dbg_fsbuild(fmt, ...) do {} while (0)
31621 #endif
31622
31623 /* Watch the object allocations */
31624 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
31625 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31626 #else
31627 -#define dbg_memalloc(fmt, ...)
31628 +#define dbg_memalloc(fmt, ...) do {} while (0)
31629 #endif
31630
31631 /* Watch the XATTR subsystem */
31632 #ifdef JFFS2_DBG_XATTR_MESSAGES
31633 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
31634 #else
31635 -#define dbg_xattr(fmt, ...)
31636 +#define dbg_xattr(fmt, ...) do {} while (0)
31637 #endif
31638
31639 /* "Sanity" checks */
31640 diff -urNp linux-2.6.36/fs/jffs2/erase.c linux-2.6.36/fs/jffs2/erase.c
31641 --- linux-2.6.36/fs/jffs2/erase.c 2010-10-20 16:30:22.000000000 -0400
31642 +++ linux-2.6.36/fs/jffs2/erase.c 2010-11-06 18:58:15.000000000 -0400
31643 @@ -439,7 +439,8 @@ static void jffs2_mark_erased_block(stru
31644 struct jffs2_unknown_node marker = {
31645 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
31646 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
31647 - .totlen = cpu_to_je32(c->cleanmarker_size)
31648 + .totlen = cpu_to_je32(c->cleanmarker_size),
31649 + .hdr_crc = cpu_to_je32(0)
31650 };
31651
31652 jffs2_prealloc_raw_node_refs(c, jeb, 1);
31653 diff -urNp linux-2.6.36/fs/jffs2/summary.h linux-2.6.36/fs/jffs2/summary.h
31654 --- linux-2.6.36/fs/jffs2/summary.h 2010-10-20 16:30:22.000000000 -0400
31655 +++ linux-2.6.36/fs/jffs2/summary.h 2010-11-06 18:58:15.000000000 -0400
31656 @@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
31657
31658 #define jffs2_sum_active() (0)
31659 #define jffs2_sum_init(a) (0)
31660 -#define jffs2_sum_exit(a)
31661 -#define jffs2_sum_disable_collecting(a)
31662 +#define jffs2_sum_exit(a) do {} while (0)
31663 +#define jffs2_sum_disable_collecting(a) do {} while (0)
31664 #define jffs2_sum_is_disabled(a) (0)
31665 -#define jffs2_sum_reset_collected(a)
31666 +#define jffs2_sum_reset_collected(a) do {} while (0)
31667 #define jffs2_sum_add_kvec(a,b,c,d) (0)
31668 -#define jffs2_sum_move_collected(a,b)
31669 +#define jffs2_sum_move_collected(a,b) do {} while (0)
31670 #define jffs2_sum_write_sumnode(a) (0)
31671 -#define jffs2_sum_add_padding_mem(a,b)
31672 -#define jffs2_sum_add_inode_mem(a,b,c)
31673 -#define jffs2_sum_add_dirent_mem(a,b,c)
31674 -#define jffs2_sum_add_xattr_mem(a,b,c)
31675 -#define jffs2_sum_add_xref_mem(a,b,c)
31676 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
31677 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
31678 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
31679 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
31680 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
31681 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
31682
31683 #endif /* CONFIG_JFFS2_SUMMARY */
31684 diff -urNp linux-2.6.36/fs/jffs2/wbuf.c linux-2.6.36/fs/jffs2/wbuf.c
31685 --- linux-2.6.36/fs/jffs2/wbuf.c 2010-10-20 16:30:22.000000000 -0400
31686 +++ linux-2.6.36/fs/jffs2/wbuf.c 2010-11-06 18:58:15.000000000 -0400
31687 @@ -1012,7 +1012,8 @@ static const struct jffs2_unknown_node o
31688 {
31689 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
31690 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
31691 - .totlen = constant_cpu_to_je32(8)
31692 + .totlen = constant_cpu_to_je32(8),
31693 + .hdr_crc = constant_cpu_to_je32(0)
31694 };
31695
31696 /*
31697 diff -urNp linux-2.6.36/fs/Kconfig.binfmt linux-2.6.36/fs/Kconfig.binfmt
31698 --- linux-2.6.36/fs/Kconfig.binfmt 2010-10-20 16:30:22.000000000 -0400
31699 +++ linux-2.6.36/fs/Kconfig.binfmt 2010-11-06 18:58:15.000000000 -0400
31700 @@ -86,7 +86,7 @@ config HAVE_AOUT
31701
31702 config BINFMT_AOUT
31703 tristate "Kernel support for a.out and ECOFF binaries"
31704 - depends on HAVE_AOUT
31705 + depends on HAVE_AOUT && BROKEN
31706 ---help---
31707 A.out (Assembler.OUTput) is a set of formats for libraries and
31708 executables used in the earliest versions of UNIX. Linux used
31709 diff -urNp linux-2.6.36/fs/lockd/svc.c linux-2.6.36/fs/lockd/svc.c
31710 --- linux-2.6.36/fs/lockd/svc.c 2010-10-20 16:30:22.000000000 -0400
31711 +++ linux-2.6.36/fs/lockd/svc.c 2010-11-06 18:58:15.000000000 -0400
31712 @@ -42,7 +42,7 @@
31713
31714 static struct svc_program nlmsvc_program;
31715
31716 -struct nlmsvc_binding * nlmsvc_ops;
31717 +const struct nlmsvc_binding * nlmsvc_ops;
31718 EXPORT_SYMBOL_GPL(nlmsvc_ops);
31719
31720 static DEFINE_MUTEX(nlmsvc_mutex);
31721 diff -urNp linux-2.6.36/fs/locks.c linux-2.6.36/fs/locks.c
31722 --- linux-2.6.36/fs/locks.c 2010-10-20 16:30:22.000000000 -0400
31723 +++ linux-2.6.36/fs/locks.c 2010-11-06 18:58:15.000000000 -0400
31724 @@ -2008,16 +2008,16 @@ void locks_remove_flock(struct file *fil
31725 return;
31726
31727 if (filp->f_op && filp->f_op->flock) {
31728 - struct file_lock fl = {
31729 + struct file_lock flock = {
31730 .fl_pid = current->tgid,
31731 .fl_file = filp,
31732 .fl_flags = FL_FLOCK,
31733 .fl_type = F_UNLCK,
31734 .fl_end = OFFSET_MAX,
31735 };
31736 - filp->f_op->flock(filp, F_SETLKW, &fl);
31737 - if (fl.fl_ops && fl.fl_ops->fl_release_private)
31738 - fl.fl_ops->fl_release_private(&fl);
31739 + filp->f_op->flock(filp, F_SETLKW, &flock);
31740 + if (flock.fl_ops && flock.fl_ops->fl_release_private)
31741 + flock.fl_ops->fl_release_private(&flock);
31742 }
31743
31744 lock_kernel();
31745 diff -urNp linux-2.6.36/fs/namei.c linux-2.6.36/fs/namei.c
31746 --- linux-2.6.36/fs/namei.c 2010-10-20 16:30:22.000000000 -0400
31747 +++ linux-2.6.36/fs/namei.c 2010-11-06 18:58:50.000000000 -0400
31748 @@ -542,7 +542,7 @@ __do_follow_link(struct path *path, stru
31749 *p = dentry->d_inode->i_op->follow_link(dentry, nd);
31750 error = PTR_ERR(*p);
31751 if (!IS_ERR(*p)) {
31752 - char *s = nd_get_link(nd);
31753 + const char *s = nd_get_link(nd);
31754 error = 0;
31755 if (s)
31756 error = __vfs_follow_link(nd, s);
31757 @@ -575,6 +575,13 @@ static inline int do_follow_link(struct
31758 err = security_inode_follow_link(path->dentry, nd);
31759 if (err)
31760 goto loop;
31761 +
31762 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
31763 + path->dentry->d_inode, path->dentry, nd->path.mnt)) {
31764 + err = -EACCES;
31765 + goto loop;
31766 + }
31767 +
31768 current->link_count++;
31769 current->total_link_count++;
31770 nd->depth++;
31771 @@ -967,11 +974,18 @@ return_reval:
31772 break;
31773 }
31774 return_base:
31775 + if (!(nd->flags & LOOKUP_PARENT) && !gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
31776 + path_put(&nd->path);
31777 + return -ENOENT;
31778 + }
31779 return 0;
31780 out_dput:
31781 path_put_conditional(&next, nd);
31782 break;
31783 }
31784 + if (!(nd->flags & LOOKUP_PARENT) && !gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
31785 + err = -ENOENT;
31786 +
31787 path_put(&nd->path);
31788 return_err:
31789 return err;
31790 @@ -1486,12 +1500,19 @@ static int __open_namei_create(struct na
31791 int error;
31792 struct dentry *dir = nd->path.dentry;
31793
31794 + if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, open_flag, mode)) {
31795 + error = -EACCES;
31796 + goto out_unlock;
31797 + }
31798 +
31799 if (!IS_POSIXACL(dir->d_inode))
31800 mode &= ~current_umask();
31801 error = security_path_mknod(&nd->path, path->dentry, mode, 0);
31802 if (error)
31803 goto out_unlock;
31804 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
31805 + if (!error)
31806 + gr_handle_create(path->dentry, nd->path.mnt);
31807 out_unlock:
31808 mutex_unlock(&dir->d_inode->i_mutex);
31809 dput(nd->path.dentry);
31810 @@ -1594,6 +1615,7 @@ static struct file *do_last(struct namei
31811 int mode, const char *pathname)
31812 {
31813 struct dentry *dir = nd->path.dentry;
31814 + int flag = open_to_namei_flags(open_flag);
31815 struct file *filp;
31816 int error = -EISDIR;
31817
31818 @@ -1642,6 +1664,22 @@ static struct file *do_last(struct namei
31819 }
31820 path_to_nameidata(path, nd);
31821 audit_inode(pathname, nd->path.dentry);
31822 +
31823 + if (gr_handle_rofs_blockwrite(nd->path.dentry, nd->path.mnt, acc_mode)) {
31824 + error = -EPERM;
31825 + goto exit;
31826 + }
31827 +
31828 + if (gr_handle_rawio(nd->path.dentry->d_inode)) {
31829 + error = -EPERM;
31830 + goto exit;
31831 + }
31832 +
31833 + if (!gr_acl_handle_open(nd->path.dentry, nd->path.mnt, flag)) {
31834 + error = -EACCES;
31835 + goto exit;
31836 + }
31837 +
31838 goto ok;
31839 }
31840
31841 @@ -1694,6 +1732,24 @@ static struct file *do_last(struct namei
31842 /*
31843 * It already exists.
31844 */
31845 +
31846 + if (gr_handle_rofs_blockwrite(path->dentry, nd->path.mnt, acc_mode)) {
31847 + error = -EPERM;
31848 + goto exit_mutex_unlock;
31849 + }
31850 + if (gr_handle_rawio(path->dentry->d_inode)) {
31851 + error = -EPERM;
31852 + goto exit_mutex_unlock;
31853 + }
31854 + if (!gr_acl_handle_open(path->dentry, nd->path.mnt, flag)) {
31855 + error = -EACCES;
31856 + goto exit_mutex_unlock;
31857 + }
31858 + if (gr_handle_fifo(path->dentry, nd->path.mnt, dir, flag, acc_mode)) {
31859 + error = -EACCES;
31860 + goto exit_mutex_unlock;
31861 + }
31862 +
31863 mutex_unlock(&dir->d_inode->i_mutex);
31864 audit_inode(pathname, path->dentry);
31865
31866 @@ -2014,6 +2070,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
31867 error = may_mknod(mode);
31868 if (error)
31869 goto out_dput;
31870 +
31871 + if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
31872 + error = -EPERM;
31873 + goto out_dput;
31874 + }
31875 +
31876 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
31877 + error = -EACCES;
31878 + goto out_dput;
31879 + }
31880 +
31881 error = mnt_want_write(nd.path.mnt);
31882 if (error)
31883 goto out_dput;
31884 @@ -2034,6 +2101,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
31885 }
31886 out_drop_write:
31887 mnt_drop_write(nd.path.mnt);
31888 +
31889 + if (!error)
31890 + gr_handle_create(dentry, nd.path.mnt);
31891 out_dput:
31892 dput(dentry);
31893 out_unlock:
31894 @@ -2086,6 +2156,11 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
31895 if (IS_ERR(dentry))
31896 goto out_unlock;
31897
31898 + if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
31899 + error = -EACCES;
31900 + goto out_dput;
31901 + }
31902 +
31903 if (!IS_POSIXACL(nd.path.dentry->d_inode))
31904 mode &= ~current_umask();
31905 error = mnt_want_write(nd.path.mnt);
31906 @@ -2097,6 +2172,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
31907 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
31908 out_drop_write:
31909 mnt_drop_write(nd.path.mnt);
31910 +
31911 + if (!error)
31912 + gr_handle_create(dentry, nd.path.mnt);
31913 +
31914 out_dput:
31915 dput(dentry);
31916 out_unlock:
31917 @@ -2178,6 +2257,8 @@ static long do_rmdir(int dfd, const char
31918 char * name;
31919 struct dentry *dentry;
31920 struct nameidata nd;
31921 + ino_t saved_ino = 0;
31922 + dev_t saved_dev = 0;
31923
31924 error = user_path_parent(dfd, pathname, &nd, &name);
31925 if (error)
31926 @@ -2202,6 +2283,19 @@ static long do_rmdir(int dfd, const char
31927 error = PTR_ERR(dentry);
31928 if (IS_ERR(dentry))
31929 goto exit2;
31930 +
31931 + if (dentry->d_inode != NULL) {
31932 + if (dentry->d_inode->i_nlink <= 1) {
31933 + saved_ino = dentry->d_inode->i_ino;
31934 + saved_dev = dentry->d_inode->i_sb->s_dev;
31935 + }
31936 +
31937 + if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
31938 + error = -EACCES;
31939 + goto exit3;
31940 + }
31941 + }
31942 +
31943 error = mnt_want_write(nd.path.mnt);
31944 if (error)
31945 goto exit3;
31946 @@ -2209,6 +2303,8 @@ static long do_rmdir(int dfd, const char
31947 if (error)
31948 goto exit4;
31949 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
31950 + if (!error && (saved_dev || saved_ino))
31951 + gr_handle_delete(saved_ino, saved_dev);
31952 exit4:
31953 mnt_drop_write(nd.path.mnt);
31954 exit3:
31955 @@ -2271,6 +2367,8 @@ static long do_unlinkat(int dfd, const c
31956 struct dentry *dentry;
31957 struct nameidata nd;
31958 struct inode *inode = NULL;
31959 + ino_t saved_ino = 0;
31960 + dev_t saved_dev = 0;
31961
31962 error = user_path_parent(dfd, pathname, &nd, &name);
31963 if (error)
31964 @@ -2290,8 +2388,19 @@ static long do_unlinkat(int dfd, const c
31965 if (nd.last.name[nd.last.len])
31966 goto slashes;
31967 inode = dentry->d_inode;
31968 - if (inode)
31969 + if (inode) {
31970 + if (inode->i_nlink <= 1) {
31971 + saved_ino = inode->i_ino;
31972 + saved_dev = inode->i_sb->s_dev;
31973 + }
31974 +
31975 atomic_inc(&inode->i_count);
31976 +
31977 + if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
31978 + error = -EACCES;
31979 + goto exit2;
31980 + }
31981 + }
31982 error = mnt_want_write(nd.path.mnt);
31983 if (error)
31984 goto exit2;
31985 @@ -2299,6 +2408,8 @@ static long do_unlinkat(int dfd, const c
31986 if (error)
31987 goto exit3;
31988 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
31989 + if (!error && (saved_ino || saved_dev))
31990 + gr_handle_delete(saved_ino, saved_dev);
31991 exit3:
31992 mnt_drop_write(nd.path.mnt);
31993 exit2:
31994 @@ -2376,6 +2487,11 @@ SYSCALL_DEFINE3(symlinkat, const char __
31995 if (IS_ERR(dentry))
31996 goto out_unlock;
31997
31998 + if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
31999 + error = -EACCES;
32000 + goto out_dput;
32001 + }
32002 +
32003 error = mnt_want_write(nd.path.mnt);
32004 if (error)
32005 goto out_dput;
32006 @@ -2383,6 +2499,8 @@ SYSCALL_DEFINE3(symlinkat, const char __
32007 if (error)
32008 goto out_drop_write;
32009 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
32010 + if (!error)
32011 + gr_handle_create(dentry, nd.path.mnt);
32012 out_drop_write:
32013 mnt_drop_write(nd.path.mnt);
32014 out_dput:
32015 @@ -2475,6 +2593,20 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
32016 error = PTR_ERR(new_dentry);
32017 if (IS_ERR(new_dentry))
32018 goto out_unlock;
32019 +
32020 + if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
32021 + old_path.dentry->d_inode,
32022 + old_path.dentry->d_inode->i_mode, to)) {
32023 + error = -EACCES;
32024 + goto out_dput;
32025 + }
32026 +
32027 + if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
32028 + old_path.dentry, old_path.mnt, to)) {
32029 + error = -EACCES;
32030 + goto out_dput;
32031 + }
32032 +
32033 error = mnt_want_write(nd.path.mnt);
32034 if (error)
32035 goto out_dput;
32036 @@ -2482,6 +2614,8 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
32037 if (error)
32038 goto out_drop_write;
32039 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
32040 + if (!error)
32041 + gr_handle_create(new_dentry, nd.path.mnt);
32042 out_drop_write:
32043 mnt_drop_write(nd.path.mnt);
32044 out_dput:
32045 @@ -2715,6 +2849,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
32046 if (new_dentry == trap)
32047 goto exit5;
32048
32049 + error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
32050 + old_dentry, old_dir->d_inode, oldnd.path.mnt,
32051 + to);
32052 + if (error)
32053 + goto exit5;
32054 +
32055 error = mnt_want_write(oldnd.path.mnt);
32056 if (error)
32057 goto exit5;
32058 @@ -2724,6 +2864,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
32059 goto exit6;
32060 error = vfs_rename(old_dir->d_inode, old_dentry,
32061 new_dir->d_inode, new_dentry);
32062 + if (!error)
32063 + gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
32064 + new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
32065 exit6:
32066 mnt_drop_write(oldnd.path.mnt);
32067 exit5:
32068 diff -urNp linux-2.6.36/fs/namespace.c linux-2.6.36/fs/namespace.c
32069 --- linux-2.6.36/fs/namespace.c 2010-10-20 16:30:22.000000000 -0400
32070 +++ linux-2.6.36/fs/namespace.c 2010-11-06 19:18:03.000000000 -0400
32071 @@ -1142,6 +1142,9 @@ static int do_umount(struct vfsmount *mn
32072 if (!(sb->s_flags & MS_RDONLY))
32073 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
32074 up_write(&sb->s_umount);
32075 +
32076 + gr_log_remount(mnt->mnt_devname, retval);
32077 +
32078 return retval;
32079 }
32080
32081 @@ -1161,6 +1164,9 @@ static int do_umount(struct vfsmount *mn
32082 br_write_unlock(vfsmount_lock);
32083 up_write(&namespace_sem);
32084 release_mounts(&umount_list);
32085 +
32086 + gr_log_unmount(mnt->mnt_devname, retval);
32087 +
32088 return retval;
32089 }
32090
32091 @@ -2056,6 +2062,16 @@ long do_mount(char *dev_name, char *dir_
32092 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
32093 MS_STRICTATIME);
32094
32095 + if (gr_handle_rofs_mount(path.dentry, path.mnt, mnt_flags)) {
32096 + retval = -EPERM;
32097 + goto dput_out;
32098 + }
32099 +
32100 + if (gr_handle_chroot_mount(path.dentry, path.mnt, dev_name)) {
32101 + retval = -EPERM;
32102 + goto dput_out;
32103 + }
32104 +
32105 if (flags & MS_REMOUNT)
32106 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
32107 data_page);
32108 @@ -2070,6 +2086,9 @@ long do_mount(char *dev_name, char *dir_
32109 dev_name, data_page);
32110 dput_out:
32111 path_put(&path);
32112 +
32113 + gr_log_mount(dev_name, dir_name, retval);
32114 +
32115 return retval;
32116 }
32117
32118 @@ -2276,6 +2295,12 @@ SYSCALL_DEFINE2(pivot_root, const char _
32119 goto out1;
32120 }
32121
32122 + if (gr_handle_chroot_pivot()) {
32123 + error = -EPERM;
32124 + path_put(&old);
32125 + goto out1;
32126 + }
32127 +
32128 get_fs_root(current->fs, &root);
32129 down_write(&namespace_sem);
32130 mutex_lock(&old.dentry->d_inode->i_mutex);
32131 diff -urNp linux-2.6.36/fs/nfs/inode.c linux-2.6.36/fs/nfs/inode.c
32132 --- linux-2.6.36/fs/nfs/inode.c 2010-10-20 16:30:22.000000000 -0400
32133 +++ linux-2.6.36/fs/nfs/inode.c 2010-11-06 18:58:15.000000000 -0400
32134 @@ -982,16 +982,16 @@ static int nfs_size_need_update(const st
32135 return nfs_size_to_loff_t(fattr->size) > i_size_read(inode);
32136 }
32137
32138 -static atomic_long_t nfs_attr_generation_counter;
32139 +static atomic_long_unchecked_t nfs_attr_generation_counter;
32140
32141 static unsigned long nfs_read_attr_generation_counter(void)
32142 {
32143 - return atomic_long_read(&nfs_attr_generation_counter);
32144 + return atomic_long_read_unchecked(&nfs_attr_generation_counter);
32145 }
32146
32147 unsigned long nfs_inc_attr_generation_counter(void)
32148 {
32149 - return atomic_long_inc_return(&nfs_attr_generation_counter);
32150 + return atomic_long_inc_return_unchecked(&nfs_attr_generation_counter);
32151 }
32152
32153 void nfs_fattr_init(struct nfs_fattr *fattr)
32154 diff -urNp linux-2.6.36/fs/nfs/nfs4proc.c linux-2.6.36/fs/nfs/nfs4proc.c
32155 --- linux-2.6.36/fs/nfs/nfs4proc.c 2010-10-20 16:30:22.000000000 -0400
32156 +++ linux-2.6.36/fs/nfs/nfs4proc.c 2010-11-06 18:58:15.000000000 -0400
32157 @@ -1184,7 +1184,7 @@ static int _nfs4_do_open_reclaim(struct
32158 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
32159 {
32160 struct nfs_server *server = NFS_SERVER(state->inode);
32161 - struct nfs4_exception exception = { };
32162 + struct nfs4_exception exception = {0, 0};
32163 int err;
32164 do {
32165 err = _nfs4_do_open_reclaim(ctx, state);
32166 @@ -1226,7 +1226,7 @@ static int _nfs4_open_delegation_recall(
32167
32168 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
32169 {
32170 - struct nfs4_exception exception = { };
32171 + struct nfs4_exception exception = {0, 0};
32172 struct nfs_server *server = NFS_SERVER(state->inode);
32173 int err;
32174 do {
32175 @@ -1595,7 +1595,7 @@ static int _nfs4_open_expired(struct nfs
32176 static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
32177 {
32178 struct nfs_server *server = NFS_SERVER(state->inode);
32179 - struct nfs4_exception exception = { };
32180 + struct nfs4_exception exception = {0, 0};
32181 int err;
32182
32183 do {
32184 @@ -1711,7 +1711,7 @@ out_err:
32185
32186 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)
32187 {
32188 - struct nfs4_exception exception = { };
32189 + struct nfs4_exception exception = {0, 0};
32190 struct nfs4_state *res;
32191 int status;
32192
32193 @@ -1802,7 +1802,7 @@ static int nfs4_do_setattr(struct inode
32194 struct nfs4_state *state)
32195 {
32196 struct nfs_server *server = NFS_SERVER(inode);
32197 - struct nfs4_exception exception = { };
32198 + struct nfs4_exception exception = {0, 0};
32199 int err;
32200 do {
32201 err = nfs4_handle_exception(server,
32202 @@ -2179,7 +2179,7 @@ static int _nfs4_server_capabilities(str
32203
32204 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
32205 {
32206 - struct nfs4_exception exception = { };
32207 + struct nfs4_exception exception = {0, 0};
32208 int err;
32209 do {
32210 err = nfs4_handle_exception(server,
32211 @@ -2213,7 +2213,7 @@ static int _nfs4_lookup_root(struct nfs_
32212 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
32213 struct nfs_fsinfo *info)
32214 {
32215 - struct nfs4_exception exception = { };
32216 + struct nfs4_exception exception = {0, 0};
32217 int err;
32218 do {
32219 err = nfs4_handle_exception(server,
32220 @@ -2301,7 +2301,7 @@ static int _nfs4_proc_getattr(struct nfs
32221
32222 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
32223 {
32224 - struct nfs4_exception exception = { };
32225 + struct nfs4_exception exception = {0, 0};
32226 int err;
32227 do {
32228 err = nfs4_handle_exception(server,
32229 @@ -2389,7 +2389,7 @@ static int nfs4_proc_lookupfh(struct nfs
32230 struct qstr *name, struct nfs_fh *fhandle,
32231 struct nfs_fattr *fattr)
32232 {
32233 - struct nfs4_exception exception = { };
32234 + struct nfs4_exception exception = {0, 0};
32235 int err;
32236 do {
32237 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
32238 @@ -2418,7 +2418,7 @@ static int _nfs4_proc_lookup(struct inod
32239
32240 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
32241 {
32242 - struct nfs4_exception exception = { };
32243 + struct nfs4_exception exception = {0, 0};
32244 int err;
32245 do {
32246 err = nfs4_handle_exception(NFS_SERVER(dir),
32247 @@ -2485,7 +2485,7 @@ static int _nfs4_proc_access(struct inod
32248
32249 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
32250 {
32251 - struct nfs4_exception exception = { };
32252 + struct nfs4_exception exception = {0, 0};
32253 int err;
32254 do {
32255 err = nfs4_handle_exception(NFS_SERVER(inode),
32256 @@ -2541,7 +2541,7 @@ static int _nfs4_proc_readlink(struct in
32257 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
32258 unsigned int pgbase, unsigned int pglen)
32259 {
32260 - struct nfs4_exception exception = { };
32261 + struct nfs4_exception exception = {0, 0};
32262 int err;
32263 do {
32264 err = nfs4_handle_exception(NFS_SERVER(inode),
32265 @@ -2637,7 +2637,7 @@ out:
32266
32267 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
32268 {
32269 - struct nfs4_exception exception = { };
32270 + struct nfs4_exception exception = {0, 0};
32271 int err;
32272 do {
32273 err = nfs4_handle_exception(NFS_SERVER(dir),
32274 @@ -2713,7 +2713,7 @@ out:
32275 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
32276 struct inode *new_dir, struct qstr *new_name)
32277 {
32278 - struct nfs4_exception exception = { };
32279 + struct nfs4_exception exception = {0, 0};
32280 int err;
32281 do {
32282 err = nfs4_handle_exception(NFS_SERVER(old_dir),
32283 @@ -2762,7 +2762,7 @@ out:
32284
32285 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
32286 {
32287 - struct nfs4_exception exception = { };
32288 + struct nfs4_exception exception = {0, 0};
32289 int err;
32290 do {
32291 err = nfs4_handle_exception(NFS_SERVER(inode),
32292 @@ -2854,7 +2854,7 @@ out:
32293 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
32294 struct page *page, unsigned int len, struct iattr *sattr)
32295 {
32296 - struct nfs4_exception exception = { };
32297 + struct nfs4_exception exception = {0, 0};
32298 int err;
32299 do {
32300 err = nfs4_handle_exception(NFS_SERVER(dir),
32301 @@ -2885,7 +2885,7 @@ out:
32302 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
32303 struct iattr *sattr)
32304 {
32305 - struct nfs4_exception exception = { };
32306 + struct nfs4_exception exception = {0, 0};
32307 int err;
32308 do {
32309 err = nfs4_handle_exception(NFS_SERVER(dir),
32310 @@ -2934,7 +2934,7 @@ static int _nfs4_proc_readdir(struct den
32311 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
32312 u64 cookie, struct page *page, unsigned int count, int plus)
32313 {
32314 - struct nfs4_exception exception = { };
32315 + struct nfs4_exception exception = {0, 0};
32316 int err;
32317 do {
32318 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
32319 @@ -2982,7 +2982,7 @@ out:
32320 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
32321 struct iattr *sattr, dev_t rdev)
32322 {
32323 - struct nfs4_exception exception = { };
32324 + struct nfs4_exception exception = {0, 0};
32325 int err;
32326 do {
32327 err = nfs4_handle_exception(NFS_SERVER(dir),
32328 @@ -3014,7 +3014,7 @@ static int _nfs4_proc_statfs(struct nfs_
32329
32330 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
32331 {
32332 - struct nfs4_exception exception = { };
32333 + struct nfs4_exception exception = {0, 0};
32334 int err;
32335 do {
32336 err = nfs4_handle_exception(server,
32337 @@ -3045,7 +3045,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
32338
32339 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
32340 {
32341 - struct nfs4_exception exception = { };
32342 + struct nfs4_exception exception = {0, 0};
32343 int err;
32344
32345 do {
32346 @@ -3091,7 +3091,7 @@ static int _nfs4_proc_pathconf(struct nf
32347 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
32348 struct nfs_pathconf *pathconf)
32349 {
32350 - struct nfs4_exception exception = { };
32351 + struct nfs4_exception exception = {0, 0};
32352 int err;
32353
32354 do {
32355 @@ -3408,7 +3408,7 @@ out_free:
32356
32357 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
32358 {
32359 - struct nfs4_exception exception = { };
32360 + struct nfs4_exception exception = {0, 0};
32361 ssize_t ret;
32362 do {
32363 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
32364 @@ -3464,7 +3464,7 @@ static int __nfs4_proc_set_acl(struct in
32365
32366 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
32367 {
32368 - struct nfs4_exception exception = { };
32369 + struct nfs4_exception exception = {0, 0};
32370 int err;
32371 do {
32372 err = nfs4_handle_exception(NFS_SERVER(inode),
32373 @@ -3749,7 +3749,7 @@ out:
32374 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
32375 {
32376 struct nfs_server *server = NFS_SERVER(inode);
32377 - struct nfs4_exception exception = { };
32378 + struct nfs4_exception exception = {0, 0};
32379 int err;
32380 do {
32381 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
32382 @@ -3822,7 +3822,7 @@ out:
32383
32384 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
32385 {
32386 - struct nfs4_exception exception = { };
32387 + struct nfs4_exception exception = {0, 0};
32388 int err;
32389
32390 do {
32391 @@ -4233,7 +4233,7 @@ static int _nfs4_do_setlk(struct nfs4_st
32392 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
32393 {
32394 struct nfs_server *server = NFS_SERVER(state->inode);
32395 - struct nfs4_exception exception = { };
32396 + struct nfs4_exception exception = {0, 0};
32397 int err;
32398
32399 do {
32400 @@ -4251,7 +4251,7 @@ static int nfs4_lock_reclaim(struct nfs4
32401 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
32402 {
32403 struct nfs_server *server = NFS_SERVER(state->inode);
32404 - struct nfs4_exception exception = { };
32405 + struct nfs4_exception exception = {0, 0};
32406 int err;
32407
32408 err = nfs4_set_lock_state(state, request);
32409 @@ -4316,7 +4316,7 @@ out:
32410
32411 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
32412 {
32413 - struct nfs4_exception exception = { };
32414 + struct nfs4_exception exception = {0, 0};
32415 int err;
32416
32417 do {
32418 @@ -4376,7 +4376,7 @@ nfs4_proc_lock(struct file *filp, int cm
32419 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
32420 {
32421 struct nfs_server *server = NFS_SERVER(state->inode);
32422 - struct nfs4_exception exception = { };
32423 + struct nfs4_exception exception = {0, 0};
32424 int err;
32425
32426 err = nfs4_set_lock_state(state, fl);
32427 diff -urNp linux-2.6.36/fs/nfsd/lockd.c linux-2.6.36/fs/nfsd/lockd.c
32428 --- linux-2.6.36/fs/nfsd/lockd.c 2010-10-20 16:30:22.000000000 -0400
32429 +++ linux-2.6.36/fs/nfsd/lockd.c 2010-11-06 18:58:15.000000000 -0400
32430 @@ -61,7 +61,7 @@ nlm_fclose(struct file *filp)
32431 fput(filp);
32432 }
32433
32434 -static struct nlmsvc_binding nfsd_nlm_ops = {
32435 +static const struct nlmsvc_binding nfsd_nlm_ops = {
32436 .fopen = nlm_fopen, /* open file for locking */
32437 .fclose = nlm_fclose, /* close file */
32438 };
32439 diff -urNp linux-2.6.36/fs/nfsd/nfsctl.c linux-2.6.36/fs/nfsd/nfsctl.c
32440 --- linux-2.6.36/fs/nfsd/nfsctl.c 2010-10-20 16:30:22.000000000 -0400
32441 +++ linux-2.6.36/fs/nfsd/nfsctl.c 2010-11-06 18:58:15.000000000 -0400
32442 @@ -163,7 +163,7 @@ static int export_features_open(struct i
32443 return single_open(file, export_features_show, NULL);
32444 }
32445
32446 -static struct file_operations export_features_operations = {
32447 +static const struct file_operations export_features_operations = {
32448 .open = export_features_open,
32449 .read = seq_read,
32450 .llseek = seq_lseek,
32451 diff -urNp linux-2.6.36/fs/nfsd/vfs.c linux-2.6.36/fs/nfsd/vfs.c
32452 --- linux-2.6.36/fs/nfsd/vfs.c 2010-10-20 16:30:22.000000000 -0400
32453 +++ linux-2.6.36/fs/nfsd/vfs.c 2010-11-06 18:58:15.000000000 -0400
32454 @@ -926,7 +926,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, st
32455 } else {
32456 oldfs = get_fs();
32457 set_fs(KERNEL_DS);
32458 - host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
32459 + host_err = vfs_readv(file, (__force struct iovec __user *)vec, vlen, &offset);
32460 set_fs(oldfs);
32461 }
32462
32463 @@ -1039,7 +1039,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
32464
32465 /* Write the data. */
32466 oldfs = get_fs(); set_fs(KERNEL_DS);
32467 - host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
32468 + host_err = vfs_writev(file, (__force struct iovec __user *)vec, vlen, &offset);
32469 set_fs(oldfs);
32470 if (host_err < 0)
32471 goto out_nfserr;
32472 @@ -1556,7 +1556,7 @@ nfsd_readlink(struct svc_rqst *rqstp, st
32473 */
32474
32475 oldfs = get_fs(); set_fs(KERNEL_DS);
32476 - host_err = inode->i_op->readlink(dentry, buf, *lenp);
32477 + host_err = inode->i_op->readlink(dentry, (__force char __user *)buf, *lenp);
32478 set_fs(oldfs);
32479
32480 if (host_err < 0)
32481 diff -urNp linux-2.6.36/fs/nls/nls_base.c linux-2.6.36/fs/nls/nls_base.c
32482 --- linux-2.6.36/fs/nls/nls_base.c 2010-10-20 16:30:22.000000000 -0400
32483 +++ linux-2.6.36/fs/nls/nls_base.c 2010-11-06 18:58:15.000000000 -0400
32484 @@ -41,7 +41,7 @@ static const struct utf8_table utf8_tabl
32485 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
32486 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
32487 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
32488 - {0, /* end of table */}
32489 + {0, 0, 0, 0, 0, /* end of table */}
32490 };
32491
32492 #define UNICODE_MAX 0x0010ffff
32493 diff -urNp linux-2.6.36/fs/ntfs/dir.c linux-2.6.36/fs/ntfs/dir.c
32494 --- linux-2.6.36/fs/ntfs/dir.c 2010-10-20 16:30:22.000000000 -0400
32495 +++ linux-2.6.36/fs/ntfs/dir.c 2010-11-06 18:58:15.000000000 -0400
32496 @@ -1329,7 +1329,7 @@ find_next_index_buffer:
32497 ia = (INDEX_ALLOCATION*)(kaddr + (ia_pos & ~PAGE_CACHE_MASK &
32498 ~(s64)(ndir->itype.index.block_size - 1)));
32499 /* Bounds checks. */
32500 - if (unlikely((u8*)ia < kaddr || (u8*)ia > kaddr + PAGE_CACHE_SIZE)) {
32501 + if (unlikely(!kaddr || (u8*)ia < kaddr || (u8*)ia > kaddr + PAGE_CACHE_SIZE)) {
32502 ntfs_error(sb, "Out of bounds check failed. Corrupt directory "
32503 "inode 0x%lx or driver bug.", vdir->i_ino);
32504 goto err_out;
32505 diff -urNp linux-2.6.36/fs/ntfs/file.c linux-2.6.36/fs/ntfs/file.c
32506 --- linux-2.6.36/fs/ntfs/file.c 2010-10-20 16:30:22.000000000 -0400
32507 +++ linux-2.6.36/fs/ntfs/file.c 2010-11-06 18:58:15.000000000 -0400
32508 @@ -2223,6 +2223,6 @@ const struct inode_operations ntfs_file_
32509 #endif /* NTFS_RW */
32510 };
32511
32512 -const struct file_operations ntfs_empty_file_ops = {};
32513 +const struct file_operations ntfs_empty_file_ops __read_only;
32514
32515 -const struct inode_operations ntfs_empty_inode_ops = {};
32516 +const struct inode_operations ntfs_empty_inode_ops __read_only;
32517 diff -urNp linux-2.6.36/fs/ocfs2/localalloc.c linux-2.6.36/fs/ocfs2/localalloc.c
32518 --- linux-2.6.36/fs/ocfs2/localalloc.c 2010-10-20 16:30:22.000000000 -0400
32519 +++ linux-2.6.36/fs/ocfs2/localalloc.c 2010-11-06 18:58:15.000000000 -0400
32520 @@ -1307,7 +1307,7 @@ static int ocfs2_local_alloc_slide_windo
32521 goto bail;
32522 }
32523
32524 - atomic_inc(&osb->alloc_stats.moves);
32525 + atomic_inc_unchecked(&osb->alloc_stats.moves);
32526
32527 bail:
32528 if (handle)
32529 diff -urNp linux-2.6.36/fs/ocfs2/ocfs2.h linux-2.6.36/fs/ocfs2/ocfs2.h
32530 --- linux-2.6.36/fs/ocfs2/ocfs2.h 2010-10-20 16:30:22.000000000 -0400
32531 +++ linux-2.6.36/fs/ocfs2/ocfs2.h 2010-11-06 18:58:15.000000000 -0400
32532 @@ -223,11 +223,11 @@ enum ocfs2_vol_state
32533
32534 struct ocfs2_alloc_stats
32535 {
32536 - atomic_t moves;
32537 - atomic_t local_data;
32538 - atomic_t bitmap_data;
32539 - atomic_t bg_allocs;
32540 - atomic_t bg_extends;
32541 + atomic_unchecked_t moves;
32542 + atomic_unchecked_t local_data;
32543 + atomic_unchecked_t bitmap_data;
32544 + atomic_unchecked_t bg_allocs;
32545 + atomic_unchecked_t bg_extends;
32546 };
32547
32548 enum ocfs2_local_alloc_state
32549 diff -urNp linux-2.6.36/fs/ocfs2/suballoc.c linux-2.6.36/fs/ocfs2/suballoc.c
32550 --- linux-2.6.36/fs/ocfs2/suballoc.c 2010-10-20 16:30:22.000000000 -0400
32551 +++ linux-2.6.36/fs/ocfs2/suballoc.c 2010-11-06 18:58:15.000000000 -0400
32552 @@ -877,7 +877,7 @@ static int ocfs2_reserve_suballoc_bits(s
32553 mlog_errno(status);
32554 goto bail;
32555 }
32556 - atomic_inc(&osb->alloc_stats.bg_extends);
32557 + atomic_inc_unchecked(&osb->alloc_stats.bg_extends);
32558
32559 /* You should never ask for this much metadata */
32560 BUG_ON(bits_wanted >
32561 @@ -2004,7 +2004,7 @@ int ocfs2_claim_metadata(handle_t *handl
32562 mlog_errno(status);
32563 goto bail;
32564 }
32565 - atomic_inc(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
32566 + atomic_inc_unchecked(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
32567
32568 *suballoc_loc = res.sr_bg_blkno;
32569 *suballoc_bit_start = res.sr_bit_offset;
32570 @@ -2211,7 +2211,7 @@ int ocfs2_claim_new_inode(handle_t *hand
32571 mlog_errno(status);
32572 goto bail;
32573 }
32574 - atomic_inc(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
32575 + atomic_inc_unchecked(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
32576
32577 BUG_ON(res.sr_bits != 1);
32578
32579 @@ -2316,7 +2316,7 @@ int __ocfs2_claim_clusters(handle_t *han
32580 cluster_start,
32581 num_clusters);
32582 if (!status)
32583 - atomic_inc(&osb->alloc_stats.local_data);
32584 + atomic_inc_unchecked(&osb->alloc_stats.local_data);
32585 } else {
32586 if (min_clusters > (osb->bitmap_cpg - 1)) {
32587 /* The only paths asking for contiguousness
32588 @@ -2342,7 +2342,7 @@ int __ocfs2_claim_clusters(handle_t *han
32589 ocfs2_desc_bitmap_to_cluster_off(ac->ac_inode,
32590 res.sr_bg_blkno,
32591 res.sr_bit_offset);
32592 - atomic_inc(&osb->alloc_stats.bitmap_data);
32593 + atomic_inc_unchecked(&osb->alloc_stats.bitmap_data);
32594 *num_clusters = res.sr_bits;
32595 }
32596 }
32597 diff -urNp linux-2.6.36/fs/ocfs2/super.c linux-2.6.36/fs/ocfs2/super.c
32598 --- linux-2.6.36/fs/ocfs2/super.c 2010-10-20 16:30:22.000000000 -0400
32599 +++ linux-2.6.36/fs/ocfs2/super.c 2010-11-06 18:58:15.000000000 -0400
32600 @@ -292,11 +292,11 @@ static int ocfs2_osb_dump(struct ocfs2_s
32601 "%10s => GlobalAllocs: %d LocalAllocs: %d "
32602 "SubAllocs: %d LAWinMoves: %d SAExtends: %d\n",
32603 "Stats",
32604 - atomic_read(&osb->alloc_stats.bitmap_data),
32605 - atomic_read(&osb->alloc_stats.local_data),
32606 - atomic_read(&osb->alloc_stats.bg_allocs),
32607 - atomic_read(&osb->alloc_stats.moves),
32608 - atomic_read(&osb->alloc_stats.bg_extends));
32609 + atomic_read_unchecked(&osb->alloc_stats.bitmap_data),
32610 + atomic_read_unchecked(&osb->alloc_stats.local_data),
32611 + atomic_read_unchecked(&osb->alloc_stats.bg_allocs),
32612 + atomic_read_unchecked(&osb->alloc_stats.moves),
32613 + atomic_read_unchecked(&osb->alloc_stats.bg_extends));
32614
32615 out += snprintf(buf + out, len - out,
32616 "%10s => State: %u Descriptor: %llu Size: %u bits "
32617 @@ -2046,11 +2046,11 @@ static int ocfs2_initialize_super(struct
32618 spin_lock_init(&osb->osb_xattr_lock);
32619 ocfs2_init_steal_slots(osb);
32620
32621 - atomic_set(&osb->alloc_stats.moves, 0);
32622 - atomic_set(&osb->alloc_stats.local_data, 0);
32623 - atomic_set(&osb->alloc_stats.bitmap_data, 0);
32624 - atomic_set(&osb->alloc_stats.bg_allocs, 0);
32625 - atomic_set(&osb->alloc_stats.bg_extends, 0);
32626 + atomic_set_unchecked(&osb->alloc_stats.moves, 0);
32627 + atomic_set_unchecked(&osb->alloc_stats.local_data, 0);
32628 + atomic_set_unchecked(&osb->alloc_stats.bitmap_data, 0);
32629 + atomic_set_unchecked(&osb->alloc_stats.bg_allocs, 0);
32630 + atomic_set_unchecked(&osb->alloc_stats.bg_extends, 0);
32631
32632 /* Copy the blockcheck stats from the superblock probe */
32633 osb->osb_ecc_stats = *stats;
32634 diff -urNp linux-2.6.36/fs/ocfs2/symlink.c linux-2.6.36/fs/ocfs2/symlink.c
32635 --- linux-2.6.36/fs/ocfs2/symlink.c 2010-10-20 16:30:22.000000000 -0400
32636 +++ linux-2.6.36/fs/ocfs2/symlink.c 2010-11-06 18:58:15.000000000 -0400
32637 @@ -148,7 +148,7 @@ bail:
32638
32639 static void ocfs2_fast_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
32640 {
32641 - char *link = nd_get_link(nd);
32642 + const char *link = nd_get_link(nd);
32643 if (!IS_ERR(link))
32644 kfree(link);
32645 }
32646 diff -urNp linux-2.6.36/fs/open.c linux-2.6.36/fs/open.c
32647 --- linux-2.6.36/fs/open.c 2010-10-20 16:30:22.000000000 -0400
32648 +++ linux-2.6.36/fs/open.c 2010-11-06 20:36:14.000000000 -0400
32649 @@ -43,6 +43,9 @@ int do_truncate(struct dentry *dentry, l
32650 if (length < 0)
32651 return -EINVAL;
32652
32653 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
32654 + return -EACCES;
32655 +
32656 newattrs.ia_size = length;
32657 newattrs.ia_valid = ATTR_SIZE | time_attrs;
32658 if (filp) {
32659 @@ -345,6 +348,9 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con
32660 if (__mnt_is_readonly(path.mnt))
32661 res = -EROFS;
32662
32663 + if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
32664 + res = -EACCES;
32665 +
32666 out_path_release:
32667 path_put(&path);
32668 out:
32669 @@ -371,6 +377,8 @@ SYSCALL_DEFINE1(chdir, const char __user
32670 if (error)
32671 goto dput_and_out;
32672
32673 + gr_log_chdir(path.dentry, path.mnt);
32674 +
32675 set_fs_pwd(current->fs, &path);
32676
32677 dput_and_out:
32678 @@ -397,6 +405,13 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd
32679 goto out_putf;
32680
32681 error = inode_permission(inode, MAY_EXEC | MAY_CHDIR);
32682 +
32683 + if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
32684 + error = -EPERM;
32685 +
32686 + if (!error)
32687 + gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
32688 +
32689 if (!error)
32690 set_fs_pwd(current->fs, &file->f_path);
32691 out_putf:
32692 @@ -425,7 +440,18 @@ SYSCALL_DEFINE1(chroot, const char __use
32693 if (error)
32694 goto dput_and_out;
32695
32696 + if (gr_handle_chroot_chroot(path.dentry, path.mnt))
32697 + goto dput_and_out;
32698 +
32699 + if (gr_handle_chroot_caps(&path)) {
32700 + error = -ENOMEM;
32701 + goto dput_and_out;
32702 + }
32703 +
32704 set_fs_root(current->fs, &path);
32705 +
32706 + gr_handle_chroot_chdir(&path);
32707 +
32708 error = 0;
32709 dput_and_out:
32710 path_put(&path);
32711 @@ -453,12 +479,25 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd
32712 err = mnt_want_write_file(file);
32713 if (err)
32714 goto out_putf;
32715 +
32716 mutex_lock(&inode->i_mutex);
32717 +
32718 + if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
32719 + err = -EACCES;
32720 + goto out_unlock;
32721 + }
32722 +
32723 err = security_path_chmod(dentry, file->f_vfsmnt, mode);
32724 if (err)
32725 goto out_unlock;
32726 if (mode == (mode_t) -1)
32727 mode = inode->i_mode;
32728 +
32729 + if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
32730 + err = -EACCES;
32731 + goto out_unlock;
32732 + }
32733 +
32734 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
32735 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
32736 err = notify_change(dentry, &newattrs);
32737 @@ -486,12 +525,25 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
32738 error = mnt_want_write(path.mnt);
32739 if (error)
32740 goto dput_and_out;
32741 +
32742 mutex_lock(&inode->i_mutex);
32743 +
32744 + if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
32745 + error = -EACCES;
32746 + goto out_unlock;
32747 + }
32748 +
32749 error = security_path_chmod(path.dentry, path.mnt, mode);
32750 if (error)
32751 goto out_unlock;
32752 if (mode == (mode_t) -1)
32753 mode = inode->i_mode;
32754 +
32755 + if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
32756 + error = -EACCES;
32757 + goto out_unlock;
32758 + }
32759 +
32760 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
32761 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
32762 error = notify_change(path.dentry, &newattrs);
32763 @@ -515,6 +567,9 @@ static int chown_common(struct path *pat
32764 int error;
32765 struct iattr newattrs;
32766
32767 + if (!gr_acl_handle_chown(path->dentry, path->mnt))
32768 + return -EACCES;
32769 +
32770 newattrs.ia_valid = ATTR_CTIME;
32771 if (user != (uid_t) -1) {
32772 newattrs.ia_valid |= ATTR_UID;
32773 diff -urNp linux-2.6.36/fs/pipe.c linux-2.6.36/fs/pipe.c
32774 --- linux-2.6.36/fs/pipe.c 2010-10-20 16:30:22.000000000 -0400
32775 +++ linux-2.6.36/fs/pipe.c 2010-11-06 18:58:50.000000000 -0400
32776 @@ -382,7 +382,7 @@ pipe_read(struct kiocb *iocb, const stru
32777 error = ops->confirm(pipe, buf);
32778 if (error) {
32779 if (!ret)
32780 - error = ret;
32781 + ret = error;
32782 break;
32783 }
32784
32785 @@ -420,9 +420,9 @@ redo:
32786 }
32787 if (bufs) /* More to do? */
32788 continue;
32789 - if (!pipe->writers)
32790 + if (!atomic_read(&pipe->writers))
32791 break;
32792 - if (!pipe->waiting_writers) {
32793 + if (!atomic_read(&pipe->waiting_writers)) {
32794 /* syscall merging: Usually we must not sleep
32795 * if O_NONBLOCK is set, or if we got some data.
32796 * But if a writer sleeps in kernel space, then
32797 @@ -481,7 +481,7 @@ pipe_write(struct kiocb *iocb, const str
32798 mutex_lock(&inode->i_mutex);
32799 pipe = inode->i_pipe;
32800
32801 - if (!pipe->readers) {
32802 + if (!atomic_read(&pipe->readers)) {
32803 send_sig(SIGPIPE, current, 0);
32804 ret = -EPIPE;
32805 goto out;
32806 @@ -530,7 +530,7 @@ redo1:
32807 for (;;) {
32808 int bufs;
32809
32810 - if (!pipe->readers) {
32811 + if (!atomic_read(&pipe->readers)) {
32812 send_sig(SIGPIPE, current, 0);
32813 if (!ret)
32814 ret = -EPIPE;
32815 @@ -616,9 +616,9 @@ redo2:
32816 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
32817 do_wakeup = 0;
32818 }
32819 - pipe->waiting_writers++;
32820 + atomic_inc(&pipe->waiting_writers);
32821 pipe_wait(pipe);
32822 - pipe->waiting_writers--;
32823 + atomic_dec(&pipe->waiting_writers);
32824 }
32825 out:
32826 mutex_unlock(&inode->i_mutex);
32827 @@ -685,7 +685,7 @@ pipe_poll(struct file *filp, poll_table
32828 mask = 0;
32829 if (filp->f_mode & FMODE_READ) {
32830 mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
32831 - if (!pipe->writers && filp->f_version != pipe->w_counter)
32832 + if (!atomic_read(&pipe->writers) && filp->f_version != pipe->w_counter)
32833 mask |= POLLHUP;
32834 }
32835
32836 @@ -695,7 +695,7 @@ pipe_poll(struct file *filp, poll_table
32837 * Most Unices do not set POLLERR for FIFOs but on Linux they
32838 * behave exactly like pipes for poll().
32839 */
32840 - if (!pipe->readers)
32841 + if (!atomic_read(&pipe->readers))
32842 mask |= POLLERR;
32843 }
32844
32845 @@ -709,10 +709,10 @@ pipe_release(struct inode *inode, int de
32846
32847 mutex_lock(&inode->i_mutex);
32848 pipe = inode->i_pipe;
32849 - pipe->readers -= decr;
32850 - pipe->writers -= decw;
32851 + atomic_sub(decr, &pipe->readers);
32852 + atomic_sub(decw, &pipe->writers);
32853
32854 - if (!pipe->readers && !pipe->writers) {
32855 + if (!atomic_read(&pipe->readers) && !atomic_read(&pipe->writers)) {
32856 free_pipe_info(inode);
32857 } else {
32858 wake_up_interruptible_sync(&pipe->wait);
32859 @@ -802,7 +802,7 @@ pipe_read_open(struct inode *inode, stru
32860
32861 if (inode->i_pipe) {
32862 ret = 0;
32863 - inode->i_pipe->readers++;
32864 + atomic_inc(&inode->i_pipe->readers);
32865 }
32866
32867 mutex_unlock(&inode->i_mutex);
32868 @@ -819,7 +819,7 @@ pipe_write_open(struct inode *inode, str
32869
32870 if (inode->i_pipe) {
32871 ret = 0;
32872 - inode->i_pipe->writers++;
32873 + atomic_inc(&inode->i_pipe->writers);
32874 }
32875
32876 mutex_unlock(&inode->i_mutex);
32877 @@ -837,9 +837,9 @@ pipe_rdwr_open(struct inode *inode, stru
32878 if (inode->i_pipe) {
32879 ret = 0;
32880 if (filp->f_mode & FMODE_READ)
32881 - inode->i_pipe->readers++;
32882 + atomic_inc(&inode->i_pipe->readers);
32883 if (filp->f_mode & FMODE_WRITE)
32884 - inode->i_pipe->writers++;
32885 + atomic_inc(&inode->i_pipe->writers);
32886 }
32887
32888 mutex_unlock(&inode->i_mutex);
32889 @@ -931,7 +931,7 @@ void free_pipe_info(struct inode *inode)
32890 inode->i_pipe = NULL;
32891 }
32892
32893 -static struct vfsmount *pipe_mnt __read_mostly;
32894 +struct vfsmount *pipe_mnt __read_mostly;
32895
32896 /*
32897 * pipefs_dname() is called from d_path().
32898 @@ -959,7 +959,8 @@ static struct inode * get_pipe_inode(voi
32899 goto fail_iput;
32900 inode->i_pipe = pipe;
32901
32902 - pipe->readers = pipe->writers = 1;
32903 + atomic_set(&pipe->readers, 1);
32904 + atomic_set(&pipe->writers, 1);
32905 inode->i_fop = &rdwr_pipefifo_fops;
32906
32907 /*
32908 diff -urNp linux-2.6.36/fs/proc/array.c linux-2.6.36/fs/proc/array.c
32909 --- linux-2.6.36/fs/proc/array.c 2010-10-20 16:30:22.000000000 -0400
32910 +++ linux-2.6.36/fs/proc/array.c 2010-11-06 18:58:50.000000000 -0400
32911 @@ -60,6 +60,7 @@
32912 #include <linux/tty.h>
32913 #include <linux/string.h>
32914 #include <linux/mman.h>
32915 +#include <linux/grsecurity.h>
32916 #include <linux/proc_fs.h>
32917 #include <linux/ioport.h>
32918 #include <linux/uaccess.h>
32919 @@ -337,6 +338,21 @@ static void task_cpus_allowed(struct seq
32920 seq_printf(m, "\n");
32921 }
32922
32923 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
32924 +static inline void task_pax(struct seq_file *m, struct task_struct *p)
32925 +{
32926 + if (p->mm)
32927 + seq_printf(m, "PaX:\t%c%c%c%c%c\n",
32928 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
32929 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
32930 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
32931 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
32932 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
32933 + else
32934 + seq_printf(m, "PaX:\t-----\n");
32935 +}
32936 +#endif
32937 +
32938 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
32939 struct pid *pid, struct task_struct *task)
32940 {
32941 @@ -357,9 +373,24 @@ int proc_pid_status(struct seq_file *m,
32942 task_show_regs(m, task);
32943 #endif
32944 task_context_switch_counts(m, task);
32945 +
32946 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
32947 + task_pax(m, task);
32948 +#endif
32949 +
32950 +#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
32951 + task_grsec_rbac(m, task);
32952 +#endif
32953 +
32954 return 0;
32955 }
32956
32957 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
32958 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
32959 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
32960 + _mm->pax_flags & MF_PAX_SEGMEXEC))
32961 +#endif
32962 +
32963 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
32964 struct pid *pid, struct task_struct *task, int whole)
32965 {
32966 @@ -452,6 +483,19 @@ static int do_task_stat(struct seq_file
32967 gtime = task->gtime;
32968 }
32969
32970 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
32971 + if (PAX_RAND_FLAGS(mm)) {
32972 + eip = 0;
32973 + esp = 0;
32974 + wchan = 0;
32975 + }
32976 +#endif
32977 +#ifdef CONFIG_GRKERNSEC_HIDESYM
32978 + wchan = 0;
32979 + eip =0;
32980 + esp =0;
32981 +#endif
32982 +
32983 /* scale priority and nice values from timeslices to -20..20 */
32984 /* to make it look like a "normal" Unix priority/nice value */
32985 priority = task_prio(task);
32986 @@ -492,9 +536,15 @@ static int do_task_stat(struct seq_file
32987 vsize,
32988 mm ? get_mm_rss(mm) : 0,
32989 rsslim,
32990 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
32991 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
32992 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
32993 + PAX_RAND_FLAGS(mm) ? 0 : ((permitted && mm) ? mm->start_stack : 0),
32994 +#else
32995 mm ? mm->start_code : 0,
32996 mm ? mm->end_code : 0,
32997 (permitted && mm) ? mm->start_stack : 0,
32998 +#endif
32999 esp,
33000 eip,
33001 /* The signal information here is obsolete.
33002 @@ -547,3 +597,10 @@ int proc_pid_statm(struct seq_file *m, s
33003
33004 return 0;
33005 }
33006 +
33007 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
33008 +int proc_pid_ipaddr(struct task_struct *task, char *buffer)
33009 +{
33010 + return sprintf(buffer, "%pI4\n", &task->signal->curr_ip);
33011 +}
33012 +#endif
33013 diff -urNp linux-2.6.36/fs/proc/base.c linux-2.6.36/fs/proc/base.c
33014 --- linux-2.6.36/fs/proc/base.c 2010-10-20 16:30:22.000000000 -0400
33015 +++ linux-2.6.36/fs/proc/base.c 2010-11-06 18:58:50.000000000 -0400
33016 @@ -104,6 +104,22 @@ struct pid_entry {
33017 union proc_op op;
33018 };
33019
33020 +struct getdents_callback {
33021 + struct linux_dirent __user * current_dir;
33022 + struct linux_dirent __user * previous;
33023 + struct file * file;
33024 + int count;
33025 + int error;
33026 +};
33027 +
33028 +static int gr_fake_filldir(void * __buf, const char *name, int namlen,
33029 + loff_t offset, u64 ino, unsigned int d_type)
33030 +{
33031 + struct getdents_callback * buf = (struct getdents_callback *) __buf;
33032 + buf->error = -EINVAL;
33033 + return 0;
33034 +}
33035 +
33036 #define NOD(NAME, MODE, IOP, FOP, OP) { \
33037 .name = (NAME), \
33038 .len = sizeof(NAME) - 1, \
33039 @@ -203,6 +219,9 @@ static int check_mem_permission(struct t
33040 if (task == current)
33041 return 0;
33042
33043 + if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
33044 + return -EPERM;
33045 +
33046 /*
33047 * If current is actively ptrace'ing, and would also be
33048 * permitted to freshly attach with ptrace now, permit it.
33049 @@ -250,6 +269,9 @@ static int proc_pid_cmdline(struct task_
33050 if (!mm->arg_end)
33051 goto out_mm; /* Shh! No looking before we're done */
33052
33053 + if (gr_acl_handle_procpidmem(task))
33054 + goto out_mm;
33055 +
33056 len = mm->arg_end - mm->arg_start;
33057
33058 if (len > PAGE_SIZE)
33059 @@ -277,12 +299,28 @@ out:
33060 return res;
33061 }
33062
33063 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33064 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
33065 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
33066 + _mm->pax_flags & MF_PAX_SEGMEXEC))
33067 +#endif
33068 +
33069 static int proc_pid_auxv(struct task_struct *task, char *buffer)
33070 {
33071 int res = 0;
33072 struct mm_struct *mm = get_task_mm(task);
33073 if (mm) {
33074 unsigned int nwords = 0;
33075 +
33076 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33077 + /* allow if we're currently ptracing this task */
33078 + if (PAX_RAND_FLAGS(mm) &&
33079 + (!(task->ptrace & PT_PTRACED) || (task->parent != current))) {
33080 + mmput(mm);
33081 + return res;
33082 + }
33083 +#endif
33084 +
33085 do {
33086 nwords += 2;
33087 } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
33088 @@ -296,7 +334,7 @@ static int proc_pid_auxv(struct task_str
33089 }
33090
33091
33092 -#ifdef CONFIG_KALLSYMS
33093 +#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33094 /*
33095 * Provides a wchan file via kallsyms in a proper one-value-per-file format.
33096 * Returns the resolved symbol. If that fails, simply return the address.
33097 @@ -318,7 +356,7 @@ static int proc_pid_wchan(struct task_st
33098 }
33099 #endif /* CONFIG_KALLSYMS */
33100
33101 -#ifdef CONFIG_STACKTRACE
33102 +#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33103
33104 #define MAX_STACK_TRACE_DEPTH 64
33105
33106 @@ -509,7 +547,7 @@ static int proc_pid_limits(struct task_s
33107 return count;
33108 }
33109
33110 -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
33111 +#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
33112 static int proc_pid_syscall(struct task_struct *task, char *buffer)
33113 {
33114 long nr;
33115 @@ -928,6 +966,9 @@ static ssize_t environ_read(struct file
33116 if (!task)
33117 goto out_no_task;
33118
33119 + if (gr_acl_handle_procpidmem(task))
33120 + goto out;
33121 +
33122 if (!ptrace_may_access(task, PTRACE_MODE_READ))
33123 goto out;
33124
33125 @@ -1614,7 +1655,11 @@ static struct inode *proc_pid_make_inode
33126 rcu_read_lock();
33127 cred = __task_cred(task);
33128 inode->i_uid = cred->euid;
33129 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33130 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
33131 +#else
33132 inode->i_gid = cred->egid;
33133 +#endif
33134 rcu_read_unlock();
33135 }
33136 security_task_to_inode(task, inode);
33137 @@ -1632,6 +1677,9 @@ static int pid_getattr(struct vfsmount *
33138 struct inode *inode = dentry->d_inode;
33139 struct task_struct *task;
33140 const struct cred *cred;
33141 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33142 + const struct cred *tmpcred = current_cred();
33143 +#endif
33144
33145 generic_fillattr(inode, stat);
33146
33147 @@ -1639,12 +1687,34 @@ static int pid_getattr(struct vfsmount *
33148 stat->uid = 0;
33149 stat->gid = 0;
33150 task = pid_task(proc_pid(inode), PIDTYPE_PID);
33151 +
33152 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
33153 + rcu_read_unlock();
33154 + return -ENOENT;
33155 + }
33156 +
33157 if (task) {
33158 + cred = __task_cred(task);
33159 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33160 + if (!tmpcred->uid || (tmpcred->uid == cred->uid)
33161 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33162 + || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
33163 +#endif
33164 + )
33165 +#endif
33166 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
33167 +#ifdef CONFIG_GRKERNSEC_PROC_USER
33168 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
33169 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33170 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
33171 +#endif
33172 task_dumpable(task)) {
33173 - cred = __task_cred(task);
33174 stat->uid = cred->euid;
33175 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33176 + stat->gid = CONFIG_GRKERNSEC_PROC_GID;
33177 +#else
33178 stat->gid = cred->egid;
33179 +#endif
33180 }
33181 }
33182 rcu_read_unlock();
33183 @@ -1676,11 +1746,20 @@ static int pid_revalidate(struct dentry
33184
33185 if (task) {
33186 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
33187 +#ifdef CONFIG_GRKERNSEC_PROC_USER
33188 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
33189 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33190 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
33191 +#endif
33192 task_dumpable(task)) {
33193 rcu_read_lock();
33194 cred = __task_cred(task);
33195 inode->i_uid = cred->euid;
33196 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33197 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
33198 +#else
33199 inode->i_gid = cred->egid;
33200 +#endif
33201 rcu_read_unlock();
33202 } else {
33203 inode->i_uid = 0;
33204 @@ -1801,7 +1880,8 @@ static int proc_fd_info(struct inode *in
33205 int fd = proc_fd(inode);
33206
33207 if (task) {
33208 - files = get_files_struct(task);
33209 + if (!gr_acl_handle_procpidmem(task))
33210 + files = get_files_struct(task);
33211 put_task_struct(task);
33212 }
33213 if (files) {
33214 @@ -2053,12 +2133,22 @@ static const struct file_operations proc
33215 static int proc_fd_permission(struct inode *inode, int mask)
33216 {
33217 int rv;
33218 + struct task_struct *task;
33219
33220 rv = generic_permission(inode, mask, NULL);
33221 - if (rv == 0)
33222 - return 0;
33223 +
33224 if (task_pid(current) == proc_pid(inode))
33225 rv = 0;
33226 +
33227 + task = get_proc_task(inode);
33228 + if (task == NULL)
33229 + return rv;
33230 +
33231 + if (gr_acl_handle_procpidmem(task))
33232 + rv = -EACCES;
33233 +
33234 + put_task_struct(task);
33235 +
33236 return rv;
33237 }
33238
33239 @@ -2167,6 +2257,9 @@ static struct dentry *proc_pident_lookup
33240 if (!task)
33241 goto out_no_task;
33242
33243 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
33244 + goto out;
33245 +
33246 /*
33247 * Yes, it does not scale. And it should not. Don't add
33248 * new entries into /proc/<tgid>/ without very good reasons.
33249 @@ -2211,6 +2304,9 @@ static int proc_pident_readdir(struct fi
33250 if (!task)
33251 goto out_no_task;
33252
33253 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
33254 + goto out;
33255 +
33256 ret = 0;
33257 i = filp->f_pos;
33258 switch (i) {
33259 @@ -2480,7 +2576,7 @@ static void *proc_self_follow_link(struc
33260 static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
33261 void *cookie)
33262 {
33263 - char *s = nd_get_link(nd);
33264 + const char *s = nd_get_link(nd);
33265 if (!IS_ERR(s))
33266 __putname(s);
33267 }
33268 @@ -2680,7 +2776,7 @@ static const struct pid_entry tgid_base_
33269 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
33270 #endif
33271 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
33272 -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
33273 +#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
33274 INF("syscall", S_IRUSR, proc_pid_syscall),
33275 #endif
33276 INF("cmdline", S_IRUGO, proc_pid_cmdline),
33277 @@ -2705,10 +2801,10 @@ static const struct pid_entry tgid_base_
33278 #ifdef CONFIG_SECURITY
33279 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
33280 #endif
33281 -#ifdef CONFIG_KALLSYMS
33282 +#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33283 INF("wchan", S_IRUGO, proc_pid_wchan),
33284 #endif
33285 -#ifdef CONFIG_STACKTRACE
33286 +#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33287 ONE("stack", S_IRUSR, proc_pid_stack),
33288 #endif
33289 #ifdef CONFIG_SCHEDSTATS
33290 @@ -2739,6 +2835,9 @@ static const struct pid_entry tgid_base_
33291 #ifdef CONFIG_TASK_IO_ACCOUNTING
33292 INF("io", S_IRUGO, proc_tgid_io_accounting),
33293 #endif
33294 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
33295 + INF("ipaddr", S_IRUSR, proc_pid_ipaddr),
33296 +#endif
33297 };
33298
33299 static int proc_tgid_base_readdir(struct file * filp,
33300 @@ -2863,7 +2962,14 @@ static struct dentry *proc_pid_instantia
33301 if (!inode)
33302 goto out;
33303
33304 +#ifdef CONFIG_GRKERNSEC_PROC_USER
33305 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
33306 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33307 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
33308 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
33309 +#else
33310 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
33311 +#endif
33312 inode->i_op = &proc_tgid_base_inode_operations;
33313 inode->i_fop = &proc_tgid_base_operations;
33314 inode->i_flags|=S_IMMUTABLE;
33315 @@ -2905,7 +3011,11 @@ struct dentry *proc_pid_lookup(struct in
33316 if (!task)
33317 goto out;
33318
33319 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
33320 + goto out_put_task;
33321 +
33322 result = proc_pid_instantiate(dir, dentry, task, NULL);
33323 +out_put_task:
33324 put_task_struct(task);
33325 out:
33326 return result;
33327 @@ -2970,6 +3080,11 @@ int proc_pid_readdir(struct file * filp,
33328 {
33329 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
33330 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
33331 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33332 + const struct cred *tmpcred = current_cred();
33333 + const struct cred *itercred;
33334 +#endif
33335 + filldir_t __filldir = filldir;
33336 struct tgid_iter iter;
33337 struct pid_namespace *ns;
33338
33339 @@ -2988,8 +3103,27 @@ int proc_pid_readdir(struct file * filp,
33340 for (iter = next_tgid(ns, iter);
33341 iter.task;
33342 iter.tgid += 1, iter = next_tgid(ns, iter)) {
33343 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33344 + rcu_read_lock();
33345 + itercred = __task_cred(iter.task);
33346 +#endif
33347 + if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
33348 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33349 + || (tmpcred->uid && (itercred->uid != tmpcred->uid)
33350 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33351 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
33352 +#endif
33353 + )
33354 +#endif
33355 + )
33356 + __filldir = &gr_fake_filldir;
33357 + else
33358 + __filldir = filldir;
33359 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33360 + rcu_read_unlock();
33361 +#endif
33362 filp->f_pos = iter.tgid + TGID_OFFSET;
33363 - if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
33364 + if (proc_pid_fill_cache(filp, dirent, __filldir, iter) < 0) {
33365 put_task_struct(iter.task);
33366 goto out;
33367 }
33368 @@ -3016,7 +3150,7 @@ static const struct pid_entry tid_base_s
33369 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
33370 #endif
33371 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
33372 -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
33373 +#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
33374 INF("syscall", S_IRUSR, proc_pid_syscall),
33375 #endif
33376 INF("cmdline", S_IRUGO, proc_pid_cmdline),
33377 @@ -3040,10 +3174,10 @@ static const struct pid_entry tid_base_s
33378 #ifdef CONFIG_SECURITY
33379 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
33380 #endif
33381 -#ifdef CONFIG_KALLSYMS
33382 +#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33383 INF("wchan", S_IRUGO, proc_pid_wchan),
33384 #endif
33385 -#ifdef CONFIG_STACKTRACE
33386 +#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
33387 ONE("stack", S_IRUSR, proc_pid_stack),
33388 #endif
33389 #ifdef CONFIG_SCHEDSTATS
33390 diff -urNp linux-2.6.36/fs/proc/cmdline.c linux-2.6.36/fs/proc/cmdline.c
33391 --- linux-2.6.36/fs/proc/cmdline.c 2010-10-20 16:30:22.000000000 -0400
33392 +++ linux-2.6.36/fs/proc/cmdline.c 2010-11-06 18:58:50.000000000 -0400
33393 @@ -23,7 +23,11 @@ static const struct file_operations cmdl
33394
33395 static int __init proc_cmdline_init(void)
33396 {
33397 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
33398 + proc_create_grsec("cmdline", 0, NULL, &cmdline_proc_fops);
33399 +#else
33400 proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
33401 +#endif
33402 return 0;
33403 }
33404 module_init(proc_cmdline_init);
33405 diff -urNp linux-2.6.36/fs/proc/devices.c linux-2.6.36/fs/proc/devices.c
33406 --- linux-2.6.36/fs/proc/devices.c 2010-10-20 16:30:22.000000000 -0400
33407 +++ linux-2.6.36/fs/proc/devices.c 2010-11-06 18:58:50.000000000 -0400
33408 @@ -64,7 +64,11 @@ static const struct file_operations proc
33409
33410 static int __init proc_devices_init(void)
33411 {
33412 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
33413 + proc_create_grsec("devices", 0, NULL, &proc_devinfo_operations);
33414 +#else
33415 proc_create("devices", 0, NULL, &proc_devinfo_operations);
33416 +#endif
33417 return 0;
33418 }
33419 module_init(proc_devices_init);
33420 diff -urNp linux-2.6.36/fs/proc/inode.c linux-2.6.36/fs/proc/inode.c
33421 --- linux-2.6.36/fs/proc/inode.c 2010-10-20 16:30:22.000000000 -0400
33422 +++ linux-2.6.36/fs/proc/inode.c 2010-11-06 18:58:50.000000000 -0400
33423 @@ -426,7 +426,11 @@ struct inode *proc_get_inode(struct supe
33424 if (de->mode) {
33425 inode->i_mode = de->mode;
33426 inode->i_uid = de->uid;
33427 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
33428 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
33429 +#else
33430 inode->i_gid = de->gid;
33431 +#endif
33432 }
33433 if (de->size)
33434 inode->i_size = de->size;
33435 diff -urNp linux-2.6.36/fs/proc/internal.h linux-2.6.36/fs/proc/internal.h
33436 --- linux-2.6.36/fs/proc/internal.h 2010-10-20 16:30:22.000000000 -0400
33437 +++ linux-2.6.36/fs/proc/internal.h 2010-11-06 18:58:50.000000000 -0400
33438 @@ -51,6 +51,9 @@ extern int proc_pid_status(struct seq_fi
33439 struct pid *pid, struct task_struct *task);
33440 extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
33441 struct pid *pid, struct task_struct *task);
33442 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
33443 +extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
33444 +#endif
33445 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
33446
33447 extern const struct file_operations proc_maps_operations;
33448 diff -urNp linux-2.6.36/fs/proc/Kconfig linux-2.6.36/fs/proc/Kconfig
33449 --- linux-2.6.36/fs/proc/Kconfig 2010-10-20 16:30:22.000000000 -0400
33450 +++ linux-2.6.36/fs/proc/Kconfig 2010-11-06 18:58:50.000000000 -0400
33451 @@ -30,12 +30,12 @@ config PROC_FS
33452
33453 config PROC_KCORE
33454 bool "/proc/kcore support" if !ARM
33455 - depends on PROC_FS && MMU
33456 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
33457
33458 config PROC_VMCORE
33459 bool "/proc/vmcore support (EXPERIMENTAL)"
33460 - depends on PROC_FS && CRASH_DUMP
33461 - default y
33462 + depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
33463 + default n
33464 help
33465 Exports the dump image of crashed kernel in ELF format.
33466
33467 @@ -59,8 +59,8 @@ config PROC_SYSCTL
33468 limited in memory.
33469
33470 config PROC_PAGE_MONITOR
33471 - default y
33472 - depends on PROC_FS && MMU
33473 + default n
33474 + depends on PROC_FS && MMU && !GRKERNSEC
33475 bool "Enable /proc page monitoring" if EMBEDDED
33476 help
33477 Various /proc files exist to monitor process memory utilization:
33478 diff -urNp linux-2.6.36/fs/proc/kcore.c linux-2.6.36/fs/proc/kcore.c
33479 --- linux-2.6.36/fs/proc/kcore.c 2010-10-20 16:30:22.000000000 -0400
33480 +++ linux-2.6.36/fs/proc/kcore.c 2010-11-06 18:58:50.000000000 -0400
33481 @@ -478,9 +478,10 @@ read_kcore(struct file *file, char __use
33482 * the addresses in the elf_phdr on our list.
33483 */
33484 start = kc_offset_to_vaddr(*fpos - elf_buflen);
33485 - if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
33486 + tsz = PAGE_SIZE - (start & ~PAGE_MASK);
33487 + if (tsz > buflen)
33488 tsz = buflen;
33489 -
33490 +
33491 while (buflen) {
33492 struct kcore_list *m;
33493
33494 @@ -509,20 +510,18 @@ read_kcore(struct file *file, char __use
33495 kfree(elf_buf);
33496 } else {
33497 if (kern_addr_valid(start)) {
33498 - unsigned long n;
33499 + char *elf_buf;
33500
33501 - n = copy_to_user(buffer, (char *)start, tsz);
33502 - /*
33503 - * We cannot distingush between fault on source
33504 - * and fault on destination. When this happens
33505 - * we clear too and hope it will trigger the
33506 - * EFAULT again.
33507 - */
33508 - if (n) {
33509 - if (clear_user(buffer + tsz - n,
33510 - n))
33511 + elf_buf = kmalloc(tsz, GFP_KERNEL);
33512 + if (!elf_buf)
33513 + return -ENOMEM;
33514 + if (!__copy_from_user(elf_buf, (const void __user *)start, tsz)) {
33515 + if (copy_to_user(buffer, elf_buf, tsz)) {
33516 + kfree(elf_buf);
33517 return -EFAULT;
33518 + }
33519 }
33520 + kfree(elf_buf);
33521 } else {
33522 if (clear_user(buffer, tsz))
33523 return -EFAULT;
33524 @@ -542,6 +541,9 @@ read_kcore(struct file *file, char __use
33525
33526 static int open_kcore(struct inode *inode, struct file *filp)
33527 {
33528 +#if defined(CONFIG_GRKERNSEC_PROC_ADD) || defined(CONFIG_GRKERNSEC_HIDESYM)
33529 + return -EPERM;
33530 +#endif
33531 if (!capable(CAP_SYS_RAWIO))
33532 return -EPERM;
33533 if (kcore_need_update)
33534 diff -urNp linux-2.6.36/fs/proc/meminfo.c linux-2.6.36/fs/proc/meminfo.c
33535 --- linux-2.6.36/fs/proc/meminfo.c 2010-10-20 16:30:22.000000000 -0400
33536 +++ linux-2.6.36/fs/proc/meminfo.c 2010-11-06 18:58:15.000000000 -0400
33537 @@ -149,7 +149,7 @@ static int meminfo_proc_show(struct seq_
33538 vmi.used >> 10,
33539 vmi.largest_chunk >> 10
33540 #ifdef CONFIG_MEMORY_FAILURE
33541 - ,atomic_long_read(&mce_bad_pages) << (PAGE_SHIFT - 10)
33542 + ,atomic_long_read_unchecked(&mce_bad_pages) << (PAGE_SHIFT - 10)
33543 #endif
33544 );
33545
33546 diff -urNp linux-2.6.36/fs/proc/nommu.c linux-2.6.36/fs/proc/nommu.c
33547 --- linux-2.6.36/fs/proc/nommu.c 2010-10-20 16:30:22.000000000 -0400
33548 +++ linux-2.6.36/fs/proc/nommu.c 2010-11-06 18:58:15.000000000 -0400
33549 @@ -66,7 +66,7 @@ static int nommu_region_show(struct seq_
33550 if (len < 1)
33551 len = 1;
33552 seq_printf(m, "%*c", len, ' ');
33553 - seq_path(m, &file->f_path, "");
33554 + seq_path(m, &file->f_path, "\n\\");
33555 }
33556
33557 seq_putc(m, '\n');
33558 diff -urNp linux-2.6.36/fs/proc/proc_net.c linux-2.6.36/fs/proc/proc_net.c
33559 --- linux-2.6.36/fs/proc/proc_net.c 2010-10-20 16:30:22.000000000 -0400
33560 +++ linux-2.6.36/fs/proc/proc_net.c 2010-11-06 18:58:50.000000000 -0400
33561 @@ -105,6 +105,17 @@ static struct net *get_proc_task_net(str
33562 struct task_struct *task;
33563 struct nsproxy *ns;
33564 struct net *net = NULL;
33565 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33566 + const struct cred *cred = current_cred();
33567 +#endif
33568 +
33569 +#ifdef CONFIG_GRKERNSEC_PROC_USER
33570 + if (cred->fsuid)
33571 + return net;
33572 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33573 + if (cred->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
33574 + return net;
33575 +#endif
33576
33577 rcu_read_lock();
33578 task = pid_task(proc_pid(dir), PIDTYPE_PID);
33579 diff -urNp linux-2.6.36/fs/proc/proc_sysctl.c linux-2.6.36/fs/proc/proc_sysctl.c
33580 --- linux-2.6.36/fs/proc/proc_sysctl.c 2010-10-20 16:30:22.000000000 -0400
33581 +++ linux-2.6.36/fs/proc/proc_sysctl.c 2010-11-06 18:58:50.000000000 -0400
33582 @@ -7,6 +7,8 @@
33583 #include <linux/security.h>
33584 #include "internal.h"
33585
33586 +extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
33587 +
33588 static const struct dentry_operations proc_sys_dentry_operations;
33589 static const struct file_operations proc_sys_file_operations;
33590 static const struct inode_operations proc_sys_inode_operations;
33591 @@ -109,6 +111,9 @@ static struct dentry *proc_sys_lookup(st
33592 if (!p)
33593 goto out;
33594
33595 + if (gr_handle_sysctl(p, MAY_EXEC))
33596 + goto out;
33597 +
33598 err = ERR_PTR(-ENOMEM);
33599 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
33600 if (h)
33601 @@ -228,6 +233,9 @@ static int scan(struct ctl_table_header
33602 if (*pos < file->f_pos)
33603 continue;
33604
33605 + if (gr_handle_sysctl(table, 0))
33606 + continue;
33607 +
33608 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
33609 if (res)
33610 return res;
33611 @@ -353,6 +361,9 @@ static int proc_sys_getattr(struct vfsmo
33612 if (IS_ERR(head))
33613 return PTR_ERR(head);
33614
33615 + if (table && gr_handle_sysctl(table, MAY_EXEC))
33616 + return -ENOENT;
33617 +
33618 generic_fillattr(inode, stat);
33619 if (table)
33620 stat->mode = (stat->mode & S_IFMT) | table->mode;
33621 diff -urNp linux-2.6.36/fs/proc/root.c linux-2.6.36/fs/proc/root.c
33622 --- linux-2.6.36/fs/proc/root.c 2010-10-20 16:30:22.000000000 -0400
33623 +++ linux-2.6.36/fs/proc/root.c 2010-11-06 18:58:50.000000000 -0400
33624 @@ -133,7 +133,15 @@ void __init proc_root_init(void)
33625 #ifdef CONFIG_PROC_DEVICETREE
33626 proc_device_tree_init();
33627 #endif
33628 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
33629 +#ifdef CONFIG_GRKERNSEC_PROC_USER
33630 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
33631 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33632 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
33633 +#endif
33634 +#else
33635 proc_mkdir("bus", NULL);
33636 +#endif
33637 proc_sys_init();
33638 }
33639
33640 diff -urNp linux-2.6.36/fs/proc/task_mmu.c linux-2.6.36/fs/proc/task_mmu.c
33641 --- linux-2.6.36/fs/proc/task_mmu.c 2010-10-20 16:30:22.000000000 -0400
33642 +++ linux-2.6.36/fs/proc/task_mmu.c 2010-11-06 18:58:50.000000000 -0400
33643 @@ -49,8 +49,13 @@ void task_mem(struct seq_file *m, struct
33644 "VmExe:\t%8lu kB\n"
33645 "VmLib:\t%8lu kB\n"
33646 "VmPTE:\t%8lu kB\n"
33647 - "VmSwap:\t%8lu kB\n",
33648 - hiwater_vm << (PAGE_SHIFT-10),
33649 + "VmSwap:\t%8lu kB\n"
33650 +
33651 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
33652 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
33653 +#endif
33654 +
33655 + ,hiwater_vm << (PAGE_SHIFT-10),
33656 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
33657 mm->locked_vm << (PAGE_SHIFT-10),
33658 hiwater_rss << (PAGE_SHIFT-10),
33659 @@ -58,7 +63,13 @@ void task_mem(struct seq_file *m, struct
33660 data << (PAGE_SHIFT-10),
33661 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
33662 (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
33663 - swap << (PAGE_SHIFT-10));
33664 + swap << (PAGE_SHIFT-10)
33665 +
33666 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
33667 + , mm->context.user_cs_base, mm->context.user_cs_limit
33668 +#endif
33669 +
33670 + );
33671 }
33672
33673 unsigned long task_vsize(struct mm_struct *mm)
33674 @@ -203,6 +214,12 @@ static int do_maps_open(struct inode *in
33675 return ret;
33676 }
33677
33678 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33679 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
33680 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
33681 + _mm->pax_flags & MF_PAX_SEGMEXEC))
33682 +#endif
33683 +
33684 static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
33685 {
33686 struct mm_struct *mm = vma->vm_mm;
33687 @@ -210,7 +227,6 @@ static void show_map_vma(struct seq_file
33688 int flags = vma->vm_flags;
33689 unsigned long ino = 0;
33690 unsigned long long pgoff = 0;
33691 - unsigned long start;
33692 dev_t dev = 0;
33693 int len;
33694
33695 @@ -221,20 +237,24 @@ static void show_map_vma(struct seq_file
33696 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
33697 }
33698
33699 - /* We don't show the stack guard page in /proc/maps */
33700 - start = vma->vm_start;
33701 - if (vma->vm_flags & VM_GROWSDOWN)
33702 - if (!vma_stack_continue(vma->vm_prev, vma->vm_start))
33703 - start += PAGE_SIZE;
33704
33705 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
33706 - start,
33707 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33708 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
33709 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
33710 +#else
33711 + vma->vm_start,
33712 vma->vm_end,
33713 +#endif
33714 flags & VM_READ ? 'r' : '-',
33715 flags & VM_WRITE ? 'w' : '-',
33716 flags & VM_EXEC ? 'x' : '-',
33717 flags & VM_MAYSHARE ? 's' : 'p',
33718 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33719 + PAX_RAND_FLAGS(mm) ? 0UL : pgoff,
33720 +#else
33721 pgoff,
33722 +#endif
33723 MAJOR(dev), MINOR(dev), ino, &len);
33724
33725 /*
33726 @@ -243,16 +263,16 @@ static void show_map_vma(struct seq_file
33727 */
33728 if (file) {
33729 pad_len_spaces(m, len);
33730 - seq_path(m, &file->f_path, "\n");
33731 + seq_path(m, &file->f_path, "\n\\");
33732 } else {
33733 const char *name = arch_vma_name(vma);
33734 if (!name) {
33735 if (mm) {
33736 - if (vma->vm_start <= mm->start_brk &&
33737 - vma->vm_end >= mm->brk) {
33738 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
33739 name = "[heap]";
33740 - } else if (vma->vm_start <= mm->start_stack &&
33741 - vma->vm_end >= mm->start_stack) {
33742 + } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
33743 + (vma->vm_start <= mm->start_stack &&
33744 + vma->vm_end >= mm->start_stack)) {
33745 name = "[stack]";
33746 }
33747 } else {
33748 @@ -394,11 +414,16 @@ static int show_smap(struct seq_file *m,
33749 };
33750
33751 memset(&mss, 0, sizeof mss);
33752 - mss.vma = vma;
33753 - /* mmap_sem is held in m_start */
33754 - if (vma->vm_mm && !is_vm_hugetlb_page(vma))
33755 - walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
33756 -
33757 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33758 + if (!PAX_RAND_FLAGS(vma->vm_mm)) {
33759 +#endif
33760 + mss.vma = vma;
33761 + /* mmap_sem is held in m_start */
33762 + if (vma->vm_mm && !is_vm_hugetlb_page(vma))
33763 + walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
33764 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33765 + }
33766 +#endif
33767 show_map_vma(m, vma);
33768
33769 seq_printf(m,
33770 @@ -413,7 +438,11 @@ static int show_smap(struct seq_file *m,
33771 "Swap: %8lu kB\n"
33772 "KernelPageSize: %8lu kB\n"
33773 "MMUPageSize: %8lu kB\n",
33774 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
33775 + PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
33776 +#else
33777 (vma->vm_end - vma->vm_start) >> 10,
33778 +#endif
33779 mss.resident >> 10,
33780 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
33781 mss.shared_clean >> 10,
33782 diff -urNp linux-2.6.36/fs/proc/task_nommu.c linux-2.6.36/fs/proc/task_nommu.c
33783 --- linux-2.6.36/fs/proc/task_nommu.c 2010-10-20 16:30:22.000000000 -0400
33784 +++ linux-2.6.36/fs/proc/task_nommu.c 2010-11-06 18:58:15.000000000 -0400
33785 @@ -51,7 +51,7 @@ void task_mem(struct seq_file *m, struct
33786 else
33787 bytes += kobjsize(mm);
33788
33789 - if (current->fs && current->fs->users > 1)
33790 + if (current->fs && atomic_read(&current->fs->users) > 1)
33791 sbytes += kobjsize(current->fs);
33792 else
33793 bytes += kobjsize(current->fs);
33794 @@ -165,7 +165,7 @@ static int nommu_vma_show(struct seq_fil
33795
33796 if (file) {
33797 pad_len_spaces(m, len);
33798 - seq_path(m, &file->f_path, "");
33799 + seq_path(m, &file->f_path, "\n\\");
33800 } else if (mm) {
33801 if (vma->vm_start <= mm->start_stack &&
33802 vma->vm_end >= mm->start_stack) {
33803 diff -urNp linux-2.6.36/fs/readdir.c linux-2.6.36/fs/readdir.c
33804 --- linux-2.6.36/fs/readdir.c 2010-10-20 16:30:22.000000000 -0400
33805 +++ linux-2.6.36/fs/readdir.c 2010-11-06 18:58:50.000000000 -0400
33806 @@ -17,6 +17,7 @@
33807 #include <linux/security.h>
33808 #include <linux/syscalls.h>
33809 #include <linux/unistd.h>
33810 +#include <linux/namei.h>
33811
33812 #include <asm/uaccess.h>
33813
33814 @@ -67,6 +68,7 @@ struct old_linux_dirent {
33815
33816 struct readdir_callback {
33817 struct old_linux_dirent __user * dirent;
33818 + struct file * file;
33819 int result;
33820 };
33821
33822 @@ -84,6 +86,10 @@ static int fillonedir(void * __buf, cons
33823 buf->result = -EOVERFLOW;
33824 return -EOVERFLOW;
33825 }
33826 +
33827 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
33828 + return 0;
33829 +
33830 buf->result++;
33831 dirent = buf->dirent;
33832 if (!access_ok(VERIFY_WRITE, dirent,
33833 @@ -116,6 +122,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned in
33834
33835 buf.result = 0;
33836 buf.dirent = dirent;
33837 + buf.file = file;
33838
33839 error = vfs_readdir(file, fillonedir, &buf);
33840 if (buf.result)
33841 @@ -142,6 +149,7 @@ struct linux_dirent {
33842 struct getdents_callback {
33843 struct linux_dirent __user * current_dir;
33844 struct linux_dirent __user * previous;
33845 + struct file * file;
33846 int count;
33847 int error;
33848 };
33849 @@ -163,6 +171,10 @@ static int filldir(void * __buf, const c
33850 buf->error = -EOVERFLOW;
33851 return -EOVERFLOW;
33852 }
33853 +
33854 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
33855 + return 0;
33856 +
33857 dirent = buf->previous;
33858 if (dirent) {
33859 if (__put_user(offset, &dirent->d_off))
33860 @@ -210,6 +222,7 @@ SYSCALL_DEFINE3(getdents, unsigned int,
33861 buf.previous = NULL;
33862 buf.count = count;
33863 buf.error = 0;
33864 + buf.file = file;
33865
33866 error = vfs_readdir(file, filldir, &buf);
33867 if (error >= 0)
33868 @@ -229,6 +242,7 @@ out:
33869 struct getdents_callback64 {
33870 struct linux_dirent64 __user * current_dir;
33871 struct linux_dirent64 __user * previous;
33872 + struct file *file;
33873 int count;
33874 int error;
33875 };
33876 @@ -244,6 +258,10 @@ static int filldir64(void * __buf, const
33877 buf->error = -EINVAL; /* only used if we fail.. */
33878 if (reclen > buf->count)
33879 return -EINVAL;
33880 +
33881 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
33882 + return 0;
33883 +
33884 dirent = buf->previous;
33885 if (dirent) {
33886 if (__put_user(offset, &dirent->d_off))
33887 @@ -291,6 +309,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int
33888
33889 buf.current_dir = dirent;
33890 buf.previous = NULL;
33891 + buf.file = file;
33892 buf.count = count;
33893 buf.error = 0;
33894
33895 diff -urNp linux-2.6.36/fs/reiserfs/do_balan.c linux-2.6.36/fs/reiserfs/do_balan.c
33896 --- linux-2.6.36/fs/reiserfs/do_balan.c 2010-10-20 16:30:22.000000000 -0400
33897 +++ linux-2.6.36/fs/reiserfs/do_balan.c 2010-11-06 18:58:15.000000000 -0400
33898 @@ -2051,7 +2051,7 @@ void do_balance(struct tree_balance *tb,
33899 return;
33900 }
33901
33902 - atomic_inc(&(fs_generation(tb->tb_sb)));
33903 + atomic_inc_unchecked(&(fs_generation(tb->tb_sb)));
33904 do_balance_starts(tb);
33905
33906 /* balance leaf returns 0 except if combining L R and S into
33907 diff -urNp linux-2.6.36/fs/reiserfs/item_ops.c linux-2.6.36/fs/reiserfs/item_ops.c
33908 --- linux-2.6.36/fs/reiserfs/item_ops.c 2010-10-20 16:30:22.000000000 -0400
33909 +++ linux-2.6.36/fs/reiserfs/item_ops.c 2010-11-06 18:58:15.000000000 -0400
33910 @@ -102,7 +102,7 @@ static void sd_print_vi(struct virtual_i
33911 vi->vi_index, vi->vi_type, vi->vi_ih);
33912 }
33913
33914 -static struct item_operations stat_data_ops = {
33915 +static const struct item_operations stat_data_ops = {
33916 .bytes_number = sd_bytes_number,
33917 .decrement_key = sd_decrement_key,
33918 .is_left_mergeable = sd_is_left_mergeable,
33919 @@ -196,7 +196,7 @@ static void direct_print_vi(struct virtu
33920 vi->vi_index, vi->vi_type, vi->vi_ih);
33921 }
33922
33923 -static struct item_operations direct_ops = {
33924 +static const struct item_operations direct_ops = {
33925 .bytes_number = direct_bytes_number,
33926 .decrement_key = direct_decrement_key,
33927 .is_left_mergeable = direct_is_left_mergeable,
33928 @@ -341,7 +341,7 @@ static void indirect_print_vi(struct vir
33929 vi->vi_index, vi->vi_type, vi->vi_ih);
33930 }
33931
33932 -static struct item_operations indirect_ops = {
33933 +static const struct item_operations indirect_ops = {
33934 .bytes_number = indirect_bytes_number,
33935 .decrement_key = indirect_decrement_key,
33936 .is_left_mergeable = indirect_is_left_mergeable,
33937 @@ -628,7 +628,7 @@ static void direntry_print_vi(struct vir
33938 printk("\n");
33939 }
33940
33941 -static struct item_operations direntry_ops = {
33942 +static const struct item_operations direntry_ops = {
33943 .bytes_number = direntry_bytes_number,
33944 .decrement_key = direntry_decrement_key,
33945 .is_left_mergeable = direntry_is_left_mergeable,
33946 @@ -724,7 +724,7 @@ static void errcatch_print_vi(struct vir
33947 "Invalid item type observed, run fsck ASAP");
33948 }
33949
33950 -static struct item_operations errcatch_ops = {
33951 +static const struct item_operations errcatch_ops = {
33952 errcatch_bytes_number,
33953 errcatch_decrement_key,
33954 errcatch_is_left_mergeable,
33955 @@ -746,7 +746,7 @@ static struct item_operations errcatch_o
33956 #error Item types must use disk-format assigned values.
33957 #endif
33958
33959 -struct item_operations *item_ops[TYPE_ANY + 1] = {
33960 +const struct item_operations * const item_ops[TYPE_ANY + 1] = {
33961 &stat_data_ops,
33962 &indirect_ops,
33963 &direct_ops,
33964 diff -urNp linux-2.6.36/fs/reiserfs/procfs.c linux-2.6.36/fs/reiserfs/procfs.c
33965 --- linux-2.6.36/fs/reiserfs/procfs.c 2010-10-20 16:30:22.000000000 -0400
33966 +++ linux-2.6.36/fs/reiserfs/procfs.c 2010-11-06 18:58:15.000000000 -0400
33967 @@ -113,7 +113,7 @@ static int show_super(struct seq_file *m
33968 "SMALL_TAILS " : "NO_TAILS ",
33969 replay_only(sb) ? "REPLAY_ONLY " : "",
33970 convert_reiserfs(sb) ? "CONV " : "",
33971 - atomic_read(&r->s_generation_counter),
33972 + atomic_read_unchecked(&r->s_generation_counter),
33973 SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes),
33974 SF(s_do_balance), SF(s_unneeded_left_neighbor),
33975 SF(s_good_search_by_key_reada), SF(s_bmaps),
33976 diff -urNp linux-2.6.36/fs/select.c linux-2.6.36/fs/select.c
33977 --- linux-2.6.36/fs/select.c 2010-10-20 16:30:22.000000000 -0400
33978 +++ linux-2.6.36/fs/select.c 2010-11-06 18:58:50.000000000 -0400
33979 @@ -20,6 +20,7 @@
33980 #include <linux/module.h>
33981 #include <linux/slab.h>
33982 #include <linux/poll.h>
33983 +#include <linux/security.h>
33984 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
33985 #include <linux/file.h>
33986 #include <linux/fdtable.h>
33987 @@ -838,6 +839,7 @@ int do_sys_poll(struct pollfd __user *uf
33988 struct poll_list *walk = head;
33989 unsigned long todo = nfds;
33990
33991 + gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
33992 if (nfds > rlimit(RLIMIT_NOFILE))
33993 return -EINVAL;
33994
33995 diff -urNp linux-2.6.36/fs/seq_file.c linux-2.6.36/fs/seq_file.c
33996 --- linux-2.6.36/fs/seq_file.c 2010-10-20 16:30:22.000000000 -0400
33997 +++ linux-2.6.36/fs/seq_file.c 2010-11-06 18:58:15.000000000 -0400
33998 @@ -76,7 +76,8 @@ static int traverse(struct seq_file *m,
33999 return 0;
34000 }
34001 if (!m->buf) {
34002 - m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
34003 + m->size = PAGE_SIZE;
34004 + m->buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
34005 if (!m->buf)
34006 return -ENOMEM;
34007 }
34008 @@ -116,7 +117,8 @@ static int traverse(struct seq_file *m,
34009 Eoverflow:
34010 m->op->stop(m, p);
34011 kfree(m->buf);
34012 - m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
34013 + m->size <<= 1;
34014 + m->buf = kmalloc(m->size, GFP_KERNEL);
34015 return !m->buf ? -ENOMEM : -EAGAIN;
34016 }
34017
34018 @@ -169,7 +171,8 @@ ssize_t seq_read(struct file *file, char
34019 m->version = file->f_version;
34020 /* grab buffer if we didn't have one */
34021 if (!m->buf) {
34022 - m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
34023 + m->size = PAGE_SIZE;
34024 + m->buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
34025 if (!m->buf)
34026 goto Enomem;
34027 }
34028 @@ -210,7 +213,8 @@ ssize_t seq_read(struct file *file, char
34029 goto Fill;
34030 m->op->stop(m, p);
34031 kfree(m->buf);
34032 - m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
34033 + m->size <<= 1;
34034 + m->buf = kmalloc(m->size, GFP_KERNEL);
34035 if (!m->buf)
34036 goto Enomem;
34037 m->count = 0;
34038 diff -urNp linux-2.6.36/fs/smbfs/symlink.c linux-2.6.36/fs/smbfs/symlink.c
34039 --- linux-2.6.36/fs/smbfs/symlink.c 2010-10-20 16:30:22.000000000 -0400
34040 +++ linux-2.6.36/fs/smbfs/symlink.c 2010-11-06 18:58:15.000000000 -0400
34041 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
34042
34043 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
34044 {
34045 - char *s = nd_get_link(nd);
34046 + const char *s = nd_get_link(nd);
34047 if (!IS_ERR(s))
34048 __putname(s);
34049 }
34050 diff -urNp linux-2.6.36/fs/splice.c linux-2.6.36/fs/splice.c
34051 --- linux-2.6.36/fs/splice.c 2010-10-20 16:30:22.000000000 -0400
34052 +++ linux-2.6.36/fs/splice.c 2010-11-06 18:58:15.000000000 -0400
34053 @@ -186,7 +186,7 @@ ssize_t splice_to_pipe(struct pipe_inode
34054 pipe_lock(pipe);
34055
34056 for (;;) {
34057 - if (!pipe->readers) {
34058 + if (!atomic_read(&pipe->readers)) {
34059 send_sig(SIGPIPE, current, 0);
34060 if (!ret)
34061 ret = -EPIPE;
34062 @@ -240,9 +240,9 @@ ssize_t splice_to_pipe(struct pipe_inode
34063 do_wakeup = 0;
34064 }
34065
34066 - pipe->waiting_writers++;
34067 + atomic_inc(&pipe->waiting_writers);
34068 pipe_wait(pipe);
34069 - pipe->waiting_writers--;
34070 + atomic_dec(&pipe->waiting_writers);
34071 }
34072
34073 pipe_unlock(pipe);
34074 @@ -556,7 +556,7 @@ static ssize_t kernel_readv(struct file
34075 old_fs = get_fs();
34076 set_fs(get_ds());
34077 /* The cast to a user pointer is valid due to the set_fs() */
34078 - res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos);
34079 + res = vfs_readv(file, (__force const struct iovec __user *)vec, vlen, &pos);
34080 set_fs(old_fs);
34081
34082 return res;
34083 @@ -571,7 +571,7 @@ static ssize_t kernel_write(struct file
34084 old_fs = get_fs();
34085 set_fs(get_ds());
34086 /* The cast to a user pointer is valid due to the set_fs() */
34087 - res = vfs_write(file, (const char __user *)buf, count, &pos);
34088 + res = vfs_write(file, (__force const char __user *)buf, count, &pos);
34089 set_fs(old_fs);
34090
34091 return res;
34092 @@ -622,7 +622,7 @@ ssize_t default_file_splice_read(struct
34093 goto err;
34094
34095 this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset);
34096 - vec[i].iov_base = (void __user *) page_address(page);
34097 + vec[i].iov_base = (__force void __user *) page_address(page);
34098 vec[i].iov_len = this_len;
34099 spd.pages[i] = page;
34100 spd.nr_pages++;
34101 @@ -849,10 +849,10 @@ EXPORT_SYMBOL(splice_from_pipe_feed);
34102 int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
34103 {
34104 while (!pipe->nrbufs) {
34105 - if (!pipe->writers)
34106 + if (!atomic_read(&pipe->writers))
34107 return 0;
34108
34109 - if (!pipe->waiting_writers && sd->num_spliced)
34110 + if (!atomic_read(&pipe->waiting_writers) && sd->num_spliced)
34111 return 0;
34112
34113 if (sd->flags & SPLICE_F_NONBLOCK)
34114 @@ -1189,7 +1189,7 @@ ssize_t splice_direct_to_actor(struct fi
34115 * out of the pipe right after the splice_to_pipe(). So set
34116 * PIPE_READERS appropriately.
34117 */
34118 - pipe->readers = 1;
34119 + atomic_set(&pipe->readers, 1);
34120
34121 current->splice_pipe = pipe;
34122 }
34123 @@ -1757,9 +1757,9 @@ static int ipipe_prep(struct pipe_inode_
34124 ret = -ERESTARTSYS;
34125 break;
34126 }
34127 - if (!pipe->writers)
34128 + if (!atomic_read(&pipe->writers))
34129 break;
34130 - if (!pipe->waiting_writers) {
34131 + if (!atomic_read(&pipe->waiting_writers)) {
34132 if (flags & SPLICE_F_NONBLOCK) {
34133 ret = -EAGAIN;
34134 break;
34135 @@ -1791,7 +1791,7 @@ static int opipe_prep(struct pipe_inode_
34136 pipe_lock(pipe);
34137
34138 while (pipe->nrbufs >= pipe->buffers) {
34139 - if (!pipe->readers) {
34140 + if (!atomic_read(&pipe->readers)) {
34141 send_sig(SIGPIPE, current, 0);
34142 ret = -EPIPE;
34143 break;
34144 @@ -1804,9 +1804,9 @@ static int opipe_prep(struct pipe_inode_
34145 ret = -ERESTARTSYS;
34146 break;
34147 }
34148 - pipe->waiting_writers++;
34149 + atomic_inc(&pipe->waiting_writers);
34150 pipe_wait(pipe);
34151 - pipe->waiting_writers--;
34152 + atomic_dec(&pipe->waiting_writers);
34153 }
34154
34155 pipe_unlock(pipe);
34156 @@ -1842,14 +1842,14 @@ retry:
34157 pipe_double_lock(ipipe, opipe);
34158
34159 do {
34160 - if (!opipe->readers) {
34161 + if (!atomic_read(&opipe->readers)) {
34162 send_sig(SIGPIPE, current, 0);
34163 if (!ret)
34164 ret = -EPIPE;
34165 break;
34166 }
34167
34168 - if (!ipipe->nrbufs && !ipipe->writers)
34169 + if (!ipipe->nrbufs && !atomic_read(&ipipe->writers))
34170 break;
34171
34172 /*
34173 @@ -1949,7 +1949,7 @@ static int link_pipe(struct pipe_inode_i
34174 pipe_double_lock(ipipe, opipe);
34175
34176 do {
34177 - if (!opipe->readers) {
34178 + if (!atomic_read(&opipe->readers)) {
34179 send_sig(SIGPIPE, current, 0);
34180 if (!ret)
34181 ret = -EPIPE;
34182 @@ -1994,7 +1994,7 @@ static int link_pipe(struct pipe_inode_i
34183 * return EAGAIN if we have the potential of some data in the
34184 * future, otherwise just return 0
34185 */
34186 - if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK))
34187 + if (!ret && atomic_read(&ipipe->waiting_writers) && (flags & SPLICE_F_NONBLOCK))
34188 ret = -EAGAIN;
34189
34190 pipe_unlock(ipipe);
34191 diff -urNp linux-2.6.36/fs/sysfs/symlink.c linux-2.6.36/fs/sysfs/symlink.c
34192 --- linux-2.6.36/fs/sysfs/symlink.c 2010-10-20 16:30:22.000000000 -0400
34193 +++ linux-2.6.36/fs/sysfs/symlink.c 2010-11-06 18:58:15.000000000 -0400
34194 @@ -286,7 +286,7 @@ static void *sysfs_follow_link(struct de
34195
34196 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
34197 {
34198 - char *page = nd_get_link(nd);
34199 + const char *page = nd_get_link(nd);
34200 if (!IS_ERR(page))
34201 free_page((unsigned long)page);
34202 }
34203 diff -urNp linux-2.6.36/fs/udf/misc.c linux-2.6.36/fs/udf/misc.c
34204 --- linux-2.6.36/fs/udf/misc.c 2010-10-20 16:30:22.000000000 -0400
34205 +++ linux-2.6.36/fs/udf/misc.c 2010-11-06 18:58:15.000000000 -0400
34206 @@ -142,8 +142,8 @@ struct genericFormat *udf_add_extendedat
34207 iinfo->i_lenEAttr += size;
34208 return (struct genericFormat *)&ea[offset];
34209 }
34210 - if (loc & 0x02)
34211 - ;
34212 + if (loc & 0x02) {
34213 + }
34214
34215 return NULL;
34216 }
34217 diff -urNp linux-2.6.36/fs/udf/udfdecl.h linux-2.6.36/fs/udf/udfdecl.h
34218 --- linux-2.6.36/fs/udf/udfdecl.h 2010-10-20 16:30:22.000000000 -0400
34219 +++ linux-2.6.36/fs/udf/udfdecl.h 2010-11-06 18:58:15.000000000 -0400
34220 @@ -26,7 +26,7 @@ do { \
34221 printk(f, ##a); \
34222 } while (0)
34223 #else
34224 -#define udf_debug(f, a...) /**/
34225 +#define udf_debug(f, a...) do {} while (0)
34226 #endif
34227
34228 #define udf_info(f, a...) \
34229 diff -urNp linux-2.6.36/fs/utimes.c linux-2.6.36/fs/utimes.c
34230 --- linux-2.6.36/fs/utimes.c 2010-10-20 16:30:22.000000000 -0400
34231 +++ linux-2.6.36/fs/utimes.c 2010-11-06 18:58:50.000000000 -0400
34232 @@ -1,6 +1,7 @@
34233 #include <linux/compiler.h>
34234 #include <linux/file.h>
34235 #include <linux/fs.h>
34236 +#include <linux/security.h>
34237 #include <linux/linkage.h>
34238 #include <linux/mount.h>
34239 #include <linux/namei.h>
34240 @@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
34241 goto mnt_drop_write_and_out;
34242 }
34243 }
34244 +
34245 + if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
34246 + error = -EACCES;
34247 + goto mnt_drop_write_and_out;
34248 + }
34249 +
34250 mutex_lock(&inode->i_mutex);
34251 error = notify_change(path->dentry, &newattrs);
34252 mutex_unlock(&inode->i_mutex);
34253 diff -urNp linux-2.6.36/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.36/fs/xfs/linux-2.6/xfs_ioctl.c
34254 --- linux-2.6.36/fs/xfs/linux-2.6/xfs_ioctl.c 2010-10-20 16:30:22.000000000 -0400
34255 +++ linux-2.6.36/fs/xfs/linux-2.6/xfs_ioctl.c 2010-11-06 18:58:50.000000000 -0400
34256 @@ -127,7 +127,7 @@ xfs_find_handle(
34257 }
34258
34259 error = -EFAULT;
34260 - if (copy_to_user(hreq->ohandle, &handle, hsize) ||
34261 + if (hsize > sizeof(handle) || copy_to_user(hreq->ohandle, &handle, hsize) ||
34262 copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
34263 goto out_put;
34264
34265 diff -urNp linux-2.6.36/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.36/fs/xfs/linux-2.6/xfs_iops.c
34266 --- linux-2.6.36/fs/xfs/linux-2.6/xfs_iops.c 2010-10-20 16:30:22.000000000 -0400
34267 +++ linux-2.6.36/fs/xfs/linux-2.6/xfs_iops.c 2010-11-06 18:58:15.000000000 -0400
34268 @@ -472,7 +472,7 @@ xfs_vn_put_link(
34269 struct nameidata *nd,
34270 void *p)
34271 {
34272 - char *s = nd_get_link(nd);
34273 + const char *s = nd_get_link(nd);
34274
34275 if (!IS_ERR(s))
34276 kfree(s);
34277 diff -urNp linux-2.6.36/fs/xfs/xfs_bmap.c linux-2.6.36/fs/xfs/xfs_bmap.c
34278 --- linux-2.6.36/fs/xfs/xfs_bmap.c 2010-10-20 16:30:22.000000000 -0400
34279 +++ linux-2.6.36/fs/xfs/xfs_bmap.c 2010-11-06 18:58:15.000000000 -0400
34280 @@ -287,7 +287,7 @@ xfs_bmap_validate_ret(
34281 int nmap,
34282 int ret_nmap);
34283 #else
34284 -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
34285 +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
34286 #endif /* DEBUG */
34287
34288 STATIC int
34289 diff -urNp linux-2.6.36/grsecurity/gracl_alloc.c linux-2.6.36/grsecurity/gracl_alloc.c
34290 --- linux-2.6.36/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
34291 +++ linux-2.6.36/grsecurity/gracl_alloc.c 2010-11-06 18:58:50.000000000 -0400
34292 @@ -0,0 +1,105 @@
34293 +#include <linux/kernel.h>
34294 +#include <linux/mm.h>
34295 +#include <linux/slab.h>
34296 +#include <linux/vmalloc.h>
34297 +#include <linux/gracl.h>
34298 +#include <linux/grsecurity.h>
34299 +
34300 +static unsigned long alloc_stack_next = 1;
34301 +static unsigned long alloc_stack_size = 1;
34302 +static void **alloc_stack;
34303 +
34304 +static __inline__ int
34305 +alloc_pop(void)
34306 +{
34307 + if (alloc_stack_next == 1)
34308 + return 0;
34309 +
34310 + kfree(alloc_stack[alloc_stack_next - 2]);
34311 +
34312 + alloc_stack_next--;
34313 +
34314 + return 1;
34315 +}
34316 +
34317 +static __inline__ int
34318 +alloc_push(void *buf)
34319 +{
34320 + if (alloc_stack_next >= alloc_stack_size)
34321 + return 1;
34322 +
34323 + alloc_stack[alloc_stack_next - 1] = buf;
34324 +
34325 + alloc_stack_next++;
34326 +
34327 + return 0;
34328 +}
34329 +
34330 +void *
34331 +acl_alloc(unsigned long len)
34332 +{
34333 + void *ret = NULL;
34334 +
34335 + if (!len || len > PAGE_SIZE)
34336 + goto out;
34337 +
34338 + ret = kmalloc(len, GFP_KERNEL);
34339 +
34340 + if (ret) {
34341 + if (alloc_push(ret)) {
34342 + kfree(ret);
34343 + ret = NULL;
34344 + }
34345 + }
34346 +
34347 +out:
34348 + return ret;
34349 +}
34350 +
34351 +void *
34352 +acl_alloc_num(unsigned long num, unsigned long len)
34353 +{
34354 + if (!len || (num > (PAGE_SIZE / len)))
34355 + return NULL;
34356 +
34357 + return acl_alloc(num * len);
34358 +}
34359 +
34360 +void
34361 +acl_free_all(void)
34362 +{
34363 + if (gr_acl_is_enabled() || !alloc_stack)
34364 + return;
34365 +
34366 + while (alloc_pop()) ;
34367 +
34368 + if (alloc_stack) {
34369 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
34370 + kfree(alloc_stack);
34371 + else
34372 + vfree(alloc_stack);
34373 + }
34374 +
34375 + alloc_stack = NULL;
34376 + alloc_stack_size = 1;
34377 + alloc_stack_next = 1;
34378 +
34379 + return;
34380 +}
34381 +
34382 +int
34383 +acl_alloc_stack_init(unsigned long size)
34384 +{
34385 + if ((size * sizeof (void *)) <= PAGE_SIZE)
34386 + alloc_stack =
34387 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
34388 + else
34389 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
34390 +
34391 + alloc_stack_size = size;
34392 +
34393 + if (!alloc_stack)
34394 + return 0;
34395 + else
34396 + return 1;
34397 +}
34398 diff -urNp linux-2.6.36/grsecurity/gracl.c linux-2.6.36/grsecurity/gracl.c
34399 --- linux-2.6.36/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
34400 +++ linux-2.6.36/grsecurity/gracl.c 2010-11-06 19:40:35.000000000 -0400
34401 @@ -0,0 +1,3874 @@
34402 +#include <linux/kernel.h>
34403 +#include <linux/module.h>
34404 +#include <linux/sched.h>
34405 +#include <linux/mm.h>
34406 +#include <linux/file.h>
34407 +#include <linux/fs.h>
34408 +#include <linux/namei.h>
34409 +#include <linux/mount.h>
34410 +#include <linux/tty.h>
34411 +#include <linux/proc_fs.h>
34412 +#include <linux/smp_lock.h>
34413 +#include <linux/slab.h>
34414 +#include <linux/vmalloc.h>
34415 +#include <linux/types.h>
34416 +#include <linux/sysctl.h>
34417 +#include <linux/netdevice.h>
34418 +#include <linux/ptrace.h>
34419 +#include <linux/gracl.h>
34420 +#include <linux/gralloc.h>
34421 +#include <linux/grsecurity.h>
34422 +#include <linux/grinternal.h>
34423 +#include <linux/pid_namespace.h>
34424 +#include <linux/fdtable.h>
34425 +#include <linux/percpu.h>
34426 +
34427 +#include <asm/uaccess.h>
34428 +#include <asm/errno.h>
34429 +#include <asm/mman.h>
34430 +
34431 +static struct acl_role_db acl_role_set;
34432 +static struct name_db name_set;
34433 +static struct inodev_db inodev_set;
34434 +
34435 +/* for keeping track of userspace pointers used for subjects, so we
34436 + can share references in the kernel as well
34437 +*/
34438 +
34439 +static struct path real_root;
34440 +
34441 +static struct acl_subj_map_db subj_map_set;
34442 +
34443 +static struct acl_role_label *default_role;
34444 +
34445 +static struct acl_role_label *role_list;
34446 +
34447 +static u16 acl_sp_role_value;
34448 +
34449 +extern char *gr_shared_page[4];
34450 +static DECLARE_MUTEX(gr_dev_sem);
34451 +DEFINE_RWLOCK(gr_inode_lock);
34452 +
34453 +struct gr_arg *gr_usermode;
34454 +
34455 +static unsigned int gr_status __read_only = GR_STATUS_INIT;
34456 +
34457 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
34458 +extern void gr_clear_learn_entries(void);
34459 +
34460 +#ifdef CONFIG_GRKERNSEC_RESLOG
34461 +extern void gr_log_resource(const struct task_struct *task,
34462 + const int res, const unsigned long wanted, const int gt);
34463 +#endif
34464 +
34465 +unsigned char *gr_system_salt;
34466 +unsigned char *gr_system_sum;
34467 +
34468 +static struct sprole_pw **acl_special_roles = NULL;
34469 +static __u16 num_sprole_pws = 0;
34470 +
34471 +static struct acl_role_label *kernel_role = NULL;
34472 +
34473 +static unsigned int gr_auth_attempts = 0;
34474 +static unsigned long gr_auth_expires = 0UL;
34475 +
34476 +extern struct vfsmount *sock_mnt;
34477 +extern struct vfsmount *pipe_mnt;
34478 +extern struct vfsmount *shm_mnt;
34479 +#ifdef CONFIG_HUGETLBFS
34480 +extern struct vfsmount *hugetlbfs_vfsmount;
34481 +#endif
34482 +
34483 +static struct acl_object_label *fakefs_obj;
34484 +
34485 +extern int gr_init_uidset(void);
34486 +extern void gr_free_uidset(void);
34487 +extern void gr_remove_uid(uid_t uid);
34488 +extern int gr_find_uid(uid_t uid);
34489 +
34490 +extern spinlock_t vfsmount_lock;
34491 +
34492 +__inline__ int
34493 +gr_acl_is_enabled(void)
34494 +{
34495 + return (gr_status & GR_READY);
34496 +}
34497 +
34498 +static char gr_task_roletype_to_char(struct task_struct *task)
34499 +{
34500 + switch (task->role->roletype &
34501 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
34502 + GR_ROLE_SPECIAL)) {
34503 + case GR_ROLE_DEFAULT:
34504 + return 'D';
34505 + case GR_ROLE_USER:
34506 + return 'U';
34507 + case GR_ROLE_GROUP:
34508 + return 'G';
34509 + case GR_ROLE_SPECIAL:
34510 + return 'S';
34511 + }
34512 +
34513 + return 'X';
34514 +}
34515 +
34516 +char gr_roletype_to_char(void)
34517 +{
34518 + return gr_task_roletype_to_char(current);
34519 +}
34520 +
34521 +__inline__ int
34522 +gr_acl_tpe_check(void)
34523 +{
34524 + if (unlikely(!(gr_status & GR_READY)))
34525 + return 0;
34526 + if (current->role->roletype & GR_ROLE_TPE)
34527 + return 1;
34528 + else
34529 + return 0;
34530 +}
34531 +
34532 +int
34533 +gr_handle_rawio(const struct inode *inode)
34534 +{
34535 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
34536 + if (inode && S_ISBLK(inode->i_mode) &&
34537 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
34538 + !capable(CAP_SYS_RAWIO))
34539 + return 1;
34540 +#endif
34541 + return 0;
34542 +}
34543 +
34544 +static int
34545 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
34546 +{
34547 + if (likely(lena != lenb))
34548 + return 0;
34549 +
34550 + return !memcmp(a, b, lena);
34551 +}
34552 +
34553 +static char *
34554 +gen_full_path(struct path *path, struct path *root, char *buf, int buflen)
34555 +{
34556 + char *retval;
34557 +
34558 + retval = __d_path(path, root, buf, buflen);
34559 + if (unlikely(IS_ERR(retval)))
34560 + retval = strcpy(buf, "<path too long>");
34561 + else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
34562 + retval[1] = '\0';
34563 +
34564 + return retval;
34565 +}
34566 +
34567 +static char *
34568 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
34569 + char *buf, int buflen)
34570 +{
34571 + struct path path;
34572 + char *res;
34573 +
34574 + path.dentry = (struct dentry *)dentry;
34575 + path.mnt = (struct vfsmount *)vfsmnt;
34576 +
34577 + /* we can use real_root.dentry, real_root.mnt, because this is only called
34578 + by the RBAC system */
34579 + res = gen_full_path(&path, &real_root, buf, buflen);
34580 +
34581 + return res;
34582 +}
34583 +
34584 +static char *
34585 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
34586 + char *buf, int buflen)
34587 +{
34588 + char *res;
34589 + struct path path;
34590 + struct path root;
34591 + struct task_struct *reaper = &init_task;
34592 +
34593 + path.dentry = (struct dentry *)dentry;
34594 + path.mnt = (struct vfsmount *)vfsmnt;
34595 +
34596 + /* we can't use real_root.dentry, real_root.mnt, because they belong only to the RBAC system */
34597 + get_fs_root(reaper->fs, &root);
34598 +
34599 + spin_lock(&dcache_lock);
34600 + res = gen_full_path(&path, &root, buf, buflen);
34601 + spin_unlock(&dcache_lock);
34602 +
34603 + path_put(&root);
34604 + return res;
34605 +}
34606 +
34607 +static char *
34608 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
34609 +{
34610 + char *ret;
34611 + spin_lock(&dcache_lock);
34612 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
34613 + PAGE_SIZE);
34614 + spin_unlock(&dcache_lock);
34615 + return ret;
34616 +}
34617 +
34618 +char *
34619 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
34620 +{
34621 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
34622 + PAGE_SIZE);
34623 +}
34624 +
34625 +char *
34626 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
34627 +{
34628 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
34629 + PAGE_SIZE);
34630 +}
34631 +
34632 +char *
34633 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
34634 +{
34635 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
34636 + PAGE_SIZE);
34637 +}
34638 +
34639 +char *
34640 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
34641 +{
34642 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
34643 + PAGE_SIZE);
34644 +}
34645 +
34646 +char *
34647 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
34648 +{
34649 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
34650 + PAGE_SIZE);
34651 +}
34652 +
34653 +__inline__ __u32
34654 +to_gr_audit(const __u32 reqmode)
34655 +{
34656 + /* masks off auditable permission flags, then shifts them to create
34657 + auditing flags, and adds the special case of append auditing if
34658 + we're requesting write */
34659 + return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
34660 +}
34661 +
34662 +struct acl_subject_label *
34663 +lookup_subject_map(const struct acl_subject_label *userp)
34664 +{
34665 + unsigned int index = shash(userp, subj_map_set.s_size);
34666 + struct subject_map *match;
34667 +
34668 + match = subj_map_set.s_hash[index];
34669 +
34670 + while (match && match->user != userp)
34671 + match = match->next;
34672 +
34673 + if (match != NULL)
34674 + return match->kernel;
34675 + else
34676 + return NULL;
34677 +}
34678 +
34679 +static void
34680 +insert_subj_map_entry(struct subject_map *subjmap)
34681 +{
34682 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
34683 + struct subject_map **curr;
34684 +
34685 + subjmap->prev = NULL;
34686 +
34687 + curr = &subj_map_set.s_hash[index];
34688 + if (*curr != NULL)
34689 + (*curr)->prev = subjmap;
34690 +
34691 + subjmap->next = *curr;
34692 + *curr = subjmap;
34693 +
34694 + return;
34695 +}
34696 +
34697 +static struct acl_role_label *
34698 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
34699 + const gid_t gid)
34700 +{
34701 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
34702 + struct acl_role_label *match;
34703 + struct role_allowed_ip *ipp;
34704 + unsigned int x;
34705 +
34706 + match = acl_role_set.r_hash[index];
34707 +
34708 + while (match) {
34709 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
34710 + for (x = 0; x < match->domain_child_num; x++) {
34711 + if (match->domain_children[x] == uid)
34712 + goto found;
34713 + }
34714 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
34715 + break;
34716 + match = match->next;
34717 + }
34718 +found:
34719 + if (match == NULL) {
34720 + try_group:
34721 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
34722 + match = acl_role_set.r_hash[index];
34723 +
34724 + while (match) {
34725 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
34726 + for (x = 0; x < match->domain_child_num; x++) {
34727 + if (match->domain_children[x] == gid)
34728 + goto found2;
34729 + }
34730 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
34731 + break;
34732 + match = match->next;
34733 + }
34734 +found2:
34735 + if (match == NULL)
34736 + match = default_role;
34737 + if (match->allowed_ips == NULL)
34738 + return match;
34739 + else {
34740 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
34741 + if (likely
34742 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
34743 + (ntohl(ipp->addr) & ipp->netmask)))
34744 + return match;
34745 + }
34746 + match = default_role;
34747 + }
34748 + } else if (match->allowed_ips == NULL) {
34749 + return match;
34750 + } else {
34751 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
34752 + if (likely
34753 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
34754 + (ntohl(ipp->addr) & ipp->netmask)))
34755 + return match;
34756 + }
34757 + goto try_group;
34758 + }
34759 +
34760 + return match;
34761 +}
34762 +
34763 +struct acl_subject_label *
34764 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
34765 + const struct acl_role_label *role)
34766 +{
34767 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
34768 + struct acl_subject_label *match;
34769 +
34770 + match = role->subj_hash[index];
34771 +
34772 + while (match && (match->inode != ino || match->device != dev ||
34773 + (match->mode & GR_DELETED))) {
34774 + match = match->next;
34775 + }
34776 +
34777 + if (match && !(match->mode & GR_DELETED))
34778 + return match;
34779 + else
34780 + return NULL;
34781 +}
34782 +
34783 +struct acl_subject_label *
34784 +lookup_acl_subj_label_deleted(const ino_t ino, const dev_t dev,
34785 + const struct acl_role_label *role)
34786 +{
34787 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
34788 + struct acl_subject_label *match;
34789 +
34790 + match = role->subj_hash[index];
34791 +
34792 + while (match && (match->inode != ino || match->device != dev ||
34793 + !(match->mode & GR_DELETED))) {
34794 + match = match->next;
34795 + }
34796 +
34797 + if (match && (match->mode & GR_DELETED))
34798 + return match;
34799 + else
34800 + return NULL;
34801 +}
34802 +
34803 +static struct acl_object_label *
34804 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
34805 + const struct acl_subject_label *subj)
34806 +{
34807 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
34808 + struct acl_object_label *match;
34809 +
34810 + match = subj->obj_hash[index];
34811 +
34812 + while (match && (match->inode != ino || match->device != dev ||
34813 + (match->mode & GR_DELETED))) {
34814 + match = match->next;
34815 + }
34816 +
34817 + if (match && !(match->mode & GR_DELETED))
34818 + return match;
34819 + else
34820 + return NULL;
34821 +}
34822 +
34823 +static struct acl_object_label *
34824 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
34825 + const struct acl_subject_label *subj)
34826 +{
34827 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
34828 + struct acl_object_label *match;
34829 +
34830 + match = subj->obj_hash[index];
34831 +
34832 + while (match && (match->inode != ino || match->device != dev ||
34833 + !(match->mode & GR_DELETED))) {
34834 + match = match->next;
34835 + }
34836 +
34837 + if (match && (match->mode & GR_DELETED))
34838 + return match;
34839 +
34840 + match = subj->obj_hash[index];
34841 +
34842 + while (match && (match->inode != ino || match->device != dev ||
34843 + (match->mode & GR_DELETED))) {
34844 + match = match->next;
34845 + }
34846 +
34847 + if (match && !(match->mode & GR_DELETED))
34848 + return match;
34849 + else
34850 + return NULL;
34851 +}
34852 +
34853 +static struct name_entry *
34854 +lookup_name_entry(const char *name)
34855 +{
34856 + unsigned int len = strlen(name);
34857 + unsigned int key = full_name_hash(name, len);
34858 + unsigned int index = key % name_set.n_size;
34859 + struct name_entry *match;
34860 +
34861 + match = name_set.n_hash[index];
34862 +
34863 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
34864 + match = match->next;
34865 +
34866 + return match;
34867 +}
34868 +
34869 +static struct name_entry *
34870 +lookup_name_entry_create(const char *name)
34871 +{
34872 + unsigned int len = strlen(name);
34873 + unsigned int key = full_name_hash(name, len);
34874 + unsigned int index = key % name_set.n_size;
34875 + struct name_entry *match;
34876 +
34877 + match = name_set.n_hash[index];
34878 +
34879 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
34880 + !match->deleted))
34881 + match = match->next;
34882 +
34883 + if (match && match->deleted)
34884 + return match;
34885 +
34886 + match = name_set.n_hash[index];
34887 +
34888 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
34889 + match->deleted))
34890 + match = match->next;
34891 +
34892 + if (match && !match->deleted)
34893 + return match;
34894 + else
34895 + return NULL;
34896 +}
34897 +
34898 +static struct inodev_entry *
34899 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
34900 +{
34901 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
34902 + struct inodev_entry *match;
34903 +
34904 + match = inodev_set.i_hash[index];
34905 +
34906 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
34907 + match = match->next;
34908 +
34909 + return match;
34910 +}
34911 +
34912 +static void
34913 +insert_inodev_entry(struct inodev_entry *entry)
34914 +{
34915 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
34916 + inodev_set.i_size);
34917 + struct inodev_entry **curr;
34918 +
34919 + entry->prev = NULL;
34920 +
34921 + curr = &inodev_set.i_hash[index];
34922 + if (*curr != NULL)
34923 + (*curr)->prev = entry;
34924 +
34925 + entry->next = *curr;
34926 + *curr = entry;
34927 +
34928 + return;
34929 +}
34930 +
34931 +static void
34932 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
34933 +{
34934 + unsigned int index =
34935 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
34936 + struct acl_role_label **curr;
34937 + struct acl_role_label *tmp;
34938 +
34939 + curr = &acl_role_set.r_hash[index];
34940 +
34941 + /* if role was already inserted due to domains and already has
34942 + a role in the same bucket as it attached, then we need to
34943 + combine these two buckets
34944 + */
34945 + if (role->next) {
34946 + tmp = role->next;
34947 + while (tmp->next)
34948 + tmp = tmp->next;
34949 + tmp->next = *curr;
34950 + } else
34951 + role->next = *curr;
34952 + *curr = role;
34953 +
34954 + return;
34955 +}
34956 +
34957 +static void
34958 +insert_acl_role_label(struct acl_role_label *role)
34959 +{
34960 + int i;
34961 +
34962 + if (role_list == NULL) {
34963 + role_list = role;
34964 + role->prev = NULL;
34965 + } else {
34966 + role->prev = role_list;
34967 + role_list = role;
34968 + }
34969 +
34970 + /* used for hash chains */
34971 + role->next = NULL;
34972 +
34973 + if (role->roletype & GR_ROLE_DOMAIN) {
34974 + for (i = 0; i < role->domain_child_num; i++)
34975 + __insert_acl_role_label(role, role->domain_children[i]);
34976 + } else
34977 + __insert_acl_role_label(role, role->uidgid);
34978 +}
34979 +
34980 +static int
34981 +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
34982 +{
34983 + struct name_entry **curr, *nentry;
34984 + struct inodev_entry *ientry;
34985 + unsigned int len = strlen(name);
34986 + unsigned int key = full_name_hash(name, len);
34987 + unsigned int index = key % name_set.n_size;
34988 +
34989 + curr = &name_set.n_hash[index];
34990 +
34991 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
34992 + curr = &((*curr)->next);
34993 +
34994 + if (*curr != NULL)
34995 + return 1;
34996 +
34997 + nentry = acl_alloc(sizeof (struct name_entry));
34998 + if (nentry == NULL)
34999 + return 0;
35000 + ientry = acl_alloc(sizeof (struct inodev_entry));
35001 + if (ientry == NULL)
35002 + return 0;
35003 + ientry->nentry = nentry;
35004 +
35005 + nentry->key = key;
35006 + nentry->name = name;
35007 + nentry->inode = inode;
35008 + nentry->device = device;
35009 + nentry->len = len;
35010 + nentry->deleted = deleted;
35011 +
35012 + nentry->prev = NULL;
35013 + curr = &name_set.n_hash[index];
35014 + if (*curr != NULL)
35015 + (*curr)->prev = nentry;
35016 + nentry->next = *curr;
35017 + *curr = nentry;
35018 +
35019 + /* insert us into the table searchable by inode/dev */
35020 + insert_inodev_entry(ientry);
35021 +
35022 + return 1;
35023 +}
35024 +
35025 +static void
35026 +insert_acl_obj_label(struct acl_object_label *obj,
35027 + struct acl_subject_label *subj)
35028 +{
35029 + unsigned int index =
35030 + fhash(obj->inode, obj->device, subj->obj_hash_size);
35031 + struct acl_object_label **curr;
35032 +
35033 +
35034 + obj->prev = NULL;
35035 +
35036 + curr = &subj->obj_hash[index];
35037 + if (*curr != NULL)
35038 + (*curr)->prev = obj;
35039 +
35040 + obj->next = *curr;
35041 + *curr = obj;
35042 +
35043 + return;
35044 +}
35045 +
35046 +static void
35047 +insert_acl_subj_label(struct acl_subject_label *obj,
35048 + struct acl_role_label *role)
35049 +{
35050 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
35051 + struct acl_subject_label **curr;
35052 +
35053 + obj->prev = NULL;
35054 +
35055 + curr = &role->subj_hash[index];
35056 + if (*curr != NULL)
35057 + (*curr)->prev = obj;
35058 +
35059 + obj->next = *curr;
35060 + *curr = obj;
35061 +
35062 + return;
35063 +}
35064 +
35065 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
35066 +
35067 +static void *
35068 +create_table(__u32 * len, int elementsize)
35069 +{
35070 + unsigned int table_sizes[] = {
35071 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
35072 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
35073 + 4194301, 8388593, 16777213, 33554393, 67108859
35074 + };
35075 + void *newtable = NULL;
35076 + unsigned int pwr = 0;
35077 +
35078 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
35079 + table_sizes[pwr] <= *len)
35080 + pwr++;
35081 +
35082 + if (table_sizes[pwr] <= *len || (table_sizes[pwr] > ULONG_MAX / elementsize))
35083 + return newtable;
35084 +
35085 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
35086 + newtable =
35087 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
35088 + else
35089 + newtable = vmalloc(table_sizes[pwr] * elementsize);
35090 +
35091 + *len = table_sizes[pwr];
35092 +
35093 + return newtable;
35094 +}
35095 +
35096 +static int
35097 +init_variables(const struct gr_arg *arg)
35098 +{
35099 + struct task_struct *reaper = &init_task;
35100 + unsigned int stacksize;
35101 +
35102 + subj_map_set.s_size = arg->role_db.num_subjects;
35103 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
35104 + name_set.n_size = arg->role_db.num_objects;
35105 + inodev_set.i_size = arg->role_db.num_objects;
35106 +
35107 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
35108 + !name_set.n_size || !inodev_set.i_size)
35109 + return 1;
35110 +
35111 + if (!gr_init_uidset())
35112 + return 1;
35113 +
35114 + /* set up the stack that holds allocation info */
35115 +
35116 + stacksize = arg->role_db.num_pointers + 5;
35117 +
35118 + if (!acl_alloc_stack_init(stacksize))
35119 + return 1;
35120 +
35121 + /* grab reference for the real root dentry and vfsmount */
35122 + get_fs_root(reaper->fs, &real_root);
35123 +
35124 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
35125 + if (fakefs_obj == NULL)
35126 + return 1;
35127 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
35128 +
35129 + subj_map_set.s_hash =
35130 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
35131 + acl_role_set.r_hash =
35132 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
35133 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
35134 + inodev_set.i_hash =
35135 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
35136 +
35137 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
35138 + !name_set.n_hash || !inodev_set.i_hash)
35139 + return 1;
35140 +
35141 + memset(subj_map_set.s_hash, 0,
35142 + sizeof(struct subject_map *) * subj_map_set.s_size);
35143 + memset(acl_role_set.r_hash, 0,
35144 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
35145 + memset(name_set.n_hash, 0,
35146 + sizeof (struct name_entry *) * name_set.n_size);
35147 + memset(inodev_set.i_hash, 0,
35148 + sizeof (struct inodev_entry *) * inodev_set.i_size);
35149 +
35150 + return 0;
35151 +}
35152 +
35153 +/* free information not needed after startup
35154 + currently contains user->kernel pointer mappings for subjects
35155 +*/
35156 +
35157 +static void
35158 +free_init_variables(void)
35159 +{
35160 + __u32 i;
35161 +
35162 + if (subj_map_set.s_hash) {
35163 + for (i = 0; i < subj_map_set.s_size; i++) {
35164 + if (subj_map_set.s_hash[i]) {
35165 + kfree(subj_map_set.s_hash[i]);
35166 + subj_map_set.s_hash[i] = NULL;
35167 + }
35168 + }
35169 +
35170 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
35171 + PAGE_SIZE)
35172 + kfree(subj_map_set.s_hash);
35173 + else
35174 + vfree(subj_map_set.s_hash);
35175 + }
35176 +
35177 + return;
35178 +}
35179 +
35180 +static void
35181 +free_variables(void)
35182 +{
35183 + struct acl_subject_label *s;
35184 + struct acl_role_label *r;
35185 + struct task_struct *task, *task2;
35186 + unsigned int x;
35187 +
35188 + gr_clear_learn_entries();
35189 +
35190 + read_lock(&tasklist_lock);
35191 + do_each_thread(task2, task) {
35192 + task->acl_sp_role = 0;
35193 + task->acl_role_id = 0;
35194 + task->acl = NULL;
35195 + task->role = NULL;
35196 + } while_each_thread(task2, task);
35197 + read_unlock(&tasklist_lock);
35198 +
35199 + /* release the reference to the real root dentry and vfsmount */
35200 + path_put(&real_root);
35201 +
35202 + /* free all object hash tables */
35203 +
35204 + FOR_EACH_ROLE_START(r)
35205 + if (r->subj_hash == NULL)
35206 + goto next_role;
35207 + FOR_EACH_SUBJECT_START(r, s, x)
35208 + if (s->obj_hash == NULL)
35209 + break;
35210 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
35211 + kfree(s->obj_hash);
35212 + else
35213 + vfree(s->obj_hash);
35214 + FOR_EACH_SUBJECT_END(s, x)
35215 + FOR_EACH_NESTED_SUBJECT_START(r, s)
35216 + if (s->obj_hash == NULL)
35217 + break;
35218 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
35219 + kfree(s->obj_hash);
35220 + else
35221 + vfree(s->obj_hash);
35222 + FOR_EACH_NESTED_SUBJECT_END(s)
35223 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
35224 + kfree(r->subj_hash);
35225 + else
35226 + vfree(r->subj_hash);
35227 + r->subj_hash = NULL;
35228 +next_role:
35229 + FOR_EACH_ROLE_END(r)
35230 +
35231 + acl_free_all();
35232 +
35233 + if (acl_role_set.r_hash) {
35234 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
35235 + PAGE_SIZE)
35236 + kfree(acl_role_set.r_hash);
35237 + else
35238 + vfree(acl_role_set.r_hash);
35239 + }
35240 + if (name_set.n_hash) {
35241 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
35242 + PAGE_SIZE)
35243 + kfree(name_set.n_hash);
35244 + else
35245 + vfree(name_set.n_hash);
35246 + }
35247 +
35248 + if (inodev_set.i_hash) {
35249 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
35250 + PAGE_SIZE)
35251 + kfree(inodev_set.i_hash);
35252 + else
35253 + vfree(inodev_set.i_hash);
35254 + }
35255 +
35256 + gr_free_uidset();
35257 +
35258 + memset(&name_set, 0, sizeof (struct name_db));
35259 + memset(&inodev_set, 0, sizeof (struct inodev_db));
35260 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
35261 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
35262 +
35263 + default_role = NULL;
35264 + role_list = NULL;
35265 +
35266 + return;
35267 +}
35268 +
35269 +static __u32
35270 +count_user_objs(struct acl_object_label *userp)
35271 +{
35272 + struct acl_object_label o_tmp;
35273 + __u32 num = 0;
35274 +
35275 + while (userp) {
35276 + if (copy_from_user(&o_tmp, userp,
35277 + sizeof (struct acl_object_label)))
35278 + break;
35279 +
35280 + userp = o_tmp.prev;
35281 + num++;
35282 + }
35283 +
35284 + return num;
35285 +}
35286 +
35287 +static struct acl_subject_label *
35288 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
35289 +
35290 +static int
35291 +copy_user_glob(struct acl_object_label *obj)
35292 +{
35293 + struct acl_object_label *g_tmp, **guser;
35294 + unsigned int len;
35295 + char *tmp;
35296 +
35297 + if (obj->globbed == NULL)
35298 + return 0;
35299 +
35300 + guser = &obj->globbed;
35301 + while (*guser) {
35302 + g_tmp = (struct acl_object_label *)
35303 + acl_alloc(sizeof (struct acl_object_label));
35304 + if (g_tmp == NULL)
35305 + return -ENOMEM;
35306 +
35307 + if (copy_from_user(g_tmp, *guser,
35308 + sizeof (struct acl_object_label)))
35309 + return -EFAULT;
35310 +
35311 + len = strnlen_user(g_tmp->filename, PATH_MAX);
35312 +
35313 + if (!len || len >= PATH_MAX)
35314 + return -EINVAL;
35315 +
35316 + if ((tmp = (char *) acl_alloc(len)) == NULL)
35317 + return -ENOMEM;
35318 +
35319 + if (copy_from_user(tmp, g_tmp->filename, len))
35320 + return -EFAULT;
35321 + tmp[len-1] = '\0';
35322 + g_tmp->filename = tmp;
35323 +
35324 + *guser = g_tmp;
35325 + guser = &(g_tmp->next);
35326 + }
35327 +
35328 + return 0;
35329 +}
35330 +
35331 +static int
35332 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
35333 + struct acl_role_label *role)
35334 +{
35335 + struct acl_object_label *o_tmp;
35336 + unsigned int len;
35337 + int ret;
35338 + char *tmp;
35339 +
35340 + while (userp) {
35341 + if ((o_tmp = (struct acl_object_label *)
35342 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
35343 + return -ENOMEM;
35344 +
35345 + if (copy_from_user(o_tmp, userp,
35346 + sizeof (struct acl_object_label)))
35347 + return -EFAULT;
35348 +
35349 + userp = o_tmp->prev;
35350 +
35351 + len = strnlen_user(o_tmp->filename, PATH_MAX);
35352 +
35353 + if (!len || len >= PATH_MAX)
35354 + return -EINVAL;
35355 +
35356 + if ((tmp = (char *) acl_alloc(len)) == NULL)
35357 + return -ENOMEM;
35358 +
35359 + if (copy_from_user(tmp, o_tmp->filename, len))
35360 + return -EFAULT;
35361 + tmp[len-1] = '\0';
35362 + o_tmp->filename = tmp;
35363 +
35364 + insert_acl_obj_label(o_tmp, subj);
35365 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
35366 + o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
35367 + return -ENOMEM;
35368 +
35369 + ret = copy_user_glob(o_tmp);
35370 + if (ret)
35371 + return ret;
35372 +
35373 + if (o_tmp->nested) {
35374 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
35375 + if (IS_ERR(o_tmp->nested))
35376 + return PTR_ERR(o_tmp->nested);
35377 +
35378 + /* insert into nested subject list */
35379 + o_tmp->nested->next = role->hash->first;
35380 + role->hash->first = o_tmp->nested;
35381 + }
35382 + }
35383 +
35384 + return 0;
35385 +}
35386 +
35387 +static __u32
35388 +count_user_subjs(struct acl_subject_label *userp)
35389 +{
35390 + struct acl_subject_label s_tmp;
35391 + __u32 num = 0;
35392 +
35393 + while (userp) {
35394 + if (copy_from_user(&s_tmp, userp,
35395 + sizeof (struct acl_subject_label)))
35396 + break;
35397 +
35398 + userp = s_tmp.prev;
35399 + /* do not count nested subjects against this count, since
35400 + they are not included in the hash table, but are
35401 + attached to objects. We have already counted
35402 + the subjects in userspace for the allocation
35403 + stack
35404 + */
35405 + if (!(s_tmp.mode & GR_NESTED))
35406 + num++;
35407 + }
35408 +
35409 + return num;
35410 +}
35411 +
35412 +static int
35413 +copy_user_allowedips(struct acl_role_label *rolep)
35414 +{
35415 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
35416 +
35417 + ruserip = rolep->allowed_ips;
35418 +
35419 + while (ruserip) {
35420 + rlast = rtmp;
35421 +
35422 + if ((rtmp = (struct role_allowed_ip *)
35423 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
35424 + return -ENOMEM;
35425 +
35426 + if (copy_from_user(rtmp, ruserip,
35427 + sizeof (struct role_allowed_ip)))
35428 + return -EFAULT;
35429 +
35430 + ruserip = rtmp->prev;
35431 +
35432 + if (!rlast) {
35433 + rtmp->prev = NULL;
35434 + rolep->allowed_ips = rtmp;
35435 + } else {
35436 + rlast->next = rtmp;
35437 + rtmp->prev = rlast;
35438 + }
35439 +
35440 + if (!ruserip)
35441 + rtmp->next = NULL;
35442 + }
35443 +
35444 + return 0;
35445 +}
35446 +
35447 +static int
35448 +copy_user_transitions(struct acl_role_label *rolep)
35449 +{
35450 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
35451 +
35452 + unsigned int len;
35453 + char *tmp;
35454 +
35455 + rusertp = rolep->transitions;
35456 +
35457 + while (rusertp) {
35458 + rlast = rtmp;
35459 +
35460 + if ((rtmp = (struct role_transition *)
35461 + acl_alloc(sizeof (struct role_transition))) == NULL)
35462 + return -ENOMEM;
35463 +
35464 + if (copy_from_user(rtmp, rusertp,
35465 + sizeof (struct role_transition)))
35466 + return -EFAULT;
35467 +
35468 + rusertp = rtmp->prev;
35469 +
35470 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
35471 +
35472 + if (!len || len >= GR_SPROLE_LEN)
35473 + return -EINVAL;
35474 +
35475 + if ((tmp = (char *) acl_alloc(len)) == NULL)
35476 + return -ENOMEM;
35477 +
35478 + if (copy_from_user(tmp, rtmp->rolename, len))
35479 + return -EFAULT;
35480 + tmp[len-1] = '\0';
35481 + rtmp->rolename = tmp;
35482 +
35483 + if (!rlast) {
35484 + rtmp->prev = NULL;
35485 + rolep->transitions = rtmp;
35486 + } else {
35487 + rlast->next = rtmp;
35488 + rtmp->prev = rlast;
35489 + }
35490 +
35491 + if (!rusertp)
35492 + rtmp->next = NULL;
35493 + }
35494 +
35495 + return 0;
35496 +}
35497 +
35498 +static struct acl_subject_label *
35499 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
35500 +{
35501 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
35502 + unsigned int len;
35503 + char *tmp;
35504 + __u32 num_objs;
35505 + struct acl_ip_label **i_tmp, *i_utmp2;
35506 + struct gr_hash_struct ghash;
35507 + struct subject_map *subjmap;
35508 + unsigned int i_num;
35509 + int err;
35510 +
35511 + s_tmp = lookup_subject_map(userp);
35512 +
35513 + /* we've already copied this subject into the kernel, just return
35514 + the reference to it, and don't copy it over again
35515 + */
35516 + if (s_tmp)
35517 + return(s_tmp);
35518 +
35519 + if ((s_tmp = (struct acl_subject_label *)
35520 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
35521 + return ERR_PTR(-ENOMEM);
35522 +
35523 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
35524 + if (subjmap == NULL)
35525 + return ERR_PTR(-ENOMEM);
35526 +
35527 + subjmap->user = userp;
35528 + subjmap->kernel = s_tmp;
35529 + insert_subj_map_entry(subjmap);
35530 +
35531 + if (copy_from_user(s_tmp, userp,
35532 + sizeof (struct acl_subject_label)))
35533 + return ERR_PTR(-EFAULT);
35534 +
35535 + len = strnlen_user(s_tmp->filename, PATH_MAX);
35536 +
35537 + if (!len || len >= PATH_MAX)
35538 + return ERR_PTR(-EINVAL);
35539 +
35540 + if ((tmp = (char *) acl_alloc(len)) == NULL)
35541 + return ERR_PTR(-ENOMEM);
35542 +
35543 + if (copy_from_user(tmp, s_tmp->filename, len))
35544 + return ERR_PTR(-EFAULT);
35545 + tmp[len-1] = '\0';
35546 + s_tmp->filename = tmp;
35547 +
35548 + if (!strcmp(s_tmp->filename, "/"))
35549 + role->root_label = s_tmp;
35550 +
35551 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
35552 + return ERR_PTR(-EFAULT);
35553 +
35554 + /* copy user and group transition tables */
35555 +
35556 + if (s_tmp->user_trans_num) {
35557 + uid_t *uidlist;
35558 +
35559 + uidlist = (uid_t *)acl_alloc_num(s_tmp->user_trans_num, sizeof(uid_t));
35560 + if (uidlist == NULL)
35561 + return ERR_PTR(-ENOMEM);
35562 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
35563 + return ERR_PTR(-EFAULT);
35564 +
35565 + s_tmp->user_transitions = uidlist;
35566 + }
35567 +
35568 + if (s_tmp->group_trans_num) {
35569 + gid_t *gidlist;
35570 +
35571 + gidlist = (gid_t *)acl_alloc_num(s_tmp->group_trans_num, sizeof(gid_t));
35572 + if (gidlist == NULL)
35573 + return ERR_PTR(-ENOMEM);
35574 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
35575 + return ERR_PTR(-EFAULT);
35576 +
35577 + s_tmp->group_transitions = gidlist;
35578 + }
35579 +
35580 + /* set up object hash table */
35581 + num_objs = count_user_objs(ghash.first);
35582 +
35583 + s_tmp->obj_hash_size = num_objs;
35584 + s_tmp->obj_hash =
35585 + (struct acl_object_label **)
35586 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
35587 +
35588 + if (!s_tmp->obj_hash)
35589 + return ERR_PTR(-ENOMEM);
35590 +
35591 + memset(s_tmp->obj_hash, 0,
35592 + s_tmp->obj_hash_size *
35593 + sizeof (struct acl_object_label *));
35594 +
35595 + /* add in objects */
35596 + err = copy_user_objs(ghash.first, s_tmp, role);
35597 +
35598 + if (err)
35599 + return ERR_PTR(err);
35600 +
35601 + /* set pointer for parent subject */
35602 + if (s_tmp->parent_subject) {
35603 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
35604 +
35605 + if (IS_ERR(s_tmp2))
35606 + return s_tmp2;
35607 +
35608 + s_tmp->parent_subject = s_tmp2;
35609 + }
35610 +
35611 + /* add in ip acls */
35612 +
35613 + if (!s_tmp->ip_num) {
35614 + s_tmp->ips = NULL;
35615 + goto insert;
35616 + }
35617 +
35618 + i_tmp =
35619 + (struct acl_ip_label **) acl_alloc_num(s_tmp->ip_num,
35620 + sizeof (struct acl_ip_label *));
35621 +
35622 + if (!i_tmp)
35623 + return ERR_PTR(-ENOMEM);
35624 +
35625 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
35626 + *(i_tmp + i_num) =
35627 + (struct acl_ip_label *)
35628 + acl_alloc(sizeof (struct acl_ip_label));
35629 + if (!*(i_tmp + i_num))
35630 + return ERR_PTR(-ENOMEM);
35631 +
35632 + if (copy_from_user
35633 + (&i_utmp2, s_tmp->ips + i_num,
35634 + sizeof (struct acl_ip_label *)))
35635 + return ERR_PTR(-EFAULT);
35636 +
35637 + if (copy_from_user
35638 + (*(i_tmp + i_num), i_utmp2,
35639 + sizeof (struct acl_ip_label)))
35640 + return ERR_PTR(-EFAULT);
35641 +
35642 + if ((*(i_tmp + i_num))->iface == NULL)
35643 + continue;
35644 +
35645 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
35646 + if (!len || len >= IFNAMSIZ)
35647 + return ERR_PTR(-EINVAL);
35648 + tmp = acl_alloc(len);
35649 + if (tmp == NULL)
35650 + return ERR_PTR(-ENOMEM);
35651 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
35652 + return ERR_PTR(-EFAULT);
35653 + (*(i_tmp + i_num))->iface = tmp;
35654 + }
35655 +
35656 + s_tmp->ips = i_tmp;
35657 +
35658 +insert:
35659 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
35660 + s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
35661 + return ERR_PTR(-ENOMEM);
35662 +
35663 + return s_tmp;
35664 +}
35665 +
35666 +static int
35667 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
35668 +{
35669 + struct acl_subject_label s_pre;
35670 + struct acl_subject_label * ret;
35671 + int err;
35672 +
35673 + while (userp) {
35674 + if (copy_from_user(&s_pre, userp,
35675 + sizeof (struct acl_subject_label)))
35676 + return -EFAULT;
35677 +
35678 + /* do not add nested subjects here, add
35679 + while parsing objects
35680 + */
35681 +
35682 + if (s_pre.mode & GR_NESTED) {
35683 + userp = s_pre.prev;
35684 + continue;
35685 + }
35686 +
35687 + ret = do_copy_user_subj(userp, role);
35688 +
35689 + err = PTR_ERR(ret);
35690 + if (IS_ERR(ret))
35691 + return err;
35692 +
35693 + insert_acl_subj_label(ret, role);
35694 +
35695 + userp = s_pre.prev;
35696 + }
35697 +
35698 + return 0;
35699 +}
35700 +
35701 +static int
35702 +copy_user_acl(struct gr_arg *arg)
35703 +{
35704 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
35705 + struct sprole_pw *sptmp;
35706 + struct gr_hash_struct *ghash;
35707 + uid_t *domainlist;
35708 + unsigned int r_num;
35709 + unsigned int len;
35710 + char *tmp;
35711 + int err = 0;
35712 + __u16 i;
35713 + __u32 num_subjs;
35714 +
35715 + /* we need a default and kernel role */
35716 + if (arg->role_db.num_roles < 2)
35717 + return -EINVAL;
35718 +
35719 + /* copy special role authentication info from userspace */
35720 +
35721 + num_sprole_pws = arg->num_sprole_pws;
35722 + acl_special_roles = (struct sprole_pw **) acl_alloc_num(num_sprole_pws, sizeof(struct sprole_pw *));
35723 +
35724 + if (!acl_special_roles) {
35725 + err = -ENOMEM;
35726 + goto cleanup;
35727 + }
35728 +
35729 + for (i = 0; i < num_sprole_pws; i++) {
35730 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
35731 + if (!sptmp) {
35732 + err = -ENOMEM;
35733 + goto cleanup;
35734 + }
35735 + if (copy_from_user(sptmp, arg->sprole_pws + i,
35736 + sizeof (struct sprole_pw))) {
35737 + err = -EFAULT;
35738 + goto cleanup;
35739 + }
35740 +
35741 + len =
35742 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
35743 +
35744 + if (!len || len >= GR_SPROLE_LEN) {
35745 + err = -EINVAL;
35746 + goto cleanup;
35747 + }
35748 +
35749 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
35750 + err = -ENOMEM;
35751 + goto cleanup;
35752 + }
35753 +
35754 + if (copy_from_user(tmp, sptmp->rolename, len)) {
35755 + err = -EFAULT;
35756 + goto cleanup;
35757 + }
35758 + tmp[len-1] = '\0';
35759 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
35760 + printk(KERN_ALERT "Copying special role %s\n", tmp);
35761 +#endif
35762 + sptmp->rolename = tmp;
35763 + acl_special_roles[i] = sptmp;
35764 + }
35765 +
35766 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
35767 +
35768 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
35769 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
35770 +
35771 + if (!r_tmp) {
35772 + err = -ENOMEM;
35773 + goto cleanup;
35774 + }
35775 +
35776 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
35777 + sizeof (struct acl_role_label *))) {
35778 + err = -EFAULT;
35779 + goto cleanup;
35780 + }
35781 +
35782 + if (copy_from_user(r_tmp, r_utmp2,
35783 + sizeof (struct acl_role_label))) {
35784 + err = -EFAULT;
35785 + goto cleanup;
35786 + }
35787 +
35788 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
35789 +
35790 + if (!len || len >= PATH_MAX) {
35791 + err = -EINVAL;
35792 + goto cleanup;
35793 + }
35794 +
35795 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
35796 + err = -ENOMEM;
35797 + goto cleanup;
35798 + }
35799 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
35800 + err = -EFAULT;
35801 + goto cleanup;
35802 + }
35803 + tmp[len-1] = '\0';
35804 + r_tmp->rolename = tmp;
35805 +
35806 + if (!strcmp(r_tmp->rolename, "default")
35807 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
35808 + default_role = r_tmp;
35809 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
35810 + kernel_role = r_tmp;
35811 + }
35812 +
35813 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
35814 + err = -ENOMEM;
35815 + goto cleanup;
35816 + }
35817 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
35818 + err = -EFAULT;
35819 + goto cleanup;
35820 + }
35821 +
35822 + r_tmp->hash = ghash;
35823 +
35824 + num_subjs = count_user_subjs(r_tmp->hash->first);
35825 +
35826 + r_tmp->subj_hash_size = num_subjs;
35827 + r_tmp->subj_hash =
35828 + (struct acl_subject_label **)
35829 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
35830 +
35831 + if (!r_tmp->subj_hash) {
35832 + err = -ENOMEM;
35833 + goto cleanup;
35834 + }
35835 +
35836 + err = copy_user_allowedips(r_tmp);
35837 + if (err)
35838 + goto cleanup;
35839 +
35840 + /* copy domain info */
35841 + if (r_tmp->domain_children != NULL) {
35842 + domainlist = acl_alloc_num(r_tmp->domain_child_num, sizeof(uid_t));
35843 + if (domainlist == NULL) {
35844 + err = -ENOMEM;
35845 + goto cleanup;
35846 + }
35847 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
35848 + err = -EFAULT;
35849 + goto cleanup;
35850 + }
35851 + r_tmp->domain_children = domainlist;
35852 + }
35853 +
35854 + err = copy_user_transitions(r_tmp);
35855 + if (err)
35856 + goto cleanup;
35857 +
35858 + memset(r_tmp->subj_hash, 0,
35859 + r_tmp->subj_hash_size *
35860 + sizeof (struct acl_subject_label *));
35861 +
35862 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
35863 +
35864 + if (err)
35865 + goto cleanup;
35866 +
35867 + /* set nested subject list to null */
35868 + r_tmp->hash->first = NULL;
35869 +
35870 + insert_acl_role_label(r_tmp);
35871 + }
35872 +
35873 + goto return_err;
35874 + cleanup:
35875 + free_variables();
35876 + return_err:
35877 + return err;
35878 +
35879 +}
35880 +
35881 +static int
35882 +gracl_init(struct gr_arg *args)
35883 +{
35884 + int error = 0;
35885 +
35886 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
35887 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
35888 +
35889 + if (init_variables(args)) {
35890 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
35891 + error = -ENOMEM;
35892 + free_variables();
35893 + goto out;
35894 + }
35895 +
35896 + error = copy_user_acl(args);
35897 + free_init_variables();
35898 + if (error) {
35899 + free_variables();
35900 + goto out;
35901 + }
35902 +
35903 + if ((error = gr_set_acls(0))) {
35904 + free_variables();
35905 + goto out;
35906 + }
35907 +
35908 + pax_open_kernel();
35909 + gr_status |= GR_READY;
35910 + pax_close_kernel();
35911 +
35912 + out:
35913 + return error;
35914 +}
35915 +
35916 +/* derived from glibc fnmatch() 0: match, 1: no match*/
35917 +
35918 +static int
35919 +glob_match(const char *p, const char *n)
35920 +{
35921 + char c;
35922 +
35923 + while ((c = *p++) != '\0') {
35924 + switch (c) {
35925 + case '?':
35926 + if (*n == '\0')
35927 + return 1;
35928 + else if (*n == '/')
35929 + return 1;
35930 + break;
35931 + case '\\':
35932 + if (*n != c)
35933 + return 1;
35934 + break;
35935 + case '*':
35936 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
35937 + if (*n == '/')
35938 + return 1;
35939 + else if (c == '?') {
35940 + if (*n == '\0')
35941 + return 1;
35942 + else
35943 + ++n;
35944 + }
35945 + }
35946 + if (c == '\0') {
35947 + return 0;
35948 + } else {
35949 + const char *endp;
35950 +
35951 + if ((endp = strchr(n, '/')) == NULL)
35952 + endp = n + strlen(n);
35953 +
35954 + if (c == '[') {
35955 + for (--p; n < endp; ++n)
35956 + if (!glob_match(p, n))
35957 + return 0;
35958 + } else if (c == '/') {
35959 + while (*n != '\0' && *n != '/')
35960 + ++n;
35961 + if (*n == '/' && !glob_match(p, n + 1))
35962 + return 0;
35963 + } else {
35964 + for (--p; n < endp; ++n)
35965 + if (*n == c && !glob_match(p, n))
35966 + return 0;
35967 + }
35968 +
35969 + return 1;
35970 + }
35971 + case '[':
35972 + {
35973 + int not;
35974 + char cold;
35975 +
35976 + if (*n == '\0' || *n == '/')
35977 + return 1;
35978 +
35979 + not = (*p == '!' || *p == '^');
35980 + if (not)
35981 + ++p;
35982 +
35983 + c = *p++;
35984 + for (;;) {
35985 + unsigned char fn = (unsigned char)*n;
35986 +
35987 + if (c == '\0')
35988 + return 1;
35989 + else {
35990 + if (c == fn)
35991 + goto matched;
35992 + cold = c;
35993 + c = *p++;
35994 +
35995 + if (c == '-' && *p != ']') {
35996 + unsigned char cend = *p++;
35997 +
35998 + if (cend == '\0')
35999 + return 1;
36000 +
36001 + if (cold <= fn && fn <= cend)
36002 + goto matched;
36003 +
36004 + c = *p++;
36005 + }
36006 + }
36007 +
36008 + if (c == ']')
36009 + break;
36010 + }
36011 + if (!not)
36012 + return 1;
36013 + break;
36014 + matched:
36015 + while (c != ']') {
36016 + if (c == '\0')
36017 + return 1;
36018 +
36019 + c = *p++;
36020 + }
36021 + if (not)
36022 + return 1;
36023 + }
36024 + break;
36025 + default:
36026 + if (c != *n)
36027 + return 1;
36028 + }
36029 +
36030 + ++n;
36031 + }
36032 +
36033 + if (*n == '\0')
36034 + return 0;
36035 +
36036 + if (*n == '/')
36037 + return 0;
36038 +
36039 + return 1;
36040 +}
36041 +
36042 +static struct acl_object_label *
36043 +chk_glob_label(struct acl_object_label *globbed,
36044 + struct dentry *dentry, struct vfsmount *mnt, char **path)
36045 +{
36046 + struct acl_object_label *tmp;
36047 +
36048 + if (*path == NULL)
36049 + *path = gr_to_filename_nolock(dentry, mnt);
36050 +
36051 + tmp = globbed;
36052 +
36053 + while (tmp) {
36054 + if (!glob_match(tmp->filename, *path))
36055 + return tmp;
36056 + tmp = tmp->next;
36057 + }
36058 +
36059 + return NULL;
36060 +}
36061 +
36062 +static struct acl_object_label *
36063 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
36064 + const ino_t curr_ino, const dev_t curr_dev,
36065 + const struct acl_subject_label *subj, char **path, const int checkglob)
36066 +{
36067 + struct acl_subject_label *tmpsubj;
36068 + struct acl_object_label *retval;
36069 + struct acl_object_label *retval2;
36070 +
36071 + tmpsubj = (struct acl_subject_label *) subj;
36072 + read_lock(&gr_inode_lock);
36073 + do {
36074 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
36075 + if (retval) {
36076 + if (checkglob && retval->globbed) {
36077 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
36078 + (struct vfsmount *)orig_mnt, path);
36079 + if (retval2)
36080 + retval = retval2;
36081 + }
36082 + break;
36083 + }
36084 + } while ((tmpsubj = tmpsubj->parent_subject));
36085 + read_unlock(&gr_inode_lock);
36086 +
36087 + return retval;
36088 +}
36089 +
36090 +static __inline__ struct acl_object_label *
36091 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
36092 + const struct dentry *curr_dentry,
36093 + const struct acl_subject_label *subj, char **path, const int checkglob)
36094 +{
36095 + return __full_lookup(orig_dentry, orig_mnt,
36096 + curr_dentry->d_inode->i_ino,
36097 + curr_dentry->d_inode->i_sb->s_dev, subj, path, checkglob);
36098 +}
36099 +
36100 +static struct acl_object_label *
36101 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36102 + const struct acl_subject_label *subj, char *path, const int checkglob)
36103 +{
36104 + struct dentry *dentry = (struct dentry *) l_dentry;
36105 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
36106 + struct acl_object_label *retval;
36107 +
36108 + spin_lock(&dcache_lock);
36109 +
36110 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
36111 +#ifdef CONFIG_HUGETLBFS
36112 + mnt == hugetlbfs_vfsmount ||
36113 +#endif
36114 + /* ignore Eric Biederman */
36115 + IS_PRIVATE(l_dentry->d_inode))) {
36116 + retval = fakefs_obj;
36117 + goto out;
36118 + }
36119 +
36120 + for (;;) {
36121 + if (dentry == real_root.dentry && mnt == real_root.mnt)
36122 + break;
36123 +
36124 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
36125 + if (mnt->mnt_parent == mnt)
36126 + break;
36127 +
36128 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
36129 + if (retval != NULL)
36130 + goto out;
36131 +
36132 + dentry = mnt->mnt_mountpoint;
36133 + mnt = mnt->mnt_parent;
36134 + continue;
36135 + }
36136 +
36137 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
36138 + if (retval != NULL)
36139 + goto out;
36140 +
36141 + dentry = dentry->d_parent;
36142 + }
36143 +
36144 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
36145 +
36146 + if (retval == NULL)
36147 + retval = full_lookup(l_dentry, l_mnt, real_root.dentry, subj, &path, checkglob);
36148 +out:
36149 + spin_unlock(&dcache_lock);
36150 + return retval;
36151 +}
36152 +
36153 +static __inline__ struct acl_object_label *
36154 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36155 + const struct acl_subject_label *subj)
36156 +{
36157 + char *path = NULL;
36158 + return __chk_obj_label(l_dentry, l_mnt, subj, path, 1);
36159 +}
36160 +
36161 +static __inline__ struct acl_object_label *
36162 +chk_obj_label_noglob(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36163 + const struct acl_subject_label *subj)
36164 +{
36165 + char *path = NULL;
36166 + return __chk_obj_label(l_dentry, l_mnt, subj, path, 0);
36167 +}
36168 +
36169 +static __inline__ struct acl_object_label *
36170 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36171 + const struct acl_subject_label *subj, char *path)
36172 +{
36173 + return __chk_obj_label(l_dentry, l_mnt, subj, path, 1);
36174 +}
36175 +
36176 +static struct acl_subject_label *
36177 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
36178 + const struct acl_role_label *role)
36179 +{
36180 + struct dentry *dentry = (struct dentry *) l_dentry;
36181 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
36182 + struct acl_subject_label *retval;
36183 +
36184 + spin_lock(&dcache_lock);
36185 +
36186 + for (;;) {
36187 + if (dentry == real_root.dentry && mnt == real_root.mnt)
36188 + break;
36189 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
36190 + if (mnt->mnt_parent == mnt)
36191 + break;
36192 +
36193 + read_lock(&gr_inode_lock);
36194 + retval =
36195 + lookup_acl_subj_label(dentry->d_inode->i_ino,
36196 + dentry->d_inode->i_sb->s_dev, role);
36197 + read_unlock(&gr_inode_lock);
36198 + if (retval != NULL)
36199 + goto out;
36200 +
36201 + dentry = mnt->mnt_mountpoint;
36202 + mnt = mnt->mnt_parent;
36203 + continue;
36204 + }
36205 +
36206 + read_lock(&gr_inode_lock);
36207 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
36208 + dentry->d_inode->i_sb->s_dev, role);
36209 + read_unlock(&gr_inode_lock);
36210 + if (retval != NULL)
36211 + goto out;
36212 +
36213 + dentry = dentry->d_parent;
36214 + }
36215 +
36216 + read_lock(&gr_inode_lock);
36217 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
36218 + dentry->d_inode->i_sb->s_dev, role);
36219 + read_unlock(&gr_inode_lock);
36220 +
36221 + if (unlikely(retval == NULL)) {
36222 + read_lock(&gr_inode_lock);
36223 + retval = lookup_acl_subj_label(real_root.dentry->d_inode->i_ino,
36224 + real_root.dentry->d_inode->i_sb->s_dev, role);
36225 + read_unlock(&gr_inode_lock);
36226 + }
36227 +out:
36228 + spin_unlock(&dcache_lock);
36229 +
36230 + return retval;
36231 +}
36232 +
36233 +static void
36234 +gr_log_learn(const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
36235 +{
36236 + struct task_struct *task = current;
36237 + const struct cred *cred = current_cred();
36238 +
36239 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
36240 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
36241 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
36242 + 1UL, 1UL, gr_to_filename(dentry, mnt), (unsigned long) mode, &task->signal->curr_ip);
36243 +
36244 + return;
36245 +}
36246 +
36247 +static void
36248 +gr_log_learn_sysctl(const char *path, const __u32 mode)
36249 +{
36250 + struct task_struct *task = current;
36251 + const struct cred *cred = current_cred();
36252 +
36253 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
36254 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
36255 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
36256 + 1UL, 1UL, path, (unsigned long) mode, &task->signal->curr_ip);
36257 +
36258 + return;
36259 +}
36260 +
36261 +static void
36262 +gr_log_learn_id_change(const char type, const unsigned int real,
36263 + const unsigned int effective, const unsigned int fs)
36264 +{
36265 + struct task_struct *task = current;
36266 + const struct cred *cred = current_cred();
36267 +
36268 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
36269 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
36270 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
36271 + type, real, effective, fs, &task->signal->curr_ip);
36272 +
36273 + return;
36274 +}
36275 +
36276 +__u32
36277 +gr_check_link(const struct dentry * new_dentry,
36278 + const struct dentry * parent_dentry,
36279 + const struct vfsmount * parent_mnt,
36280 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
36281 +{
36282 + struct acl_object_label *obj;
36283 + __u32 oldmode, newmode;
36284 + __u32 needmode;
36285 +
36286 + if (unlikely(!(gr_status & GR_READY)))
36287 + return (GR_CREATE | GR_LINK);
36288 +
36289 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
36290 + oldmode = obj->mode;
36291 +
36292 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
36293 + oldmode |= (GR_CREATE | GR_LINK);
36294 +
36295 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
36296 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
36297 + needmode |= GR_SETID | GR_AUDIT_SETID;
36298 +
36299 + newmode =
36300 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
36301 + oldmode | needmode);
36302 +
36303 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
36304 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
36305 + GR_INHERIT | GR_AUDIT_INHERIT);
36306 +
36307 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
36308 + goto bad;
36309 +
36310 + if ((oldmode & needmode) != needmode)
36311 + goto bad;
36312 +
36313 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
36314 + if ((newmode & needmode) != needmode)
36315 + goto bad;
36316 +
36317 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
36318 + return newmode;
36319 +bad:
36320 + needmode = oldmode;
36321 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
36322 + needmode |= GR_SETID;
36323 +
36324 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
36325 + gr_log_learn(old_dentry, old_mnt, needmode);
36326 + return (GR_CREATE | GR_LINK);
36327 + } else if (newmode & GR_SUPPRESS)
36328 + return GR_SUPPRESS;
36329 + else
36330 + return 0;
36331 +}
36332 +
36333 +__u32
36334 +gr_search_file(const struct dentry * dentry, const __u32 mode,
36335 + const struct vfsmount * mnt)
36336 +{
36337 + __u32 retval = mode;
36338 + struct acl_subject_label *curracl;
36339 + struct acl_object_label *currobj;
36340 +
36341 + if (unlikely(!(gr_status & GR_READY)))
36342 + return (mode & ~GR_AUDITS);
36343 +
36344 + curracl = current->acl;
36345 +
36346 + currobj = chk_obj_label(dentry, mnt, curracl);
36347 + retval = currobj->mode & mode;
36348 +
36349 + if (unlikely
36350 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
36351 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
36352 + __u32 new_mode = mode;
36353 +
36354 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
36355 +
36356 + retval = new_mode;
36357 +
36358 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
36359 + new_mode |= GR_INHERIT;
36360 +
36361 + if (!(mode & GR_NOLEARN))
36362 + gr_log_learn(dentry, mnt, new_mode);
36363 + }
36364 +
36365 + return retval;
36366 +}
36367 +
36368 +__u32
36369 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
36370 + const struct vfsmount * mnt, const __u32 mode)
36371 +{
36372 + struct name_entry *match;
36373 + struct acl_object_label *matchpo;
36374 + struct acl_subject_label *curracl;
36375 + char *path;
36376 + __u32 retval;
36377 +
36378 + if (unlikely(!(gr_status & GR_READY)))
36379 + return (mode & ~GR_AUDITS);
36380 +
36381 + preempt_disable();
36382 + path = gr_to_filename_rbac(new_dentry, mnt);
36383 + match = lookup_name_entry_create(path);
36384 +
36385 + if (!match)
36386 + goto check_parent;
36387 +
36388 + curracl = current->acl;
36389 +
36390 + read_lock(&gr_inode_lock);
36391 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
36392 + read_unlock(&gr_inode_lock);
36393 +
36394 + if (matchpo) {
36395 + if ((matchpo->mode & mode) !=
36396 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
36397 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
36398 + __u32 new_mode = mode;
36399 +
36400 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
36401 +
36402 + gr_log_learn(new_dentry, mnt, new_mode);
36403 +
36404 + preempt_enable();
36405 + return new_mode;
36406 + }
36407 + preempt_enable();
36408 + return (matchpo->mode & mode);
36409 + }
36410 +
36411 + check_parent:
36412 + curracl = current->acl;
36413 +
36414 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
36415 + retval = matchpo->mode & mode;
36416 +
36417 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
36418 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
36419 + __u32 new_mode = mode;
36420 +
36421 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
36422 +
36423 + gr_log_learn(new_dentry, mnt, new_mode);
36424 + preempt_enable();
36425 + return new_mode;
36426 + }
36427 +
36428 + preempt_enable();
36429 + return retval;
36430 +}
36431 +
36432 +int
36433 +gr_check_hidden_task(const struct task_struct *task)
36434 +{
36435 + if (unlikely(!(gr_status & GR_READY)))
36436 + return 0;
36437 +
36438 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
36439 + return 1;
36440 +
36441 + return 0;
36442 +}
36443 +
36444 +int
36445 +gr_check_protected_task(const struct task_struct *task)
36446 +{
36447 + if (unlikely(!(gr_status & GR_READY) || !task))
36448 + return 0;
36449 +
36450 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
36451 + task->acl != current->acl)
36452 + return 1;
36453 +
36454 + return 0;
36455 +}
36456 +
36457 +int
36458 +gr_check_protected_task_fowner(struct pid *pid, enum pid_type type)
36459 +{
36460 + struct task_struct *p;
36461 + int ret = 0;
36462 +
36463 + if (unlikely(!(gr_status & GR_READY) || !pid))
36464 + return ret;
36465 +
36466 + read_lock(&tasklist_lock);
36467 + do_each_pid_task(pid, type, p) {
36468 + if ((p->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
36469 + p->acl != current->acl) {
36470 + ret = 1;
36471 + goto out;
36472 + }
36473 + } while_each_pid_task(pid, type, p);
36474 +out:
36475 + read_unlock(&tasklist_lock);
36476 +
36477 + return ret;
36478 +}
36479 +
36480 +void
36481 +gr_copy_label(struct task_struct *tsk)
36482 +{
36483 + tsk->signal->used_accept = 0;
36484 + tsk->acl_sp_role = 0;
36485 + tsk->acl_role_id = current->acl_role_id;
36486 + tsk->acl = current->acl;
36487 + tsk->role = current->role;
36488 + tsk->signal->curr_ip = current->signal->curr_ip;
36489 + if (current->exec_file)
36490 + get_file(current->exec_file);
36491 + tsk->exec_file = current->exec_file;
36492 + tsk->is_writable = current->is_writable;
36493 + if (unlikely(current->signal->used_accept))
36494 + current->signal->curr_ip = 0;
36495 +
36496 + return;
36497 +}
36498 +
36499 +static void
36500 +gr_set_proc_res(struct task_struct *task)
36501 +{
36502 + struct acl_subject_label *proc;
36503 + unsigned short i;
36504 +
36505 + proc = task->acl;
36506 +
36507 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
36508 + return;
36509 +
36510 + for (i = 0; i < RLIM_NLIMITS; i++) {
36511 + if (!(proc->resmask & (1 << i)))
36512 + continue;
36513 +
36514 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
36515 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
36516 + }
36517 +
36518 + return;
36519 +}
36520 +
36521 +int
36522 +gr_check_user_change(int real, int effective, int fs)
36523 +{
36524 + unsigned int i;
36525 + __u16 num;
36526 + uid_t *uidlist;
36527 + int curuid;
36528 + int realok = 0;
36529 + int effectiveok = 0;
36530 + int fsok = 0;
36531 +
36532 + if (unlikely(!(gr_status & GR_READY)))
36533 + return 0;
36534 +
36535 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
36536 + gr_log_learn_id_change('u', real, effective, fs);
36537 +
36538 + num = current->acl->user_trans_num;
36539 + uidlist = current->acl->user_transitions;
36540 +
36541 + if (uidlist == NULL)
36542 + return 0;
36543 +
36544 + if (real == -1)
36545 + realok = 1;
36546 + if (effective == -1)
36547 + effectiveok = 1;
36548 + if (fs == -1)
36549 + fsok = 1;
36550 +
36551 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
36552 + for (i = 0; i < num; i++) {
36553 + curuid = (int)uidlist[i];
36554 + if (real == curuid)
36555 + realok = 1;
36556 + if (effective == curuid)
36557 + effectiveok = 1;
36558 + if (fs == curuid)
36559 + fsok = 1;
36560 + }
36561 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
36562 + for (i = 0; i < num; i++) {
36563 + curuid = (int)uidlist[i];
36564 + if (real == curuid)
36565 + break;
36566 + if (effective == curuid)
36567 + break;
36568 + if (fs == curuid)
36569 + break;
36570 + }
36571 + /* not in deny list */
36572 + if (i == num) {
36573 + realok = 1;
36574 + effectiveok = 1;
36575 + fsok = 1;
36576 + }
36577 + }
36578 +
36579 + if (realok && effectiveok && fsok)
36580 + return 0;
36581 + else {
36582 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
36583 + return 1;
36584 + }
36585 +}
36586 +
36587 +int
36588 +gr_check_group_change(int real, int effective, int fs)
36589 +{
36590 + unsigned int i;
36591 + __u16 num;
36592 + gid_t *gidlist;
36593 + int curgid;
36594 + int realok = 0;
36595 + int effectiveok = 0;
36596 + int fsok = 0;
36597 +
36598 + if (unlikely(!(gr_status & GR_READY)))
36599 + return 0;
36600 +
36601 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
36602 + gr_log_learn_id_change('g', real, effective, fs);
36603 +
36604 + num = current->acl->group_trans_num;
36605 + gidlist = current->acl->group_transitions;
36606 +
36607 + if (gidlist == NULL)
36608 + return 0;
36609 +
36610 + if (real == -1)
36611 + realok = 1;
36612 + if (effective == -1)
36613 + effectiveok = 1;
36614 + if (fs == -1)
36615 + fsok = 1;
36616 +
36617 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
36618 + for (i = 0; i < num; i++) {
36619 + curgid = (int)gidlist[i];
36620 + if (real == curgid)
36621 + realok = 1;
36622 + if (effective == curgid)
36623 + effectiveok = 1;
36624 + if (fs == curgid)
36625 + fsok = 1;
36626 + }
36627 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
36628 + for (i = 0; i < num; i++) {
36629 + curgid = (int)gidlist[i];
36630 + if (real == curgid)
36631 + break;
36632 + if (effective == curgid)
36633 + break;
36634 + if (fs == curgid)
36635 + break;
36636 + }
36637 + /* not in deny list */
36638 + if (i == num) {
36639 + realok = 1;
36640 + effectiveok = 1;
36641 + fsok = 1;
36642 + }
36643 + }
36644 +
36645 + if (realok && effectiveok && fsok)
36646 + return 0;
36647 + else {
36648 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
36649 + return 1;
36650 + }
36651 +}
36652 +
36653 +void
36654 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
36655 +{
36656 + struct acl_role_label *role = task->role;
36657 + struct acl_subject_label *subj = NULL;
36658 + struct acl_object_label *obj;
36659 + struct file *filp;
36660 +
36661 + if (unlikely(!(gr_status & GR_READY)))
36662 + return;
36663 +
36664 + filp = task->exec_file;
36665 +
36666 + /* kernel process, we'll give them the kernel role */
36667 + if (unlikely(!filp)) {
36668 + task->role = kernel_role;
36669 + task->acl = kernel_role->root_label;
36670 + return;
36671 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
36672 + role = lookup_acl_role_label(task, uid, gid);
36673 +
36674 + /* perform subject lookup in possibly new role
36675 + we can use this result below in the case where role == task->role
36676 + */
36677 + subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
36678 +
36679 + /* if we changed uid/gid, but result in the same role
36680 + and are using inheritance, don't lose the inherited subject
36681 + if current subject is other than what normal lookup
36682 + would result in, we arrived via inheritance, don't
36683 + lose subject
36684 + */
36685 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
36686 + (subj == task->acl)))
36687 + task->acl = subj;
36688 +
36689 + task->role = role;
36690 +
36691 + task->is_writable = 0;
36692 +
36693 + /* ignore additional mmap checks for processes that are writable
36694 + by the default ACL */
36695 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
36696 + if (unlikely(obj->mode & GR_WRITE))
36697 + task->is_writable = 1;
36698 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
36699 + if (unlikely(obj->mode & GR_WRITE))
36700 + task->is_writable = 1;
36701 +
36702 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
36703 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
36704 +#endif
36705 +
36706 + gr_set_proc_res(task);
36707 +
36708 + return;
36709 +}
36710 +
36711 +int
36712 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
36713 + const int unsafe_share)
36714 +{
36715 + struct task_struct *task = current;
36716 + struct acl_subject_label *newacl;
36717 + struct acl_object_label *obj;
36718 + __u32 retmode;
36719 +
36720 + if (unlikely(!(gr_status & GR_READY)))
36721 + return 0;
36722 +
36723 + newacl = chk_subj_label(dentry, mnt, task->role);
36724 +
36725 + task_lock(task);
36726 + if ((((task->ptrace & PT_PTRACED) || unsafe_share) &&
36727 + !(task->acl->mode & GR_POVERRIDE) && (task->acl != newacl) &&
36728 + !(task->role->roletype & GR_ROLE_GOD) &&
36729 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
36730 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))) {
36731 + task_unlock(task);
36732 + if (unsafe_share)
36733 + gr_log_fs_generic(GR_DONT_AUDIT, GR_UNSAFESHARE_EXEC_ACL_MSG, dentry, mnt);
36734 + else
36735 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
36736 + return -EACCES;
36737 + }
36738 + task_unlock(task);
36739 +
36740 + obj = chk_obj_label(dentry, mnt, task->acl);
36741 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
36742 +
36743 + if (!(task->acl->mode & GR_INHERITLEARN) &&
36744 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
36745 + if (obj->nested)
36746 + task->acl = obj->nested;
36747 + else
36748 + task->acl = newacl;
36749 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
36750 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
36751 +
36752 + task->is_writable = 0;
36753 +
36754 + /* ignore additional mmap checks for processes that are writable
36755 + by the default ACL */
36756 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
36757 + if (unlikely(obj->mode & GR_WRITE))
36758 + task->is_writable = 1;
36759 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
36760 + if (unlikely(obj->mode & GR_WRITE))
36761 + task->is_writable = 1;
36762 +
36763 + gr_set_proc_res(task);
36764 +
36765 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
36766 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
36767 +#endif
36768 + return 0;
36769 +}
36770 +
36771 +/* always called with valid inodev ptr */
36772 +static void
36773 +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
36774 +{
36775 + struct acl_object_label *matchpo;
36776 + struct acl_subject_label *matchps;
36777 + struct acl_subject_label *subj;
36778 + struct acl_role_label *role;
36779 + unsigned int x;
36780 +
36781 + FOR_EACH_ROLE_START(role)
36782 + FOR_EACH_SUBJECT_START(role, subj, x)
36783 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
36784 + matchpo->mode |= GR_DELETED;
36785 + FOR_EACH_SUBJECT_END(subj,x)
36786 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
36787 + if (subj->inode == ino && subj->device == dev)
36788 + subj->mode |= GR_DELETED;
36789 + FOR_EACH_NESTED_SUBJECT_END(subj)
36790 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
36791 + matchps->mode |= GR_DELETED;
36792 + FOR_EACH_ROLE_END(role)
36793 +
36794 + inodev->nentry->deleted = 1;
36795 +
36796 + return;
36797 +}
36798 +
36799 +void
36800 +gr_handle_delete(const ino_t ino, const dev_t dev)
36801 +{
36802 + struct inodev_entry *inodev;
36803 +
36804 + if (unlikely(!(gr_status & GR_READY)))
36805 + return;
36806 +
36807 + write_lock(&gr_inode_lock);
36808 + inodev = lookup_inodev_entry(ino, dev);
36809 + if (inodev != NULL)
36810 + do_handle_delete(inodev, ino, dev);
36811 + write_unlock(&gr_inode_lock);
36812 +
36813 + return;
36814 +}
36815 +
36816 +static void
36817 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
36818 + const ino_t newinode, const dev_t newdevice,
36819 + struct acl_subject_label *subj)
36820 +{
36821 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
36822 + struct acl_object_label *match;
36823 +
36824 + match = subj->obj_hash[index];
36825 +
36826 + while (match && (match->inode != oldinode ||
36827 + match->device != olddevice ||
36828 + !(match->mode & GR_DELETED)))
36829 + match = match->next;
36830 +
36831 + if (match && (match->inode == oldinode)
36832 + && (match->device == olddevice)
36833 + && (match->mode & GR_DELETED)) {
36834 + if (match->prev == NULL) {
36835 + subj->obj_hash[index] = match->next;
36836 + if (match->next != NULL)
36837 + match->next->prev = NULL;
36838 + } else {
36839 + match->prev->next = match->next;
36840 + if (match->next != NULL)
36841 + match->next->prev = match->prev;
36842 + }
36843 + match->prev = NULL;
36844 + match->next = NULL;
36845 + match->inode = newinode;
36846 + match->device = newdevice;
36847 + match->mode &= ~GR_DELETED;
36848 +
36849 + insert_acl_obj_label(match, subj);
36850 + }
36851 +
36852 + return;
36853 +}
36854 +
36855 +static void
36856 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
36857 + const ino_t newinode, const dev_t newdevice,
36858 + struct acl_role_label *role)
36859 +{
36860 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
36861 + struct acl_subject_label *match;
36862 +
36863 + match = role->subj_hash[index];
36864 +
36865 + while (match && (match->inode != oldinode ||
36866 + match->device != olddevice ||
36867 + !(match->mode & GR_DELETED)))
36868 + match = match->next;
36869 +
36870 + if (match && (match->inode == oldinode)
36871 + && (match->device == olddevice)
36872 + && (match->mode & GR_DELETED)) {
36873 + if (match->prev == NULL) {
36874 + role->subj_hash[index] = match->next;
36875 + if (match->next != NULL)
36876 + match->next->prev = NULL;
36877 + } else {
36878 + match->prev->next = match->next;
36879 + if (match->next != NULL)
36880 + match->next->prev = match->prev;
36881 + }
36882 + match->prev = NULL;
36883 + match->next = NULL;
36884 + match->inode = newinode;
36885 + match->device = newdevice;
36886 + match->mode &= ~GR_DELETED;
36887 +
36888 + insert_acl_subj_label(match, role);
36889 + }
36890 +
36891 + return;
36892 +}
36893 +
36894 +static void
36895 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
36896 + const ino_t newinode, const dev_t newdevice)
36897 +{
36898 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
36899 + struct inodev_entry *match;
36900 +
36901 + match = inodev_set.i_hash[index];
36902 +
36903 + while (match && (match->nentry->inode != oldinode ||
36904 + match->nentry->device != olddevice || !match->nentry->deleted))
36905 + match = match->next;
36906 +
36907 + if (match && (match->nentry->inode == oldinode)
36908 + && (match->nentry->device == olddevice) &&
36909 + match->nentry->deleted) {
36910 + if (match->prev == NULL) {
36911 + inodev_set.i_hash[index] = match->next;
36912 + if (match->next != NULL)
36913 + match->next->prev = NULL;
36914 + } else {
36915 + match->prev->next = match->next;
36916 + if (match->next != NULL)
36917 + match->next->prev = match->prev;
36918 + }
36919 + match->prev = NULL;
36920 + match->next = NULL;
36921 + match->nentry->inode = newinode;
36922 + match->nentry->device = newdevice;
36923 + match->nentry->deleted = 0;
36924 +
36925 + insert_inodev_entry(match);
36926 + }
36927 +
36928 + return;
36929 +}
36930 +
36931 +static void
36932 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
36933 + const struct vfsmount *mnt)
36934 +{
36935 + struct acl_subject_label *subj;
36936 + struct acl_role_label *role;
36937 + unsigned int x;
36938 +
36939 + FOR_EACH_ROLE_START(role)
36940 + update_acl_subj_label(matchn->inode, matchn->device,
36941 + dentry->d_inode->i_ino,
36942 + dentry->d_inode->i_sb->s_dev, role);
36943 +
36944 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
36945 + if ((subj->inode == dentry->d_inode->i_ino) &&
36946 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
36947 + subj->inode = dentry->d_inode->i_ino;
36948 + subj->device = dentry->d_inode->i_sb->s_dev;
36949 + }
36950 + FOR_EACH_NESTED_SUBJECT_END(subj)
36951 + FOR_EACH_SUBJECT_START(role, subj, x)
36952 + update_acl_obj_label(matchn->inode, matchn->device,
36953 + dentry->d_inode->i_ino,
36954 + dentry->d_inode->i_sb->s_dev, subj);
36955 + FOR_EACH_SUBJECT_END(subj,x)
36956 + FOR_EACH_ROLE_END(role)
36957 +
36958 + update_inodev_entry(matchn->inode, matchn->device,
36959 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
36960 +
36961 + return;
36962 +}
36963 +
36964 +void
36965 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
36966 +{
36967 + struct name_entry *matchn;
36968 +
36969 + if (unlikely(!(gr_status & GR_READY)))
36970 + return;
36971 +
36972 + preempt_disable();
36973 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
36974 +
36975 + if (unlikely((unsigned long)matchn)) {
36976 + write_lock(&gr_inode_lock);
36977 + do_handle_create(matchn, dentry, mnt);
36978 + write_unlock(&gr_inode_lock);
36979 + }
36980 + preempt_enable();
36981 +
36982 + return;
36983 +}
36984 +
36985 +void
36986 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
36987 + struct dentry *old_dentry,
36988 + struct dentry *new_dentry,
36989 + struct vfsmount *mnt, const __u8 replace)
36990 +{
36991 + struct name_entry *matchn;
36992 + struct inodev_entry *inodev;
36993 +
36994 + /* vfs_rename swaps the name and parent link for old_dentry and
36995 + new_dentry
36996 + at this point, old_dentry has the new name, parent link, and inode
36997 + for the renamed file
36998 + if a file is being replaced by a rename, new_dentry has the inode
36999 + and name for the replaced file
37000 + */
37001 +
37002 + if (unlikely(!(gr_status & GR_READY)))
37003 + return;
37004 +
37005 + preempt_disable();
37006 + matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
37007 +
37008 + /* we wouldn't have to check d_inode if it weren't for
37009 + NFS silly-renaming
37010 + */
37011 +
37012 + write_lock(&gr_inode_lock);
37013 + if (unlikely(replace && new_dentry->d_inode)) {
37014 + inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
37015 + new_dentry->d_inode->i_sb->s_dev);
37016 + if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
37017 + do_handle_delete(inodev, new_dentry->d_inode->i_ino,
37018 + new_dentry->d_inode->i_sb->s_dev);
37019 + }
37020 +
37021 + inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
37022 + old_dentry->d_inode->i_sb->s_dev);
37023 + if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
37024 + do_handle_delete(inodev, old_dentry->d_inode->i_ino,
37025 + old_dentry->d_inode->i_sb->s_dev);
37026 +
37027 + if (unlikely((unsigned long)matchn))
37028 + do_handle_create(matchn, old_dentry, mnt);
37029 +
37030 + write_unlock(&gr_inode_lock);
37031 + preempt_enable();
37032 +
37033 + return;
37034 +}
37035 +
37036 +static int
37037 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
37038 + unsigned char **sum)
37039 +{
37040 + struct acl_role_label *r;
37041 + struct role_allowed_ip *ipp;
37042 + struct role_transition *trans;
37043 + unsigned int i;
37044 + int found = 0;
37045 +
37046 + /* check transition table */
37047 +
37048 + for (trans = current->role->transitions; trans; trans = trans->next) {
37049 + if (!strcmp(rolename, trans->rolename)) {
37050 + found = 1;
37051 + break;
37052 + }
37053 + }
37054 +
37055 + if (!found)
37056 + return 0;
37057 +
37058 + /* handle special roles that do not require authentication
37059 + and check ip */
37060 +
37061 + FOR_EACH_ROLE_START(r)
37062 + if (!strcmp(rolename, r->rolename) &&
37063 + (r->roletype & GR_ROLE_SPECIAL)) {
37064 + found = 0;
37065 + if (r->allowed_ips != NULL) {
37066 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
37067 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
37068 + (ntohl(ipp->addr) & ipp->netmask))
37069 + found = 1;
37070 + }
37071 + } else
37072 + found = 2;
37073 + if (!found)
37074 + return 0;
37075 +
37076 + if (((mode == GR_SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
37077 + ((mode == GR_SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
37078 + *salt = NULL;
37079 + *sum = NULL;
37080 + return 1;
37081 + }
37082 + }
37083 + FOR_EACH_ROLE_END(r)
37084 +
37085 + for (i = 0; i < num_sprole_pws; i++) {
37086 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
37087 + *salt = acl_special_roles[i]->salt;
37088 + *sum = acl_special_roles[i]->sum;
37089 + return 1;
37090 + }
37091 + }
37092 +
37093 + return 0;
37094 +}
37095 +
37096 +static void
37097 +assign_special_role(char *rolename)
37098 +{
37099 + struct acl_object_label *obj;
37100 + struct acl_role_label *r;
37101 + struct acl_role_label *assigned = NULL;
37102 + struct task_struct *tsk;
37103 + struct file *filp;
37104 +
37105 + FOR_EACH_ROLE_START(r)
37106 + if (!strcmp(rolename, r->rolename) &&
37107 + (r->roletype & GR_ROLE_SPECIAL)) {
37108 + assigned = r;
37109 + break;
37110 + }
37111 + FOR_EACH_ROLE_END(r)
37112 +
37113 + if (!assigned)
37114 + return;
37115 +
37116 + read_lock(&tasklist_lock);
37117 + read_lock(&grsec_exec_file_lock);
37118 +
37119 + tsk = current->real_parent;
37120 + if (tsk == NULL)
37121 + goto out_unlock;
37122 +
37123 + filp = tsk->exec_file;
37124 + if (filp == NULL)
37125 + goto out_unlock;
37126 +
37127 + tsk->is_writable = 0;
37128 +
37129 + tsk->acl_sp_role = 1;
37130 + tsk->acl_role_id = ++acl_sp_role_value;
37131 + tsk->role = assigned;
37132 + tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
37133 +
37134 + /* ignore additional mmap checks for processes that are writable
37135 + by the default ACL */
37136 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
37137 + if (unlikely(obj->mode & GR_WRITE))
37138 + tsk->is_writable = 1;
37139 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
37140 + if (unlikely(obj->mode & GR_WRITE))
37141 + tsk->is_writable = 1;
37142 +
37143 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
37144 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
37145 +#endif
37146 +
37147 +out_unlock:
37148 + read_unlock(&grsec_exec_file_lock);
37149 + read_unlock(&tasklist_lock);
37150 + return;
37151 +}
37152 +
37153 +int gr_check_secure_terminal(struct task_struct *task)
37154 +{
37155 + struct task_struct *p, *p2, *p3;
37156 + struct files_struct *files;
37157 + struct fdtable *fdt;
37158 + struct file *our_file = NULL, *file;
37159 + int i;
37160 +
37161 + if (task->signal->tty == NULL)
37162 + return 1;
37163 +
37164 + files = get_files_struct(task);
37165 + if (files != NULL) {
37166 + rcu_read_lock();
37167 + fdt = files_fdtable(files);
37168 + for (i=0; i < fdt->max_fds; i++) {
37169 + file = fcheck_files(files, i);
37170 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
37171 + get_file(file);
37172 + our_file = file;
37173 + }
37174 + }
37175 + rcu_read_unlock();
37176 + put_files_struct(files);
37177 + }
37178 +
37179 + if (our_file == NULL)
37180 + return 1;
37181 +
37182 + read_lock(&tasklist_lock);
37183 + do_each_thread(p2, p) {
37184 + files = get_files_struct(p);
37185 + if (files == NULL ||
37186 + (p->signal && p->signal->tty == task->signal->tty)) {
37187 + if (files != NULL)
37188 + put_files_struct(files);
37189 + continue;
37190 + }
37191 + rcu_read_lock();
37192 + fdt = files_fdtable(files);
37193 + for (i=0; i < fdt->max_fds; i++) {
37194 + file = fcheck_files(files, i);
37195 + if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
37196 + file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
37197 + p3 = task;
37198 + while (p3->pid > 0) {
37199 + if (p3 == p)
37200 + break;
37201 + p3 = p3->real_parent;
37202 + }
37203 + if (p3 == p)
37204 + break;
37205 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
37206 + gr_handle_alertkill(p);
37207 + rcu_read_unlock();
37208 + put_files_struct(files);
37209 + read_unlock(&tasklist_lock);
37210 + fput(our_file);
37211 + return 0;
37212 + }
37213 + }
37214 + rcu_read_unlock();
37215 + put_files_struct(files);
37216 + } while_each_thread(p2, p);
37217 + read_unlock(&tasklist_lock);
37218 +
37219 + fput(our_file);
37220 + return 1;
37221 +}
37222 +
37223 +ssize_t
37224 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
37225 +{
37226 + struct gr_arg_wrapper uwrap;
37227 + unsigned char *sprole_salt = NULL;
37228 + unsigned char *sprole_sum = NULL;
37229 + int error = sizeof (struct gr_arg_wrapper);
37230 + int error2 = 0;
37231 +
37232 + down(&gr_dev_sem);
37233 +
37234 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
37235 + error = -EPERM;
37236 + goto out;
37237 + }
37238 +
37239 + if (count != sizeof (struct gr_arg_wrapper)) {
37240 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
37241 + error = -EINVAL;
37242 + goto out;
37243 + }
37244 +
37245 +
37246 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
37247 + gr_auth_expires = 0;
37248 + gr_auth_attempts = 0;
37249 + }
37250 +
37251 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
37252 + error = -EFAULT;
37253 + goto out;
37254 + }
37255 +
37256 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
37257 + error = -EINVAL;
37258 + goto out;
37259 + }
37260 +
37261 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
37262 + error = -EFAULT;
37263 + goto out;
37264 + }
37265 +
37266 + if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_SPROLEPAM &&
37267 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
37268 + time_after(gr_auth_expires, get_seconds())) {
37269 + error = -EBUSY;
37270 + goto out;
37271 + }
37272 +
37273 + /* if non-root trying to do anything other than use a special role,
37274 + do not attempt authentication, do not count towards authentication
37275 + locking
37276 + */
37277 +
37278 + if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_STATUS &&
37279 + gr_usermode->mode != GR_UNSPROLE && gr_usermode->mode != GR_SPROLEPAM &&
37280 + current_uid()) {
37281 + error = -EPERM;
37282 + goto out;
37283 + }
37284 +
37285 + /* ensure pw and special role name are null terminated */
37286 +
37287 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
37288 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
37289 +
37290 + /* Okay.
37291 + * We have our enough of the argument structure..(we have yet
37292 + * to copy_from_user the tables themselves) . Copy the tables
37293 + * only if we need them, i.e. for loading operations. */
37294 +
37295 + switch (gr_usermode->mode) {
37296 + case GR_STATUS:
37297 + if (gr_status & GR_READY) {
37298 + error = 1;
37299 + if (!gr_check_secure_terminal(current))
37300 + error = 3;
37301 + } else
37302 + error = 2;
37303 + goto out;
37304 + case GR_SHUTDOWN:
37305 + if ((gr_status & GR_READY)
37306 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
37307 + pax_open_kernel();
37308 + gr_status &= ~GR_READY;
37309 + pax_close_kernel();
37310 +
37311 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
37312 + free_variables();
37313 + memset(gr_usermode, 0, sizeof (struct gr_arg));
37314 + memset(gr_system_salt, 0, GR_SALT_LEN);
37315 + memset(gr_system_sum, 0, GR_SHA_LEN);
37316 + } else if (gr_status & GR_READY) {
37317 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
37318 + error = -EPERM;
37319 + } else {
37320 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
37321 + error = -EAGAIN;
37322 + }
37323 + break;
37324 + case GR_ENABLE:
37325 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
37326 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
37327 + else {
37328 + if (gr_status & GR_READY)
37329 + error = -EAGAIN;
37330 + else
37331 + error = error2;
37332 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
37333 + }
37334 + break;
37335 + case GR_RELOAD:
37336 + if (!(gr_status & GR_READY)) {
37337 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
37338 + error = -EAGAIN;
37339 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
37340 + lock_kernel();
37341 +
37342 + pax_open_kernel();
37343 + gr_status &= ~GR_READY;
37344 + pax_close_kernel();
37345 +
37346 + free_variables();
37347 + if (!(error2 = gracl_init(gr_usermode))) {
37348 + unlock_kernel();
37349 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
37350 + } else {
37351 + unlock_kernel();
37352 + error = error2;
37353 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
37354 + }
37355 + } else {
37356 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
37357 + error = -EPERM;
37358 + }
37359 + break;
37360 + case GR_SEGVMOD:
37361 + if (unlikely(!(gr_status & GR_READY))) {
37362 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
37363 + error = -EAGAIN;
37364 + break;
37365 + }
37366 +
37367 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
37368 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
37369 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
37370 + struct acl_subject_label *segvacl;
37371 + segvacl =
37372 + lookup_acl_subj_label(gr_usermode->segv_inode,
37373 + gr_usermode->segv_device,
37374 + current->role);
37375 + if (segvacl) {
37376 + segvacl->crashes = 0;
37377 + segvacl->expires = 0;
37378 + }
37379 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
37380 + gr_remove_uid(gr_usermode->segv_uid);
37381 + }
37382 + } else {
37383 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
37384 + error = -EPERM;
37385 + }
37386 + break;
37387 + case GR_SPROLE:
37388 + case GR_SPROLEPAM:
37389 + if (unlikely(!(gr_status & GR_READY))) {
37390 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
37391 + error = -EAGAIN;
37392 + break;
37393 + }
37394 +
37395 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
37396 + current->role->expires = 0;
37397 + current->role->auth_attempts = 0;
37398 + }
37399 +
37400 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
37401 + time_after(current->role->expires, get_seconds())) {
37402 + error = -EBUSY;
37403 + goto out;
37404 + }
37405 +
37406 + if (lookup_special_role_auth
37407 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
37408 + && ((!sprole_salt && !sprole_sum)
37409 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
37410 + char *p = "";
37411 + assign_special_role(gr_usermode->sp_role);
37412 + read_lock(&tasklist_lock);
37413 + if (current->real_parent)
37414 + p = current->real_parent->role->rolename;
37415 + read_unlock(&tasklist_lock);
37416 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
37417 + p, acl_sp_role_value);
37418 + } else {
37419 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
37420 + error = -EPERM;
37421 + if(!(current->role->auth_attempts++))
37422 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
37423 +
37424 + goto out;
37425 + }
37426 + break;
37427 + case GR_UNSPROLE:
37428 + if (unlikely(!(gr_status & GR_READY))) {
37429 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
37430 + error = -EAGAIN;
37431 + break;
37432 + }
37433 +
37434 + if (current->role->roletype & GR_ROLE_SPECIAL) {
37435 + char *p = "";
37436 + int i = 0;
37437 +
37438 + read_lock(&tasklist_lock);
37439 + if (current->real_parent) {
37440 + p = current->real_parent->role->rolename;
37441 + i = current->real_parent->acl_role_id;
37442 + }
37443 + read_unlock(&tasklist_lock);
37444 +
37445 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
37446 + gr_set_acls(1);
37447 + } else {
37448 + error = -EPERM;
37449 + goto out;
37450 + }
37451 + break;
37452 + default:
37453 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
37454 + error = -EINVAL;
37455 + break;
37456 + }
37457 +
37458 + if (error != -EPERM)
37459 + goto out;
37460 +
37461 + if(!(gr_auth_attempts++))
37462 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
37463 +
37464 + out:
37465 + up(&gr_dev_sem);
37466 + return error;
37467 +}
37468 +
37469 +int
37470 +gr_set_acls(const int type)
37471 +{
37472 + struct acl_object_label *obj;
37473 + struct task_struct *task, *task2;
37474 + struct file *filp;
37475 + struct acl_role_label *role = current->role;
37476 + __u16 acl_role_id = current->acl_role_id;
37477 + const struct cred *cred;
37478 + char *tmpname;
37479 + struct name_entry *nmatch;
37480 + struct acl_subject_label *tmpsubj;
37481 +
37482 + rcu_read_lock();
37483 + read_lock(&tasklist_lock);
37484 + read_lock(&grsec_exec_file_lock);
37485 + do_each_thread(task2, task) {
37486 + /* check to see if we're called from the exit handler,
37487 + if so, only replace ACLs that have inherited the admin
37488 + ACL */
37489 +
37490 + if (type && (task->role != role ||
37491 + task->acl_role_id != acl_role_id))
37492 + continue;
37493 +
37494 + task->acl_role_id = 0;
37495 + task->acl_sp_role = 0;
37496 +
37497 + if ((filp = task->exec_file)) {
37498 + cred = __task_cred(task);
37499 + task->role = lookup_acl_role_label(task, cred->uid, cred->gid);
37500 +
37501 + /* the following is to apply the correct subject
37502 + on binaries running when the RBAC system
37503 + is enabled, when the binaries have been
37504 + replaced or deleted since their execution
37505 + -----
37506 + when the RBAC system starts, the inode/dev
37507 + from exec_file will be one the RBAC system
37508 + is unaware of. It only knows the inode/dev
37509 + of the present file on disk, or the absence
37510 + of it.
37511 + */
37512 + preempt_disable();
37513 + tmpname = gr_to_filename_rbac(filp->f_path.dentry, filp->f_path.mnt);
37514 +
37515 + nmatch = lookup_name_entry(tmpname);
37516 + preempt_enable();
37517 + tmpsubj = NULL;
37518 + if (nmatch) {
37519 + if (nmatch->deleted)
37520 + tmpsubj = lookup_acl_subj_label_deleted(nmatch->inode, nmatch->device, task->role);
37521 + else
37522 + tmpsubj = lookup_acl_subj_label(nmatch->inode, nmatch->device, task->role);
37523 + if (tmpsubj != NULL)
37524 + task->acl = tmpsubj;
37525 + }
37526 + if (tmpsubj == NULL)
37527 + task->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
37528 + task->role);
37529 + if (task->acl) {
37530 + struct acl_subject_label *curr;
37531 + curr = task->acl;
37532 +
37533 + task->is_writable = 0;
37534 + /* ignore additional mmap checks for processes that are writable
37535 + by the default ACL */
37536 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
37537 + if (unlikely(obj->mode & GR_WRITE))
37538 + task->is_writable = 1;
37539 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
37540 + if (unlikely(obj->mode & GR_WRITE))
37541 + task->is_writable = 1;
37542 +
37543 + gr_set_proc_res(task);
37544 +
37545 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
37546 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
37547 +#endif
37548 + } else {
37549 + read_unlock(&grsec_exec_file_lock);
37550 + read_unlock(&tasklist_lock);
37551 + rcu_read_unlock();
37552 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
37553 + return 1;
37554 + }
37555 + } else {
37556 + // it's a kernel process
37557 + task->role = kernel_role;
37558 + task->acl = kernel_role->root_label;
37559 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
37560 + task->acl->mode &= ~GR_PROCFIND;
37561 +#endif
37562 + }
37563 + } while_each_thread(task2, task);
37564 + read_unlock(&grsec_exec_file_lock);
37565 + read_unlock(&tasklist_lock);
37566 + rcu_read_unlock();
37567 +
37568 + return 0;
37569 +}
37570 +
37571 +void
37572 +gr_learn_resource(const struct task_struct *task,
37573 + const int res, const unsigned long wanted, const int gt)
37574 +{
37575 + struct acl_subject_label *acl;
37576 + const struct cred *cred;
37577 +
37578 + if (unlikely((gr_status & GR_READY) &&
37579 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
37580 + goto skip_reslog;
37581 +
37582 +#ifdef CONFIG_GRKERNSEC_RESLOG
37583 + gr_log_resource(task, res, wanted, gt);
37584 +#endif
37585 + skip_reslog:
37586 +
37587 + if (unlikely(!(gr_status & GR_READY) || !wanted || res >= GR_NLIMITS))
37588 + return;
37589 +
37590 + acl = task->acl;
37591 +
37592 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
37593 + !(acl->resmask & (1 << (unsigned short) res))))
37594 + return;
37595 +
37596 + if (wanted >= acl->res[res].rlim_cur) {
37597 + unsigned long res_add;
37598 +
37599 + res_add = wanted;
37600 + switch (res) {
37601 + case RLIMIT_CPU:
37602 + res_add += GR_RLIM_CPU_BUMP;
37603 + break;
37604 + case RLIMIT_FSIZE:
37605 + res_add += GR_RLIM_FSIZE_BUMP;
37606 + break;
37607 + case RLIMIT_DATA:
37608 + res_add += GR_RLIM_DATA_BUMP;
37609 + break;
37610 + case RLIMIT_STACK:
37611 + res_add += GR_RLIM_STACK_BUMP;
37612 + break;
37613 + case RLIMIT_CORE:
37614 + res_add += GR_RLIM_CORE_BUMP;
37615 + break;
37616 + case RLIMIT_RSS:
37617 + res_add += GR_RLIM_RSS_BUMP;
37618 + break;
37619 + case RLIMIT_NPROC:
37620 + res_add += GR_RLIM_NPROC_BUMP;
37621 + break;
37622 + case RLIMIT_NOFILE:
37623 + res_add += GR_RLIM_NOFILE_BUMP;
37624 + break;
37625 + case RLIMIT_MEMLOCK:
37626 + res_add += GR_RLIM_MEMLOCK_BUMP;
37627 + break;
37628 + case RLIMIT_AS:
37629 + res_add += GR_RLIM_AS_BUMP;
37630 + break;
37631 + case RLIMIT_LOCKS:
37632 + res_add += GR_RLIM_LOCKS_BUMP;
37633 + break;
37634 + case RLIMIT_SIGPENDING:
37635 + res_add += GR_RLIM_SIGPENDING_BUMP;
37636 + break;
37637 + case RLIMIT_MSGQUEUE:
37638 + res_add += GR_RLIM_MSGQUEUE_BUMP;
37639 + break;
37640 + case RLIMIT_NICE:
37641 + res_add += GR_RLIM_NICE_BUMP;
37642 + break;
37643 + case RLIMIT_RTPRIO:
37644 + res_add += GR_RLIM_RTPRIO_BUMP;
37645 + break;
37646 + case RLIMIT_RTTIME:
37647 + res_add += GR_RLIM_RTTIME_BUMP;
37648 + break;
37649 + }
37650 +
37651 + acl->res[res].rlim_cur = res_add;
37652 +
37653 + if (wanted > acl->res[res].rlim_max)
37654 + acl->res[res].rlim_max = res_add;
37655 +
37656 + /* only log the subject filename, since resource logging is supported for
37657 + single-subject learning only */
37658 + rcu_read_lock();
37659 + cred = __task_cred(task);
37660 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
37661 + task->role->roletype, cred->uid, cred->gid, acl->filename,
37662 + acl->filename, acl->res[res].rlim_cur, acl->res[res].rlim_max,
37663 + "", (unsigned long) res, &task->signal->curr_ip);
37664 + rcu_read_unlock();
37665 + }
37666 +
37667 + return;
37668 +}
37669 +
37670 +#if defined(CONFIG_PAX_HAVE_ACL_FLAGS) && (defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR))
37671 +void
37672 +pax_set_initial_flags(struct linux_binprm *bprm)
37673 +{
37674 + struct task_struct *task = current;
37675 + struct acl_subject_label *proc;
37676 + unsigned long flags;
37677 +
37678 + if (unlikely(!(gr_status & GR_READY)))
37679 + return;
37680 +
37681 + flags = pax_get_flags(task);
37682 +
37683 + proc = task->acl;
37684 +
37685 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
37686 + flags &= ~MF_PAX_PAGEEXEC;
37687 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
37688 + flags &= ~MF_PAX_SEGMEXEC;
37689 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
37690 + flags &= ~MF_PAX_RANDMMAP;
37691 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
37692 + flags &= ~MF_PAX_EMUTRAMP;
37693 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
37694 + flags &= ~MF_PAX_MPROTECT;
37695 +
37696 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
37697 + flags |= MF_PAX_PAGEEXEC;
37698 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
37699 + flags |= MF_PAX_SEGMEXEC;
37700 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
37701 + flags |= MF_PAX_RANDMMAP;
37702 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
37703 + flags |= MF_PAX_EMUTRAMP;
37704 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
37705 + flags |= MF_PAX_MPROTECT;
37706 +
37707 + pax_set_flags(task, flags);
37708 +
37709 + return;
37710 +}
37711 +#endif
37712 +
37713 +#ifdef CONFIG_SYSCTL
37714 +/* Eric Biederman likes breaking userland ABI and every inode-based security
37715 + system to save 35kb of memory */
37716 +
37717 +/* we modify the passed in filename, but adjust it back before returning */
37718 +static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
37719 +{
37720 + struct name_entry *nmatch;
37721 + char *p, *lastp = NULL;
37722 + struct acl_object_label *obj = NULL, *tmp;
37723 + struct acl_subject_label *tmpsubj;
37724 + char c = '\0';
37725 +
37726 + read_lock(&gr_inode_lock);
37727 +
37728 + p = name + len - 1;
37729 + do {
37730 + nmatch = lookup_name_entry(name);
37731 + if (lastp != NULL)
37732 + *lastp = c;
37733 +
37734 + if (nmatch == NULL)
37735 + goto next_component;
37736 + tmpsubj = current->acl;
37737 + do {
37738 + obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
37739 + if (obj != NULL) {
37740 + tmp = obj->globbed;
37741 + while (tmp) {
37742 + if (!glob_match(tmp->filename, name)) {
37743 + obj = tmp;
37744 + goto found_obj;
37745 + }
37746 + tmp = tmp->next;
37747 + }
37748 + goto found_obj;
37749 + }
37750 + } while ((tmpsubj = tmpsubj->parent_subject));
37751 +next_component:
37752 + /* end case */
37753 + if (p == name)
37754 + break;
37755 +
37756 + while (*p != '/')
37757 + p--;
37758 + if (p == name)
37759 + lastp = p + 1;
37760 + else {
37761 + lastp = p;
37762 + p--;
37763 + }
37764 + c = *lastp;
37765 + *lastp = '\0';
37766 + } while (1);
37767 +found_obj:
37768 + read_unlock(&gr_inode_lock);
37769 + /* obj returned will always be non-null */
37770 + return obj;
37771 +}
37772 +
37773 +/* returns 0 when allowing, non-zero on error
37774 + op of 0 is used for readdir, so we don't log the names of hidden files
37775 +*/
37776 +__u32
37777 +gr_handle_sysctl(const struct ctl_table *table, const int op)
37778 +{
37779 + struct ctl_table *tmp;
37780 + const char *proc_sys = "/proc/sys";
37781 + char *path;
37782 + struct acl_object_label *obj;
37783 + unsigned short len = 0, pos = 0, depth = 0, i;
37784 + __u32 err = 0;
37785 + __u32 mode = 0;
37786 +
37787 + if (unlikely(!(gr_status & GR_READY)))
37788 + return 0;
37789 +
37790 + /* for now, ignore operations on non-sysctl entries if it's not a
37791 + readdir*/
37792 + if (table->child != NULL && op != 0)
37793 + return 0;
37794 +
37795 + mode |= GR_FIND;
37796 + /* it's only a read if it's an entry, read on dirs is for readdir */
37797 + if (op & MAY_READ)
37798 + mode |= GR_READ;
37799 + if (op & MAY_WRITE)
37800 + mode |= GR_WRITE;
37801 +
37802 + preempt_disable();
37803 +
37804 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
37805 +
37806 + /* it's only a read/write if it's an actual entry, not a dir
37807 + (which are opened for readdir)
37808 + */
37809 +
37810 + /* convert the requested sysctl entry into a pathname */
37811 +
37812 + for (tmp = (struct ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
37813 + len += strlen(tmp->procname);
37814 + len++;
37815 + depth++;
37816 + }
37817 +
37818 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
37819 + /* deny */
37820 + goto out;
37821 + }
37822 +
37823 + memset(path, 0, PAGE_SIZE);
37824 +
37825 + memcpy(path, proc_sys, strlen(proc_sys));
37826 +
37827 + pos += strlen(proc_sys);
37828 +
37829 + for (; depth > 0; depth--) {
37830 + path[pos] = '/';
37831 + pos++;
37832 + for (i = 1, tmp = (struct ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
37833 + if (depth == i) {
37834 + memcpy(path + pos, tmp->procname,
37835 + strlen(tmp->procname));
37836 + pos += strlen(tmp->procname);
37837 + }
37838 + i++;
37839 + }
37840 + }
37841 +
37842 + obj = gr_lookup_by_name(path, pos);
37843 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
37844 +
37845 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
37846 + ((err & mode) != mode))) {
37847 + __u32 new_mode = mode;
37848 +
37849 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
37850 +
37851 + err = 0;
37852 + gr_log_learn_sysctl(path, new_mode);
37853 + } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
37854 + gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
37855 + err = -ENOENT;
37856 + } else if (!(err & GR_FIND)) {
37857 + err = -ENOENT;
37858 + } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
37859 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
37860 + path, (mode & GR_READ) ? " reading" : "",
37861 + (mode & GR_WRITE) ? " writing" : "");
37862 + err = -EACCES;
37863 + } else if ((err & mode) != mode) {
37864 + err = -EACCES;
37865 + } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
37866 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
37867 + path, (mode & GR_READ) ? " reading" : "",
37868 + (mode & GR_WRITE) ? " writing" : "");
37869 + err = 0;
37870 + } else
37871 + err = 0;
37872 +
37873 + out:
37874 + preempt_enable();
37875 +
37876 + return err;
37877 +}
37878 +#endif
37879 +
37880 +int
37881 +gr_handle_proc_ptrace(struct task_struct *task)
37882 +{
37883 + struct file *filp;
37884 + struct task_struct *tmp = task;
37885 + struct task_struct *curtemp = current;
37886 + __u32 retmode;
37887 +
37888 +#ifndef CONFIG_GRKERNSEC_HARDEN_PTRACE
37889 + if (unlikely(!(gr_status & GR_READY)))
37890 + return 0;
37891 +#endif
37892 +
37893 + read_lock(&tasklist_lock);
37894 + read_lock(&grsec_exec_file_lock);
37895 + filp = task->exec_file;
37896 +
37897 + while (tmp->pid > 0) {
37898 + if (tmp == curtemp)
37899 + break;
37900 + tmp = tmp->real_parent;
37901 + }
37902 +
37903 + if (!filp || (tmp->pid == 0 && ((grsec_enable_harden_ptrace && current_uid() && !(gr_status & GR_READY)) ||
37904 + ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE))))) {
37905 + read_unlock(&grsec_exec_file_lock);
37906 + read_unlock(&tasklist_lock);
37907 + return 1;
37908 + }
37909 +
37910 +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
37911 + if (!(gr_status & GR_READY)) {
37912 + read_unlock(&grsec_exec_file_lock);
37913 + read_unlock(&tasklist_lock);
37914 + return 0;
37915 + }
37916 +#endif
37917 +
37918 + retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
37919 + read_unlock(&grsec_exec_file_lock);
37920 + read_unlock(&tasklist_lock);
37921 +
37922 + if (retmode & GR_NOPTRACE)
37923 + return 1;
37924 +
37925 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
37926 + && (current->acl != task->acl || (current->acl != current->role->root_label
37927 + && current->pid != task->pid)))
37928 + return 1;
37929 +
37930 + return 0;
37931 +}
37932 +
37933 +void task_grsec_rbac(struct seq_file *m, struct task_struct *p)
37934 +{
37935 + if (unlikely(!(gr_status & GR_READY)))
37936 + return;
37937 +
37938 + if (!(current->role->roletype & GR_ROLE_GOD))
37939 + return;
37940 +
37941 + seq_printf(m, "RBAC:\t%.64s:%c:%.950s\n",
37942 + p->role->rolename, gr_task_roletype_to_char(p),
37943 + p->acl->filename);
37944 +}
37945 +
37946 +int
37947 +gr_handle_ptrace(struct task_struct *task, const long request)
37948 +{
37949 + struct task_struct *tmp = task;
37950 + struct task_struct *curtemp = current;
37951 + __u32 retmode;
37952 +
37953 +#ifndef CONFIG_GRKERNSEC_HARDEN_PTRACE
37954 + if (unlikely(!(gr_status & GR_READY)))
37955 + return 0;
37956 +#endif
37957 +
37958 + read_lock(&tasklist_lock);
37959 + while (tmp->pid > 0) {
37960 + if (tmp == curtemp)
37961 + break;
37962 + tmp = tmp->real_parent;
37963 + }
37964 +
37965 + if (tmp->pid == 0 && ((grsec_enable_harden_ptrace && current_uid() && !(gr_status & GR_READY)) ||
37966 + ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE)))) {
37967 + read_unlock(&tasklist_lock);
37968 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
37969 + return 1;
37970 + }
37971 + read_unlock(&tasklist_lock);
37972 +
37973 +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
37974 + if (!(gr_status & GR_READY))
37975 + return 0;
37976 +#endif
37977 +
37978 + read_lock(&grsec_exec_file_lock);
37979 + if (unlikely(!task->exec_file)) {
37980 + read_unlock(&grsec_exec_file_lock);
37981 + return 0;
37982 + }
37983 +
37984 + retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
37985 + read_unlock(&grsec_exec_file_lock);
37986 +
37987 + if (retmode & GR_NOPTRACE) {
37988 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
37989 + return 1;
37990 + }
37991 +
37992 + if (retmode & GR_PTRACERD) {
37993 + switch (request) {
37994 + case PTRACE_POKETEXT:
37995 + case PTRACE_POKEDATA:
37996 + case PTRACE_POKEUSR:
37997 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
37998 + case PTRACE_SETREGS:
37999 + case PTRACE_SETFPREGS:
38000 +#endif
38001 +#ifdef CONFIG_X86
38002 + case PTRACE_SETFPXREGS:
38003 +#endif
38004 +#ifdef CONFIG_ALTIVEC
38005 + case PTRACE_SETVRREGS:
38006 +#endif
38007 + return 1;
38008 + default:
38009 + return 0;
38010 + }
38011 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
38012 + !(current->role->roletype & GR_ROLE_GOD) &&
38013 + (current->acl != task->acl)) {
38014 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
38015 + return 1;
38016 + }
38017 +
38018 + return 0;
38019 +}
38020 +
38021 +static int is_writable_mmap(const struct file *filp)
38022 +{
38023 + struct task_struct *task = current;
38024 + struct acl_object_label *obj, *obj2;
38025 +
38026 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
38027 + !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode) && filp->f_path.mnt != shm_mnt) {
38028 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
38029 + obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
38030 + task->role->root_label);
38031 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
38032 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
38033 + return 1;
38034 + }
38035 + }
38036 + return 0;
38037 +}
38038 +
38039 +int
38040 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
38041 +{
38042 + __u32 mode;
38043 +
38044 + if (unlikely(!file || !(prot & PROT_EXEC)))
38045 + return 1;
38046 +
38047 + if (is_writable_mmap(file))
38048 + return 0;
38049 +
38050 + mode =
38051 + gr_search_file(file->f_path.dentry,
38052 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
38053 + file->f_path.mnt);
38054 +
38055 + if (!gr_tpe_allow(file))
38056 + return 0;
38057 +
38058 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
38059 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
38060 + return 0;
38061 + } else if (unlikely(!(mode & GR_EXEC))) {
38062 + return 0;
38063 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
38064 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
38065 + return 1;
38066 + }
38067 +
38068 + return 1;
38069 +}
38070 +
38071 +int
38072 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
38073 +{
38074 + __u32 mode;
38075 +
38076 + if (unlikely(!file || !(prot & PROT_EXEC)))
38077 + return 1;
38078 +
38079 + if (is_writable_mmap(file))
38080 + return 0;
38081 +
38082 + mode =
38083 + gr_search_file(file->f_path.dentry,
38084 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
38085 + file->f_path.mnt);
38086 +
38087 + if (!gr_tpe_allow(file))
38088 + return 0;
38089 +
38090 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
38091 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
38092 + return 0;
38093 + } else if (unlikely(!(mode & GR_EXEC))) {
38094 + return 0;
38095 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
38096 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
38097 + return 1;
38098 + }
38099 +
38100 + return 1;
38101 +}
38102 +
38103 +void
38104 +gr_acl_handle_psacct(struct task_struct *task, const long code)
38105 +{
38106 + unsigned long runtime;
38107 + unsigned long cputime;
38108 + unsigned int wday, cday;
38109 + __u8 whr, chr;
38110 + __u8 wmin, cmin;
38111 + __u8 wsec, csec;
38112 + struct timespec timeval;
38113 +
38114 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
38115 + !(task->acl->mode & GR_PROCACCT)))
38116 + return;
38117 +
38118 + do_posix_clock_monotonic_gettime(&timeval);
38119 + runtime = timeval.tv_sec - task->start_time.tv_sec;
38120 + wday = runtime / (3600 * 24);
38121 + runtime -= wday * (3600 * 24);
38122 + whr = runtime / 3600;
38123 + runtime -= whr * 3600;
38124 + wmin = runtime / 60;
38125 + runtime -= wmin * 60;
38126 + wsec = runtime;
38127 +
38128 + cputime = (task->utime + task->stime) / HZ;
38129 + cday = cputime / (3600 * 24);
38130 + cputime -= cday * (3600 * 24);
38131 + chr = cputime / 3600;
38132 + cputime -= chr * 3600;
38133 + cmin = cputime / 60;
38134 + cputime -= cmin * 60;
38135 + csec = cputime;
38136 +
38137 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
38138 +
38139 + return;
38140 +}
38141 +
38142 +void gr_set_kernel_label(struct task_struct *task)
38143 +{
38144 + if (gr_status & GR_READY) {
38145 + task->role = kernel_role;
38146 + task->acl = kernel_role->root_label;
38147 + }
38148 + return;
38149 +}
38150 +
38151 +#ifdef CONFIG_TASKSTATS
38152 +int gr_is_taskstats_denied(int pid)
38153 +{
38154 + struct task_struct *task;
38155 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
38156 + const struct cred *cred;
38157 +#endif
38158 + int ret = 0;
38159 +
38160 + /* restrict taskstats viewing to un-chrooted root users
38161 + who have the 'view' subject flag if the RBAC system is enabled
38162 + */
38163 +
38164 + rcu_read_lock();
38165 + read_lock(&tasklist_lock);
38166 + task = find_task_by_vpid(pid);
38167 + if (task) {
38168 +#ifdef CONFIG_GRKERNSEC_CHROOT
38169 + if (proc_is_chrooted(task))
38170 + ret = -EACCES;
38171 +#endif
38172 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
38173 + cred = __task_cred(task);
38174 +#ifdef CONFIG_GRKERNSEC_PROC_USER
38175 + if (cred->uid != 0)
38176 + ret = -EACCES;
38177 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
38178 + if (cred->uid != 0 && !groups_search(cred->group_info, CONFIG_GRKERNSEC_PROC_GID))
38179 + ret = -EACCES;
38180 +#endif
38181 +#endif
38182 + if (gr_status & GR_READY) {
38183 + if (!(task->acl->mode & GR_VIEW))
38184 + ret = -EACCES;
38185 + }
38186 + } else
38187 + ret = -ENOENT;
38188 +
38189 + read_unlock(&tasklist_lock);
38190 + rcu_read_unlock();
38191 +
38192 + return ret;
38193 +}
38194 +#endif
38195 +
38196 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
38197 +{
38198 + struct task_struct *task = current;
38199 + struct dentry *dentry = file->f_path.dentry;
38200 + struct vfsmount *mnt = file->f_path.mnt;
38201 + struct acl_object_label *obj, *tmp;
38202 + struct acl_subject_label *subj;
38203 + unsigned int bufsize;
38204 + int is_not_root;
38205 + char *path;
38206 +
38207 + if (unlikely(!(gr_status & GR_READY)))
38208 + return 1;
38209 +
38210 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
38211 + return 1;
38212 +
38213 + /* ignore Eric Biederman */
38214 + if (IS_PRIVATE(dentry->d_inode))
38215 + return 1;
38216 +
38217 + subj = task->acl;
38218 + do {
38219 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
38220 + if (obj != NULL)
38221 + return (obj->mode & GR_FIND) ? 1 : 0;
38222 + } while ((subj = subj->parent_subject));
38223 +
38224 + /* this is purely an optimization since we're looking for an object
38225 + for the directory we're doing a readdir on
38226 + if it's possible for any globbed object to match the entry we're
38227 + filling into the directory, then the object we find here will be
38228 + an anchor point with attached globbed objects
38229 + */
38230 + obj = chk_obj_label_noglob(dentry, mnt, task->acl);
38231 + if (obj->globbed == NULL)
38232 + return (obj->mode & GR_FIND) ? 1 : 0;
38233 +
38234 + is_not_root = ((obj->filename[0] == '/') &&
38235 + (obj->filename[1] == '\0')) ? 0 : 1;
38236 + bufsize = PAGE_SIZE - namelen - is_not_root;
38237 +
38238 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
38239 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
38240 + return 1;
38241 +
38242 + preempt_disable();
38243 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
38244 + bufsize);
38245 +
38246 + bufsize = strlen(path);
38247 +
38248 + /* if base is "/", don't append an additional slash */
38249 + if (is_not_root)
38250 + *(path + bufsize) = '/';
38251 + memcpy(path + bufsize + is_not_root, name, namelen);
38252 + *(path + bufsize + namelen + is_not_root) = '\0';
38253 +
38254 + tmp = obj->globbed;
38255 + while (tmp) {
38256 + if (!glob_match(tmp->filename, path)) {
38257 + preempt_enable();
38258 + return (tmp->mode & GR_FIND) ? 1 : 0;
38259 + }
38260 + tmp = tmp->next;
38261 + }
38262 + preempt_enable();
38263 + return (obj->mode & GR_FIND) ? 1 : 0;
38264 +}
38265 +
38266 +#ifdef CONFIG_NETFILTER_XT_MATCH_GRADM_MODULE
38267 +EXPORT_SYMBOL(gr_acl_is_enabled);
38268 +#endif
38269 +EXPORT_SYMBOL(gr_learn_resource);
38270 +EXPORT_SYMBOL(gr_set_kernel_label);
38271 +#ifdef CONFIG_SECURITY
38272 +EXPORT_SYMBOL(gr_check_user_change);
38273 +EXPORT_SYMBOL(gr_check_group_change);
38274 +#endif
38275 +
38276 diff -urNp linux-2.6.36/grsecurity/gracl_cap.c linux-2.6.36/grsecurity/gracl_cap.c
38277 --- linux-2.6.36/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
38278 +++ linux-2.6.36/grsecurity/gracl_cap.c 2010-11-06 18:58:50.000000000 -0400
38279 @@ -0,0 +1,138 @@
38280 +#include <linux/kernel.h>
38281 +#include <linux/module.h>
38282 +#include <linux/sched.h>
38283 +#include <linux/gracl.h>
38284 +#include <linux/grsecurity.h>
38285 +#include <linux/grinternal.h>
38286 +
38287 +static const char *captab_log[] = {
38288 + "CAP_CHOWN",
38289 + "CAP_DAC_OVERRIDE",
38290 + "CAP_DAC_READ_SEARCH",
38291 + "CAP_FOWNER",
38292 + "CAP_FSETID",
38293 + "CAP_KILL",
38294 + "CAP_SETGID",
38295 + "CAP_SETUID",
38296 + "CAP_SETPCAP",
38297 + "CAP_LINUX_IMMUTABLE",
38298 + "CAP_NET_BIND_SERVICE",
38299 + "CAP_NET_BROADCAST",
38300 + "CAP_NET_ADMIN",
38301 + "CAP_NET_RAW",
38302 + "CAP_IPC_LOCK",
38303 + "CAP_IPC_OWNER",
38304 + "CAP_SYS_MODULE",
38305 + "CAP_SYS_RAWIO",
38306 + "CAP_SYS_CHROOT",
38307 + "CAP_SYS_PTRACE",
38308 + "CAP_SYS_PACCT",
38309 + "CAP_SYS_ADMIN",
38310 + "CAP_SYS_BOOT",
38311 + "CAP_SYS_NICE",
38312 + "CAP_SYS_RESOURCE",
38313 + "CAP_SYS_TIME",
38314 + "CAP_SYS_TTY_CONFIG",
38315 + "CAP_MKNOD",
38316 + "CAP_LEASE",
38317 + "CAP_AUDIT_WRITE",
38318 + "CAP_AUDIT_CONTROL",
38319 + "CAP_SETFCAP",
38320 + "CAP_MAC_OVERRIDE",
38321 + "CAP_MAC_ADMIN"
38322 +};
38323 +
38324 +EXPORT_SYMBOL(gr_is_capable);
38325 +EXPORT_SYMBOL(gr_is_capable_nolog);
38326 +
38327 +int
38328 +gr_is_capable(const int cap)
38329 +{
38330 + struct task_struct *task = current;
38331 + const struct cred *cred = current_cred();
38332 + struct acl_subject_label *curracl;
38333 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
38334 + kernel_cap_t cap_audit = __cap_empty_set;
38335 +
38336 + if (!gr_acl_is_enabled())
38337 + return 1;
38338 +
38339 + curracl = task->acl;
38340 +
38341 + cap_drop = curracl->cap_lower;
38342 + cap_mask = curracl->cap_mask;
38343 + cap_audit = curracl->cap_invert_audit;
38344 +
38345 + while ((curracl = curracl->parent_subject)) {
38346 + /* if the cap isn't specified in the current computed mask but is specified in the
38347 + current level subject, and is lowered in the current level subject, then add
38348 + it to the set of dropped capabilities
38349 + otherwise, add the current level subject's mask to the current computed mask
38350 + */
38351 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
38352 + cap_raise(cap_mask, cap);
38353 + if (cap_raised(curracl->cap_lower, cap))
38354 + cap_raise(cap_drop, cap);
38355 + if (cap_raised(curracl->cap_invert_audit, cap))
38356 + cap_raise(cap_audit, cap);
38357 + }
38358 + }
38359 +
38360 + if (!cap_raised(cap_drop, cap)) {
38361 + if (cap_raised(cap_audit, cap))
38362 + gr_log_cap(GR_DO_AUDIT, GR_CAP_ACL_MSG2, task, captab_log[cap]);
38363 + return 1;
38364 + }
38365 +
38366 + curracl = task->acl;
38367 +
38368 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
38369 + && cap_raised(cred->cap_effective, cap)) {
38370 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
38371 + task->role->roletype, cred->uid,
38372 + cred->gid, task->exec_file ?
38373 + gr_to_filename(task->exec_file->f_path.dentry,
38374 + task->exec_file->f_path.mnt) : curracl->filename,
38375 + curracl->filename, 0UL,
38376 + 0UL, "", (unsigned long) cap, &task->signal->curr_ip);
38377 + return 1;
38378 + }
38379 +
38380 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(cred->cap_effective, cap) && !cap_raised(cap_audit, cap))
38381 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
38382 + return 0;
38383 +}
38384 +
38385 +int
38386 +gr_is_capable_nolog(const int cap)
38387 +{
38388 + struct acl_subject_label *curracl;
38389 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
38390 +
38391 + if (!gr_acl_is_enabled())
38392 + return 1;
38393 +
38394 + curracl = current->acl;
38395 +
38396 + cap_drop = curracl->cap_lower;
38397 + cap_mask = curracl->cap_mask;
38398 +
38399 + while ((curracl = curracl->parent_subject)) {
38400 + /* if the cap isn't specified in the current computed mask but is specified in the
38401 + current level subject, and is lowered in the current level subject, then add
38402 + it to the set of dropped capabilities
38403 + otherwise, add the current level subject's mask to the current computed mask
38404 + */
38405 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
38406 + cap_raise(cap_mask, cap);
38407 + if (cap_raised(curracl->cap_lower, cap))
38408 + cap_raise(cap_drop, cap);
38409 + }
38410 + }
38411 +
38412 + if (!cap_raised(cap_drop, cap))
38413 + return 1;
38414 +
38415 + return 0;
38416 +}
38417 +
38418 diff -urNp linux-2.6.36/grsecurity/gracl_fs.c linux-2.6.36/grsecurity/gracl_fs.c
38419 --- linux-2.6.36/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
38420 +++ linux-2.6.36/grsecurity/gracl_fs.c 2010-11-06 18:58:50.000000000 -0400
38421 @@ -0,0 +1,424 @@
38422 +#include <linux/kernel.h>
38423 +#include <linux/sched.h>
38424 +#include <linux/types.h>
38425 +#include <linux/fs.h>
38426 +#include <linux/file.h>
38427 +#include <linux/stat.h>
38428 +#include <linux/grsecurity.h>
38429 +#include <linux/grinternal.h>
38430 +#include <linux/gracl.h>
38431 +
38432 +__u32
38433 +gr_acl_handle_hidden_file(const struct dentry * dentry,
38434 + const struct vfsmount * mnt)
38435 +{
38436 + __u32 mode;
38437 +
38438 + if (unlikely(!dentry->d_inode))
38439 + return GR_FIND;
38440 +
38441 + mode =
38442 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
38443 +
38444 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
38445 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
38446 + return mode;
38447 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
38448 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
38449 + return 0;
38450 + } else if (unlikely(!(mode & GR_FIND)))
38451 + return 0;
38452 +
38453 + return GR_FIND;
38454 +}
38455 +
38456 +__u32
38457 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
38458 + const int fmode)
38459 +{
38460 + __u32 reqmode = GR_FIND;
38461 + __u32 mode;
38462 +
38463 + if (unlikely(!dentry->d_inode))
38464 + return reqmode;
38465 +
38466 + if (unlikely(fmode & O_APPEND))
38467 + reqmode |= GR_APPEND;
38468 + else if (unlikely(fmode & FMODE_WRITE))
38469 + reqmode |= GR_WRITE;
38470 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
38471 + reqmode |= GR_READ;
38472 + if ((fmode & FMODE_GREXEC) && (fmode & FMODE_EXEC))
38473 + reqmode &= ~GR_READ;
38474 + mode =
38475 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
38476 + mnt);
38477 +
38478 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
38479 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
38480 + reqmode & GR_READ ? " reading" : "",
38481 + reqmode & GR_WRITE ? " writing" : reqmode &
38482 + GR_APPEND ? " appending" : "");
38483 + return reqmode;
38484 + } else
38485 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
38486 + {
38487 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
38488 + reqmode & GR_READ ? " reading" : "",
38489 + reqmode & GR_WRITE ? " writing" : reqmode &
38490 + GR_APPEND ? " appending" : "");
38491 + return 0;
38492 + } else if (unlikely((mode & reqmode) != reqmode))
38493 + return 0;
38494 +
38495 + return reqmode;
38496 +}
38497 +
38498 +__u32
38499 +gr_acl_handle_creat(const struct dentry * dentry,
38500 + const struct dentry * p_dentry,
38501 + const struct vfsmount * p_mnt, const int fmode,
38502 + const int imode)
38503 +{
38504 + __u32 reqmode = GR_WRITE | GR_CREATE;
38505 + __u32 mode;
38506 +
38507 + if (unlikely(fmode & O_APPEND))
38508 + reqmode |= GR_APPEND;
38509 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
38510 + reqmode |= GR_READ;
38511 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
38512 + reqmode |= GR_SETID;
38513 +
38514 + mode =
38515 + gr_check_create(dentry, p_dentry, p_mnt,
38516 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
38517 +
38518 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
38519 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
38520 + reqmode & GR_READ ? " reading" : "",
38521 + reqmode & GR_WRITE ? " writing" : reqmode &
38522 + GR_APPEND ? " appending" : "");
38523 + return reqmode;
38524 + } else
38525 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
38526 + {
38527 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
38528 + reqmode & GR_READ ? " reading" : "",
38529 + reqmode & GR_WRITE ? " writing" : reqmode &
38530 + GR_APPEND ? " appending" : "");
38531 + return 0;
38532 + } else if (unlikely((mode & reqmode) != reqmode))
38533 + return 0;
38534 +
38535 + return reqmode;
38536 +}
38537 +
38538 +__u32
38539 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
38540 + const int fmode)
38541 +{
38542 + __u32 mode, reqmode = GR_FIND;
38543 +
38544 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
38545 + reqmode |= GR_EXEC;
38546 + if (fmode & S_IWOTH)
38547 + reqmode |= GR_WRITE;
38548 + if (fmode & S_IROTH)
38549 + reqmode |= GR_READ;
38550 +
38551 + mode =
38552 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
38553 + mnt);
38554 +
38555 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
38556 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
38557 + reqmode & GR_READ ? " reading" : "",
38558 + reqmode & GR_WRITE ? " writing" : "",
38559 + reqmode & GR_EXEC ? " executing" : "");
38560 + return reqmode;
38561 + } else
38562 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
38563 + {
38564 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
38565 + reqmode & GR_READ ? " reading" : "",
38566 + reqmode & GR_WRITE ? " writing" : "",
38567 + reqmode & GR_EXEC ? " executing" : "");
38568 + return 0;
38569 + } else if (unlikely((mode & reqmode) != reqmode))
38570 + return 0;
38571 +
38572 + return reqmode;
38573 +}
38574 +
38575 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
38576 +{
38577 + __u32 mode;
38578 +
38579 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
38580 +
38581 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
38582 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
38583 + return mode;
38584 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
38585 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
38586 + return 0;
38587 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
38588 + return 0;
38589 +
38590 + return (reqmode);
38591 +}
38592 +
38593 +__u32
38594 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
38595 +{
38596 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
38597 +}
38598 +
38599 +__u32
38600 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
38601 +{
38602 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
38603 +}
38604 +
38605 +__u32
38606 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
38607 +{
38608 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
38609 +}
38610 +
38611 +__u32
38612 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
38613 +{
38614 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
38615 +}
38616 +
38617 +__u32
38618 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
38619 + mode_t mode)
38620 +{
38621 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
38622 + return 1;
38623 +
38624 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
38625 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
38626 + GR_FCHMOD_ACL_MSG);
38627 + } else {
38628 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
38629 + }
38630 +}
38631 +
38632 +__u32
38633 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
38634 + mode_t mode)
38635 +{
38636 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
38637 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
38638 + GR_CHMOD_ACL_MSG);
38639 + } else {
38640 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
38641 + }
38642 +}
38643 +
38644 +__u32
38645 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
38646 +{
38647 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
38648 +}
38649 +
38650 +__u32
38651 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
38652 +{
38653 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
38654 +}
38655 +
38656 +__u32
38657 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
38658 +{
38659 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
38660 + GR_UNIXCONNECT_ACL_MSG);
38661 +}
38662 +
38663 +/* hardlinks require at minimum create permission,
38664 + any additional privilege required is based on the
38665 + privilege of the file being linked to
38666 +*/
38667 +__u32
38668 +gr_acl_handle_link(const struct dentry * new_dentry,
38669 + const struct dentry * parent_dentry,
38670 + const struct vfsmount * parent_mnt,
38671 + const struct dentry * old_dentry,
38672 + const struct vfsmount * old_mnt, const char *to)
38673 +{
38674 + __u32 mode;
38675 + __u32 needmode = GR_CREATE | GR_LINK;
38676 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
38677 +
38678 + mode =
38679 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
38680 + old_mnt);
38681 +
38682 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
38683 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
38684 + return mode;
38685 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
38686 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
38687 + return 0;
38688 + } else if (unlikely((mode & needmode) != needmode))
38689 + return 0;
38690 +
38691 + return 1;
38692 +}
38693 +
38694 +__u32
38695 +gr_acl_handle_symlink(const struct dentry * new_dentry,
38696 + const struct dentry * parent_dentry,
38697 + const struct vfsmount * parent_mnt, const char *from)
38698 +{
38699 + __u32 needmode = GR_WRITE | GR_CREATE;
38700 + __u32 mode;
38701 +
38702 + mode =
38703 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
38704 + GR_CREATE | GR_AUDIT_CREATE |
38705 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
38706 +
38707 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
38708 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
38709 + return mode;
38710 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
38711 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
38712 + return 0;
38713 + } else if (unlikely((mode & needmode) != needmode))
38714 + return 0;
38715 +
38716 + return (GR_WRITE | GR_CREATE);
38717 +}
38718 +
38719 +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)
38720 +{
38721 + __u32 mode;
38722 +
38723 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
38724 +
38725 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
38726 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
38727 + return mode;
38728 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
38729 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
38730 + return 0;
38731 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
38732 + return 0;
38733 +
38734 + return (reqmode);
38735 +}
38736 +
38737 +__u32
38738 +gr_acl_handle_mknod(const struct dentry * new_dentry,
38739 + const struct dentry * parent_dentry,
38740 + const struct vfsmount * parent_mnt,
38741 + const int mode)
38742 +{
38743 + __u32 reqmode = GR_WRITE | GR_CREATE;
38744 + if (unlikely(mode & (S_ISUID | S_ISGID)))
38745 + reqmode |= GR_SETID;
38746 +
38747 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
38748 + reqmode, GR_MKNOD_ACL_MSG);
38749 +}
38750 +
38751 +__u32
38752 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
38753 + const struct dentry *parent_dentry,
38754 + const struct vfsmount *parent_mnt)
38755 +{
38756 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
38757 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
38758 +}
38759 +
38760 +#define RENAME_CHECK_SUCCESS(old, new) \
38761 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
38762 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
38763 +
38764 +int
38765 +gr_acl_handle_rename(struct dentry *new_dentry,
38766 + struct dentry *parent_dentry,
38767 + const struct vfsmount *parent_mnt,
38768 + struct dentry *old_dentry,
38769 + struct inode *old_parent_inode,
38770 + struct vfsmount *old_mnt, const char *newname)
38771 +{
38772 + __u32 comp1, comp2;
38773 + int error = 0;
38774 +
38775 + if (unlikely(!gr_acl_is_enabled()))
38776 + return 0;
38777 +
38778 + if (!new_dentry->d_inode) {
38779 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
38780 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
38781 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
38782 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
38783 + GR_DELETE | GR_AUDIT_DELETE |
38784 + GR_AUDIT_READ | GR_AUDIT_WRITE |
38785 + GR_SUPPRESS, old_mnt);
38786 + } else {
38787 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
38788 + GR_CREATE | GR_DELETE |
38789 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
38790 + GR_AUDIT_READ | GR_AUDIT_WRITE |
38791 + GR_SUPPRESS, parent_mnt);
38792 + comp2 =
38793 + gr_search_file(old_dentry,
38794 + GR_READ | GR_WRITE | GR_AUDIT_READ |
38795 + GR_DELETE | GR_AUDIT_DELETE |
38796 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
38797 + }
38798 +
38799 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
38800 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
38801 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
38802 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
38803 + && !(comp2 & GR_SUPPRESS)) {
38804 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
38805 + error = -EACCES;
38806 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
38807 + error = -EACCES;
38808 +
38809 + return error;
38810 +}
38811 +
38812 +void
38813 +gr_acl_handle_exit(void)
38814 +{
38815 + u16 id;
38816 + char *rolename;
38817 + struct file *exec_file;
38818 +
38819 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
38820 + id = current->acl_role_id;
38821 + rolename = current->role->rolename;
38822 + gr_set_acls(1);
38823 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
38824 + }
38825 +
38826 + write_lock(&grsec_exec_file_lock);
38827 + exec_file = current->exec_file;
38828 + current->exec_file = NULL;
38829 + write_unlock(&grsec_exec_file_lock);
38830 +
38831 + if (exec_file)
38832 + fput(exec_file);
38833 +}
38834 +
38835 +int
38836 +gr_acl_handle_procpidmem(const struct task_struct *task)
38837 +{
38838 + if (unlikely(!gr_acl_is_enabled()))
38839 + return 0;
38840 +
38841 + if (task != current && task->acl->mode & GR_PROTPROCFD)
38842 + return -EACCES;
38843 +
38844 + return 0;
38845 +}
38846 diff -urNp linux-2.6.36/grsecurity/gracl_ip.c linux-2.6.36/grsecurity/gracl_ip.c
38847 --- linux-2.6.36/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
38848 +++ linux-2.6.36/grsecurity/gracl_ip.c 2010-11-06 18:58:50.000000000 -0400
38849 @@ -0,0 +1,339 @@
38850 +#include <linux/kernel.h>
38851 +#include <asm/uaccess.h>
38852 +#include <asm/errno.h>
38853 +#include <net/sock.h>
38854 +#include <linux/file.h>
38855 +#include <linux/fs.h>
38856 +#include <linux/net.h>
38857 +#include <linux/in.h>
38858 +#include <linux/skbuff.h>
38859 +#include <linux/ip.h>
38860 +#include <linux/udp.h>
38861 +#include <linux/smp_lock.h>
38862 +#include <linux/types.h>
38863 +#include <linux/sched.h>
38864 +#include <linux/netdevice.h>
38865 +#include <linux/inetdevice.h>
38866 +#include <linux/gracl.h>
38867 +#include <linux/grsecurity.h>
38868 +#include <linux/grinternal.h>
38869 +
38870 +#define GR_BIND 0x01
38871 +#define GR_CONNECT 0x02
38872 +#define GR_INVERT 0x04
38873 +#define GR_BINDOVERRIDE 0x08
38874 +#define GR_CONNECTOVERRIDE 0x10
38875 +
38876 +static const char * gr_protocols[256] = {
38877 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
38878 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
38879 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
38880 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
38881 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
38882 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
38883 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
38884 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
38885 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
38886 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
38887 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
38888 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
38889 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
38890 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
38891 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
38892 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
38893 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
38894 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
38895 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
38896 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
38897 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
38898 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
38899 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
38900 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
38901 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
38902 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
38903 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
38904 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
38905 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
38906 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
38907 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
38908 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
38909 + };
38910 +
38911 +static const char * gr_socktypes[11] = {
38912 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
38913 + "unknown:7", "unknown:8", "unknown:9", "packet"
38914 + };
38915 +
38916 +const char *
38917 +gr_proto_to_name(unsigned char proto)
38918 +{
38919 + return gr_protocols[proto];
38920 +}
38921 +
38922 +const char *
38923 +gr_socktype_to_name(unsigned char type)
38924 +{
38925 + return gr_socktypes[type];
38926 +}
38927 +
38928 +int
38929 +gr_search_socket(const int domain, const int type, const int protocol)
38930 +{
38931 + struct acl_subject_label *curr;
38932 + const struct cred *cred = current_cred();
38933 +
38934 + if (unlikely(!gr_acl_is_enabled()))
38935 + goto exit;
38936 +
38937 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
38938 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
38939 + goto exit; // let the kernel handle it
38940 +
38941 + curr = current->acl;
38942 +
38943 + if (!curr->ips)
38944 + goto exit;
38945 +
38946 + if ((curr->ip_type & (1 << type)) &&
38947 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
38948 + goto exit;
38949 +
38950 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
38951 + /* we don't place acls on raw sockets , and sometimes
38952 + dgram/ip sockets are opened for ioctl and not
38953 + bind/connect, so we'll fake a bind learn log */
38954 + if (type == SOCK_RAW || type == SOCK_PACKET) {
38955 + __u32 fakeip = 0;
38956 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
38957 + current->role->roletype, cred->uid,
38958 + cred->gid, current->exec_file ?
38959 + gr_to_filename(current->exec_file->f_path.dentry,
38960 + current->exec_file->f_path.mnt) :
38961 + curr->filename, curr->filename,
38962 + &fakeip, 0, type,
38963 + protocol, GR_CONNECT, &current->signal->curr_ip);
38964 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
38965 + __u32 fakeip = 0;
38966 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
38967 + current->role->roletype, cred->uid,
38968 + cred->gid, current->exec_file ?
38969 + gr_to_filename(current->exec_file->f_path.dentry,
38970 + current->exec_file->f_path.mnt) :
38971 + curr->filename, curr->filename,
38972 + &fakeip, 0, type,
38973 + protocol, GR_BIND, &current->signal->curr_ip);
38974 + }
38975 + /* we'll log when they use connect or bind */
38976 + goto exit;
38977 + }
38978 +
38979 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
38980 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
38981 +
38982 + return 0;
38983 + exit:
38984 + return 1;
38985 +}
38986 +
38987 +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)
38988 +{
38989 + if ((ip->mode & mode) &&
38990 + (ip_port >= ip->low) &&
38991 + (ip_port <= ip->high) &&
38992 + ((ntohl(ip_addr) & our_netmask) ==
38993 + (ntohl(our_addr) & our_netmask))
38994 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
38995 + && (ip->type & (1 << type))) {
38996 + if (ip->mode & GR_INVERT)
38997 + return 2; // specifically denied
38998 + else
38999 + return 1; // allowed
39000 + }
39001 +
39002 + return 0; // not specifically allowed, may continue parsing
39003 +}
39004 +
39005 +static int
39006 +gr_search_connectbind(const int full_mode, struct sock *sk,
39007 + struct sockaddr_in *addr, const int type)
39008 +{
39009 + char iface[IFNAMSIZ] = {0};
39010 + struct acl_subject_label *curr;
39011 + struct acl_ip_label *ip;
39012 + struct inet_sock *isk;
39013 + struct net_device *dev;
39014 + struct in_device *idev;
39015 + unsigned long i;
39016 + int ret;
39017 + int mode = full_mode & (GR_BIND | GR_CONNECT);
39018 + __u32 ip_addr = 0;
39019 + __u32 our_addr;
39020 + __u32 our_netmask;
39021 + char *p;
39022 + __u16 ip_port = 0;
39023 + const struct cred *cred = current_cred();
39024 +
39025 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
39026 + return 0;
39027 +
39028 + curr = current->acl;
39029 + isk = inet_sk(sk);
39030 +
39031 + /* INADDR_ANY overriding for binds, inaddr_any_override is already in network order */
39032 + if ((full_mode & GR_BINDOVERRIDE) && addr->sin_addr.s_addr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0)
39033 + addr->sin_addr.s_addr = curr->inaddr_any_override;
39034 + if ((full_mode & GR_CONNECT) && isk->inet_saddr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) {
39035 + struct sockaddr_in saddr;
39036 + int err;
39037 +
39038 + saddr.sin_family = AF_INET;
39039 + saddr.sin_addr.s_addr = curr->inaddr_any_override;
39040 + saddr.sin_port = isk->inet_sport;
39041 +
39042 + err = security_socket_bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
39043 + if (err)
39044 + return err;
39045 +
39046 + err = sk->sk_socket->ops->bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
39047 + if (err)
39048 + return err;
39049 + }
39050 +
39051 + if (!curr->ips)
39052 + return 0;
39053 +
39054 + ip_addr = addr->sin_addr.s_addr;
39055 + ip_port = ntohs(addr->sin_port);
39056 +
39057 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
39058 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
39059 + current->role->roletype, cred->uid,
39060 + cred->gid, current->exec_file ?
39061 + gr_to_filename(current->exec_file->f_path.dentry,
39062 + current->exec_file->f_path.mnt) :
39063 + curr->filename, curr->filename,
39064 + &ip_addr, ip_port, type,
39065 + sk->sk_protocol, mode, &current->signal->curr_ip);
39066 + return 0;
39067 + }
39068 +
39069 + for (i = 0; i < curr->ip_num; i++) {
39070 + ip = *(curr->ips + i);
39071 + if (ip->iface != NULL) {
39072 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
39073 + p = strchr(iface, ':');
39074 + if (p != NULL)
39075 + *p = '\0';
39076 + dev = dev_get_by_name(sock_net(sk), iface);
39077 + if (dev == NULL)
39078 + continue;
39079 + idev = in_dev_get(dev);
39080 + if (idev == NULL) {
39081 + dev_put(dev);
39082 + continue;
39083 + }
39084 + rcu_read_lock();
39085 + for_ifa(idev) {
39086 + if (!strcmp(ip->iface, ifa->ifa_label)) {
39087 + our_addr = ifa->ifa_address;
39088 + our_netmask = 0xffffffff;
39089 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
39090 + if (ret == 1) {
39091 + rcu_read_unlock();
39092 + in_dev_put(idev);
39093 + dev_put(dev);
39094 + return 0;
39095 + } else if (ret == 2) {
39096 + rcu_read_unlock();
39097 + in_dev_put(idev);
39098 + dev_put(dev);
39099 + goto denied;
39100 + }
39101 + }
39102 + } endfor_ifa(idev);
39103 + rcu_read_unlock();
39104 + in_dev_put(idev);
39105 + dev_put(dev);
39106 + } else {
39107 + our_addr = ip->addr;
39108 + our_netmask = ip->netmask;
39109 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
39110 + if (ret == 1)
39111 + return 0;
39112 + else if (ret == 2)
39113 + goto denied;
39114 + }
39115 + }
39116 +
39117 +denied:
39118 + if (mode == GR_BIND)
39119 + 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));
39120 + else if (mode == GR_CONNECT)
39121 + 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));
39122 +
39123 + return -EACCES;
39124 +}
39125 +
39126 +int
39127 +gr_search_connect(struct socket *sock, struct sockaddr_in *addr)
39128 +{
39129 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sock->sk, addr, sock->type);
39130 +}
39131 +
39132 +int
39133 +gr_search_bind(struct socket *sock, struct sockaddr_in *addr)
39134 +{
39135 + return gr_search_connectbind(GR_BIND | GR_BINDOVERRIDE, sock->sk, addr, sock->type);
39136 +}
39137 +
39138 +int gr_search_listen(struct socket *sock)
39139 +{
39140 + struct sock *sk = sock->sk;
39141 + struct sockaddr_in addr;
39142 +
39143 + addr.sin_addr.s_addr = inet_sk(sk)->inet_saddr;
39144 + addr.sin_port = inet_sk(sk)->inet_sport;
39145 +
39146 + return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
39147 +}
39148 +
39149 +int gr_search_accept(struct socket *sock)
39150 +{
39151 + struct sock *sk = sock->sk;
39152 + struct sockaddr_in addr;
39153 +
39154 + addr.sin_addr.s_addr = inet_sk(sk)->inet_saddr;
39155 + addr.sin_port = inet_sk(sk)->inet_sport;
39156 +
39157 + return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
39158 +}
39159 +
39160 +int
39161 +gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr)
39162 +{
39163 + if (addr)
39164 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
39165 + else {
39166 + struct sockaddr_in sin;
39167 + const struct inet_sock *inet = inet_sk(sk);
39168 +
39169 + sin.sin_addr.s_addr = inet->inet_daddr;
39170 + sin.sin_port = inet->inet_dport;
39171 +
39172 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
39173 + }
39174 +}
39175 +
39176 +int
39177 +gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb)
39178 +{
39179 + struct sockaddr_in sin;
39180 +
39181 + if (unlikely(skb->len < sizeof (struct udphdr)))
39182 + return 0; // skip this packet
39183 +
39184 + sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
39185 + sin.sin_port = udp_hdr(skb)->source;
39186 +
39187 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
39188 +}
39189 diff -urNp linux-2.6.36/grsecurity/gracl_learn.c linux-2.6.36/grsecurity/gracl_learn.c
39190 --- linux-2.6.36/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
39191 +++ linux-2.6.36/grsecurity/gracl_learn.c 2010-11-06 18:58:50.000000000 -0400
39192 @@ -0,0 +1,211 @@
39193 +#include <linux/kernel.h>
39194 +#include <linux/mm.h>
39195 +#include <linux/sched.h>
39196 +#include <linux/poll.h>
39197 +#include <linux/smp_lock.h>
39198 +#include <linux/string.h>
39199 +#include <linux/file.h>
39200 +#include <linux/types.h>
39201 +#include <linux/vmalloc.h>
39202 +#include <linux/grinternal.h>
39203 +
39204 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
39205 + size_t count, loff_t *ppos);
39206 +extern int gr_acl_is_enabled(void);
39207 +
39208 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
39209 +static int gr_learn_attached;
39210 +
39211 +/* use a 512k buffer */
39212 +#define LEARN_BUFFER_SIZE (512 * 1024)
39213 +
39214 +static DEFINE_SPINLOCK(gr_learn_lock);
39215 +static DECLARE_MUTEX(gr_learn_user_sem);
39216 +
39217 +/* we need to maintain two buffers, so that the kernel context of grlearn
39218 + uses a semaphore around the userspace copying, and the other kernel contexts
39219 + use a spinlock when copying into the buffer, since they cannot sleep
39220 +*/
39221 +static char *learn_buffer;
39222 +static char *learn_buffer_user;
39223 +static int learn_buffer_len;
39224 +static int learn_buffer_user_len;
39225 +
39226 +static ssize_t
39227 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
39228 +{
39229 + DECLARE_WAITQUEUE(wait, current);
39230 + ssize_t retval = 0;
39231 +
39232 + add_wait_queue(&learn_wait, &wait);
39233 + set_current_state(TASK_INTERRUPTIBLE);
39234 + do {
39235 + down(&gr_learn_user_sem);
39236 + spin_lock(&gr_learn_lock);
39237 + if (learn_buffer_len)
39238 + break;
39239 + spin_unlock(&gr_learn_lock);
39240 + up(&gr_learn_user_sem);
39241 + if (file->f_flags & O_NONBLOCK) {
39242 + retval = -EAGAIN;
39243 + goto out;
39244 + }
39245 + if (signal_pending(current)) {
39246 + retval = -ERESTARTSYS;
39247 + goto out;
39248 + }
39249 +
39250 + schedule();
39251 + } while (1);
39252 +
39253 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
39254 + learn_buffer_user_len = learn_buffer_len;
39255 + retval = learn_buffer_len;
39256 + learn_buffer_len = 0;
39257 +
39258 + spin_unlock(&gr_learn_lock);
39259 +
39260 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
39261 + retval = -EFAULT;
39262 +
39263 + up(&gr_learn_user_sem);
39264 +out:
39265 + set_current_state(TASK_RUNNING);
39266 + remove_wait_queue(&learn_wait, &wait);
39267 + return retval;
39268 +}
39269 +
39270 +static unsigned int
39271 +poll_learn(struct file * file, poll_table * wait)
39272 +{
39273 + poll_wait(file, &learn_wait, wait);
39274 +
39275 + if (learn_buffer_len)
39276 + return (POLLIN | POLLRDNORM);
39277 +
39278 + return 0;
39279 +}
39280 +
39281 +void
39282 +gr_clear_learn_entries(void)
39283 +{
39284 + char *tmp;
39285 +
39286 + down(&gr_learn_user_sem);
39287 + if (learn_buffer != NULL) {
39288 + spin_lock(&gr_learn_lock);
39289 + tmp = learn_buffer;
39290 + learn_buffer = NULL;
39291 + spin_unlock(&gr_learn_lock);
39292 + vfree(learn_buffer);
39293 + }
39294 + if (learn_buffer_user != NULL) {
39295 + vfree(learn_buffer_user);
39296 + learn_buffer_user = NULL;
39297 + }
39298 + learn_buffer_len = 0;
39299 + up(&gr_learn_user_sem);
39300 +
39301 + return;
39302 +}
39303 +
39304 +void
39305 +gr_add_learn_entry(const char *fmt, ...)
39306 +{
39307 + va_list args;
39308 + unsigned int len;
39309 +
39310 + if (!gr_learn_attached)
39311 + return;
39312 +
39313 + spin_lock(&gr_learn_lock);
39314 +
39315 + /* leave a gap at the end so we know when it's "full" but don't have to
39316 + compute the exact length of the string we're trying to append
39317 + */
39318 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
39319 + spin_unlock(&gr_learn_lock);
39320 + wake_up_interruptible(&learn_wait);
39321 + return;
39322 + }
39323 + if (learn_buffer == NULL) {
39324 + spin_unlock(&gr_learn_lock);
39325 + return;
39326 + }
39327 +
39328 + va_start(args, fmt);
39329 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
39330 + va_end(args);
39331 +
39332 + learn_buffer_len += len + 1;
39333 +
39334 + spin_unlock(&gr_learn_lock);
39335 + wake_up_interruptible(&learn_wait);
39336 +
39337 + return;
39338 +}
39339 +
39340 +static int
39341 +open_learn(struct inode *inode, struct file *file)
39342 +{
39343 + if (file->f_mode & FMODE_READ && gr_learn_attached)
39344 + return -EBUSY;
39345 + if (file->f_mode & FMODE_READ) {
39346 + int retval = 0;
39347 + down(&gr_learn_user_sem);
39348 + if (learn_buffer == NULL)
39349 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
39350 + if (learn_buffer_user == NULL)
39351 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
39352 + if (learn_buffer == NULL) {
39353 + retval = -ENOMEM;
39354 + goto out_error;
39355 + }
39356 + if (learn_buffer_user == NULL) {
39357 + retval = -ENOMEM;
39358 + goto out_error;
39359 + }
39360 + learn_buffer_len = 0;
39361 + learn_buffer_user_len = 0;
39362 + gr_learn_attached = 1;
39363 +out_error:
39364 + up(&gr_learn_user_sem);
39365 + return retval;
39366 + }
39367 + return 0;
39368 +}
39369 +
39370 +static int
39371 +close_learn(struct inode *inode, struct file *file)
39372 +{
39373 + char *tmp;
39374 +
39375 + if (file->f_mode & FMODE_READ) {
39376 + down(&gr_learn_user_sem);
39377 + if (learn_buffer != NULL) {
39378 + spin_lock(&gr_learn_lock);
39379 + tmp = learn_buffer;
39380 + learn_buffer = NULL;
39381 + spin_unlock(&gr_learn_lock);
39382 + vfree(tmp);
39383 + }
39384 + if (learn_buffer_user != NULL) {
39385 + vfree(learn_buffer_user);
39386 + learn_buffer_user = NULL;
39387 + }
39388 + learn_buffer_len = 0;
39389 + learn_buffer_user_len = 0;
39390 + gr_learn_attached = 0;
39391 + up(&gr_learn_user_sem);
39392 + }
39393 +
39394 + return 0;
39395 +}
39396 +
39397 +const struct file_operations grsec_fops = {
39398 + .read = read_learn,
39399 + .write = write_grsec_handler,
39400 + .open = open_learn,
39401 + .release = close_learn,
39402 + .poll = poll_learn,
39403 +};
39404 diff -urNp linux-2.6.36/grsecurity/gracl_res.c linux-2.6.36/grsecurity/gracl_res.c
39405 --- linux-2.6.36/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
39406 +++ linux-2.6.36/grsecurity/gracl_res.c 2010-11-06 18:58:50.000000000 -0400
39407 @@ -0,0 +1,68 @@
39408 +#include <linux/kernel.h>
39409 +#include <linux/sched.h>
39410 +#include <linux/gracl.h>
39411 +#include <linux/grinternal.h>
39412 +
39413 +static const char *restab_log[] = {
39414 + [RLIMIT_CPU] = "RLIMIT_CPU",
39415 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
39416 + [RLIMIT_DATA] = "RLIMIT_DATA",
39417 + [RLIMIT_STACK] = "RLIMIT_STACK",
39418 + [RLIMIT_CORE] = "RLIMIT_CORE",
39419 + [RLIMIT_RSS] = "RLIMIT_RSS",
39420 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
39421 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
39422 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
39423 + [RLIMIT_AS] = "RLIMIT_AS",
39424 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
39425 + [RLIMIT_SIGPENDING] = "RLIMIT_SIGPENDING",
39426 + [RLIMIT_MSGQUEUE] = "RLIMIT_MSGQUEUE",
39427 + [RLIMIT_NICE] = "RLIMIT_NICE",
39428 + [RLIMIT_RTPRIO] = "RLIMIT_RTPRIO",
39429 + [RLIMIT_RTTIME] = "RLIMIT_RTTIME",
39430 + [GR_CRASH_RES] = "RLIMIT_CRASH"
39431 +};
39432 +
39433 +void
39434 +gr_log_resource(const struct task_struct *task,
39435 + const int res, const unsigned long wanted, const int gt)
39436 +{
39437 + const struct cred *cred;
39438 + unsigned long rlim;
39439 +
39440 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
39441 + return;
39442 +
39443 + // not yet supported resource
39444 + if (unlikely(!restab_log[res]))
39445 + return;
39446 +
39447 + if (res == RLIMIT_CPU || res == RLIMIT_RTTIME)
39448 + rlim = task_rlimit_max(task, res);
39449 + else
39450 + rlim = task_rlimit(task, res);
39451 +
39452 + if (likely((rlim == RLIM_INFINITY) || (gt && wanted <= rlim) || (!gt && wanted < rlim)))
39453 + return;
39454 +
39455 + rcu_read_lock();
39456 + cred = __task_cred(task);
39457 +
39458 + if (res == RLIMIT_NPROC &&
39459 + (cap_raised(cred->cap_effective, CAP_SYS_ADMIN) ||
39460 + cap_raised(cred->cap_effective, CAP_SYS_RESOURCE)))
39461 + goto out_rcu_unlock;
39462 + else if (res == RLIMIT_MEMLOCK &&
39463 + cap_raised(cred->cap_effective, CAP_IPC_LOCK))
39464 + goto out_rcu_unlock;
39465 + else if (res == RLIMIT_NICE && cap_raised(cred->cap_effective, CAP_SYS_NICE))
39466 + goto out_rcu_unlock;
39467 + rcu_read_unlock();
39468 +
39469 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], rlim);
39470 +
39471 + return;
39472 +out_rcu_unlock:
39473 + rcu_read_unlock();
39474 + return;
39475 +}
39476 diff -urNp linux-2.6.36/grsecurity/gracl_segv.c linux-2.6.36/grsecurity/gracl_segv.c
39477 --- linux-2.6.36/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
39478 +++ linux-2.6.36/grsecurity/gracl_segv.c 2010-11-06 18:58:50.000000000 -0400
39479 @@ -0,0 +1,310 @@
39480 +#include <linux/kernel.h>
39481 +#include <linux/mm.h>
39482 +#include <asm/uaccess.h>
39483 +#include <asm/errno.h>
39484 +#include <asm/mman.h>
39485 +#include <net/sock.h>
39486 +#include <linux/file.h>
39487 +#include <linux/fs.h>
39488 +#include <linux/net.h>
39489 +#include <linux/in.h>
39490 +#include <linux/smp_lock.h>
39491 +#include <linux/slab.h>
39492 +#include <linux/types.h>
39493 +#include <linux/sched.h>
39494 +#include <linux/timer.h>
39495 +#include <linux/gracl.h>
39496 +#include <linux/grsecurity.h>
39497 +#include <linux/grinternal.h>
39498 +
39499 +static struct crash_uid *uid_set;
39500 +static unsigned short uid_used;
39501 +static DEFINE_SPINLOCK(gr_uid_lock);
39502 +extern rwlock_t gr_inode_lock;
39503 +extern struct acl_subject_label *
39504 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
39505 + struct acl_role_label *role);
39506 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
39507 +
39508 +int
39509 +gr_init_uidset(void)
39510 +{
39511 + uid_set =
39512 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
39513 + uid_used = 0;
39514 +
39515 + return uid_set ? 1 : 0;
39516 +}
39517 +
39518 +void
39519 +gr_free_uidset(void)
39520 +{
39521 + if (uid_set)
39522 + kfree(uid_set);
39523 +
39524 + return;
39525 +}
39526 +
39527 +int
39528 +gr_find_uid(const uid_t uid)
39529 +{
39530 + struct crash_uid *tmp = uid_set;
39531 + uid_t buid;
39532 + int low = 0, high = uid_used - 1, mid;
39533 +
39534 + while (high >= low) {
39535 + mid = (low + high) >> 1;
39536 + buid = tmp[mid].uid;
39537 + if (buid == uid)
39538 + return mid;
39539 + if (buid > uid)
39540 + high = mid - 1;
39541 + if (buid < uid)
39542 + low = mid + 1;
39543 + }
39544 +
39545 + return -1;
39546 +}
39547 +
39548 +static __inline__ void
39549 +gr_insertsort(void)
39550 +{
39551 + unsigned short i, j;
39552 + struct crash_uid index;
39553 +
39554 + for (i = 1; i < uid_used; i++) {
39555 + index = uid_set[i];
39556 + j = i;
39557 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
39558 + uid_set[j] = uid_set[j - 1];
39559 + j--;
39560 + }
39561 + uid_set[j] = index;
39562 + }
39563 +
39564 + return;
39565 +}
39566 +
39567 +static __inline__ void
39568 +gr_insert_uid(const uid_t uid, const unsigned long expires)
39569 +{
39570 + int loc;
39571 +
39572 + if (uid_used == GR_UIDTABLE_MAX)
39573 + return;
39574 +
39575 + loc = gr_find_uid(uid);
39576 +
39577 + if (loc >= 0) {
39578 + uid_set[loc].expires = expires;
39579 + return;
39580 + }
39581 +
39582 + uid_set[uid_used].uid = uid;
39583 + uid_set[uid_used].expires = expires;
39584 + uid_used++;
39585 +
39586 + gr_insertsort();
39587 +
39588 + return;
39589 +}
39590 +
39591 +void
39592 +gr_remove_uid(const unsigned short loc)
39593 +{
39594 + unsigned short i;
39595 +
39596 + for (i = loc + 1; i < uid_used; i++)
39597 + uid_set[i - 1] = uid_set[i];
39598 +
39599 + uid_used--;
39600 +
39601 + return;
39602 +}
39603 +
39604 +int
39605 +gr_check_crash_uid(const uid_t uid)
39606 +{
39607 + int loc;
39608 + int ret = 0;
39609 +
39610 + if (unlikely(!gr_acl_is_enabled()))
39611 + return 0;
39612 +
39613 + spin_lock(&gr_uid_lock);
39614 + loc = gr_find_uid(uid);
39615 +
39616 + if (loc < 0)
39617 + goto out_unlock;
39618 +
39619 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
39620 + gr_remove_uid(loc);
39621 + else
39622 + ret = 1;
39623 +
39624 +out_unlock:
39625 + spin_unlock(&gr_uid_lock);
39626 + return ret;
39627 +}
39628 +
39629 +static __inline__ int
39630 +proc_is_setxid(const struct cred *cred)
39631 +{
39632 + if (cred->uid != cred->euid || cred->uid != cred->suid ||
39633 + cred->uid != cred->fsuid)
39634 + return 1;
39635 + if (cred->gid != cred->egid || cred->gid != cred->sgid ||
39636 + cred->gid != cred->fsgid)
39637 + return 1;
39638 +
39639 + return 0;
39640 +}
39641 +static __inline__ int
39642 +gr_fake_force_sig(int sig, struct task_struct *t)
39643 +{
39644 + unsigned long int flags;
39645 + int ret, blocked, ignored;
39646 + struct k_sigaction *action;
39647 +
39648 + spin_lock_irqsave(&t->sighand->siglock, flags);
39649 + action = &t->sighand->action[sig-1];
39650 + ignored = action->sa.sa_handler == SIG_IGN;
39651 + blocked = sigismember(&t->blocked, sig);
39652 + if (blocked || ignored) {
39653 + action->sa.sa_handler = SIG_DFL;
39654 + if (blocked) {
39655 + sigdelset(&t->blocked, sig);
39656 + recalc_sigpending_and_wake(t);
39657 + }
39658 + }
39659 + if (action->sa.sa_handler == SIG_DFL)
39660 + t->signal->flags &= ~SIGNAL_UNKILLABLE;
39661 + ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
39662 +
39663 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
39664 +
39665 + return ret;
39666 +}
39667 +
39668 +void
39669 +gr_handle_crash(struct task_struct *task, const int sig)
39670 +{
39671 + struct acl_subject_label *curr;
39672 + struct acl_subject_label *curr2;
39673 + struct task_struct *tsk, *tsk2;
39674 + const struct cred *cred;
39675 + const struct cred *cred2;
39676 +
39677 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
39678 + return;
39679 +
39680 + if (unlikely(!gr_acl_is_enabled()))
39681 + return;
39682 +
39683 + curr = task->acl;
39684 +
39685 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
39686 + return;
39687 +
39688 + if (time_before_eq(curr->expires, get_seconds())) {
39689 + curr->expires = 0;
39690 + curr->crashes = 0;
39691 + }
39692 +
39693 + curr->crashes++;
39694 +
39695 + if (!curr->expires)
39696 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
39697 +
39698 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
39699 + time_after(curr->expires, get_seconds())) {
39700 + rcu_read_lock();
39701 + cred = __task_cred(task);
39702 + if (cred->uid && proc_is_setxid(cred)) {
39703 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
39704 + spin_lock(&gr_uid_lock);
39705 + gr_insert_uid(cred->uid, curr->expires);
39706 + spin_unlock(&gr_uid_lock);
39707 + curr->expires = 0;
39708 + curr->crashes = 0;
39709 + read_lock(&tasklist_lock);
39710 + do_each_thread(tsk2, tsk) {
39711 + cred2 = __task_cred(tsk);
39712 + if (tsk != task && cred2->uid == cred->uid)
39713 + gr_fake_force_sig(SIGKILL, tsk);
39714 + } while_each_thread(tsk2, tsk);
39715 + read_unlock(&tasklist_lock);
39716 + } else {
39717 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
39718 + read_lock(&tasklist_lock);
39719 + do_each_thread(tsk2, tsk) {
39720 + if (likely(tsk != task)) {
39721 + curr2 = tsk->acl;
39722 +
39723 + if (curr2->device == curr->device &&
39724 + curr2->inode == curr->inode)
39725 + gr_fake_force_sig(SIGKILL, tsk);
39726 + }
39727 + } while_each_thread(tsk2, tsk);
39728 + read_unlock(&tasklist_lock);
39729 + }
39730 + rcu_read_unlock();
39731 + }
39732 +
39733 + return;
39734 +}
39735 +
39736 +int
39737 +gr_check_crash_exec(const struct file *filp)
39738 +{
39739 + struct acl_subject_label *curr;
39740 +
39741 + if (unlikely(!gr_acl_is_enabled()))
39742 + return 0;
39743 +
39744 + read_lock(&gr_inode_lock);
39745 + curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
39746 + filp->f_path.dentry->d_inode->i_sb->s_dev,
39747 + current->role);
39748 + read_unlock(&gr_inode_lock);
39749 +
39750 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
39751 + (!curr->crashes && !curr->expires))
39752 + return 0;
39753 +
39754 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
39755 + time_after(curr->expires, get_seconds()))
39756 + return 1;
39757 + else if (time_before_eq(curr->expires, get_seconds())) {
39758 + curr->crashes = 0;
39759 + curr->expires = 0;
39760 + }
39761 +
39762 + return 0;
39763 +}
39764 +
39765 +void
39766 +gr_handle_alertkill(struct task_struct *task)
39767 +{
39768 + struct acl_subject_label *curracl;
39769 + __u32 curr_ip;
39770 + struct task_struct *p, *p2;
39771 +
39772 + if (unlikely(!gr_acl_is_enabled()))
39773 + return;
39774 +
39775 + curracl = task->acl;
39776 + curr_ip = task->signal->curr_ip;
39777 +
39778 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
39779 + read_lock(&tasklist_lock);
39780 + do_each_thread(p2, p) {
39781 + if (p->signal->curr_ip == curr_ip)
39782 + gr_fake_force_sig(SIGKILL, p);
39783 + } while_each_thread(p2, p);
39784 + read_unlock(&tasklist_lock);
39785 + } else if (curracl->mode & GR_KILLPROC)
39786 + gr_fake_force_sig(SIGKILL, task);
39787 +
39788 + return;
39789 +}
39790 diff -urNp linux-2.6.36/grsecurity/gracl_shm.c linux-2.6.36/grsecurity/gracl_shm.c
39791 --- linux-2.6.36/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
39792 +++ linux-2.6.36/grsecurity/gracl_shm.c 2010-11-06 18:58:50.000000000 -0400
39793 @@ -0,0 +1,40 @@
39794 +#include <linux/kernel.h>
39795 +#include <linux/mm.h>
39796 +#include <linux/sched.h>
39797 +#include <linux/file.h>
39798 +#include <linux/ipc.h>
39799 +#include <linux/gracl.h>
39800 +#include <linux/grsecurity.h>
39801 +#include <linux/grinternal.h>
39802 +
39803 +int
39804 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
39805 + const time_t shm_createtime, const uid_t cuid, const int shmid)
39806 +{
39807 + struct task_struct *task;
39808 +
39809 + if (!gr_acl_is_enabled())
39810 + return 1;
39811 +
39812 + rcu_read_lock();
39813 + read_lock(&tasklist_lock);
39814 +
39815 + task = find_task_by_vpid(shm_cprid);
39816 +
39817 + if (unlikely(!task))
39818 + task = find_task_by_vpid(shm_lapid);
39819 +
39820 + if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
39821 + (task->pid == shm_lapid)) &&
39822 + (task->acl->mode & GR_PROTSHM) &&
39823 + (task->acl != current->acl))) {
39824 + read_unlock(&tasklist_lock);
39825 + rcu_read_unlock();
39826 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
39827 + return 0;
39828 + }
39829 + read_unlock(&tasklist_lock);
39830 + rcu_read_unlock();
39831 +
39832 + return 1;
39833 +}
39834 diff -urNp linux-2.6.36/grsecurity/grsec_chdir.c linux-2.6.36/grsecurity/grsec_chdir.c
39835 --- linux-2.6.36/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
39836 +++ linux-2.6.36/grsecurity/grsec_chdir.c 2010-11-06 18:58:50.000000000 -0400
39837 @@ -0,0 +1,19 @@
39838 +#include <linux/kernel.h>
39839 +#include <linux/sched.h>
39840 +#include <linux/fs.h>
39841 +#include <linux/file.h>
39842 +#include <linux/grsecurity.h>
39843 +#include <linux/grinternal.h>
39844 +
39845 +void
39846 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
39847 +{
39848 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
39849 + if ((grsec_enable_chdir && grsec_enable_group &&
39850 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
39851 + !grsec_enable_group)) {
39852 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
39853 + }
39854 +#endif
39855 + return;
39856 +}
39857 diff -urNp linux-2.6.36/grsecurity/grsec_chroot.c linux-2.6.36/grsecurity/grsec_chroot.c
39858 --- linux-2.6.36/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
39859 +++ linux-2.6.36/grsecurity/grsec_chroot.c 2010-11-06 20:00:34.000000000 -0400
39860 @@ -0,0 +1,372 @@
39861 +#include <linux/kernel.h>
39862 +#include <linux/module.h>
39863 +#include <linux/sched.h>
39864 +#include <linux/file.h>
39865 +#include <linux/fs.h>
39866 +#include <linux/mount.h>
39867 +#include <linux/types.h>
39868 +#include <linux/pid_namespace.h>
39869 +#include <linux/grsecurity.h>
39870 +#include <linux/grinternal.h>
39871 +
39872 +void gr_set_chroot_entries(struct task_struct *task, struct path *path)
39873 +{
39874 +#ifdef CONFIG_GRKERNSEC
39875 + if (task->pid > 1 && path->dentry != init_task.fs->root.dentry &&
39876 + path->dentry != task->nsproxy->mnt_ns->root->mnt_root)
39877 + task->gr_is_chrooted = 1;
39878 + else
39879 + task->gr_is_chrooted = 0;
39880 +
39881 + task->gr_chroot_dentry = path->dentry;
39882 +#endif
39883 + return;
39884 +}
39885 +
39886 +void gr_clear_chroot_entries(struct task_struct *task)
39887 +{
39888 +#ifdef CONFIG_GRKERNSEC
39889 + task->gr_is_chrooted = 0;
39890 + task->gr_chroot_dentry = NULL;
39891 +#endif
39892 + return;
39893 +}
39894 +
39895 +int
39896 +gr_handle_chroot_unix(struct pid *pid)
39897 +{
39898 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
39899 + struct task_struct *p;
39900 +
39901 + if (unlikely(!grsec_enable_chroot_unix))
39902 + return 1;
39903 +
39904 + if (likely(!proc_is_chrooted(current)))
39905 + return 1;
39906 +
39907 + rcu_read_lock();
39908 + read_lock(&tasklist_lock);
39909 + p = pid_task(pid, PIDTYPE_PID);
39910 + if (unlikely(!have_same_root(current, p))) {
39911 + read_unlock(&tasklist_lock);
39912 + rcu_read_unlock();
39913 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
39914 + return 0;
39915 + }
39916 + read_unlock(&tasklist_lock);
39917 + rcu_read_unlock();
39918 +#endif
39919 + return 1;
39920 +}
39921 +
39922 +int
39923 +gr_handle_chroot_nice(void)
39924 +{
39925 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
39926 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
39927 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
39928 + return -EPERM;
39929 + }
39930 +#endif
39931 + return 0;
39932 +}
39933 +
39934 +int
39935 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
39936 +{
39937 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
39938 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
39939 + && proc_is_chrooted(current)) {
39940 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
39941 + return -EACCES;
39942 + }
39943 +#endif
39944 + return 0;
39945 +}
39946 +
39947 +int
39948 +gr_handle_chroot_rawio(const struct inode *inode)
39949 +{
39950 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
39951 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
39952 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
39953 + return 1;
39954 +#endif
39955 + return 0;
39956 +}
39957 +
39958 +int
39959 +gr_handle_chroot_fowner(struct pid *pid, enum pid_type type)
39960 +{
39961 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
39962 + struct task_struct *p;
39963 + int ret = 0;
39964 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !pid)
39965 + return ret;
39966 +
39967 + read_lock(&tasklist_lock);
39968 + do_each_pid_task(pid, type, p) {
39969 + if (!have_same_root(current, p)) {
39970 + ret = 1;
39971 + goto out;
39972 + }
39973 + } while_each_pid_task(pid, type, p);
39974 +out:
39975 + read_unlock(&tasklist_lock);
39976 + return ret;
39977 +#endif
39978 + return 0;
39979 +}
39980 +
39981 +int
39982 +gr_pid_is_chrooted(struct task_struct *p)
39983 +{
39984 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
39985 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
39986 + return 0;
39987 +
39988 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
39989 + !have_same_root(current, p)) {
39990 + return 1;
39991 + }
39992 +#endif
39993 + return 0;
39994 +}
39995 +
39996 +EXPORT_SYMBOL(gr_pid_is_chrooted);
39997 +
39998 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
39999 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
40000 +{
40001 + struct dentry *dentry = (struct dentry *)u_dentry;
40002 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
40003 + struct path realroot, currentroot;
40004 + struct task_struct *reaper = &init_task;
40005 + int ret = 1;
40006 +
40007 + get_fs_root(reaper->fs, &realroot);
40008 + get_fs_root(current->fs, &currentroot);
40009 +
40010 + spin_lock(&dcache_lock);
40011 + for (;;) {
40012 + if (unlikely((dentry == realroot.dentry && mnt == realroot.mnt)
40013 + || (dentry == currentroot.dentry && mnt == currentroot.mnt)))
40014 + break;
40015 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
40016 + if (mnt->mnt_parent == mnt)
40017 + break;
40018 + dentry = mnt->mnt_mountpoint;
40019 + mnt = mnt->mnt_parent;
40020 + continue;
40021 + }
40022 + dentry = dentry->d_parent;
40023 + }
40024 + spin_unlock(&dcache_lock);
40025 +
40026 + path_put(&currentroot);
40027 +
40028 + /* access is outside of chroot */
40029 + if (dentry == realroot.dentry && mnt == realroot.mnt)
40030 + ret = 0;
40031 +
40032 + path_put(&realroot);
40033 + return ret;
40034 +}
40035 +#endif
40036 +
40037 +int
40038 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
40039 +{
40040 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
40041 + if (!grsec_enable_chroot_fchdir)
40042 + return 1;
40043 +
40044 + if (!proc_is_chrooted(current))
40045 + return 1;
40046 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
40047 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
40048 + return 0;
40049 + }
40050 +#endif
40051 + return 1;
40052 +}
40053 +
40054 +int
40055 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
40056 + const time_t shm_createtime)
40057 +{
40058 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
40059 + struct pid *pid = NULL;
40060 + time_t starttime;
40061 +
40062 + if (unlikely(!grsec_enable_chroot_shmat))
40063 + return 1;
40064 +
40065 + if (likely(!proc_is_chrooted(current)))
40066 + return 1;
40067 +
40068 + rcu_read_lock();
40069 + read_lock(&tasklist_lock);
40070 +
40071 + pid = find_vpid(shm_cprid);
40072 + if (pid) {
40073 + struct task_struct *p;
40074 + p = pid_task(pid, PIDTYPE_PID);
40075 + starttime = p->start_time.tv_sec;
40076 + if (unlikely(!have_same_root(current, p) &&
40077 + time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
40078 + read_unlock(&tasklist_lock);
40079 + rcu_read_unlock();
40080 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
40081 + return 0;
40082 + }
40083 + } else {
40084 + pid = find_vpid(shm_lapid);
40085 + if (pid) {
40086 + struct task_struct *p;
40087 + p = pid_task(pid, PIDTYPE_PID);
40088 + if (unlikely(!have_same_root(current, p))) {
40089 + read_unlock(&tasklist_lock);
40090 + rcu_read_unlock();
40091 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
40092 + return 0;
40093 + }
40094 + }
40095 + }
40096 +
40097 + read_unlock(&tasklist_lock);
40098 + rcu_read_unlock();
40099 +#endif
40100 + return 1;
40101 +}
40102 +
40103 +void
40104 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
40105 +{
40106 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
40107 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
40108 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
40109 +#endif
40110 + return;
40111 +}
40112 +
40113 +int
40114 +gr_handle_chroot_mknod(const struct dentry *dentry,
40115 + const struct vfsmount *mnt, const int mode)
40116 +{
40117 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
40118 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
40119 + proc_is_chrooted(current)) {
40120 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
40121 + return -EPERM;
40122 + }
40123 +#endif
40124 + return 0;
40125 +}
40126 +
40127 +int
40128 +gr_handle_chroot_mount(const struct dentry *dentry,
40129 + const struct vfsmount *mnt, const char *dev_name)
40130 +{
40131 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
40132 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
40133 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
40134 + return -EPERM;
40135 + }
40136 +#endif
40137 + return 0;
40138 +}
40139 +
40140 +int
40141 +gr_handle_chroot_pivot(void)
40142 +{
40143 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
40144 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
40145 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
40146 + return -EPERM;
40147 + }
40148 +#endif
40149 + return 0;
40150 +}
40151 +
40152 +int
40153 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
40154 +{
40155 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
40156 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
40157 + !gr_is_outside_chroot(dentry, mnt)) {
40158 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
40159 + return -EPERM;
40160 + }
40161 +#endif
40162 + return 0;
40163 +}
40164 +
40165 +int
40166 +gr_handle_chroot_caps(struct path *path)
40167 +{
40168 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
40169 + if (grsec_enable_chroot_caps && current->pid > 1 && current->fs != NULL &&
40170 + (init_task.fs->root.dentry != path->dentry) &&
40171 + (current->nsproxy->mnt_ns->root->mnt_root != path->dentry)) {
40172 +
40173 + kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
40174 + const struct cred *old = current_cred();
40175 + struct cred *new = prepare_creds();
40176 + if (new == NULL)
40177 + return 1;
40178 +
40179 + new->cap_permitted = cap_drop(old->cap_permitted,
40180 + chroot_caps);
40181 + new->cap_inheritable = cap_drop(old->cap_inheritable,
40182 + chroot_caps);
40183 + new->cap_effective = cap_drop(old->cap_effective,
40184 + chroot_caps);
40185 +
40186 + commit_creds(new);
40187 +
40188 + return 0;
40189 + }
40190 +#endif
40191 + return 0;
40192 +}
40193 +
40194 +int
40195 +gr_handle_chroot_sysctl(const int op)
40196 +{
40197 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
40198 + if (grsec_enable_chroot_sysctl && (op & MAY_WRITE) &&
40199 + proc_is_chrooted(current))
40200 + return -EACCES;
40201 +#endif
40202 + return 0;
40203 +}
40204 +
40205 +void
40206 +gr_handle_chroot_chdir(struct path *path)
40207 +{
40208 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
40209 + if (grsec_enable_chroot_chdir)
40210 + set_fs_pwd(current->fs, path);
40211 +#endif
40212 + return;
40213 +}
40214 +
40215 +int
40216 +gr_handle_chroot_chmod(const struct dentry *dentry,
40217 + const struct vfsmount *mnt, const int mode)
40218 +{
40219 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
40220 + if (grsec_enable_chroot_chmod &&
40221 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
40222 + proc_is_chrooted(current)) {
40223 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
40224 + return -EPERM;
40225 + }
40226 +#endif
40227 + return 0;
40228 +}
40229 +
40230 +#ifdef CONFIG_SECURITY
40231 +EXPORT_SYMBOL(gr_handle_chroot_caps);
40232 +#endif
40233 diff -urNp linux-2.6.36/grsecurity/grsec_disabled.c linux-2.6.36/grsecurity/grsec_disabled.c
40234 --- linux-2.6.36/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
40235 +++ linux-2.6.36/grsecurity/grsec_disabled.c 2010-11-06 18:58:50.000000000 -0400
40236 @@ -0,0 +1,431 @@
40237 +#include <linux/kernel.h>
40238 +#include <linux/module.h>
40239 +#include <linux/sched.h>
40240 +#include <linux/file.h>
40241 +#include <linux/fs.h>
40242 +#include <linux/kdev_t.h>
40243 +#include <linux/net.h>
40244 +#include <linux/in.h>
40245 +#include <linux/ip.h>
40246 +#include <linux/skbuff.h>
40247 +#include <linux/sysctl.h>
40248 +
40249 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
40250 +void
40251 +pax_set_initial_flags(struct linux_binprm *bprm)
40252 +{
40253 + return;
40254 +}
40255 +#endif
40256 +
40257 +#ifdef CONFIG_SYSCTL
40258 +__u32
40259 +gr_handle_sysctl(const struct ctl_table * table, const int op)
40260 +{
40261 + return 0;
40262 +}
40263 +#endif
40264 +
40265 +#ifdef CONFIG_TASKSTATS
40266 +int gr_is_taskstats_denied(int pid)
40267 +{
40268 + return 0;
40269 +}
40270 +#endif
40271 +
40272 +int
40273 +gr_acl_is_enabled(void)
40274 +{
40275 + return 0;
40276 +}
40277 +
40278 +int
40279 +gr_handle_rawio(const struct inode *inode)
40280 +{
40281 + return 0;
40282 +}
40283 +
40284 +void
40285 +gr_acl_handle_psacct(struct task_struct *task, const long code)
40286 +{
40287 + return;
40288 +}
40289 +
40290 +int
40291 +gr_handle_ptrace(struct task_struct *task, const long request)
40292 +{
40293 + return 0;
40294 +}
40295 +
40296 +int
40297 +gr_handle_proc_ptrace(struct task_struct *task)
40298 +{
40299 + return 0;
40300 +}
40301 +
40302 +void
40303 +gr_learn_resource(const struct task_struct *task,
40304 + const int res, const unsigned long wanted, const int gt)
40305 +{
40306 + return;
40307 +}
40308 +
40309 +int
40310 +gr_set_acls(const int type)
40311 +{
40312 + return 0;
40313 +}
40314 +
40315 +int
40316 +gr_check_hidden_task(const struct task_struct *tsk)
40317 +{
40318 + return 0;
40319 +}
40320 +
40321 +int
40322 +gr_check_protected_task(const struct task_struct *task)
40323 +{
40324 + return 0;
40325 +}
40326 +
40327 +int
40328 +gr_check_protected_task_fowner(struct pid *pid, enum pid_type type)
40329 +{
40330 + return 0;
40331 +}
40332 +
40333 +void
40334 +gr_copy_label(struct task_struct *tsk)
40335 +{
40336 + return;
40337 +}
40338 +
40339 +void
40340 +gr_set_pax_flags(struct task_struct *task)
40341 +{
40342 + return;
40343 +}
40344 +
40345 +int
40346 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
40347 + const int unsafe_share)
40348 +{
40349 + return 0;
40350 +}
40351 +
40352 +void
40353 +gr_handle_delete(const ino_t ino, const dev_t dev)
40354 +{
40355 + return;
40356 +}
40357 +
40358 +void
40359 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
40360 +{
40361 + return;
40362 +}
40363 +
40364 +void
40365 +gr_handle_crash(struct task_struct *task, const int sig)
40366 +{
40367 + return;
40368 +}
40369 +
40370 +int
40371 +gr_check_crash_exec(const struct file *filp)
40372 +{
40373 + return 0;
40374 +}
40375 +
40376 +int
40377 +gr_check_crash_uid(const uid_t uid)
40378 +{
40379 + return 0;
40380 +}
40381 +
40382 +void
40383 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
40384 + struct dentry *old_dentry,
40385 + struct dentry *new_dentry,
40386 + struct vfsmount *mnt, const __u8 replace)
40387 +{
40388 + return;
40389 +}
40390 +
40391 +int
40392 +gr_search_socket(const int family, const int type, const int protocol)
40393 +{
40394 + return 1;
40395 +}
40396 +
40397 +int
40398 +gr_search_connectbind(const int mode, const struct socket *sock,
40399 + const struct sockaddr_in *addr)
40400 +{
40401 + return 0;
40402 +}
40403 +
40404 +int
40405 +gr_is_capable(const int cap)
40406 +{
40407 + return 1;
40408 +}
40409 +
40410 +int
40411 +gr_is_capable_nolog(const int cap)
40412 +{
40413 + return 1;
40414 +}
40415 +
40416 +void
40417 +gr_handle_alertkill(struct task_struct *task)
40418 +{
40419 + return;
40420 +}
40421 +
40422 +__u32
40423 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
40424 +{
40425 + return 1;
40426 +}
40427 +
40428 +__u32
40429 +gr_acl_handle_hidden_file(const struct dentry * dentry,
40430 + const struct vfsmount * mnt)
40431 +{
40432 + return 1;
40433 +}
40434 +
40435 +__u32
40436 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
40437 + const int fmode)
40438 +{
40439 + return 1;
40440 +}
40441 +
40442 +__u32
40443 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
40444 +{
40445 + return 1;
40446 +}
40447 +
40448 +__u32
40449 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
40450 +{
40451 + return 1;
40452 +}
40453 +
40454 +int
40455 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
40456 + unsigned int *vm_flags)
40457 +{
40458 + return 1;
40459 +}
40460 +
40461 +__u32
40462 +gr_acl_handle_truncate(const struct dentry * dentry,
40463 + const struct vfsmount * mnt)
40464 +{
40465 + return 1;
40466 +}
40467 +
40468 +__u32
40469 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
40470 +{
40471 + return 1;
40472 +}
40473 +
40474 +__u32
40475 +gr_acl_handle_access(const struct dentry * dentry,
40476 + const struct vfsmount * mnt, const int fmode)
40477 +{
40478 + return 1;
40479 +}
40480 +
40481 +__u32
40482 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
40483 + mode_t mode)
40484 +{
40485 + return 1;
40486 +}
40487 +
40488 +__u32
40489 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
40490 + mode_t mode)
40491 +{
40492 + return 1;
40493 +}
40494 +
40495 +__u32
40496 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
40497 +{
40498 + return 1;
40499 +}
40500 +
40501 +void
40502 +grsecurity_init(void)
40503 +{
40504 + return;
40505 +}
40506 +
40507 +__u32
40508 +gr_acl_handle_mknod(const struct dentry * new_dentry,
40509 + const struct dentry * parent_dentry,
40510 + const struct vfsmount * parent_mnt,
40511 + const int mode)
40512 +{
40513 + return 1;
40514 +}
40515 +
40516 +__u32
40517 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
40518 + const struct dentry * parent_dentry,
40519 + const struct vfsmount * parent_mnt)
40520 +{
40521 + return 1;
40522 +}
40523 +
40524 +__u32
40525 +gr_acl_handle_symlink(const struct dentry * new_dentry,
40526 + const struct dentry * parent_dentry,
40527 + const struct vfsmount * parent_mnt, const char *from)
40528 +{
40529 + return 1;
40530 +}
40531 +
40532 +__u32
40533 +gr_acl_handle_link(const struct dentry * new_dentry,
40534 + const struct dentry * parent_dentry,
40535 + const struct vfsmount * parent_mnt,
40536 + const struct dentry * old_dentry,
40537 + const struct vfsmount * old_mnt, const char *to)
40538 +{
40539 + return 1;
40540 +}
40541 +
40542 +int
40543 +gr_acl_handle_rename(const struct dentry *new_dentry,
40544 + const struct dentry *parent_dentry,
40545 + const struct vfsmount *parent_mnt,
40546 + const struct dentry *old_dentry,
40547 + const struct inode *old_parent_inode,
40548 + const struct vfsmount *old_mnt, const char *newname)
40549 +{
40550 + return 0;
40551 +}
40552 +
40553 +int
40554 +gr_acl_handle_filldir(const struct file *file, const char *name,
40555 + const int namelen, const ino_t ino)
40556 +{
40557 + return 1;
40558 +}
40559 +
40560 +int
40561 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
40562 + const time_t shm_createtime, const uid_t cuid, const int shmid)
40563 +{
40564 + return 1;
40565 +}
40566 +
40567 +int
40568 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
40569 +{
40570 + return 0;
40571 +}
40572 +
40573 +int
40574 +gr_search_accept(const struct socket *sock)
40575 +{
40576 + return 0;
40577 +}
40578 +
40579 +int
40580 +gr_search_listen(const struct socket *sock)
40581 +{
40582 + return 0;
40583 +}
40584 +
40585 +int
40586 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
40587 +{
40588 + return 0;
40589 +}
40590 +
40591 +__u32
40592 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
40593 +{
40594 + return 1;
40595 +}
40596 +
40597 +__u32
40598 +gr_acl_handle_creat(const struct dentry * dentry,
40599 + const struct dentry * p_dentry,
40600 + const struct vfsmount * p_mnt, const int fmode,
40601 + const int imode)
40602 +{
40603 + return 1;
40604 +}
40605 +
40606 +void
40607 +gr_acl_handle_exit(void)
40608 +{
40609 + return;
40610 +}
40611 +
40612 +int
40613 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
40614 +{
40615 + return 1;
40616 +}
40617 +
40618 +void
40619 +gr_set_role_label(const uid_t uid, const gid_t gid)
40620 +{
40621 + return;
40622 +}
40623 +
40624 +int
40625 +gr_acl_handle_procpidmem(const struct task_struct *task)
40626 +{
40627 + return 0;
40628 +}
40629 +
40630 +int
40631 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
40632 +{
40633 + return 0;
40634 +}
40635 +
40636 +int
40637 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
40638 +{
40639 + return 0;
40640 +}
40641 +
40642 +void
40643 +gr_set_kernel_label(struct task_struct *task)
40644 +{
40645 + return;
40646 +}
40647 +
40648 +int
40649 +gr_check_user_change(int real, int effective, int fs)
40650 +{
40651 + return 0;
40652 +}
40653 +
40654 +int
40655 +gr_check_group_change(int real, int effective, int fs)
40656 +{
40657 + return 0;
40658 +}
40659 +
40660 +EXPORT_SYMBOL(gr_is_capable);
40661 +EXPORT_SYMBOL(gr_is_capable_nolog);
40662 +EXPORT_SYMBOL(gr_learn_resource);
40663 +EXPORT_SYMBOL(gr_set_kernel_label);
40664 +#ifdef CONFIG_SECURITY
40665 +EXPORT_SYMBOL(gr_check_user_change);
40666 +EXPORT_SYMBOL(gr_check_group_change);
40667 +#endif
40668 diff -urNp linux-2.6.36/grsecurity/grsec_exec.c linux-2.6.36/grsecurity/grsec_exec.c
40669 --- linux-2.6.36/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
40670 +++ linux-2.6.36/grsecurity/grsec_exec.c 2010-11-06 19:52:16.000000000 -0400
40671 @@ -0,0 +1,88 @@
40672 +#include <linux/kernel.h>
40673 +#include <linux/sched.h>
40674 +#include <linux/file.h>
40675 +#include <linux/binfmts.h>
40676 +#include <linux/smp_lock.h>
40677 +#include <linux/fs.h>
40678 +#include <linux/types.h>
40679 +#include <linux/grdefs.h>
40680 +#include <linux/grinternal.h>
40681 +#include <linux/capability.h>
40682 +
40683 +#include <asm/uaccess.h>
40684 +
40685 +#ifdef CONFIG_GRKERNSEC_EXECLOG
40686 +static char gr_exec_arg_buf[132];
40687 +static DECLARE_MUTEX(gr_exec_arg_sem);
40688 +#endif
40689 +
40690 +int
40691 +gr_handle_nproc(void)
40692 +{
40693 +#ifdef CONFIG_GRKERNSEC_EXECVE
40694 + const struct cred *cred = current_cred();
40695 + if (grsec_enable_execve && cred->user &&
40696 + (atomic_read(&cred->user->processes) > rlimit(RLIMIT_NPROC)) &&
40697 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
40698 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
40699 + return -EAGAIN;
40700 + }
40701 +#endif
40702 + return 0;
40703 +}
40704 +
40705 +void
40706 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *const __user *argv)
40707 +{
40708 +#ifdef CONFIG_GRKERNSEC_EXECLOG
40709 + char *grarg = gr_exec_arg_buf;
40710 + unsigned int i, x, execlen = 0;
40711 + char c;
40712 +
40713 + if (!((grsec_enable_execlog && grsec_enable_group &&
40714 + in_group_p(grsec_audit_gid))
40715 + || (grsec_enable_execlog && !grsec_enable_group)))
40716 + return;
40717 +
40718 + down(&gr_exec_arg_sem);
40719 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
40720 +
40721 + if (unlikely(argv == NULL))
40722 + goto log;
40723 +
40724 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
40725 + const char __user *p;
40726 + unsigned int len;
40727 +
40728 + if (copy_from_user(&p, argv + i, sizeof(p)))
40729 + goto log;
40730 + if (!p)
40731 + goto log;
40732 + len = strnlen_user(p, 128 - execlen);
40733 + if (len > 128 - execlen)
40734 + len = 128 - execlen;
40735 + else if (len > 0)
40736 + len--;
40737 + if (copy_from_user(grarg + execlen, p, len))
40738 + goto log;
40739 +
40740 + /* rewrite unprintable characters */
40741 + for (x = 0; x < len; x++) {
40742 + c = *(grarg + execlen + x);
40743 + if (c < 32 || c > 126)
40744 + *(grarg + execlen + x) = ' ';
40745 + }
40746 +
40747 + execlen += len;
40748 + *(grarg + execlen) = ' ';
40749 + *(grarg + execlen + 1) = '\0';
40750 + execlen++;
40751 + }
40752 +
40753 + log:
40754 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
40755 + bprm->file->f_path.mnt, grarg);
40756 + up(&gr_exec_arg_sem);
40757 +#endif
40758 + return;
40759 +}
40760 diff -urNp linux-2.6.36/grsecurity/grsec_fifo.c linux-2.6.36/grsecurity/grsec_fifo.c
40761 --- linux-2.6.36/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
40762 +++ linux-2.6.36/grsecurity/grsec_fifo.c 2010-11-06 18:58:50.000000000 -0400
40763 @@ -0,0 +1,24 @@
40764 +#include <linux/kernel.h>
40765 +#include <linux/sched.h>
40766 +#include <linux/fs.h>
40767 +#include <linux/file.h>
40768 +#include <linux/grinternal.h>
40769 +
40770 +int
40771 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
40772 + const struct dentry *dir, const int flag, const int acc_mode)
40773 +{
40774 +#ifdef CONFIG_GRKERNSEC_FIFO
40775 + const struct cred *cred = current_cred();
40776 +
40777 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
40778 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
40779 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
40780 + (cred->fsuid != dentry->d_inode->i_uid)) {
40781 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
40782 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
40783 + return -EACCES;
40784 + }
40785 +#endif
40786 + return 0;
40787 +}
40788 diff -urNp linux-2.6.36/grsecurity/grsec_fork.c linux-2.6.36/grsecurity/grsec_fork.c
40789 --- linux-2.6.36/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
40790 +++ linux-2.6.36/grsecurity/grsec_fork.c 2010-11-06 18:58:50.000000000 -0400
40791 @@ -0,0 +1,23 @@
40792 +#include <linux/kernel.h>
40793 +#include <linux/sched.h>
40794 +#include <linux/grsecurity.h>
40795 +#include <linux/grinternal.h>
40796 +#include <linux/errno.h>
40797 +
40798 +void
40799 +gr_log_forkfail(const int retval)
40800 +{
40801 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
40802 + if (grsec_enable_forkfail && (retval == -EAGAIN || retval == -ENOMEM)) {
40803 + switch (retval) {
40804 + case -EAGAIN:
40805 + gr_log_str(GR_DONT_AUDIT, GR_FAILFORK_MSG, "EAGAIN");
40806 + break;
40807 + case -ENOMEM:
40808 + gr_log_str(GR_DONT_AUDIT, GR_FAILFORK_MSG, "ENOMEM");
40809 + break;
40810 + }
40811 + }
40812 +#endif
40813 + return;
40814 +}
40815 diff -urNp linux-2.6.36/grsecurity/grsec_init.c linux-2.6.36/grsecurity/grsec_init.c
40816 --- linux-2.6.36/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
40817 +++ linux-2.6.36/grsecurity/grsec_init.c 2010-11-06 18:58:50.000000000 -0400
40818 @@ -0,0 +1,270 @@
40819 +#include <linux/kernel.h>
40820 +#include <linux/sched.h>
40821 +#include <linux/mm.h>
40822 +#include <linux/smp_lock.h>
40823 +#include <linux/gracl.h>
40824 +#include <linux/slab.h>
40825 +#include <linux/vmalloc.h>
40826 +#include <linux/percpu.h>
40827 +#include <linux/module.h>
40828 +
40829 +int grsec_enable_link;
40830 +int grsec_enable_dmesg;
40831 +int grsec_enable_harden_ptrace;
40832 +int grsec_enable_fifo;
40833 +int grsec_enable_execve;
40834 +int grsec_enable_execlog;
40835 +int grsec_enable_signal;
40836 +int grsec_enable_forkfail;
40837 +int grsec_enable_audit_ptrace;
40838 +int grsec_enable_time;
40839 +int grsec_enable_audit_textrel;
40840 +int grsec_enable_group;
40841 +int grsec_audit_gid;
40842 +int grsec_enable_chdir;
40843 +int grsec_enable_mount;
40844 +int grsec_enable_rofs;
40845 +int grsec_enable_chroot_findtask;
40846 +int grsec_enable_chroot_mount;
40847 +int grsec_enable_chroot_shmat;
40848 +int grsec_enable_chroot_fchdir;
40849 +int grsec_enable_chroot_double;
40850 +int grsec_enable_chroot_pivot;
40851 +int grsec_enable_chroot_chdir;
40852 +int grsec_enable_chroot_chmod;
40853 +int grsec_enable_chroot_mknod;
40854 +int grsec_enable_chroot_nice;
40855 +int grsec_enable_chroot_execlog;
40856 +int grsec_enable_chroot_caps;
40857 +int grsec_enable_chroot_sysctl;
40858 +int grsec_enable_chroot_unix;
40859 +int grsec_enable_tpe;
40860 +int grsec_tpe_gid;
40861 +int grsec_enable_blackhole;
40862 +#ifdef CONFIG_IPV6_MODULE
40863 +EXPORT_SYMBOL(grsec_enable_blackhole);
40864 +#endif
40865 +int grsec_lastack_retries;
40866 +int grsec_enable_tpe_all;
40867 +int grsec_enable_tpe_invert;
40868 +int grsec_enable_socket_all;
40869 +int grsec_socket_all_gid;
40870 +int grsec_enable_socket_client;
40871 +int grsec_socket_client_gid;
40872 +int grsec_enable_socket_server;
40873 +int grsec_socket_server_gid;
40874 +int grsec_resource_logging;
40875 +int grsec_disable_privio;
40876 +int grsec_enable_log_rwxmaps;
40877 +int grsec_lock;
40878 +
40879 +DEFINE_SPINLOCK(grsec_alert_lock);
40880 +unsigned long grsec_alert_wtime = 0;
40881 +unsigned long grsec_alert_fyet = 0;
40882 +
40883 +DEFINE_SPINLOCK(grsec_audit_lock);
40884 +
40885 +DEFINE_RWLOCK(grsec_exec_file_lock);
40886 +
40887 +char *gr_shared_page[4];
40888 +
40889 +char *gr_alert_log_fmt;
40890 +char *gr_audit_log_fmt;
40891 +char *gr_alert_log_buf;
40892 +char *gr_audit_log_buf;
40893 +
40894 +extern struct gr_arg *gr_usermode;
40895 +extern unsigned char *gr_system_salt;
40896 +extern unsigned char *gr_system_sum;
40897 +
40898 +void __init
40899 +grsecurity_init(void)
40900 +{
40901 + int j;
40902 + /* create the per-cpu shared pages */
40903 +
40904 +#ifdef CONFIG_X86
40905 + memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
40906 +#endif
40907 +
40908 + for (j = 0; j < 4; j++) {
40909 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(unsigned long long));
40910 + if (gr_shared_page[j] == NULL) {
40911 + panic("Unable to allocate grsecurity shared page");
40912 + return;
40913 + }
40914 + }
40915 +
40916 + /* allocate log buffers */
40917 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
40918 + if (!gr_alert_log_fmt) {
40919 + panic("Unable to allocate grsecurity alert log format buffer");
40920 + return;
40921 + }
40922 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
40923 + if (!gr_audit_log_fmt) {
40924 + panic("Unable to allocate grsecurity audit log format buffer");
40925 + return;
40926 + }
40927 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
40928 + if (!gr_alert_log_buf) {
40929 + panic("Unable to allocate grsecurity alert log buffer");
40930 + return;
40931 + }
40932 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
40933 + if (!gr_audit_log_buf) {
40934 + panic("Unable to allocate grsecurity audit log buffer");
40935 + return;
40936 + }
40937 +
40938 + /* allocate memory for authentication structure */
40939 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
40940 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
40941 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
40942 +
40943 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
40944 + panic("Unable to allocate grsecurity authentication structure");
40945 + return;
40946 + }
40947 +
40948 +
40949 +#ifdef CONFIG_GRKERNSEC_IO
40950 +#if !defined(CONFIG_GRKERNSEC_SYSCTL_DISTRO)
40951 + grsec_disable_privio = 1;
40952 +#elif defined(CONFIG_GRKERNSEC_SYSCTL_ON)
40953 + grsec_disable_privio = 1;
40954 +#else
40955 + grsec_disable_privio = 0;
40956 +#endif
40957 +#endif
40958 +
40959 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
40960 + /* for backward compatibility, tpe_invert always defaults to on if
40961 + enabled in the kernel
40962 + */
40963 + grsec_enable_tpe_invert = 1;
40964 +#endif
40965 +
40966 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
40967 +#ifndef CONFIG_GRKERNSEC_SYSCTL
40968 + grsec_lock = 1;
40969 +#endif
40970 +
40971 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
40972 + grsec_enable_audit_textrel = 1;
40973 +#endif
40974 +#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
40975 + grsec_enable_log_rwxmaps = 1;
40976 +#endif
40977 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
40978 + grsec_enable_group = 1;
40979 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
40980 +#endif
40981 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
40982 + grsec_enable_chdir = 1;
40983 +#endif
40984 +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
40985 + grsec_enable_harden_ptrace = 1;
40986 +#endif
40987 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
40988 + grsec_enable_mount = 1;
40989 +#endif
40990 +#ifdef CONFIG_GRKERNSEC_LINK
40991 + grsec_enable_link = 1;
40992 +#endif
40993 +#ifdef CONFIG_GRKERNSEC_DMESG
40994 + grsec_enable_dmesg = 1;
40995 +#endif
40996 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
40997 + grsec_enable_blackhole = 1;
40998 + grsec_lastack_retries = 4;
40999 +#endif
41000 +#ifdef CONFIG_GRKERNSEC_FIFO
41001 + grsec_enable_fifo = 1;
41002 +#endif
41003 +#ifdef CONFIG_GRKERNSEC_EXECVE
41004 + grsec_enable_execve = 1;
41005 +#endif
41006 +#ifdef CONFIG_GRKERNSEC_EXECLOG
41007 + grsec_enable_execlog = 1;
41008 +#endif
41009 +#ifdef CONFIG_GRKERNSEC_SIGNAL
41010 + grsec_enable_signal = 1;
41011 +#endif
41012 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
41013 + grsec_enable_forkfail = 1;
41014 +#endif
41015 +#ifdef CONFIG_GRKERNSEC_TIME
41016 + grsec_enable_time = 1;
41017 +#endif
41018 +#ifdef CONFIG_GRKERNSEC_RESLOG
41019 + grsec_resource_logging = 1;
41020 +#endif
41021 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
41022 + grsec_enable_chroot_findtask = 1;
41023 +#endif
41024 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
41025 + grsec_enable_chroot_unix = 1;
41026 +#endif
41027 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
41028 + grsec_enable_chroot_mount = 1;
41029 +#endif
41030 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
41031 + grsec_enable_chroot_fchdir = 1;
41032 +#endif
41033 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
41034 + grsec_enable_chroot_shmat = 1;
41035 +#endif
41036 +#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
41037 + grsec_enable_audit_ptrace = 1;
41038 +#endif
41039 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
41040 + grsec_enable_chroot_double = 1;
41041 +#endif
41042 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
41043 + grsec_enable_chroot_pivot = 1;
41044 +#endif
41045 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
41046 + grsec_enable_chroot_chdir = 1;
41047 +#endif
41048 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
41049 + grsec_enable_chroot_chmod = 1;
41050 +#endif
41051 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
41052 + grsec_enable_chroot_mknod = 1;
41053 +#endif
41054 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
41055 + grsec_enable_chroot_nice = 1;
41056 +#endif
41057 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
41058 + grsec_enable_chroot_execlog = 1;
41059 +#endif
41060 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
41061 + grsec_enable_chroot_caps = 1;
41062 +#endif
41063 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
41064 + grsec_enable_chroot_sysctl = 1;
41065 +#endif
41066 +#ifdef CONFIG_GRKERNSEC_TPE
41067 + grsec_enable_tpe = 1;
41068 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
41069 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
41070 + grsec_enable_tpe_all = 1;
41071 +#endif
41072 +#endif
41073 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
41074 + grsec_enable_socket_all = 1;
41075 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
41076 +#endif
41077 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
41078 + grsec_enable_socket_client = 1;
41079 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
41080 +#endif
41081 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
41082 + grsec_enable_socket_server = 1;
41083 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
41084 +#endif
41085 +#endif
41086 +
41087 + return;
41088 +}
41089 diff -urNp linux-2.6.36/grsecurity/grsec_link.c linux-2.6.36/grsecurity/grsec_link.c
41090 --- linux-2.6.36/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
41091 +++ linux-2.6.36/grsecurity/grsec_link.c 2010-11-06 18:58:50.000000000 -0400
41092 @@ -0,0 +1,43 @@
41093 +#include <linux/kernel.h>
41094 +#include <linux/sched.h>
41095 +#include <linux/fs.h>
41096 +#include <linux/file.h>
41097 +#include <linux/grinternal.h>
41098 +
41099 +int
41100 +gr_handle_follow_link(const struct inode *parent,
41101 + const struct inode *inode,
41102 + const struct dentry *dentry, const struct vfsmount *mnt)
41103 +{
41104 +#ifdef CONFIG_GRKERNSEC_LINK
41105 + const struct cred *cred = current_cred();
41106 +
41107 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
41108 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
41109 + (parent->i_mode & S_IWOTH) && (cred->fsuid != inode->i_uid)) {
41110 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
41111 + return -EACCES;
41112 + }
41113 +#endif
41114 + return 0;
41115 +}
41116 +
41117 +int
41118 +gr_handle_hardlink(const struct dentry *dentry,
41119 + const struct vfsmount *mnt,
41120 + struct inode *inode, const int mode, const char *to)
41121 +{
41122 +#ifdef CONFIG_GRKERNSEC_LINK
41123 + const struct cred *cred = current_cred();
41124 +
41125 + if (grsec_enable_link && cred->fsuid != inode->i_uid &&
41126 + (!S_ISREG(mode) || (mode & S_ISUID) ||
41127 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
41128 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
41129 + !capable(CAP_FOWNER) && cred->uid) {
41130 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
41131 + return -EPERM;
41132 + }
41133 +#endif
41134 + return 0;
41135 +}
41136 diff -urNp linux-2.6.36/grsecurity/grsec_log.c linux-2.6.36/grsecurity/grsec_log.c
41137 --- linux-2.6.36/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
41138 +++ linux-2.6.36/grsecurity/grsec_log.c 2010-11-06 18:58:50.000000000 -0400
41139 @@ -0,0 +1,310 @@
41140 +#include <linux/kernel.h>
41141 +#include <linux/sched.h>
41142 +#include <linux/file.h>
41143 +#include <linux/tty.h>
41144 +#include <linux/fs.h>
41145 +#include <linux/grinternal.h>
41146 +
41147 +#ifdef CONFIG_TREE_PREEMPT_RCU
41148 +#define DISABLE_PREEMPT() preempt_disable()
41149 +#define ENABLE_PREEMPT() preempt_enable()
41150 +#else
41151 +#define DISABLE_PREEMPT()
41152 +#define ENABLE_PREEMPT()
41153 +#endif
41154 +
41155 +#define BEGIN_LOCKS(x) \
41156 + DISABLE_PREEMPT(); \
41157 + rcu_read_lock(); \
41158 + read_lock(&tasklist_lock); \
41159 + read_lock(&grsec_exec_file_lock); \
41160 + if (x != GR_DO_AUDIT) \
41161 + spin_lock(&grsec_alert_lock); \
41162 + else \
41163 + spin_lock(&grsec_audit_lock)
41164 +
41165 +#define END_LOCKS(x) \
41166 + if (x != GR_DO_AUDIT) \
41167 + spin_unlock(&grsec_alert_lock); \
41168 + else \
41169 + spin_unlock(&grsec_audit_lock); \
41170 + read_unlock(&grsec_exec_file_lock); \
41171 + read_unlock(&tasklist_lock); \
41172 + rcu_read_unlock(); \
41173 + ENABLE_PREEMPT(); \
41174 + if (x == GR_DONT_AUDIT) \
41175 + gr_handle_alertkill(current)
41176 +
41177 +enum {
41178 + FLOODING,
41179 + NO_FLOODING
41180 +};
41181 +
41182 +extern char *gr_alert_log_fmt;
41183 +extern char *gr_audit_log_fmt;
41184 +extern char *gr_alert_log_buf;
41185 +extern char *gr_audit_log_buf;
41186 +
41187 +static int gr_log_start(int audit)
41188 +{
41189 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
41190 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
41191 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
41192 +
41193 + if (audit == GR_DO_AUDIT)
41194 + goto set_fmt;
41195 +
41196 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
41197 + grsec_alert_wtime = jiffies;
41198 + grsec_alert_fyet = 0;
41199 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
41200 + grsec_alert_fyet++;
41201 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
41202 + grsec_alert_wtime = jiffies;
41203 + grsec_alert_fyet++;
41204 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
41205 + return FLOODING;
41206 + } else return FLOODING;
41207 +
41208 +set_fmt:
41209 + memset(buf, 0, PAGE_SIZE);
41210 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
41211 + sprintf(fmt, "%s%s", loglevel, "grsec: From %pI4: (%.64s:%c:%.950s) ");
41212 + snprintf(buf, PAGE_SIZE - 1, fmt, &current->signal->curr_ip, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
41213 + } else if (current->signal->curr_ip) {
41214 + sprintf(fmt, "%s%s", loglevel, "grsec: From %pI4: ");
41215 + snprintf(buf, PAGE_SIZE - 1, fmt, &current->signal->curr_ip);
41216 + } else if (gr_acl_is_enabled()) {
41217 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
41218 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
41219 + } else {
41220 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
41221 + strcpy(buf, fmt);
41222 + }
41223 +
41224 + return NO_FLOODING;
41225 +}
41226 +
41227 +static void gr_log_middle(int audit, const char *msg, va_list ap)
41228 + __attribute__ ((format (printf, 2, 0)));
41229 +
41230 +static void gr_log_middle(int audit, const char *msg, va_list ap)
41231 +{
41232 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
41233 + unsigned int len = strlen(buf);
41234 +
41235 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
41236 +
41237 + return;
41238 +}
41239 +
41240 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
41241 + __attribute__ ((format (printf, 2, 3)));
41242 +
41243 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
41244 +{
41245 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
41246 + unsigned int len = strlen(buf);
41247 + va_list ap;
41248 +
41249 + va_start(ap, msg);
41250 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
41251 + va_end(ap);
41252 +
41253 + return;
41254 +}
41255 +
41256 +static void gr_log_end(int audit)
41257 +{
41258 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
41259 + unsigned int len = strlen(buf);
41260 +
41261 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current, current_cred(), __task_cred(current->real_parent)));
41262 + printk("%s\n", buf);
41263 +
41264 + return;
41265 +}
41266 +
41267 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
41268 +{
41269 + int logtype;
41270 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
41271 + char *str1, *str2, *str3;
41272 + void *voidptr;
41273 + int num1, num2;
41274 + unsigned long ulong1, ulong2;
41275 + struct dentry *dentry;
41276 + struct vfsmount *mnt;
41277 + struct file *file;
41278 + struct task_struct *task;
41279 + const struct cred *cred, *pcred;
41280 + va_list ap;
41281 +
41282 + BEGIN_LOCKS(audit);
41283 + logtype = gr_log_start(audit);
41284 + if (logtype == FLOODING) {
41285 + END_LOCKS(audit);
41286 + return;
41287 + }
41288 + va_start(ap, argtypes);
41289 + switch (argtypes) {
41290 + case GR_TTYSNIFF:
41291 + task = va_arg(ap, struct task_struct *);
41292 + 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);
41293 + break;
41294 + case GR_SYSCTL_HIDDEN:
41295 + str1 = va_arg(ap, char *);
41296 + gr_log_middle_varargs(audit, msg, result, str1);
41297 + break;
41298 + case GR_RBAC:
41299 + dentry = va_arg(ap, struct dentry *);
41300 + mnt = va_arg(ap, struct vfsmount *);
41301 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
41302 + break;
41303 + case GR_RBAC_STR:
41304 + dentry = va_arg(ap, struct dentry *);
41305 + mnt = va_arg(ap, struct vfsmount *);
41306 + str1 = va_arg(ap, char *);
41307 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
41308 + break;
41309 + case GR_STR_RBAC:
41310 + str1 = va_arg(ap, char *);
41311 + dentry = va_arg(ap, struct dentry *);
41312 + mnt = va_arg(ap, struct vfsmount *);
41313 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
41314 + break;
41315 + case GR_RBAC_MODE2:
41316 + dentry = va_arg(ap, struct dentry *);
41317 + mnt = va_arg(ap, struct vfsmount *);
41318 + str1 = va_arg(ap, char *);
41319 + str2 = va_arg(ap, char *);
41320 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
41321 + break;
41322 + case GR_RBAC_MODE3:
41323 + dentry = va_arg(ap, struct dentry *);
41324 + mnt = va_arg(ap, struct vfsmount *);
41325 + str1 = va_arg(ap, char *);
41326 + str2 = va_arg(ap, char *);
41327 + str3 = va_arg(ap, char *);
41328 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
41329 + break;
41330 + case GR_FILENAME:
41331 + dentry = va_arg(ap, struct dentry *);
41332 + mnt = va_arg(ap, struct vfsmount *);
41333 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
41334 + break;
41335 + case GR_STR_FILENAME:
41336 + str1 = va_arg(ap, char *);
41337 + dentry = va_arg(ap, struct dentry *);
41338 + mnt = va_arg(ap, struct vfsmount *);
41339 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
41340 + break;
41341 + case GR_FILENAME_STR:
41342 + dentry = va_arg(ap, struct dentry *);
41343 + mnt = va_arg(ap, struct vfsmount *);
41344 + str1 = va_arg(ap, char *);
41345 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
41346 + break;
41347 + case GR_FILENAME_TWO_INT:
41348 + dentry = va_arg(ap, struct dentry *);
41349 + mnt = va_arg(ap, struct vfsmount *);
41350 + num1 = va_arg(ap, int);
41351 + num2 = va_arg(ap, int);
41352 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
41353 + break;
41354 + case GR_FILENAME_TWO_INT_STR:
41355 + dentry = va_arg(ap, struct dentry *);
41356 + mnt = va_arg(ap, struct vfsmount *);
41357 + num1 = va_arg(ap, int);
41358 + num2 = va_arg(ap, int);
41359 + str1 = va_arg(ap, char *);
41360 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
41361 + break;
41362 + case GR_TEXTREL:
41363 + file = va_arg(ap, struct file *);
41364 + ulong1 = va_arg(ap, unsigned long);
41365 + ulong2 = va_arg(ap, unsigned long);
41366 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
41367 + break;
41368 + case GR_PTRACE:
41369 + task = va_arg(ap, struct task_struct *);
41370 + 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);
41371 + break;
41372 + case GR_RESOURCE:
41373 + task = va_arg(ap, struct task_struct *);
41374 + cred = __task_cred(task);
41375 + pcred = __task_cred(task->real_parent);
41376 + ulong1 = va_arg(ap, unsigned long);
41377 + str1 = va_arg(ap, char *);
41378 + ulong2 = va_arg(ap, unsigned long);
41379 + 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);
41380 + break;
41381 + case GR_CAP:
41382 + task = va_arg(ap, struct task_struct *);
41383 + cred = __task_cred(task);
41384 + pcred = __task_cred(task->real_parent);
41385 + str1 = va_arg(ap, char *);
41386 + 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);
41387 + break;
41388 + case GR_SIG:
41389 + str1 = va_arg(ap, char *);
41390 + voidptr = va_arg(ap, void *);
41391 + gr_log_middle_varargs(audit, msg, str1, voidptr);
41392 + break;
41393 + case GR_SIG2:
41394 + task = va_arg(ap, struct task_struct *);
41395 + cred = __task_cred(task);
41396 + pcred = __task_cred(task->real_parent);
41397 + num1 = va_arg(ap, int);
41398 + 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);
41399 + break;
41400 + case GR_CRASH1:
41401 + task = va_arg(ap, struct task_struct *);
41402 + cred = __task_cred(task);
41403 + pcred = __task_cred(task->real_parent);
41404 + ulong1 = va_arg(ap, unsigned long);
41405 + 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);
41406 + break;
41407 + case GR_CRASH2:
41408 + task = va_arg(ap, struct task_struct *);
41409 + cred = __task_cred(task);
41410 + pcred = __task_cred(task->real_parent);
41411 + ulong1 = va_arg(ap, unsigned long);
41412 + 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);
41413 + break;
41414 + case GR_RWXMAP:
41415 + file = va_arg(ap, struct file *);
41416 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>");
41417 + break;
41418 + case GR_PSACCT:
41419 + {
41420 + unsigned int wday, cday;
41421 + __u8 whr, chr;
41422 + __u8 wmin, cmin;
41423 + __u8 wsec, csec;
41424 + char cur_tty[64] = { 0 };
41425 + char parent_tty[64] = { 0 };
41426 +
41427 + task = va_arg(ap, struct task_struct *);
41428 + wday = va_arg(ap, unsigned int);
41429 + cday = va_arg(ap, unsigned int);
41430 + whr = va_arg(ap, int);
41431 + chr = va_arg(ap, int);
41432 + wmin = va_arg(ap, int);
41433 + cmin = va_arg(ap, int);
41434 + wsec = va_arg(ap, int);
41435 + csec = va_arg(ap, int);
41436 + ulong1 = va_arg(ap, unsigned long);
41437 + cred = __task_cred(task);
41438 + pcred = __task_cred(task->real_parent);
41439 +
41440 + 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);
41441 + }
41442 + break;
41443 + default:
41444 + gr_log_middle(audit, msg, ap);
41445 + }
41446 + va_end(ap);
41447 + gr_log_end(audit);
41448 + END_LOCKS(audit);
41449 +}
41450 diff -urNp linux-2.6.36/grsecurity/grsec_mem.c linux-2.6.36/grsecurity/grsec_mem.c
41451 --- linux-2.6.36/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
41452 +++ linux-2.6.36/grsecurity/grsec_mem.c 2010-11-06 18:58:50.000000000 -0400
41453 @@ -0,0 +1,85 @@
41454 +#include <linux/kernel.h>
41455 +#include <linux/sched.h>
41456 +#include <linux/mm.h>
41457 +#include <linux/mman.h>
41458 +#include <linux/grinternal.h>
41459 +
41460 +void
41461 +gr_handle_ioperm(void)
41462 +{
41463 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
41464 + return;
41465 +}
41466 +
41467 +void
41468 +gr_handle_iopl(void)
41469 +{
41470 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
41471 + return;
41472 +}
41473 +
41474 +void
41475 +gr_handle_mem_write(void)
41476 +{
41477 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
41478 + return;
41479 +}
41480 +
41481 +void
41482 +gr_handle_kmem_write(void)
41483 +{
41484 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
41485 + return;
41486 +}
41487 +
41488 +void
41489 +gr_handle_open_port(void)
41490 +{
41491 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
41492 + return;
41493 +}
41494 +
41495 +int
41496 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
41497 +{
41498 + unsigned long start, end;
41499 +
41500 + start = offset;
41501 + end = start + vma->vm_end - vma->vm_start;
41502 +
41503 + if (start > end) {
41504 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
41505 + return -EPERM;
41506 + }
41507 +
41508 + /* allowed ranges : ISA I/O BIOS */
41509 + if ((start >= __pa(high_memory))
41510 +#if defined(CONFIG_X86) || defined(CONFIG_PPC)
41511 + || (start >= 0x000a0000 && end <= 0x00100000)
41512 + || (start >= 0x00000000 && end <= 0x00001000)
41513 +#endif
41514 + )
41515 + return 0;
41516 +
41517 + if (vma->vm_flags & VM_WRITE) {
41518 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
41519 + return -EPERM;
41520 + } else
41521 + vma->vm_flags &= ~VM_MAYWRITE;
41522 +
41523 + return 0;
41524 +}
41525 +
41526 +void
41527 +gr_log_nonroot_mod_load(const char *modname)
41528 +{
41529 + gr_log_str(GR_DONT_AUDIT, GR_NONROOT_MODLOAD_MSG, modname);
41530 + return;
41531 +}
41532 +
41533 +void
41534 +gr_handle_vm86(void)
41535 +{
41536 + gr_log_noargs(GR_DONT_AUDIT, GR_VM86_MSG);
41537 + return;
41538 +}
41539 diff -urNp linux-2.6.36/grsecurity/grsec_mount.c linux-2.6.36/grsecurity/grsec_mount.c
41540 --- linux-2.6.36/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
41541 +++ linux-2.6.36/grsecurity/grsec_mount.c 2010-11-06 18:58:50.000000000 -0400
41542 @@ -0,0 +1,62 @@
41543 +#include <linux/kernel.h>
41544 +#include <linux/sched.h>
41545 +#include <linux/mount.h>
41546 +#include <linux/grsecurity.h>
41547 +#include <linux/grinternal.h>
41548 +
41549 +void
41550 +gr_log_remount(const char *devname, const int retval)
41551 +{
41552 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
41553 + if (grsec_enable_mount && (retval >= 0))
41554 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
41555 +#endif
41556 + return;
41557 +}
41558 +
41559 +void
41560 +gr_log_unmount(const char *devname, const int retval)
41561 +{
41562 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
41563 + if (grsec_enable_mount && (retval >= 0))
41564 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
41565 +#endif
41566 + return;
41567 +}
41568 +
41569 +void
41570 +gr_log_mount(const char *from, const char *to, const int retval)
41571 +{
41572 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
41573 + if (grsec_enable_mount && (retval >= 0))
41574 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
41575 +#endif
41576 + return;
41577 +}
41578 +
41579 +int
41580 +gr_handle_rofs_mount(struct dentry *dentry, struct vfsmount *mnt, int mnt_flags)
41581 +{
41582 +#ifdef CONFIG_GRKERNSEC_ROFS
41583 + if (grsec_enable_rofs && !(mnt_flags & MNT_READONLY)) {
41584 + gr_log_fs_generic(GR_DO_AUDIT, GR_ROFS_MOUNT_MSG, dentry, mnt);
41585 + return -EPERM;
41586 + } else
41587 + return 0;
41588 +#endif
41589 + return 0;
41590 +}
41591 +
41592 +int
41593 +gr_handle_rofs_blockwrite(struct dentry *dentry, struct vfsmount *mnt, int acc_mode)
41594 +{
41595 +#ifdef CONFIG_GRKERNSEC_ROFS
41596 + if (grsec_enable_rofs && (acc_mode & MAY_WRITE) &&
41597 + dentry->d_inode && S_ISBLK(dentry->d_inode->i_mode)) {
41598 + gr_log_fs_generic(GR_DO_AUDIT, GR_ROFS_BLOCKWRITE_MSG, dentry, mnt);
41599 + return -EPERM;
41600 + } else
41601 + return 0;
41602 +#endif
41603 + return 0;
41604 +}
41605 diff -urNp linux-2.6.36/grsecurity/grsec_pax.c linux-2.6.36/grsecurity/grsec_pax.c
41606 --- linux-2.6.36/grsecurity/grsec_pax.c 1969-12-31 19:00:00.000000000 -0500
41607 +++ linux-2.6.36/grsecurity/grsec_pax.c 2010-11-06 18:58:50.000000000 -0400
41608 @@ -0,0 +1,36 @@
41609 +#include <linux/kernel.h>
41610 +#include <linux/sched.h>
41611 +#include <linux/mm.h>
41612 +#include <linux/file.h>
41613 +#include <linux/grinternal.h>
41614 +#include <linux/grsecurity.h>
41615 +
41616 +void
41617 +gr_log_textrel(struct vm_area_struct * vma)
41618 +{
41619 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
41620 + if (grsec_enable_audit_textrel)
41621 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
41622 +#endif
41623 + return;
41624 +}
41625 +
41626 +void
41627 +gr_log_rwxmmap(struct file *file)
41628 +{
41629 +#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
41630 + if (grsec_enable_log_rwxmaps)
41631 + gr_log_rwxmap(GR_DONT_AUDIT, GR_RWXMMAP_MSG, file);
41632 +#endif
41633 + return;
41634 +}
41635 +
41636 +void
41637 +gr_log_rwxmprotect(struct file *file)
41638 +{
41639 +#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
41640 + if (grsec_enable_log_rwxmaps)
41641 + gr_log_rwxmap(GR_DONT_AUDIT, GR_RWXMPROTECT_MSG, file);
41642 +#endif
41643 + return;
41644 +}
41645 diff -urNp linux-2.6.36/grsecurity/grsec_ptrace.c linux-2.6.36/grsecurity/grsec_ptrace.c
41646 --- linux-2.6.36/grsecurity/grsec_ptrace.c 1969-12-31 19:00:00.000000000 -0500
41647 +++ linux-2.6.36/grsecurity/grsec_ptrace.c 2010-11-06 18:58:50.000000000 -0400
41648 @@ -0,0 +1,14 @@
41649 +#include <linux/kernel.h>
41650 +#include <linux/sched.h>
41651 +#include <linux/grinternal.h>
41652 +#include <linux/grsecurity.h>
41653 +
41654 +void
41655 +gr_audit_ptrace(struct task_struct *task)
41656 +{
41657 +#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
41658 + if (grsec_enable_audit_ptrace)
41659 + gr_log_ptrace(GR_DO_AUDIT, GR_PTRACE_AUDIT_MSG, task);
41660 +#endif
41661 + return;
41662 +}
41663 diff -urNp linux-2.6.36/grsecurity/grsec_sig.c linux-2.6.36/grsecurity/grsec_sig.c
41664 --- linux-2.6.36/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
41665 +++ linux-2.6.36/grsecurity/grsec_sig.c 2010-11-06 18:58:50.000000000 -0400
41666 @@ -0,0 +1,65 @@
41667 +#include <linux/kernel.h>
41668 +#include <linux/sched.h>
41669 +#include <linux/delay.h>
41670 +#include <linux/grsecurity.h>
41671 +#include <linux/grinternal.h>
41672 +
41673 +char *signames[] = {
41674 + [SIGSEGV] = "Segmentation fault",
41675 + [SIGILL] = "Illegal instruction",
41676 + [SIGABRT] = "Abort",
41677 + [SIGBUS] = "Invalid alignment/Bus error"
41678 +};
41679 +
41680 +void
41681 +gr_log_signal(const int sig, const void *addr, const struct task_struct *t)
41682 +{
41683 +#ifdef CONFIG_GRKERNSEC_SIGNAL
41684 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
41685 + (sig == SIGABRT) || (sig == SIGBUS))) {
41686 + if (t->pid == current->pid) {
41687 + gr_log_sig_addr(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, signames[sig], addr);
41688 + } else {
41689 + gr_log_sig_task(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
41690 + }
41691 + }
41692 +#endif
41693 + return;
41694 +}
41695 +
41696 +int
41697 +gr_handle_signal(const struct task_struct *p, const int sig)
41698 +{
41699 +#ifdef CONFIG_GRKERNSEC
41700 + if (current->pid > 1 && gr_check_protected_task(p)) {
41701 + gr_log_sig_task(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
41702 + return -EPERM;
41703 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
41704 + return -EPERM;
41705 + }
41706 +#endif
41707 + return 0;
41708 +}
41709 +
41710 +void gr_handle_brute_attach(struct task_struct *p)
41711 +{
41712 +#ifdef CONFIG_GRKERNSEC_BRUTE
41713 + read_lock(&tasklist_lock);
41714 + read_lock(&grsec_exec_file_lock);
41715 + if (p->real_parent && p->real_parent->exec_file == p->exec_file)
41716 + p->real_parent->brute = 1;
41717 + read_unlock(&grsec_exec_file_lock);
41718 + read_unlock(&tasklist_lock);
41719 +#endif
41720 + return;
41721 +}
41722 +
41723 +void gr_handle_brute_check(void)
41724 +{
41725 +#ifdef CONFIG_GRKERNSEC_BRUTE
41726 + if (current->brute)
41727 + msleep(30 * 1000);
41728 +#endif
41729 + return;
41730 +}
41731 +
41732 diff -urNp linux-2.6.36/grsecurity/grsec_sock.c linux-2.6.36/grsecurity/grsec_sock.c
41733 --- linux-2.6.36/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
41734 +++ linux-2.6.36/grsecurity/grsec_sock.c 2010-11-06 18:58:50.000000000 -0400
41735 @@ -0,0 +1,271 @@
41736 +#include <linux/kernel.h>
41737 +#include <linux/module.h>
41738 +#include <linux/sched.h>
41739 +#include <linux/file.h>
41740 +#include <linux/net.h>
41741 +#include <linux/in.h>
41742 +#include <linux/ip.h>
41743 +#include <net/sock.h>
41744 +#include <net/inet_sock.h>
41745 +#include <linux/grsecurity.h>
41746 +#include <linux/grinternal.h>
41747 +#include <linux/gracl.h>
41748 +
41749 +kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
41750 +EXPORT_SYMBOL(gr_cap_rtnetlink);
41751 +
41752 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
41753 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
41754 +
41755 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
41756 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
41757 +
41758 +#ifdef CONFIG_UNIX_MODULE
41759 +EXPORT_SYMBOL(gr_acl_handle_unix);
41760 +EXPORT_SYMBOL(gr_acl_handle_mknod);
41761 +EXPORT_SYMBOL(gr_handle_chroot_unix);
41762 +EXPORT_SYMBOL(gr_handle_create);
41763 +#endif
41764 +
41765 +#ifdef CONFIG_GRKERNSEC
41766 +#define gr_conn_table_size 32749
41767 +struct conn_table_entry {
41768 + struct conn_table_entry *next;
41769 + struct signal_struct *sig;
41770 +};
41771 +
41772 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
41773 +DEFINE_SPINLOCK(gr_conn_table_lock);
41774 +
41775 +extern const char * gr_socktype_to_name(unsigned char type);
41776 +extern const char * gr_proto_to_name(unsigned char proto);
41777 +
41778 +static __inline__ int
41779 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
41780 +{
41781 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
41782 +}
41783 +
41784 +static __inline__ int
41785 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
41786 + __u16 sport, __u16 dport)
41787 +{
41788 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
41789 + sig->gr_sport == sport && sig->gr_dport == dport))
41790 + return 1;
41791 + else
41792 + return 0;
41793 +}
41794 +
41795 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
41796 +{
41797 + struct conn_table_entry **match;
41798 + unsigned int index;
41799 +
41800 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
41801 + sig->gr_sport, sig->gr_dport,
41802 + gr_conn_table_size);
41803 +
41804 + newent->sig = sig;
41805 +
41806 + match = &gr_conn_table[index];
41807 + newent->next = *match;
41808 + *match = newent;
41809 +
41810 + return;
41811 +}
41812 +
41813 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
41814 +{
41815 + struct conn_table_entry *match, *last = NULL;
41816 + unsigned int index;
41817 +
41818 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
41819 + sig->gr_sport, sig->gr_dport,
41820 + gr_conn_table_size);
41821 +
41822 + match = gr_conn_table[index];
41823 + while (match && !conn_match(match->sig,
41824 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
41825 + sig->gr_dport)) {
41826 + last = match;
41827 + match = match->next;
41828 + }
41829 +
41830 + if (match) {
41831 + if (last)
41832 + last->next = match->next;
41833 + else
41834 + gr_conn_table[index] = NULL;
41835 + kfree(match);
41836 + }
41837 +
41838 + return;
41839 +}
41840 +
41841 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
41842 + __u16 sport, __u16 dport)
41843 +{
41844 + struct conn_table_entry *match;
41845 + unsigned int index;
41846 +
41847 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
41848 +
41849 + match = gr_conn_table[index];
41850 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
41851 + match = match->next;
41852 +
41853 + if (match)
41854 + return match->sig;
41855 + else
41856 + return NULL;
41857 +}
41858 +
41859 +#endif
41860 +
41861 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
41862 +{
41863 +#ifdef CONFIG_GRKERNSEC
41864 + struct signal_struct *sig = task->signal;
41865 + struct conn_table_entry *newent;
41866 +
41867 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
41868 + if (newent == NULL)
41869 + return;
41870 + /* no bh lock needed since we are called with bh disabled */
41871 + spin_lock(&gr_conn_table_lock);
41872 + gr_del_task_from_ip_table_nolock(sig);
41873 + sig->gr_saddr = inet->inet_rcv_saddr;
41874 + sig->gr_daddr = inet->inet_daddr;
41875 + sig->gr_sport = inet->inet_sport;
41876 + sig->gr_dport = inet->inet_dport;
41877 + gr_add_to_task_ip_table_nolock(sig, newent);
41878 + spin_unlock(&gr_conn_table_lock);
41879 +#endif
41880 + return;
41881 +}
41882 +
41883 +void gr_del_task_from_ip_table(struct task_struct *task)
41884 +{
41885 +#ifdef CONFIG_GRKERNSEC
41886 + spin_lock_bh(&gr_conn_table_lock);
41887 + gr_del_task_from_ip_table_nolock(task->signal);
41888 + spin_unlock_bh(&gr_conn_table_lock);
41889 +#endif
41890 + return;
41891 +}
41892 +
41893 +void
41894 +gr_attach_curr_ip(const struct sock *sk)
41895 +{
41896 +#ifdef CONFIG_GRKERNSEC
41897 + struct signal_struct *p, *set;
41898 + const struct inet_sock *inet = inet_sk(sk);
41899 +
41900 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
41901 + return;
41902 +
41903 + set = current->signal;
41904 +
41905 + spin_lock_bh(&gr_conn_table_lock);
41906 + p = gr_lookup_task_ip_table(inet->inet_daddr, inet->inet_rcv_saddr,
41907 + inet->inet_dport, inet->inet_sport);
41908 + if (unlikely(p != NULL)) {
41909 + set->curr_ip = p->curr_ip;
41910 + set->used_accept = 1;
41911 + gr_del_task_from_ip_table_nolock(p);
41912 + spin_unlock_bh(&gr_conn_table_lock);
41913 + return;
41914 + }
41915 + spin_unlock_bh(&gr_conn_table_lock);
41916 +
41917 + set->curr_ip = inet->inet_daddr;
41918 + set->used_accept = 1;
41919 +#endif
41920 + return;
41921 +}
41922 +
41923 +int
41924 +gr_handle_sock_all(const int family, const int type, const int protocol)
41925 +{
41926 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
41927 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
41928 + (family != AF_UNIX) && (family != AF_LOCAL)) {
41929 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
41930 + return -EACCES;
41931 + }
41932 +#endif
41933 + return 0;
41934 +}
41935 +
41936 +int
41937 +gr_handle_sock_server(const struct sockaddr *sck)
41938 +{
41939 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
41940 + if (grsec_enable_socket_server &&
41941 + in_group_p(grsec_socket_server_gid) &&
41942 + sck && (sck->sa_family != AF_UNIX) &&
41943 + (sck->sa_family != AF_LOCAL)) {
41944 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
41945 + return -EACCES;
41946 + }
41947 +#endif
41948 + return 0;
41949 +}
41950 +
41951 +int
41952 +gr_handle_sock_server_other(const struct sock *sck)
41953 +{
41954 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
41955 + if (grsec_enable_socket_server &&
41956 + in_group_p(grsec_socket_server_gid) &&
41957 + sck && (sck->sk_family != AF_UNIX) &&
41958 + (sck->sk_family != AF_LOCAL)) {
41959 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
41960 + return -EACCES;
41961 + }
41962 +#endif
41963 + return 0;
41964 +}
41965 +
41966 +int
41967 +gr_handle_sock_client(const struct sockaddr *sck)
41968 +{
41969 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
41970 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
41971 + sck && (sck->sa_family != AF_UNIX) &&
41972 + (sck->sa_family != AF_LOCAL)) {
41973 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
41974 + return -EACCES;
41975 + }
41976 +#endif
41977 + return 0;
41978 +}
41979 +
41980 +kernel_cap_t
41981 +gr_cap_rtnetlink(struct sock *sock)
41982 +{
41983 +#ifdef CONFIG_GRKERNSEC
41984 + if (!gr_acl_is_enabled())
41985 + return current_cap();
41986 + else if (sock->sk_protocol == NETLINK_ISCSI &&
41987 + cap_raised(current_cap(), CAP_SYS_ADMIN) &&
41988 + gr_is_capable(CAP_SYS_ADMIN))
41989 + return current_cap();
41990 + else if (sock->sk_protocol == NETLINK_AUDIT &&
41991 + cap_raised(current_cap(), CAP_AUDIT_WRITE) &&
41992 + gr_is_capable(CAP_AUDIT_WRITE) &&
41993 + cap_raised(current_cap(), CAP_AUDIT_CONTROL) &&
41994 + gr_is_capable(CAP_AUDIT_CONTROL))
41995 + return current_cap();
41996 + else if (cap_raised(current_cap(), CAP_NET_ADMIN) &&
41997 + ((sock->sk_protocol == NETLINK_ROUTE) ?
41998 + gr_is_capable_nolog(CAP_NET_ADMIN) :
41999 + gr_is_capable(CAP_NET_ADMIN)))
42000 + return current_cap();
42001 + else
42002 + return __cap_empty_set;
42003 +#else
42004 + return current_cap();
42005 +#endif
42006 +}
42007 diff -urNp linux-2.6.36/grsecurity/grsec_sysctl.c linux-2.6.36/grsecurity/grsec_sysctl.c
42008 --- linux-2.6.36/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
42009 +++ linux-2.6.36/grsecurity/grsec_sysctl.c 2010-11-06 18:58:50.000000000 -0400
42010 @@ -0,0 +1,433 @@
42011 +#include <linux/kernel.h>
42012 +#include <linux/sched.h>
42013 +#include <linux/sysctl.h>
42014 +#include <linux/grsecurity.h>
42015 +#include <linux/grinternal.h>
42016 +
42017 +int
42018 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
42019 +{
42020 +#ifdef CONFIG_GRKERNSEC_SYSCTL
42021 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
42022 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
42023 + return -EACCES;
42024 + }
42025 +#endif
42026 + return 0;
42027 +}
42028 +
42029 +#ifdef CONFIG_GRKERNSEC_ROFS
42030 +static int __maybe_unused one = 1;
42031 +#endif
42032 +
42033 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_ROFS)
42034 +struct ctl_table grsecurity_table[] = {
42035 +#ifdef CONFIG_GRKERNSEC_SYSCTL
42036 +#ifdef CONFIG_GRKERNSEC_SYSCTL_DISTRO
42037 +#ifdef CONFIG_GRKERNSEC_IO
42038 + {
42039 + .procname = "disable_priv_io",
42040 + .data = &grsec_disable_privio,
42041 + .maxlen = sizeof(int),
42042 + .mode = 0600,
42043 + .proc_handler = &proc_dointvec,
42044 + },
42045 +#endif
42046 +#endif
42047 +#ifdef CONFIG_GRKERNSEC_LINK
42048 + {
42049 + .procname = "linking_restrictions",
42050 + .data = &grsec_enable_link,
42051 + .maxlen = sizeof(int),
42052 + .mode = 0600,
42053 + .proc_handler = &proc_dointvec,
42054 + },
42055 +#endif
42056 +#ifdef CONFIG_GRKERNSEC_FIFO
42057 + {
42058 + .procname = "fifo_restrictions",
42059 + .data = &grsec_enable_fifo,
42060 + .maxlen = sizeof(int),
42061 + .mode = 0600,
42062 + .proc_handler = &proc_dointvec,
42063 + },
42064 +#endif
42065 +#ifdef CONFIG_GRKERNSEC_EXECVE
42066 + {
42067 + .procname = "execve_limiting",
42068 + .data = &grsec_enable_execve,
42069 + .maxlen = sizeof(int),
42070 + .mode = 0600,
42071 + .proc_handler = &proc_dointvec,
42072 + },
42073 +#endif
42074 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
42075 + {
42076 + .procname = "ip_blackhole",
42077 + .data = &grsec_enable_blackhole,
42078 + .maxlen = sizeof(int),
42079 + .mode = 0600,
42080 + .proc_handler = &proc_dointvec,
42081 + },
42082 + {
42083 + .procname = "lastack_retries",
42084 + .data = &grsec_lastack_retries,
42085 + .maxlen = sizeof(int),
42086 + .mode = 0600,
42087 + .proc_handler = &proc_dointvec,
42088 + },
42089 +#endif
42090 +#ifdef CONFIG_GRKERNSEC_EXECLOG
42091 + {
42092 + .procname = "exec_logging",
42093 + .data = &grsec_enable_execlog,
42094 + .maxlen = sizeof(int),
42095 + .mode = 0600,
42096 + .proc_handler = &proc_dointvec,
42097 + },
42098 +#endif
42099 +#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
42100 + {
42101 + .procname = "rwxmap_logging",
42102 + .data = &grsec_enable_log_rwxmaps,
42103 + .maxlen = sizeof(int),
42104 + .mode = 0600,
42105 + .proc_handler = &proc_dointvec,
42106 + },
42107 +#endif
42108 +#ifdef CONFIG_GRKERNSEC_SIGNAL
42109 + {
42110 + .procname = "signal_logging",
42111 + .data = &grsec_enable_signal,
42112 + .maxlen = sizeof(int),
42113 + .mode = 0600,
42114 + .proc_handler = &proc_dointvec,
42115 + },
42116 +#endif
42117 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
42118 + {
42119 + .procname = "forkfail_logging",
42120 + .data = &grsec_enable_forkfail,
42121 + .maxlen = sizeof(int),
42122 + .mode = 0600,
42123 + .proc_handler = &proc_dointvec,
42124 + },
42125 +#endif
42126 +#ifdef CONFIG_GRKERNSEC_TIME
42127 + {
42128 + .procname = "timechange_logging",
42129 + .data = &grsec_enable_time,
42130 + .maxlen = sizeof(int),
42131 + .mode = 0600,
42132 + .proc_handler = &proc_dointvec,
42133 + },
42134 +#endif
42135 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
42136 + {
42137 + .procname = "chroot_deny_shmat",
42138 + .data = &grsec_enable_chroot_shmat,
42139 + .maxlen = sizeof(int),
42140 + .mode = 0600,
42141 + .proc_handler = &proc_dointvec,
42142 + },
42143 +#endif
42144 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
42145 + {
42146 + .procname = "chroot_deny_unix",
42147 + .data = &grsec_enable_chroot_unix,
42148 + .maxlen = sizeof(int),
42149 + .mode = 0600,
42150 + .proc_handler = &proc_dointvec,
42151 + },
42152 +#endif
42153 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
42154 + {
42155 + .procname = "chroot_deny_mount",
42156 + .data = &grsec_enable_chroot_mount,
42157 + .maxlen = sizeof(int),
42158 + .mode = 0600,
42159 + .proc_handler = &proc_dointvec,
42160 + },
42161 +#endif
42162 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
42163 + {
42164 + .procname = "chroot_deny_fchdir",
42165 + .data = &grsec_enable_chroot_fchdir,
42166 + .maxlen = sizeof(int),
42167 + .mode = 0600,
42168 + .proc_handler = &proc_dointvec,
42169 + },
42170 +#endif
42171 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
42172 + {
42173 + .procname = "chroot_deny_chroot",
42174 + .data = &grsec_enable_chroot_double,
42175 + .maxlen = sizeof(int),
42176 + .mode = 0600,
42177 + .proc_handler = &proc_dointvec,
42178 + },
42179 +#endif
42180 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
42181 + {
42182 + .procname = "chroot_deny_pivot",
42183 + .data = &grsec_enable_chroot_pivot,
42184 + .maxlen = sizeof(int),
42185 + .mode = 0600,
42186 + .proc_handler = &proc_dointvec,
42187 + },
42188 +#endif
42189 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
42190 + {
42191 + .procname = "chroot_enforce_chdir",
42192 + .data = &grsec_enable_chroot_chdir,
42193 + .maxlen = sizeof(int),
42194 + .mode = 0600,
42195 + .proc_handler = &proc_dointvec,
42196 + },
42197 +#endif
42198 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
42199 + {
42200 + .procname = "chroot_deny_chmod",
42201 + .data = &grsec_enable_chroot_chmod,
42202 + .maxlen = sizeof(int),
42203 + .mode = 0600,
42204 + .proc_handler = &proc_dointvec,
42205 + },
42206 +#endif
42207 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
42208 + {
42209 + .procname = "chroot_deny_mknod",
42210 + .data = &grsec_enable_chroot_mknod,
42211 + .maxlen = sizeof(int),
42212 + .mode = 0600,
42213 + .proc_handler = &proc_dointvec,
42214 + },
42215 +#endif
42216 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
42217 + {
42218 + .procname = "chroot_restrict_nice",
42219 + .data = &grsec_enable_chroot_nice,
42220 + .maxlen = sizeof(int),
42221 + .mode = 0600,
42222 + .proc_handler = &proc_dointvec,
42223 + },
42224 +#endif
42225 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
42226 + {
42227 + .procname = "chroot_execlog",
42228 + .data = &grsec_enable_chroot_execlog,
42229 + .maxlen = sizeof(int),
42230 + .mode = 0600,
42231 + .proc_handler = &proc_dointvec,
42232 + },
42233 +#endif
42234 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
42235 + {
42236 + .procname = "chroot_caps",
42237 + .data = &grsec_enable_chroot_caps,
42238 + .maxlen = sizeof(int),
42239 + .mode = 0600,
42240 + .proc_handler = &proc_dointvec,
42241 + },
42242 +#endif
42243 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
42244 + {
42245 + .procname = "chroot_deny_sysctl",
42246 + .data = &grsec_enable_chroot_sysctl,
42247 + .maxlen = sizeof(int),
42248 + .mode = 0600,
42249 + .proc_handler = &proc_dointvec,
42250 + },
42251 +#endif
42252 +#ifdef CONFIG_GRKERNSEC_TPE
42253 + {
42254 + .procname = "tpe",
42255 + .data = &grsec_enable_tpe,
42256 + .maxlen = sizeof(int),
42257 + .mode = 0600,
42258 + .proc_handler = &proc_dointvec,
42259 + },
42260 + {
42261 + .procname = "tpe_gid",
42262 + .data = &grsec_tpe_gid,
42263 + .maxlen = sizeof(int),
42264 + .mode = 0600,
42265 + .proc_handler = &proc_dointvec,
42266 + },
42267 +#endif
42268 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
42269 + {
42270 + .procname = "tpe_invert",
42271 + .data = &grsec_enable_tpe_invert,
42272 + .maxlen = sizeof(int),
42273 + .mode = 0600,
42274 + .proc_handler = &proc_dointvec,
42275 + },
42276 +#endif
42277 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
42278 + {
42279 + .procname = "tpe_restrict_all",
42280 + .data = &grsec_enable_tpe_all,
42281 + .maxlen = sizeof(int),
42282 + .mode = 0600,
42283 + .proc_handler = &proc_dointvec,
42284 + },
42285 +#endif
42286 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
42287 + {
42288 + .procname = "socket_all",
42289 + .data = &grsec_enable_socket_all,
42290 + .maxlen = sizeof(int),
42291 + .mode = 0600,
42292 + .proc_handler = &proc_dointvec,
42293 + },
42294 + {
42295 + .procname = "socket_all_gid",
42296 + .data = &grsec_socket_all_gid,
42297 + .maxlen = sizeof(int),
42298 + .mode = 0600,
42299 + .proc_handler = &proc_dointvec,
42300 + },
42301 +#endif
42302 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
42303 + {
42304 + .procname = "socket_client",
42305 + .data = &grsec_enable_socket_client,
42306 + .maxlen = sizeof(int),
42307 + .mode = 0600,
42308 + .proc_handler = &proc_dointvec,
42309 + },
42310 + {
42311 + .procname = "socket_client_gid",
42312 + .data = &grsec_socket_client_gid,
42313 + .maxlen = sizeof(int),
42314 + .mode = 0600,
42315 + .proc_handler = &proc_dointvec,
42316 + },
42317 +#endif
42318 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
42319 + {
42320 + .procname = "socket_server",
42321 + .data = &grsec_enable_socket_server,
42322 + .maxlen = sizeof(int),
42323 + .mode = 0600,
42324 + .proc_handler = &proc_dointvec,
42325 + },
42326 + {
42327 + .procname = "socket_server_gid",
42328 + .data = &grsec_socket_server_gid,
42329 + .maxlen = sizeof(int),
42330 + .mode = 0600,
42331 + .proc_handler = &proc_dointvec,
42332 + },
42333 +#endif
42334 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
42335 + {
42336 + .procname = "audit_group",
42337 + .data = &grsec_enable_group,
42338 + .maxlen = sizeof(int),
42339 + .mode = 0600,
42340 + .proc_handler = &proc_dointvec,
42341 + },
42342 + {
42343 + .procname = "audit_gid",
42344 + .data = &grsec_audit_gid,
42345 + .maxlen = sizeof(int),
42346 + .mode = 0600,
42347 + .proc_handler = &proc_dointvec,
42348 + },
42349 +#endif
42350 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
42351 + {
42352 + .procname = "audit_chdir",
42353 + .data = &grsec_enable_chdir,
42354 + .maxlen = sizeof(int),
42355 + .mode = 0600,
42356 + .proc_handler = &proc_dointvec,
42357 + },
42358 +#endif
42359 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
42360 + {
42361 + .procname = "audit_mount",
42362 + .data = &grsec_enable_mount,
42363 + .maxlen = sizeof(int),
42364 + .mode = 0600,
42365 + .proc_handler = &proc_dointvec,
42366 + },
42367 +#endif
42368 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
42369 + {
42370 + .procname = "audit_textrel",
42371 + .data = &grsec_enable_audit_textrel,
42372 + .maxlen = sizeof(int),
42373 + .mode = 0600,
42374 + .proc_handler = &proc_dointvec,
42375 + },
42376 +#endif
42377 +#ifdef CONFIG_GRKERNSEC_DMESG
42378 + {
42379 + .procname = "dmesg",
42380 + .data = &grsec_enable_dmesg,
42381 + .maxlen = sizeof(int),
42382 + .mode = 0600,
42383 + .proc_handler = &proc_dointvec,
42384 + },
42385 +#endif
42386 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
42387 + {
42388 + .procname = "chroot_findtask",
42389 + .data = &grsec_enable_chroot_findtask,
42390 + .maxlen = sizeof(int),
42391 + .mode = 0600,
42392 + .proc_handler = &proc_dointvec,
42393 + },
42394 +#endif
42395 +#ifdef CONFIG_GRKERNSEC_RESLOG
42396 + {
42397 + .procname = "resource_logging",
42398 + .data = &grsec_resource_logging,
42399 + .maxlen = sizeof(int),
42400 + .mode = 0600,
42401 + .proc_handler = &proc_dointvec,
42402 + },
42403 +#endif
42404 +#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
42405 + {
42406 + .procname = "audit_ptrace",
42407 + .data = &grsec_enable_audit_ptrace,
42408 + .maxlen = sizeof(int),
42409 + .mode = 0600,
42410 + .proc_handler = &proc_dointvec,
42411 + },
42412 +#endif
42413 +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
42414 + {
42415 + .procname = "harden_ptrace",
42416 + .data = &grsec_enable_harden_ptrace,
42417 + .maxlen = sizeof(int),
42418 + .mode = 0600,
42419 + .proc_handler = &proc_dointvec,
42420 + },
42421 +#endif
42422 + {
42423 + .procname = "grsec_lock",
42424 + .data = &grsec_lock,
42425 + .maxlen = sizeof(int),
42426 + .mode = 0600,
42427 + .proc_handler = &proc_dointvec,
42428 + },
42429 +#endif
42430 +#ifdef CONFIG_GRKERNSEC_ROFS
42431 + {
42432 + .procname = "romount_protect",
42433 + .data = &grsec_enable_rofs,
42434 + .maxlen = sizeof(int),
42435 + .mode = 0600,
42436 + .proc_handler = &proc_dointvec_minmax,
42437 + .extra1 = &one,
42438 + .extra2 = &one,
42439 + },
42440 +#endif
42441 + { }
42442 +};
42443 +#endif
42444 diff -urNp linux-2.6.36/grsecurity/grsec_time.c linux-2.6.36/grsecurity/grsec_time.c
42445 --- linux-2.6.36/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
42446 +++ linux-2.6.36/grsecurity/grsec_time.c 2010-11-06 18:58:50.000000000 -0400
42447 @@ -0,0 +1,13 @@
42448 +#include <linux/kernel.h>
42449 +#include <linux/sched.h>
42450 +#include <linux/grinternal.h>
42451 +
42452 +void
42453 +gr_log_timechange(void)
42454 +{
42455 +#ifdef CONFIG_GRKERNSEC_TIME
42456 + if (grsec_enable_time)
42457 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
42458 +#endif
42459 + return;
42460 +}
42461 diff -urNp linux-2.6.36/grsecurity/grsec_tpe.c linux-2.6.36/grsecurity/grsec_tpe.c
42462 --- linux-2.6.36/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
42463 +++ linux-2.6.36/grsecurity/grsec_tpe.c 2010-11-06 18:58:50.000000000 -0400
42464 @@ -0,0 +1,39 @@
42465 +#include <linux/kernel.h>
42466 +#include <linux/sched.h>
42467 +#include <linux/file.h>
42468 +#include <linux/fs.h>
42469 +#include <linux/grinternal.h>
42470 +
42471 +extern int gr_acl_tpe_check(void);
42472 +
42473 +int
42474 +gr_tpe_allow(const struct file *file)
42475 +{
42476 +#ifdef CONFIG_GRKERNSEC
42477 + struct inode *inode = file->f_path.dentry->d_parent->d_inode;
42478 + const struct cred *cred = current_cred();
42479 +
42480 + if (cred->uid && ((grsec_enable_tpe &&
42481 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
42482 + ((grsec_enable_tpe_invert && !in_group_p(grsec_tpe_gid)) ||
42483 + (!grsec_enable_tpe_invert && in_group_p(grsec_tpe_gid)))
42484 +#else
42485 + in_group_p(grsec_tpe_gid)
42486 +#endif
42487 + ) || gr_acl_tpe_check()) &&
42488 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
42489 + (inode->i_mode & S_IWOTH))))) {
42490 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
42491 + return 0;
42492 + }
42493 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
42494 + if (cred->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
42495 + ((inode->i_uid && (inode->i_uid != cred->uid)) ||
42496 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
42497 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
42498 + return 0;
42499 + }
42500 +#endif
42501 +#endif
42502 + return 1;
42503 +}
42504 diff -urNp linux-2.6.36/grsecurity/grsum.c linux-2.6.36/grsecurity/grsum.c
42505 --- linux-2.6.36/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
42506 +++ linux-2.6.36/grsecurity/grsum.c 2010-11-06 18:58:50.000000000 -0400
42507 @@ -0,0 +1,61 @@
42508 +#include <linux/err.h>
42509 +#include <linux/kernel.h>
42510 +#include <linux/sched.h>
42511 +#include <linux/mm.h>
42512 +#include <linux/scatterlist.h>
42513 +#include <linux/crypto.h>
42514 +#include <linux/gracl.h>
42515 +
42516 +
42517 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
42518 +#error "crypto and sha256 must be built into the kernel"
42519 +#endif
42520 +
42521 +int
42522 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
42523 +{
42524 + char *p;
42525 + struct crypto_hash *tfm;
42526 + struct hash_desc desc;
42527 + struct scatterlist sg;
42528 + unsigned char temp_sum[GR_SHA_LEN];
42529 + volatile int retval = 0;
42530 + volatile int dummy = 0;
42531 + unsigned int i;
42532 +
42533 + sg_init_table(&sg, 1);
42534 +
42535 + tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
42536 + if (IS_ERR(tfm)) {
42537 + /* should never happen, since sha256 should be built in */
42538 + return 1;
42539 + }
42540 +
42541 + desc.tfm = tfm;
42542 + desc.flags = 0;
42543 +
42544 + crypto_hash_init(&desc);
42545 +
42546 + p = salt;
42547 + sg_set_buf(&sg, p, GR_SALT_LEN);
42548 + crypto_hash_update(&desc, &sg, sg.length);
42549 +
42550 + p = entry->pw;
42551 + sg_set_buf(&sg, p, strlen(p));
42552 +
42553 + crypto_hash_update(&desc, &sg, sg.length);
42554 +
42555 + crypto_hash_final(&desc, temp_sum);
42556 +
42557 + memset(entry->pw, 0, GR_PW_LEN);
42558 +
42559 + for (i = 0; i < GR_SHA_LEN; i++)
42560 + if (sum[i] != temp_sum[i])
42561 + retval = 1;
42562 + else
42563 + dummy = 1; // waste a cycle
42564 +
42565 + crypto_free_hash(tfm);
42566 +
42567 + return retval;
42568 +}
42569 diff -urNp linux-2.6.36/grsecurity/Kconfig linux-2.6.36/grsecurity/Kconfig
42570 --- linux-2.6.36/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
42571 +++ linux-2.6.36/grsecurity/Kconfig 2010-11-06 18:58:50.000000000 -0400
42572 @@ -0,0 +1,995 @@
42573 +#
42574 +# grecurity configuration
42575 +#
42576 +
42577 +menu "Grsecurity"
42578 +
42579 +config GRKERNSEC
42580 + bool "Grsecurity"
42581 + select CRYPTO
42582 + select CRYPTO_SHA256
42583 + help
42584 + If you say Y here, you will be able to configure many features
42585 + that will enhance the security of your system. It is highly
42586 + recommended that you say Y here and read through the help
42587 + for each option so that you fully understand the features and
42588 + can evaluate their usefulness for your machine.
42589 +
42590 +choice
42591 + prompt "Security Level"
42592 + depends on GRKERNSEC
42593 + default GRKERNSEC_CUSTOM
42594 +
42595 +config GRKERNSEC_LOW
42596 + bool "Low"
42597 + select GRKERNSEC_LINK
42598 + select GRKERNSEC_FIFO
42599 + select GRKERNSEC_EXECVE
42600 + select GRKERNSEC_RANDNET
42601 + select GRKERNSEC_DMESG
42602 + select GRKERNSEC_CHROOT
42603 + select GRKERNSEC_CHROOT_CHDIR
42604 +
42605 + help
42606 + If you choose this option, several of the grsecurity options will
42607 + be enabled that will give you greater protection against a number
42608 + of attacks, while assuring that none of your software will have any
42609 + conflicts with the additional security measures. If you run a lot
42610 + of unusual software, or you are having problems with the higher
42611 + security levels, you should say Y here. With this option, the
42612 + following features are enabled:
42613 +
42614 + - Linking restrictions
42615 + - FIFO restrictions
42616 + - Enforcing RLIMIT_NPROC on execve
42617 + - Restricted dmesg
42618 + - Enforced chdir("/") on chroot
42619 + - Runtime module disabling
42620 +
42621 +config GRKERNSEC_MEDIUM
42622 + bool "Medium"
42623 + select PAX
42624 + select PAX_EI_PAX
42625 + select PAX_PT_PAX_FLAGS
42626 + select PAX_HAVE_ACL_FLAGS
42627 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
42628 + select GRKERNSEC_CHROOT
42629 + select GRKERNSEC_CHROOT_SYSCTL
42630 + select GRKERNSEC_LINK
42631 + select GRKERNSEC_FIFO
42632 + select GRKERNSEC_EXECVE
42633 + select GRKERNSEC_DMESG
42634 + select GRKERNSEC_RANDNET
42635 + select GRKERNSEC_FORKFAIL
42636 + select GRKERNSEC_TIME
42637 + select GRKERNSEC_SIGNAL
42638 + select GRKERNSEC_CHROOT
42639 + select GRKERNSEC_CHROOT_UNIX
42640 + select GRKERNSEC_CHROOT_MOUNT
42641 + select GRKERNSEC_CHROOT_PIVOT
42642 + select GRKERNSEC_CHROOT_DOUBLE
42643 + select GRKERNSEC_CHROOT_CHDIR
42644 + select GRKERNSEC_CHROOT_MKNOD
42645 + select GRKERNSEC_PROC
42646 + select GRKERNSEC_PROC_USERGROUP
42647 + select PAX_RANDUSTACK
42648 + select PAX_ASLR
42649 + select PAX_RANDMMAP
42650 + select PAX_REFCOUNT if (X86 || SPARC64)
42651 + select PAX_USERCOPY if ((X86 || SPARC32 || SPARC64 || PPC) && (SLAB || SLUB || SLOB))
42652 +
42653 + help
42654 + If you say Y here, several features in addition to those included
42655 + in the low additional security level will be enabled. These
42656 + features provide even more security to your system, though in rare
42657 + cases they may be incompatible with very old or poorly written
42658 + software. If you enable this option, make sure that your auth
42659 + service (identd) is running as gid 1001. With this option,
42660 + the following features (in addition to those provided in the
42661 + low additional security level) will be enabled:
42662 +
42663 + - Failed fork logging
42664 + - Time change logging
42665 + - Signal logging
42666 + - Deny mounts in chroot
42667 + - Deny double chrooting
42668 + - Deny sysctl writes in chroot
42669 + - Deny mknod in chroot
42670 + - Deny access to abstract AF_UNIX sockets out of chroot
42671 + - Deny pivot_root in chroot
42672 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
42673 + - /proc restrictions with special GID set to 10 (usually wheel)
42674 + - Address Space Layout Randomization (ASLR)
42675 + - Prevent exploitation of most refcount overflows
42676 + - Bounds checking of copying between the kernel and userland
42677 +
42678 +config GRKERNSEC_HIGH
42679 + bool "High"
42680 + select GRKERNSEC_LINK
42681 + select GRKERNSEC_FIFO
42682 + select GRKERNSEC_EXECVE
42683 + select GRKERNSEC_DMESG
42684 + select GRKERNSEC_FORKFAIL
42685 + select GRKERNSEC_TIME
42686 + select GRKERNSEC_SIGNAL
42687 + select GRKERNSEC_CHROOT
42688 + select GRKERNSEC_CHROOT_SHMAT
42689 + select GRKERNSEC_CHROOT_UNIX
42690 + select GRKERNSEC_CHROOT_MOUNT
42691 + select GRKERNSEC_CHROOT_FCHDIR
42692 + select GRKERNSEC_CHROOT_PIVOT
42693 + select GRKERNSEC_CHROOT_DOUBLE
42694 + select GRKERNSEC_CHROOT_CHDIR
42695 + select GRKERNSEC_CHROOT_MKNOD
42696 + select GRKERNSEC_CHROOT_CAPS
42697 + select GRKERNSEC_CHROOT_SYSCTL
42698 + select GRKERNSEC_CHROOT_FINDTASK
42699 + select GRKERNSEC_PROC
42700 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
42701 + select GRKERNSEC_HIDESYM
42702 + select GRKERNSEC_BRUTE
42703 + select GRKERNSEC_PROC_USERGROUP
42704 + select GRKERNSEC_KMEM
42705 + select GRKERNSEC_RESLOG
42706 + select GRKERNSEC_RANDNET
42707 + select GRKERNSEC_PROC_ADD
42708 + select GRKERNSEC_CHROOT_CHMOD
42709 + select GRKERNSEC_CHROOT_NICE
42710 + select GRKERNSEC_AUDIT_MOUNT
42711 + select GRKERNSEC_MODHARDEN if (MODULES)
42712 + select GRKERNSEC_HARDEN_PTRACE
42713 + select GRKERNSEC_VM86 if (X86_32)
42714 + select PAX
42715 + select PAX_RANDUSTACK
42716 + select PAX_ASLR
42717 + select PAX_RANDMMAP
42718 + select PAX_NOEXEC
42719 + select PAX_MPROTECT
42720 + select PAX_EI_PAX
42721 + select PAX_PT_PAX_FLAGS
42722 + select PAX_HAVE_ACL_FLAGS
42723 + select PAX_KERNEXEC if ((PPC || X86) && (!X86_32 || X86_WP_WORKS_OK) && !XEN)
42724 + select PAX_MEMORY_UDEREF if (X86 && !XEN)
42725 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
42726 + select PAX_SEGMEXEC if (X86_32)
42727 + select PAX_PAGEEXEC
42728 + select PAX_EMUPLT if (ALPHA || PARISC || SPARC32 || SPARC64)
42729 + select PAX_EMUTRAMP if (PARISC)
42730 + select PAX_EMUSIGRT if (PARISC)
42731 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
42732 + select PAX_ELFRELOCS if (PAX_ETEXECRELOCS || (IA64 || PPC || X86))
42733 + select PAX_REFCOUNT if (X86 || SPARC64)
42734 + select PAX_USERCOPY if ((X86 || PPC || SPARC32 || SPARC64) && (SLAB || SLUB || SLOB))
42735 + help
42736 + If you say Y here, many of the features of grsecurity will be
42737 + enabled, which will protect you against many kinds of attacks
42738 + against your system. The heightened security comes at a cost
42739 + of an increased chance of incompatibilities with rare software
42740 + on your machine. Since this security level enables PaX, you should
42741 + view <http://pax.grsecurity.net> and read about the PaX
42742 + project. While you are there, download chpax and run it on
42743 + binaries that cause problems with PaX. Also remember that
42744 + since the /proc restrictions are enabled, you must run your
42745 + identd as gid 1001. This security level enables the following
42746 + features in addition to those listed in the low and medium
42747 + security levels:
42748 +
42749 + - Additional /proc restrictions
42750 + - Chmod restrictions in chroot
42751 + - No signals, ptrace, or viewing of processes outside of chroot
42752 + - Capability restrictions in chroot
42753 + - Deny fchdir out of chroot
42754 + - Priority restrictions in chroot
42755 + - Segmentation-based implementation of PaX
42756 + - Mprotect restrictions
42757 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
42758 + - Kernel stack randomization
42759 + - Mount/unmount/remount logging
42760 + - Kernel symbol hiding
42761 + - Prevention of memory exhaustion-based exploits
42762 + - Hardening of module auto-loading
42763 + - Ptrace restrictions
42764 + - Restricted vm86 mode
42765 +
42766 +config GRKERNSEC_CUSTOM
42767 + bool "Custom"
42768 + help
42769 + If you say Y here, you will be able to configure every grsecurity
42770 + option, which allows you to enable many more features that aren't
42771 + covered in the basic security levels. These additional features
42772 + include TPE, socket restrictions, and the sysctl system for
42773 + grsecurity. It is advised that you read through the help for
42774 + each option to determine its usefulness in your situation.
42775 +
42776 +endchoice
42777 +
42778 +menu "Address Space Protection"
42779 +depends on GRKERNSEC
42780 +
42781 +config GRKERNSEC_KMEM
42782 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
42783 + help
42784 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
42785 + be written to via mmap or otherwise to modify the running kernel.
42786 + /dev/port will also not be allowed to be opened. If you have module
42787 + support disabled, enabling this will close up four ways that are
42788 + currently used to insert malicious code into the running kernel.
42789 + Even with all these features enabled, we still highly recommend that
42790 + you use the RBAC system, as it is still possible for an attacker to
42791 + modify the running kernel through privileged I/O granted by ioperm/iopl.
42792 + If you are not using XFree86, you may be able to stop this additional
42793 + case by enabling the 'Disable privileged I/O' option. Though nothing
42794 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
42795 + but only to video memory, which is the only writing we allow in this
42796 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
42797 + not be allowed to mprotect it with PROT_WRITE later.
42798 + It is highly recommended that you say Y here if you meet all the
42799 + conditions above.
42800 +
42801 +config GRKERNSEC_VM86
42802 + bool "Restrict VM86 mode"
42803 + depends on X86_32
42804 +
42805 + help
42806 + If you say Y here, only processes with CAP_SYS_RAWIO will be able to
42807 + make use of a special execution mode on 32bit x86 processors called
42808 + Virtual 8086 (VM86) mode. XFree86 may need vm86 mode for certain
42809 + video cards and will still work with this option enabled. The purpose
42810 + of the option is to prevent exploitation of emulation errors in
42811 + virtualization of vm86 mode like the one discovered in VMWare in 2009.
42812 + Nearly all users should be able to enable this option.
42813 +
42814 +config GRKERNSEC_IO
42815 + bool "Disable privileged I/O"
42816 + depends on X86
42817 + select RTC_CLASS
42818 + select RTC_INTF_DEV
42819 + select RTC_DRV_CMOS
42820 +
42821 + help
42822 + If you say Y here, all ioperm and iopl calls will return an error.
42823 + Ioperm and iopl can be used to modify the running kernel.
42824 + Unfortunately, some programs need this access to operate properly,
42825 + the most notable of which are XFree86 and hwclock. hwclock can be
42826 + remedied by having RTC support in the kernel, so real-time
42827 + clock support is enabled if this option is enabled, to ensure
42828 + that hwclock operates correctly. XFree86 still will not
42829 + operate correctly with this option enabled, so DO NOT CHOOSE Y
42830 + IF YOU USE XFree86. If you use XFree86 and you still want to
42831 + protect your kernel against modification, use the RBAC system.
42832 +
42833 +config GRKERNSEC_PROC_MEMMAP
42834 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
42835 + default y if (PAX_NOEXEC || PAX_ASLR)
42836 + depends on PAX_NOEXEC || PAX_ASLR
42837 + help
42838 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
42839 + give no information about the addresses of its mappings if
42840 + PaX features that rely on random addresses are enabled on the task.
42841 + If you use PaX it is greatly recommended that you say Y here as it
42842 + closes up a hole that makes the full ASLR useless for suid
42843 + binaries.
42844 +
42845 +config GRKERNSEC_BRUTE
42846 + bool "Deter exploit bruteforcing"
42847 + help
42848 + If you say Y here, attempts to bruteforce exploits against forking
42849 + daemons such as apache or sshd will be deterred. When a child of a
42850 + forking daemon is killed by PaX or crashes due to an illegal
42851 + instruction, the parent process will be delayed 30 seconds upon every
42852 + subsequent fork until the administrator is able to assess the
42853 + situation and restart the daemon. It is recommended that you also
42854 + enable signal logging in the auditing section so that logs are
42855 + generated when a process performs an illegal instruction.
42856 +
42857 +config GRKERNSEC_MODHARDEN
42858 + bool "Harden module auto-loading"
42859 + depends on MODULES
42860 + help
42861 + If you say Y here, module auto-loading in response to use of some
42862 + feature implemented by an unloaded module will be restricted to
42863 + root users. Enabling this option helps defend against attacks
42864 + by unprivileged users who abuse the auto-loading behavior to
42865 + cause a vulnerable module to load that is then exploited.
42866 +
42867 + If this option prevents a legitimate use of auto-loading for a
42868 + non-root user, the administrator can execute modprobe manually
42869 + with the exact name of the module mentioned in the alert log.
42870 + Alternatively, the administrator can add the module to the list
42871 + of modules loaded at boot by modifying init scripts.
42872 +
42873 + Modification of init scripts will most likely be needed on
42874 + Ubuntu servers with encrypted home directory support enabled,
42875 + as the first non-root user logging in will cause the ecb(aes),
42876 + ecb(aes)-all, cbc(aes), and cbc(aes)-all modules to be loaded.
42877 +
42878 +config GRKERNSEC_HIDESYM
42879 + bool "Hide kernel symbols"
42880 + help
42881 + If you say Y here, getting information on loaded modules, and
42882 + displaying all kernel symbols through a syscall will be restricted
42883 + to users with CAP_SYS_MODULE. For software compatibility reasons,
42884 + /proc/kallsyms will be restricted to the root user. The RBAC
42885 + system can hide that entry even from root.
42886 +
42887 + This option also prevents leaking of kernel addresses through
42888 + several /proc entries.
42889 +
42890 + Note that this option is only effective provided the following
42891 + conditions are met:
42892 + 1) The kernel using grsecurity is not precompiled by some distribution
42893 + 2) You are using the RBAC system and hiding other files such as your
42894 + kernel image and System.map. Alternatively, enabling this option
42895 + causes the permissions on /boot, /lib/modules, and the kernel
42896 + source directory to change at compile time to prevent
42897 + reading by non-root users.
42898 + If the above conditions are met, this option will aid in providing a
42899 + useful protection against local kernel exploitation of overflows
42900 + and arbitrary read/write vulnerabilities.
42901 +
42902 +endmenu
42903 +menu "Role Based Access Control Options"
42904 +depends on GRKERNSEC
42905 +
42906 +config GRKERNSEC_NO_RBAC
42907 + bool "Disable RBAC system"
42908 + help
42909 + If you say Y here, the /dev/grsec device will be removed from the kernel,
42910 + preventing the RBAC system from being enabled. You should only say Y
42911 + here if you have no intention of using the RBAC system, so as to prevent
42912 + an attacker with root access from misusing the RBAC system to hide files
42913 + and processes when loadable module support and /dev/[k]mem have been
42914 + locked down.
42915 +
42916 +config GRKERNSEC_ACL_HIDEKERN
42917 + bool "Hide kernel processes"
42918 + help
42919 + If you say Y here, all kernel threads will be hidden to all
42920 + processes but those whose subject has the "view hidden processes"
42921 + flag.
42922 +
42923 +config GRKERNSEC_ACL_MAXTRIES
42924 + int "Maximum tries before password lockout"
42925 + default 3
42926 + help
42927 + This option enforces the maximum number of times a user can attempt
42928 + to authorize themselves with the grsecurity RBAC system before being
42929 + denied the ability to attempt authorization again for a specified time.
42930 + The lower the number, the harder it will be to brute-force a password.
42931 +
42932 +config GRKERNSEC_ACL_TIMEOUT
42933 + int "Time to wait after max password tries, in seconds"
42934 + default 30
42935 + help
42936 + This option specifies the time the user must wait after attempting to
42937 + authorize to the RBAC system with the maximum number of invalid
42938 + passwords. The higher the number, the harder it will be to brute-force
42939 + a password.
42940 +
42941 +endmenu
42942 +menu "Filesystem Protections"
42943 +depends on GRKERNSEC
42944 +
42945 +config GRKERNSEC_PROC
42946 + bool "Proc restrictions"
42947 + help
42948 + If you say Y here, the permissions of the /proc filesystem
42949 + will be altered to enhance system security and privacy. You MUST
42950 + choose either a user only restriction or a user and group restriction.
42951 + Depending upon the option you choose, you can either restrict users to
42952 + see only the processes they themselves run, or choose a group that can
42953 + view all processes and files normally restricted to root if you choose
42954 + the "restrict to user only" option. NOTE: If you're running identd as
42955 + a non-root user, you will have to run it as the group you specify here.
42956 +
42957 +config GRKERNSEC_PROC_USER
42958 + bool "Restrict /proc to user only"
42959 + depends on GRKERNSEC_PROC
42960 + help
42961 + If you say Y here, non-root users will only be able to view their own
42962 + processes, and restricts them from viewing network-related information,
42963 + and viewing kernel symbol and module information.
42964 +
42965 +config GRKERNSEC_PROC_USERGROUP
42966 + bool "Allow special group"
42967 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
42968 + help
42969 + If you say Y here, you will be able to select a group that will be
42970 + able to view all processes, network-related information, and
42971 + kernel and symbol information. This option is useful if you want
42972 + to run identd as a non-root user.
42973 +
42974 +config GRKERNSEC_PROC_GID
42975 + int "GID for special group"
42976 + depends on GRKERNSEC_PROC_USERGROUP
42977 + default 1001
42978 +
42979 +config GRKERNSEC_PROC_ADD
42980 + bool "Additional restrictions"
42981 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
42982 + help
42983 + If you say Y here, additional restrictions will be placed on
42984 + /proc that keep normal users from viewing device information and
42985 + slabinfo information that could be useful for exploits.
42986 +
42987 +config GRKERNSEC_LINK
42988 + bool "Linking restrictions"
42989 + help
42990 + If you say Y here, /tmp race exploits will be prevented, since users
42991 + will no longer be able to follow symlinks owned by other users in
42992 + world-writable +t directories (i.e. /tmp), unless the owner of the
42993 + symlink is the owner of the directory. users will also not be
42994 + able to hardlink to files they do not own. If the sysctl option is
42995 + enabled, a sysctl option with name "linking_restrictions" is created.
42996 +
42997 +config GRKERNSEC_FIFO
42998 + bool "FIFO restrictions"
42999 + help
43000 + If you say Y here, users will not be able to write to FIFOs they don't
43001 + own in world-writable +t directories (i.e. /tmp), unless the owner of
43002 + the FIFO is the same owner of the directory it's held in. If the sysctl
43003 + option is enabled, a sysctl option with name "fifo_restrictions" is
43004 + created.
43005 +
43006 +config GRKERNSEC_ROFS
43007 + bool "Runtime read-only mount protection"
43008 + help
43009 + If you say Y here, a sysctl option with name "romount_protect" will
43010 + be created. By setting this option to 1 at runtime, filesystems
43011 + will be protected in the following ways:
43012 + * No new writable mounts will be allowed
43013 + * Existing read-only mounts won't be able to be remounted read/write
43014 + * Write operations will be denied on all block devices
43015 + This option acts independently of grsec_lock: once it is set to 1,
43016 + it cannot be turned off. Therefore, please be mindful of the resulting
43017 + behavior if this option is enabled in an init script on a read-only
43018 + filesystem. This feature is mainly intended for secure embedded systems.
43019 +
43020 +config GRKERNSEC_CHROOT
43021 + bool "Chroot jail restrictions"
43022 + help
43023 + If you say Y here, you will be able to choose several options that will
43024 + make breaking out of a chrooted jail much more difficult. If you
43025 + encounter no software incompatibilities with the following options, it
43026 + is recommended that you enable each one.
43027 +
43028 +config GRKERNSEC_CHROOT_MOUNT
43029 + bool "Deny mounts"
43030 + depends on GRKERNSEC_CHROOT
43031 + help
43032 + If you say Y here, processes inside a chroot will not be able to
43033 + mount or remount filesystems. If the sysctl option is enabled, a
43034 + sysctl option with name "chroot_deny_mount" is created.
43035 +
43036 +config GRKERNSEC_CHROOT_DOUBLE
43037 + bool "Deny double-chroots"
43038 + depends on GRKERNSEC_CHROOT
43039 + help
43040 + If you say Y here, processes inside a chroot will not be able to chroot
43041 + again outside the chroot. This is a widely used method of breaking
43042 + out of a chroot jail and should not be allowed. If the sysctl
43043 + option is enabled, a sysctl option with name
43044 + "chroot_deny_chroot" is created.
43045 +
43046 +config GRKERNSEC_CHROOT_PIVOT
43047 + bool "Deny pivot_root in chroot"
43048 + depends on GRKERNSEC_CHROOT
43049 + help
43050 + If you say Y here, processes inside a chroot will not be able to use
43051 + a function called pivot_root() that was introduced in Linux 2.3.41. It
43052 + works similar to chroot in that it changes the root filesystem. This
43053 + function could be misused in a chrooted process to attempt to break out
43054 + of the chroot, and therefore should not be allowed. If the sysctl
43055 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
43056 + created.
43057 +
43058 +config GRKERNSEC_CHROOT_CHDIR
43059 + bool "Enforce chdir(\"/\") on all chroots"
43060 + depends on GRKERNSEC_CHROOT
43061 + help
43062 + If you say Y here, the current working directory of all newly-chrooted
43063 + applications will be set to the the root directory of the chroot.
43064 + The man page on chroot(2) states:
43065 + Note that this call does not change the current working
43066 + directory, so that `.' can be outside the tree rooted at
43067 + `/'. In particular, the super-user can escape from a
43068 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
43069 +
43070 + It is recommended that you say Y here, since it's not known to break
43071 + any software. If the sysctl option is enabled, a sysctl option with
43072 + name "chroot_enforce_chdir" is created.
43073 +
43074 +config GRKERNSEC_CHROOT_CHMOD
43075 + bool "Deny (f)chmod +s"
43076 + depends on GRKERNSEC_CHROOT
43077 + help
43078 + If you say Y here, processes inside a chroot will not be able to chmod
43079 + or fchmod files to make them have suid or sgid bits. This protects
43080 + against another published method of breaking a chroot. If the sysctl
43081 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
43082 + created.
43083 +
43084 +config GRKERNSEC_CHROOT_FCHDIR
43085 + bool "Deny fchdir out of chroot"
43086 + depends on GRKERNSEC_CHROOT
43087 + help
43088 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
43089 + to a file descriptor of the chrooting process that points to a directory
43090 + outside the filesystem will be stopped. If the sysctl option
43091 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
43092 +
43093 +config GRKERNSEC_CHROOT_MKNOD
43094 + bool "Deny mknod"
43095 + depends on GRKERNSEC_CHROOT
43096 + help
43097 + If you say Y here, processes inside a chroot will not be allowed to
43098 + mknod. The problem with using mknod inside a chroot is that it
43099 + would allow an attacker to create a device entry that is the same
43100 + as one on the physical root of your system, which could range from
43101 + anything from the console device to a device for your harddrive (which
43102 + they could then use to wipe the drive or steal data). It is recommended
43103 + that you say Y here, unless you run into software incompatibilities.
43104 + If the sysctl option is enabled, a sysctl option with name
43105 + "chroot_deny_mknod" is created.
43106 +
43107 +config GRKERNSEC_CHROOT_SHMAT
43108 + bool "Deny shmat() out of chroot"
43109 + depends on GRKERNSEC_CHROOT
43110 + help
43111 + If you say Y here, processes inside a chroot will not be able to attach
43112 + to shared memory segments that were created outside of the chroot jail.
43113 + It is recommended that you say Y here. If the sysctl option is enabled,
43114 + a sysctl option with name "chroot_deny_shmat" is created.
43115 +
43116 +config GRKERNSEC_CHROOT_UNIX
43117 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
43118 + depends on GRKERNSEC_CHROOT
43119 + help
43120 + If you say Y here, processes inside a chroot will not be able to
43121 + connect to abstract (meaning not belonging to a filesystem) Unix
43122 + domain sockets that were bound outside of a chroot. It is recommended
43123 + that you say Y here. If the sysctl option is enabled, a sysctl option
43124 + with name "chroot_deny_unix" is created.
43125 +
43126 +config GRKERNSEC_CHROOT_FINDTASK
43127 + bool "Protect outside processes"
43128 + depends on GRKERNSEC_CHROOT
43129 + help
43130 + If you say Y here, processes inside a chroot will not be able to
43131 + kill, send signals with fcntl, ptrace, capget, getpgid, setpgid,
43132 + getsid, or view any process outside of the chroot. If the sysctl
43133 + option is enabled, a sysctl option with name "chroot_findtask" is
43134 + created.
43135 +
43136 +config GRKERNSEC_CHROOT_NICE
43137 + bool "Restrict priority changes"
43138 + depends on GRKERNSEC_CHROOT
43139 + help
43140 + If you say Y here, processes inside a chroot will not be able to raise
43141 + the priority of processes in the chroot, or alter the priority of
43142 + processes outside the chroot. This provides more security than simply
43143 + removing CAP_SYS_NICE from the process' capability set. If the
43144 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
43145 + is created.
43146 +
43147 +config GRKERNSEC_CHROOT_SYSCTL
43148 + bool "Deny sysctl writes"
43149 + depends on GRKERNSEC_CHROOT
43150 + help
43151 + If you say Y here, an attacker in a chroot will not be able to
43152 + write to sysctl entries, either by sysctl(2) or through a /proc
43153 + interface. It is strongly recommended that you say Y here. If the
43154 + sysctl option is enabled, a sysctl option with name
43155 + "chroot_deny_sysctl" is created.
43156 +
43157 +config GRKERNSEC_CHROOT_CAPS
43158 + bool "Capability restrictions"
43159 + depends on GRKERNSEC_CHROOT
43160 + help
43161 + If you say Y here, the capabilities on all root processes within a
43162 + chroot jail will be lowered to stop module insertion, raw i/o,
43163 + system and net admin tasks, rebooting the system, modifying immutable
43164 + files, modifying IPC owned by another, and changing the system time.
43165 + This is left an option because it can break some apps. Disable this
43166 + if your chrooted apps are having problems performing those kinds of
43167 + tasks. If the sysctl option is enabled, a sysctl option with
43168 + name "chroot_caps" is created.
43169 +
43170 +endmenu
43171 +menu "Kernel Auditing"
43172 +depends on GRKERNSEC
43173 +
43174 +config GRKERNSEC_AUDIT_GROUP
43175 + bool "Single group for auditing"
43176 + help
43177 + If you say Y here, the exec, chdir, and (un)mount logging features
43178 + will only operate on a group you specify. This option is recommended
43179 + if you only want to watch certain users instead of having a large
43180 + amount of logs from the entire system. If the sysctl option is enabled,
43181 + a sysctl option with name "audit_group" is created.
43182 +
43183 +config GRKERNSEC_AUDIT_GID
43184 + int "GID for auditing"
43185 + depends on GRKERNSEC_AUDIT_GROUP
43186 + default 1007
43187 +
43188 +config GRKERNSEC_EXECLOG
43189 + bool "Exec logging"
43190 + help
43191 + If you say Y here, all execve() calls will be logged (since the
43192 + other exec*() calls are frontends to execve(), all execution
43193 + will be logged). Useful for shell-servers that like to keep track
43194 + of their users. If the sysctl option is enabled, a sysctl option with
43195 + name "exec_logging" is created.
43196 + WARNING: This option when enabled will produce a LOT of logs, especially
43197 + on an active system.
43198 +
43199 +config GRKERNSEC_RESLOG
43200 + bool "Resource logging"
43201 + help
43202 + If you say Y here, all attempts to overstep resource limits will
43203 + be logged with the resource name, the requested size, and the current
43204 + limit. It is highly recommended that you say Y here. If the sysctl
43205 + option is enabled, a sysctl option with name "resource_logging" is
43206 + created. If the RBAC system is enabled, the sysctl value is ignored.
43207 +
43208 +config GRKERNSEC_CHROOT_EXECLOG
43209 + bool "Log execs within chroot"
43210 + help
43211 + If you say Y here, all executions inside a chroot jail will be logged
43212 + to syslog. This can cause a large amount of logs if certain
43213 + applications (eg. djb's daemontools) are installed on the system, and
43214 + is therefore left as an option. If the sysctl option is enabled, a
43215 + sysctl option with name "chroot_execlog" is created.
43216 +
43217 +config GRKERNSEC_AUDIT_PTRACE
43218 + bool "Ptrace logging"
43219 + help
43220 + If you say Y here, all attempts to attach to a process via ptrace
43221 + will be logged. If the sysctl option is enabled, a sysctl option
43222 + with name "audit_ptrace" is created.
43223 +
43224 +config GRKERNSEC_AUDIT_CHDIR
43225 + bool "Chdir logging"
43226 + help
43227 + If you say Y here, all chdir() calls will be logged. If the sysctl
43228 + option is enabled, a sysctl option with name "audit_chdir" is created.
43229 +
43230 +config GRKERNSEC_AUDIT_MOUNT
43231 + bool "(Un)Mount logging"
43232 + help
43233 + If you say Y here, all mounts and unmounts will be logged. If the
43234 + sysctl option is enabled, a sysctl option with name "audit_mount" is
43235 + created.
43236 +
43237 +config GRKERNSEC_SIGNAL
43238 + bool "Signal logging"
43239 + help
43240 + If you say Y here, certain important signals will be logged, such as
43241 + SIGSEGV, which will as a result inform you of when a error in a program
43242 + occurred, which in some cases could mean a possible exploit attempt.
43243 + If the sysctl option is enabled, a sysctl option with name
43244 + "signal_logging" is created.
43245 +
43246 +config GRKERNSEC_FORKFAIL
43247 + bool "Fork failure logging"
43248 + help
43249 + If you say Y here, all failed fork() attempts will be logged.
43250 + This could suggest a fork bomb, or someone attempting to overstep
43251 + their process limit. If the sysctl option is enabled, a sysctl option
43252 + with name "forkfail_logging" is created.
43253 +
43254 +config GRKERNSEC_TIME
43255 + bool "Time change logging"
43256 + help
43257 + If you say Y here, any changes of the system clock will be logged.
43258 + If the sysctl option is enabled, a sysctl option with name
43259 + "timechange_logging" is created.
43260 +
43261 +config GRKERNSEC_PROC_IPADDR
43262 + bool "/proc/<pid>/ipaddr support"
43263 + help
43264 + If you say Y here, a new entry will be added to each /proc/<pid>
43265 + directory that contains the IP address of the person using the task.
43266 + The IP is carried across local TCP and AF_UNIX stream sockets.
43267 + This information can be useful for IDS/IPSes to perform remote response
43268 + to a local attack. The entry is readable by only the owner of the
43269 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
43270 + the RBAC system), and thus does not create privacy concerns.
43271 +
43272 +config GRKERNSEC_RWXMAP_LOG
43273 + bool 'Denied RWX mmap/mprotect logging'
43274 + depends on PAX_MPROTECT && !PAX_EMUPLT && !PAX_EMUSIGRT
43275 + help
43276 + If you say Y here, calls to mmap() and mprotect() with explicit
43277 + usage of PROT_WRITE and PROT_EXEC together will be logged when
43278 + denied by the PAX_MPROTECT feature. If the sysctl option is
43279 + enabled, a sysctl option with name "rwxmap_logging" is created.
43280 +
43281 +config GRKERNSEC_AUDIT_TEXTREL
43282 + bool 'ELF text relocations logging (READ HELP)'
43283 + depends on PAX_MPROTECT
43284 + help
43285 + If you say Y here, text relocations will be logged with the filename
43286 + of the offending library or binary. The purpose of the feature is
43287 + to help Linux distribution developers get rid of libraries and
43288 + binaries that need text relocations which hinder the future progress
43289 + of PaX. Only Linux distribution developers should say Y here, and
43290 + never on a production machine, as this option creates an information
43291 + leak that could aid an attacker in defeating the randomization of
43292 + a single memory region. If the sysctl option is enabled, a sysctl
43293 + option with name "audit_textrel" is created.
43294 +
43295 +endmenu
43296 +
43297 +menu "Executable Protections"
43298 +depends on GRKERNSEC
43299 +
43300 +config GRKERNSEC_EXECVE
43301 + bool "Enforce RLIMIT_NPROC on execs"
43302 + help
43303 + If you say Y here, users with a resource limit on processes will
43304 + have the value checked during execve() calls. The current system
43305 + only checks the system limit during fork() calls. If the sysctl option
43306 + is enabled, a sysctl option with name "execve_limiting" is created.
43307 +
43308 +config GRKERNSEC_DMESG
43309 + bool "Dmesg(8) restriction"
43310 + help
43311 + If you say Y here, non-root users will not be able to use dmesg(8)
43312 + to view up to the last 4kb of messages in the kernel's log buffer.
43313 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
43314 + created.
43315 +
43316 +config GRKERNSEC_HARDEN_PTRACE
43317 + bool "Deter ptrace-based process snooping"
43318 + help
43319 + If you say Y here, TTY sniffers and other malicious monitoring
43320 + programs implemented through ptrace will be defeated. If you
43321 + have been using the RBAC system, this option has already been
43322 + enabled for several years for all users, with the ability to make
43323 + fine-grained exceptions.
43324 +
43325 + This option only affects the ability of non-root users to ptrace
43326 + processes that are not a descendent of the ptracing process.
43327 + This means that strace ./binary and gdb ./binary will still work,
43328 + but attaching to arbitrary processes will not. If the sysctl
43329 + option is enabled, a sysctl option with name "harden_ptrace" is
43330 + created.
43331 +
43332 +config GRKERNSEC_TPE
43333 + bool "Trusted Path Execution (TPE)"
43334 + help
43335 + If you say Y here, you will be able to choose a gid to add to the
43336 + supplementary groups of users you want to mark as "untrusted."
43337 + These users will not be able to execute any files that are not in
43338 + root-owned directories writable only by root. If the sysctl option
43339 + is enabled, a sysctl option with name "tpe" is created.
43340 +
43341 +config GRKERNSEC_TPE_ALL
43342 + bool "Partially restrict all non-root users"
43343 + depends on GRKERNSEC_TPE
43344 + help
43345 + If you say Y here, all non-root users will be covered under
43346 + a weaker TPE restriction. This is separate from, and in addition to,
43347 + the main TPE options that you have selected elsewhere. Thus, if a
43348 + "trusted" GID is chosen, this restriction applies to even that GID.
43349 + Under this restriction, all non-root users will only be allowed to
43350 + execute files in directories they own that are not group or
43351 + world-writable, or in directories owned by root and writable only by
43352 + root. If the sysctl option is enabled, a sysctl option with name
43353 + "tpe_restrict_all" is created.
43354 +
43355 +config GRKERNSEC_TPE_INVERT
43356 + bool "Invert GID option"
43357 + depends on GRKERNSEC_TPE
43358 + help
43359 + If you say Y here, the group you specify in the TPE configuration will
43360 + decide what group TPE restrictions will be *disabled* for. This
43361 + option is useful if you want TPE restrictions to be applied to most
43362 + users on the system. If the sysctl option is enabled, a sysctl option
43363 + with name "tpe_invert" is created. Unlike other sysctl options, this
43364 + entry will default to on for backward-compatibility.
43365 +
43366 +config GRKERNSEC_TPE_GID
43367 + int "GID for untrusted users"
43368 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
43369 + default 1005
43370 + help
43371 + Setting this GID determines what group TPE restrictions will be
43372 + *enabled* for. If the sysctl option is enabled, a sysctl option
43373 + with name "tpe_gid" is created.
43374 +
43375 +config GRKERNSEC_TPE_GID
43376 + int "GID for trusted users"
43377 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
43378 + default 1005
43379 + help
43380 + Setting this GID determines what group TPE restrictions will be
43381 + *disabled* for. If the sysctl option is enabled, a sysctl option
43382 + with name "tpe_gid" is created.
43383 +
43384 +endmenu
43385 +menu "Network Protections"
43386 +depends on GRKERNSEC
43387 +
43388 +config GRKERNSEC_RANDNET
43389 + bool "Larger entropy pools"
43390 + help
43391 + If you say Y here, the entropy pools used for many features of Linux
43392 + and grsecurity will be doubled in size. Since several grsecurity
43393 + features use additional randomness, it is recommended that you say Y
43394 + here. Saying Y here has a similar effect as modifying
43395 + /proc/sys/kernel/random/poolsize.
43396 +
43397 +config GRKERNSEC_BLACKHOLE
43398 + bool "TCP/UDP blackhole and LAST_ACK DoS prevention"
43399 + help
43400 + If you say Y here, neither TCP resets nor ICMP
43401 + destination-unreachable packets will be sent in response to packets
43402 + sent to ports for which no associated listening process exists.
43403 + This feature supports both IPV4 and IPV6 and exempts the
43404 + loopback interface from blackholing. Enabling this feature
43405 + makes a host more resilient to DoS attacks and reduces network
43406 + visibility against scanners.
43407 +
43408 + The blackhole feature as-implemented is equivalent to the FreeBSD
43409 + blackhole feature, as it prevents RST responses to all packets, not
43410 + just SYNs. Under most application behavior this causes no
43411 + problems, but applications (like haproxy) may not close certain
43412 + connections in a way that cleanly terminates them on the remote
43413 + end, leaving the remote host in LAST_ACK state. Because of this
43414 + side-effect and to prevent intentional LAST_ACK DoSes, this
43415 + feature also adds automatic mitigation against such attacks.
43416 + The mitigation drastically reduces the amount of time a socket
43417 + can spend in LAST_ACK state. If you're using haproxy and not
43418 + all servers it connects to have this option enabled, consider
43419 + disabling this feature on the haproxy host.
43420 +
43421 + If the sysctl option is enabled, two sysctl options with names
43422 + "ip_blackhole" and "lastack_retries" will be created.
43423 + While "ip_blackhole" takes the standard zero/non-zero on/off
43424 + toggle, "lastack_retries" uses the same kinds of values as
43425 + "tcp_retries1" and "tcp_retries2". The default value of 4
43426 + prevents a socket from lasting more than 45 seconds in LAST_ACK
43427 + state.
43428 +
43429 +config GRKERNSEC_SOCKET
43430 + bool "Socket restrictions"
43431 + help
43432 + If you say Y here, you will be able to choose from several options.
43433 + If you assign a GID on your system and add it to the supplementary
43434 + groups of users you want to restrict socket access to, this patch
43435 + will perform up to three things, based on the option(s) you choose.
43436 +
43437 +config GRKERNSEC_SOCKET_ALL
43438 + bool "Deny any sockets to group"
43439 + depends on GRKERNSEC_SOCKET
43440 + help
43441 + If you say Y here, you will be able to choose a GID of whose users will
43442 + be unable to connect to other hosts from your machine or run server
43443 + applications from your machine. If the sysctl option is enabled, a
43444 + sysctl option with name "socket_all" is created.
43445 +
43446 +config GRKERNSEC_SOCKET_ALL_GID
43447 + int "GID to deny all sockets for"
43448 + depends on GRKERNSEC_SOCKET_ALL
43449 + default 1004
43450 + help
43451 + Here you can choose the GID to disable socket access for. Remember to
43452 + add the users you want socket access disabled for to the GID
43453 + specified here. If the sysctl option is enabled, a sysctl option
43454 + with name "socket_all_gid" is created.
43455 +
43456 +config GRKERNSEC_SOCKET_CLIENT
43457 + bool "Deny client sockets to group"
43458 + depends on GRKERNSEC_SOCKET
43459 + help
43460 + If you say Y here, you will be able to choose a GID of whose users will
43461 + be unable to connect to other hosts from your machine, but will be
43462 + able to run servers. If this option is enabled, all users in the group
43463 + you specify will have to use passive mode when initiating ftp transfers
43464 + from the shell on your machine. If the sysctl option is enabled, a
43465 + sysctl option with name "socket_client" is created.
43466 +
43467 +config GRKERNSEC_SOCKET_CLIENT_GID
43468 + int "GID to deny client sockets for"
43469 + depends on GRKERNSEC_SOCKET_CLIENT
43470 + default 1003
43471 + help
43472 + Here you can choose the GID to disable client socket access for.
43473 + Remember to add the users you want client socket access disabled for to
43474 + the GID specified here. If the sysctl option is enabled, a sysctl
43475 + option with name "socket_client_gid" is created.
43476 +
43477 +config GRKERNSEC_SOCKET_SERVER
43478 + bool "Deny server sockets to group"
43479 + depends on GRKERNSEC_SOCKET
43480 + help
43481 + If you say Y here, you will be able to choose a GID of whose users will
43482 + be unable to run server applications from your machine. If the sysctl
43483 + option is enabled, a sysctl option with name "socket_server" is created.
43484 +
43485 +config GRKERNSEC_SOCKET_SERVER_GID
43486 + int "GID to deny server sockets for"
43487 + depends on GRKERNSEC_SOCKET_SERVER
43488 + default 1002
43489 + help
43490 + Here you can choose the GID to disable server socket access for.
43491 + Remember to add the users you want server socket access disabled for to
43492 + the GID specified here. If the sysctl option is enabled, a sysctl
43493 + option with name "socket_server_gid" is created.
43494 +
43495 +endmenu
43496 +menu "Sysctl support"
43497 +depends on GRKERNSEC && SYSCTL
43498 +
43499 +config GRKERNSEC_SYSCTL
43500 + bool "Sysctl support"
43501 + help
43502 + If you say Y here, you will be able to change the options that
43503 + grsecurity runs with at bootup, without having to recompile your
43504 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
43505 + to enable (1) or disable (0) various features. All the sysctl entries
43506 + are mutable until the "grsec_lock" entry is set to a non-zero value.
43507 + All features enabled in the kernel configuration are disabled at boot
43508 + if you do not say Y to the "Turn on features by default" option.
43509 + All options should be set at startup, and the grsec_lock entry should
43510 + be set to a non-zero value after all the options are set.
43511 + *THIS IS EXTREMELY IMPORTANT*
43512 +
43513 +config GRKERNSEC_SYSCTL_DISTRO
43514 + bool "Extra sysctl support for distro makers (READ HELP)"
43515 + depends on GRKERNSEC_SYSCTL && GRKERNSEC_IO
43516 + help
43517 + If you say Y here, additional sysctl options will be created
43518 + for features that affect processes running as root. Therefore,
43519 + it is critical when using this option that the grsec_lock entry be
43520 + enabled after boot. Only distros with prebuilt kernel packages
43521 + with this option enabled that can ensure grsec_lock is enabled
43522 + after boot should use this option.
43523 + *Failure to set grsec_lock after boot makes all grsec features
43524 + this option covers useless*
43525 +
43526 + Currently this option creates the following sysctl entries:
43527 + "Disable Privileged I/O": "disable_priv_io"
43528 +
43529 +config GRKERNSEC_SYSCTL_ON
43530 + bool "Turn on features by default"
43531 + depends on GRKERNSEC_SYSCTL
43532 + help
43533 + If you say Y here, instead of having all features enabled in the
43534 + kernel configuration disabled at boot time, the features will be
43535 + enabled at boot time. It is recommended you say Y here unless
43536 + there is some reason you would want all sysctl-tunable features to
43537 + be disabled by default. As mentioned elsewhere, it is important
43538 + to enable the grsec_lock entry once you have finished modifying
43539 + the sysctl entries.
43540 +
43541 +endmenu
43542 +menu "Logging Options"
43543 +depends on GRKERNSEC
43544 +
43545 +config GRKERNSEC_FLOODTIME
43546 + int "Seconds in between log messages (minimum)"
43547 + default 10
43548 + help
43549 + This option allows you to enforce the number of seconds between
43550 + grsecurity log messages. The default should be suitable for most
43551 + people, however, if you choose to change it, choose a value small enough
43552 + to allow informative logs to be produced, but large enough to
43553 + prevent flooding.
43554 +
43555 +config GRKERNSEC_FLOODBURST
43556 + int "Number of messages in a burst (maximum)"
43557 + default 4
43558 + help
43559 + This option allows you to choose the maximum number of messages allowed
43560 + within the flood time interval you chose in a separate option. The
43561 + default should be suitable for most people, however if you find that
43562 + many of your logs are being interpreted as flooding, you may want to
43563 + raise this value.
43564 +
43565 +endmenu
43566 +
43567 +endmenu
43568 diff -urNp linux-2.6.36/grsecurity/Makefile linux-2.6.36/grsecurity/Makefile
43569 --- linux-2.6.36/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
43570 +++ linux-2.6.36/grsecurity/Makefile 2010-11-06 18:58:50.000000000 -0400
43571 @@ -0,0 +1,29 @@
43572 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
43573 +# during 2001-2009 it has been completely redesigned by Brad Spengler
43574 +# into an RBAC system
43575 +#
43576 +# All code in this directory and various hooks inserted throughout the kernel
43577 +# are copyright Brad Spengler - Open Source Security, Inc., and released
43578 +# under the GPL v2 or higher
43579 +
43580 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
43581 + grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
43582 + grsec_time.o grsec_tpe.o grsec_link.o grsec_pax.o grsec_ptrace.o
43583 +
43584 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
43585 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
43586 + gracl_learn.o grsec_log.o
43587 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
43588 +
43589 +ifndef CONFIG_GRKERNSEC
43590 +obj-y += grsec_disabled.o
43591 +endif
43592 +
43593 +ifdef CONFIG_GRKERNSEC_HIDESYM
43594 +extra-y := grsec_hidesym.o
43595 +$(obj)/grsec_hidesym.o:
43596 + @-chmod -f 500 /boot
43597 + @-chmod -f 500 /lib/modules
43598 + @-chmod -f 700 .
43599 + @echo ' grsec: protected kernel image paths'
43600 +endif
43601 diff -urNp linux-2.6.36/include/acpi/acoutput.h linux-2.6.36/include/acpi/acoutput.h
43602 --- linux-2.6.36/include/acpi/acoutput.h 2010-10-20 16:30:22.000000000 -0400
43603 +++ linux-2.6.36/include/acpi/acoutput.h 2010-11-06 18:58:15.000000000 -0400
43604 @@ -269,8 +269,8 @@
43605 * leaving no executable debug code!
43606 */
43607 #define ACPI_FUNCTION_NAME(a)
43608 -#define ACPI_DEBUG_PRINT(pl)
43609 -#define ACPI_DEBUG_PRINT_RAW(pl)
43610 +#define ACPI_DEBUG_PRINT(pl) do {} while (0)
43611 +#define ACPI_DEBUG_PRINT_RAW(pl) do {} while (0)
43612
43613 #endif /* ACPI_DEBUG_OUTPUT */
43614
43615 diff -urNp linux-2.6.36/include/acpi/acpi_drivers.h linux-2.6.36/include/acpi/acpi_drivers.h
43616 --- linux-2.6.36/include/acpi/acpi_drivers.h 2010-10-20 16:30:22.000000000 -0400
43617 +++ linux-2.6.36/include/acpi/acpi_drivers.h 2010-11-06 18:58:15.000000000 -0400
43618 @@ -121,8 +121,8 @@ int acpi_processor_set_thermal_limit(acp
43619 Dock Station
43620 -------------------------------------------------------------------------- */
43621 struct acpi_dock_ops {
43622 - acpi_notify_handler handler;
43623 - acpi_notify_handler uevent;
43624 + const acpi_notify_handler handler;
43625 + const acpi_notify_handler uevent;
43626 };
43627
43628 #if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
43629 @@ -130,7 +130,7 @@ extern int is_dock_device(acpi_handle ha
43630 extern int register_dock_notifier(struct notifier_block *nb);
43631 extern void unregister_dock_notifier(struct notifier_block *nb);
43632 extern int register_hotplug_dock_device(acpi_handle handle,
43633 - struct acpi_dock_ops *ops,
43634 + const struct acpi_dock_ops *ops,
43635 void *context);
43636 extern void unregister_hotplug_dock_device(acpi_handle handle);
43637 #else
43638 @@ -146,7 +146,7 @@ static inline void unregister_dock_notif
43639 {
43640 }
43641 static inline int register_hotplug_dock_device(acpi_handle handle,
43642 - struct acpi_dock_ops *ops,
43643 + const struct acpi_dock_ops *ops,
43644 void *context)
43645 {
43646 return -ENODEV;
43647 diff -urNp linux-2.6.36/include/asm-generic/atomic-long.h linux-2.6.36/include/asm-generic/atomic-long.h
43648 --- linux-2.6.36/include/asm-generic/atomic-long.h 2010-10-20 16:30:22.000000000 -0400
43649 +++ linux-2.6.36/include/asm-generic/atomic-long.h 2010-11-06 18:58:15.000000000 -0400
43650 @@ -22,6 +22,12 @@
43651
43652 typedef atomic64_t atomic_long_t;
43653
43654 +#ifdef CONFIG_PAX_REFCOUNT
43655 +typedef atomic64_unchecked_t atomic_long_unchecked_t;
43656 +#else
43657 +typedef atomic64_t atomic_long_unchecked_t;
43658 +#endif
43659 +
43660 #define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i)
43661
43662 static inline long atomic_long_read(atomic_long_t *l)
43663 @@ -31,6 +37,15 @@ static inline long atomic_long_read(atom
43664 return (long)atomic64_read(v);
43665 }
43666
43667 +#ifdef CONFIG_PAX_REFCOUNT
43668 +static inline long atomic_long_read_unchecked(atomic_long_unchecked_t *l)
43669 +{
43670 + atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
43671 +
43672 + return (long)atomic64_read_unchecked(v);
43673 +}
43674 +#endif
43675 +
43676 static inline void atomic_long_set(atomic_long_t *l, long i)
43677 {
43678 atomic64_t *v = (atomic64_t *)l;
43679 @@ -38,6 +53,15 @@ static inline void atomic_long_set(atomi
43680 atomic64_set(v, i);
43681 }
43682
43683 +#ifdef CONFIG_PAX_REFCOUNT
43684 +static inline void atomic_long_set_unchecked(atomic_long_unchecked_t *l, long i)
43685 +{
43686 + atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
43687 +
43688 + atomic64_set_unchecked(v, i);
43689 +}
43690 +#endif
43691 +
43692 static inline void atomic_long_inc(atomic_long_t *l)
43693 {
43694 atomic64_t *v = (atomic64_t *)l;
43695 @@ -45,6 +69,15 @@ static inline void atomic_long_inc(atomi
43696 atomic64_inc(v);
43697 }
43698
43699 +#ifdef CONFIG_PAX_REFCOUNT
43700 +static inline void atomic_long_inc_unchecked(atomic_long_unchecked_t *l)
43701 +{
43702 + atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
43703 +
43704 + atomic64_inc_unchecked(v);
43705 +}
43706 +#endif
43707 +
43708 static inline void atomic_long_dec(atomic_long_t *l)
43709 {
43710 atomic64_t *v = (atomic64_t *)l;
43711 @@ -52,6 +85,15 @@ static inline void atomic_long_dec(atomi
43712 atomic64_dec(v);
43713 }
43714
43715 +#ifdef CONFIG_PAX_REFCOUNT
43716 +static inline void atomic_long_dec_unchecked(atomic_long_unchecked_t *l)
43717 +{
43718 + atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
43719 +
43720 + atomic64_dec_unchecked(v);
43721 +}
43722 +#endif
43723 +
43724 static inline void atomic_long_add(long i, atomic_long_t *l)
43725 {
43726 atomic64_t *v = (atomic64_t *)l;
43727 @@ -59,6 +101,15 @@ static inline void atomic_long_add(long
43728 atomic64_add(i, v);
43729 }
43730
43731 +#ifdef CONFIG_PAX_REFCOUNT
43732 +static inline void atomic_long_add_unchecked(long i, atomic_long_unchecked_t *l)
43733 +{
43734 + atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
43735 +
43736 + atomic64_add_unchecked(i, v);
43737 +}
43738 +#endif
43739 +
43740 static inline void atomic_long_sub(long i, atomic_long_t *l)
43741 {
43742 atomic64_t *v = (atomic64_t *)l;
43743 @@ -66,6 +117,15 @@ static inline void atomic_long_sub(long
43744 atomic64_sub(i, v);
43745 }
43746
43747 +#ifdef CONFIG_PAX_REFCOUNT
43748 +static inline void atomic_long_sub_unchecked(long i, atomic_long_unchecked_t *l)
43749 +{
43750 + atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
43751 +
43752 + atomic64_sub_unchecked(i, v);
43753 +}
43754 +#endif
43755 +
43756 static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
43757 {
43758 atomic64_t *v = (atomic64_t *)l;
43759 @@ -115,6 +175,15 @@ static inline long atomic_long_inc_retur
43760 return (long)atomic64_inc_return(v);
43761 }
43762
43763 +#ifdef CONFIG_PAX_REFCOUNT
43764 +static inline long atomic_long_inc_return_unchecked(atomic_long_unchecked_t *l)
43765 +{
43766 + atomic64_unchecked_t *v = (atomic64_unchecked_t *)l;
43767 +
43768 + return (long)atomic64_inc_return_unchecked(v);
43769 +}
43770 +#endif
43771 +
43772 static inline long atomic_long_dec_return(atomic_long_t *l)
43773 {
43774 atomic64_t *v = (atomic64_t *)l;
43775 @@ -140,6 +209,12 @@ static inline long atomic_long_add_unles
43776
43777 typedef atomic_t atomic_long_t;
43778
43779 +#ifdef CONFIG_PAX_REFCOUNT
43780 +typedef atomic_unchecked_t atomic_long_unchecked_t;
43781 +#else
43782 +typedef atomic_t atomic_long_unchecked_t;
43783 +#endif
43784 +
43785 #define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i)
43786 static inline long atomic_long_read(atomic_long_t *l)
43787 {
43788 @@ -148,6 +223,15 @@ static inline long atomic_long_read(atom
43789 return (long)atomic_read(v);
43790 }
43791
43792 +#ifdef CONFIG_PAX_REFCOUNT
43793 +static inline long atomic_long_read_unchecked(atomic_long_unchecked_t *l)
43794 +{
43795 + atomic_unchecked_t *v = (atomic_unchecked_t *)l;
43796 +
43797 + return (long)atomic_read_unchecked(v);
43798 +}
43799 +#endif
43800 +
43801 static inline void atomic_long_set(atomic_long_t *l, long i)
43802 {
43803 atomic_t *v = (atomic_t *)l;
43804 @@ -155,6 +239,15 @@ static inline void atomic_long_set(atomi
43805 atomic_set(v, i);
43806 }
43807
43808 +#ifdef CONFIG_PAX_REFCOUNT
43809 +static inline void atomic_long_set_unchecked(atomic_long_unchecked_t *l, long i)
43810 +{
43811 + atomic_unchecked_t *v = (atomic_unchecked_t *)l;
43812 +
43813 + atomic_set_unchecked(v, i);
43814 +}
43815 +#endif
43816 +
43817 static inline void atomic_long_inc(atomic_long_t *l)
43818 {
43819 atomic_t *v = (atomic_t *)l;
43820 @@ -162,6 +255,15 @@ static inline void atomic_long_inc(atomi
43821 atomic_inc(v);
43822 }
43823
43824 +#ifdef CONFIG_PAX_REFCOUNT
43825 +static inline void atomic_long_inc_unchecked(atomic_long_unchecked_t *l)
43826 +{
43827 + atomic_unchecked_t *v = (atomic_unchecked_t *)l;
43828 +
43829 + atomic_inc_unchecked(v);
43830 +}
43831 +#endif
43832 +
43833 static inline void atomic_long_dec(atomic_long_t *l)
43834 {
43835 atomic_t *v = (atomic_t *)l;
43836 @@ -169,6 +271,15 @@ static inline void atomic_long_dec(atomi
43837 atomic_dec(v);
43838 }
43839
43840 +#ifdef CONFIG_PAX_REFCOUNT
43841 +static inline void atomic_long_dec_unchecked(atomic_long_unchecked_t *l)
43842 +{
43843 + atomic_unchecked_t *v = (atomic_unchecked_t *)l;
43844 +
43845 + atomic_dec_unchecked(v);
43846 +}
43847 +#endif
43848 +
43849 static inline void atomic_long_add(long i, atomic_long_t *l)
43850 {
43851 atomic_t *v = (atomic_t *)l;
43852 @@ -176,6 +287,15 @@ static inline void atomic_long_add(long
43853 atomic_add(i, v);
43854 }
43855
43856 +#ifdef CONFIG_PAX_REFCOUNT
43857 +static inline void atomic_long_add_unchecked(long i, atomic_long_unchecked_t *l)
43858 +{
43859 + atomic_unchecked_t *v = (atomic_unchecked_t *)l;
43860 +
43861 + atomic_add_unchecked(i, v);
43862 +}
43863 +#endif
43864 +
43865 static inline void atomic_long_sub(long i, atomic_long_t *l)
43866 {
43867 atomic_t *v = (atomic_t *)l;
43868 @@ -183,6 +303,15 @@ static inline void atomic_long_sub(long
43869 atomic_sub(i, v);
43870 }
43871
43872 +#ifdef CONFIG_PAX_REFCOUNT
43873 +static inline void atomic_long_sub_unchecked(long i, atomic_long_unchecked_t *l)
43874 +{
43875 + atomic_unchecked_t *v = (atomic_unchecked_t *)l;
43876 +
43877 + atomic_sub_unchecked(i, v);
43878 +}
43879 +#endif
43880 +
43881 static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
43882 {
43883 atomic_t *v = (atomic_t *)l;
43884 @@ -232,6 +361,15 @@ static inline long atomic_long_inc_retur
43885 return (long)atomic_inc_return(v);
43886 }
43887
43888 +#ifdef CONFIG_PAX_REFCOUNT
43889 +static inline long atomic_long_inc_return_unchecked(atomic_long_unchecked_t *l)
43890 +{
43891 + atomic_unchecked_t *v = (atomic_unchecked_t *)l;
43892 +
43893 + return (long)atomic_inc_return_unchecked(v);
43894 +}
43895 +#endif
43896 +
43897 static inline long atomic_long_dec_return(atomic_long_t *l)
43898 {
43899 atomic_t *v = (atomic_t *)l;
43900 @@ -255,4 +393,41 @@ static inline long atomic_long_add_unles
43901
43902 #endif /* BITS_PER_LONG == 64 */
43903
43904 +#ifdef CONFIG_PAX_REFCOUNT
43905 +static inline void pax_refcount_needs_these_functions(void)
43906 +{
43907 + atomic_read_unchecked((atomic_unchecked_t *)NULL);
43908 + atomic_set_unchecked((atomic_unchecked_t *)NULL, 0);
43909 + atomic_add_unchecked(0, (atomic_unchecked_t *)NULL);
43910 + atomic_sub_unchecked(0, (atomic_unchecked_t *)NULL);
43911 + atomic_inc_unchecked((atomic_unchecked_t *)NULL);
43912 + atomic_inc_return_unchecked((atomic_unchecked_t *)NULL);
43913 + atomic_add_return_unchecked(0, (atomic_unchecked_t *)NULL);
43914 +
43915 + atomic_long_read_unchecked((atomic_long_unchecked_t *)NULL);
43916 + atomic_long_set_unchecked((atomic_long_unchecked_t *)NULL, 0);
43917 + atomic_long_add_unchecked(0, (atomic_long_unchecked_t *)NULL);
43918 + atomic_long_sub_unchecked(0, (atomic_long_unchecked_t *)NULL);
43919 + atomic_long_inc_unchecked((atomic_long_unchecked_t *)NULL);
43920 + atomic_long_inc_return_unchecked((atomic_long_unchecked_t *)NULL);
43921 + atomic_long_dec_unchecked((atomic_long_unchecked_t *)NULL);
43922 +}
43923 +#else
43924 +#define atomic_read_unchecked(v) atomic_read(v)
43925 +#define atomic_set_unchecked(v, i) atomic_set((v), (i))
43926 +#define atomic_add_unchecked(i, v) atomic_add((i), (v))
43927 +#define atomic_sub_unchecked(i, v) atomic_sub((i), (v))
43928 +#define atomic_inc_unchecked(v) atomic_inc(v)
43929 +#define atomic_inc_return_unchecked(v) atomic_inc_return(v)
43930 +#define atomic_add_return_unchecked(i, v) atomic_add_return((i), (v))
43931 +
43932 +#define atomic_long_read_unchecked(v) atomic_long_read(v)
43933 +#define atomic_long_set_unchecked(v, i) atomic_long_set((v), (i))
43934 +#define atomic_long_add_unchecked(i, v) atomic_long_add((i), (v))
43935 +#define atomic_long_sub_unchecked(i, v) atomic_long_sub((i), (v))
43936 +#define atomic_long_inc_unchecked(v) atomic_long_inc(v)
43937 +#define atomic_long_inc_return_unchecked(v) atomic_long_inc_return(v)
43938 +#define atomic_long_dec_unchecked(v) atomic_long_dec(v)
43939 +#endif
43940 +
43941 #endif /* _ASM_GENERIC_ATOMIC_LONG_H */
43942 diff -urNp linux-2.6.36/include/asm-generic/dma-mapping-common.h linux-2.6.36/include/asm-generic/dma-mapping-common.h
43943 --- linux-2.6.36/include/asm-generic/dma-mapping-common.h 2010-10-20 16:30:22.000000000 -0400
43944 +++ linux-2.6.36/include/asm-generic/dma-mapping-common.h 2010-11-06 18:58:15.000000000 -0400
43945 @@ -11,7 +11,7 @@ static inline dma_addr_t dma_map_single_
43946 enum dma_data_direction dir,
43947 struct dma_attrs *attrs)
43948 {
43949 - struct dma_map_ops *ops = get_dma_ops(dev);
43950 + const struct dma_map_ops *ops = get_dma_ops(dev);
43951 dma_addr_t addr;
43952
43953 kmemcheck_mark_initialized(ptr, size);
43954 @@ -30,7 +30,7 @@ static inline void dma_unmap_single_attr
43955 enum dma_data_direction dir,
43956 struct dma_attrs *attrs)
43957 {
43958 - struct dma_map_ops *ops = get_dma_ops(dev);
43959 + const struct dma_map_ops *ops = get_dma_ops(dev);
43960
43961 BUG_ON(!valid_dma_direction(dir));
43962 if (ops->unmap_page)
43963 @@ -42,7 +42,7 @@ static inline int dma_map_sg_attrs(struc
43964 int nents, enum dma_data_direction dir,
43965 struct dma_attrs *attrs)
43966 {
43967 - struct dma_map_ops *ops = get_dma_ops(dev);
43968 + const struct dma_map_ops *ops = get_dma_ops(dev);
43969 int i, ents;
43970 struct scatterlist *s;
43971
43972 @@ -59,7 +59,7 @@ static inline void dma_unmap_sg_attrs(st
43973 int nents, enum dma_data_direction dir,
43974 struct dma_attrs *attrs)
43975 {
43976 - struct dma_map_ops *ops = get_dma_ops(dev);
43977 + const struct dma_map_ops *ops = get_dma_ops(dev);
43978
43979 BUG_ON(!valid_dma_direction(dir));
43980 debug_dma_unmap_sg(dev, sg, nents, dir);
43981 @@ -71,7 +71,7 @@ static inline dma_addr_t dma_map_page(st
43982 size_t offset, size_t size,
43983 enum dma_data_direction dir)
43984 {
43985 - struct dma_map_ops *ops = get_dma_ops(dev);
43986 + const struct dma_map_ops *ops = get_dma_ops(dev);
43987 dma_addr_t addr;
43988
43989 kmemcheck_mark_initialized(page_address(page) + offset, size);
43990 @@ -85,7 +85,7 @@ static inline dma_addr_t dma_map_page(st
43991 static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
43992 size_t size, enum dma_data_direction dir)
43993 {
43994 - struct dma_map_ops *ops = get_dma_ops(dev);
43995 + const struct dma_map_ops *ops = get_dma_ops(dev);
43996
43997 BUG_ON(!valid_dma_direction(dir));
43998 if (ops->unmap_page)
43999 @@ -97,7 +97,7 @@ static inline void dma_sync_single_for_c
44000 size_t size,
44001 enum dma_data_direction dir)
44002 {
44003 - struct dma_map_ops *ops = get_dma_ops(dev);
44004 + const struct dma_map_ops *ops = get_dma_ops(dev);
44005
44006 BUG_ON(!valid_dma_direction(dir));
44007 if (ops->sync_single_for_cpu)
44008 @@ -109,7 +109,7 @@ static inline void dma_sync_single_for_d
44009 dma_addr_t addr, size_t size,
44010 enum dma_data_direction dir)
44011 {
44012 - struct dma_map_ops *ops = get_dma_ops(dev);
44013 + const struct dma_map_ops *ops = get_dma_ops(dev);
44014
44015 BUG_ON(!valid_dma_direction(dir));
44016 if (ops->sync_single_for_device)
44017 @@ -139,7 +139,7 @@ static inline void
44018 dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
44019 int nelems, enum dma_data_direction dir)
44020 {
44021 - struct dma_map_ops *ops = get_dma_ops(dev);
44022 + const struct dma_map_ops *ops = get_dma_ops(dev);
44023
44024 BUG_ON(!valid_dma_direction(dir));
44025 if (ops->sync_sg_for_cpu)
44026 @@ -151,7 +151,7 @@ static inline void
44027 dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
44028 int nelems, enum dma_data_direction dir)
44029 {
44030 - struct dma_map_ops *ops = get_dma_ops(dev);
44031 + const struct dma_map_ops *ops = get_dma_ops(dev);
44032
44033 BUG_ON(!valid_dma_direction(dir));
44034 if (ops->sync_sg_for_device)
44035 diff -urNp linux-2.6.36/include/asm-generic/futex.h linux-2.6.36/include/asm-generic/futex.h
44036 --- linux-2.6.36/include/asm-generic/futex.h 2010-10-20 16:30:22.000000000 -0400
44037 +++ linux-2.6.36/include/asm-generic/futex.h 2010-11-06 18:58:15.000000000 -0400
44038 @@ -6,7 +6,7 @@
44039 #include <asm/errno.h>
44040
44041 static inline int
44042 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
44043 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
44044 {
44045 int op = (encoded_op >> 28) & 7;
44046 int cmp = (encoded_op >> 24) & 15;
44047 @@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
44048 }
44049
44050 static inline int
44051 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
44052 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
44053 {
44054 return -ENOSYS;
44055 }
44056 diff -urNp linux-2.6.36/include/asm-generic/int-l64.h linux-2.6.36/include/asm-generic/int-l64.h
44057 --- linux-2.6.36/include/asm-generic/int-l64.h 2010-10-20 16:30:22.000000000 -0400
44058 +++ linux-2.6.36/include/asm-generic/int-l64.h 2010-11-06 18:58:15.000000000 -0400
44059 @@ -46,6 +46,8 @@ typedef unsigned int u32;
44060 typedef signed long s64;
44061 typedef unsigned long u64;
44062
44063 +typedef unsigned int intoverflow_t __attribute__ ((mode(TI)));
44064 +
44065 #define S8_C(x) x
44066 #define U8_C(x) x ## U
44067 #define S16_C(x) x
44068 diff -urNp linux-2.6.36/include/asm-generic/int-ll64.h linux-2.6.36/include/asm-generic/int-ll64.h
44069 --- linux-2.6.36/include/asm-generic/int-ll64.h 2010-10-20 16:30:22.000000000 -0400
44070 +++ linux-2.6.36/include/asm-generic/int-ll64.h 2010-11-06 18:58:15.000000000 -0400
44071 @@ -51,6 +51,8 @@ typedef unsigned int u32;
44072 typedef signed long long s64;
44073 typedef unsigned long long u64;
44074
44075 +typedef unsigned long long intoverflow_t;
44076 +
44077 #define S8_C(x) x
44078 #define U8_C(x) x ## U
44079 #define S16_C(x) x
44080 diff -urNp linux-2.6.36/include/asm-generic/kmap_types.h linux-2.6.36/include/asm-generic/kmap_types.h
44081 --- linux-2.6.36/include/asm-generic/kmap_types.h 2010-10-20 16:30:22.000000000 -0400
44082 +++ linux-2.6.36/include/asm-generic/kmap_types.h 2010-11-06 18:58:15.000000000 -0400
44083 @@ -29,10 +29,11 @@ KMAP_D(16) KM_IRQ_PTE,
44084 KMAP_D(17) KM_NMI,
44085 KMAP_D(18) KM_NMI_PTE,
44086 KMAP_D(19) KM_KDB,
44087 +KMAP_D(20) KM_CLEARPAGE,
44088 /*
44089 * Remember to update debug_kmap_atomic() when adding new kmap types!
44090 */
44091 -KMAP_D(20) KM_TYPE_NR
44092 +KMAP_D(21) KM_TYPE_NR
44093 };
44094
44095 #undef KMAP_D
44096 diff -urNp linux-2.6.36/include/asm-generic/pgtable.h linux-2.6.36/include/asm-generic/pgtable.h
44097 --- linux-2.6.36/include/asm-generic/pgtable.h 2010-10-20 16:30:22.000000000 -0400
44098 +++ linux-2.6.36/include/asm-generic/pgtable.h 2010-11-06 18:58:15.000000000 -0400
44099 @@ -344,6 +344,14 @@ extern void untrack_pfn_vma(struct vm_ar
44100 unsigned long size);
44101 #endif
44102
44103 +#ifndef __HAVE_ARCH_PAX_OPEN_KERNEL
44104 +static inline unsigned long pax_open_kernel(void) { return 0; }
44105 +#endif
44106 +
44107 +#ifndef __HAVE_ARCH_PAX_CLOSE_KERNEL
44108 +static inline unsigned long pax_close_kernel(void) { return 0; }
44109 +#endif
44110 +
44111 #endif /* !__ASSEMBLY__ */
44112
44113 #endif /* _ASM_GENERIC_PGTABLE_H */
44114 diff -urNp linux-2.6.36/include/asm-generic/pgtable-nopmd.h linux-2.6.36/include/asm-generic/pgtable-nopmd.h
44115 --- linux-2.6.36/include/asm-generic/pgtable-nopmd.h 2010-10-20 16:30:22.000000000 -0400
44116 +++ linux-2.6.36/include/asm-generic/pgtable-nopmd.h 2010-11-06 18:58:15.000000000 -0400
44117 @@ -1,14 +1,19 @@
44118 #ifndef _PGTABLE_NOPMD_H
44119 #define _PGTABLE_NOPMD_H
44120
44121 -#ifndef __ASSEMBLY__
44122 -
44123 #include <asm-generic/pgtable-nopud.h>
44124
44125 -struct mm_struct;
44126 -
44127 #define __PAGETABLE_PMD_FOLDED
44128
44129 +#define PMD_SHIFT PUD_SHIFT
44130 +#define PTRS_PER_PMD 1
44131 +#define PMD_SIZE (_AC(1,UL) << PMD_SHIFT)
44132 +#define PMD_MASK (~(PMD_SIZE-1))
44133 +
44134 +#ifndef __ASSEMBLY__
44135 +
44136 +struct mm_struct;
44137 +
44138 /*
44139 * Having the pmd type consist of a pud gets the size right, and allows
44140 * us to conceptually access the pud entry that this pmd is folded into
44141 @@ -16,11 +21,6 @@ struct mm_struct;
44142 */
44143 typedef struct { pud_t pud; } pmd_t;
44144
44145 -#define PMD_SHIFT PUD_SHIFT
44146 -#define PTRS_PER_PMD 1
44147 -#define PMD_SIZE (1UL << PMD_SHIFT)
44148 -#define PMD_MASK (~(PMD_SIZE-1))
44149 -
44150 /*
44151 * The "pud_xxx()" functions here are trivial for a folded two-level
44152 * setup: the pmd is never bad, and a pmd always exists (as it's folded
44153 diff -urNp linux-2.6.36/include/asm-generic/pgtable-nopud.h linux-2.6.36/include/asm-generic/pgtable-nopud.h
44154 --- linux-2.6.36/include/asm-generic/pgtable-nopud.h 2010-10-20 16:30:22.000000000 -0400
44155 +++ linux-2.6.36/include/asm-generic/pgtable-nopud.h 2010-11-06 18:58:15.000000000 -0400
44156 @@ -1,10 +1,15 @@
44157 #ifndef _PGTABLE_NOPUD_H
44158 #define _PGTABLE_NOPUD_H
44159
44160 -#ifndef __ASSEMBLY__
44161 -
44162 #define __PAGETABLE_PUD_FOLDED
44163
44164 +#define PUD_SHIFT PGDIR_SHIFT
44165 +#define PTRS_PER_PUD 1
44166 +#define PUD_SIZE (_AC(1,UL) << PUD_SHIFT)
44167 +#define PUD_MASK (~(PUD_SIZE-1))
44168 +
44169 +#ifndef __ASSEMBLY__
44170 +
44171 /*
44172 * Having the pud type consist of a pgd gets the size right, and allows
44173 * us to conceptually access the pgd entry that this pud is folded into
44174 @@ -12,11 +17,6 @@
44175 */
44176 typedef struct { pgd_t pgd; } pud_t;
44177
44178 -#define PUD_SHIFT PGDIR_SHIFT
44179 -#define PTRS_PER_PUD 1
44180 -#define PUD_SIZE (1UL << PUD_SHIFT)
44181 -#define PUD_MASK (~(PUD_SIZE-1))
44182 -
44183 /*
44184 * The "pgd_xxx()" functions here are trivial for a folded two-level
44185 * setup: the pud is never bad, and a pud always exists (as it's folded
44186 diff -urNp linux-2.6.36/include/asm-generic/vmlinux.lds.h linux-2.6.36/include/asm-generic/vmlinux.lds.h
44187 --- linux-2.6.36/include/asm-generic/vmlinux.lds.h 2010-10-20 16:30:22.000000000 -0400
44188 +++ linux-2.6.36/include/asm-generic/vmlinux.lds.h 2010-11-06 18:58:15.000000000 -0400
44189 @@ -209,6 +209,7 @@
44190 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
44191 VMLINUX_SYMBOL(__start_rodata) = .; \
44192 *(.rodata) *(.rodata.*) \
44193 + *(.data..read_only) \
44194 *(__vermagic) /* Kernel version magic */ \
44195 *(__markers_strings) /* Markers: strings */ \
44196 *(__tracepoints_strings)/* Tracepoints: strings */ \
44197 @@ -667,22 +668,24 @@
44198 * section in the linker script will go there too. @phdr should have
44199 * a leading colon.
44200 *
44201 - * Note that this macros defines __per_cpu_load as an absolute symbol.
44202 + * Note that this macros defines per_cpu_load as an absolute symbol.
44203 * If there is no need to put the percpu section at a predetermined
44204 * address, use PERCPU().
44205 */
44206 #define PERCPU_VADDR(vaddr, phdr) \
44207 - VMLINUX_SYMBOL(__per_cpu_load) = .; \
44208 - .data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
44209 + per_cpu_load = .; \
44210 + .data..percpu vaddr : AT(VMLINUX_SYMBOL(per_cpu_load) \
44211 - LOAD_OFFSET) { \
44212 + VMLINUX_SYMBOL(__per_cpu_load) = . + per_cpu_load; \
44213 VMLINUX_SYMBOL(__per_cpu_start) = .; \
44214 *(.data..percpu..first) \
44215 - *(.data..percpu..page_aligned) \
44216 *(.data..percpu) \
44217 + . = ALIGN(PAGE_SIZE); \
44218 + *(.data..percpu..page_aligned) \
44219 *(.data..percpu..shared_aligned) \
44220 VMLINUX_SYMBOL(__per_cpu_end) = .; \
44221 } phdr \
44222 - . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu);
44223 + . = VMLINUX_SYMBOL(per_cpu_load) + SIZEOF(.data..percpu);
44224
44225 /**
44226 * PERCPU - define output section for percpu area, simple version
44227 diff -urNp linux-2.6.36/include/drm/drm_pciids.h linux-2.6.36/include/drm/drm_pciids.h
44228 --- linux-2.6.36/include/drm/drm_pciids.h 2010-10-20 16:30:22.000000000 -0400
44229 +++ linux-2.6.36/include/drm/drm_pciids.h 2010-11-06 18:58:15.000000000 -0400
44230 @@ -419,7 +419,7 @@
44231 {0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
44232 {0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
44233 {0x1002, 0x9715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
44234 - {0, 0, 0}
44235 + {0, 0, 0, 0, 0, 0}
44236
44237 #define r128_PCI_IDS \
44238 {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44239 @@ -459,14 +459,14 @@
44240 {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44241 {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44242 {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44243 - {0, 0, 0}
44244 + {0, 0, 0, 0, 0, 0}
44245
44246 #define mga_PCI_IDS \
44247 {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
44248 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
44249 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
44250 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
44251 - {0, 0, 0}
44252 + {0, 0, 0, 0, 0, 0}
44253
44254 #define mach64_PCI_IDS \
44255 {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44256 @@ -489,7 +489,7 @@
44257 {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44258 {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44259 {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44260 - {0, 0, 0}
44261 + {0, 0, 0, 0, 0, 0}
44262
44263 #define sisdrv_PCI_IDS \
44264 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44265 @@ -500,7 +500,7 @@
44266 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44267 {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
44268 {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
44269 - {0, 0, 0}
44270 + {0, 0, 0, 0, 0, 0}
44271
44272 #define tdfx_PCI_IDS \
44273 {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44274 @@ -509,7 +509,7 @@
44275 {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44276 {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44277 {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44278 - {0, 0, 0}
44279 + {0, 0, 0, 0, 0, 0}
44280
44281 #define viadrv_PCI_IDS \
44282 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44283 @@ -521,14 +521,14 @@
44284 {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44285 {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
44286 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
44287 - {0, 0, 0}
44288 + {0, 0, 0, 0, 0, 0}
44289
44290 #define i810_PCI_IDS \
44291 {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44292 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44293 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44294 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44295 - {0, 0, 0}
44296 + {0, 0, 0, 0, 0, 0}
44297
44298 #define i830_PCI_IDS \
44299 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44300 @@ -536,11 +536,11 @@
44301 {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44302 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44303 {0x8086, 0x358e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44304 - {0, 0, 0}
44305 + {0, 0, 0, 0, 0, 0}
44306
44307 #define gamma_PCI_IDS \
44308 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
44309 - {0, 0, 0}
44310 + {0, 0, 0, 0, 0, 0}
44311
44312 #define savage_PCI_IDS \
44313 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
44314 @@ -566,10 +566,10 @@
44315 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
44316 {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
44317 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
44318 - {0, 0, 0}
44319 + {0, 0, 0, 0, 0, 0}
44320
44321 #define ffb_PCI_IDS \
44322 - {0, 0, 0}
44323 + {0, 0, 0, 0, 0, 0}
44324
44325 #define i915_PCI_IDS \
44326 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
44327 @@ -603,4 +603,4 @@
44328 {0x8086, 0x0042, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
44329 {0x8086, 0x0046, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
44330 {0x8086, 0x0102, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
44331 - {0, 0, 0}
44332 + {0, 0, 0, 0, 0, 0}
44333 diff -urNp linux-2.6.36/include/drm/drmP.h linux-2.6.36/include/drm/drmP.h
44334 --- linux-2.6.36/include/drm/drmP.h 2010-10-20 16:30:22.000000000 -0400
44335 +++ linux-2.6.36/include/drm/drmP.h 2010-11-06 18:58:15.000000000 -0400
44336 @@ -813,7 +813,7 @@ struct drm_driver {
44337 void (*vgaarb_irq)(struct drm_device *dev, bool state);
44338
44339 /* Driver private ops for this object */
44340 - struct vm_operations_struct *gem_vm_ops;
44341 + const struct vm_operations_struct *gem_vm_ops;
44342
44343 int major;
44344 int minor;
44345 @@ -923,7 +923,7 @@ struct drm_device {
44346
44347 /** \name Usage Counters */
44348 /*@{ */
44349 - int open_count; /**< Outstanding files open */
44350 + atomic_t open_count; /**< Outstanding files open */
44351 atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
44352 atomic_t vma_count; /**< Outstanding vma areas open */
44353 int buf_use; /**< Buffers in use -- cannot alloc */
44354 @@ -934,7 +934,7 @@ struct drm_device {
44355 /*@{ */
44356 unsigned long counters;
44357 enum drm_stat_type types[15];
44358 - atomic_t counts[15];
44359 + atomic_unchecked_t counts[15];
44360 /*@} */
44361
44362 struct list_head filelist;
44363 diff -urNp linux-2.6.36/include/linux/a.out.h linux-2.6.36/include/linux/a.out.h
44364 --- linux-2.6.36/include/linux/a.out.h 2010-10-20 16:30:22.000000000 -0400
44365 +++ linux-2.6.36/include/linux/a.out.h 2010-11-06 18:58:15.000000000 -0400
44366 @@ -39,6 +39,14 @@ enum machine_type {
44367 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
44368 };
44369
44370 +/* Constants for the N_FLAGS field */
44371 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
44372 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
44373 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
44374 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
44375 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
44376 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
44377 +
44378 #if !defined (N_MAGIC)
44379 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
44380 #endif
44381 diff -urNp linux-2.6.36/include/linux/atmdev.h linux-2.6.36/include/linux/atmdev.h
44382 --- linux-2.6.36/include/linux/atmdev.h 2010-10-20 16:30:22.000000000 -0400
44383 +++ linux-2.6.36/include/linux/atmdev.h 2010-11-06 18:58:15.000000000 -0400
44384 @@ -237,7 +237,7 @@ struct compat_atm_iobuf {
44385 #endif
44386
44387 struct k_atm_aal_stats {
44388 -#define __HANDLE_ITEM(i) atomic_t i
44389 +#define __HANDLE_ITEM(i) atomic_unchecked_t i
44390 __AAL_STAT_ITEMS
44391 #undef __HANDLE_ITEM
44392 };
44393 diff -urNp linux-2.6.36/include/linux/binfmts.h linux-2.6.36/include/linux/binfmts.h
44394 --- linux-2.6.36/include/linux/binfmts.h 2010-10-20 16:30:22.000000000 -0400
44395 +++ linux-2.6.36/include/linux/binfmts.h 2010-11-06 18:58:15.000000000 -0400
44396 @@ -87,6 +87,7 @@ struct linux_binfmt {
44397 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
44398 int (*load_shlib)(struct file *);
44399 int (*core_dump)(struct coredump_params *cprm);
44400 + void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags);
44401 unsigned long min_coredump; /* minimal dump size */
44402 int hasvdso;
44403 };
44404 diff -urNp linux-2.6.36/include/linux/blkdev.h linux-2.6.36/include/linux/blkdev.h
44405 --- linux-2.6.36/include/linux/blkdev.h 2010-10-20 16:30:22.000000000 -0400
44406 +++ linux-2.6.36/include/linux/blkdev.h 2010-11-06 18:58:15.000000000 -0400
44407 @@ -1249,19 +1249,19 @@ static inline int blk_integrity_rq(struc
44408 #endif /* CONFIG_BLK_DEV_INTEGRITY */
44409
44410 struct block_device_operations {
44411 - int (*open) (struct block_device *, fmode_t);
44412 - int (*release) (struct gendisk *, fmode_t);
44413 - int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
44414 - int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
44415 - int (*direct_access) (struct block_device *, sector_t,
44416 + int (* const open) (struct block_device *, fmode_t);
44417 + int (* const release) (struct gendisk *, fmode_t);
44418 + int (* const ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
44419 + int (* const compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
44420 + int (* const direct_access) (struct block_device *, sector_t,
44421 void **, unsigned long *);
44422 - int (*media_changed) (struct gendisk *);
44423 - void (*unlock_native_capacity) (struct gendisk *);
44424 - int (*revalidate_disk) (struct gendisk *);
44425 - int (*getgeo)(struct block_device *, struct hd_geometry *);
44426 + int (* const media_changed) (struct gendisk *);
44427 + void (* const unlock_native_capacity) (struct gendisk *);
44428 + int (* const revalidate_disk) (struct gendisk *);
44429 + int (* const getgeo)(struct block_device *, struct hd_geometry *);
44430 /* this callback is with swap_lock and sometimes page table lock held */
44431 - void (*swap_slot_free_notify) (struct block_device *, unsigned long);
44432 - struct module *owner;
44433 + void (* const swap_slot_free_notify) (struct block_device *, unsigned long);
44434 + struct module * const owner;
44435 };
44436
44437 extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
44438 diff -urNp linux-2.6.36/include/linux/cache.h linux-2.6.36/include/linux/cache.h
44439 --- linux-2.6.36/include/linux/cache.h 2010-10-20 16:30:22.000000000 -0400
44440 +++ linux-2.6.36/include/linux/cache.h 2010-11-06 18:58:15.000000000 -0400
44441 @@ -16,6 +16,10 @@
44442 #define __read_mostly
44443 #endif
44444
44445 +#ifndef __read_only
44446 +#define __read_only __read_mostly
44447 +#endif
44448 +
44449 #ifndef ____cacheline_aligned
44450 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
44451 #endif
44452 diff -urNp linux-2.6.36/include/linux/capability.h linux-2.6.36/include/linux/capability.h
44453 --- linux-2.6.36/include/linux/capability.h 2010-10-20 16:30:22.000000000 -0400
44454 +++ linux-2.6.36/include/linux/capability.h 2010-11-06 18:58:50.000000000 -0400
44455 @@ -558,6 +558,7 @@ extern const kernel_cap_t __cap_init_eff
44456 (security_real_capable_noaudit((t), (cap)) == 0)
44457
44458 extern int capable(int cap);
44459 +int capable_nolog(int cap);
44460
44461 /* audit system wants to get cap info from files as well */
44462 struct dentry;
44463 diff -urNp linux-2.6.36/include/linux/compiler-gcc4.h linux-2.6.36/include/linux/compiler-gcc4.h
44464 --- linux-2.6.36/include/linux/compiler-gcc4.h 2010-10-20 16:30:22.000000000 -0400
44465 +++ linux-2.6.36/include/linux/compiler-gcc4.h 2010-11-06 18:58:15.000000000 -0400
44466 @@ -54,6 +54,10 @@
44467
44468 #endif
44469
44470 +#define __alloc_size(...) __attribute((alloc_size(__VA_ARGS__)))
44471 +#define __bos(ptr, arg) __builtin_object_size((ptr), (arg))
44472 +#define __bos0(ptr) __bos((ptr), 0)
44473 +#define __bos1(ptr) __bos((ptr), 1)
44474 #endif
44475
44476 #if __GNUC_MINOR__ > 0
44477 diff -urNp linux-2.6.36/include/linux/compiler.h linux-2.6.36/include/linux/compiler.h
44478 --- linux-2.6.36/include/linux/compiler.h 2010-10-20 16:30:22.000000000 -0400
44479 +++ linux-2.6.36/include/linux/compiler.h 2010-11-06 18:58:15.000000000 -0400
44480 @@ -269,6 +269,22 @@ void ftrace_likely_update(struct ftrace_
44481 #define __cold
44482 #endif
44483
44484 +#ifndef __alloc_size
44485 +#define __alloc_size
44486 +#endif
44487 +
44488 +#ifndef __bos
44489 +#define __bos
44490 +#endif
44491 +
44492 +#ifndef __bos0
44493 +#define __bos0
44494 +#endif
44495 +
44496 +#ifndef __bos1
44497 +#define __bos1
44498 +#endif
44499 +
44500 /* Simple shorthand for a section definition */
44501 #ifndef __section
44502 # define __section(S) __attribute__ ((__section__(#S)))
44503 diff -urNp linux-2.6.36/include/linux/decompress/mm.h linux-2.6.36/include/linux/decompress/mm.h
44504 --- linux-2.6.36/include/linux/decompress/mm.h 2010-10-20 16:30:22.000000000 -0400
44505 +++ linux-2.6.36/include/linux/decompress/mm.h 2010-11-06 18:58:15.000000000 -0400
44506 @@ -78,7 +78,7 @@ static void free(void *where)
44507 * warnings when not needed (indeed large_malloc / large_free are not
44508 * needed by inflate */
44509
44510 -#define malloc(a) kmalloc(a, GFP_KERNEL)
44511 +#define malloc(a) kmalloc((a), GFP_KERNEL)
44512 #define free(a) kfree(a)
44513
44514 #define large_malloc(a) vmalloc(a)
44515 diff -urNp linux-2.6.36/include/linux/dma-mapping.h linux-2.6.36/include/linux/dma-mapping.h
44516 --- linux-2.6.36/include/linux/dma-mapping.h 2010-10-20 16:30:22.000000000 -0400
44517 +++ linux-2.6.36/include/linux/dma-mapping.h 2010-11-06 18:58:15.000000000 -0400
44518 @@ -16,40 +16,40 @@ enum dma_data_direction {
44519 };
44520
44521 struct dma_map_ops {
44522 - void* (*alloc_coherent)(struct device *dev, size_t size,
44523 + void* (* const alloc_coherent)(struct device *dev, size_t size,
44524 dma_addr_t *dma_handle, gfp_t gfp);
44525 - void (*free_coherent)(struct device *dev, size_t size,
44526 + void (* const free_coherent)(struct device *dev, size_t size,
44527 void *vaddr, dma_addr_t dma_handle);
44528 - dma_addr_t (*map_page)(struct device *dev, struct page *page,
44529 + dma_addr_t (* const map_page)(struct device *dev, struct page *page,
44530 unsigned long offset, size_t size,
44531 enum dma_data_direction dir,
44532 struct dma_attrs *attrs);
44533 - void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
44534 + void (* const unmap_page)(struct device *dev, dma_addr_t dma_handle,
44535 size_t size, enum dma_data_direction dir,
44536 struct dma_attrs *attrs);
44537 - int (*map_sg)(struct device *dev, struct scatterlist *sg,
44538 + int (* const map_sg)(struct device *dev, struct scatterlist *sg,
44539 int nents, enum dma_data_direction dir,
44540 struct dma_attrs *attrs);
44541 - void (*unmap_sg)(struct device *dev,
44542 + void (* const unmap_sg)(struct device *dev,
44543 struct scatterlist *sg, int nents,
44544 enum dma_data_direction dir,
44545 struct dma_attrs *attrs);
44546 - void (*sync_single_for_cpu)(struct device *dev,
44547 + void (* const sync_single_for_cpu)(struct device *dev,
44548 dma_addr_t dma_handle, size_t size,
44549 enum dma_data_direction dir);
44550 - void (*sync_single_for_device)(struct device *dev,
44551 + void (* const sync_single_for_device)(struct device *dev,
44552 dma_addr_t dma_handle, size_t size,
44553 enum dma_data_direction dir);
44554 - void (*sync_sg_for_cpu)(struct device *dev,
44555 + void (* const sync_sg_for_cpu)(struct device *dev,
44556 struct scatterlist *sg, int nents,
44557 enum dma_data_direction dir);
44558 - void (*sync_sg_for_device)(struct device *dev,
44559 + void (* const sync_sg_for_device)(struct device *dev,
44560 struct scatterlist *sg, int nents,
44561 enum dma_data_direction dir);
44562 - int (*mapping_error)(struct device *dev, dma_addr_t dma_addr);
44563 - int (*dma_supported)(struct device *dev, u64 mask);
44564 - int (*set_dma_mask)(struct device *dev, u64 mask);
44565 - int is_phys;
44566 + int (* const mapping_error)(struct device *dev, dma_addr_t dma_addr);
44567 + int (* const dma_supported)(struct device *dev, u64 mask);
44568 + int (* set_dma_mask)(struct device *dev, u64 mask);
44569 + const int is_phys;
44570 };
44571
44572 #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
44573 diff -urNp linux-2.6.36/include/linux/elf.h linux-2.6.36/include/linux/elf.h
44574 --- linux-2.6.36/include/linux/elf.h 2010-10-20 16:30:22.000000000 -0400
44575 +++ linux-2.6.36/include/linux/elf.h 2010-11-06 18:58:15.000000000 -0400
44576 @@ -49,6 +49,17 @@ typedef __s64 Elf64_Sxword;
44577 #define PT_GNU_EH_FRAME 0x6474e550
44578
44579 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
44580 +#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
44581 +
44582 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
44583 +
44584 +/* Constants for the e_flags field */
44585 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
44586 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
44587 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
44588 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
44589 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
44590 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
44591
44592 /*
44593 * Extended Numbering
44594 @@ -106,6 +117,8 @@ typedef __s64 Elf64_Sxword;
44595 #define DT_DEBUG 21
44596 #define DT_TEXTREL 22
44597 #define DT_JMPREL 23
44598 +#define DT_FLAGS 30
44599 + #define DF_TEXTREL 0x00000004
44600 #define DT_ENCODING 32
44601 #define OLD_DT_LOOS 0x60000000
44602 #define DT_LOOS 0x6000000d
44603 @@ -252,6 +265,19 @@ typedef struct elf64_hdr {
44604 #define PF_W 0x2
44605 #define PF_X 0x1
44606
44607 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
44608 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
44609 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
44610 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
44611 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
44612 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
44613 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
44614 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
44615 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
44616 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
44617 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
44618 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
44619 +
44620 typedef struct elf32_phdr{
44621 Elf32_Word p_type;
44622 Elf32_Off p_offset;
44623 @@ -344,6 +370,8 @@ typedef struct elf64_shdr {
44624 #define EI_OSABI 7
44625 #define EI_PAD 8
44626
44627 +#define EI_PAX 14
44628 +
44629 #define ELFMAG0 0x7f /* EI_MAG */
44630 #define ELFMAG1 'E'
44631 #define ELFMAG2 'L'
44632 @@ -421,6 +449,7 @@ extern Elf32_Dyn _DYNAMIC [];
44633 #define elf_note elf32_note
44634 #define elf_addr_t Elf32_Off
44635 #define Elf_Half Elf32_Half
44636 +#define elf_dyn Elf32_Dyn
44637
44638 #else
44639
44640 @@ -431,6 +460,7 @@ extern Elf64_Dyn _DYNAMIC [];
44641 #define elf_note elf64_note
44642 #define elf_addr_t Elf64_Off
44643 #define Elf_Half Elf64_Half
44644 +#define elf_dyn Elf64_Dyn
44645
44646 #endif
44647
44648 diff -urNp linux-2.6.36/include/linux/fs.h linux-2.6.36/include/linux/fs.h
44649 --- linux-2.6.36/include/linux/fs.h 2010-10-20 16:30:22.000000000 -0400
44650 +++ linux-2.6.36/include/linux/fs.h 2010-11-06 19:01:56.000000000 -0400
44651 @@ -92,6 +92,11 @@ struct inodes_stat_t {
44652 /* Expect random access pattern */
44653 #define FMODE_RANDOM ((__force fmode_t)0x1000)
44654
44655 +/* Hack for grsec so as not to require read permission simply to execute
44656 + * a binary
44657 + */
44658 +#define FMODE_GREXEC ((__force fmode_t)0x2000)
44659 +
44660 /* File was opened by fanotify and shouldn't generate fanotify events */
44661 #define FMODE_NONOTIFY ((__force fmode_t)0x1000000)
44662
44663 @@ -569,41 +574,41 @@ typedef int (*read_actor_t)(read_descrip
44664 unsigned long, unsigned long);
44665
44666 struct address_space_operations {
44667 - int (*writepage)(struct page *page, struct writeback_control *wbc);
44668 - int (*readpage)(struct file *, struct page *);
44669 - void (*sync_page)(struct page *);
44670 + int (* const writepage)(struct page *page, struct writeback_control *wbc);
44671 + int (* const readpage)(struct file *, struct page *);
44672 + void (* const sync_page)(struct page *);
44673
44674 /* Write back some dirty pages from this mapping. */
44675 - int (*writepages)(struct address_space *, struct writeback_control *);
44676 + int (* const writepages)(struct address_space *, struct writeback_control *);
44677
44678 /* Set a page dirty. Return true if this dirtied it */
44679 - int (*set_page_dirty)(struct page *page);
44680 + int (* const set_page_dirty)(struct page *page);
44681
44682 - int (*readpages)(struct file *filp, struct address_space *mapping,
44683 + int (* const readpages)(struct file *filp, struct address_space *mapping,
44684 struct list_head *pages, unsigned nr_pages);
44685
44686 - int (*write_begin)(struct file *, struct address_space *mapping,
44687 + int (* const write_begin)(struct file *, struct address_space *mapping,
44688 loff_t pos, unsigned len, unsigned flags,
44689 struct page **pagep, void **fsdata);
44690 - int (*write_end)(struct file *, struct address_space *mapping,
44691 + int (* const write_end)(struct file *, struct address_space *mapping,
44692 loff_t pos, unsigned len, unsigned copied,
44693 struct page *page, void *fsdata);
44694
44695 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
44696 - sector_t (*bmap)(struct address_space *, sector_t);
44697 - void (*invalidatepage) (struct page *, unsigned long);
44698 - int (*releasepage) (struct page *, gfp_t);
44699 - ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
44700 + sector_t (* const bmap)(struct address_space *, sector_t);
44701 + void (* const invalidatepage) (struct page *, unsigned long);
44702 + int (* const releasepage) (struct page *, gfp_t);
44703 + ssize_t (* const direct_IO)(int, struct kiocb *, const struct iovec *iov,
44704 loff_t offset, unsigned long nr_segs);
44705 - int (*get_xip_mem)(struct address_space *, pgoff_t, int,
44706 + int (* const get_xip_mem)(struct address_space *, pgoff_t, int,
44707 void **, unsigned long *);
44708 /* migrate the contents of a page to the specified target */
44709 - int (*migratepage) (struct address_space *,
44710 + int (* const migratepage) (struct address_space *,
44711 struct page *, struct page *);
44712 - int (*launder_page) (struct page *);
44713 - int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
44714 + int (* const launder_page) (struct page *);
44715 + int (* const is_partially_uptodate) (struct page *, read_descriptor_t *,
44716 unsigned long);
44717 - int (*error_remove_page)(struct address_space *, struct page *);
44718 + int (* const error_remove_page)(struct address_space *, struct page *);
44719 };
44720
44721 /*
44722 @@ -1029,19 +1034,19 @@ static inline int file_check_writeable(s
44723 typedef struct files_struct *fl_owner_t;
44724
44725 struct file_lock_operations {
44726 - void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
44727 - void (*fl_release_private)(struct file_lock *);
44728 + void (* const fl_copy_lock)(struct file_lock *, struct file_lock *);
44729 + void (* const fl_release_private)(struct file_lock *);
44730 };
44731
44732 struct lock_manager_operations {
44733 - int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
44734 - void (*fl_notify)(struct file_lock *); /* unblock callback */
44735 - int (*fl_grant)(struct file_lock *, struct file_lock *, int);
44736 - void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
44737 - void (*fl_release_private)(struct file_lock *);
44738 - void (*fl_break)(struct file_lock *);
44739 - int (*fl_mylease)(struct file_lock *, struct file_lock *);
44740 - int (*fl_change)(struct file_lock **, int);
44741 + int (* const fl_compare_owner)(struct file_lock *, struct file_lock *);
44742 + void (* const fl_notify)(struct file_lock *); /* unblock callback */
44743 + int (* const fl_grant)(struct file_lock *, struct file_lock *, int);
44744 + void (* const fl_copy_lock)(struct file_lock *, struct file_lock *);
44745 + void (* const fl_release_private)(struct file_lock *);
44746 + void (* const fl_break)(struct file_lock *);
44747 + int (* const fl_mylease)(struct file_lock *, struct file_lock *);
44748 + int (* const fl_change)(struct file_lock **, int);
44749 };
44750
44751 struct lock_manager {
44752 @@ -1442,7 +1447,7 @@ struct fiemap_extent_info {
44753 unsigned int fi_flags; /* Flags as passed from user */
44754 unsigned int fi_extents_mapped; /* Number of mapped extents */
44755 unsigned int fi_extents_max; /* Size of fiemap_extent array */
44756 - struct fiemap_extent *fi_extents_start; /* Start of fiemap_extent
44757 + struct fiemap_extent __user *fi_extents_start; /* Start of fiemap_extent
44758 * array */
44759 };
44760 int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
44761 @@ -1558,29 +1563,29 @@ extern ssize_t vfs_writev(struct file *,
44762 unsigned long, loff_t *);
44763
44764 struct super_operations {
44765 - struct inode *(*alloc_inode)(struct super_block *sb);
44766 - void (*destroy_inode)(struct inode *);
44767 + struct inode *(* const alloc_inode)(struct super_block *sb);
44768 + void (* const destroy_inode)(struct inode *);
44769
44770 - void (*dirty_inode) (struct inode *);
44771 - int (*write_inode) (struct inode *, struct writeback_control *wbc);
44772 - int (*drop_inode) (struct inode *);
44773 - void (*evict_inode) (struct inode *);
44774 - void (*put_super) (struct super_block *);
44775 - void (*write_super) (struct super_block *);
44776 - int (*sync_fs)(struct super_block *sb, int wait);
44777 - int (*freeze_fs) (struct super_block *);
44778 - int (*unfreeze_fs) (struct super_block *);
44779 - int (*statfs) (struct dentry *, struct kstatfs *);
44780 - int (*remount_fs) (struct super_block *, int *, char *);
44781 - void (*umount_begin) (struct super_block *);
44782 + void (* const dirty_inode) (struct inode *);
44783 + int (* const write_inode) (struct inode *, struct writeback_control *wbc);
44784 + int (* const drop_inode) (struct inode *);
44785 + void (* const evict_inode) (struct inode *);
44786 + void (* const put_super) (struct super_block *);
44787 + void (* const write_super) (struct super_block *);
44788 + int (* const sync_fs)(struct super_block *sb, int wait);
44789 + int (* const freeze_fs) (struct super_block *);
44790 + int (* const unfreeze_fs) (struct super_block *);
44791 + int (* const statfs) (struct dentry *, struct kstatfs *);
44792 + int (* const remount_fs) (struct super_block *, int *, char *);
44793 + void (* const umount_begin) (struct super_block *);
44794
44795 - int (*show_options)(struct seq_file *, struct vfsmount *);
44796 - int (*show_stats)(struct seq_file *, struct vfsmount *);
44797 + int (* const show_options)(struct seq_file *, struct vfsmount *);
44798 + int (* const show_stats)(struct seq_file *, struct vfsmount *);
44799 #ifdef CONFIG_QUOTA
44800 - ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
44801 - ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
44802 + ssize_t (* const quota_read)(struct super_block *, int, char *, size_t, loff_t);
44803 + ssize_t (* const quota_write)(struct super_block *, int, const char *, size_t, loff_t);
44804 #endif
44805 - int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
44806 + int (* const bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
44807 };
44808
44809 /*
44810 diff -urNp linux-2.6.36/include/linux/fs_struct.h linux-2.6.36/include/linux/fs_struct.h
44811 --- linux-2.6.36/include/linux/fs_struct.h 2010-10-20 16:30:22.000000000 -0400
44812 +++ linux-2.6.36/include/linux/fs_struct.h 2010-11-06 18:58:15.000000000 -0400
44813 @@ -4,7 +4,7 @@
44814 #include <linux/path.h>
44815
44816 struct fs_struct {
44817 - int users;
44818 + atomic_t users;
44819 spinlock_t lock;
44820 int umask;
44821 int in_exec;
44822 diff -urNp linux-2.6.36/include/linux/genhd.h linux-2.6.36/include/linux/genhd.h
44823 --- linux-2.6.36/include/linux/genhd.h 2010-10-20 16:30:22.000000000 -0400
44824 +++ linux-2.6.36/include/linux/genhd.h 2010-11-06 18:58:15.000000000 -0400
44825 @@ -162,7 +162,7 @@ struct gendisk {
44826
44827 struct timer_rand_state *random;
44828
44829 - atomic_t sync_io; /* RAID */
44830 + atomic_unchecked_t sync_io; /* RAID */
44831 struct work_struct async_notify;
44832 #ifdef CONFIG_BLK_DEV_INTEGRITY
44833 struct blk_integrity *integrity;
44834 diff -urNp linux-2.6.36/include/linux/gracl.h linux-2.6.36/include/linux/gracl.h
44835 --- linux-2.6.36/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
44836 +++ linux-2.6.36/include/linux/gracl.h 2010-11-06 18:58:50.000000000 -0400
44837 @@ -0,0 +1,310 @@
44838 +#ifndef GR_ACL_H
44839 +#define GR_ACL_H
44840 +
44841 +#include <linux/grdefs.h>
44842 +#include <linux/resource.h>
44843 +#include <linux/capability.h>
44844 +#include <linux/dcache.h>
44845 +#include <asm/resource.h>
44846 +
44847 +/* Major status information */
44848 +
44849 +#define GR_VERSION "grsecurity 2.2.0"
44850 +#define GRSECURITY_VERSION 0x2200
44851 +
44852 +enum {
44853 + GR_SHUTDOWN = 0,
44854 + GR_ENABLE = 1,
44855 + GR_SPROLE = 2,
44856 + GR_RELOAD = 3,
44857 + GR_SEGVMOD = 4,
44858 + GR_STATUS = 5,
44859 + GR_UNSPROLE = 6,
44860 + GR_PASSSET = 7,
44861 + GR_SPROLEPAM = 8,
44862 +};
44863 +
44864 +/* Password setup definitions
44865 + * kernel/grhash.c */
44866 +enum {
44867 + GR_PW_LEN = 128,
44868 + GR_SALT_LEN = 16,
44869 + GR_SHA_LEN = 32,
44870 +};
44871 +
44872 +enum {
44873 + GR_SPROLE_LEN = 64,
44874 +};
44875 +
44876 +#define GR_NLIMITS 32
44877 +
44878 +/* Begin Data Structures */
44879 +
44880 +struct sprole_pw {
44881 + unsigned char *rolename;
44882 + unsigned char salt[GR_SALT_LEN];
44883 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
44884 +};
44885 +
44886 +struct name_entry {
44887 + __u32 key;
44888 + ino_t inode;
44889 + dev_t device;
44890 + char *name;
44891 + __u16 len;
44892 + __u8 deleted;
44893 + struct name_entry *prev;
44894 + struct name_entry *next;
44895 +};
44896 +
44897 +struct inodev_entry {
44898 + struct name_entry *nentry;
44899 + struct inodev_entry *prev;
44900 + struct inodev_entry *next;
44901 +};
44902 +
44903 +struct acl_role_db {
44904 + struct acl_role_label **r_hash;
44905 + __u32 r_size;
44906 +};
44907 +
44908 +struct inodev_db {
44909 + struct inodev_entry **i_hash;
44910 + __u32 i_size;
44911 +};
44912 +
44913 +struct name_db {
44914 + struct name_entry **n_hash;
44915 + __u32 n_size;
44916 +};
44917 +
44918 +struct crash_uid {
44919 + uid_t uid;
44920 + unsigned long expires;
44921 +};
44922 +
44923 +struct gr_hash_struct {
44924 + void **table;
44925 + void **nametable;
44926 + void *first;
44927 + __u32 table_size;
44928 + __u32 used_size;
44929 + int type;
44930 +};
44931 +
44932 +/* Userspace Grsecurity ACL data structures */
44933 +
44934 +struct acl_subject_label {
44935 + char *filename;
44936 + ino_t inode;
44937 + dev_t device;
44938 + __u32 mode;
44939 + kernel_cap_t cap_mask;
44940 + kernel_cap_t cap_lower;
44941 + kernel_cap_t cap_invert_audit;
44942 +
44943 + struct rlimit res[GR_NLIMITS];
44944 + __u32 resmask;
44945 +
44946 + __u8 user_trans_type;
44947 + __u8 group_trans_type;
44948 + uid_t *user_transitions;
44949 + gid_t *group_transitions;
44950 + __u16 user_trans_num;
44951 + __u16 group_trans_num;
44952 +
44953 + __u32 ip_proto[8];
44954 + __u32 ip_type;
44955 + struct acl_ip_label **ips;
44956 + __u32 ip_num;
44957 + __u32 inaddr_any_override;
44958 +
44959 + __u32 crashes;
44960 + unsigned long expires;
44961 +
44962 + struct acl_subject_label *parent_subject;
44963 + struct gr_hash_struct *hash;
44964 + struct acl_subject_label *prev;
44965 + struct acl_subject_label *next;
44966 +
44967 + struct acl_object_label **obj_hash;
44968 + __u32 obj_hash_size;
44969 + __u16 pax_flags;
44970 +};
44971 +
44972 +struct role_allowed_ip {
44973 + __u32 addr;
44974 + __u32 netmask;
44975 +
44976 + struct role_allowed_ip *prev;
44977 + struct role_allowed_ip *next;
44978 +};
44979 +
44980 +struct role_transition {
44981 + char *rolename;
44982 +
44983 + struct role_transition *prev;
44984 + struct role_transition *next;
44985 +};
44986 +
44987 +struct acl_role_label {
44988 + char *rolename;
44989 + uid_t uidgid;
44990 + __u16 roletype;
44991 +
44992 + __u16 auth_attempts;
44993 + unsigned long expires;
44994 +
44995 + struct acl_subject_label *root_label;
44996 + struct gr_hash_struct *hash;
44997 +
44998 + struct acl_role_label *prev;
44999 + struct acl_role_label *next;
45000 +
45001 + struct role_transition *transitions;
45002 + struct role_allowed_ip *allowed_ips;
45003 + uid_t *domain_children;
45004 + __u16 domain_child_num;
45005 +
45006 + struct acl_subject_label **subj_hash;
45007 + __u32 subj_hash_size;
45008 +};
45009 +
45010 +struct user_acl_role_db {
45011 + struct acl_role_label **r_table;
45012 + __u32 num_pointers; /* Number of allocations to track */
45013 + __u32 num_roles; /* Number of roles */
45014 + __u32 num_domain_children; /* Number of domain children */
45015 + __u32 num_subjects; /* Number of subjects */
45016 + __u32 num_objects; /* Number of objects */
45017 +};
45018 +
45019 +struct acl_object_label {
45020 + char *filename;
45021 + ino_t inode;
45022 + dev_t device;
45023 + __u32 mode;
45024 +
45025 + struct acl_subject_label *nested;
45026 + struct acl_object_label *globbed;
45027 +
45028 + /* next two structures not used */
45029 +
45030 + struct acl_object_label *prev;
45031 + struct acl_object_label *next;
45032 +};
45033 +
45034 +struct acl_ip_label {
45035 + char *iface;
45036 + __u32 addr;
45037 + __u32 netmask;
45038 + __u16 low, high;
45039 + __u8 mode;
45040 + __u32 type;
45041 + __u32 proto[8];
45042 +
45043 + /* next two structures not used */
45044 +
45045 + struct acl_ip_label *prev;
45046 + struct acl_ip_label *next;
45047 +};
45048 +
45049 +struct gr_arg {
45050 + struct user_acl_role_db role_db;
45051 + unsigned char pw[GR_PW_LEN];
45052 + unsigned char salt[GR_SALT_LEN];
45053 + unsigned char sum[GR_SHA_LEN];
45054 + unsigned char sp_role[GR_SPROLE_LEN];
45055 + struct sprole_pw *sprole_pws;
45056 + dev_t segv_device;
45057 + ino_t segv_inode;
45058 + uid_t segv_uid;
45059 + __u16 num_sprole_pws;
45060 + __u16 mode;
45061 +};
45062 +
45063 +struct gr_arg_wrapper {
45064 + struct gr_arg *arg;
45065 + __u32 version;
45066 + __u32 size;
45067 +};
45068 +
45069 +struct subject_map {
45070 + struct acl_subject_label *user;
45071 + struct acl_subject_label *kernel;
45072 + struct subject_map *prev;
45073 + struct subject_map *next;
45074 +};
45075 +
45076 +struct acl_subj_map_db {
45077 + struct subject_map **s_hash;
45078 + __u32 s_size;
45079 +};
45080 +
45081 +/* End Data Structures Section */
45082 +
45083 +/* Hash functions generated by empirical testing by Brad Spengler
45084 + Makes good use of the low bits of the inode. Generally 0-1 times
45085 + in loop for successful match. 0-3 for unsuccessful match.
45086 + Shift/add algorithm with modulus of table size and an XOR*/
45087 +
45088 +static __inline__ unsigned int
45089 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
45090 +{
45091 + return ((((uid + type) << (16 + type)) ^ uid) % sz);
45092 +}
45093 +
45094 + static __inline__ unsigned int
45095 +shash(const struct acl_subject_label *userp, const unsigned int sz)
45096 +{
45097 + return ((const unsigned long)userp % sz);
45098 +}
45099 +
45100 +static __inline__ unsigned int
45101 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
45102 +{
45103 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
45104 +}
45105 +
45106 +static __inline__ unsigned int
45107 +nhash(const char *name, const __u16 len, const unsigned int sz)
45108 +{
45109 + return full_name_hash((const unsigned char *)name, len) % sz;
45110 +}
45111 +
45112 +#define FOR_EACH_ROLE_START(role) \
45113 + role = role_list; \
45114 + while (role) {
45115 +
45116 +#define FOR_EACH_ROLE_END(role) \
45117 + role = role->prev; \
45118 + }
45119 +
45120 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
45121 + subj = NULL; \
45122 + iter = 0; \
45123 + while (iter < role->subj_hash_size) { \
45124 + if (subj == NULL) \
45125 + subj = role->subj_hash[iter]; \
45126 + if (subj == NULL) { \
45127 + iter++; \
45128 + continue; \
45129 + }
45130 +
45131 +#define FOR_EACH_SUBJECT_END(subj,iter) \
45132 + subj = subj->next; \
45133 + if (subj == NULL) \
45134 + iter++; \
45135 + }
45136 +
45137 +
45138 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
45139 + subj = role->hash->first; \
45140 + while (subj != NULL) {
45141 +
45142 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
45143 + subj = subj->next; \
45144 + }
45145 +
45146 +#endif
45147 +
45148 diff -urNp linux-2.6.36/include/linux/gralloc.h linux-2.6.36/include/linux/gralloc.h
45149 --- linux-2.6.36/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
45150 +++ linux-2.6.36/include/linux/gralloc.h 2010-11-06 18:58:50.000000000 -0400
45151 @@ -0,0 +1,9 @@
45152 +#ifndef __GRALLOC_H
45153 +#define __GRALLOC_H
45154 +
45155 +void acl_free_all(void);
45156 +int acl_alloc_stack_init(unsigned long size);
45157 +void *acl_alloc(unsigned long len);
45158 +void *acl_alloc_num(unsigned long num, unsigned long len);
45159 +
45160 +#endif
45161 diff -urNp linux-2.6.36/include/linux/grdefs.h linux-2.6.36/include/linux/grdefs.h
45162 --- linux-2.6.36/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
45163 +++ linux-2.6.36/include/linux/grdefs.h 2010-11-06 18:58:50.000000000 -0400
45164 @@ -0,0 +1,136 @@
45165 +#ifndef GRDEFS_H
45166 +#define GRDEFS_H
45167 +
45168 +/* Begin grsecurity status declarations */
45169 +
45170 +enum {
45171 + GR_READY = 0x01,
45172 + GR_STATUS_INIT = 0x00 // disabled state
45173 +};
45174 +
45175 +/* Begin ACL declarations */
45176 +
45177 +/* Role flags */
45178 +
45179 +enum {
45180 + GR_ROLE_USER = 0x0001,
45181 + GR_ROLE_GROUP = 0x0002,
45182 + GR_ROLE_DEFAULT = 0x0004,
45183 + GR_ROLE_SPECIAL = 0x0008,
45184 + GR_ROLE_AUTH = 0x0010,
45185 + GR_ROLE_NOPW = 0x0020,
45186 + GR_ROLE_GOD = 0x0040,
45187 + GR_ROLE_LEARN = 0x0080,
45188 + GR_ROLE_TPE = 0x0100,
45189 + GR_ROLE_DOMAIN = 0x0200,
45190 + GR_ROLE_PAM = 0x0400
45191 +};
45192 +
45193 +/* ACL Subject and Object mode flags */
45194 +enum {
45195 + GR_DELETED = 0x80000000
45196 +};
45197 +
45198 +/* ACL Object-only mode flags */
45199 +enum {
45200 + GR_READ = 0x00000001,
45201 + GR_APPEND = 0x00000002,
45202 + GR_WRITE = 0x00000004,
45203 + GR_EXEC = 0x00000008,
45204 + GR_FIND = 0x00000010,
45205 + GR_INHERIT = 0x00000020,
45206 + GR_SETID = 0x00000040,
45207 + GR_CREATE = 0x00000080,
45208 + GR_DELETE = 0x00000100,
45209 + GR_LINK = 0x00000200,
45210 + GR_AUDIT_READ = 0x00000400,
45211 + GR_AUDIT_APPEND = 0x00000800,
45212 + GR_AUDIT_WRITE = 0x00001000,
45213 + GR_AUDIT_EXEC = 0x00002000,
45214 + GR_AUDIT_FIND = 0x00004000,
45215 + GR_AUDIT_INHERIT= 0x00008000,
45216 + GR_AUDIT_SETID = 0x00010000,
45217 + GR_AUDIT_CREATE = 0x00020000,
45218 + GR_AUDIT_DELETE = 0x00040000,
45219 + GR_AUDIT_LINK = 0x00080000,
45220 + GR_PTRACERD = 0x00100000,
45221 + GR_NOPTRACE = 0x00200000,
45222 + GR_SUPPRESS = 0x00400000,
45223 + GR_NOLEARN = 0x00800000
45224 +};
45225 +
45226 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
45227 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
45228 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
45229 +
45230 +/* ACL subject-only mode flags */
45231 +enum {
45232 + GR_KILL = 0x00000001,
45233 + GR_VIEW = 0x00000002,
45234 + GR_PROTECTED = 0x00000004,
45235 + GR_LEARN = 0x00000008,
45236 + GR_OVERRIDE = 0x00000010,
45237 + /* just a placeholder, this mode is only used in userspace */
45238 + GR_DUMMY = 0x00000020,
45239 + GR_PROTSHM = 0x00000040,
45240 + GR_KILLPROC = 0x00000080,
45241 + GR_KILLIPPROC = 0x00000100,
45242 + /* just a placeholder, this mode is only used in userspace */
45243 + GR_NOTROJAN = 0x00000200,
45244 + GR_PROTPROCFD = 0x00000400,
45245 + GR_PROCACCT = 0x00000800,
45246 + GR_RELAXPTRACE = 0x00001000,
45247 + GR_NESTED = 0x00002000,
45248 + GR_INHERITLEARN = 0x00004000,
45249 + GR_PROCFIND = 0x00008000,
45250 + GR_POVERRIDE = 0x00010000,
45251 + GR_KERNELAUTH = 0x00020000,
45252 +};
45253 +
45254 +enum {
45255 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
45256 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
45257 + GR_PAX_ENABLE_MPROTECT = 0x0004,
45258 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
45259 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
45260 + GR_PAX_DISABLE_SEGMEXEC = 0x0100,
45261 + GR_PAX_DISABLE_PAGEEXEC = 0x0200,
45262 + GR_PAX_DISABLE_MPROTECT = 0x0400,
45263 + GR_PAX_DISABLE_RANDMMAP = 0x0800,
45264 + GR_PAX_DISABLE_EMUTRAMP = 0x1000,
45265 +};
45266 +
45267 +enum {
45268 + GR_ID_USER = 0x01,
45269 + GR_ID_GROUP = 0x02,
45270 +};
45271 +
45272 +enum {
45273 + GR_ID_ALLOW = 0x01,
45274 + GR_ID_DENY = 0x02,
45275 +};
45276 +
45277 +#define GR_CRASH_RES 31
45278 +#define GR_UIDTABLE_MAX 500
45279 +
45280 +/* begin resource learning section */
45281 +enum {
45282 + GR_RLIM_CPU_BUMP = 60,
45283 + GR_RLIM_FSIZE_BUMP = 50000,
45284 + GR_RLIM_DATA_BUMP = 10000,
45285 + GR_RLIM_STACK_BUMP = 1000,
45286 + GR_RLIM_CORE_BUMP = 10000,
45287 + GR_RLIM_RSS_BUMP = 500000,
45288 + GR_RLIM_NPROC_BUMP = 1,
45289 + GR_RLIM_NOFILE_BUMP = 5,
45290 + GR_RLIM_MEMLOCK_BUMP = 50000,
45291 + GR_RLIM_AS_BUMP = 500000,
45292 + GR_RLIM_LOCKS_BUMP = 2,
45293 + GR_RLIM_SIGPENDING_BUMP = 5,
45294 + GR_RLIM_MSGQUEUE_BUMP = 10000,
45295 + GR_RLIM_NICE_BUMP = 1,
45296 + GR_RLIM_RTPRIO_BUMP = 1,
45297 + GR_RLIM_RTTIME_BUMP = 1000000
45298 +};
45299 +
45300 +#endif
45301 diff -urNp linux-2.6.36/include/linux/grinternal.h linux-2.6.36/include/linux/grinternal.h
45302 --- linux-2.6.36/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
45303 +++ linux-2.6.36/include/linux/grinternal.h 2010-11-06 18:58:50.000000000 -0400
45304 @@ -0,0 +1,214 @@
45305 +#ifndef __GRINTERNAL_H
45306 +#define __GRINTERNAL_H
45307 +
45308 +#ifdef CONFIG_GRKERNSEC
45309 +
45310 +#include <linux/fs.h>
45311 +#include <linux/mnt_namespace.h>
45312 +#include <linux/nsproxy.h>
45313 +#include <linux/gracl.h>
45314 +#include <linux/grdefs.h>
45315 +#include <linux/grmsg.h>
45316 +
45317 +void gr_add_learn_entry(const char *fmt, ...)
45318 + __attribute__ ((format (printf, 1, 2)));
45319 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
45320 + const struct vfsmount *mnt);
45321 +__u32 gr_check_create(const struct dentry *new_dentry,
45322 + const struct dentry *parent,
45323 + const struct vfsmount *mnt, const __u32 mode);
45324 +int gr_check_protected_task(const struct task_struct *task);
45325 +__u32 to_gr_audit(const __u32 reqmode);
45326 +int gr_set_acls(const int type);
45327 +
45328 +int gr_acl_is_enabled(void);
45329 +char gr_roletype_to_char(void);
45330 +
45331 +void gr_handle_alertkill(struct task_struct *task);
45332 +char *gr_to_filename(const struct dentry *dentry,
45333 + const struct vfsmount *mnt);
45334 +char *gr_to_filename1(const struct dentry *dentry,
45335 + const struct vfsmount *mnt);
45336 +char *gr_to_filename2(const struct dentry *dentry,
45337 + const struct vfsmount *mnt);
45338 +char *gr_to_filename3(const struct dentry *dentry,
45339 + const struct vfsmount *mnt);
45340 +
45341 +extern int grsec_enable_harden_ptrace;
45342 +extern int grsec_enable_link;
45343 +extern int grsec_enable_fifo;
45344 +extern int grsec_enable_execve;
45345 +extern int grsec_enable_shm;
45346 +extern int grsec_enable_execlog;
45347 +extern int grsec_enable_signal;
45348 +extern int grsec_enable_audit_ptrace;
45349 +extern int grsec_enable_forkfail;
45350 +extern int grsec_enable_time;
45351 +extern int grsec_enable_rofs;
45352 +extern int grsec_enable_chroot_shmat;
45353 +extern int grsec_enable_chroot_findtask;
45354 +extern int grsec_enable_chroot_mount;
45355 +extern int grsec_enable_chroot_double;
45356 +extern int grsec_enable_chroot_pivot;
45357 +extern int grsec_enable_chroot_chdir;
45358 +extern int grsec_enable_chroot_chmod;
45359 +extern int grsec_enable_chroot_mknod;
45360 +extern int grsec_enable_chroot_fchdir;
45361 +extern int grsec_enable_chroot_nice;
45362 +extern int grsec_enable_chroot_execlog;
45363 +extern int grsec_enable_chroot_caps;
45364 +extern int grsec_enable_chroot_sysctl;
45365 +extern int grsec_enable_chroot_unix;
45366 +extern int grsec_enable_tpe;
45367 +extern int grsec_tpe_gid;
45368 +extern int grsec_enable_tpe_all;
45369 +extern int grsec_enable_tpe_invert;
45370 +extern int grsec_enable_socket_all;
45371 +extern int grsec_socket_all_gid;
45372 +extern int grsec_enable_socket_client;
45373 +extern int grsec_socket_client_gid;
45374 +extern int grsec_enable_socket_server;
45375 +extern int grsec_socket_server_gid;
45376 +extern int grsec_audit_gid;
45377 +extern int grsec_enable_group;
45378 +extern int grsec_enable_audit_textrel;
45379 +extern int grsec_enable_log_rwxmaps;
45380 +extern int grsec_enable_mount;
45381 +extern int grsec_enable_chdir;
45382 +extern int grsec_resource_logging;
45383 +extern int grsec_enable_blackhole;
45384 +extern int grsec_lastack_retries;
45385 +extern int grsec_lock;
45386 +
45387 +extern spinlock_t grsec_alert_lock;
45388 +extern unsigned long grsec_alert_wtime;
45389 +extern unsigned long grsec_alert_fyet;
45390 +
45391 +extern spinlock_t grsec_audit_lock;
45392 +
45393 +extern rwlock_t grsec_exec_file_lock;
45394 +
45395 +#define gr_task_fullpath(tsk) ((tsk)->exec_file ? \
45396 + gr_to_filename2((tsk)->exec_file->f_path.dentry, \
45397 + (tsk)->exec_file->f_vfsmnt) : "/")
45398 +
45399 +#define gr_parent_task_fullpath(tsk) ((tsk)->real_parent->exec_file ? \
45400 + gr_to_filename3((tsk)->real_parent->exec_file->f_path.dentry, \
45401 + (tsk)->real_parent->exec_file->f_vfsmnt) : "/")
45402 +
45403 +#define gr_task_fullpath0(tsk) ((tsk)->exec_file ? \
45404 + gr_to_filename((tsk)->exec_file->f_path.dentry, \
45405 + (tsk)->exec_file->f_vfsmnt) : "/")
45406 +
45407 +#define gr_parent_task_fullpath0(tsk) ((tsk)->real_parent->exec_file ? \
45408 + gr_to_filename1((tsk)->real_parent->exec_file->f_path.dentry, \
45409 + (tsk)->real_parent->exec_file->f_vfsmnt) : "/")
45410 +
45411 +#define proc_is_chrooted(tsk_a) ((tsk_a)->gr_is_chrooted)
45412 +
45413 +#define have_same_root(tsk_a,tsk_b) ((tsk_a)->gr_chroot_dentry == (tsk_b)->gr_chroot_dentry)
45414 +
45415 +#define DEFAULTSECARGS(task, cred, pcred) gr_task_fullpath(task), (task)->comm, \
45416 + (task)->pid, (cred)->uid, \
45417 + (cred)->euid, (cred)->gid, (cred)->egid, \
45418 + gr_parent_task_fullpath(task), \
45419 + (task)->real_parent->comm, (task)->real_parent->pid, \
45420 + (pcred)->uid, (pcred)->euid, \
45421 + (pcred)->gid, (pcred)->egid
45422 +
45423 +#define GR_CHROOT_CAPS {{ \
45424 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
45425 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
45426 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
45427 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
45428 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
45429 + CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
45430 +
45431 +#define security_learn(normal_msg,args...) \
45432 +({ \
45433 + read_lock(&grsec_exec_file_lock); \
45434 + gr_add_learn_entry(normal_msg "\n", ## args); \
45435 + read_unlock(&grsec_exec_file_lock); \
45436 +})
45437 +
45438 +enum {
45439 + GR_DO_AUDIT,
45440 + GR_DONT_AUDIT,
45441 + GR_DONT_AUDIT_GOOD
45442 +};
45443 +
45444 +enum {
45445 + GR_TTYSNIFF,
45446 + GR_RBAC,
45447 + GR_RBAC_STR,
45448 + GR_STR_RBAC,
45449 + GR_RBAC_MODE2,
45450 + GR_RBAC_MODE3,
45451 + GR_FILENAME,
45452 + GR_SYSCTL_HIDDEN,
45453 + GR_NOARGS,
45454 + GR_ONE_INT,
45455 + GR_ONE_INT_TWO_STR,
45456 + GR_ONE_STR,
45457 + GR_STR_INT,
45458 + GR_TWO_INT,
45459 + GR_THREE_INT,
45460 + GR_FIVE_INT_TWO_STR,
45461 + GR_TWO_STR,
45462 + GR_THREE_STR,
45463 + GR_FOUR_STR,
45464 + GR_STR_FILENAME,
45465 + GR_FILENAME_STR,
45466 + GR_FILENAME_TWO_INT,
45467 + GR_FILENAME_TWO_INT_STR,
45468 + GR_TEXTREL,
45469 + GR_PTRACE,
45470 + GR_RESOURCE,
45471 + GR_CAP,
45472 + GR_SIG,
45473 + GR_SIG2,
45474 + GR_CRASH1,
45475 + GR_CRASH2,
45476 + GR_PSACCT,
45477 + GR_RWXMAP
45478 +};
45479 +
45480 +#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
45481 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
45482 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
45483 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
45484 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
45485 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
45486 +#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)
45487 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
45488 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
45489 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
45490 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
45491 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
45492 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
45493 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
45494 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
45495 +#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)
45496 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
45497 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
45498 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
45499 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
45500 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
45501 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
45502 +#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)
45503 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
45504 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
45505 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
45506 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
45507 +#define gr_log_sig_addr(audit, msg, str, addr) gr_log_varargs(audit, msg, GR_SIG, str, addr)
45508 +#define gr_log_sig_task(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG2, task, num)
45509 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
45510 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
45511 +#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)
45512 +#define gr_log_rwxmap(audit, msg, str) gr_log_varargs(audit, msg, GR_RWXMAP, str)
45513 +
45514 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
45515 +
45516 +#endif
45517 +
45518 +#endif
45519 diff -urNp linux-2.6.36/include/linux/grmsg.h linux-2.6.36/include/linux/grmsg.h
45520 --- linux-2.6.36/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
45521 +++ linux-2.6.36/include/linux/grmsg.h 2010-11-06 18:58:50.000000000 -0400
45522 @@ -0,0 +1,110 @@
45523 +#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"
45524 +#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"
45525 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
45526 +#define GR_STOPMOD_MSG "denied modification of module state by "
45527 +#define GR_ROFS_BLOCKWRITE_MSG "denied write to block device %.950s by "
45528 +#define GR_ROFS_MOUNT_MSG "denied writable mount of %.950s by "
45529 +#define GR_IOPERM_MSG "denied use of ioperm() by "
45530 +#define GR_IOPL_MSG "denied use of iopl() by "
45531 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
45532 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
45533 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
45534 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
45535 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
45536 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
45537 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
45538 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
45539 +#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"
45540 +#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"
45541 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
45542 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
45543 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
45544 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
45545 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
45546 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
45547 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
45548 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%pI4 %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
45549 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
45550 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
45551 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
45552 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
45553 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
45554 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
45555 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
45556 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
45557 +#define GR_UNSAFESHARE_EXEC_ACL_MSG "denied exec with cloned fs of %.950s by "
45558 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
45559 +#define GR_NPROC_MSG "denied overstep of process limit by "
45560 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
45561 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
45562 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
45563 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
45564 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
45565 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
45566 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
45567 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
45568 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
45569 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
45570 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
45571 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
45572 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
45573 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
45574 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
45575 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
45576 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
45577 +#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"
45578 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
45579 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
45580 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
45581 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
45582 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
45583 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
45584 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
45585 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
45586 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
45587 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
45588 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
45589 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
45590 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
45591 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
45592 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
45593 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
45594 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
45595 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
45596 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
45597 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
45598 +#define GR_FAILFORK_MSG "failed fork with errno %s by "
45599 +#define GR_NICE_CHROOT_MSG "denied priority change by "
45600 +#define GR_UNISIGLOG_MSG "%.32s occurred at %p in "
45601 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
45602 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
45603 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
45604 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
45605 +#define GR_TIME_MSG "time set by "
45606 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
45607 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
45608 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
45609 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
45610 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
45611 +#define GR_BIND_MSG "denied bind() by "
45612 +#define GR_CONNECT_MSG "denied connect() by "
45613 +#define GR_BIND_ACL_MSG "denied bind() to %pI4 port %u sock type %.16s protocol %.16s by "
45614 +#define GR_CONNECT_ACL_MSG "denied connect() to %pI4 port %u sock type %.16s protocol %.16s by "
45615 +#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"
45616 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
45617 +#define GR_CAP_ACL_MSG "use of %s denied for "
45618 +#define GR_CAP_ACL_MSG2 "use of %s permitted for "
45619 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
45620 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
45621 +#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
45622 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
45623 +#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
45624 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
45625 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
45626 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
45627 +#define GR_RWXMMAP_MSG "denied RWX mmap of %.950s by "
45628 +#define GR_RWXMPROTECT_MSG "denied RWX mprotect of %.950s by "
45629 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
45630 +#define GR_NONROOT_MODLOAD_MSG "denied kernel module auto-load of %.64s by "
45631 +#define GR_VM86_MSG "denied use of vm86 by "
45632 +#define GR_PTRACE_AUDIT_MSG "process %.950s(%.16s:%d) attached to via ptrace by "
45633 diff -urNp linux-2.6.36/include/linux/grsecurity.h linux-2.6.36/include/linux/grsecurity.h
45634 --- linux-2.6.36/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
45635 +++ linux-2.6.36/include/linux/grsecurity.h 2010-11-06 20:09:12.000000000 -0400
45636 @@ -0,0 +1,206 @@
45637 +#ifndef GR_SECURITY_H
45638 +#define GR_SECURITY_H
45639 +#include <linux/fs.h>
45640 +#include <linux/fs_struct.h>
45641 +#include <linux/binfmts.h>
45642 +#include <linux/gracl.h>
45643 +
45644 +/* notify of brain-dead configs */
45645 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
45646 +#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
45647 +#endif
45648 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
45649 +#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
45650 +#endif
45651 +#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
45652 +#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
45653 +#endif
45654 +#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
45655 +#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
45656 +#endif
45657 +#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
45658 +#error "CONFIG_PAX enabled, but no PaX options are enabled."
45659 +#endif
45660 +
45661 +void gr_handle_brute_attach(struct task_struct *p);
45662 +void gr_handle_brute_check(void);
45663 +
45664 +char gr_roletype_to_char(void);
45665 +
45666 +int gr_check_user_change(int real, int effective, int fs);
45667 +int gr_check_group_change(int real, int effective, int fs);
45668 +
45669 +void gr_del_task_from_ip_table(struct task_struct *p);
45670 +
45671 +int gr_pid_is_chrooted(struct task_struct *p);
45672 +int gr_handle_chroot_fowner(struct pid *pid, enum pid_type type);
45673 +int gr_handle_chroot_nice(void);
45674 +int gr_handle_chroot_sysctl(const int op);
45675 +int gr_handle_chroot_setpriority(struct task_struct *p,
45676 + const int niceval);
45677 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
45678 +int gr_handle_chroot_chroot(const struct dentry *dentry,
45679 + const struct vfsmount *mnt);
45680 +int gr_handle_chroot_caps(struct path *path);
45681 +void gr_handle_chroot_chdir(struct path *path);
45682 +int gr_handle_chroot_chmod(const struct dentry *dentry,
45683 + const struct vfsmount *mnt, const int mode);
45684 +int gr_handle_chroot_mknod(const struct dentry *dentry,
45685 + const struct vfsmount *mnt, const int mode);
45686 +int gr_handle_chroot_mount(const struct dentry *dentry,
45687 + const struct vfsmount *mnt,
45688 + const char *dev_name);
45689 +int gr_handle_chroot_pivot(void);
45690 +int gr_handle_chroot_unix(struct pid *pid);
45691 +
45692 +int gr_handle_rawio(const struct inode *inode);
45693 +int gr_handle_nproc(void);
45694 +
45695 +void gr_handle_ioperm(void);
45696 +void gr_handle_iopl(void);
45697 +
45698 +int gr_tpe_allow(const struct file *file);
45699 +
45700 +void gr_set_chroot_entries(struct task_struct *task, struct path *path);
45701 +void gr_clear_chroot_entries(struct task_struct *task);
45702 +
45703 +void gr_log_forkfail(const int retval);
45704 +void gr_log_timechange(void);
45705 +void gr_log_signal(const int sig, const void *addr, const struct task_struct *t);
45706 +void gr_log_chdir(const struct dentry *dentry,
45707 + const struct vfsmount *mnt);
45708 +void gr_log_chroot_exec(const struct dentry *dentry,
45709 + const struct vfsmount *mnt);
45710 +void gr_handle_exec_args(struct linux_binprm *bprm, const char __user *const __user *argv);
45711 +void gr_log_remount(const char *devname, const int retval);
45712 +void gr_log_unmount(const char *devname, const int retval);
45713 +void gr_log_mount(const char *from, const char *to, const int retval);
45714 +void gr_log_textrel(struct vm_area_struct *vma);
45715 +void gr_log_rwxmmap(struct file *file);
45716 +void gr_log_rwxmprotect(struct file *file);
45717 +
45718 +int gr_handle_follow_link(const struct inode *parent,
45719 + const struct inode *inode,
45720 + const struct dentry *dentry,
45721 + const struct vfsmount *mnt);
45722 +int gr_handle_fifo(const struct dentry *dentry,
45723 + const struct vfsmount *mnt,
45724 + const struct dentry *dir, const int flag,
45725 + const int acc_mode);
45726 +int gr_handle_hardlink(const struct dentry *dentry,
45727 + const struct vfsmount *mnt,
45728 + struct inode *inode,
45729 + const int mode, const char *to);
45730 +
45731 +int gr_is_capable(const int cap);
45732 +int gr_is_capable_nolog(const int cap);
45733 +void gr_learn_resource(const struct task_struct *task, const int limit,
45734 + const unsigned long wanted, const int gt);
45735 +void gr_copy_label(struct task_struct *tsk);
45736 +void gr_handle_crash(struct task_struct *task, const int sig);
45737 +int gr_handle_signal(const struct task_struct *p, const int sig);
45738 +int gr_check_crash_uid(const uid_t uid);
45739 +int gr_check_protected_task(const struct task_struct *task);
45740 +int gr_check_protected_task_fowner(struct pid *pid, enum pid_type type);
45741 +int gr_acl_handle_mmap(const struct file *file,
45742 + const unsigned long prot);
45743 +int gr_acl_handle_mprotect(const struct file *file,
45744 + const unsigned long prot);
45745 +int gr_check_hidden_task(const struct task_struct *tsk);
45746 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
45747 + const struct vfsmount *mnt);
45748 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
45749 + const struct vfsmount *mnt);
45750 +__u32 gr_acl_handle_access(const struct dentry *dentry,
45751 + const struct vfsmount *mnt, const int fmode);
45752 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
45753 + const struct vfsmount *mnt, mode_t mode);
45754 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
45755 + const struct vfsmount *mnt, mode_t mode);
45756 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
45757 + const struct vfsmount *mnt);
45758 +int gr_handle_ptrace(struct task_struct *task, const long request);
45759 +int gr_handle_proc_ptrace(struct task_struct *task);
45760 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
45761 + const struct vfsmount *mnt);
45762 +int gr_check_crash_exec(const struct file *filp);
45763 +int gr_acl_is_enabled(void);
45764 +void gr_set_kernel_label(struct task_struct *task);
45765 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
45766 + const gid_t gid);
45767 +int gr_set_proc_label(const struct dentry *dentry,
45768 + const struct vfsmount *mnt,
45769 + const int unsafe_share);
45770 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
45771 + const struct vfsmount *mnt);
45772 +__u32 gr_acl_handle_open(const struct dentry *dentry,
45773 + const struct vfsmount *mnt, const int fmode);
45774 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
45775 + const struct dentry *p_dentry,
45776 + const struct vfsmount *p_mnt, const int fmode,
45777 + const int imode);
45778 +void gr_handle_create(const struct dentry *dentry,
45779 + const struct vfsmount *mnt);
45780 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
45781 + const struct dentry *parent_dentry,
45782 + const struct vfsmount *parent_mnt,
45783 + const int mode);
45784 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
45785 + const struct dentry *parent_dentry,
45786 + const struct vfsmount *parent_mnt);
45787 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
45788 + const struct vfsmount *mnt);
45789 +void gr_handle_delete(const ino_t ino, const dev_t dev);
45790 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
45791 + const struct vfsmount *mnt);
45792 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
45793 + const struct dentry *parent_dentry,
45794 + const struct vfsmount *parent_mnt,
45795 + const char *from);
45796 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
45797 + const struct dentry *parent_dentry,
45798 + const struct vfsmount *parent_mnt,
45799 + const struct dentry *old_dentry,
45800 + const struct vfsmount *old_mnt, const char *to);
45801 +int gr_acl_handle_rename(struct dentry *new_dentry,
45802 + struct dentry *parent_dentry,
45803 + const struct vfsmount *parent_mnt,
45804 + struct dentry *old_dentry,
45805 + struct inode *old_parent_inode,
45806 + struct vfsmount *old_mnt, const char *newname);
45807 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
45808 + struct dentry *old_dentry,
45809 + struct dentry *new_dentry,
45810 + struct vfsmount *mnt, const __u8 replace);
45811 +__u32 gr_check_link(const struct dentry *new_dentry,
45812 + const struct dentry *parent_dentry,
45813 + const struct vfsmount *parent_mnt,
45814 + const struct dentry *old_dentry,
45815 + const struct vfsmount *old_mnt);
45816 +int gr_acl_handle_filldir(const struct file *file, const char *name,
45817 + const unsigned int namelen, const ino_t ino);
45818 +
45819 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
45820 + const struct vfsmount *mnt);
45821 +void gr_acl_handle_exit(void);
45822 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
45823 +int gr_acl_handle_procpidmem(const struct task_struct *task);
45824 +int gr_handle_rofs_mount(struct dentry *dentry, struct vfsmount *mnt, int mnt_flags);
45825 +int gr_handle_rofs_blockwrite(struct dentry *dentry, struct vfsmount *mnt, int acc_mode);
45826 +void gr_audit_ptrace(struct task_struct *task);
45827 +
45828 +#ifdef CONFIG_GRKERNSEC
45829 +void task_grsec_rbac(struct seq_file *m, struct task_struct *p);
45830 +void gr_log_nonroot_mod_load(const char *modname);
45831 +void gr_handle_vm86(void);
45832 +void gr_handle_mem_write(void);
45833 +void gr_handle_kmem_write(void);
45834 +void gr_handle_open_port(void);
45835 +int gr_handle_mem_mmap(const unsigned long offset,
45836 + struct vm_area_struct *vma);
45837 +
45838 +extern int grsec_enable_dmesg;
45839 +extern int grsec_disable_privio;
45840 +#endif
45841 +
45842 +#endif
45843 diff -urNp linux-2.6.36/include/linux/grsock.h linux-2.6.36/include/linux/grsock.h
45844 --- linux-2.6.36/include/linux/grsock.h 1969-12-31 19:00:00.000000000 -0500
45845 +++ linux-2.6.36/include/linux/grsock.h 2010-11-06 18:58:50.000000000 -0400
45846 @@ -0,0 +1,19 @@
45847 +#ifndef __GRSOCK_H
45848 +#define __GRSOCK_H
45849 +
45850 +extern void gr_attach_curr_ip(const struct sock *sk);
45851 +extern int gr_handle_sock_all(const int family, const int type,
45852 + const int protocol);
45853 +extern int gr_handle_sock_server(const struct sockaddr *sck);
45854 +extern int gr_handle_sock_server_other(const struct sock *sck);
45855 +extern int gr_handle_sock_client(const struct sockaddr *sck);
45856 +extern int gr_search_connect(struct socket * sock,
45857 + struct sockaddr_in * addr);
45858 +extern int gr_search_bind(struct socket * sock,
45859 + struct sockaddr_in * addr);
45860 +extern int gr_search_listen(struct socket * sock);
45861 +extern int gr_search_accept(struct socket * sock);
45862 +extern int gr_search_socket(const int domain, const int type,
45863 + const int protocol);
45864 +
45865 +#endif
45866 diff -urNp linux-2.6.36/include/linux/highmem.h linux-2.6.36/include/linux/highmem.h
45867 --- linux-2.6.36/include/linux/highmem.h 2010-10-20 16:30:22.000000000 -0400
45868 +++ linux-2.6.36/include/linux/highmem.h 2010-11-06 18:58:15.000000000 -0400
45869 @@ -155,6 +155,18 @@ static inline void clear_highpage(struct
45870 kunmap_atomic(kaddr, KM_USER0);
45871 }
45872
45873 +static inline void sanitize_highpage(struct page *page)
45874 +{
45875 + void *kaddr;
45876 + unsigned long flags;
45877 +
45878 + local_irq_save(flags);
45879 + kaddr = kmap_atomic(page, KM_CLEARPAGE);
45880 + clear_page(kaddr);
45881 + kunmap_atomic(kaddr, KM_CLEARPAGE);
45882 + local_irq_restore(flags);
45883 +}
45884 +
45885 static inline void zero_user_segments(struct page *page,
45886 unsigned start1, unsigned end1,
45887 unsigned start2, unsigned end2)
45888 diff -urNp linux-2.6.36/include/linux/init.h linux-2.6.36/include/linux/init.h
45889 --- linux-2.6.36/include/linux/init.h 2010-10-20 16:30:22.000000000 -0400
45890 +++ linux-2.6.36/include/linux/init.h 2010-11-06 18:58:15.000000000 -0400
45891 @@ -286,13 +286,13 @@ void __init parse_early_options(char *cm
45892
45893 /* Each module must use one module_init(). */
45894 #define module_init(initfn) \
45895 - static inline initcall_t __inittest(void) \
45896 + static inline __used initcall_t __inittest(void) \
45897 { return initfn; } \
45898 int init_module(void) __attribute__((alias(#initfn)));
45899
45900 /* This is only required if you want to be unloadable. */
45901 #define module_exit(exitfn) \
45902 - static inline exitcall_t __exittest(void) \
45903 + static inline __used exitcall_t __exittest(void) \
45904 { return exitfn; } \
45905 void cleanup_module(void) __attribute__((alias(#exitfn)));
45906
45907 diff -urNp linux-2.6.36/include/linux/interrupt.h linux-2.6.36/include/linux/interrupt.h
45908 --- linux-2.6.36/include/linux/interrupt.h 2010-10-20 16:30:22.000000000 -0400
45909 +++ linux-2.6.36/include/linux/interrupt.h 2010-11-06 18:58:15.000000000 -0400
45910 @@ -392,7 +392,7 @@ enum
45911 /* map softirq index to softirq name. update 'softirq_to_name' in
45912 * kernel/softirq.c when adding a new softirq.
45913 */
45914 -extern char *softirq_to_name[NR_SOFTIRQS];
45915 +extern const char * const softirq_to_name[NR_SOFTIRQS];
45916
45917 /* softirq mask and active fields moved to irq_cpustat_t in
45918 * asm/hardirq.h to get better cache usage. KAO
45919 @@ -400,12 +400,12 @@ extern char *softirq_to_name[NR_SOFTIRQS
45920
45921 struct softirq_action
45922 {
45923 - void (*action)(struct softirq_action *);
45924 + void (*action)(void);
45925 };
45926
45927 asmlinkage void do_softirq(void);
45928 asmlinkage void __do_softirq(void);
45929 -extern void open_softirq(int nr, void (*action)(struct softirq_action *));
45930 +extern void open_softirq(int nr, void (*action)(void));
45931 extern void softirq_init(void);
45932 #define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
45933 extern void raise_softirq_irqoff(unsigned int nr);
45934 diff -urNp linux-2.6.36/include/linux/jbd2.h linux-2.6.36/include/linux/jbd2.h
45935 --- linux-2.6.36/include/linux/jbd2.h 2010-10-20 16:30:22.000000000 -0400
45936 +++ linux-2.6.36/include/linux/jbd2.h 2010-11-06 18:58:15.000000000 -0400
45937 @@ -67,7 +67,7 @@ extern u8 jbd2_journal_enable_debug;
45938 } \
45939 } while (0)
45940 #else
45941 -#define jbd_debug(f, a...) /**/
45942 +#define jbd_debug(f, a...) do {} while (0)
45943 #endif
45944
45945 extern void *jbd2_alloc(size_t size, gfp_t flags);
45946 diff -urNp linux-2.6.36/include/linux/jbd.h linux-2.6.36/include/linux/jbd.h
45947 --- linux-2.6.36/include/linux/jbd.h 2010-10-20 16:30:22.000000000 -0400
45948 +++ linux-2.6.36/include/linux/jbd.h 2010-11-06 18:58:15.000000000 -0400
45949 @@ -67,7 +67,7 @@ extern u8 journal_enable_debug;
45950 } \
45951 } while (0)
45952 #else
45953 -#define jbd_debug(f, a...) /**/
45954 +#define jbd_debug(f, a...) do {} while (0)
45955 #endif
45956
45957 static inline void *jbd_alloc(size_t size, gfp_t flags)
45958 diff -urNp linux-2.6.36/include/linux/kallsyms.h linux-2.6.36/include/linux/kallsyms.h
45959 --- linux-2.6.36/include/linux/kallsyms.h 2010-10-20 16:30:22.000000000 -0400
45960 +++ linux-2.6.36/include/linux/kallsyms.h 2010-11-06 18:58:50.000000000 -0400
45961 @@ -15,7 +15,8 @@
45962
45963 struct module;
45964
45965 -#ifdef CONFIG_KALLSYMS
45966 +#ifndef __INCLUDED_BY_HIDESYM
45967 +#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
45968 /* Lookup the address for a symbol. Returns 0 if not found. */
45969 unsigned long kallsyms_lookup_name(const char *name);
45970
45971 @@ -92,6 +93,9 @@ static inline int lookup_symbol_attrs(un
45972 /* Stupid that this does nothing, but I didn't create this mess. */
45973 #define __print_symbol(fmt, addr)
45974 #endif /*CONFIG_KALLSYMS*/
45975 +#else /* when included by kallsyms.c, with HIDESYM enabled */
45976 +extern void __print_symbol(const char *fmt, unsigned long address);
45977 +#endif
45978
45979 /* This macro allows us to keep printk typechecking */
45980 static void __check_printsym_format(const char *fmt, ...)
45981 diff -urNp linux-2.6.36/include/linux/kgdb.h linux-2.6.36/include/linux/kgdb.h
45982 --- linux-2.6.36/include/linux/kgdb.h 2010-10-20 16:30:22.000000000 -0400
45983 +++ linux-2.6.36/include/linux/kgdb.h 2010-11-06 18:58:15.000000000 -0400
45984 @@ -276,22 +276,22 @@ struct kgdb_arch {
45985 */
45986 struct kgdb_io {
45987 const char *name;
45988 - int (*read_char) (void);
45989 - void (*write_char) (u8);
45990 - void (*flush) (void);
45991 - int (*init) (void);
45992 - void (*pre_exception) (void);
45993 - void (*post_exception) (void);
45994 + int (* const read_char) (void);
45995 + void (* const write_char) (u8);
45996 + void (* const flush) (void);
45997 + int (* const init) (void);
45998 + void (* const pre_exception) (void);
45999 + void (* const post_exception) (void);
46000 int is_console;
46001 };
46002
46003 -extern struct kgdb_arch arch_kgdb_ops;
46004 +extern const struct kgdb_arch arch_kgdb_ops;
46005
46006 extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs);
46007
46008 -extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops);
46009 -extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops);
46010 -extern struct kgdb_io *dbg_io_ops;
46011 +extern int kgdb_register_io_module(const struct kgdb_io *local_kgdb_io_ops);
46012 +extern void kgdb_unregister_io_module(const struct kgdb_io *local_kgdb_io_ops);
46013 +extern const struct kgdb_io *dbg_io_ops;
46014
46015 extern int kgdb_hex2long(char **ptr, unsigned long *long_val);
46016 extern char *kgdb_mem2hex(char *mem, char *buf, int count);
46017 diff -urNp linux-2.6.36/include/linux/kvm_host.h linux-2.6.36/include/linux/kvm_host.h
46018 --- linux-2.6.36/include/linux/kvm_host.h 2010-10-20 16:30:22.000000000 -0400
46019 +++ linux-2.6.36/include/linux/kvm_host.h 2010-11-06 18:58:15.000000000 -0400
46020 @@ -245,7 +245,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vc
46021 void vcpu_load(struct kvm_vcpu *vcpu);
46022 void vcpu_put(struct kvm_vcpu *vcpu);
46023
46024 -int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
46025 +int kvm_init(const void *opaque, unsigned vcpu_size, unsigned vcpu_align,
46026 struct module *module);
46027 void kvm_exit(void);
46028
46029 @@ -369,7 +369,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(
46030 struct kvm_guest_debug *dbg);
46031 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
46032
46033 -int kvm_arch_init(void *opaque);
46034 +int kvm_arch_init(const void *opaque);
46035 void kvm_arch_exit(void);
46036
46037 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu);
46038 diff -urNp linux-2.6.36/include/linux/libata.h linux-2.6.36/include/linux/libata.h
46039 --- linux-2.6.36/include/linux/libata.h 2010-10-20 16:30:22.000000000 -0400
46040 +++ linux-2.6.36/include/linux/libata.h 2010-11-06 18:58:15.000000000 -0400
46041 @@ -64,11 +64,11 @@
46042 #ifdef ATA_VERBOSE_DEBUG
46043 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
46044 #else
46045 -#define VPRINTK(fmt, args...)
46046 +#define VPRINTK(fmt, args...) do {} while (0)
46047 #endif /* ATA_VERBOSE_DEBUG */
46048 #else
46049 -#define DPRINTK(fmt, args...)
46050 -#define VPRINTK(fmt, args...)
46051 +#define DPRINTK(fmt, args...) do {} while (0)
46052 +#define VPRINTK(fmt, args...) do {} while (0)
46053 #endif /* ATA_DEBUG */
46054
46055 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
46056 @@ -524,11 +524,11 @@ struct ata_ioports {
46057
46058 struct ata_host {
46059 spinlock_t lock;
46060 - struct device *dev;
46061 + struct device *dev;
46062 void __iomem * const *iomap;
46063 unsigned int n_ports;
46064 void *private_data;
46065 - struct ata_port_operations *ops;
46066 + const struct ata_port_operations *ops;
46067 unsigned long flags;
46068 #ifdef CONFIG_ATA_ACPI
46069 acpi_handle acpi_handle;
46070 @@ -710,7 +710,7 @@ struct ata_link {
46071
46072 struct ata_port {
46073 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */
46074 - struct ata_port_operations *ops;
46075 + const struct ata_port_operations *ops;
46076 spinlock_t *lock;
46077 /* Flags owned by the EH context. Only EH should touch these once the
46078 port is active */
46079 @@ -897,7 +897,7 @@ struct ata_port_info {
46080 unsigned long pio_mask;
46081 unsigned long mwdma_mask;
46082 unsigned long udma_mask;
46083 - struct ata_port_operations *port_ops;
46084 + const struct ata_port_operations *port_ops;
46085 void *private_data;
46086 };
46087
46088 @@ -921,7 +921,7 @@ extern const unsigned long sata_deb_timi
46089 extern const unsigned long sata_deb_timing_hotplug[];
46090 extern const unsigned long sata_deb_timing_long[];
46091
46092 -extern struct ata_port_operations ata_dummy_port_ops;
46093 +extern const struct ata_port_operations ata_dummy_port_ops;
46094 extern const struct ata_port_info ata_dummy_port_info;
46095
46096 static inline const unsigned long *
46097 @@ -965,7 +965,7 @@ extern int ata_host_activate(struct ata_
46098 struct scsi_host_template *sht);
46099 extern void ata_host_detach(struct ata_host *host);
46100 extern void ata_host_init(struct ata_host *, struct device *,
46101 - unsigned long, struct ata_port_operations *);
46102 + unsigned long, const struct ata_port_operations *);
46103 extern int ata_scsi_detect(struct scsi_host_template *sht);
46104 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
46105 extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
46106 diff -urNp linux-2.6.36/include/linux/lockd/bind.h linux-2.6.36/include/linux/lockd/bind.h
46107 --- linux-2.6.36/include/linux/lockd/bind.h 2010-10-20 16:30:22.000000000 -0400
46108 +++ linux-2.6.36/include/linux/lockd/bind.h 2010-11-06 18:58:15.000000000 -0400
46109 @@ -23,13 +23,13 @@ struct svc_rqst;
46110 * This is the set of functions for lockd->nfsd communication
46111 */
46112 struct nlmsvc_binding {
46113 - __be32 (*fopen)(struct svc_rqst *,
46114 + __be32 (* const fopen)(struct svc_rqst *,
46115 struct nfs_fh *,
46116 struct file **);
46117 - void (*fclose)(struct file *);
46118 + void (* const fclose)(struct file *);
46119 };
46120
46121 -extern struct nlmsvc_binding * nlmsvc_ops;
46122 +extern const struct nlmsvc_binding * nlmsvc_ops;
46123
46124 /*
46125 * Similar to nfs_client_initdata, but without the NFS-specific
46126 diff -urNp linux-2.6.36/include/linux/mm.h linux-2.6.36/include/linux/mm.h
46127 --- linux-2.6.36/include/linux/mm.h 2010-10-20 16:30:22.000000000 -0400
46128 +++ linux-2.6.36/include/linux/mm.h 2010-11-06 18:58:50.000000000 -0400
46129 @@ -107,7 +107,14 @@ extern unsigned int kobjsize(const void
46130
46131 #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
46132 #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
46133 +
46134 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
46135 +#define VM_SAO 0x00000000 /* Strong Access Ordering (powerpc) */
46136 +#define VM_PAGEEXEC 0x20000000 /* vma->vm_page_prot needs special handling */
46137 +#else
46138 #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
46139 +#endif
46140 +
46141 #define VM_PFN_AT_MMAP 0x40000000 /* PFNMAP vma that is fully mapped at mmap time */
46142 #define VM_MERGEABLE 0x80000000 /* KSM may merge identical pages */
46143
46144 @@ -1021,6 +1028,15 @@ struct shrinker {
46145 extern void register_shrinker(struct shrinker *);
46146 extern void unregister_shrinker(struct shrinker *);
46147
46148 +#ifdef CONFIG_MMU
46149 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
46150 +#else
46151 +static inline pgprot_t vm_get_page_prot(unsigned long vm_flags)
46152 +{
46153 + return __pgprot(0);
46154 +}
46155 +#endif
46156 +
46157 int vma_wants_writenotify(struct vm_area_struct *vma);
46158
46159 extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
46160 @@ -1297,6 +1313,7 @@ out:
46161 }
46162
46163 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
46164 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
46165
46166 extern unsigned long do_brk(unsigned long, unsigned long);
46167
46168 @@ -1353,6 +1370,10 @@ extern struct vm_area_struct * find_vma(
46169 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
46170 struct vm_area_struct **pprev);
46171
46172 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
46173 +extern __must_check long pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
46174 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
46175 +
46176 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
46177 NULL if none. Assume start_addr < end_addr. */
46178 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
46179 @@ -1369,15 +1390,6 @@ static inline unsigned long vma_pages(st
46180 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
46181 }
46182
46183 -#ifdef CONFIG_MMU
46184 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
46185 -#else
46186 -static inline pgprot_t vm_get_page_prot(unsigned long vm_flags)
46187 -{
46188 - return __pgprot(0);
46189 -}
46190 -#endif
46191 -
46192 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
46193 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
46194 unsigned long pfn, unsigned long size, pgprot_t);
46195 @@ -1484,7 +1496,7 @@ extern int unpoison_memory(unsigned long
46196 extern int sysctl_memory_failure_early_kill;
46197 extern int sysctl_memory_failure_recovery;
46198 extern void shake_page(struct page *p, int access);
46199 -extern atomic_long_t mce_bad_pages;
46200 +extern atomic_long_unchecked_t mce_bad_pages;
46201 extern int soft_offline_page(struct page *page, int flags);
46202 #ifdef CONFIG_MEMORY_FAILURE
46203 int is_hwpoison_address(unsigned long addr);
46204 @@ -1497,5 +1509,11 @@ static inline int is_hwpoison_address(un
46205
46206 extern void dump_page(struct page *page);
46207
46208 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
46209 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
46210 +#else
46211 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
46212 +#endif
46213 +
46214 #endif /* __KERNEL__ */
46215 #endif /* _LINUX_MM_H */
46216 diff -urNp linux-2.6.36/include/linux/mm_types.h linux-2.6.36/include/linux/mm_types.h
46217 --- linux-2.6.36/include/linux/mm_types.h 2010-10-20 16:30:22.000000000 -0400
46218 +++ linux-2.6.36/include/linux/mm_types.h 2010-11-06 18:58:15.000000000 -0400
46219 @@ -183,6 +183,8 @@ struct vm_area_struct {
46220 #ifdef CONFIG_NUMA
46221 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
46222 #endif
46223 +
46224 + struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
46225 };
46226
46227 struct core_thread {
46228 @@ -310,6 +312,24 @@ struct mm_struct {
46229 #ifdef CONFIG_MMU_NOTIFIER
46230 struct mmu_notifier_mm *mmu_notifier_mm;
46231 #endif
46232 +
46233 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
46234 + unsigned long pax_flags;
46235 +#endif
46236 +
46237 +#ifdef CONFIG_PAX_DLRESOLVE
46238 + unsigned long call_dl_resolve;
46239 +#endif
46240 +
46241 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
46242 + unsigned long call_syscall;
46243 +#endif
46244 +
46245 +#ifdef CONFIG_PAX_ASLR
46246 + unsigned long delta_mmap; /* randomized offset */
46247 + unsigned long delta_stack; /* randomized offset */
46248 +#endif
46249 +
46250 };
46251
46252 /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */
46253 diff -urNp linux-2.6.36/include/linux/mmu_notifier.h linux-2.6.36/include/linux/mmu_notifier.h
46254 --- linux-2.6.36/include/linux/mmu_notifier.h 2010-10-20 16:30:22.000000000 -0400
46255 +++ linux-2.6.36/include/linux/mmu_notifier.h 2010-11-06 18:58:15.000000000 -0400
46256 @@ -235,12 +235,12 @@ static inline void mmu_notifier_mm_destr
46257 */
46258 #define ptep_clear_flush_notify(__vma, __address, __ptep) \
46259 ({ \
46260 - pte_t __pte; \
46261 + pte_t ___pte; \
46262 struct vm_area_struct *___vma = __vma; \
46263 unsigned long ___address = __address; \
46264 - __pte = ptep_clear_flush(___vma, ___address, __ptep); \
46265 + ___pte = ptep_clear_flush(___vma, ___address, __ptep); \
46266 mmu_notifier_invalidate_page(___vma->vm_mm, ___address); \
46267 - __pte; \
46268 + ___pte; \
46269 })
46270
46271 #define ptep_clear_flush_young_notify(__vma, __address, __ptep) \
46272 diff -urNp linux-2.6.36/include/linux/mmzone.h linux-2.6.36/include/linux/mmzone.h
46273 --- linux-2.6.36/include/linux/mmzone.h 2010-10-20 16:30:22.000000000 -0400
46274 +++ linux-2.6.36/include/linux/mmzone.h 2010-11-06 18:58:15.000000000 -0400
46275 @@ -352,7 +352,7 @@ struct zone {
46276 unsigned long flags; /* zone flags, see below */
46277
46278 /* Zone statistics */
46279 - atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
46280 + atomic_long_unchecked_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
46281
46282 /*
46283 * The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on
46284 diff -urNp linux-2.6.36/include/linux/mod_devicetable.h linux-2.6.36/include/linux/mod_devicetable.h
46285 --- linux-2.6.36/include/linux/mod_devicetable.h 2010-10-20 16:30:22.000000000 -0400
46286 +++ linux-2.6.36/include/linux/mod_devicetable.h 2010-11-06 18:58:15.000000000 -0400
46287 @@ -12,7 +12,7 @@
46288 typedef unsigned long kernel_ulong_t;
46289 #endif
46290
46291 -#define PCI_ANY_ID (~0)
46292 +#define PCI_ANY_ID ((__u16)~0)
46293
46294 struct pci_device_id {
46295 __u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
46296 @@ -131,7 +131,7 @@ struct usb_device_id {
46297 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
46298 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
46299
46300 -#define HID_ANY_ID (~0)
46301 +#define HID_ANY_ID (~0U)
46302
46303 struct hid_device_id {
46304 __u16 bus;
46305 diff -urNp linux-2.6.36/include/linux/module.h linux-2.6.36/include/linux/module.h
46306 --- linux-2.6.36/include/linux/module.h 2010-10-20 16:30:22.000000000 -0400
46307 +++ linux-2.6.36/include/linux/module.h 2010-11-06 18:58:15.000000000 -0400
46308 @@ -297,16 +297,16 @@ struct module
46309 int (*init)(void);
46310
46311 /* If this is non-NULL, vfree after init() returns */
46312 - void *module_init;
46313 + void *module_init_rx, *module_init_rw;
46314
46315 /* Here is the actual code + data, vfree'd on unload. */
46316 - void *module_core;
46317 + void *module_core_rx, *module_core_rw;
46318
46319 /* Here are the sizes of the init and core sections */
46320 - unsigned int init_size, core_size;
46321 + unsigned int init_size_rw, core_size_rw;
46322
46323 /* The size of the executable code in each section. */
46324 - unsigned int init_text_size, core_text_size;
46325 + unsigned int init_size_rx, core_size_rx;
46326
46327 /* Arch-specific module values */
46328 struct mod_arch_specific arch;
46329 @@ -408,16 +408,46 @@ bool is_module_address(unsigned long add
46330 bool is_module_percpu_address(unsigned long addr);
46331 bool is_module_text_address(unsigned long addr);
46332
46333 +static inline int within_module_range(unsigned long addr, void *start, unsigned long size)
46334 +{
46335 +
46336 +#ifdef CONFIG_PAX_KERNEXEC
46337 + if (ktla_ktva(addr) >= (unsigned long)start &&
46338 + ktla_ktva(addr) < (unsigned long)start + size)
46339 + return 1;
46340 +#endif
46341 +
46342 + return ((void *)addr >= start && (void *)addr < start + size);
46343 +}
46344 +
46345 +static inline int within_module_core_rx(unsigned long addr, struct module *mod)
46346 +{
46347 + return within_module_range(addr, mod->module_core_rx, mod->core_size_rx);
46348 +}
46349 +
46350 +static inline int within_module_core_rw(unsigned long addr, struct module *mod)
46351 +{
46352 + return within_module_range(addr, mod->module_core_rw, mod->core_size_rw);
46353 +}
46354 +
46355 +static inline int within_module_init_rx(unsigned long addr, struct module *mod)
46356 +{
46357 + return within_module_range(addr, mod->module_init_rx, mod->init_size_rx);
46358 +}
46359 +
46360 +static inline int within_module_init_rw(unsigned long addr, struct module *mod)
46361 +{
46362 + return within_module_range(addr, mod->module_init_rw, mod->init_size_rw);
46363 +}
46364 +
46365 static inline int within_module_core(unsigned long addr, struct module *mod)
46366 {
46367 - return (unsigned long)mod->module_core <= addr &&
46368 - addr < (unsigned long)mod->module_core + mod->core_size;
46369 + return within_module_core_rx(addr, mod) || within_module_core_rw(addr, mod);
46370 }
46371
46372 static inline int within_module_init(unsigned long addr, struct module *mod)
46373 {
46374 - return (unsigned long)mod->module_init <= addr &&
46375 - addr < (unsigned long)mod->module_init + mod->init_size;
46376 + return within_module_init_rx(addr, mod) || within_module_init_rw(addr, mod);
46377 }
46378
46379 /* Search for module by name: must hold module_mutex. */
46380 diff -urNp linux-2.6.36/include/linux/moduleloader.h linux-2.6.36/include/linux/moduleloader.h
46381 --- linux-2.6.36/include/linux/moduleloader.h 2010-10-20 16:30:22.000000000 -0400
46382 +++ linux-2.6.36/include/linux/moduleloader.h 2010-11-06 18:58:15.000000000 -0400
46383 @@ -20,9 +20,21 @@ unsigned int arch_mod_section_prepend(st
46384 sections. Returns NULL on failure. */
46385 void *module_alloc(unsigned long size);
46386
46387 +#ifdef CONFIG_PAX_KERNEXEC
46388 +void *module_alloc_exec(unsigned long size);
46389 +#else
46390 +#define module_alloc_exec(x) module_alloc(x)
46391 +#endif
46392 +
46393 /* Free memory returned from module_alloc. */
46394 void module_free(struct module *mod, void *module_region);
46395
46396 +#ifdef CONFIG_PAX_KERNEXEC
46397 +void module_free_exec(struct module *mod, void *module_region);
46398 +#else
46399 +#define module_free_exec(x, y) module_free((x), (y))
46400 +#endif
46401 +
46402 /* Apply the given relocation to the (simplified) ELF. Return -error
46403 or 0. */
46404 int apply_relocate(Elf_Shdr *sechdrs,
46405 diff -urNp linux-2.6.36/include/linux/moduleparam.h linux-2.6.36/include/linux/moduleparam.h
46406 --- linux-2.6.36/include/linux/moduleparam.h 2010-10-20 16:30:22.000000000 -0400
46407 +++ linux-2.6.36/include/linux/moduleparam.h 2010-11-06 18:58:15.000000000 -0400
46408 @@ -253,7 +253,7 @@ static inline void __kernel_param_unlock
46409 * @len is usually just sizeof(string).
46410 */
46411 #define module_param_string(name, string, len, perm) \
46412 - static const struct kparam_string __param_string_##name \
46413 + static const struct kparam_string __param_string_##name __used \
46414 = { len, string }; \
46415 __module_param_call(MODULE_PARAM_PREFIX, name, \
46416 &param_ops_string, \
46417 @@ -368,7 +368,7 @@ extern int param_get_invbool(char *buffe
46418 * module_param_named() for why this might be necessary.
46419 */
46420 #define module_param_array_named(name, array, type, nump, perm) \
46421 - static const struct kparam_array __param_arr_##name \
46422 + static const struct kparam_array __param_arr_##name __used \
46423 = { ARRAY_SIZE(array), nump, &param_ops_##type, \
46424 sizeof(array[0]), array }; \
46425 __module_param_call(MODULE_PARAM_PREFIX, name, \
46426 diff -urNp linux-2.6.36/include/linux/namei.h linux-2.6.36/include/linux/namei.h
46427 --- linux-2.6.36/include/linux/namei.h 2010-10-20 16:30:22.000000000 -0400
46428 +++ linux-2.6.36/include/linux/namei.h 2010-11-06 18:58:15.000000000 -0400
46429 @@ -22,7 +22,7 @@ struct nameidata {
46430 unsigned int flags;
46431 int last_type;
46432 unsigned depth;
46433 - char *saved_names[MAX_NESTED_LINKS + 1];
46434 + const char *saved_names[MAX_NESTED_LINKS + 1];
46435
46436 /* Intent data */
46437 union {
46438 @@ -81,12 +81,12 @@ extern int follow_up(struct path *);
46439 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
46440 extern void unlock_rename(struct dentry *, struct dentry *);
46441
46442 -static inline void nd_set_link(struct nameidata *nd, char *path)
46443 +static inline void nd_set_link(struct nameidata *nd, const char *path)
46444 {
46445 nd->saved_names[nd->depth] = path;
46446 }
46447
46448 -static inline char *nd_get_link(struct nameidata *nd)
46449 +static inline const char *nd_get_link(const struct nameidata *nd)
46450 {
46451 return nd->saved_names[nd->depth];
46452 }
46453 diff -urNp linux-2.6.36/include/linux/netfilter/xt_gradm.h linux-2.6.36/include/linux/netfilter/xt_gradm.h
46454 --- linux-2.6.36/include/linux/netfilter/xt_gradm.h 1969-12-31 19:00:00.000000000 -0500
46455 +++ linux-2.6.36/include/linux/netfilter/xt_gradm.h 2010-11-06 18:58:50.000000000 -0400
46456 @@ -0,0 +1,9 @@
46457 +#ifndef _LINUX_NETFILTER_XT_GRADM_H
46458 +#define _LINUX_NETFILTER_XT_GRADM_H 1
46459 +
46460 +struct xt_gradm_mtinfo {
46461 + __u16 flags;
46462 + __u16 invflags;
46463 +};
46464 +
46465 +#endif
46466 diff -urNp linux-2.6.36/include/linux/oprofile.h linux-2.6.36/include/linux/oprofile.h
46467 --- linux-2.6.36/include/linux/oprofile.h 2010-10-20 16:30:22.000000000 -0400
46468 +++ linux-2.6.36/include/linux/oprofile.h 2010-11-06 18:58:15.000000000 -0400
46469 @@ -129,9 +129,9 @@ int oprofilefs_create_ulong(struct super
46470 int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root,
46471 char const * name, ulong * val);
46472
46473 -/** Create a file for read-only access to an atomic_t. */
46474 +/** Create a file for read-only access to an atomic_unchecked_t. */
46475 int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root,
46476 - char const * name, atomic_t * val);
46477 + char const * name, atomic_unchecked_t * val);
46478
46479 /** create a directory */
46480 struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root,
46481 diff -urNp linux-2.6.36/include/linux/pipe_fs_i.h linux-2.6.36/include/linux/pipe_fs_i.h
46482 --- linux-2.6.36/include/linux/pipe_fs_i.h 2010-10-20 16:30:22.000000000 -0400
46483 +++ linux-2.6.36/include/linux/pipe_fs_i.h 2010-11-06 18:58:15.000000000 -0400
46484 @@ -45,9 +45,9 @@ struct pipe_buffer {
46485 struct pipe_inode_info {
46486 wait_queue_head_t wait;
46487 unsigned int nrbufs, curbuf, buffers;
46488 - unsigned int readers;
46489 - unsigned int writers;
46490 - unsigned int waiting_writers;
46491 + atomic_t readers;
46492 + atomic_t writers;
46493 + atomic_t waiting_writers;
46494 unsigned int r_counter;
46495 unsigned int w_counter;
46496 struct page *tmp_page;
46497 diff -urNp linux-2.6.36/include/linux/poison.h linux-2.6.36/include/linux/poison.h
46498 --- linux-2.6.36/include/linux/poison.h 2010-10-20 16:30:22.000000000 -0400
46499 +++ linux-2.6.36/include/linux/poison.h 2010-11-06 18:58:15.000000000 -0400
46500 @@ -19,8 +19,8 @@
46501 * under normal circumstances, used to verify that nobody uses
46502 * non-initialized list entries.
46503 */
46504 -#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)
46505 -#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA)
46506 +#define LIST_POISON1 ((void *) (long)0xFFFFFF01)
46507 +#define LIST_POISON2 ((void *) (long)0xFFFFFF02)
46508
46509 /********** include/linux/timer.h **********/
46510 /*
46511 diff -urNp linux-2.6.36/include/linux/proc_fs.h linux-2.6.36/include/linux/proc_fs.h
46512 --- linux-2.6.36/include/linux/proc_fs.h 2010-10-20 16:30:22.000000000 -0400
46513 +++ linux-2.6.36/include/linux/proc_fs.h 2010-11-06 18:58:50.000000000 -0400
46514 @@ -155,6 +155,19 @@ static inline struct proc_dir_entry *pro
46515 return proc_create_data(name, mode, parent, proc_fops, NULL);
46516 }
46517
46518 +static inline struct proc_dir_entry *proc_create_grsec(const char *name, mode_t mode,
46519 + struct proc_dir_entry *parent, const struct file_operations *proc_fops)
46520 +{
46521 +#ifdef CONFIG_GRKERNSEC_PROC_USER
46522 + return proc_create_data(name, S_IRUSR, parent, proc_fops, NULL);
46523 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
46524 + return proc_create_data(name, S_IRUSR | S_IRGRP, parent, proc_fops, NULL);
46525 +#else
46526 + return proc_create_data(name, mode, parent, proc_fops, NULL);
46527 +#endif
46528 +}
46529 +
46530 +
46531 static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
46532 mode_t mode, struct proc_dir_entry *base,
46533 read_proc_t *read_proc, void * data)
46534 diff -urNp linux-2.6.36/include/linux/random.h linux-2.6.36/include/linux/random.h
46535 --- linux-2.6.36/include/linux/random.h 2010-10-20 16:30:22.000000000 -0400
46536 +++ linux-2.6.36/include/linux/random.h 2010-11-06 18:58:15.000000000 -0400
46537 @@ -80,12 +80,17 @@ void srandom32(u32 seed);
46538
46539 u32 prandom32(struct rnd_state *);
46540
46541 +static inline unsigned long pax_get_random_long(void)
46542 +{
46543 + return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
46544 +}
46545 +
46546 /*
46547 * Handle minimum values for seeds
46548 */
46549 static inline u32 __seed(u32 x, u32 m)
46550 {
46551 - return (x < m) ? x + m : x;
46552 + return (x <= m) ? x + m + 1 : x;
46553 }
46554
46555 /**
46556 diff -urNp linux-2.6.36/include/linux/reiserfs_fs.h linux-2.6.36/include/linux/reiserfs_fs.h
46557 --- linux-2.6.36/include/linux/reiserfs_fs.h 2010-10-20 16:30:22.000000000 -0400
46558 +++ linux-2.6.36/include/linux/reiserfs_fs.h 2010-11-06 18:58:15.000000000 -0400
46559 @@ -1404,7 +1404,7 @@ static inline loff_t max_reiserfs_offset
46560 #define REISERFS_USER_MEM 1 /* reiserfs user memory mode */
46561
46562 #define fs_generation(s) (REISERFS_SB(s)->s_generation_counter)
46563 -#define get_generation(s) atomic_read (&fs_generation(s))
46564 +#define get_generation(s) atomic_read_unchecked (&fs_generation(s))
46565 #define FILESYSTEM_CHANGED_TB(tb) (get_generation((tb)->tb_sb) != (tb)->fs_gen)
46566 #define __fs_changed(gen,s) (gen != get_generation (s))
46567 #define fs_changed(gen,s) \
46568 @@ -1616,24 +1616,24 @@ static inline struct super_block *sb_fro
46569 */
46570
46571 struct item_operations {
46572 - int (*bytes_number) (struct item_head * ih, int block_size);
46573 - void (*decrement_key) (struct cpu_key *);
46574 - int (*is_left_mergeable) (struct reiserfs_key * ih,
46575 + int (* const bytes_number) (struct item_head * ih, int block_size);
46576 + void (* const decrement_key) (struct cpu_key *);
46577 + int (* const is_left_mergeable) (struct reiserfs_key * ih,
46578 unsigned long bsize);
46579 - void (*print_item) (struct item_head *, char *item);
46580 - void (*check_item) (struct item_head *, char *item);
46581 + void (* const print_item) (struct item_head *, char *item);
46582 + void (* const check_item) (struct item_head *, char *item);
46583
46584 - int (*create_vi) (struct virtual_node * vn, struct virtual_item * vi,
46585 + int (* const create_vi) (struct virtual_node * vn, struct virtual_item * vi,
46586 int is_affected, int insert_size);
46587 - int (*check_left) (struct virtual_item * vi, int free,
46588 + int (* const check_left) (struct virtual_item * vi, int free,
46589 int start_skip, int end_skip);
46590 - int (*check_right) (struct virtual_item * vi, int free);
46591 - int (*part_size) (struct virtual_item * vi, int from, int to);
46592 - int (*unit_num) (struct virtual_item * vi);
46593 - void (*print_vi) (struct virtual_item * vi);
46594 + int (* const check_right) (struct virtual_item * vi, int free);
46595 + int (* const part_size) (struct virtual_item * vi, int from, int to);
46596 + int (* const unit_num) (struct virtual_item * vi);
46597 + void (* const print_vi) (struct virtual_item * vi);
46598 };
46599
46600 -extern struct item_operations *item_ops[TYPE_ANY + 1];
46601 +extern const struct item_operations * const item_ops[TYPE_ANY + 1];
46602
46603 #define op_bytes_number(ih,bsize) item_ops[le_ih_k_type (ih)]->bytes_number (ih, bsize)
46604 #define op_is_left_mergeable(key,bsize) item_ops[le_key_k_type (le_key_version (key), key)]->is_left_mergeable (key, bsize)
46605 diff -urNp linux-2.6.36/include/linux/reiserfs_fs_sb.h linux-2.6.36/include/linux/reiserfs_fs_sb.h
46606 --- linux-2.6.36/include/linux/reiserfs_fs_sb.h 2010-10-20 16:30:22.000000000 -0400
46607 +++ linux-2.6.36/include/linux/reiserfs_fs_sb.h 2010-11-06 18:58:15.000000000 -0400
46608 @@ -386,7 +386,7 @@ struct reiserfs_sb_info {
46609 /* Comment? -Hans */
46610 wait_queue_head_t s_wait;
46611 /* To be obsoleted soon by per buffer seals.. -Hans */
46612 - atomic_t s_generation_counter; // increased by one every time the
46613 + atomic_unchecked_t s_generation_counter; // increased by one every time the
46614 // tree gets re-balanced
46615 unsigned long s_properties; /* File system properties. Currently holds
46616 on-disk FS format */
46617 diff -urNp linux-2.6.36/include/linux/rmap.h linux-2.6.36/include/linux/rmap.h
46618 --- linux-2.6.36/include/linux/rmap.h 2010-10-20 16:30:22.000000000 -0400
46619 +++ linux-2.6.36/include/linux/rmap.h 2010-11-06 18:58:15.000000000 -0400
46620 @@ -145,8 +145,8 @@ static inline void anon_vma_unlock(struc
46621 void anon_vma_init(void); /* create anon_vma_cachep */
46622 int anon_vma_prepare(struct vm_area_struct *);
46623 void unlink_anon_vmas(struct vm_area_struct *);
46624 -int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
46625 -int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
46626 +int anon_vma_clone(struct vm_area_struct *, const struct vm_area_struct *);
46627 +int anon_vma_fork(struct vm_area_struct *, const struct vm_area_struct *);
46628 void __anon_vma_link(struct vm_area_struct *);
46629 void anon_vma_free(struct anon_vma *);
46630
46631 diff -urNp linux-2.6.36/include/linux/sched.h linux-2.6.36/include/linux/sched.h
46632 --- linux-2.6.36/include/linux/sched.h 2010-10-20 16:30:22.000000000 -0400
46633 +++ linux-2.6.36/include/linux/sched.h 2010-11-06 19:00:55.000000000 -0400
46634 @@ -100,6 +100,7 @@ struct robust_list_head;
46635 struct bio_list;
46636 struct fs_struct;
46637 struct perf_event_context;
46638 +struct linux_binprm;
46639
46640 /*
46641 * List of flags we want to share for kernel threads,
46642 @@ -374,10 +375,12 @@ struct user_namespace;
46643 #define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN)
46644
46645 extern int sysctl_max_map_count;
46646 +extern unsigned long sysctl_heap_stack_gap;
46647
46648 #include <linux/aio.h>
46649
46650 #ifdef CONFIG_MMU
46651 +extern bool check_heap_stack_gap(struct vm_area_struct *vma, unsigned long addr, unsigned long len);
46652 extern void arch_pick_mmap_layout(struct mm_struct *mm);
46653 extern unsigned long
46654 arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
46655 @@ -621,6 +624,15 @@ struct signal_struct {
46656 struct tty_audit_buf *tty_audit_buf;
46657 #endif
46658
46659 +#ifdef CONFIG_GRKERNSEC
46660 + u32 curr_ip;
46661 + u32 gr_saddr;
46662 + u32 gr_daddr;
46663 + u16 gr_sport;
46664 + u16 gr_dport;
46665 + u8 used_accept:1;
46666 +#endif
46667 +
46668 int oom_adj; /* OOM kill score adjustment (bit shift) */
46669 int oom_score_adj; /* OOM kill score adjustment */
46670 };
46671 @@ -1162,7 +1174,7 @@ struct rcu_node;
46672
46673 struct task_struct {
46674 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
46675 - void *stack;
46676 + struct thread_info *stack;
46677 atomic_t usage;
46678 unsigned int flags; /* per process flags, defined below */
46679 unsigned int ptrace;
46680 @@ -1270,8 +1282,8 @@ struct task_struct {
46681 struct list_head thread_group;
46682
46683 struct completion *vfork_done; /* for vfork() */
46684 - int __user *set_child_tid; /* CLONE_CHILD_SETTID */
46685 - int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
46686 + pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
46687 + pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
46688
46689 cputime_t utime, stime, utimescaled, stimescaled;
46690 cputime_t gtime;
46691 @@ -1287,16 +1299,6 @@ struct task_struct {
46692 struct task_cputime cputime_expires;
46693 struct list_head cpu_timers[3];
46694
46695 -/* process credentials */
46696 - const struct cred *real_cred; /* objective and real subjective task
46697 - * credentials (COW) */
46698 - const struct cred *cred; /* effective (overridable) subjective task
46699 - * credentials (COW) */
46700 - struct mutex cred_guard_mutex; /* guard against foreign influences on
46701 - * credential calculations
46702 - * (notably. ptrace) */
46703 - struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */
46704 -
46705 char comm[TASK_COMM_LEN]; /* executable name excluding path
46706 - access with [gs]et_task_comm (which lock
46707 it with task_lock())
46708 @@ -1380,6 +1382,15 @@ struct task_struct {
46709 int softirqs_enabled;
46710 int softirq_context;
46711 #endif
46712 +
46713 +/* process credentials */
46714 + const struct cred *real_cred; /* objective and real subjective task
46715 + * credentials (COW) */
46716 + struct mutex cred_guard_mutex; /* guard against foreign influences on
46717 + * credential calculations
46718 + * (notably. ptrace) */
46719 + struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */
46720 +
46721 #ifdef CONFIG_LOCKDEP
46722 # define MAX_LOCK_DEPTH 48UL
46723 u64 curr_chain_key;
46724 @@ -1400,6 +1411,9 @@ struct task_struct {
46725
46726 struct backing_dev_info *backing_dev_info;
46727
46728 + const struct cred *cred; /* effective (overridable) subjective task
46729 + * credentials (COW) */
46730 +
46731 struct io_context *io_context;
46732
46733 unsigned long ptrace_message;
46734 @@ -1465,6 +1479,20 @@ struct task_struct {
46735 unsigned long default_timer_slack_ns;
46736
46737 struct list_head *scm_work_list;
46738 +
46739 +#ifdef CONFIG_GRKERNSEC
46740 + /* grsecurity */
46741 + struct dentry *gr_chroot_dentry;
46742 + struct acl_subject_label *acl;
46743 + struct acl_role_label *role;
46744 + struct file *exec_file;
46745 + u16 acl_role_id;
46746 + u8 acl_sp_role;
46747 + u8 is_writable;
46748 + u8 brute;
46749 + u8 gr_is_chrooted;
46750 +#endif
46751 +
46752 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
46753 /* Index of current stored address in ret_stack */
46754 int curr_ret_stack;
46755 @@ -1496,6 +1524,52 @@ struct task_struct {
46756 #endif
46757 };
46758
46759 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
46760 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
46761 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
46762 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
46763 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
46764 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
46765 +
46766 +#ifdef CONFIG_PAX_SOFTMODE
46767 +extern unsigned int pax_softmode;
46768 +#endif
46769 +
46770 +extern int pax_check_flags(unsigned long *);
46771 +
46772 +/* if tsk != current then task_lock must be held on it */
46773 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
46774 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
46775 +{
46776 + if (likely(tsk->mm))
46777 + return tsk->mm->pax_flags;
46778 + else
46779 + return 0UL;
46780 +}
46781 +
46782 +/* if tsk != current then task_lock must be held on it */
46783 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
46784 +{
46785 + if (likely(tsk->mm)) {
46786 + tsk->mm->pax_flags = flags;
46787 + return 0;
46788 + }
46789 + return -EINVAL;
46790 +}
46791 +#endif
46792 +
46793 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
46794 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
46795 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
46796 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
46797 +#endif
46798 +
46799 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
46800 +void pax_report_insns(void *pc, void *sp);
46801 +void pax_report_refcount_overflow(struct pt_regs *regs);
46802 +void pax_report_leak_to_user(const void *ptr, unsigned long len);
46803 +void pax_report_overflow_from_user(const void *ptr, unsigned long len);
46804 +
46805 /* Future-safe accessor for struct task_struct's cpus_allowed. */
46806 #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
46807
46808 @@ -2103,7 +2177,7 @@ extern void __cleanup_sighand(struct sig
46809 extern void exit_itimers(struct signal_struct *);
46810 extern void flush_itimer_signals(void);
46811
46812 -extern NORET_TYPE void do_group_exit(int);
46813 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
46814
46815 extern void daemonize(const char *, ...);
46816 extern int allow_signal(int);
46817 @@ -2221,8 +2295,8 @@ static inline void unlock_task_sighand(s
46818
46819 #ifndef __HAVE_THREAD_FUNCTIONS
46820
46821 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
46822 -#define task_stack_page(task) ((task)->stack)
46823 +#define task_thread_info(task) ((task)->stack)
46824 +#define task_stack_page(task) ((void *)(task)->stack)
46825
46826 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
46827 {
46828 @@ -2237,13 +2311,17 @@ static inline unsigned long *end_of_stac
46829
46830 #endif
46831
46832 -static inline int object_is_on_stack(void *obj)
46833 +static inline int object_starts_on_stack(void *obj)
46834 {
46835 - void *stack = task_stack_page(current);
46836 + const void *stack = task_stack_page(current);
46837
46838 return (obj >= stack) && (obj < (stack + THREAD_SIZE));
46839 }
46840
46841 +#ifdef CONFIG_PAX_USERCOPY
46842 +extern int object_is_on_stack(const void *obj, unsigned long len);
46843 +#endif
46844 +
46845 extern void thread_info_cache_init(void);
46846
46847 #ifdef CONFIG_DEBUG_STACK_USAGE
46848 diff -urNp linux-2.6.36/include/linux/screen_info.h linux-2.6.36/include/linux/screen_info.h
46849 --- linux-2.6.36/include/linux/screen_info.h 2010-10-20 16:30:22.000000000 -0400
46850 +++ linux-2.6.36/include/linux/screen_info.h 2010-11-06 18:58:15.000000000 -0400
46851 @@ -43,7 +43,8 @@ struct screen_info {
46852 __u16 pages; /* 0x32 */
46853 __u16 vesa_attributes; /* 0x34 */
46854 __u32 capabilities; /* 0x36 */
46855 - __u8 _reserved[6]; /* 0x3a */
46856 + __u16 vesapm_size; /* 0x3a */
46857 + __u8 _reserved[4]; /* 0x3c */
46858 } __attribute__((packed));
46859
46860 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
46861 diff -urNp linux-2.6.36/include/linux/security.h linux-2.6.36/include/linux/security.h
46862 --- linux-2.6.36/include/linux/security.h 2010-10-20 16:30:22.000000000 -0400
46863 +++ linux-2.6.36/include/linux/security.h 2010-11-06 18:58:50.000000000 -0400
46864 @@ -35,6 +35,7 @@
46865 #include <linux/key.h>
46866 #include <linux/xfrm.h>
46867 #include <linux/slab.h>
46868 +#include <linux/grsecurity.h>
46869 #include <net/flow.h>
46870
46871 /* Maximum number of letters for an LSM name string */
46872 diff -urNp linux-2.6.36/include/linux/shm.h linux-2.6.36/include/linux/shm.h
46873 --- linux-2.6.36/include/linux/shm.h 2010-10-20 16:30:22.000000000 -0400
46874 +++ linux-2.6.36/include/linux/shm.h 2010-11-06 18:58:50.000000000 -0400
46875 @@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
46876 pid_t shm_cprid;
46877 pid_t shm_lprid;
46878 struct user_struct *mlock_user;
46879 +#ifdef CONFIG_GRKERNSEC
46880 + time_t shm_createtime;
46881 + pid_t shm_lapid;
46882 +#endif
46883 };
46884
46885 /* shm_mode upper byte flags */
46886 diff -urNp linux-2.6.36/include/linux/slab.h linux-2.6.36/include/linux/slab.h
46887 --- linux-2.6.36/include/linux/slab.h 2010-10-20 16:30:22.000000000 -0400
46888 +++ linux-2.6.36/include/linux/slab.h 2010-11-06 18:58:15.000000000 -0400
46889 @@ -11,6 +11,7 @@
46890
46891 #include <linux/gfp.h>
46892 #include <linux/types.h>
46893 +#include <linux/err.h>
46894
46895 /*
46896 * Flags to pass to kmem_cache_create().
46897 @@ -87,10 +88,13 @@
46898 * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
46899 * Both make kfree a no-op.
46900 */
46901 -#define ZERO_SIZE_PTR ((void *)16)
46902 +#define ZERO_SIZE_PTR \
46903 +({ \
46904 + BUILD_BUG_ON(!(MAX_ERRNO & ~PAGE_MASK));\
46905 + (void *)(-MAX_ERRNO-1L); \
46906 +})
46907
46908 -#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
46909 - (unsigned long)ZERO_SIZE_PTR)
46910 +#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) - 1 >= (unsigned long)ZERO_SIZE_PTR - 1)
46911
46912 /*
46913 * struct kmem_cache related prototypes
46914 @@ -144,6 +148,7 @@ void * __must_check krealloc(const void
46915 void kfree(const void *);
46916 void kzfree(const void *);
46917 size_t ksize(const void *);
46918 +void check_object_size(const void *ptr, unsigned long n, bool to);
46919
46920 /*
46921 * Allocator specific definitions. These are mainly used to establish optimized
46922 @@ -336,4 +341,37 @@ static inline void *kzalloc_node(size_t
46923
46924 void __init kmem_cache_init_late(void);
46925
46926 +#define kmalloc(x, y) \
46927 +({ \
46928 + void *___retval; \
46929 + intoverflow_t ___x = (intoverflow_t)x; \
46930 + if (WARN(___x > ULONG_MAX, "kmalloc size overflow\n"))\
46931 + ___retval = NULL; \
46932 + else \
46933 + ___retval = kmalloc((size_t)___x, (y)); \
46934 + ___retval; \
46935 +})
46936 +
46937 +#define kmalloc_node(x, y, z) \
46938 +({ \
46939 + void *___retval; \
46940 + intoverflow_t ___x = (intoverflow_t)x; \
46941 + if (WARN(___x > ULONG_MAX, "kmalloc_node size overflow\n"))\
46942 + ___retval = NULL; \
46943 + else \
46944 + ___retval = kmalloc_node((size_t)___x, (y), (z));\
46945 + ___retval; \
46946 +})
46947 +
46948 +#define kzalloc(x, y) \
46949 +({ \
46950 + void *___retval; \
46951 + intoverflow_t ___x = (intoverflow_t)x; \
46952 + if (WARN(___x > ULONG_MAX, "kzalloc size overflow\n"))\
46953 + ___retval = NULL; \
46954 + else \
46955 + ___retval = kzalloc((size_t)___x, (y)); \
46956 + ___retval; \
46957 +})
46958 +
46959 #endif /* _LINUX_SLAB_H */
46960 diff -urNp linux-2.6.36/include/linux/slub_def.h linux-2.6.36/include/linux/slub_def.h
46961 --- linux-2.6.36/include/linux/slub_def.h 2010-10-20 16:30:22.000000000 -0400
46962 +++ linux-2.6.36/include/linux/slub_def.h 2010-11-06 18:58:15.000000000 -0400
46963 @@ -80,7 +80,7 @@ struct kmem_cache {
46964 struct kmem_cache_order_objects max;
46965 struct kmem_cache_order_objects min;
46966 gfp_t allocflags; /* gfp flags to use on each alloc */
46967 - int refcount; /* Refcount for slab cache destroy */
46968 + atomic_t refcount; /* Refcount for slab cache destroy */
46969 void (*ctor)(void *);
46970 int inuse; /* Offset to metadata */
46971 int align; /* Alignment */
46972 diff -urNp linux-2.6.36/include/linux/sonet.h linux-2.6.36/include/linux/sonet.h
46973 --- linux-2.6.36/include/linux/sonet.h 2010-10-20 16:30:22.000000000 -0400
46974 +++ linux-2.6.36/include/linux/sonet.h 2010-11-06 18:58:15.000000000 -0400
46975 @@ -61,7 +61,7 @@ struct sonet_stats {
46976 #include <asm/atomic.h>
46977
46978 struct k_sonet_stats {
46979 -#define __HANDLE_ITEM(i) atomic_t i
46980 +#define __HANDLE_ITEM(i) atomic_unchecked_t i
46981 __SONET_ITEMS
46982 #undef __HANDLE_ITEM
46983 };
46984 diff -urNp linux-2.6.36/include/linux/suspend.h linux-2.6.36/include/linux/suspend.h
46985 --- linux-2.6.36/include/linux/suspend.h 2010-10-20 16:30:22.000000000 -0400
46986 +++ linux-2.6.36/include/linux/suspend.h 2010-11-06 18:58:15.000000000 -0400
46987 @@ -106,15 +106,15 @@ typedef int __bitwise suspend_state_t;
46988 * which require special recovery actions in that situation.
46989 */
46990 struct platform_suspend_ops {
46991 - int (*valid)(suspend_state_t state);
46992 - int (*begin)(suspend_state_t state);
46993 - int (*prepare)(void);
46994 - int (*prepare_late)(void);
46995 - int (*enter)(suspend_state_t state);
46996 - void (*wake)(void);
46997 - void (*finish)(void);
46998 - void (*end)(void);
46999 - void (*recover)(void);
47000 + int (* const valid)(suspend_state_t state);
47001 + int (* const begin)(suspend_state_t state);
47002 + int (* const prepare)(void);
47003 + int (* const prepare_late)(void);
47004 + int (* const enter)(suspend_state_t state);
47005 + void (* const wake)(void);
47006 + void (* const finish)(void);
47007 + void (* const end)(void);
47008 + void (* const recover)(void);
47009 };
47010
47011 #ifdef CONFIG_SUSPEND
47012 @@ -122,7 +122,7 @@ struct platform_suspend_ops {
47013 * suspend_set_ops - set platform dependent suspend operations
47014 * @ops: The new suspend operations to set.
47015 */
47016 -extern void suspend_set_ops(struct platform_suspend_ops *ops);
47017 +extern void suspend_set_ops(const struct platform_suspend_ops *ops);
47018 extern int suspend_valid_only_mem(suspend_state_t state);
47019
47020 /**
47021 @@ -147,7 +147,7 @@ extern int pm_suspend(suspend_state_t st
47022 #else /* !CONFIG_SUSPEND */
47023 #define suspend_valid_only_mem NULL
47024
47025 -static inline void suspend_set_ops(struct platform_suspend_ops *ops) {}
47026 +static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {}
47027 static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
47028 #endif /* !CONFIG_SUSPEND */
47029
47030 @@ -217,16 +217,16 @@ extern void mark_free_pages(struct zone
47031 * platforms which require special recovery actions in that situation.
47032 */
47033 struct platform_hibernation_ops {
47034 - int (*begin)(void);
47035 - void (*end)(void);
47036 - int (*pre_snapshot)(void);
47037 - void (*finish)(void);
47038 - int (*prepare)(void);
47039 - int (*enter)(void);
47040 - void (*leave)(void);
47041 - int (*pre_restore)(void);
47042 - void (*restore_cleanup)(void);
47043 - void (*recover)(void);
47044 + int (* const begin)(void);
47045 + void (* const end)(void);
47046 + int (* const pre_snapshot)(void);
47047 + void (* const finish)(void);
47048 + int (* const prepare)(void);
47049 + int (* const enter)(void);
47050 + void (* const leave)(void);
47051 + int (* const pre_restore)(void);
47052 + void (* const restore_cleanup)(void);
47053 + void (* const recover)(void);
47054 };
47055
47056 #ifdef CONFIG_HIBERNATION
47057 @@ -245,7 +245,7 @@ extern void swsusp_set_page_free(struct
47058 extern void swsusp_unset_page_free(struct page *);
47059 extern unsigned long get_safe_page(gfp_t gfp_mask);
47060
47061 -extern void hibernation_set_ops(struct platform_hibernation_ops *ops);
47062 +extern void hibernation_set_ops(const struct platform_hibernation_ops *ops);
47063 extern int hibernate(void);
47064 extern bool system_entering_hibernation(void);
47065 #else /* CONFIG_HIBERNATION */
47066 @@ -253,7 +253,7 @@ static inline int swsusp_page_is_forbidd
47067 static inline void swsusp_set_page_free(struct page *p) {}
47068 static inline void swsusp_unset_page_free(struct page *p) {}
47069
47070 -static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {}
47071 +static inline void hibernation_set_ops(const struct platform_hibernation_ops *ops) {}
47072 static inline int hibernate(void) { return -ENOSYS; }
47073 static inline bool system_entering_hibernation(void) { return false; }
47074 #endif /* CONFIG_HIBERNATION */
47075 diff -urNp linux-2.6.36/include/linux/sysctl.h linux-2.6.36/include/linux/sysctl.h
47076 --- linux-2.6.36/include/linux/sysctl.h 2010-10-20 16:30:22.000000000 -0400
47077 +++ linux-2.6.36/include/linux/sysctl.h 2010-11-06 18:58:15.000000000 -0400
47078 @@ -155,7 +155,11 @@ enum
47079 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
47080 };
47081
47082 -
47083 +#ifdef CONFIG_PAX_SOFTMODE
47084 +enum {
47085 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
47086 +};
47087 +#endif
47088
47089 /* CTL_VM names: */
47090 enum
47091 diff -urNp linux-2.6.36/include/linux/sysfs.h linux-2.6.36/include/linux/sysfs.h
47092 --- linux-2.6.36/include/linux/sysfs.h 2010-10-20 16:30:22.000000000 -0400
47093 +++ linux-2.6.36/include/linux/sysfs.h 2010-11-06 18:58:15.000000000 -0400
47094 @@ -110,8 +110,8 @@ struct bin_attribute {
47095 #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr)
47096
47097 struct sysfs_ops {
47098 - ssize_t (*show)(struct kobject *, struct attribute *,char *);
47099 - ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
47100 + ssize_t (* const show)(struct kobject *, struct attribute *,char *);
47101 + ssize_t (* const store)(struct kobject *,struct attribute *,const char *, size_t);
47102 };
47103
47104 struct sysfs_dirent;
47105 diff -urNp linux-2.6.36/include/linux/thread_info.h linux-2.6.36/include/linux/thread_info.h
47106 --- linux-2.6.36/include/linux/thread_info.h 2010-10-20 16:30:22.000000000 -0400
47107 +++ linux-2.6.36/include/linux/thread_info.h 2010-11-06 18:58:15.000000000 -0400
47108 @@ -23,7 +23,7 @@ struct restart_block {
47109 };
47110 /* For futex_wait and futex_wait_requeue_pi */
47111 struct {
47112 - u32 *uaddr;
47113 + u32 __user *uaddr;
47114 u32 val;
47115 u32 flags;
47116 u32 bitset;
47117 diff -urNp linux-2.6.36/include/linux/tty.h linux-2.6.36/include/linux/tty.h
47118 --- linux-2.6.36/include/linux/tty.h 2010-10-20 16:30:22.000000000 -0400
47119 +++ linux-2.6.36/include/linux/tty.h 2010-11-06 18:58:15.000000000 -0400
47120 @@ -13,6 +13,7 @@
47121 #include <linux/tty_driver.h>
47122 #include <linux/tty_ldisc.h>
47123 #include <linux/mutex.h>
47124 +#include <linux/poll.h>
47125 #include <linux/smp_lock.h>
47126
47127 #include <asm/system.h>
47128 @@ -463,7 +464,6 @@ extern int tty_perform_flush(struct tty_
47129 extern dev_t tty_devnum(struct tty_struct *tty);
47130 extern void proc_clear_tty(struct task_struct *p);
47131 extern struct tty_struct *get_current_tty(void);
47132 -extern void tty_default_fops(struct file_operations *fops);
47133 extern struct tty_struct *alloc_tty_struct(void);
47134 extern void tty_add_file(struct tty_struct *tty, struct file *file);
47135 extern void free_tty_struct(struct tty_struct *tty);
47136 @@ -526,6 +526,18 @@ extern void tty_ldisc_begin(void);
47137 /* This last one is just for the tty layer internals and shouldn't be used elsewhere */
47138 extern void tty_ldisc_enable(struct tty_struct *tty);
47139
47140 +/* tty_io.c */
47141 +extern ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
47142 +extern ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
47143 +extern unsigned int tty_poll(struct file *, poll_table *);
47144 +#ifdef CONFIG_COMPAT
47145 +extern long tty_compat_ioctl(struct file *file, unsigned int cmd,
47146 + unsigned long arg);
47147 +#else
47148 +#define tty_compat_ioctl NULL
47149 +#endif
47150 +extern int tty_release(struct inode *, struct file *);
47151 +extern int tty_fasync(int fd, struct file *filp, int on);
47152
47153 /* n_tty.c */
47154 extern struct tty_ldisc_ops tty_ldisc_N_TTY;
47155 diff -urNp linux-2.6.36/include/linux/tty_ldisc.h linux-2.6.36/include/linux/tty_ldisc.h
47156 --- linux-2.6.36/include/linux/tty_ldisc.h 2010-10-20 16:30:22.000000000 -0400
47157 +++ linux-2.6.36/include/linux/tty_ldisc.h 2010-11-06 18:58:15.000000000 -0400
47158 @@ -147,7 +147,7 @@ struct tty_ldisc_ops {
47159
47160 struct module *owner;
47161
47162 - int refcount;
47163 + atomic_t refcount;
47164 };
47165
47166 struct tty_ldisc {
47167 diff -urNp linux-2.6.36/include/linux/types.h linux-2.6.36/include/linux/types.h
47168 --- linux-2.6.36/include/linux/types.h 2010-10-20 16:30:22.000000000 -0400
47169 +++ linux-2.6.36/include/linux/types.h 2010-11-06 18:58:15.000000000 -0400
47170 @@ -207,10 +207,26 @@ typedef struct {
47171 int counter;
47172 } atomic_t;
47173
47174 +#ifdef CONFIG_PAX_REFCOUNT
47175 +typedef struct {
47176 + int counter;
47177 +} atomic_unchecked_t;
47178 +#else
47179 +typedef atomic_t atomic_unchecked_t;
47180 +#endif
47181 +
47182 #ifdef CONFIG_64BIT
47183 typedef struct {
47184 long counter;
47185 } atomic64_t;
47186 +
47187 +#ifdef CONFIG_PAX_REFCOUNT
47188 +typedef struct {
47189 + long counter;
47190 +} atomic64_unchecked_t;
47191 +#else
47192 +typedef atomic64_t atomic64_unchecked_t;
47193 +#endif
47194 #endif
47195
47196 struct list_head {
47197 diff -urNp linux-2.6.36/include/linux/uaccess.h linux-2.6.36/include/linux/uaccess.h
47198 --- linux-2.6.36/include/linux/uaccess.h 2010-10-20 16:30:22.000000000 -0400
47199 +++ linux-2.6.36/include/linux/uaccess.h 2010-11-06 18:58:15.000000000 -0400
47200 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
47201 long ret; \
47202 mm_segment_t old_fs = get_fs(); \
47203 \
47204 - set_fs(KERNEL_DS); \
47205 pagefault_disable(); \
47206 + set_fs(KERNEL_DS); \
47207 ret = __copy_from_user_inatomic(&(retval), (__force typeof(retval) __user *)(addr), sizeof(retval)); \
47208 - pagefault_enable(); \
47209 set_fs(old_fs); \
47210 + pagefault_enable(); \
47211 ret; \
47212 })
47213
47214 @@ -93,8 +93,8 @@ static inline unsigned long __copy_from_
47215 * Safely read from address @src to the buffer at @dst. If a kernel fault
47216 * happens, handle that and return -EFAULT.
47217 */
47218 -extern long probe_kernel_read(void *dst, void *src, size_t size);
47219 -extern long __probe_kernel_read(void *dst, void *src, size_t size);
47220 +extern long probe_kernel_read(void *dst, const void *src, size_t size);
47221 +extern long __probe_kernel_read(void *dst, const void *src, size_t size);
47222
47223 /*
47224 * probe_kernel_write(): safely attempt to write to a location
47225 @@ -105,7 +105,7 @@ extern long __probe_kernel_read(void *ds
47226 * Safely write to address @dst from the buffer at @src. If a kernel fault
47227 * happens, handle that and return -EFAULT.
47228 */
47229 -extern long notrace probe_kernel_write(void *dst, void *src, size_t size);
47230 -extern long notrace __probe_kernel_write(void *dst, void *src, size_t size);
47231 +extern long notrace probe_kernel_write(void *dst, const void *src, size_t size);
47232 +extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size);
47233
47234 #endif /* __LINUX_UACCESS_H__ */
47235 diff -urNp linux-2.6.36/include/linux/usb/hcd.h linux-2.6.36/include/linux/usb/hcd.h
47236 --- linux-2.6.36/include/linux/usb/hcd.h 2010-10-20 16:30:22.000000000 -0400
47237 +++ linux-2.6.36/include/linux/usb/hcd.h 2010-11-06 18:58:15.000000000 -0400
47238 @@ -578,7 +578,7 @@ struct usb_mon_operations {
47239 /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
47240 };
47241
47242 -extern struct usb_mon_operations *mon_ops;
47243 +extern const struct usb_mon_operations *mon_ops;
47244
47245 static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb)
47246 {
47247 @@ -600,7 +600,7 @@ static inline void usbmon_urb_complete(s
47248 (*mon_ops->urb_complete)(bus, urb, status);
47249 }
47250
47251 -int usb_mon_register(struct usb_mon_operations *ops);
47252 +int usb_mon_register(const struct usb_mon_operations *ops);
47253 void usb_mon_deregister(void);
47254
47255 #else
47256 diff -urNp linux-2.6.36/include/linux/vmalloc.h linux-2.6.36/include/linux/vmalloc.h
47257 --- linux-2.6.36/include/linux/vmalloc.h 2010-10-20 16:30:22.000000000 -0400
47258 +++ linux-2.6.36/include/linux/vmalloc.h 2010-11-06 18:58:15.000000000 -0400
47259 @@ -15,6 +15,11 @@ extern bool vmap_lazy_unmap;
47260 #define VM_MAP 0x00000004 /* vmap()ed pages */
47261 #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
47262 #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
47263 +
47264 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86) && defined(CONFIG_PAX_KERNEXEC)
47265 +#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
47266 +#endif
47267 +
47268 /* bits [20..32] reserved for arch specific ioremap internals */
47269
47270 /*
47271 @@ -123,4 +128,81 @@ struct vm_struct **pcpu_get_vm_areas(con
47272
47273 void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms);
47274
47275 +#define vmalloc(x) \
47276 +({ \
47277 + void *___retval; \
47278 + intoverflow_t ___x = (intoverflow_t)x; \
47279 + if (WARN(___x > ULONG_MAX, "vmalloc size overflow\n")) \
47280 + ___retval = NULL; \
47281 + else \
47282 + ___retval = vmalloc((unsigned long)___x); \
47283 + ___retval; \
47284 +})
47285 +
47286 +#define __vmalloc(x, y, z) \
47287 +({ \
47288 + void *___retval; \
47289 + intoverflow_t ___x = (intoverflow_t)x; \
47290 + if (WARN(___x > ULONG_MAX, "__vmalloc size overflow\n"))\
47291 + ___retval = NULL; \
47292 + else \
47293 + ___retval = __vmalloc((unsigned long)___x, (y), (z));\
47294 + ___retval; \
47295 +})
47296 +
47297 +#define vmalloc_user(x) \
47298 +({ \
47299 + void *___retval; \
47300 + intoverflow_t ___x = (intoverflow_t)x; \
47301 + if (WARN(___x > ULONG_MAX, "vmalloc_user size overflow\n"))\
47302 + ___retval = NULL; \
47303 + else \
47304 + ___retval = vmalloc_user((unsigned long)___x); \
47305 + ___retval; \
47306 +})
47307 +
47308 +#define vmalloc_exec(x) \
47309 +({ \
47310 + void *___retval; \
47311 + intoverflow_t ___x = (intoverflow_t)x; \
47312 + if (WARN(___x > ULONG_MAX, "vmalloc_exec size overflow\n"))\
47313 + ___retval = NULL; \
47314 + else \
47315 + ___retval = vmalloc_exec((unsigned long)___x); \
47316 + ___retval; \
47317 +})
47318 +
47319 +#define vmalloc_node(x, y) \
47320 +({ \
47321 + void *___retval; \
47322 + intoverflow_t ___x = (intoverflow_t)x; \
47323 + if (WARN(___x > ULONG_MAX, "vmalloc_node size overflow\n"))\
47324 + ___retval = NULL; \
47325 + else \
47326 + ___retval = vmalloc_node((unsigned long)___x, (y));\
47327 + ___retval; \
47328 +})
47329 +
47330 +#define vmalloc_32(x) \
47331 +({ \
47332 + void *___retval; \
47333 + intoverflow_t ___x = (intoverflow_t)x; \
47334 + if (WARN(___x > ULONG_MAX, "vmalloc_32 size overflow\n"))\
47335 + ___retval = NULL; \
47336 + else \
47337 + ___retval = vmalloc_32((unsigned long)___x); \
47338 + ___retval; \
47339 +})
47340 +
47341 +#define vmalloc_32_user(x) \
47342 +({ \
47343 + void *___retval; \
47344 + intoverflow_t ___x = (intoverflow_t)x; \
47345 + if (WARN(___x > ULONG_MAX, "vmalloc_32_user size overflow\n"))\
47346 + ___retval = NULL; \
47347 + else \
47348 + ___retval = vmalloc_32_user((unsigned long)___x);\
47349 + ___retval; \
47350 +})
47351 +
47352 #endif /* _LINUX_VMALLOC_H */
47353 diff -urNp linux-2.6.36/include/linux/vmstat.h linux-2.6.36/include/linux/vmstat.h
47354 --- linux-2.6.36/include/linux/vmstat.h 2010-10-20 16:30:22.000000000 -0400
47355 +++ linux-2.6.36/include/linux/vmstat.h 2010-11-06 18:58:15.000000000 -0400
47356 @@ -140,18 +140,18 @@ static inline void vm_events_fold_cpu(in
47357 /*
47358 * Zone based page accounting with per cpu differentials.
47359 */
47360 -extern atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
47361 +extern atomic_long_unchecked_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
47362
47363 static inline void zone_page_state_add(long x, struct zone *zone,
47364 enum zone_stat_item item)
47365 {
47366 - atomic_long_add(x, &zone->vm_stat[item]);
47367 - atomic_long_add(x, &vm_stat[item]);
47368 + atomic_long_add_unchecked(x, &zone->vm_stat[item]);
47369 + atomic_long_add_unchecked(x, &vm_stat[item]);
47370 }
47371
47372 static inline unsigned long global_page_state(enum zone_stat_item item)
47373 {
47374 - long x = atomic_long_read(&vm_stat[item]);
47375 + long x = atomic_long_read_unchecked(&vm_stat[item]);
47376 #ifdef CONFIG_SMP
47377 if (x < 0)
47378 x = 0;
47379 @@ -162,7 +162,7 @@ static inline unsigned long global_page_
47380 static inline unsigned long zone_page_state(struct zone *zone,
47381 enum zone_stat_item item)
47382 {
47383 - long x = atomic_long_read(&zone->vm_stat[item]);
47384 + long x = atomic_long_read_unchecked(&zone->vm_stat[item]);
47385 #ifdef CONFIG_SMP
47386 if (x < 0)
47387 x = 0;
47388 @@ -179,7 +179,7 @@ static inline unsigned long zone_page_st
47389 static inline unsigned long zone_page_state_snapshot(struct zone *zone,
47390 enum zone_stat_item item)
47391 {
47392 - long x = atomic_long_read(&zone->vm_stat[item]);
47393 + long x = atomic_long_read_unchecked(&zone->vm_stat[item]);
47394
47395 #ifdef CONFIG_SMP
47396 int cpu;
47397 @@ -268,8 +268,8 @@ static inline void __mod_zone_page_state
47398
47399 static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
47400 {
47401 - atomic_long_inc(&zone->vm_stat[item]);
47402 - atomic_long_inc(&vm_stat[item]);
47403 + atomic_long_inc_unchecked(&zone->vm_stat[item]);
47404 + atomic_long_inc_unchecked(&vm_stat[item]);
47405 }
47406
47407 static inline void __inc_zone_page_state(struct page *page,
47408 @@ -280,8 +280,8 @@ static inline void __inc_zone_page_state
47409
47410 static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
47411 {
47412 - atomic_long_dec(&zone->vm_stat[item]);
47413 - atomic_long_dec(&vm_stat[item]);
47414 + atomic_long_dec_unchecked(&zone->vm_stat[item]);
47415 + atomic_long_dec_unchecked(&vm_stat[item]);
47416 }
47417
47418 static inline void __dec_zone_page_state(struct page *page,
47419 diff -urNp linux-2.6.36/include/net/inetpeer.h linux-2.6.36/include/net/inetpeer.h
47420 --- linux-2.6.36/include/net/inetpeer.h 2010-10-20 16:30:22.000000000 -0400
47421 +++ linux-2.6.36/include/net/inetpeer.h 2010-11-06 18:58:15.000000000 -0400
47422 @@ -30,8 +30,8 @@ struct inet_peer {
47423 */
47424 union {
47425 struct {
47426 - atomic_t rid; /* Frag reception counter */
47427 - atomic_t ip_id_count; /* IP ID for the next packet */
47428 + atomic_unchecked_t rid; /* Frag reception counter */
47429 + atomic_unchecked_t ip_id_count; /* IP ID for the next packet */
47430 __u32 tcp_ts;
47431 __u32 tcp_ts_stamp;
47432 };
47433 @@ -62,7 +62,7 @@ static inline __u16 inet_getid(struct in
47434 {
47435 more++;
47436 inet_peer_refcheck(p);
47437 - return atomic_add_return(more, &p->ip_id_count) - more;
47438 + return atomic_add_return_unchecked(more, &p->ip_id_count) - more;
47439 }
47440
47441 #endif /* _NET_INETPEER_H */
47442 diff -urNp linux-2.6.36/include/net/irda/ircomm_tty.h linux-2.6.36/include/net/irda/ircomm_tty.h
47443 --- linux-2.6.36/include/net/irda/ircomm_tty.h 2010-10-20 16:30:22.000000000 -0400
47444 +++ linux-2.6.36/include/net/irda/ircomm_tty.h 2010-11-06 18:58:15.000000000 -0400
47445 @@ -105,8 +105,8 @@ struct ircomm_tty_cb {
47446 unsigned short close_delay;
47447 unsigned short closing_wait; /* time to wait before closing */
47448
47449 - int open_count;
47450 - int blocked_open; /* # of blocked opens */
47451 + atomic_t open_count;
47452 + atomic_t blocked_open; /* # of blocked opens */
47453
47454 /* Protect concurent access to :
47455 * o self->open_count
47456 diff -urNp linux-2.6.36/include/net/neighbour.h linux-2.6.36/include/net/neighbour.h
47457 --- linux-2.6.36/include/net/neighbour.h 2010-10-20 16:30:22.000000000 -0400
47458 +++ linux-2.6.36/include/net/neighbour.h 2010-11-06 18:58:15.000000000 -0400
47459 @@ -116,12 +116,12 @@ struct neighbour {
47460
47461 struct neigh_ops {
47462 int family;
47463 - void (*solicit)(struct neighbour *, struct sk_buff*);
47464 - void (*error_report)(struct neighbour *, struct sk_buff*);
47465 - int (*output)(struct sk_buff*);
47466 - int (*connected_output)(struct sk_buff*);
47467 - int (*hh_output)(struct sk_buff*);
47468 - int (*queue_xmit)(struct sk_buff*);
47469 + void (* const solicit)(struct neighbour *, struct sk_buff*);
47470 + void (* const error_report)(struct neighbour *, struct sk_buff*);
47471 + int (* const output)(struct sk_buff*);
47472 + int (* const connected_output)(struct sk_buff*);
47473 + int (* const hh_output)(struct sk_buff*);
47474 + int (* const queue_xmit)(struct sk_buff*);
47475 };
47476
47477 struct pneigh_entry {
47478 diff -urNp linux-2.6.36/include/net/sctp/sctp.h linux-2.6.36/include/net/sctp/sctp.h
47479 --- linux-2.6.36/include/net/sctp/sctp.h 2010-10-20 16:30:22.000000000 -0400
47480 +++ linux-2.6.36/include/net/sctp/sctp.h 2010-11-06 18:58:15.000000000 -0400
47481 @@ -305,8 +305,8 @@ extern int sctp_debug_flag;
47482
47483 #else /* SCTP_DEBUG */
47484
47485 -#define SCTP_DEBUG_PRINTK(whatever...)
47486 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
47487 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
47488 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
47489 #define SCTP_ENABLE_DEBUG
47490 #define SCTP_DISABLE_DEBUG
47491 #define SCTP_ASSERT(expr, str, func)
47492 diff -urNp linux-2.6.36/include/net/tcp.h linux-2.6.36/include/net/tcp.h
47493 --- linux-2.6.36/include/net/tcp.h 2010-10-20 16:30:22.000000000 -0400
47494 +++ linux-2.6.36/include/net/tcp.h 2010-11-06 18:58:15.000000000 -0400
47495 @@ -1373,6 +1373,7 @@ enum tcp_seq_states {
47496 struct tcp_seq_afinfo {
47497 char *name;
47498 sa_family_t family;
47499 + /* cannot be const */
47500 struct file_operations seq_fops;
47501 struct seq_operations seq_ops;
47502 };
47503 diff -urNp linux-2.6.36/include/net/udp.h linux-2.6.36/include/net/udp.h
47504 --- linux-2.6.36/include/net/udp.h 2010-10-20 16:30:22.000000000 -0400
47505 +++ linux-2.6.36/include/net/udp.h 2010-11-06 18:58:15.000000000 -0400
47506 @@ -220,6 +220,7 @@ struct udp_seq_afinfo {
47507 char *name;
47508 sa_family_t family;
47509 struct udp_table *udp_table;
47510 + /* cannot be const */
47511 struct file_operations seq_fops;
47512 struct seq_operations seq_ops;
47513 };
47514 diff -urNp linux-2.6.36/include/sound/ac97_codec.h linux-2.6.36/include/sound/ac97_codec.h
47515 --- linux-2.6.36/include/sound/ac97_codec.h 2010-10-20 16:30:22.000000000 -0400
47516 +++ linux-2.6.36/include/sound/ac97_codec.h 2010-11-06 18:58:15.000000000 -0400
47517 @@ -419,15 +419,15 @@
47518 struct snd_ac97;
47519
47520 struct snd_ac97_build_ops {
47521 - int (*build_3d) (struct snd_ac97 *ac97);
47522 - int (*build_specific) (struct snd_ac97 *ac97);
47523 - int (*build_spdif) (struct snd_ac97 *ac97);
47524 - int (*build_post_spdif) (struct snd_ac97 *ac97);
47525 + int (* const build_3d) (struct snd_ac97 *ac97);
47526 + int (* const build_specific) (struct snd_ac97 *ac97);
47527 + int (* const build_spdif) (struct snd_ac97 *ac97);
47528 + int (* const build_post_spdif) (struct snd_ac97 *ac97);
47529 #ifdef CONFIG_PM
47530 - void (*suspend) (struct snd_ac97 *ac97);
47531 - void (*resume) (struct snd_ac97 *ac97);
47532 + void (* const suspend) (struct snd_ac97 *ac97);
47533 + void (* const resume) (struct snd_ac97 *ac97);
47534 #endif
47535 - void (*update_jacks) (struct snd_ac97 *ac97); /* for jack-sharing */
47536 + void (* const update_jacks) (struct snd_ac97 *ac97); /* for jack-sharing */
47537 };
47538
47539 struct snd_ac97_bus_ops {
47540 @@ -477,7 +477,7 @@ struct snd_ac97_template {
47541
47542 struct snd_ac97 {
47543 /* -- lowlevel (hardware) driver specific -- */
47544 - struct snd_ac97_build_ops * build_ops;
47545 + const struct snd_ac97_build_ops * build_ops;
47546 void *private_data;
47547 void (*private_free) (struct snd_ac97 *ac97);
47548 /* --- */
47549 diff -urNp linux-2.6.36/include/trace/events/irq.h linux-2.6.36/include/trace/events/irq.h
47550 --- linux-2.6.36/include/trace/events/irq.h 2010-10-20 16:30:22.000000000 -0400
47551 +++ linux-2.6.36/include/trace/events/irq.h 2010-11-06 18:58:15.000000000 -0400
47552 @@ -34,7 +34,7 @@
47553 */
47554 TRACE_EVENT(irq_handler_entry,
47555
47556 - TP_PROTO(int irq, struct irqaction *action),
47557 + TP_PROTO(int irq, const struct irqaction *action),
47558
47559 TP_ARGS(irq, action),
47560
47561 @@ -64,7 +64,7 @@ TRACE_EVENT(irq_handler_entry,
47562 */
47563 TRACE_EVENT(irq_handler_exit,
47564
47565 - TP_PROTO(int irq, struct irqaction *action, int ret),
47566 + TP_PROTO(int irq, const struct irqaction *action, int ret),
47567
47568 TP_ARGS(irq, action, ret),
47569
47570 @@ -84,7 +84,7 @@ TRACE_EVENT(irq_handler_exit,
47571
47572 DECLARE_EVENT_CLASS(softirq,
47573
47574 - TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
47575 + TP_PROTO(const struct softirq_action *h, const struct softirq_action *vec),
47576
47577 TP_ARGS(h, vec),
47578
47579 @@ -113,7 +113,7 @@ DECLARE_EVENT_CLASS(softirq,
47580 */
47581 DEFINE_EVENT(softirq, softirq_entry,
47582
47583 - TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
47584 + TP_PROTO(const struct softirq_action *h, const struct softirq_action *vec),
47585
47586 TP_ARGS(h, vec)
47587 );
47588 @@ -131,7 +131,7 @@ DEFINE_EVENT(softirq, softirq_entry,
47589 */
47590 DEFINE_EVENT(softirq, softirq_exit,
47591
47592 - TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
47593 + TP_PROTO(const struct softirq_action *h, const struct softirq_action *vec),
47594
47595 TP_ARGS(h, vec)
47596 );
47597 diff -urNp linux-2.6.36/include/video/uvesafb.h linux-2.6.36/include/video/uvesafb.h
47598 --- linux-2.6.36/include/video/uvesafb.h 2010-10-20 16:30:22.000000000 -0400
47599 +++ linux-2.6.36/include/video/uvesafb.h 2010-11-06 18:58:15.000000000 -0400
47600 @@ -177,6 +177,7 @@ struct uvesafb_par {
47601 u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
47602 u8 pmi_setpal; /* PMI for palette changes */
47603 u16 *pmi_base; /* protected mode interface location */
47604 + u8 *pmi_code; /* protected mode code location */
47605 void *pmi_start;
47606 void *pmi_pal;
47607 u8 *vbe_state_orig; /*
47608 diff -urNp linux-2.6.36/init/do_mounts.c linux-2.6.36/init/do_mounts.c
47609 --- linux-2.6.36/init/do_mounts.c 2010-10-20 16:30:22.000000000 -0400
47610 +++ linux-2.6.36/init/do_mounts.c 2010-11-06 18:58:15.000000000 -0400
47611 @@ -217,11 +217,11 @@ static void __init get_fs_names(char *pa
47612
47613 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
47614 {
47615 - int err = sys_mount(name, "/root", fs, flags, data);
47616 + int err = sys_mount((__force char __user *)name, (__force char __user *)"/root", (__force char __user *)fs, flags, (__force void __user *)data);
47617 if (err)
47618 return err;
47619
47620 - sys_chdir("/root");
47621 + sys_chdir((__force char __user *)"/root");
47622 ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
47623 printk("VFS: Mounted root (%s filesystem)%s on device %u:%u.\n",
47624 current->fs->pwd.mnt->mnt_sb->s_type->name,
47625 @@ -312,18 +312,18 @@ void __init change_floppy(char *fmt, ...
47626 va_start(args, fmt);
47627 vsprintf(buf, fmt, args);
47628 va_end(args);
47629 - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
47630 + fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
47631 if (fd >= 0) {
47632 sys_ioctl(fd, FDEJECT, 0);
47633 sys_close(fd);
47634 }
47635 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
47636 - fd = sys_open("/dev/console", O_RDWR, 0);
47637 + fd = sys_open((__force const char __user *)"/dev/console", O_RDWR, 0);
47638 if (fd >= 0) {
47639 sys_ioctl(fd, TCGETS, (long)&termios);
47640 termios.c_lflag &= ~ICANON;
47641 sys_ioctl(fd, TCSETSF, (long)&termios);
47642 - sys_read(fd, &c, 1);
47643 + sys_read(fd, (char __user *)&c, 1);
47644 termios.c_lflag |= ICANON;
47645 sys_ioctl(fd, TCSETSF, (long)&termios);
47646 sys_close(fd);
47647 @@ -417,6 +417,6 @@ void __init prepare_namespace(void)
47648 mount_root();
47649 out:
47650 devtmpfs_mount("dev");
47651 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
47652 - sys_chroot(".");
47653 + sys_mount((__force char __user *)".", (__force char __user *)"/", NULL, MS_MOVE, NULL);
47654 + sys_chroot((__force char __user *)".");
47655 }
47656 diff -urNp linux-2.6.36/init/do_mounts.h linux-2.6.36/init/do_mounts.h
47657 --- linux-2.6.36/init/do_mounts.h 2010-10-20 16:30:22.000000000 -0400
47658 +++ linux-2.6.36/init/do_mounts.h 2010-11-06 18:58:15.000000000 -0400
47659 @@ -15,15 +15,15 @@ extern int root_mountflags;
47660
47661 static inline int create_dev(char *name, dev_t dev)
47662 {
47663 - sys_unlink(name);
47664 - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
47665 + sys_unlink((__force char __user *)name);
47666 + return sys_mknod((__force char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
47667 }
47668
47669 #if BITS_PER_LONG == 32
47670 static inline u32 bstat(char *name)
47671 {
47672 struct stat64 stat;
47673 - if (sys_stat64(name, &stat) != 0)
47674 + if (sys_stat64((__force char __user *)name, (__force struct stat64 __user *)&stat) != 0)
47675 return 0;
47676 if (!S_ISBLK(stat.st_mode))
47677 return 0;
47678 diff -urNp linux-2.6.36/init/do_mounts_initrd.c linux-2.6.36/init/do_mounts_initrd.c
47679 --- linux-2.6.36/init/do_mounts_initrd.c 2010-10-20 16:30:22.000000000 -0400
47680 +++ linux-2.6.36/init/do_mounts_initrd.c 2010-11-06 18:58:15.000000000 -0400
47681 @@ -44,13 +44,13 @@ static void __init handle_initrd(void)
47682 create_dev("/dev/root.old", Root_RAM0);
47683 /* mount initrd on rootfs' /root */
47684 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
47685 - sys_mkdir("/old", 0700);
47686 - root_fd = sys_open("/", 0, 0);
47687 - old_fd = sys_open("/old", 0, 0);
47688 + sys_mkdir((__force const char __user *)"/old", 0700);
47689 + root_fd = sys_open((__force const char __user *)"/", 0, 0);
47690 + old_fd = sys_open((__force const char __user *)"/old", 0, 0);
47691 /* move initrd over / and chdir/chroot in initrd root */
47692 - sys_chdir("/root");
47693 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
47694 - sys_chroot(".");
47695 + sys_chdir((__force const char __user *)"/root");
47696 + sys_mount((__force char __user *)".", (__force char __user *)"/", NULL, MS_MOVE, NULL);
47697 + sys_chroot((__force const char __user *)".");
47698
47699 /*
47700 * In case that a resume from disk is carried out by linuxrc or one of
47701 @@ -67,15 +67,15 @@ static void __init handle_initrd(void)
47702
47703 /* move initrd to rootfs' /old */
47704 sys_fchdir(old_fd);
47705 - sys_mount("/", ".", NULL, MS_MOVE, NULL);
47706 + sys_mount((__force char __user *)"/", (__force char __user *)".", NULL, MS_MOVE, NULL);
47707 /* switch root and cwd back to / of rootfs */
47708 sys_fchdir(root_fd);
47709 - sys_chroot(".");
47710 + sys_chroot((__force const char __user *)".");
47711 sys_close(old_fd);
47712 sys_close(root_fd);
47713
47714 if (new_decode_dev(real_root_dev) == Root_RAM0) {
47715 - sys_chdir("/old");
47716 + sys_chdir((__force const char __user *)"/old");
47717 return;
47718 }
47719
47720 @@ -83,17 +83,17 @@ static void __init handle_initrd(void)
47721 mount_root();
47722
47723 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
47724 - error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
47725 + error = sys_mount((__force char __user *)"/old", (__force char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
47726 if (!error)
47727 printk("okay\n");
47728 else {
47729 - int fd = sys_open("/dev/root.old", O_RDWR, 0);
47730 + int fd = sys_open((__force const char __user *)"/dev/root.old", O_RDWR, 0);
47731 if (error == -ENOENT)
47732 printk("/initrd does not exist. Ignored.\n");
47733 else
47734 printk("failed\n");
47735 printk(KERN_NOTICE "Unmounting old root\n");
47736 - sys_umount("/old", MNT_DETACH);
47737 + sys_umount((__force char __user *)"/old", MNT_DETACH);
47738 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
47739 if (fd < 0) {
47740 error = fd;
47741 @@ -116,11 +116,11 @@ int __init initrd_load(void)
47742 * mounted in the normal path.
47743 */
47744 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
47745 - sys_unlink("/initrd.image");
47746 + sys_unlink((__force const char __user *)"/initrd.image");
47747 handle_initrd();
47748 return 1;
47749 }
47750 }
47751 - sys_unlink("/initrd.image");
47752 + sys_unlink((__force const char __user *)"/initrd.image");
47753 return 0;
47754 }
47755 diff -urNp linux-2.6.36/init/do_mounts_md.c linux-2.6.36/init/do_mounts_md.c
47756 --- linux-2.6.36/init/do_mounts_md.c 2010-10-20 16:30:22.000000000 -0400
47757 +++ linux-2.6.36/init/do_mounts_md.c 2010-11-06 18:58:15.000000000 -0400
47758 @@ -170,7 +170,7 @@ static void __init md_setup_drive(void)
47759 partitioned ? "_d" : "", minor,
47760 md_setup_args[ent].device_names);
47761
47762 - fd = sys_open(name, 0, 0);
47763 + fd = sys_open((__force char __user *)name, 0, 0);
47764 if (fd < 0) {
47765 printk(KERN_ERR "md: open failed - cannot start "
47766 "array %s\n", name);
47767 @@ -233,7 +233,7 @@ static void __init md_setup_drive(void)
47768 * array without it
47769 */
47770 sys_close(fd);
47771 - fd = sys_open(name, 0, 0);
47772 + fd = sys_open((__force char __user *)name, 0, 0);
47773 sys_ioctl(fd, BLKRRPART, 0);
47774 }
47775 sys_close(fd);
47776 @@ -283,7 +283,7 @@ static void __init autodetect_raid(void)
47777
47778 wait_for_device_probe();
47779
47780 - fd = sys_open("/dev/md0", 0, 0);
47781 + fd = sys_open((__force char __user *)"/dev/md0", 0, 0);
47782 if (fd >= 0) {
47783 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
47784 sys_close(fd);
47785 diff -urNp linux-2.6.36/init/initramfs.c linux-2.6.36/init/initramfs.c
47786 --- linux-2.6.36/init/initramfs.c 2010-10-20 16:30:22.000000000 -0400
47787 +++ linux-2.6.36/init/initramfs.c 2010-11-06 18:58:15.000000000 -0400
47788 @@ -74,7 +74,7 @@ static void __init free_hash(void)
47789 }
47790 }
47791
47792 -static long __init do_utime(char __user *filename, time_t mtime)
47793 +static long __init do_utime(__force char __user *filename, time_t mtime)
47794 {
47795 struct timespec t[2];
47796
47797 @@ -109,7 +109,7 @@ static void __init dir_utime(void)
47798 struct dir_entry *de, *tmp;
47799 list_for_each_entry_safe(de, tmp, &dir_list, list) {
47800 list_del(&de->list);
47801 - do_utime(de->name, de->mtime);
47802 + do_utime((__force char __user *)de->name, de->mtime);
47803 kfree(de->name);
47804 kfree(de);
47805 }
47806 @@ -271,7 +271,7 @@ static int __init maybe_link(void)
47807 if (nlink >= 2) {
47808 char *old = find_link(major, minor, ino, mode, collected);
47809 if (old)
47810 - return (sys_link(old, collected) < 0) ? -1 : 1;
47811 + return (sys_link((__force char __user *)old, (__force char __user *)collected) < 0) ? -1 : 1;
47812 }
47813 return 0;
47814 }
47815 @@ -280,11 +280,11 @@ static void __init clean_path(char *path
47816 {
47817 struct stat st;
47818
47819 - if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
47820 + if (!sys_newlstat((__force char __user *)path, (__force struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
47821 if (S_ISDIR(st.st_mode))
47822 - sys_rmdir(path);
47823 + sys_rmdir((__force char __user *)path);
47824 else
47825 - sys_unlink(path);
47826 + sys_unlink((__force char __user *)path);
47827 }
47828 }
47829
47830 @@ -305,7 +305,7 @@ static int __init do_name(void)
47831 int openflags = O_WRONLY|O_CREAT;
47832 if (ml != 1)
47833 openflags |= O_TRUNC;
47834 - wfd = sys_open(collected, openflags, mode);
47835 + wfd = sys_open((__force char __user *)collected, openflags, mode);
47836
47837 if (wfd >= 0) {
47838 sys_fchown(wfd, uid, gid);
47839 @@ -317,17 +317,17 @@ static int __init do_name(void)
47840 }
47841 }
47842 } else if (S_ISDIR(mode)) {
47843 - sys_mkdir(collected, mode);
47844 - sys_chown(collected, uid, gid);
47845 - sys_chmod(collected, mode);
47846 + sys_mkdir((__force char __user *)collected, mode);
47847 + sys_chown((__force char __user *)collected, uid, gid);
47848 + sys_chmod((__force char __user *)collected, mode);
47849 dir_add(collected, mtime);
47850 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
47851 S_ISFIFO(mode) || S_ISSOCK(mode)) {
47852 if (maybe_link() == 0) {
47853 - sys_mknod(collected, mode, rdev);
47854 - sys_chown(collected, uid, gid);
47855 - sys_chmod(collected, mode);
47856 - do_utime(collected, mtime);
47857 + sys_mknod((__force char __user *)collected, mode, rdev);
47858 + sys_chown((__force char __user *)collected, uid, gid);
47859 + sys_chmod((__force char __user *)collected, mode);
47860 + do_utime((__force char __user *)collected, mtime);
47861 }
47862 }
47863 return 0;
47864 @@ -336,15 +336,15 @@ static int __init do_name(void)
47865 static int __init do_copy(void)
47866 {
47867 if (count >= body_len) {
47868 - sys_write(wfd, victim, body_len);
47869 + sys_write(wfd, (__force char __user *)victim, body_len);
47870 sys_close(wfd);
47871 - do_utime(vcollected, mtime);
47872 + do_utime((__force char __user *)vcollected, mtime);
47873 kfree(vcollected);
47874 eat(body_len);
47875 state = SkipIt;
47876 return 0;
47877 } else {
47878 - sys_write(wfd, victim, count);
47879 + sys_write(wfd, (__force char __user *)victim, count);
47880 body_len -= count;
47881 eat(count);
47882 return 1;
47883 @@ -355,9 +355,9 @@ static int __init do_symlink(void)
47884 {
47885 collected[N_ALIGN(name_len) + body_len] = '\0';
47886 clean_path(collected, 0);
47887 - sys_symlink(collected + N_ALIGN(name_len), collected);
47888 - sys_lchown(collected, uid, gid);
47889 - do_utime(collected, mtime);
47890 + sys_symlink((__force char __user *)collected + N_ALIGN(name_len), (__force char __user *)collected);
47891 + sys_lchown((__force char __user *)collected, uid, gid);
47892 + do_utime((__force char __user *)collected, mtime);
47893 state = SkipIt;
47894 next_state = Reset;
47895 return 0;
47896 diff -urNp linux-2.6.36/init/Kconfig linux-2.6.36/init/Kconfig
47897 --- linux-2.6.36/init/Kconfig 2010-10-20 16:30:22.000000000 -0400
47898 +++ linux-2.6.36/init/Kconfig 2010-11-06 18:58:15.000000000 -0400
47899 @@ -1067,7 +1067,7 @@ config SLUB_DEBUG
47900
47901 config COMPAT_BRK
47902 bool "Disable heap randomization"
47903 - default y
47904 + default n
47905 help
47906 Randomizing heap placement makes heap exploits harder, but it
47907 also breaks ancient binaries (including anything libc5 based).
47908 diff -urNp linux-2.6.36/init/main.c linux-2.6.36/init/main.c
47909 --- linux-2.6.36/init/main.c 2010-10-20 16:30:22.000000000 -0400
47910 +++ linux-2.6.36/init/main.c 2010-11-06 18:58:50.000000000 -0400
47911 @@ -95,6 +95,7 @@ static inline void mark_rodata_ro(void)
47912 #ifdef CONFIG_TC
47913 extern void tc_init(void);
47914 #endif
47915 +extern void grsecurity_init(void);
47916
47917 enum system_states system_state __read_mostly;
47918 EXPORT_SYMBOL(system_state);
47919 @@ -197,6 +198,47 @@ static int __init set_reset_devices(char
47920
47921 __setup("reset_devices", set_reset_devices);
47922
47923 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
47924 +extern void pax_enter_kernel_user(void);
47925 +extern void pax_exit_kernel_user(void);
47926 +extern pgdval_t clone_pgd_mask;
47927 +#endif
47928 +
47929 +#if defined(CONFIG_X86) && defined(CONFIG_PAX_MEMORY_UDEREF)
47930 +static int __init setup_pax_nouderef(char *str)
47931 +{
47932 +#ifdef CONFIG_X86_32
47933 + unsigned int cpu;
47934 +
47935 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
47936 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].type = 3;
47937 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].limit = 0xf;
47938 + }
47939 + asm("mov %0, %%ds" : : "r" (__KERNEL_DS) : "memory");
47940 + asm("mov %0, %%es" : : "r" (__KERNEL_DS) : "memory");
47941 + asm("mov %0, %%ss" : : "r" (__KERNEL_DS) : "memory");
47942 +#else
47943 + memcpy(pax_enter_kernel_user, (unsigned char []){0xc3}, 1);
47944 + memcpy(pax_exit_kernel_user, (unsigned char []){0xc3}, 1);
47945 + clone_pgd_mask = ~(pgdval_t)0UL;
47946 +#endif
47947 +
47948 + return 0;
47949 +}
47950 +early_param("pax_nouderef", setup_pax_nouderef);
47951 +#endif
47952 +
47953 +#ifdef CONFIG_PAX_SOFTMODE
47954 +unsigned int pax_softmode;
47955 +
47956 +static int __init setup_pax_softmode(char *str)
47957 +{
47958 + get_option(&str, &pax_softmode);
47959 + return 1;
47960 +}
47961 +__setup("pax_softmode=", setup_pax_softmode);
47962 +#endif
47963 +
47964 static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
47965 const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
47966 static const char *panic_later, *panic_param;
47967 @@ -743,6 +785,7 @@ int __init_or_module do_one_initcall(ini
47968 {
47969 int count = preempt_count();
47970 int ret;
47971 + const char *msg1 = "", *msg2 = "";
47972
47973 if (initcall_debug)
47974 ret = do_one_initcall_debug(fn);
47975 @@ -755,15 +798,15 @@ int __init_or_module do_one_initcall(ini
47976 sprintf(msgbuf, "error code %d ", ret);
47977
47978 if (preempt_count() != count) {
47979 - strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
47980 + msg1 = " preemption imbalance";
47981 preempt_count() = count;
47982 }
47983 if (irqs_disabled()) {
47984 - strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
47985 + msg2 = " disabled interrupts";
47986 local_irq_enable();
47987 }
47988 - if (msgbuf[0]) {
47989 - printk("initcall %pF returned with %s\n", fn, msgbuf);
47990 + if (msgbuf[0] || *msg1 || *msg2) {
47991 + printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
47992 }
47993
47994 return ret;
47995 @@ -893,7 +936,7 @@ static int __init kernel_init(void * unu
47996 do_basic_setup();
47997
47998 /* Open the /dev/console on the rootfs, this should never fail */
47999 - if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
48000 + if (sys_open((__force const char __user *) "/dev/console", O_RDWR, 0) < 0)
48001 printk(KERN_WARNING "Warning: unable to open an initial console.\n");
48002
48003 (void) sys_dup(0);
48004 @@ -906,11 +949,13 @@ static int __init kernel_init(void * unu
48005 if (!ramdisk_execute_command)
48006 ramdisk_execute_command = "/init";
48007
48008 - if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
48009 + if (sys_access((__force const char __user *) ramdisk_execute_command, 0) != 0) {
48010 ramdisk_execute_command = NULL;
48011 prepare_namespace();
48012 }
48013
48014 + grsecurity_init();
48015 +
48016 /*
48017 * Ok, we have completed the initial bootup, and
48018 * we're essentially up and running. Get rid of the
48019 diff -urNp linux-2.6.36/init/noinitramfs.c linux-2.6.36/init/noinitramfs.c
48020 --- linux-2.6.36/init/noinitramfs.c 2010-10-20 16:30:22.000000000 -0400
48021 +++ linux-2.6.36/init/noinitramfs.c 2010-11-06 18:58:15.000000000 -0400
48022 @@ -29,17 +29,17 @@ static int __init default_rootfs(void)
48023 {
48024 int err;
48025
48026 - err = sys_mkdir("/dev", 0755);
48027 + err = sys_mkdir((const char __user *)"/dev", 0755);
48028 if (err < 0)
48029 goto out;
48030
48031 - err = sys_mknod((const char __user *) "/dev/console",
48032 + err = sys_mknod((__force const char __user *) "/dev/console",
48033 S_IFCHR | S_IRUSR | S_IWUSR,
48034 new_encode_dev(MKDEV(5, 1)));
48035 if (err < 0)
48036 goto out;
48037
48038 - err = sys_mkdir("/root", 0700);
48039 + err = sys_mkdir((const char __user *)"/root", 0700);
48040 if (err < 0)
48041 goto out;
48042
48043 diff -urNp linux-2.6.36/ipc/compat.c linux-2.6.36/ipc/compat.c
48044 --- linux-2.6.36/ipc/compat.c 2010-10-20 16:30:22.000000000 -0400
48045 +++ linux-2.6.36/ipc/compat.c 2010-11-06 18:58:50.000000000 -0400
48046 @@ -241,6 +241,8 @@ long compat_sys_semctl(int first, int se
48047 struct semid64_ds __user *up64;
48048 int version = compat_ipc_parse_version(&third);
48049
48050 + memset(&s64, 0, sizeof(s64));
48051 +
48052 if (!uptr)
48053 return -EINVAL;
48054 if (get_user(pad, (u32 __user *) uptr))
48055 @@ -421,6 +423,8 @@ long compat_sys_msgctl(int first, int se
48056 int version = compat_ipc_parse_version(&second);
48057 void __user *p;
48058
48059 + memset(&m64, 0, sizeof(m64));
48060 +
48061 switch (second & (~IPC_64)) {
48062 case IPC_INFO:
48063 case IPC_RMID:
48064 @@ -594,6 +598,8 @@ long compat_sys_shmctl(int first, int se
48065 int err, err2;
48066 int version = compat_ipc_parse_version(&second);
48067
48068 + memset(&s64, 0, sizeof(s64));
48069 +
48070 switch (second & (~IPC_64)) {
48071 case IPC_RMID:
48072 case SHM_LOCK:
48073 diff -urNp linux-2.6.36/ipc/compat_mq.c linux-2.6.36/ipc/compat_mq.c
48074 --- linux-2.6.36/ipc/compat_mq.c 2010-10-20 16:30:22.000000000 -0400
48075 +++ linux-2.6.36/ipc/compat_mq.c 2010-11-06 18:58:50.000000000 -0400
48076 @@ -53,6 +53,9 @@ asmlinkage long compat_sys_mq_open(const
48077 void __user *p = NULL;
48078 if (u_attr && oflag & O_CREAT) {
48079 struct mq_attr attr;
48080 +
48081 + memset(&attr, 0, sizeof(attr));
48082 +
48083 p = compat_alloc_user_space(sizeof(attr));
48084 if (get_compat_mq_attr(&attr, u_attr) ||
48085 copy_to_user(p, &attr, sizeof(attr)))
48086 @@ -127,6 +130,8 @@ asmlinkage long compat_sys_mq_getsetattr
48087 struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p));
48088 long ret;
48089
48090 + memset(&mqstat, 0, sizeof(mqstat));
48091 +
48092 if (u_mqstat) {
48093 if (get_compat_mq_attr(&mqstat, u_mqstat) ||
48094 copy_to_user(p, &mqstat, sizeof(mqstat)))
48095 diff -urNp linux-2.6.36/ipc/mqueue.c linux-2.6.36/ipc/mqueue.c
48096 --- linux-2.6.36/ipc/mqueue.c 2010-10-20 16:30:22.000000000 -0400
48097 +++ linux-2.6.36/ipc/mqueue.c 2010-11-06 18:58:50.000000000 -0400
48098 @@ -153,6 +153,7 @@ static struct inode *mqueue_get_inode(st
48099 mq_bytes = (mq_msg_tblsz +
48100 (info->attr.mq_maxmsg * info->attr.mq_msgsize));
48101
48102 + gr_learn_resource(current, RLIMIT_MSGQUEUE, u->mq_bytes + mq_bytes, 1);
48103 spin_lock(&mq_lock);
48104 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
48105 u->mq_bytes + mq_bytes >
48106 diff -urNp linux-2.6.36/ipc/shm.c linux-2.6.36/ipc/shm.c
48107 --- linux-2.6.36/ipc/shm.c 2010-10-20 16:30:22.000000000 -0400
48108 +++ linux-2.6.36/ipc/shm.c 2010-11-06 18:58:50.000000000 -0400
48109 @@ -69,6 +69,14 @@ static void shm_destroy (struct ipc_name
48110 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
48111 #endif
48112
48113 +#ifdef CONFIG_GRKERNSEC
48114 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
48115 + const time_t shm_createtime, const uid_t cuid,
48116 + const int shmid);
48117 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
48118 + const time_t shm_createtime);
48119 +#endif
48120 +
48121 void shm_init_ns(struct ipc_namespace *ns)
48122 {
48123 ns->shm_ctlmax = SHMMAX;
48124 @@ -395,6 +403,14 @@ static int newseg(struct ipc_namespace *
48125 shp->shm_lprid = 0;
48126 shp->shm_atim = shp->shm_dtim = 0;
48127 shp->shm_ctim = get_seconds();
48128 +#ifdef CONFIG_GRKERNSEC
48129 + {
48130 + struct timespec timeval;
48131 + do_posix_clock_monotonic_gettime(&timeval);
48132 +
48133 + shp->shm_createtime = timeval.tv_sec;
48134 + }
48135 +#endif
48136 shp->shm_segsz = size;
48137 shp->shm_nattch = 0;
48138 shp->shm_file = file;
48139 @@ -473,6 +489,8 @@ static inline unsigned long copy_shmid_t
48140 {
48141 struct shmid_ds out;
48142
48143 + memset(&out, 0, sizeof(out));
48144 +
48145 ipc64_perm_to_ipc_perm(&in->shm_perm, &out.shm_perm);
48146 out.shm_segsz = in->shm_segsz;
48147 out.shm_atime = in->shm_atime;
48148 @@ -877,9 +895,21 @@ long do_shmat(int shmid, char __user *sh
48149 if (err)
48150 goto out_unlock;
48151
48152 +#ifdef CONFIG_GRKERNSEC
48153 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
48154 + shp->shm_perm.cuid, shmid) ||
48155 + !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
48156 + err = -EACCES;
48157 + goto out_unlock;
48158 + }
48159 +#endif
48160 +
48161 path = shp->shm_file->f_path;
48162 path_get(&path);
48163 shp->shm_nattch++;
48164 +#ifdef CONFIG_GRKERNSEC
48165 + shp->shm_lapid = current->pid;
48166 +#endif
48167 size = i_size_read(path.dentry->d_inode);
48168 shm_unlock(shp);
48169
48170 diff -urNp linux-2.6.36/kernel/acct.c linux-2.6.36/kernel/acct.c
48171 --- linux-2.6.36/kernel/acct.c 2010-10-20 16:30:22.000000000 -0400
48172 +++ linux-2.6.36/kernel/acct.c 2010-11-06 18:58:15.000000000 -0400
48173 @@ -570,7 +570,7 @@ static void do_acct_process(struct bsd_a
48174 */
48175 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
48176 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
48177 - file->f_op->write(file, (char *)&ac,
48178 + file->f_op->write(file, (__force char __user *)&ac,
48179 sizeof(acct_t), &file->f_pos);
48180 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
48181 set_fs(fs);
48182 diff -urNp linux-2.6.36/kernel/capability.c linux-2.6.36/kernel/capability.c
48183 --- linux-2.6.36/kernel/capability.c 2010-10-20 16:30:22.000000000 -0400
48184 +++ linux-2.6.36/kernel/capability.c 2010-11-06 18:58:50.000000000 -0400
48185 @@ -205,6 +205,9 @@ SYSCALL_DEFINE2(capget, cap_user_header_
48186 * before modification is attempted and the application
48187 * fails.
48188 */
48189 + if (tocopy > ARRAY_SIZE(kdata))
48190 + return -EFAULT;
48191 +
48192 if (copy_to_user(dataptr, kdata, tocopy
48193 * sizeof(struct __user_cap_data_struct))) {
48194 return -EFAULT;
48195 @@ -306,10 +309,21 @@ int capable(int cap)
48196 BUG();
48197 }
48198
48199 - if (security_capable(cap) == 0) {
48200 + if (security_capable(cap) == 0 && gr_is_capable(cap)) {
48201 + current->flags |= PF_SUPERPRIV;
48202 + return 1;
48203 + }
48204 + return 0;
48205 +}
48206 +
48207 +int capable_nolog(int cap)
48208 +{
48209 + if (security_capable(cap) == 0 && gr_is_capable_nolog(cap)) {
48210 current->flags |= PF_SUPERPRIV;
48211 return 1;
48212 }
48213 return 0;
48214 }
48215 +
48216 EXPORT_SYMBOL(capable);
48217 +EXPORT_SYMBOL(capable_nolog);
48218 diff -urNp linux-2.6.36/kernel/compat.c linux-2.6.36/kernel/compat.c
48219 --- linux-2.6.36/kernel/compat.c 2010-10-20 16:30:22.000000000 -0400
48220 +++ linux-2.6.36/kernel/compat.c 2010-11-06 18:58:50.000000000 -0400
48221 @@ -13,6 +13,7 @@
48222
48223 #include <linux/linkage.h>
48224 #include <linux/compat.h>
48225 +#include <linux/module.h>
48226 #include <linux/errno.h>
48227 #include <linux/time.h>
48228 #include <linux/signal.h>
48229 diff -urNp linux-2.6.36/kernel/configs.c linux-2.6.36/kernel/configs.c
48230 --- linux-2.6.36/kernel/configs.c 2010-10-20 16:30:22.000000000 -0400
48231 +++ linux-2.6.36/kernel/configs.c 2010-11-06 18:58:50.000000000 -0400
48232 @@ -73,8 +73,19 @@ static int __init ikconfig_init(void)
48233 struct proc_dir_entry *entry;
48234
48235 /* create the current config file */
48236 +#if defined(CONFIG_GRKERNSEC_PROC_ADD) || defined(CONFIG_GRKERNSEC_HIDESYM)
48237 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_HIDESYM)
48238 + entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
48239 + &ikconfig_file_ops);
48240 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
48241 + entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
48242 + &ikconfig_file_ops);
48243 +#endif
48244 +#else
48245 entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
48246 &ikconfig_file_ops);
48247 +#endif
48248 +
48249 if (!entry)
48250 return -ENOMEM;
48251
48252 diff -urNp linux-2.6.36/kernel/cred.c linux-2.6.36/kernel/cred.c
48253 --- linux-2.6.36/kernel/cred.c 2010-10-20 16:30:22.000000000 -0400
48254 +++ linux-2.6.36/kernel/cred.c 2010-11-06 18:58:50.000000000 -0400
48255 @@ -485,6 +485,8 @@ int commit_creds(struct cred *new)
48256
48257 get_cred(new); /* we will require a ref for the subj creds too */
48258
48259 + gr_set_role_label(task, new->uid, new->gid);
48260 +
48261 /* dumpability changes */
48262 if (old->euid != new->euid ||
48263 old->egid != new->egid ||
48264 diff -urNp linux-2.6.36/kernel/debug/debug_core.c linux-2.6.36/kernel/debug/debug_core.c
48265 --- linux-2.6.36/kernel/debug/debug_core.c 2010-10-20 16:30:22.000000000 -0400
48266 +++ linux-2.6.36/kernel/debug/debug_core.c 2010-11-06 18:58:15.000000000 -0400
48267 @@ -71,7 +71,7 @@ int kgdb_io_module_registered;
48268 /* Guard for recursive entry */
48269 static int exception_level;
48270
48271 -struct kgdb_io *dbg_io_ops;
48272 +const struct kgdb_io *dbg_io_ops;
48273 static DEFINE_SPINLOCK(kgdb_registration_lock);
48274
48275 /* kgdb console driver is loaded */
48276 @@ -873,7 +873,7 @@ static void kgdb_initial_breakpoint(void
48277 *
48278 * Register it with the KGDB core.
48279 */
48280 -int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops)
48281 +int kgdb_register_io_module(const struct kgdb_io *new_dbg_io_ops)
48282 {
48283 int err;
48284
48285 @@ -918,7 +918,7 @@ EXPORT_SYMBOL_GPL(kgdb_register_io_modul
48286 *
48287 * Unregister it with the KGDB core.
48288 */
48289 -void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops)
48290 +void kgdb_unregister_io_module(const struct kgdb_io *old_dbg_io_ops)
48291 {
48292 BUG_ON(kgdb_connected);
48293
48294 diff -urNp linux-2.6.36/kernel/debug/kdb/kdb_main.c linux-2.6.36/kernel/debug/kdb/kdb_main.c
48295 --- linux-2.6.36/kernel/debug/kdb/kdb_main.c 2010-10-20 16:30:22.000000000 -0400
48296 +++ linux-2.6.36/kernel/debug/kdb/kdb_main.c 2010-11-06 18:58:15.000000000 -0400
48297 @@ -1980,7 +1980,7 @@ static int kdb_lsmod(int argc, const cha
48298 list_for_each_entry(mod, kdb_modules, list) {
48299
48300 kdb_printf("%-20s%8u 0x%p ", mod->name,
48301 - mod->core_size, (void *)mod);
48302 + mod->core_size_rx + mod->core_size_rw, (void *)mod);
48303 #ifdef CONFIG_MODULE_UNLOAD
48304 kdb_printf("%4d ", module_refcount(mod));
48305 #endif
48306 @@ -1990,7 +1990,7 @@ static int kdb_lsmod(int argc, const cha
48307 kdb_printf(" (Loading)");
48308 else
48309 kdb_printf(" (Live)");
48310 - kdb_printf(" 0x%p", mod->module_core);
48311 + kdb_printf(" 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
48312
48313 #ifdef CONFIG_MODULE_UNLOAD
48314 {
48315 diff -urNp linux-2.6.36/kernel/exit.c linux-2.6.36/kernel/exit.c
48316 --- linux-2.6.36/kernel/exit.c 2010-10-20 16:30:22.000000000 -0400
48317 +++ linux-2.6.36/kernel/exit.c 2010-11-06 18:58:50.000000000 -0400
48318 @@ -56,6 +56,10 @@
48319 #include <asm/pgtable.h>
48320 #include <asm/mmu_context.h>
48321
48322 +#ifdef CONFIG_GRKERNSEC
48323 +extern rwlock_t grsec_exec_file_lock;
48324 +#endif
48325 +
48326 static void exit_mm(struct task_struct * tsk);
48327
48328 static void __unhash_process(struct task_struct *p, bool group_dead)
48329 @@ -162,6 +166,8 @@ void release_task(struct task_struct * p
48330 struct task_struct *leader;
48331 int zap_leader;
48332 repeat:
48333 + gr_del_task_from_ip_table(p);
48334 +
48335 tracehook_prepare_release_task(p);
48336 /* don't need to get the RCU readlock here - the process is dead and
48337 * can't be modifying its own credentials. But shut RCU-lockdep up */
48338 @@ -331,11 +337,22 @@ static void reparent_to_kthreadd(void)
48339 {
48340 write_lock_irq(&tasklist_lock);
48341
48342 +#ifdef CONFIG_GRKERNSEC
48343 + write_lock(&grsec_exec_file_lock);
48344 + if (current->exec_file) {
48345 + fput(current->exec_file);
48346 + current->exec_file = NULL;
48347 + }
48348 + write_unlock(&grsec_exec_file_lock);
48349 +#endif
48350 +
48351 ptrace_unlink(current);
48352 /* Reparent to init */
48353 current->real_parent = current->parent = kthreadd_task;
48354 list_move_tail(&current->sibling, &current->real_parent->children);
48355
48356 + gr_set_kernel_label(current);
48357 +
48358 /* Set the exit signal to SIGCHLD so we signal init on exit */
48359 current->exit_signal = SIGCHLD;
48360
48361 @@ -387,7 +404,7 @@ int allow_signal(int sig)
48362 * know it'll be handled, so that they don't get converted to
48363 * SIGKILL or just silently dropped.
48364 */
48365 - current->sighand->action[(sig)-1].sa.sa_handler = (void __user *)2;
48366 + current->sighand->action[(sig)-1].sa.sa_handler = (__force void __user *)2;
48367 recalc_sigpending();
48368 spin_unlock_irq(&current->sighand->siglock);
48369 return 0;
48370 @@ -423,6 +440,17 @@ void daemonize(const char *name, ...)
48371 vsnprintf(current->comm, sizeof(current->comm), name, args);
48372 va_end(args);
48373
48374 +#ifdef CONFIG_GRKERNSEC
48375 + write_lock(&grsec_exec_file_lock);
48376 + if (current->exec_file) {
48377 + fput(current->exec_file);
48378 + current->exec_file = NULL;
48379 + }
48380 + write_unlock(&grsec_exec_file_lock);
48381 +#endif
48382 +
48383 + gr_set_kernel_label(current);
48384 +
48385 /*
48386 * If we were started as result of loading a module, close all of the
48387 * user space pages. We don't need them, and if we didn't close them
48388 @@ -963,6 +991,9 @@ NORET_TYPE void do_exit(long code)
48389 tsk->exit_code = code;
48390 taskstats_exit(tsk, group_dead);
48391
48392 + gr_acl_handle_psacct(tsk, code);
48393 + gr_acl_handle_exit();
48394 +
48395 exit_mm(tsk);
48396
48397 if (group_dead)
48398 diff -urNp linux-2.6.36/kernel/fork.c linux-2.6.36/kernel/fork.c
48399 --- linux-2.6.36/kernel/fork.c 2010-10-20 16:30:22.000000000 -0400
48400 +++ linux-2.6.36/kernel/fork.c 2010-11-06 19:20:52.000000000 -0400
48401 @@ -276,7 +276,7 @@ static struct task_struct *dup_task_stru
48402 *stackend = STACK_END_MAGIC; /* for overflow detection */
48403
48404 #ifdef CONFIG_CC_STACKPROTECTOR
48405 - tsk->stack_canary = get_random_int();
48406 + tsk->stack_canary = pax_get_random_long();
48407 #endif
48408
48409 /* One for us, one for whoever does the "release_task()" (usually parent) */
48410 @@ -298,13 +298,78 @@ out:
48411 }
48412
48413 #ifdef CONFIG_MMU
48414 +static struct vm_area_struct *dup_vma(struct mm_struct *mm, struct vm_area_struct *mpnt)
48415 +{
48416 + struct vm_area_struct *tmp;
48417 + unsigned long charge;
48418 + struct mempolicy *pol;
48419 + struct file *file;
48420 +
48421 + charge = 0;
48422 + if (mpnt->vm_flags & VM_ACCOUNT) {
48423 + unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
48424 + if (security_vm_enough_memory(len))
48425 + goto fail_nomem;
48426 + charge = len;
48427 + }
48428 + tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
48429 + if (!tmp)
48430 + goto fail_nomem;
48431 + *tmp = *mpnt;
48432 + tmp->vm_mm = mm;
48433 + INIT_LIST_HEAD(&tmp->anon_vma_chain);
48434 + pol = mpol_dup(vma_policy(mpnt));
48435 + if (IS_ERR(pol))
48436 + goto fail_nomem_policy;
48437 + vma_set_policy(tmp, pol);
48438 + if (anon_vma_fork(tmp, mpnt))
48439 + goto fail_nomem_anon_vma_fork;
48440 + tmp->vm_flags &= ~VM_LOCKED;
48441 + tmp->vm_next = tmp->vm_prev = NULL;
48442 + tmp->vm_mirror = NULL;
48443 + file = tmp->vm_file;
48444 + if (file) {
48445 + struct inode *inode = file->f_path.dentry->d_inode;
48446 + struct address_space *mapping = file->f_mapping;
48447 +
48448 + get_file(file);
48449 + if (tmp->vm_flags & VM_DENYWRITE)
48450 + atomic_dec(&inode->i_writecount);
48451 + spin_lock(&mapping->i_mmap_lock);
48452 + if (tmp->vm_flags & VM_SHARED)
48453 + mapping->i_mmap_writable++;
48454 + tmp->vm_truncate_count = mpnt->vm_truncate_count;
48455 + flush_dcache_mmap_lock(mapping);
48456 + /* insert tmp into the share list, just after mpnt */
48457 + vma_prio_tree_add(tmp, mpnt);
48458 + flush_dcache_mmap_unlock(mapping);
48459 + spin_unlock(&mapping->i_mmap_lock);
48460 + }
48461 +
48462 + /*
48463 + * Clear hugetlb-related page reserves for children. This only
48464 + * affects MAP_PRIVATE mappings. Faults generated by the child
48465 + * are not guaranteed to succeed, even if read-only
48466 + */
48467 + if (is_vm_hugetlb_page(tmp))
48468 + reset_vma_resv_huge_pages(tmp);
48469 +
48470 + return tmp;
48471 +
48472 +fail_nomem_anon_vma_fork:
48473 + mpol_put(pol);
48474 +fail_nomem_policy:
48475 + kmem_cache_free(vm_area_cachep, tmp);
48476 +fail_nomem:
48477 + vm_unacct_memory(charge);
48478 + return NULL;
48479 +}
48480 +
48481 static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
48482 {
48483 struct vm_area_struct *mpnt, *tmp, *prev, **pprev;
48484 struct rb_node **rb_link, *rb_parent;
48485 int retval;
48486 - unsigned long charge;
48487 - struct mempolicy *pol;
48488
48489 down_write(&oldmm->mmap_sem);
48490 flush_cache_dup_mm(oldmm);
48491 @@ -316,8 +381,8 @@ static int dup_mmap(struct mm_struct *mm
48492 mm->locked_vm = 0;
48493 mm->mmap = NULL;
48494 mm->mmap_cache = NULL;
48495 - mm->free_area_cache = oldmm->mmap_base;
48496 - mm->cached_hole_size = ~0UL;
48497 + mm->free_area_cache = oldmm->free_area_cache;
48498 + mm->cached_hole_size = oldmm->cached_hole_size;
48499 mm->map_count = 0;
48500 cpumask_clear(mm_cpumask(mm));
48501 mm->mm_rb = RB_ROOT;
48502 @@ -330,8 +395,6 @@ static int dup_mmap(struct mm_struct *mm
48503
48504 prev = NULL;
48505 for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
48506 - struct file *file;
48507 -
48508 if (mpnt->vm_flags & VM_DONTCOPY) {
48509 long pages = vma_pages(mpnt);
48510 mm->total_vm -= pages;
48511 @@ -339,56 +402,13 @@ static int dup_mmap(struct mm_struct *mm
48512 -pages);
48513 continue;
48514 }
48515 - charge = 0;
48516 - if (mpnt->vm_flags & VM_ACCOUNT) {
48517 - unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
48518 - if (security_vm_enough_memory(len))
48519 - goto fail_nomem;
48520 - charge = len;
48521 - }
48522 - tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
48523 - if (!tmp)
48524 - goto fail_nomem;
48525 - *tmp = *mpnt;
48526 - INIT_LIST_HEAD(&tmp->anon_vma_chain);
48527 - pol = mpol_dup(vma_policy(mpnt));
48528 - retval = PTR_ERR(pol);
48529 - if (IS_ERR(pol))
48530 - goto fail_nomem_policy;
48531 - vma_set_policy(tmp, pol);
48532 - tmp->vm_mm = mm;
48533 - if (anon_vma_fork(tmp, mpnt))
48534 - goto fail_nomem_anon_vma_fork;
48535 - tmp->vm_flags &= ~VM_LOCKED;
48536 - tmp->vm_next = tmp->vm_prev = NULL;
48537 - file = tmp->vm_file;
48538 - if (file) {
48539 - struct inode *inode = file->f_path.dentry->d_inode;
48540 - struct address_space *mapping = file->f_mapping;
48541 -
48542 - get_file(file);
48543 - if (tmp->vm_flags & VM_DENYWRITE)
48544 - atomic_dec(&inode->i_writecount);
48545 - spin_lock(&mapping->i_mmap_lock);
48546 - if (tmp->vm_flags & VM_SHARED)
48547 - mapping->i_mmap_writable++;
48548 - tmp->vm_truncate_count = mpnt->vm_truncate_count;
48549 - flush_dcache_mmap_lock(mapping);
48550 - /* insert tmp into the share list, just after mpnt */
48551 - vma_prio_tree_add(tmp, mpnt);
48552 - flush_dcache_mmap_unlock(mapping);
48553 - spin_unlock(&mapping->i_mmap_lock);
48554 + tmp = dup_vma(mm, mpnt);
48555 + if (!tmp) {
48556 + retval = -ENOMEM;
48557 + goto out;
48558 }
48559
48560 /*
48561 - * Clear hugetlb-related page reserves for children. This only
48562 - * affects MAP_PRIVATE mappings. Faults generated by the child
48563 - * are not guaranteed to succeed, even if read-only
48564 - */
48565 - if (is_vm_hugetlb_page(tmp))
48566 - reset_vma_resv_huge_pages(tmp);
48567 -
48568 - /*
48569 * Link in the new vma and copy the page table entries.
48570 */
48571 *pprev = tmp;
48572 @@ -409,6 +429,31 @@ static int dup_mmap(struct mm_struct *mm
48573 if (retval)
48574 goto out;
48575 }
48576 +
48577 +#ifdef CONFIG_PAX_SEGMEXEC
48578 + if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
48579 + struct vm_area_struct *mpnt_m;
48580 +
48581 + for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
48582 + BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
48583 +
48584 + if (!mpnt->vm_mirror)
48585 + continue;
48586 +
48587 + if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
48588 + BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
48589 + mpnt->vm_mirror = mpnt_m;
48590 + } else {
48591 + BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
48592 + mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
48593 + mpnt_m->vm_mirror->vm_mirror = mpnt_m;
48594 + mpnt->vm_mirror->vm_mirror = mpnt;
48595 + }
48596 + }
48597 + BUG_ON(mpnt_m);
48598 + }
48599 +#endif
48600 +
48601 /* a new mm has just been created */
48602 arch_dup_mmap(oldmm, mm);
48603 retval = 0;
48604 @@ -417,14 +462,6 @@ out:
48605 flush_tlb_mm(oldmm);
48606 up_write(&oldmm->mmap_sem);
48607 return retval;
48608 -fail_nomem_anon_vma_fork:
48609 - mpol_put(pol);
48610 -fail_nomem_policy:
48611 - kmem_cache_free(vm_area_cachep, tmp);
48612 -fail_nomem:
48613 - retval = -ENOMEM;
48614 - vm_unacct_memory(charge);
48615 - goto out;
48616 }
48617
48618 static inline int mm_alloc_pgd(struct mm_struct * mm)
48619 @@ -760,13 +797,14 @@ static int copy_fs(unsigned long clone_f
48620 spin_unlock(&fs->lock);
48621 return -EAGAIN;
48622 }
48623 - fs->users++;
48624 + atomic_inc(&fs->users);
48625 spin_unlock(&fs->lock);
48626 return 0;
48627 }
48628 tsk->fs = copy_fs_struct(fs);
48629 if (!tsk->fs)
48630 return -ENOMEM;
48631 + gr_set_chroot_entries(tsk, &tsk->fs->root);
48632 return 0;
48633 }
48634
48635 @@ -1020,10 +1058,13 @@ static struct task_struct *copy_process(
48636 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
48637 #endif
48638 retval = -EAGAIN;
48639 +
48640 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->real_cred->user->processes), 0);
48641 +
48642 if (atomic_read(&p->real_cred->user->processes) >=
48643 task_rlimit(p, RLIMIT_NPROC)) {
48644 - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
48645 - p->real_cred->user != INIT_USER)
48646 + if (p->real_cred->user != INIT_USER &&
48647 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
48648 goto bad_fork_free;
48649 }
48650
48651 @@ -1177,6 +1218,8 @@ static struct task_struct *copy_process(
48652 goto bad_fork_free_pid;
48653 }
48654
48655 + gr_copy_label(p);
48656 +
48657 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
48658 /*
48659 * Clear TID on mm_release()?
48660 @@ -1329,6 +1372,8 @@ bad_fork_cleanup_count:
48661 bad_fork_free:
48662 free_task(p);
48663 fork_out:
48664 + gr_log_forkfail(retval);
48665 +
48666 return ERR_PTR(retval);
48667 }
48668
48669 @@ -1434,6 +1479,8 @@ long do_fork(unsigned long clone_flags,
48670 if (clone_flags & CLONE_PARENT_SETTID)
48671 put_user(nr, parent_tidptr);
48672
48673 + gr_handle_brute_check();
48674 +
48675 if (clone_flags & CLONE_VFORK) {
48676 p->vfork_done = &vfork;
48677 init_completion(&vfork);
48678 @@ -1558,7 +1605,7 @@ static int unshare_fs(unsigned long unsh
48679 return 0;
48680
48681 /* don't need lock here; in the worst case we'll do useless copy */
48682 - if (fs->users == 1)
48683 + if (atomic_read(&fs->users) == 1)
48684 return 0;
48685
48686 *new_fsp = copy_fs_struct(fs);
48687 @@ -1681,7 +1728,8 @@ SYSCALL_DEFINE1(unshare, unsigned long,
48688 fs = current->fs;
48689 spin_lock(&fs->lock);
48690 current->fs = new_fs;
48691 - if (--fs->users)
48692 + gr_set_chroot_entries(current, &current->fs->root);
48693 + if (atomic_dec_return(&fs->users))
48694 new_fs = NULL;
48695 else
48696 new_fs = fs;
48697 diff -urNp linux-2.6.36/kernel/futex.c linux-2.6.36/kernel/futex.c
48698 --- linux-2.6.36/kernel/futex.c 2010-10-20 16:30:22.000000000 -0400
48699 +++ linux-2.6.36/kernel/futex.c 2010-11-06 18:58:50.000000000 -0400
48700 @@ -54,6 +54,7 @@
48701 #include <linux/mount.h>
48702 #include <linux/pagemap.h>
48703 #include <linux/syscalls.h>
48704 +#include <linux/ptrace.h>
48705 #include <linux/signal.h>
48706 #include <linux/module.h>
48707 #include <linux/magic.h>
48708 @@ -221,6 +222,11 @@ get_futex_key(u32 __user *uaddr, int fsh
48709 struct page *page;
48710 int err;
48711
48712 +#ifdef CONFIG_PAX_SEGMEXEC
48713 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
48714 + return -EFAULT;
48715 +#endif
48716 +
48717 /*
48718 * The futex address must be "naturally" aligned.
48719 */
48720 @@ -1843,7 +1849,7 @@ retry:
48721
48722 restart = &current_thread_info()->restart_block;
48723 restart->fn = futex_wait_restart;
48724 - restart->futex.uaddr = (u32 *)uaddr;
48725 + restart->futex.uaddr = uaddr;
48726 restart->futex.val = val;
48727 restart->futex.time = abs_time->tv64;
48728 restart->futex.bitset = bitset;
48729 @@ -2376,7 +2382,9 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
48730 {
48731 struct robust_list_head __user *head;
48732 unsigned long ret;
48733 +#ifndef CONFIG_GRKERNSEC_PROC_MEMMAP
48734 const struct cred *cred = current_cred(), *pcred;
48735 +#endif
48736
48737 if (!futex_cmpxchg_enabled)
48738 return -ENOSYS;
48739 @@ -2392,11 +2400,16 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
48740 if (!p)
48741 goto err_unlock;
48742 ret = -EPERM;
48743 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
48744 + if (!ptrace_may_access(p, PTRACE_MODE_READ))
48745 + goto err_unlock;
48746 +#else
48747 pcred = __task_cred(p);
48748 if (cred->euid != pcred->euid &&
48749 cred->euid != pcred->uid &&
48750 !capable(CAP_SYS_PTRACE))
48751 goto err_unlock;
48752 +#endif
48753 head = p->robust_list;
48754 rcu_read_unlock();
48755 }
48756 @@ -2458,7 +2471,7 @@ retry:
48757 */
48758 static inline int fetch_robust_entry(struct robust_list __user **entry,
48759 struct robust_list __user * __user *head,
48760 - int *pi)
48761 + unsigned int *pi)
48762 {
48763 unsigned long uentry;
48764
48765 diff -urNp linux-2.6.36/kernel/futex_compat.c linux-2.6.36/kernel/futex_compat.c
48766 --- linux-2.6.36/kernel/futex_compat.c 2010-10-20 16:30:22.000000000 -0400
48767 +++ linux-2.6.36/kernel/futex_compat.c 2010-11-06 18:58:50.000000000 -0400
48768 @@ -10,6 +10,7 @@
48769 #include <linux/compat.h>
48770 #include <linux/nsproxy.h>
48771 #include <linux/futex.h>
48772 +#include <linux/ptrace.h>
48773
48774 #include <asm/uaccess.h>
48775
48776 @@ -135,7 +136,10 @@ compat_sys_get_robust_list(int pid, comp
48777 {
48778 struct compat_robust_list_head __user *head;
48779 unsigned long ret;
48780 - const struct cred *cred = current_cred(), *pcred;
48781 +#ifndef CONFIG_GRKERNSEC_PROC_MEMMAP
48782 + const struct cred *cred = current_cred();
48783 + const struct cred *pcred;
48784 +#endif
48785
48786 if (!futex_cmpxchg_enabled)
48787 return -ENOSYS;
48788 @@ -151,11 +155,16 @@ compat_sys_get_robust_list(int pid, comp
48789 if (!p)
48790 goto err_unlock;
48791 ret = -EPERM;
48792 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
48793 + if (!ptrace_may_access(p, PTRACE_MODE_READ))
48794 + goto err_unlock;
48795 +#else
48796 pcred = __task_cred(p);
48797 if (cred->euid != pcred->euid &&
48798 cred->euid != pcred->uid &&
48799 !capable(CAP_SYS_PTRACE))
48800 goto err_unlock;
48801 +#endif
48802 head = p->compat_robust_list;
48803 rcu_read_unlock();
48804 }
48805 diff -urNp linux-2.6.36/kernel/gcov/base.c linux-2.6.36/kernel/gcov/base.c
48806 --- linux-2.6.36/kernel/gcov/base.c 2010-10-20 16:30:22.000000000 -0400
48807 +++ linux-2.6.36/kernel/gcov/base.c 2010-11-06 18:58:15.000000000 -0400
48808 @@ -102,11 +102,6 @@ void gcov_enable_events(void)
48809 }
48810
48811 #ifdef CONFIG_MODULES
48812 -static inline int within(void *addr, void *start, unsigned long size)
48813 -{
48814 - return ((addr >= start) && (addr < start + size));
48815 -}
48816 -
48817 /* Update list and generate events when modules are unloaded. */
48818 static int gcov_module_notifier(struct notifier_block *nb, unsigned long event,
48819 void *data)
48820 @@ -121,7 +116,7 @@ static int gcov_module_notifier(struct n
48821 prev = NULL;
48822 /* Remove entries located in module from linked list. */
48823 for (info = gcov_info_head; info; info = info->next) {
48824 - if (within(info, mod->module_core, mod->core_size)) {
48825 + if (within_module_core_rw((unsigned long)info, mod)) {
48826 if (prev)
48827 prev->next = info->next;
48828 else
48829 diff -urNp linux-2.6.36/kernel/hrtimer.c linux-2.6.36/kernel/hrtimer.c
48830 --- linux-2.6.36/kernel/hrtimer.c 2010-10-20 16:30:22.000000000 -0400
48831 +++ linux-2.6.36/kernel/hrtimer.c 2010-11-06 18:58:15.000000000 -0400
48832 @@ -1401,7 +1401,7 @@ void hrtimer_peek_ahead_timers(void)
48833 local_irq_restore(flags);
48834 }
48835
48836 -static void run_hrtimer_softirq(struct softirq_action *h)
48837 +static void run_hrtimer_softirq(void)
48838 {
48839 hrtimer_peek_ahead_timers();
48840 }
48841 diff -urNp linux-2.6.36/kernel/kallsyms.c linux-2.6.36/kernel/kallsyms.c
48842 --- linux-2.6.36/kernel/kallsyms.c 2010-10-20 16:30:22.000000000 -0400
48843 +++ linux-2.6.36/kernel/kallsyms.c 2010-11-06 18:58:50.000000000 -0400
48844 @@ -11,6 +11,9 @@
48845 * Changed the compression method from stem compression to "table lookup"
48846 * compression (see scripts/kallsyms.c for a more complete description)
48847 */
48848 +#ifdef CONFIG_GRKERNSEC_HIDESYM
48849 +#define __INCLUDED_BY_HIDESYM 1
48850 +#endif
48851 #include <linux/kallsyms.h>
48852 #include <linux/module.h>
48853 #include <linux/init.h>
48854 @@ -53,12 +56,33 @@ extern const unsigned long kallsyms_mark
48855
48856 static inline int is_kernel_inittext(unsigned long addr)
48857 {
48858 + if (system_state != SYSTEM_BOOTING)
48859 + return 0;
48860 +
48861 if (addr >= (unsigned long)_sinittext
48862 && addr <= (unsigned long)_einittext)
48863 return 1;
48864 return 0;
48865 }
48866
48867 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
48868 +#ifdef CONFIG_MODULES
48869 +static inline int is_module_text(unsigned long addr)
48870 +{
48871 + if ((unsigned long)MODULES_EXEC_VADDR <= addr && addr <= (unsigned long)MODULES_EXEC_END)
48872 + return 1;
48873 +
48874 + addr = ktla_ktva(addr);
48875 + return (unsigned long)MODULES_EXEC_VADDR <= addr && addr <= (unsigned long)MODULES_EXEC_END;
48876 +}
48877 +#else
48878 +static inline int is_module_text(unsigned long addr)
48879 +{
48880 + return 0;
48881 +}
48882 +#endif
48883 +#endif
48884 +
48885 static inline int is_kernel_text(unsigned long addr)
48886 {
48887 if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) ||
48888 @@ -69,13 +93,28 @@ static inline int is_kernel_text(unsigne
48889
48890 static inline int is_kernel(unsigned long addr)
48891 {
48892 +
48893 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
48894 + if (is_kernel_text(addr) || is_kernel_inittext(addr))
48895 + return 1;
48896 +
48897 + if (ktla_ktva((unsigned long)_text) <= addr && addr < (unsigned long)_end)
48898 +#else
48899 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
48900 +#endif
48901 +
48902 return 1;
48903 return in_gate_area_no_task(addr);
48904 }
48905
48906 static int is_ksym_addr(unsigned long addr)
48907 {
48908 +
48909 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
48910 + if (is_module_text(addr))
48911 + return 0;
48912 +#endif
48913 +
48914 if (all_var)
48915 return is_kernel(addr);
48916
48917 @@ -416,7 +455,6 @@ static unsigned long get_ksymbol_core(st
48918
48919 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
48920 {
48921 - iter->name[0] = '\0';
48922 iter->nameoff = get_symbol_offset(new_pos);
48923 iter->pos = new_pos;
48924 }
48925 @@ -464,6 +502,11 @@ static int s_show(struct seq_file *m, vo
48926 {
48927 struct kallsym_iter *iter = m->private;
48928
48929 +#ifdef CONFIG_GRKERNSEC_HIDESYM
48930 + if (current_uid())
48931 + return 0;
48932 +#endif
48933 +
48934 /* Some debugging symbols have no name. Ignore them. */
48935 if (!iter->name[0])
48936 return 0;
48937 @@ -504,7 +547,7 @@ static int kallsyms_open(struct inode *i
48938 struct kallsym_iter *iter;
48939 int ret;
48940
48941 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
48942 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
48943 if (!iter)
48944 return -ENOMEM;
48945 reset_iter(iter, 0);
48946 diff -urNp linux-2.6.36/kernel/kmod.c linux-2.6.36/kernel/kmod.c
48947 --- linux-2.6.36/kernel/kmod.c 2010-10-20 16:30:22.000000000 -0400
48948 +++ linux-2.6.36/kernel/kmod.c 2010-11-06 18:58:50.000000000 -0400
48949 @@ -90,6 +90,18 @@ int __request_module(bool wait, const ch
48950 if (ret)
48951 return ret;
48952
48953 +#ifdef CONFIG_GRKERNSEC_MODHARDEN
48954 + /* we could do a tighter check here, but some distros
48955 + are taking it upon themselves to remove CAP_SYS_MODULE
48956 + from even root-running apps which cause modules to be
48957 + auto-loaded
48958 + */
48959 + if (current_uid()) {
48960 + gr_log_nonroot_mod_load(module_name);
48961 + return -EPERM;
48962 + }
48963 +#endif
48964 +
48965 /* If modprobe needs a service that is in a module, we get a recursive
48966 * loop. Limit the number of running kmod threads to max_threads/2 or
48967 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
48968 diff -urNp linux-2.6.36/kernel/kprobes.c linux-2.6.36/kernel/kprobes.c
48969 --- linux-2.6.36/kernel/kprobes.c 2010-10-20 16:30:22.000000000 -0400
48970 +++ linux-2.6.36/kernel/kprobes.c 2010-11-06 18:58:15.000000000 -0400
48971 @@ -183,7 +183,7 @@ static kprobe_opcode_t __kprobes *__get_
48972 * kernel image and loaded module images reside. This is required
48973 * so x86_64 can correctly handle the %rip-relative fixups.
48974 */
48975 - kip->insns = module_alloc(PAGE_SIZE);
48976 + kip->insns = module_alloc_exec(PAGE_SIZE);
48977 if (!kip->insns) {
48978 kfree(kip);
48979 return NULL;
48980 @@ -223,7 +223,7 @@ static int __kprobes collect_one_slot(st
48981 */
48982 if (!list_is_singular(&kip->list)) {
48983 list_del(&kip->list);
48984 - module_free(NULL, kip->insns);
48985 + module_free_exec(NULL, kip->insns);
48986 kfree(kip);
48987 }
48988 return 1;
48989 @@ -1709,7 +1709,7 @@ static int __init init_kprobes(void)
48990 {
48991 int i, err = 0;
48992 unsigned long offset = 0, size = 0;
48993 - char *modname, namebuf[128];
48994 + char *modname, namebuf[KSYM_NAME_LEN];
48995 const char *symbol_name;
48996 void *addr;
48997 struct kprobe_blackpoint *kb;
48998 @@ -1835,7 +1835,7 @@ static int __kprobes show_kprobe_addr(st
48999 const char *sym = NULL;
49000 unsigned int i = *(loff_t *) v;
49001 unsigned long offset = 0;
49002 - char *modname, namebuf[128];
49003 + char *modname, namebuf[KSYM_NAME_LEN];
49004
49005 head = &kprobe_table[i];
49006 preempt_disable();
49007 diff -urNp linux-2.6.36/kernel/lockdep.c linux-2.6.36/kernel/lockdep.c
49008 --- linux-2.6.36/kernel/lockdep.c 2010-10-20 16:30:22.000000000 -0400
49009 +++ linux-2.6.36/kernel/lockdep.c 2010-11-06 18:58:15.000000000 -0400
49010 @@ -571,6 +571,10 @@ static int static_obj(void *obj)
49011 end = (unsigned long) &_end,
49012 addr = (unsigned long) obj;
49013
49014 +#ifdef CONFIG_PAX_KERNEXEC
49015 + start = ktla_ktva(start);
49016 +#endif
49017 +
49018 /*
49019 * static variable?
49020 */
49021 @@ -696,6 +700,7 @@ register_lock_class(struct lockdep_map *
49022 if (!static_obj(lock->key)) {
49023 debug_locks_off();
49024 printk("INFO: trying to register non-static key.\n");
49025 + printk("lock:%pS key:%pS.\n", lock, lock->key);
49026 printk("the code is fine but needs lockdep annotation.\n");
49027 printk("turning off the locking correctness validator.\n");
49028 dump_stack();
49029 diff -urNp linux-2.6.36/kernel/lockdep_proc.c linux-2.6.36/kernel/lockdep_proc.c
49030 --- linux-2.6.36/kernel/lockdep_proc.c 2010-10-20 16:30:22.000000000 -0400
49031 +++ linux-2.6.36/kernel/lockdep_proc.c 2010-11-06 18:58:15.000000000 -0400
49032 @@ -39,7 +39,7 @@ static void l_stop(struct seq_file *m, v
49033
49034 static void print_name(struct seq_file *m, struct lock_class *class)
49035 {
49036 - char str[128];
49037 + char str[KSYM_NAME_LEN];
49038 const char *name = class->name;
49039
49040 if (!name) {
49041 diff -urNp linux-2.6.36/kernel/module.c linux-2.6.36/kernel/module.c
49042 --- linux-2.6.36/kernel/module.c 2010-10-20 16:30:22.000000000 -0400
49043 +++ linux-2.6.36/kernel/module.c 2010-11-06 18:58:50.000000000 -0400
49044 @@ -96,7 +96,8 @@ static BLOCKING_NOTIFIER_HEAD(module_not
49045
49046 /* Bounds of module allocation, for speeding __module_address.
49047 * Protected by module_mutex. */
49048 -static unsigned long module_addr_min = -1UL, module_addr_max = 0;
49049 +static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
49050 +static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
49051
49052 int register_module_notifier(struct notifier_block * nb)
49053 {
49054 @@ -260,7 +261,7 @@ bool each_symbol(bool (*fn)(const struct
49055 return true;
49056
49057 list_for_each_entry_rcu(mod, &modules, list) {
49058 - struct symsearch arr[] = {
49059 + struct symsearch modarr[] = {
49060 { mod->syms, mod->syms + mod->num_syms, mod->crcs,
49061 NOT_GPL_ONLY, false },
49062 { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
49063 @@ -282,7 +283,7 @@ bool each_symbol(bool (*fn)(const struct
49064 #endif
49065 };
49066
49067 - if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
49068 + if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
49069 return true;
49070 }
49071 return false;
49072 @@ -393,7 +394,7 @@ static inline void __percpu *mod_percpu(
49073 static int percpu_modalloc(struct module *mod,
49074 unsigned long size, unsigned long align)
49075 {
49076 - if (align > PAGE_SIZE) {
49077 + if (align-1 >= PAGE_SIZE) {
49078 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
49079 mod->name, align, PAGE_SIZE);
49080 align = PAGE_SIZE;
49081 @@ -1565,15 +1566,18 @@ static void free_module(struct module *m
49082 destroy_params(mod->kp, mod->num_kp);
49083
49084 /* This may be NULL, but that's OK */
49085 - module_free(mod, mod->module_init);
49086 + module_free(mod, mod->module_init_rw);
49087 + module_free_exec(mod, mod->module_init_rx);
49088 kfree(mod->args);
49089 percpu_modfree(mod);
49090
49091 /* Free lock-classes: */
49092 - lockdep_free_key_range(mod->module_core, mod->core_size);
49093 + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
49094 + lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
49095
49096 /* Finally, free the core (containing the module structure) */
49097 - module_free(mod, mod->module_core);
49098 + module_free_exec(mod, mod->module_core_rx);
49099 + module_free(mod, mod->module_core_rw);
49100
49101 #ifdef CONFIG_MPU
49102 update_protections(current->mm);
49103 @@ -1666,7 +1670,9 @@ static int simplify_symbols(struct modul
49104 ksym = resolve_symbol_wait(mod, info, name);
49105 /* Ok if resolved. */
49106 if (ksym && !IS_ERR(ksym)) {
49107 + pax_open_kernel();
49108 sym[i].st_value = ksym->value;
49109 + pax_close_kernel();
49110 break;
49111 }
49112
49113 @@ -1685,7 +1691,9 @@ static int simplify_symbols(struct modul
49114 secbase = (unsigned long)mod_percpu(mod);
49115 else
49116 secbase = info->sechdrs[sym[i].st_shndx].sh_addr;
49117 + pax_open_kernel();
49118 sym[i].st_value += secbase;
49119 + pax_close_kernel();
49120 break;
49121 }
49122 }
49123 @@ -1773,11 +1781,12 @@ static void layout_sections(struct modul
49124 || s->sh_entsize != ~0UL
49125 || strstarts(sname, ".init"))
49126 continue;
49127 - s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
49128 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
49129 + s->sh_entsize = get_offset(mod, &mod->core_size_rw, s, i);
49130 + else
49131 + s->sh_entsize = get_offset(mod, &mod->core_size_rx, s, i);
49132 DEBUGP("\t%s\n", name);
49133 }
49134 - if (m == 0)
49135 - mod->core_text_size = mod->core_size;
49136 }
49137
49138 DEBUGP("Init section allocation order:\n");
49139 @@ -1791,12 +1800,13 @@ static void layout_sections(struct modul
49140 || s->sh_entsize != ~0UL
49141 || !strstarts(sname, ".init"))
49142 continue;
49143 - s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
49144 - | INIT_OFFSET_MASK);
49145 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
49146 + s->sh_entsize = get_offset(mod, &mod->init_size_rw, s, i);
49147 + else
49148 + s->sh_entsize = get_offset(mod, &mod->init_size_rx, s, i);
49149 + s->sh_entsize |= INIT_OFFSET_MASK;
49150 DEBUGP("\t%s\n", sname);
49151 }
49152 - if (m == 0)
49153 - mod->init_text_size = mod->init_size;
49154 }
49155 }
49156
49157 @@ -1964,7 +1974,7 @@ static void layout_symtab(struct module
49158
49159 /* Put symbol section at end of init part of module. */
49160 symsect->sh_flags |= SHF_ALLOC;
49161 - symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect,
49162 + symsect->sh_entsize = get_offset(mod, &mod->init_size_rx, symsect,
49163 info->index.sym) | INIT_OFFSET_MASK;
49164 DEBUGP("\t%s\n", info->secstrings + symsect->sh_name);
49165
49166 @@ -1981,19 +1991,19 @@ static void layout_symtab(struct module
49167 }
49168
49169 /* Append room for core symbols at end of core part. */
49170 - info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
49171 - mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym);
49172 + info->symoffs = ALIGN(mod->core_size_rx, symsect->sh_addralign ?: 1);
49173 + mod->core_size_rx = info->symoffs + ndst * sizeof(Elf_Sym);
49174
49175 /* Put string table section at end of init part of module. */
49176 strsect->sh_flags |= SHF_ALLOC;
49177 - strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
49178 + strsect->sh_entsize = get_offset(mod, &mod->init_size_rx, strsect,
49179 info->index.str) | INIT_OFFSET_MASK;
49180 DEBUGP("\t%s\n", info->secstrings + strsect->sh_name);
49181
49182 /* Append room for core symbols' strings at end of core part. */
49183 - info->stroffs = mod->core_size;
49184 + info->stroffs = mod->core_size_rx;
49185 __set_bit(0, info->strmap);
49186 - mod->core_size += bitmap_weight(info->strmap, strsect->sh_size);
49187 + mod->core_size_rx += bitmap_weight(info->strmap, strsect->sh_size);
49188 }
49189
49190 static void add_kallsyms(struct module *mod, const struct load_info *info)
49191 @@ -2009,11 +2019,13 @@ static void add_kallsyms(struct module *
49192 /* Make sure we get permanent strtab: don't use info->strtab. */
49193 mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
49194
49195 + pax_open_kernel();
49196 +
49197 /* Set types up while we still have access to sections. */
49198 for (i = 0; i < mod->num_symtab; i++)
49199 mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
49200
49201 - mod->core_symtab = dst = mod->module_core + info->symoffs;
49202 + mod->core_symtab = dst = mod->module_core_rx + info->symoffs;
49203 src = mod->symtab;
49204 *dst = *src;
49205 for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
49206 @@ -2026,10 +2038,12 @@ static void add_kallsyms(struct module *
49207 }
49208 mod->core_num_syms = ndst;
49209
49210 - mod->core_strtab = s = mod->module_core + info->stroffs;
49211 + mod->core_strtab = s = mod->module_core_rx + info->stroffs;
49212 for (*s = 0, i = 1; i < info->sechdrs[info->index.str].sh_size; ++i)
49213 if (test_bit(i, info->strmap))
49214 *++s = mod->strtab[i];
49215 +
49216 + pax_close_kernel();
49217 }
49218 #else
49219 static inline void layout_symtab(struct module *mod, struct load_info *info)
49220 @@ -2058,17 +2072,33 @@ static void dynamic_debug_remove(struct
49221 ddebug_remove_module(debug->modname);
49222 }
49223
49224 -static void *module_alloc_update_bounds(unsigned long size)
49225 +static void *module_alloc_update_bounds_rw(unsigned long size)
49226 {
49227 void *ret = module_alloc(size);
49228
49229 if (ret) {
49230 mutex_lock(&module_mutex);
49231 /* Update module bounds. */
49232 - if ((unsigned long)ret < module_addr_min)
49233 - module_addr_min = (unsigned long)ret;
49234 - if ((unsigned long)ret + size > module_addr_max)
49235 - module_addr_max = (unsigned long)ret + size;
49236 + if ((unsigned long)ret < module_addr_min_rw)
49237 + module_addr_min_rw = (unsigned long)ret;
49238 + if ((unsigned long)ret + size > module_addr_max_rw)
49239 + module_addr_max_rw = (unsigned long)ret + size;
49240 + mutex_unlock(&module_mutex);
49241 + }
49242 + return ret;
49243 +}
49244 +
49245 +static void *module_alloc_update_bounds_rx(unsigned long size)
49246 +{
49247 + void *ret = module_alloc_exec(size);
49248 +
49249 + if (ret) {
49250 + mutex_lock(&module_mutex);
49251 + /* Update module bounds. */
49252 + if ((unsigned long)ret < module_addr_min_rx)
49253 + module_addr_min_rx = (unsigned long)ret;
49254 + if ((unsigned long)ret + size > module_addr_max_rx)
49255 + module_addr_max_rx = (unsigned long)ret + size;
49256 mutex_unlock(&module_mutex);
49257 }
49258 return ret;
49259 @@ -2344,7 +2374,7 @@ static int move_module(struct module *mo
49260 void *ptr;
49261
49262 /* Do the allocs. */
49263 - ptr = module_alloc_update_bounds(mod->core_size);
49264 + ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
49265 /*
49266 * The pointer to this block is stored in the module structure
49267 * which is inside the block. Just mark it as not being a
49268 @@ -2354,23 +2384,50 @@ static int move_module(struct module *mo
49269 if (!ptr)
49270 return -ENOMEM;
49271
49272 - memset(ptr, 0, mod->core_size);
49273 - mod->module_core = ptr;
49274 + memset(ptr, 0, mod->core_size_rw);
49275 + mod->module_core_rw = ptr;
49276
49277 - ptr = module_alloc_update_bounds(mod->init_size);
49278 + ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
49279 /*
49280 * The pointer to this block is stored in the module structure
49281 * which is inside the block. This block doesn't need to be
49282 * scanned as it contains data and code that will be freed
49283 * after the module is initialized.
49284 */
49285 - kmemleak_ignore(ptr);
49286 - if (!ptr && mod->init_size) {
49287 - module_free(mod, mod->module_core);
49288 + kmemleak_not_leak(ptr);
49289 + if (!ptr && mod->init_size_rw) {
49290 + module_free(mod, mod->module_core_rw);
49291 + return -ENOMEM;
49292 + }
49293 + memset(ptr, 0, mod->init_size_rw);
49294 + mod->module_init_rw = ptr;
49295 +
49296 + ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
49297 + kmemleak_not_leak(ptr);
49298 + if (!ptr) {
49299 + module_free(mod, mod->module_init_rw);
49300 + module_free(mod, mod->module_core_rw);
49301 return -ENOMEM;
49302 }
49303 - memset(ptr, 0, mod->init_size);
49304 - mod->module_init = ptr;
49305 +
49306 + pax_open_kernel();
49307 + memset(ptr, 0, mod->core_size_rx);
49308 + pax_close_kernel();
49309 + mod->module_core_rx = ptr;
49310 +
49311 + ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
49312 + kmemleak_not_leak(ptr);
49313 + if (!ptr && mod->init_size_rx) {
49314 + module_free_exec(mod, mod->module_core_rx);
49315 + module_free(mod, mod->module_init_rw);
49316 + module_free(mod, mod->module_core_rw);
49317 + return -ENOMEM;
49318 + }
49319 +
49320 + pax_open_kernel();
49321 + memset(ptr, 0, mod->init_size_rx);
49322 + pax_close_kernel();
49323 + mod->module_init_rx = ptr;
49324
49325 /* Transfer each section which specifies SHF_ALLOC */
49326 DEBUGP("final section addresses:\n");
49327 @@ -2381,16 +2438,41 @@ static int move_module(struct module *mo
49328 if (!(shdr->sh_flags & SHF_ALLOC))
49329 continue;
49330
49331 - if (shdr->sh_entsize & INIT_OFFSET_MASK)
49332 - dest = mod->module_init
49333 - + (shdr->sh_entsize & ~INIT_OFFSET_MASK);
49334 - else
49335 - dest = mod->module_core + shdr->sh_entsize;
49336 + if (shdr->sh_entsize & INIT_OFFSET_MASK) {
49337 + if ((shdr->sh_flags & SHF_WRITE) || !(shdr->sh_flags & SHF_ALLOC))
49338 + dest = mod->module_init_rw
49339 + + (shdr->sh_entsize & ~INIT_OFFSET_MASK);
49340 + else
49341 + dest = mod->module_init_rx
49342 + + (shdr->sh_entsize & ~INIT_OFFSET_MASK);
49343 + } else {
49344 + if ((shdr->sh_flags & SHF_WRITE) || !(shdr->sh_flags & SHF_ALLOC))
49345 + dest = mod->module_core_rw + shdr->sh_entsize;
49346 + else
49347 + dest = mod->module_core_rx + shdr->sh_entsize;
49348 + }
49349 +
49350 + if (shdr->sh_type != SHT_NOBITS) {
49351 +
49352 +#ifdef CONFIG_PAX_KERNEXEC
49353 + if (!(shdr->sh_flags & SHF_WRITE) && (shdr->sh_flags & SHF_ALLOC)) {
49354 + pax_open_kernel();
49355 + memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
49356 + pax_close_kernel();
49357 + } else
49358 +#endif
49359
49360 - if (shdr->sh_type != SHT_NOBITS)
49361 memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
49362 + }
49363 /* Update sh_addr to point to copy in image. */
49364 - shdr->sh_addr = (unsigned long)dest;
49365 +
49366 +#ifdef CONFIG_PAX_KERNEXEC
49367 + if (shdr->sh_flags & SHF_EXECINSTR)
49368 + shdr->sh_addr = ktva_ktla((unsigned long)dest);
49369 + else
49370 +#endif
49371 +
49372 + shdr->sh_addr = (unsigned long)dest;
49373 DEBUGP("\t0x%lx %s\n",
49374 shdr->sh_addr, info->secstrings + shdr->sh_name);
49375 }
49376 @@ -2441,12 +2523,12 @@ static void flush_module_icache(const st
49377 * Do it before processing of module parameters, so the module
49378 * can provide parameter accessor functions of its own.
49379 */
49380 - if (mod->module_init)
49381 - flush_icache_range((unsigned long)mod->module_init,
49382 - (unsigned long)mod->module_init
49383 - + mod->init_size);
49384 - flush_icache_range((unsigned long)mod->module_core,
49385 - (unsigned long)mod->module_core + mod->core_size);
49386 + if (mod->module_init_rx)
49387 + flush_icache_range((unsigned long)mod->module_init_rx,
49388 + (unsigned long)mod->module_init_rx
49389 + + mod->init_size_rx);
49390 + flush_icache_range((unsigned long)mod->module_core_rx,
49391 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
49392
49393 set_fs(old_fs);
49394 }
49395 @@ -2518,8 +2600,10 @@ static void module_deallocate(struct mod
49396 {
49397 kfree(info->strmap);
49398 percpu_modfree(mod);
49399 - module_free(mod, mod->module_init);
49400 - module_free(mod, mod->module_core);
49401 + module_free_exec(mod, mod->module_init_rx);
49402 + module_free_exec(mod, mod->module_core_rx);
49403 + module_free(mod, mod->module_init_rw);
49404 + module_free(mod, mod->module_core_rw);
49405 }
49406
49407 static int post_relocation(struct module *mod, const struct load_info *info)
49408 @@ -2747,10 +2831,12 @@ SYSCALL_DEFINE3(init_module, void __user
49409 mod->symtab = mod->core_symtab;
49410 mod->strtab = mod->core_strtab;
49411 #endif
49412 - module_free(mod, mod->module_init);
49413 - mod->module_init = NULL;
49414 - mod->init_size = 0;
49415 - mod->init_text_size = 0;
49416 + module_free(mod, mod->module_init_rw);
49417 + module_free_exec(mod, mod->module_init_rx);
49418 + mod->module_init_rw = NULL;
49419 + mod->module_init_rx = NULL;
49420 + mod->init_size_rw = 0;
49421 + mod->init_size_rx = 0;
49422 mutex_unlock(&module_mutex);
49423
49424 return 0;
49425 @@ -2781,10 +2867,16 @@ static const char *get_ksymbol(struct mo
49426 unsigned long nextval;
49427
49428 /* At worse, next value is at end of module */
49429 - if (within_module_init(addr, mod))
49430 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
49431 + if (within_module_init_rx(addr, mod))
49432 + nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
49433 + else if (within_module_init_rw(addr, mod))
49434 + nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
49435 + else if (within_module_core_rx(addr, mod))
49436 + nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
49437 + else if (within_module_core_rw(addr, mod))
49438 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
49439 else
49440 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
49441 + return NULL;
49442
49443 /* Scan for closest preceeding symbol, and next symbol. (ELF
49444 starts real symbols at 1). */
49445 @@ -3030,7 +3122,7 @@ static int m_show(struct seq_file *m, vo
49446 char buf[8];
49447
49448 seq_printf(m, "%s %u",
49449 - mod->name, mod->init_size + mod->core_size);
49450 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
49451 print_unload_info(m, mod);
49452
49453 /* Informative for users. */
49454 @@ -3039,7 +3131,7 @@ static int m_show(struct seq_file *m, vo
49455 mod->state == MODULE_STATE_COMING ? "Loading":
49456 "Live");
49457 /* Used by oprofile and other similar tools. */
49458 - seq_printf(m, " 0x%p", mod->module_core);
49459 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
49460
49461 /* Taints info */
49462 if (mod->taints)
49463 @@ -3075,7 +3167,17 @@ static const struct file_operations proc
49464
49465 static int __init proc_modules_init(void)
49466 {
49467 +#ifndef CONFIG_GRKERNSEC_HIDESYM
49468 +#ifdef CONFIG_GRKERNSEC_PROC_USER
49469 + proc_create("modules", S_IRUSR, NULL, &proc_modules_operations);
49470 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
49471 + proc_create("modules", S_IRUSR | S_IRGRP, NULL, &proc_modules_operations);
49472 +#else
49473 proc_create("modules", 0, NULL, &proc_modules_operations);
49474 +#endif
49475 +#else
49476 + proc_create("modules", S_IRUSR, NULL, &proc_modules_operations);
49477 +#endif
49478 return 0;
49479 }
49480 module_init(proc_modules_init);
49481 @@ -3134,12 +3236,12 @@ struct module *__module_address(unsigned
49482 {
49483 struct module *mod;
49484
49485 - if (addr < module_addr_min || addr > module_addr_max)
49486 + if ((addr < module_addr_min_rx || addr > module_addr_max_rx) &&
49487 + (addr < module_addr_min_rw || addr > module_addr_max_rw))
49488 return NULL;
49489
49490 list_for_each_entry_rcu(mod, &modules, list)
49491 - if (within_module_core(addr, mod)
49492 - || within_module_init(addr, mod))
49493 + if (within_module_init(addr, mod) || within_module_core(addr, mod))
49494 return mod;
49495 return NULL;
49496 }
49497 @@ -3173,11 +3275,20 @@ bool is_module_text_address(unsigned lon
49498 */
49499 struct module *__module_text_address(unsigned long addr)
49500 {
49501 - struct module *mod = __module_address(addr);
49502 + struct module *mod;
49503 +
49504 +#ifdef CONFIG_X86_32
49505 + addr = ktla_ktva(addr);
49506 +#endif
49507 +
49508 + if (addr < module_addr_min_rx || addr > module_addr_max_rx)
49509 + return NULL;
49510 +
49511 + mod = __module_address(addr);
49512 +
49513 if (mod) {
49514 /* Make sure it's within the text section. */
49515 - if (!within(addr, mod->module_init, mod->init_text_size)
49516 - && !within(addr, mod->module_core, mod->core_text_size))
49517 + if (!within_module_init_rx(addr, mod) && !within_module_core_rx(addr, mod))
49518 mod = NULL;
49519 }
49520 return mod;
49521 diff -urNp linux-2.6.36/kernel/panic.c linux-2.6.36/kernel/panic.c
49522 --- linux-2.6.36/kernel/panic.c 2010-10-20 16:30:22.000000000 -0400
49523 +++ linux-2.6.36/kernel/panic.c 2010-11-06 18:58:15.000000000 -0400
49524 @@ -423,7 +423,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
49525 */
49526 void __stack_chk_fail(void)
49527 {
49528 - panic("stack-protector: Kernel stack is corrupted in: %p\n",
49529 + dump_stack();
49530 + panic("stack-protector: Kernel stack is corrupted in: %pS\n",
49531 __builtin_return_address(0));
49532 }
49533 EXPORT_SYMBOL(__stack_chk_fail);
49534 diff -urNp linux-2.6.36/kernel/pid.c linux-2.6.36/kernel/pid.c
49535 --- linux-2.6.36/kernel/pid.c 2010-10-20 16:30:22.000000000 -0400
49536 +++ linux-2.6.36/kernel/pid.c 2010-11-06 18:58:50.000000000 -0400
49537 @@ -33,6 +33,7 @@
49538 #include <linux/rculist.h>
49539 #include <linux/bootmem.h>
49540 #include <linux/hash.h>
49541 +#include <linux/security.h>
49542 #include <linux/pid_namespace.h>
49543 #include <linux/init_task.h>
49544 #include <linux/syscalls.h>
49545 @@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
49546
49547 int pid_max = PID_MAX_DEFAULT;
49548
49549 -#define RESERVED_PIDS 300
49550 +#define RESERVED_PIDS 500
49551
49552 int pid_max_min = RESERVED_PIDS + 1;
49553 int pid_max_max = PID_MAX_LIMIT;
49554 @@ -416,7 +417,14 @@ EXPORT_SYMBOL(pid_task);
49555 */
49556 struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
49557 {
49558 - return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
49559 + struct task_struct *task;
49560 +
49561 + task = pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
49562 +
49563 + if (gr_pid_is_chrooted(task))
49564 + return NULL;
49565 +
49566 + return task;
49567 }
49568
49569 struct task_struct *find_task_by_vpid(pid_t vnr)
49570 diff -urNp linux-2.6.36/kernel/posix-cpu-timers.c linux-2.6.36/kernel/posix-cpu-timers.c
49571 --- linux-2.6.36/kernel/posix-cpu-timers.c 2010-10-20 16:30:22.000000000 -0400
49572 +++ linux-2.6.36/kernel/posix-cpu-timers.c 2010-11-06 18:58:50.000000000 -0400
49573 @@ -6,6 +6,7 @@
49574 #include <linux/posix-timers.h>
49575 #include <linux/errno.h>
49576 #include <linux/math64.h>
49577 +#include <linux/security.h>
49578 #include <asm/uaccess.h>
49579 #include <linux/kernel_stat.h>
49580 #include <trace/events/timer.h>
49581 @@ -965,6 +966,7 @@ static void check_thread_timers(struct t
49582 unsigned long hard =
49583 ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max);
49584
49585 + gr_learn_resource(tsk, RLIMIT_RTTIME, tsk->rt.timeout * (USEC_PER_SEC/HZ), 1);
49586 if (hard != RLIM_INFINITY &&
49587 tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
49588 /*
49589 @@ -1131,6 +1133,7 @@ static void check_process_timers(struct
49590 unsigned long hard =
49591 ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max);
49592 cputime_t x;
49593 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 0);
49594 if (psecs >= hard) {
49595 /*
49596 * At the hard limit, we just die.
49597 diff -urNp linux-2.6.36/kernel/power/hibernate.c linux-2.6.36/kernel/power/hibernate.c
49598 --- linux-2.6.36/kernel/power/hibernate.c 2010-10-20 16:30:22.000000000 -0400
49599 +++ linux-2.6.36/kernel/power/hibernate.c 2010-11-06 18:58:15.000000000 -0400
49600 @@ -50,14 +50,14 @@ enum {
49601
49602 static int hibernation_mode = HIBERNATION_SHUTDOWN;
49603
49604 -static struct platform_hibernation_ops *hibernation_ops;
49605 +static const struct platform_hibernation_ops *hibernation_ops;
49606
49607 /**
49608 * hibernation_set_ops - set the global hibernate operations
49609 * @ops: the hibernation operations to use in subsequent hibernation transitions
49610 */
49611
49612 -void hibernation_set_ops(struct platform_hibernation_ops *ops)
49613 +void hibernation_set_ops(const struct platform_hibernation_ops *ops)
49614 {
49615 if (ops && !(ops->begin && ops->end && ops->pre_snapshot
49616 && ops->prepare && ops->finish && ops->enter && ops->pre_restore
49617 diff -urNp linux-2.6.36/kernel/power/poweroff.c linux-2.6.36/kernel/power/poweroff.c
49618 --- linux-2.6.36/kernel/power/poweroff.c 2010-10-20 16:30:22.000000000 -0400
49619 +++ linux-2.6.36/kernel/power/poweroff.c 2010-11-06 18:58:15.000000000 -0400
49620 @@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
49621 .enable_mask = SYSRQ_ENABLE_BOOT,
49622 };
49623
49624 -static int pm_sysrq_init(void)
49625 +static int __init pm_sysrq_init(void)
49626 {
49627 register_sysrq_key('o', &sysrq_poweroff_op);
49628 return 0;
49629 diff -urNp linux-2.6.36/kernel/power/process.c linux-2.6.36/kernel/power/process.c
49630 --- linux-2.6.36/kernel/power/process.c 2010-10-20 16:30:22.000000000 -0400
49631 +++ linux-2.6.36/kernel/power/process.c 2010-11-06 18:58:15.000000000 -0400
49632 @@ -40,6 +40,7 @@ static int try_to_freeze_tasks(bool sig_
49633 struct timeval start, end;
49634 u64 elapsed_csecs64;
49635 unsigned int elapsed_csecs;
49636 + bool timedout = false;
49637
49638 do_gettimeofday(&start);
49639
49640 @@ -50,6 +51,8 @@ static int try_to_freeze_tasks(bool sig_
49641
49642 while (true) {
49643 todo = 0;
49644 + if (time_after(jiffies, end_time))
49645 + timedout = true;
49646 read_lock(&tasklist_lock);
49647 do_each_thread(g, p) {
49648 if (frozen(p) || !freezeable(p))
49649 @@ -64,9 +67,13 @@ static int try_to_freeze_tasks(bool sig_
49650 * It is "frozen enough". If the task does wake
49651 * up, it will immediately call try_to_freeze.
49652 */
49653 - if (!task_is_stopped_or_traced(p) &&
49654 - !freezer_should_skip(p))
49655 + if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) {
49656 todo++;
49657 + if (timedout) {
49658 + printk(KERN_ERR "Task refusing to freeze:\n");
49659 + sched_show_task(p);
49660 + }
49661 + }
49662 } while_each_thread(g, p);
49663 read_unlock(&tasklist_lock);
49664
49665 @@ -75,7 +82,7 @@ static int try_to_freeze_tasks(bool sig_
49666 todo += wq_busy;
49667 }
49668
49669 - if (!todo || time_after(jiffies, end_time))
49670 + if (!todo || timedout)
49671 break;
49672
49673 /*
49674 diff -urNp linux-2.6.36/kernel/power/suspend.c linux-2.6.36/kernel/power/suspend.c
49675 --- linux-2.6.36/kernel/power/suspend.c 2010-10-20 16:30:22.000000000 -0400
49676 +++ linux-2.6.36/kernel/power/suspend.c 2010-11-06 18:58:15.000000000 -0400
49677 @@ -30,13 +30,13 @@ const char *const pm_states[PM_SUSPEND_M
49678 [PM_SUSPEND_MEM] = "mem",
49679 };
49680
49681 -static struct platform_suspend_ops *suspend_ops;
49682 +static const struct platform_suspend_ops *suspend_ops;
49683
49684 /**
49685 * suspend_set_ops - Set the global suspend method table.
49686 * @ops: Pointer to ops structure.
49687 */
49688 -void suspend_set_ops(struct platform_suspend_ops *ops)
49689 +void suspend_set_ops(const struct platform_suspend_ops *ops)
49690 {
49691 mutex_lock(&pm_mutex);
49692 suspend_ops = ops;
49693 diff -urNp linux-2.6.36/kernel/printk.c linux-2.6.36/kernel/printk.c
49694 --- linux-2.6.36/kernel/printk.c 2010-10-20 16:30:22.000000000 -0400
49695 +++ linux-2.6.36/kernel/printk.c 2010-11-06 18:58:50.000000000 -0400
49696 @@ -268,6 +268,11 @@ int do_syslog(int type, char __user *buf
49697 char c;
49698 int error = 0;
49699
49700 +#ifdef CONFIG_GRKERNSEC_DMESG
49701 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
49702 + return -EPERM;
49703 +#endif
49704 +
49705 error = security_syslog(type, from_file);
49706 if (error)
49707 return error;
49708 diff -urNp linux-2.6.36/kernel/ptrace.c linux-2.6.36/kernel/ptrace.c
49709 --- linux-2.6.36/kernel/ptrace.c 2010-10-20 16:30:22.000000000 -0400
49710 +++ linux-2.6.36/kernel/ptrace.c 2010-11-06 18:58:50.000000000 -0400
49711 @@ -140,7 +140,7 @@ int __ptrace_may_access(struct task_stru
49712 cred->gid != tcred->egid ||
49713 cred->gid != tcred->sgid ||
49714 cred->gid != tcred->gid) &&
49715 - !capable(CAP_SYS_PTRACE)) {
49716 + !capable_nolog(CAP_SYS_PTRACE)) {
49717 rcu_read_unlock();
49718 return -EPERM;
49719 }
49720 @@ -148,7 +148,7 @@ int __ptrace_may_access(struct task_stru
49721 smp_rmb();
49722 if (task->mm)
49723 dumpable = get_dumpable(task->mm);
49724 - if (!dumpable && !capable(CAP_SYS_PTRACE))
49725 + if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
49726 return -EPERM;
49727
49728 return security_ptrace_access_check(task, mode);
49729 @@ -198,7 +198,7 @@ int ptrace_attach(struct task_struct *ta
49730 goto unlock_tasklist;
49731
49732 task->ptrace = PT_PTRACED;
49733 - if (capable(CAP_SYS_PTRACE))
49734 + if (capable_nolog(CAP_SYS_PTRACE))
49735 task->ptrace |= PT_PTRACE_CAP;
49736
49737 __ptrace_link(task, current);
49738 @@ -367,7 +367,7 @@ int ptrace_readdata(struct task_struct *
49739 break;
49740 return -EIO;
49741 }
49742 - if (copy_to_user(dst, buf, retval))
49743 + if (retval > sizeof(buf) || copy_to_user(dst, buf, retval))
49744 return -EFAULT;
49745 copied += retval;
49746 src += retval;
49747 @@ -578,18 +578,18 @@ int ptrace_request(struct task_struct *c
49748 ret = ptrace_setoptions(child, data);
49749 break;
49750 case PTRACE_GETEVENTMSG:
49751 - ret = put_user(child->ptrace_message, (unsigned long __user *) data);
49752 + ret = put_user(child->ptrace_message, (__force unsigned long __user *) data);
49753 break;
49754
49755 case PTRACE_GETSIGINFO:
49756 ret = ptrace_getsiginfo(child, &siginfo);
49757 if (!ret)
49758 - ret = copy_siginfo_to_user((siginfo_t __user *) data,
49759 + ret = copy_siginfo_to_user((__force siginfo_t __user *) data,
49760 &siginfo);
49761 break;
49762
49763 case PTRACE_SETSIGINFO:
49764 - if (copy_from_user(&siginfo, (siginfo_t __user *) data,
49765 + if (copy_from_user(&siginfo, (__force siginfo_t __user *) data,
49766 sizeof siginfo))
49767 ret = -EFAULT;
49768 else
49769 @@ -709,14 +709,21 @@ SYSCALL_DEFINE4(ptrace, long, request, l
49770 goto out;
49771 }
49772
49773 + if (gr_handle_ptrace(child, request)) {
49774 + ret = -EPERM;
49775 + goto out_put_task_struct;
49776 + }
49777 +
49778 if (request == PTRACE_ATTACH) {
49779 ret = ptrace_attach(child);
49780 /*
49781 * Some architectures need to do book-keeping after
49782 * a ptrace attach.
49783 */
49784 - if (!ret)
49785 + if (!ret) {
49786 arch_ptrace_attach(child);
49787 + gr_audit_ptrace(child);
49788 + }
49789 goto out_put_task_struct;
49790 }
49791
49792 @@ -740,7 +747,7 @@ int generic_ptrace_peekdata(struct task_
49793 copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
49794 if (copied != sizeof(tmp))
49795 return -EIO;
49796 - return put_user(tmp, (unsigned long __user *)data);
49797 + return put_user(tmp, (__force unsigned long __user *)data);
49798 }
49799
49800 int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
49801 diff -urNp linux-2.6.36/kernel/rcutree.c linux-2.6.36/kernel/rcutree.c
49802 --- linux-2.6.36/kernel/rcutree.c 2010-10-20 16:30:22.000000000 -0400
49803 +++ linux-2.6.36/kernel/rcutree.c 2010-11-06 18:58:15.000000000 -0400
49804 @@ -1357,7 +1357,7 @@ __rcu_process_callbacks(struct rcu_state
49805 /*
49806 * Do softirq processing for the current CPU.
49807 */
49808 -static void rcu_process_callbacks(struct softirq_action *unused)
49809 +static void rcu_process_callbacks(void)
49810 {
49811 /*
49812 * Memory references from any prior RCU read-side critical sections
49813 diff -urNp linux-2.6.36/kernel/resource.c linux-2.6.36/kernel/resource.c
49814 --- linux-2.6.36/kernel/resource.c 2010-10-20 16:30:22.000000000 -0400
49815 +++ linux-2.6.36/kernel/resource.c 2010-11-06 18:58:50.000000000 -0400
49816 @@ -133,8 +133,18 @@ static const struct file_operations proc
49817
49818 static int __init ioresources_init(void)
49819 {
49820 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
49821 +#ifdef CONFIG_GRKERNSEC_PROC_USER
49822 + proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
49823 + proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
49824 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
49825 + proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
49826 + proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
49827 +#endif
49828 +#else
49829 proc_create("ioports", 0, NULL, &proc_ioports_operations);
49830 proc_create("iomem", 0, NULL, &proc_iomem_operations);
49831 +#endif
49832 return 0;
49833 }
49834 __initcall(ioresources_init);
49835 diff -urNp linux-2.6.36/kernel/rtmutex.c linux-2.6.36/kernel/rtmutex.c
49836 --- linux-2.6.36/kernel/rtmutex.c 2010-10-20 16:30:22.000000000 -0400
49837 +++ linux-2.6.36/kernel/rtmutex.c 2010-11-06 18:58:15.000000000 -0400
49838 @@ -511,7 +511,7 @@ static void wakeup_next_waiter(struct rt
49839 */
49840 raw_spin_lock_irqsave(&pendowner->pi_lock, flags);
49841
49842 - WARN_ON(!pendowner->pi_blocked_on);
49843 + BUG_ON(!pendowner->pi_blocked_on);
49844 WARN_ON(pendowner->pi_blocked_on != waiter);
49845 WARN_ON(pendowner->pi_blocked_on->lock != lock);
49846
49847 diff -urNp linux-2.6.36/kernel/sched.c linux-2.6.36/kernel/sched.c
49848 --- linux-2.6.36/kernel/sched.c 2010-10-20 16:30:22.000000000 -0400
49849 +++ linux-2.6.36/kernel/sched.c 2010-11-06 19:41:42.000000000 -0400
49850 @@ -4443,6 +4443,8 @@ int can_nice(const struct task_struct *p
49851 /* convert nice value [19,-20] to rlimit style value [1,40] */
49852 int nice_rlim = 20 - nice;
49853
49854 + gr_learn_resource(p, RLIMIT_NICE, nice_rlim, 1);
49855 +
49856 return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
49857 capable(CAP_SYS_NICE));
49858 }
49859 @@ -4476,7 +4478,8 @@ SYSCALL_DEFINE1(nice, int, increment)
49860 if (nice > 19)
49861 nice = 19;
49862
49863 - if (increment < 0 && !can_nice(current, nice))
49864 + if (increment < 0 && (!can_nice(current, nice) ||
49865 + gr_handle_chroot_nice()))
49866 return -EPERM;
49867
49868 retval = security_task_setnice(current, nice);
49869 @@ -4619,6 +4622,7 @@ recheck:
49870 unsigned long rlim_rtprio =
49871 task_rlimit(p, RLIMIT_RTPRIO);
49872
49873 + gr_learn_resource(p, RLIMIT_RTPRIO, param->sched_priority, 1);
49874 /* can't set/change the rt policy */
49875 if (policy != p->policy && !rlim_rtprio)
49876 return -EPERM;
49877 @@ -6785,7 +6789,7 @@ static void init_sched_groups_power(int
49878 long power;
49879 int weight;
49880
49881 - WARN_ON(!sd || !sd->groups);
49882 + BUG_ON(!sd || !sd->groups);
49883
49884 if (cpu != group_first_cpu(sd->groups))
49885 return;
49886 diff -urNp linux-2.6.36/kernel/sched_fair.c linux-2.6.36/kernel/sched_fair.c
49887 --- linux-2.6.36/kernel/sched_fair.c 2010-10-20 16:30:22.000000000 -0400
49888 +++ linux-2.6.36/kernel/sched_fair.c 2010-11-06 18:58:15.000000000 -0400
49889 @@ -3662,7 +3662,7 @@ static void nohz_idle_balance(int this_c
49890 * run_rebalance_domains is triggered when needed from the scheduler tick.
49891 * Also triggered for nohz idle balancing (with nohz_balancing_kick set).
49892 */
49893 -static void run_rebalance_domains(struct softirq_action *h)
49894 +static void run_rebalance_domains(void)
49895 {
49896 int this_cpu = smp_processor_id();
49897 struct rq *this_rq = cpu_rq(this_cpu);
49898 diff -urNp linux-2.6.36/kernel/signal.c linux-2.6.36/kernel/signal.c
49899 --- linux-2.6.36/kernel/signal.c 2010-10-20 16:30:22.000000000 -0400
49900 +++ linux-2.6.36/kernel/signal.c 2010-11-06 18:58:50.000000000 -0400
49901 @@ -45,12 +45,12 @@ static struct kmem_cache *sigqueue_cache
49902
49903 int print_fatal_signals __read_mostly;
49904
49905 -static void __user *sig_handler(struct task_struct *t, int sig)
49906 +static __sighandler_t sig_handler(struct task_struct *t, int sig)
49907 {
49908 return t->sighand->action[sig - 1].sa.sa_handler;
49909 }
49910
49911 -static int sig_handler_ignored(void __user *handler, int sig)
49912 +static int sig_handler_ignored(__sighandler_t handler, int sig)
49913 {
49914 /* Is it explicitly or implicitly ignored? */
49915 return handler == SIG_IGN ||
49916 @@ -60,7 +60,7 @@ static int sig_handler_ignored(void __us
49917 static int sig_task_ignored(struct task_struct *t, int sig,
49918 int from_ancestor_ns)
49919 {
49920 - void __user *handler;
49921 + __sighandler_t handler;
49922
49923 handler = sig_handler(t, sig);
49924
49925 @@ -243,6 +243,9 @@ __sigqueue_alloc(int sig, struct task_st
49926 atomic_inc(&user->sigpending);
49927 rcu_read_unlock();
49928
49929 + if (!override_rlimit)
49930 + gr_learn_resource(t, RLIMIT_SIGPENDING, atomic_read(&user->sigpending), 1);
49931 +
49932 if (override_rlimit ||
49933 atomic_read(&user->sigpending) <=
49934 task_rlimit(t, RLIMIT_SIGPENDING)) {
49935 @@ -367,7 +370,7 @@ flush_signal_handlers(struct task_struct
49936
49937 int unhandled_signal(struct task_struct *tsk, int sig)
49938 {
49939 - void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler;
49940 + __sighandler_t handler = tsk->sighand->action[sig-1].sa.sa_handler;
49941 if (is_global_init(tsk))
49942 return 1;
49943 if (handler != SIG_IGN && handler != SIG_DFL)
49944 @@ -678,6 +681,9 @@ static int check_kill_permission(int sig
49945 }
49946 }
49947
49948 + if (gr_handle_signal(t, sig))
49949 + return -EPERM;
49950 +
49951 return security_task_kill(t, info, sig, 0);
49952 }
49953
49954 @@ -1025,7 +1031,7 @@ __group_send_sig_info(int sig, struct si
49955 return send_signal(sig, info, p, 1);
49956 }
49957
49958 -static int
49959 +int
49960 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
49961 {
49962 return send_signal(sig, info, t, 0);
49963 @@ -1079,6 +1085,9 @@ force_sig_info(int sig, struct siginfo *
49964 ret = specific_send_sig_info(sig, info, t);
49965 spin_unlock_irqrestore(&t->sighand->siglock, flags);
49966
49967 + gr_log_signal(sig, !is_si_special(info) ? info->si_addr : NULL, t);
49968 + gr_handle_crash(t, sig);
49969 +
49970 return ret;
49971 }
49972
49973 @@ -1136,8 +1145,11 @@ int group_send_sig_info(int sig, struct
49974 ret = check_kill_permission(sig, info, p);
49975 rcu_read_unlock();
49976
49977 - if (!ret && sig)
49978 + if (!ret && sig) {
49979 ret = do_send_sig_info(sig, info, p, true);
49980 + if (!ret)
49981 + gr_log_signal(sig, !is_si_special(info) ? info->si_addr : NULL, p);
49982 + }
49983
49984 return ret;
49985 }
49986 diff -urNp linux-2.6.36/kernel/smp.c linux-2.6.36/kernel/smp.c
49987 --- linux-2.6.36/kernel/smp.c 2010-10-20 16:30:22.000000000 -0400
49988 +++ linux-2.6.36/kernel/smp.c 2010-11-06 18:58:15.000000000 -0400
49989 @@ -510,22 +510,22 @@ int smp_call_function(void (*func)(void
49990 }
49991 EXPORT_SYMBOL(smp_call_function);
49992
49993 -void ipi_call_lock(void)
49994 +void ipi_call_lock(void) __acquires(call_function.lock)
49995 {
49996 raw_spin_lock(&call_function.lock);
49997 }
49998
49999 -void ipi_call_unlock(void)
50000 +void ipi_call_unlock(void) __releases(call_function.lock)
50001 {
50002 raw_spin_unlock(&call_function.lock);
50003 }
50004
50005 -void ipi_call_lock_irq(void)
50006 +void ipi_call_lock_irq(void) __acquires(call_function.lock)
50007 {
50008 raw_spin_lock_irq(&call_function.lock);
50009 }
50010
50011 -void ipi_call_unlock_irq(void)
50012 +void ipi_call_unlock_irq(void) __releases(call_function.lock)
50013 {
50014 raw_spin_unlock_irq(&call_function.lock);
50015 }
50016 diff -urNp linux-2.6.36/kernel/softirq.c linux-2.6.36/kernel/softirq.c
50017 --- linux-2.6.36/kernel/softirq.c 2010-10-20 16:30:22.000000000 -0400
50018 +++ linux-2.6.36/kernel/softirq.c 2010-11-06 18:58:15.000000000 -0400
50019 @@ -56,7 +56,7 @@ static struct softirq_action softirq_vec
50020
50021 static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
50022
50023 -char *softirq_to_name[NR_SOFTIRQS] = {
50024 +const char * const softirq_to_name[NR_SOFTIRQS] = {
50025 "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
50026 "TASKLET", "SCHED", "HRTIMER", "RCU"
50027 };
50028 @@ -190,7 +190,7 @@ EXPORT_SYMBOL(local_bh_enable_ip);
50029
50030 asmlinkage void __do_softirq(void)
50031 {
50032 - struct softirq_action *h;
50033 + const struct softirq_action *h;
50034 __u32 pending;
50035 int max_restart = MAX_SOFTIRQ_RESTART;
50036 int cpu;
50037 @@ -216,7 +216,7 @@ restart:
50038 kstat_incr_softirqs_this_cpu(h - softirq_vec);
50039
50040 trace_softirq_entry(h, softirq_vec);
50041 - h->action(h);
50042 + h->action();
50043 trace_softirq_exit(h, softirq_vec);
50044 if (unlikely(prev_count != preempt_count())) {
50045 printk(KERN_ERR "huh, entered softirq %td %s %p"
50046 @@ -340,7 +340,7 @@ void raise_softirq(unsigned int nr)
50047 local_irq_restore(flags);
50048 }
50049
50050 -void open_softirq(int nr, void (*action)(struct softirq_action *))
50051 +void open_softirq(int nr, void (*action)(void))
50052 {
50053 softirq_vec[nr].action = action;
50054 }
50055 @@ -396,7 +396,7 @@ void __tasklet_hi_schedule_first(struct
50056
50057 EXPORT_SYMBOL(__tasklet_hi_schedule_first);
50058
50059 -static void tasklet_action(struct softirq_action *a)
50060 +static void tasklet_action(void)
50061 {
50062 struct tasklet_struct *list;
50063
50064 @@ -431,7 +431,7 @@ static void tasklet_action(struct softir
50065 }
50066 }
50067
50068 -static void tasklet_hi_action(struct softirq_action *a)
50069 +static void tasklet_hi_action(void)
50070 {
50071 struct tasklet_struct *list;
50072
50073 diff -urNp linux-2.6.36/kernel/sys.c linux-2.6.36/kernel/sys.c
50074 --- linux-2.6.36/kernel/sys.c 2010-10-20 16:30:22.000000000 -0400
50075 +++ linux-2.6.36/kernel/sys.c 2010-11-06 18:58:50.000000000 -0400
50076 @@ -134,6 +134,12 @@ static int set_one_prio(struct task_stru
50077 error = -EACCES;
50078 goto out;
50079 }
50080 +
50081 + if (gr_handle_chroot_setpriority(p, niceval)) {
50082 + error = -EACCES;
50083 + goto out;
50084 + }
50085 +
50086 no_nice = security_task_setnice(p, niceval);
50087 if (no_nice) {
50088 error = no_nice;
50089 @@ -511,6 +517,9 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g
50090 goto error;
50091 }
50092
50093 + if (gr_check_group_change(new->gid, new->egid, -1))
50094 + goto error;
50095 +
50096 if (rgid != (gid_t) -1 ||
50097 (egid != (gid_t) -1 && egid != old->gid))
50098 new->sgid = new->egid;
50099 @@ -540,6 +549,10 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
50100 old = current_cred();
50101
50102 retval = -EPERM;
50103 +
50104 + if (gr_check_group_change(gid, gid, gid))
50105 + goto error;
50106 +
50107 if (capable(CAP_SETGID))
50108 new->gid = new->egid = new->sgid = new->fsgid = gid;
50109 else if (gid == old->gid || gid == old->sgid)
50110 @@ -620,6 +633,9 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, u
50111 goto error;
50112 }
50113
50114 + if (gr_check_user_change(new->uid, new->euid, -1))
50115 + goto error;
50116 +
50117 if (new->uid != old->uid) {
50118 retval = set_user(new);
50119 if (retval < 0)
50120 @@ -664,6 +680,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
50121 old = current_cred();
50122
50123 retval = -EPERM;
50124 +
50125 + if (gr_check_crash_uid(uid))
50126 + goto error;
50127 + if (gr_check_user_change(uid, uid, uid))
50128 + goto error;
50129 +
50130 if (capable(CAP_SETUID)) {
50131 new->suid = new->uid = uid;
50132 if (uid != old->uid) {
50133 @@ -718,6 +740,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid,
50134 goto error;
50135 }
50136
50137 + if (gr_check_user_change(ruid, euid, -1))
50138 + goto error;
50139 +
50140 if (ruid != (uid_t) -1) {
50141 new->uid = ruid;
50142 if (ruid != old->uid) {
50143 @@ -782,6 +807,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid,
50144 goto error;
50145 }
50146
50147 + if (gr_check_group_change(rgid, egid, -1))
50148 + goto error;
50149 +
50150 if (rgid != (gid_t) -1)
50151 new->gid = rgid;
50152 if (egid != (gid_t) -1)
50153 @@ -828,6 +856,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
50154 old = current_cred();
50155 old_fsuid = old->fsuid;
50156
50157 + if (gr_check_user_change(-1, -1, uid))
50158 + goto error;
50159 +
50160 if (uid == old->uid || uid == old->euid ||
50161 uid == old->suid || uid == old->fsuid ||
50162 capable(CAP_SETUID)) {
50163 @@ -838,6 +869,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
50164 }
50165 }
50166
50167 +error:
50168 abort_creds(new);
50169 return old_fsuid;
50170
50171 @@ -864,12 +896,16 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
50172 if (gid == old->gid || gid == old->egid ||
50173 gid == old->sgid || gid == old->fsgid ||
50174 capable(CAP_SETGID)) {
50175 + if (gr_check_group_change(-1, -1, gid))
50176 + goto error;
50177 +
50178 if (gid != old_fsgid) {
50179 new->fsgid = gid;
50180 goto change_okay;
50181 }
50182 }
50183
50184 +error:
50185 abort_creds(new);
50186 return old_fsgid;
50187
50188 @@ -1607,7 +1643,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
50189 error = get_dumpable(me->mm);
50190 break;
50191 case PR_SET_DUMPABLE:
50192 - if (arg2 < 0 || arg2 > 1) {
50193 + if (arg2 > 1) {
50194 error = -EINVAL;
50195 break;
50196 }
50197 diff -urNp linux-2.6.36/kernel/sysctl.c linux-2.6.36/kernel/sysctl.c
50198 --- linux-2.6.36/kernel/sysctl.c 2010-10-20 16:30:22.000000000 -0400
50199 +++ linux-2.6.36/kernel/sysctl.c 2010-11-06 18:58:50.000000000 -0400
50200 @@ -83,6 +83,13 @@
50201
50202
50203 #if defined(CONFIG_SYSCTL)
50204 +#include <linux/grsecurity.h>
50205 +#include <linux/grinternal.h>
50206 +
50207 +extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
50208 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
50209 + const int op);
50210 +extern int gr_handle_chroot_sysctl(const int op);
50211
50212 /* External variables not in a header file. */
50213 extern int sysctl_overcommit_memory;
50214 @@ -190,6 +197,7 @@ static int sysrq_sysctl_handler(ctl_tabl
50215 }
50216
50217 #endif
50218 +extern struct ctl_table grsecurity_table[];
50219
50220 static struct ctl_table root_table[];
50221 static struct ctl_table_root sysctl_table_root;
50222 @@ -219,6 +227,20 @@ extern struct ctl_table epoll_table[];
50223 int sysctl_legacy_va_layout;
50224 #endif
50225
50226 +#ifdef CONFIG_PAX_SOFTMODE
50227 +static ctl_table pax_table[] = {
50228 + {
50229 + .procname = "softmode",
50230 + .data = &pax_softmode,
50231 + .maxlen = sizeof(unsigned int),
50232 + .mode = 0600,
50233 + .proc_handler = &proc_dointvec,
50234 + },
50235 +
50236 + { }
50237 +};
50238 +#endif
50239 +
50240 /* The default sysctl tables: */
50241
50242 static struct ctl_table root_table[] = {
50243 @@ -271,6 +293,22 @@ static int max_extfrag_threshold = 1000;
50244 #endif
50245
50246 static struct ctl_table kern_table[] = {
50247 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_ROFS)
50248 + {
50249 + .procname = "grsecurity",
50250 + .mode = 0500,
50251 + .child = grsecurity_table,
50252 + },
50253 +#endif
50254 +
50255 +#ifdef CONFIG_PAX_SOFTMODE
50256 + {
50257 + .procname = "pax",
50258 + .mode = 0500,
50259 + .child = pax_table,
50260 + },
50261 +#endif
50262 +
50263 {
50264 .procname = "sched_child_runs_first",
50265 .data = &sysctl_sched_child_runs_first,
50266 @@ -1173,6 +1211,13 @@ static struct ctl_table vm_table[] = {
50267 .proc_handler = proc_dointvec_minmax,
50268 .extra1 = &zero,
50269 },
50270 + {
50271 + .procname = "heap_stack_gap",
50272 + .data = &sysctl_heap_stack_gap,
50273 + .maxlen = sizeof(sysctl_heap_stack_gap),
50274 + .mode = 0644,
50275 + .proc_handler = proc_doulongvec_minmax,
50276 + },
50277 #else
50278 {
50279 .procname = "nr_trim_pages",
50280 @@ -1688,6 +1733,16 @@ int sysctl_perm(struct ctl_table_root *r
50281 int error;
50282 int mode;
50283
50284 + if (table->parent != NULL && table->parent->procname != NULL &&
50285 + table->procname != NULL &&
50286 + gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
50287 + return -EACCES;
50288 + if (gr_handle_chroot_sysctl(op))
50289 + return -EACCES;
50290 + error = gr_handle_sysctl(table, op);
50291 + if (error)
50292 + return error;
50293 +
50294 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
50295 if (error)
50296 return error;
50297 @@ -2200,6 +2255,8 @@ static int proc_put_long(void __user **b
50298 len = strlen(tmp);
50299 if (len > *size)
50300 len = *size;
50301 + if (len > sizeof(tmp))
50302 + len = sizeof(tmp);
50303 if (copy_to_user(*buf, tmp, len))
50304 return -EFAULT;
50305 *size -= len;
50306 @@ -2505,8 +2562,11 @@ static int __do_proc_doulongvec_minmax(v
50307 *i = val;
50308 } else {
50309 val = convdiv * (*i) / convmul;
50310 - if (!first)
50311 + if (!first) {
50312 err = proc_put_char(&buffer, &left, '\t');
50313 + if (err)
50314 + break;
50315 + }
50316 err = proc_put_long(&buffer, &left, val, false);
50317 if (err)
50318 break;
50319 diff -urNp linux-2.6.36/kernel/taskstats.c linux-2.6.36/kernel/taskstats.c
50320 --- linux-2.6.36/kernel/taskstats.c 2010-10-20 16:30:22.000000000 -0400
50321 +++ linux-2.6.36/kernel/taskstats.c 2010-11-06 18:58:50.000000000 -0400
50322 @@ -27,9 +27,12 @@
50323 #include <linux/cgroup.h>
50324 #include <linux/fs.h>
50325 #include <linux/file.h>
50326 +#include <linux/grsecurity.h>
50327 #include <net/genetlink.h>
50328 #include <asm/atomic.h>
50329
50330 +extern int gr_is_taskstats_denied(int pid);
50331 +
50332 /*
50333 * Maximum length of a cpumask that can be specified in
50334 * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute
50335 @@ -432,6 +435,9 @@ static int taskstats_user_cmd(struct sk_
50336 size_t size;
50337 cpumask_var_t mask;
50338
50339 + if (gr_is_taskstats_denied(current->pid))
50340 + return -EACCES;
50341 +
50342 if (!alloc_cpumask_var(&mask, GFP_KERNEL))
50343 return -ENOMEM;
50344
50345 diff -urNp linux-2.6.36/kernel/time/tick-broadcast.c linux-2.6.36/kernel/time/tick-broadcast.c
50346 --- linux-2.6.36/kernel/time/tick-broadcast.c 2010-10-20 16:30:22.000000000 -0400
50347 +++ linux-2.6.36/kernel/time/tick-broadcast.c 2010-11-06 18:58:15.000000000 -0400
50348 @@ -116,7 +116,7 @@ int tick_device_uses_broadcast(struct cl
50349 * then clear the broadcast bit.
50350 */
50351 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
50352 - int cpu = smp_processor_id();
50353 + cpu = smp_processor_id();
50354
50355 cpumask_clear_cpu(cpu, tick_get_broadcast_mask());
50356 tick_broadcast_clear_oneshot(cpu);
50357 diff -urNp linux-2.6.36/kernel/time/timer_list.c linux-2.6.36/kernel/time/timer_list.c
50358 --- linux-2.6.36/kernel/time/timer_list.c 2010-10-20 16:30:22.000000000 -0400
50359 +++ linux-2.6.36/kernel/time/timer_list.c 2010-11-06 18:58:50.000000000 -0400
50360 @@ -38,12 +38,16 @@ DECLARE_PER_CPU(struct hrtimer_cpu_base,
50361
50362 static void print_name_offset(struct seq_file *m, void *sym)
50363 {
50364 +#ifdef CONFIG_GRKERNSEC_HIDESYM
50365 + SEQ_printf(m, "<%p>", NULL);
50366 +#else
50367 char symname[KSYM_NAME_LEN];
50368
50369 if (lookup_symbol_name((unsigned long)sym, symname) < 0)
50370 SEQ_printf(m, "<%p>", sym);
50371 else
50372 SEQ_printf(m, "%s", symname);
50373 +#endif
50374 }
50375
50376 static void
50377 @@ -112,7 +116,11 @@ next_one:
50378 static void
50379 print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
50380 {
50381 +#ifdef CONFIG_GRKERNSEC_HIDESYM
50382 + SEQ_printf(m, " .base: %p\n", NULL);
50383 +#else
50384 SEQ_printf(m, " .base: %p\n", base);
50385 +#endif
50386 SEQ_printf(m, " .index: %d\n",
50387 base->index);
50388 SEQ_printf(m, " .resolution: %Lu nsecs\n",
50389 @@ -293,7 +301,11 @@ static int __init init_timer_list_procfs
50390 {
50391 struct proc_dir_entry *pe;
50392
50393 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
50394 + pe = proc_create("timer_list", 0400, NULL, &timer_list_fops);
50395 +#else
50396 pe = proc_create("timer_list", 0444, NULL, &timer_list_fops);
50397 +#endif
50398 if (!pe)
50399 return -ENOMEM;
50400 return 0;
50401 diff -urNp linux-2.6.36/kernel/time/timer_stats.c linux-2.6.36/kernel/time/timer_stats.c
50402 --- linux-2.6.36/kernel/time/timer_stats.c 2010-10-20 16:30:22.000000000 -0400
50403 +++ linux-2.6.36/kernel/time/timer_stats.c 2010-11-06 18:58:50.000000000 -0400
50404 @@ -269,12 +269,16 @@ void timer_stats_update_stats(void *time
50405
50406 static void print_name_offset(struct seq_file *m, unsigned long addr)
50407 {
50408 +#ifdef CONFIG_GRKERNSEC_HIDESYM
50409 + seq_printf(m, "<%p>", NULL);
50410 +#else
50411 char symname[KSYM_NAME_LEN];
50412
50413 if (lookup_symbol_name(addr, symname) < 0)
50414 seq_printf(m, "<%p>", (void *)addr);
50415 else
50416 seq_printf(m, "%s", symname);
50417 +#endif
50418 }
50419
50420 static int tstats_show(struct seq_file *m, void *v)
50421 @@ -417,7 +421,11 @@ static int __init init_tstats_procfs(voi
50422 {
50423 struct proc_dir_entry *pe;
50424
50425 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
50426 + pe = proc_create("timer_stats", 0600, NULL, &tstats_fops);
50427 +#else
50428 pe = proc_create("timer_stats", 0644, NULL, &tstats_fops);
50429 +#endif
50430 if (!pe)
50431 return -ENOMEM;
50432 return 0;
50433 diff -urNp linux-2.6.36/kernel/time.c linux-2.6.36/kernel/time.c
50434 --- linux-2.6.36/kernel/time.c 2010-10-20 16:30:22.000000000 -0400
50435 +++ linux-2.6.36/kernel/time.c 2010-11-06 18:58:50.000000000 -0400
50436 @@ -93,6 +93,9 @@ SYSCALL_DEFINE1(stime, time_t __user *,
50437 return err;
50438
50439 do_settimeofday(&tv);
50440 +
50441 + gr_log_timechange();
50442 +
50443 return 0;
50444 }
50445
50446 @@ -200,6 +203,8 @@ SYSCALL_DEFINE2(settimeofday, struct tim
50447 return -EFAULT;
50448 }
50449
50450 + gr_log_timechange();
50451 +
50452 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
50453 }
50454
50455 @@ -238,7 +243,7 @@ EXPORT_SYMBOL(current_fs_time);
50456 * Avoid unnecessary multiplications/divisions in the
50457 * two most common HZ cases:
50458 */
50459 -unsigned int inline jiffies_to_msecs(const unsigned long j)
50460 +inline unsigned int jiffies_to_msecs(const unsigned long j)
50461 {
50462 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
50463 return (MSEC_PER_SEC / HZ) * j;
50464 @@ -254,7 +259,7 @@ unsigned int inline jiffies_to_msecs(con
50465 }
50466 EXPORT_SYMBOL(jiffies_to_msecs);
50467
50468 -unsigned int inline jiffies_to_usecs(const unsigned long j)
50469 +inline unsigned int jiffies_to_usecs(const unsigned long j)
50470 {
50471 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
50472 return (USEC_PER_SEC / HZ) * j;
50473 diff -urNp linux-2.6.36/kernel/timer.c linux-2.6.36/kernel/timer.c
50474 --- linux-2.6.36/kernel/timer.c 2010-10-20 16:30:22.000000000 -0400
50475 +++ linux-2.6.36/kernel/timer.c 2010-11-06 18:58:15.000000000 -0400
50476 @@ -1287,7 +1287,7 @@ void update_process_times(int user_tick)
50477 /*
50478 * This function runs timers and the timer-tq in bottom half context.
50479 */
50480 -static void run_timer_softirq(struct softirq_action *h)
50481 +static void run_timer_softirq(void)
50482 {
50483 struct tvec_base *base = __get_cpu_var(tvec_bases);
50484
50485 diff -urNp linux-2.6.36/kernel/trace/ftrace.c linux-2.6.36/kernel/trace/ftrace.c
50486 --- linux-2.6.36/kernel/trace/ftrace.c 2010-10-20 16:30:22.000000000 -0400
50487 +++ linux-2.6.36/kernel/trace/ftrace.c 2010-11-06 18:58:15.000000000 -0400
50488 @@ -1108,13 +1108,18 @@ ftrace_code_disable(struct module *mod,
50489
50490 ip = rec->ip;
50491
50492 + ret = ftrace_arch_code_modify_prepare();
50493 + FTRACE_WARN_ON(ret);
50494 + if (ret)
50495 + return 0;
50496 +
50497 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
50498 + FTRACE_WARN_ON(ftrace_arch_code_modify_post_process());
50499 if (ret) {
50500 ftrace_bug(ret, ip);
50501 rec->flags |= FTRACE_FL_FAILED;
50502 - return 0;
50503 }
50504 - return 1;
50505 + return ret ? 0 : 1;
50506 }
50507
50508 /*
50509 diff -urNp linux-2.6.36/kernel/trace/ring_buffer.c linux-2.6.36/kernel/trace/ring_buffer.c
50510 --- linux-2.6.36/kernel/trace/ring_buffer.c 2010-10-20 16:30:22.000000000 -0400
50511 +++ linux-2.6.36/kernel/trace/ring_buffer.c 2010-11-06 18:58:15.000000000 -0400
50512 @@ -635,7 +635,7 @@ static struct list_head *rb_list_head(st
50513 * the reader page). But if the next page is a header page,
50514 * its flags will be non zero.
50515 */
50516 -static int inline
50517 +static inline int
50518 rb_is_head_page(struct ring_buffer_per_cpu *cpu_buffer,
50519 struct buffer_page *page, struct list_head *list)
50520 {
50521 diff -urNp linux-2.6.36/kernel/trace/trace.c linux-2.6.36/kernel/trace/trace.c
50522 --- linux-2.6.36/kernel/trace/trace.c 2010-10-20 16:30:22.000000000 -0400
50523 +++ linux-2.6.36/kernel/trace/trace.c 2010-11-06 18:58:15.000000000 -0400
50524 @@ -3943,10 +3943,9 @@ static const struct file_operations trac
50525 };
50526 #endif
50527
50528 -static struct dentry *d_tracer;
50529 -
50530 struct dentry *tracing_init_dentry(void)
50531 {
50532 + static struct dentry *d_tracer;
50533 static int once;
50534
50535 if (d_tracer)
50536 @@ -3966,10 +3965,9 @@ struct dentry *tracing_init_dentry(void)
50537 return d_tracer;
50538 }
50539
50540 -static struct dentry *d_percpu;
50541 -
50542 struct dentry *tracing_dentry_percpu(void)
50543 {
50544 + static struct dentry *d_percpu;
50545 static int once;
50546 struct dentry *d_tracer;
50547
50548 diff -urNp linux-2.6.36/kernel/trace/trace_output.c linux-2.6.36/kernel/trace/trace_output.c
50549 --- linux-2.6.36/kernel/trace/trace_output.c 2010-10-20 16:30:22.000000000 -0400
50550 +++ linux-2.6.36/kernel/trace/trace_output.c 2010-11-06 18:58:15.000000000 -0400
50551 @@ -278,7 +278,7 @@ int trace_seq_path(struct trace_seq *s,
50552
50553 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
50554 if (!IS_ERR(p)) {
50555 - p = mangle_path(s->buffer + s->len, p, "\n");
50556 + p = mangle_path(s->buffer + s->len, p, "\n\\");
50557 if (p) {
50558 s->len = p - s->buffer;
50559 return 1;
50560 diff -urNp linux-2.6.36/kernel/trace/trace_stack.c linux-2.6.36/kernel/trace/trace_stack.c
50561 --- linux-2.6.36/kernel/trace/trace_stack.c 2010-10-20 16:30:22.000000000 -0400
50562 +++ linux-2.6.36/kernel/trace/trace_stack.c 2010-11-06 18:58:15.000000000 -0400
50563 @@ -50,7 +50,7 @@ static inline void check_stack(void)
50564 return;
50565
50566 /* we do not handle interrupt stacks yet */
50567 - if (!object_is_on_stack(&this_size))
50568 + if (!object_starts_on_stack(&this_size))
50569 return;
50570
50571 local_irq_save(flags);
50572 diff -urNp linux-2.6.36/lib/bug.c linux-2.6.36/lib/bug.c
50573 --- linux-2.6.36/lib/bug.c 2010-10-20 16:30:22.000000000 -0400
50574 +++ linux-2.6.36/lib/bug.c 2010-11-06 18:58:15.000000000 -0400
50575 @@ -133,6 +133,8 @@ enum bug_trap_type report_bug(unsigned l
50576 return BUG_TRAP_TYPE_NONE;
50577
50578 bug = find_bug(bugaddr);
50579 + if (!bug)
50580 + return BUG_TRAP_TYPE_NONE;
50581
50582 file = NULL;
50583 line = 0;
50584 diff -urNp linux-2.6.36/lib/debugobjects.c linux-2.6.36/lib/debugobjects.c
50585 --- linux-2.6.36/lib/debugobjects.c 2010-10-20 16:30:22.000000000 -0400
50586 +++ linux-2.6.36/lib/debugobjects.c 2010-11-06 18:58:15.000000000 -0400
50587 @@ -281,7 +281,7 @@ static void debug_object_is_on_stack(voi
50588 if (limit > 4)
50589 return;
50590
50591 - is_on_stack = object_is_on_stack(addr);
50592 + is_on_stack = object_starts_on_stack(addr);
50593 if (is_on_stack == onstack)
50594 return;
50595
50596 diff -urNp linux-2.6.36/lib/dma-debug.c linux-2.6.36/lib/dma-debug.c
50597 --- linux-2.6.36/lib/dma-debug.c 2010-10-20 16:30:22.000000000 -0400
50598 +++ linux-2.6.36/lib/dma-debug.c 2010-11-06 18:58:15.000000000 -0400
50599 @@ -861,7 +861,7 @@ out:
50600
50601 static void check_for_stack(struct device *dev, void *addr)
50602 {
50603 - if (object_is_on_stack(addr))
50604 + if (object_starts_on_stack(addr))
50605 err_printk(dev, NULL, "DMA-API: device driver maps memory from"
50606 "stack [addr=%p]\n", addr);
50607 }
50608 diff -urNp linux-2.6.36/lib/inflate.c linux-2.6.36/lib/inflate.c
50609 --- linux-2.6.36/lib/inflate.c 2010-10-20 16:30:22.000000000 -0400
50610 +++ linux-2.6.36/lib/inflate.c 2010-11-06 18:58:15.000000000 -0400
50611 @@ -269,7 +269,7 @@ static void free(void *where)
50612 malloc_ptr = free_mem_ptr;
50613 }
50614 #else
50615 -#define malloc(a) kmalloc(a, GFP_KERNEL)
50616 +#define malloc(a) kmalloc((a), GFP_KERNEL)
50617 #define free(a) kfree(a)
50618 #endif
50619
50620 diff -urNp linux-2.6.36/lib/Kconfig.debug linux-2.6.36/lib/Kconfig.debug
50621 --- linux-2.6.36/lib/Kconfig.debug 2010-10-20 16:30:22.000000000 -0400
50622 +++ linux-2.6.36/lib/Kconfig.debug 2010-11-06 19:03:24.000000000 -0400
50623 @@ -998,6 +998,7 @@ config LATENCYTOP
50624 depends on DEBUG_KERNEL
50625 depends on STACKTRACE_SUPPORT
50626 depends on PROC_FS
50627 + depends on !GRKERNSEC_HIDESYM
50628 select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE
50629 select KALLSYMS
50630 select KALLSYMS_ALL
50631 diff -urNp linux-2.6.36/lib/kref.c linux-2.6.36/lib/kref.c
50632 --- linux-2.6.36/lib/kref.c 2010-10-20 16:30:22.000000000 -0400
50633 +++ linux-2.6.36/lib/kref.c 2010-11-06 18:58:15.000000000 -0400
50634 @@ -52,7 +52,7 @@ void kref_get(struct kref *kref)
50635 */
50636 int kref_put(struct kref *kref, void (*release)(struct kref *kref))
50637 {
50638 - WARN_ON(release == NULL);
50639 + BUG_ON(release == NULL);
50640 WARN_ON(release == (void (*)(struct kref *))kfree);
50641
50642 if (atomic_dec_and_test(&kref->refcount)) {
50643 diff -urNp linux-2.6.36/lib/parser.c linux-2.6.36/lib/parser.c
50644 --- linux-2.6.36/lib/parser.c 2010-10-20 16:30:22.000000000 -0400
50645 +++ linux-2.6.36/lib/parser.c 2010-11-06 18:58:15.000000000 -0400
50646 @@ -129,7 +129,7 @@ static int match_number(substring_t *s,
50647 char *buf;
50648 int ret;
50649
50650 - buf = kmalloc(s->to - s->from + 1, GFP_KERNEL);
50651 + buf = kmalloc((s->to - s->from) + 1, GFP_KERNEL);
50652 if (!buf)
50653 return -ENOMEM;
50654 memcpy(buf, s->from, s->to - s->from);
50655 diff -urNp linux-2.6.36/lib/radix-tree.c linux-2.6.36/lib/radix-tree.c
50656 --- linux-2.6.36/lib/radix-tree.c 2010-10-20 16:30:22.000000000 -0400
50657 +++ linux-2.6.36/lib/radix-tree.c 2010-11-06 18:58:15.000000000 -0400
50658 @@ -80,7 +80,7 @@ struct radix_tree_preload {
50659 int nr;
50660 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
50661 };
50662 -static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
50663 +static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
50664
50665 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
50666 {
50667 diff -urNp linux-2.6.36/lib/vsprintf.c linux-2.6.36/lib/vsprintf.c
50668 --- linux-2.6.36/lib/vsprintf.c 2010-10-20 16:30:22.000000000 -0400
50669 +++ linux-2.6.36/lib/vsprintf.c 2010-11-06 18:58:15.000000000 -0400
50670 @@ -989,7 +989,7 @@ char *pointer(const char *fmt, char *buf
50671 struct printf_spec spec)
50672 {
50673 if (!ptr)
50674 - return string(buf, end, "(null)", spec);
50675 + return string(buf, end, "(nil)", spec);
50676
50677 switch (*fmt) {
50678 case 'F':
50679 diff -urNp linux-2.6.36/localversion-grsec linux-2.6.36/localversion-grsec
50680 --- linux-2.6.36/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
50681 +++ linux-2.6.36/localversion-grsec 2010-11-06 18:58:50.000000000 -0400
50682 @@ -0,0 +1 @@
50683 +-grsec
50684 diff -urNp linux-2.6.36/Makefile linux-2.6.36/Makefile
50685 --- linux-2.6.36/Makefile 2010-10-20 16:30:22.000000000 -0400
50686 +++ linux-2.6.36/Makefile 2010-11-06 18:58:50.000000000 -0400
50687 @@ -229,8 +229,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
50688
50689 HOSTCC = gcc
50690 HOSTCXX = g++
50691 -HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
50692 -HOSTCXXFLAGS = -O2
50693 +HOSTCFLAGS = -Wall -W -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-delete-null-pointer-checks
50694 +HOSTCXXFLAGS = -O2 -fno-delete-null-pointer-checks
50695
50696 # Decide whether to build built-in, modular, or both.
50697 # Normally, just do built-in.
50698 @@ -659,7 +659,7 @@ export mod_strip_cmd
50699
50700
50701 ifeq ($(KBUILD_EXTMOD),)
50702 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
50703 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
50704
50705 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
50706 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
50707 diff -urNp linux-2.6.36/mm/bootmem.c linux-2.6.36/mm/bootmem.c
50708 --- linux-2.6.36/mm/bootmem.c 2010-10-20 16:30:22.000000000 -0400
50709 +++ linux-2.6.36/mm/bootmem.c 2010-11-06 18:58:15.000000000 -0400
50710 @@ -200,19 +200,30 @@ static void __init __free_pages_memory(u
50711 unsigned long __init free_all_memory_core_early(int nodeid)
50712 {
50713 int i;
50714 - u64 start, end;
50715 + u64 start, end, startrange, endrange;
50716 unsigned long count = 0;
50717 - struct range *range = NULL;
50718 + struct range *range = NULL, rangerange = { 0, 0 };
50719 int nr_range;
50720
50721 nr_range = get_free_all_memory_range(&range, nodeid);
50722 + startrange = __pa(range) >> PAGE_SHIFT;
50723 + endrange = (__pa(range + nr_range) - 1) >> PAGE_SHIFT;
50724
50725 for (i = 0; i < nr_range; i++) {
50726 start = range[i].start;
50727 end = range[i].end;
50728 + if (start <= endrange && startrange < end) {
50729 + BUG_ON(rangerange.start | rangerange.end);
50730 + rangerange = range[i];
50731 + continue;
50732 + }
50733 count += end - start;
50734 __free_pages_memory(start, end);
50735 }
50736 + start = rangerange.start;
50737 + end = rangerange.end;
50738 + count += end - start;
50739 + __free_pages_memory(start, end);
50740
50741 return count;
50742 }
50743 diff -urNp linux-2.6.36/mm/filemap.c linux-2.6.36/mm/filemap.c
50744 --- linux-2.6.36/mm/filemap.c 2010-10-20 16:30:22.000000000 -0400
50745 +++ linux-2.6.36/mm/filemap.c 2010-11-06 18:58:50.000000000 -0400
50746 @@ -1640,7 +1640,7 @@ int generic_file_mmap(struct file * file
50747 struct address_space *mapping = file->f_mapping;
50748
50749 if (!mapping->a_ops->readpage)
50750 - return -ENOEXEC;
50751 + return -ENODEV;
50752 file_accessed(file);
50753 vma->vm_ops = &generic_file_vm_ops;
50754 vma->vm_flags |= VM_CAN_NONLINEAR;
50755 @@ -2036,6 +2036,7 @@ inline int generic_write_checks(struct f
50756 *pos = i_size_read(inode);
50757
50758 if (limit != RLIM_INFINITY) {
50759 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
50760 if (*pos >= limit) {
50761 send_sig(SIGXFSZ, current, 0);
50762 return -EFBIG;
50763 diff -urNp linux-2.6.36/mm/fremap.c linux-2.6.36/mm/fremap.c
50764 --- linux-2.6.36/mm/fremap.c 2010-10-20 16:30:22.000000000 -0400
50765 +++ linux-2.6.36/mm/fremap.c 2010-11-06 18:58:15.000000000 -0400
50766 @@ -156,6 +156,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
50767 retry:
50768 vma = find_vma(mm, start);
50769
50770 +#ifdef CONFIG_PAX_SEGMEXEC
50771 + if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC))
50772 + goto out;
50773 +#endif
50774 +
50775 /*
50776 * Make sure the vma is shared, that it supports prefaulting,
50777 * and that the remapped range is valid and fully within
50778 @@ -224,7 +229,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
50779 /*
50780 * drop PG_Mlocked flag for over-mapped range
50781 */
50782 - unsigned int saved_flags = vma->vm_flags;
50783 + unsigned long saved_flags = vma->vm_flags;
50784 munlock_vma_pages_range(vma, start, start + size);
50785 vma->vm_flags = saved_flags;
50786 }
50787 diff -urNp linux-2.6.36/mm/highmem.c linux-2.6.36/mm/highmem.c
50788 --- linux-2.6.36/mm/highmem.c 2010-10-20 16:30:22.000000000 -0400
50789 +++ linux-2.6.36/mm/highmem.c 2010-11-06 18:58:15.000000000 -0400
50790 @@ -117,9 +117,10 @@ static void flush_all_zero_pkmaps(void)
50791 * So no dangers, even with speculative execution.
50792 */
50793 page = pte_page(pkmap_page_table[i]);
50794 + pax_open_kernel();
50795 pte_clear(&init_mm, (unsigned long)page_address(page),
50796 &pkmap_page_table[i]);
50797 -
50798 + pax_close_kernel();
50799 set_page_address(page, NULL);
50800 need_flush = 1;
50801 }
50802 @@ -178,9 +179,11 @@ start:
50803 }
50804 }
50805 vaddr = PKMAP_ADDR(last_pkmap_nr);
50806 +
50807 + pax_open_kernel();
50808 set_pte_at(&init_mm, vaddr,
50809 &(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot));
50810 -
50811 + pax_close_kernel();
50812 pkmap_count[last_pkmap_nr] = 1;
50813 set_page_address(page, (void *)vaddr);
50814
50815 diff -urNp linux-2.6.36/mm/hugetlb.c linux-2.6.36/mm/hugetlb.c
50816 --- linux-2.6.36/mm/hugetlb.c 2010-10-20 16:30:22.000000000 -0400
50817 +++ linux-2.6.36/mm/hugetlb.c 2010-11-06 18:58:15.000000000 -0400
50818 @@ -2305,6 +2305,27 @@ static int unmap_ref_private(struct mm_s
50819 return 1;
50820 }
50821
50822 +#ifdef CONFIG_PAX_SEGMEXEC
50823 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
50824 +{
50825 + struct mm_struct *mm = vma->vm_mm;
50826 + struct vm_area_struct *vma_m;
50827 + unsigned long address_m;
50828 + pte_t *ptep_m;
50829 +
50830 + vma_m = pax_find_mirror_vma(vma);
50831 + if (!vma_m)
50832 + return;
50833 +
50834 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
50835 + address_m = address + SEGMEXEC_TASK_SIZE;
50836 + ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
50837 + get_page(page_m);
50838 + hugepage_add_anon_rmap(page_m, vma_m, address_m);
50839 + set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
50840 +}
50841 +#endif
50842 +
50843 /*
50844 * Hugetlb_cow() should be called with page lock of the original hugepage held.
50845 */
50846 @@ -2402,6 +2423,11 @@ retry_avoidcopy:
50847 make_huge_pte(vma, new_page, 1));
50848 page_remove_rmap(old_page);
50849 hugepage_add_new_anon_rmap(new_page, vma, address);
50850 +
50851 +#ifdef CONFIG_PAX_SEGMEXEC
50852 + pax_mirror_huge_pte(vma, address, new_page);
50853 +#endif
50854 +
50855 /* Make the old page be freed below */
50856 new_page = old_page;
50857 mmu_notifier_invalidate_range_end(mm,
50858 @@ -2555,6 +2581,10 @@ retry:
50859 && (vma->vm_flags & VM_SHARED)));
50860 set_huge_pte_at(mm, address, ptep, new_pte);
50861
50862 +#ifdef CONFIG_PAX_SEGMEXEC
50863 + pax_mirror_huge_pte(vma, address, page);
50864 +#endif
50865 +
50866 if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
50867 /* Optimization, do the COW without a second fault */
50868 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
50869 @@ -2584,6 +2614,10 @@ int hugetlb_fault(struct mm_struct *mm,
50870 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
50871 struct hstate *h = hstate_vma(vma);
50872
50873 +#ifdef CONFIG_PAX_SEGMEXEC
50874 + struct vm_area_struct *vma_m;
50875 +#endif
50876 +
50877 ptep = huge_pte_offset(mm, address);
50878 if (ptep) {
50879 entry = huge_ptep_get(ptep);
50880 @@ -2591,6 +2625,26 @@ int hugetlb_fault(struct mm_struct *mm,
50881 return VM_FAULT_HWPOISON;
50882 }
50883
50884 +#ifdef CONFIG_PAX_SEGMEXEC
50885 + vma_m = pax_find_mirror_vma(vma);
50886 + if (vma_m) {
50887 + unsigned long address_m;
50888 +
50889 + if (vma->vm_start > vma_m->vm_start) {
50890 + address_m = address;
50891 + address -= SEGMEXEC_TASK_SIZE;
50892 + vma = vma_m;
50893 + h = hstate_vma(vma);
50894 + } else
50895 + address_m = address + SEGMEXEC_TASK_SIZE;
50896 +
50897 + if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
50898 + return VM_FAULT_OOM;
50899 + address_m &= HPAGE_MASK;
50900 + unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
50901 + }
50902 +#endif
50903 +
50904 ptep = huge_pte_alloc(mm, address, huge_page_size(h));
50905 if (!ptep)
50906 return VM_FAULT_OOM;
50907 diff -urNp linux-2.6.36/mm/Kconfig linux-2.6.36/mm/Kconfig
50908 --- linux-2.6.36/mm/Kconfig 2010-10-20 16:30:22.000000000 -0400
50909 +++ linux-2.6.36/mm/Kconfig 2010-11-06 18:58:50.000000000 -0400
50910 @@ -240,7 +240,7 @@ config KSM
50911 config DEFAULT_MMAP_MIN_ADDR
50912 int "Low address space to protect from user allocation"
50913 depends on MMU
50914 - default 4096
50915 + default 65536
50916 help
50917 This is the portion of low virtual memory which should be protected
50918 from userspace allocation. Keeping a user from writing to low pages
50919 diff -urNp linux-2.6.36/mm/maccess.c linux-2.6.36/mm/maccess.c
50920 --- linux-2.6.36/mm/maccess.c 2010-10-20 16:30:22.000000000 -0400
50921 +++ linux-2.6.36/mm/maccess.c 2010-11-06 18:58:15.000000000 -0400
50922 @@ -15,10 +15,10 @@
50923 * happens, handle that and return -EFAULT.
50924 */
50925
50926 -long __weak probe_kernel_read(void *dst, void *src, size_t size)
50927 +long __weak probe_kernel_read(void *dst, const void *src, size_t size)
50928 __attribute__((alias("__probe_kernel_read")));
50929
50930 -long __probe_kernel_read(void *dst, void *src, size_t size)
50931 +long __probe_kernel_read(void *dst, const void *src, size_t size)
50932 {
50933 long ret;
50934 mm_segment_t old_fs = get_fs();
50935 @@ -43,10 +43,10 @@ EXPORT_SYMBOL_GPL(probe_kernel_read);
50936 * Safely write to address @dst from the buffer at @src. If a kernel fault
50937 * happens, handle that and return -EFAULT.
50938 */
50939 -long __weak probe_kernel_write(void *dst, void *src, size_t size)
50940 +long __weak probe_kernel_write(void *dst, const void *src, size_t size)
50941 __attribute__((alias("__probe_kernel_write")));
50942
50943 -long __probe_kernel_write(void *dst, void *src, size_t size)
50944 +long __probe_kernel_write(void *dst, const void *src, size_t size)
50945 {
50946 long ret;
50947 mm_segment_t old_fs = get_fs();
50948 diff -urNp linux-2.6.36/mm/madvise.c linux-2.6.36/mm/madvise.c
50949 --- linux-2.6.36/mm/madvise.c 2010-10-20 16:30:22.000000000 -0400
50950 +++ linux-2.6.36/mm/madvise.c 2010-11-06 18:58:15.000000000 -0400
50951 @@ -45,6 +45,10 @@ static long madvise_behavior(struct vm_a
50952 pgoff_t pgoff;
50953 unsigned long new_flags = vma->vm_flags;
50954
50955 +#ifdef CONFIG_PAX_SEGMEXEC
50956 + struct vm_area_struct *vma_m;
50957 +#endif
50958 +
50959 switch (behavior) {
50960 case MADV_NORMAL:
50961 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
50962 @@ -104,6 +108,13 @@ success:
50963 /*
50964 * vm_flags is protected by the mmap_sem held in write mode.
50965 */
50966 +
50967 +#ifdef CONFIG_PAX_SEGMEXEC
50968 + vma_m = pax_find_mirror_vma(vma);
50969 + if (vma_m)
50970 + vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
50971 +#endif
50972 +
50973 vma->vm_flags = new_flags;
50974
50975 out:
50976 @@ -162,6 +173,11 @@ static long madvise_dontneed(struct vm_a
50977 struct vm_area_struct ** prev,
50978 unsigned long start, unsigned long end)
50979 {
50980 +
50981 +#ifdef CONFIG_PAX_SEGMEXEC
50982 + struct vm_area_struct *vma_m;
50983 +#endif
50984 +
50985 *prev = vma;
50986 if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
50987 return -EINVAL;
50988 @@ -174,6 +190,21 @@ static long madvise_dontneed(struct vm_a
50989 zap_page_range(vma, start, end - start, &details);
50990 } else
50991 zap_page_range(vma, start, end - start, NULL);
50992 +
50993 +#ifdef CONFIG_PAX_SEGMEXEC
50994 + vma_m = pax_find_mirror_vma(vma);
50995 + if (vma_m) {
50996 + if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
50997 + struct zap_details details = {
50998 + .nonlinear_vma = vma_m,
50999 + .last_index = ULONG_MAX,
51000 + };
51001 + zap_page_range(vma, start + SEGMEXEC_TASK_SIZE, end - start, &details);
51002 + } else
51003 + zap_page_range(vma, start + SEGMEXEC_TASK_SIZE, end - start, NULL);
51004 + }
51005 +#endif
51006 +
51007 return 0;
51008 }
51009
51010 @@ -366,6 +397,16 @@ SYSCALL_DEFINE3(madvise, unsigned long,
51011 if (end < start)
51012 goto out;
51013
51014 +#ifdef CONFIG_PAX_SEGMEXEC
51015 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
51016 + if (end > SEGMEXEC_TASK_SIZE)
51017 + goto out;
51018 + } else
51019 +#endif
51020 +
51021 + if (end > TASK_SIZE)
51022 + goto out;
51023 +
51024 error = 0;
51025 if (end == start)
51026 goto out;
51027 diff -urNp linux-2.6.36/mm/memory.c linux-2.6.36/mm/memory.c
51028 --- linux-2.6.36/mm/memory.c 2010-10-20 16:30:22.000000000 -0400
51029 +++ linux-2.6.36/mm/memory.c 2010-11-06 18:58:50.000000000 -0400
51030 @@ -259,8 +259,12 @@ static inline void free_pmd_range(struct
51031 return;
51032
51033 pmd = pmd_offset(pud, start);
51034 +
51035 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_PER_CPU_PGD)
51036 pud_clear(pud);
51037 pmd_free_tlb(tlb, pmd, start);
51038 +#endif
51039 +
51040 }
51041
51042 static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
51043 @@ -291,9 +295,12 @@ static inline void free_pud_range(struct
51044 if (end - 1 > ceiling - 1)
51045 return;
51046
51047 +#if !defined(CONFIG_X86_64) || !defined(CONFIG_PAX_PER_CPU_PGD)
51048 pud = pud_offset(pgd, start);
51049 pgd_clear(pgd);
51050 pud_free_tlb(tlb, pud, start);
51051 +#endif
51052 +
51053 }
51054
51055 /*
51056 @@ -1361,10 +1368,10 @@ int __get_user_pages(struct task_struct
51057 (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
51058 i = 0;
51059
51060 - do {
51061 + while (nr_pages) {
51062 struct vm_area_struct *vma;
51063
51064 - vma = find_extend_vma(mm, start);
51065 + vma = find_vma(mm, start);
51066 if (!vma && in_gate_area(tsk, start)) {
51067 unsigned long pg = start & PAGE_MASK;
51068 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
51069 @@ -1416,7 +1423,7 @@ int __get_user_pages(struct task_struct
51070 continue;
51071 }
51072
51073 - if (!vma ||
51074 + if (!vma || start < vma->vm_start ||
51075 (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
51076 !(vm_flags & vma->vm_flags))
51077 return i ? : -EFAULT;
51078 @@ -1491,7 +1498,7 @@ int __get_user_pages(struct task_struct
51079 start += PAGE_SIZE;
51080 nr_pages--;
51081 } while (nr_pages && start < vma->vm_end);
51082 - } while (nr_pages);
51083 + }
51084 return i;
51085 }
51086
51087 @@ -1636,6 +1643,10 @@ static int insert_page(struct vm_area_st
51088 page_add_file_rmap(page);
51089 set_pte_at(mm, addr, pte, mk_pte(page, prot));
51090
51091 +#ifdef CONFIG_PAX_SEGMEXEC
51092 + pax_mirror_file_pte(vma, addr, page, ptl);
51093 +#endif
51094 +
51095 retval = 0;
51096 pte_unmap_unlock(pte, ptl);
51097 return retval;
51098 @@ -1670,10 +1681,22 @@ out:
51099 int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
51100 struct page *page)
51101 {
51102 +
51103 +#ifdef CONFIG_PAX_SEGMEXEC
51104 + struct vm_area_struct *vma_m;
51105 +#endif
51106 +
51107 if (addr < vma->vm_start || addr >= vma->vm_end)
51108 return -EFAULT;
51109 if (!page_count(page))
51110 return -EINVAL;
51111 +
51112 +#ifdef CONFIG_PAX_SEGMEXEC
51113 + vma_m = pax_find_mirror_vma(vma);
51114 + if (vma_m)
51115 + vma_m->vm_flags |= VM_INSERTPAGE;
51116 +#endif
51117 +
51118 vma->vm_flags |= VM_INSERTPAGE;
51119 return insert_page(vma, addr, page, vma->vm_page_prot);
51120 }
51121 @@ -1759,6 +1782,7 @@ int vm_insert_mixed(struct vm_area_struc
51122 unsigned long pfn)
51123 {
51124 BUG_ON(!(vma->vm_flags & VM_MIXEDMAP));
51125 + BUG_ON(vma->vm_mirror);
51126
51127 if (addr < vma->vm_start || addr >= vma->vm_end)
51128 return -EFAULT;
51129 @@ -2086,6 +2110,186 @@ static inline void cow_user_page(struct
51130 copy_user_highpage(dst, src, va, vma);
51131 }
51132
51133 +#ifdef CONFIG_PAX_SEGMEXEC
51134 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
51135 +{
51136 + struct mm_struct *mm = vma->vm_mm;
51137 + spinlock_t *ptl;
51138 + pte_t *pte, entry;
51139 +
51140 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
51141 + entry = *pte;
51142 + if (!pte_present(entry)) {
51143 + if (!pte_none(entry)) {
51144 + BUG_ON(pte_file(entry));
51145 + free_swap_and_cache(pte_to_swp_entry(entry));
51146 + pte_clear_not_present_full(mm, address, pte, 0);
51147 + }
51148 + } else {
51149 + struct page *page;
51150 +
51151 + flush_cache_page(vma, address, pte_pfn(entry));
51152 + entry = ptep_clear_flush(vma, address, pte);
51153 + BUG_ON(pte_dirty(entry));
51154 + page = vm_normal_page(vma, address, entry);
51155 + if (page) {
51156 + update_hiwater_rss(mm);
51157 + if (PageAnon(page))
51158 + dec_mm_counter_fast(mm, MM_ANONPAGES);
51159 + else
51160 + dec_mm_counter_fast(mm, MM_FILEPAGES);
51161 + page_remove_rmap(page);
51162 + page_cache_release(page);
51163 + }
51164 + }
51165 + pte_unmap_unlock(pte, ptl);
51166 +}
51167 +
51168 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
51169 + *
51170 + * the ptl of the lower mapped page is held on entry and is not released on exit
51171 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
51172 + */
51173 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
51174 +{
51175 + struct mm_struct *mm = vma->vm_mm;
51176 + unsigned long address_m;
51177 + spinlock_t *ptl_m;
51178 + struct vm_area_struct *vma_m;
51179 + pmd_t *pmd_m;
51180 + pte_t *pte_m, entry_m;
51181 +
51182 + BUG_ON(!page_m || !PageAnon(page_m));
51183 +
51184 + vma_m = pax_find_mirror_vma(vma);
51185 + if (!vma_m)
51186 + return;
51187 +
51188 + BUG_ON(!PageLocked(page_m));
51189 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
51190 + address_m = address + SEGMEXEC_TASK_SIZE;
51191 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
51192 + pte_m = pte_offset_map_nested(pmd_m, address_m);
51193 + ptl_m = pte_lockptr(mm, pmd_m);
51194 + if (ptl != ptl_m) {
51195 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
51196 + if (!pte_none(*pte_m))
51197 + goto out;
51198 + }
51199 +
51200 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
51201 + page_cache_get(page_m);
51202 + page_add_anon_rmap(page_m, vma_m, address_m);
51203 + inc_mm_counter_fast(mm, MM_ANONPAGES);
51204 + set_pte_at(mm, address_m, pte_m, entry_m);
51205 + update_mmu_cache(vma_m, address_m, entry_m);
51206 +out:
51207 + if (ptl != ptl_m)
51208 + spin_unlock(ptl_m);
51209 + pte_unmap_nested(pte_m);
51210 + unlock_page(page_m);
51211 +}
51212 +
51213 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
51214 +{
51215 + struct mm_struct *mm = vma->vm_mm;
51216 + unsigned long address_m;
51217 + spinlock_t *ptl_m;
51218 + struct vm_area_struct *vma_m;
51219 + pmd_t *pmd_m;
51220 + pte_t *pte_m, entry_m;
51221 +
51222 + BUG_ON(!page_m || PageAnon(page_m));
51223 +
51224 + vma_m = pax_find_mirror_vma(vma);
51225 + if (!vma_m)
51226 + return;
51227 +
51228 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
51229 + address_m = address + SEGMEXEC_TASK_SIZE;
51230 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
51231 + pte_m = pte_offset_map_nested(pmd_m, address_m);
51232 + ptl_m = pte_lockptr(mm, pmd_m);
51233 + if (ptl != ptl_m) {
51234 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
51235 + if (!pte_none(*pte_m))
51236 + goto out;
51237 + }
51238 +
51239 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
51240 + page_cache_get(page_m);
51241 + page_add_file_rmap(page_m);
51242 + inc_mm_counter_fast(mm, MM_FILEPAGES);
51243 + set_pte_at(mm, address_m, pte_m, entry_m);
51244 + update_mmu_cache(vma_m, address_m, entry_m);
51245 +out:
51246 + if (ptl != ptl_m)
51247 + spin_unlock(ptl_m);
51248 + pte_unmap_nested(pte_m);
51249 +}
51250 +
51251 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
51252 +{
51253 + struct mm_struct *mm = vma->vm_mm;
51254 + unsigned long address_m;
51255 + spinlock_t *ptl_m;
51256 + struct vm_area_struct *vma_m;
51257 + pmd_t *pmd_m;
51258 + pte_t *pte_m, entry_m;
51259 +
51260 + vma_m = pax_find_mirror_vma(vma);
51261 + if (!vma_m)
51262 + return;
51263 +
51264 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
51265 + address_m = address + SEGMEXEC_TASK_SIZE;
51266 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
51267 + pte_m = pte_offset_map_nested(pmd_m, address_m);
51268 + ptl_m = pte_lockptr(mm, pmd_m);
51269 + if (ptl != ptl_m) {
51270 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
51271 + if (!pte_none(*pte_m))
51272 + goto out;
51273 + }
51274 +
51275 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
51276 + set_pte_at(mm, address_m, pte_m, entry_m);
51277 +out:
51278 + if (ptl != ptl_m)
51279 + spin_unlock(ptl_m);
51280 + pte_unmap_nested(pte_m);
51281 +}
51282 +
51283 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
51284 +{
51285 + struct page *page_m;
51286 + pte_t entry;
51287 +
51288 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
51289 + goto out;
51290 +
51291 + entry = *pte;
51292 + page_m = vm_normal_page(vma, address, entry);
51293 + if (!page_m)
51294 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
51295 + else if (PageAnon(page_m)) {
51296 + if (pax_find_mirror_vma(vma)) {
51297 + pte_unmap_unlock(pte, ptl);
51298 + lock_page(page_m);
51299 + pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
51300 + if (pte_same(entry, *pte))
51301 + pax_mirror_anon_pte(vma, address, page_m, ptl);
51302 + else
51303 + unlock_page(page_m);
51304 + }
51305 + } else
51306 + pax_mirror_file_pte(vma, address, page_m, ptl);
51307 +
51308 +out:
51309 + pte_unmap_unlock(pte, ptl);
51310 +}
51311 +#endif
51312 +
51313 /*
51314 * This routine handles present pages, when users try to write
51315 * to a shared page. It is done by copying the page to a new address
51316 @@ -2272,6 +2476,12 @@ gotten:
51317 */
51318 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
51319 if (likely(pte_same(*page_table, orig_pte))) {
51320 +
51321 +#ifdef CONFIG_PAX_SEGMEXEC
51322 + if (pax_find_mirror_vma(vma))
51323 + BUG_ON(!trylock_page(new_page));
51324 +#endif
51325 +
51326 if (old_page) {
51327 if (!PageAnon(old_page)) {
51328 dec_mm_counter_fast(mm, MM_FILEPAGES);
51329 @@ -2323,6 +2533,10 @@ gotten:
51330 page_remove_rmap(old_page);
51331 }
51332
51333 +#ifdef CONFIG_PAX_SEGMEXEC
51334 + pax_mirror_anon_pte(vma, address, new_page, ptl);
51335 +#endif
51336 +
51337 /* Free the old page.. */
51338 new_page = old_page;
51339 ret |= VM_FAULT_WRITE;
51340 @@ -2749,19 +2963,12 @@ static int do_swap_page(struct mm_struct
51341 swap_free(entry);
51342 if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
51343 try_to_free_swap(page);
51344 +
51345 +#ifdef CONFIG_PAX_SEGMEXEC
51346 + if ((flags & FAULT_FLAG_WRITE) || !pax_find_mirror_vma(vma))
51347 +#endif
51348 +
51349 unlock_page(page);
51350 - if (swapcache) {
51351 - /*
51352 - * Hold the lock to avoid the swap entry to be reused
51353 - * until we take the PT lock for the pte_same() check
51354 - * (to avoid false positives from pte_same). For
51355 - * further safety release the lock after the swap_free
51356 - * so that the swap count won't change under a
51357 - * parallel locked swapcache.
51358 - */
51359 - unlock_page(swapcache);
51360 - page_cache_release(swapcache);
51361 - }
51362
51363 if (flags & FAULT_FLAG_WRITE) {
51364 ret |= do_wp_page(mm, vma, address, page_table, pmd, ptl, pte);
51365 @@ -2772,6 +2979,11 @@ static int do_swap_page(struct mm_struct
51366
51367 /* No need to invalidate - it was non-present before */
51368 update_mmu_cache(vma, address, page_table);
51369 +
51370 +#ifdef CONFIG_PAX_SEGMEXEC
51371 + pax_mirror_anon_pte(vma, address, page, ptl);
51372 +#endif
51373 +
51374 unlock:
51375 pte_unmap_unlock(page_table, ptl);
51376 out:
51377 @@ -2783,48 +2995,10 @@ out_page:
51378 unlock_page(page);
51379 out_release:
51380 page_cache_release(page);
51381 - if (swapcache) {
51382 - unlock_page(swapcache);
51383 - page_cache_release(swapcache);
51384 - }
51385 return ret;
51386 }
51387
51388 /*
51389 - * This is like a special single-page "expand_{down|up}wards()",
51390 - * except we must first make sure that 'address{-|+}PAGE_SIZE'
51391 - * doesn't hit another vma.
51392 - */
51393 -static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
51394 -{
51395 - address &= PAGE_MASK;
51396 - if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
51397 - struct vm_area_struct *prev = vma->vm_prev;
51398 -
51399 - /*
51400 - * Is there a mapping abutting this one below?
51401 - *
51402 - * That's only ok if it's the same stack mapping
51403 - * that has gotten split..
51404 - */
51405 - if (prev && prev->vm_end == address)
51406 - return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
51407 -
51408 - expand_stack(vma, address - PAGE_SIZE);
51409 - }
51410 - if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) {
51411 - struct vm_area_struct *next = vma->vm_next;
51412 -
51413 - /* As VM_GROWSDOWN but s/below/above/ */
51414 - if (next && next->vm_start == address + PAGE_SIZE)
51415 - return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM;
51416 -
51417 - expand_upwards(vma, address + PAGE_SIZE);
51418 - }
51419 - return 0;
51420 -}
51421 -
51422 -/*
51423 * We enter with non-exclusive mmap_sem (to exclude vma changes,
51424 * but allow concurrent faults), and pte mapped but not yet locked.
51425 * We return with mmap_sem still held, but pte unmapped and unlocked.
51426 @@ -2833,27 +3007,23 @@ static int do_anonymous_page(struct mm_s
51427 unsigned long address, pte_t *page_table, pmd_t *pmd,
51428 unsigned int flags)
51429 {
51430 - struct page *page;
51431 + struct page *page = NULL;
51432 spinlock_t *ptl;
51433 pte_t entry;
51434
51435 - pte_unmap(page_table);
51436 -
51437 - /* Check if we need to add a guard page to the stack */
51438 - if (check_stack_guard_page(vma, address) < 0)
51439 - return VM_FAULT_SIGBUS;
51440 -
51441 - /* Use the zero-page for reads */
51442 if (!(flags & FAULT_FLAG_WRITE)) {
51443 entry = pte_mkspecial(pfn_pte(my_zero_pfn(address),
51444 vma->vm_page_prot));
51445 - page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
51446 + ptl = pte_lockptr(mm, pmd);
51447 + spin_lock(ptl);
51448 if (!pte_none(*page_table))
51449 goto unlock;
51450 goto setpte;
51451 }
51452
51453 /* Allocate our own private page. */
51454 + pte_unmap(page_table);
51455 +
51456 if (unlikely(anon_vma_prepare(vma)))
51457 goto oom;
51458 page = alloc_zeroed_user_highpage_movable(vma, address);
51459 @@ -2872,6 +3042,11 @@ static int do_anonymous_page(struct mm_s
51460 if (!pte_none(*page_table))
51461 goto release;
51462
51463 +#ifdef CONFIG_PAX_SEGMEXEC
51464 + if (pax_find_mirror_vma(vma))
51465 + BUG_ON(!trylock_page(page));
51466 +#endif
51467 +
51468 inc_mm_counter_fast(mm, MM_ANONPAGES);
51469 page_add_new_anon_rmap(page, vma, address);
51470 setpte:
51471 @@ -2879,6 +3054,12 @@ setpte:
51472
51473 /* No need to invalidate - it was non-present before */
51474 update_mmu_cache(vma, address, page_table);
51475 +
51476 +#ifdef CONFIG_PAX_SEGMEXEC
51477 + if (page)
51478 + pax_mirror_anon_pte(vma, address, page, ptl);
51479 +#endif
51480 +
51481 unlock:
51482 pte_unmap_unlock(page_table, ptl);
51483 return 0;
51484 @@ -3021,6 +3202,12 @@ static int __do_fault(struct mm_struct *
51485 */
51486 /* Only go through if we didn't race with anybody else... */
51487 if (likely(pte_same(*page_table, orig_pte))) {
51488 +
51489 +#ifdef CONFIG_PAX_SEGMEXEC
51490 + if (anon && pax_find_mirror_vma(vma))
51491 + BUG_ON(!trylock_page(page));
51492 +#endif
51493 +
51494 flush_icache_page(vma, page);
51495 entry = mk_pte(page, vma->vm_page_prot);
51496 if (flags & FAULT_FLAG_WRITE)
51497 @@ -3040,6 +3227,14 @@ static int __do_fault(struct mm_struct *
51498
51499 /* no need to invalidate: a not-present page won't be cached */
51500 update_mmu_cache(vma, address, page_table);
51501 +
51502 +#ifdef CONFIG_PAX_SEGMEXEC
51503 + if (anon)
51504 + pax_mirror_anon_pte(vma, address, page, ptl);
51505 + else
51506 + pax_mirror_file_pte(vma, address, page, ptl);
51507 +#endif
51508 +
51509 } else {
51510 if (charged)
51511 mem_cgroup_uncharge_page(page);
51512 @@ -3187,6 +3382,12 @@ static inline int handle_pte_fault(struc
51513 if (flags & FAULT_FLAG_WRITE)
51514 flush_tlb_page(vma, address);
51515 }
51516 +
51517 +#ifdef CONFIG_PAX_SEGMEXEC
51518 + pax_mirror_pte(vma, address, pte, pmd, ptl);
51519 + return 0;
51520 +#endif
51521 +
51522 unlock:
51523 pte_unmap_unlock(pte, ptl);
51524 return 0;
51525 @@ -3203,6 +3404,10 @@ int handle_mm_fault(struct mm_struct *mm
51526 pmd_t *pmd;
51527 pte_t *pte;
51528
51529 +#ifdef CONFIG_PAX_SEGMEXEC
51530 + struct vm_area_struct *vma_m;
51531 +#endif
51532 +
51533 __set_current_state(TASK_RUNNING);
51534
51535 count_vm_event(PGFAULT);
51536 @@ -3213,6 +3418,34 @@ int handle_mm_fault(struct mm_struct *mm
51537 if (unlikely(is_vm_hugetlb_page(vma)))
51538 return hugetlb_fault(mm, vma, address, flags);
51539
51540 +#ifdef CONFIG_PAX_SEGMEXEC
51541 + vma_m = pax_find_mirror_vma(vma);
51542 + if (vma_m) {
51543 + unsigned long address_m;
51544 + pgd_t *pgd_m;
51545 + pud_t *pud_m;
51546 + pmd_t *pmd_m;
51547 +
51548 + if (vma->vm_start > vma_m->vm_start) {
51549 + address_m = address;
51550 + address -= SEGMEXEC_TASK_SIZE;
51551 + vma = vma_m;
51552 + } else
51553 + address_m = address + SEGMEXEC_TASK_SIZE;
51554 +
51555 + pgd_m = pgd_offset(mm, address_m);
51556 + pud_m = pud_alloc(mm, pgd_m, address_m);
51557 + if (!pud_m)
51558 + return VM_FAULT_OOM;
51559 + pmd_m = pmd_alloc(mm, pud_m, address_m);
51560 + if (!pmd_m)
51561 + return VM_FAULT_OOM;
51562 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
51563 + return VM_FAULT_OOM;
51564 + pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
51565 + }
51566 +#endif
51567 +
51568 pgd = pgd_offset(mm, address);
51569 pud = pud_alloc(mm, pgd, address);
51570 if (!pud)
51571 @@ -3310,7 +3543,7 @@ static int __init gate_vma_init(void)
51572 gate_vma.vm_start = FIXADDR_USER_START;
51573 gate_vma.vm_end = FIXADDR_USER_END;
51574 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
51575 - gate_vma.vm_page_prot = __P101;
51576 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
51577 /*
51578 * Make sure the vDSO gets into every core dump.
51579 * Dumping its contents makes post-mortem fully interpretable later
51580 diff -urNp linux-2.6.36/mm/memory-failure.c linux-2.6.36/mm/memory-failure.c
51581 --- linux-2.6.36/mm/memory-failure.c 2010-10-20 16:30:22.000000000 -0400
51582 +++ linux-2.6.36/mm/memory-failure.c 2010-11-06 18:58:15.000000000 -0400
51583 @@ -53,7 +53,7 @@ int sysctl_memory_failure_early_kill __r
51584
51585 int sysctl_memory_failure_recovery __read_mostly = 1;
51586
51587 -atomic_long_t mce_bad_pages __read_mostly = ATOMIC_LONG_INIT(0);
51588 +atomic_long_unchecked_t mce_bad_pages __read_mostly = ATOMIC_LONG_INIT(0);
51589
51590 #if defined(CONFIG_HWPOISON_INJECT) || defined(CONFIG_HWPOISON_INJECT_MODULE)
51591
51592 @@ -975,7 +975,7 @@ int __memory_failure(unsigned long pfn,
51593 }
51594
51595 nr_pages = 1 << compound_order(hpage);
51596 - atomic_long_add(nr_pages, &mce_bad_pages);
51597 + atomic_long_add_unchecked(nr_pages, &mce_bad_pages);
51598
51599 /*
51600 * We need/can do nothing about count=0 pages.
51601 @@ -1039,7 +1039,7 @@ int __memory_failure(unsigned long pfn,
51602 }
51603 if (hwpoison_filter(p)) {
51604 if (TestClearPageHWPoison(p))
51605 - atomic_long_sub(nr_pages, &mce_bad_pages);
51606 + atomic_long_sub_unchecked(nr_pages, &mce_bad_pages);
51607 unlock_page(hpage);
51608 put_page(hpage);
51609 return 0;
51610 @@ -1155,7 +1155,7 @@ int unpoison_memory(unsigned long pfn)
51611
51612 if (!get_page_unless_zero(page)) {
51613 if (TestClearPageHWPoison(p))
51614 - atomic_long_sub(nr_pages, &mce_bad_pages);
51615 + atomic_long_sub_unchecked(nr_pages, &mce_bad_pages);
51616 pr_debug("MCE: Software-unpoisoned free page %#lx\n", pfn);
51617 return 0;
51618 }
51619 @@ -1169,7 +1169,7 @@ int unpoison_memory(unsigned long pfn)
51620 */
51621 if (TestClearPageHWPoison(page)) {
51622 pr_debug("MCE: Software-unpoisoned page %#lx\n", pfn);
51623 - atomic_long_sub(nr_pages, &mce_bad_pages);
51624 + atomic_long_sub_unchecked(nr_pages, &mce_bad_pages);
51625 freeit = 1;
51626 }
51627 if (PageHuge(p))
51628 @@ -1352,7 +1352,7 @@ int soft_offline_page(struct page *page,
51629 return ret;
51630
51631 done:
51632 - atomic_long_add(1, &mce_bad_pages);
51633 + atomic_long_add_unchecked(1, &mce_bad_pages);
51634 SetPageHWPoison(page);
51635 /* keep elevated page count for bad page */
51636 return ret;
51637 diff -urNp linux-2.6.36/mm/mempolicy.c linux-2.6.36/mm/mempolicy.c
51638 --- linux-2.6.36/mm/mempolicy.c 2010-10-20 16:30:22.000000000 -0400
51639 +++ linux-2.6.36/mm/mempolicy.c 2010-11-06 19:43:34.000000000 -0400
51640 @@ -642,6 +642,10 @@ static int mbind_range(struct mm_struct
51641 unsigned long vmstart;
51642 unsigned long vmend;
51643
51644 +#ifdef CONFIG_PAX_SEGMEXEC
51645 + struct vm_area_struct *vma_m;
51646 +#endif
51647 +
51648 vma = find_vma_prev(mm, start, &prev);
51649 if (!vma || vma->vm_start > start)
51650 return -EFAULT;
51651 @@ -672,6 +676,16 @@ static int mbind_range(struct mm_struct
51652 err = policy_vma(vma, new_pol);
51653 if (err)
51654 goto out;
51655 +
51656 +#ifdef CONFIG_PAX_SEGMEXEC
51657 + vma_m = pax_find_mirror_vma(vma);
51658 + if (vma_m) {
51659 + err = policy_vma(vma_m, new_pol);
51660 + if (err)
51661 + goto out;
51662 + }
51663 +#endif
51664 +
51665 }
51666
51667 out:
51668 @@ -1098,6 +1112,17 @@ static long do_mbind(unsigned long start
51669
51670 if (end < start)
51671 return -EINVAL;
51672 +
51673 +#ifdef CONFIG_PAX_SEGMEXEC
51674 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
51675 + if (end > SEGMEXEC_TASK_SIZE)
51676 + return -EINVAL;
51677 + } else
51678 +#endif
51679 +
51680 + if (end > TASK_SIZE)
51681 + return -EINVAL;
51682 +
51683 if (end == start)
51684 return 0;
51685
51686 @@ -1312,6 +1337,14 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi
51687 if (!mm)
51688 goto out;
51689
51690 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
51691 + if (mm != current->mm &&
51692 + (mm->pax_flags & MF_PAX_RANDMMAP || mm->pax_flags & MF_PAX_SEGMEXEC)) {
51693 + err = -EPERM;
51694 + goto out;
51695 + }
51696 +#endif
51697 +
51698 /*
51699 * Check if this process has the right to modify the specified
51700 * process. The right exists if the process has administrative
51701 @@ -1321,8 +1354,7 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi
51702 rcu_read_lock();
51703 tcred = __task_cred(task);
51704 if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
51705 - cred->uid != tcred->suid && cred->uid != tcred->uid &&
51706 - !capable(CAP_SYS_NICE)) {
51707 + cred->uid != tcred->suid && !capable(CAP_SYS_NICE)) {
51708 rcu_read_unlock();
51709 err = -EPERM;
51710 goto out;
51711 @@ -2620,7 +2652,7 @@ int show_numa_map(struct seq_file *m, vo
51712
51713 if (file) {
51714 seq_printf(m, " file=");
51715 - seq_path(m, &file->f_path, "\n\t= ");
51716 + seq_path(m, &file->f_path, "\n\t\\= ");
51717 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
51718 seq_printf(m, " heap");
51719 } else if (vma->vm_start <= mm->start_stack &&
51720 diff -urNp linux-2.6.36/mm/migrate.c linux-2.6.36/mm/migrate.c
51721 --- linux-2.6.36/mm/migrate.c 2010-10-20 16:30:22.000000000 -0400
51722 +++ linux-2.6.36/mm/migrate.c 2010-11-06 18:58:50.000000000 -0400
51723 @@ -1098,6 +1098,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
51724 if (!mm)
51725 return -EINVAL;
51726
51727 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
51728 + if (mm != current->mm &&
51729 + (mm->pax_flags & MF_PAX_RANDMMAP || mm->pax_flags & MF_PAX_SEGMEXEC)) {
51730 + err = -EPERM;
51731 + goto out;
51732 + }
51733 +#endif
51734 +
51735 /*
51736 * Check if this process has the right to modify the specified
51737 * process. The right exists if the process has administrative
51738 @@ -1107,8 +1115,7 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
51739 rcu_read_lock();
51740 tcred = __task_cred(task);
51741 if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
51742 - cred->uid != tcred->suid && cred->uid != tcred->uid &&
51743 - !capable(CAP_SYS_NICE)) {
51744 + cred->uid != tcred->suid && !capable(CAP_SYS_NICE)) {
51745 rcu_read_unlock();
51746 err = -EPERM;
51747 goto out;
51748 diff -urNp linux-2.6.36/mm/mlock.c linux-2.6.36/mm/mlock.c
51749 --- linux-2.6.36/mm/mlock.c 2010-10-20 16:30:22.000000000 -0400
51750 +++ linux-2.6.36/mm/mlock.c 2010-11-06 18:58:50.000000000 -0400
51751 @@ -13,6 +13,7 @@
51752 #include <linux/pagemap.h>
51753 #include <linux/mempolicy.h>
51754 #include <linux/syscalls.h>
51755 +#include <linux/security.h>
51756 #include <linux/sched.h>
51757 #include <linux/module.h>
51758 #include <linux/rmap.h>
51759 @@ -135,13 +136,6 @@ void munlock_vma_page(struct page *page)
51760 }
51761 }
51762
51763 -static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr)
51764 -{
51765 - return (vma->vm_flags & VM_GROWSDOWN) &&
51766 - (vma->vm_start == addr) &&
51767 - !vma_stack_continue(vma->vm_prev, addr);
51768 -}
51769 -
51770 /**
51771 * __mlock_vma_pages_range() - mlock a range of pages in the vma.
51772 * @vma: target vma
51773 @@ -174,12 +168,6 @@ static long __mlock_vma_pages_range(stru
51774 if (vma->vm_flags & VM_WRITE)
51775 gup_flags |= FOLL_WRITE;
51776
51777 - /* We don't try to access the guard page of a stack vma */
51778 - if (stack_guard_page(vma, start)) {
51779 - addr += PAGE_SIZE;
51780 - nr_pages--;
51781 - }
51782 -
51783 while (nr_pages > 0) {
51784 int i;
51785
51786 @@ -445,6 +433,9 @@ static int do_mlock(unsigned long start,
51787 return -EINVAL;
51788 if (end == start)
51789 return 0;
51790 + if (end > TASK_SIZE)
51791 + return -EINVAL;
51792 +
51793 vma = find_vma_prev(current->mm, start, &prev);
51794 if (!vma || vma->vm_start > start)
51795 return -ENOMEM;
51796 @@ -455,6 +446,11 @@ static int do_mlock(unsigned long start,
51797 for (nstart = start ; ; ) {
51798 unsigned int newflags;
51799
51800 +#ifdef CONFIG_PAX_SEGMEXEC
51801 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
51802 + break;
51803 +#endif
51804 +
51805 /* Here we know that vma->vm_start <= nstart < vma->vm_end. */
51806
51807 newflags = vma->vm_flags | VM_LOCKED;
51808 @@ -504,6 +500,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
51809 lock_limit >>= PAGE_SHIFT;
51810
51811 /* check against resource limits */
51812 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
51813 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
51814 error = do_mlock(start, len, 1);
51815 up_write(&current->mm->mmap_sem);
51816 @@ -525,17 +522,23 @@ SYSCALL_DEFINE2(munlock, unsigned long,
51817 static int do_mlockall(int flags)
51818 {
51819 struct vm_area_struct * vma, * prev = NULL;
51820 - unsigned int def_flags = 0;
51821
51822 if (flags & MCL_FUTURE)
51823 - def_flags = VM_LOCKED;
51824 - current->mm->def_flags = def_flags;
51825 + current->mm->def_flags |= VM_LOCKED;
51826 + else
51827 + current->mm->def_flags &= ~VM_LOCKED;
51828 if (flags == MCL_FUTURE)
51829 goto out;
51830
51831 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
51832 - unsigned int newflags;
51833 + unsigned long newflags;
51834 +
51835 +#ifdef CONFIG_PAX_SEGMEXEC
51836 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
51837 + break;
51838 +#endif
51839
51840 + BUG_ON(vma->vm_end > TASK_SIZE);
51841 newflags = vma->vm_flags | VM_LOCKED;
51842 if (!(flags & MCL_CURRENT))
51843 newflags &= ~VM_LOCKED;
51844 @@ -567,6 +570,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
51845 lock_limit >>= PAGE_SHIFT;
51846
51847 ret = -ENOMEM;
51848 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm << PAGE_SHIFT, 1);
51849 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
51850 capable(CAP_IPC_LOCK))
51851 ret = do_mlockall(flags);
51852 diff -urNp linux-2.6.36/mm/mmap.c linux-2.6.36/mm/mmap.c
51853 --- linux-2.6.36/mm/mmap.c 2010-10-20 16:30:22.000000000 -0400
51854 +++ linux-2.6.36/mm/mmap.c 2010-11-06 18:58:50.000000000 -0400
51855 @@ -44,6 +44,16 @@
51856 #define arch_rebalance_pgtables(addr, len) (addr)
51857 #endif
51858
51859 +static inline void verify_mm_writelocked(struct mm_struct *mm)
51860 +{
51861 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
51862 + if (unlikely(down_read_trylock(&mm->mmap_sem))) {
51863 + up_read(&mm->mmap_sem);
51864 + BUG();
51865 + }
51866 +#endif
51867 +}
51868 +
51869 static void unmap_region(struct mm_struct *mm,
51870 struct vm_area_struct *vma, struct vm_area_struct *prev,
51871 unsigned long start, unsigned long end);
51872 @@ -69,22 +79,32 @@ static void unmap_region(struct mm_struc
51873 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
51874 *
51875 */
51876 -pgprot_t protection_map[16] = {
51877 +pgprot_t protection_map[16] __read_only = {
51878 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
51879 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
51880 };
51881
51882 pgprot_t vm_get_page_prot(unsigned long vm_flags)
51883 {
51884 - return __pgprot(pgprot_val(protection_map[vm_flags &
51885 + pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
51886 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
51887 pgprot_val(arch_vm_get_page_prot(vm_flags)));
51888 +
51889 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
51890 + if (!(__supported_pte_mask & _PAGE_NX) &&
51891 + (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
51892 + (vm_flags & (VM_READ | VM_WRITE)))
51893 + prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
51894 +#endif
51895 +
51896 + return prot;
51897 }
51898 EXPORT_SYMBOL(vm_get_page_prot);
51899
51900 int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
51901 int sysctl_overcommit_ratio = 50; /* default is 50% */
51902 int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
51903 +unsigned long sysctl_heap_stack_gap __read_mostly = 64*1024;
51904 struct percpu_counter vm_committed_as;
51905
51906 /*
51907 @@ -230,6 +250,7 @@ static struct vm_area_struct *remove_vma
51908 struct vm_area_struct *next = vma->vm_next;
51909
51910 might_sleep();
51911 + BUG_ON(vma->vm_mirror);
51912 if (vma->vm_ops && vma->vm_ops->close)
51913 vma->vm_ops->close(vma);
51914 if (vma->vm_file) {
51915 @@ -266,6 +287,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
51916 * not page aligned -Ram Gupta
51917 */
51918 rlim = rlimit(RLIMIT_DATA);
51919 + gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
51920 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
51921 (mm->end_data - mm->start_data) > rlim)
51922 goto out;
51923 @@ -707,6 +729,12 @@ static int
51924 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
51925 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
51926 {
51927 +
51928 +#ifdef CONFIG_PAX_SEGMEXEC
51929 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
51930 + return 0;
51931 +#endif
51932 +
51933 if (is_mergeable_vma(vma, file, vm_flags) &&
51934 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
51935 if (vma->vm_pgoff == vm_pgoff)
51936 @@ -726,6 +754,12 @@ static int
51937 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
51938 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
51939 {
51940 +
51941 +#ifdef CONFIG_PAX_SEGMEXEC
51942 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
51943 + return 0;
51944 +#endif
51945 +
51946 if (is_mergeable_vma(vma, file, vm_flags) &&
51947 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
51948 pgoff_t vm_pglen;
51949 @@ -768,13 +802,20 @@ can_vma_merge_after(struct vm_area_struc
51950 struct vm_area_struct *vma_merge(struct mm_struct *mm,
51951 struct vm_area_struct *prev, unsigned long addr,
51952 unsigned long end, unsigned long vm_flags,
51953 - struct anon_vma *anon_vma, struct file *file,
51954 + struct anon_vma *anon_vma, struct file *file,
51955 pgoff_t pgoff, struct mempolicy *policy)
51956 {
51957 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
51958 struct vm_area_struct *area, *next;
51959 int err;
51960
51961 +#ifdef CONFIG_PAX_SEGMEXEC
51962 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
51963 + struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
51964 +
51965 + BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
51966 +#endif
51967 +
51968 /*
51969 * We later require that vma->vm_flags == vm_flags,
51970 * so this tests vma->vm_flags & VM_SPECIAL, too.
51971 @@ -790,6 +831,15 @@ struct vm_area_struct *vma_merge(struct
51972 if (next && next->vm_end == end) /* cases 6, 7, 8 */
51973 next = next->vm_next;
51974
51975 +#ifdef CONFIG_PAX_SEGMEXEC
51976 + if (prev)
51977 + prev_m = pax_find_mirror_vma(prev);
51978 + if (area)
51979 + area_m = pax_find_mirror_vma(area);
51980 + if (next)
51981 + next_m = pax_find_mirror_vma(next);
51982 +#endif
51983 +
51984 /*
51985 * Can it merge with the predecessor?
51986 */
51987 @@ -809,9 +859,24 @@ struct vm_area_struct *vma_merge(struct
51988 /* cases 1, 6 */
51989 err = vma_adjust(prev, prev->vm_start,
51990 next->vm_end, prev->vm_pgoff, NULL);
51991 - } else /* cases 2, 5, 7 */
51992 +
51993 +#ifdef CONFIG_PAX_SEGMEXEC
51994 + if (!err && prev_m)
51995 + err = vma_adjust(prev_m, prev_m->vm_start,
51996 + next_m->vm_end, prev_m->vm_pgoff, NULL);
51997 +#endif
51998 +
51999 + } else { /* cases 2, 5, 7 */
52000 err = vma_adjust(prev, prev->vm_start,
52001 end, prev->vm_pgoff, NULL);
52002 +
52003 +#ifdef CONFIG_PAX_SEGMEXEC
52004 + if (!err && prev_m)
52005 + err = vma_adjust(prev_m, prev_m->vm_start,
52006 + end_m, prev_m->vm_pgoff, NULL);
52007 +#endif
52008 +
52009 + }
52010 if (err)
52011 return NULL;
52012 return prev;
52013 @@ -824,12 +889,27 @@ struct vm_area_struct *vma_merge(struct
52014 mpol_equal(policy, vma_policy(next)) &&
52015 can_vma_merge_before(next, vm_flags,
52016 anon_vma, file, pgoff+pglen)) {
52017 - if (prev && addr < prev->vm_end) /* case 4 */
52018 + if (prev && addr < prev->vm_end) { /* case 4 */
52019 err = vma_adjust(prev, prev->vm_start,
52020 addr, prev->vm_pgoff, NULL);
52021 - else /* cases 3, 8 */
52022 +
52023 +#ifdef CONFIG_PAX_SEGMEXEC
52024 + if (!err && prev_m)
52025 + err = vma_adjust(prev_m, prev_m->vm_start,
52026 + addr_m, prev_m->vm_pgoff, NULL);
52027 +#endif
52028 +
52029 + } else { /* cases 3, 8 */
52030 err = vma_adjust(area, addr, next->vm_end,
52031 next->vm_pgoff - pglen, NULL);
52032 +
52033 +#ifdef CONFIG_PAX_SEGMEXEC
52034 + if (!err && area_m)
52035 + err = vma_adjust(area_m, addr_m, next_m->vm_end,
52036 + next_m->vm_pgoff - pglen, NULL);
52037 +#endif
52038 +
52039 + }
52040 if (err)
52041 return NULL;
52042 return area;
52043 @@ -944,14 +1024,11 @@ none:
52044 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
52045 struct file *file, long pages)
52046 {
52047 - const unsigned long stack_flags
52048 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
52049 -
52050 if (file) {
52051 mm->shared_vm += pages;
52052 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
52053 mm->exec_vm += pages;
52054 - } else if (flags & stack_flags)
52055 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
52056 mm->stack_vm += pages;
52057 if (flags & (VM_RESERVED|VM_IO))
52058 mm->reserved_vm += pages;
52059 @@ -978,7 +1055,7 @@ unsigned long do_mmap_pgoff(struct file
52060 * (the exception is when the underlying filesystem is noexec
52061 * mounted, in which case we dont add PROT_EXEC.)
52062 */
52063 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
52064 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
52065 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
52066 prot |= PROT_EXEC;
52067
52068 @@ -1004,7 +1081,7 @@ unsigned long do_mmap_pgoff(struct file
52069 /* Obtain the address to map to. we verify (or select) it and ensure
52070 * that it represents a valid section of the address space.
52071 */
52072 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
52073 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
52074 if (addr & ~PAGE_MASK)
52075 return addr;
52076
52077 @@ -1015,6 +1092,31 @@ unsigned long do_mmap_pgoff(struct file
52078 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
52079 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
52080
52081 +#ifdef CONFIG_PAX_MPROTECT
52082 + if (mm->pax_flags & MF_PAX_MPROTECT) {
52083 + if ((vm_flags & (VM_WRITE | VM_EXEC)) == (VM_WRITE | VM_EXEC)) {
52084 + gr_log_rwxmmap(file);
52085 +
52086 +#ifdef CONFIG_PAX_EMUPLT
52087 + vm_flags &= ~VM_EXEC;
52088 +#else
52089 + return -EPERM;
52090 +#endif
52091 +
52092 + }
52093 +
52094 + if (!(vm_flags & VM_EXEC))
52095 + vm_flags &= ~VM_MAYEXEC;
52096 + else
52097 + vm_flags &= ~VM_MAYWRITE;
52098 + }
52099 +#endif
52100 +
52101 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
52102 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
52103 + vm_flags &= ~VM_PAGEEXEC;
52104 +#endif
52105 +
52106 if (flags & MAP_LOCKED)
52107 if (!can_do_mlock())
52108 return -EPERM;
52109 @@ -1026,6 +1128,7 @@ unsigned long do_mmap_pgoff(struct file
52110 locked += mm->locked_vm;
52111 lock_limit = rlimit(RLIMIT_MEMLOCK);
52112 lock_limit >>= PAGE_SHIFT;
52113 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
52114 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
52115 return -EAGAIN;
52116 }
52117 @@ -1096,6 +1199,9 @@ unsigned long do_mmap_pgoff(struct file
52118 if (error)
52119 return error;
52120
52121 + if (!gr_acl_handle_mmap(file, prot))
52122 + return -EACCES;
52123 +
52124 return mmap_region(file, addr, len, flags, vm_flags, pgoff);
52125 }
52126 EXPORT_SYMBOL(do_mmap_pgoff);
52127 @@ -1172,10 +1278,10 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_ar
52128 */
52129 int vma_wants_writenotify(struct vm_area_struct *vma)
52130 {
52131 - unsigned int vm_flags = vma->vm_flags;
52132 + unsigned long vm_flags = vma->vm_flags;
52133
52134 /* If it was private or non-writable, the write bit is already clear */
52135 - if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
52136 + if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
52137 return 0;
52138
52139 /* The backer wishes to know when pages are first written to? */
52140 @@ -1224,14 +1330,24 @@ unsigned long mmap_region(struct file *f
52141 unsigned long charged = 0;
52142 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
52143
52144 +#ifdef CONFIG_PAX_SEGMEXEC
52145 + struct vm_area_struct *vma_m = NULL;
52146 +#endif
52147 +
52148 + /*
52149 + * mm->mmap_sem is required to protect against another thread
52150 + * changing the mappings in case we sleep.
52151 + */
52152 + verify_mm_writelocked(mm);
52153 +
52154 /* Clear old maps */
52155 error = -ENOMEM;
52156 -munmap_back:
52157 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
52158 if (vma && vma->vm_start < addr + len) {
52159 if (do_munmap(mm, addr, len))
52160 return -ENOMEM;
52161 - goto munmap_back;
52162 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
52163 + BUG_ON(vma && vma->vm_start < addr + len);
52164 }
52165
52166 /* Check against address space limit. */
52167 @@ -1280,6 +1396,16 @@ munmap_back:
52168 goto unacct_error;
52169 }
52170
52171 +#ifdef CONFIG_PAX_SEGMEXEC
52172 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
52173 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
52174 + if (!vma_m) {
52175 + error = -ENOMEM;
52176 + goto free_vma;
52177 + }
52178 + }
52179 +#endif
52180 +
52181 vma->vm_mm = mm;
52182 vma->vm_start = addr;
52183 vma->vm_end = addr + len;
52184 @@ -1303,6 +1429,19 @@ munmap_back:
52185 error = file->f_op->mmap(file, vma);
52186 if (error)
52187 goto unmap_and_free_vma;
52188 +
52189 +#ifdef CONFIG_PAX_SEGMEXEC
52190 + if (vma_m && (vm_flags & VM_EXECUTABLE))
52191 + added_exe_file_vma(mm);
52192 +#endif
52193 +
52194 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
52195 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
52196 + vma->vm_flags |= VM_PAGEEXEC;
52197 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
52198 + }
52199 +#endif
52200 +
52201 if (vm_flags & VM_EXECUTABLE)
52202 added_exe_file_vma(mm);
52203
52204 @@ -1338,6 +1477,11 @@ munmap_back:
52205 vma_link(mm, vma, prev, rb_link, rb_parent);
52206 file = vma->vm_file;
52207
52208 +#ifdef CONFIG_PAX_SEGMEXEC
52209 + if (vma_m)
52210 + BUG_ON(pax_mirror_vma(vma_m, vma));
52211 +#endif
52212 +
52213 /* Once vma denies write, undo our temporary denial count */
52214 if (correct_wcount)
52215 atomic_inc(&inode->i_writecount);
52216 @@ -1346,6 +1490,7 @@ out:
52217
52218 mm->total_vm += len >> PAGE_SHIFT;
52219 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
52220 + track_exec_limit(mm, addr, addr + len, vm_flags);
52221 if (vm_flags & VM_LOCKED) {
52222 if (!mlock_vma_pages_range(vma, addr, addr + len))
52223 mm->locked_vm += (len >> PAGE_SHIFT);
52224 @@ -1363,6 +1508,12 @@ unmap_and_free_vma:
52225 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
52226 charged = 0;
52227 free_vma:
52228 +
52229 +#ifdef CONFIG_PAX_SEGMEXEC
52230 + if (vma_m)
52231 + kmem_cache_free(vm_area_cachep, vma_m);
52232 +#endif
52233 +
52234 kmem_cache_free(vm_area_cachep, vma);
52235 unacct_error:
52236 if (charged)
52237 @@ -1370,6 +1521,33 @@ unacct_error:
52238 return error;
52239 }
52240
52241 +bool check_heap_stack_gap(struct vm_area_struct *vma, unsigned long addr, unsigned long len)
52242 +{
52243 + if (!vma) {
52244 +#ifdef CONFIG_STACK_GROWSUP
52245 + if (addr > sysctl_heap_stack_gap)
52246 + vma = find_vma(current->mm, addr - sysctl_heap_stack_gap);
52247 + else
52248 + vma = find_vma(current->mm, 0);
52249 + if (vma && (vma->vm_flags & VM_GROWSUP))
52250 + return false;
52251 +#endif
52252 + return true;
52253 + }
52254 +
52255 + if (addr + len > vma->vm_start)
52256 + return false;
52257 +
52258 + if (vma->vm_flags & VM_GROWSDOWN)
52259 + return sysctl_heap_stack_gap <= vma->vm_start - addr - len;
52260 +#ifdef CONFIG_STACK_GROWSUP
52261 + else if (vma->vm_prev && (vma->vm_prev->vm_flags & VM_GROWSUP))
52262 + return addr - vma->vm_prev->vm_end <= sysctl_heap_stack_gap;
52263 +#endif
52264 +
52265 + return true;
52266 +}
52267 +
52268 /* Get an address range which is currently unmapped.
52269 * For shmat() with addr=0.
52270 *
52271 @@ -1396,18 +1574,23 @@ arch_get_unmapped_area(struct file *filp
52272 if (flags & MAP_FIXED)
52273 return addr;
52274
52275 +#ifdef CONFIG_PAX_RANDMMAP
52276 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
52277 +#endif
52278 +
52279 if (addr) {
52280 addr = PAGE_ALIGN(addr);
52281 - vma = find_vma(mm, addr);
52282 - if (TASK_SIZE - len >= addr &&
52283 - (!vma || addr + len <= vma->vm_start))
52284 - return addr;
52285 + if (TASK_SIZE - len >= addr) {
52286 + vma = find_vma(mm, addr);
52287 + if (check_heap_stack_gap(vma, addr, len))
52288 + return addr;
52289 + }
52290 }
52291 if (len > mm->cached_hole_size) {
52292 - start_addr = addr = mm->free_area_cache;
52293 + start_addr = addr = mm->free_area_cache;
52294 } else {
52295 - start_addr = addr = TASK_UNMAPPED_BASE;
52296 - mm->cached_hole_size = 0;
52297 + start_addr = addr = mm->mmap_base;
52298 + mm->cached_hole_size = 0;
52299 }
52300
52301 full_search:
52302 @@ -1418,34 +1601,40 @@ full_search:
52303 * Start a new search - just in case we missed
52304 * some holes.
52305 */
52306 - if (start_addr != TASK_UNMAPPED_BASE) {
52307 - addr = TASK_UNMAPPED_BASE;
52308 - start_addr = addr;
52309 + if (start_addr != mm->mmap_base) {
52310 + start_addr = addr = mm->mmap_base;
52311 mm->cached_hole_size = 0;
52312 goto full_search;
52313 }
52314 return -ENOMEM;
52315 }
52316 - if (!vma || addr + len <= vma->vm_start) {
52317 - /*
52318 - * Remember the place where we stopped the search:
52319 - */
52320 - mm->free_area_cache = addr + len;
52321 - return addr;
52322 - }
52323 + if (check_heap_stack_gap(vma, addr, len))
52324 + break;
52325 if (addr + mm->cached_hole_size < vma->vm_start)
52326 mm->cached_hole_size = vma->vm_start - addr;
52327 addr = vma->vm_end;
52328 }
52329 +
52330 + /*
52331 + * Remember the place where we stopped the search:
52332 + */
52333 + mm->free_area_cache = addr + len;
52334 + return addr;
52335 }
52336 #endif
52337
52338 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
52339 {
52340 +
52341 +#ifdef CONFIG_PAX_SEGMEXEC
52342 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
52343 + return;
52344 +#endif
52345 +
52346 /*
52347 * Is this a new hole at the lowest possible address?
52348 */
52349 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
52350 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
52351 mm->free_area_cache = addr;
52352 mm->cached_hole_size = ~0UL;
52353 }
52354 @@ -1463,7 +1652,7 @@ arch_get_unmapped_area_topdown(struct fi
52355 {
52356 struct vm_area_struct *vma;
52357 struct mm_struct *mm = current->mm;
52358 - unsigned long addr = addr0;
52359 + unsigned long base = mm->mmap_base, addr = addr0;
52360
52361 /* requested length too big for entire address space */
52362 if (len > TASK_SIZE)
52363 @@ -1472,13 +1661,18 @@ arch_get_unmapped_area_topdown(struct fi
52364 if (flags & MAP_FIXED)
52365 return addr;
52366
52367 +#ifdef CONFIG_PAX_RANDMMAP
52368 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
52369 +#endif
52370 +
52371 /* requesting a specific address */
52372 if (addr) {
52373 addr = PAGE_ALIGN(addr);
52374 - vma = find_vma(mm, addr);
52375 - if (TASK_SIZE - len >= addr &&
52376 - (!vma || addr + len <= vma->vm_start))
52377 - return addr;
52378 + if (TASK_SIZE - len >= addr) {
52379 + vma = find_vma(mm, addr);
52380 + if (check_heap_stack_gap(vma, addr, len))
52381 + return addr;
52382 + }
52383 }
52384
52385 /* check if free_area_cache is useful for us */
52386 @@ -1493,7 +1687,7 @@ arch_get_unmapped_area_topdown(struct fi
52387 /* make sure it can fit in the remaining address space */
52388 if (addr > len) {
52389 vma = find_vma(mm, addr-len);
52390 - if (!vma || addr <= vma->vm_start)
52391 + if (check_heap_stack_gap(vma, addr - len, len))
52392 /* remember the address as a hint for next time */
52393 return (mm->free_area_cache = addr-len);
52394 }
52395 @@ -1510,7 +1704,7 @@ arch_get_unmapped_area_topdown(struct fi
52396 * return with success:
52397 */
52398 vma = find_vma(mm, addr);
52399 - if (!vma || addr+len <= vma->vm_start)
52400 + if (check_heap_stack_gap(vma, addr, len))
52401 /* remember the address as a hint for next time */
52402 return (mm->free_area_cache = addr);
52403
52404 @@ -1529,13 +1723,21 @@ bottomup:
52405 * can happen with large stack limits and large mmap()
52406 * allocations.
52407 */
52408 + mm->mmap_base = TASK_UNMAPPED_BASE;
52409 +
52410 +#ifdef CONFIG_PAX_RANDMMAP
52411 + if (mm->pax_flags & MF_PAX_RANDMMAP)
52412 + mm->mmap_base += mm->delta_mmap;
52413 +#endif
52414 +
52415 + mm->free_area_cache = mm->mmap_base;
52416 mm->cached_hole_size = ~0UL;
52417 - mm->free_area_cache = TASK_UNMAPPED_BASE;
52418 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
52419 /*
52420 * Restore the topdown base:
52421 */
52422 - mm->free_area_cache = mm->mmap_base;
52423 + mm->mmap_base = base;
52424 + mm->free_area_cache = base;
52425 mm->cached_hole_size = ~0UL;
52426
52427 return addr;
52428 @@ -1544,6 +1746,12 @@ bottomup:
52429
52430 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
52431 {
52432 +
52433 +#ifdef CONFIG_PAX_SEGMEXEC
52434 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
52435 + return;
52436 +#endif
52437 +
52438 /*
52439 * Is this a new hole at the highest possible address?
52440 */
52441 @@ -1551,8 +1759,10 @@ void arch_unmap_area_topdown(struct mm_s
52442 mm->free_area_cache = addr;
52443
52444 /* dont allow allocations above current base */
52445 - if (mm->free_area_cache > mm->mmap_base)
52446 + if (mm->free_area_cache > mm->mmap_base) {
52447 mm->free_area_cache = mm->mmap_base;
52448 + mm->cached_hole_size = ~0UL;
52449 + }
52450 }
52451
52452 unsigned long
52453 @@ -1660,6 +1870,28 @@ out:
52454 return prev ? prev->vm_next : vma;
52455 }
52456
52457 +#ifdef CONFIG_PAX_SEGMEXEC
52458 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
52459 +{
52460 + struct vm_area_struct *vma_m;
52461 +
52462 + BUG_ON(!vma || vma->vm_start >= vma->vm_end);
52463 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
52464 + BUG_ON(vma->vm_mirror);
52465 + return NULL;
52466 + }
52467 + BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
52468 + vma_m = vma->vm_mirror;
52469 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
52470 + BUG_ON(vma->vm_file != vma_m->vm_file);
52471 + BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
52472 + BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff);
52473 + BUG_ON(vma->anon_vma != vma_m->anon_vma && vma->anon_vma->root != vma_m->anon_vma->root);
52474 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_RESERVED));
52475 + return vma_m;
52476 +}
52477 +#endif
52478 +
52479 /*
52480 * Verify that the stack growth is acceptable and
52481 * update accounting. This is shared with both the
52482 @@ -1676,6 +1908,7 @@ static int acct_stack_growth(struct vm_a
52483 return -ENOMEM;
52484
52485 /* Stack limit test */
52486 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
52487 if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
52488 return -ENOMEM;
52489
52490 @@ -1686,6 +1919,7 @@ static int acct_stack_growth(struct vm_a
52491 locked = mm->locked_vm + grow;
52492 limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur);
52493 limit >>= PAGE_SHIFT;
52494 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
52495 if (locked > limit && !capable(CAP_IPC_LOCK))
52496 return -ENOMEM;
52497 }
52498 @@ -1716,37 +1950,47 @@ static int acct_stack_growth(struct vm_a
52499 * PA-RISC uses this for its stack; IA64 for its Register Backing Store.
52500 * vma is the last one with address > vma->vm_end. Have to extend vma.
52501 */
52502 +#ifndef CONFIG_IA64
52503 +static
52504 +#endif
52505 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
52506 {
52507 - int error;
52508 + int error, locknext;
52509
52510 if (!(vma->vm_flags & VM_GROWSUP))
52511 return -EFAULT;
52512
52513 + /* Also guard against wrapping around to address 0. */
52514 + if (address < PAGE_ALIGN(address+1))
52515 + address = PAGE_ALIGN(address+1);
52516 + else
52517 + return -ENOMEM;
52518 +
52519 /*
52520 * We must make sure the anon_vma is allocated
52521 * so that the anon_vma locking is not a noop.
52522 */
52523 if (unlikely(anon_vma_prepare(vma)))
52524 return -ENOMEM;
52525 + locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
52526 + if (locknext && anon_vma_prepare(vma->vm_next))
52527 + return -ENOMEM;
52528 vma_lock_anon_vma(vma);
52529 + if (locknext)
52530 + vma_lock_anon_vma(vma->vm_next);
52531
52532 /*
52533 * vma->vm_start/vm_end cannot change under us because the caller
52534 * is required to hold the mmap_sem in read mode. We need the
52535 - * anon_vma lock to serialize against concurrent expand_stacks.
52536 - * Also guard against wrapping around to address 0.
52537 + * anon_vma locks to serialize against concurrent expand_stacks
52538 + * and expand_upwards.
52539 */
52540 - if (address < PAGE_ALIGN(address+4))
52541 - address = PAGE_ALIGN(address+4);
52542 - else {
52543 - vma_unlock_anon_vma(vma);
52544 - return -ENOMEM;
52545 - }
52546 error = 0;
52547
52548 /* Somebody else might have raced and expanded it already */
52549 - if (address > vma->vm_end) {
52550 + 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)
52551 + error = -ENOMEM;
52552 + else if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
52553 unsigned long size, grow;
52554
52555 size = address - vma->vm_start;
52556 @@ -1758,6 +2002,8 @@ int expand_upwards(struct vm_area_struct
52557 perf_event_mmap(vma);
52558 }
52559 }
52560 + if (locknext)
52561 + vma_unlock_anon_vma(vma->vm_next);
52562 vma_unlock_anon_vma(vma);
52563 return error;
52564 }
52565 @@ -1769,7 +2015,8 @@ int expand_upwards(struct vm_area_struct
52566 static int expand_downwards(struct vm_area_struct *vma,
52567 unsigned long address)
52568 {
52569 - int error;
52570 + int error, lockprev = 0;
52571 + struct vm_area_struct *prev;
52572
52573 /*
52574 * We must make sure the anon_vma is allocated
52575 @@ -1783,6 +2030,15 @@ static int expand_downwards(struct vm_ar
52576 if (error)
52577 return error;
52578
52579 + prev = vma->vm_prev;
52580 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
52581 + lockprev = prev && (prev->vm_flags & VM_GROWSUP);
52582 +#endif
52583 + if (lockprev && anon_vma_prepare(prev))
52584 + return -ENOMEM;
52585 + if (lockprev)
52586 + vma_lock_anon_vma(prev);
52587 +
52588 vma_lock_anon_vma(vma);
52589
52590 /*
52591 @@ -1792,9 +2048,17 @@ static int expand_downwards(struct vm_ar
52592 */
52593
52594 /* Somebody else might have raced and expanded it already */
52595 - if (address < vma->vm_start) {
52596 + if (prev && (prev->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) && address - prev->vm_end < sysctl_heap_stack_gap)
52597 + error = -ENOMEM;
52598 + else if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
52599 unsigned long size, grow;
52600
52601 +#ifdef CONFIG_PAX_SEGMEXEC
52602 + struct vm_area_struct *vma_m;
52603 +
52604 + vma_m = pax_find_mirror_vma(vma);
52605 +#endif
52606 +
52607 size = vma->vm_end - address;
52608 grow = (vma->vm_start - address) >> PAGE_SHIFT;
52609
52610 @@ -1802,10 +2066,21 @@ static int expand_downwards(struct vm_ar
52611 if (!error) {
52612 vma->vm_start = address;
52613 vma->vm_pgoff -= grow;
52614 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
52615 +
52616 +#ifdef CONFIG_PAX_SEGMEXEC
52617 + if (vma_m) {
52618 + vma_m->vm_start -= grow << PAGE_SHIFT;
52619 + vma_m->vm_pgoff -= grow;
52620 + }
52621 +#endif
52622 +
52623 perf_event_mmap(vma);
52624 }
52625 }
52626 vma_unlock_anon_vma(vma);
52627 + if (lockprev)
52628 + vma_unlock_anon_vma(prev);
52629 return error;
52630 }
52631
52632 @@ -1879,6 +2154,13 @@ static void remove_vma_list(struct mm_st
52633 do {
52634 long nrpages = vma_pages(vma);
52635
52636 +#ifdef CONFIG_PAX_SEGMEXEC
52637 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
52638 + vma = remove_vma(vma);
52639 + continue;
52640 + }
52641 +#endif
52642 +
52643 mm->total_vm -= nrpages;
52644 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
52645 vma = remove_vma(vma);
52646 @@ -1924,6 +2206,16 @@ detach_vmas_to_be_unmapped(struct mm_str
52647 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
52648 vma->vm_prev = NULL;
52649 do {
52650 +
52651 +#ifdef CONFIG_PAX_SEGMEXEC
52652 + if (vma->vm_mirror) {
52653 + BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
52654 + vma->vm_mirror->vm_mirror = NULL;
52655 + vma->vm_mirror->vm_flags &= ~VM_EXEC;
52656 + vma->vm_mirror = NULL;
52657 + }
52658 +#endif
52659 +
52660 rb_erase(&vma->vm_rb, &mm->mm_rb);
52661 mm->map_count--;
52662 tail_vma = vma;
52663 @@ -1952,14 +2244,33 @@ static int __split_vma(struct mm_struct
52664 struct vm_area_struct *new;
52665 int err = -ENOMEM;
52666
52667 +#ifdef CONFIG_PAX_SEGMEXEC
52668 + struct vm_area_struct *vma_m, *new_m = NULL;
52669 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
52670 +#endif
52671 +
52672 if (is_vm_hugetlb_page(vma) && (addr &
52673 ~(huge_page_mask(hstate_vma(vma)))))
52674 return -EINVAL;
52675
52676 +#ifdef CONFIG_PAX_SEGMEXEC
52677 + vma_m = pax_find_mirror_vma(vma);
52678 +#endif
52679 +
52680 new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
52681 if (!new)
52682 goto out_err;
52683
52684 +#ifdef CONFIG_PAX_SEGMEXEC
52685 + if (vma_m) {
52686 + new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
52687 + if (!new_m) {
52688 + kmem_cache_free(vm_area_cachep, new);
52689 + goto out_err;
52690 + }
52691 + }
52692 +#endif
52693 +
52694 /* most fields are the same, copy all, and then fixup */
52695 *new = *vma;
52696
52697 @@ -1972,6 +2283,22 @@ static int __split_vma(struct mm_struct
52698 new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
52699 }
52700
52701 +#ifdef CONFIG_PAX_SEGMEXEC
52702 + if (vma_m) {
52703 + *new_m = *vma_m;
52704 + INIT_LIST_HEAD(&new_m->anon_vma_chain);
52705 + new_m->vm_mirror = new;
52706 + new->vm_mirror = new_m;
52707 +
52708 + if (new_below)
52709 + new_m->vm_end = addr_m;
52710 + else {
52711 + new_m->vm_start = addr_m;
52712 + new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
52713 + }
52714 + }
52715 +#endif
52716 +
52717 pol = mpol_dup(vma_policy(vma));
52718 if (IS_ERR(pol)) {
52719 err = PTR_ERR(pol);
52720 @@ -1997,6 +2324,42 @@ static int __split_vma(struct mm_struct
52721 else
52722 err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
52723
52724 +#ifdef CONFIG_PAX_SEGMEXEC
52725 + if (!err && vma_m) {
52726 + if (anon_vma_clone(new_m, vma_m))
52727 + goto out_free_mpol;
52728 +
52729 + mpol_get(pol);
52730 + vma_set_policy(new_m, pol);
52731 +
52732 + if (new_m->vm_file) {
52733 + get_file(new_m->vm_file);
52734 + if (vma_m->vm_flags & VM_EXECUTABLE)
52735 + added_exe_file_vma(mm);
52736 + }
52737 +
52738 + if (new_m->vm_ops && new_m->vm_ops->open)
52739 + new_m->vm_ops->open(new_m);
52740 +
52741 + if (new_below)
52742 + err = vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
52743 + ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
52744 + else
52745 + err = vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
52746 +
52747 + if (err) {
52748 + if (new_m->vm_ops && new_m->vm_ops->close)
52749 + new_m->vm_ops->close(new_m);
52750 + if (new_m->vm_file) {
52751 + if (vma_m->vm_flags & VM_EXECUTABLE)
52752 + removed_exe_file_vma(mm);
52753 + fput(new_m->vm_file);
52754 + }
52755 + mpol_put(pol);
52756 + }
52757 + }
52758 +#endif
52759 +
52760 /* Success. */
52761 if (!err)
52762 return 0;
52763 @@ -2009,10 +2372,18 @@ static int __split_vma(struct mm_struct
52764 removed_exe_file_vma(mm);
52765 fput(new->vm_file);
52766 }
52767 - unlink_anon_vmas(new);
52768 out_free_mpol:
52769 mpol_put(pol);
52770 out_free_vma:
52771 +
52772 +#ifdef CONFIG_PAX_SEGMEXEC
52773 + if (new_m) {
52774 + unlink_anon_vmas(new_m);
52775 + kmem_cache_free(vm_area_cachep, new_m);
52776 + }
52777 +#endif
52778 +
52779 + unlink_anon_vmas(new);
52780 kmem_cache_free(vm_area_cachep, new);
52781 out_err:
52782 return err;
52783 @@ -2025,6 +2396,15 @@ static int __split_vma(struct mm_struct
52784 int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
52785 unsigned long addr, int new_below)
52786 {
52787 +
52788 +#ifdef CONFIG_PAX_SEGMEXEC
52789 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
52790 + BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
52791 + if (mm->map_count >= sysctl_max_map_count-1)
52792 + return -ENOMEM;
52793 + } else
52794 +#endif
52795 +
52796 if (mm->map_count >= sysctl_max_map_count)
52797 return -ENOMEM;
52798
52799 @@ -2036,11 +2416,30 @@ int split_vma(struct mm_struct *mm, stru
52800 * work. This now handles partial unmappings.
52801 * Jeremy Fitzhardinge <jeremy@goop.org>
52802 */
52803 +#ifdef CONFIG_PAX_SEGMEXEC
52804 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
52805 +{
52806 + int ret = __do_munmap(mm, start, len);
52807 + if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
52808 + return ret;
52809 +
52810 + return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
52811 +}
52812 +
52813 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
52814 +#else
52815 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
52816 +#endif
52817 {
52818 unsigned long end;
52819 struct vm_area_struct *vma, *prev, *last;
52820
52821 + /*
52822 + * mm->mmap_sem is required to protect against another thread
52823 + * changing the mappings in case we sleep.
52824 + */
52825 + verify_mm_writelocked(mm);
52826 +
52827 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
52828 return -EINVAL;
52829
52830 @@ -2114,6 +2513,8 @@ int do_munmap(struct mm_struct *mm, unsi
52831 /* Fix up all other VM information */
52832 remove_vma_list(mm, vma);
52833
52834 + track_exec_limit(mm, start, end, 0UL);
52835 +
52836 return 0;
52837 }
52838
52839 @@ -2126,22 +2527,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, a
52840
52841 profile_munmap(addr);
52842
52843 +#ifdef CONFIG_PAX_SEGMEXEC
52844 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
52845 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
52846 + return -EINVAL;
52847 +#endif
52848 +
52849 down_write(&mm->mmap_sem);
52850 ret = do_munmap(mm, addr, len);
52851 up_write(&mm->mmap_sem);
52852 return ret;
52853 }
52854
52855 -static inline void verify_mm_writelocked(struct mm_struct *mm)
52856 -{
52857 -#ifdef CONFIG_DEBUG_VM
52858 - if (unlikely(down_read_trylock(&mm->mmap_sem))) {
52859 - WARN_ON(1);
52860 - up_read(&mm->mmap_sem);
52861 - }
52862 -#endif
52863 -}
52864 -
52865 /*
52866 * this is really a simplified "do_mmap". it only handles
52867 * anonymous maps. eventually we may be able to do some
52868 @@ -2155,6 +2552,7 @@ unsigned long do_brk(unsigned long addr,
52869 struct rb_node ** rb_link, * rb_parent;
52870 pgoff_t pgoff = addr >> PAGE_SHIFT;
52871 int error;
52872 + unsigned long charged;
52873
52874 len = PAGE_ALIGN(len);
52875 if (!len)
52876 @@ -2166,16 +2564,30 @@ unsigned long do_brk(unsigned long addr,
52877
52878 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
52879
52880 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
52881 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
52882 + flags &= ~VM_EXEC;
52883 +
52884 +#ifdef CONFIG_PAX_MPROTECT
52885 + if (mm->pax_flags & MF_PAX_MPROTECT)
52886 + flags &= ~VM_MAYEXEC;
52887 +#endif
52888 +
52889 + }
52890 +#endif
52891 +
52892 error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
52893 if (error & ~PAGE_MASK)
52894 return error;
52895
52896 + charged = len >> PAGE_SHIFT;
52897 +
52898 /*
52899 * mlock MCL_FUTURE?
52900 */
52901 if (mm->def_flags & VM_LOCKED) {
52902 unsigned long locked, lock_limit;
52903 - locked = len >> PAGE_SHIFT;
52904 + locked = charged;
52905 locked += mm->locked_vm;
52906 lock_limit = rlimit(RLIMIT_MEMLOCK);
52907 lock_limit >>= PAGE_SHIFT;
52908 @@ -2192,22 +2604,22 @@ unsigned long do_brk(unsigned long addr,
52909 /*
52910 * Clear old maps. this also does some error checking for us
52911 */
52912 - munmap_back:
52913 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
52914 if (vma && vma->vm_start < addr + len) {
52915 if (do_munmap(mm, addr, len))
52916 return -ENOMEM;
52917 - goto munmap_back;
52918 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
52919 + BUG_ON(vma && vma->vm_start < addr + len);
52920 }
52921
52922 /* Check against address space limits *after* clearing old maps... */
52923 - if (!may_expand_vm(mm, len >> PAGE_SHIFT))
52924 + if (!may_expand_vm(mm, charged))
52925 return -ENOMEM;
52926
52927 if (mm->map_count > sysctl_max_map_count)
52928 return -ENOMEM;
52929
52930 - if (security_vm_enough_memory(len >> PAGE_SHIFT))
52931 + if (security_vm_enough_memory(charged))
52932 return -ENOMEM;
52933
52934 /* Can we just expand an old private anonymous mapping? */
52935 @@ -2221,7 +2633,7 @@ unsigned long do_brk(unsigned long addr,
52936 */
52937 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
52938 if (!vma) {
52939 - vm_unacct_memory(len >> PAGE_SHIFT);
52940 + vm_unacct_memory(charged);
52941 return -ENOMEM;
52942 }
52943
52944 @@ -2235,11 +2647,12 @@ unsigned long do_brk(unsigned long addr,
52945 vma_link(mm, vma, prev, rb_link, rb_parent);
52946 out:
52947 perf_event_mmap(vma);
52948 - mm->total_vm += len >> PAGE_SHIFT;
52949 + mm->total_vm += charged;
52950 if (flags & VM_LOCKED) {
52951 if (!mlock_vma_pages_range(vma, addr, addr + len))
52952 - mm->locked_vm += (len >> PAGE_SHIFT);
52953 + mm->locked_vm += charged;
52954 }
52955 + track_exec_limit(mm, addr, addr + len, flags);
52956 return addr;
52957 }
52958
52959 @@ -2286,8 +2699,10 @@ void exit_mmap(struct mm_struct *mm)
52960 * Walk the list again, actually closing and freeing it,
52961 * with preemption enabled, without holding any MM locks.
52962 */
52963 - while (vma)
52964 + while (vma) {
52965 + vma->vm_mirror = NULL;
52966 vma = remove_vma(vma);
52967 + }
52968
52969 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
52970 }
52971 @@ -2301,6 +2716,10 @@ int insert_vm_struct(struct mm_struct *
52972 struct vm_area_struct * __vma, * prev;
52973 struct rb_node ** rb_link, * rb_parent;
52974
52975 +#ifdef CONFIG_PAX_SEGMEXEC
52976 + struct vm_area_struct *vma_m = NULL;
52977 +#endif
52978 +
52979 /*
52980 * The vm_pgoff of a purely anonymous vma should be irrelevant
52981 * until its first write fault, when page's anon_vma and index
52982 @@ -2323,7 +2742,22 @@ int insert_vm_struct(struct mm_struct *
52983 if ((vma->vm_flags & VM_ACCOUNT) &&
52984 security_vm_enough_memory_mm(mm, vma_pages(vma)))
52985 return -ENOMEM;
52986 +
52987 +#ifdef CONFIG_PAX_SEGMEXEC
52988 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
52989 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
52990 + if (!vma_m)
52991 + return -ENOMEM;
52992 + }
52993 +#endif
52994 +
52995 vma_link(mm, vma, prev, rb_link, rb_parent);
52996 +
52997 +#ifdef CONFIG_PAX_SEGMEXEC
52998 + if (vma_m)
52999 + BUG_ON(pax_mirror_vma(vma_m, vma));
53000 +#endif
53001 +
53002 return 0;
53003 }
53004
53005 @@ -2341,6 +2775,8 @@ struct vm_area_struct *copy_vma(struct v
53006 struct rb_node **rb_link, *rb_parent;
53007 struct mempolicy *pol;
53008
53009 + BUG_ON(vma->vm_mirror);
53010 +
53011 /*
53012 * If anonymous vma has not yet been faulted, update new pgoff
53013 * to match new location, to increase its chance of merging.
53014 @@ -2390,6 +2826,39 @@ struct vm_area_struct *copy_vma(struct v
53015 kmem_cache_free(vm_area_cachep, new_vma);
53016 return NULL;
53017 }
53018 +
53019 +#ifdef CONFIG_PAX_SEGMEXEC
53020 +long pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
53021 +{
53022 + struct vm_area_struct *prev_m;
53023 + struct rb_node **rb_link_m, *rb_parent_m;
53024 + struct mempolicy *pol_m;
53025 +
53026 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
53027 + BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
53028 + BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
53029 + *vma_m = *vma;
53030 + INIT_LIST_HEAD(&vma_m->anon_vma_chain);
53031 + if (anon_vma_clone(vma_m, vma))
53032 + return -ENOMEM;
53033 + pol_m = vma_policy(vma_m);
53034 + mpol_get(pol_m);
53035 + vma_set_policy(vma_m, pol_m);
53036 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
53037 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
53038 + vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
53039 + vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
53040 + if (vma_m->vm_file)
53041 + get_file(vma_m->vm_file);
53042 + if (vma_m->vm_ops && vma_m->vm_ops->open)
53043 + vma_m->vm_ops->open(vma_m);
53044 + find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
53045 + vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
53046 + vma_m->vm_mirror = vma;
53047 + vma->vm_mirror = vma_m;
53048 + return 0;
53049 +}
53050 +#endif
53051
53052 /*
53053 * Return true if the calling process may expand its vm space by the passed
53054 @@ -2401,7 +2870,7 @@ int may_expand_vm(struct mm_struct *mm,
53055 unsigned long lim;
53056
53057 lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT;
53058 -
53059 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
53060 if (cur + npages > lim)
53061 return 0;
53062 return 1;
53063 @@ -2471,6 +2940,17 @@ int install_special_mapping(struct mm_st
53064 vma->vm_start = addr;
53065 vma->vm_end = addr + len;
53066
53067 +#ifdef CONFIG_PAX_MPROTECT
53068 + if (mm->pax_flags & MF_PAX_MPROTECT) {
53069 + if ((vm_flags & (VM_WRITE | VM_EXEC)) == (VM_WRITE | VM_EXEC))
53070 + return -EPERM;
53071 + if (!(vm_flags & VM_EXEC))
53072 + vm_flags &= ~VM_MAYEXEC;
53073 + else
53074 + vm_flags &= ~VM_MAYWRITE;
53075 + }
53076 +#endif
53077 +
53078 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
53079 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
53080
53081 diff -urNp linux-2.6.36/mm/mprotect.c linux-2.6.36/mm/mprotect.c
53082 --- linux-2.6.36/mm/mprotect.c 2010-10-20 16:30:22.000000000 -0400
53083 +++ linux-2.6.36/mm/mprotect.c 2010-11-06 18:58:50.000000000 -0400
53084 @@ -23,10 +23,16 @@
53085 #include <linux/mmu_notifier.h>
53086 #include <linux/migrate.h>
53087 #include <linux/perf_event.h>
53088 +
53089 +#ifdef CONFIG_PAX_MPROTECT
53090 +#include <linux/elf.h>
53091 +#endif
53092 +
53093 #include <asm/uaccess.h>
53094 #include <asm/pgtable.h>
53095 #include <asm/cacheflush.h>
53096 #include <asm/tlbflush.h>
53097 +#include <asm/mmu_context.h>
53098
53099 #ifndef pgprot_modify
53100 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
53101 @@ -131,6 +137,48 @@ static void change_protection(struct vm_
53102 flush_tlb_range(vma, start, end);
53103 }
53104
53105 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
53106 +/* called while holding the mmap semaphor for writing except stack expansion */
53107 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
53108 +{
53109 + unsigned long oldlimit, newlimit = 0UL;
53110 +
53111 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || (__supported_pte_mask & _PAGE_NX))
53112 + return;
53113 +
53114 + spin_lock(&mm->page_table_lock);
53115 + oldlimit = mm->context.user_cs_limit;
53116 + if ((prot & VM_EXEC) && oldlimit < end)
53117 + /* USER_CS limit moved up */
53118 + newlimit = end;
53119 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
53120 + /* USER_CS limit moved down */
53121 + newlimit = start;
53122 +
53123 + if (newlimit) {
53124 + mm->context.user_cs_limit = newlimit;
53125 +
53126 +#ifdef CONFIG_SMP
53127 + wmb();
53128 + cpus_clear(mm->context.cpu_user_cs_mask);
53129 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
53130 +#endif
53131 +
53132 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
53133 + }
53134 + spin_unlock(&mm->page_table_lock);
53135 + if (newlimit == end) {
53136 + struct vm_area_struct *vma = find_vma(mm, oldlimit);
53137 +
53138 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
53139 + if (is_vm_hugetlb_page(vma))
53140 + hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
53141 + else
53142 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
53143 + }
53144 +}
53145 +#endif
53146 +
53147 int
53148 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
53149 unsigned long start, unsigned long end, unsigned long newflags)
53150 @@ -143,11 +191,29 @@ mprotect_fixup(struct vm_area_struct *vm
53151 int error;
53152 int dirty_accountable = 0;
53153
53154 +#ifdef CONFIG_PAX_SEGMEXEC
53155 + struct vm_area_struct *vma_m = NULL;
53156 + unsigned long start_m, end_m;
53157 +
53158 + start_m = start + SEGMEXEC_TASK_SIZE;
53159 + end_m = end + SEGMEXEC_TASK_SIZE;
53160 +#endif
53161 +
53162 if (newflags == oldflags) {
53163 *pprev = vma;
53164 return 0;
53165 }
53166
53167 + if (newflags & (VM_READ | VM_WRITE | VM_EXEC)) {
53168 + struct vm_area_struct *prev = vma->vm_prev, *next = vma->vm_next;
53169 +
53170 + if (next && (next->vm_flags & VM_GROWSDOWN) && sysctl_heap_stack_gap > next->vm_start - end)
53171 + return -ENOMEM;
53172 +
53173 + if (prev && (prev->vm_flags & VM_GROWSUP) && sysctl_heap_stack_gap > start - prev->vm_end)
53174 + return -ENOMEM;
53175 + }
53176 +
53177 /*
53178 * If we make a private mapping writable we increase our commit;
53179 * but (without finer accounting) cannot reduce our commit if we
53180 @@ -164,6 +230,42 @@ mprotect_fixup(struct vm_area_struct *vm
53181 }
53182 }
53183
53184 +#ifdef CONFIG_PAX_SEGMEXEC
53185 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
53186 + if (start != vma->vm_start) {
53187 + error = split_vma(mm, vma, start, 1);
53188 + if (error)
53189 + goto fail;
53190 + BUG_ON(!*pprev || (*pprev)->vm_next == vma);
53191 + *pprev = (*pprev)->vm_next;
53192 + }
53193 +
53194 + if (end != vma->vm_end) {
53195 + error = split_vma(mm, vma, end, 0);
53196 + if (error)
53197 + goto fail;
53198 + }
53199 +
53200 + if (pax_find_mirror_vma(vma)) {
53201 + error = __do_munmap(mm, start_m, end_m - start_m);
53202 + if (error)
53203 + goto fail;
53204 + } else {
53205 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
53206 + if (!vma_m) {
53207 + error = -ENOMEM;
53208 + goto fail;
53209 + }
53210 + vma->vm_flags = newflags;
53211 + error = pax_mirror_vma(vma_m, vma);
53212 + if (error) {
53213 + vma->vm_flags = oldflags;
53214 + goto fail;
53215 + }
53216 + }
53217 + }
53218 +#endif
53219 +
53220 /*
53221 * First try to merge with previous and/or next vma.
53222 */
53223 @@ -194,9 +296,21 @@ success:
53224 * vm_flags and vm_page_prot are protected by the mmap_sem
53225 * held in write mode.
53226 */
53227 +
53228 +#ifdef CONFIG_PAX_SEGMEXEC
53229 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (newflags & VM_EXEC) && ((vma->vm_flags ^ newflags) & VM_READ))
53230 + pax_find_mirror_vma(vma)->vm_flags ^= VM_READ;
53231 +#endif
53232 +
53233 vma->vm_flags = newflags;
53234 +
53235 +#ifdef CONFIG_PAX_MPROTECT
53236 + if (mm->binfmt && mm->binfmt->handle_mprotect)
53237 + mm->binfmt->handle_mprotect(vma, newflags);
53238 +#endif
53239 +
53240 vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
53241 - vm_get_page_prot(newflags));
53242 + vm_get_page_prot(vma->vm_flags));
53243
53244 if (vma_wants_writenotify(vma)) {
53245 vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
53246 @@ -237,6 +351,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
53247 end = start + len;
53248 if (end <= start)
53249 return -ENOMEM;
53250 +
53251 +#ifdef CONFIG_PAX_SEGMEXEC
53252 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
53253 + if (end > SEGMEXEC_TASK_SIZE)
53254 + return -EINVAL;
53255 + } else
53256 +#endif
53257 +
53258 + if (end > TASK_SIZE)
53259 + return -EINVAL;
53260 +
53261 if (!arch_validate_prot(prot))
53262 return -EINVAL;
53263
53264 @@ -244,7 +369,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
53265 /*
53266 * Does the application expect PROT_READ to imply PROT_EXEC:
53267 */
53268 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
53269 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
53270 prot |= PROT_EXEC;
53271
53272 vm_flags = calc_vm_prot_bits(prot);
53273 @@ -276,6 +401,11 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
53274 if (start > vma->vm_start)
53275 prev = vma;
53276
53277 +#ifdef CONFIG_PAX_MPROTECT
53278 + if (current->mm->binfmt && current->mm->binfmt->handle_mprotect)
53279 + current->mm->binfmt->handle_mprotect(vma, vm_flags);
53280 +#endif
53281 +
53282 for (nstart = start ; ; ) {
53283 unsigned long newflags;
53284
53285 @@ -285,6 +415,14 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
53286
53287 /* newflags >> 4 shift VM_MAY% in place of VM_% */
53288 if ((newflags & ~(newflags >> 4)) & (VM_READ | VM_WRITE | VM_EXEC)) {
53289 + if (prot & (PROT_WRITE | PROT_EXEC))
53290 + gr_log_rwxmprotect(vma->vm_file);
53291 +
53292 + error = -EACCES;
53293 + goto out;
53294 + }
53295 +
53296 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
53297 error = -EACCES;
53298 goto out;
53299 }
53300 @@ -300,6 +438,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
53301 if (error)
53302 goto out;
53303 perf_event_mmap(vma);
53304 +
53305 + track_exec_limit(current->mm, nstart, tmp, vm_flags);
53306 +
53307 nstart = tmp;
53308
53309 if (nstart < prev->vm_end)
53310 diff -urNp linux-2.6.36/mm/mremap.c linux-2.6.36/mm/mremap.c
53311 --- linux-2.6.36/mm/mremap.c 2010-10-20 16:30:22.000000000 -0400
53312 +++ linux-2.6.36/mm/mremap.c 2010-11-06 18:58:15.000000000 -0400
53313 @@ -113,6 +113,12 @@ static void move_ptes(struct vm_area_str
53314 continue;
53315 pte = ptep_clear_flush(vma, old_addr, old_pte);
53316 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
53317 +
53318 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
53319 + if (!(__supported_pte_mask & _PAGE_NX) && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
53320 + pte = pte_exprotect(pte);
53321 +#endif
53322 +
53323 set_pte_at(mm, new_addr, new_pte, pte);
53324 }
53325
53326 @@ -272,6 +278,11 @@ static struct vm_area_struct *vma_to_res
53327 if (is_vm_hugetlb_page(vma))
53328 goto Einval;
53329
53330 +#ifdef CONFIG_PAX_SEGMEXEC
53331 + if (pax_find_mirror_vma(vma))
53332 + goto Einval;
53333 +#endif
53334 +
53335 /* We can't remap across vm area boundaries */
53336 if (old_len > vma->vm_end - addr)
53337 goto Efault;
53338 @@ -321,20 +332,25 @@ static unsigned long mremap_to(unsigned
53339 unsigned long ret = -EINVAL;
53340 unsigned long charged = 0;
53341 unsigned long map_flags;
53342 + unsigned long pax_task_size = TASK_SIZE;
53343
53344 if (new_addr & ~PAGE_MASK)
53345 goto out;
53346
53347 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
53348 +#ifdef CONFIG_PAX_SEGMEXEC
53349 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
53350 + pax_task_size = SEGMEXEC_TASK_SIZE;
53351 +#endif
53352 +
53353 + pax_task_size -= PAGE_SIZE;
53354 +
53355 + if (new_len > TASK_SIZE || new_addr > pax_task_size - new_len)
53356 goto out;
53357
53358 /* Check if the location we're moving into overlaps the
53359 * old location at all, and fail if it does.
53360 */
53361 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
53362 - goto out;
53363 -
53364 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
53365 + if (addr + old_len > new_addr && new_addr + new_len > addr)
53366 goto out;
53367
53368 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
53369 @@ -406,6 +422,7 @@ unsigned long do_mremap(unsigned long ad
53370 struct vm_area_struct *vma;
53371 unsigned long ret = -EINVAL;
53372 unsigned long charged = 0;
53373 + unsigned long pax_task_size = TASK_SIZE;
53374
53375 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
53376 goto out;
53377 @@ -424,6 +441,17 @@ unsigned long do_mremap(unsigned long ad
53378 if (!new_len)
53379 goto out;
53380
53381 +#ifdef CONFIG_PAX_SEGMEXEC
53382 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
53383 + pax_task_size = SEGMEXEC_TASK_SIZE;
53384 +#endif
53385 +
53386 + pax_task_size -= PAGE_SIZE;
53387 +
53388 + if (new_len > pax_task_size || addr > pax_task_size-new_len ||
53389 + old_len > pax_task_size || addr > pax_task_size-old_len)
53390 + goto out;
53391 +
53392 if (flags & MREMAP_FIXED) {
53393 if (flags & MREMAP_MAYMOVE)
53394 ret = mremap_to(addr, old_len, new_addr, new_len);
53395 @@ -473,6 +501,7 @@ unsigned long do_mremap(unsigned long ad
53396 addr + new_len);
53397 }
53398 ret = addr;
53399 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
53400 goto out;
53401 }
53402 }
53403 @@ -499,7 +528,13 @@ unsigned long do_mremap(unsigned long ad
53404 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
53405 if (ret)
53406 goto out;
53407 +
53408 + map_flags = vma->vm_flags;
53409 ret = move_vma(vma, addr, old_len, new_len, new_addr);
53410 + if (!(ret & ~PAGE_MASK)) {
53411 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
53412 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
53413 + }
53414 }
53415 out:
53416 if (ret & ~PAGE_MASK)
53417 diff -urNp linux-2.6.36/mm/nommu.c linux-2.6.36/mm/nommu.c
53418 --- linux-2.6.36/mm/nommu.c 2010-10-20 16:30:22.000000000 -0400
53419 +++ linux-2.6.36/mm/nommu.c 2010-11-06 18:58:15.000000000 -0400
53420 @@ -62,7 +62,6 @@ int sysctl_overcommit_memory = OVERCOMMI
53421 int sysctl_overcommit_ratio = 50; /* default is 50% */
53422 int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
53423 int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
53424 -int heap_stack_gap = 0;
53425
53426 atomic_long_t mmap_pages_allocated;
53427
53428 @@ -757,15 +756,6 @@ struct vm_area_struct *find_vma(struct m
53429 EXPORT_SYMBOL(find_vma);
53430
53431 /*
53432 - * find a VMA
53433 - * - we don't extend stack VMAs under NOMMU conditions
53434 - */
53435 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
53436 -{
53437 - return find_vma(mm, addr);
53438 -}
53439 -
53440 -/*
53441 * expand a stack to a given address
53442 * - not supported under NOMMU conditions
53443 */
53444 @@ -1486,6 +1476,7 @@ int split_vma(struct mm_struct *mm, stru
53445
53446 /* most fields are the same, copy all, and then fixup */
53447 *new = *vma;
53448 + INIT_LIST_HEAD(&new->anon_vma_chain);
53449 *region = *vma->vm_region;
53450 new->vm_region = region;
53451
53452 diff -urNp linux-2.6.36/mm/page_alloc.c linux-2.6.36/mm/page_alloc.c
53453 --- linux-2.6.36/mm/page_alloc.c 2010-10-20 16:30:22.000000000 -0400
53454 +++ linux-2.6.36/mm/page_alloc.c 2010-11-06 18:58:15.000000000 -0400
53455 @@ -642,6 +642,10 @@ static bool free_pages_prepare(struct pa
53456 int i;
53457 int bad = 0;
53458
53459 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
53460 + unsigned long index = 1UL << order;
53461 +#endif
53462 +
53463 trace_mm_page_free_direct(page, order);
53464 kmemcheck_free_shadow(page, order);
53465
53466 @@ -660,6 +664,12 @@ static bool free_pages_prepare(struct pa
53467 debug_check_no_obj_freed(page_address(page),
53468 PAGE_SIZE << order);
53469 }
53470 +
53471 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
53472 + for (; index; --index)
53473 + sanitize_highpage(page + index - 1);
53474 +#endif
53475 +
53476 arch_free_page(page, order);
53477 kernel_map_pages(page, 1 << order, 0);
53478
53479 @@ -774,8 +784,10 @@ static int prep_new_page(struct page *pa
53480 arch_alloc_page(page, order);
53481 kernel_map_pages(page, 1 << order, 1);
53482
53483 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
53484 if (gfp_flags & __GFP_ZERO)
53485 prep_zero_page(page, order, gfp_flags);
53486 +#endif
53487
53488 if (order && (gfp_flags & __GFP_COMP))
53489 prep_compound_page(page, order);
53490 @@ -3997,7 +4009,7 @@ static void __init setup_usemap(struct p
53491 zone->pageblock_flags = alloc_bootmem_node(pgdat, usemapsize);
53492 }
53493 #else
53494 -static void inline setup_usemap(struct pglist_data *pgdat,
53495 +static inline void setup_usemap(struct pglist_data *pgdat,
53496 struct zone *zone, unsigned long zonesize) {}
53497 #endif /* CONFIG_SPARSEMEM */
53498
53499 diff -urNp linux-2.6.36/mm/percpu.c linux-2.6.36/mm/percpu.c
53500 --- linux-2.6.36/mm/percpu.c 2010-10-20 16:30:22.000000000 -0400
53501 +++ linux-2.6.36/mm/percpu.c 2010-11-06 18:58:15.000000000 -0400
53502 @@ -115,7 +115,7 @@ static unsigned int pcpu_first_unit_cpu
53503 static unsigned int pcpu_last_unit_cpu __read_mostly;
53504
53505 /* the address of the first chunk which starts with the kernel static area */
53506 -void *pcpu_base_addr __read_mostly;
53507 +void *pcpu_base_addr __read_only;
53508 EXPORT_SYMBOL_GPL(pcpu_base_addr);
53509
53510 static const int *pcpu_unit_map __read_mostly; /* cpu -> unit */
53511 diff -urNp linux-2.6.36/mm/rmap.c linux-2.6.36/mm/rmap.c
53512 --- linux-2.6.36/mm/rmap.c 2010-10-20 16:30:22.000000000 -0400
53513 +++ linux-2.6.36/mm/rmap.c 2010-11-06 18:58:15.000000000 -0400
53514 @@ -117,6 +117,10 @@ int anon_vma_prepare(struct vm_area_stru
53515 struct anon_vma *anon_vma = vma->anon_vma;
53516 struct anon_vma_chain *avc;
53517
53518 +#ifdef CONFIG_PAX_SEGMEXEC
53519 + struct anon_vma_chain *avc_m = NULL;
53520 +#endif
53521 +
53522 might_sleep();
53523 if (unlikely(!anon_vma)) {
53524 struct mm_struct *mm = vma->vm_mm;
53525 @@ -126,6 +130,12 @@ int anon_vma_prepare(struct vm_area_stru
53526 if (!avc)
53527 goto out_enomem;
53528
53529 +#ifdef CONFIG_PAX_SEGMEXEC
53530 + avc_m = anon_vma_chain_alloc();
53531 + if (!avc_m)
53532 + goto out_enomem_free_avc;
53533 +#endif
53534 +
53535 anon_vma = find_mergeable_anon_vma(vma);
53536 allocated = NULL;
53537 if (!anon_vma) {
53538 @@ -144,6 +154,21 @@ int anon_vma_prepare(struct vm_area_stru
53539 /* page_table_lock to protect against threads */
53540 spin_lock(&mm->page_table_lock);
53541 if (likely(!vma->anon_vma)) {
53542 +
53543 +#ifdef CONFIG_PAX_SEGMEXEC
53544 + struct vm_area_struct *vma_m = pax_find_mirror_vma(vma);
53545 +
53546 + if (vma_m) {
53547 + BUG_ON(vma_m->anon_vma);
53548 + vma_m->anon_vma = anon_vma;
53549 + avc_m->anon_vma = anon_vma;
53550 + avc_m->vma = vma;
53551 + list_add(&avc_m->same_vma, &vma_m->anon_vma_chain);
53552 + list_add(&avc_m->same_anon_vma, &anon_vma->head);
53553 + avc_m = NULL;
53554 + }
53555 +#endif
53556 +
53557 vma->anon_vma = anon_vma;
53558 avc->anon_vma = anon_vma;
53559 avc->vma = vma;
53560 @@ -157,12 +182,24 @@ int anon_vma_prepare(struct vm_area_stru
53561
53562 if (unlikely(allocated))
53563 anon_vma_free(allocated);
53564 +
53565 +#ifdef CONFIG_PAX_SEGMEXEC
53566 + if (unlikely(avc_m))
53567 + anon_vma_chain_free(avc_m);
53568 +#endif
53569 +
53570 if (unlikely(avc))
53571 anon_vma_chain_free(avc);
53572 }
53573 return 0;
53574
53575 out_enomem_free_avc:
53576 +
53577 +#ifdef CONFIG_PAX_SEGMEXEC
53578 + if (avc_m)
53579 + anon_vma_chain_free(avc_m);
53580 +#endif
53581 +
53582 anon_vma_chain_free(avc);
53583 out_enomem:
53584 return -ENOMEM;
53585 @@ -185,7 +222,7 @@ static void anon_vma_chain_link(struct v
53586 * Attach the anon_vmas from src to dst.
53587 * Returns 0 on success, -ENOMEM on failure.
53588 */
53589 -int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
53590 +int anon_vma_clone(struct vm_area_struct *dst, const struct vm_area_struct *src)
53591 {
53592 struct anon_vma_chain *avc, *pavc;
53593
53594 @@ -207,7 +244,7 @@ int anon_vma_clone(struct vm_area_struct
53595 * the corresponding VMA in the parent process is attached to.
53596 * Returns 0 on success, non-zero on failure.
53597 */
53598 -int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
53599 +int anon_vma_fork(struct vm_area_struct *vma, const struct vm_area_struct *pvma)
53600 {
53601 struct anon_vma_chain *avc;
53602 struct anon_vma *anon_vma;
53603 diff -urNp linux-2.6.36/mm/shmem.c linux-2.6.36/mm/shmem.c
53604 --- linux-2.6.36/mm/shmem.c 2010-10-20 16:30:22.000000000 -0400
53605 +++ linux-2.6.36/mm/shmem.c 2010-11-06 19:42:24.000000000 -0400
53606 @@ -31,7 +31,7 @@
53607 #include <linux/percpu_counter.h>
53608 #include <linux/swap.h>
53609
53610 -static struct vfsmount *shm_mnt;
53611 +struct vfsmount *shm_mnt;
53612
53613 #ifdef CONFIG_SHMEM
53614 /*
53615 diff -urNp linux-2.6.36/mm/slab.c linux-2.6.36/mm/slab.c
53616 --- linux-2.6.36/mm/slab.c 2010-10-20 16:30:22.000000000 -0400
53617 +++ linux-2.6.36/mm/slab.c 2010-11-06 18:58:50.000000000 -0400
53618 @@ -284,7 +284,7 @@ struct kmem_list3 {
53619 * Need this for bootstrapping a per node allocator.
53620 */
53621 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
53622 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
53623 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
53624 #define CACHE_CACHE 0
53625 #define SIZE_AC MAX_NUMNODES
53626 #define SIZE_L3 (2 * MAX_NUMNODES)
53627 @@ -534,7 +534,7 @@ static inline void *index_to_obj(struct
53628 * reciprocal_divide(offset, cache->reciprocal_buffer_size)
53629 */
53630 static inline unsigned int obj_to_index(const struct kmem_cache *cache,
53631 - const struct slab *slab, void *obj)
53632 + const struct slab *slab, const void *obj)
53633 {
53634 u32 offset = (obj - slab->s_mem);
53635 return reciprocal_divide(offset, cache->reciprocal_buffer_size);
53636 @@ -560,14 +560,14 @@ struct cache_names {
53637 static struct cache_names __initdata cache_names[] = {
53638 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
53639 #include <linux/kmalloc_sizes.h>
53640 - {NULL,}
53641 + {NULL, NULL}
53642 #undef CACHE
53643 };
53644
53645 static struct arraycache_init initarray_cache __initdata =
53646 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
53647 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
53648 static struct arraycache_init initarray_generic =
53649 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
53650 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
53651
53652 /* internal cache of cache description objs */
53653 static struct kmem_cache cache_cache = {
53654 @@ -4557,15 +4557,66 @@ static const struct file_operations proc
53655
53656 static int __init slab_proc_init(void)
53657 {
53658 - proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
53659 + mode_t gr_mode = S_IRUGO;
53660 +
53661 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
53662 + gr_mode = S_IRUSR;
53663 +#endif
53664 +
53665 + proc_create("slabinfo",S_IWUSR|gr_mode,NULL,&proc_slabinfo_operations);
53666 #ifdef CONFIG_DEBUG_SLAB_LEAK
53667 - proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
53668 + proc_create("slab_allocators", gr_mode, NULL, &proc_slabstats_operations);
53669 #endif
53670 return 0;
53671 }
53672 module_init(slab_proc_init);
53673 #endif
53674
53675 +void check_object_size(const void *ptr, unsigned long n, bool to)
53676 +{
53677 +
53678 +#ifdef CONFIG_PAX_USERCOPY
53679 + struct kmem_cache *cachep;
53680 + struct slab *slabp;
53681 + struct page *page;
53682 + unsigned int objnr;
53683 + unsigned long offset;
53684 +
53685 + if (!n)
53686 + return;
53687 +
53688 + if (ZERO_OR_NULL_PTR(ptr))
53689 + goto report;
53690 +
53691 + if (!virt_addr_valid(ptr))
53692 + return;
53693 +
53694 + page = virt_to_head_page(ptr);
53695 +
53696 + if (!PageSlab(page)) {
53697 + if (object_is_on_stack(ptr, n) == -1)
53698 + goto report;
53699 + return;
53700 + }
53701 +
53702 + cachep = page_get_cache(page);
53703 + slabp = page_get_slab(page);
53704 + objnr = obj_to_index(cachep, slabp, ptr);
53705 + BUG_ON(objnr >= cachep->num);
53706 + offset = ptr - index_to_obj(cachep, slabp, objnr) - obj_offset(cachep);
53707 + if (offset <= obj_size(cachep) && n <= obj_size(cachep) - offset)
53708 + return;
53709 +
53710 +report:
53711 + if (to)
53712 + pax_report_leak_to_user(ptr, n);
53713 + else
53714 + pax_report_overflow_from_user(ptr, n);
53715 +#endif
53716 +
53717 +}
53718 +EXPORT_SYMBOL(check_object_size);
53719 +
53720 /**
53721 * ksize - get the actual amount of memory allocated for a given object
53722 * @objp: Pointer to the object
53723 diff -urNp linux-2.6.36/mm/slob.c linux-2.6.36/mm/slob.c
53724 --- linux-2.6.36/mm/slob.c 2010-10-20 16:30:22.000000000 -0400
53725 +++ linux-2.6.36/mm/slob.c 2010-11-06 18:58:15.000000000 -0400
53726 @@ -29,7 +29,7 @@
53727 * If kmalloc is asked for objects of PAGE_SIZE or larger, it calls
53728 * alloc_pages() directly, allocating compound pages so the page order
53729 * does not have to be separately tracked, and also stores the exact
53730 - * allocation size in page->private so that it can be used to accurately
53731 + * allocation size in slob_page->size so that it can be used to accurately
53732 * provide ksize(). These objects are detected in kfree() because slob_page()
53733 * is false for them.
53734 *
53735 @@ -58,6 +58,7 @@
53736 */
53737
53738 #include <linux/kernel.h>
53739 +#include <linux/sched.h>
53740 #include <linux/slab.h>
53741 #include <linux/mm.h>
53742 #include <linux/swap.h> /* struct reclaim_state */
53743 @@ -102,7 +103,8 @@ struct slob_page {
53744 unsigned long flags; /* mandatory */
53745 atomic_t _count; /* mandatory */
53746 slobidx_t units; /* free units left in page */
53747 - unsigned long pad[2];
53748 + unsigned long pad[1];
53749 + unsigned long size; /* size when >=PAGE_SIZE */
53750 slob_t *free; /* first free slob_t in page */
53751 struct list_head list; /* linked list of free pages */
53752 };
53753 @@ -135,7 +137,7 @@ static LIST_HEAD(free_slob_large);
53754 */
53755 static inline int is_slob_page(struct slob_page *sp)
53756 {
53757 - return PageSlab((struct page *)sp);
53758 + return PageSlab((struct page *)sp) && !sp->size;
53759 }
53760
53761 static inline void set_slob_page(struct slob_page *sp)
53762 @@ -150,7 +152,7 @@ static inline void clear_slob_page(struc
53763
53764 static inline struct slob_page *slob_page(const void *addr)
53765 {
53766 - return (struct slob_page *)virt_to_page(addr);
53767 + return (struct slob_page *)virt_to_head_page(addr);
53768 }
53769
53770 /*
53771 @@ -210,7 +212,7 @@ static void set_slob(slob_t *s, slobidx_
53772 /*
53773 * Return the size of a slob block.
53774 */
53775 -static slobidx_t slob_units(slob_t *s)
53776 +static slobidx_t slob_units(const slob_t *s)
53777 {
53778 if (s->units > 0)
53779 return s->units;
53780 @@ -220,7 +222,7 @@ static slobidx_t slob_units(slob_t *s)
53781 /*
53782 * Return the next free slob block pointer after this one.
53783 */
53784 -static slob_t *slob_next(slob_t *s)
53785 +static slob_t *slob_next(const slob_t *s)
53786 {
53787 slob_t *base = (slob_t *)((unsigned long)s & PAGE_MASK);
53788 slobidx_t next;
53789 @@ -235,7 +237,7 @@ static slob_t *slob_next(slob_t *s)
53790 /*
53791 * Returns true if s is the last free block in its page.
53792 */
53793 -static int slob_last(slob_t *s)
53794 +static int slob_last(const slob_t *s)
53795 {
53796 return !((unsigned long)slob_next(s) & ~PAGE_MASK);
53797 }
53798 @@ -254,6 +256,7 @@ static void *slob_new_pages(gfp_t gfp, i
53799 if (!page)
53800 return NULL;
53801
53802 + set_slob_page(page);
53803 return page_address(page);
53804 }
53805
53806 @@ -370,11 +373,11 @@ static void *slob_alloc(size_t size, gfp
53807 if (!b)
53808 return NULL;
53809 sp = slob_page(b);
53810 - set_slob_page(sp);
53811
53812 spin_lock_irqsave(&slob_lock, flags);
53813 sp->units = SLOB_UNITS(PAGE_SIZE);
53814 sp->free = b;
53815 + sp->size = 0;
53816 INIT_LIST_HEAD(&sp->list);
53817 set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
53818 set_slob_page_free(sp, slob_list);
53819 @@ -476,10 +479,9 @@ out:
53820 * End of slob allocator proper. Begin kmem_cache_alloc and kmalloc frontend.
53821 */
53822
53823 -void *__kmalloc_node(size_t size, gfp_t gfp, int node)
53824 +static void *__kmalloc_node_align(size_t size, gfp_t gfp, int node, int align)
53825 {
53826 - unsigned int *m;
53827 - int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
53828 + slob_t *m;
53829 void *ret;
53830
53831 lockdep_trace_alloc(gfp);
53832 @@ -492,7 +494,10 @@ void *__kmalloc_node(size_t size, gfp_t
53833
53834 if (!m)
53835 return NULL;
53836 - *m = size;
53837 + BUILD_BUG_ON(ARCH_KMALLOC_MINALIGN < 2 * SLOB_UNIT);
53838 + BUILD_BUG_ON(ARCH_SLAB_MINALIGN < 2 * SLOB_UNIT);
53839 + m[0].units = size;
53840 + m[1].units = align;
53841 ret = (void *)m + align;
53842
53843 trace_kmalloc_node(_RET_IP_, ret,
53844 @@ -502,9 +507,9 @@ void *__kmalloc_node(size_t size, gfp_t
53845
53846 ret = slob_new_pages(gfp | __GFP_COMP, get_order(size), node);
53847 if (ret) {
53848 - struct page *page;
53849 - page = virt_to_page(ret);
53850 - page->private = size;
53851 + struct slob_page *sp;
53852 + sp = slob_page(ret);
53853 + sp->size = size;
53854 }
53855
53856 trace_kmalloc_node(_RET_IP_, ret,
53857 @@ -514,6 +519,13 @@ void *__kmalloc_node(size_t size, gfp_t
53858 kmemleak_alloc(ret, size, 1, gfp);
53859 return ret;
53860 }
53861 +
53862 +void *__kmalloc_node(size_t size, gfp_t gfp, int node)
53863 +{
53864 + int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
53865 +
53866 + return __kmalloc_node_align(size, gfp, node, align);
53867 +}
53868 EXPORT_SYMBOL(__kmalloc_node);
53869
53870 void kfree(const void *block)
53871 @@ -529,13 +541,84 @@ void kfree(const void *block)
53872 sp = slob_page(block);
53873 if (is_slob_page(sp)) {
53874 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
53875 - unsigned int *m = (unsigned int *)(block - align);
53876 - slob_free(m, *m + align);
53877 - } else
53878 + slob_t *m = (slob_t *)(block - align);
53879 + slob_free(m, m[0].units + align);
53880 + } else {
53881 + clear_slob_page(sp);
53882 + free_slob_page(sp);
53883 + sp->size = 0;
53884 put_page(&sp->page);
53885 + }
53886 }
53887 EXPORT_SYMBOL(kfree);
53888
53889 +void check_object_size(const void *ptr, unsigned long n, bool to)
53890 +{
53891 +
53892 +#ifdef CONFIG_PAX_USERCOPY
53893 + struct slob_page *sp;
53894 + const slob_t *free;
53895 + const void *base;
53896 +
53897 + if (!n)
53898 + return;
53899 +
53900 + if (ZERO_OR_NULL_PTR(ptr))
53901 + goto report;
53902 +
53903 + if (!virt_addr_valid(ptr))
53904 + return;
53905 +
53906 + sp = slob_page(ptr);
53907 + if (!PageSlab((struct page*)sp)) {
53908 + if (object_is_on_stack(ptr, n) == -1)
53909 + goto report;
53910 + return;
53911 + }
53912 +
53913 + if (sp->size) {
53914 + base = page_address(&sp->page);
53915 + if (base <= ptr && n <= sp->size - (ptr - base))
53916 + return;
53917 + goto report;
53918 + }
53919 +
53920 + /* some tricky double walking to find the chunk */
53921 + base = (void *)((unsigned long)ptr & PAGE_MASK);
53922 + free = sp->free;
53923 +
53924 + while (!slob_last(free) && (void *)free <= ptr) {
53925 + base = free + slob_units(free);
53926 + free = slob_next(free);
53927 + }
53928 +
53929 + while (base < (void *)free) {
53930 + slobidx_t m = ((slob_t *)base)[0].units, align = ((slob_t *)base)[1].units;
53931 + int size = SLOB_UNIT * SLOB_UNITS(m + align);
53932 + int offset;
53933 +
53934 + if (ptr < base + align)
53935 + goto report;
53936 +
53937 + offset = ptr - base - align;
53938 + if (offset < m) {
53939 + if (n <= m - offset)
53940 + return;
53941 + goto report;
53942 + }
53943 + base += size;
53944 + }
53945 +
53946 +report:
53947 + if (to)
53948 + pax_report_leak_to_user(ptr, n);
53949 + else
53950 + pax_report_overflow_from_user(ptr, n);
53951 +#endif
53952 +
53953 +}
53954 +EXPORT_SYMBOL(check_object_size);
53955 +
53956 /* can't use ksize for kmem_cache_alloc memory, only kmalloc */
53957 size_t ksize(const void *block)
53958 {
53959 @@ -548,10 +631,10 @@ size_t ksize(const void *block)
53960 sp = slob_page(block);
53961 if (is_slob_page(sp)) {
53962 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
53963 - unsigned int *m = (unsigned int *)(block - align);
53964 - return SLOB_UNITS(*m) * SLOB_UNIT;
53965 + slob_t *m = (slob_t *)(block - align);
53966 + return SLOB_UNITS(m[0].units) * SLOB_UNIT;
53967 } else
53968 - return sp->page.private;
53969 + return sp->size;
53970 }
53971 EXPORT_SYMBOL(ksize);
53972
53973 @@ -606,17 +689,25 @@ void *kmem_cache_alloc_node(struct kmem_
53974 {
53975 void *b;
53976
53977 +#ifdef CONFIG_PAX_USERCOPY
53978 + b = __kmalloc_node_align(c->size, flags, node, c->align);
53979 +#else
53980 if (c->size < PAGE_SIZE) {
53981 b = slob_alloc(c->size, flags, c->align, node);
53982 trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
53983 SLOB_UNITS(c->size) * SLOB_UNIT,
53984 flags, node);
53985 } else {
53986 + struct slob_page *sp;
53987 +
53988 b = slob_new_pages(flags, get_order(c->size), node);
53989 + sp = slob_page(b);
53990 + sp->size = c->size;
53991 trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
53992 PAGE_SIZE << get_order(c->size),
53993 flags, node);
53994 }
53995 +#endif
53996
53997 if (c->ctor)
53998 c->ctor(b);
53999 @@ -628,10 +719,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
54000
54001 static void __kmem_cache_free(void *b, int size)
54002 {
54003 - if (size < PAGE_SIZE)
54004 + struct slob_page *sp = slob_page(b);
54005 +
54006 + if (is_slob_page(sp))
54007 slob_free(b, size);
54008 - else
54009 + else {
54010 + clear_slob_page(sp);
54011 + free_slob_page(sp);
54012 + sp->size = 0;
54013 slob_free_pages(b, get_order(size));
54014 + }
54015 }
54016
54017 static void kmem_rcu_free(struct rcu_head *head)
54018 @@ -644,14 +741,23 @@ static void kmem_rcu_free(struct rcu_hea
54019
54020 void kmem_cache_free(struct kmem_cache *c, void *b)
54021 {
54022 + int size = c->size;
54023 +
54024 +#ifdef CONFIG_PAX_USERCOPY
54025 + if (size + c->align < PAGE_SIZE) {
54026 + size += c->align;
54027 + b -= c->align;
54028 + }
54029 +#endif
54030 +
54031 kmemleak_free_recursive(b, c->flags);
54032 if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
54033 struct slob_rcu *slob_rcu;
54034 - slob_rcu = b + (c->size - sizeof(struct slob_rcu));
54035 - slob_rcu->size = c->size;
54036 + slob_rcu = b + (size - sizeof(struct slob_rcu));
54037 + slob_rcu->size = size;
54038 call_rcu(&slob_rcu->head, kmem_rcu_free);
54039 } else {
54040 - __kmem_cache_free(b, c->size);
54041 + __kmem_cache_free(b, size);
54042 }
54043
54044 trace_kmem_cache_free(_RET_IP_, b);
54045 diff -urNp linux-2.6.36/mm/slub.c linux-2.6.36/mm/slub.c
54046 --- linux-2.6.36/mm/slub.c 2010-10-20 16:30:22.000000000 -0400
54047 +++ linux-2.6.36/mm/slub.c 2010-11-06 18:58:50.000000000 -0400
54048 @@ -1873,6 +1873,8 @@ void kmem_cache_free(struct kmem_cache *
54049
54050 page = virt_to_head_page(x);
54051
54052 + BUG_ON(!PageSlab(page));
54053 +
54054 slab_free(s, page, x, _RET_IP_);
54055
54056 trace_kmem_cache_free(_RET_IP_, x);
54057 @@ -1917,7 +1919,7 @@ static int slub_min_objects;
54058 * Merge control. If this is set then no merging of slab caches will occur.
54059 * (Could be removed. This was introduced to pacify the merge skeptics.)
54060 */
54061 -static int slub_nomerge;
54062 +static int slub_nomerge = 1;
54063
54064 /*
54065 * Calculate the order of allocation given an slab object size.
54066 @@ -2344,7 +2346,7 @@ static int kmem_cache_open(struct kmem_c
54067 * list to avoid pounding the page allocator excessively.
54068 */
54069 set_min_partial(s, ilog2(s->size));
54070 - s->refcount = 1;
54071 + atomic_set(&s->refcount, 1);
54072 #ifdef CONFIG_NUMA
54073 s->remote_node_defrag_ratio = 1000;
54074 #endif
54075 @@ -2487,8 +2489,7 @@ static inline int kmem_cache_close(struc
54076 void kmem_cache_destroy(struct kmem_cache *s)
54077 {
54078 down_write(&slub_lock);
54079 - s->refcount--;
54080 - if (!s->refcount) {
54081 + if (atomic_dec_and_test(&s->refcount)) {
54082 list_del(&s->list);
54083 if (kmem_cache_close(s)) {
54084 printk(KERN_ERR "SLUB %s: %s called for cache that "
54085 @@ -2779,6 +2780,46 @@ void *__kmalloc_node(size_t size, gfp_t
54086 EXPORT_SYMBOL(__kmalloc_node);
54087 #endif
54088
54089 +void check_object_size(const void *ptr, unsigned long n, bool to)
54090 +{
54091 +
54092 +#ifdef CONFIG_PAX_USERCOPY
54093 + struct page *page;
54094 + struct kmem_cache *s;
54095 + unsigned long offset;
54096 +
54097 + if (!n)
54098 + return;
54099 +
54100 + if (ZERO_OR_NULL_PTR(ptr))
54101 + goto report;
54102 +
54103 + if (!virt_addr_valid(ptr))
54104 + return;
54105 +
54106 + page = get_object_page(ptr);
54107 +
54108 + if (!page) {
54109 + if (object_is_on_stack(ptr, n) == -1)
54110 + goto report;
54111 + return;
54112 + }
54113 +
54114 + s = page->slab;
54115 + offset = (ptr - page_address(page)) % s->size;
54116 + if (offset <= s->objsize && n <= s->objsize - offset)
54117 + return;
54118 +
54119 +report:
54120 + if (to)
54121 + pax_report_leak_to_user(ptr, n);
54122 + else
54123 + pax_report_overflow_from_user(ptr, n);
54124 +#endif
54125 +
54126 +}
54127 +EXPORT_SYMBOL(check_object_size);
54128 +
54129 size_t ksize(const void *object)
54130 {
54131 struct page *page;
54132 @@ -3048,7 +3089,7 @@ void __init kmem_cache_init(void)
54133 */
54134 create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
54135 sizeof(struct kmem_cache_node), GFP_NOWAIT);
54136 - kmalloc_caches[0].refcount = -1;
54137 + atomic_set(&kmalloc_caches[0].refcount, -1);
54138 caches++;
54139
54140 hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
54141 @@ -3160,7 +3201,7 @@ static int slab_unmergeable(struct kmem_
54142 /*
54143 * We may have set a slab to be unmergeable during bootstrap.
54144 */
54145 - if (s->refcount < 0)
54146 + if (atomic_read(&s->refcount) < 0)
54147 return 1;
54148
54149 return 0;
54150 @@ -3218,7 +3259,7 @@ struct kmem_cache *kmem_cache_create(con
54151 down_write(&slub_lock);
54152 s = find_mergeable(size, align, flags, name, ctor);
54153 if (s) {
54154 - s->refcount++;
54155 + atomic_inc(&s->refcount);
54156 /*
54157 * Adjust the object sizes so that we clear
54158 * the complete object on kzalloc.
54159 @@ -3227,7 +3268,7 @@ struct kmem_cache *kmem_cache_create(con
54160 s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
54161
54162 if (sysfs_slab_alias(s, name)) {
54163 - s->refcount--;
54164 + atomic_dec(&s->refcount);
54165 goto err;
54166 }
54167 up_write(&slub_lock);
54168 @@ -3941,7 +3982,7 @@ SLAB_ATTR_RO(ctor);
54169
54170 static ssize_t aliases_show(struct kmem_cache *s, char *buf)
54171 {
54172 - return sprintf(buf, "%d\n", s->refcount - 1);
54173 + return sprintf(buf, "%d\n", atomic_read(&s->refcount) - 1);
54174 }
54175 SLAB_ATTR_RO(aliases);
54176
54177 @@ -4673,7 +4714,13 @@ static const struct file_operations proc
54178
54179 static int __init slab_proc_init(void)
54180 {
54181 - proc_create("slabinfo", S_IRUGO, NULL, &proc_slabinfo_operations);
54182 + mode_t gr_mode = S_IRUGO;
54183 +
54184 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
54185 + gr_mode = S_IRUSR;
54186 +#endif
54187 +
54188 + proc_create("slabinfo", gr_mode, NULL, &proc_slabinfo_operations);
54189 return 0;
54190 }
54191 module_init(slab_proc_init);
54192 diff -urNp linux-2.6.36/mm/util.c linux-2.6.36/mm/util.c
54193 --- linux-2.6.36/mm/util.c 2010-10-20 16:30:22.000000000 -0400
54194 +++ linux-2.6.36/mm/util.c 2010-11-06 18:58:15.000000000 -0400
54195 @@ -240,6 +240,12 @@ EXPORT_SYMBOL(strndup_user);
54196 void arch_pick_mmap_layout(struct mm_struct *mm)
54197 {
54198 mm->mmap_base = TASK_UNMAPPED_BASE;
54199 +
54200 +#ifdef CONFIG_PAX_RANDMMAP
54201 + if (mm->pax_flags & MF_PAX_RANDMMAP)
54202 + mm->mmap_base += mm->delta_mmap;
54203 +#endif
54204 +
54205 mm->get_unmapped_area = arch_get_unmapped_area;
54206 mm->unmap_area = arch_unmap_area;
54207 }
54208 diff -urNp linux-2.6.36/mm/vmalloc.c linux-2.6.36/mm/vmalloc.c
54209 --- linux-2.6.36/mm/vmalloc.c 2010-10-20 16:30:22.000000000 -0400
54210 +++ linux-2.6.36/mm/vmalloc.c 2010-11-06 18:58:15.000000000 -0400
54211 @@ -41,8 +41,19 @@ static void vunmap_pte_range(pmd_t *pmd,
54212
54213 pte = pte_offset_kernel(pmd, addr);
54214 do {
54215 - pte_t ptent = ptep_get_and_clear(&init_mm, addr, pte);
54216 - WARN_ON(!pte_none(ptent) && !pte_present(ptent));
54217 +
54218 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
54219 + if ((unsigned long)MODULES_EXEC_VADDR <= addr && addr < (unsigned long)MODULES_EXEC_END) {
54220 + BUG_ON(!pte_exec(*pte));
54221 + set_pte_at(&init_mm, addr, pte, pfn_pte(__pa(addr) >> PAGE_SHIFT, PAGE_KERNEL_EXEC));
54222 + continue;
54223 + }
54224 +#endif
54225 +
54226 + {
54227 + pte_t ptent = ptep_get_and_clear(&init_mm, addr, pte);
54228 + WARN_ON(!pte_none(ptent) && !pte_present(ptent));
54229 + }
54230 } while (pte++, addr += PAGE_SIZE, addr != end);
54231 }
54232
54233 @@ -93,6 +104,7 @@ static int vmap_pte_range(pmd_t *pmd, un
54234 unsigned long end, pgprot_t prot, struct page **pages, int *nr)
54235 {
54236 pte_t *pte;
54237 + int ret = -ENOMEM;
54238
54239 /*
54240 * nr is a running index into the array which helps higher level
54241 @@ -102,17 +114,30 @@ static int vmap_pte_range(pmd_t *pmd, un
54242 pte = pte_alloc_kernel(pmd, addr);
54243 if (!pte)
54244 return -ENOMEM;
54245 +
54246 + pax_open_kernel();
54247 do {
54248 struct page *page = pages[*nr];
54249
54250 - if (WARN_ON(!pte_none(*pte)))
54251 - return -EBUSY;
54252 - if (WARN_ON(!page))
54253 - return -ENOMEM;
54254 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
54255 + if (pgprot_val(prot) & _PAGE_NX)
54256 +#endif
54257 +
54258 + if (WARN_ON(!pte_none(*pte))) {
54259 + ret = -EBUSY;
54260 + goto out;
54261 + }
54262 + if (WARN_ON(!page)) {
54263 + ret = -ENOMEM;
54264 + goto out;
54265 + }
54266 set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
54267 (*nr)++;
54268 } while (pte++, addr += PAGE_SIZE, addr != end);
54269 - return 0;
54270 + ret = 0;
54271 +out:
54272 + pax_close_kernel();
54273 + return ret;
54274 }
54275
54276 static int vmap_pmd_range(pud_t *pud, unsigned long addr,
54277 @@ -193,11 +218,20 @@ int is_vmalloc_or_module_addr(const void
54278 * and fall back on vmalloc() if that fails. Others
54279 * just put it in the vmalloc space.
54280 */
54281 -#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
54282 +#ifdef CONFIG_MODULES
54283 +#ifdef MODULES_VADDR
54284 unsigned long addr = (unsigned long)x;
54285 if (addr >= MODULES_VADDR && addr < MODULES_END)
54286 return 1;
54287 #endif
54288 +
54289 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
54290 + if (x >= (const void *)MODULES_EXEC_VADDR && x < (const void *)MODULES_EXEC_END)
54291 + return 1;
54292 +#endif
54293 +
54294 +#endif
54295 +
54296 return is_vmalloc_addr(x);
54297 }
54298
54299 @@ -218,8 +252,14 @@ struct page *vmalloc_to_page(const void
54300
54301 if (!pgd_none(*pgd)) {
54302 pud_t *pud = pud_offset(pgd, addr);
54303 +#ifdef CONFIG_X86
54304 + if (!pud_large(*pud))
54305 +#endif
54306 if (!pud_none(*pud)) {
54307 pmd_t *pmd = pmd_offset(pud, addr);
54308 +#ifdef CONFIG_X86
54309 + if (!pmd_large(*pmd))
54310 +#endif
54311 if (!pmd_none(*pmd)) {
54312 pte_t *ptep, pte;
54313
54314 @@ -293,13 +333,13 @@ static void __insert_vmap_area(struct vm
54315 struct rb_node *tmp;
54316
54317 while (*p) {
54318 - struct vmap_area *tmp;
54319 + struct vmap_area *varea;
54320
54321 parent = *p;
54322 - tmp = rb_entry(parent, struct vmap_area, rb_node);
54323 - if (va->va_start < tmp->va_end)
54324 + varea = rb_entry(parent, struct vmap_area, rb_node);
54325 + if (va->va_start < varea->va_end)
54326 p = &(*p)->rb_left;
54327 - else if (va->va_end > tmp->va_start)
54328 + else if (va->va_end > varea->va_start)
54329 p = &(*p)->rb_right;
54330 else
54331 BUG();
54332 @@ -1228,6 +1268,16 @@ static struct vm_struct *__get_vm_area_n
54333 struct vm_struct *area;
54334
54335 BUG_ON(in_interrupt());
54336 +
54337 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86) && defined(CONFIG_PAX_KERNEXEC)
54338 + if (flags & VM_KERNEXEC) {
54339 + if (start != VMALLOC_START || end != VMALLOC_END)
54340 + return NULL;
54341 + start = (unsigned long)MODULES_EXEC_VADDR;
54342 + end = (unsigned long)MODULES_EXEC_END;
54343 + }
54344 +#endif
54345 +
54346 if (flags & VM_IOREMAP) {
54347 int bit = fls(size);
54348
54349 @@ -1453,6 +1503,11 @@ void *vmap(struct page **pages, unsigned
54350 if (count > totalram_pages)
54351 return NULL;
54352
54353 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86) && defined(CONFIG_PAX_KERNEXEC)
54354 + if (!(pgprot_val(prot) & _PAGE_NX))
54355 + flags |= VM_KERNEXEC;
54356 +#endif
54357 +
54358 area = get_vm_area_caller((count << PAGE_SHIFT), flags,
54359 __builtin_return_address(0));
54360 if (!area)
54361 @@ -1562,6 +1617,13 @@ static void *__vmalloc_node(unsigned lon
54362 if (!size || (size >> PAGE_SHIFT) > totalram_pages)
54363 return NULL;
54364
54365 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86) && defined(CONFIG_PAX_KERNEXEC)
54366 + if (!(pgprot_val(prot) & _PAGE_NX))
54367 + area = __get_vm_area_node(size, align, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
54368 + node, gfp_mask, caller);
54369 + else
54370 +#endif
54371 +
54372 area = __get_vm_area_node(size, align, VM_ALLOC, VMALLOC_START,
54373 VMALLOC_END, node, gfp_mask, caller);
54374
54375 @@ -1580,6 +1642,7 @@ static void *__vmalloc_node(unsigned lon
54376 return addr;
54377 }
54378
54379 +#undef __vmalloc
54380 void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
54381 {
54382 return __vmalloc_node(size, 1, gfp_mask, prot, -1,
54383 @@ -1596,6 +1659,7 @@ EXPORT_SYMBOL(__vmalloc);
54384 * For tight control over page level allocator and protection flags
54385 * use __vmalloc() instead.
54386 */
54387 +#undef vmalloc
54388 void *vmalloc(unsigned long size)
54389 {
54390 return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
54391 @@ -1610,6 +1674,7 @@ EXPORT_SYMBOL(vmalloc);
54392 * The resulting memory area is zeroed so it can be mapped to userspace
54393 * without leaking data.
54394 */
54395 +#undef vmalloc_user
54396 void *vmalloc_user(unsigned long size)
54397 {
54398 struct vm_struct *area;
54399 @@ -1637,6 +1702,7 @@ EXPORT_SYMBOL(vmalloc_user);
54400 * For tight control over page level allocator and protection flags
54401 * use __vmalloc() instead.
54402 */
54403 +#undef vmalloc_node
54404 void *vmalloc_node(unsigned long size, int node)
54405 {
54406 return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
54407 @@ -1659,10 +1725,10 @@ EXPORT_SYMBOL(vmalloc_node);
54408 * For tight control over page level allocator and protection flags
54409 * use __vmalloc() instead.
54410 */
54411 -
54412 +#undef vmalloc_exec
54413 void *vmalloc_exec(unsigned long size)
54414 {
54415 - return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
54416 + return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC,
54417 -1, __builtin_return_address(0));
54418 }
54419
54420 @@ -1681,6 +1747,7 @@ void *vmalloc_exec(unsigned long size)
54421 * Allocate enough 32bit PA addressable pages to cover @size from the
54422 * page level allocator and map them into contiguous kernel virtual space.
54423 */
54424 +#undef vmalloc_32
54425 void *vmalloc_32(unsigned long size)
54426 {
54427 return __vmalloc_node(size, 1, GFP_VMALLOC32, PAGE_KERNEL,
54428 @@ -1695,6 +1762,7 @@ EXPORT_SYMBOL(vmalloc_32);
54429 * The resulting memory area is 32bit addressable and zeroed so it can be
54430 * mapped to userspace without leaking data.
54431 */
54432 +#undef vmalloc_32_user
54433 void *vmalloc_32_user(unsigned long size)
54434 {
54435 struct vm_struct *area;
54436 @@ -1959,6 +2027,8 @@ int remap_vmalloc_range(struct vm_area_s
54437 unsigned long uaddr = vma->vm_start;
54438 unsigned long usize = vma->vm_end - vma->vm_start;
54439
54440 + BUG_ON(vma->vm_mirror);
54441 +
54442 if ((PAGE_SIZE-1) & (unsigned long)addr)
54443 return -EINVAL;
54444
54445 diff -urNp linux-2.6.36/mm/vmstat.c linux-2.6.36/mm/vmstat.c
54446 --- linux-2.6.36/mm/vmstat.c 2010-10-20 16:30:22.000000000 -0400
54447 +++ linux-2.6.36/mm/vmstat.c 2010-11-06 18:58:50.000000000 -0400
54448 @@ -76,7 +76,7 @@ void vm_events_fold_cpu(int cpu)
54449 *
54450 * vm_stat contains the global counters
54451 */
54452 -atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
54453 +atomic_long_unchecked_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
54454 EXPORT_SYMBOL(vm_stat);
54455
54456 #ifdef CONFIG_SMP
54457 @@ -328,7 +328,7 @@ void refresh_cpu_vm_stats(int cpu)
54458 v = p->vm_stat_diff[i];
54459 p->vm_stat_diff[i] = 0;
54460 local_irq_restore(flags);
54461 - atomic_long_add(v, &zone->vm_stat[i]);
54462 + atomic_long_add_unchecked(v, &zone->vm_stat[i]);
54463 global_diff[i] += v;
54464 #ifdef CONFIG_NUMA
54465 /* 3 seconds idle till flush */
54466 @@ -366,7 +366,7 @@ void refresh_cpu_vm_stats(int cpu)
54467
54468 for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
54469 if (global_diff[i])
54470 - atomic_long_add(global_diff[i], &vm_stat[i]);
54471 + atomic_long_add_unchecked(global_diff[i], &vm_stat[i]);
54472 }
54473
54474 #endif
54475 @@ -1050,10 +1050,16 @@ static int __init setup_vmstat(void)
54476 start_cpu_timer(cpu);
54477 #endif
54478 #ifdef CONFIG_PROC_FS
54479 - proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
54480 - proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
54481 - proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
54482 - proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
54483 + {
54484 + mode_t gr_mode = S_IRUGO;
54485 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
54486 + gr_mode = S_IRUSR;
54487 +#endif
54488 + proc_create("buddyinfo", gr_mode, NULL, &fragmentation_file_operations);
54489 + proc_create("pagetypeinfo", gr_mode, NULL, &pagetypeinfo_file_ops);
54490 + proc_create("vmstat", gr_mode, NULL, &proc_vmstat_file_operations);
54491 + proc_create("zoneinfo", gr_mode, NULL, &proc_zoneinfo_file_operations);
54492 + }
54493 #endif
54494 return 0;
54495 }
54496 diff -urNp linux-2.6.36/net/8021q/vlan.c linux-2.6.36/net/8021q/vlan.c
54497 --- linux-2.6.36/net/8021q/vlan.c 2010-10-20 16:30:22.000000000 -0400
54498 +++ linux-2.6.36/net/8021q/vlan.c 2010-11-06 18:58:15.000000000 -0400
54499 @@ -627,8 +627,7 @@ static int vlan_ioctl_handler(struct net
54500 err = -EPERM;
54501 if (!capable(CAP_NET_ADMIN))
54502 break;
54503 - if ((args.u.name_type >= 0) &&
54504 - (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
54505 + if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
54506 struct vlan_net *vn;
54507
54508 vn = net_generic(net, vlan_net_id);
54509 diff -urNp linux-2.6.36/net/atm/atm_misc.c linux-2.6.36/net/atm/atm_misc.c
54510 --- linux-2.6.36/net/atm/atm_misc.c 2010-10-20 16:30:22.000000000 -0400
54511 +++ linux-2.6.36/net/atm/atm_misc.c 2010-11-06 18:58:15.000000000 -0400
54512 @@ -17,7 +17,7 @@ int atm_charge(struct atm_vcc *vcc, int
54513 if (atomic_read(&sk_atm(vcc)->sk_rmem_alloc) <= sk_atm(vcc)->sk_rcvbuf)
54514 return 1;
54515 atm_return(vcc, truesize);
54516 - atomic_inc(&vcc->stats->rx_drop);
54517 + atomic_inc_unchecked(&vcc->stats->rx_drop);
54518 return 0;
54519 }
54520 EXPORT_SYMBOL(atm_charge);
54521 @@ -39,7 +39,7 @@ struct sk_buff *atm_alloc_charge(struct
54522 }
54523 }
54524 atm_return(vcc, guess);
54525 - atomic_inc(&vcc->stats->rx_drop);
54526 + atomic_inc_unchecked(&vcc->stats->rx_drop);
54527 return NULL;
54528 }
54529 EXPORT_SYMBOL(atm_alloc_charge);
54530 @@ -86,7 +86,7 @@ EXPORT_SYMBOL(atm_pcr_goal);
54531
54532 void sonet_copy_stats(struct k_sonet_stats *from, struct sonet_stats *to)
54533 {
54534 -#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
54535 +#define __HANDLE_ITEM(i) to->i = atomic_read_unchecked(&from->i)
54536 __SONET_ITEMS
54537 #undef __HANDLE_ITEM
54538 }
54539 @@ -94,7 +94,7 @@ EXPORT_SYMBOL(sonet_copy_stats);
54540
54541 void sonet_subtract_stats(struct k_sonet_stats *from, struct sonet_stats *to)
54542 {
54543 -#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
54544 +#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i,&from->i)
54545 __SONET_ITEMS
54546 #undef __HANDLE_ITEM
54547 }
54548 diff -urNp linux-2.6.36/net/atm/proc.c linux-2.6.36/net/atm/proc.c
54549 --- linux-2.6.36/net/atm/proc.c 2010-10-20 16:30:22.000000000 -0400
54550 +++ linux-2.6.36/net/atm/proc.c 2010-11-06 18:58:50.000000000 -0400
54551 @@ -44,9 +44,9 @@ static void add_stats(struct seq_file *s
54552 const struct k_atm_aal_stats *stats)
54553 {
54554 seq_printf(seq, "%s ( %d %d %d %d %d )", aal,
54555 - atomic_read(&stats->tx), atomic_read(&stats->tx_err),
54556 - atomic_read(&stats->rx), atomic_read(&stats->rx_err),
54557 - atomic_read(&stats->rx_drop));
54558 + atomic_read_unchecked(&stats->tx),atomic_read_unchecked(&stats->tx_err),
54559 + atomic_read_unchecked(&stats->rx),atomic_read_unchecked(&stats->rx_err),
54560 + atomic_read_unchecked(&stats->rx_drop));
54561 }
54562
54563 static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev)
54564 @@ -190,7 +190,12 @@ static void vcc_info(struct seq_file *se
54565 {
54566 struct sock *sk = sk_atm(vcc);
54567
54568 +#ifdef CONFIG_GRKERNSEC_HIDESYM
54569 + seq_printf(seq, "%p ", NULL);
54570 +#else
54571 seq_printf(seq, "%p ", vcc);
54572 +#endif
54573 +
54574 if (!vcc->dev)
54575 seq_printf(seq, "Unassigned ");
54576 else
54577 diff -urNp linux-2.6.36/net/atm/resources.c linux-2.6.36/net/atm/resources.c
54578 --- linux-2.6.36/net/atm/resources.c 2010-10-20 16:30:22.000000000 -0400
54579 +++ linux-2.6.36/net/atm/resources.c 2010-11-06 18:58:15.000000000 -0400
54580 @@ -159,7 +159,7 @@ EXPORT_SYMBOL(atm_dev_deregister);
54581 static void copy_aal_stats(struct k_atm_aal_stats *from,
54582 struct atm_aal_stats *to)
54583 {
54584 -#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
54585 +#define __HANDLE_ITEM(i) to->i = atomic_read_unchecked(&from->i)
54586 __AAL_STAT_ITEMS
54587 #undef __HANDLE_ITEM
54588 }
54589 @@ -167,7 +167,7 @@ static void copy_aal_stats(struct k_atm_
54590 static void subtract_aal_stats(struct k_atm_aal_stats *from,
54591 struct atm_aal_stats *to)
54592 {
54593 -#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
54594 +#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i, &from->i)
54595 __AAL_STAT_ITEMS
54596 #undef __HANDLE_ITEM
54597 }
54598 diff -urNp linux-2.6.36/net/ax25/af_ax25.c linux-2.6.36/net/ax25/af_ax25.c
54599 --- linux-2.6.36/net/ax25/af_ax25.c 2010-10-20 16:30:22.000000000 -0400
54600 +++ linux-2.6.36/net/ax25/af_ax25.c 2010-11-06 18:58:50.000000000 -0400
54601 @@ -1392,6 +1392,7 @@ static int ax25_getname(struct socket *s
54602 ax25_cb *ax25;
54603 int err = 0;
54604
54605 + memset(fsa, 0, sizeof(*fsa));
54606 lock_sock(sk);
54607 ax25 = ax25_sk(sk);
54608
54609 @@ -1403,7 +1404,6 @@ static int ax25_getname(struct socket *s
54610
54611 fsa->fsa_ax25.sax25_family = AF_AX25;
54612 fsa->fsa_ax25.sax25_call = ax25->dest_addr;
54613 - fsa->fsa_ax25.sax25_ndigis = 0;
54614
54615 if (ax25->digipeat != NULL) {
54616 ndigi = ax25->digipeat->ndigi;
54617 diff -urNp linux-2.6.36/net/bridge/br_multicast.c linux-2.6.36/net/bridge/br_multicast.c
54618 --- linux-2.6.36/net/bridge/br_multicast.c 2010-10-20 16:30:22.000000000 -0400
54619 +++ linux-2.6.36/net/bridge/br_multicast.c 2010-11-06 18:58:15.000000000 -0400
54620 @@ -1461,7 +1461,7 @@ static int br_multicast_ipv6_rcv(struct
54621 nexthdr = ip6h->nexthdr;
54622 offset = ipv6_skip_exthdr(skb, sizeof(*ip6h), &nexthdr);
54623
54624 - if (offset < 0 || nexthdr != IPPROTO_ICMPV6)
54625 + if (nexthdr != IPPROTO_ICMPV6)
54626 return 0;
54627
54628 /* Okay, we found ICMPv6 header */
54629 diff -urNp linux-2.6.36/net/bridge/br_stp_if.c linux-2.6.36/net/bridge/br_stp_if.c
54630 --- linux-2.6.36/net/bridge/br_stp_if.c 2010-10-20 16:30:22.000000000 -0400
54631 +++ linux-2.6.36/net/bridge/br_stp_if.c 2010-11-06 18:58:15.000000000 -0400
54632 @@ -145,7 +145,7 @@ static void br_stp_stop(struct net_bridg
54633 char *envp[] = { NULL };
54634
54635 if (br->stp_enabled == BR_USER_STP) {
54636 - r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
54637 + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
54638 br_info(br, "userspace STP stopped, return code %d\n", r);
54639
54640 /* To start timers on any ports left in blocking */
54641 diff -urNp linux-2.6.36/net/bridge/netfilter/ebtables.c linux-2.6.36/net/bridge/netfilter/ebtables.c
54642 --- linux-2.6.36/net/bridge/netfilter/ebtables.c 2010-10-20 16:30:22.000000000 -0400
54643 +++ linux-2.6.36/net/bridge/netfilter/ebtables.c 2010-11-06 18:58:15.000000000 -0400
54644 @@ -1504,7 +1504,7 @@ static int do_ebt_get_ctl(struct sock *s
54645 tmp.valid_hooks = t->table->valid_hooks;
54646 }
54647 mutex_unlock(&ebt_mutex);
54648 - if (copy_to_user(user, &tmp, *len) != 0){
54649 + if (*len > sizeof(tmp) || copy_to_user(user, &tmp, *len) != 0){
54650 BUGPRINT("c2u Didn't work\n");
54651 ret = -EFAULT;
54652 break;
54653 diff -urNp linux-2.6.36/net/core/dev.c linux-2.6.36/net/core/dev.c
54654 --- linux-2.6.36/net/core/dev.c 2010-10-20 16:30:22.000000000 -0400
54655 +++ linux-2.6.36/net/core/dev.c 2010-11-06 18:58:15.000000000 -0400
54656 @@ -2554,7 +2554,7 @@ int netif_rx_ni(struct sk_buff *skb)
54657 }
54658 EXPORT_SYMBOL(netif_rx_ni);
54659
54660 -static void net_tx_action(struct softirq_action *h)
54661 +static void net_tx_action(void)
54662 {
54663 struct softnet_data *sd = &__get_cpu_var(softnet_data);
54664
54665 @@ -3482,7 +3482,7 @@ void netif_napi_del(struct napi_struct *
54666 }
54667 EXPORT_SYMBOL(netif_napi_del);
54668
54669 -static void net_rx_action(struct softirq_action *h)
54670 +static void net_rx_action(void)
54671 {
54672 struct softnet_data *sd = &__get_cpu_var(softnet_data);
54673 unsigned long time_limit = jiffies + 2;
54674 diff -urNp linux-2.6.36/net/core/net-sysfs.c linux-2.6.36/net/core/net-sysfs.c
54675 --- linux-2.6.36/net/core/net-sysfs.c 2010-10-20 16:30:22.000000000 -0400
54676 +++ linux-2.6.36/net/core/net-sysfs.c 2010-11-06 18:58:15.000000000 -0400
54677 @@ -515,7 +515,7 @@ static ssize_t rx_queue_attr_store(struc
54678 return attribute->store(queue, attribute, buf, count);
54679 }
54680
54681 -static struct sysfs_ops rx_queue_sysfs_ops = {
54682 +static const struct sysfs_ops rx_queue_sysfs_ops = {
54683 .show = rx_queue_attr_show,
54684 .store = rx_queue_attr_store,
54685 };
54686 diff -urNp linux-2.6.36/net/core/sock.c linux-2.6.36/net/core/sock.c
54687 --- linux-2.6.36/net/core/sock.c 2010-10-20 16:30:22.000000000 -0400
54688 +++ linux-2.6.36/net/core/sock.c 2010-11-06 18:58:15.000000000 -0400
54689 @@ -934,7 +934,7 @@ int sock_getsockopt(struct socket *sock,
54690 return -ENOTCONN;
54691 if (lv < len)
54692 return -EINVAL;
54693 - if (copy_to_user(optval, address, len))
54694 + if (len > sizeof(address) || copy_to_user(optval, address, len))
54695 return -EFAULT;
54696 goto lenout;
54697 }
54698 @@ -967,7 +967,7 @@ int sock_getsockopt(struct socket *sock,
54699
54700 if (len > lv)
54701 len = lv;
54702 - if (copy_to_user(optval, &v, len))
54703 + if (len > sizeof(v) || copy_to_user(optval, &v, len))
54704 return -EFAULT;
54705 lenout:
54706 if (put_user(len, optlen))
54707 diff -urNp linux-2.6.36/net/dccp/ccids/ccid3.c linux-2.6.36/net/dccp/ccids/ccid3.c
54708 --- linux-2.6.36/net/dccp/ccids/ccid3.c 2010-10-20 16:30:22.000000000 -0400
54709 +++ linux-2.6.36/net/dccp/ccids/ccid3.c 2010-11-06 18:58:15.000000000 -0400
54710 @@ -41,7 +41,7 @@
54711 static int ccid3_debug;
54712 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
54713 #else
54714 -#define ccid3_pr_debug(format, a...)
54715 +#define ccid3_pr_debug(format, a...) do {} while (0)
54716 #endif
54717
54718 /*
54719 diff -urNp linux-2.6.36/net/dccp/dccp.h linux-2.6.36/net/dccp/dccp.h
54720 --- linux-2.6.36/net/dccp/dccp.h 2010-10-20 16:30:22.000000000 -0400
54721 +++ linux-2.6.36/net/dccp/dccp.h 2010-11-06 18:58:15.000000000 -0400
54722 @@ -44,9 +44,9 @@ extern int dccp_debug;
54723 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
54724 #define dccp_debug(fmt, a...) dccp_pr_debug_cat(KERN_DEBUG fmt, ##a)
54725 #else
54726 -#define dccp_pr_debug(format, a...)
54727 -#define dccp_pr_debug_cat(format, a...)
54728 -#define dccp_debug(format, a...)
54729 +#define dccp_pr_debug(format, a...) do {} while (0)
54730 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
54731 +#define dccp_debug(format, a...) do {} while (0)
54732 #endif
54733
54734 extern struct inet_hashinfo dccp_hashinfo;
54735 diff -urNp linux-2.6.36/net/decnet/sysctl_net_decnet.c linux-2.6.36/net/decnet/sysctl_net_decnet.c
54736 --- linux-2.6.36/net/decnet/sysctl_net_decnet.c 2010-10-20 16:30:22.000000000 -0400
54737 +++ linux-2.6.36/net/decnet/sysctl_net_decnet.c 2010-11-06 18:58:50.000000000 -0400
54738 @@ -173,7 +173,7 @@ static int dn_node_address_handler(ctl_t
54739
54740 if (len > *lenp) len = *lenp;
54741
54742 - if (copy_to_user(buffer, addr, len))
54743 + if (len > sizeof(addr) || copy_to_user(buffer, addr, len))
54744 return -EFAULT;
54745
54746 *lenp = len;
54747 @@ -236,7 +236,7 @@ static int dn_def_dev_handler(ctl_table
54748
54749 if (len > *lenp) len = *lenp;
54750
54751 - if (copy_to_user(buffer, devname, len))
54752 + if (len > sizeof(devname) || copy_to_user(buffer, devname, len))
54753 return -EFAULT;
54754
54755 *lenp = len;
54756 diff -urNp linux-2.6.36/net/ipv4/inet_hashtables.c linux-2.6.36/net/ipv4/inet_hashtables.c
54757 --- linux-2.6.36/net/ipv4/inet_hashtables.c 2010-10-20 16:30:22.000000000 -0400
54758 +++ linux-2.6.36/net/ipv4/inet_hashtables.c 2010-11-06 18:58:50.000000000 -0400
54759 @@ -18,11 +18,14 @@
54760 #include <linux/sched.h>
54761 #include <linux/slab.h>
54762 #include <linux/wait.h>
54763 +#include <linux/security.h>
54764
54765 #include <net/inet_connection_sock.h>
54766 #include <net/inet_hashtables.h>
54767 #include <net/ip.h>
54768
54769 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
54770 +
54771 /*
54772 * Allocate and initialize a new local port bind bucket.
54773 * The bindhash mutex for snum's hash chain must be held here.
54774 @@ -506,6 +509,8 @@ ok:
54775 twrefcnt += inet_twsk_bind_unhash(tw, hinfo);
54776 spin_unlock(&head->lock);
54777
54778 + gr_update_task_in_ip_table(current, inet_sk(sk));
54779 +
54780 if (tw) {
54781 inet_twsk_deschedule(tw, death_row);
54782 while (twrefcnt) {
54783 diff -urNp linux-2.6.36/net/ipv4/inetpeer.c linux-2.6.36/net/ipv4/inetpeer.c
54784 --- linux-2.6.36/net/ipv4/inetpeer.c 2010-10-20 16:30:22.000000000 -0400
54785 +++ linux-2.6.36/net/ipv4/inetpeer.c 2010-11-06 18:58:15.000000000 -0400
54786 @@ -447,8 +447,8 @@ struct inet_peer *inet_getpeer(__be32 da
54787 if (p) {
54788 p->v4daddr = daddr;
54789 atomic_set(&p->refcnt, 1);
54790 - atomic_set(&p->rid, 0);
54791 - atomic_set(&p->ip_id_count, secure_ip_id(daddr));
54792 + atomic_set_unchecked(&p->rid, 0);
54793 + atomic_set_unchecked(&p->ip_id_count, secure_ip_id(daddr));
54794 p->tcp_ts_stamp = 0;
54795 INIT_LIST_HEAD(&p->unused);
54796
54797 diff -urNp linux-2.6.36/net/ipv4/ip_fragment.c linux-2.6.36/net/ipv4/ip_fragment.c
54798 --- linux-2.6.36/net/ipv4/ip_fragment.c 2010-10-20 16:30:22.000000000 -0400
54799 +++ linux-2.6.36/net/ipv4/ip_fragment.c 2010-11-06 18:58:15.000000000 -0400
54800 @@ -279,7 +279,7 @@ static inline int ip_frag_too_far(struct
54801 return 0;
54802
54803 start = qp->rid;
54804 - end = atomic_inc_return(&peer->rid);
54805 + end = atomic_inc_return_unchecked(&peer->rid);
54806 qp->rid = end;
54807
54808 rc = qp->q.fragments && (end - start) > max;
54809 diff -urNp linux-2.6.36/net/ipv4/netfilter/arp_tables.c linux-2.6.36/net/ipv4/netfilter/arp_tables.c
54810 --- linux-2.6.36/net/ipv4/netfilter/arp_tables.c 2010-10-20 16:30:22.000000000 -0400
54811 +++ linux-2.6.36/net/ipv4/netfilter/arp_tables.c 2010-11-06 18:58:50.000000000 -0400
54812 @@ -927,6 +927,7 @@ static int get_info(struct net *net, voi
54813 private = &tmp;
54814 }
54815 #endif
54816 + memset(&info, 0, sizeof(info));
54817 info.valid_hooks = t->valid_hooks;
54818 memcpy(info.hook_entry, private->hook_entry,
54819 sizeof(info.hook_entry));
54820 diff -urNp linux-2.6.36/net/ipv4/netfilter/ip_tables.c linux-2.6.36/net/ipv4/netfilter/ip_tables.c
54821 --- linux-2.6.36/net/ipv4/netfilter/ip_tables.c 2010-10-20 16:30:22.000000000 -0400
54822 +++ linux-2.6.36/net/ipv4/netfilter/ip_tables.c 2010-11-06 18:58:50.000000000 -0400
54823 @@ -1124,6 +1124,7 @@ static int get_info(struct net *net, voi
54824 private = &tmp;
54825 }
54826 #endif
54827 + memset(&info, 0, sizeof(info));
54828 info.valid_hooks = t->valid_hooks;
54829 memcpy(info.hook_entry, private->hook_entry,
54830 sizeof(info.hook_entry));
54831 diff -urNp linux-2.6.36/net/ipv4/netfilter/nf_nat_snmp_basic.c linux-2.6.36/net/ipv4/netfilter/nf_nat_snmp_basic.c
54832 --- linux-2.6.36/net/ipv4/netfilter/nf_nat_snmp_basic.c 2010-10-20 16:30:22.000000000 -0400
54833 +++ linux-2.6.36/net/ipv4/netfilter/nf_nat_snmp_basic.c 2010-11-06 18:58:15.000000000 -0400
54834 @@ -398,7 +398,7 @@ static unsigned char asn1_octets_decode(
54835
54836 *len = 0;
54837
54838 - *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
54839 + *octets = kmalloc((eoc - ctx->pointer), GFP_ATOMIC);
54840 if (*octets == NULL) {
54841 if (net_ratelimit())
54842 pr_notice("OOM in bsalg (%d)\n", __LINE__);
54843 diff -urNp linux-2.6.36/net/ipv4/route.c linux-2.6.36/net/ipv4/route.c
54844 --- linux-2.6.36/net/ipv4/route.c 2010-10-20 16:30:22.000000000 -0400
54845 +++ linux-2.6.36/net/ipv4/route.c 2010-11-06 18:58:15.000000000 -0400
54846 @@ -2890,7 +2890,7 @@ static int rt_fill_info(struct net *net,
54847 expires = rt->dst.expires ? rt->dst.expires - jiffies : 0;
54848 if (rt->peer) {
54849 inet_peer_refcheck(rt->peer);
54850 - id = atomic_read(&rt->peer->ip_id_count) & 0xffff;
54851 + id = atomic_read_unchecked(&rt->peer->ip_id_count) & 0xffff;
54852 if (rt->peer->tcp_ts_stamp) {
54853 ts = rt->peer->tcp_ts;
54854 tsage = get_seconds() - rt->peer->tcp_ts_stamp;
54855 diff -urNp linux-2.6.36/net/ipv4/tcp_ipv4.c linux-2.6.36/net/ipv4/tcp_ipv4.c
54856 --- linux-2.6.36/net/ipv4/tcp_ipv4.c 2010-10-20 16:30:22.000000000 -0400
54857 +++ linux-2.6.36/net/ipv4/tcp_ipv4.c 2010-11-06 19:08:40.000000000 -0400
54858 @@ -86,6 +86,9 @@ int sysctl_tcp_tw_reuse __read_mostly;
54859 int sysctl_tcp_low_latency __read_mostly;
54860 EXPORT_SYMBOL(sysctl_tcp_low_latency);
54861
54862 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
54863 +extern int grsec_enable_blackhole;
54864 +#endif
54865
54866 #ifdef CONFIG_TCP_MD5SIG
54867 static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
54868 @@ -1597,6 +1600,9 @@ int tcp_v4_do_rcv(struct sock *sk, struc
54869 return 0;
54870
54871 reset:
54872 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
54873 + if (!grsec_enable_blackhole)
54874 +#endif
54875 tcp_v4_send_reset(rsk, skb);
54876 discard:
54877 kfree_skb(skb);
54878 @@ -1659,12 +1665,19 @@ int tcp_v4_rcv(struct sk_buff *skb)
54879 TCP_SKB_CB(skb)->sacked = 0;
54880
54881 sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
54882 - if (!sk)
54883 + if (!sk) {
54884 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
54885 + ret = 1;
54886 +#endif
54887 goto no_tcp_socket;
54888 -
54889 + }
54890 process:
54891 - if (sk->sk_state == TCP_TIME_WAIT)
54892 + if (sk->sk_state == TCP_TIME_WAIT) {
54893 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
54894 + ret = 2;
54895 +#endif
54896 goto do_time_wait;
54897 + }
54898
54899 if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
54900 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
54901 @@ -1714,6 +1727,10 @@ no_tcp_socket:
54902 bad_packet:
54903 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
54904 } else {
54905 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
54906 + if (!grsec_enable_blackhole || (ret == 1 &&
54907 + (skb->dev->flags & IFF_LOOPBACK)))
54908 +#endif
54909 tcp_v4_send_reset(NULL, skb);
54910 }
54911
54912 @@ -2400,7 +2417,11 @@ static void get_openreq4(struct sock *sk
54913 0, /* non standard timer */
54914 0, /* open_requests have no inode */
54915 atomic_read(&sk->sk_refcnt),
54916 +#ifdef CONFIG_GRKERNSEC_HIDESYM
54917 + NULL,
54918 +#else
54919 req,
54920 +#endif
54921 len);
54922 }
54923
54924 @@ -2450,7 +2471,12 @@ static void get_tcp4_sock(struct sock *s
54925 sock_i_uid(sk),
54926 icsk->icsk_probes_out,
54927 sock_i_ino(sk),
54928 - atomic_read(&sk->sk_refcnt), sk,
54929 + atomic_read(&sk->sk_refcnt),
54930 +#ifdef CONFIG_GRKERNSEC_HIDESYM
54931 + NULL,
54932 +#else
54933 + sk,
54934 +#endif
54935 jiffies_to_clock_t(icsk->icsk_rto),
54936 jiffies_to_clock_t(icsk->icsk_ack.ato),
54937 (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
54938 @@ -2478,7 +2504,13 @@ static void get_timewait4_sock(struct in
54939 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p%n",
54940 i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
54941 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
54942 - atomic_read(&tw->tw_refcnt), tw, len);
54943 + atomic_read(&tw->tw_refcnt),
54944 +#ifdef CONFIG_GRKERNSEC_HIDESYM
54945 + NULL,
54946 +#else
54947 + tw,
54948 +#endif
54949 + len);
54950 }
54951
54952 #define TMPSZ 150
54953 diff -urNp linux-2.6.36/net/ipv4/tcp_minisocks.c linux-2.6.36/net/ipv4/tcp_minisocks.c
54954 --- linux-2.6.36/net/ipv4/tcp_minisocks.c 2010-10-20 16:30:22.000000000 -0400
54955 +++ linux-2.6.36/net/ipv4/tcp_minisocks.c 2010-11-06 18:58:50.000000000 -0400
54956 @@ -27,6 +27,10 @@
54957 #include <net/inet_common.h>
54958 #include <net/xfrm.h>
54959
54960 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
54961 +extern int grsec_enable_blackhole;
54962 +#endif
54963 +
54964 int sysctl_tcp_syncookies __read_mostly = 1;
54965 EXPORT_SYMBOL(sysctl_tcp_syncookies);
54966
54967 @@ -700,6 +704,10 @@ listen_overflow:
54968
54969 embryonic_reset:
54970 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS);
54971 +
54972 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
54973 + if (!grsec_enable_blackhole)
54974 +#endif
54975 if (!(flg & TCP_FLAG_RST))
54976 req->rsk_ops->send_reset(sk, skb);
54977
54978 diff -urNp linux-2.6.36/net/ipv4/tcp_probe.c linux-2.6.36/net/ipv4/tcp_probe.c
54979 --- linux-2.6.36/net/ipv4/tcp_probe.c 2010-10-20 16:30:22.000000000 -0400
54980 +++ linux-2.6.36/net/ipv4/tcp_probe.c 2010-11-06 18:58:50.000000000 -0400
54981 @@ -202,7 +202,7 @@ static ssize_t tcpprobe_read(struct file
54982 if (cnt + width >= len)
54983 break;
54984
54985 - if (copy_to_user(buf + cnt, tbuf, width))
54986 + if (width > sizeof(tbuf) || copy_to_user(buf + cnt, tbuf, width))
54987 return -EFAULT;
54988 cnt += width;
54989 }
54990 diff -urNp linux-2.6.36/net/ipv4/tcp_timer.c linux-2.6.36/net/ipv4/tcp_timer.c
54991 --- linux-2.6.36/net/ipv4/tcp_timer.c 2010-10-20 16:30:22.000000000 -0400
54992 +++ linux-2.6.36/net/ipv4/tcp_timer.c 2010-11-06 19:10:03.000000000 -0400
54993 @@ -22,6 +22,10 @@
54994 #include <linux/gfp.h>
54995 #include <net/tcp.h>
54996
54997 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
54998 +extern int grsec_lastack_retries;
54999 +#endif
55000 +
55001 int sysctl_tcp_syn_retries __read_mostly = TCP_SYN_RETRIES;
55002 int sysctl_tcp_synack_retries __read_mostly = TCP_SYNACK_RETRIES;
55003 int sysctl_tcp_keepalive_time __read_mostly = TCP_KEEPALIVE_TIME;
55004 @@ -198,6 +202,13 @@ static int tcp_write_timeout(struct sock
55005 }
55006 }
55007
55008 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55009 + if ((sk->sk_state == TCP_LAST_ACK) &&
55010 + (grsec_lastack_retries > 0) &&
55011 + (grsec_lastack_retries < retry_until))
55012 + retry_until = grsec_lastack_retries;
55013 +#endif
55014 +
55015 if (retransmits_timed_out(sk, retry_until, syn_set)) {
55016 /* Has it gone just too far? */
55017 tcp_write_err(sk);
55018 diff -urNp linux-2.6.36/net/ipv4/udp.c linux-2.6.36/net/ipv4/udp.c
55019 --- linux-2.6.36/net/ipv4/udp.c 2010-10-20 16:30:22.000000000 -0400
55020 +++ linux-2.6.36/net/ipv4/udp.c 2010-11-06 18:58:50.000000000 -0400
55021 @@ -86,6 +86,7 @@
55022 #include <linux/types.h>
55023 #include <linux/fcntl.h>
55024 #include <linux/module.h>
55025 +#include <linux/security.h>
55026 #include <linux/socket.h>
55027 #include <linux/sockios.h>
55028 #include <linux/igmp.h>
55029 @@ -107,6 +108,10 @@
55030 #include <net/xfrm.h>
55031 #include "udp_impl.h"
55032
55033 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55034 +extern int grsec_enable_blackhole;
55035 +#endif
55036 +
55037 struct udp_table udp_table __read_mostly;
55038 EXPORT_SYMBOL(udp_table);
55039
55040 @@ -564,6 +569,9 @@ found:
55041 return s;
55042 }
55043
55044 +extern int gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb);
55045 +extern int gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr);
55046 +
55047 /*
55048 * This routine is called by the ICMP module when it gets some
55049 * sort of error condition. If err < 0 then the socket should
55050 @@ -832,9 +840,18 @@ int udp_sendmsg(struct kiocb *iocb, stru
55051 dport = usin->sin_port;
55052 if (dport == 0)
55053 return -EINVAL;
55054 +
55055 + err = gr_search_udp_sendmsg(sk, usin);
55056 + if (err)
55057 + return err;
55058 } else {
55059 if (sk->sk_state != TCP_ESTABLISHED)
55060 return -EDESTADDRREQ;
55061 +
55062 + err = gr_search_udp_sendmsg(sk, NULL);
55063 + if (err)
55064 + return err;
55065 +
55066 daddr = inet->inet_daddr;
55067 dport = inet->inet_dport;
55068 /* Open fast path for connected socket.
55069 @@ -1141,6 +1158,10 @@ try_again:
55070 if (!skb)
55071 goto out;
55072
55073 + err = gr_search_udp_recvmsg(sk, skb);
55074 + if (err)
55075 + goto out_free;
55076 +
55077 ulen = skb->len - sizeof(struct udphdr);
55078 if (len > ulen)
55079 len = ulen;
55080 @@ -1625,6 +1646,9 @@ int __udp4_lib_rcv(struct sk_buff *skb,
55081 goto csum_error;
55082
55083 UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
55084 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55085 + if (!grsec_enable_blackhole || (skb->dev->flags & IFF_LOOPBACK))
55086 +#endif
55087 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
55088
55089 /*
55090 @@ -2051,7 +2075,12 @@ static void udp4_format_sock(struct sock
55091 sk_wmem_alloc_get(sp),
55092 sk_rmem_alloc_get(sp),
55093 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
55094 - atomic_read(&sp->sk_refcnt), sp,
55095 + atomic_read(&sp->sk_refcnt),
55096 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55097 + NULL,
55098 +#else
55099 + sp,
55100 +#endif
55101 atomic_read(&sp->sk_drops), len);
55102 }
55103
55104 diff -urNp linux-2.6.36/net/ipv6/exthdrs.c linux-2.6.36/net/ipv6/exthdrs.c
55105 --- linux-2.6.36/net/ipv6/exthdrs.c 2010-10-20 16:30:22.000000000 -0400
55106 +++ linux-2.6.36/net/ipv6/exthdrs.c 2010-11-06 18:58:15.000000000 -0400
55107 @@ -634,7 +634,7 @@ static struct tlvtype_proc tlvprochopopt
55108 .type = IPV6_TLV_JUMBO,
55109 .func = ipv6_hop_jumbo,
55110 },
55111 - { -1, }
55112 + { -1, NULL }
55113 };
55114
55115 int ipv6_parse_hopopts(struct sk_buff *skb)
55116 diff -urNp linux-2.6.36/net/ipv6/netfilter/ip6_tables.c linux-2.6.36/net/ipv6/netfilter/ip6_tables.c
55117 --- linux-2.6.36/net/ipv6/netfilter/ip6_tables.c 2010-10-20 16:30:22.000000000 -0400
55118 +++ linux-2.6.36/net/ipv6/netfilter/ip6_tables.c 2010-11-06 18:58:50.000000000 -0400
55119 @@ -1137,6 +1137,7 @@ static int get_info(struct net *net, voi
55120 private = &tmp;
55121 }
55122 #endif
55123 + memset(&info, 0, sizeof(info));
55124 info.valid_hooks = t->valid_hooks;
55125 memcpy(info.hook_entry, private->hook_entry,
55126 sizeof(info.hook_entry));
55127 diff -urNp linux-2.6.36/net/ipv6/raw.c linux-2.6.36/net/ipv6/raw.c
55128 --- linux-2.6.36/net/ipv6/raw.c 2010-10-20 16:30:22.000000000 -0400
55129 +++ linux-2.6.36/net/ipv6/raw.c 2010-11-06 18:58:50.000000000 -0400
55130 @@ -601,7 +601,7 @@ out:
55131 return err;
55132 }
55133
55134 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
55135 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
55136 struct flowi *fl, struct dst_entry **dstp,
55137 unsigned int flags)
55138 {
55139 @@ -1243,7 +1243,13 @@ static void raw6_sock_seq_show(struct se
55140 0, 0L, 0,
55141 sock_i_uid(sp), 0,
55142 sock_i_ino(sp),
55143 - atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
55144 + atomic_read(&sp->sk_refcnt),
55145 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55146 + NULL,
55147 +#else
55148 + sp,
55149 +#endif
55150 + atomic_read(&sp->sk_drops));
55151 }
55152
55153 static int raw6_seq_show(struct seq_file *seq, void *v)
55154 diff -urNp linux-2.6.36/net/ipv6/tcp_ipv6.c linux-2.6.36/net/ipv6/tcp_ipv6.c
55155 --- linux-2.6.36/net/ipv6/tcp_ipv6.c 2010-10-20 16:30:22.000000000 -0400
55156 +++ linux-2.6.36/net/ipv6/tcp_ipv6.c 2010-11-06 18:58:50.000000000 -0400
55157 @@ -92,6 +92,10 @@ static struct tcp_md5sig_key *tcp_v6_md5
55158 }
55159 #endif
55160
55161 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55162 +extern int grsec_enable_blackhole;
55163 +#endif
55164 +
55165 static void tcp_v6_hash(struct sock *sk)
55166 {
55167 if (sk->sk_state != TCP_CLOSE) {
55168 @@ -1627,6 +1631,9 @@ static int tcp_v6_do_rcv(struct sock *sk
55169 return 0;
55170
55171 reset:
55172 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55173 + if (!grsec_enable_blackhole)
55174 +#endif
55175 tcp_v6_send_reset(sk, skb);
55176 discard:
55177 if (opt_skb)
55178 @@ -1706,12 +1713,20 @@ static int tcp_v6_rcv(struct sk_buff *sk
55179 TCP_SKB_CB(skb)->sacked = 0;
55180
55181 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
55182 - if (!sk)
55183 + if (!sk) {
55184 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55185 + ret = 1;
55186 +#endif
55187 goto no_tcp_socket;
55188 + }
55189
55190 process:
55191 - if (sk->sk_state == TCP_TIME_WAIT)
55192 + if (sk->sk_state == TCP_TIME_WAIT) {
55193 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55194 + ret = 2;
55195 +#endif
55196 goto do_time_wait;
55197 + }
55198
55199 if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) {
55200 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
55201 @@ -1759,6 +1774,10 @@ no_tcp_socket:
55202 bad_packet:
55203 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
55204 } else {
55205 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55206 + if (!grsec_enable_blackhole || (ret == 1 &&
55207 + (skb->dev->flags & IFF_LOOPBACK)))
55208 +#endif
55209 tcp_v6_send_reset(NULL, skb);
55210 }
55211
55212 @@ -1987,7 +2006,13 @@ static void get_openreq6(struct seq_file
55213 uid,
55214 0, /* non standard timer */
55215 0, /* open_requests have no inode */
55216 - 0, req);
55217 + 0,
55218 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55219 + NULL
55220 +#else
55221 + req
55222 +#endif
55223 + );
55224 }
55225
55226 static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
55227 @@ -2037,7 +2062,12 @@ static void get_tcp6_sock(struct seq_fil
55228 sock_i_uid(sp),
55229 icsk->icsk_probes_out,
55230 sock_i_ino(sp),
55231 - atomic_read(&sp->sk_refcnt), sp,
55232 + atomic_read(&sp->sk_refcnt),
55233 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55234 + NULL,
55235 +#else
55236 + sp,
55237 +#endif
55238 jiffies_to_clock_t(icsk->icsk_rto),
55239 jiffies_to_clock_t(icsk->icsk_ack.ato),
55240 (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
55241 @@ -2072,7 +2102,13 @@ static void get_timewait6_sock(struct se
55242 dest->s6_addr32[2], dest->s6_addr32[3], destp,
55243 tw->tw_substate, 0, 0,
55244 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
55245 - atomic_read(&tw->tw_refcnt), tw);
55246 + atomic_read(&tw->tw_refcnt),
55247 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55248 + NULL
55249 +#else
55250 + tw
55251 +#endif
55252 + );
55253 }
55254
55255 static int tcp6_seq_show(struct seq_file *seq, void *v)
55256 diff -urNp linux-2.6.36/net/ipv6/udp.c linux-2.6.36/net/ipv6/udp.c
55257 --- linux-2.6.36/net/ipv6/udp.c 2010-10-20 16:30:22.000000000 -0400
55258 +++ linux-2.6.36/net/ipv6/udp.c 2010-11-06 18:58:50.000000000 -0400
55259 @@ -50,6 +50,10 @@
55260 #include <linux/seq_file.h>
55261 #include "udp_impl.h"
55262
55263 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55264 +extern int grsec_enable_blackhole;
55265 +#endif
55266 +
55267 int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
55268 {
55269 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
55270 @@ -765,6 +769,9 @@ int __udp6_lib_rcv(struct sk_buff *skb,
55271 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS,
55272 proto == IPPROTO_UDPLITE);
55273
55274 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
55275 + if (!grsec_enable_blackhole || (skb->dev->flags & IFF_LOOPBACK))
55276 +#endif
55277 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
55278
55279 kfree_skb(skb);
55280 @@ -1399,7 +1406,12 @@ static void udp6_sock_seq_show(struct se
55281 0, 0L, 0,
55282 sock_i_uid(sp), 0,
55283 sock_i_ino(sp),
55284 - atomic_read(&sp->sk_refcnt), sp,
55285 + atomic_read(&sp->sk_refcnt),
55286 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55287 + NULL,
55288 +#else
55289 + sp,
55290 +#endif
55291 atomic_read(&sp->sk_drops));
55292 }
55293
55294 diff -urNp linux-2.6.36/net/irda/ircomm/ircomm_tty.c linux-2.6.36/net/irda/ircomm/ircomm_tty.c
55295 --- linux-2.6.36/net/irda/ircomm/ircomm_tty.c 2010-10-20 16:30:22.000000000 -0400
55296 +++ linux-2.6.36/net/irda/ircomm/ircomm_tty.c 2010-11-06 18:58:15.000000000 -0400
55297 @@ -281,16 +281,16 @@ static int ircomm_tty_block_til_ready(st
55298 add_wait_queue(&self->open_wait, &wait);
55299
55300 IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
55301 - __FILE__,__LINE__, tty->driver->name, self->open_count );
55302 + __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count) );
55303
55304 /* As far as I can see, we protect open_count - Jean II */
55305 spin_lock_irqsave(&self->spinlock, flags);
55306 if (!tty_hung_up_p(filp)) {
55307 extra_count = 1;
55308 - self->open_count--;
55309 + atomic_dec(&self->open_count);
55310 }
55311 spin_unlock_irqrestore(&self->spinlock, flags);
55312 - self->blocked_open++;
55313 + atomic_inc(&self->blocked_open);
55314
55315 while (1) {
55316 if (tty->termios->c_cflag & CBAUD) {
55317 @@ -330,7 +330,7 @@ static int ircomm_tty_block_til_ready(st
55318 }
55319
55320 IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
55321 - __FILE__,__LINE__, tty->driver->name, self->open_count );
55322 + __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count) );
55323
55324 schedule();
55325 }
55326 @@ -341,13 +341,13 @@ static int ircomm_tty_block_til_ready(st
55327 if (extra_count) {
55328 /* ++ is not atomic, so this should be protected - Jean II */
55329 spin_lock_irqsave(&self->spinlock, flags);
55330 - self->open_count++;
55331 + atomic_inc(&self->open_count);
55332 spin_unlock_irqrestore(&self->spinlock, flags);
55333 }
55334 - self->blocked_open--;
55335 + atomic_dec(&self->blocked_open);
55336
55337 IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
55338 - __FILE__,__LINE__, tty->driver->name, self->open_count);
55339 + __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count));
55340
55341 if (!retval)
55342 self->flags |= ASYNC_NORMAL_ACTIVE;
55343 @@ -416,14 +416,14 @@ static int ircomm_tty_open(struct tty_st
55344 }
55345 /* ++ is not atomic, so this should be protected - Jean II */
55346 spin_lock_irqsave(&self->spinlock, flags);
55347 - self->open_count++;
55348 + atomic_inc(&self->open_count);
55349
55350 tty->driver_data = self;
55351 self->tty = tty;
55352 spin_unlock_irqrestore(&self->spinlock, flags);
55353
55354 IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
55355 - self->line, self->open_count);
55356 + self->line, atomic_read(&self->open_count));
55357
55358 /* Not really used by us, but lets do it anyway */
55359 self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
55360 @@ -509,7 +509,7 @@ static void ircomm_tty_close(struct tty_
55361 return;
55362 }
55363
55364 - if ((tty->count == 1) && (self->open_count != 1)) {
55365 + if ((tty->count == 1) && (atomic_read(&self->open_count) != 1)) {
55366 /*
55367 * Uh, oh. tty->count is 1, which means that the tty
55368 * structure will be freed. state->count should always
55369 @@ -519,16 +519,16 @@ static void ircomm_tty_close(struct tty_
55370 */
55371 IRDA_DEBUG(0, "%s(), bad serial port count; "
55372 "tty->count is 1, state->count is %d\n", __func__ ,
55373 - self->open_count);
55374 - self->open_count = 1;
55375 + atomic_read(&self->open_count));
55376 + atomic_set(&self->open_count, 1);
55377 }
55378
55379 - if (--self->open_count < 0) {
55380 + if (atomic_dec_return(&self->open_count) < 0) {
55381 IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
55382 - __func__, self->line, self->open_count);
55383 - self->open_count = 0;
55384 + __func__, self->line, atomic_read(&self->open_count));
55385 + atomic_set(&self->open_count, 0);
55386 }
55387 - if (self->open_count) {
55388 + if (atomic_read(&self->open_count)) {
55389 spin_unlock_irqrestore(&self->spinlock, flags);
55390
55391 IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
55392 @@ -560,7 +560,7 @@ static void ircomm_tty_close(struct tty_
55393 tty->closing = 0;
55394 self->tty = NULL;
55395
55396 - if (self->blocked_open) {
55397 + if (atomic_read(&self->blocked_open)) {
55398 if (self->close_delay)
55399 schedule_timeout_interruptible(self->close_delay);
55400 wake_up_interruptible(&self->open_wait);
55401 @@ -1012,7 +1012,7 @@ static void ircomm_tty_hangup(struct tty
55402 spin_lock_irqsave(&self->spinlock, flags);
55403 self->flags &= ~ASYNC_NORMAL_ACTIVE;
55404 self->tty = NULL;
55405 - self->open_count = 0;
55406 + atomic_set(&self->open_count, 0);
55407 spin_unlock_irqrestore(&self->spinlock, flags);
55408
55409 wake_up_interruptible(&self->open_wait);
55410 @@ -1364,7 +1364,7 @@ static void ircomm_tty_line_info(struct
55411 seq_putc(m, '\n');
55412
55413 seq_printf(m, "Role: %s\n", self->client ? "client" : "server");
55414 - seq_printf(m, "Open count: %d\n", self->open_count);
55415 + seq_printf(m, "Open count: %d\n", atomic_read(&self->open_count));
55416 seq_printf(m, "Max data size: %d\n", self->max_data_size);
55417 seq_printf(m, "Max header size: %d\n", self->max_header_size);
55418
55419 diff -urNp linux-2.6.36/net/key/af_key.c linux-2.6.36/net/key/af_key.c
55420 --- linux-2.6.36/net/key/af_key.c 2010-10-20 16:30:22.000000000 -0400
55421 +++ linux-2.6.36/net/key/af_key.c 2010-11-06 18:58:50.000000000 -0400
55422 @@ -3644,7 +3644,11 @@ static int pfkey_seq_show(struct seq_fil
55423 seq_printf(f ,"sk RefCnt Rmem Wmem User Inode\n");
55424 else
55425 seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n",
55426 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55427 + NULL,
55428 +#else
55429 s,
55430 +#endif
55431 atomic_read(&s->sk_refcnt),
55432 sk_rmem_alloc_get(s),
55433 sk_wmem_alloc_get(s),
55434 diff -urNp linux-2.6.36/net/mac80211/ieee80211_i.h linux-2.6.36/net/mac80211/ieee80211_i.h
55435 --- linux-2.6.36/net/mac80211/ieee80211_i.h 2010-10-20 16:30:22.000000000 -0400
55436 +++ linux-2.6.36/net/mac80211/ieee80211_i.h 2010-11-06 18:58:15.000000000 -0400
55437 @@ -650,7 +650,7 @@ struct ieee80211_local {
55438 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
55439 spinlock_t queue_stop_reason_lock;
55440
55441 - int open_count;
55442 + atomic_t open_count;
55443 int monitors, cooked_mntrs;
55444 /* number of interfaces with corresponding FIF_ flags */
55445 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
55446 diff -urNp linux-2.6.36/net/mac80211/iface.c linux-2.6.36/net/mac80211/iface.c
55447 --- linux-2.6.36/net/mac80211/iface.c 2010-10-20 16:30:22.000000000 -0400
55448 +++ linux-2.6.36/net/mac80211/iface.c 2010-11-06 18:58:15.000000000 -0400
55449 @@ -183,7 +183,7 @@ static int ieee80211_open(struct net_dev
55450 break;
55451 }
55452
55453 - if (local->open_count == 0) {
55454 + if (atomic_read(&local->open_count) == 0) {
55455 res = drv_start(local);
55456 if (res)
55457 goto err_del_bss;
55458 @@ -215,7 +215,7 @@ static int ieee80211_open(struct net_dev
55459 * Validate the MAC address for this device.
55460 */
55461 if (!is_valid_ether_addr(dev->dev_addr)) {
55462 - if (!local->open_count)
55463 + if (!atomic_read(&local->open_count))
55464 drv_stop(local);
55465 return -EADDRNOTAVAIL;
55466 }
55467 @@ -309,7 +309,7 @@ static int ieee80211_open(struct net_dev
55468
55469 hw_reconf_flags |= __ieee80211_recalc_idle(local);
55470
55471 - local->open_count++;
55472 + atomic_inc(&local->open_count);
55473 if (hw_reconf_flags) {
55474 ieee80211_hw_config(local, hw_reconf_flags);
55475 /*
55476 @@ -328,7 +328,7 @@ static int ieee80211_open(struct net_dev
55477 err_del_interface:
55478 drv_remove_interface(local, &sdata->vif);
55479 err_stop:
55480 - if (!local->open_count)
55481 + if (!atomic_read(&local->open_count))
55482 drv_stop(local);
55483 err_del_bss:
55484 sdata->bss = NULL;
55485 @@ -418,7 +418,7 @@ static int ieee80211_stop(struct net_dev
55486 WARN_ON(!list_empty(&sdata->u.ap.vlans));
55487 }
55488
55489 - local->open_count--;
55490 + atomic_dec(&local->open_count);
55491
55492 switch (sdata->vif.type) {
55493 case NL80211_IFTYPE_AP_VLAN:
55494 @@ -518,7 +518,7 @@ static int ieee80211_stop(struct net_dev
55495
55496 ieee80211_recalc_ps(local, -1);
55497
55498 - if (local->open_count == 0) {
55499 + if (atomic_read(&local->open_count) == 0) {
55500 ieee80211_clear_tx_pending(local);
55501 ieee80211_stop_device(local);
55502
55503 diff -urNp linux-2.6.36/net/mac80211/main.c linux-2.6.36/net/mac80211/main.c
55504 --- linux-2.6.36/net/mac80211/main.c 2010-10-20 16:30:22.000000000 -0400
55505 +++ linux-2.6.36/net/mac80211/main.c 2010-11-06 18:58:15.000000000 -0400
55506 @@ -152,7 +152,7 @@ int ieee80211_hw_config(struct ieee80211
55507 local->hw.conf.power_level = power;
55508 }
55509
55510 - if (changed && local->open_count) {
55511 + if (changed && atomic_read(&local->open_count)) {
55512 ret = drv_config(local, changed);
55513 /*
55514 * Goal:
55515 diff -urNp linux-2.6.36/net/mac80211/pm.c linux-2.6.36/net/mac80211/pm.c
55516 --- linux-2.6.36/net/mac80211/pm.c 2010-10-20 16:30:22.000000000 -0400
55517 +++ linux-2.6.36/net/mac80211/pm.c 2010-11-06 18:58:15.000000000 -0400
55518 @@ -95,7 +95,7 @@ int __ieee80211_suspend(struct ieee80211
55519 }
55520
55521 /* stop hardware - this must stop RX */
55522 - if (local->open_count)
55523 + if (atomic_read(&local->open_count))
55524 ieee80211_stop_device(local);
55525
55526 local->suspended = true;
55527 diff -urNp linux-2.6.36/net/mac80211/rate.c linux-2.6.36/net/mac80211/rate.c
55528 --- linux-2.6.36/net/mac80211/rate.c 2010-10-20 16:30:22.000000000 -0400
55529 +++ linux-2.6.36/net/mac80211/rate.c 2010-11-06 18:58:15.000000000 -0400
55530 @@ -357,7 +357,7 @@ int ieee80211_init_rate_ctrl_alg(struct
55531
55532 ASSERT_RTNL();
55533
55534 - if (local->open_count)
55535 + if (atomic_read(&local->open_count))
55536 return -EBUSY;
55537
55538 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) {
55539 diff -urNp linux-2.6.36/net/mac80211/rc80211_pid_debugfs.c linux-2.6.36/net/mac80211/rc80211_pid_debugfs.c
55540 --- linux-2.6.36/net/mac80211/rc80211_pid_debugfs.c 2010-10-20 16:30:22.000000000 -0400
55541 +++ linux-2.6.36/net/mac80211/rc80211_pid_debugfs.c 2010-11-06 18:58:15.000000000 -0400
55542 @@ -192,7 +192,7 @@ static ssize_t rate_control_pid_events_r
55543
55544 spin_unlock_irqrestore(&events->lock, status);
55545
55546 - if (copy_to_user(buf, pb, p))
55547 + if (p > sizeof(pb) || copy_to_user(buf, pb, p))
55548 return -EFAULT;
55549
55550 return p;
55551 diff -urNp linux-2.6.36/net/mac80211/tx.c linux-2.6.36/net/mac80211/tx.c
55552 --- linux-2.6.36/net/mac80211/tx.c 2010-10-20 16:30:22.000000000 -0400
55553 +++ linux-2.6.36/net/mac80211/tx.c 2010-11-06 18:58:15.000000000 -0400
55554 @@ -173,7 +173,7 @@ static __le16 ieee80211_duration(struct
55555 return cpu_to_le16(dur);
55556 }
55557
55558 -static int inline is_ieee80211_device(struct ieee80211_local *local,
55559 +static inline int is_ieee80211_device(struct ieee80211_local *local,
55560 struct net_device *dev)
55561 {
55562 return local == wdev_priv(dev->ieee80211_ptr);
55563 diff -urNp linux-2.6.36/net/mac80211/util.c linux-2.6.36/net/mac80211/util.c
55564 --- linux-2.6.36/net/mac80211/util.c 2010-10-20 16:30:22.000000000 -0400
55565 +++ linux-2.6.36/net/mac80211/util.c 2010-11-06 18:58:15.000000000 -0400
55566 @@ -1101,7 +1101,7 @@ int ieee80211_reconfig(struct ieee80211_
55567 local->resuming = true;
55568
55569 /* restart hardware */
55570 - if (local->open_count) {
55571 + if (atomic_read(&local->open_count)) {
55572 /*
55573 * Upon resume hardware can sometimes be goofy due to
55574 * various platform / driver / bus issues, so restarting
55575 diff -urNp linux-2.6.36/net/netfilter/Kconfig linux-2.6.36/net/netfilter/Kconfig
55576 --- linux-2.6.36/net/netfilter/Kconfig 2010-10-20 16:30:22.000000000 -0400
55577 +++ linux-2.6.36/net/netfilter/Kconfig 2010-11-06 18:58:50.000000000 -0400
55578 @@ -708,6 +708,16 @@ config NETFILTER_XT_MATCH_ESP
55579
55580 To compile it as a module, choose M here. If unsure, say N.
55581
55582 +config NETFILTER_XT_MATCH_GRADM
55583 + tristate '"gradm" match support'
55584 + depends on NETFILTER_XTABLES && NETFILTER_ADVANCED
55585 + depends on GRKERNSEC && !GRKERNSEC_NO_RBAC
55586 + ---help---
55587 + The gradm match allows to match on grsecurity RBAC being enabled.
55588 + It is useful when iptables rules are applied early on bootup to
55589 + prevent connections to the machine (except from a trusted host)
55590 + while the RBAC system is disabled.
55591 +
55592 config NETFILTER_XT_MATCH_HASHLIMIT
55593 tristate '"hashlimit" match support'
55594 depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
55595 diff -urNp linux-2.6.36/net/netfilter/Makefile linux-2.6.36/net/netfilter/Makefile
55596 --- linux-2.6.36/net/netfilter/Makefile 2010-10-20 16:30:22.000000000 -0400
55597 +++ linux-2.6.36/net/netfilter/Makefile 2010-11-06 18:58:50.000000000 -0400
55598 @@ -74,6 +74,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CPU) +=
55599 obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
55600 obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
55601 obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
55602 +obj-$(CONFIG_NETFILTER_XT_MATCH_GRADM) += xt_gradm.o
55603 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
55604 obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
55605 obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o
55606 diff -urNp linux-2.6.36/net/netfilter/xt_gradm.c linux-2.6.36/net/netfilter/xt_gradm.c
55607 --- linux-2.6.36/net/netfilter/xt_gradm.c 1969-12-31 19:00:00.000000000 -0500
55608 +++ linux-2.6.36/net/netfilter/xt_gradm.c 2010-11-06 18:58:50.000000000 -0400
55609 @@ -0,0 +1,51 @@
55610 +/*
55611 + * gradm match for netfilter
55612 + * Copyright © Zbigniew Krzystolik, 2010
55613 + *
55614 + * This program is free software; you can redistribute it and/or modify
55615 + * it under the terms of the GNU General Public License; either version
55616 + * 2 or 3 as published by the Free Software Foundation.
55617 + */
55618 +#include <linux/module.h>
55619 +#include <linux/moduleparam.h>
55620 +#include <linux/skbuff.h>
55621 +#include <linux/netfilter/x_tables.h>
55622 +#include <linux/grsecurity.h>
55623 +#include <linux/netfilter/xt_gradm.h>
55624 +
55625 +static bool
55626 +gradm_mt(const struct sk_buff *skb, struct xt_action_param *par)
55627 +{
55628 + const struct xt_gradm_mtinfo *info = par->matchinfo;
55629 + bool retval = false;
55630 + if (gr_acl_is_enabled())
55631 + retval = true;
55632 + return retval ^ info->invflags;
55633 +}
55634 +
55635 +static struct xt_match gradm_mt_reg __read_mostly = {
55636 + .name = "gradm",
55637 + .revision = 0,
55638 + .family = NFPROTO_UNSPEC,
55639 + .match = gradm_mt,
55640 + .matchsize = XT_ALIGN(sizeof(struct xt_gradm_mtinfo)),
55641 + .me = THIS_MODULE,
55642 +};
55643 +
55644 +static int __init gradm_mt_init(void)
55645 +{
55646 + return xt_register_match(&gradm_mt_reg);
55647 +}
55648 +
55649 +static void __exit gradm_mt_exit(void)
55650 +{
55651 + xt_unregister_match(&gradm_mt_reg);
55652 +}
55653 +
55654 +module_init(gradm_mt_init);
55655 +module_exit(gradm_mt_exit);
55656 +MODULE_AUTHOR("Zbigniew Krzystolik <zbyniu@destrukcja.pl>");
55657 +MODULE_DESCRIPTION("Xtables: Grsecurity RBAC match");
55658 +MODULE_LICENSE("GPL");
55659 +MODULE_ALIAS("ipt_gradm");
55660 +MODULE_ALIAS("ip6t_gradm");
55661 diff -urNp linux-2.6.36/net/netlink/af_netlink.c linux-2.6.36/net/netlink/af_netlink.c
55662 --- linux-2.6.36/net/netlink/af_netlink.c 2010-10-20 16:30:22.000000000 -0400
55663 +++ linux-2.6.36/net/netlink/af_netlink.c 2010-11-06 18:58:50.000000000 -0400
55664 @@ -2007,13 +2007,21 @@ static int netlink_seq_show(struct seq_f
55665 struct netlink_sock *nlk = nlk_sk(s);
55666
55667 seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %-8d %-8d %-8lu\n",
55668 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55669 + NULL,
55670 +#else
55671 s,
55672 +#endif
55673 s->sk_protocol,
55674 nlk->pid,
55675 nlk->groups ? (u32)nlk->groups[0] : 0,
55676 sk_rmem_alloc_get(s),
55677 sk_wmem_alloc_get(s),
55678 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55679 + NULL,
55680 +#else
55681 nlk->cb,
55682 +#endif
55683 atomic_read(&s->sk_refcnt),
55684 atomic_read(&s->sk_drops),
55685 sock_i_ino(s)
55686 diff -urNp linux-2.6.36/net/netrom/af_netrom.c linux-2.6.36/net/netrom/af_netrom.c
55687 --- linux-2.6.36/net/netrom/af_netrom.c 2010-10-20 16:30:22.000000000 -0400
55688 +++ linux-2.6.36/net/netrom/af_netrom.c 2010-11-06 18:58:50.000000000 -0400
55689 @@ -840,6 +840,7 @@ static int nr_getname(struct socket *soc
55690 struct sock *sk = sock->sk;
55691 struct nr_sock *nr = nr_sk(sk);
55692
55693 + memset(sax, 0, sizeof(*sax));
55694 lock_sock(sk);
55695 if (peer != 0) {
55696 if (sk->sk_state != TCP_ESTABLISHED) {
55697 @@ -854,7 +855,6 @@ static int nr_getname(struct socket *soc
55698 *uaddr_len = sizeof(struct full_sockaddr_ax25);
55699 } else {
55700 sax->fsa_ax25.sax25_family = AF_NETROM;
55701 - sax->fsa_ax25.sax25_ndigis = 0;
55702 sax->fsa_ax25.sax25_call = nr->source_addr;
55703 *uaddr_len = sizeof(struct sockaddr_ax25);
55704 }
55705 diff -urNp linux-2.6.36/net/packet/af_packet.c linux-2.6.36/net/packet/af_packet.c
55706 --- linux-2.6.36/net/packet/af_packet.c 2010-10-20 16:30:22.000000000 -0400
55707 +++ linux-2.6.36/net/packet/af_packet.c 2010-11-06 18:58:50.000000000 -0400
55708 @@ -1610,8 +1610,9 @@ static int packet_recvmsg(struct kiocb *
55709
55710 err = -EINVAL;
55711 vnet_hdr_len = sizeof(vnet_hdr);
55712 - if ((len -= vnet_hdr_len) < 0)
55713 + if (len < vnet_hdr_len)
55714 goto out_free;
55715 + len -= vnet_hdr_len;
55716
55717 if (skb_is_gso(skb)) {
55718 struct skb_shared_info *sinfo = skb_shinfo(skb);
55719 @@ -1719,7 +1720,7 @@ static int packet_getname_spkt(struct so
55720 rcu_read_lock();
55721 dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex);
55722 if (dev)
55723 - strlcpy(uaddr->sa_data, dev->name, 15);
55724 + strncpy(uaddr->sa_data, dev->name, 14);
55725 else
55726 memset(uaddr->sa_data, 0, 14);
55727 rcu_read_unlock();
55728 @@ -1742,6 +1743,7 @@ static int packet_getname(struct socket
55729 sll->sll_family = AF_PACKET;
55730 sll->sll_ifindex = po->ifindex;
55731 sll->sll_protocol = po->num;
55732 + sll->sll_pkttype = 0;
55733 rcu_read_lock();
55734 dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex);
55735 if (dev) {
55736 @@ -2120,7 +2122,7 @@ static int packet_getsockopt(struct sock
55737 case PACKET_HDRLEN:
55738 if (len > sizeof(int))
55739 len = sizeof(int);
55740 - if (copy_from_user(&val, optval, len))
55741 + if (len > sizeof(val) || copy_from_user(&val, optval, len))
55742 return -EFAULT;
55743 switch (val) {
55744 case TPACKET_V1:
55745 @@ -2158,7 +2160,7 @@ static int packet_getsockopt(struct sock
55746
55747 if (put_user(len, optlen))
55748 return -EFAULT;
55749 - if (copy_to_user(optval, data, len))
55750 + if (len > sizeof(st) || copy_to_user(optval, data, len))
55751 return -EFAULT;
55752 return 0;
55753 }
55754 @@ -2637,7 +2639,11 @@ static int packet_seq_show(struct seq_fi
55755
55756 seq_printf(seq,
55757 "%p %-6d %-4d %04x %-5d %1d %-6u %-6u %-6lu\n",
55758 +#ifdef CONFIG_GRKERNSEC_HIDESYM
55759 + NULL,
55760 +#else
55761 s,
55762 +#endif
55763 atomic_read(&s->sk_refcnt),
55764 s->sk_type,
55765 ntohs(po->num),
55766 diff -urNp linux-2.6.36/net/phonet/af_phonet.c linux-2.6.36/net/phonet/af_phonet.c
55767 --- linux-2.6.36/net/phonet/af_phonet.c 2010-10-20 16:30:22.000000000 -0400
55768 +++ linux-2.6.36/net/phonet/af_phonet.c 2010-11-06 18:58:50.000000000 -0400
55769 @@ -41,7 +41,7 @@ static struct phonet_protocol *phonet_pr
55770 {
55771 struct phonet_protocol *pp;
55772
55773 - if (protocol >= PHONET_NPROTO)
55774 + if (protocol < 0 || protocol >= PHONET_NPROTO)
55775 return NULL;
55776
55777 rcu_read_lock();
55778 @@ -446,7 +446,7 @@ int __init_or_module phonet_proto_regist
55779 {
55780 int err = 0;
55781
55782 - if (protocol >= PHONET_NPROTO)
55783 + if (protocol < 0 || protocol >= PHONET_NPROTO)
55784 return -EINVAL;
55785
55786 err = proto_register(pp->prot, 1);
55787 diff -urNp linux-2.6.36/net/sctp/socket.c linux-2.6.36/net/sctp/socket.c
55788 --- linux-2.6.36/net/sctp/socket.c 2010-10-20 16:30:22.000000000 -0400
55789 +++ linux-2.6.36/net/sctp/socket.c 2010-11-06 18:58:15.000000000 -0400
55790 @@ -1494,7 +1494,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
55791 struct sctp_sndrcvinfo *sinfo;
55792 struct sctp_initmsg *sinit;
55793 sctp_assoc_t associd = 0;
55794 - sctp_cmsgs_t cmsgs = { NULL };
55795 + sctp_cmsgs_t cmsgs = { NULL, NULL };
55796 int err;
55797 sctp_scope_t scope;
55798 long timeo;
55799 @@ -4398,7 +4398,7 @@ static int sctp_getsockopt_peer_addrs(st
55800 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
55801 if (space_left < addrlen)
55802 return -ENOMEM;
55803 - if (copy_to_user(to, &temp, addrlen))
55804 + if (addrlen > sizeof(temp) || copy_to_user(to, &temp, addrlen))
55805 return -EFAULT;
55806 to += addrlen;
55807 cnt++;
55808 diff -urNp linux-2.6.36/net/socket.c linux-2.6.36/net/socket.c
55809 --- linux-2.6.36/net/socket.c 2010-10-20 16:30:22.000000000 -0400
55810 +++ linux-2.6.36/net/socket.c 2010-11-06 18:58:50.000000000 -0400
55811 @@ -88,6 +88,7 @@
55812 #include <linux/nsproxy.h>
55813 #include <linux/magic.h>
55814 #include <linux/slab.h>
55815 +#include <linux/in.h>
55816
55817 #include <asm/uaccess.h>
55818 #include <asm/unistd.h>
55819 @@ -105,6 +106,8 @@
55820 #include <linux/sockios.h>
55821 #include <linux/atalk.h>
55822
55823 +#include <linux/grsock.h>
55824 +
55825 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
55826 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
55827 unsigned long nr_segs, loff_t pos);
55828 @@ -313,7 +316,7 @@ static int sockfs_get_sb(struct file_sys
55829 mnt);
55830 }
55831
55832 -static struct vfsmount *sock_mnt __read_mostly;
55833 +struct vfsmount *sock_mnt __read_mostly;
55834
55835 static struct file_system_type sock_fs_type = {
55836 .name = "sockfs",
55837 @@ -1158,6 +1161,8 @@ static int __sock_create(struct net *net
55838 return -EAFNOSUPPORT;
55839 if (type < 0 || type >= SOCK_MAX)
55840 return -EINVAL;
55841 + if (protocol < 0)
55842 + return -EINVAL;
55843
55844 /* Compatibility.
55845
55846 @@ -1289,6 +1294,16 @@ SYSCALL_DEFINE3(socket, int, family, int
55847 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
55848 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
55849
55850 + if(!gr_search_socket(family, type, protocol)) {
55851 + retval = -EACCES;
55852 + goto out;
55853 + }
55854 +
55855 + if (gr_handle_sock_all(family, type, protocol)) {
55856 + retval = -EACCES;
55857 + goto out;
55858 + }
55859 +
55860 retval = sock_create(family, type, protocol, &sock);
55861 if (retval < 0)
55862 goto out;
55863 @@ -1401,6 +1416,14 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
55864 if (sock) {
55865 err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
55866 if (err >= 0) {
55867 + if (gr_handle_sock_server((struct sockaddr *)&address)) {
55868 + err = -EACCES;
55869 + goto error;
55870 + }
55871 + err = gr_search_bind(sock, (struct sockaddr_in *)&address);
55872 + if (err)
55873 + goto error;
55874 +
55875 err = security_socket_bind(sock,
55876 (struct sockaddr *)&address,
55877 addrlen);
55878 @@ -1409,6 +1432,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
55879 (struct sockaddr *)
55880 &address, addrlen);
55881 }
55882 +error:
55883 fput_light(sock->file, fput_needed);
55884 }
55885 return err;
55886 @@ -1432,10 +1456,20 @@ SYSCALL_DEFINE2(listen, int, fd, int, ba
55887 if ((unsigned)backlog > somaxconn)
55888 backlog = somaxconn;
55889
55890 + if (gr_handle_sock_server_other(sock->sk)) {
55891 + err = -EPERM;
55892 + goto error;
55893 + }
55894 +
55895 + err = gr_search_listen(sock);
55896 + if (err)
55897 + goto error;
55898 +
55899 err = security_socket_listen(sock, backlog);
55900 if (!err)
55901 err = sock->ops->listen(sock, backlog);
55902
55903 +error:
55904 fput_light(sock->file, fput_needed);
55905 }
55906 return err;
55907 @@ -1479,6 +1513,18 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
55908 newsock->type = sock->type;
55909 newsock->ops = sock->ops;
55910
55911 + if (gr_handle_sock_server_other(sock->sk)) {
55912 + err = -EPERM;
55913 + sock_release(newsock);
55914 + goto out_put;
55915 + }
55916 +
55917 + err = gr_search_accept(sock);
55918 + if (err) {
55919 + sock_release(newsock);
55920 + goto out_put;
55921 + }
55922 +
55923 /*
55924 * We don't need try_module_get here, as the listening socket (sock)
55925 * has the protocol module (sock->ops->owner) held.
55926 @@ -1517,6 +1563,8 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
55927 fd_install(newfd, newfile);
55928 err = newfd;
55929
55930 + gr_attach_curr_ip(newsock->sk);
55931 +
55932 out_put:
55933 fput_light(sock->file, fput_needed);
55934 out:
55935 @@ -1549,6 +1597,7 @@ SYSCALL_DEFINE3(connect, int, fd, struct
55936 int, addrlen)
55937 {
55938 struct socket *sock;
55939 + struct sockaddr *sck;
55940 struct sockaddr_storage address;
55941 int err, fput_needed;
55942
55943 @@ -1559,6 +1608,17 @@ SYSCALL_DEFINE3(connect, int, fd, struct
55944 if (err < 0)
55945 goto out_put;
55946
55947 + sck = (struct sockaddr *)&address;
55948 +
55949 + if (gr_handle_sock_client(sck)) {
55950 + err = -EACCES;
55951 + goto out_put;
55952 + }
55953 +
55954 + err = gr_search_connect(sock, (struct sockaddr_in *)sck);
55955 + if (err)
55956 + goto out_put;
55957 +
55958 err =
55959 security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
55960 if (err)
55961 diff -urNp linux-2.6.36/net/sunrpc/sched.c linux-2.6.36/net/sunrpc/sched.c
55962 --- linux-2.6.36/net/sunrpc/sched.c 2010-10-20 16:30:22.000000000 -0400
55963 +++ linux-2.6.36/net/sunrpc/sched.c 2010-11-06 18:58:15.000000000 -0400
55964 @@ -234,9 +234,9 @@ static int rpc_wait_bit_killable(void *w
55965 #ifdef RPC_DEBUG
55966 static void rpc_task_set_debuginfo(struct rpc_task *task)
55967 {
55968 - static atomic_t rpc_pid;
55969 + static atomic_unchecked_t rpc_pid;
55970
55971 - task->tk_pid = atomic_inc_return(&rpc_pid);
55972 + task->tk_pid = atomic_inc_return_unchecked(&rpc_pid);
55973 }
55974 #else
55975 static inline void rpc_task_set_debuginfo(struct rpc_task *task)
55976 diff -urNp linux-2.6.36/net/sunrpc/xprtrdma/svc_rdma.c linux-2.6.36/net/sunrpc/xprtrdma/svc_rdma.c
55977 --- linux-2.6.36/net/sunrpc/xprtrdma/svc_rdma.c 2010-10-20 16:30:22.000000000 -0400
55978 +++ linux-2.6.36/net/sunrpc/xprtrdma/svc_rdma.c 2010-11-06 18:58:50.000000000 -0400
55979 @@ -106,7 +106,7 @@ static int read_reset_stat(ctl_table *ta
55980 len -= *ppos;
55981 if (len > *lenp)
55982 len = *lenp;
55983 - if (len && copy_to_user(buffer, str_buf, len))
55984 + if (len > sizeof(str_buf) || (len && copy_to_user(buffer, str_buf, len)))
55985 return -EFAULT;
55986 *lenp = len;
55987 *ppos += len;
55988 diff -urNp linux-2.6.36/net/sysctl_net.c linux-2.6.36/net/sysctl_net.c
55989 --- linux-2.6.36/net/sysctl_net.c 2010-10-20 16:30:22.000000000 -0400
55990 +++ linux-2.6.36/net/sysctl_net.c 2010-11-06 18:58:50.000000000 -0400
55991 @@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ct
55992 struct ctl_table *table)
55993 {
55994 /* Allow network administrator to have same access as root. */
55995 - if (capable(CAP_NET_ADMIN)) {
55996 + if (capable_nolog(CAP_NET_ADMIN)) {
55997 int mode = (table->mode >> 6) & 7;
55998 return (mode << 6) | (mode << 3) | mode;
55999 }
56000 diff -urNp linux-2.6.36/net/tipc/socket.c linux-2.6.36/net/tipc/socket.c
56001 --- linux-2.6.36/net/tipc/socket.c 2010-10-20 16:30:22.000000000 -0400
56002 +++ linux-2.6.36/net/tipc/socket.c 2010-11-06 18:58:50.000000000 -0400
56003 @@ -395,6 +395,7 @@ static int get_name(struct socket *sock,
56004 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
56005 struct tipc_sock *tsock = tipc_sk(sock->sk);
56006
56007 + memset(addr, 0, sizeof(*addr));
56008 if (peer) {
56009 if ((sock->state != SS_CONNECTED) &&
56010 ((peer != 2) || (sock->state != SS_DISCONNECTING)))
56011 @@ -1451,8 +1452,9 @@ static int connect(struct socket *sock,
56012 } else {
56013 if (res == 0)
56014 res = -ETIMEDOUT;
56015 - else
56016 - ; /* leave "res" unchanged */
56017 + else {
56018 + /* leave "res" unchanged */
56019 + }
56020 sock->state = SS_DISCONNECTING;
56021 }
56022
56023 diff -urNp linux-2.6.36/net/unix/af_unix.c linux-2.6.36/net/unix/af_unix.c
56024 --- linux-2.6.36/net/unix/af_unix.c 2010-10-20 16:30:22.000000000 -0400
56025 +++ linux-2.6.36/net/unix/af_unix.c 2010-11-06 20:08:14.000000000 -0400
56026 @@ -764,6 +764,12 @@ static struct sock *unix_find_other(stru
56027 err = -ECONNREFUSED;
56028 if (!S_ISSOCK(inode->i_mode))
56029 goto put_fail;
56030 +
56031 + if (!gr_acl_handle_unix(path.dentry, path.mnt)) {
56032 + err = -EACCES;
56033 + goto put_fail;
56034 + }
56035 +
56036 u = unix_find_socket_byinode(inode);
56037 if (!u)
56038 goto put_fail;
56039 @@ -784,6 +790,13 @@ static struct sock *unix_find_other(stru
56040 if (u) {
56041 struct dentry *dentry;
56042 dentry = unix_sk(u)->dentry;
56043 +
56044 + if (!gr_handle_chroot_unix(u->sk_peer_pid)) {
56045 + err = -EPERM;
56046 + sock_put(u);
56047 + goto fail;
56048 + }
56049 +
56050 if (dentry)
56051 touch_atime(unix_sk(u)->mnt, dentry);
56052 } else
56053 @@ -869,11 +882,18 @@ static int unix_bind(struct socket *sock
56054 err = security_path_mknod(&nd.path, dentry, mode, 0);
56055 if (err)
56056 goto out_mknod_drop_write;
56057 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
56058 + err = -EACCES;
56059 + goto out_mknod_drop_write;
56060 + }
56061 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
56062 out_mknod_drop_write:
56063 mnt_drop_write(nd.path.mnt);
56064 if (err)
56065 goto out_mknod_dput;
56066 +
56067 + gr_handle_create(dentry, nd.path.mnt);
56068 +
56069 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
56070 dput(nd.path.dentry);
56071 nd.path.dentry = dentry;
56072 @@ -891,6 +911,11 @@ out_mknod_drop_write:
56073 goto out_unlock;
56074 }
56075
56076 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
56077 + put_pid(sk->sk_peer_pid);
56078 + sk->sk_peer_pid = get_pid(task_tgid(current));
56079 +#endif
56080 +
56081 list = &unix_socket_table[addr->hash];
56082 } else {
56083 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
56084 @@ -2195,7 +2220,11 @@ static int unix_seq_show(struct seq_file
56085 unix_state_lock(s);
56086
56087 seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
56088 +#ifdef CONFIG_GRKERNSEC_HIDESYM
56089 + NULL,
56090 +#else
56091 s,
56092 +#endif
56093 atomic_read(&s->sk_refcnt),
56094 0,
56095 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
56096 diff -urNp linux-2.6.36/net/wireless/reg.c linux-2.6.36/net/wireless/reg.c
56097 --- linux-2.6.36/net/wireless/reg.c 2010-10-20 16:30:22.000000000 -0400
56098 +++ linux-2.6.36/net/wireless/reg.c 2010-11-06 18:58:15.000000000 -0400
56099 @@ -50,7 +50,7 @@
56100 printk(KERN_DEBUG format , ## args); \
56101 } while (0)
56102 #else
56103 -#define REG_DBG_PRINT(args...)
56104 +#define REG_DBG_PRINT(args...) do {} while (0)
56105 #endif
56106
56107 /* Receipt of information from last regulatory request */
56108 diff -urNp linux-2.6.36/net/wireless/wext-core.c linux-2.6.36/net/wireless/wext-core.c
56109 --- linux-2.6.36/net/wireless/wext-core.c 2010-10-20 16:30:22.000000000 -0400
56110 +++ linux-2.6.36/net/wireless/wext-core.c 2010-11-06 18:58:15.000000000 -0400
56111 @@ -744,8 +744,7 @@ static int ioctl_standard_iw_point(struc
56112 */
56113
56114 /* Support for very large requests */
56115 - if ((descr->flags & IW_DESCR_FLAG_NOMAX) &&
56116 - (user_length > descr->max_tokens)) {
56117 + if (user_length > descr->max_tokens) {
56118 /* Allow userspace to GET more than max so
56119 * we can support any size GET requests.
56120 * There is still a limit : -ENOMEM.
56121 @@ -782,22 +781,6 @@ static int ioctl_standard_iw_point(struc
56122 }
56123 }
56124
56125 - if (IW_IS_GET(cmd) && !(descr->flags & IW_DESCR_FLAG_NOMAX)) {
56126 - /*
56127 - * If this is a GET, but not NOMAX, it means that the extra
56128 - * data is not bounded by userspace, but by max_tokens. Thus
56129 - * set the length to max_tokens. This matches the extra data
56130 - * allocation.
56131 - * The driver should fill it with the number of tokens it
56132 - * provided, and it may check iwp->length rather than having
56133 - * knowledge of max_tokens. If the driver doesn't change the
56134 - * iwp->length, this ioctl just copies back max_token tokens
56135 - * filled with zeroes. Hopefully the driver isn't claiming
56136 - * them to be valid data.
56137 - */
56138 - iwp->length = descr->max_tokens;
56139 - }
56140 -
56141 err = handler(dev, info, (union iwreq_data *) iwp, extra);
56142
56143 iwp->length += essid_compat;
56144 diff -urNp linux-2.6.36/net/x25/x25_facilities.c linux-2.6.36/net/x25/x25_facilities.c
56145 --- linux-2.6.36/net/x25/x25_facilities.c 2010-10-20 16:30:22.000000000 -0400
56146 +++ linux-2.6.36/net/x25/x25_facilities.c 2010-11-06 18:58:50.000000000 -0400
56147 @@ -134,15 +134,15 @@ int x25_parse_facilities(struct sk_buff
56148 case X25_FAC_CLASS_D:
56149 switch (*p) {
56150 case X25_FAC_CALLING_AE:
56151 - if (p[1] > X25_MAX_DTE_FACIL_LEN)
56152 - break;
56153 + if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
56154 + return 0;
56155 dte_facs->calling_len = p[2];
56156 memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
56157 *vc_fac_mask |= X25_MASK_CALLING_AE;
56158 break;
56159 case X25_FAC_CALLED_AE:
56160 - if (p[1] > X25_MAX_DTE_FACIL_LEN)
56161 - break;
56162 + if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
56163 + return 0;
56164 dte_facs->called_len = p[2];
56165 memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
56166 *vc_fac_mask |= X25_MASK_CALLED_AE;
56167 diff -urNp linux-2.6.36/net/x25/x25_in.c linux-2.6.36/net/x25/x25_in.c
56168 --- linux-2.6.36/net/x25/x25_in.c 2010-10-20 16:30:22.000000000 -0400
56169 +++ linux-2.6.36/net/x25/x25_in.c 2010-11-06 18:58:50.000000000 -0400
56170 @@ -119,6 +119,8 @@ static int x25_state1_machine(struct soc
56171 &x25->vc_facil_mask);
56172 if (len > 0)
56173 skb_pull(skb, len);
56174 + else
56175 + return -1;
56176 /*
56177 * Copy any Call User Data.
56178 */
56179 diff -urNp linux-2.6.36/net/xfrm/xfrm_policy.c linux-2.6.36/net/xfrm/xfrm_policy.c
56180 --- linux-2.6.36/net/xfrm/xfrm_policy.c 2010-10-20 16:30:22.000000000 -0400
56181 +++ linux-2.6.36/net/xfrm/xfrm_policy.c 2010-11-06 18:58:15.000000000 -0400
56182 @@ -1501,7 +1501,7 @@ free_dst:
56183 goto out;
56184 }
56185
56186 -static int inline
56187 +static inline int
56188 xfrm_dst_alloc_copy(void **target, void *src, int size)
56189 {
56190 if (!*target) {
56191 @@ -1513,7 +1513,7 @@ xfrm_dst_alloc_copy(void **target, void
56192 return 0;
56193 }
56194
56195 -static int inline
56196 +static inline int
56197 xfrm_dst_update_parent(struct dst_entry *dst, struct xfrm_selector *sel)
56198 {
56199 #ifdef CONFIG_XFRM_SUB_POLICY
56200 @@ -1525,7 +1525,7 @@ xfrm_dst_update_parent(struct dst_entry
56201 #endif
56202 }
56203
56204 -static int inline
56205 +static inline int
56206 xfrm_dst_update_origin(struct dst_entry *dst, struct flowi *fl)
56207 {
56208 #ifdef CONFIG_XFRM_SUB_POLICY
56209 diff -urNp linux-2.6.36/scripts/basic/fixdep.c linux-2.6.36/scripts/basic/fixdep.c
56210 --- linux-2.6.36/scripts/basic/fixdep.c 2010-10-20 16:30:22.000000000 -0400
56211 +++ linux-2.6.36/scripts/basic/fixdep.c 2010-11-06 18:58:15.000000000 -0400
56212 @@ -222,9 +222,9 @@ static void use_config(char *m, int slen
56213
56214 static void parse_config_file(char *map, size_t len)
56215 {
56216 - int *end = (int *) (map + len);
56217 + unsigned int *end = (unsigned int *) (map + len);
56218 /* start at +1, so that p can never be < map */
56219 - int *m = (int *) map + 1;
56220 + unsigned int *m = (unsigned int *) map + 1;
56221 char *p, *q;
56222
56223 for (; m < end; m++) {
56224 @@ -371,7 +371,7 @@ static void print_deps(void)
56225 static void traps(void)
56226 {
56227 static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
56228 - int *p = (int *)test;
56229 + unsigned int *p = (unsigned int *)test;
56230
56231 if (*p != INT_CONF) {
56232 fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
56233 diff -urNp linux-2.6.36/scripts/kallsyms.c linux-2.6.36/scripts/kallsyms.c
56234 --- linux-2.6.36/scripts/kallsyms.c 2010-10-20 16:30:22.000000000 -0400
56235 +++ linux-2.6.36/scripts/kallsyms.c 2010-11-06 18:58:15.000000000 -0400
56236 @@ -43,10 +43,10 @@ struct text_range {
56237
56238 static unsigned long long _text;
56239 static struct text_range text_ranges[] = {
56240 - { "_stext", "_etext" },
56241 - { "_sinittext", "_einittext" },
56242 - { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */
56243 - { "_stext_l2", "_etext_l2" }, /* Blackfin on-chip L2 SRAM */
56244 + { "_stext", "_etext", 0, 0 },
56245 + { "_sinittext", "_einittext", 0, 0 },
56246 + { "_stext_l1", "_etext_l1", 0, 0 }, /* Blackfin on-chip L1 inst SRAM */
56247 + { "_stext_l2", "_etext_l2", 0, 0 }, /* Blackfin on-chip L2 SRAM */
56248 };
56249 #define text_range_text (&text_ranges[0])
56250 #define text_range_inittext (&text_ranges[1])
56251 diff -urNp linux-2.6.36/scripts/mod/file2alias.c linux-2.6.36/scripts/mod/file2alias.c
56252 --- linux-2.6.36/scripts/mod/file2alias.c 2010-10-20 16:30:22.000000000 -0400
56253 +++ linux-2.6.36/scripts/mod/file2alias.c 2010-11-06 18:58:15.000000000 -0400
56254 @@ -72,7 +72,7 @@ static void device_id_check(const char *
56255 unsigned long size, unsigned long id_size,
56256 void *symval)
56257 {
56258 - int i;
56259 + unsigned int i;
56260
56261 if (size % id_size || size < id_size) {
56262 if (cross_build != 0)
56263 @@ -102,7 +102,7 @@ static void device_id_check(const char *
56264 /* USB is special because the bcdDevice can be matched against a numeric range */
56265 /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
56266 static void do_usb_entry(struct usb_device_id *id,
56267 - unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
56268 + unsigned int bcdDevice_initial, unsigned int bcdDevice_initial_digits,
56269 unsigned char range_lo, unsigned char range_hi,
56270 unsigned char max, struct module *mod)
56271 {
56272 @@ -437,7 +437,7 @@ static void do_pnp_device_entry(void *sy
56273 for (i = 0; i < count; i++) {
56274 const char *id = (char *)devs[i].id;
56275 char acpi_id[sizeof(devs[0].id)];
56276 - int j;
56277 + unsigned int j;
56278
56279 buf_printf(&mod->dev_table_buf,
56280 "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
56281 @@ -467,7 +467,7 @@ static void do_pnp_card_entries(void *sy
56282
56283 for (j = 0; j < PNP_MAX_DEVICES; j++) {
56284 const char *id = (char *)card->devs[j].id;
56285 - int i2, j2;
56286 + unsigned int i2, j2;
56287 int dup = 0;
56288
56289 if (!id[0])
56290 @@ -493,7 +493,7 @@ static void do_pnp_card_entries(void *sy
56291 /* add an individual alias for every device entry */
56292 if (!dup) {
56293 char acpi_id[sizeof(card->devs[0].id)];
56294 - int k;
56295 + unsigned int k;
56296
56297 buf_printf(&mod->dev_table_buf,
56298 "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
56299 @@ -768,7 +768,7 @@ static void dmi_ascii_filter(char *d, co
56300 static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
56301 char *alias)
56302 {
56303 - int i, j;
56304 + unsigned int i, j;
56305
56306 sprintf(alias, "dmi*");
56307
56308 diff -urNp linux-2.6.36/scripts/mod/modpost.c linux-2.6.36/scripts/mod/modpost.c
56309 --- linux-2.6.36/scripts/mod/modpost.c 2010-10-20 16:30:22.000000000 -0400
56310 +++ linux-2.6.36/scripts/mod/modpost.c 2010-11-06 18:58:15.000000000 -0400
56311 @@ -895,6 +895,7 @@ enum mismatch {
56312 ANY_INIT_TO_ANY_EXIT,
56313 ANY_EXIT_TO_ANY_INIT,
56314 EXPORT_TO_INIT_EXIT,
56315 + DATA_TO_TEXT
56316 };
56317
56318 struct sectioncheck {
56319 @@ -1003,6 +1004,12 @@ const struct sectioncheck sectioncheck[]
56320 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
56321 .mismatch = EXPORT_TO_INIT_EXIT,
56322 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
56323 +},
56324 +/* Do not reference code from writable data */
56325 +{
56326 + .fromsec = { DATA_SECTIONS, NULL },
56327 + .tosec = { TEXT_SECTIONS, NULL },
56328 + .mismatch = DATA_TO_TEXT
56329 }
56330 };
56331
56332 @@ -1125,10 +1132,10 @@ static Elf_Sym *find_elf_symbol(struct e
56333 continue;
56334 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
56335 continue;
56336 - if (sym->st_value == addr)
56337 - return sym;
56338 /* Find a symbol nearby - addr are maybe negative */
56339 d = sym->st_value - addr;
56340 + if (d == 0)
56341 + return sym;
56342 if (d < 0)
56343 d = addr - sym->st_value;
56344 if (d < distance) {
56345 @@ -1397,6 +1404,14 @@ static void report_sec_mismatch(const ch
56346 tosym, prl_to, prl_to, tosym);
56347 free(prl_to);
56348 break;
56349 + case DATA_TO_TEXT:
56350 +/*
56351 + fprintf(stderr,
56352 + "The variable %s references\n"
56353 + "the %s %s%s%s\n",
56354 + fromsym, to, sec2annotation(tosec), tosym, to_p);
56355 +*/
56356 + break;
56357 }
56358 fprintf(stderr, "\n");
56359 }
56360 @@ -1720,7 +1735,7 @@ void __attribute__((format(printf, 2, 3)
56361 va_end(ap);
56362 }
56363
56364 -void buf_write(struct buffer *buf, const char *s, int len)
56365 +void buf_write(struct buffer *buf, const char *s, unsigned int len)
56366 {
56367 if (buf->size - buf->pos < len) {
56368 buf->size += len + SZ;
56369 @@ -1932,7 +1947,7 @@ static void write_if_changed(struct buff
56370 if (fstat(fileno(file), &st) < 0)
56371 goto close_write;
56372
56373 - if (st.st_size != b->pos)
56374 + if (st.st_size != (off_t)b->pos)
56375 goto close_write;
56376
56377 tmp = NOFAIL(malloc(b->pos));
56378 diff -urNp linux-2.6.36/scripts/mod/modpost.h linux-2.6.36/scripts/mod/modpost.h
56379 --- linux-2.6.36/scripts/mod/modpost.h 2010-10-20 16:30:22.000000000 -0400
56380 +++ linux-2.6.36/scripts/mod/modpost.h 2010-11-06 18:58:15.000000000 -0400
56381 @@ -92,15 +92,15 @@ void *do_nofail(void *ptr, const char *e
56382
56383 struct buffer {
56384 char *p;
56385 - int pos;
56386 - int size;
56387 + unsigned int pos;
56388 + unsigned int size;
56389 };
56390
56391 void __attribute__((format(printf, 2, 3)))
56392 buf_printf(struct buffer *buf, const char *fmt, ...);
56393
56394 void
56395 -buf_write(struct buffer *buf, const char *s, int len);
56396 +buf_write(struct buffer *buf, const char *s, unsigned int len);
56397
56398 struct module {
56399 struct module *next;
56400 diff -urNp linux-2.6.36/scripts/mod/sumversion.c linux-2.6.36/scripts/mod/sumversion.c
56401 --- linux-2.6.36/scripts/mod/sumversion.c 2010-10-20 16:30:22.000000000 -0400
56402 +++ linux-2.6.36/scripts/mod/sumversion.c 2010-11-06 18:58:15.000000000 -0400
56403 @@ -455,7 +455,7 @@ static void write_version(const char *fi
56404 goto out;
56405 }
56406
56407 - if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {
56408 + if (write(fd, sum, strlen(sum)+1) != (ssize_t)strlen(sum)+1) {
56409 warn("writing sum in %s failed: %s\n",
56410 filename, strerror(errno));
56411 goto out;
56412 diff -urNp linux-2.6.36/scripts/pnmtologo.c linux-2.6.36/scripts/pnmtologo.c
56413 --- linux-2.6.36/scripts/pnmtologo.c 2010-10-20 16:30:22.000000000 -0400
56414 +++ linux-2.6.36/scripts/pnmtologo.c 2010-11-06 18:58:15.000000000 -0400
56415 @@ -237,14 +237,14 @@ static void write_header(void)
56416 fprintf(out, " * Linux logo %s\n", logoname);
56417 fputs(" */\n\n", out);
56418 fputs("#include <linux/linux_logo.h>\n\n", out);
56419 - fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
56420 + fprintf(out, "static unsigned char %s_data[] = {\n",
56421 logoname);
56422 }
56423
56424 static void write_footer(void)
56425 {
56426 fputs("\n};\n\n", out);
56427 - fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);
56428 + fprintf(out, "const struct linux_logo %s = {\n", logoname);
56429 fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);
56430 fprintf(out, "\t.width\t\t= %d,\n", logo_width);
56431 fprintf(out, "\t.height\t\t= %d,\n", logo_height);
56432 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
56433 fputs("\n};\n\n", out);
56434
56435 /* write logo clut */
56436 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
56437 + fprintf(out, "static unsigned char %s_clut[] = {\n",
56438 logoname);
56439 write_hex_cnt = 0;
56440 for (i = 0; i < logo_clutsize; i++) {
56441 diff -urNp linux-2.6.36/security/apparmor/lsm.c linux-2.6.36/security/apparmor/lsm.c
56442 --- linux-2.6.36/security/apparmor/lsm.c 2010-10-20 16:30:22.000000000 -0400
56443 +++ linux-2.6.36/security/apparmor/lsm.c 2010-11-06 19:46:26.000000000 -0400
56444 @@ -619,7 +619,7 @@ static int apparmor_task_setrlimit(struc
56445 return error;
56446 }
56447
56448 -static struct security_operations apparmor_ops = {
56449 +static struct security_operations apparmor_ops __read_only = {
56450 .name = "apparmor",
56451
56452 .ptrace_access_check = apparmor_ptrace_access_check,
56453 diff -urNp linux-2.6.36/security/commoncap.c linux-2.6.36/security/commoncap.c
56454 --- linux-2.6.36/security/commoncap.c 2010-10-20 16:30:22.000000000 -0400
56455 +++ linux-2.6.36/security/commoncap.c 2010-11-06 18:58:50.000000000 -0400
56456 @@ -28,6 +28,7 @@
56457 #include <linux/prctl.h>
56458 #include <linux/securebits.h>
56459 #include <linux/syslog.h>
56460 +#include <net/sock.h>
56461
56462 /*
56463 * If a non-root user executes a setuid-root binary in
56464 @@ -51,9 +52,11 @@ static void warn_setuid_and_fcaps_mixed(
56465 }
56466 }
56467
56468 +extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
56469 +
56470 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
56471 {
56472 - NETLINK_CB(skb).eff_cap = current_cap();
56473 + NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
56474 return 0;
56475 }
56476
56477 diff -urNp linux-2.6.36/security/integrity/ima/ima_api.c linux-2.6.36/security/integrity/ima/ima_api.c
56478 --- linux-2.6.36/security/integrity/ima/ima_api.c 2010-10-20 16:30:22.000000000 -0400
56479 +++ linux-2.6.36/security/integrity/ima/ima_api.c 2010-11-06 18:58:15.000000000 -0400
56480 @@ -75,7 +75,7 @@ void ima_add_violation(struct inode *ino
56481 int result;
56482
56483 /* can overflow, only indicator */
56484 - atomic_long_inc(&ima_htable.violations);
56485 + atomic_long_inc_unchecked(&ima_htable.violations);
56486
56487 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
56488 if (!entry) {
56489 diff -urNp linux-2.6.36/security/integrity/ima/ima_fs.c linux-2.6.36/security/integrity/ima/ima_fs.c
56490 --- linux-2.6.36/security/integrity/ima/ima_fs.c 2010-10-20 16:30:22.000000000 -0400
56491 +++ linux-2.6.36/security/integrity/ima/ima_fs.c 2010-11-06 18:58:15.000000000 -0400
56492 @@ -28,12 +28,12 @@
56493 static int valid_policy = 1;
56494 #define TMPBUFLEN 12
56495 static ssize_t ima_show_htable_value(char __user *buf, size_t count,
56496 - loff_t *ppos, atomic_long_t *val)
56497 + loff_t *ppos, atomic_long_unchecked_t *val)
56498 {
56499 char tmpbuf[TMPBUFLEN];
56500 ssize_t len;
56501
56502 - len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val));
56503 + len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read_unchecked(val));
56504 return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
56505 }
56506
56507 diff -urNp linux-2.6.36/security/integrity/ima/ima.h linux-2.6.36/security/integrity/ima/ima.h
56508 --- linux-2.6.36/security/integrity/ima/ima.h 2010-10-20 16:30:22.000000000 -0400
56509 +++ linux-2.6.36/security/integrity/ima/ima.h 2010-11-06 18:58:15.000000000 -0400
56510 @@ -84,8 +84,8 @@ void ima_add_violation(struct inode *ino
56511 extern spinlock_t ima_queue_lock;
56512
56513 struct ima_h_table {
56514 - atomic_long_t len; /* number of stored measurements in the list */
56515 - atomic_long_t violations;
56516 + atomic_long_unchecked_t len; /* number of stored measurements in the list */
56517 + atomic_long_unchecked_t violations;
56518 struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE];
56519 };
56520 extern struct ima_h_table ima_htable;
56521 diff -urNp linux-2.6.36/security/integrity/ima/ima_queue.c linux-2.6.36/security/integrity/ima/ima_queue.c
56522 --- linux-2.6.36/security/integrity/ima/ima_queue.c 2010-10-20 16:30:22.000000000 -0400
56523 +++ linux-2.6.36/security/integrity/ima/ima_queue.c 2010-11-06 18:58:15.000000000 -0400
56524 @@ -79,7 +79,7 @@ static int ima_add_digest_entry(struct i
56525 INIT_LIST_HEAD(&qe->later);
56526 list_add_tail_rcu(&qe->later, &ima_measurements);
56527
56528 - atomic_long_inc(&ima_htable.len);
56529 + atomic_long_inc_unchecked(&ima_htable.len);
56530 key = ima_hash_key(entry->digest);
56531 hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]);
56532 return 0;
56533 diff -urNp linux-2.6.36/security/Kconfig linux-2.6.36/security/Kconfig
56534 --- linux-2.6.36/security/Kconfig 2010-10-20 16:30:22.000000000 -0400
56535 +++ linux-2.6.36/security/Kconfig 2010-11-06 18:58:50.000000000 -0400
56536 @@ -4,6 +4,505 @@
56537
56538 menu "Security options"
56539
56540 +source grsecurity/Kconfig
56541 +
56542 +menu "PaX"
56543 +
56544 + config PAX_PER_CPU_PGD
56545 + bool
56546 +
56547 + config TASK_SIZE_MAX_SHIFT
56548 + int
56549 + depends on X86_64
56550 + default 47 if !PAX_PER_CPU_PGD
56551 + default 42 if PAX_PER_CPU_PGD
56552 +
56553 + config PAX_ENABLE_PAE
56554 + bool
56555 + default y if (X86_32 && (MPENTIUM4 || MK8 || MPSC || MCORE2 || MATOM))
56556 +
56557 +config PAX
56558 + bool "Enable various PaX features"
56559 + depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS || PARISC || PPC || SPARC || X86)
56560 + help
56561 + This allows you to enable various PaX features. PaX adds
56562 + intrusion prevention mechanisms to the kernel that reduce
56563 + the risks posed by exploitable memory corruption bugs.
56564 +
56565 +menu "PaX Control"
56566 + depends on PAX
56567 +
56568 +config PAX_SOFTMODE
56569 + bool 'Support soft mode'
56570 + select PAX_PT_PAX_FLAGS
56571 + help
56572 + Enabling this option will allow you to run PaX in soft mode, that
56573 + is, PaX features will not be enforced by default, only on executables
56574 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
56575 + is the only way to mark executables for soft mode use.
56576 +
56577 + Soft mode can be activated by using the "pax_softmode=1" kernel command
56578 + line option on boot. Furthermore you can control various PaX features
56579 + at runtime via the entries in /proc/sys/kernel/pax.
56580 +
56581 +config PAX_EI_PAX
56582 + bool 'Use legacy ELF header marking'
56583 + help
56584 + Enabling this option will allow you to control PaX features on
56585 + a per executable basis via the 'chpax' utility available at
56586 + http://pax.grsecurity.net/. The control flags will be read from
56587 + an otherwise reserved part of the ELF header. This marking has
56588 + numerous drawbacks (no support for soft-mode, toolchain does not
56589 + know about the non-standard use of the ELF header) therefore it
56590 + has been deprecated in favour of PT_PAX_FLAGS support.
56591 +
56592 + If you have applications not marked by the PT_PAX_FLAGS ELF
56593 + program header then you MUST enable this option otherwise they
56594 + will not get any protection.
56595 +
56596 + Note that if you enable PT_PAX_FLAGS marking support as well,
56597 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
56598 +
56599 +config PAX_PT_PAX_FLAGS
56600 + bool 'Use ELF program header marking'
56601 + help
56602 + Enabling this option will allow you to control PaX features on
56603 + a per executable basis via the 'paxctl' utility available at
56604 + http://pax.grsecurity.net/. The control flags will be read from
56605 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
56606 + has the benefits of supporting both soft mode and being fully
56607 + integrated into the toolchain (the binutils patch is available
56608 + from http://pax.grsecurity.net).
56609 +
56610 + If you have applications not marked by the PT_PAX_FLAGS ELF
56611 + program header then you MUST enable the EI_PAX marking support
56612 + otherwise they will not get any protection.
56613 +
56614 + Note that if you enable the legacy EI_PAX marking support as well,
56615 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
56616 +
56617 +choice
56618 + prompt 'MAC system integration'
56619 + default PAX_HAVE_ACL_FLAGS
56620 + help
56621 + Mandatory Access Control systems have the option of controlling
56622 + PaX flags on a per executable basis, choose the method supported
56623 + by your particular system.
56624 +
56625 + - "none": if your MAC system does not interact with PaX,
56626 + - "direct": if your MAC system defines pax_set_initial_flags() itself,
56627 + - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
56628 +
56629 + NOTE: this option is for developers/integrators only.
56630 +
56631 + config PAX_NO_ACL_FLAGS
56632 + bool 'none'
56633 +
56634 + config PAX_HAVE_ACL_FLAGS
56635 + bool 'direct'
56636 +
56637 + config PAX_HOOK_ACL_FLAGS
56638 + bool 'hook'
56639 +endchoice
56640 +
56641 +endmenu
56642 +
56643 +menu "Non-executable pages"
56644 + depends on PAX
56645 +
56646 +config PAX_NOEXEC
56647 + bool "Enforce non-executable pages"
56648 + depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || (ARM && (CPU_V6 || CPU_V7)) || IA64 || MIPS || PARISC || PPC || S390 || SPARC || X86)
56649 + help
56650 + By design some architectures do not allow for protecting memory
56651 + pages against execution or even if they do, Linux does not make
56652 + use of this feature. In practice this means that if a page is
56653 + readable (such as the stack or heap) it is also executable.
56654 +
56655 + There is a well known exploit technique that makes use of this
56656 + fact and a common programming mistake where an attacker can
56657 + introduce code of his choice somewhere in the attacked program's
56658 + memory (typically the stack or the heap) and then execute it.
56659 +
56660 + If the attacked program was running with different (typically
56661 + higher) privileges than that of the attacker, then he can elevate
56662 + his own privilege level (e.g. get a root shell, write to files for
56663 + which he does not have write access to, etc).
56664 +
56665 + Enabling this option will let you choose from various features
56666 + that prevent the injection and execution of 'foreign' code in
56667 + a program.
56668 +
56669 + This will also break programs that rely on the old behaviour and
56670 + expect that dynamically allocated memory via the malloc() family
56671 + of functions is executable (which it is not). Notable examples
56672 + are the XFree86 4.x server, the java runtime and wine.
56673 +
56674 +config PAX_PAGEEXEC
56675 + bool "Paging based non-executable pages"
56676 + depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MATOM || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7)
56677 + select S390_SWITCH_AMODE if S390
56678 + select S390_EXEC_PROTECT if S390
56679 + help
56680 + This implementation is based on the paging feature of the CPU.
56681 + On i386 without hardware non-executable bit support there is a
56682 + variable but usually low performance impact, however on Intel's
56683 + P4 core based CPUs it is very high so you should not enable this
56684 + for kernels meant to be used on such CPUs.
56685 +
56686 + On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
56687 + with hardware non-executable bit support there is no performance
56688 + impact, on ppc the impact is negligible.
56689 +
56690 + Note that several architectures require various emulations due to
56691 + badly designed userland ABIs, this will cause a performance impact
56692 + but will disappear as soon as userland is fixed. For example, ppc
56693 + userland MUST have been built with secure-plt by a recent toolchain.
56694 +
56695 +config PAX_SEGMEXEC
56696 + bool "Segmentation based non-executable pages"
56697 + depends on PAX_NOEXEC && X86_32
56698 + help
56699 + This implementation is based on the segmentation feature of the
56700 + CPU and has a very small performance impact, however applications
56701 + will be limited to a 1.5 GB address space instead of the normal
56702 + 3 GB.
56703 +
56704 +config PAX_EMUTRAMP
56705 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || X86)
56706 + default y if PARISC
56707 + help
56708 + There are some programs and libraries that for one reason or
56709 + another attempt to execute special small code snippets from
56710 + non-executable memory pages. Most notable examples are the
56711 + signal handler return code generated by the kernel itself and
56712 + the GCC trampolines.
56713 +
56714 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
56715 + such programs will no longer work under your kernel.
56716 +
56717 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
56718 + utilities to enable trampoline emulation for the affected programs
56719 + yet still have the protection provided by the non-executable pages.
56720 +
56721 + On parisc you MUST enable this option and EMUSIGRT as well, otherwise
56722 + your system will not even boot.
56723 +
56724 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
56725 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
56726 + for the affected files.
56727 +
56728 + NOTE: enabling this feature *may* open up a loophole in the
56729 + protection provided by non-executable pages that an attacker
56730 + could abuse. Therefore the best solution is to not have any
56731 + files on your system that would require this option. This can
56732 + be achieved by not using libc5 (which relies on the kernel
56733 + signal handler return code) and not using or rewriting programs
56734 + that make use of the nested function implementation of GCC.
56735 + Skilled users can just fix GCC itself so that it implements
56736 + nested function calls in a way that does not interfere with PaX.
56737 +
56738 +config PAX_EMUSIGRT
56739 + bool "Automatically emulate sigreturn trampolines"
56740 + depends on PAX_EMUTRAMP && PARISC
56741 + default y
56742 + help
56743 + Enabling this option will have the kernel automatically detect
56744 + and emulate signal return trampolines executing on the stack
56745 + that would otherwise lead to task termination.
56746 +
56747 + This solution is intended as a temporary one for users with
56748 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
56749 + Modula-3 runtime, etc) or executables linked to such, basically
56750 + everything that does not specify its own SA_RESTORER function in
56751 + normal executable memory like glibc 2.1+ does.
56752 +
56753 + On parisc you MUST enable this option, otherwise your system will
56754 + not even boot.
56755 +
56756 + NOTE: this feature cannot be disabled on a per executable basis
56757 + and since it *does* open up a loophole in the protection provided
56758 + by non-executable pages, the best solution is to not have any
56759 + files on your system that would require this option.
56760 +
56761 +config PAX_MPROTECT
56762 + bool "Restrict mprotect()"
56763 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC)
56764 + help
56765 + Enabling this option will prevent programs from
56766 + - changing the executable status of memory pages that were
56767 + not originally created as executable,
56768 + - making read-only executable pages writable again,
56769 + - creating executable pages from anonymous memory,
56770 + - making read-only-after-relocations (RELRO) data pages writable again.
56771 +
56772 + You should say Y here to complete the protection provided by
56773 + the enforcement of non-executable pages.
56774 +
56775 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
56776 + this feature on a per file basis.
56777 +
56778 +config PAX_ELFRELOCS
56779 + bool "Allow ELF text relocations (read help)"
56780 + depends on PAX_MPROTECT
56781 + default n
56782 + help
56783 + Non-executable pages and mprotect() restrictions are effective
56784 + in preventing the introduction of new executable code into an
56785 + attacked task's address space. There remain only two venues
56786 + for this kind of attack: if the attacker can execute already
56787 + existing code in the attacked task then he can either have it
56788 + create and mmap() a file containing his code or have it mmap()
56789 + an already existing ELF library that does not have position
56790 + independent code in it and use mprotect() on it to make it
56791 + writable and copy his code there. While protecting against
56792 + the former approach is beyond PaX, the latter can be prevented
56793 + by having only PIC ELF libraries on one's system (which do not
56794 + need to relocate their code). If you are sure this is your case,
56795 + as is the case with all modern Linux distributions, then leave
56796 + this option disabled. You should say 'n' here.
56797 +
56798 +config PAX_ETEXECRELOCS
56799 + bool "Allow ELF ET_EXEC text relocations"
56800 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
56801 + select PAX_ELFRELOCS
56802 + default y
56803 + help
56804 + On some architectures there are incorrectly created applications
56805 + that require text relocations and would not work without enabling
56806 + this option. If you are an alpha, ia64 or parisc user, you should
56807 + enable this option and disable it once you have made sure that
56808 + none of your applications need it.
56809 +
56810 +config PAX_EMUPLT
56811 + bool "Automatically emulate ELF PLT"
56812 + depends on PAX_MPROTECT && (ALPHA || PARISC || SPARC)
56813 + default y
56814 + help
56815 + Enabling this option will have the kernel automatically detect
56816 + and emulate the Procedure Linkage Table entries in ELF files.
56817 + On some architectures such entries are in writable memory, and
56818 + become non-executable leading to task termination. Therefore
56819 + it is mandatory that you enable this option on alpha, parisc,
56820 + sparc and sparc64, otherwise your system would not even boot.
56821 +
56822 + NOTE: this feature *does* open up a loophole in the protection
56823 + provided by the non-executable pages, therefore the proper
56824 + solution is to modify the toolchain to produce a PLT that does
56825 + not need to be writable.
56826 +
56827 +config PAX_DLRESOLVE
56828 + bool 'Emulate old glibc resolver stub'
56829 + depends on PAX_EMUPLT && SPARC
56830 + default n
56831 + help
56832 + This option is needed if userland has an old glibc (before 2.4)
56833 + that puts a 'save' instruction into the runtime generated resolver
56834 + stub that needs special emulation.
56835 +
56836 +config PAX_KERNEXEC
56837 + bool "Enforce non-executable kernel pages"
56838 + depends on PAX_NOEXEC && (PPC || X86) && (!X86_32 || X86_WP_WORKS_OK) && !XEN
56839 + select PAX_PER_CPU_PGD if X86_64 || (X86_32 && X86_PAE)
56840 + help
56841 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
56842 + that is, enabling this option will make it harder to inject
56843 + and execute 'foreign' code in kernel memory itself.
56844 +
56845 +config PAX_KERNEXEC_MODULE_TEXT
56846 + int "Minimum amount of memory reserved for module code"
56847 + default "4"
56848 + depends on PAX_KERNEXEC && X86_32 && MODULES
56849 + help
56850 + Due to implementation details the kernel must reserve a fixed
56851 + amount of memory for module code at compile time that cannot be
56852 + changed at runtime. Here you can specify the minimum amount
56853 + in MB that will be reserved. Due to the same implementation
56854 + details this size will always be rounded up to the next 2/4 MB
56855 + boundary (depends on PAE) so the actually available memory for
56856 + module code will usually be more than this minimum.
56857 +
56858 + The default 4 MB should be enough for most users but if you have
56859 + an excessive number of modules (e.g., most distribution configs
56860 + compile many drivers as modules) or use huge modules such as
56861 + nvidia's kernel driver, you will need to adjust this amount.
56862 + A good rule of thumb is to look at your currently loaded kernel
56863 + modules and add up their sizes.
56864 +
56865 +endmenu
56866 +
56867 +menu "Address Space Layout Randomization"
56868 + depends on PAX
56869 +
56870 +config PAX_ASLR
56871 + bool "Address Space Layout Randomization"
56872 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
56873 + help
56874 + Many if not most exploit techniques rely on the knowledge of
56875 + certain addresses in the attacked program. The following options
56876 + will allow the kernel to apply a certain amount of randomization
56877 + to specific parts of the program thereby forcing an attacker to
56878 + guess them in most cases. Any failed guess will most likely crash
56879 + the attacked program which allows the kernel to detect such attempts
56880 + and react on them. PaX itself provides no reaction mechanisms,
56881 + instead it is strongly encouraged that you make use of Nergal's
56882 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
56883 + (http://www.grsecurity.net/) built-in crash detection features or
56884 + develop one yourself.
56885 +
56886 + By saying Y here you can choose to randomize the following areas:
56887 + - top of the task's kernel stack
56888 + - top of the task's userland stack
56889 + - base address for mmap() requests that do not specify one
56890 + (this includes all libraries)
56891 + - base address of the main executable
56892 +
56893 + It is strongly recommended to say Y here as address space layout
56894 + randomization has negligible impact on performance yet it provides
56895 + a very effective protection.
56896 +
56897 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
56898 + this feature on a per file basis.
56899 +
56900 +config PAX_RANDKSTACK
56901 + bool "Randomize kernel stack base"
56902 + depends on PAX_ASLR && X86_TSC && X86_32
56903 + help
56904 + By saying Y here the kernel will randomize every task's kernel
56905 + stack on every system call. This will not only force an attacker
56906 + to guess it but also prevent him from making use of possible
56907 + leaked information about it.
56908 +
56909 + Since the kernel stack is a rather scarce resource, randomization
56910 + may cause unexpected stack overflows, therefore you should very
56911 + carefully test your system. Note that once enabled in the kernel
56912 + configuration, this feature cannot be disabled on a per file basis.
56913 +
56914 +config PAX_RANDUSTACK
56915 + bool "Randomize user stack base"
56916 + depends on PAX_ASLR
56917 + help
56918 + By saying Y here the kernel will randomize every task's userland
56919 + stack. The randomization is done in two steps where the second
56920 + one may apply a big amount of shift to the top of the stack and
56921 + cause problems for programs that want to use lots of memory (more
56922 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
56923 + For this reason the second step can be controlled by 'chpax' or
56924 + 'paxctl' on a per file basis.
56925 +
56926 +config PAX_RANDMMAP
56927 + bool "Randomize mmap() base"
56928 + depends on PAX_ASLR
56929 + help
56930 + By saying Y here the kernel will use a randomized base address for
56931 + mmap() requests that do not specify one themselves. As a result
56932 + all dynamically loaded libraries will appear at random addresses
56933 + and therefore be harder to exploit by a technique where an attacker
56934 + attempts to execute library code for his purposes (e.g. spawn a
56935 + shell from an exploited program that is running at an elevated
56936 + privilege level).
56937 +
56938 + Furthermore, if a program is relinked as a dynamic ELF file, its
56939 + base address will be randomized as well, completing the full
56940 + randomization of the address space layout. Attacking such programs
56941 + becomes a guess game. You can find an example of doing this at
56942 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
56943 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
56944 +
56945 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
56946 + feature on a per file basis.
56947 +
56948 +endmenu
56949 +
56950 +menu "Miscellaneous hardening features"
56951 +
56952 +config PAX_MEMORY_SANITIZE
56953 + bool "Sanitize all freed memory"
56954 + help
56955 + By saying Y here the kernel will erase memory pages as soon as they
56956 + are freed. This in turn reduces the lifetime of data stored in the
56957 + pages, making it less likely that sensitive information such as
56958 + passwords, cryptographic secrets, etc stay in memory for too long.
56959 +
56960 + This is especially useful for programs whose runtime is short, long
56961 + lived processes and the kernel itself benefit from this as long as
56962 + they operate on whole memory pages and ensure timely freeing of pages
56963 + that may hold sensitive information.
56964 +
56965 + The tradeoff is performance impact, on a single CPU system kernel
56966 + compilation sees a 3% slowdown, other systems and workloads may vary
56967 + and you are advised to test this feature on your expected workload
56968 + before deploying it.
56969 +
56970 + Note that this feature does not protect data stored in live pages,
56971 + e.g., process memory swapped to disk may stay there for a long time.
56972 +
56973 +config PAX_MEMORY_UDEREF
56974 + bool "Prevent invalid userland pointer dereference"
56975 + depends on X86 && !UML_X86 && !XEN
56976 + select PAX_PER_CPU_PGD if X86_64
56977 + help
56978 + By saying Y here the kernel will be prevented from dereferencing
56979 + userland pointers in contexts where the kernel expects only kernel
56980 + pointers. This is both a useful runtime debugging feature and a
56981 + security measure that prevents exploiting a class of kernel bugs.
56982 +
56983 + The tradeoff is that some virtualization solutions may experience
56984 + a huge slowdown and therefore you should not enable this feature
56985 + for kernels meant to run in such environments. Whether a given VM
56986 + solution is affected or not is best determined by simply trying it
56987 + out, the performance impact will be obvious right on boot as this
56988 + mechanism engages from very early on. A good rule of thumb is that
56989 + VMs running on CPUs without hardware virtualization support (i.e.,
56990 + the majority of IA-32 CPUs) will likely experience the slowdown.
56991 +
56992 +config PAX_REFCOUNT
56993 + bool "Prevent various kernel object reference counter overflows"
56994 + depends on GRKERNSEC && (X86 || SPARC64)
56995 + help
56996 + By saying Y here the kernel will detect and prevent overflowing
56997 + various (but not all) kinds of object reference counters. Such
56998 + overflows can normally occur due to bugs only and are often, if
56999 + not always, exploitable.
57000 +
57001 + The tradeoff is that data structures protected by an overflowed
57002 + refcount will never be freed and therefore will leak memory. Note
57003 + that this leak also happens even without this protection but in
57004 + that case the overflow can eventually trigger the freeing of the
57005 + data structure while it is still being used elsewhere, resulting
57006 + in the exploitable situation that this feature prevents.
57007 +
57008 + Since this has a negligible performance impact, you should enable
57009 + this feature.
57010 +
57011 +config PAX_USERCOPY
57012 + bool "Bounds check heap object copies between kernel and userland"
57013 + depends on X86 || PPC || SPARC
57014 + depends on GRKERNSEC && (SLAB || SLUB || SLOB)
57015 + help
57016 + By saying Y here the kernel will enforce the size of heap objects
57017 + when they are copied in either direction between the kernel and
57018 + userland, even if only a part of the heap object is copied.
57019 +
57020 + Specifically, this checking prevents information leaking from the
57021 + kernel heap during kernel to userland copies (if the kernel heap
57022 + object is otherwise fully initialized) and prevents kernel heap
57023 + overflows during userland to kernel copies.
57024 +
57025 + Note that the current implementation provides the strictest checks
57026 + for the SLUB allocator.
57027 +
57028 + If frame pointers are enabled on x86, this option will also
57029 + restrict copies into and out of the kernel stack to local variables
57030 + within a single frame.
57031 +
57032 + Since this has a negligible performance impact, you should enable
57033 + this feature.
57034 +
57035 +endmenu
57036 +
57037 +endmenu
57038 +
57039 config KEYS
57040 bool "Enable access key retention support"
57041 help
57042 @@ -124,7 +623,7 @@ config INTEL_TXT
57043 config LSM_MMAP_MIN_ADDR
57044 int "Low address space for LSM to protect from user allocation"
57045 depends on SECURITY && SECURITY_SELINUX
57046 - default 65536
57047 + default 32768
57048 help
57049 This is the portion of low virtual memory which should be protected
57050 from userspace allocation. Keeping a user from writing to low pages
57051 diff -urNp linux-2.6.36/security/min_addr.c linux-2.6.36/security/min_addr.c
57052 --- linux-2.6.36/security/min_addr.c 2010-10-20 16:30:22.000000000 -0400
57053 +++ linux-2.6.36/security/min_addr.c 2010-11-06 18:58:50.000000000 -0400
57054 @@ -14,6 +14,7 @@ unsigned long dac_mmap_min_addr = CONFIG
57055 */
57056 static void update_mmap_min_addr(void)
57057 {
57058 +#ifndef SPARC
57059 #ifdef CONFIG_LSM_MMAP_MIN_ADDR
57060 if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
57061 mmap_min_addr = dac_mmap_min_addr;
57062 @@ -22,6 +23,7 @@ static void update_mmap_min_addr(void)
57063 #else
57064 mmap_min_addr = dac_mmap_min_addr;
57065 #endif
57066 +#endif
57067 }
57068
57069 /*
57070 diff -urNp linux-2.6.36/security/security.c linux-2.6.36/security/security.c
57071 --- linux-2.6.36/security/security.c 2010-10-20 16:30:22.000000000 -0400
57072 +++ linux-2.6.36/security/security.c 2010-11-06 18:58:50.000000000 -0400
57073 @@ -25,8 +25,8 @@ static __initdata char chosen_lsm[SECURI
57074 /* things that live in capability.c */
57075 extern void __init security_fixup_ops(struct security_operations *ops);
57076
57077 -static struct security_operations *security_ops;
57078 -static struct security_operations default_security_ops = {
57079 +static struct security_operations *security_ops __read_only;
57080 +static struct security_operations default_security_ops __read_only = {
57081 .name = "default",
57082 };
57083
57084 @@ -67,7 +67,9 @@ int __init security_init(void)
57085
57086 void reset_security_ops(void)
57087 {
57088 + pax_open_kernel();
57089 security_ops = &default_security_ops;
57090 + pax_close_kernel();
57091 }
57092
57093 /* Save user chosen LSM */
57094 diff -urNp linux-2.6.36/security/selinux/hooks.c linux-2.6.36/security/selinux/hooks.c
57095 --- linux-2.6.36/security/selinux/hooks.c 2010-10-20 16:30:22.000000000 -0400
57096 +++ linux-2.6.36/security/selinux/hooks.c 2010-11-06 18:58:50.000000000 -0400
57097 @@ -90,7 +90,6 @@
57098 #define NUM_SEL_MNT_OPTS 5
57099
57100 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
57101 -extern struct security_operations *security_ops;
57102
57103 /* SECMARK reference count */
57104 atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
57105 @@ -5371,7 +5370,7 @@ static int selinux_key_getsecurity(struc
57106
57107 #endif
57108
57109 -static struct security_operations selinux_ops = {
57110 +static struct security_operations selinux_ops __read_only = {
57111 .name = "selinux",
57112
57113 .ptrace_access_check = selinux_ptrace_access_check,
57114 diff -urNp linux-2.6.36/security/smack/smack_lsm.c linux-2.6.36/security/smack/smack_lsm.c
57115 --- linux-2.6.36/security/smack/smack_lsm.c 2010-10-20 16:30:22.000000000 -0400
57116 +++ linux-2.6.36/security/smack/smack_lsm.c 2010-11-06 18:58:15.000000000 -0400
57117 @@ -3056,7 +3056,7 @@ static int smack_inode_getsecctx(struct
57118 return 0;
57119 }
57120
57121 -struct security_operations smack_ops = {
57122 +struct security_operations smack_ops __read_only = {
57123 .name = "smack",
57124
57125 .ptrace_access_check = smack_ptrace_access_check,
57126 diff -urNp linux-2.6.36/security/tomoyo/tomoyo.c linux-2.6.36/security/tomoyo/tomoyo.c
57127 --- linux-2.6.36/security/tomoyo/tomoyo.c 2010-10-20 16:30:22.000000000 -0400
57128 +++ linux-2.6.36/security/tomoyo/tomoyo.c 2010-11-06 18:58:15.000000000 -0400
57129 @@ -240,7 +240,7 @@ static int tomoyo_sb_pivotroot(struct pa
57130 * tomoyo_security_ops is a "struct security_operations" which is used for
57131 * registering TOMOYO.
57132 */
57133 -static struct security_operations tomoyo_security_ops = {
57134 +static struct security_operations tomoyo_security_ops __read_only = {
57135 .name = "tomoyo",
57136 .cred_alloc_blank = tomoyo_cred_alloc_blank,
57137 .cred_prepare = tomoyo_cred_prepare,
57138 diff -urNp linux-2.6.36/sound/aoa/codecs/onyx.c linux-2.6.36/sound/aoa/codecs/onyx.c
57139 --- linux-2.6.36/sound/aoa/codecs/onyx.c 2010-10-20 16:30:22.000000000 -0400
57140 +++ linux-2.6.36/sound/aoa/codecs/onyx.c 2010-11-06 18:58:15.000000000 -0400
57141 @@ -54,7 +54,7 @@ struct onyx {
57142 spdif_locked:1,
57143 analog_locked:1,
57144 original_mute:2;
57145 - int open_count;
57146 + atomic_t open_count;
57147 struct codec_info *codec_info;
57148
57149 /* mutex serializes concurrent access to the device
57150 @@ -753,7 +753,7 @@ static int onyx_open(struct codec_info_i
57151 struct onyx *onyx = cii->codec_data;
57152
57153 mutex_lock(&onyx->mutex);
57154 - onyx->open_count++;
57155 + atomic_inc(&onyx->open_count);
57156 mutex_unlock(&onyx->mutex);
57157
57158 return 0;
57159 @@ -765,8 +765,7 @@ static int onyx_close(struct codec_info_
57160 struct onyx *onyx = cii->codec_data;
57161
57162 mutex_lock(&onyx->mutex);
57163 - onyx->open_count--;
57164 - if (!onyx->open_count)
57165 + if (atomic_dec_and_test(&onyx->open_count))
57166 onyx->spdif_locked = onyx->analog_locked = 0;
57167 mutex_unlock(&onyx->mutex);
57168
57169 diff -urNp linux-2.6.36/sound/core/oss/pcm_oss.c linux-2.6.36/sound/core/oss/pcm_oss.c
57170 --- linux-2.6.36/sound/core/oss/pcm_oss.c 2010-10-20 16:30:22.000000000 -0400
57171 +++ linux-2.6.36/sound/core/oss/pcm_oss.c 2010-11-06 18:58:15.000000000 -0400
57172 @@ -2966,8 +2966,8 @@ static void snd_pcm_oss_proc_done(struct
57173 }
57174 }
57175 #else /* !CONFIG_SND_VERBOSE_PROCFS */
57176 -#define snd_pcm_oss_proc_init(pcm)
57177 -#define snd_pcm_oss_proc_done(pcm)
57178 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
57179 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
57180 #endif /* CONFIG_SND_VERBOSE_PROCFS */
57181
57182 /*
57183 diff -urNp linux-2.6.36/sound/core/seq/seq_lock.h linux-2.6.36/sound/core/seq/seq_lock.h
57184 --- linux-2.6.36/sound/core/seq/seq_lock.h 2010-10-20 16:30:22.000000000 -0400
57185 +++ linux-2.6.36/sound/core/seq/seq_lock.h 2010-11-06 18:58:15.000000000 -0400
57186 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
57187 #else /* SMP || CONFIG_SND_DEBUG */
57188
57189 typedef spinlock_t snd_use_lock_t; /* dummy */
57190 -#define snd_use_lock_init(lockp) /**/
57191 -#define snd_use_lock_use(lockp) /**/
57192 -#define snd_use_lock_free(lockp) /**/
57193 -#define snd_use_lock_sync(lockp) /**/
57194 +#define snd_use_lock_init(lockp) do {} while (0)
57195 +#define snd_use_lock_use(lockp) do {} while (0)
57196 +#define snd_use_lock_free(lockp) do {} while (0)
57197 +#define snd_use_lock_sync(lockp) do {} while (0)
57198
57199 #endif /* SMP || CONFIG_SND_DEBUG */
57200
57201 diff -urNp linux-2.6.36/sound/drivers/mts64.c linux-2.6.36/sound/drivers/mts64.c
57202 --- linux-2.6.36/sound/drivers/mts64.c 2010-10-20 16:30:22.000000000 -0400
57203 +++ linux-2.6.36/sound/drivers/mts64.c 2010-11-06 18:58:15.000000000 -0400
57204 @@ -66,7 +66,7 @@ struct mts64 {
57205 struct pardevice *pardev;
57206 int pardev_claimed;
57207
57208 - int open_count;
57209 + atomic_t open_count;
57210 int current_midi_output_port;
57211 int current_midi_input_port;
57212 u8 mode[MTS64_NUM_INPUT_PORTS];
57213 @@ -696,7 +696,7 @@ static int snd_mts64_rawmidi_open(struct
57214 {
57215 struct mts64 *mts = substream->rmidi->private_data;
57216
57217 - if (mts->open_count == 0) {
57218 + if (atomic_read(&mts->open_count) == 0) {
57219 /* We don't need a spinlock here, because this is just called
57220 if the device has not been opened before.
57221 So there aren't any IRQs from the device */
57222 @@ -704,7 +704,7 @@ static int snd_mts64_rawmidi_open(struct
57223
57224 msleep(50);
57225 }
57226 - ++(mts->open_count);
57227 + atomic_inc(&mts->open_count);
57228
57229 return 0;
57230 }
57231 @@ -714,8 +714,7 @@ static int snd_mts64_rawmidi_close(struc
57232 struct mts64 *mts = substream->rmidi->private_data;
57233 unsigned long flags;
57234
57235 - --(mts->open_count);
57236 - if (mts->open_count == 0) {
57237 + if (atomic_dec_return(&mts->open_count) == 0) {
57238 /* We need the spinlock_irqsave here because we can still
57239 have IRQs at this point */
57240 spin_lock_irqsave(&mts->lock, flags);
57241 @@ -724,8 +723,8 @@ static int snd_mts64_rawmidi_close(struc
57242
57243 msleep(500);
57244
57245 - } else if (mts->open_count < 0)
57246 - mts->open_count = 0;
57247 + } else if (atomic_read(&mts->open_count) < 0)
57248 + atomic_set(&mts->open_count, 0);
57249
57250 return 0;
57251 }
57252 diff -urNp linux-2.6.36/sound/drivers/portman2x4.c linux-2.6.36/sound/drivers/portman2x4.c
57253 --- linux-2.6.36/sound/drivers/portman2x4.c 2010-10-20 16:30:22.000000000 -0400
57254 +++ linux-2.6.36/sound/drivers/portman2x4.c 2010-11-06 18:58:15.000000000 -0400
57255 @@ -84,7 +84,7 @@ struct portman {
57256 struct pardevice *pardev;
57257 int pardev_claimed;
57258
57259 - int open_count;
57260 + atomic_t open_count;
57261 int mode[PORTMAN_NUM_INPUT_PORTS];
57262 struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS];
57263 };
57264 diff -urNp linux-2.6.36/sound/oss/sb_audio.c linux-2.6.36/sound/oss/sb_audio.c
57265 --- linux-2.6.36/sound/oss/sb_audio.c 2010-10-20 16:30:22.000000000 -0400
57266 +++ linux-2.6.36/sound/oss/sb_audio.c 2010-11-06 18:58:15.000000000 -0400
57267 @@ -901,7 +901,7 @@ sb16_copy_from_user(int dev,
57268 buf16 = (signed short *)(localbuf + localoffs);
57269 while (c)
57270 {
57271 - locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c);
57272 + locallen = ((unsigned)c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c);
57273 if (copy_from_user(lbuf8,
57274 userbuf+useroffs + p,
57275 locallen))
57276 diff -urNp linux-2.6.36/sound/pci/ac97/ac97_codec.c linux-2.6.36/sound/pci/ac97/ac97_codec.c
57277 --- linux-2.6.36/sound/pci/ac97/ac97_codec.c 2010-10-20 16:30:22.000000000 -0400
57278 +++ linux-2.6.36/sound/pci/ac97/ac97_codec.c 2010-11-06 18:58:15.000000000 -0400
57279 @@ -1962,7 +1962,7 @@ static int snd_ac97_dev_disconnect(struc
57280 }
57281
57282 /* build_ops to do nothing */
57283 -static struct snd_ac97_build_ops null_build_ops;
57284 +static const struct snd_ac97_build_ops null_build_ops;
57285
57286 #ifdef CONFIG_SND_AC97_POWER_SAVE
57287 static void do_update_power(struct work_struct *work)
57288 diff -urNp linux-2.6.36/sound/pci/ac97/ac97_patch.c linux-2.6.36/sound/pci/ac97/ac97_patch.c
57289 --- linux-2.6.36/sound/pci/ac97/ac97_patch.c 2010-10-20 16:30:22.000000000 -0400
57290 +++ linux-2.6.36/sound/pci/ac97/ac97_patch.c 2010-11-06 18:58:15.000000000 -0400
57291 @@ -371,7 +371,7 @@ static int patch_yamaha_ymf743_build_spd
57292 return 0;
57293 }
57294
57295 -static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
57296 +static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
57297 .build_spdif = patch_yamaha_ymf743_build_spdif,
57298 .build_3d = patch_yamaha_ymf7x3_3d,
57299 };
57300 @@ -455,7 +455,7 @@ static int patch_yamaha_ymf753_post_spdi
57301 return 0;
57302 }
57303
57304 -static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
57305 +static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
57306 .build_3d = patch_yamaha_ymf7x3_3d,
57307 .build_post_spdif = patch_yamaha_ymf753_post_spdif
57308 };
57309 @@ -502,7 +502,7 @@ static int patch_wolfson_wm9703_specific
57310 return 0;
57311 }
57312
57313 -static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
57314 +static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
57315 .build_specific = patch_wolfson_wm9703_specific,
57316 };
57317
57318 @@ -533,7 +533,7 @@ static int patch_wolfson_wm9704_specific
57319 return 0;
57320 }
57321
57322 -static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
57323 +static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
57324 .build_specific = patch_wolfson_wm9704_specific,
57325 };
57326
57327 @@ -677,7 +677,7 @@ static int patch_wolfson_wm9711_specific
57328 return 0;
57329 }
57330
57331 -static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
57332 +static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
57333 .build_specific = patch_wolfson_wm9711_specific,
57334 };
57335
57336 @@ -871,7 +871,7 @@ static void patch_wolfson_wm9713_resume
57337 }
57338 #endif
57339
57340 -static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
57341 +static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
57342 .build_specific = patch_wolfson_wm9713_specific,
57343 .build_3d = patch_wolfson_wm9713_3d,
57344 #ifdef CONFIG_PM
57345 @@ -976,7 +976,7 @@ static int patch_sigmatel_stac97xx_speci
57346 return 0;
57347 }
57348
57349 -static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
57350 +static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
57351 .build_3d = patch_sigmatel_stac9700_3d,
57352 .build_specific = patch_sigmatel_stac97xx_specific
57353 };
57354 @@ -1023,7 +1023,7 @@ static int patch_sigmatel_stac9708_speci
57355 return patch_sigmatel_stac97xx_specific(ac97);
57356 }
57357
57358 -static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
57359 +static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
57360 .build_3d = patch_sigmatel_stac9708_3d,
57361 .build_specific = patch_sigmatel_stac9708_specific
57362 };
57363 @@ -1252,7 +1252,7 @@ static int patch_sigmatel_stac9758_speci
57364 return 0;
57365 }
57366
57367 -static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
57368 +static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
57369 .build_3d = patch_sigmatel_stac9700_3d,
57370 .build_specific = patch_sigmatel_stac9758_specific
57371 };
57372 @@ -1327,7 +1327,7 @@ static int patch_cirrus_build_spdif(stru
57373 return 0;
57374 }
57375
57376 -static struct snd_ac97_build_ops patch_cirrus_ops = {
57377 +static const struct snd_ac97_build_ops patch_cirrus_ops = {
57378 .build_spdif = patch_cirrus_build_spdif
57379 };
57380
57381 @@ -1384,7 +1384,7 @@ static int patch_conexant_build_spdif(st
57382 return 0;
57383 }
57384
57385 -static struct snd_ac97_build_ops patch_conexant_ops = {
57386 +static const struct snd_ac97_build_ops patch_conexant_ops = {
57387 .build_spdif = patch_conexant_build_spdif
57388 };
57389
57390 @@ -1486,7 +1486,7 @@ static const struct snd_ac97_res_table a
57391 { AC97_VIDEO, 0x9f1f },
57392 { AC97_AUX, 0x9f1f },
57393 { AC97_PCM, 0x9f1f },
57394 - { } /* terminator */
57395 + { 0, 0 } /* terminator */
57396 };
57397
57398 static int patch_ad1819(struct snd_ac97 * ac97)
57399 @@ -1560,7 +1560,7 @@ static void patch_ad1881_chained(struct
57400 }
57401 }
57402
57403 -static struct snd_ac97_build_ops patch_ad1881_build_ops = {
57404 +static const struct snd_ac97_build_ops patch_ad1881_build_ops = {
57405 #ifdef CONFIG_PM
57406 .resume = ad18xx_resume
57407 #endif
57408 @@ -1647,7 +1647,7 @@ static int patch_ad1885_specific(struct
57409 return 0;
57410 }
57411
57412 -static struct snd_ac97_build_ops patch_ad1885_build_ops = {
57413 +static const struct snd_ac97_build_ops patch_ad1885_build_ops = {
57414 .build_specific = &patch_ad1885_specific,
57415 #ifdef CONFIG_PM
57416 .resume = ad18xx_resume
57417 @@ -1674,7 +1674,7 @@ static int patch_ad1886_specific(struct
57418 return 0;
57419 }
57420
57421 -static struct snd_ac97_build_ops patch_ad1886_build_ops = {
57422 +static const struct snd_ac97_build_ops patch_ad1886_build_ops = {
57423 .build_specific = &patch_ad1886_specific,
57424 #ifdef CONFIG_PM
57425 .resume = ad18xx_resume
57426 @@ -1881,7 +1881,7 @@ static int patch_ad1981a_specific(struct
57427 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
57428 }
57429
57430 -static struct snd_ac97_build_ops patch_ad1981a_build_ops = {
57431 +static const struct snd_ac97_build_ops patch_ad1981a_build_ops = {
57432 .build_post_spdif = patch_ad198x_post_spdif,
57433 .build_specific = patch_ad1981a_specific,
57434 #ifdef CONFIG_PM
57435 @@ -1936,7 +1936,7 @@ static int patch_ad1981b_specific(struct
57436 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
57437 }
57438
57439 -static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
57440 +static const struct snd_ac97_build_ops patch_ad1981b_build_ops = {
57441 .build_post_spdif = patch_ad198x_post_spdif,
57442 .build_specific = patch_ad1981b_specific,
57443 #ifdef CONFIG_PM
57444 @@ -2075,7 +2075,7 @@ static int patch_ad1888_specific(struct
57445 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
57446 }
57447
57448 -static struct snd_ac97_build_ops patch_ad1888_build_ops = {
57449 +static const struct snd_ac97_build_ops patch_ad1888_build_ops = {
57450 .build_post_spdif = patch_ad198x_post_spdif,
57451 .build_specific = patch_ad1888_specific,
57452 #ifdef CONFIG_PM
57453 @@ -2124,7 +2124,7 @@ static int patch_ad1980_specific(struct
57454 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
57455 }
57456
57457 -static struct snd_ac97_build_ops patch_ad1980_build_ops = {
57458 +static const struct snd_ac97_build_ops patch_ad1980_build_ops = {
57459 .build_post_spdif = patch_ad198x_post_spdif,
57460 .build_specific = patch_ad1980_specific,
57461 #ifdef CONFIG_PM
57462 @@ -2239,7 +2239,7 @@ static int patch_ad1985_specific(struct
57463 ARRAY_SIZE(snd_ac97_ad1985_controls));
57464 }
57465
57466 -static struct snd_ac97_build_ops patch_ad1985_build_ops = {
57467 +static const struct snd_ac97_build_ops patch_ad1985_build_ops = {
57468 .build_post_spdif = patch_ad198x_post_spdif,
57469 .build_specific = patch_ad1985_specific,
57470 #ifdef CONFIG_PM
57471 @@ -2531,7 +2531,7 @@ static int patch_ad1986_specific(struct
57472 ARRAY_SIZE(snd_ac97_ad1985_controls));
57473 }
57474
57475 -static struct snd_ac97_build_ops patch_ad1986_build_ops = {
57476 +static const struct snd_ac97_build_ops patch_ad1986_build_ops = {
57477 .build_post_spdif = patch_ad198x_post_spdif,
57478 .build_specific = patch_ad1986_specific,
57479 #ifdef CONFIG_PM
57480 @@ -2636,7 +2636,7 @@ static int patch_alc650_specific(struct
57481 return 0;
57482 }
57483
57484 -static struct snd_ac97_build_ops patch_alc650_ops = {
57485 +static const struct snd_ac97_build_ops patch_alc650_ops = {
57486 .build_specific = patch_alc650_specific,
57487 .update_jacks = alc650_update_jacks
57488 };
57489 @@ -2788,7 +2788,7 @@ static int patch_alc655_specific(struct
57490 return 0;
57491 }
57492
57493 -static struct snd_ac97_build_ops patch_alc655_ops = {
57494 +static const struct snd_ac97_build_ops patch_alc655_ops = {
57495 .build_specific = patch_alc655_specific,
57496 .update_jacks = alc655_update_jacks
57497 };
57498 @@ -2900,7 +2900,7 @@ static int patch_alc850_specific(struct
57499 return 0;
57500 }
57501
57502 -static struct snd_ac97_build_ops patch_alc850_ops = {
57503 +static const struct snd_ac97_build_ops patch_alc850_ops = {
57504 .build_specific = patch_alc850_specific,
57505 .update_jacks = alc850_update_jacks
57506 };
57507 @@ -2962,7 +2962,7 @@ static int patch_cm9738_specific(struct
57508 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
57509 }
57510
57511 -static struct snd_ac97_build_ops patch_cm9738_ops = {
57512 +static const struct snd_ac97_build_ops patch_cm9738_ops = {
57513 .build_specific = patch_cm9738_specific,
57514 .update_jacks = cm9738_update_jacks
57515 };
57516 @@ -3053,7 +3053,7 @@ static int patch_cm9739_post_spdif(struc
57517 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
57518 }
57519
57520 -static struct snd_ac97_build_ops patch_cm9739_ops = {
57521 +static const struct snd_ac97_build_ops patch_cm9739_ops = {
57522 .build_specific = patch_cm9739_specific,
57523 .build_post_spdif = patch_cm9739_post_spdif,
57524 .update_jacks = cm9739_update_jacks
57525 @@ -3227,7 +3227,7 @@ static int patch_cm9761_specific(struct
57526 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
57527 }
57528
57529 -static struct snd_ac97_build_ops patch_cm9761_ops = {
57530 +static const struct snd_ac97_build_ops patch_cm9761_ops = {
57531 .build_specific = patch_cm9761_specific,
57532 .build_post_spdif = patch_cm9761_post_spdif,
57533 .update_jacks = cm9761_update_jacks
57534 @@ -3323,7 +3323,7 @@ static int patch_cm9780_specific(struct
57535 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
57536 }
57537
57538 -static struct snd_ac97_build_ops patch_cm9780_ops = {
57539 +static const struct snd_ac97_build_ops patch_cm9780_ops = {
57540 .build_specific = patch_cm9780_specific,
57541 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */
57542 };
57543 @@ -3443,7 +3443,7 @@ static int patch_vt1616_specific(struct
57544 return 0;
57545 }
57546
57547 -static struct snd_ac97_build_ops patch_vt1616_ops = {
57548 +static const struct snd_ac97_build_ops patch_vt1616_ops = {
57549 .build_specific = patch_vt1616_specific
57550 };
57551
57552 @@ -3797,7 +3797,7 @@ static int patch_it2646_specific(struct
57553 return 0;
57554 }
57555
57556 -static struct snd_ac97_build_ops patch_it2646_ops = {
57557 +static const struct snd_ac97_build_ops patch_it2646_ops = {
57558 .build_specific = patch_it2646_specific,
57559 .update_jacks = it2646_update_jacks
57560 };
57561 @@ -3831,7 +3831,7 @@ static int patch_si3036_specific(struct
57562 return 0;
57563 }
57564
57565 -static struct snd_ac97_build_ops patch_si3036_ops = {
57566 +static const struct snd_ac97_build_ops patch_si3036_ops = {
57567 .build_specific = patch_si3036_specific,
57568 };
57569
57570 @@ -3864,7 +3864,7 @@ static struct snd_ac97_res_table lm4550_
57571 { AC97_AUX, 0x1f1f },
57572 { AC97_PCM, 0x1f1f },
57573 { AC97_REC_GAIN, 0x0f0f },
57574 - { } /* terminator */
57575 + { 0, 0 } /* terminator */
57576 };
57577
57578 static int patch_lm4550(struct snd_ac97 *ac97)
57579 @@ -3898,7 +3898,7 @@ static int patch_ucb1400_specific(struct
57580 return 0;
57581 }
57582
57583 -static struct snd_ac97_build_ops patch_ucb1400_ops = {
57584 +static const struct snd_ac97_build_ops patch_ucb1400_ops = {
57585 .build_specific = patch_ucb1400_specific,
57586 };
57587
57588 diff -urNp linux-2.6.36/sound/pci/ens1370.c linux-2.6.36/sound/pci/ens1370.c
57589 --- linux-2.6.36/sound/pci/ens1370.c 2010-10-20 16:30:22.000000000 -0400
57590 +++ linux-2.6.36/sound/pci/ens1370.c 2010-11-06 18:58:15.000000000 -0400
57591 @@ -452,7 +452,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_audio
57592 { PCI_VDEVICE(ENSONIQ, 0x5880), 0, }, /* ES1373 - CT5880 */
57593 { PCI_VDEVICE(ECTIVA, 0x8938), 0, }, /* Ectiva EV1938 */
57594 #endif
57595 - { 0, }
57596 + { 0, 0, 0, 0, 0, 0, 0 }
57597 };
57598
57599 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
57600 diff -urNp linux-2.6.36/sound/pci/hda/patch_hdmi.c linux-2.6.36/sound/pci/hda/patch_hdmi.c
57601 --- linux-2.6.36/sound/pci/hda/patch_hdmi.c 2010-10-20 16:30:22.000000000 -0400
57602 +++ linux-2.6.36/sound/pci/hda/patch_hdmi.c 2010-11-06 18:58:15.000000000 -0400
57603 @@ -671,10 +671,10 @@ static void hdmi_non_intrinsic_event(str
57604 cp_ready);
57605
57606 /* TODO */
57607 - if (cp_state)
57608 - ;
57609 - if (cp_ready)
57610 - ;
57611 + if (cp_state) {
57612 + }
57613 + if (cp_ready) {
57614 + }
57615 }
57616
57617
57618 diff -urNp linux-2.6.36/sound/pci/intel8x0.c linux-2.6.36/sound/pci/intel8x0.c
57619 --- linux-2.6.36/sound/pci/intel8x0.c 2010-10-20 16:30:22.000000000 -0400
57620 +++ linux-2.6.36/sound/pci/intel8x0.c 2010-11-06 18:58:15.000000000 -0400
57621 @@ -444,7 +444,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_intel
57622 { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
57623 { PCI_VDEVICE(AMD, 0x7445), DEVICE_INTEL }, /* AMD768 */
57624 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
57625 - { 0, }
57626 + { 0, 0, 0, 0, 0, 0, 0 }
57627 };
57628
57629 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
57630 @@ -2135,7 +2135,7 @@ static struct ac97_quirk ac97_quirks[] _
57631 .type = AC97_TUNE_HP_ONLY
57632 },
57633 #endif
57634 - { } /* terminator */
57635 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
57636 };
57637
57638 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
57639 diff -urNp linux-2.6.36/sound/pci/intel8x0m.c linux-2.6.36/sound/pci/intel8x0m.c
57640 --- linux-2.6.36/sound/pci/intel8x0m.c 2010-10-20 16:30:22.000000000 -0400
57641 +++ linux-2.6.36/sound/pci/intel8x0m.c 2010-11-06 18:58:15.000000000 -0400
57642 @@ -239,7 +239,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_intel
57643 { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
57644 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
57645 #endif
57646 - { 0, }
57647 + { 0, 0, 0, 0, 0, 0, 0 }
57648 };
57649
57650 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
57651 @@ -1264,7 +1264,7 @@ static struct shortname_table {
57652 { 0x5455, "ALi M5455" },
57653 { 0x746d, "AMD AMD8111" },
57654 #endif
57655 - { 0 },
57656 + { 0, NULL },
57657 };
57658
57659 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
57660 diff -urNp linux-2.6.36/usr/gen_init_cpio.c linux-2.6.36/usr/gen_init_cpio.c
57661 --- linux-2.6.36/usr/gen_init_cpio.c 2010-10-20 16:30:22.000000000 -0400
57662 +++ linux-2.6.36/usr/gen_init_cpio.c 2010-11-06 18:58:15.000000000 -0400
57663 @@ -299,7 +299,7 @@ static int cpio_mkfile(const char *name,
57664 int retval;
57665 int rc = -1;
57666 int namesize;
57667 - int i;
57668 + unsigned int i;
57669
57670 mode |= S_IFREG;
57671
57672 @@ -386,9 +386,10 @@ static char *cpio_replace_env(char *new_
57673 *env_var = *expanded = '\0';
57674 strncat(env_var, start + 2, end - start - 2);
57675 strncat(expanded, new_location, start - new_location);
57676 - strncat(expanded, getenv(env_var), PATH_MAX);
57677 - strncat(expanded, end + 1, PATH_MAX);
57678 + strncat(expanded, getenv(env_var), PATH_MAX - strlen(expanded));
57679 + strncat(expanded, end + 1, PATH_MAX - strlen(expanded));
57680 strncpy(new_location, expanded, PATH_MAX);
57681 + new_location[PATH_MAX] = 0;
57682 } else
57683 break;
57684 }
57685 diff -urNp linux-2.6.36/virt/kvm/kvm_main.c linux-2.6.36/virt/kvm/kvm_main.c
57686 --- linux-2.6.36/virt/kvm/kvm_main.c 2010-10-20 16:30:22.000000000 -0400
57687 +++ linux-2.6.36/virt/kvm/kvm_main.c 2010-11-06 18:58:15.000000000 -0400
57688 @@ -1300,6 +1300,7 @@ static int kvm_vcpu_release(struct inode
57689 return 0;
57690 }
57691
57692 +/* cannot be const */
57693 static struct file_operations kvm_vcpu_fops = {
57694 .release = kvm_vcpu_release,
57695 .unlocked_ioctl = kvm_vcpu_ioctl,
57696 @@ -1767,6 +1768,7 @@ static int kvm_vm_mmap(struct file *file
57697 return 0;
57698 }
57699
57700 +/* cannot be const */
57701 static struct file_operations kvm_vm_fops = {
57702 .release = kvm_vm_release,
57703 .unlocked_ioctl = kvm_vm_ioctl,
57704 @@ -1864,6 +1866,7 @@ out:
57705 return r;
57706 }
57707
57708 +/* cannot be const */
57709 static struct file_operations kvm_chardev_ops = {
57710 .unlocked_ioctl = kvm_dev_ioctl,
57711 .compat_ioctl = kvm_dev_ioctl,
57712 @@ -1873,6 +1876,9 @@ static struct miscdevice kvm_dev = {
57713 KVM_MINOR,
57714 "kvm",
57715 &kvm_chardev_ops,
57716 + {NULL, NULL},
57717 + NULL,
57718 + NULL
57719 };
57720
57721 static void hardware_enable(void *junk)
57722 @@ -1974,7 +1980,7 @@ asmlinkage void kvm_handle_fault_on_rebo
57723 /* spin while reset goes on */
57724 local_irq_enable();
57725 while (true)
57726 - ;
57727 + cpu_relax();
57728 }
57729 /* Fault while not rebooting. We want the trace. */
57730 BUG();
57731 @@ -2208,7 +2214,7 @@ static void kvm_sched_out(struct preempt
57732 kvm_arch_vcpu_put(vcpu);
57733 }
57734
57735 -int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
57736 +int kvm_init(const void *opaque, unsigned vcpu_size, unsigned vcpu_align,
57737 struct module *module)
57738 {
57739 int r;