From b0018f1e7df47099ee22f3c5fcc91a4112e10523 Mon Sep 17 00:00:00 2001 From: Jordan Whited Date: Mon, 4 Aug 2025 14:21:32 -0700 Subject: [PATCH] wgengine/magicsock: fix looksLikeInitiationMsg endianness (#16771) WireGuard message type is little-endian encoded. Updates tailscale/corp#30903 Signed-off-by: Jordan Whited --- wgengine/magicsock/magicsock.go | 7 ++----- wgengine/magicsock/magicsock_test.go | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index 6495b13b5..c99d1b68f 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -1765,11 +1765,8 @@ func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFu // looksLikeInitiationMsg returns true if b looks like a WireGuard initiation // message, otherwise it returns false. func looksLikeInitiationMsg(b []byte) bool { - if len(b) == device.MessageInitiationSize && - binary.BigEndian.Uint32(b) == device.MessageInitiationType { - return true - } - return false + return len(b) == device.MessageInitiationSize && + binary.LittleEndian.Uint32(b) == device.MessageInitiationType } // receiveIP is the shared bits of ReceiveIPv4 and ReceiveIPv6. diff --git a/wgengine/magicsock/magicsock_test.go b/wgengine/magicsock/magicsock_test.go index 480faa694..0d1ac9dfd 100644 --- a/wgengine/magicsock/magicsock_test.go +++ b/wgengine/magicsock/magicsock_test.go @@ -9,6 +9,7 @@ crand "crypto/rand" "crypto/tls" "encoding/binary" + "encoding/hex" "errors" "fmt" "io" @@ -3390,10 +3391,17 @@ func Test_virtualNetworkID(t *testing.T) { } func Test_looksLikeInitiationMsg(t *testing.T) { - initMsg := make([]byte, device.MessageInitiationSize) - binary.BigEndian.PutUint32(initMsg, device.MessageInitiationType) - initMsgSizeTransportType := make([]byte, device.MessageInitiationSize) - binary.BigEndian.PutUint32(initMsgSizeTransportType, device.MessageTransportType) + // initMsg was captured as the first packet from a WireGuard "session" + initMsg, err := hex.DecodeString("01000000d9205f67915a500e377b409e0c3d97ca91e68654b95952de965e75df491000cce00632678cd9e8c8525556aa8daf24e6cfc44c48812bb560ff3c1c5dee061b3f833dfaa48acf13b64bd1e0027aa4d977a3721b82fd6072338702fc3193651404980ad46dae2869ba6416cc0eb38621a4140b5b918eb6402b697202adb3002a6d00000000000000000000000000000000") + if err != nil { + t.Fatal(err) + } + if len(initMsg) != device.MessageInitiationSize { + t.Fatalf("initMsg is not %d bytes long", device.MessageInitiationSize) + } + initMsgSizeTransportType := make([]byte, len(initMsg)) + copy(initMsgSizeTransportType, initMsg) + binary.LittleEndian.PutUint32(initMsgSizeTransportType, device.MessageTransportType) tests := []struct { name string b []byte