]> git.pld-linux.org Git - packages/kernel.git/blob - exec-shield-nx-2.6.7-A0
- obsolete
[packages/kernel.git] / exec-shield-nx-2.6.7-A0
1 --- linux/drivers/char/drm/ffb_drv.c.orig       
2 +++ linux/drivers/char/drm/ffb_drv.c    
3 @@ -285,19 +285,19 @@ static unsigned long ffb_get_unmapped_ar
4         unsigned long addr = -ENOMEM;
5  
6         if (!map)
7 -               return get_unmapped_area(NULL, hint, len, pgoff, flags);
8 +               return get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
9  
10         if (map->type == _DRM_FRAME_BUFFER ||
11             map->type == _DRM_REGISTERS) {
12  #ifdef HAVE_ARCH_FB_UNMAPPED_AREA
13                 addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags);
14  #else
15 -               addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
16 +               addr = get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
17  #endif
18         } else if (map->type == _DRM_SHM && SHMLBA > PAGE_SIZE) {
19                 unsigned long slack = SHMLBA - PAGE_SIZE;
20  
21 -               addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags);
22 +               addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags, 0);
23                 if (!(addr & ~PAGE_MASK)) {
24                         unsigned long kvirt = (unsigned long) map->handle;
25  
26 @@ -313,7 +313,7 @@ static unsigned long ffb_get_unmapped_ar
27                         }
28                 }
29         } else {
30 -               addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
31 +               addr = get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
32         }
33  
34         return addr;
35 --- linux/arch/sparc64/kernel/sys_sparc.c.orig  
36 +++ linux/arch/sparc64/kernel/sys_sparc.c       
37 @@ -127,7 +127,7 @@ unsigned long get_fb_unmapped_area(struc
38  
39         if (flags & MAP_FIXED) {
40                 /* Ok, don't mess with it. */
41 -               return get_unmapped_area(NULL, addr, len, pgoff, flags);
42 +               return get_unmapped_area(NULL, addr, len, pgoff, flags, 0);
43         }
44         flags &= ~MAP_SHARED;
45  
46 @@ -140,7 +140,7 @@ unsigned long get_fb_unmapped_area(struc
47                 align_goal = (64UL * 1024);
48  
49         do {
50 -               addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
51 +               addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags, 0);
52                 if (!(addr & ~PAGE_MASK)) {
53                         addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
54                         break;
55 @@ -158,7 +158,7 @@ unsigned long get_fb_unmapped_area(struc
56          * be obtained.
57          */
58         if (addr & ~PAGE_MASK)
59 -               addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
60 +               addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags, 0);
61  
62         return addr;
63  }
64 @@ -402,7 +402,7 @@ asmlinkage unsigned long sys64_mremap(un
65                 /* MREMAP_FIXED checked above. */
66                 new_addr = get_unmapped_area(file, addr, new_len,
67                                     vma ? vma->vm_pgoff : 0,
68 -                                   map_flags);
69 +                                   map_flags, vma->vm_flags & VM_EXEC);
70                 ret = new_addr;
71                 if (new_addr & ~PAGE_MASK)
72                         goto out_sem;
73 --- linux/arch/sparc64/kernel/sys_sparc32.c.orig        
74 +++ linux/arch/sparc64/kernel/sys_sparc32.c     
75 @@ -1750,7 +1750,7 @@ asmlinkage unsigned long sys32_mremap(un
76                 /* MREMAP_FIXED checked above. */
77                 new_addr = get_unmapped_area(file, addr, new_len,
78                                     vma ? vma->vm_pgoff : 0,
79 -                                   map_flags);
80 +                                   map_flags, vma->vm_flags & VM_EXEC);
81                 ret = new_addr;
82                 if (new_addr & ~PAGE_MASK)
83                         goto out_sem;
84 --- linux/arch/i386/kernel/cpu/proc.c.orig      
85 +++ linux/arch/i386/kernel/cpu/proc.c   
86 @@ -27,7 +27,7 @@ static int show_cpuinfo(struct seq_file 
87                 /* AMD-defined */
88                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
89                 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
90 -               NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL,
91 +               NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
92                 NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
93  
94                 /* Transmeta-defined */
95 --- linux/arch/i386/kernel/asm-offsets.c.orig   
96 +++ linux/arch/i386/kernel/asm-offsets.c        
97 @@ -52,6 +52,7 @@ void foo(void)
98         OFFSET(TI_preempt_count, thread_info, preempt_count);
99         OFFSET(TI_addr_limit, thread_info, addr_limit);
100         OFFSET(TI_restart_block, thread_info, restart_block);
101 +       OFFSET(TI_sysenter_return, thread_info, sysenter_return);
102         BLANK();
103  
104         OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
105 --- linux/arch/i386/kernel/entry.S.orig 
106 +++ linux/arch/i386/kernel/entry.S      
107 @@ -238,8 +238,12 @@ sysenter_past_esp:
108         pushl %ebp
109         pushfl
110         pushl $(__USER_CS)
111 -       pushl $SYSENTER_RETURN
112 -
113 +       /*
114 +        * Push current_thread_info()->sysenter_return to the stack.
115 +        * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
116 +        * pushed above, and the word being pushed now:
117 +        */
118 +       pushl (TI_sysenter_return-THREAD_SIZE+4*4)(%esp)
119  /*
120   * Load the potential sixth argument from user stack.
121   * Careful about security.
122 --- linux/arch/i386/kernel/head.S.orig  
123 +++ linux/arch/i386/kernel/head.S       
124 @@ -153,6 +153,32 @@ ENTRY(startup_32_smp)
125         orl %edx,%eax
126         movl %eax,%cr4
127  
128 +       btl $5, %eax            # check if PAE is enabled
129 +       jnc 6f
130 +
131 +       /* Check if extended functions are implemented */
132 +       movl $0x80000000, %eax
133 +       cpuid
134 +       cmpl $0x80000000, %eax
135 +       jbe 6f
136 +       mov $0x80000001, %eax
137 +       cpuid
138 +       /* Execute Disable bit supported? */
139 +       btl $20, %edx
140 +       jnc 6f
141 +
142 +       /* Setup EFER (Extended Feature Enable Register) */
143 +       movl $0xc0000080, %ecx
144 +       rdmsr
145 +
146 +       btsl $11, %eax
147 +       /* Make changes effective */
148 +       wrmsr
149 +
150 +6:
151 +       /* cpuid clobbered ebx, set it up again: */
152 +       xorl %ebx,%ebx
153 +       incl %ebx
154  3:
155  #endif /* CONFIG_SMP */
156  
157 --- linux/arch/i386/kernel/module.c.orig        
158 +++ linux/arch/i386/kernel/module.c     
159 @@ -32,7 +32,7 @@ void *module_alloc(unsigned long size)
160  {
161         if (size == 0)
162                 return NULL;
163 -       return vmalloc(size);
164 +       return vmalloc_exec(size);
165  }
166  
167  
168 --- linux/arch/i386/kernel/process.c.orig       
169 +++ linux/arch/i386/kernel/process.c    
170 @@ -36,6 +36,8 @@
171  #include <linux/module.h>
172  #include <linux/kallsyms.h>
173  #include <linux/ptrace.h>
174 +#include <linux/mman.h>
175 +#include <linux/random.h>
176  
177  #include <asm/uaccess.h>
178  #include <asm/pgtable.h>
179 @@ -512,6 +514,8 @@ struct task_struct fastcall * __switch_t
180         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
181  
182         __unlazy_fpu(prev_p);
183 +       if (next_p->mm)
184 +               load_user_cs_desc(cpu, next_p->mm);
185  
186         /*
187          * Reload esp0, LDT and the page table pointer:
188 @@ -776,3 +780,303 @@ asmlinkage int sys_get_thread_area(struc
189         return 0;
190  }
191  
192 +/*
193 + * Get a random word:
194 + */
195 +static inline unsigned int get_random_int(void)
196 +{
197 +       unsigned int val = 0;
198 +
199 +       if (!exec_shield_randomize)
200 +               return 0;
201 +
202 +#ifdef CONFIG_X86_HAS_TSC
203 +       rdtscl(val);
204 +#endif
205 +       val += current->pid + jiffies + (int)&val;
206 +
207 +       /*
208 +        * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
209 +        * every second, from the entropy pool (and thus creates a limited
210 +        * drain on it), and uses halfMD4Transform within the second. We
211 +        * also spice it with the TSC (if available), jiffies, PID and the
212 +        * stack address:
213 +        */
214 +       return secure_ip_id(val);
215 +}
216 +
217 +unsigned long arch_align_stack(unsigned long sp)
218 +{
219 +       if (current->mm && !(current->mm->def_flags & VM_EXEC))
220 +               sp -= ((get_random_int() % 65536) << 4);
221 +       return sp & ~0xf;
222 +}
223 +
224 +#if SHLIB_BASE >= 0x01000000
225 +# error SHLIB_BASE must be under 16MB!
226 +#endif
227 +
228 +static unsigned long
229 +arch_get_unmapped_nonexecutable_area(struct mm_struct *mm, unsigned long addr, unsigned long len)
230 +{
231 +       struct vm_area_struct *vma, *prev_vma;
232 +       unsigned long stack_limit;
233 +       int first_time = 1;     
234 +
235 +       if (!mm->mmap_top) {
236 +               printk("hm, %s:%d, !mmap_top.\n", current->comm, current->pid);
237 +               mm->mmap_top = mmap_top();
238 +       }
239 +       stack_limit = mm->mmap_top;
240 +
241 +       /* requested length too big for entire address space */
242 +       if (len > TASK_SIZE) 
243 +               return -ENOMEM;
244 +
245 +       /* dont allow allocations above current stack limit */
246 +       if (mm->non_executable_cache > stack_limit)
247 +               mm->non_executable_cache = stack_limit;
248 +
249 +       /* requesting a specific address */
250 +        if (addr) {
251 +                addr = PAGE_ALIGN(addr);
252 +                vma = find_vma(mm, addr);
253 +               if (TASK_SIZE - len >= addr && 
254 +                   (!vma || addr + len <= vma->vm_start))
255 +                       return addr;
256 +        }
257 +
258 +       /* make sure it can fit in the remaining address space */
259 +       if (mm->non_executable_cache < len)
260 +               return -ENOMEM;
261 +
262 +       /* either no address requested or cant fit in requested address hole */
263 +try_again:
264 +        addr = (mm->non_executable_cache - len)&PAGE_MASK;
265 +       do {
266 +                       if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
267 +                        return -ENOMEM;
268 +
269 +               /* new region fits between prev_vma->vm_end and vma->vm_start, use it */
270 +               if (addr+len <= vma->vm_start && (!prev_vma || (addr >= prev_vma->vm_end))) {
271 +                       /* remember the address as a hint for next time */
272 +                       mm->non_executable_cache = addr;
273 +                       return addr;
274 +
275 +               /* pull non_executable_cache down to the first hole */
276 +               } else if (mm->non_executable_cache == vma->vm_end)
277 +                               mm->non_executable_cache = vma->vm_start;       
278 +
279 +               /* try just below the current vma->vm_start */
280 +               addr = vma->vm_start-len;
281 +        } while (len <= vma->vm_start);
282 +       /* if hint left us with no space for the requested mapping try again */
283 +       if (first_time) {
284 +               first_time = 0;
285 +               mm->non_executable_cache = stack_limit;
286 +               goto try_again;
287 +       }
288 +       return -ENOMEM;
289 +}
290 +
291 +static unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len)
292 +{
293 +       unsigned long range = end - len - start;
294 +       if (end <= start + len)
295 +               return 0;
296 +       return PAGE_ALIGN(get_random_int() % range + start);
297 +}
298 +
299 +static inline unsigned long
300 +stock_arch_get_unmapped_area(struct file *filp, unsigned long addr,
301 +               unsigned long len, unsigned long pgoff, unsigned long flags)
302 +{
303 +       struct mm_struct *mm = current->mm;
304 +       struct vm_area_struct *vma;
305 +       unsigned long start_addr;
306 +
307 +       if (len > TASK_SIZE)
308 +               return -ENOMEM;
309 +
310 +       if (addr) {
311 +               addr = PAGE_ALIGN(addr);
312 +               vma = find_vma(mm, addr);
313 +               if (TASK_SIZE - len >= addr &&
314 +                   (!vma || addr + len <= vma->vm_start))
315 +                       return addr;
316 +       }
317 +       start_addr = addr = mm->free_area_cache;
318 +
319 +full_search:
320 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
321 +               /* At this point:  (!vma || addr < vma->vm_end). */
322 +               if (TASK_SIZE - len < addr) {
323 +                       /*
324 +                        * Start a new search - just in case we missed
325 +                        * some holes.
326 +                        */
327 +                       if (start_addr != TASK_UNMAPPED_BASE) {
328 +                               start_addr = addr = TASK_UNMAPPED_BASE;
329 +                               goto full_search;
330 +                       }
331 +                       return -ENOMEM;
332 +               }
333 +               if (!vma || addr + len <= vma->vm_start) {
334 +                       /*
335 +                        * Remember the place where we stopped the search:
336 +                        */
337 +                       mm->free_area_cache = addr + len;
338 +                       return addr;
339 +               }
340 +               addr = vma->vm_end;
341 +       }
342 +}
343 +
344 +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0,
345 +               unsigned long len0, unsigned long pgoff, unsigned long flags,
346 +               unsigned long prot)
347 +{
348 +       unsigned long addr = addr0, len = len0;
349 +       struct mm_struct *mm = current->mm;
350 +       struct vm_area_struct *vma;
351 +       int ascii_shield = 0;
352 +       unsigned long tmp;
353 +
354 +       /*
355 +        * Fall back to the old layout:
356 +        */
357 +       if (current->mm->def_flags & VM_EXEC)
358 +              return stock_arch_get_unmapped_area(filp, addr0, len0, pgoff, flags);
359 +       if (len > TASK_SIZE)
360 +               return -ENOMEM;
361 +
362 +       if (!addr && (prot & PROT_EXEC) && !(flags & MAP_FIXED))
363 +               addr = randomize_range(SHLIB_BASE, 0x01000000, len);
364 +
365 +       if (addr) {
366 +               addr = PAGE_ALIGN(addr);
367 +               vma = find_vma(mm, addr);
368 +               if (TASK_SIZE - len >= addr &&
369 +                   (!vma || addr + len <= vma->vm_start)) {
370 +                       return addr;
371 +               }
372 +       }
373 +
374 +       if (prot & PROT_EXEC) {
375 +               ascii_shield = 1;
376 +               addr = SHLIB_BASE;
377 +       } else {
378 +               /* this can fail if the stack was unlimited */
379 +               if ((tmp = arch_get_unmapped_nonexecutable_area(mm, addr, len)) != -ENOMEM)
380 +                       return tmp;
381 +search_upper:
382 +               addr = PAGE_ALIGN(arch_align_stack(TASK_UNMAPPED_BASE));
383 +       }
384 +
385 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
386 +               /* At this point:  (!vma || addr < vma->vm_end). */
387 +               if (TASK_SIZE - len < addr) {
388 +                       return -ENOMEM;
389 +               }
390 +               if (!vma || addr + len <= vma->vm_start) {
391 +                       /*
392 +                        * Must not let a PROT_EXEC mapping get into the
393 +                        * brk area:
394 +                        */
395 +                       if (ascii_shield && (addr + len > mm->brk)) {
396 +                               ascii_shield = 0;
397 +                               goto search_upper;
398 +                       }
399 +                       /*
400 +                        * Up until the brk area we randomize addresses
401 +                        * as much as possible:
402 +                        */
403 +                       if (ascii_shield && (addr >= 0x01000000)) {
404 +                               tmp = randomize_range(0x01000000, mm->brk, len);
405 +                               vma = find_vma(mm, tmp);
406 +                               if (TASK_SIZE - len >= tmp &&
407 +                                   (!vma || tmp + len <= vma->vm_start))
408 +                                       return tmp;
409 +                       }
410 +                       /*
411 +                        * Ok, randomization didnt work out - return
412 +                        * the result of the linear search:
413 +                        */
414 +                       return addr;
415 +               }
416 +               addr = vma->vm_end;
417 +       }
418 +}
419 +
420 +void arch_add_exec_range(struct mm_struct *mm, unsigned long limit)
421 +{
422 +       if (limit > mm->context.exec_limit) {
423 +               mm->context.exec_limit = limit;
424 +               set_user_cs(&mm->context.user_cs, limit);
425 +               if (mm == current->mm)
426 +                       load_user_cs_desc(smp_processor_id(), mm);
427 +       }
428 +}
429 +
430 +void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end)
431 +{
432 +       struct vm_area_struct *vma;
433 +       unsigned long limit = 0;
434 +
435 +       if (old_end == mm->context.exec_limit) {
436 +               for (vma = mm->mmap; vma; vma = vma->vm_next)
437 +                       if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
438 +                               limit = vma->vm_end;
439 +
440 +               mm->context.exec_limit = limit;
441 +               set_user_cs(&mm->context.user_cs, limit);
442 +               if (mm == current->mm)
443 +                       load_user_cs_desc(smp_processor_id(), mm);
444 +       }
445 +}
446 +
447 +void arch_flush_exec_range(struct mm_struct *mm)
448 +{
449 +       mm->context.exec_limit = 0;
450 +       set_user_cs(&mm->context.user_cs, 0);
451 +}
452 +
453 +/*
454 + * Generate random brk address between 128MB and 196MB. (if the layout
455 + * allows it.)
456 + */
457 +void randomize_brk(unsigned long old_brk)
458 +{
459 +       unsigned long new_brk, range_start, range_end;
460 +
461 +       range_start = 0x08000000;
462 +       if (current->mm->brk >= range_start)
463 +               range_start = current->mm->brk;
464 +       range_end = range_start + 0x02000000;
465 +       new_brk = randomize_range(range_start, range_end, 0);
466 +       if (new_brk)
467 +               current->mm->brk = new_brk;
468 +}
469 +
470 +/*
471 + * Top of mmap area (just below the process stack).
472 + * leave an at least ~128 MB hole. Randomize it.
473 + */
474 +#define MIN_GAP (128*1024*1024)
475 +#define MAX_GAP (TASK_SIZE/6*5)
476 +
477 +unsigned long mmap_top(void)
478 +{
479 +       unsigned long gap = 0;
480 +
481 +       gap = current->rlim[RLIMIT_STACK].rlim_cur;
482 +       if (gap < MIN_GAP)
483 +               gap = MIN_GAP;
484 +       else if (gap > MAX_GAP)
485 +               gap = MAX_GAP;
486 +
487 +       gap = arch_align_stack(gap) & PAGE_MASK;
488 +
489 +       return TASK_SIZE - gap;
490 +}
491 +
492 --- linux/arch/i386/kernel/signal.c.orig        
493 +++ linux/arch/i386/kernel/signal.c     
494 @@ -333,7 +333,7 @@ get_sigframe(struct k_sigaction *ka, str
495  
496  /* These symbols are defined with the addresses in the vsyscall page.
497     See vsyscall-sigreturn.S.  */
498 -extern void __kernel_sigreturn, __kernel_rt_sigreturn;
499 +extern char __kernel_sigreturn, __kernel_rt_sigreturn, SYSENTER_RETURN;
500  
501  static void setup_frame(int sig, struct k_sigaction *ka,
502                         sigset_t *set, struct pt_regs * regs)
503 @@ -367,7 +367,7 @@ static void setup_frame(int sig, struct 
504         if (err)
505                 goto give_sigsegv;
506  
507 -       restorer = &__kernel_sigreturn;
508 +       restorer = current->mm->context.vdso + (long)&__kernel_sigreturn;
509         if (ka->sa.sa_flags & SA_RESTORER)
510                 restorer = ka->sa.sa_restorer;
511  
512 @@ -450,9 +450,10 @@ static void setup_rt_frame(int sig, stru
513                 goto give_sigsegv;
514  
515         /* Set up to return from userspace.  */
516 -       restorer = &__kernel_rt_sigreturn;
517 +       restorer = current->mm->context.vdso + (long)&__kernel_rt_sigreturn;
518         if (ka->sa.sa_flags & SA_RESTORER)
519                 restorer = ka->sa.sa_restorer;
520 +
521         err |= __put_user(restorer, &frame->pretcode);
522          
523         /*
524 --- linux/arch/i386/kernel/sysenter.c.orig      
525 +++ linux/arch/i386/kernel/sysenter.c   
526 @@ -13,6 +13,7 @@
527  #include <linux/gfp.h>
528  #include <linux/string.h>
529  #include <linux/elf.h>
530 +#include <linux/mman.h>
531  
532  #include <asm/cpufeature.h>
533  #include <asm/msr.h>
534 @@ -41,11 +42,14 @@ void enable_sep_cpu(void *info)
535  extern const char vsyscall_int80_start, vsyscall_int80_end;
536  extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
537  
538 +struct page *sysenter_page;
539 +
540  static int __init sysenter_setup(void)
541  {
542         unsigned long page = get_zeroed_page(GFP_ATOMIC);
543  
544 -       __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY);
545 +       __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_KERNEL_RO);
546 +       sysenter_page = virt_to_page(page);
547  
548         if (!boot_cpu_has(X86_FEATURE_SEP)) {
549                 memcpy((void *) page,
550 @@ -59,7 +63,51 @@ static int __init sysenter_setup(void)
551                &vsyscall_sysenter_end - &vsyscall_sysenter_start);
552  
553         on_each_cpu(enable_sep_cpu, NULL, 1, 1);
554 +
555         return 0;
556  }
557  
558  __initcall(sysenter_setup);
559 +
560 +extern void SYSENTER_RETURN_OFFSET;
561 +
562 +unsigned int vdso_enabled = 1;
563 +
564 +void map_vsyscall(void)
565 +{
566 +       struct thread_info *ti = current_thread_info();
567 +       struct vm_area_struct *vma;
568 +       unsigned long addr;
569 +
570 +       if (unlikely(!vdso_enabled)) {
571 +               current->mm->context.vdso = NULL;
572 +               return;
573 +       }
574 +
575 +       /*
576 +        * Map the vDSO (it will be randomized):
577 +        */
578 +       down_write(&current->mm->mmap_sem);
579 +       addr = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, 0);
580 +       current->mm->context.vdso = (void *)addr;
581 +       ti->sysenter_return = (void *)addr + (long)&SYSENTER_RETURN_OFFSET;
582 +       if (addr != -1) {
583 +               vma = find_vma(current->mm, addr);
584 +               if (vma) {
585 +                       pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
586 +                       get_page(sysenter_page);
587 +                       install_page(current->mm, vma, addr,
588 +                                       sysenter_page, vma->vm_page_prot);
589 +                       
590 +               }
591 +       }
592 +       up_write(&current->mm->mmap_sem);
593 +}
594 +
595 +static int __init vdso_setup(char *str)
596 +{
597 +        vdso_enabled = simple_strtoul(str, NULL, 0);
598 +        return 1;
599 +}
600 +__setup("vdso=", vdso_setup);
601 +
602 --- linux/arch/i386/kernel/traps.c.orig 
603 +++ linux/arch/i386/kernel/traps.c      
604 @@ -428,6 +428,10 @@ DO_ERROR(11, SIGBUS,  "segment not prese
605  DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
606  DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2())
607  
608 +/*
609 + * the original non-exec stack patch was written by
610 + * Solar Designer <solar at openwall.com>. Thanks!
611 + */
612  asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
613  {
614         if (regs->eflags & X86_EFLAGS_IF)
615 @@ -439,6 +443,46 @@ asmlinkage void do_general_protection(st
616         if (!(regs->xcs & 3))
617                 goto gp_in_kernel;
618  
619 +       /*
620 +        * lazy-check for CS validity on exec-shield binaries:
621 +        */
622 +       if (current->mm) {
623 +               int cpu = smp_processor_id();
624 +               struct desc_struct *desc1, *desc2;
625 +               struct vm_area_struct *vma;
626 +               unsigned long limit = 0;
627 +               
628 +               spin_lock(&current->mm->page_table_lock);
629 +               for (vma = current->mm->mmap; vma; vma = vma->vm_next)
630 +                       if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
631 +                               limit = vma->vm_end;
632 +               spin_unlock(&current->mm->page_table_lock);
633 +
634 +               current->mm->context.exec_limit = limit;
635 +               set_user_cs(&current->mm->context.user_cs, limit);
636 +
637 +               desc1 = &current->mm->context.user_cs;
638 +               desc2 = cpu_gdt_table[cpu] + GDT_ENTRY_DEFAULT_USER_CS;
639 +
640 +               /*
641 +                * The CS was not in sync - reload it and retry the
642 +                * instruction. If the instruction still faults then
643 +                * we wont hit this branch next time around.
644 +                */
645 +               if (desc1->a != desc2->a || desc1->b != desc2->b) {
646 +                       if (print_fatal_signals >= 2) {
647 +                               printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
648 +                               printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
649 +                       }
650 +                       load_user_cs_desc(cpu, current->mm);
651 +                       return;
652 +               }
653 +       }
654 +       if (print_fatal_signals) {
655 +               printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
656 +               printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
657 +       }
658 +
659         current->thread.error_code = error_code;
660         current->thread.trap_no = 13;
661         force_sig(SIGSEGV, current);
662 --- linux/arch/i386/kernel/vsyscall-sysenter.S.orig     
663 +++ linux/arch/i386/kernel/vsyscall-sysenter.S  
664 @@ -24,11 +24,11 @@ __kernel_vsyscall:
665         /* 7: align return point with nop's to make disassembly easier */
666         .space 7,0x90
667  
668 -       /* 14: System call restart point is here! (SYSENTER_RETURN - 2) */
669 +       /* 14: System call restart point is here! (SYSENTER_RETURN_OFFSET-2) */
670         jmp .Lenter_kernel
671         /* 16: System call normal return point is here! */
672 -       .globl SYSENTER_RETURN  /* Symbol used by entry.S.  */
673 -SYSENTER_RETURN:
674 +       .globl SYSENTER_RETURN_OFFSET   /* Symbol used by sysenter.c  */
675 +SYSENTER_RETURN_OFFSET:
676         pop %ebp
677  .Lpop_ebp:
678         pop %edx
679 --- linux/arch/i386/kernel/vsyscall.lds.orig    
680 +++ linux/arch/i386/kernel/vsyscall.lds 
681 @@ -1,15 +1,12 @@
682  /*
683   * Linker script for vsyscall DSO.  The vsyscall page is an ELF shared
684 - * object prelinked to its virtual address, and with only one read-only
685 - * segment (that fits in one page).  This script controls its layout.
686 + * object with only one read-only segment (that fits in one page).
687 + * This script controls its layout.
688   */
689  
690 -/* This must match <asm/fixmap.h>.  */
691 -VSYSCALL_BASE = 0xffffe000;
692 -
693  SECTIONS
694  {
695 -  . = VSYSCALL_BASE + SIZEOF_HEADERS;
696 +  . = SIZEOF_HEADERS;
697  
698    .hash           : { *(.hash) }               :text
699    .dynsym         : { *(.dynsym) }
700 @@ -22,7 +19,7 @@ SECTIONS
701       For the layouts to match, we need to skip more than enough
702       space for the dynamic symbol table et al.  If this amount
703       is insufficient, ld -shared will barf.  Just increase it here.  */
704 -  . = VSYSCALL_BASE + 0x400;
705 +  . = 0x400;
706  
707    .text           : { *(.text) }               :text =0x90909090
708  
709 --- linux/arch/i386/mm/fault.c.orig     
710 +++ linux/arch/i386/mm/fault.c  
711 @@ -405,6 +405,21 @@ no_context:
712  
713         bust_spinlocks(1);
714  
715 +#ifdef CONFIG_X86_PAE
716 +       {
717 +               pgd_t *pgd;
718 +               pmd_t *pmd;
719 +
720 +
721 +
722 +               pgd = init_mm.pgd + pgd_index(address);
723 +               if (pgd_present(*pgd)) {
724 +                       pmd = pmd_offset(pgd, address);
725 +                       if (pmd_val(*pmd) & _PAGE_NX)
726 +                               printk(KERN_CRIT "kernel tried to access NX-protected page - exploit attempt? (uid: %d)\n", current->uid);
727 +               }
728 +       }
729 +#endif
730         if (address < PAGE_SIZE)
731                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
732         else
733 --- linux/arch/i386/mm/init.c.orig      
734 +++ linux/arch/i386/mm/init.c   
735 @@ -122,6 +122,13 @@ static void __init page_table_range_init
736         }
737  }
738  
739 +static inline int is_kernel_text(unsigned long addr)
740 +{
741 +       if (addr >= (unsigned long)_stext && addr <= (unsigned long)__init_end)
742 +               return 1;
743 +       return 0;
744 +}
745 +
746  /*
747   * This maps the physical memory to kernel virtual address space, a total 
748   * of max_low_pfn pages, by creating page tables starting from address 
749 @@ -144,18 +151,29 @@ static void __init kernel_physical_mappi
750                 if (pfn >= max_low_pfn)
751                         continue;
752                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
753 +                       unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
754 +
755                         /* Map with big pages if possible, otherwise create normal page tables. */
756                         if (cpu_has_pse) {
757 -                               set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
758 +                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
759 +
760 +                               if (is_kernel_text(address) || is_kernel_text(address2))
761 +                                       set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
762 +                               else
763 +                                       set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
764                                 pfn += PTRS_PER_PTE;
765                         } else {
766                                 pte = one_page_table_init(pmd);
767  
768 -                               for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++)
769 -                                       set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
770 +                               for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
771 +                                               if (is_kernel_text(address))
772 +                                                       set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
773 +                                               else
774 +                                                       set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
775 +                               }
776                         }
777                 }
778 -       }       
779 +       }
780  }
781  
782  static inline int page_kills_ppro(unsigned long pagenr)
783 @@ -272,7 +290,8 @@ extern void set_highmem_pages_init(int);
784  #define set_highmem_pages_init(bad_ppro) do { } while (0)
785  #endif /* CONFIG_HIGHMEM */
786  
787 -unsigned long __PAGE_KERNEL = _PAGE_KERNEL;
788 +unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
789 +unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
790  
791  #ifndef CONFIG_DISCONTIGMEM
792  #define remap_numa_kva() do {} while (0)
793 @@ -301,6 +320,7 @@ static void __init pagetable_init (void)
794         if (cpu_has_pge) {
795                 set_in_cr4(X86_CR4_PGE);
796                 __PAGE_KERNEL |= _PAGE_GLOBAL;
797 +               __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
798         }
799  
800         kernel_physical_mapping_init(pgd_base);
801 @@ -391,6 +411,53 @@ void __init zone_sizes_init(void)
802  extern void zone_sizes_init(void);
803  #endif /* !CONFIG_DISCONTIGMEM */
804  
805 +static int disable_nx __initdata = 0;
806 +u64 __supported_pte_mask = ~_PAGE_NX;
807 +int use_nx = 0;
808 +
809 +/*
810 + * noexec = on|off
811 + *
812 + * Control non executable mappings.
813 + *
814 + * on      Enable
815 + * off     Disable (disables exec-shield too)
816 + */
817 +static int __init noexec_setup(char *str)
818 +{
819 +       if (!strncmp(str, "on",2) && cpu_has_nx) {
820 +               __supported_pte_mask |= _PAGE_NX;
821 +               disable_nx = 0;
822 +       } else if (!strncmp(str,"off",3)) {
823 +               disable_nx = 1;
824 +               __supported_pte_mask &= ~_PAGE_NX;
825 +               exec_shield = 0;
826 +       }
827 +       return 1;
828 +}
829 +
830 +__setup("noexec=", noexec_setup);
831 +
832 +#ifdef CONFIG_X86_PAE
833 +
834 +static void __init set_nx(void)
835 +{
836 +       unsigned int v[4], l, h;
837 +
838 +       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
839 +               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
840 +               if ((v[3] & (1 << 20)) && !disable_nx) {
841 +                       rdmsr(MSR_EFER, l, h);
842 +                       l |= EFER_NX;
843 +                       wrmsr(MSR_EFER, l, h);
844 +                       use_nx = 1;
845 +                       __supported_pte_mask |= _PAGE_NX;
846 +               }
847 +       }
848 +}
849 +
850 +#endif
851 +
852  /*
853   * paging_init() sets up the page tables - note that the first 8MB are
854   * already mapped by head.S.
855 @@ -400,6 +467,14 @@ extern void zone_sizes_init(void);
856   */
857  void __init paging_init(void)
858  {
859 +#ifdef CONFIG_X86_PAE
860 +       set_nx();
861 +       if (use_nx)
862 +               printk("NX (Execute Disable) protection: active\n");
863 +       else if (exec_shield)
864 +               printk("Using x86 segment limits to approximate NX (Execute Disable) protection\n");
865 +#endif
866 +
867         pagetable_init();
868  
869         load_cr3(swapper_pg_dir);
870 --- linux/arch/sparc/kernel/sys_sparc.c.orig    
871 +++ linux/arch/sparc/kernel/sys_sparc.c 
872 @@ -332,7 +332,7 @@ asmlinkage unsigned long sparc_mremap(un
873  
874                 new_addr = get_unmapped_area(file, addr, new_len,
875                                      vma ? vma->vm_pgoff : 0,
876 -                                    map_flags);
877 +                                    map_flags, vma->vm_flags & VM_EXEC);
878                 ret = new_addr;
879                 if (new_addr & ~PAGE_MASK)
880                         goto out_sem;
881 --- linux/arch/ia64/kernel/perfmon.c.orig       
882 +++ linux/arch/ia64/kernel/perfmon.c    
883 @@ -600,7 +600,7 @@ pfm_do_munmap(struct mm_struct *mm, unsi
884  static inline unsigned long 
885  pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
886  {
887 -       return get_unmapped_area(file, addr, len, pgoff, flags);
888 +       return get_unmapped_area(file, addr, len, pgoff, flags, 0);
889  }
890  
891  
892 --- linux/arch/ia64/ia32/binfmt_elf32.c.orig    
893 +++ linux/arch/ia64/ia32/binfmt_elf32.c 
894 @@ -215,7 +215,7 @@ elf32_set_personality (void)
895  }
896  
897  static unsigned long
898 -elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
899 +elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
900  {
901         unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
902  
903 --- linux/arch/x86_64/kernel/module.c.orig      
904 +++ linux/arch/x86_64/kernel/module.c   
905 @@ -121,7 +121,7 @@ void *module_alloc(unsigned long size)
906                         goto fail;
907         }
908         
909 -       if (map_vm_area(area, PAGE_KERNEL_EXECUTABLE, &pages))
910 +       if (map_vm_area(area, PAGE_KERNEL_EXEC, &pages))
911                 goto fail;
912         
913         memset(addr, 0, size);
914 --- linux/arch/x86_64/mm/pageattr.c.orig        
915 +++ linux/arch/x86_64/mm/pageattr.c     
916 @@ -180,7 +180,7 @@ int change_page_attr(struct page *page, 
917                         unsigned long addr2;
918                         addr2 = __START_KERNEL_map + page_to_phys(page);
919                         err = __change_page_attr(addr2, page, prot, 
920 -                                                PAGE_KERNEL_EXECUTABLE);
921 +                                                PAGE_KERNEL_EXEC);
922                 } 
923         }       
924         up_write(&init_mm.mmap_sem); 
925 --- linux/arch/x86_64/ia32/ia32_binfmt.c.orig   
926 +++ linux/arch/x86_64/ia32/ia32_binfmt.c        
927 @@ -382,7 +382,7 @@ int setup_arg_pages(struct linux_binprm 
928  }
929  
930  static unsigned long
931 -elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
932 +elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
933  {
934         unsigned long map_addr;
935         struct task_struct *me = current; 
936 --- linux/include/asm-x86_64/pgalloc.h.orig     
937 +++ linux/include/asm-x86_64/pgalloc.h  
938 @@ -7,6 +7,11 @@
939  #include <linux/threads.h>
940  #include <linux/mm.h>
941  
942 +#define arch_add_exec_range(mm, limit) do { ; } while (0)
943 +#define arch_flush_exec_range(mm)      do { ; } while (0)
944 +#define arch_remove_exec_range(mm, limit) do { ; } while (0)
945 +
946 +
947  #define pmd_populate_kernel(mm, pmd, pte) \
948                 set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
949  #define pgd_populate(mm, pgd, pmd) \
950 --- linux/include/asm-x86_64/pgtable.h.orig     
951 +++ linux/include/asm-x86_64/pgtable.h  
952 @@ -172,7 +172,7 @@ static inline void set_pml4(pml4_t *dst,
953  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
954  #define __PAGE_KERNEL \
955         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
956 -#define __PAGE_KERNEL_EXECUTABLE \
957 +#define __PAGE_KERNEL_EXEC \
958         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
959  #define __PAGE_KERNEL_NOCACHE \
960         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX)
961 @@ -188,7 +188,7 @@ static inline void set_pml4(pml4_t *dst,
962  #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL)
963  
964  #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
965 -#define PAGE_KERNEL_EXECUTABLE MAKE_GLOBAL(__PAGE_KERNEL_EXECUTABLE)
966 +#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
967  #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
968  #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
969  #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
970 --- linux/include/linux/mm.h.orig       
971 +++ linux/include/linux/mm.h    
972 @@ -630,7 +630,7 @@ extern struct vm_area_struct *copy_vma(s
973         unsigned long addr, unsigned long len, pgoff_t pgoff);
974  extern void exit_mmap(struct mm_struct *);
975  
976 -extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
977 +extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
978  
979  extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
980         unsigned long len, unsigned long prot,
981 --- linux/include/linux/resource.h.orig 
982 +++ linux/include/linux/resource.h      
983 @@ -52,8 +52,11 @@ struct rlimit {
984  /*
985   * Limit the stack by to some sane default: root can always
986   * increase this limit if needed..  8MB seems reasonable.
987 + *
988 + * (2MB more to cover randomization effects.)
989   */
990 -#define _STK_LIM       (8*1024*1024)
991 +#define _STK_LIM       (10*1024*1024)
992 +#define EXEC_STACK_BIAS        (2*1024*1024)
993  
994  /*
995   * Due to binary compatibility, the actual resource numbers
996 --- linux/include/linux/sched.h.orig    
997 +++ linux/include/linux/sched.h 
998 @@ -31,6 +31,9 @@
999  #include <linux/percpu.h>
1000  
1001  struct exec_domain;
1002 +extern int exec_shield;
1003 +extern int exec_shield_randomize;
1004 +extern int print_fatal_signals;
1005  
1006  /*
1007   * cloning flags:
1008 @@ -194,6 +197,8 @@ struct mm_struct {
1009         struct rb_root mm_rb;
1010         struct vm_area_struct * mmap_cache;     /* last find_vma result */
1011         unsigned long free_area_cache;          /* first hole */
1012 +       unsigned long non_executable_cache;     /* last hole top */
1013 +       unsigned long mmap_top;                 /* top of mmap area */
1014         pgd_t * pgd;
1015         atomic_t mm_users;                      /* How many users with user space? */
1016         atomic_t mm_count;                      /* How many references to "struct mm_struct" (users count as 1) */
1017 --- linux/include/linux/vmalloc.h.orig  
1018 +++ linux/include/linux/vmalloc.h       
1019 @@ -23,6 +23,7 @@ struct vm_struct {
1020   *     Highlevel APIs for driver use
1021   */
1022  extern void *vmalloc(unsigned long size);
1023 +extern void *vmalloc_exec(unsigned long size);
1024  extern void *vmalloc_32(unsigned long size);
1025  extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot);
1026  extern void vfree(void *addr);
1027 --- linux/include/asm-ppc64/pgalloc.h.orig      
1028 +++ linux/include/asm-ppc64/pgalloc.h   
1029 @@ -10,6 +10,11 @@
1030  
1031  extern kmem_cache_t *zero_cache;
1032  
1033 +/* Dummy functions since we don't support execshield on ppc */
1034 +#define arch_add_exec_range(mm, limit) do { ; } while (0)
1035 +#define arch_flush_exec_range(mm)      do { ; } while (0)
1036 +#define arch_remove_exec_range(mm, limit) do { ; } while (0)
1037 +
1038  /*
1039   * This program is free software; you can redistribute it and/or
1040   * modify it under the terms of the GNU General Public License
1041 --- linux/include/asm-ia64/pgalloc.h.orig       
1042 +++ linux/include/asm-ia64/pgalloc.h    
1043 @@ -23,6 +23,10 @@
1044  #include <asm/mmu_context.h>
1045  #include <asm/processor.h>
1046  
1047 +#define arch_add_exec_range(mm, limit)         do { ; } while (0)
1048 +#define arch_flush_exec_range(mm)              do { ; } while (0)
1049 +#define arch_remove_exec_range(mm, limit)      do { ; } while (0)
1050 +
1051  /*
1052   * Very stupidly, we used to get new pgd's and pmd's, init their contents
1053   * to point to the NULL versions of the next level page table, later on
1054 --- linux/include/asm-ppc/pgalloc.h.orig        
1055 +++ linux/include/asm-ppc/pgalloc.h     
1056 @@ -40,5 +40,10 @@ extern void pte_free(struct page *pte);
1057  
1058  #define check_pgt_cache()      do { } while (0)
1059  
1060 +#define arch_add_exec_range(mm, limit)         do { ; } while (0)
1061 +#define arch_flush_exec_range(mm)              do { ; } while (0)
1062 +#define arch_remove_exec_range(mm, limit)      do { ; } while (0)
1063 +
1064 +
1065  #endif /* _PPC_PGALLOC_H */
1066  #endif /* __KERNEL__ */
1067 --- linux/include/asm-sparc/pgalloc.h.orig      
1068 +++ linux/include/asm-sparc/pgalloc.h   
1069 @@ -66,4 +66,8 @@ BTFIXUPDEF_CALL(void, pte_free, struct p
1070  #define pte_free(pte)          BTFIXUP_CALL(pte_free)(pte)
1071  #define __pte_free_tlb(tlb, pte)       pte_free(pte)
1072  
1073 +#define arch_add_exec_range(mm, limit)         do { ; } while (0)
1074 +#define arch_flush_exec_range(mm)              do { ; } while (0)
1075 +#define arch_remove_exec_range(mm, limit)      do { ; } while (0)
1076 +
1077  #endif /* _SPARC_PGALLOC_H */
1078 --- linux/include/asm-s390/pgalloc.h.orig       
1079 +++ linux/include/asm-s390/pgalloc.h    
1080 @@ -19,6 +19,10 @@
1081  #include <linux/gfp.h>
1082  #include <linux/mm.h>
1083  
1084 +#define arch_add_exec_range(mm, limit) do { ; } while (0)
1085 +#define arch_flush_exec_range(mm)      do { ; } while (0)
1086 +#define arch_remove_exec_range(mm, limit) do { ; } while (0)
1087 +
1088  #define check_pgt_cache()      do {} while (0)
1089  
1090  extern void diag10(unsigned long addr);
1091 --- linux/include/asm-i386/desc.h.orig  
1092 +++ linux/include/asm-i386/desc.h       
1093 @@ -123,6 +123,20 @@ static inline void load_LDT(mm_context_t
1094         put_cpu();
1095  }
1096  
1097 +static inline void set_user_cs(struct desc_struct *desc, unsigned long limit)
1098 +{
1099 +       limit = (limit - 1) / PAGE_SIZE;
1100 +       desc->a = limit & 0xffff;
1101 +       desc->b = (limit & 0xf0000) | 0x00c0fb00;
1102 +}
1103 +
1104 +#define load_user_cs_desc(cpu, mm) \
1105 +       cpu_gdt_table[(cpu)][GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs
1106 +
1107 +extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit);
1108 +extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit);
1109 +extern void arch_flush_exec_range(struct mm_struct *mm);
1110 +
1111  #endif /* !__ASSEMBLY__ */
1112  
1113  #endif
1114 --- linux/include/asm-i386/cpufeature.h.orig    
1115 +++ linux/include/asm-i386/cpufeature.h 
1116 @@ -47,6 +47,7 @@
1117  /* Don't duplicate feature flags which are redundant with Intel! */
1118  #define X86_FEATURE_SYSCALL    (1*32+11) /* SYSCALL/SYSRET */
1119  #define X86_FEATURE_MP         (1*32+19) /* MP Capable. */
1120 +#define X86_FEATURE_NX         (1*32+20) /* Execute Disable */
1121  #define X86_FEATURE_MMXEXT     (1*32+22) /* AMD MMX extensions */
1122  #define X86_FEATURE_LM         (1*32+29) /* Long Mode (x86-64) */
1123  #define X86_FEATURE_3DNOWEXT   (1*32+30) /* AMD 3DNow! extensions */
1124 @@ -100,6 +101,7 @@
1125  #define cpu_has_xmm            boot_cpu_has(X86_FEATURE_XMM)
1126  #define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
1127  #define cpu_has_mp             boot_cpu_has(X86_FEATURE_MP)
1128 +#define cpu_has_nx             boot_cpu_has(X86_FEATURE_NX)
1129  #define cpu_has_k6_mtrr                boot_cpu_has(X86_FEATURE_K6_MTRR)
1130  #define cpu_has_cyrix_arr      boot_cpu_has(X86_FEATURE_CYRIX_ARR)
1131  #define cpu_has_centaur_mcr    boot_cpu_has(X86_FEATURE_CENTAUR_MCR)
1132 --- linux/include/asm-i386/elf.h.orig   
1133 +++ linux/include/asm-i386/elf.h        
1134 @@ -9,6 +9,7 @@
1135  #include <asm/user.h>
1136  #include <asm/processor.h>
1137  #include <asm/system.h>                /* for savesegment */
1138 +#include <asm/desc.h>
1139  
1140  #include <linux/utsname.h>
1141  
1142 @@ -117,7 +118,8 @@ typedef struct user_fxsr_struct elf_fpxr
1143  #define AT_SYSINFO_EHDR                33
1144  
1145  #ifdef __KERNEL__
1146 -#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
1147 +/* child inherits the personality of the parent */
1148 +#define SET_PERSONALITY(ex, ibcs2) do { } while (0)
1149  
1150  extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
1151  extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
1152 @@ -127,15 +129,22 @@ extern int dump_task_extended_fpu (struc
1153  #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
1154  #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
1155  
1156 -#define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
1157 -#define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
1158 -#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
1159  extern void __kernel_vsyscall;
1160 +#define VSYSCALL_BASE  ((unsigned long)current->mm->context.vdso)
1161 +#define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
1162 +#define VSYSCALL_OFFSET        ((unsigned long) &__kernel_vsyscall)
1163 +#define VSYSCALL_ENTRY (VSYSCALL_BASE + VSYSCALL_OFFSET)
1164  
1165 -#define ARCH_DLINFO                                            \
1166 -do {                                                           \
1167 -               NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);        \
1168 -               NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);    \
1169 +/* kernel-internal fixmap address: */
1170 +#define __VSYSCALL_BASE        (__fix_to_virt(FIX_VSYSCALL))
1171 +#define __VSYSCALL_EHDR        ((const struct elfhdr *) __VSYSCALL_BASE)
1172 +
1173 +#define ARCH_DLINFO                                                    \
1174 +do {                                                                   \
1175 +       if (VSYSCALL_BASE) {                                            \
1176 +               NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);                \
1177 +               NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);            \
1178 +       }                                                               \
1179  } while (0)
1180  
1181  /*
1182 @@ -146,15 +155,15 @@ do {                                                              \
1183   * Dumping its extra ELF program headers includes all the other information
1184   * a debugger needs to easily find how the vsyscall DSO was being used.
1185   */
1186 -#define ELF_CORE_EXTRA_PHDRS           (VSYSCALL_EHDR->e_phnum)
1187 +#define ELF_CORE_EXTRA_PHDRS           (__VSYSCALL_EHDR->e_phnum)
1188  #define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
1189  do {                                                                         \
1190         const struct elf_phdr *const vsyscall_phdrs =                         \
1191 -               (const struct elf_phdr *) (VSYSCALL_BASE                      \
1192 -                                          + VSYSCALL_EHDR->e_phoff);         \
1193 +               (const struct elf_phdr *) (__VSYSCALL_BASE                    \
1194 +                                          + __VSYSCALL_EHDR->e_phoff);       \
1195         int i;                                                                \
1196         Elf32_Off ofs = 0;                                                    \
1197 -       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
1198 +       for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) {                      \
1199                 struct elf_phdr phdr = vsyscall_phdrs[i];                     \
1200                 if (phdr.p_type == PT_LOAD) {                                 \
1201                         BUG_ON(ofs != 0);                                     \
1202 @@ -172,10 +181,10 @@ do {                                                                            \
1203  #define ELF_CORE_WRITE_EXTRA_DATA                                            \
1204  do {                                                                         \
1205         const struct elf_phdr *const vsyscall_phdrs =                         \
1206 -               (const struct elf_phdr *) (VSYSCALL_BASE                      \
1207 -                                          + VSYSCALL_EHDR->e_phoff);         \
1208 +               (const struct elf_phdr *) (__VSYSCALL_BASE                    \
1209 +                                          + __VSYSCALL_EHDR->e_phoff);       \
1210         int i;                                                                \
1211 -       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
1212 +       for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) {                      \
1213                 if (vsyscall_phdrs[i].p_type == PT_LOAD)                      \
1214                         DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,        \
1215                                    PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
1216 @@ -184,4 +193,10 @@ do {                                                                             \
1217  
1218  #endif
1219  
1220 +#define __HAVE_ARCH_RANDOMIZE_BRK
1221 +extern void randomize_brk(unsigned long old_brk);
1222 +
1223 +#define __HAVE_ARCH_VSYSCALL
1224 +extern void map_vsyscall(void);
1225 +
1226  #endif
1227 --- linux/include/asm-i386/mmu.h.orig   
1228 +++ linux/include/asm-i386/mmu.h        
1229 @@ -7,11 +7,17 @@
1230   * we put the segment information here.
1231   *
1232   * cpu_vm_mask is used to optimize ldt flushing.
1233 + *
1234 + * exec_limit is used to track the range PROT_EXEC
1235 + * mappings span.
1236   */
1237  typedef struct { 
1238         int size;
1239         struct semaphore sem;
1240         void *ldt;
1241 +       struct desc_struct user_cs;
1242 +       unsigned long exec_limit;
1243 +       void *vdso;
1244  } mm_context_t;
1245  
1246  #endif
1247 --- linux/include/asm-i386/msr.h.orig   
1248 +++ linux/include/asm-i386/msr.h        
1249 @@ -217,6 +217,15 @@ static inline void wrmsrl (unsigned long
1250  #define MSR_K7_FID_VID_CTL             0xC0010041
1251  #define MSR_K7_FID_VID_STATUS          0xC0010042
1252  
1253 +/* extended feature register */
1254 +#define MSR_EFER                       0xc0000080
1255 +
1256 +/* EFER bits: */
1257 +
1258 +/* Execute Disable enable */
1259 +#define _EFER_NX                       11
1260 +#define EFER_NX                                (1<<_EFER_NX)
1261 +
1262  /* Centaur-Hauls/IDT defined MSRs. */
1263  #define MSR_IDT_FCR1                   0x107
1264  #define MSR_IDT_FCR2                   0x108
1265 --- linux/include/asm-i386/page.h.orig  
1266 +++ linux/include/asm-i386/page.h       
1267 @@ -40,15 +40,18 @@
1268   * These are used to make use of C type-checking..
1269   */
1270  #ifdef CONFIG_X86_PAE
1271 +extern unsigned long long __supported_pte_mask;
1272  typedef struct { unsigned long pte_low, pte_high; } pte_t;
1273  typedef struct { unsigned long long pmd; } pmd_t;
1274  typedef struct { unsigned long long pgd; } pgd_t;
1275 +typedef struct { unsigned long long pgprot; } pgprot_t;
1276  #define pte_val(x)     ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
1277  #define HPAGE_SHIFT    21
1278  #else
1279  typedef struct { unsigned long pte_low; } pte_t;
1280  typedef struct { unsigned long pmd; } pmd_t;
1281  typedef struct { unsigned long pgd; } pgd_t;
1282 +typedef struct { unsigned long pgprot; } pgprot_t;
1283  #define boot_pte_t pte_t /* or would you rather have a typedef */
1284  #define pte_val(x)     ((x).pte_low)
1285  #define HPAGE_SHIFT    22
1286 @@ -61,7 +64,6 @@ typedef struct { unsigned long pgd; } pg
1287  #define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
1288  #endif
1289  
1290 -typedef struct { unsigned long pgprot; } pgprot_t;
1291  
1292  #define pmd_val(x)     ((x).pmd)
1293  #define pgd_val(x)     ((x).pgd)
1294 @@ -136,7 +138,7 @@ static __inline__ int get_order(unsigned
1295  
1296  #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
1297  
1298 -#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
1299 +#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | \
1300                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1301  
1302  #endif /* __KERNEL__ */
1303 --- linux/include/asm-i386/pgalloc.h.orig       
1304 +++ linux/include/asm-i386/pgalloc.h    
1305 @@ -4,6 +4,7 @@
1306  #include <linux/config.h>
1307  #include <asm/processor.h>
1308  #include <asm/fixmap.h>
1309 +#include <asm/desc.h>
1310  #include <linux/threads.h>
1311  #include <linux/mm.h>          /* for struct page */
1312  
1313 @@ -52,4 +53,6 @@ static inline void pte_free(struct page 
1314  
1315  #define check_pgt_cache()      do { } while (0)
1316  
1317 +#define HAVE_ARCH_UNMAPPED_AREA 1
1318 +
1319  #endif /* _I386_PGALLOC_H */
1320 --- linux/include/asm-i386/pgtable-3level.h.orig        
1321 +++ linux/include/asm-i386/pgtable-3level.h     
1322 @@ -101,18 +101,24 @@ static inline unsigned long pte_pfn(pte_
1323                 (pte.pte_high << (32 - PAGE_SHIFT));
1324  }
1325  
1326 +extern unsigned long long __supported_pte_mask;
1327 +
1328  static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
1329  {
1330         pte_t pte;
1331  
1332 -       pte.pte_high = page_nr >> (32 - PAGE_SHIFT);
1333 -       pte.pte_low = (page_nr << PAGE_SHIFT) | pgprot_val(pgprot);
1334 +       pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \
1335 +                                       (pgprot_val(pgprot) >> 32);
1336 +       pte.pte_high &= (__supported_pte_mask >> 32);
1337 +       pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \
1338 +                                                       __supported_pte_mask;
1339         return pte;
1340  }
1341  
1342  static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
1343  {
1344 -       return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
1345 +       return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \
1346 +                       pgprot_val(pgprot)) & __supported_pte_mask);
1347  }
1348  
1349  /*
1350 --- linux/include/asm-i386/pgtable.h.orig       
1351 +++ linux/include/asm-i386/pgtable.h    
1352 @@ -110,6 +110,7 @@ void paging_init(void);
1353  #define _PAGE_BIT_UNUSED1      9       /* available for programmer */
1354  #define _PAGE_BIT_UNUSED2      10
1355  #define _PAGE_BIT_UNUSED3      11
1356 +#define _PAGE_BIT_NX           63
1357  
1358  #define _PAGE_PRESENT  0x001
1359  #define _PAGE_RW       0x002
1360 @@ -126,28 +127,51 @@ void paging_init(void);
1361  
1362  #define _PAGE_FILE     0x040   /* set:pagecache unset:swap */
1363  #define _PAGE_PROTNONE 0x080   /* If not present */
1364 +#ifdef CONFIG_X86_PAE
1365 +#define _PAGE_NX       (1ULL<<_PAGE_BIT_NX)
1366 +#else
1367 +#define _PAGE_NX       0
1368 +#endif
1369  
1370  #define _PAGE_TABLE    (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
1371  #define _KERNPG_TABLE  (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
1372  #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
1373  
1374 -#define PAGE_NONE      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
1375 -#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
1376 -#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
1377 -#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
1378 +#define PAGE_NONE \
1379 +       __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
1380 +#define PAGE_SHARED \
1381 +       __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
1382 +
1383 +#define PAGE_SHARED_EXEC \
1384 +       __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
1385 +#define PAGE_COPY_NOEXEC \
1386 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
1387 +#define PAGE_COPY_EXEC \
1388 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
1389 +#define PAGE_COPY \
1390 +       PAGE_COPY_NOEXEC
1391 +#define PAGE_READONLY \
1392 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
1393 +#define PAGE_READONLY_EXEC \
1394 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
1395  
1396  #define _PAGE_KERNEL \
1397 +       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
1398 +#define _PAGE_KERNEL_EXEC \
1399         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
1400  
1401 -extern unsigned long __PAGE_KERNEL;
1402 -#define __PAGE_KERNEL_RO       (__PAGE_KERNEL & ~_PAGE_RW)
1403 -#define __PAGE_KERNEL_NOCACHE  (__PAGE_KERNEL | _PAGE_PCD)
1404 -#define __PAGE_KERNEL_LARGE    (__PAGE_KERNEL | _PAGE_PSE)
1405 +extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
1406 +#define __PAGE_KERNEL_RO               (__PAGE_KERNEL & ~_PAGE_RW)
1407 +#define __PAGE_KERNEL_NOCACHE          (__PAGE_KERNEL | _PAGE_PCD)
1408 +#define __PAGE_KERNEL_LARGE            (__PAGE_KERNEL | _PAGE_PSE)
1409 +#define __PAGE_KERNEL_LARGE_EXEC       (__PAGE_KERNEL_EXEC | _PAGE_PSE)
1410  
1411  #define PAGE_KERNEL            __pgprot(__PAGE_KERNEL)
1412  #define PAGE_KERNEL_RO         __pgprot(__PAGE_KERNEL_RO)
1413 +#define PAGE_KERNEL_EXEC       __pgprot(__PAGE_KERNEL_EXEC)
1414  #define PAGE_KERNEL_NOCACHE    __pgprot(__PAGE_KERNEL_NOCACHE)
1415  #define PAGE_KERNEL_LARGE      __pgprot(__PAGE_KERNEL_LARGE)
1416 +#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC)
1417  
1418  /*
1419   * The i386 can't do page protection for execute, and considers that
1420 @@ -158,19 +182,19 @@ extern unsigned long __PAGE_KERNEL;
1421  #define __P001 PAGE_READONLY
1422  #define __P010 PAGE_COPY
1423  #define __P011 PAGE_COPY
1424 -#define __P100 PAGE_READONLY
1425 -#define __P101 PAGE_READONLY
1426 -#define __P110 PAGE_COPY
1427 -#define __P111 PAGE_COPY
1428 +#define __P100 PAGE_READONLY_EXEC
1429 +#define __P101 PAGE_READONLY_EXEC
1430 +#define __P110 PAGE_COPY_EXEC
1431 +#define __P111 PAGE_COPY_EXEC
1432  
1433  #define __S000 PAGE_NONE
1434  #define __S001 PAGE_READONLY
1435  #define __S010 PAGE_SHARED
1436  #define __S011 PAGE_SHARED
1437 -#define __S100 PAGE_READONLY
1438 -#define __S101 PAGE_READONLY
1439 -#define __S110 PAGE_SHARED
1440 -#define __S111 PAGE_SHARED
1441 +#define __S100 PAGE_READONLY_EXEC
1442 +#define __S101 PAGE_READONLY_EXEC
1443 +#define __S110 PAGE_SHARED_EXEC
1444 +#define __S111 PAGE_SHARED_EXEC
1445  
1446  /*
1447   * Define this if things work differently on an i386 and an i486:
1448 @@ -256,6 +280,15 @@ static inline pte_t pte_modify(pte_t pte
1449  {
1450         pte.pte_low &= _PAGE_CHG_MASK;
1451         pte.pte_low |= pgprot_val(newprot);
1452 +#ifdef CONFIG_X86_PAE
1453 +       /*
1454 +        * Chop off the NX bit (if present), and add the NX portion of
1455 +        * the newprot (if present):
1456 +        */
1457 +       pte.pte_high &= -1 ^ (1 << (_PAGE_BIT_NX - 32));
1458 +       pte.pte_high |= (pgprot_val(newprot) >> 32) & \
1459 +                                       (__supported_pte_mask >> 32);
1460 +#endif
1461         return pte;
1462  }
1463  
1464 --- linux/include/asm-i386/processor.h.orig     
1465 +++ linux/include/asm-i386/processor.h  
1466 @@ -294,7 +294,15 @@ extern unsigned int mca_pentium_flag;
1467  /* This decides where the kernel will search for a free chunk of vm
1468   * space during mmap's.
1469   */
1470 -#define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
1471 +#define TASK_UNMAPPED_BASE     PAGE_ALIGN(TASK_SIZE/3)
1472 +
1473 +#define SHLIB_BASE             0x00111000
1474
1475 +#define __HAVE_ARCH_ALIGN_STACK
1476 +extern unsigned long arch_align_stack(unsigned long sp);
1477 +
1478 +#define __HAVE_ARCH_MMAP_TOP
1479 +extern unsigned long mmap_top(void);
1480  
1481  /*
1482   * Size of io_bitmap, covering ports 0 to 0x3ff.
1483 @@ -456,6 +464,8 @@ static inline void load_esp0(struct tss_
1484         }
1485  }
1486  
1487 +extern int use_nx;
1488 +
1489  #define start_thread(regs, new_eip, new_esp) do {              \
1490         __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0));       \
1491         set_fs(USER_DS);                                        \
1492 @@ -465,6 +475,7 @@ static inline void load_esp0(struct tss_
1493         regs->xcs = __USER_CS;                                  \
1494         regs->eip = new_eip;                                    \
1495         regs->esp = new_esp;                                    \
1496 +       load_user_cs_desc(smp_processor_id(), current->mm);     \
1497  } while (0)
1498  
1499  /* Forward declaration, a strange C thing */
1500 --- linux/include/asm-i386/thread_info.h.orig   
1501 +++ linux/include/asm-i386/thread_info.h        
1502 @@ -37,6 +37,7 @@ struct thread_info {
1503                                                    0-0xBFFFFFFF for user-thead
1504                                                    0-0xFFFFFFFF for kernel-thread
1505                                                 */
1506 +       void                    *sysenter_return;
1507         struct restart_block    restart_block;
1508  
1509         unsigned long           previous_esp;   /* ESP of the previous stack in case
1510 --- linux/include/asm-sparc64/pgalloc.h.orig    
1511 +++ linux/include/asm-sparc64/pgalloc.h 
1512 @@ -236,4 +236,8 @@ static __inline__ void free_pte_slow(pte
1513  #define pgd_free(pgd)          free_pgd_fast(pgd)
1514  #define pgd_alloc(mm)          get_pgd_fast()
1515  
1516 +#define arch_add_exec_range(mm, limit)         do { ; } while (0)
1517 +#define arch_flush_exec_range(mm)              do { ; } while (0)
1518 +#define arch_remove_exec_range(mm, limit)      do { ; } while (0)
1519 +
1520  #endif /* _SPARC64_PGALLOC_H */
1521 --- linux/fs/proc/array.c.orig  
1522 +++ linux/fs/proc/array.c       
1523 @@ -324,7 +324,10 @@ int proc_pid_stat(struct task_struct *ta
1524                 up_read(&mm->mmap_sem);
1525         }
1526  
1527 -       wchan = get_wchan(task);
1528 +       wchan = 0;
1529 +       if (current->uid == task->uid || current->euid == task->uid ||
1530 +                                                       capable(CAP_SYS_NICE))
1531 +               wchan = get_wchan(task);
1532  
1533         sigemptyset(&sigign);
1534         sigemptyset(&sigcatch);
1535 --- linux/fs/proc/base.c.orig   
1536 +++ linux/fs/proc/base.c        
1537 @@ -111,7 +111,7 @@ static struct pid_entry tgid_base_stuff[
1538         E(PROC_TGID_CMDLINE,   "cmdline", S_IFREG|S_IRUGO),
1539         E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
1540         E(PROC_TGID_STATM,     "statm",   S_IFREG|S_IRUGO),
1541 -       E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUGO),
1542 +       E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUSR),
1543         E(PROC_TGID_MEM,       "mem",     S_IFREG|S_IRUSR|S_IWUSR),
1544         E(PROC_TGID_CWD,       "cwd",     S_IFLNK|S_IRWXUGO),
1545         E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
1546 @@ -133,7 +133,7 @@ static struct pid_entry tid_base_stuff[]
1547         E(PROC_TID_CMDLINE,    "cmdline", S_IFREG|S_IRUGO),
1548         E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
1549         E(PROC_TID_STATM,      "statm",   S_IFREG|S_IRUGO),
1550 -       E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUGO),
1551 +       E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUSR),
1552         E(PROC_TID_MEM,        "mem",     S_IFREG|S_IRUSR|S_IWUSR),
1553         E(PROC_TID_CWD,        "cwd",     S_IFLNK|S_IRWXUGO),
1554         E(PROC_TID_ROOT,       "root",    S_IFLNK|S_IRWXUGO),
1555 --- linux/fs/proc/task_mmu.c.orig       
1556 +++ linux/fs/proc/task_mmu.c    
1557 @@ -34,12 +34,23 @@ char *task_mem(struct mm_struct *mm, cha
1558                 "VmData:\t%8lu kB\n"
1559                 "VmStk:\t%8lu kB\n"
1560                 "VmExe:\t%8lu kB\n"
1561 -               "VmLib:\t%8lu kB\n",
1562 +               "VmLib:\t%8lu kB\n"
1563 +               "StaBrk:\t%08lx kB\n"
1564 +               "Brk:\t%08lx kB\n"
1565 +               "StaStk:\t%08lx kB\n"
1566 +#if __i386__
1567 +               "ExecLim:\t%08lx\n"
1568 +#endif
1569 +               ,
1570                 mm->total_vm << (PAGE_SHIFT-10),
1571                 mm->locked_vm << (PAGE_SHIFT-10),
1572                 mm->rss << (PAGE_SHIFT-10),
1573                 data - stack, stack,
1574 -               exec - lib, lib);
1575 +               exec - lib, lib, mm->start_brk, mm->brk, mm->start_stack
1576 +#if __i386__
1577 +               , mm->context.exec_limit
1578 +#endif
1579 +               );
1580         up_read(&mm->mmap_sem);
1581         return buffer;
1582  }
1583 --- linux/fs/binfmt_aout.c.orig 
1584 +++ linux/fs/binfmt_aout.c      
1585 @@ -308,7 +308,8 @@ static int load_aout_binary(struct linux
1586         current->mm->brk = ex.a_bss +
1587                 (current->mm->start_brk = N_BSSADDR(ex));
1588         current->mm->free_area_cache = TASK_UNMAPPED_BASE;
1589 -
1590 +       /* unlimited stack is larger than TASK_SIZE */
1591 +       current->mm->non_executable_cache = current->mm->mmap_top;
1592         current->mm->rss = 0;
1593         current->mm->mmap = NULL;
1594         compute_creds(bprm);
1595 --- linux/fs/binfmt_elf.c.orig  
1596 +++ linux/fs/binfmt_elf.c       
1597 @@ -45,7 +45,7 @@
1598  
1599  static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
1600  static int load_elf_library(struct file*);
1601 -static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
1602 +static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long);
1603  extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
1604  
1605  #ifndef elf_addr_t
1606 @@ -155,20 +155,8 @@ create_elf_tables(struct linux_binprm *b
1607         if (k_platform) {
1608                 size_t len = strlen(k_platform) + 1;
1609  
1610 -#ifdef CONFIG_X86_HT
1611 -               /*
1612 -                * In some cases (e.g. Hyper-Threading), we want to avoid L1
1613 -                * evictions by the processes running on the same package. One
1614 -                * thing we can do is to shuffle the initial stack for them.
1615 -                *
1616 -                * The conditionals here are unneeded, but kept in to make the
1617 -                * code behaviour the same as pre change unless we have
1618 -                * hyperthreaded processors. This should be cleaned up
1619 -                * before 2.6
1620 -                */
1621 -        
1622 -               if (smp_num_siblings > 1)
1623 -                       STACK_ALLOC(p, ((current->pid % 64) << 7));
1624 +#ifdef __HAVE_ARCH_ALIGN_STACK
1625 +               p = (unsigned long)arch_align_stack((unsigned long)p);
1626  #endif
1627                 u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
1628                 __copy_to_user(u_platform, k_platform, len);
1629 @@ -272,20 +260,59 @@ create_elf_tables(struct linux_binprm *b
1630  #ifndef elf_map
1631  
1632  static unsigned long elf_map(struct file *filep, unsigned long addr,
1633 -                       struct elf_phdr *eppnt, int prot, int type)
1634 +                            struct elf_phdr *eppnt, int prot, int type,
1635 +                            unsigned long total_size)
1636  {
1637         unsigned long map_addr;
1638 +       unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
1639 +       unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
1640 +
1641 +       addr = ELF_PAGESTART(addr);
1642 +       size = ELF_PAGEALIGN(size);
1643  
1644         down_write(&current->mm->mmap_sem);
1645 -       map_addr = do_mmap(filep, ELF_PAGESTART(addr),
1646 -                          eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
1647 -                          eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
1648 +
1649 +       /*
1650 +        * total_size is the size of the ELF (interpreter) image.
1651 +        * The _first_ mmap needs to know the full size, otherwise
1652 +        * randomization might put this image into an overlapping
1653 +        * position with the ELF binary image. (since size < total_size)
1654 +        * So we first map the 'big' image - and unmap the remainder at
1655 +        * the end. (which unmap is needed for ELF images with holes.)
1656 +        */
1657 +       if (total_size) {
1658 +               total_size = ELF_PAGEALIGN(total_size);
1659 +               map_addr = do_mmap(filep, addr, total_size, prot, type, off);
1660 +               if (!BAD_ADDR(map_addr))
1661 +                       do_munmap(current->mm, map_addr+size, total_size-size);
1662 +       } else
1663 +               map_addr = do_mmap(filep, addr, size, prot, type, off);
1664 +               
1665         up_write(&current->mm->mmap_sem);
1666 -       return(map_addr);
1667 +
1668 +       return map_addr;
1669  }
1670  
1671  #endif /* !elf_map */
1672  
1673 +static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
1674 +{
1675 +       int i, first_idx = -1, last_idx = -1;
1676 +
1677 +       for (i = 0; i < nr; i++)
1678 +               if (cmds[i].p_type == PT_LOAD) {
1679 +                       last_idx = i;
1680 +                       if (first_idx == -1)
1681 +                               first_idx = i;
1682 +               }
1683 +
1684 +       if (first_idx == -1)
1685 +               return 0;
1686 +
1687 +       return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz -
1688 +                               ELF_PAGESTART(cmds[first_idx].p_vaddr);
1689 +}
1690 +
1691  /* This is much more generalized than the library routine read function,
1692     so we keep this separate.  Technically the library read function
1693     is only provided so that we can read a.out libraries that have
1694 @@ -293,7 +320,8 @@ static unsigned long elf_map(struct file
1695  
1696  static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
1697                                      struct file * interpreter,
1698 -                                    unsigned long *interp_load_addr)
1699 +                                    unsigned long *interp_load_addr,
1700 +                                    unsigned long no_base)
1701  {
1702         struct elf_phdr *elf_phdata;
1703         struct elf_phdr *eppnt;
1704 @@ -301,6 +329,7 @@ static unsigned long load_elf_interp(str
1705         int load_addr_set = 0;
1706         unsigned long last_bss = 0, elf_bss = 0;
1707         unsigned long error = ~0UL;
1708 +       unsigned long total_size;
1709         int retval, i, size;
1710  
1711         /* First of all, some simple consistency checks */
1712 @@ -335,6 +364,10 @@ static unsigned long load_elf_interp(str
1713         if (retval < 0)
1714                 goto out_close;
1715  
1716 +       total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
1717 +       if (!total_size)
1718 +               goto out_close;
1719 +
1720         eppnt = elf_phdata;
1721         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
1722           if (eppnt->p_type == PT_LOAD) {
1723 @@ -349,8 +382,11 @@ static unsigned long load_elf_interp(str
1724             vaddr = eppnt->p_vaddr;
1725             if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
1726                 elf_type |= MAP_FIXED;
1727 +           else if (no_base && interp_elf_ex->e_type == ET_DYN)
1728 +               load_addr = -vaddr;
1729  
1730 -           map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
1731 +           map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type, total_size);
1732 +           total_size = 0;
1733             error = map_addr;
1734             if (BAD_ADDR(map_addr))
1735                 goto out_close;
1736 @@ -490,6 +526,7 @@ static int load_elf_binary(struct linux_
1737         char passed_fileno[6];
1738         struct files_struct *files;
1739         int executable_stack = EXSTACK_DEFAULT;
1740 +       unsigned long def_flags = 0;
1741         
1742         /* Get the exec-header */
1743         elf_ex = *((struct elfhdr *) bprm->buf);
1744 @@ -621,7 +658,18 @@ static int load_elf_binary(struct linux_
1745                                 executable_stack = EXSTACK_ENABLE_X;
1746                         else
1747                                 executable_stack = EXSTACK_DISABLE_X;
1748 +                       break;
1749                 }
1750 +       if (i == elf_ex.e_phnum)
1751 +               def_flags |= VM_EXEC | VM_MAYEXEC;
1752 +
1753 +       if (current->personality == PER_LINUX)
1754 +       switch (exec_shield) {
1755 +       case 2:
1756 +               executable_stack = EXSTACK_DISABLE_X;
1757 +               def_flags &= ~(VM_EXEC | VM_MAYEXEC);
1758 +               break;
1759 +       }
1760  
1761         /* Some simple consistency checks for the interpreter */
1762         if (elf_interpreter) {
1763 @@ -676,6 +724,15 @@ static int load_elf_binary(struct linux_
1764         if (retval)
1765                 goto out_free_dentry;
1766  
1767 +#ifdef __i386__
1768 +       /*
1769 +        * Turn off the CS limit completely if exec-shield disabled or
1770 +        * NX active:
1771 +        */
1772 +       if (!exec_shield || use_nx)
1773 +               arch_add_exec_range(current->mm, -1);
1774 +#endif
1775 +
1776         /* Discard our unneeded old files struct */
1777         if (files) {
1778                 steal_locks(files);
1779 @@ -688,7 +745,11 @@ static int load_elf_binary(struct linux_
1780         current->mm->end_data = 0;
1781         current->mm->end_code = 0;
1782         current->mm->mmap = NULL;
1783 +#ifdef __HAVE_ARCH_MMAP_TOP
1784 +       current->mm->mmap_top = mmap_top();
1785 +#endif
1786         current->flags &= ~PF_FORKNOEXEC;
1787 +       current->mm->def_flags = def_flags;
1788  
1789         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
1790            may depend on the personality.  */
1791 @@ -698,6 +759,7 @@ static int load_elf_binary(struct linux_
1792            change some of these later */
1793         current->mm->rss = 0;
1794         current->mm->free_area_cache = TASK_UNMAPPED_BASE;
1795 +       current->mm->non_executable_cache = current->mm->mmap_top;
1796         retval = setup_arg_pages(bprm, executable_stack);
1797         if (retval < 0) {
1798                 send_sig(SIGKILL, current, 0);
1799 @@ -706,10 +768,10 @@ static int load_elf_binary(struct linux_
1800         
1801         current->mm->start_stack = bprm->p;
1802  
1803 +
1804         /* Now we do a little grungy work by mmaping the ELF image into
1805 -          the correct location in memory.  At this point, we assume that
1806 -          the image should be loaded at fixed address, not at a variable
1807 -          address. */
1808 +          the correct location in memory.
1809 +        */
1810  
1811         for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
1812                 int elf_prot = 0, elf_flags;
1813 @@ -746,16 +808,16 @@ static int load_elf_binary(struct linux_
1814                 elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
1815  
1816                 vaddr = elf_ppnt->p_vaddr;
1817 -               if (elf_ex.e_type == ET_EXEC || load_addr_set) {
1818 +               if (elf_ex.e_type == ET_EXEC || load_addr_set)
1819                         elf_flags |= MAP_FIXED;
1820 -               } else if (elf_ex.e_type == ET_DYN) {
1821 -                       /* Try and get dynamic programs out of the way of the default mmap
1822 -                          base, as well as whatever program they might try to exec.  This
1823 -                          is because the brk will follow the loader, and is not movable.  */
1824 +               else if (elf_ex.e_type == ET_DYN)
1825 +#ifdef __i386__
1826 +                       load_bias = 0;
1827 +#else
1828                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
1829 -               }
1830 +#endif
1831  
1832 -               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
1833 +               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags, 0);
1834                 if (BAD_ADDR(error))
1835                         continue;
1836  
1837 @@ -826,7 +888,8 @@ static int load_elf_binary(struct linux_
1838                 else
1839                         elf_entry = load_elf_interp(&interp_elf_ex,
1840                                                     interpreter,
1841 -                                                   &interp_load_addr);
1842 +                                                   &interp_load_addr,
1843 +                                                   load_bias);
1844                 if (BAD_ADDR(elf_entry)) {
1845                         printk(KERN_ERR "Unable to load interpreter\n");
1846                         send_sig(SIGSEGV, current, 0);
1847 @@ -849,6 +912,14 @@ static int load_elf_binary(struct linux_
1848  
1849         set_binfmt(&elf_format);
1850  
1851 +       /*
1852 +        * Map the vsyscall trampoline. This address is then passed via
1853 +        * AT_SYSINFO.
1854 +        */
1855 +#ifdef __HAVE_ARCH_VSYSCALL
1856 +       map_vsyscall();
1857 +#endif
1858 +
1859         compute_creds(bprm);
1860         current->flags &= ~PF_FORKNOEXEC;
1861         create_elf_tables(bprm, &elf_ex, (interpreter_type == INTERPRETER_AOUT),
1862 @@ -862,6 +933,10 @@ static int load_elf_binary(struct linux_
1863         current->mm->end_data = end_data;
1864         current->mm->start_stack = bprm->p;
1865  
1866 +#ifdef __HAVE_ARCH_RANDOMIZE_BRK
1867 +       if (!(current->mm->def_flags & VM_EXEC))
1868 +               randomize_brk(elf_brk);
1869 +#endif
1870         if (current->personality & MMAP_PAGE_ZERO) {
1871                 /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
1872                    and some applications "depend" upon this behavior.
1873 --- linux/fs/exec.c.orig        
1874 +++ linux/fs/exec.c     
1875 @@ -389,7 +389,12 @@ int setup_arg_pages(struct linux_binprm 
1876         while (i < MAX_ARG_PAGES)
1877                 bprm->page[i++] = NULL;
1878  #else
1879 +#ifdef __HAVE_ARCH_ALIGN_STACK
1880 +       stack_base = arch_align_stack(STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE);
1881 +       stack_base = PAGE_ALIGN(stack_base);
1882 +#else
1883         stack_base = STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE;
1884 +#endif
1885         mm->arg_start = bprm->p + stack_base;
1886         arg_size = STACK_TOP - (PAGE_MASK & (unsigned long) mm->arg_start);
1887  #endif
1888 @@ -430,6 +435,7 @@ int setup_arg_pages(struct linux_binprm 
1889                         mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
1890                 else
1891                         mpnt->vm_flags = VM_STACK_FLAGS;
1892 +               mpnt->vm_flags |= mm->def_flags;
1893                 mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
1894                 insert_vm_struct(mm, mpnt);
1895                 mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
1896 @@ -886,8 +892,13 @@ int prepare_binprm(struct linux_binprm *
1897  
1898         if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
1899                 /* Set-uid? */
1900 -               if (mode & S_ISUID)
1901 +               if (mode & S_ISUID) {
1902                         bprm->e_uid = inode->i_uid;
1903 +#ifdef __i386__
1904 +                       /* reset personality */
1905 +                       current->personality = PER_LINUX;
1906 +#endif
1907 +               }
1908  
1909                 /* Set-gid? */
1910                 /*
1911 @@ -895,8 +906,13 @@ int prepare_binprm(struct linux_binprm *
1912                  * is a candidate for mandatory locking, not a setgid
1913                  * executable.
1914                  */
1915 -               if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
1916 +               if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
1917                         bprm->e_gid = inode->i_gid;
1918 +#ifdef __i386__
1919 +                       /* reset personality */
1920 +                       current->personality = PER_LINUX;
1921 +#endif
1922 +               }
1923         }
1924  
1925         /* fill in binprm security blob */
1926 --- linux/kernel/fork.c.orig    
1927 +++ linux/kernel/fork.c 
1928 @@ -417,6 +417,9 @@ static struct mm_struct * mm_init(struct
1929  
1930         if (likely(!mm_alloc_pgd(mm))) {
1931                 mm->def_flags = 0;
1932 +#ifdef __HAVE_ARCH_MMAP_TOP
1933 +               mm->mmap_top = mmap_top();
1934 +#endif
1935                 return mm;
1936         }
1937         free_mm(mm);
1938 --- linux/kernel/signal.c.orig  
1939 +++ linux/kernel/signal.c       
1940 @@ -1552,6 +1552,34 @@ do_notify_parent_cldstop(struct task_str
1941         spin_unlock_irqrestore(&sighand->siglock, flags);
1942  }
1943  
1944 +int print_fatal_signals = 0;
1945 +
1946 +static void print_fatal_signal(struct pt_regs *regs, int signr)
1947 +{
1948 +       int i;
1949 +       unsigned char insn;
1950 +       printk("%s/%d: potentially unexpected fatal signal %d.\n",
1951 +               current->comm, current->pid, signr);
1952 +               
1953 +#ifdef __i386__
1954 +       printk("code at %08lx: ", regs->eip);
1955 +       for (i = 0; i < 16; i++) {
1956 +               __get_user(insn, (unsigned char *)(regs->eip + i));
1957 +               printk("%02x ", insn);
1958 +       }
1959 +#endif 
1960 +       printk("\n");
1961 +       show_regs(regs);
1962 +}
1963 +
1964 +static int __init setup_print_fatal_signals(char *str)
1965 +{
1966 +       get_option (&str, &print_fatal_signals);
1967 +
1968 +       return 1;
1969 +}
1970 +
1971 +__setup("print-fatal-signals=", setup_print_fatal_signals);
1972  
1973  #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
1974  
1975 @@ -1743,6 +1771,11 @@ relock:
1976                 if (!signr)
1977                         break; /* will return 0 */
1978  
1979 +               if ((signr == SIGSEGV) && print_fatal_signals) {
1980 +                       spin_unlock_irq(&current->sighand->siglock);
1981 +                       print_fatal_signal(regs, signr);
1982 +                       spin_lock_irq(&current->sighand->siglock);
1983 +               }
1984                 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
1985                         ptrace_signal_deliver(regs, cookie);
1986  
1987 @@ -1847,6 +1880,8 @@ relock:
1988                  * Anything else is fatal, maybe with a core dump.
1989                  */
1990                 current->flags |= PF_SIGNALED;
1991 +               if (print_fatal_signals)
1992 +                       print_fatal_signal(regs, signr);
1993                 if (sig_kernel_coredump(signr) &&
1994                     do_coredump((long)signr, signr, regs)) {
1995                         /*
1996 --- linux/kernel/sysctl.c.orig  
1997 +++ linux/kernel/sysctl.c       
1998 @@ -63,6 +63,29 @@ extern int min_free_kbytes;
1999  extern int printk_ratelimit_jiffies;
2000  extern int printk_ratelimit_burst;
2001  
2002 +extern unsigned int vdso_enabled;
2003 +
2004 +int exec_shield = 2;
2005 +int exec_shield_randomize = 1;
2006 +
2007 +static int __init setup_exec_shield(char *str)
2008 +{
2009 +        get_option (&str, &exec_shield);
2010 +
2011 +        return 1;
2012 +}
2013 +
2014 +__setup("exec-shield=", setup_exec_shield);
2015 +
2016 +static int __init setup_exec_shield_randomize(char *str)
2017 +{
2018 +        get_option (&str, &exec_shield_randomize);
2019 +
2020 +        return 1;
2021 +}
2022 +
2023 +__setup("exec-shield-randomize=", setup_exec_shield_randomize);
2024 +
2025  /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
2026  static int maxolduid = 65535;
2027  static int minolduid;
2028 @@ -266,6 +289,40 @@ static ctl_table kern_table[] = {
2029                 .proc_handler   = &proc_dointvec,
2030         },
2031         {
2032 +               .ctl_name       = KERN_PANIC,
2033 +               .procname       = "exec-shield",
2034 +               .data           = &exec_shield,
2035 +               .maxlen         = sizeof(int),
2036 +               .mode           = 0644,
2037 +               .proc_handler   = &proc_dointvec,
2038 +       },
2039 +       {
2040 +               .ctl_name       = KERN_PANIC,
2041 +               .procname       = "exec-shield-randomize",
2042 +               .data           = &exec_shield_randomize,
2043 +               .maxlen         = sizeof(int),
2044 +               .mode           = 0644,
2045 +               .proc_handler   = &proc_dointvec,
2046 +       },
2047 +       {
2048 +               .ctl_name       = KERN_PANIC,
2049 +               .procname       = "print-fatal-signals",
2050 +               .data           = &print_fatal_signals,
2051 +               .maxlen         = sizeof(int),
2052 +               .mode           = 0644,
2053 +               .proc_handler   = &proc_dointvec,
2054 +       },
2055 +#if __i386__
2056 +       {
2057 +               .ctl_name       = KERN_PANIC,
2058 +               .procname       = "vdso",
2059 +               .data           = &vdso_enabled,
2060 +               .maxlen         = sizeof(int),
2061 +               .mode           = 0644,
2062 +               .proc_handler   = &proc_dointvec,
2063 +       },
2064 +#endif
2065 +       {
2066                 .ctl_name       = KERN_CORE_USES_PID,
2067                 .procname       = "core_uses_pid",
2068                 .data           = &core_uses_pid,
2069 --- linux/mm/fremap.c.orig      
2070 +++ linux/mm/fremap.c   
2071 @@ -61,12 +61,6 @@ int install_page(struct mm_struct *mm, s
2072         pmd_t *pmd;
2073         pte_t pte_val;
2074  
2075 -       /*
2076 -        * We use page_add_file_rmap below: if install_page is
2077 -        * ever extended to anonymous pages, this will warn us.
2078 -        */
2079 -       BUG_ON(!page_mapping(page));
2080 -
2081         pgd = pgd_offset(mm, addr);
2082         spin_lock(&mm->page_table_lock);
2083  
2084 --- linux/mm/mmap.c.orig        
2085 +++ linux/mm/mmap.c     
2086 @@ -244,6 +244,8 @@ static inline void
2087  __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
2088                 struct vm_area_struct *prev, struct rb_node *rb_parent)
2089  {
2090 +       if (vma->vm_flags & VM_EXEC)
2091 +               arch_add_exec_range(mm, vma->vm_end);
2092         if (prev) {
2093                 vma->vm_next = prev->vm_next;
2094                 prev->vm_next = vma;
2095 @@ -348,6 +350,8 @@ __vma_unlink(struct mm_struct *mm, struc
2096         rb_erase(&vma->vm_rb, &mm->mm_rb);
2097         if (mm->mmap_cache == vma)
2098                 mm->mmap_cache = prev;
2099 +       if (vma->vm_flags & VM_EXEC)
2100 +               arch_remove_exec_range(mm, vma->vm_end);
2101  }
2102  
2103  /*
2104 @@ -646,6 +650,8 @@ struct vm_area_struct *vma_merge(struct 
2105                 } else                                  /* cases 2, 5, 7 */
2106                         vma_adjust(prev, prev->vm_start,
2107                                 end, prev->vm_pgoff, NULL);
2108 +               if (prev->vm_flags & VM_EXEC)
2109 +                       arch_add_exec_range(mm, prev->vm_end);
2110                 return prev;
2111         }
2112  
2113 @@ -782,7 +788,7 @@ unsigned long do_mmap_pgoff(struct file 
2114         /* Obtain the address to map to. we verify (or select) it and ensure
2115          * that it represents a valid section of the address space.
2116          */
2117 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
2118 +       addr = get_unmapped_area(file, addr, len, pgoff, flags, prot & PROT_EXEC);
2119         if (addr & ~PAGE_MASK)
2120                 return addr;
2121  
2122 @@ -1016,7 +1022,7 @@ EXPORT_SYMBOL(do_mmap_pgoff);
2123  #ifndef HAVE_ARCH_UNMAPPED_AREA
2124  static inline unsigned long
2125  arch_get_unmapped_area(struct file *filp, unsigned long addr,
2126 -               unsigned long len, unsigned long pgoff, unsigned long flags)
2127 +               unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
2128  {
2129         struct mm_struct *mm = current->mm;
2130         struct vm_area_struct *vma;
2131 @@ -1061,12 +1067,12 @@ full_search:
2132  #else
2133  extern unsigned long
2134  arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
2135 -                       unsigned long, unsigned long);
2136 +                       unsigned long, unsigned long, unsigned long);
2137  #endif 
2138  
2139  unsigned long
2140  get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
2141 -               unsigned long pgoff, unsigned long flags)
2142 +               unsigned long pgoff, unsigned long flags, unsigned long exec)
2143  {
2144         if (flags & MAP_FIXED) {
2145                 unsigned long ret;
2146 @@ -1098,7 +1104,7 @@ get_unmapped_area(struct file *file, uns
2147                 return file->f_op->get_unmapped_area(file, addr, len,
2148                                                 pgoff, flags);
2149  
2150 -       return arch_get_unmapped_area(file, addr, len, pgoff, flags);
2151 +       return arch_get_unmapped_area(file, addr, len, pgoff, flags, exec);
2152  }
2153  
2154  EXPORT_SYMBOL(get_unmapped_area);
2155 @@ -1176,6 +1182,14 @@ out:
2156         return prev ? prev->vm_next : vma;
2157  }
2158  
2159 +
2160 +static int over_stack_limit(unsigned long sz)
2161 +{
2162 +       if (sz < EXEC_STACK_BIAS)
2163 +               return 0;
2164 +       return (sz - EXEC_STACK_BIAS) > current->rlim[RLIMIT_STACK].rlim_cur;
2165 +}
2166 +
2167  #ifdef CONFIG_STACK_GROWSUP
2168  /*
2169   * vma is the first one with address > vma->vm_end.  Have to extend vma.
2170 @@ -1210,7 +1224,7 @@ int expand_stack(struct vm_area_struct *
2171                 return -ENOMEM;
2172         }
2173         
2174 -       if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
2175 +       if (over_stack_limit(address - vma->vm_start) ||
2176                         ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
2177                         current->rlim[RLIMIT_AS].rlim_cur) {
2178                 anon_vma_unlock(vma);
2179 @@ -1271,7 +1285,7 @@ int expand_stack(struct vm_area_struct *
2180                 return -ENOMEM;
2181         }
2182         
2183 -       if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
2184 +       if (over_stack_limit(vma->vm_end - address) ||
2185                         ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
2186                         current->rlim[RLIMIT_AS].rlim_cur) {
2187                 anon_vma_unlock(vma);
2188 @@ -1384,6 +1398,7 @@ no_mmaps:
2189  static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area)
2190  {
2191         size_t len = area->vm_end - area->vm_start;
2192 +       unsigned long old_end = area->vm_end;
2193  
2194         area->vm_mm->total_vm -= len >> PAGE_SHIFT;
2195         if (area->vm_flags & VM_LOCKED)
2196 @@ -1394,8 +1409,14 @@ static void unmap_vma(struct mm_struct *
2197         if (area->vm_start >= TASK_UNMAPPED_BASE &&
2198                                 area->vm_start < area->vm_mm->free_area_cache)
2199               area->vm_mm->free_area_cache = area->vm_start;
2200 -
2201 +       /*
2202 +        * Is this a new hole at the highest possible address?
2203 +        */
2204 +       if (area->vm_start > area->vm_mm->non_executable_cache)
2205 +               area->vm_mm->non_executable_cache = area->vm_start;
2206         remove_vm_struct(area);
2207 +       if (unlikely(area->vm_flags & VM_EXEC))
2208 +               arch_remove_exec_range(mm, old_end);
2209  }
2210  
2211  /*
2212 @@ -1505,10 +1526,14 @@ int split_vma(struct mm_struct * mm, str
2213         if (new->vm_ops && new->vm_ops->open)
2214                 new->vm_ops->open(new);
2215  
2216 -       if (new_below)
2217 +       if (new_below) {
2218 +               unsigned long old_end = vma->vm_end;
2219 +
2220                 vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
2221                         ((addr - new->vm_start) >> PAGE_SHIFT), new);
2222 -       else
2223 +               if (vma->vm_flags & VM_EXEC)
2224 +                       arch_remove_exec_range(mm, old_end);
2225 +       } else
2226                 vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
2227  
2228         return 0;
2229 @@ -1716,6 +1741,7 @@ void exit_mmap(struct mm_struct *mm)
2230         mm->rss = 0;
2231         mm->total_vm = 0;
2232         mm->locked_vm = 0;
2233 +       arch_flush_exec_range(mm);
2234  
2235         spin_unlock(&mm->page_table_lock);
2236  
2237 --- linux/mm/mprotect.c.orig    
2238 +++ linux/mm/mprotect.c 
2239 @@ -20,6 +20,7 @@
2240  
2241  #include <asm/uaccess.h>
2242  #include <asm/pgtable.h>
2243 +#include <asm/pgalloc.h>
2244  #include <asm/cacheflush.h>
2245  #include <asm/tlbflush.h>
2246  
2247 @@ -112,8 +113,9 @@ mprotect_fixup(struct vm_area_struct *vm
2248         unsigned long start, unsigned long end, unsigned int newflags)
2249  {
2250         struct mm_struct * mm = vma->vm_mm;
2251 -       unsigned long charged = 0;
2252 +       unsigned long charged = 0, old_end = vma->vm_end;
2253         pgprot_t newprot;
2254 +       unsigned int oldflags;
2255         pgoff_t pgoff;
2256         int error;
2257  
2258 @@ -174,8 +176,11 @@ success:
2259          * vm_flags and vm_page_prot are protected by the mmap_sem
2260          * held in write mode.
2261          */
2262 +       oldflags = vma->vm_flags;
2263         vma->vm_flags = newflags;
2264         vma->vm_page_prot = newprot;
2265 +       if (oldflags & VM_EXEC)
2266 +               arch_remove_exec_range(current->mm, old_end);
2267         change_protection(vma, start, end, newprot);
2268         return 0;
2269  
2270 --- linux/mm/mremap.c.orig      
2271 +++ linux/mm/mremap.c   
2272 @@ -380,7 +380,8 @@ unsigned long do_mremap(unsigned long ad
2273                                 map_flags |= MAP_SHARED;
2274  
2275                         new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
2276 -                                               vma->vm_pgoff, map_flags);
2277 +                                       vma->vm_pgoff, map_flags,
2278 +                                               vma->vm_flags & VM_EXEC);
2279                         ret = new_addr;
2280                         if (new_addr & ~PAGE_MASK)
2281                                 goto out;
2282 --- linux/mm/vmalloc.c.orig     
2283 +++ linux/mm/vmalloc.c  
2284 @@ -455,6 +455,28 @@ void *vmalloc(unsigned long size)
2285  EXPORT_SYMBOL(vmalloc);
2286  
2287  /**
2288 + *     vmalloc_exec  -  allocate virtually contiguous, executable memory
2289 + *
2290 + *     @size:          allocation size
2291 + *
2292 + *     Kernel-internal function to allocate enough pages to cover @size
2293 + *     the page level allocator and map them into contiguous and
2294 + *     executable kernel virtual space.
2295 + *
2296 + *     For tight cotrol over page level allocator and protection flags
2297 + *     use __vmalloc() instead.
2298 + */
2299 +
2300 +#ifndef PAGE_KERNEL_EXEC
2301 +# define PAGE_KERNEL_EXEC PAGE_KERNEL
2302 +#endif
2303 +
2304 +void *vmalloc_exec(unsigned long size)
2305 +{
2306 +       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
2307 +}
2308 +
2309 +/**
2310   *     vmalloc_32  -  allocate virtually contiguous memory (32bit addressable)
2311   *
2312   *     @size:          allocation size
This page took 0.255777 seconds and 3 git commands to generate.