From 245345bddcf8e9cd504598c9de0b4bf18648bec2 Mon Sep 17 00:00:00 2001 From: Lucas Manning Date: Tue, 4 Feb 2025 18:26:04 -0800 Subject: [PATCH] Fix TOCTOU bug in sending packets with the experiment option header. In cases where sendRaw runs concurrently with a setsocketopt that sets the experiment option, it's possible to read a zero experiment option when adjusting reserved header space and a non-zero experiment option when sending the packet. This causes the sentry to panic when adding the IPv6 header. PiperOrigin-RevId: 723303802 --- pkg/tcpip/transport/tcp/connect.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index e3f87ffe9..c04def4f4 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -1028,7 +1028,8 @@ func (e *Endpoint) sendRaw(pkt *stack.PacketBuffer, flags header.TCPFlags, seq, options := e.makeOptions(sackBlocks) defer putOptions(options) hdrSize := header.TCPMinimumSize + int(e.route.MaxHeaderLength()) + len(options) - if e.route.NetProto() == header.IPv6ProtocolNumber && e.getExperimentOptionValue(e.route) != 0 { + expOptVal := e.getExperimentOptionValue(e.route) + if e.route.NetProto() == header.IPv6ProtocolNumber && expOptVal != 0 { hdrSize += header.IPv6ExperimentHdrLength } pkt.ReserveHeaderBytes(hdrSize) @@ -1042,7 +1043,7 @@ func (e *Endpoint) sendRaw(pkt *stack.PacketBuffer, flags header.TCPFlags, seq, rcvWnd: rcvWnd, opts: options, df: e.pmtud == tcpip.PMTUDiscoveryWant || e.pmtud == tcpip.PMTUDiscoveryDo, - expOptVal: e.getExperimentOptionValue(e.route), + expOptVal: expOptVal, }, pkt, e.gso) }