lkml.org 
[lkml]   [2007]   [Apr]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[2/6] add config option to vmalloc stacks (was: Re: [-mm patch] i386: enable 4k stacks by default)
    On Mon, Apr 30, 2007 at 10:38:19AM -0700, William Lee Irwin III wrote:
    > Here's what I did for i386 for someone concerned about blowing the stack.

    Add a config option to vmalloc() task stacks so that stack overflows are
    detected without fail, and with a fatal failure mode at that.

    Signed-off-by: William Irwin <wli@holomorphy.com>


    Index: stack-paranoia/arch/i386/Kconfig.debug
    ===================================================================
    --- stack-paranoia.orig/arch/i386/Kconfig.debug 2007-04-30 10:31:43.878562345 -0700
    +++ stack-paranoia/arch/i386/Kconfig.debug 2007-04-30 10:32:56.182682722 -0700
    @@ -35,6 +35,15 @@

    This option will slow down process creation somewhat.

    +config VMALLOC_STACK
    + bool "vmalloc() the stack"
    + depends on DEBUG_KERNEL
    + help
    + Allocates the stack physically discontiguously and from high
    + memory. Furthermore an unmapped guard page follows the stack.
    + This is not for end-users. It's intended to trigger fatal
    + system errors under various forms of stack abuse.
    +
    comment "Page alloc debug is incompatible with Software Suspend on i386"
    depends on DEBUG_KERNEL && SOFTWARE_SUSPEND

    Index: stack-paranoia/arch/i386/kernel/process.c
    ===================================================================
    --- stack-paranoia.orig/arch/i386/kernel/process.c 2007-04-30 10:26:15.979876464 -0700
    +++ stack-paranoia/arch/i386/kernel/process.c 2007-04-30 10:32:56.178682494 -0700
    @@ -25,6 +25,7 @@
    #include <linux/stddef.h>
    #include <linux/slab.h>
    #include <linux/vmalloc.h>
    +#include <linux/workqueue.h>
    #include <linux/user.h>
    #include <linux/a.out.h>
    #include <linux/interrupt.h>
    @@ -322,6 +323,58 @@
    show_trace(NULL, regs, &regs->esp);
    }

    +#ifdef CONFIG_VMALLOC_STACK
    +struct thread_info *alloc_thread_info(struct task_struct *unused)
    +{
    + int i;
    + struct page *pages[THREAD_SIZE/PAGE_SIZE], **tmp = pages;
    + struct vm_struct *area;
    +
    + /*
    + * passing VM_IOREMAP for the sake of alignment is why
    + * all this is done by hand.
    + */
    + area = get_vm_area(THREAD_SIZE, VM_IOREMAP);
    + if (!area)
    + return NULL;
    + for (i = 0; i < THREAD_SIZE/PAGE_SIZE; ++i) {
    + pages[i] = alloc_page(GFP_HIGHUSER);
    + if (!pages[i])
    + goto out_free_pages;
    + }
    + /* implicitly transfer page refcounts to the vm_struct */
    + if (map_vm_area(area, PAGE_KERNEL, &tmp))
    + goto out_remove_area;
    + /* it may be worth poisoning, save thread_info proper */
    + return (struct thread_info *)area->addr;
    +out_remove_area:
    + remove_vm_area(area);
    +out_free_pages:
    + do {
    + __free_page(pages[--i]);
    + } while (i >= 0);
    + return NULL;
    +}
    +
    +static void work_free_thread_info(struct work_struct *work)
    +{
    + int i;
    + void *p = work;
    +
    + for (i = 0; i < THREAD_SIZE/PAGE_SIZE; ++i)
    + __free_page(vmalloc_to_page(p + PAGE_SIZE*i));
    + vfree(p);
    +}
    +
    +void free_thread_info(struct thread_info *info)
    +{
    + struct work_struct *work = (struct work_struct *)info;
    +
    + INIT_WORK(work, work_free_thread_info);
    + schedule_work(work);
    +}
    +#endif
    +
    /*
    * This gets run with %ebx containing the
    * function to call, and %edx containing
    Index: stack-paranoia/include/asm-i386/module.h
    ===================================================================
    --- stack-paranoia.orig/include/asm-i386/module.h 2007-04-30 10:31:43.882562573 -0700
    +++ stack-paranoia/include/asm-i386/module.h 2007-04-30 10:32:56.182682722 -0700
    @@ -74,6 +74,13 @@
    #define MODULE_STACKSIZE "64KSTACKS "
    #endif

    -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
    +#ifdef CONFIG_VMALLOC_STACK
    +#define MODULE_VMALLOC_STACK "VMALLOCSTACKS "
    +#else
    +#define MODULE_VMALLOC_STACK ""
    +#endif
    +
    +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE \
    + MODULE_VMALLOC_STACK

    #endif /* _ASM_I386_MODULE_H */
    Index: stack-paranoia/include/asm-i386/thread_info.h
    ===================================================================
    --- stack-paranoia.orig/include/asm-i386/thread_info.h 2007-04-30 10:31:43.882562573 -0700
    +++ stack-paranoia/include/asm-i386/thread_info.h 2007-04-30 10:32:56.182682722 -0700
    @@ -102,6 +102,11 @@
    }

    /* thread information allocation */
    +#ifdef CONFIG_VMALLOC_STACK
    +struct task_struct;
    +struct thread_info *alloc_thread_info(struct task_struct *);
    +void free_thread_info(struct thread_info *);
    +#else /* !CONFIG_VMALLOC_STACK */
    #ifdef CONFIG_DEBUG_STACK_USAGE
    #define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL)
    #else
    @@ -109,6 +114,7 @@
    #endif

    #define free_thread_info(info) kfree(info)
    +#endif /* !CONFIG_VMALLOC_STACK */

    #else /* !__ASSEMBLY__ */

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-04-30 19:45    [W:0.032 / U:30.200 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site