bpf: sockmap only allow ESTABLISHED sock state
After this patch we only allow socks that are in ESTABLISHED state or
are being added via a sock_ops event that is transitioning into an
ESTABLISHED state. By allowing sock_ops events we allow users to
manage sockmaps directly from sock ops programs. The two supported
sock_ops ops are BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB and
BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB.
Similar to TLS ULP this ensures sk_user_data is correct.
Reported-by: Eric Dumazet <edumazet@google.com>
Fixes: 1aa12bdf1b
("bpf: sockmap, add sock close() hook to remove socks")
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
parent
080220b687
commit
5607fff303
1 changed files with 30 additions and 1 deletions
|
@ -2097,8 +2097,12 @@ static int sock_map_update_elem(struct bpf_map *map,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* ULPs are currently supported only for TCP sockets in ESTABLISHED
|
||||
* state.
|
||||
*/
|
||||
if (skops.sk->sk_type != SOCK_STREAM ||
|
||||
skops.sk->sk_protocol != IPPROTO_TCP) {
|
||||
skops.sk->sk_protocol != IPPROTO_TCP ||
|
||||
skops.sk->sk_state != TCP_ESTABLISHED) {
|
||||
fput(socket->file);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
@ -2453,6 +2457,16 @@ static int sock_hash_update_elem(struct bpf_map *map,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* ULPs are currently supported only for TCP sockets in ESTABLISHED
|
||||
* state.
|
||||
*/
|
||||
if (skops.sk->sk_type != SOCK_STREAM ||
|
||||
skops.sk->sk_protocol != IPPROTO_TCP ||
|
||||
skops.sk->sk_state != TCP_ESTABLISHED) {
|
||||
fput(socket->file);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
lock_sock(skops.sk);
|
||||
preempt_disable();
|
||||
rcu_read_lock();
|
||||
|
@ -2543,10 +2557,22 @@ const struct bpf_map_ops sock_hash_ops = {
|
|||
.map_check_btf = map_check_no_btf,
|
||||
};
|
||||
|
||||
static bool bpf_is_valid_sock_op(struct bpf_sock_ops_kern *ops)
|
||||
{
|
||||
return ops->op == BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB ||
|
||||
ops->op == BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB;
|
||||
}
|
||||
BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock,
|
||||
struct bpf_map *, map, void *, key, u64, flags)
|
||||
{
|
||||
WARN_ON_ONCE(!rcu_read_lock_held());
|
||||
|
||||
/* ULPs are currently supported only for TCP sockets in ESTABLISHED
|
||||
* state. This checks that the sock ops triggering the update is
|
||||
* one indicating we are (or will be soon) in an ESTABLISHED state.
|
||||
*/
|
||||
if (!bpf_is_valid_sock_op(bpf_sock))
|
||||
return -EOPNOTSUPP;
|
||||
return sock_map_ctx_update_elem(bpf_sock, map, key, flags);
|
||||
}
|
||||
|
||||
|
@ -2565,6 +2591,9 @@ BPF_CALL_4(bpf_sock_hash_update, struct bpf_sock_ops_kern *, bpf_sock,
|
|||
struct bpf_map *, map, void *, key, u64, flags)
|
||||
{
|
||||
WARN_ON_ONCE(!rcu_read_lock_held());
|
||||
|
||||
if (!bpf_is_valid_sock_op(bpf_sock))
|
||||
return -EOPNOTSUPP;
|
||||
return sock_hash_ctx_update_elem(bpf_sock, map, key, flags);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue