lkml.org 
[lkml]   [2022]   [May]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH bpf v4 1/3] bpf_trace: check size for overflow in bpf_kprobe_multi_link_attach
    Check that size would not overflow before calculation (and return
    -EOVERFLOW if it will), to prevent potential out-of-bounds write
    with the following copy_from_user. Add the same check
    to kprobe_multi_resolve_syms in case it will be called from elsewhere
    in the future. The INT_MAX checks are performed in order to avoid
    triggering kvmalloc_node warning [1].

    [1] https://lore.kernel.org/lkml/cfe6abea-8d00-8f8c-f84c-e6f27753b5d1@fb.com/

    Fixes: 0dcac272540613d4 ("bpf: Add multi kprobe link")
    Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
    ---
    kernel/trace/bpf_trace.c | 13 ++++++++-----
    1 file changed, 8 insertions(+), 5 deletions(-)

    diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
    index d8553f4..26cf99c 100644
    --- a/kernel/trace/bpf_trace.c
    +++ b/kernel/trace/bpf_trace.c
    @@ -2352,13 +2352,15 @@ static int
    kprobe_multi_resolve_syms(const void __user *usyms, u32 cnt,
    unsigned long *addrs)
    {
    - unsigned long addr, size;
    + unsigned long addr, sym_size;
    + u32 size;
    const char __user **syms;
    int err = -ENOMEM;
    unsigned int i;
    char *func;

    - size = cnt * sizeof(*syms);
    + if (check_mul_overflow(cnt, (u32)sizeof(*syms), &size) || size > INT_MAX)
    + return -EOVERFLOW;
    syms = kvzalloc(size, GFP_KERNEL);
    if (!syms)
    return -ENOMEM;
    @@ -2382,9 +2384,9 @@ kprobe_multi_resolve_syms(const void __user *usyms, u32 cnt,
    addr = kallsyms_lookup_name(func);
    if (!addr)
    goto error;
    - if (!kallsyms_lookup_size_offset(addr, &size, NULL))
    + if (!kallsyms_lookup_size_offset(addr, &sym_size, NULL))
    goto error;
    - addr = ftrace_location_range(addr, addr + size - 1);
    + addr = ftrace_location_range(addr, addr + sym_size - 1);
    if (!addr)
    goto error;
    addrs[i] = addr;
    @@ -2429,7 +2431,8 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
    if (!cnt)
    return -EINVAL;

    - size = cnt * sizeof(*addrs);
    + if (check_mul_overflow(cnt, (u32)sizeof(*addrs), &size) || size > INT_MAX)
    + return -EOVERFLOW;
    addrs = kvmalloc(size, GFP_KERNEL);
    if (!addrs)
    return -ENOMEM;
    --
    2.1.4
    \
     
     \ /
      Last update: 2022-05-19 20:16    [W:3.102 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site