From 0301bb07efabc1b6e441727814fce25cf8a847ca Mon Sep 17 00:00:00 2001 From: Zach Koopmans Date: Mon, 13 Jun 2022 10:48:51 -0700 Subject: [PATCH] [bugs] Don't hold root taskset mutex when starting kernel tasks. Holding the kernel.taskSetRWMutex isn't necessary while calling t.Start() and doing so can cause a nested locking error. We only need to make sure start is called on each task once. PiperOrigin-RevId: 454648122 --- pkg/sentry/kernel/kernel.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 623e96ba4..c2973adcc 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -1122,11 +1122,18 @@ func (k *Kernel) Start() error { // Kernel.SaveTo and need to be resumed. If k was created by NewKernel, // this is a no-op. k.resumeTimeLocked(k.SupervisorContext()) - // Start task goroutines. k.tasks.mu.RLock() - defer k.tasks.mu.RUnlock() - for t, tid := range k.tasks.Root.tids { - t.Start(tid) + ts := make([]*Task, 0, len(k.tasks.Root.tids)) + for t := range k.tasks.Root.tids { + ts = append(ts, t) + } + k.tasks.mu.RUnlock() + // Start task goroutines. + // NOTE(b/235349091): We don't actually need the TaskSet mutex, we just + // need to make sure we only call t.Start() once for each task. Holding the + // mutex for each task start may cause a nested locking error. + for _, t := range ts { + t.Start(t.ThreadID()) } return nil }