Skip to content

Commit

Permalink
skmsg: introduce sk_psock_get_checked()
Browse files Browse the repository at this point in the history
Although we have sk_psock_get(), it assumes the psock
retrieved from sk_user_data is for sockmap, this is not
sufficient if we call it outside of sockmap, for example,
reuseport_array.

Fortunately sock_map_psock_get_checked() is more strict
and checks for sock_map_close before using psock. So we can
refactor it and rename it to sk_psock_get_checked(), which
can be safely called outside of sockmap.

Cc: John Fastabend <john.fastabend@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Jakub Sitnicki <jakub@cloudflare.com>
Cc: Lorenz Bauer <lmb@cloudflare.com>
Signed-off-by: Cong Wang <cong.wang@bytedance.com>
  • Loading branch information
Cong Wang committed Sep 27, 2021
1 parent 2248c2f commit 2efd723
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 21 deletions.
20 changes: 20 additions & 0 deletions include/linux/skmsg.h
Expand Up @@ -452,6 +452,26 @@ static inline struct sk_psock *sk_psock_get(struct sock *sk)
return psock;
}

static inline struct sk_psock *sk_psock_get_checked(struct sock *sk)
{
struct sk_psock *psock;

rcu_read_lock();
psock = sk_psock(sk);
if (psock) {
if (sk->sk_prot->close != sock_map_close) {
psock = ERR_PTR(-EBUSY);
goto out;
}

if (!refcount_inc_not_zero(&psock->refcnt))
psock = ERR_PTR(-EBUSY);
}
out:
rcu_read_unlock();
return psock;
}

void sk_psock_drop(struct sock *sk, struct sk_psock *psock);

static inline void sk_psock_put(struct sock *sk, struct sk_psock *psock)
Expand Down
22 changes: 1 addition & 21 deletions net/core/sock_map.c
Expand Up @@ -191,26 +191,6 @@ static int sock_map_init_proto(struct sock *sk, struct sk_psock *psock)
return sk->sk_prot->psock_update_sk_prot(sk, psock, false);
}

static struct sk_psock *sock_map_psock_get_checked(struct sock *sk)
{
struct sk_psock *psock;

rcu_read_lock();
psock = sk_psock(sk);
if (psock) {
if (sk->sk_prot->close != sock_map_close) {
psock = ERR_PTR(-EBUSY);
goto out;
}

if (!refcount_inc_not_zero(&psock->refcnt))
psock = ERR_PTR(-EBUSY);
}
out:
rcu_read_unlock();
return psock;
}

static int sock_map_link(struct bpf_map *map, struct sock *sk)
{
struct sk_psock_progs *progs = sock_map_progs(map);
Expand Down Expand Up @@ -255,7 +235,7 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
}
}

psock = sock_map_psock_get_checked(sk);
psock = sk_psock_get_checked(sk);
if (IS_ERR(psock)) {
ret = PTR_ERR(psock);
goto out_progs;
Expand Down

0 comments on commit 2efd723

Please sign in to comment.