From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC7CB3E49F2 for ; Fri, 31 Jul 2026 10:19:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785493204; cv=none; b=e1X82P/mLmEymf6+inHMZPIjwJ2YWaGpmTGY6vUyt1RMn62pZRfBa12sv++jiDewBanPGbhmHNKL3nmDGTB8z7CiXZmgAZ62VTQipQ6mTC1cpZqhe8zN3I7rLa7Pu/Dm2x+rp6gv8o/kGReEylLA6IYPan/Rp2C404Hs6d/FzyE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785493204; c=relaxed/simple; bh=qvFaAifF1fTntockERUiok0vYuoGWsDv7nbDVki6Dfo=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=IhsmtnKNMIH50yssVC/2FGEnaNGde2ywkNArukUJLe7Cd5xxdOE0crDe5lfK5U+YJri8uhyNWuKmEbO54+EPKNQTITtxSgF2WWB0GZWWtXtOkoZJQt3OOrGJBCPrV9+GlMKmcEERwSQifvoses2sEpFFIw8W3NWG6Z+Nr45NxxE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CglkFJB/; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CglkFJB/" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-2cf452def93so13352385ad.1 for ; Fri, 31 Jul 2026 03:19:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785493178; x=1786097978; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=7Fm4l+XBZNPZNokjVv0ih44ynafzkizelSQk/oJzlO0=; b=CglkFJB/GxvX4e/1aF4Mpd0iwKY3Vq7OTMFELuFevahYoCiyraszZplWdZkGFw6A7V Y6ABvQR3y3SJTS0yupHhle9Pzwa/cEc3s4mgDl3Cl3Fdj4LZr2vHrpTwGWcf5QUwaGHI jf4MAl8zoUFoSbe4FvnZxetlOvNKyR0dYuAYX0JAOLgztSP3Mmeq7F5pQ5VrU3DI/SNK 7anZrPR+HSqmmuQTnteMxSRVOwVkRXkG5aiCKaqVKHgGk75zYz+7/DZz+KXo84Xv+2Qj yZaYGiirlbWmzq3YvrXxUXVHQ6DAy2YtyV3t5Tu7JHvZv6z6SHnwXo7o6fdUYLspkB87 +pvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785493178; x=1786097978; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=7Fm4l+XBZNPZNokjVv0ih44ynafzkizelSQk/oJzlO0=; b=NMpoZYtoB0qnucTlSVShFheHi/h1Wh8tZCo/3C7VmbH1TgJOhyveseWtXgyJl0acDT DgCNgVzd5jqCt6bibYIO8UjSoBkhihQjZLIlW6hE6RT/bhQaA9odrKCWMy2o4m9L95zt Mn8ovt2C40VvtD3yN971Gyd/oGXCBlP5y9GsIutFDn2EQrSOHSwe3PrIY+IUReoiHiZB C/EuVGYzrwfpmTRpWD+I3XSF3gMMamhNnuiY2mjcyqOWG3FLdmEbH7HykDqm5cpHgJTT WsD51pH+iSkaeCFEA8BmRuMpI8FQkYq2pYn9loN3f6VopODqiwUx6FKvk24ZTtbtl7Fk wciQ== X-Forwarded-Encrypted: i=1; AHgh+RrV9d3KgA7NbB/ZEBdbLAMEuoZ+KKVXk754Z0uXzhfQUFptmVjKfukIB6htuUfs/jmwy3HjfPEK/r+uqCs=@vger.kernel.org X-Gm-Message-State: AOJu0YxHu3pxK9tazqm/mbyRd8V5YyUEehthbp8yk+XHaHMErgoTSwcK 0KYdSoyMoYMRZ+kXoCRARpB3JCK89Rx08eZ1dW1zvtphVSbhwoj1fZIH X-Gm-Gg: AR+sD138YF4Pv0xhFeAuO9HFBAclPFPg8H3veqYp9nMJWkJ3mwc6X6QSDgi0e3TYwQA 8HHI5bHbmgKLjQHtxBE/ceTTOV5pXyk1B3/km/btaCLQMHqK8Qqlyz+urC7YD/fVs7NDlu0uLus LANwWq8P9Y9cHOaChXKmN4N5ysHnnA0FCPyiqCJQ5zhaHHUF/M5CKSphvGvjhKE4o4wmnG6GYvn WehnO1ewL2Ui8ZBMWo8KaJObF7Csu/ZrkiTGvEG3m2rvEMkPrcE4/ZeZyNIY4xvIxuVRnbzid1e KUkiTPCyXvxJYsr1mBG68ilg0NNyWix7rYBsValMf5lxV0ayR3oQxG/BYUiPBK3Mk4H8XccCB8e yaLmDS18Jkf78CzjWjNpM45FOcmHNOGXf/8jwlZtr+4n8UtoClWtf/YTFzn+RB9C0QpN+ywk0YK nO5OE6stDpcau5TEobp8QjSLKtBZlbM9A3uizH/ENEJ6OLr41udafjZSd1ennkAJ+AH9bPK3AyG whmeuolbXYs59BKgd198XRJ8wc= X-Received: by 2002:a17:90b:3c8e:b0:37f:d265:18d2 with SMTP id 98e67ed59e1d1-38fb2b0dfa6mr945985a91.7.1785493177965; Fri, 31 Jul 2026 03:19:37 -0700 (PDT) Received: from JUNVYYANG-MC1.tencent.com ([43.132.141.25]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-38fb2afa8f3sm261162a91.2.2026.07.31.03.19.35 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Fri, 31 Jul 2026 03:19:37 -0700 (PDT) From: Jun Yang To: netdev@vger.kernel.org Cc: Jun Yang , stable@kernel.org, TencentOS Corvus AI , Jon Maloy , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Ying Xue , Parthasarathy Bhuvaragan , tipc-discussion@lists.sourceforge.net, linux-kernel@vger.kernel.org Subject: [PATCH net] tipc: purge cong_links under the socket lock in tipc_release() Date: Fri, 31 Jul 2026 18:18:52 +0800 Message-ID: <20260731101926.31514-1-juny24602@gmail.com> X-Mailer: git-send-email 2.50.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Jun Yang tipc_release() frees the elements of tsk->cong_links after release_sock(), i.e. with no lock held: tipc_sk_remove(tsk); sock_orphan(sk); release_sock(sk); tipc_dest_list_purge(&tsk->cong_links); /* no lock */ tsk->cong_link_cnt = 0; Every other accessor of that list runs under the socket lock, including the SOCK_WAKEUP handler in tipc_sk_proto_rcv(), which does tipc_dest_del(&tsk->cong_links, ...) while holding only sk->sk_lock.slock via tipc_sk_rcv()'s spin_trylock_bh(). Because the purge never acquires that spinlock, it provides no mutual exclusion against the wakeup path. A SOCK_WAKEUP delivered for this port can therefore run concurrently with the purge: tipc_sk_rcv() looks the socket up and takes a reference before tipc_sk_remove() unhashes it, is then delayed past release_sock() so sock_owned_by_user() is false, its spin_trylock_bh() succeeds, and it list_del()s and kfree()s a struct tipc_dest that the closing task is walking at the same time. Both paths free entries of the same list. __tipc_shutdown() does not close this window: it waits on !tsk->cong_link_cnt but ignores the return value of tipc_wait_for_cond(), which returns early on timeout, on a pending signal, or on sk_err, so the close can proceed with cong_links still populated. BUG: KASAN: slab-use-after-free in __list_del_entry_valid_or_report+0x1ce/0x280 Read of size 8 at addr ffff888105ddda88 by task poc_cong_race/7856 __list_del_entry_valid_or_report+0x1ce/0x280 tipc_dest_list_purge+0xad/0x240 tipc_release+0x9a5/0x1340 Allocated by task 7856: tipc_dest_push+0x11c/0x2f0 __tipc_sendmsg+0x1443/0x17a0 Freed by task 7851: tipc_dest_del+0x1ce/0x280 tipc_sk_filter_rcv+0x1da7/0x2e70 tipc_sk_rcv+0xdaa/0x1a80 tipc_udp_recv+0x42a/0x7e0 Oops: general protection fault ... Kernel panic - not syncing: Fatal exception Move the purge above release_sock() so it runs under the socket lock, the same discipline commit 844cf763fba6 ("tipc: make macro tipc_wait_for_cond() smp safe") established for the wait condition. A concurrent tipc_sk_rcv() then either backlogs the wakeup because the socket is owned, or processes it against an already empty list, and no new delivery can arrive because tipc_sk_remove() has already unhashed the socket. Fixes: 365ad353c256 ("tipc: reduce risk of user starvation during link congestion") Cc: stable@kernel.org Reported-by: TencentOS Corvus AI Signed-off-by: Jun Yang --- net/tipc/socket.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index d5d70eb230b5..9b45b16d0a31 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -647,11 +647,17 @@ static int tipc_release(struct socket *sock) sk_stop_timer(sk, &sk->sk_timer); tipc_sk_remove(tsk); + /* Purge under the socket lock: a straggler SOCK_WAKEUP that looked the + * socket up before tipc_sk_remove() can still reach tipc_dest_del() on + * this list, and it only holds the socket spinlock. Purging after + * release_sock() would race that list_del()/kfree(). + */ + tipc_dest_list_purge(&tsk->cong_links); + tsk->cong_link_cnt = 0; + sock_orphan(sk); /* Reject any messages that accumulated in backlog queue */ release_sock(sk); - tipc_dest_list_purge(&tsk->cong_links); - tsk->cong_link_cnt = 0; call_rcu(&tsk->rcu, tipc_sk_callback); sock->sk = NULL; -- 2.55.0