lkml.org 
[lkml]   [2021]   [Oct]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.14 25/40] net: prevent user from passing illegal stab size
    Date
    From: 王贇 <yun.wang@linux.alibaba.com>

    [ Upstream commit b193e15ac69d56f35e1d8e2b5d16cbd47764d053 ]

    We observed below report when playing with netlink sock:

    UBSAN: shift-out-of-bounds in net/sched/sch_api.c:580:10
    shift exponent 249 is too large for 32-bit type
    CPU: 0 PID: 685 Comm: a.out Not tainted
    Call Trace:
    dump_stack_lvl+0x8d/0xcf
    ubsan_epilogue+0xa/0x4e
    __ubsan_handle_shift_out_of_bounds+0x161/0x182
    __qdisc_calculate_pkt_len+0xf0/0x190
    __dev_queue_xmit+0x2ed/0x15b0

    it seems like kernel won't check the stab log value passing from
    user, and will use the insane value later to calculate pkt_len.

    This patch just add a check on the size/cell_log to avoid insane
    calculation.

    Reported-by: Abaci <abaci@linux.alibaba.com>
    Signed-off-by: Michael Wang <yun.wang@linux.alibaba.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/net/pkt_sched.h | 1 +
    net/sched/sch_api.c | 6 ++++++
    2 files changed, 7 insertions(+)

    diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
    index 6d7b12cba015..bf79f3a890af 100644
    --- a/include/net/pkt_sched.h
    +++ b/include/net/pkt_sched.h
    @@ -11,6 +11,7 @@
    #include <uapi/linux/pkt_sched.h>

    #define DEFAULT_TX_QUEUE_LEN 1000
    +#define STAB_SIZE_LOG_MAX 30

    struct qdisc_walker {
    int stop;
    diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
    index f87d07736a14..148edd0e71e3 100644
    --- a/net/sched/sch_api.c
    +++ b/net/sched/sch_api.c
    @@ -513,6 +513,12 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt,
    return stab;
    }

    + if (s->size_log > STAB_SIZE_LOG_MAX ||
    + s->cell_log > STAB_SIZE_LOG_MAX) {
    + NL_SET_ERR_MSG(extack, "Invalid logarithmic size of size table");
    + return ERR_PTR(-EINVAL);
    + }
    +
    stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL);
    if (!stab)
    return ERR_PTR(-ENOMEM);
    --
    2.33.0
    \
     
     \ /
      Last update: 2021-10-05 15:52    [W:4.043 / U:3.216 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site