Fix TOCTOU MSG_PEEK bug in endpoint read methods.

This fixes a race condition where peeking a packet did not increment
its reference count before releasing the queue mutex.

PiperOrigin-RevId: 964890164
This commit is contained in:
Nayana Bidari
2026-08-14 14:29:32 -07:00
committed by gVisor bot
parent 3260327039
commit c439f8a028
4 changed files with 16 additions and 8 deletions
+4 -2
View File
@@ -176,11 +176,13 @@ func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult
}
p := e.rcvList.Front()
if !opts.Peek {
if opts.Peek {
p.data.IncRef()
} else {
e.rcvList.Remove(p)
defer p.data.DecRef()
e.rcvBufSize -= p.data.Data().Size()
}
defer p.data.DecRef()
e.rcvMu.Unlock()
+4 -2
View File
@@ -195,11 +195,13 @@ func (ep *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResul
}
packet := ep.rcvList.Front()
if !opts.Peek {
if opts.Peek {
packet.data.IncRef()
} else {
ep.rcvList.Remove(packet)
defer packet.data.DecRef()
ep.rcvBufSize -= packet.data.Size()
}
defer packet.data.DecRef()
ep.rcvMu.Unlock()
+4 -2
View File
@@ -236,11 +236,13 @@ func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult
}
pkt := e.rcvList.Front()
if !opts.Peek {
if opts.Peek {
pkt.data.IncRef()
} else {
e.rcvList.Remove(pkt)
defer pkt.data.DecRef()
e.rcvBufSize -= pkt.data.Data().Size()
}
defer pkt.data.DecRef()
e.rcvMu.Unlock()
+4 -2
View File
@@ -232,11 +232,13 @@ func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult
}
p := e.rcvList.Front()
if !opts.Peek {
if opts.Peek {
p.pkt.IncRef()
} else {
e.rcvList.Remove(p)
defer p.pkt.DecRef()
e.rcvBufSize -= p.pkt.Data().Size()
}
defer p.pkt.DecRef()
e.rcvMu.Unlock()
// Control Messages