Merge branch 'bpf: fix a bpf_timer initialization issue'

Yonghong Song says:

====================

The patch [1] exposed a bpf_timer initialization bug in function
check_and_init_map_value(). With bug fix here, the patch [1]
can be applied with all selftests passed. Please see individual
patches for fix details.

  [1] https://lore.kernel.org/bpf/20220209070324.1093182-2-memxor@gmail.com/

Changelog:
  v3 -> v4:
    . move header file in patch #1 to avoid bpf-next merge conflict
  v2 -> v3:
    . switch patch #1 and patch #2 for better bisecting
  v1 -> v2:
    . add Fixes tag for patch #1
    . rebase against bpf tree
====================

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Alexei Starovoitov 2022-02-11 13:21:47 -08:00
commit 3df9d80316
2 changed files with 4 additions and 4 deletions

View File

@ -209,11 +209,9 @@ static inline bool map_value_has_timer(const struct bpf_map *map)
static inline void check_and_init_map_value(struct bpf_map *map, void *dst) static inline void check_and_init_map_value(struct bpf_map *map, void *dst)
{ {
if (unlikely(map_value_has_spin_lock(map))) if (unlikely(map_value_has_spin_lock(map)))
*(struct bpf_spin_lock *)(dst + map->spin_lock_off) = memset(dst + map->spin_lock_off, 0, sizeof(struct bpf_spin_lock));
(struct bpf_spin_lock){};
if (unlikely(map_value_has_timer(map))) if (unlikely(map_value_has_timer(map)))
*(struct bpf_timer *)(dst + map->timer_off) = memset(dst + map->timer_off, 0, sizeof(struct bpf_timer));
(struct bpf_timer){};
} }
/* copy everything but bpf_spin_lock and bpf_timer. There could be one of each. */ /* copy everything but bpf_spin_lock and bpf_timer. There could be one of each. */

View File

@ -2,6 +2,7 @@
/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
*/ */
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/btf.h>
#include <linux/bpf-cgroup.h> #include <linux/bpf-cgroup.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/random.h> #include <linux/random.h>
@ -1075,6 +1076,7 @@ static enum hrtimer_restart bpf_timer_cb(struct hrtimer *hrtimer)
void *key; void *key;
u32 idx; u32 idx;
BTF_TYPE_EMIT(struct bpf_timer);
callback_fn = rcu_dereference_check(t->callback_fn, rcu_read_lock_bh_held()); callback_fn = rcu_dereference_check(t->callback_fn, rcu_read_lock_bh_held());
if (!callback_fn) if (!callback_fn)
goto out; goto out;