From 604233c9f66914f149e8e77582a4c13db75483b1 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 19 May 2022 18:27:34 -0700 Subject: [PATCH] kernel: use lockdep mutexes PiperOrigin-RevId: 449877248 --- pkg/sentry/kernel/BUILD | 66 ++++++++++++++++++++++++ pkg/sentry/kernel/auth/BUILD | 13 +++++ pkg/sentry/kernel/auth/id_map.go | 4 +- pkg/sentry/kernel/auth/user_namespace.go | 3 +- pkg/sentry/kernel/cgroup.go | 3 +- pkg/sentry/kernel/epoll/BUILD | 25 +++++++++ pkg/sentry/kernel/epoll/epoll.go | 4 +- pkg/sentry/kernel/fd_table.go | 3 +- pkg/sentry/kernel/futex/BUILD | 13 +++++ pkg/sentry/kernel/futex/futex.go | 9 ++-- pkg/sentry/kernel/kernel.go | 6 +-- pkg/sentry/kernel/pipe/BUILD | 37 +++++++++++++ pkg/sentry/kernel/pipe/pipe.go | 3 +- pkg/sentry/kernel/pipe/pipe_unsafe.go | 4 +- pkg/sentry/kernel/pipe/vfs.go | 2 +- pkg/sentry/kernel/sessions.go | 8 +-- pkg/sentry/kernel/signal_handlers.go | 3 +- pkg/sentry/kernel/signalfd/BUILD | 14 ++++- pkg/sentry/kernel/signalfd/signalfd.go | 3 +- pkg/sentry/kernel/task.go | 2 +- pkg/sentry/kernel/task_cgroup.go | 4 +- pkg/sentry/kernel/thread_group.go | 6 +-- pkg/sentry/kernel/threads.go | 2 +- 23 files changed, 198 insertions(+), 39 deletions(-) diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 6249de0bf..c53b54742 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,8 +1,65 @@ load("//tools:defs.bzl", "go_library", "go_test", "proto_library") load("//tools/go_generics:defs.bzl", "go_template_instance") +load("//pkg/sync/locking:locking.bzl", "declare_mutex", "declare_rwmutex") package(licenses = ["notice"]) +declare_mutex( + name = "user_counters_mutex", + out = "user_counters_mutex.go", + package = "kernel", + prefix = "userCounters", +) + +declare_rwmutex( + name = "taskset_mutex", + out = "taskset_mutex.go", + package = "kernel", + prefix = "taskSet", +) + +declare_mutex( + name = "task_mutex", + out = "task_mutex.go", + package = "kernel", + prefix = "task", +) + +declare_mutex( + name = "cgroup_mutex", + out = "cgroup_mutex.go", + package = "kernel", + prefix = "cgroup", +) + +declare_mutex( + name = "fd_table_mutex", + out = "fd_table_mutex.go", + package = "kernel", + prefix = "fdTable", +) + +declare_mutex( + name = "running_tasks_mutex", + out = "running_tasks_mutex.go", + package = "kernel", + prefix = "runningTasks", +) + +declare_mutex( + name = "signal_handlers_mutex", + out = "signal_handlers_mutex.go", + package = "kernel", + prefix = "signalHandlers", +) + +declare_mutex( + name = "thread_group_timer_mutex", + out = "thread_group_timer_mutex.go", + package = "kernel", + prefix = "threadGroupTimer", +) + go_template_instance( name = "pending_signals_list", out = "pending_signals_list.go", @@ -142,8 +199,10 @@ go_library( "abstract_socket_namespace.go", "aio.go", "cgroup.go", + "cgroup_mutex.go", "context.go", "fd_table.go", + "fd_table_mutex.go", "fd_table_refs.go", "fd_table_unsafe.go", "fs_context.go", @@ -165,6 +224,7 @@ go_library( "ptrace_amd64.go", "ptrace_arm64.go", "rseq.go", + "running_tasks_mutex.go", "seccheck.go", "seccomp.go", "seqatomic_taskgoroutineschedinfo_unsafe.go", @@ -173,6 +233,7 @@ go_library( "sessions.go", "signal.go", "signal_handlers.go", + "signal_handlers_mutex.go", "socket_list.go", "syscalls.go", "syscalls_state.go", @@ -190,6 +251,7 @@ go_library( "task_image.go", "task_list.go", "task_log.go", + "task_mutex.go", "task_net.go", "task_run.go", "task_sched.go", @@ -199,12 +261,15 @@ go_library( "task_syscall.go", "task_usermem.go", "task_work.go", + "taskset_mutex.go", "thread_group.go", + "thread_group_timer_mutex.go", "threads.go", "threads_impl.go", "timekeeper.go", "timekeeper_state.go", "tty.go", + "user_counters_mutex.go", "uts_namespace.go", "vdso.go", "version.go", @@ -286,6 +351,7 @@ go_library( "//pkg/state/statefile", "//pkg/state/wire", "//pkg/sync", + "//pkg/sync/locking", "//pkg/syserr", "//pkg/tcpip", "//pkg/tcpip/stack", diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index 73c906136..51827d147 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -42,6 +42,17 @@ go_template_instance( }, ) +go_template_instance( + name = "user_namespace_mutex", + out = "user_namespace_mutex.go", + package = "auth", + prefix = "userNamespace", + substrs = { + "genericMark": "userNamespace", + }, + template = "//pkg/sync/locking:generic_mutex", +) + go_library( name = "auth", srcs = [ @@ -56,6 +67,7 @@ go_library( "id_map_range.go", "id_map_set.go", "user_namespace.go", + "user_namespace_mutex.go", ], marshal = True, visibility = ["//pkg/sentry:internal"], @@ -68,5 +80,6 @@ go_library( "//pkg/sentry/seccheck", "//pkg/sentry/seccheck/points:points_go_proto", "//pkg/sync", + "//pkg/sync/locking", ], ) diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index 5c33009c9..59b407c13 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -69,8 +69,8 @@ func (ns *UserNamespace) mapID(m *idMapSet, id uint32) uint32 { // // Preconditions: end >= start. func (ns *UserNamespace) allIDsMapped(m *idMapSet, start, end uint32) bool { - ns.mu.Lock() - defer ns.mu.Unlock() + ns.mu.NestedLock() + defer ns.mu.NestedUnlock() return m.SpanRange(idMapRange{start, end}) == end-start } diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index 40a406f9d..1f9151657 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -18,7 +18,6 @@ import ( "math" "gvisor.dev/gvisor/pkg/errors/linuxerr" - "gvisor.dev/gvisor/pkg/sync" ) // A UserNamespace represents a user namespace. See user_namespaces(7) for @@ -38,7 +37,7 @@ type UserNamespace struct { // // If mu will be locked in multiple UserNamespaces, it must be locked in // descendant namespaces before ancestors. - mu sync.Mutex `state:"nosave"` + mu userNamespaceMutex `state:"nosave"` // Mappings of user/group IDs between this namespace and its parent. // diff --git a/pkg/sentry/kernel/cgroup.go b/pkg/sentry/kernel/cgroup.go index 98f48ee8a..511f8fbdb 100644 --- a/pkg/sentry/kernel/cgroup.go +++ b/pkg/sentry/kernel/cgroup.go @@ -23,7 +23,6 @@ import ( "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs" "gvisor.dev/gvisor/pkg/sentry/vfs" - "gvisor.dev/gvisor/pkg/sync" ) // InvalidCgroupHierarchyID indicates an uninitialized hierarchy ID. @@ -218,7 +217,7 @@ type CgroupRegistry struct { // lastHierarchyID atomicbitops.Uint32 - mu sync.Mutex `state:"nosave"` + mu cgroupMutex `state:"nosave"` // controllers is the set of currently known cgroup controllers on the // system. Protected by mu. diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 723a85f64..7e08f22a5 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -3,6 +3,28 @@ load("//tools/go_generics:defs.bzl", "go_template_instance") package(licenses = ["notice"]) +go_template_instance( + name = "epoll_mutex", + out = "epoll_mutex.go", + package = "epoll", + prefix = "epoll", + substrs = { + "genericMark": "epoll", + }, + template = "//pkg/sync/locking:generic_mutex", +) + +go_template_instance( + name = "epoll_list_mutex", + out = "epoll_list_mutex.go", + package = "epoll", + prefix = "epollList", + substrs = { + "genericMark": "epollList", + }, + template = "//pkg/sync/locking:generic_mutex", +) + go_template_instance( name = "epoll_list", out = "epoll_list.go", @@ -20,6 +42,8 @@ go_library( srcs = [ "epoll.go", "epoll_list.go", + "epoll_list_mutex.go", + "epoll_mutex.go", "epoll_state.go", ], visibility = ["//pkg/sentry:internal"], @@ -31,6 +55,7 @@ go_library( "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sync", + "//pkg/sync/locking", "//pkg/usermem", "//pkg/waiter", "@org_golang_x_sys//unix:go_default_library", diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index 09425c10b..7ab08a73e 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -109,7 +109,7 @@ type EventPoll struct { // files is the map of all the files currently being observed, it is // protected by mu. - mu sync.Mutex `state:"nosave"` + mu epollMutex `state:"nosave"` files map[FileIdentifier]*pollEntry // listsMu protects manipulation of the lists below. It needs to be a @@ -129,7 +129,7 @@ type EventPoll struct { // called on it before it gets moved to the readyList. // disabledList -- when the entry is disabled. This happens when // a one-shot entry gets delivered via readEvents(). - listsMu sync.Mutex `state:"nosave"` + listsMu epollListMutex `state:"nosave"` readyList pollEntryList waitingList pollEntryList disabledList pollEntryList diff --git a/pkg/sentry/kernel/fd_table.go b/pkg/sentry/kernel/fd_table.go index 28e9fc49c..258d23580 100644 --- a/pkg/sentry/kernel/fd_table.go +++ b/pkg/sentry/kernel/fd_table.go @@ -28,7 +28,6 @@ import ( "gvisor.dev/gvisor/pkg/sentry/fs/lock" "gvisor.dev/gvisor/pkg/sentry/limits" "gvisor.dev/gvisor/pkg/sentry/vfs" - "gvisor.dev/gvisor/pkg/sync" ) // FDFlags define flags for an individual descriptor. @@ -85,7 +84,7 @@ type FDTable struct { k *Kernel // mu protects below. - mu sync.Mutex `state:"nosave"` + mu fdTableMutex `state:"nosave"` // fdBitmap shows which fds are already in use. fdBitmap bitmap.Bitmap `state:"nosave"` diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index c5078fd26..11bfe8e5d 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -3,6 +3,17 @@ load("//tools/go_generics:defs.bzl", "go_template_instance") package(licenses = ["notice"]) +go_template_instance( + name = "futex_mutex", + out = "futex_mutex.go", + package = "futex", + prefix = "futexBucket", + substrs = { + "genericMark": "futexBucket", + }, + template = "//pkg/sync/locking:generic_mutex", +) + go_template_instance( name = "atomicptr_bucket", out = "atomicptr_bucket_unsafe.go", @@ -31,6 +42,7 @@ go_library( srcs = [ "atomicptr_bucket_unsafe.go", "futex.go", + "futex_mutex.go", "waiter_list.go", ], visibility = ["//pkg/sentry:internal"], @@ -42,6 +54,7 @@ go_library( "//pkg/log", "//pkg/sentry/memmap", "//pkg/sync", + "//pkg/sync/locking", "//pkg/usermem", ], ) diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index 5783519c0..6e6687ec4 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -23,7 +23,6 @@ import ( "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/hostarch" "gvisor.dev/gvisor/pkg/sentry/memmap" - "gvisor.dev/gvisor/pkg/sync" ) // KeyKind indicates the type of a Key. @@ -252,7 +251,7 @@ func (w *Waiter) woken() bool { // +stateify savable type bucket struct { // mu protects waiters and contained Waiter state. See comment in Waiter. - mu sync.Mutex `state:"nosave"` + mu futexBucketMutex `state:"nosave"` waiters waiterList `state:"zerovalue"` } @@ -426,10 +425,10 @@ func (m *Manager) lockBuckets(k1, k2 *Key) (b1 *bucket, b2 *bucket) { switch { case i1 < i2: b1.mu.Lock() - b2.mu.Lock() + b2.mu.NestedLock() case i2 < i1: b2.mu.Lock() - b1.mu.Lock() + b1.mu.NestedLock() default: b1.mu.Lock() } @@ -452,7 +451,7 @@ func (m *Manager) lockBuckets(k1, k2 *Key) (b1 *bucket, b2 *bucket) { // +checklocksrelease:b1.mu // +checklocksrelease:b2.mu func (m *Manager) unlockBuckets(b1, b2 *bucket) { - b1.mu.Unlock() + b1.mu.NestedUnlock() if b1 != b2 { b2.mu.Unlock() } diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 241c205ab..91b38077c 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -189,7 +189,7 @@ type Kernel struct { // runningTasksMu is used to exclude critical sections when the timer // disables itself and when the first active task enables the timer, // ensuring that tasks always see a valid cpuClock value. - runningTasksMu sync.Mutex `state:"nosave"` + runningTasksMu runningTasksMutex `state:"nosave"` // runningTasks is the total count of tasks currently in // TaskGoroutineRunningSys or TaskGoroutineRunningApp. i.e., they are @@ -330,9 +330,9 @@ type Kernel struct { // the system. cgroupRegistry *CgroupRegistry - // userCountersMa maps auth.KUID into a set of user counters. + // userCountersMap maps auth.KUID into a set of user counters. userCountersMap map[auth.KUID]*userCounters - userCountersMapMu sync.Mutex `state:"nosave"` + userCountersMapMu userCountersMutex `state:"nosave"` } // InitKernelArgs holds arguments to Init. diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 8c845633b..bb6787673 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,13 +1,49 @@ load("//tools:defs.bzl", "go_library", "go_test") +load("//tools/go_generics:defs.bzl", "go_template_instance") package(licenses = ["notice"]) +go_template_instance( + name = "vfs_mutex", + out = "vfs_mutex.go", + package = "pipe", + prefix = "vfs", + substrs = { + "genericMark": "vfs", + }, + template = "//pkg/sync/locking:generic_mutex", +) + +go_template_instance( + name = "pipe_mutex", + out = "pipe_mutex.go", + package = "pipe", + prefix = "pipe", + substrs = { + "genericMark": "pipe", + }, + template = "//pkg/sync/locking:generic_mutex", +) + +go_template_instance( + name = "inode_mutex", + out = "inode_mutex.go", + package = "pipe", + prefix = "inode", + substrs = { + "genericMark": "inode", + }, + template = "//pkg/sync/locking:generic_mutex", +) + go_library( name = "pipe", srcs = [ "device.go", + "inode_mutex.go", "node.go", "pipe.go", + "pipe_mutex.go", "pipe_unsafe.go", "pipe_util.go", "reader.go", @@ -31,6 +67,7 @@ go_library( "//pkg/sentry/fs/fsutil", "//pkg/sentry/vfs", "//pkg/sync", + "//pkg/sync/locking", "//pkg/usermem", "//pkg/waiter", "@org_golang_x_sys//unix:go_default_library", diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index fdf8e4792..8ae324ab0 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -26,7 +26,6 @@ import ( "gvisor.dev/gvisor/pkg/hostarch" "gvisor.dev/gvisor/pkg/safemem" "gvisor.dev/gvisor/pkg/sentry/fs" - "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/waiter" ) @@ -132,7 +131,7 @@ type Pipe struct { totalWriters atomicbitops.Int32 // mu protects all pipe internal state below. - mu sync.Mutex `state:"nosave"` + mu pipeMutex `state:"nosave"` // buf holds the pipe's data. buf is a circular buffer; the first valid // byte in buf is at offset off, and the pipe contains size valid bytes. diff --git a/pkg/sentry/kernel/pipe/pipe_unsafe.go b/pkg/sentry/kernel/pipe/pipe_unsafe.go index 077c5d596..5fdab6587 100644 --- a/pkg/sentry/kernel/pipe/pipe_unsafe.go +++ b/pkg/sentry/kernel/pipe/pipe_unsafe.go @@ -29,9 +29,9 @@ func lockTwoPipes(x, y *Pipe) { // Lock the two pipes in order of increasing address. if uintptr(unsafe.Pointer(x)) < uintptr(unsafe.Pointer(y)) { x.mu.Lock() - y.mu.Lock() + y.mu.NestedLock() } else { y.mu.Lock() - x.mu.Lock() + x.mu.NestedLock() } } diff --git a/pkg/sentry/kernel/pipe/vfs.go b/pkg/sentry/kernel/pipe/vfs.go index e79514770..efdf50bd4 100644 --- a/pkg/sentry/kernel/pipe/vfs.go +++ b/pkg/sentry/kernel/pipe/vfs.go @@ -415,7 +415,7 @@ func spliceOrTee(ctx context.Context, dst, src *VFSPipeFD, count int64, removeFr return uint64(n), err }) dst.pipe.mu.Unlock() - src.pipe.mu.Unlock() + src.pipe.mu.NestedUnlock() if n > 0 { dst.pipe.queue.Notify(waiter.ReadableEvents) diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index 26e3e3020..c217707ef 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -202,11 +202,11 @@ func (pg *ProcessGroup) handleOrphan() { if tg.processGroup != pg { return } - tg.signalHandlers.mu.Lock() + tg.signalHandlers.mu.NestedLock() if tg.groupStopComplete { hasStopped = true } - tg.signalHandlers.mu.Unlock() + tg.signalHandlers.mu.NestedUnlock() }) if !hasStopped { return @@ -217,10 +217,10 @@ func (pg *ProcessGroup) handleOrphan() { if tg.processGroup != pg { return } - tg.signalHandlers.mu.Lock() + tg.signalHandlers.mu.NestedLock() tg.leader.sendSignalLocked(SignalInfoPriv(linux.SIGHUP), true /* group */) tg.leader.sendSignalLocked(SignalInfoPriv(linux.SIGCONT), true /* group */) - tg.signalHandlers.mu.Unlock() + tg.signalHandlers.mu.NestedUnlock() }) return diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 147cc41bb..3510b9dea 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -16,7 +16,6 @@ package kernel import ( "gvisor.dev/gvisor/pkg/abi/linux" - "gvisor.dev/gvisor/pkg/sync" ) // SignalHandlers holds information about signal actions. @@ -26,7 +25,7 @@ type SignalHandlers struct { // mu protects actions, as well as the signal state of all tasks and thread // groups using this SignalHandlers object. (See comment on // ThreadGroup.signalHandlers.) - mu sync.Mutex `state:"nosave"` + mu signalHandlersMutex `state:"nosave"` // actions is the action to be taken upon receiving each signal. actions map[linux.Signal]linux.SigAction diff --git a/pkg/sentry/kernel/signalfd/BUILD b/pkg/sentry/kernel/signalfd/BUILD index 4180ca28e..13c762d89 100644 --- a/pkg/sentry/kernel/signalfd/BUILD +++ b/pkg/sentry/kernel/signalfd/BUILD @@ -1,10 +1,21 @@ load("//tools:defs.bzl", "go_library") +load("//pkg/sync/locking:locking.bzl", "declare_mutex") licenses(["notice"]) +declare_mutex( + name = "signal_operations_mutex", + out = "signal_operations_mutex.go", + package = "signalfd", + prefix = "operations", +) + go_library( name = "signalfd", - srcs = ["signalfd.go"], + srcs = [ + "signal_operations_mutex.go", + "signalfd.go", + ], visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", @@ -15,6 +26,7 @@ go_library( "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel", "//pkg/sync", + "//pkg/sync/locking", "//pkg/usermem", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/signalfd/signalfd.go b/pkg/sentry/kernel/signalfd/signalfd.go index 8ff74b12d..ed23f3312 100644 --- a/pkg/sentry/kernel/signalfd/signalfd.go +++ b/pkg/sentry/kernel/signalfd/signalfd.go @@ -23,7 +23,6 @@ import ( "gvisor.dev/gvisor/pkg/sentry/fs/anon" "gvisor.dev/gvisor/pkg/sentry/fs/fsutil" "gvisor.dev/gvisor/pkg/sentry/kernel" - "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/usermem" "gvisor.dev/gvisor/pkg/waiter" ) @@ -55,7 +54,7 @@ type SignalOperations struct { queue waiter.Queue // mu protects below. - mu sync.Mutex `state:"nosave"` + mu operationsMutex `state:"nosave"` // entry is the entry reigstered with the target. entry waiter.Entry diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index a4b966207..8deda92f1 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -255,7 +255,7 @@ type Task struct { containerID string // mu protects some of the following fields. - mu sync.Mutex `state:"nosave"` + mu taskMutex `state:"nosave"` // image holds task data provided by the ELF loader. // diff --git a/pkg/sentry/kernel/task_cgroup.go b/pkg/sentry/kernel/task_cgroup.go index aebe492e4..f5bfed70c 100644 --- a/pkg/sentry/kernel/task_cgroup.go +++ b/pkg/sentry/kernel/task_cgroup.go @@ -38,8 +38,8 @@ func (t *Task) EnterInitialCgroups(parent *Task) { } joinSet := t.k.cgroupRegistry.computeInitialGroups(inherit) - t.mu.Lock() - defer t.mu.Unlock() + t.mu.NestedLock() + defer t.mu.NestedUnlock() // Transfer ownership of joinSet refs to the task's cgset. t.cgroups = joinSet for c := range t.cgroups { diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index f1a55f25f..77953ad41 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -159,7 +159,7 @@ type ThreadGroup struct { // restarted by Task.Start. liveGoroutines sync.WaitGroup `state:"nosave"` - timerMu sync.Mutex `state:"nosave"` + timerMu threadGroupTimerMutex `state:"nosave"` // itimerRealTimer implements ITIMER_REAL for the thread group. itimerRealTimer *ktime.Timer @@ -381,9 +381,9 @@ func (tg *ThreadGroup) SetControllingTTY(tty *TTY, steal bool, isReadable bool) // the same session as the tty's controlling thread // group. if othertg.processGroup.session == tty.tg.processGroup.session { - othertg.signalHandlers.mu.Lock() + othertg.signalHandlers.mu.NestedLock() othertg.tty = nil - othertg.signalHandlers.mu.Unlock() + othertg.signalHandlers.mu.NestedUnlock() } } } diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 953c113a1..b90118ee2 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -58,7 +58,7 @@ const InitTID ThreadID = 1 type TaskSet struct { // mu protects all relationships between tasks and thread groups in the // TaskSet. (mu is approximately equivalent to Linux's tasklist_lock.) - mu sync.RWMutex `state:"nosave"` + mu taskSetRWMutex `state:"nosave"` // Root is the root PID namespace, in which all tasks in the TaskSet are // visible. The Root pointer is immutable.