Date: Sun, 05 Jul 2026 18:34:14 +0000 From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Abdelkader Boudih <freebsd@seuros.com> Subject: git: 22ddc9eb1d7a - main - fwip: Fix M_PKTHDR loss in fwip_async_output broadcast path Message-ID: <6a4aa3a6.390af.45346727@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=22ddc9eb1d7a4fffe78b0692bdc4ec03e1d04ac4 commit 22ddc9eb1d7a4fffe78b0692bdc4ec03e1d04ac4 Author: Abdelkader Boudih <freebsd@seuros.com> AuthorDate: 2026-07-05 18:26:05 +0000 Commit: Adrian Chadd <adrian@FreeBSD.org> CommitDate: 2026-07-05 18:34:02 +0000 fwip: Fix M_PKTHDR loss in fwip_async_output broadcast path M_PREPEND in the broadcast branch may call m_prepend(9) which allocates a new head mbuf and calls m_move_pkthdr(), stripping M_PKTHDR from the old mbuf. xfer->mbuf was set before M_PREPEND, so it pointed at the deheadered old mbuf. bus_dmamap_load_mbuf(9) asserts M_PKTHDR and panics. Reviewed by: zlei, adrian Differential Revision: https://reviews.freebsd.org/D57495 --- sys/dev/firewire/if_fwip.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/sys/dev/firewire/if_fwip.c b/sys/dev/firewire/if_fwip.c index 0f37ce6a8e41..bdbe76e2caf4 100644 --- a/sys/dev/firewire/if_fwip.c +++ b/sys/dev/firewire/if_fwip.c @@ -539,13 +539,6 @@ fwip_async_output(struct fwip_softc *fwip, if_t ifp) * it adds the link-level encapsulation. */ - /* - * Put the mbuf in the xfer early in case we hit an - * error case below - fwip_output_callback will free - * the mbuf. - */ - xfer->mbuf = m; - /* * We use the arp result (if any) to add a suitable firewire * packet header before handing off to the bus. @@ -561,7 +554,18 @@ fwip_async_output(struct fwip_softc *fwip, if_t ifp) */ uint32_t *p; + /* + * M_PREPEND may move M_PKTHDR to a new head mbuf. + * Keep xfer->mbuf NULL until it succeeds. + */ + xfer->mbuf = NULL; M_PREPEND(m, 2*sizeof(uint32_t), M_NOWAIT); + if (m == NULL) { + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + fwip_output_callback(xfer); + continue; + } + xfer->mbuf = m; p = mtod(m, uint32_t *); fp->mode.stream.len = m->m_pkthdr.len; fp->mode.stream.chtag = broadcast_channel; @@ -584,6 +588,10 @@ fwip_async_output(struct fwip_softc *fwip, if_t ifp) struct fw_device *fd; struct fw_eui64 eui; + /* + * Error paths below let the callback free m. + */ + xfer->mbuf = m; eui.hi = ntohl(destfw->sender_unique_ID_hi); eui.lo = ntohl(destfw->sender_unique_ID_lo); if (fwip->last_dest.hi != eui.hi ||home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a4aa3a6.390af.45346727>
