Skip to content

Commit 8574921

Browse files
arthurfabreAlexei Starovoitov
authored andcommitted
bpf: Fix out of bounds memory access in bpf_sk_storage
bpf_sk_storage maps use multiple spin locks to reduce contention. The number of locks to use is determined by the number of possible CPUs. With only 1 possible CPU, bucket_log == 0, and 2^0 = 1 locks are used. When updating elements, the correct lock is determined with hash_ptr(). Calling hash_ptr() with 0 bits is undefined behavior, as it does: x >> (64 - bits) Using the value results in an out of bounds memory access. In my case, this manifested itself as a page fault when raw_spin_lock_bh() is called later, when running the self tests: ./tools/testing/selftests/bpf/test_verifier 773 775 [ 16.366342] BUG: unable to handle page fault for address: ffff8fe7a66f93f8 Force the minimum number of locks to two. Signed-off-by: Arthur Fabre <[email protected]> Fixes: 6ac99e8 ("bpf: Introduce bpf sk local storage") Acked-by: Andrii Nakryiko <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent fe8d957 commit 8574921

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

net/core/bpf_sk_storage.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,8 @@ static struct bpf_map *bpf_sk_storage_map_alloc(union bpf_attr *attr)
633633
return ERR_PTR(-ENOMEM);
634634
bpf_map_init_from_attr(&smap->map, attr);
635635

636-
smap->bucket_log = ilog2(roundup_pow_of_two(num_possible_cpus()));
636+
/* Use at least 2 buckets, select_bucket() is undefined behavior with 1 bucket */
637+
smap->bucket_log = max_t(u32, 1, ilog2(roundup_pow_of_two(num_possible_cpus())));
637638
nbuckets = 1U << smap->bucket_log;
638639
smap->buckets = kvcalloc(sizeof(*smap->buckets), nbuckets,
639640
GFP_USER | __GFP_NOWARN);

0 commit comments

Comments
 (0)