lkml.org 
[lkml]   [2011]   [Apr]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 159/173] exec: make argv/envp memory visible to oom-killer
    2.6.27.59-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: Oleg Nesterov <oleg@redhat.com>

    commit 3c77f845722158206a7209c45ccddc264d19319c upstream.

    Brad Spengler published a local memory-allocation DoS that
    evades the OOM-killer (though not the virtual memory RLIMIT):
    http://www.grsecurity.net/~spender/64bit_dos.c

    execve()->copy_strings() can allocate a lot of memory, but
    this is not visible to oom-killer, nobody can see the nascent
    bprm->mm and take it into account.

    With this patch get_arg_page() increments current's MM_ANONPAGES
    counter every time we allocate the new page for argv/envp. When
    do_execve() succeds or fails, we change this counter back.

    Technically this is not 100% correct, we can't know if the new
    page is swapped out and turn MM_ANONPAGES into MM_SWAPENTS, but
    I don't think this really matters and everything becomes correct
    once exec changes ->mm or fails.

    Reported-by: Brad Spengler <spender@grsecurity.net>
    Reviewed-and-discussed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Signed-off-by: Oleg Nesterov <oleg@redhat.com>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Moritz Muehlenhoff <jmm@debian.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    fs/exec.c | 28 ++++++++++++++++++++++++++--
    include/linux/binfmts.h | 1 +
    2 files changed, 27 insertions(+), 2 deletions(-)

    Index: longterm-2.6.27/fs/exec.c
    ===================================================================
    --- longterm-2.6.27.orig/fs/exec.c 2011-02-09 22:45:33.000000000 +0100
    +++ longterm-2.6.27/fs/exec.c 2011-04-25 17:22:50.655279537 +0200
    @@ -168,6 +168,21 @@

    #ifdef CONFIG_MMU

    +static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
    +{
    + struct mm_struct *mm = current->mm;
    + long diff = (long)(pages - bprm->vma_pages);
    +
    + if (!mm || !diff)
    + return;
    +
    + bprm->vma_pages = pages;
    +
    + down_write(&mm->mmap_sem);
    + mm->total_vm += diff;
    + up_write(&mm->mmap_sem);
    +}
    +
    static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
    int write)
    {
    @@ -190,6 +205,8 @@
    unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
    struct rlimit *rlim;

    + acct_arg_size(bprm, size / PAGE_SIZE);
    +
    /*
    * We've historically supported up to 32 pages (ARG_MAX)
    * of argument strings even with small stacks
    @@ -291,6 +308,10 @@

    #else

    +static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
    +{
    +}
    +
    static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
    int write)
    {
    @@ -995,6 +1016,7 @@
    /*
    * Release all of the old mmap stuff
    */
    + acct_arg_size(bprm, 0);
    retval = exec_mmap(bprm->mm);
    if (retval)
    goto out;
    @@ -1378,8 +1400,10 @@
    security_bprm_free(bprm);

    out_mm:
    - if (bprm->mm)
    + if (bprm->mm) {
    + acct_arg_size(bprm, 0);
    mmput (bprm->mm);
    + }

    out_file:
    if (bprm->file) {
    Index: longterm-2.6.27/include/linux/binfmts.h
    ===================================================================
    --- longterm-2.6.27.orig/include/linux/binfmts.h 2011-01-23 10:52:34.000000000 +0100
    +++ longterm-2.6.27/include/linux/binfmts.h 2011-04-25 17:22:24.856278432 +0200
    @@ -28,6 +28,7 @@
    char buf[BINPRM_BUF_SIZE];
    #ifdef CONFIG_MMU
    struct vm_area_struct *vma;
    + unsigned long vma_pages;
    #else
    # define MAX_ARG_PAGES 32
    struct page *page[MAX_ARG_PAGES];



    \
     
     \ /
      Last update: 2011-04-25 22:35    [W:0.026 / U:29.408 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site