From nobody Mon Jul 08 16:10:58 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4WHpyB2dd5z5Q33F; Mon, 08 Jul 2024 16:10:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4WHpyB1SDBz463M; Mon, 8 Jul 2024 16:10:58 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1720455058; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qEyJx4xCu9rjO/11Mm0BGaezCjWMbEZizPybtLpCFA0=; b=pti1cprRWuFJ0hI0u4qssver0MPQ9Rcvg8G3hHVZWxUtxzjbsJIoTbPZXzuYLHZi679qMl 9Bk3CSW1EDD9j2VKuAaQ4sMGcbSpHWAj14YsrEcL9N3Hd8rNEmmUqXbG+EaAz7EWMM9diw 6tBL71/Q67kkeRrPOGyTNvvQmkmvRvOEHYfhdeGvdynPz/tgQujDvv43/AVNeFLwbRatrd 6QRuQTW3Ger4aTfXml7/dG/A7gUPup3ee1GwHsu6dI919LFpWCKBiwOnGCslmOopeZWzsY PV02fr3RLqGgipGSR3myCZGo+nwTExT/jXCu34PsCuEJH5upWBMORq7M6DqyTw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1720455058; a=rsa-sha256; cv=none; b=KJEwyegfJ48w+dGF9yaNdHj7RlVivSldmunBsDBa6te0+sG/NazBsW8SmMUQcDtOIL1sVx z/b9z78pC50LUqmXndHZQQgl/eh9xEGhX/NaenEUP7tnD8oubEVVTraZxdghfBkuMYeefr zACicyh5MDFjqyBoUyqxWQzIL55Uu9YEcCUs8A8CL6kYxZCQwQlXqC9aUjBHfGubqZbyRU FSCg7fbgGVrFprm0d5Smr3M8ZP1n33tIseJkDD8SuZOOYULI1OqQOtKnVQyUUBvXPCuT/c LzEdJEnhW6htRs9buIdPA9rI9IyYg1BHTaJ4XNh8SC17/aK2x4ewxJ9ieW7bqA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1720455058; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qEyJx4xCu9rjO/11Mm0BGaezCjWMbEZizPybtLpCFA0=; b=GU05bU4Z+BqnHbFroRJyOzskpqaTRK0P7Pq/ZxN0WNKuqZghDFVImekz/SzmxXWNFXuF1z nqbSUHrmkZNdmSgjAainbi5siftds0DTx7QVA5hRMMLKPB1YYBITNhdtPPkuaLdDGL5q5U SJ9uoyFxKRBpvONIV/Zj26rU8Km7nRiqSme21i94GQTznOBrcnUzGBvek36ev0HY18Ru9h ci/tlta7xIRZXgmiVzYOxBm+/7tsCoR3FWfY3+9eF6pP/b2QsWOM0BVe1d7Ug3RQOyVSGR PJGYws4JXGNMVDKcN0LYT3/Bg56VKysP5C4nFA1IP8qXa2aT5f0rijD1ki8BcQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4WHpyB13dKzxgk; Mon, 8 Jul 2024 16:10:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 468GAwwb077306; Mon, 8 Jul 2024 16:10:58 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 468GAwKi077303; Mon, 8 Jul 2024 16:10:58 GMT (envelope-from git) Date: Mon, 8 Jul 2024 16:10:58 GMT Message-Id: <202407081610.468GAwKi077303@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 163cdf6a32b9 - main - ktls: Fix races that can lead to double initialization List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 163cdf6a32b9a0f84226a70101d143c10707336f Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=163cdf6a32b9a0f84226a70101d143c10707336f commit 163cdf6a32b9a0f84226a70101d143c10707336f Author: Mark Johnston AuthorDate: 2024-07-08 15:49:29 +0000 Commit: Mark Johnston CommitDate: 2024-07-08 16:10:48 +0000 ktls: Fix races that can lead to double initialization ktls_enable_rx() and ktls_enable_tx() have checks to return EALREADY if the socket already has KTLS enabled. However, these are done without any locks held and nothing blocks concurrent attempts to set the socket option. I believe the worst outcome of the race is leaked memory. Fix the problem by rechecking under the sockbuf lock. While here, unify the locking protocol for sb_tls_info: require both the sockbuf and socket I/O locks in order to enable KTLS. This means that either lock is sufficient for checking whether KTLS is enabled in a given sockbuf, which simplifies some refactoring further down the road. Note that the SOLISTENING() check can go away because SOCK_IO_RECV_LOCK() atomically locks the socket buffer and checks whether the socket is a listening socket. This changes the returned errno value, so update a test which checks it. Reviewed by: gallatin MFC after: 2 weeks Sponsored by: Klara, Inc. Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D45674 --- sys/kern/uipc_ktls.c | 23 +++++++++++++++++++++-- sys/sys/sockbuf.h | 3 ++- tests/sys/kern/ktls_test.c | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c index fd1bc7bf8bfe..5ea99966bf13 100644 --- a/sys/kern/uipc_ktls.c +++ b/sys/kern/uipc_ktls.c @@ -1320,12 +1320,23 @@ ktls_enable_rx(struct socket *so, struct tls_enable *en) return (error); } + /* + * Serialize with soreceive_generic() and make sure that we're not + * operating on a listening socket. + */ + error = SOCK_IO_RECV_LOCK(so, SBL_WAIT); + if (error) { + ktls_free(tls); + return (error); + } + /* Mark the socket as using TLS offload. */ SOCK_RECVBUF_LOCK(so); - if (SOLISTENING(so)) { + if (__predict_false(so->so_rcv.sb_tls_info != NULL)) { SOCK_RECVBUF_UNLOCK(so); + SOCK_IO_RECV_UNLOCK(so); ktls_free(tls); - return (EINVAL); + return (EALREADY); } so->so_rcv.sb_tls_seqno = be64dec(en->rec_seq); so->so_rcv.sb_tls_info = tls; @@ -1335,6 +1346,7 @@ ktls_enable_rx(struct socket *so, struct tls_enable *en) sb_mark_notready(&so->so_rcv); ktls_check_rx(&so->so_rcv); SOCK_RECVBUF_UNLOCK(so); + SOCK_IO_RECV_UNLOCK(so); /* Prefer TOE -> ifnet TLS -> software TLS. */ #ifdef TCP_OFFLOAD @@ -1420,6 +1432,13 @@ ktls_enable_tx(struct socket *so, struct tls_enable *en) inp = so->so_pcb; INP_WLOCK(inp); SOCK_SENDBUF_LOCK(so); + if (__predict_false(so->so_snd.sb_tls_info != NULL)) { + SOCK_SENDBUF_UNLOCK(so); + INP_WUNLOCK(inp); + SOCK_IO_SEND_UNLOCK(so); + ktls_free(tls); + return (EALREADY); + } so->so_snd.sb_tls_seqno = be64dec(en->rec_seq); so->so_snd.sb_tls_info = tls; if (tls->mode != TCP_TLS_MODE_SW) { diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h index c6093883be4a..a2e327bbb5df 100644 --- a/sys/sys/sockbuf.h +++ b/sys/sys/sockbuf.h @@ -128,7 +128,8 @@ struct sockbuf { struct mbuf *sb_mtls; /* TLS mbuf chain */ struct mbuf *sb_mtlstail; /* last mbuf in TLS chain */ uint64_t sb_tls_seqno; /* TLS seqno */ - struct ktls_session *sb_tls_info; /* TLS state */ + /* TLS state, locked by sockbuf and sock I/O mutexes. */ + struct ktls_session *sb_tls_info; }; /* * PF_UNIX/SOCK_DGRAM diff --git a/tests/sys/kern/ktls_test.c b/tests/sys/kern/ktls_test.c index f57ae74112a2..72497196b945 100644 --- a/tests/sys/kern/ktls_test.c +++ b/tests/sys/kern/ktls_test.c @@ -2812,7 +2812,7 @@ ATF_TC_BODY(ktls_listening_socket, tc) TLS_MINOR_VER_THREE, (uint64_t)random(), &en); ATF_REQUIRE_ERRNO(ENOTCONN, setsockopt(s, IPPROTO_TCP, TCP_TXTLS_ENABLE, &en, sizeof(en)) != 0); - ATF_REQUIRE_ERRNO(EINVAL, + ATF_REQUIRE_ERRNO(ENOTCONN, setsockopt(s, IPPROTO_TCP, TCP_RXTLS_ENABLE, &en, sizeof(en)) != 0); ATF_REQUIRE(close(s) == 0); }