Re: [PATCH bpf-next v3 1/3] bpf, sockmap: avoid using sk_socket after free when sending

From: Michal Luczaj
Date: Thu Mar 20 2025 - 08:35:02 EST


On 3/17/25 10:22, Jiayuan Chen wrote:
> The sk->sk_socket is not locked or referenced, and during the call to
> skb_send_sock(), there is a race condition with the release of sk_socket.
> All types of sockets(tcp/udp/unix/vsock) will be affected.
> ...
> Some approach I tried
> ...
> 2. Increased the reference of sk_socket->file:
> - If the user calls close(fd), we will do nothing because the reference
> count is not set to 0. It's unexpected.

Have you considered bumping file's refcnt only for the time of
send/callback? Along the lines of:

static struct file *sock_get_file(struct sock *sk)
{
struct file *file = NULL;
struct socket *sock;

rcu_read_lock();
sock = sk->sk_socket;
if (sock)
file = get_file_active(&sock->file);
rcu_read_unlock();

return file;
}

static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb,
u32 off, u32 len, bool ingress)
{
int err;

if (!ingress) {
struct sock *sk = psock->sk;
struct file *file;
...

file = sock_get_file(sk);
if (!file)
return -EIO;

err = skb_send_sock(sk, skb, off, len);
fput(file);
return err;
}
...
}

static void sk_psock_verdict_data_ready(struct sock *sk)
{
struct file *file;
...

file = sock_get_file(sk);
if (!file)
return;

copied = sk->sk_socket->ops->read_skb(sk, sk_psock_verdict_recv);
fput(file);
...
}