CVE-2024-36904 - Linux Kernel Use-After-Free Vulnerability in tcp_twsk_unique()

The Linux Kernel has recently addressed a use-after-free vulnerability in the tcp_twsk_unique() function. This vulnerability was reported by Anderson Nascimento who provided an in-depth analysis of the issue.

The Problem

The vulnerability originates from the commit ec94c2696fb ("tcp/dccp: avoid one atomic operation for timewait hashdance"). Since this commit, inet_twsk_hashdance() sets the TIME-WAIT socket's sk_refcnt after putting it into ehash and releasing the bucket lock. This creates a small race window where other threads could try to reuse the port during connect() and call sock_hold() in tcp_twsk_unique() for the TIME-WAIT socket with a zero refcnt.

If this situation occurs, the refcnt that is taken by tcp_twsk_unique() is overwritten and sock_put() will cause an underflow, ultimately triggering a real use-after-free issue somewhere else.

The Solution

To avoid the use-after-free problem, we need to use refcount_inc_not_zero() in tcp_twsk_unique() and give up on reusing the port if it returns false.

The following is a code snippet from the Linux Kernel patch that implements this fix

static bool tcp_twsk_unique(struct sock *sk, struct sock *ssk, __u16 port,
                    bool *first, bool *second)
{
        struct inet_timewait_sock *tw = inet_twsk(ssk);
        bool reuse_port;
        bool inc_refcnt;

        if (!tw)
                return false;

        *first = false;
        *second = false;

        inc_refcnt = refcount_inc_not_zero(&ssk->sk_refcnt);

        if (!refcount_read(&tw->tw_refcnt))
                reuse_port = true;
        else
                reuse_port = tcp_bind_conflict(sk, inet_twsk(sk)->tw_tb);

        if (!reuse_port && inc_refcnt)
                sock_put(ssk);

        return reuse_port;
}

On their analysis report, Anderson Nascimento documented the vulnerability, which presents the following warning message:

refcount_t: addition on ; use-after-free.
WARNING: CPU:  PID: 1039313 at lib/refcount.c:25 refcount_warn_saturate+xe5/x110
CPU:  PID: 1039313 Comm: trigger Not tainted 6.8.6-200.fc39.x86_64 #1
[...]
</TASK>

In conclusion, this use-after-free vulnerability in the Linux Kernel has been resolved by using refcount_inc_not_zero() in the tcp_twsk_unique() function. Adopting this approach prevents the underflow issue from occurring and mitigates the risk of a real use-after-free situation elsewhere in the Linux Kernel.

Timeline

Published on: 05/30/2024 16:15:13 UTC
Last modified on: 06/27/2024 13:16:00 UTC