From a549026d25fa95dd66e9a8f57b801930ad585d98 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Wed, 27 Jun 2018 18:35:48 -0400 Subject: [PATCH] freebsd11_network: Actually set numBytes instead of silently truncating it. If numBytes was greater than MCLBYTES (presently 1 << 11 = 2048), then the data beyond MCLBYTES would be silently discarded instead of being written. Now, we store the result of the min_c in numBytes, so the caller knows how much was written. I turn on the printf that's commented out here and found that in practice this seems to never happen (it's larger than the ethernet limit), so it seems unlikely to fix any "transmission mysteriously failed" bugs. Also backported this to the FreeBSD 9 layer. --- src/libs/compat/freebsd11_network/device.c | 8 +++++--- src/libs/compat/freebsd_network/device.c | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/libs/compat/freebsd11_network/device.c b/src/libs/compat/freebsd11_network/device.c index dfb4cdb862..6fa8789e0d 100644 --- a/src/libs/compat/freebsd11_network/device.c +++ b/src/libs/compat/freebsd11_network/device.c @@ -165,17 +165,19 @@ compat_write(void *cookie, off_t position, const void *buffer, //if_printf(ifp, "compat_write(%lld, %p, [%lu])\n", position, // buffer, *numBytes); - if (*numBytes > MHLEN) + if (*numBytes > MHLEN) { mb = m_getcl(0, MT_DATA, M_PKTHDR); - else + *numBytes = min_c(*numBytes, (size_t)MCLBYTES); + } else { mb = m_gethdr(0, MT_DATA); + } if (mb == NULL) return ENOBUFS; // if we waited, check after if the ifp is still valid - mb->m_pkthdr.len = mb->m_len = min_c(*numBytes, (size_t)MCLBYTES); + mb->m_pkthdr.len = mb->m_len = *numBytes; memcpy(mtod(mb, void *), buffer, mb->m_len); return ifp->if_output(ifp, mb, NULL, NULL); diff --git a/src/libs/compat/freebsd_network/device.c b/src/libs/compat/freebsd_network/device.c index da9964752f..87cc7fcfa7 100644 --- a/src/libs/compat/freebsd_network/device.c +++ b/src/libs/compat/freebsd_network/device.c @@ -165,17 +165,19 @@ compat_write(void *cookie, off_t position, const void *buffer, //if_printf(ifp, "compat_write(%lld, %p, [%lu])\n", position, // buffer, *numBytes); - if (*numBytes > MHLEN) + if (*numBytes > MHLEN) { mb = m_getcl(0, MT_DATA, M_PKTHDR); - else + *numBytes = min_c(*numBytes, (size_t)MCLBYTES); + } else { mb = m_gethdr(0, MT_DATA); + } if (mb == NULL) return ENOBUFS; // if we waited, check after if the ifp is still valid - mb->m_pkthdr.len = mb->m_len = min_c(*numBytes, (size_t)MCLBYTES); + mb->m_pkthdr.len = mb->m_len = *numBytes; memcpy(mtod(mb, void *), buffer, mb->m_len); return ifp->if_output(ifp, mb, NULL, NULL);