Skip to content

Commit 8a12098

Browse files
ntgvisor-bot
authored andcommitted
tcp: skip RST in resetConnectionLocked when snd/rcv are nil
resetConnectionLocked dereferences e.snd to compute the RST sequence number, but snd (and rcv) are only initialized when the TCP handshake completes in transitionToStateEstablishedLocked. Endpoints still in StateSynSent or StateSynRecv have nil snd/rcv, and calling resetConnectionLocked on them (e.g. from beforeSave during checkpoint) panics with a nil pointer dereference. Guard the RST-sending block behind a nil check on e.snd. The rest of the function (set hardError, purge queues, cleanup, transition to StateError) is still unconditionally executed. This address the following crash: ``` encoding error: runtime error: invalid memory address or nil pointer dereference: goroutine 3057 [running]: gvisor.dev/gvisor/pkg/state.safely.func1() \tpkg/state/state.go:309 +0x170 panic({0x124f2a0?, 0x31fb280?}) \tGOROOT/src/runtime/panic.go:792 +0x132 gvisor.dev/gvisor/pkg/tcpip/transport/tcp.(*Endpoint).resetConnectionLocked(0xc000a7d508, {0x1685100?, 0x324f8a0?}) \tpkg/tcpip/transport/tcp/connect.go:1084 +0x84 gvisor.dev/gvisor/pkg/tcpip/transport/tcp.(*Endpoint).beforeSave(0xc000a7d508) \tpkg/tcpip/transport/tcp/endpoint_state.go:59 +0x188 gvisor.dev/gvisor/pkg/tcpip/transport/tcp.(*Endpoint).StateSave(0xc000a7d508, {{0xc001139c08?, 0xc0016e4f48?}}) \tbazel-out/k8-opt/bin/pkg/tcpip/transport/tcp/tcp_state_autogen.go:504 +0x4a gvisor.dev/gvisor/pkg/state.(*encodeState).encodeStruct(0xc001139c08, {0x144da00, 0xc000a7d508, 0x199}, 0xc0014dc9e0) \tpkg/state/encode.go:536 +0x58e gvisor.dev/gvisor/pkg/state.(*encodeState).encodeObject(0xc001139c08, {0x144da00?, 0xc000a7d508?, 0xc000bb0008?}, 0x0, 0xc0014dc9e0) \tpkg/state/encode.go:733 +0x5e5 gvisor.dev/gvisor/pkg/state.(*encodeState).Save.func2() \tpkg/state/encode.go:770 +0x8b gvisor.dev/gvisor/pkg/state.safely(0xc001139c08?) \tpkg/state/state.go:322 +0x51 gvisor.dev/gvisor/pkg/state.(*encodeState).Save(0xc001139c08, {0x144e140?, 0xc000004408?, 0xc001139c08?}) \tpkg/state/encode.go:763 +0x1eb gvisor.dev/gvisor/pkg/state.Save.func1() \tpkg/state/state.go:104 +0x8e gvisor.dev/gvisor/pkg/state.safely(0xa694fe?) \tpkg/state/state.go:322 +0x51 gvisor.dev/gvisor/pkg/state.Save({0x7e8a46be5fe0, 0xc000a92740}, {0x7e89c478fc78, 0xc001a16880}, {0x144e8a0, 0xc000004408}) \tpkg/state/state.go:103 +0x1c5 gvisor.dev/gvisor/pkg/sentry/kernel.(*Kernel).SaveTo(0xc000004408, {0x1697558, 0xc000a92740}, {0x1674740, 0xc001a16880}, {0x0, 0x0}, {0x0, 0x0}, 0x0, ...) \tpkg/sentry/kernel/kernel.go:710 +0xd6a gvisor.dev/gvisor/pkg/sentry/state.(*SaveOpts).Save(0xc0003b2e40, {0x1697558, 0xc000a92740}, 0xc000004408, 0xc0002ce180) \tpkg/sentry/state/state.go:109 +0x325 gvisor.dev/gvisor/pkg/sentry/control.(*State).SaveWithOpts(0xc001337530, 0xc0003b2e40, 0x1466f14?) \tpkg/sentry/control/state.go:180 +0xb2 gvisor.dev/gvisor/runsc/boot.(*Loader).saveWithOpts(0xc000384008, 0xc0003b2e40, 0xc001490128) \trunsc/boot/restore.go:453 +0x265 gvisor.dev/gvisor/runsc/boot.(*Loader).save(0xc000384008, 0xc0014900e0) \trunsc/boot/restore.go:419 +0x89 gvisor.dev/gvisor/runsc/boot.(*containerManager).Checkpoint(0xc000220740, 0xc0014900e0, 0x0?) \trunsc/boot/controller.go:464 +0x52 reflect.Value.call({0xc0002be660?, 0xc0001fc7a0?, 0xc00063dc18?}, {0x145ae28, 0x4}, {0xc00063dea8, 0x3, 0xc00063dc48?}) \tGOROOT/src/reflect/value.go:584 +0xca6 reflect.Value.Call({0xc0002be660?, 0xc0001fc7a0?, 0xf0?}, {0xc00063dea8?, 0xc0014900e0?, 0x16?}) \tGOROOT/src/reflect/value.go:368 +0xb9 gvisor.dev/gvisor/pkg/urpc.(*Server).handleOne(0xc0002d81e0, 0xc0012a2180) \tpkg/urpc/urpc.go:343 +0x731 gvisor.dev/gvisor/pkg/urpc.(*Server).handleRegistered(...) \tpkg/urpc/urpc.go:454 gvisor.dev/gvisor/pkg/urpc.(*Server).StartHandling.func1() \tpkg/urpc/urpc.go:474 +0x67 created by gvisor.dev/gvisor/pkg/urpc.(*Server).StartHandling in goroutine 392 \tpkg/urpc/urpc.go:472 +0x6b for object tcp.Endpoint{TCPEndpointStateInner:tcp.TCPEndpointStateInner{TSOffset:tcp.TSOffset{milliseconds:0x8020a5db}, SACKPermitted:false, SendTSOk:false, RecentTS:0x0}, TransportEndpointInfo:stack.TransportEndpointInfo{NetProto:0x800, TransProto:0x6, ID:stack.TransportEndpointID{LocalPort:0x873b, LocalAddress:tcpip.Address{addr:[16]uint8{0x15, 0x0, 0x1, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, length:4}, RemotePort:0x1bb, RemoteAddress:tcpip.Address{addr:[16]uint8{0xa, 0x7c, 0xd, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, length:4}}, BindNICID:0, BindAddr:tcpip.Address{addr:[16]uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, length:0}, RegisterNICID:0}, DefaultSocketOptionsHandler:tcpip.DefaultSocketOptionsHandler{}, endpointEntry:tcp.endpointEntry{next:(*tcp.Endpoint)(nil), prev:(*tcp.Endpoint)(nil)}, pendingProcessingMu:tcp.pendingProcessingMutex{mu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}}, pendingProcessing:false, stack:(*stack.Stack)(0xc000581808), protocol:(*tcp.protocol)(0xc0003cb0e0), waiterQueue:(*waiter.Queue)(0xc00230cde0), hardError:(*tcpip.ErrConnectionAborted)(0x324f8a0), lastErrorMu:tcp.lastErrorMutex{mu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}}, lastError:tcpip.Error(nil), rcvQueueMu:tcp.rcvQueueMutex{mu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}}, TCPRcvBufState:tcp.TCPRcvBufState{RcvBufUsed:0, RcvAutoParams:tcp.RcvBufAutoTuneParams{MeasureTime:tcpip.MonotonicTime{nanoseconds:0}, CopiedBytes:0, PrevCopiedBytes:0, RcvBufSize:0, RTT:0, RTTVar:0, RTTMeasureSeqNumber:0x0, RTTMeasureTime:tcpip.MonotonicTime{nanoseconds:0}, Disabled:false}, RcvClosed:false}, rcvMemUsed:atomicbitops.Int32{:sync.NoCopy{}, value:0}, mu:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}, ownedByUser:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, rcvQueue:tcp.segmentList{head:(*tcp.segment)(nil), tail:(*tcp.segment)(nil)}, state:atomicbitops.Uint32{:sync.NoCopy{}, value:0x2}, connectionDirectionState:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, origEndpointState:0x0, isPortReserved:true, isRegistered:true, boundNICID:0, route:(*stack.Route)(0xc00085a300), ipv4TTL:0x0, ipv6HopLimit:-1, isConnectNotified:false, h:(*tcp.handshake)(0xc000987c20), portFlags:ports.Flags{MostRecent:false, LoadBalanced:false, TupleOnly:false}, boundBindToDevice:0, boundPortFlags:ports.Flags{MostRecent:false, LoadBalanced:false, TupleOnly:false}, boundDest:tcpip.FullAddress{NIC:0, Addr:tcpip.Address{addr:[16]uint8{0xa, 0x7c, 0xd, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, length:4}, Port:0x1bb, LinkAddr:""}, effectiveNetProtos:[]tcpip.NetworkProtocolNumber{0x800}, recentTSTime:tcpip.MonotonicTime{nanoseconds:0}, shutdownFlags:0, tcpRecovery:0, sack:tcp.SACKInfo{Blocks:[6]header.SACKBlock{header.SACKBlock{Start:0x0, End:0x0}, header.SACKBlock{Start:0x0, End:0x0}, header.SACKBlock{Start:0x0, End:0x0}, header.SACKBlock{Start:0x0, End:0x0}, header.SACKBlock{Start:0x0, End:0x0}, header.SACKBlock{Start:0x0, End:0x0}}, NumBlocks:0}, delay:0x0, scoreboard:(*tcp.SACKScoreboard)(nil), segmentQueue:tcp.segmentQueue{mu:tcp.segmentQueueMutex{mu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}}, list:tcp.segmentList{head:(*tcp.segment)(nil), tail:(*tcp.segment)(nil)}, ep:(*tcp.Endpoint)(0xc000a7d508), frozen:true}, userMSS:0x0, maxSynRetries:0x6, windowClamp:0x100000, sndQueueInfo:tcp.sndQueueInfo{sndQueueMu:tcp.sndQueueMutex{mu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}}, TCPSndBufState:tcp.TCPSndBufState{SndBufSize:0, SndBufUsed:0, SndClosed:false, PacketTooBigCount:0, SndMTU:2147483647, AutoTuneSndBufDisabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}}}, cc:"reno", keepalive:tcp.keepalive{keepaliveMutex:tcp.keepaliveMutex{mu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}}, idle:7200000000000, interval:75000000000, count:9, unacked:0, timer:tcp.timer{state:1, clock:(*kernel.Timekeeper)(0xc000413e30), target:tcpip.MonotonicTime{nanoseconds:0}, clockTarget:tcpip.MonotonicTime{nanoseconds:0}, timer:tcpip.Timer(nil), callback:(func())(0xb8d7c0)}, waker:sleep.Waker{:sync.NoCopy{}, s:(unsafe.Pointer)(nil), next:(*sleep.Waker)(nil), allWakersNext:(*sleep.Waker)(nil)}}, userTimeout:0, deferAccept:0, acceptMu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}, acceptQueue:tcp.acceptQueue{endpoints:list.List{root:list.Element{next:(*list.Element)(nil), prev:(*list.Element)(nil), list:(*list.List)(nil), Value:interface {}(nil)}, len:0}, pendingEndpoints:map[*tcp.Endpoint]struct {}(nil), capacity:0}, rcv:(*tcp.receiver)(nil), snd:(*tcp.sender)(nil), drainDone:(chan struct {})(nil), undrain:(chan struct {})(nil), probe:(tcp.TCPProbeFunc)(nil), connectingAddress:tcpip.Address{addr:[16]uint8{0xa, 0x7c, 0xd, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, length:4}, amss:0x5b4, sendTOS:0x0, gso:stack.GSO{Type:1, NeedsCsum:true, CsumOffset:0x10, MSS:0x0, L3HdrLen:0x14, MaxSize:0x10000}, stats:tcp.Stats{SegmentsReceived:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, SegmentsSent:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x6}}, FailedConnectionAttempts:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, ReceiveErrors:tcp.ReceiveErrors{ReceiveErrors:tcpip.ReceiveErrors{ReceiveBufferOverflow:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, MalformedPacketsReceived:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, ClosedReceiver:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, ChecksumErrors:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}}, SegmentQueueDropped:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, ChecksumErrors:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, ListenOverflowSynDrop:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, ListenOverflowAckDrop:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, ZeroRcvWindowState:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, WantZeroRcvWindow:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}}, ReadErrors:tcpip.ReadErrors{ReadClosed:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, InvalidEndpointState:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, NotConnected:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}}, SendErrors:tcp.SendErrors{SendErrors:tcpip.SendErrors{SendToNetworkFailed:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, NoRoute:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}}, SegmentSendToNetworkFailed:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, SynSendToNetworkFailed:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, Retransmits:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, FastRetransmit:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, Timeouts:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}}, WriteErrors:tcpip.WriteErrors{WriteClosed:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, InvalidEndpointState:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}, InvalidArgs:tcpip.StatCounter{count:atomicbitops.Uint64{:sync.NoCopy{}, value:0x0}}}}, tcpLingerTimeout:60000000000, closed:false, txHash:0xde1870cc, owner:(*kernel.Task)(0xc001505908), ops:tcpip.SocketOptions{handler:(*tcp.Endpoint)(0xc000a7d508), stackHandler:(*stack.Stack)(0xc000581808), broadcastEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, passCredEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, noChecksumEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, reuseAddressEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, reusePortEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, keepAliveEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, multicastLoopEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x1}, receiveTOSEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, receiveTTLEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, receiveHopLimitEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, receiveTClassEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, receivePacketInfoEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, receiveIPv6PacketInfoEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, hdrIncludedEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, v6OnlyEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, quickAckEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x1}, delayOptionEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x1}, corkOptionEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, receiveOriginalDstAddress:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, ipv4RecvErrEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, ipv6RecvErrEnabled:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}, errQueueMu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}, errQueue:tcpip.sockErrorList{head:(*tcpip.SockError)(nil), tail:(*tcpip.SockError)(nil)}, bindToDevice:atomicbitops.Int32{:sync.NoCopy{}, value:0}, getSendBufferLimits:(tcpip.GetSendBufferLimits)(0xb98f20), sendBufferSize:atomicbitops.Int64{:sync.NoCopy{}, value:1048576}, getReceiveBufferLimits:(tcpip.GetReceiveBufferLimits)(0xb99180), receiveBufferSize:atomicbitops.Int64{:sync.NoCopy{}, value:1048576}, mu:sync.Mutex{m:sync.CrossGoroutineMutex{m:sync.Mutex{:sync.noCopy{}, mu:sync.Mutex{state:0, sema:0x0}}}}, linger:tcpip.LingerOption{Enabled:false, Timeout:0}, rcvlowat:atomicbitops.Int32{:sync.NoCopy{}, value:0}, experimentOptionValue:atomicbitops.Uint32{:sync.NoCopy{}, value:0x0}}, lastOutOfWindowAckTime:tcpip.MonotonicTime{nanoseconds:0}, finWait2Timer:tcpip.Timer(nil), timeWaitTimer:tcpip.Timer(nil), listenCtx:(*tcp.listenContext)(nil), limRdr:(*io.LimitedReader)(0xc001bd9ce0), pmtud:0, alsoBindToV4:false}: goroutine 3057 [running]: gvisor.dev/gvisor/pkg/state.safely.func1() \tpkg/state/state.go:309 +0x170 panic({0x125bf80?, 0xc001595e20?}) \tGOROOT/src/runtime/panic.go:792 +0x132 gvisor.dev/gvisor/pkg/state.Failf(...) \tpkg/state/state.go:269 gvisor.dev/gvisor/pkg/state.(*encodeState).Save(0xc001139c08, {0x144e140?, 0xc000004408?, 0xc001139c08?}) \tpkg/state/encode.go:774 +0x427 gvisor.dev/gvisor/pkg/state.Save.func1() \tpkg/state/state.go:104 +0x8e gvisor.dev/gvisor/pkg/state.safely(0xa694fe?) \tpkg/state/state.go:322 +0x51 gvisor.dev/gvisor/pkg/state.Save({0x7e8a46be5fe0, 0xc000a92740}, {0x7e89c478fc78, 0xc001a16880}, {0x144e8a0, 0xc000004408}) \tpkg/state/state.go:103 +0x1c5 gvisor.dev/gvisor/pkg/sentry/kernel.(*Kernel).SaveTo(0xc000004408, {0x1697558, 0xc000a92740}, {0x1674740, 0xc001a16880}, {0x0, 0x0}, {0x0, 0x0}, 0x0, ...) \tpkg/sentry/kernel/kernel.go:710 +0xd6a gvisor.dev/gvisor/pkg/sentry/state.(*SaveOpts).Save(0xc0003b2e40, {0x1697558, 0xc000a92740}, 0xc000004408, 0xc0002ce180) \tpkg/sentry/state/state.go:109 +0x325 gvisor.dev/gvisor/pkg/sentry/control.(*State).SaveWithOpts(0xc001337530, 0xc0003b2e40, 0x1466f14?) \tpkg/sentry/control/state.go:180 +0xb2 gvisor.dev/gvisor/runsc/boot.(*Loader).saveWithOpts(0xc000384008, 0xc0003b2e40, 0xc001490128) \trunsc/boot/restore.go:453 +0x265 gvisor.dev/gvisor/runsc/boot.(*Loader).save(0xc000384008, 0xc0014900e0) \trunsc/boot/restore.go:419 +0x89 gvisor.dev/gvisor/runsc/boot.(*containerManager).Checkpoint(0xc000220740, 0xc0014900e0, 0x0?) \trunsc/boot/controller.go:464 +0x52 reflect.Value.call({0xc0002be660?, 0xc0001fc7a0?, 0xc00063dc18?}, {0x145ae28, 0x4}, {0xc00063dea8, 0x3, 0xc00063dc48?}) \tGOROOT/src/reflect/value.go:584 +0xca6 reflect.Value.Call({0xc0002be660?, 0xc0001fc7a0?, 0xf0?}, {0xc00063dea8?, 0xc0014900e0?, 0x16?}) \tGOROOT/src/reflect/value.go:368 +0xb9 gvisor.dev/gvisor/pkg/urpc.(*Server).handleOne(0xc0002d81e0, 0xc0012a2180) \tpkg/urpc/urpc.go:343 +0x731 gvisor.dev/gvisor/pkg/urpc.(*Server).handleRegistered(...) \tpkg/urpc/urpc.go:454 gvisor.dev/gvisor/pkg/urpc.(*Server).StartHandling.func1() \tpkg/urpc/urpc.go:474 +0x67 created by gvisor.dev/gvisor/pkg/urpc.(*Server).StartHandling in goroutine 392 \tpkg/urpc/urpc.go:472 +0x6b ``` ``` 0130 11:50:36.087642 1 cli.go:189] Version release-20250820.0-120-g6bf3c4885132-dirty, go1.24.1, amd64, 180 CPUs, linux, PID 1, PPID 0, UID 0, GID 0 D0130 11:50:36.087661 1 cli.go:190] Page size: 0x1000 (4096 bytes) I0130 11:50:36.087676 1 cli.go:191] Args: [runsc-sandbox --root=/var/run/runsc --debug=true --debug-log=/dev/shm/sandboxing-debug/meager-eager-tidy-chin/runsc/ --file-access=shared --overlay2=none --network=sandbox --net-raw=true --net-disconnect-ok=true --systrap-disable-syscall-patching=true --debug-log-fd=3 boot --bundle=/dev/shm/sandboxing/meager-eager-tidy-chin --gofer-mount-confs=lisafs:none,lisafs:none,lisafs:none --apply-caps=true --setup-root --total-host-memory 760451858432 --cpu-num 4 --total-memory 74088185856 --attached --io-fds=4 --io-fds=5 --io-fds=6 --dev-io-fd=-1 --mounts-fd=7 --start-sync-fd=8 --controller-fd=9 --spec-fd=10 --stdio-fds=11 --stdio-fds=12 --stdio-fds=13 meager-eager-tidy-chin] I0130 11:50:36.087706 1 config.go:461] Platform: systrap I0130 11:50:36.087735 1 config.go:462] RootDir: /var/run/runsc I0130 11:50:36.087747 1 config.go:463] FileAccess: shared / Directfs: true / Overlay: none I0130 11:50:36.087762 1 config.go:464] Network: sandbox I0130 11:50:36.087774 1 config.go:466] Debug: true. Strace: false, max size: 1024, syscalls: W0130 11:50:36.087785 1 config.go:469] --allow-suid is disabled, SUID/SGID bits on executables will be ignored. D0130 11:50:36.087799 1 config.go:487] Config.RootDir (--root): /var/run/runsc D0130 11:50:36.087813 1 config.go:487] Config.Traceback (--traceback): system D0130 11:50:36.087831 1 config.go:487] Config.Debug (--debug): true D0130 11:50:36.087842 1 config.go:487] Config.LogFilename (--log): (empty) D0130 11:50:36.087877 1 config.go:487] Config.LogFormat (--log-format): text D0130 11:50:36.087887 1 config.go:487] Config.DebugLog (--debug-log): /dev/shm/sandboxing-debug/meager-eager-tidy-chin/runsc/ D0130 11:50:36.087898 1 config.go:487] Config.DebugToUserLog (--debug-to-user-log): false D0130 11:50:36.087908 1 config.go:487] Config.DebugCommand (--debug-command): (empty) D0130 11:50:36.087918 1 config.go:487] Config.PanicLog (--panic-log): (empty) D0130 11:50:36.087932 1 config.go:487] Config.CoverageReport (--coverage-report): (empty) D0130 11:50:36.087942 1 config.go:487] Config.DebugLogFormat (--debug-log-format): text D0130 11:50:36.087953 1 config.go:487] Config.FileAccess (--file-access): shared D0130 11:50:36.087965 1 config.go:487] Config.FileAccessMounts (--file-access-mounts): shared D0130 11:50:36.087975 1 config.go:487] Config.Overlay (--overlay): false D0130 11:50:36.087986 1 config.go:487] Config.Overlay2 (--overlay2): none D0130 11:50:36.087997 1 config.go:487] Config.FSGoferHostUDS (--fsgofer-host-uds): false D0130 11:50:36.088014 1 config.go:487] Config.HostUDS (--host-uds): none D0130 11:50:36.088031 1 config.go:487] Config.HostFifo (--host-fifo): none D0130 11:50:36.088043 1 config.go:487] Config.HostSettings (--host-settings): check D0130 11:50:36.088052 1 config.go:487] Config.Network (--network): sandbox D0130 11:50:36.088060 1 config.go:487] Config.EnableRaw (--net-raw): true D0130 11:50:36.088067 1 config.go:487] Config.AllowPacketEndpointWrite (--TESTONLY-allow-packet-endpoint-write): false D0130 11:50:36.088075 1 config.go:487] Config.HostGSO (--gso): true D0130 11:50:36.088082 1 config.go:487] Config.GVisorGSO (--software-gso): true D0130 11:50:36.088090 1 config.go:487] Config.GVisorGRO (--gvisor-gro): false D0130 11:50:36.088097 1 config.go:487] Config.TXChecksumOffload (--tx-checksum-offload): false D0130 11:50:36.088105 1 config.go:487] Config.RXChecksumOffload (--rx-checksum-offload): true D0130 11:50:36.088113 1 config.go:487] Config.QDisc (--qdisc): fifo D0130 11:50:36.088121 1 config.go:487] Config.LogPackets (--log-packets): false D0130 11:50:36.088132 1 config.go:487] Config.PCAP (--pcap-log): (empty) D0130 11:50:36.088148 1 config.go:487] Config.Platform (--platform): systrap D0130 11:50:36.088159 1 config.go:487] Config.PlatformDevicePath (--platform_device_path): (empty) D0130 11:50:36.088170 1 config.go:487] Config.MetricServer (--metric-server): (empty) D0130 11:50:36.088181 1 config.go:487] Config.FinalMetricsLog (--final-metrics-log): (empty) D0130 11:50:36.088190 1 config.go:487] Config.ProfilingMetrics (--profiling-metrics): (empty) D0130 11:50:36.088199 1 config.go:487] Config.ProfilingMetricsLog (--profiling-metrics-log): (empty) D0130 11:50:36.088209 1 config.go:487] Config.ProfilingMetricsRate (--profiling-metrics-rate-us): 1000 D0130 11:50:36.088219 1 config.go:487] Config.Strace (--strace): false D0130 11:50:36.088228 1 config.go:487] Config.StraceSyscalls (--strace-syscalls): (empty) D0130 11:50:36.088238 1 config.go:487] Config.StraceLogSize (--strace-log-size): 1024 D0130 11:50:36.088247 1 config.go:487] Config.StraceEvent (--strace-event): false D0130 11:50:36.088255 1 config.go:489] Config.DisableSeccomp: false D0130 11:50:36.088272 1 config.go:487] Config.EnableCoreTags (--enable-core-tags): false D0130 11:50:36.088285 1 config.go:487] Config.WatchdogAction (--watchdog-action): logWarning D0130 11:50:36.088302 1 config.go:487] Config.PanicSignal (--panic-signal): -1 D0130 11:50:36.088312 1 config.go:487] Config.ProfileEnable (--profile): false D0130 11:50:36.088322 1 config.go:487] Config.ProfileBlock (--profile-block): (empty) D0130 11:50:36.088333 1 config.go:487] Config.ProfileCPU (--profile-cpu): (empty) D0130 11:50:36.088343 1 config.go:487] Config.ProfileGCInterval (--profile-gc-interval): 0s D0130 11:50:36.088359 1 config.go:487] Config.ProfileHeap (--profile-heap): (empty) D0130 11:50:36.088369 1 config.go:487] Config.ProfileMutex (--profile-mutex): (empty) D0130 11:50:36.088379 1 config.go:487] Config.TraceFile (--trace): (empty) D0130 11:50:36.088393 1 config.go:487] Config.NumNetworkChannels (--num-network-channels): 1 D0130 11:50:36.088404 1 config.go:487] Config.NetworkProcessorsPerChannel (--network-processors-per-channel): 0 D0130 11:50:36.088414 1 config.go:487] Config.Rootless (--rootless): false D0130 11:50:36.088424 1 config.go:487] Config.AlsoLogToStderr (--alsologtostderr): false D0130 11:50:36.088436 1 config.go:487] Config.ReferenceLeak (--ref-leak-mode): disabled D0130 11:50:36.088447 1 config.go:487] Config.CPUNumFromQuota (--cpu-num-from-quota): true D0130 11:50:36.088457 1 config.go:487] Config.AllowFlagOverride (--allow-flag-override): false D0130 11:50:36.088466 1 config.go:487] Config.OCISeccomp (--oci-seccomp): false D0130 11:50:36.088475 1 config.go:487] Config.IgnoreCgroups (--ignore-cgroups): false D0130 11:50:36.088485 1 config.go:487] Config.SystemdCgroup (--systemd-cgroup): false D0130 11:50:36.088496 1 config.go:487] Config.PodInitConfig (--pod-init-config): (empty) D0130 11:50:36.088503 1 config.go:487] Config.BufferPooling (--buffer-pooling): true D0130 11:50:36.088511 1 config.go:487] Config.XDP (--EXPERIMENTAL-xdp): {0 } D0130 11:50:36.088520 1 config.go:487] Config.AFXDPUseNeedWakeup (--EXPERIMENTAL-xdp-need-wakeup): true D0130 11:50:36.088528 1 config.go:487] Config.FDLimit (--fdlimit): -1 D0130 11:50:36.088535 1 config.go:487] Config.DCache (--dcache): -1 D0130 11:50:36.088544 1 config.go:487] Config.IOUring (--iouring): false D0130 11:50:36.088554 1 config.go:487] Config.DirectFS (--directfs): true D0130 11:50:36.088564 1 config.go:487] Config.AppHugePages (--app-huge-pages): true D0130 11:50:36.088574 1 config.go:487] Config.NVProxy (--nvproxy): false D0130 11:50:36.088583 1 config.go:487] Config.NVProxyDocker (--nvproxy-docker): false D0130 11:50:36.088592 1 config.go:487] Config.NVProxyDriverVersion (--nvproxy-driver-version): (empty) D0130 11:50:36.088609 1 config.go:487] Config.NVProxyAllowedDriverCapabilities (--nvproxy-allowed-driver-capabilities): utility,compute D0130 11:50:36.088618 1 config.go:487] Config.TPUProxy (--tpuproxy): false D0130 11:50:36.088630 1 config.go:487] Config.TestOnlyAllowRunAsCurrentUserWithoutChroot (--TESTONLY-unsafe-nonroot): false D0130 11:50:36.088637 1 config.go:487] Config.TestOnlyTestNameEnv (--TESTONLY-test-name-env): (empty) D0130 11:50:36.088645 1 config.go:487] Config.TestOnlyAFSSyscallPanic (--TESTONLY-afs-syscall-panic): false D0130 11:50:36.088653 1 config.go:489] Config.explicitlySet: <map[string]struct {} Value> (unexported) D0130 11:50:36.088661 1 config.go:487] Config.ReproduceNAT (--reproduce-nat): false D0130 11:50:36.088669 1 config.go:487] Config.ReproduceNftables (--reproduce-nftables): false D0130 11:50:36.088681 1 config.go:487] Config.NetDisconnectOk (--net-disconnect-ok): true D0130 11:50:36.088689 1 config.go:487] Config.TestOnlyAutosaveImagePath (--TESTONLY-autosave-image-path): (empty) D0130 11:50:36.088697 1 config.go:487] Config.TestOnlyAutosaveResume (--TESTONLY-autosave-resume): false D0130 11:50:36.088704 1 config.go:487] Config.RestoreSpecValidation (--restore-spec-validation): enforce D0130 11:50:36.088713 1 config.go:487] Config.GVisorMarkerFile (--gvisor-marker-file): false D0130 11:50:36.088721 1 config.go:487] Config.SystrapDisableSyscallPatching (--systrap-disable-syscall-patching): true D0130 11:50:36.088728 1 config.go:487] Config.SaveRestoreNetstack (--save-restore-netstack): true D0130 11:50:36.088735 1 config.go:487] Config.Nftables (--TESTONLY-nftables): false D0130 11:50:36.088742 1 config.go:487] Config.AllowSUID (--allow-suid): false D0130 11:50:36.088752 1 cli.go:197] runsc process spawned at 11:50:36.086274, Go started execution at 11:50:36.087214. Startup overhead: 939.687µs I0130 11:50:36.088767 1 cli.go:200] **************** gVisor **************** I0130 11:50:36.089555 1 boot.go:283] Setting product_name: "Google Compute Engine" I0130 11:50:36.089742 1 boot.go:294] Setting host-thp-shmem-enabled: "never" I0130 11:50:36.089800 1 boot.go:304] Setting host-thp-defrag: "defer" I0130 11:50:36.090725 1 chroot.go:162] Setting up sandbox chroot in "/tmp" I0130 11:50:36.102251 1 chroot.go:37] Mounting "proc" at "/tmp/proc/sandbox-proc" D0130 11:50:36.125546 1 specutils.go:114] Spec: ``` FUTURE_COPYBARA_INTEGRATE_REVIEW=#12567 from nt:claude/fix-turbine-orch-error-X0OIm d8c4fa8 PiperOrigin-RevId: 865007585
1 parent 387f068 commit 8a12098

