bpf: sockmap: Allow update from BPF
authorLorenz Bauer <lmb@cloudflare.com>
Fri, 21 Aug 2020 10:29:47 +0000 (11:29 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 21 Aug 2020 22:16:12 +0000 (15:16 -0700)
commit0126240f448d5bba29d0d1593aa527d3bf67b916
tree04bc8ea13709d775a46afe969872e703ebdedd4b
parent912f442cfb1fc695510e055bdae5f4a88e4de6b8
bpf: sockmap: Allow update from BPF

Allow calling bpf_map_update_elem on sockmap and sockhash from a BPF
context. The synchronization required for this is a bit fiddly: we
need to prevent the socket from changing its state while we add it
to the sockmap, since we rely on getting a callback via
sk_prot->unhash. However, we can't just lock_sock like in
sock_map_sk_acquire because that might sleep. So instead we disable
softirq processing and use bh_lock_sock to prevent further
modification.

Yet, this is still not enough. BPF can be called in contexts where
the current CPU might have locked a socket. If the BPF can get
a hold of such a socket, inserting it into a sockmap would lead to
a deadlock. One straight forward example are sock_ops programs that
have ctx->sk, but the same problem exists for kprobes, etc.
We deal with this by allowing sockmap updates only from known safe
contexts. Improper usage is rejected by the verifier.

I've audited the enabled contexts to make sure they can't run in
a locked context. It's possible that CGROUP_SKB and others are
safe as well, but the auditing here is much more difficult. In
any case, we can extend the safe contexts when the need arises.

Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20200821102948.21918-6-lmb@cloudflare.com
kernel/bpf/verifier.c
net/core/sock_map.c