diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index d9f7bd5e6..6dfd22671 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -243,7 +243,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de tailscale.com/net/tunstats from tailscale.com/net/tstun+ tailscale.com/net/wsconn from tailscale.com/control/controlhttp+ tailscale.com/paths from tailscale.com/ipn/ipnlocal+ - tailscale.com/portlist from tailscale.com/ipn/ipnlocal + 💣 tailscale.com/portlist from tailscale.com/ipn/ipnlocal tailscale.com/safesocket from tailscale.com/client/tailscale+ tailscale.com/smallzstd from tailscale.com/ipn/ipnserver+ LD 💣 tailscale.com/ssh/tailssh from tailscale.com/cmd/tailscaled diff --git a/portlist/portlist_linux.go b/portlist/portlist_linux.go index a40fb9909..4d5faabbf 100644 --- a/portlist/portlist_linux.go +++ b/portlist/portlist_linux.go @@ -18,6 +18,7 @@ "sync/atomic" "syscall" "time" + "unsafe" "go4.org/mem" "golang.org/x/sys/unix" @@ -215,6 +216,8 @@ func addProcesses(pl []Port) ([]Port, error) { pm[pl[i].inode] = &pl[i] } + var pathBuf []byte + err := foreachPID(func(pid string) error { fdPath := fmt.Sprintf("/proc/%s/fd", pid) @@ -251,8 +254,9 @@ func addProcesses(pl []Port) ([]Port, error) { return fmt.Errorf("addProcesses.readDir: %w", err) } for _, fd := range fds { - n, err := unix.Readlink(fmt.Sprintf("/proc/%s/fd/%s", pid, fd), targetBuf) - if err != nil { + pathBuf = fmt.Appendf(pathBuf[:0], "/proc/%s/fd/%s\x00", pid, fd) + n, ok := readlink(pathBuf, targetBuf) + if !ok { // Not a symlink or no permission. // Skip it. continue @@ -337,3 +341,22 @@ func fieldIndex(line []byte, n int) int { } return skip } + +// path must be null terminated. +func readlink(path, buf []byte) (n int, ok bool) { + if len(buf) == 0 || len(path) < 2 || path[len(path)-1] != 0 { + return 0, false + } + var dirfd int = unix.AT_FDCWD + r0, _, e1 := unix.Syscall6(unix.SYS_READLINKAT, + uintptr(dirfd), + uintptr(unsafe.Pointer(&path[0])), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(len(buf)), + 0, 0) + n = int(r0) + if e1 != 0 { + return 0, false + } + return n, true +}