Page MenuHomeFreeBSD

D26729.id78071.diff
No OneTemporary

D26729.id78071.diff

Index: sys/kern/uipc_ktls.c
===================================================================
--- sys/kern/uipc_ktls.c
+++ sys/kern/uipc_ktls.c
@@ -1384,7 +1384,9 @@
* The enq_count argument on return is set to the number of pages of
* payload data for this entire chain that need to be encrypted via SW
* encryption. The returned value should be passed to ktls_enqueue
- * when scheduling encryption of this chain of mbufs.
+ * when scheduling encryption of this chain of mbufs. To handle the
+ * special case of empty fragments for TLS 1.0 sessions, an empty
+ * fragment counts as one page.
*/
void
ktls_frame(struct mbuf *top, struct ktls_session *tls, int *enq_cnt,
@@ -1400,12 +1402,16 @@
*enq_cnt = 0;
for (m = top; m != NULL; m = m->m_next) {
/*
- * All mbufs in the chain should be non-empty TLS
- * records whose payload does not exceed the maximum
- * frame length.
+ * All mbufs in the chain should be TLS records whose
+ * payload does not exceed the maximum frame length.
+ *
+ * Empty TLS records are permitted when using CBC.
*/
- KASSERT(m->m_len <= maxlen && m->m_len > 0,
+ KASSERT(m->m_len <= maxlen &&
+ (tls->params.cipher_algorithm == CRYPTO_AES_CBC ?
+ m->m_len >= 0 : m->m_len > 0),
("ktls_frame: m %p len %d\n", m, m->m_len));
+
/*
* TLS frames require unmapped mbufs to store session
* info.
@@ -1496,7 +1502,11 @@
if (tls->mode == TCP_TLS_MODE_SW) {
m->m_flags |= M_NOTREADY;
m->m_epg_nrdy = m->m_epg_npgs;
- *enq_cnt += m->m_epg_npgs;
+ if (tls_len == 0) {
+ /* TLS 1.0 empty fragment. */
+ *enq_cnt += 1;
+ } else
+ *enq_cnt += m->m_epg_npgs;
}
}
}
@@ -1961,7 +1971,11 @@
dst_iov[i].iov_len = len;
}
- npages += i;
+ if (m->m_epg_npgs == 0) {
+ /* TLS 1.0 empty fragment. */
+ npages++;
+ } else
+ npages += i;
error = (*tls->sw_encrypt)(tls,
(const struct tls_record_layer *)m->m_epg_hdr,
Index: sys/kern/uipc_mbuf.c
===================================================================
--- sys/kern/uipc_mbuf.c
+++ sys/kern/uipc_mbuf.c
@@ -1655,6 +1655,8 @@
int pflags = malloc2vm_flags(how) | VM_ALLOC_NOOBJ | VM_ALLOC_NODUMP |
VM_ALLOC_WIRED;
+ MPASS((flags & M_PKTHDR) == 0);
+
/*
* len can be zero or an arbitrary large value bound by
* the total data supplied by the uio.
@@ -1667,11 +1669,24 @@
if (maxseg == 0)
maxseg = MBUF_PEXT_MAX_PGS * PAGE_SIZE;
+ /*
+ * If total is zero, return an empty mbuf. This can occur
+ * for TLS 1.0 connections which send empty fragments as
+ * a countermeasure against the known-IV weakness in CBC
+ * ciphersuites.
+ */
+ if (total == 0) {
+ mb = mb_alloc_ext_pgs(how, mb_free_mext_pgs);
+ if (mb == NULL)
+ return (NULL);
+ mb->m_epg_flags = EPG_FLAG_ANON;
+ return (mb);
+ }
+
/*
* Allocate the pages
*/
m = NULL;
- MPASS((flags & M_PKTHDR) == 0);
while (total > 0) {
mb = mb_alloc_ext_pgs(how, mb_free_mext_pgs);
if (mb == NULL)
Index: sys/kern/uipc_sockbuf.c
===================================================================
--- sys/kern/uipc_sockbuf.c
+++ sys/kern/uipc_sockbuf.c
@@ -212,7 +212,7 @@
while (count > 0) {
KASSERT(m->m_flags & M_NOTREADY,
("%s: m %p !M_NOTREADY", __func__, m));
- if ((m->m_flags & M_EXTPG) != 0) {
+ if ((m->m_flags & M_EXTPG) != 0 && m->m_epg_npgs != 0) {
if (count < m->m_epg_nrdy) {
m->m_epg_nrdy -= count;
count = 0;

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 6, 3:22 PM (8 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16495243
Default Alt Text
D26729.id78071.diff (3 KB)

Event Timeline