The branch main has been updated by gallatin:

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

commit fd9af1e7084c550358d9598407f9ee7583e6a53f
Author:     Andrew Gallatin <[email protected]>
AuthorDate: 2026-05-22 17:57:54 +0000
Commit:     Andrew Gallatin <[email protected]>
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);

Reply via email to