From nobody Tue Apr 22 15:59:40 2025 X-Original-To: dev-commits-src-main@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 4Zhn4D3rzqz5spbj; Tue, 22 Apr 2025 15:59:40 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Zhn4D26Npz3hcK; Tue, 22 Apr 2025 15:59:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1745337580; 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=Z7oTwjpR/7FWtfwNNXw+Xn3ebSF3dowFKadfHD40Y2s=; b=pAj8N552yMfFwmpO8RR1EvOJ6+snAL8jjESqCXACtL5VwMOGjWEkN0HXSwfCtMUboxAu2y uyAK3Djrke3qJzWmGNJzQgSB6QVXFBfBZQa7gUEaL2Vw+v5cKruE6X6LRJcHmHvgd/zEuP wpJQcLpTQnDMGRKqJaaiuQtB8z0Q8YejseSLo2NtK04zP0jPKDnN70DBhDOnPcMG7WmaC/ R9wz9aA/Pfs224ijMpC2Z3Pe9sgw8TJY8DOoUvosXgxap8m7CihJvXH7ezqpJkVWcMXUxX nGIuXptvlKm1QwzdUBgWSsT1srHCBm/RJ76gPcGAAhDmY+CPPneysoI3/O0t8g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1745337580; a=rsa-sha256; cv=none; b=uYk+ZaLmoFaZTWRqfFPoGQNXkJaIneeqf5TFcFhcnx4YIrKBEAG/rgzHDlHyxWIZQgC5m/ hrZXm/ttEmVKy0PXZ+YyWfheTWjm8g0BRK+pbXcGMHoRsROOkPpJ8lpGZYwWid5F1fDlTF L7gtWjXTn6V1z7so9JknrbuAowaCNMEr/94cB8lSdrSOqoxKiCaidOVQFgNdzsmPz+l1jd h0wAdYayEk9T5FE+w2OaWiiTVtgDenwJ7UdbzbKSg0EjoXziJmwWkRqyf1xTS1+TOgFykx LS+M2LWraaY+zRIFyqQ0t0rqKLGtvMNn1JWxmXhtoHhZwnOtgNra8C66iouv4Q== 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=1745337580; 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=Z7oTwjpR/7FWtfwNNXw+Xn3ebSF3dowFKadfHD40Y2s=; b=cva9Im1zOEiqIGS6jQZRpgF26Vc9ubep+ummVHMF+1KMG+Ly7DprclC6PmlZccrWd33mes 7yUduqswMGpfc85M2C0KMbFSF1YJUtLFWFx+UwMfffBiDNFOSqF7vNF0iRrUP1MgTuCk1C veB1swlPEAhh1OJz4aLyBWtcoCUJc4iJr0GLnK9tDlc2CmoM5tUKU+9MiUkg8C0Wec9yWj blq6hIkN7QYE5ucNf+JN96mRxmk44aSDuW1EZrz/ER2CDMy+c6T8O//1IDtpv0A4cTZ0+k /Jy2zchax2/Ms5g9ZDCHucPIabBMIT6cIAB6GM4jzTRfhKDD78mgWCbCcKfgTg== 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 4Zhn4D1bhGz9Kn; Tue, 22 Apr 2025 15:59:40 +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 53MFxeNo031706; Tue, 22 Apr 2025 15:59:40 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 53MFxeY7031703; Tue, 22 Apr 2025 15:59:40 GMT (envelope-from git) Date: Tue, 22 Apr 2025 15:59:40 GMT Message-Id: <202504221559.53MFxeY7031703@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: 1000cc4a0d39 - main - so_splice: Disallow splicing with KTLS-enabled sockets List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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: 1000cc4a0d39faeb3e681bb167ed38f164c56604 Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=1000cc4a0d39faeb3e681bb167ed38f164c56604 commit 1000cc4a0d39faeb3e681bb167ed38f164c56604 Author: Mark Johnston AuthorDate: 2025-04-22 14:53:34 +0000 Commit: Mark Johnston CommitDate: 2025-04-22 14:53:34 +0000 so_splice: Disallow splicing with KTLS-enabled sockets Suppose the sink socket in a splice has KTLS enabled. When data is transmitted from the source socket, sosend_generic_locked() receives an mbuf rather than a UIO as it would if userspace were transferring data. In this case, ktls_frame() expects the mbuf to be unmapped, but in general this won't be the case. Simply disallow the combination for now. Modify so_unsplice() to handle dismantling a partially initialized splice, in order to simplify error handling in so_splice(). Make sure that one can't enable KTLS on a spliced socket, or more specifically, that one can't enable RXTLS on the source side of a splice, or TXTLS on the sink side of a splice. Reported by: syzbot+9cc248c4b0ca9b931ab4@syzkaller.appspotmail.com Reviewed by: gallatin MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D49920 --- sys/kern/uipc_ktls.c | 14 +++++++++++--- sys/kern/uipc_socket.c | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c index 6815667594a4..5e9dd254debd 100644 --- a/sys/kern/uipc_ktls.c +++ b/sys/kern/uipc_ktls.c @@ -1332,7 +1332,11 @@ ktls_enable_rx(struct socket *so, struct tls_enable *en) /* Mark the socket as using TLS offload. */ SOCK_RECVBUF_LOCK(so); - if (__predict_false(so->so_rcv.sb_tls_info != NULL)) { + if (__predict_false(so->so_rcv.sb_tls_info != NULL)) + error = EALREADY; + else if ((so->so_rcv.sb_flags & SB_SPLICED) != 0) + error = EINVAL; + if (error != 0) { SOCK_RECVBUF_UNLOCK(so); SOCK_IO_RECV_UNLOCK(so); ktls_free(tls); @@ -1432,12 +1436,16 @@ 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)) { + if (__predict_false(so->so_snd.sb_tls_info != NULL)) + error = EALREADY; + else if ((so->so_snd.sb_flags & SB_SPLICED) != 0) + error = EINVAL; + if (error != 0) { SOCK_SENDBUF_UNLOCK(so); INP_WUNLOCK(inp); SOCK_IO_SEND_UNLOCK(so); ktls_free(tls); - return (EALREADY); + return (error); } so->so_snd.sb_tls_seqno = be64dec(en->rec_seq); so->so_snd.sb_tls_info = tls; diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 291a832189e5..10f81a959147 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1699,10 +1699,16 @@ so_splice(struct socket *so, struct socket *so2, struct splice *splice) uma_zfree(splice_zone, sp); return (error); } - soref(so); - so->so_splice = sp; SOCK_RECVBUF_LOCK(so); + if (so->so_rcv.sb_tls_info != NULL) { + SOCK_RECVBUF_UNLOCK(so); + SOCK_UNLOCK(so); + uma_zfree(splice_zone, sp); + return (EINVAL); + } so->so_rcv.sb_flags |= SB_SPLICED; + so->so_splice = sp; + soref(so); SOCK_RECVBUF_UNLOCK(so); SOCK_UNLOCK(so); @@ -1716,20 +1722,19 @@ so_splice(struct socket *so, struct socket *so2, struct splice *splice) error = EBUSY; if (error != 0) { SOCK_UNLOCK(so2); - SOCK_LOCK(so); - so->so_splice = NULL; - SOCK_RECVBUF_LOCK(so); - so->so_rcv.sb_flags &= ~SB_SPLICED; - SOCK_RECVBUF_UNLOCK(so); - SOCK_UNLOCK(so); - sorele(so); - uma_zfree(splice_zone, sp); + so_unsplice(so, false); return (error); } - soref(so2); - so2->so_splice_back = sp; SOCK_SENDBUF_LOCK(so2); + if (so->so_snd.sb_tls_info != NULL) { + SOCK_SENDBUF_UNLOCK(so2); + SOCK_UNLOCK(so2); + so_unsplice(so, false); + return (EINVAL); + } so2->so_snd.sb_flags |= SB_SPLICED; + so2->so_splice_back = sp; + soref(so2); mtx_lock(&sp->mtx); SOCK_SENDBUF_UNLOCK(so2); SOCK_UNLOCK(so2); @@ -1754,7 +1759,7 @@ so_unsplice(struct socket *so, bool timeout) { struct socket *so2; struct so_splice *sp; - bool drain; + bool drain, so2rele; /* * First unset SB_SPLICED and hide the splice structure so that @@ -1793,11 +1798,14 @@ so_unsplice(struct socket *so, bool timeout) SOCK_LOCK(so2); KASSERT(!SOLISTENING(so2), ("%s: so2 is listening", __func__)); SOCK_SENDBUF_LOCK(so2); - KASSERT((so2->so_snd.sb_flags & SB_SPLICED) != 0, + KASSERT(sp->state == SPLICE_INIT || + (so2->so_snd.sb_flags & SB_SPLICED) != 0, ("%s: so2 is not spliced", __func__)); - KASSERT(so2->so_splice_back == sp, + KASSERT(sp->state == SPLICE_INIT || + so2->so_splice_back == sp, ("%s: so_splice_back != sp", __func__)); so2->so_snd.sb_flags &= ~SB_SPLICED; + so2rele = so2->so_splice_back != NULL; so2->so_splice_back = NULL; SOCK_SENDBUF_UNLOCK(so2); SOCK_UNLOCK(so2); @@ -1815,6 +1823,7 @@ so_unsplice(struct socket *so, bool timeout) while (sp->state == SPLICE_CLOSING) msleep(sp, &sp->mtx, PSOCK, "unsplice", 0); break; + case SPLICE_INIT: case SPLICE_IDLE: case SPLICE_EXCEPTION: sp->state = SPLICE_CLOSED; @@ -1840,7 +1849,8 @@ so_unsplice(struct socket *so, bool timeout) CURVNET_SET(so->so_vnet); sorele(so); sowwakeup(so2); - sorele(so2); + if (so2rele) + sorele(so2); CURVNET_RESTORE(); so_splice_free(sp); return (0);