lkml.org 
[lkml]   [2014]   [Nov]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.17 011/141] net: ppp: Dont call bpf_prog_create() in ppp_lock
    Date
    3.17-stable review patch.  If anyone has any objections, please let me know.

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

    From: Takashi Iwai <tiwai@suse.de>

    [ Upstream commit 5748eb8f8e989a9da1ac7c96dc73d68cbdedf7df ]

    In ppp_ioctl(), bpf_prog_create() is called inside ppp_lock, which
    eventually calls vmalloc() and hits BUG_ON() in vmalloc.c. This patch
    works around the problem by moving the allocation outside the lock.

    The bug was revealed by the recent change in net/core/filter.c, as it
    allocates via vmalloc() instead of kmalloc() now.

    Reported-and-tested-by: Stefan Seyfried <stefan.seyfried@googlemail.com>
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/ppp/ppp_generic.c | 40 ++++++++++++++++++++--------------------
    1 file changed, 20 insertions(+), 20 deletions(-)

    --- a/drivers/net/ppp/ppp_generic.c
    +++ b/drivers/net/ppp/ppp_generic.c
    @@ -755,23 +755,23 @@ static long ppp_ioctl(struct file *file,

    err = get_filter(argp, &code);
    if (err >= 0) {
    + struct bpf_prog *pass_filter = NULL;
    struct sock_fprog_kern fprog = {
    .len = err,
    .filter = code,
    };

    - ppp_lock(ppp);
    - if (ppp->pass_filter) {
    - bpf_prog_destroy(ppp->pass_filter);
    - ppp->pass_filter = NULL;
    + err = 0;
    + if (fprog.filter)
    + err = bpf_prog_create(&pass_filter, &fprog);
    + if (!err) {
    + ppp_lock(ppp);
    + if (ppp->pass_filter)
    + bpf_prog_destroy(ppp->pass_filter);
    + ppp->pass_filter = pass_filter;
    + ppp_unlock(ppp);
    }
    - if (fprog.filter != NULL)
    - err = bpf_prog_create(&ppp->pass_filter,
    - &fprog);
    - else
    - err = 0;
    kfree(code);
    - ppp_unlock(ppp);
    }
    break;
    }
    @@ -781,23 +781,23 @@ static long ppp_ioctl(struct file *file,

    err = get_filter(argp, &code);
    if (err >= 0) {
    + struct bpf_prog *active_filter = NULL;
    struct sock_fprog_kern fprog = {
    .len = err,
    .filter = code,
    };

    - ppp_lock(ppp);
    - if (ppp->active_filter) {
    - bpf_prog_destroy(ppp->active_filter);
    - ppp->active_filter = NULL;
    + err = 0;
    + if (fprog.filter)
    + err = bpf_prog_create(&active_filter, &fprog);
    + if (!err) {
    + ppp_lock(ppp);
    + if (ppp->active_filter)
    + bpf_prog_destroy(ppp->active_filter);
    + ppp->active_filter = active_filter;
    + ppp_unlock(ppp);
    }
    - if (fprog.filter != NULL)
    - err = bpf_prog_create(&ppp->active_filter,
    - &fprog);
    - else
    - err = 0;
    kfree(code);
    - ppp_unlock(ppp);
    }
    break;
    }



    \
     
     \ /
      Last update: 2014-11-20 00:21    [W:4.033 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site