aboutsummaryrefslogtreecommitdiffstats
path: root/vm/vmimpl/vmimpl.go
diff options
context:
space:
mode:
authorIvan Gulakov <gulakov@amazon.de>2025-01-07 13:45:03 +0000
committerAleksandr Nogikh <nogikh@google.com>2025-01-13 12:42:34 +0000
commit3f6ed5888bda84980406819a976c6c8155e89c58 (patch)
treea959a9d7fd155bb1726ef14aab4a995cf7f1b420 /vm/vmimpl/vmimpl.go
parent249ceea9b77a9eda26fb696c50b673d6f295d7f4 (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/vmimpl.go')
-rw-r--r--vm/vmimpl/vmimpl.go15
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)
}
}