Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 May 2026 18:33:57 +0000
From:      Andrew Gallatin <gallatin@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: fd9af1e7084c - main - sendfile: Fix bug when using headers with SW KTLS offload
Message-ID:  <6a10a195.3db1a.b58a602@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by gallatin:

URL: https://cgit.FreeBSD.org/src/commit/?id=fd9af1e7084c550358d9598407f9ee7583e6a53f

commit fd9af1e7084c550358d9598407f9ee7583e6a53f
Author:     Andrew Gallatin <gallatin@FreeBSD.org>
AuthorDate: 2026-05-22 17:57:54 +0000
Commit:     Andrew Gallatin <gallatin@FreeBSD.org>
CommitDate: 2026-05-22 18:33:41 +0000

    sendfile: Fix bug when using headers with SW KTLS offload
    
    When using SW KTLS, we must account for the headers in sf_iodone()
    in terms of either freeing or enqueuing them for TLS work.
    Not doing so can lead to a situation where we enqueue only
    the payload, and not the header, for encryption. Rather than
    leaking the header, the socket is left "hung" with the header marked
    M_NOTREADY.
    
    Sponsored by: Netflix
    Reviewed by: glebius, kib
    Differential Revision: https://reviews.freebsd.org/D57134
    MFC After: 14 days
---
 sys/kern/kern_sendfile.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c
index 9992b83ad6a8..cf9716560c07 100644
--- a/sys/kern/kern_sendfile.c
+++ b/sys/kern/kern_sendfile.c
@@ -95,6 +95,8 @@ struct sf_io {
 	vm_pindex_t	pindex0;
 #ifdef KERN_TLS
 	struct ktls_session *tls;
+	struct mbuf	*tls_m;
+	int		tls_enq_cnt;
 #endif
 	vm_page_t	pa[];
 };
@@ -338,7 +340,12 @@ sendfile_iodone(void *arg, vm_page_t *pa, int count, int error)
 		so->so_proto->pr_abort(so);
 		so->so_error = EIO;
 
-		mb_free_notready(sfio->m, sfio->npages);
+#ifdef KERN_TLS
+		if (sfio->tls_m != NULL)
+			mb_free_notready(sfio->tls_m, sfio->tls_enq_cnt);
+		else
+#endif
+			mb_free_notready(sfio->m, sfio->npages);
 #ifdef KERN_TLS
 	} else if (sfio->tls != NULL && sfio->tls->mode == TCP_TLS_MODE_SW) {
 		/*
@@ -350,7 +357,10 @@ sendfile_iodone(void *arg, vm_page_t *pa, int count, int error)
 		 * Donate the socket reference from sfio to rather
 		 * than explicitly invoking soref().
 		 */
-		ktls_enqueue(sfio->m, so, sfio->npages);
+		if (sfio->tls_m != NULL)
+			ktls_enqueue(sfio->tls_m, so, sfio->tls_enq_cnt);
+		else
+			ktls_enqueue(sfio->m, so, sfio->npages);
 		goto out_with_ref;
 #endif
 	} else
@@ -897,6 +907,8 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
 		 * for all of sfio's lifetime.
 		 */
 		sfio->tls = tls;
+		sfio->tls_m = NULL;
+		sfio->tls_enq_cnt = 0;
 #endif
 		vm_object_pip_add(obj, 1);
 		error = sendfile_swapin(obj, sfio, &nios, off, space, rhpages,
@@ -1125,6 +1137,13 @@ prepend_header:
 		} else {
 			sfio->so = so;
 			sfio->m = m0;
+#ifdef KERN_TLS
+			if (hdrlen != 0 && tls != NULL &&
+			    tls->mode == TCP_TLS_MODE_SW) {
+				sfio->tls_m = m;
+				sfio->tls_enq_cnt = tls_enq_cnt;
+			}
+#endif
 			soref(so);
 			error = pr->pr_send(so, PRUS_NOTREADY, m, NULL, NULL,
 			    td);


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a10a195.3db1a.b58a602>