From 2044c3449153acc33a5adf172a478d3d55221bdd Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Tue, 9 May 2023 15:17:40 -0700 Subject: [PATCH] Don't hold streamQueueReceiver.mu while calling RightsControlMessage.Release(). This leads to lock order violations. Reported-by: syzbot+c8a2ae926db29417b836@syzkaller.appspotmail.com PiperOrigin-RevId: 530726950 --- pkg/sentry/socket/unix/transport/unix.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/sentry/socket/unix/transport/unix.go b/pkg/sentry/socket/unix/transport/unix.go index 58d2c6409..3b865950a 100644 --- a/pkg/sentry/socket/unix/transport/unix.go +++ b/pkg/sentry/socket/unix/transport/unix.go @@ -504,6 +504,15 @@ func (q *streamQueueReceiver) RecvMaxQueueSize() int64 { // Recv implements Receiver.Recv. func (q *streamQueueReceiver) Recv(ctx context.Context, data [][]byte, wantCreds bool, numRights int, peek bool) (int64, int64, ControlMessages, bool, Address, bool, *syserr.Error) { + // RightsControlMessages must be released without q.mu held. We do this in a + // defer to simplify control flow logic. + var rightsToRelease []RightsControlMessage + defer func() { + for _, rcm := range rightsToRelease { + rcm.Release(ctx) + } + }() + q.mu.Lock() defer q.mu.Unlock() @@ -549,7 +558,7 @@ func (q *streamQueueReceiver) Recv(ctx context.Context, data [][]byte, wantCreds var cmTruncated bool if c.Rights != nil && numRights == 0 { - c.Rights.Release(ctx) + rightsToRelease = append(rightsToRelease, c.Rights) c.Rights = nil cmTruncated = true } @@ -604,7 +613,7 @@ func (q *streamQueueReceiver) Recv(ctx context.Context, data [][]byte, wantCreds // Consume rights. if numRights == 0 { cmTruncated = true - q.control.Rights.Release(ctx) + rightsToRelease = append(rightsToRelease, q.control.Rights) } else { c.Rights = q.control.Rights haveRights = true