File tree

2 files changed

+108
-5
lines changed

2 files changed

+108
-5
lines changed

pkg/tcpip/transport/tcp/connect.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,12 +1081,26 @@ func (e *Endpoint) resetConnectionLocked(err tcpip.Error) {
10811081
//
10821082
// See: https://www.snellman.net/blog/archive/2016-02-01-tcp-rst/ for more
10831083
// information.
1084-
sndWndEnd := e.snd.SndUna.Add(e.snd.SndWnd)
1085-
resetSeqNum := sndWndEnd
1086-
if !sndWndEnd.LessThan(e.snd.SndNxt) || e.snd.SndNxt.Size(sndWndEnd) < (1<<e.snd.SndWndScale) {
1087-
resetSeqNum = e.snd.SndNxt
1084+
//
1085+
// e.snd and e.rcv may be nil if the endpoint is in a handshake
1086+
// state (e.g. SynSent) where the sender and receiver have not
1087+
// yet been initialized. Per Linux behavior, use a sequence
1088+
// number of zero when no ACK has been received (snd is nil),
1089+
// and a receive window of zero when rcv is nil since the
1090+
// connection will be immediately terminated.
1091+
var resetSeqNum seqnum.Value
1092+
var ackNum seqnum.Value
1093+
if e.snd != nil {
1094+
sndWndEnd := e.snd.SndUna.Add(e.snd.SndWnd)
1095+
resetSeqNum = sndWndEnd
1096+
if !sndWndEnd.LessThan(e.snd.SndNxt) || e.snd.SndNxt.Size(sndWndEnd) < (1<<e.snd.SndWndScale) {
1097+
resetSeqNum = e.snd.SndNxt
1098+
}
1099+
}
1100+
if e.rcv != nil {
1101+
ackNum = e.rcv.RcvNxt
10881102
}
1089-
e.sendEmptyRaw(header.TCPFlagAck|header.TCPFlagRst, resetSeqNum, e.rcv.RcvNxt, 0)
1103+
e.sendEmptyRaw(header.TCPFlagAck|header.TCPFlagRst, resetSeqNum, ackNum, 0)
10901104
}
10911105
// Don't purge read queues here. If there's buffered data, it's still allowed
10921106
// to be read.

pkg/tcpip/transport/tcp/test/e2e/tcp_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9576,6 +9576,95 @@ func TestSetExperimentOptionWithOptionDisabled(t *testing.T) {
95769576
checker.IPv4(t, v, checker.IPv4Options(want))
95779577
}
95789578

9579+
func TestCloseInSynRecvWithLinger(t *testing.T) {
9580+
c := context.New(t, e2e.DefaultMTU)
9581+
defer c.Cleanup()
9582+
9583+
// Create an endpoint, don't handshake because we want to interfere with the
9584+
// handshake process.
9585+
c.Create(-1)
9586+
9587+
// Set SO_LINGER with 0 timeout.
9588+
l := tcpip.LingerOption{Enabled: true, Timeout: 0}
9589+
c.EP.(*tcp.Endpoint).SocketOptions().SetLinger(l)
9590+
9591+
// Start connection attempt.
9592+
waitEntry, _ := waiter.NewChannelEntry(waiter.EventHUp)
9593+
c.WQ.EventRegister(&waitEntry)
9594+
defer c.WQ.EventUnregister(&waitEntry)
9595+
9596+
addr := tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}
9597+
{
9598+
err := c.EP.Connect(addr)
9599+
if d := cmp.Diff(&tcpip.ErrConnectStarted{}, err); d != "" {
9600+
t.Fatalf("Connect(...) mismatch (-want +got):\n%s", d)
9601+
}
9602+
}
9603+
9604+
// Receive SYN packet.
9605+
v := c.GetPacket()
9606+
defer v.Release()
9607+
checker.IPv4(t, v,
9608+
checker.TCP(
9609+
checker.DstPort(context.TestPort),
9610+
checker.TCPFlags(header.TCPFlagSyn),
9611+
),
9612+
)
9613+
9614+
if got, want := tcp.EndpointState(c.EP.State()), tcp.StateSynSent; got != want {
9615+
t.Fatalf("got State() = %s, want %s", got, want)
9616+
}
9617+
tcpHdr := header.TCP(header.IPv4(v.AsSlice()).Payload())
9618+
c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
9619+
9620+
// Send SYN instead of SYN-ACK to trigger simultaneous open and move
9621+
// endpoint to SYN-RCVD state.
9622+
iss := seqnum.Value(context.TestInitialSequenceNumber)
9623+
c.SendPacket(nil, &context.Headers{
9624+
SrcPort: tcpHdr.DestinationPort(),
9625+
DstPort: tcpHdr.SourcePort(),
9626+
Flags: header.TCPFlagSyn,
9627+
SeqNum: iss,
9628+
RcvWnd: 30000,
9629+
})
9630+
9631+
// Receive SYN-ACK from endpoint.
9632+
v = c.GetPacket()
9633+
defer v.Release()
9634+
checker.IPv4(t, v,
9635+
checker.TCP(
9636+
checker.DstPort(context.TestPort),
9637+
checker.TCPFlags(header.TCPFlagSyn|header.TCPFlagAck),
9638+
checker.TCPAckNum(uint32(iss)+1),
9639+
),
9640+
)
9641+
9642+
if got, want := tcp.EndpointState(c.EP.State()), tcp.StateSynRecv; got != want {
9643+
t.Fatalf("got State() = %s, want %s", got, want)
9644+
}
9645+
9646+
c.EP.Close()
9647+
9648+
// With SO_LINGER enabled and timeout 0, Close() should cause an RST to
9649+
// be sent. As the endpoint is not established, it should have snd and rcv
9650+
// fields as nil, which should cause the RST packet to have sequence number
9651+
// and receive window size to be zero.
9652+
v = c.GetPacket()
9653+
defer v.Release()
9654+
checker.IPv4(t, v,
9655+
checker.TCP(
9656+
checker.DstPort(context.TestPort),
9657+
checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck),
9658+
checker.TCPSeqNum(0),
9659+
checker.TCPWindow(0),
9660+
),
9661+
)
9662+
9663+
if got, want := tcp.EndpointState(c.EP.State()), tcp.StateError; got != want {
9664+
t.Fatalf("got State() = %s, want %s", got, want)
9665+
}
9666+
}
9667+
95799668
func TestMain(m *testing.M) {
95809669
refs.SetLeakMode(refs.LeaksPanic)
95819670
code := m.Run()

0 commit comments

Comments
 (0)