Page MenuHomeFreeBSD

iflib: Fix mbufs leaked by 0 len packets emitted from the if driver
AcceptedPublic

Authored by linnemannr_gmail.com on Wed, Jun 10, 10:49 PM.
Referenced Files
Unknown Object (File)
Sat, Jun 13, 7:22 AM
Unknown Object (File)
Fri, Jun 12, 7:01 PM
Unknown Object (File)
Thu, Jun 11, 6:19 PM

Details

Reviewers
shurd
gallatin
Group Reviewers
iflib
Summary

Some interface drivers, notably bnxt, can insert 0 length packets onto
their receive queues when certain conditions are met, such as discarding
packets in the case of bnxt.

When this packet gets processed by assemble_segments(), The solitary
mbuf on the queue that composes it consist of a single zero length
fragment. The loop in assemble_segments() doesn't seem to expect
that a 0 length fragment can exist in the iri_frags list without a
non-zero length header preceding it. In this situation, without filter
intervention rxd_frag_to_sd() returns a pointer to the corresponding
mbuf in the rxq, where it is matched as a zero-length fragment and
immediately discarded without freeing as mh has not yet been assigned.

This change corrects this behavior by falling through the mh == NULL
case and freeing m on the condition that it is not NULL before
continuing the loop.

Sponsored by: Spectra Logic

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 73815
Build 70698: arc lint + arc unit

Event Timeline

I'm debating on whether we should also change rxd_frag_to_sd() to not pop the mbuf off the freelist and instead return NULL if irf->irf_len == 0. If the fragment is 0 length I don't think there is any point in consuming an mbuf over it, since it will just be immediately freed.

Shouldn't this be actually handled by this condition? (https://cgit.freebsd.org/src/tree/sys/net/iflib.c#n2969)

/* was this only a completion queue message? */
if (__predict_false(ri.iri_nfrags == 0))
	continue;

I mean if a packet is discarded does it need to use any iri_frags?

Shouldn't this be actually handled by this condition? (https://cgit.freebsd.org/src/tree/sys/net/iflib.c#n2969)

/* was this only a completion queue message? */
if (__predict_false(ri.iri_nfrags == 0))
	continue;

I mean if a packet is discarded does it need to use any iri_frags?

No, in the case we hit there was a packet of one fragment of zero length placed on the rxq. Ultimately there may be a bnxt bug, but the fact remains that it is logically possible to wind up at original line 2803 with mh == NULL and m != NULL, and we leak the mbuf as a result. That condition needs to be accounted for.

It took me a while, but I think your patch is correct.

This revision is now accepted and ready to land.Fri, Jun 12, 7:37 PM