[PATCH] net/memif: fix multi-segment RX data corruption and truncation

Stephen Hemminger stephen at networkplumber.org
Tue Mar 24 00:33:04 CET 2026


On Mon, 16 Mar 2026 16:59:18 +0100
Sriram Yagnaraman <sriram.yagnaraman at ericsson.com> wrote:

> 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: stable at dpdk.org
> 
> Reported-by: Mike Bly <bly454 at gmail.com>
> Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman at ericsson.com>

It looked good to me, but AI review spotted an issue.


---

OK, so my error finding stands but with refined reasoning. Here's the corrected summary:

**Error: Double free of `mbuf_head` in the fast-path truncation error path.**

In the new truncation check added to the fast path:
```c
if (unlikely(n_slots == 0)) {
    MIF_LOG(ERR, "Truncated packet: ...");
    rte_pktmbuf_free(mbuf_head);
    rte_pktmbuf_free_bulk(mbufs + rx_pkts,
            MAX_PKT_BURST - rx_pkts);
    goto no_free_bufs;
}
```

`mbuf_head` is `mbufs[rx_pkts]` (assigned at line 359). `rte_pktmbuf_free(mbuf_head)` frees the head and its entire chain. Then `rte_pktmbuf_free_bulk(mbufs + rx_pkts, ...)` processes the same array starting at `mbufs[rx_pkts]`, which still holds the now-freed pointer. Since `rte_pktmbuf_free_bulk` walks `m->next` chains (confirmed in `lib/mbuf/rte_mbuf.c:574`), this frees `mbuf_head` a second time.

The existing error paths at lines 383-386 and 391-394 do NOT have this bug — they don't call `rte_pktmbuf_free(mbuf_head)` first; they let `rte_pktmbuf_free_bulk` handle the entire chain. The fix is to remove the separate `rte_pktmbuf_free(mbuf_head)` and just do:
```c
rte_pktmbuf_free_bulk(mbufs + rx_pkts,
        MAX_PKT_BURST - rx_pkts);
```

This works because `rte_pktmbuf_free_bulk` already walks the chain on `mbufs[rx_pkts]`, freeing `mbuf_head` and all segments chained onto it, plus the remaining unused mbufs.

No other issues found. The `dst_off` fix and the slow-path bounds check are both correct.


More information about the dev mailing list