Skip to content

Commit 96b3b6c

Browse files
lmbborkmann
authored andcommitted
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: Lorenz Bauer <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 2349944 commit 96b3b6c

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

include/uapi/linux/bpf.h

+3
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ enum bpf_attach_type {
269269
/* Flag for stack_map, store build_id+offset instead of pointer */
270270
#define BPF_F_STACK_BUILD_ID (1U << 5)
271271

272+
/* Zero-initialize hash function seed. This should only be used for testing. */
273+
#define BPF_F_ZERO_SEED (1U << 6)
274+
272275
enum bpf_stack_build_id_status {
273276
/* user space need an empty entry to identify end of a trace */
274277
BPF_STACK_BUILD_ID_EMPTY = 0,

kernel/bpf/hashtab.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
#define HTAB_CREATE_FLAG_MASK \
2525
(BPF_F_NO_PREALLOC | BPF_F_NO_COMMON_LRU | BPF_F_NUMA_NODE | \
26-
BPF_F_RDONLY | BPF_F_WRONLY)
26+
BPF_F_RDONLY | BPF_F_WRONLY | BPF_F_ZERO_SEED)
2727

2828
struct bucket {
2929
struct hlist_nulls_head head;
@@ -244,6 +244,7 @@ static int htab_map_alloc_check(union bpf_attr *attr)
244244
*/
245245
bool percpu_lru = (attr->map_flags & BPF_F_NO_COMMON_LRU);
246246
bool prealloc = !(attr->map_flags & BPF_F_NO_PREALLOC);
247+
bool zero_seed = (attr->map_flags & BPF_F_ZERO_SEED);
247248
int numa_node = bpf_map_attr_numa_node(attr);
248249

249250
BUILD_BUG_ON(offsetof(struct htab_elem, htab) !=
@@ -257,6 +258,10 @@ static int htab_map_alloc_check(union bpf_attr *attr)
257258
*/
258259
return -EPERM;
259260

261+
if (zero_seed && !capable(CAP_SYS_ADMIN))
262+
/* Guard against local DoS, and discourage production use. */
263+
return -EPERM;
264+
260265
if (attr->map_flags & ~HTAB_CREATE_FLAG_MASK)
261266
/* reserved bits should not be used */
262267
return -EINVAL;
@@ -373,7 +378,11 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
373378
if (!htab->buckets)
374379
goto free_htab;
375380

376-
htab->hashrnd = get_random_int();
381+
if (htab->map.map_flags & BPF_F_ZERO_SEED)
382+
htab->hashrnd = 0;
383+
else
384+
htab->hashrnd = get_random_int();
385+
377386
for (i = 0; i < htab->n_buckets; i++) {
378387
INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i);
379388
raw_spin_lock_init(&htab->buckets[i].lock);

0 commit comments

Comments
 (0)