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);
        ...
}


Reply via email to