On Sun, Jun 02, 2024 at 11:27:03AM -0700, Cong Wang wrote: > From: Cong Wang <cong.wang@xxxxxxxxxxxxx> > > After commit 1a80dbcb2dba, bpf_link can be freed by > link->ops->dealloc_deferred, but the code still tests and uses > link->ops->dealloc afterward, which leads to a use-after-free as > reported by syzbot. Actually, one of them should be sufficient, so > just call one of them instead of both. Also add a WARN_ON() in case > of any problematic implementation. > > Reported-by: syzbot+1989ee16d94720836244@xxxxxxxxxxxxxxxxxxxxxxxxx > Fixes: 1a80dbcb2dba ("bpf: support deferring bpf_link dealloc to after RCU grace period") > Cc: Andrii Nakryiko <andrii@xxxxxxxxxx> > Signed-off-by: Cong Wang <cong.wang@xxxxxxxxxxxxx> > --- > kernel/bpf/syscall.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c > index 2222c3ff88e7..d8f244069495 100644 > --- a/kernel/bpf/syscall.c > +++ b/kernel/bpf/syscall.c > @@ -2998,6 +2998,7 @@ static int bpf_obj_get(const union bpf_attr *attr) > void bpf_link_init(struct bpf_link *link, enum bpf_link_type type, > const struct bpf_link_ops *ops, struct bpf_prog *prog) > { > + WARN_ON(ops->dealloc && ops->dealloc_deferred); > atomic64_set(&link->refcnt, 1); > link->type = type; > link->id = 0; > @@ -3074,8 +3075,7 @@ static void bpf_link_free(struct bpf_link *link) > call_rcu_tasks_trace(&link->rcu, bpf_link_defer_dealloc_mult_rcu_gp); > else > call_rcu(&link->rcu, bpf_link_defer_dealloc_rcu_gp); > - } > - if (link->ops->dealloc) > + } else if (link->ops->dealloc) > link->ops->dealloc(link); nice catch Acked-by: Jiri Olsa <jolsa@xxxxxxxxxx> jirka