OSDN Git Service

bpf: Introduce kptr_rcu.
authorAlexei Starovoitov <ast@kernel.org>
Fri, 3 Mar 2023 04:14:43 +0000 (20:14 -0800)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 3 Mar 2023 16:42:20 +0000 (17:42 +0100)
commit20c09d92faeefb8536f705d3a4629e0dc314c8a1
treef68b08f9877e6905e1bbcaf90ec85d52bc83cc8e
parent8d093b4e95a2a16a2cfcd36869b348a17112fabe
bpf: Introduce kptr_rcu.

The life time of certain kernel structures like 'struct cgroup' is protected by RCU.
Hence it's safe to dereference them directly from __kptr tagged pointers in bpf maps.
The resulting pointer is MEM_RCU and can be passed to kfuncs that expect KF_RCU.
Derefrence of other kptr-s returns PTR_UNTRUSTED.

For example:
struct map_value {
   struct cgroup __kptr *cgrp;
};

SEC("tp_btf/cgroup_mkdir")
int BPF_PROG(test_cgrp_get_ancestors, struct cgroup *cgrp_arg, const char *path)
{
  struct cgroup *cg, *cg2;

  cg = bpf_cgroup_acquire(cgrp_arg); // cg is PTR_TRUSTED and ref_obj_id > 0
  bpf_kptr_xchg(&v->cgrp, cg);

  cg2 = v->cgrp; // This is new feature introduced by this patch.
  // cg2 is PTR_MAYBE_NULL | MEM_RCU.
  // When cg2 != NULL, it's a valid cgroup, but its percpu_ref could be zero

  if (cg2)
    bpf_cgroup_ancestor(cg2, level); // safe to do.
}

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: David Vernet <void@manifault.com>
Link: https://lore.kernel.org/bpf/20230303041446.3630-4-alexei.starovoitov@gmail.com
Documentation/bpf/kfuncs.rst
include/linux/btf.h
kernel/bpf/helpers.c
kernel/bpf/verifier.c
net/bpf/test_run.c
tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c
tools/testing/selftests/bpf/progs/map_kptr_fail.c
tools/testing/selftests/bpf/verifier/calls.c
tools/testing/selftests/bpf/verifier/map_kptr.c