RE: [PATCH net v2] tipc: clear sock->sk on the failed-insert path in tipc_sk_create()
From: Tung Quang Nguyen
Date: Tue Jul 14 2026 - 05:37:15 EST
>Subject: [PATCH net v2] tipc: clear sock->sk on the failed-insert path in
>tipc_sk_create()
>
>When tipc_sk_create() fails to insert the new socket (tipc_sk_insert() returns
>non-zero), its error path frees the sk with sk_free() but leaves
>sock->sk pointing at the freed object:
>
> if (tipc_sk_insert(tsk)) {
> sk_free(sk);
> pr_warn("Socket create failed; port number exhausted\n");
> return -EINVAL;
> }
>
>This is harmless for plain socket(): the syscall layer clears sock->ops before
>releasing, so tipc_release() is never called. It is not harmless on the accept()
>path. tipc_accept() creates the pre-allocated child socket with
>tipc_sk_create(net, new_sock, 0, kern); on failure it leaves new_sock->sk
>dangling and new_sock->ops non-NULL, and do_accept() then fput()s the new
>file, so __sock_release() -> tipc_release() runs
>lock_sock(new_sock->sk) on the freed sk -- a use-after-free write of the sk_lock
>spinlock.
>
>tipc_release() already guards this exact "failed accept() releases a pre-allocated
>child" case with "if (sk == NULL) return 0;", but the guard is bypassed because
>tipc_sk_create() left sock->sk non-NULL
>(dangling) rather than NULL.
>
>Clear sock->sk on the failed-insert path so the existing tipc_release() NULL
>check fires and the use-after-free is avoided.
Reviewed-by: Tung Nguyen <tung.quang.nguyen@xxxxxxxx>