Page MenuHomeFreeBSD

bridge: Don't share broadcast packets
ClosedPublic

Authored by kp on Feb 19 2022, 9:49 AM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Apr 17, 7:27 AM
Unknown Object (File)
Mon, Apr 1, 3:50 AM
Unknown Object (File)
Jan 25 2024, 5:19 AM
Unknown Object (File)
Dec 17 2023, 3:38 AM
Unknown Object (File)
Dec 11 2023, 12:05 AM
Unknown Object (File)
Nov 26 2023, 1:38 AM
Unknown Object (File)
Sep 9 2023, 11:26 AM
Unknown Object (File)
Aug 30 2023, 10:23 AM

Details

Summary

if_bridge duplicates broadcast packets with m_copypacket(), which
creates shared packets. In certain circumstances these packets can be
processed by udp_usrreq.c:udp_input() first, which modifies the mbuf as
part of the checksum verification. That may lead to incorrect packets
being transmitted.

Use m_dup() to create independent mbufs instead.

Reported by: Richard Russo <toast@ruka.org>
MFC after: 2 weeks

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kp requested review of this revision.Feb 19 2022, 9:49 AM

I'm concerned about two things:

  1. Is this the only case with if_epair(4)? I don't see any guarantee that some other interface won't change the shared mbuf.
  1. if_bridge.c::bridge_output uses m_copypacket() for broadcast only (multicast, unknown destination, span ports, etc.). After the fix, if_epair(4) calls m_unshare() for each packet, which can increase overhead since m_unshare() allocates memory.

I think it's very dangerous to use m_copypacket() and if_bridge(4) code should use m_dup().

I'm concerned about two things:

  1. Is this the only case with if_epair(4)? I don't see any guarantee that some other interface won't change the shared mbuf.

It's probably the most realistic way to manifest this issue, but you're right, there could be other case.

  1. if_bridge.c::bridge_output uses m_copypacket() for broadcast only (multicast, unknown destination, span ports, etc.). After the fix, if_epair(4) calls m_unshare() for each packet, which can increase overhead since m_unshare() allocates memory.

I had somehow convinced myself that m_unshare() would only do work for shared mbufs, but that's not actually the case.

I think it's very dangerous to use m_copypacket() and if_bridge(4) code should use m_dup().

And you're also right that that's going to be a better fix. There's another m_copypacket() in the span path in if_bridge. I'll test a patch to replace them both with m_dup().

kp planned changes to this revision.Feb 19 2022, 12:50 PM
kp retitled this revision from epair: fix issue with shared mbufs to bridge: Don't share broadcast packets.
kp edited the summary of this revision. (Show Details)
donner added a subscriber: donner.

Similar to ng_bridge, but there was hope that if_bridge could avoid such problems.

This revision is now accepted and ready to land.Feb 20 2022, 6:57 PM
This revision was automatically updated to reflect the committed changes.