Page MenuHomeFreeBSD

Fix a double free in ixgbe_rxeof()

Authored by rstone on Apr 3 2017, 7:00 PM.



When a packet is longer than PAGE_SIZE bytes, ixgbe has to
split it across multiple descriptors. As it build up the
mbuf chain representing the packet, it saves the mbuf chain
in the rxbuf struct for the next descriptor index. If the
interface is disabled while ixgbe is doing this, a stale mbuf
chain will be left in the rxbuf.

When the interface is brought back up, the init routine ignores
the built-up mbuf chain, but it does free the mbuf associated with
the descriptor. This means that the mbuf chain is left in a state
where the final mbuf in the chain is now free. When receive starts
again, once it processes that descriptor rxeof will encounter the
stale mbuf chain and begin processing it, eventually passing it up
the stack. Eventually the chain is freed and the final mbuf in
the chain is freed a second time, leading to all the hilarity that
a double free in the kernel can cause.

Also correct an error case that did not perform proper locking
before touching an rx ring.

Diff Detail

rS FreeBSD src repository
Automatic diff as part of commit; lint not applicable.
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

rstone created this revision.Apr 3 2017, 7:00 PM
rstone added a comment.Apr 3 2017, 7:02 PM

I'm not sure what we want to do with this fix given the imminent iflib conversion, but at least this should go into stable branches.

rstone updated this revision to Diff 26980.Apr 3 2017, 7:04 PM

Add the locking mentioned the description but omitted from the
actual revision.

sbruno accepted this revision.Apr 5 2017, 7:49 PM

I'm going to commit this to head and then mfc it next week to stable/11 and whatnot. This shouldn't be blocked due to iflib-ification.

This revision is now accepted and ready to land.Apr 5 2017, 7:49 PM
This revision was automatically updated to reflect the committed changes.