All of lore.kernel.org
 help / color / mirror / Atom feed
From: bugzilla@dpdk.org
To: dev@dpdk.org
Subject: [DPDK/ethdev Bug 1886] net/avp: tx_burst callbacks free mbufs then return short count, causing double-free
Date: Thu, 19 Feb 2026 01:23:55 +0000	[thread overview]
Message-ID: <bug-1886-3@http.bugs.dpdk.org/> (raw)

http://bugs.dpdk.org/show_bug.cgi?id=1886

            Bug ID: 1886
           Summary: net/avp: tx_burst callbacks free mbufs then return
                    short count, causing double-free
           Product: DPDK
           Version: 25.11
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: Normal
         Component: ethdev
          Assignee: dev@dpdk.org
          Reporter: stephen@networkplumber.org
  Target Milestone: ---

Recent audit of how tx_pkt_burst is (or is not) being handled in drivers found
this.

The AVP PMD tx_burst callbacks (`avp_xmit_pkts` and `avp_xmit_scattered_pkts`)
violate the `rte_eth_tx_burst()` mbuf ownership contract.  Both functions free
all mbufs they process, but return the result of `avp_fifo_put()` which may be
smaller.  When the caller follows the standard pattern:

```c
n = rte_eth_tx_burst(port, txq, mbufs, nb_pkts);
for (i = n; i < nb_pkts; i++)
    rte_pktmbuf_free(mbufs[i]);
```

any mbufs that were freed by the driver but not reported as consumed will be
freed a second time by the caller.

There are several additional bugs in the same code paths, listed below.

### Bug 1: Double-free in avp_xmit_pkts (avp_ethdev.c ~line 1917 vs 1926)

The function frees each mbuf at line 1917 (`rte_pktmbuf_free(m)`) inside the
processing loop which runs for `count` packets.  At line 1924 it calls
`avp_fifo_put()` and returns the FIFO result `n` at line 1926.  If the FIFO
fills between the earlier free-count check and the put, `n < count`, and
`tx_pkts[n..count-1]` get double-freed.

Fix: return `count` instead of `n`, since all `count` mbufs have already been
consumed.

### Bug 2: Double-free in avp_xmit_scattered_pkts (line 1793 vs 1809)

Same pattern.  All `nb_pkts` mbufs are freed in the loop (line 1793) but
`avp_fifo_put()` result is returned (line 1809).

Fix: return `nb_pkts` instead of `n`.

### Bug 3: AVP host buffer leak on partial avp_fifo_get (lines 1862-1866)

```c
n = avp_fifo_get(alloc_q, (void **)&avp_bufs, count);
if (unlikely(n != count)) {
    txq->errors++;
    return 0;
}
```

If `avp_fifo_get()` returns a partial result (0 < n < count), those `n` AVP
buffers have been dequeued from the allocation queue but are never returned.
They are permanently leaked.  The same pattern exists in
`avp_xmit_scattered_pkts` at lines 1769-1774.

Fix: return partial buffers to alloc_q before returning:

```c
if (unlikely(n != count)) {
    if (n > 0)
        avp_fifo_put(alloc_q, (void **)&avp_bufs[0], n);
    return 0;
}
```

### Bug 4: Wrong variable in error comparison (line 1806)

```c
if (unlikely(n != orig_nb_pkts))
    txq->errors += (orig_nb_pkts - n);
```

`n` is the result of putting `nb_pkts` entries, but it is compared against
`orig_nb_pkts` which is the original caller count before clamping by
`AVP_MAX_TX_BURST` and resource limits.  These values differ whenever the
burst was clamped, so the error count is wrong.

Fix: compare against `nb_pkts`.

### Bug 5: Spurious error counting for unconsumed packets

Both TX functions increment `txq->errors` for all `nb_pkts` when returning 0
due to resource exhaustion or detach (lines 1714, 1761, 1832, 1855).  Since
the function returns 0, no mbufs were consumed — the caller still owns all of
them.  These are not transmission errors; they are backpressure.  Inflating
`oerrors` is misleading.

Fix: remove the error increments on the early-return-zero paths.

### Bug 6: Oversized packets silently truncated (lines 1886-1899)

When a packet exceeds both `guest_mbuf_size` and `host_mbuf_size`,
`avp_xmit_pkts` truncates it to the smaller buffer size and transmits a
corrupt frame.  Per the tx_burst contract, the driver should consume and
free the mbuf and count it in tx_errors, not send garbage.

Fix: set the AVP buffer length to 0 (skip the copy) and count the error.

## Steps to Reproduce

Code inspection of `drivers/net/avp/avp_ethdev.c` at tag v26.03-rc1.

The double-free (bugs 1-2) can trigger when the tx FIFO fills between the
`avp_fifo_free_count()` check and the `avp_fifo_put()` call.  This is a race
against the host consumer and is timing-dependent.

The buffer leak (bug 3) triggers when `avp_fifo_get()` from the alloc queue
returns a partial result, which can occur under host-side memory pressure.

## Suggested Patch

A patch addressing all six issues is available.  The key changes are:

- Return the number of mbufs freed (consumed) rather than the FIFO put count
- Return partially dequeued AVP buffers on allocation failure
- Remove error counting for unconsumed packets (backpressure is not an error)
- Drop oversized packets instead of truncating
- Fix the orig_nb_pkts vs nb_pkts comparison

-- 
You are receiving this mail because:
You are the assignee for the bug.

                 reply	other threads:[~2026-02-19  1:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-1886-3@http.bugs.dpdk.org/ \
    --to=bugzilla@dpdk.org \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.