aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorSean Bruno <sbruno@FreeBSD.org>2017-08-10 03:43:23 +0000
committerSean Bruno <sbruno@FreeBSD.org>2017-08-10 03:43:23 +0000
commit5c5ca36ca2d40a09e089413731131f430eb39e0e (patch)
treeb4306c09304313944e6651a27bbe00d82bd21c28 /sys/net
parent18a660b34495e86c3f0cfc39cac104a1449eb74a (diff)
downloadsrc-5c5ca36ca2d40a09e089413731131f430eb39e0e.tar.gz
src-5c5ca36ca2d40a09e089413731131f430eb39e0e.zip
Don't leak mbufs if clusers exceeds the number of segments. This would
leak mbufs over time causing crashes. PR: 221202 Submitted by: Matt Macy <matt@mattmacy.io> Reported by: gergely.czuczy@harmless.hu Sponsored by: Limelight Networks
Notes
Notes: svn path=/head/; revision=322338
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/iflib.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index 1296d9c3474f..83e4d497eb14 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -267,6 +267,8 @@ iflib_get_sctx(if_ctx_t ctx)
#define RX_SW_DESC_INUSE (1 << 3)
#define TX_SW_DESC_MAPPED (1 << 4)
+#define M_TOOBIG M_UNUSED_8
+
typedef struct iflib_sw_rx_desc_array {
bus_dmamap_t *ifsd_map; /* bus_dma maps for packet */
struct mbuf **ifsd_m; /* pkthdr mbufs */
@@ -2930,8 +2932,11 @@ iflib_busdma_load_mbuf_sg(iflib_txq_t txq, bus_dma_tag_t tag, bus_dmamap_t map,
m = m->m_next;
count++;
} while (m != NULL);
- if (count > *nsegs)
+ if (count > *nsegs) {
+ ifsd_m[pidx] = *m0;
+ ifsd_m[pidx]->m_flags |= M_TOOBIG;
return (0);
+ }
m = *m0;
count = 0;
do {
@@ -3241,8 +3246,15 @@ iflib_tx_desc_free(iflib_txq_t txq, int n)
if ((m = ifsd_m[cidx]) != NULL) {
/* XXX we don't support any drivers that batch packets yet */
MPASS(m->m_nextpkt == NULL);
-
- m_free(m);
+ /* if the number of clusters exceeds the number of segments
+ * there won't be space on the ring to save a pointer to each
+ * cluster so we simply free the list here
+ */
+ if (m->m_flags & M_TOOBIG) {
+ m_freem(m);
+ } else {
+ m_free(m);
+ }
ifsd_m[cidx] = NULL;
#if MEMORY_LOGGING
txq->ift_dequeued++;