From 3f6ed5888bda84980406819a976c6c8155e89c58 Mon Sep 17 00:00:00 2001 From: Ivan Gulakov Date: Tue, 7 Jan 2025 13:45:03 +0000 Subject: vm: fix deadlock in UnusedTCPPort If localhost is not configured on a system, UnusedTCPPort will loop forever without producing any errors. By checking EADDRINUSE and ENOACC and then skipping only in these cases, we'd avoid at least the mentioned deadlock. On top of this, this change should catch other errors without locking, like other DNS errors and so on. Signed-off-by: Ivan Gulakov --- vm/vmimpl/vmimpl.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'vm') diff --git a/vm/vmimpl/vmimpl.go b/vm/vmimpl/vmimpl.go index b95bd2a18..8106d6166 100644 --- a/vm/vmimpl/vmimpl.go +++ b/vm/vmimpl/vmimpl.go @@ -14,8 +14,10 @@ import ( "io" "math/big" "net" + "os" "os/exec" "strings" + "syscall" "time" "github.com/google/syzkaller/pkg/log" @@ -241,6 +243,19 @@ func UnusedTCPPort() int { ln.Close() return port } + + // Continue searching for a port only if we fail with EADDRINUSE or don't have permissions to use this port. + // Although we exclude ports <1024 in RandomPort(), it's still possible that we can face a restricted port. + var opErr *net.OpError + if errors.As(err, &opErr) && opErr.Op == "listen" { + var syscallErr *os.SyscallError + if errors.As(opErr.Err, &syscallErr) { + if errors.Is(syscallErr.Err, syscall.EADDRINUSE) || errors.Is(syscallErr.Err, syscall.EACCES) { + continue + } + } + } + log.Fatalf("error allocating port localhost:%d: %v", port, err) } } -- cgit mrf-deployment