Re: [PATCH v1] af_unix: fix use-after-free in unix_stream_recv_urg()

From: Kuniyuki Iwashima

Date: Thu Jul 30 2026 - 15:04:45 EST


On Tue, Jul 28, 2026 at 6:15 PM Muhammad Bilal <meatuni001@xxxxxxxxx> wrote:
>
> unix_stream_recv_urg() saves a bare pointer to the OOB skb and then
> drops sk_receive_queue.lock and unix_state_lock before accessing it
> at lines that call recv_actor() and update UNIXCB().consumed.
>
> After commit 8594d9b85c07 ("af_unix: Don't call skb_get() for OOB
> skb.") removed the extra reference count, oob_skb is just a pointer
> into the receive queue with no additional refcount protection.
>
> A concurrent close() via unix_release_sock() does not acquire u->iolock
> and can race as follows:
>
> 1. recv_urg() saves oob_skb pointer under queue lock
> 2. recv_urg() drops queue lock and state lock
> 3. unix_release_sock() sets u->oob_skb = NULL (locklessly)
> 4. unix_release_sock() drains receive queue, kfree_skb() frees oob_skb
> 5. recv_urg() accesses freed oob_skb via recv_actor() -> UAF
>
> Additionally, unix_release_sock() cleared u->oob_skb with a plain store
> outside any lock, which is a data race against READ_ONCE(u->oob_skb) in
> manage_oob() and unix_stream_poll() which expect all writers to use
> WRITE_ONCE() under sk_receive_queue.lock.
>
> Fix the UAF by taking skb_get() on oob_skb while holding the queue lock
> in unix_stream_recv_urg(), ensuring the skb survives until consume_skb()
> drops the extra reference after use.
>
> Fix the data race by clearing u->oob_skb in unix_release_sock() under
> sk_receive_queue.lock using WRITE_ONCE(), consistent with all other
> writers.
>
> Fixes: 8594d9b85c07 ("af_unix: Don't call skb_get() for OOB skb.")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Muhammad Bilal <meatuni001@xxxxxxxxx>

The patch seems duplicated.

---
pw-bot: cr