Commit 96b3b6c9 authored by Lorenz Bauer's avatar Lorenz Bauer Committed by Daniel Borkmann

bpf: allow zero-initializing hash map seed

Add a new flag BPF_F_ZERO_SEED, which forces a hash map
to initialize the seed to zero. This is useful when doing
performance analysis both on individual BPF programs, as
well as the kernel's hash table implementation.
Signed-off-by: default avatarLorenz Bauer <lmb@cloudflare.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 23499442
...@@ -269,6 +269,9 @@ enum bpf_attach_type { ...@@ -269,6 +269,9 @@ enum bpf_attach_type {
/* Flag for stack_map, store build_id+offset instead of pointer */ /* Flag for stack_map, store build_id+offset instead of pointer */
#define BPF_F_STACK_BUILD_ID (1U << 5) #define BPF_F_STACK_BUILD_ID (1U << 5)
/* Zero-initialize hash function seed. This should only be used for testing. */
#define BPF_F_ZERO_SEED (1U << 6)
enum bpf_stack_build_id_status { enum bpf_stack_build_id_status {
/* user space need an empty entry to identify end of a trace */ /* user space need an empty entry to identify end of a trace */
BPF_STACK_BUILD_ID_EMPTY = 0, BPF_STACK_BUILD_ID_EMPTY = 0,
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#define HTAB_CREATE_FLAG_MASK \ #define HTAB_CREATE_FLAG_MASK \
(BPF_F_NO_PREALLOC | BPF_F_NO_COMMON_LRU | BPF_F_NUMA_NODE | \ (BPF_F_NO_PREALLOC | BPF_F_NO_COMMON_LRU | BPF_F_NUMA_NODE | \
BPF_F_RDONLY | BPF_F_WRONLY) BPF_F_RDONLY | BPF_F_WRONLY | BPF_F_ZERO_SEED)
struct bucket { struct bucket {
struct hlist_nulls_head head; struct hlist_nulls_head head;
...@@ -244,6 +244,7 @@ static int htab_map_alloc_check(union bpf_attr *attr) ...@@ -244,6 +244,7 @@ static int htab_map_alloc_check(union bpf_attr *attr)
*/ */
bool percpu_lru = (attr->map_flags & BPF_F_NO_COMMON_LRU); bool percpu_lru = (attr->map_flags & BPF_F_NO_COMMON_LRU);
bool prealloc = !(attr->map_flags & BPF_F_NO_PREALLOC); bool prealloc = !(attr->map_flags & BPF_F_NO_PREALLOC);
bool zero_seed = (attr->map_flags & BPF_F_ZERO_SEED);
int numa_node = bpf_map_attr_numa_node(attr); int numa_node = bpf_map_attr_numa_node(attr);
BUILD_BUG_ON(offsetof(struct htab_elem, htab) != BUILD_BUG_ON(offsetof(struct htab_elem, htab) !=
...@@ -257,6 +258,10 @@ static int htab_map_alloc_check(union bpf_attr *attr) ...@@ -257,6 +258,10 @@ static int htab_map_alloc_check(union bpf_attr *attr)
*/ */
return -EPERM; return -EPERM;
if (zero_seed && !capable(CAP_SYS_ADMIN))
/* Guard against local DoS, and discourage production use. */
return -EPERM;
if (attr->map_flags & ~HTAB_CREATE_FLAG_MASK) if (attr->map_flags & ~HTAB_CREATE_FLAG_MASK)
/* reserved bits should not be used */ /* reserved bits should not be used */
return -EINVAL; return -EINVAL;
...@@ -373,7 +378,11 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) ...@@ -373,7 +378,11 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
if (!htab->buckets) if (!htab->buckets)
goto free_htab; goto free_htab;
htab->hashrnd = get_random_int(); if (htab->map.map_flags & BPF_F_ZERO_SEED)
htab->hashrnd = 0;
else
htab->hashrnd = get_random_int();
for (i = 0; i < htab->n_buckets; i++) { for (i = 0; i < htab->n_buckets; i++) {
INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i); INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i);
raw_spin_lock_init(&htab->buckets[i].lock); raw_spin_lock_init(&htab->buckets[i].lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment