Fix dst_off being reset per-descriptor instead of per-packet in the RX
slow path. When processing chained descriptors (MEMIF_DESC_FLAG_NEXT),
goto next_slot2 reset dst_off to 0, overwriting the beginning of the
current mbuf with data from subsequent descriptors. Move dst_off
initialization before the next_slot2 label so it is only reset once
per packet.
Add boundary check in both RX paths before processing next segment.
If MEMIF_DESC_FLAG_NEXT is set but n_slots is 0, free the incomplete
mbuf chain and exit gracefully to prevent reading beyond available
descriptors.
Bugzilla ID: 1609
Fixes: aa17df860891 ("net/memif: add a Rx fast path")
Cc: [email protected]
Reported-by: Mike Bly <[email protected]>
Signed-off-by: Sriram Yagnaraman <[email protected]>
---
drivers/net/memif/rte_eth_memif.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/net/memif/rte_eth_memif.c
b/drivers/net/memif/rte_eth_memif.c
index 0002e24..cef1b0d 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -376,6 +376,13 @@ eth_memif_rx(void *queue, struct rte_mbuf **bufs, uint16_t
nb_pkts)
n_slots--;
if (d0->flags & MEMIF_DESC_FLAG_NEXT) {
+ if (unlikely(n_slots == 0)) {
+ MIF_LOG(ERR, "Truncated packet: NEXT
flag set but no more slots");
+ rte_pktmbuf_free(mbuf_head);
+ rte_pktmbuf_free_bulk(mbufs + rx_pkts,
+ MAX_PKT_BURST -
rx_pkts);
+ goto no_free_bufs;
+ }
mbuf_tail = mbuf;
mbuf = rte_pktmbuf_alloc(mq->mempool);
if (unlikely(mbuf == NULL)) {
@@ -414,13 +421,13 @@ eth_memif_rx(void *queue, struct rte_mbuf **bufs,
uint16_t nb_pkts)
goto no_free_bufs;
mbuf = mbuf_head;
mbuf->port = mq->in_port;
+ dst_off = 0;
next_slot2:
s0 = cur_slot & mask;
d0 = &ring->desc[s0];
src_len = d0->length;
- dst_off = 0;
src_off = 0;
do {
@@ -462,8 +469,14 @@ eth_memif_rx(void *queue, struct rte_mbuf **bufs, uint16_t
nb_pkts)
cur_slot++;
n_slots--;
- if (d0->flags & MEMIF_DESC_FLAG_NEXT)
+ if (d0->flags & MEMIF_DESC_FLAG_NEXT) {
+ if (unlikely(n_slots == 0)) {
+ MIF_LOG(ERR, "Truncated packet: NEXT
flag set but no more slots");
+ rte_pktmbuf_free(mbuf_head);
+ goto no_free_bufs;
+ }
goto next_slot2;
+ }
mq->n_bytes += rte_pktmbuf_pkt_len(mbuf_head);
*bufs++ = mbuf_head;
--
2.43.7