git: fd9af1e7084c - main - sendfile: Fix bug when using headers with SW KTLS offload
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 22 May 2026 18:33:57 UTC
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);