Skip to content

Commit fd9af1e

Browse files
Andrew GallatinAndrew Gallatin
authored andcommitted
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
1 parent 4e2bf6e commit fd9af1e

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

sys/kern/kern_sendfile.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ struct sf_io {
9595
vm_pindex_t pindex0;
9696
#ifdef KERN_TLS
9797
struct ktls_session *tls;
98+
struct mbuf *tls_m;
99+
int tls_enq_cnt;
98100
#endif
99101
vm_page_t pa[];
100102
};
@@ -338,7 +340,12 @@ sendfile_iodone(void *arg, vm_page_t *pa, int count, int error)
338340
so->so_proto->pr_abort(so);
339341
so->so_error = EIO;
340342

341-
mb_free_notready(sfio->m, sfio->npages);
343+
#ifdef KERN_TLS
344+
if (sfio->tls_m != NULL)
345+
mb_free_notready(sfio->tls_m, sfio->tls_enq_cnt);
346+
else
347+
#endif
348+
mb_free_notready(sfio->m, sfio->npages);
342349
#ifdef KERN_TLS
343350
} else if (sfio->tls != NULL && sfio->tls->mode == TCP_TLS_MODE_SW) {
344351
/*
@@ -350,7 +357,10 @@ sendfile_iodone(void *arg, vm_page_t *pa, int count, int error)
350357
* Donate the socket reference from sfio to rather
351358
* than explicitly invoking soref().
352359
*/
353-
ktls_enqueue(sfio->m, so, sfio->npages);
360+
if (sfio->tls_m != NULL)
361+
ktls_enqueue(sfio->tls_m, so, sfio->tls_enq_cnt);
362+
else
363+
ktls_enqueue(sfio->m, so, sfio->npages);
354364
goto out_with_ref;
355365
#endif
356366
} else
@@ -897,6 +907,8 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
897907
* for all of sfio's lifetime.
898908
*/
899909
sfio->tls = tls;
910+
sfio->tls_m = NULL;
911+
sfio->tls_enq_cnt = 0;
900912
#endif
901913
vm_object_pip_add(obj, 1);
902914
error = sendfile_swapin(obj, sfio, &nios, off, space, rhpages,
@@ -1125,6 +1137,13 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
11251137
} else {
11261138
sfio->so = so;
11271139
sfio->m = m0;
1140+
#ifdef KERN_TLS
1141+
if (hdrlen != 0 && tls != NULL &&
1142+
tls->mode == TCP_TLS_MODE_SW) {
1143+
sfio->tls_m = m;
1144+
sfio->tls_enq_cnt = tls_enq_cnt;
1145+
}
1146+
#endif
11281147
soref(so);
11291148
error = pr->pr_send(so, PRUS_NOTREADY, m, NULL, NULL,
11301149
td);

0 commit comments

Comments
 (0)