From 833200da6f89a6dc2439c4a36ecedbb6d43ebd11 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 16 Aug 2021 12:18:06 -0700 Subject: [PATCH] net/tstun: don't exec uname -r on Linux in TUN failure diagnostics Fixes https://twitter.com/zekjur/status/1425557520513486848 Signed-off-by: Brad Fitzpatrick --- net/tstun/tun_linux.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/net/tstun/tun_linux.go b/net/tstun/tun_linux.go index 3d33b4e79..fd77d9aaa 100644 --- a/net/tstun/tun_linux.go +++ b/net/tstun/tun_linux.go @@ -8,6 +8,8 @@ import ( "bytes" "os" "os/exec" + "strings" + "syscall" "tailscale.com/types/logger" "tailscale.com/version/distro" @@ -18,12 +20,13 @@ func init() { } func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf) { - kernel, err := exec.Command("uname", "-r").Output() - kernel = bytes.TrimSpace(kernel) + var un syscall.Utsname + err := syscall.Uname(&un) if err != nil { logf("no TUN, and failed to look up kernel version: %v", err) return } + kernel := utsField(&un.Release) logf("Linux kernel version: %s", kernel) modprobeOut, err := exec.Command("/sbin/modprobe", "tun").CombinedOutput() @@ -55,7 +58,7 @@ func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf) { logf("tun module not loaded nor found on disk") return } - if !bytes.Contains(dpkgOut, kernel) { + if !bytes.Contains(dpkgOut, []byte(kernel)) { logf("kernel/drivers/net/tun.ko found on disk, but not for current kernel; are you in middle of a system update and haven't rebooted? found: %s", dpkgOut) } case distro.Arch: @@ -64,7 +67,7 @@ func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf) { logf("tun module not loaded nor found on disk") return } - if !bytes.Contains(findOut, kernel) { + if !bytes.Contains(findOut, []byte(kernel)) { logf("kernel/drivers/net/tun.ko found on disk, but not for current kernel; are you in middle of a system update and haven't rebooted? found: %s", findOut) } case distro.OpenWrt: @@ -80,3 +83,14 @@ func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf) { } } } + +func utsField(p *[65]int8) string { + var sb strings.Builder + for _, v := range p { + if v == 0 { + break + } + sb.WriteByte(byte(v)) + } + return strings.TrimSpace(sb.String()) +}