Page MenuHomeFreeBSD

rge: Preserve replacement mbufs after defragmentation
ClosedPublic

Authored by markj on Tue, Sep 29, 7:31 PM.
Referenced Files
F174278350: D60142.id188138.diff
Thu, Oct 1, 11:29 PM
F174248893: D60142.diff
Thu, Oct 1, 5:25 PM
F174243778: D60142.diff
Thu, Oct 1, 4:22 PM
F174212130: D60142.diff
Thu, Oct 1, 9:55 AM
Unknown Object (File)
Wed, Sep 30, 11:24 PM
Unknown Object (File)
Wed, Sep 30, 11:16 PM
Unknown Object (File)
Wed, Sep 30, 11:14 PM
Unknown Object (File)
Wed, Sep 30, 3:43 PM
Subscribers

Details

Summary

m_defrag() has pointer-return ownership semantics: success frees the
original chain and returns a replacement, while failure returns NULL and
leaves the original owned by the caller. rge_encap() compared that
pointer as an integer status and could return failure after success,
causing rge_tx_task() to free its stale old head.

Pass the mbuf by reference, retain the replacement returned by
m_defrag(), and publish it to the caller before retrying DMA mapping. A
later mapping failure is then cleaned up through the current chain, and
a successful transmission uses that same chain for BPF and TX ownership.

An unprivileged process can reach the EFBIG branch in mapped-sendfile
mode.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 77465
Build 74348: arc lint + arc unit

Event Timeline

markj requested review of this revision.Tue, Sep 29, 7:31 PM
adrian added a project: drivers.

nice catch! thanks!

This revision is now accepted and ready to land.Tue, Sep 29, 7:59 PM
sys/dev/rge/if_rge.c
2508

Maybe add a note here, something like /* Note: m can change due to m_defrag() */

This revision was automatically updated to reflect the committed changes.
markj marked an inline comment as done.