From patchwork Sat Nov 19 23:16:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kirill Tkhai X-Patchwork-Id: 13049873 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 755D4C433FE for ; Sat, 19 Nov 2022 23:23:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234785AbiKSXW7 (ORCPT ); Sat, 19 Nov 2022 18:22:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234167AbiKSXW6 (ORCPT ); Sat, 19 Nov 2022 18:22:58 -0500 X-Greylist: delayed 366 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Sat, 19 Nov 2022 15:22:56 PST Received: from forward103j.mail.yandex.net (forward103j.mail.yandex.net [IPv6:2a02:6b8:0:801:2::106]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C2C11A222 for ; Sat, 19 Nov 2022 15:22:56 -0800 (PST) Received: from sas1-37da021029ee.qloud-c.yandex.net (sas1-37da021029ee.qloud-c.yandex.net [IPv6:2a02:6b8:c08:1612:0:640:37da:210]) by forward103j.mail.yandex.net (Yandex) with ESMTP id C03F2101106; Sun, 20 Nov 2022 02:16:48 +0300 (MSK) Received: by sas1-37da021029ee.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id mVpumYQ42L-GlVC0qr7; Sun, 20 Nov 2022 02:16:48 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ya.ru; s=mail; t=1668899808; bh=yd/fkg+OYJTlFcvY7y3spR3kjjO29FukjCfBxfmVrp4=; h=To:Subject:From:Date:Message-ID; b=quXUOdZM4qkI/s87noA9km9BhPeiJtPl5x07lsIp4zsM/5urdr5AOO509mTvN4i+Q BkTpBaGfBSG6pylApZnCkEls4Q8YmakGRQhDNnR+GlUKPXe6ZMDWaFiJ2PzL5eKxkI MOJR5vYSvH8ZmW5wrdhLL1TeF9ybr4hSykIUDhQI= Authentication-Results: sas1-37da021029ee.qloud-c.yandex.net; dkim=pass header.i=@ya.ru Message-ID: <38a920a7-cfba-7929-886d-c3c6effc0c43@ya.ru> Date: Sun, 20 Nov 2022 02:16:47 +0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.5.0 From: Kirill Tkhai Subject: [PATCH net] unix: Fix race in SOCK_SEQPACKET's unix_dgram_sendmsg() To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, tkhai@ya.ru Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org There is a race resulting in alive SOCK_SEQPACKET socket may change its state from TCP_ESTABLISHED to TCP_CLOSE: unix_release_sock(peer) unix_dgram_sendmsg(sk) sock_orphan(peer) sock_set_flag(peer, SOCK_DEAD) sock_alloc_send_pskb() if !(sk->sk_shutdown & SEND_SHUTDOWN) OK if sock_flag(peer, SOCK_DEAD) sk->sk_state = TCP_CLOSE sk->sk_shutdown = SHUTDOWN_MASK After that socket sk remains almost normal: it is able to connect, listen, accept and recvmsg, while it can't sendmsg. Since this is the only possibility for alive SOCK_SEQPACKET to change the state in such way, we should better fix this strange and potentially danger corner case. Also, move TCP_CLOSE assignment for SOCK_DGRAM sockets under state lock. Signed-off-by: Kirill Tkhai --- net/unix/af_unix.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index b3545fc68097..6fd745cfc492 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1999,13 +1999,20 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, unix_state_lock(sk); err = 0; - if (unix_peer(sk) == other) { + if (sk->sk_type == SOCK_SEQPACKET) { + /* We are here only when racing with unix_release_sock() + * is clearing @other. Never change state to TCP_CLOSE + * unlike SOCK_DGRAM wants. + */ + unix_state_unlock(sk); + err = -EPIPE; + } else if (unix_peer(sk) == other) { unix_peer(sk) = NULL; unix_dgram_peer_wake_disconnect_wakeup(sk, other); + sk->sk_state = TCP_CLOSE; unix_state_unlock(sk); - sk->sk_state = TCP_CLOSE; unix_dgram_disconnected(sk, other); sock_put(other); err = -ECONNREFUSED;