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
This commit is contained in:
Lucas Manning
2025-02-04 18:30:02 -08:00
committed by gVisor bot
parent 2207271d76
commit 245345bddc
+3 -2
View File
@@ -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)
}