diff -urN linux-2.4.32/Documentation/Configure.help linux-2.4.32-aslr-200604281210/Documentation/Configure.help --- linux-2.4.32/Documentation/Configure.help 2006-03-03 09:55:55.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/Documentation/Configure.help 2006-06-19 21:57:12.000000000 +0200 @@ -29057,6 +29057,121 @@ If unsure, say N. +Support soft mode +CONFIG_PAX_SOFTMODE + Enabling this option will allow you to run PaX in soft mode, that + is, PaX features will not be enforced by default, only on executables + marked explicitly. You must also enable PT_PAX_FLAGS support as it + is the only way to mark executables for soft mode use. + + Soft mode can be activated by using the "pax_softmode=1" kernel command + line option on boot. Furthermore you can control various PaX features + at runtime via the entries in /proc/sys/kernel/pax. + +Use legacy ELF header marking +CONFIG_PAX_EI_PAX + Enabling this option will allow you to control PaX features on + a per executable basis via the 'chpax' utility available at + http://pax.grsecurity.net/. The control flags will be read from + an otherwise reserved part of the ELF header. This marking has + numerous drawbacks (no support for soft-mode, toolchain does not + know about the non-standard use of the ELF header) therefore it + has been deprecated in favour of PT_PAX_FLAGS support. + + If you have applications not marked by the PT_PAX_FLAGS ELF + program header then you MUST enable this option otherwise they + will not get any protection. + + Note that if you enable PT_PAX_FLAGS marking support as well, + the PT_PAX_FLAG marks will override the legacy EI_PAX marks. + +Use ELF program header marking +CONFIG_PAX_PT_PAX_FLAGS + Enabling this option will allow you to control PaX features on + a per executable basis via the 'paxctl' utility available at + http://pax.grsecurity.net/. The control flags will be read from + a PaX specific ELF program header (PT_PAX_FLAGS). This marking + has the benefits of supporting both soft mode and being fully + integrated into the toolchain (the binutils patch is available + from http://pax.grsecurity.net). + + If you have applications not marked by the PT_PAX_FLAGS ELF + program header then you MUST enable the EI_PAX marking support + otherwise they will not get any protection. + + Note that if you enable the legacy EI_PAX marking support as well, + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks. + +Address Space Layout Randomization +CONFIG_PAX_ASLR + Many if not most exploit techniques rely on the knowledge of + certain addresses in the attacked program. The following options + will allow the kernel to apply a certain amount of randomization + to specific parts of the program thereby forcing an attacker to + guess them in most cases. Any failed guess will most likely crash + the attacked program which allows the kernel to detect such attempts + and react on them. PaX itself provides no reaction mechanisms, + instead it is strongly encouraged that you make use of Nergal's + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's + (http://www.grsecurity.net/) built-in crash detection features or + develop one yourself. + + By saying Y here you can choose to randomize the following areas: + - top of the task's kernel stack + - top of the task's userland stack + - base address for mmap() requests that do not specify one + (this includes all libraries) + - base address of the main executable + + It is strongly recommended to say Y here as address space layout + randomization has negligible impact on performance yet it provides + a very effective protection. + + NOTE: you can use the 'chpax' or 'paxctl' utilities to control most + of these features on a per file basis. + +Randomize kernel stack base +CONFIG_PAX_RANDKSTACK + By saying Y here the kernel will randomize every task's kernel + stack on every system call. This will not only force an attacker + to guess it but also prevent him from making use of possible + leaked information about it. + + Since the kernel stack is a rather scarce resource, randomization + may cause unexpected stack overflows, therefore you should very + carefully test your system. Note that once enabled in the kernel + configuration, this feature cannot be disabled on a per file basis. + +Randomize user stack base +CONFIG_PAX_RANDUSTACK + By saying Y here the kernel will randomize every task's userland + stack. The randomization is done in two steps where the second + one may apply a big amount of shift to the top of the stack and + cause problems for programs that want to use lots of memory (more + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is). + For this reason the second step can be controlled by 'chpax' or + 'paxctl' on a per file basis. + +Randomize mmap() base +CONFIG_PAX_RANDMMAP + By saying Y here the kernel will use a randomized base address for + mmap() requests that do not specify one themselves. As a result + all dynamically loaded libraries will appear at random addresses + and therefore be harder to exploit by a technique where an attacker + attempts to execute library code for his purposes (e.g. spawn a + shell from an exploited program that is running at an elevated + privilege level). + + Furthermore, if a program is relinked as a dynamic ELF file, its + base address will be randomized as well, completing the full + randomization of the address space layout. Attacking such programs + becomes a guess game. You can find an example of doing this at + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples + at http://www.grsecurity.net/grsec-gcc-specs.tar.gz . + + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this + feature on a per file basis. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, diff -urN linux-2.4.32/arch/alpha/config.in linux-2.4.32-aslr-200604281210/arch/alpha/config.in --- linux-2.4.32/arch/alpha/config.in 2004-11-17 12:54:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/alpha/config.in 2006-06-19 21:57:12.000000000 +0200 @@ -466,5 +466,29 @@ endmenu +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' +if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + source crypto/Config.in source lib/Config.in diff -urN linux-2.4.32/arch/alpha/kernel/osf_sys.c linux-2.4.32-aslr-200604281210/arch/alpha/kernel/osf_sys.c --- linux-2.4.32/arch/alpha/kernel/osf_sys.c 2003-06-13 16:51:29.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/arch/alpha/kernel/osf_sys.c 2006-06-19 21:59:32.000000000 +0200 @@ -1357,6 +1357,10 @@ merely specific addresses, but regions of memory -- perhaps this feature should be incorporated into all ports? */ +#ifdef CONFIG_PAX_RANDMMAP + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) +#endif + if (addr) { addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); if (addr != -ENOMEM) @@ -1364,8 +1368,15 @@ } /* Next, try allocating at TASK_UNMAPPED_BASE. */ - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE), - len, limit); + + addr = TASK_UNMAPPED_BASE; + +#ifdef CONFIG_PAX_RANDMMAP + if (current->mm->pax_flags & MF_PAX_RANDMMAP) + addr += current->mm->delta_mmap; +#endif + + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); if (addr != -ENOMEM) return addr; diff -urN linux-2.4.32/arch/i386/config.in linux-2.4.32-aslr-200604281210/arch/i386/config.in --- linux-2.4.32/arch/i386/config.in 2004-11-17 12:54:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/i386/config.in 2006-06-19 21:57:12.000000000 +0200 @@ -485,5 +485,32 @@ endmenu +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' +if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + if [ "$CONFIG_X86_TSC" = "y" ]; then + bool ' Randomize kernel stack base' CONFIG_PAX_RANDKSTACK + fi + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + source crypto/Config.in source lib/Config.in diff -urN linux-2.4.32/arch/i386/kernel/entry.S linux-2.4.32-aslr-200604281210/arch/i386/kernel/entry.S --- linux-2.4.32/arch/i386/kernel/entry.S 2003-06-13 16:51:29.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/arch/i386/kernel/entry.S 2006-06-19 21:57:12.000000000 +0200 @@ -209,6 +209,17 @@ jae badsys call *SYMBOL_NAME(sys_call_table)(,%eax,4) movl %eax,EAX(%esp) # save the return value + +#ifdef CONFIG_PAX_RANDKSTACK + cli # need_resched and signals atomic test + cmpl $0,need_resched(%ebx) + jne reschedule + cmpl $0,sigpending(%ebx) + jne signal_return + call SYMBOL_NAME(pax_randomize_kstack) + jmp restore_all +#endif + ENTRY(ret_from_sys_call) cli # need_resched and signals atomic test cmpl $0,need_resched(%ebx) diff -urN linux-2.4.32/arch/i386/kernel/process.c linux-2.4.32-aslr-200604281210/arch/i386/kernel/process.c --- linux-2.4.32/arch/i386/kernel/process.c 2005-11-18 21:08:35.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/i386/kernel/process.c 2006-06-19 21:57:12.000000000 +0200 @@ -792,3 +792,34 @@ } #undef last_sched #undef first_sched + +#ifdef CONFIG_PAX_RANDKSTACK +asmlinkage void pax_randomize_kstack(void) +{ + struct tss_struct *tss = init_tss + smp_processor_id(); + unsigned long time; + + +#ifdef CONFIG_PAX_SOFTMODE + if (!pax_aslr) + return; +#endif + + rdtscl(time); + + /* P4 seems to return a 0 LSB, ignore it */ +#ifdef CONFIG_MPENTIUM4 + time &= 0x1EUL; + time <<= 2; +#else + time &= 0xFUL; + time <<= 3; +#endif + + + tss->esp0 ^= time; + current->thread.esp0 = tss->esp0; + + +} +#endif diff -urN linux-2.4.32/arch/ia64/config.in linux-2.4.32-aslr-200604281210/arch/ia64/config.in --- linux-2.4.32/arch/ia64/config.in 2004-11-17 12:54:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/ia64/config.in 2006-06-19 21:57:12.000000000 +0200 @@ -316,6 +316,30 @@ bool ' Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ fi +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' +if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 endmenu diff -urN linux-2.4.32/arch/ia64/ia32/binfmt_elf32.c linux-2.4.32-aslr-200604281210/arch/ia64/ia32/binfmt_elf32.c --- linux-2.4.32/arch/ia64/ia32/binfmt_elf32.c 2005-01-27 18:57:30.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/ia64/ia32/binfmt_elf32.c 2006-06-19 21:57:12.000000000 +0200 @@ -53,6 +53,17 @@ #undef SET_PERSONALITY #define SET_PERSONALITY(ex, ibcs2) elf32_set_personality() +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) + +#define PAX_DELTA_MMAP_LSB(tsk) IA32_PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT) +#define PAX_DELTA_EXEC_LSB(tsk) IA32_PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT) +#define PAX_DELTA_STACK_LSB(tsk) IA32_PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT) +#endif + /* Ugly but avoids duplication */ #include "../../../fs/binfmt_elf.c" diff -urN linux-2.4.32/arch/ia64/kernel/sys_ia64.c linux-2.4.32-aslr-200604281210/arch/ia64/kernel/sys_ia64.c --- linux-2.4.32/arch/ia64/kernel/sys_ia64.c 2004-02-18 14:36:30.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/ia64/kernel/sys_ia64.c 2006-06-19 21:57:12.000000000 +0200 @@ -34,6 +34,13 @@ if (rgn_index(addr)==REGION_HPAGE) addr = 0; #endif + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_BASE; diff -urN linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-aslr-200604281210/arch/mips/config-shared.in --- linux-2.4.32/arch/mips/config-shared.in 2005-01-27 18:57:30.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/mips/config-shared.in 2006-06-19 21:57:12.000000000 +0200 @@ -1038,5 +1038,29 @@ endmenu +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' + if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + source crypto/Config.in source lib/Config.in diff -urN linux-2.4.32/arch/mips/kernel/syscall.c linux-2.4.32-aslr-200604281210/arch/mips/kernel/syscall.c --- linux-2.4.32/arch/mips/kernel/syscall.c 2005-01-27 18:57:30.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/mips/kernel/syscall.c 2006-06-19 21:57:12.000000000 +0200 @@ -82,6 +82,11 @@ do_color_align = 0; if (filp || (flags & MAP_SHARED)) do_color_align = 1; + +#ifdef CONFIG_PAX_RANDMMAP + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) +#endif + if (addr) { if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); @@ -92,6 +97,13 @@ (!vmm || addr + len <= vmm->vm_start)) return addr; } + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + addr = TASK_UNMAPPED_BASE; if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); diff -urN linux-2.4.32/arch/mips64/kernel/binfmt_elfn32.c linux-2.4.32-aslr-200604281210/arch/mips64/kernel/binfmt_elfn32.c --- linux-2.4.32/arch/mips64/kernel/binfmt_elfn32.c 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/arch/mips64/kernel/binfmt_elfn32.c 2006-06-19 21:57:12.000000000 +0200 @@ -50,6 +50,17 @@ #undef ELF_ET_DYN_BASE #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#endif + #include #include #include diff -urN linux-2.4.32/arch/mips64/kernel/binfmt_elfo32.c linux-2.4.32-aslr-200604281210/arch/mips64/kernel/binfmt_elfo32.c --- linux-2.4.32/arch/mips64/kernel/binfmt_elfo32.c 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/arch/mips64/kernel/binfmt_elfo32.c 2006-06-19 21:57:12.000000000 +0200 @@ -52,6 +52,17 @@ #undef ELF_ET_DYN_BASE #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#endif + #include #include #include diff -urN linux-2.4.32/arch/mips64/kernel/syscall.c linux-2.4.32-aslr-200604281210/arch/mips64/kernel/syscall.c --- linux-2.4.32/arch/mips64/kernel/syscall.c 2005-01-27 18:57:31.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/mips64/kernel/syscall.c 2006-06-19 21:57:12.000000000 +0200 @@ -80,6 +80,11 @@ do_color_align = 0; if (filp || (flags & MAP_SHARED)) do_color_align = 1; + +#ifdef CONFIG_PAX_RANDMMAP + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) +#endif + if (addr) { if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); @@ -90,7 +95,14 @@ (!vmm || addr + len <= vmm->vm_start)) return addr; } - addr = TASK_UNMAPPED_BASE; + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + + addr = TASK_UNMAPPED_BASE; if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); else diff -urN linux-2.4.32/arch/parisc/config.in linux-2.4.32-aslr-200604281210/arch/parisc/config.in --- linux-2.4.32/arch/parisc/config.in 2004-11-17 12:54:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/parisc/config.in 2006-06-19 21:57:12.000000000 +0200 @@ -202,5 +202,29 @@ endmenu +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' +if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + source crypto/Config.in source lib/Config.in diff -urN linux-2.4.32/arch/parisc/kernel/sys_parisc.c linux-2.4.32-aslr-200604281210/arch/parisc/kernel/sys_parisc.c --- linux-2.4.32/arch/parisc/kernel/sys_parisc.c 2002-11-29 00:53:10.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/parisc/kernel/sys_parisc.c 2006-06-19 21:57:12.000000000 +0200 @@ -90,6 +90,11 @@ inode = filp->f_dentry->d_inode; } +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; +#endif + if (inode && (flags & MAP_SHARED) && (inode->i_mapping->i_mmap_shared)) { addr = get_shared_area(inode, addr, len, pgoff); } else { diff -urN linux-2.4.32/arch/parisc/kernel/sys_parisc32.c linux-2.4.32-aslr-200604281210/arch/parisc/kernel/sys_parisc32.c --- linux-2.4.32/arch/parisc/kernel/sys_parisc32.c 2006-03-03 09:55:55.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/parisc/kernel/sys_parisc32.c 2006-06-19 21:57:12.000000000 +0200 @@ -185,6 +185,11 @@ return retval; bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); + +#ifdef CONFIG_PAX_RANDUSTACK + bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK; +#endif + memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); DBG(("do_execve32(%s, %p, %p, %p)\n", filename, argv, envp, regs)); diff -urN linux-2.4.32/arch/ppc/config.in linux-2.4.32-aslr-200604281210/arch/ppc/config.in --- linux-2.4.32/arch/ppc/config.in 2004-08-08 01:26:04.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/arch/ppc/config.in 2006-06-19 21:57:12.000000000 +0200 @@ -665,4 +665,28 @@ int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' +if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + endmenu diff -urN linux-2.4.32/arch/sparc/config.in linux-2.4.32-aslr-200604281210/arch/sparc/config.in --- linux-2.4.32/arch/sparc/config.in 2004-11-17 12:54:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/sparc/config.in 2006-06-19 21:57:12.000000000 +0200 @@ -280,5 +280,29 @@ endmenu +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' +if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + source crypto/Config.in source lib/Config.in diff -urN linux-2.4.32/arch/sparc/kernel/sys_sparc.c linux-2.4.32-aslr-200604281210/arch/sparc/kernel/sys_sparc.c --- linux-2.4.32/arch/sparc/kernel/sys_sparc.c 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/arch/sparc/kernel/sys_sparc.c 2006-06-19 21:57:12.000000000 +0200 @@ -54,6 +54,13 @@ return -ENOMEM; if (ARCH_SUN4C_SUN4 && len > 0x20000000) return -ENOMEM; + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_BASE; diff -urN linux-2.4.32/arch/sparc64/config.in linux-2.4.32-aslr-200604281210/arch/sparc64/config.in --- linux-2.4.32/arch/sparc64/config.in 2004-11-17 12:54:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/sparc64/config.in 2006-06-19 21:57:12.000000000 +0200 @@ -318,5 +318,29 @@ endmenu +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' +if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + source crypto/Config.in source lib/Config.in diff -urN linux-2.4.32/arch/sparc64/kernel/sys_sparc.c linux-2.4.32-aslr-200604281210/arch/sparc64/kernel/sys_sparc.c --- linux-2.4.32/arch/sparc64/kernel/sys_sparc.c 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/arch/sparc64/kernel/sys_sparc.c 2006-06-19 21:57:12.000000000 +0200 @@ -63,6 +63,13 @@ task_size = 0xf0000000UL; if (len > task_size || len > -PAGE_OFFSET) return -ENOMEM; + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_BASE; diff -urN linux-2.4.32/arch/sparc64/kernel/sys_sparc32.c linux-2.4.32-aslr-200604281210/arch/sparc64/kernel/sys_sparc32.c --- linux-2.4.32/arch/sparc64/kernel/sys_sparc32.c 2006-03-03 09:55:55.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/sparc64/kernel/sys_sparc32.c 2006-06-19 21:57:12.000000000 +0200 @@ -3270,6 +3270,11 @@ int i; bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); + +#ifdef CONFIG_PAX_RANDUSTACK + bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK; +#endif + memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0])); file = open_exec(filename); diff -urN linux-2.4.32/arch/x86_64/config.in linux-2.4.32-aslr-200604281210/arch/x86_64/config.in --- linux-2.4.32/arch/x86_64/config.in 2004-11-17 12:54:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/x86_64/config.in 2006-06-19 21:57:12.000000000 +0200 @@ -261,4 +261,28 @@ endmenu +mainmenu_option next_comment +comment 'PaX options' + +mainmenu_option next_comment +comment 'PaX Control' +bool 'Support soft mode' CONFIG_PAX_SOFTMODE +bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX +bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS +endmenu + +mainmenu_option next_comment +comment 'Address Space Layout Randomization' +if [ "$CONFIG_PAX_EI_PAX" = "y" -o \ + "$CONFIG_PAX_PT_PAX_FLAGS" = "y" ]; then + bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR + if [ "$CONFIG_PAX_ASLR" = "y" ]; then + bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK + bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP + fi +fi +endmenu + +endmenu + source lib/Config.in diff -urN linux-2.4.32/arch/x86_64/ia32/ia32_binfmt.c linux-2.4.32-aslr-200604281210/arch/x86_64/ia32/ia32_binfmt.c --- linux-2.4.32/arch/x86_64/ia32/ia32_binfmt.c 2005-01-27 18:57:31.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/x86_64/ia32/ia32_binfmt.c 2006-06-19 21:57:12.000000000 +0200 @@ -28,7 +28,14 @@ #define ELF_NAME "elf/i386" -#define IA32_STACK_TOP IA32_PAGE_OFFSET +#ifdef CONFIG_PAX_RANDUSTACK +#define __IA32_DELTA_STACK (current->mm->delta_stack) +#else +#define __IA32_DELTA_STACK 0UL +#endif + +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK) + #define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000) #undef ELF_ARCH @@ -129,6 +136,17 @@ #include #include +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) 0x08048000UL + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) 16 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) 16 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) 16 +#endif + typedef struct user_i387_ia32_struct elf_fpregset_t; typedef struct user32_fxsr_struct elf_fpxregset_t; diff -urN linux-2.4.32/arch/x86_64/kernel/sys_x86_64.c linux-2.4.32-aslr-200604281210/arch/x86_64/kernel/sys_x86_64.c --- linux-2.4.32/arch/x86_64/kernel/sys_x86_64.c 2003-11-28 19:26:19.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/arch/x86_64/kernel/sys_x86_64.c 2006-06-19 21:57:12.000000000 +0200 @@ -72,6 +72,13 @@ unsigned long end = TASK_SIZE; if (current->thread.flags & THREAD_IA32) { + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_32 + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_32; end = 0xffff0000; @@ -82,10 +89,24 @@ base down for this case. This may give conflicts with the heap, but we assume that malloc falls back to mmap. Give it 1GB of playground for now. -AK */ + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = 0x40000000 + (current->mm->delta_mmap & 0x0FFFFFFFU); + else +#endif + if (!addr) addr = 0x40000000; end = 0x80000000; } else { + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_64 + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_64; end = TASK_SIZE; diff -urN linux-2.4.32/drivers/char/random.c linux-2.4.32-aslr-200604281210/drivers/char/random.c --- linux-2.4.32/drivers/char/random.c 2005-06-02 16:39:06.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/drivers/char/random.c 2006-06-19 22:06:32.000000000 +0200 @@ -2315,7 +2315,27 @@ } #endif +#ifdef CONFIG_PAX_ASLR +unsigned long pax_get_random_long(void) +{ + static time_t rekey_time; + static __u32 secret[12]; + time_t t; + /* + * Pick a random secret every REKEY_INTERVAL seconds. + */ + t = CURRENT_TIME; + if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) { + rekey_time = t; + get_random_bytes(secret, sizeof(secret)); + } + + secret[1] = halfMD4Transform(secret+8, secret); + secret[0] = halfMD4Transform(secret+8, secret); + return *(unsigned long *)secret; +} +#endif #ifndef CONFIG_ARCH_S390 EXPORT_SYMBOL(add_keyboard_randomness); diff -urN linux-2.4.32/fs/binfmt_aout.c linux-2.4.32-aslr-200604281210/fs/binfmt_aout.c --- linux-2.4.32/fs/binfmt_aout.c 2005-01-27 18:57:33.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/fs/binfmt_aout.c 2006-06-19 21:57:12.000000000 +0200 @@ -315,6 +315,11 @@ current->mm->mmap = NULL; compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; + +#if defined(CONFIG_PAX_ASLR) + current->mm->pax_flags = 0UL; +#endif + #ifdef __sparc__ if (N_MAGIC(ex) == NMAGIC) { loff_t pos = fd_offset; diff -urN linux-2.4.32/fs/binfmt_elf.c linux-2.4.32-aslr-200604281210/fs/binfmt_elf.c --- linux-2.4.32/fs/binfmt_elf.c 2006-03-03 09:55:55.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/fs/binfmt_elf.c 2006-06-19 21:57:12.000000000 +0200 @@ -33,10 +33,12 @@ #include #include #include +#include #include #include #include +#include #define DLINFO_ITEMS 13 @@ -81,6 +83,10 @@ static int set_brk(unsigned long start, unsigned long end) { +#ifdef CONFIG_PAX_RANDMMAP + unsigned long unaligned_end = end; +#endif + start = ELF_PAGEALIGN(start); end = ELF_PAGEALIGN(end); if (end > start) { @@ -91,6 +97,10 @@ if (BAD_ADDR(addr)) return addr; } +#ifdef CONFIG_PAX_RANDMMAP + /* We don't want it to be aligned or we'll loose randomization */ + end = unaligned_end; +#endif current->mm->start_brk = current->mm->brk = end; return 0; } @@ -452,6 +462,109 @@ return elf_entry; } +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE) +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata) +{ + unsigned long pax_flags = 0UL; + +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_aslr) +#endif + + if (elf_phdata->p_flags & PF_RANDMMAP) + pax_flags |= MF_PAX_RANDMMAP; +#endif + + return pax_flags; +} +#endif + +#ifdef CONFIG_PAX_PT_PAX_FLAGS +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata) +{ + unsigned long pax_flags = 0UL; + +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_aslr) +#endif + + if (!(elf_phdata->p_flags & PF_NORANDMMAP)) + pax_flags |= MF_PAX_RANDMMAP; +#endif + + return pax_flags; +} +#endif + +#ifdef CONFIG_PAX_EI_PAX +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex) +{ + unsigned long pax_flags = 0UL; + +#ifdef CONFIG_PAX_ASLR + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_aslr) +#endif + + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP)) + pax_flags |= MF_PAX_RANDMMAP; +#endif + + return pax_flags; +} +#endif + +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata) +{ + unsigned long pax_flags = 0UL; + +#ifdef CONFIG_PAX_PT_PAX_FLAGS + unsigned long i; +#endif + +#ifdef CONFIG_PAX_EI_PAX + pax_flags = pax_parse_ei_pax(elf_ex); +#endif + +#ifdef CONFIG_PAX_PT_PAX_FLAGS + for (i = 0UL; i < elf_ex->e_phnum; i++) + if (elf_phdata[i].p_type == PT_PAX_FLAGS) { + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) || + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) || + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) || + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) || + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)) || + ((elf_phdata[i].p_flags & PF_RANDEXEC) && ((elf_phdata[i].p_flags & PF_NORANDEXEC) || elf_ex->e_type == ET_DYN || !(elf_phdata[i].p_flags & PF_MPROTECT))) || + (!(elf_phdata[i].p_flags & PF_NORANDEXEC) && (elf_ex->e_type == ET_DYN || (elf_phdata[i].p_flags & PF_NOMPROTECT)))) + return -EINVAL; + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_softmode) + pax_flags = pax_parse_softmode(&elf_phdata[i]); + else +#endif + + pax_flags = pax_parse_hardmode(&elf_phdata[i]); + break; + } +#endif + + //if (0 > pax_check_flags(&pax_flags)) + // return -EINVAL; + +#ifdef CONFIG_PAX_ASLR + current->mm->pax_flags = pax_flags; +#endif + return 0; +} +#endif + /* * These are the functions used to load ELF style executables and shared * libraries. There is no binary dependent code anywhere else. @@ -679,7 +792,33 @@ current->mm->end_data = 0; current->mm->end_code = 0; current->mm->mmap = NULL; + +#if defined(CONFIG_PAX_ASLR) + current->mm->pax_flags = 0UL; + current->mm->delta_mmap = 0UL; + current->mm->delta_exec = 0UL; + current->mm->delta_stack = 0UL; +#endif + current->flags &= ~PF_FORKNOEXEC; + +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) + if (0 > pax_parse_elf_flags(&elf_ex, elf_phdata)) { + send_sig(SIGKILL, current, 0); + goto out_free_dentry; + } +#endif + +#ifdef CONFIG_PAX_ASLR + if (current->mm->pax_flags & MF_PAX_RANDMMAP) { +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb)) + + current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current)); + current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current)); + current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current)); + } +#endif + elf_entry = (unsigned long) elf_ex.e_entry; /* Do this so that we can load the interpreter, if need be. We will @@ -688,7 +827,7 @@ retval = setup_arg_pages(bprm); if (retval < 0) { send_sig(SIGKILL, current, 0); - return retval; + goto out_free_dentry; } current->mm->start_stack = bprm->p; @@ -740,6 +879,15 @@ base, as well as whatever program they might try to exec. This is because the brk will follow the loader, and is not movable. */ load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); + +#ifdef CONFIG_PAX_RANDMMAP + /* PaX: randomize base address at the default exe base if requested */ + if (current->mm->pax_flags & MF_PAX_RANDMMAP) { + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec); + elf_flags |= MAP_FIXED; + } +#endif + } error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags); @@ -796,6 +944,17 @@ start_data += load_bias; end_data += load_bias; +#ifdef CONFIG_PAX_RANDMMAP + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_aslr) +#endif + + if (current->mm->pax_flags & MF_PAX_RANDMMAP) + elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT); +#undef pax_delta_mask +#endif + /* Calling set_brk effectively mmaps the pages that we need * for the bss and break sections. We must do this before * mapping in the interpreter, to make sure it doesn't wind diff -urN linux-2.4.32/fs/exec.c linux-2.4.32-aslr-200604281210/fs/exec.c --- linux-2.4.32/fs/exec.c 2005-01-27 18:57:33.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/fs/exec.c 2006-06-19 21:57:12.000000000 +0200 @@ -37,6 +37,7 @@ #include #include #include +#include #define __NO_VERSION__ #include @@ -56,6 +57,15 @@ static struct linux_binfmt *formats; static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED; +#ifdef CONFIG_PAX_SOFTMODE + +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK) +unsigned int pax_aslr=1; +#endif + +unsigned int pax_softmode; +#endif + int register_binfmt(struct linux_binfmt * fmt) { struct linux_binfmt ** tmp = &formats; @@ -942,6 +952,16 @@ return retval; bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); + +#ifdef CONFIG_PAX_RANDUSTACK + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_aslr) +#endif + + bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK; +#endif + memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); bprm.file = file; diff -urN linux-2.4.32/include/asm-alpha/a.out.h linux-2.4.32-aslr-200604281210/include/asm-alpha/a.out.h --- linux-2.4.32/include/asm-alpha/a.out.h 2002-08-03 02:39:45.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-alpha/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -98,7 +98,7 @@ set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \ ? ADDR_LIMIT_32BIT : 0) | PER_OSF4)) -#define STACK_TOP \ +#define __STACK_TOP \ (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL) #endif diff -urN linux-2.4.32/include/asm-alpha/elf.h linux-2.4.32-aslr-200604281210/include/asm-alpha/elf.h --- linux-2.4.32/include/asm-alpha/elf.h 2004-02-18 14:36:32.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-alpha/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -41,6 +41,17 @@ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL) + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28) +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28) +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19) +#endif + /* $0 is set by ld.so to a pointer to a function which might be registered using atexit. This provides a mean for the dynamic linker to call DT_FINI functions for shared libraries that have diff -urN linux-2.4.32/include/asm-i386/a.out.h linux-2.4.32-aslr-200604281210/include/asm-i386/a.out.h --- linux-2.4.32/include/asm-i386/a.out.h 1995-06-16 20:33:06.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-i386/a.out.h 2006-06-19 22:14:46.000000000 +0200 @@ -19,7 +19,7 @@ #ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE +#define __STACK_TOP TASK_SIZE #endif diff -urN linux-2.4.32/include/asm-i386/elf.h linux-2.4.32-aslr-200604281210/include/asm-i386/elf.h --- linux-2.4.32/include/asm-i386/elf.h 2006-05-31 18:11:41.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-i386/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -57,6 +57,17 @@ #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) 0x08048000UL + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) 16 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) 16 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16) +#endif + /* Wow, the "main" arch needs arch dependent functions too.. :) */ /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is diff -urN linux-2.4.32/include/asm-ia64/elf.h linux-2.4.32-aslr-200604281210/include/asm-ia64/elf.h --- linux-2.4.32/include/asm-ia64/elf.h 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-ia64/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -41,6 +41,16 @@ */ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) +#endif /* * We use (abuse?) this macro to insert the (empty) vm_area that is diff -urN linux-2.4.32/include/asm-ia64/ia32.h linux-2.4.32-aslr-200604281210/include/asm-ia64/ia32.h --- linux-2.4.32/include/asm-ia64/ia32.h 2004-08-08 01:26:06.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-ia64/ia32.h 2006-06-19 21:57:12.000000000 +0200 @@ -367,7 +367,14 @@ #define ELF_ARCH EM_386 #define IA32_PAGE_OFFSET 0xc0000000 -#define IA32_STACK_TOP IA32_PAGE_OFFSET + +#ifdef CONFIG_PAX_RANDUSTACK +#define __IA32_DELTA_STACK (current->mm->delta_stack) +#else +#define __IA32_DELTA_STACK 0UL +#endif + +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK) /* * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can diff -urN linux-2.4.32/include/asm-ia64/ustack.h linux-2.4.32-aslr-200604281210/include/asm-ia64/ustack.h --- linux-2.4.32/include/asm-ia64/ustack.h 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-ia64/ustack.h 2006-06-19 21:57:12.000000000 +0200 @@ -11,6 +11,6 @@ #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2) /* Make a default stack size of 2GB */ #define DEFAULT_USER_STACK_SIZE (1UL << 31) -#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT) +#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT) #endif /* _ASM_IA64_USTACK_H */ diff -urN linux-2.4.32/include/asm-mips/a.out.h linux-2.4.32-aslr-200604281210/include/asm-mips/a.out.h --- linux-2.4.32/include/asm-mips/a.out.h 1995-12-13 11:39:45.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-mips/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -19,7 +19,7 @@ #ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE +#define __STACK_TOP TASK_SIZE #endif diff -urN linux-2.4.32/include/asm-mips/elf.h linux-2.4.32-aslr-200604281210/include/asm-mips/elf.h --- linux-2.4.32/include/asm-mips/elf.h 2004-02-18 14:36:32.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-mips/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -107,6 +107,17 @@ #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) 0x00400000UL + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) (27 - PAGE_SHIFT) +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) (27 - PAGE_SHIFT) +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) (27 - PAGE_SHIFT) +#endif + #ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) #endif diff -urN linux-2.4.32/include/asm-mips64/a.out.h linux-2.4.32-aslr-200604281210/include/asm-mips64/a.out.h --- linux-2.4.32/include/asm-mips64/a.out.h 2003-08-25 13:44:44.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-mips64/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -26,7 +26,7 @@ #ifdef __KERNEL__ -#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE) +#define __STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE) #endif diff -urN linux-2.4.32/include/asm-mips64/elf.h linux-2.4.32-aslr-200604281210/include/asm-mips64/elf.h --- linux-2.4.32/include/asm-mips64/elf.h 2004-02-18 14:36:32.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-mips64/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -107,6 +107,17 @@ #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) #endif +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#endif + #ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) \ do { current->thread.mflags &= ~MF_ABI_MASK; \ diff -urN linux-2.4.32/include/asm-parisc/a.out.h linux-2.4.32-aslr-200604281210/include/asm-parisc/a.out.h --- linux-2.4.32/include/asm-parisc/a.out.h 2000-12-05 21:29:39.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-parisc/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -22,7 +22,7 @@ /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc. * prumpf */ -#define STACK_TOP TASK_SIZE +#define __STACK_TOP TASK_SIZE #endif diff -urN linux-2.4.32/include/asm-parisc/elf.h linux-2.4.32-aslr-200604281210/include/asm-parisc/elf.h --- linux-2.4.32/include/asm-parisc/elf.h 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-parisc/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -135,6 +135,17 @@ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) 16 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) 16 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) 16 +#endif + /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This could be done in user space, but it's not easy, and we've already done it here. */ diff -urN linux-2.4.32/include/asm-ppc/a.out.h linux-2.4.32-aslr-200604281210/include/asm-ppc/a.out.h --- linux-2.4.32/include/asm-ppc/a.out.h 2003-08-25 13:44:44.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-ppc/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -2,7 +2,7 @@ #define __PPC_A_OUT_H__ /* grabbed from the intel stuff */ -#define STACK_TOP TASK_SIZE +#define __STACK_TOP TASK_SIZE struct exec diff -urN linux-2.4.32/include/asm-ppc/elf.h linux-2.4.32-aslr-200604281210/include/asm-ppc/elf.h --- linux-2.4.32/include/asm-ppc/elf.h 2003-06-13 16:51:38.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-ppc/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -46,6 +46,17 @@ #define ELF_ET_DYN_BASE (0x08000000) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000000UL + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) 15 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) 15 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) 15 +#endif + #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 diff -urN linux-2.4.32/include/asm-sparc/a.out.h linux-2.4.32-aslr-200604281210/include/asm-sparc/a.out.h --- linux-2.4.32/include/asm-sparc/a.out.h 2000-01-13 21:03:00.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-sparc/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -91,7 +91,7 @@ #include -#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE) +#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE) #endif /* __KERNEL__ */ diff -urN linux-2.4.32/include/asm-sparc/elf.h linux-2.4.32-aslr-200604281210/include/asm-sparc/elf.h --- linux-2.4.32/include/asm-sparc/elf.h 2005-01-27 18:57:34.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-sparc/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -83,6 +83,17 @@ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) 16 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) 16 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) 16 +#endif + /* This yields a mask that user programs can use to figure out what instruction set this cpu supports. This can NOT be done in userspace on Sparc. */ diff -urN linux-2.4.32/include/asm-sparc/uaccess.h linux-2.4.32-aslr-200604281210/include/asm-sparc/uaccess.h --- linux-2.4.32/include/asm-sparc/uaccess.h 2003-06-13 16:51:38.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-sparc/uaccess.h 2006-06-19 21:57:12.000000000 +0200 @@ -39,7 +39,7 @@ * No one can read/write anything from userland in the kernel space by setting * large size and address near to PAGE_OFFSET - a fault will break his intentions. */ -#define __user_ok(addr,size) ((addr) < STACK_TOP) +#define __user_ok(addr,size) ((addr) < __STACK_TOP) #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) diff -urN linux-2.4.32/include/asm-sparc64/a.out.h linux-2.4.32-aslr-200604281210/include/asm-sparc64/a.out.h --- linux-2.4.32/include/asm-sparc64/a.out.h 2001-04-27 07:17:26.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-sparc64/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -95,7 +95,7 @@ #ifdef __KERNEL__ -#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L) +#define __STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L) #endif diff -urN linux-2.4.32/include/asm-sparc64/elf.h linux-2.4.32-aslr-200604281210/include/asm-sparc64/elf.h --- linux-2.4.32/include/asm-sparc64/elf.h 2003-06-13 16:51:38.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/asm-sparc64/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -82,6 +82,16 @@ #define ELF_ET_DYN_BASE 0x0000010000000000UL #endif +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 0x10000UL : 0x100000UL) + +#define PAX_DELTA_MMAP_LSB(tsk) (PAGE_SHIFT + 1) +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 ) +#define PAX_DELTA_EXEC_LSB(tsk) (PAGE_SHIFT + 1) +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 ) +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 15 : 29 ) +#endif /* This yields a mask that user programs can use to figure out what instruction set this cpu supports. */ diff -urN linux-2.4.32/include/asm-x86_64/a.out.h linux-2.4.32-aslr-200604281210/include/asm-x86_64/a.out.h --- linux-2.4.32/include/asm-x86_64/a.out.h 2002-11-29 00:53:15.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-x86_64/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -23,7 +23,7 @@ #ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE +#define __STACK_TOP TASK_SIZE #endif diff -urN linux-2.4.32/include/asm-x86_64/elf.h linux-2.4.32-aslr-200604281210/include/asm-x86_64/elf.h --- linux-2.4.32/include/asm-x86_64/elf.h 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/asm-x86_64/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -68,6 +68,17 @@ #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 0x08048000UL : 0x400000UL) + +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24) +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24) +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24) +#endif + /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is now struct_user_regs, they are different). Assumes current is the process getting dumped. */ diff -urN linux-2.4.32/include/linux/a.out.h linux-2.4.32-aslr-200604281210/include/linux/a.out.h --- linux-2.4.32/include/linux/a.out.h 2006-05-31 18:06:34.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/linux/a.out.h 2006-06-19 21:57:12.000000000 +0200 @@ -7,6 +7,16 @@ #include +#ifdef CONFIG_PAX_RANDUSTACK +#define __DELTA_STACK (current->mm->delta_stack) +#else +#define __DELTA_STACK 0UL +#endif + +#ifndef STACK_TOP +#define STACK_TOP (__STACK_TOP - __DELTA_STACK) +#endif + #endif /* __STRUCT_EXEC_OVERRIDE__ */ /* these go in the N_MACHTYPE field */ @@ -37,6 +47,14 @@ M_MIPS2 = 152 /* MIPS R6000/R4000 binary */ }; +/* Constants for the N_FLAGS field */ +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */ +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */ +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */ +#define F_PAX_RANDEXEC 16 /* Randomize ET_EXEC base */ +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ + #if !defined (N_MAGIC) #define N_MAGIC(exec) ((exec).a_info & 0xffff) #endif diff -urN linux-2.4.32/include/linux/elf.h linux-2.4.32-aslr-200604281210/include/linux/elf.h --- linux-2.4.32/include/linux/elf.h 2006-05-31 18:11:41.000000000 +0200 +++ linux-2.4.32-aslr-200604281210/include/linux/elf.h 2006-06-19 21:57:12.000000000 +0200 @@ -34,6 +34,10 @@ #define PT_MIPS_REGINFO 0x70000000 #define PT_MIPS_OPTIONS 0x70000001 +#define PT_LOOS 0x60000000 +#define PT_GNU_STACK (PT_LOOS + 0x474e551) +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580) + /* Flags in the e_flags field of the header */ #define EF_MIPS_NOREORDER 0x00000001 #define EF_MIPS_PIC 0x00000002 @@ -44,6 +48,14 @@ #define EF_MIPS_ABI 0x0000f000 #define EF_MIPS_ARCH 0xf0000000 +/* Constants for the e_flags field */ +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */ +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */ +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */ +#define EF_PAX_RANDEXEC 16 /* Randomize ET_EXEC base */ +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ + /* These constants define the different elf file types */ #define ET_NONE 0 #define ET_REL 1 @@ -458,6 +470,19 @@ #define PF_W 0x2 #define PF_X 0x1 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */ +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */ +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */ +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */ +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */ +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */ +#define PF_RANDEXEC (1U << 10) /* Enable RANDEXEC */ +#define PF_NORANDEXEC (1U << 11) /* Disable RANDEXEC */ +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */ +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */ +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */ +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */ + typedef struct elf32_phdr{ Elf32_Word p_type; Elf32_Off p_offset; @@ -555,6 +580,8 @@ #define EI_VERSION 6 #define EI_PAD 7 +#define EI_PAX 14 + #define ELFMAG0 0x7f /* EI_MAG */ #define ELFMAG1 'E' #define ELFMAG2 'L' diff -urN linux-2.4.32/include/linux/random.h linux-2.4.32-aslr-200604281210/include/linux/random.h --- linux-2.4.32/include/linux/random.h 2005-11-02 10:29:31.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/linux/random.h 2006-06-19 21:57:12.000000000 +0200 @@ -72,6 +72,8 @@ extern __u32 secure_ipv6_id(__u32 *daddr); +extern unsigned long pax_get_random_long(void); + #ifndef MODULE extern struct file_operations random_fops, urandom_fops; #endif diff -urN linux-2.4.32/include/linux/sched.h linux-2.4.32-aslr-200604281210/include/linux/sched.h --- linux-2.4.32/include/linux/sched.h 2006-01-02 18:14:30.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/linux/sched.h 2006-06-19 21:57:12.000000000 +0200 @@ -231,8 +231,23 @@ /* Architecture-specific MM context */ mm_context_t context; + +#if defined(CONFIG_PAX_ASLR) + unsigned long pax_flags; + unsigned long delta_mmap; /* randomized offset */ + unsigned long delta_exec; /* randomized offset */ + unsigned long delta_stack; /* randomized offset */ +#endif + }; +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */ +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */ +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */ +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */ +#define MF_PAX_RANDEXEC 0x10000000 /* Randomize ET_EXEC base */ +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */ + extern int mmlist_nr; #define INIT_MM(name) \ @@ -436,6 +451,14 @@ #define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ +#ifdef CONFIG_PAX_SOFTMODE +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK) +extern unsigned int pax_aslr; +#endif + +extern unsigned int pax_softmode; +#endif + /* * Ptrace flags */ diff -urN linux-2.4.32/include/linux/sysctl.h linux-2.4.32-aslr-200604281210/include/linux/sysctl.h --- linux-2.4.32/include/linux/sysctl.h 2006-03-03 09:55:56.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/include/linux/sysctl.h 2006-06-19 21:57:12.000000000 +0200 @@ -129,8 +129,19 @@ KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */ KERN_CORE_SETUID=59, /* int: set to allow core dumps of setuid apps */ KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */ + +#ifdef CONFIG_PAX_SOFTMODE + KERN_PAX=69, /* PaX control */ +#endif + }; +#ifdef CONFIG_PAX_SOFTMODE +enum { + PAX_ASLR=1, /* PaX: disable/enable all randomization features */ + PAX_SOFTMODE=2 /* PaX: disable/enable soft mode */ +}; +#endif /* CTL_VM names: */ enum diff -urN linux-2.4.32/init/main.c linux-2.4.32-aslr-200604281210/init/main.c --- linux-2.4.32/init/main.c 2004-11-17 12:54:22.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/init/main.c 2006-06-19 21:57:12.000000000 +0200 @@ -142,6 +142,15 @@ __setup("profile=", profile_setup); +#ifdef CONFIG_PAX_SOFTMODE +static int __init setup_pax_softmode(char *str) +{ + get_option(&str, &pax_softmode); + return 1; +} +__setup("pax_softmode=", setup_pax_softmode); +#endif + static int __init checksetup(char *line) { struct kernel_param *p; diff -urN linux-2.4.32/kernel/sysctl.c linux-2.4.32-aslr-200604281210/kernel/sysctl.c --- linux-2.4.32/kernel/sysctl.c 2006-03-03 09:55:56.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/kernel/sysctl.c 2006-06-19 21:57:12.000000000 +0200 @@ -128,6 +128,19 @@ static ctl_table dev_table[]; extern ctl_table random_table[]; +#ifdef CONFIG_PAX_SOFTMODE +static ctl_table pax_table[] = { + +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK) + {PAX_ASLR, "aslr", &pax_aslr, sizeof(unsigned int), 0600, NULL, &proc_dointvec}, +#endif + + {PAX_SOFTMODE, "softmode", &pax_softmode, sizeof(unsigned int), 0600, NULL, &proc_dointvec}, + + {0} +}; +#endif + /* /proc declarations: */ #ifdef CONFIG_PROC_FS @@ -278,6 +291,11 @@ {KERN_EXCEPTION_TRACE,"exception-trace", &exception_trace,sizeof(int),0644,NULL,&proc_dointvec}, #endif + +#ifdef CONFIG_PAX_SOFTMODE + {KERN_PAX,"pax",NULL,0,0500,pax_table}, +#endif + {0} }; diff -urN linux-2.4.32/mm/mmap.c linux-2.4.32-aslr-200604281210/mm/mmap.c --- linux-2.4.32/mm/mmap.c 2005-01-27 18:57:34.000000000 +0100 +++ linux-2.4.32-aslr-200604281210/mm/mmap.c 2006-06-19 21:57:12.000000000 +0200 @@ -625,6 +625,10 @@ if (len > TASK_SIZE) return -ENOMEM; +#ifdef CONFIG_PAX_RANDMMAP + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) +#endif + if (addr) { addr = PAGE_ALIGN(addr); vma = find_vma(current->mm, addr); @@ -634,6 +638,12 @@ } addr = PAGE_ALIGN(TASK_UNMAPPED_BASE); +#ifdef CONFIG_PAX_RANDMMAP + /* PaX: randomize base address if requested */ + if (current->mm->pax_flags & MF_PAX_RANDMMAP) + addr += current->mm->delta_mmap; +#endif + for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { /* At this point: (!vma || addr < vma->vm_end). */ if (TASK_SIZE - len < addr)