diff -urNp linux-2.6.16.16/arch/i386/kernel/process.c linux-2.6.16.16-randparam/arch/i386/kernel/process.c --- linux-2.6.16.16/arch/i386/kernel/process.c 2006-05-10 21:56:24.000000000 -0400 +++ linux-2.6.16.16-randparam/arch/i386/kernel/process.c 2006-05-19 23:47:09.000000000 -0400 @@ -907,7 +907,30 @@ asmlinkage int sys_get_thread_area(struc unsigned long arch_align_stack(unsigned long sp) { - if (randomize_va_space) - sp -= get_random_int() % 8192; + unsigned int random_interval = 0; + unsigned int random_places = 0; + /* + * The stack is shifted around within 4k in intervals of + * 16 bytes. + * + * The position of the stack in VMA is set in binfmt_elf.c + */ + if (randomize_va_space && (stack_random_bits > 0)) { + /*XXX: Should we tune this for PAGE_SIZE instead of 4096?*/ + if (stack_random_bits > 8) + random_interval = 4096 / (1 << 8); + else + random_interval = 4096 / (1 << stack_random_bits); + + /*How many positions can we have?*/ + random_places = 4096 / random_interval; + + /* + * get_random_int() % random_places = how many steps we move + * Multiply this by random_interval to get our position. + */ + sp -= (get_random_int() % random_places) * random_interval; + } return sp & ~0xf; } + diff -urNp linux-2.6.16.16/arch/i386/mm/mmap.c linux-2.6.16.16-randparam/arch/i386/mm/mmap.c --- linux-2.6.16.16/arch/i386/mm/mmap.c 2006-05-10 21:56:24.000000000 -0400 +++ linux-2.6.16.16-randparam/arch/i386/mm/mmap.c 2006-05-19 23:51:52.000000000 -0400 @@ -41,8 +41,12 @@ static inline unsigned long mmap_base(st unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; unsigned long random_factor = 0; - if (current->flags & PF_RANDOMIZE) - random_factor = get_random_int() % (1024*1024); + /* + * Our page size is 4096, although we should use PAGE_SIZE + * here instead really. + */ + if (current->flags & PF_RANDOMIZE && mmap_random_bits) + random_factor = get_random_int() % (4096 << mmap_random_bits); if (gap < MIN_GAP) gap = MIN_GAP; diff -urNp linux-2.6.16.16/arch/x86_64/kernel/process.c linux-2.6.16.16-randparam/arch/x86_64/kernel/process.c --- linux-2.6.16.16/arch/x86_64/kernel/process.c 2006-05-10 21:56:24.000000000 -0400 +++ linux-2.6.16.16-randparam/arch/x86_64/kernel/process.c 2006-05-19 23:46:50.000000000 -0400 @@ -841,7 +841,30 @@ int dump_task_regs(struct task_struct *t unsigned long arch_align_stack(unsigned long sp) { - if (randomize_va_space) - sp -= get_random_int() % 8192; + unsigned int random_interval = 0; + unsigned int random_places = 0; + /* + * The stack is shifted around within 4k in intervals of + * 16 bytes. + * + * The position of the stack in VMA is set in binfmt_elf.c + */ + if (randomize_va_space && (stack_random_bits > 0)) { + /*XXX: Should we tune this for PAGE_SIZE instead of 4096?*/ + if (stack_random_bits > 8) + random_interval = 4096 / (1 << 8); + else + random_interval = 4096 / (1 << stack_random_bits); + + /*How many positions can we have?*/ + random_places = 4096 / random_interval; + + /* + * get_random_int() % random_places = how many steps we move + * Multiply this by random_interval to get our position. + */ + sp -= (get_random_int() % random_places) * random_interval; + } return sp & ~0xf; } + diff -urNp linux-2.6.16.16/Documentation/kernel-parameters.txt linux-2.6.16.16-randparam/Documentation/kernel-parameters.txt --- linux-2.6.16.16/Documentation/kernel-parameters.txt 2006-05-10 21:56:24.000000000 -0400 +++ linux-2.6.16.16-randparam/Documentation/kernel-parameters.txt 2006-05-19 23:39:07.000000000 -0400 @@ -918,6 +918,10 @@ running once the system is up. scheduler performance, so it's only for scheduler development purposes, not production environments. + mmap_random_bits= + Control how much entropy is used for mmap() base + randomization. + mousedev.tap_time= [MOUSE] Maximum time between finger touching and leaving touchpad surface for touch to be considered @@ -1549,6 +1553,10 @@ running once the system is up. st0x= [HW,SCSI] See header of drivers/scsi/seagate.c. + stack_random_bits= + Sets the number of bits of stack randomization to + perform. + sti= [PARISC,HW] Format: Set the STI (builtin display/keyboard on the HP-PARISC diff -urNp linux-2.6.16.16/fs/binfmt_elf.c linux-2.6.16.16-randparam/fs/binfmt_elf.c --- linux-2.6.16.16/fs/binfmt_elf.c 2006-05-10 21:56:24.000000000 -0400 +++ linux-2.6.16.16-randparam/fs/binfmt_elf.c 2006-05-19 23:57:25.000000000 -0400 @@ -504,9 +504,16 @@ out: static unsigned long randomize_stack_top(unsigned long stack_top) { unsigned int random_variable = 0; - - if (current->flags & PF_RANDOMIZE) - random_variable = get_random_int() % (8*1024*1024); + unsigned int random_range = 0; + /* + * Randomization happens here if doing more than 8 bits of entropy, + * otherwise look to process.c only; the other 8 bits are there. + */ + if (current->flags & PF_RANDOMIZE && stack_random_bits > 8) { + /*XXX: We should probably PAGE_SIZE instead of 4096 here*/ + random_range = 4096 * (1 << (stack_random_bits - 8)); + random_variable = get_random_int() % (random_range); + } #ifdef CONFIG_STACK_GROWSUP return PAGE_ALIGN(stack_top + random_variable); #else diff -urNp linux-2.6.16.16/fs/exec.c linux-2.6.16.16-randparam/fs/exec.c --- linux-2.6.16.16/fs/exec.c 2006-05-10 21:56:24.000000000 -0400 +++ linux-2.6.16.16-randparam/fs/exec.c 2006-05-19 23:51:30.000000000 -0400 @@ -67,6 +67,81 @@ EXPORT_SYMBOL(suid_dumpable); static struct linux_binfmt *formats; static DEFINE_RWLOCK(binfmt_lock); +/* + * stack_random_bits: How much stack randomization to apply. + * We default to 8iMiB on 16 byte intervals (19 bits). + * + * For any value over 8 bits, the higher order bits are used to + * apply page randomization; for example, our default of 19 supplies + * 11 bits of VMA randomization, giving 2048 possible positions in + * 4096 byte page interval, 8MiB. The other 8 bits are covered by + * randomization inside the page, shifting sp by 16 byte intervals. + * + * For values under 8 bits, the size of a page is divided by + * (1 << stack_random_bits) and the stack is placed in one of those + * intervals. + */ +int stack_random_bits = 19; + +EXPORT_SYMBOL(stack_random_bits); + +/* + * Here we allow a command line setting to handle + * adjusting stack base randomization, based on bits + * of entropy. + */ +static int __init stack_random_bits_setup(char *str) +{ + get_option(&str, &stack_random_bits); + /*512M: Maximum randomization for i386*/ + /* + * FIXME: Use an arch-specific header and a construct + * such as: + * if (stack_random_bits > STACK_RANDOM_BITS_MAX) + * stack_random_bits = STACK_RANDOM_BITS_MAX; + */ + if (stack_random_bits > 25) + stack_random_bits = 25; + /*If it's negative something is wrong, zero it*/ + if (stack_random_bits < 1) + stack_random_bits = 0; + return 1; +} + +__setup("stack_random_bits=", stack_random_bits_setup); + +/* + * mmap_random_bits: How much mmap() randomization to apply. + * We default to 1 megabyte (8 bits) + */ +int mmap_random_bits = 8; + +EXPORT_SYMBOL(mmap_random_bits); + +/* + * Here we allow a command line setting to handle + * adjusting mmap() base randomization, based on bits + * of entropy. + */ +static int __init mmap_random_bits_setup(char *str) +{ + get_option(&str, &mmap_random_bits); + /*256M: Maximum randomization for i386*/ + /*FIXME: Use a construct from a define in a header, + * like: + * if (mmap_random_bits > MMAP_RANDOM_BITS_MAX) + * mmap_random_bits = MMAP_RANDOM_BITS_MAX; + */ + if (mmap_random_bits > 16) + mmap_random_bits = 16; + /*If it's negative something is wrong, zero it*/ + if (mmap_random_bits < 1) + mmap_random_bits = 0; + return 1; +} + +__setup("mmap_random_bits=", mmap_random_bits_setup); + int register_binfmt(struct linux_binfmt * fmt) { struct linux_binfmt ** tmp = &formats; diff -urNp linux-2.6.16.16/include/linux/mm.h linux-2.6.16.16-randparam/include/linux/mm.h --- linux-2.6.16.16/include/linux/mm.h 2006-05-10 21:56:24.000000000 -0400 +++ linux-2.6.16.16-randparam/include/linux/mm.h 2006-05-19 23:46:27.000000000 -0400 @@ -23,6 +23,17 @@ struct anon_vma; extern unsigned long max_mapnr; #endif +/* + * stack_random_bits: how much entropy to apply to the stack + * - Currently only actually works (right) on IA-32 and x86-64 + * - Defined in fs/exec.c + * mmap_random_bits: how much entropy to apply to mmap() + * - Currently only used in arch/i386/mm/mmap.c + * - Defined in fs/exec.c for consistency + */ +extern int stack_random_bits; +extern int mmap_random_bits; + extern unsigned long num_physpages; extern void * high_memory; extern unsigned long vmalloc_earlyreserve;