From 41cf01fa9391c117e602aafa604ee5cbe1ff18ce Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 19 May 2021 19:42:18 +0200 Subject: [PATCH] pkg/signal.CatchAll: ignore SIGURG on Linux Do not handle SIGURG on Linux, as in go1.14+, the go runtime issues SIGURG as an interrupt to support preemptable system calls on Linux. This issue was caught in TestCatchAll, which could fail when updating to Go 1.14 or above; === Failed === FAIL: pkg/signal TestCatchAll (0.01s) signal_linux_test.go:32: assertion failed: urgent I/O condition (string) != continued (string) signal_linux_test.go:32: assertion failed: continued (string) != hangup (string) signal_linux_test.go:32: assertion failed: hangup (string) != child exited (string) signal_linux_test.go:32: assertion failed: child exited (string) != illegal instruction (string) signal_linux_test.go:32: assertion failed: illegal instruction (string) != floating point exception (string) Signed-off-by: Sebastiaan van Stijn (cherry picked from commit b7ebf32ba3f0342343558431df976d4ccb8039ba) Signed-off-by: Sebastiaan van Stijn --- pkg/signal/signal.go | 7 +++++++ pkg/signal/signal_darwin.go | 5 +++++ pkg/signal/signal_freebsd.go | 5 +++++ pkg/signal/signal_linux.go | 5 +++++ pkg/signal/signal_linux_mipsx.go | 5 +++++ pkg/signal/signal_linux_test.go | 17 +++++++++++++++++ pkg/signal/signal_windows.go | 5 +++++ 7 files changed, 49 insertions(+) diff --git a/pkg/signal/signal.go b/pkg/signal/signal.go index 88ef7b5ea2..bbe006bd0b 100644 --- a/pkg/signal/signal.go +++ b/pkg/signal/signal.go @@ -12,9 +12,16 @@ import ( ) // CatchAll catches all signals and relays them to the specified channel. +// On Linux, SIGURG is not handled, as it's used by the Go runtime to support +// preemptable system calls. func CatchAll(sigc chan os.Signal) { var handledSigs []os.Signal for _, s := range SignalMap { + if isRuntimeSig(s) { + // Do not handle SIGURG on Linux, as in go1.14+, the go runtime issues + // SIGURG as an interrupt to support preemptable system calls on Linux. + continue + } handledSigs = append(handledSigs, s) } signal.Notify(sigc, handledSigs...) diff --git a/pkg/signal/signal_darwin.go b/pkg/signal/signal_darwin.go index ee5501e3d9..8ffd3d73d3 100644 --- a/pkg/signal/signal_darwin.go +++ b/pkg/signal/signal_darwin.go @@ -1,6 +1,7 @@ package signal // import "github.com/docker/docker/pkg/signal" import ( + "os" "syscall" ) @@ -39,3 +40,7 @@ var SignalMap = map[string]syscall.Signal{ "XCPU": syscall.SIGXCPU, "XFSZ": syscall.SIGXFSZ, } + +func isRuntimeSig(_ os.Signal) bool { + return false +} diff --git a/pkg/signal/signal_freebsd.go b/pkg/signal/signal_freebsd.go index 764f90e264..a5e774a538 100644 --- a/pkg/signal/signal_freebsd.go +++ b/pkg/signal/signal_freebsd.go @@ -1,6 +1,7 @@ package signal // import "github.com/docker/docker/pkg/signal" import ( + "os" "syscall" ) @@ -41,3 +42,7 @@ var SignalMap = map[string]syscall.Signal{ "XCPU": syscall.SIGXCPU, "XFSZ": syscall.SIGXFSZ, } + +func isRuntimeSig(_ os.Signal) bool { + return false +} diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go index 4013bded13..46fe6bbad0 100644 --- a/pkg/signal/signal_linux.go +++ b/pkg/signal/signal_linux.go @@ -3,6 +3,7 @@ package signal // import "github.com/docker/docker/pkg/signal" import ( + "os" "syscall" "golang.org/x/sys/unix" @@ -81,3 +82,7 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +func isRuntimeSig(s os.Signal) bool { + return s == unix.SIGURG +} diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go index c78c887af5..665d849adb 100644 --- a/pkg/signal/signal_linux_mipsx.go +++ b/pkg/signal/signal_linux_mipsx.go @@ -4,6 +4,7 @@ package signal // import "github.com/docker/docker/pkg/signal" import ( + "os" "syscall" "golang.org/x/sys/unix" @@ -82,3 +83,7 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +func isRuntimeSig(s os.Signal) bool { + return s == unix.SIGURG +} diff --git a/pkg/signal/signal_linux_test.go b/pkg/signal/signal_linux_test.go index 8e2fb98dbb..decd454de3 100644 --- a/pkg/signal/signal_linux_test.go +++ b/pkg/signal/signal_linux_test.go @@ -6,6 +6,7 @@ import ( "os" "syscall" "testing" + "time" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -34,6 +35,22 @@ func TestCatchAll(t *testing.T) { } } +func TestCatchAllIgnoreSigUrg(t *testing.T) { + sigs := make(chan os.Signal, 1) + CatchAll(sigs) + defer StopCatch(sigs) + + err := syscall.Kill(syscall.Getpid(), syscall.SIGURG) + assert.NilError(t, err) + timer := time.NewTimer(1 * time.Second) + defer timer.Stop() + select { + case <-timer.C: + case s := <-sigs: + t.Fatalf("expected no signals to be handled, but received %q", s.String()) + } +} + func TestStopCatch(t *testing.T) { signal := SignalMap["HUP"] channel := make(chan os.Signal, 1) diff --git a/pkg/signal/signal_windows.go b/pkg/signal/signal_windows.go index 65752f24aa..d44662c4e4 100644 --- a/pkg/signal/signal_windows.go +++ b/pkg/signal/signal_windows.go @@ -1,6 +1,7 @@ package signal // import "github.com/docker/docker/pkg/signal" import ( + "os" "syscall" ) @@ -24,3 +25,7 @@ var SignalMap = map[string]syscall.Signal{ "KILL": syscall.SIGKILL, "TERM": syscall.SIGTERM, } + +func isRuntimeSig(_ os.Signal) bool { + return false +}