diff options
author | chris.zn <chris.zn@antfin.com> | 2020-01-14 18:59:33 +0800 |
---|---|---|
committer | chris.zn <chris.zn@antfin.com> | 2020-01-15 13:00:59 +0800 |
commit | 376a777c55680f8139313d87bd460248fd251941 (patch) | |
tree | 8644c21cbe60e0d896850d9005bb5c246d5e8b7a | |
parent | 1ad8381eac108304f7b96162674624b34b95ec7b (diff) |
Fix "unlock of unlocked mutex" crash when getting tty
This patch holds taskset.mu when getting tty. If we don't
do this, it may cause a "unlock of unlocked mutex" problem,
since signalHandlers may be replaced by CopyForExec() in
runSyscallAfterExecStop after the signalHandlers.mu has
been holded in TTY().
The problem is easy to reproduce with keeping to do "runsc ps".
The crash log is :
fatal error: sync: unlock of unlocked mutex
goroutine 5801304 [running]:
runtime.throw(0xfd019c, 0x1e)
GOROOT/src/runtime/panic.go:774 +0x72 fp=0xc001ba47b0 sp=0xc001ba4780 pc=0x431702
sync.throw(0xfd019c, 0x1e)
GOROOT/src/runtime/panic.go:760 +0x35 fp=0xc001ba47d0 sp=0xc001ba47b0 pc=0x431685
sync.(*Mutex).unlockSlow(0xc00cf94a30, 0xc0ffffffff)
GOROOT/src/sync/mutex.go:196 +0xd6 fp=0xc001ba47f8 sp=0xc001ba47d0 pc=0x4707d6
sync.(*Mutex).Unlock(0xc00cf94a30)
GOROOT/src/sync/mutex.go:190 +0x48 fp=0xc001ba4818 sp=0xc001ba47f8 pc=0x4706e8
gvisor.dev/gvisor/pkg/sentry/kernel.(*ThreadGroup).TTY(0xc011a9e800, 0x0)
pkg/sentry/kernel/tty.go:38 +0x88 fp=0xc001ba4868 sp=0xc001ba4818 pc=0x835fa8
gvisor.dev/gvisor/pkg/sentry/control.Processes(0xc00025ae00, 0xc013e397c0, 0x40, 0xc0137b9800, 0x1, 0x7f292e9a4cc0)
pkg/sentry/control/proc.go:366 +0x355 fp=0xc001ba49a0 sp=0xc001ba4868 pc=0x9ac4a5
gvisor.dev/gvisor/runsc/boot.(*containerManager).Processes(0xc0003b62c0, 0xc0051423d0, 0xc0137b9800, 0x0, 0x0)
runsc/boot/controller.go:228 +0xdf fp=0xc001ba49e8 sp=0xc001ba49a0 pc=0xaf06cf
Signed-off-by: chris.zn <chris.zn@antfin.com>
-rw-r--r-- | pkg/sentry/kernel/tty.go | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/pkg/sentry/kernel/tty.go b/pkg/sentry/kernel/tty.go index 464d2306a..d0e0810e8 100644 --- a/pkg/sentry/kernel/tty.go +++ b/pkg/sentry/kernel/tty.go @@ -33,6 +33,8 @@ type TTY struct { // TTY returns the thread group's controlling terminal. If nil, there is no // controlling terminal. func (tg *ThreadGroup) TTY() *TTY { + tg.pidns.owner.mu.RLock() + defer tg.pidns.owner.mu.RUnlock() tg.signalHandlers.mu.Lock() defer tg.signalHandlers.mu.Unlock() return tg.tty |