From 31cdbd68b12790dfa6c432844a8340563286bc58 Mon Sep 17 00:00:00 2001 From: Jordan Whited Date: Tue, 27 Aug 2024 14:59:43 -0700 Subject: [PATCH] net/tstun: fix gvisor inbound GSO packet injection (#13283) buffs[0] was not sized to hold pkt with GSO, resulting in a panic. Updates tailscale/corp#22511 Signed-off-by: Jordan Whited --- net/tstun/wrap.go | 4 ++-- wgengine/netstack/netstack.go | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/net/tstun/wrap.go b/net/tstun/wrap.go index dc1aeabc6..c37ffb246 100644 --- a/net/tstun/wrap.go +++ b/net/tstun/wrap.go @@ -1258,8 +1258,8 @@ func (t *Wrapper) SetJailedFilter(filt *filter.Filter) { // // pkt will be copied into buffs before writing to the underlying tun.Device. // Therefore, callers must allocate and pass a buffs slice that is sized -// appropriately for holding pkt.Size() + PacketStartOffset as either a single -// element (buffs[0]), or split across multiple elements if the originating +// appropriately for holding pkt.Size() + PacketStartOffset as a single +// element (buffs[0]) and split across multiple elements if the originating // stack supports GSO. sizes must be sized with similar consideration, // len(buffs) should be equal to len(sizes). If any len(buffs[]) was // mutated by InjectInboundPacketBuffer it will be reset to cap(buffs[]) diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go index 01af13b09..47fe23203 100644 --- a/wgengine/netstack/netstack.go +++ b/wgengine/netstack/netstack.go @@ -826,13 +826,18 @@ func (ns *Impl) DialContextUDP(ctx context.Context, ipp netip.AddrPort) (*gonet. // across subsequent inbound packet injection calls. func (ns *Impl) getInjectInboundBuffsSizes() (buffs [][]byte, sizes []int) { batchSize := 1 - if ns.linkEP.SupportedGSO() == stack.HostGSOSupported { + gsoEnabled := ns.linkEP.SupportedGSO() == stack.HostGSOSupported + if gsoEnabled { batchSize = conn.IdealBatchSize } buffs = make([][]byte, batchSize) sizes = make([]int, batchSize) for i := 0; i < batchSize; i++ { - buffs[i] = make([]byte, tstun.PacketStartOffset+tstun.DefaultTUNMTU()) + if i == 0 && gsoEnabled { + buffs[i] = make([]byte, tstun.PacketStartOffset+ns.linkEP.GSOMaxSize()) + } else { + buffs[i] = make([]byte, tstun.PacketStartOffset+tstun.DefaultTUNMTU()) + } } return buffs, sizes }