diff options
| author | Ivan Gulakov <gulakov@amazon.de> | 2025-01-07 13:45:03 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2025-01-13 12:42:34 +0000 |
| commit | 3f6ed5888bda84980406819a976c6c8155e89c58 (patch) | |
| tree | a959a9d7fd155bb1726ef14aab4a995cf7f1b420 /vm/vmimpl | |
| parent | 249ceea9b77a9eda26fb696c50b673d6f295d7f4 (diff) | |
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 <gulakov@amazon.de>
Diffstat (limited to 'vm/vmimpl')
| -rw-r--r-- | vm/vmimpl/vmimpl.go | 15 |
1 files changed, 15 insertions, 0 deletions
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) } } |
