safesocket: return an error for LocalTCPPortAndToken for tailscaled (#15144)

fixes tailscale/corp#26806

Fixes a regression where LocalTCPPortAndToken needs to error out early
if we're not running as sandboxed macos so that we attempt to connect
using the normal unix machinery.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This commit is contained in:
Jonathan Nobels 2025-02-27 18:55:46 -05:00 committed by GitHub
parent 6df0aa58bb
commit 90273a7f70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 5 deletions

View File

@ -37,14 +37,16 @@ type safesocketDarwin struct {
sameuserproofFD *os.File // file descriptor for macos app store sameuserproof file sameuserproofFD *os.File // file descriptor for macos app store sameuserproof file
sharedDir string // shared directory for location of sameuserproof file sharedDir string // shared directory for location of sameuserproof file
checkConn bool // Check macsys safesocket port before returning it checkConn bool // Check macsys safesocket port before returning it
isMacSysExt func() bool // For testing only to force macsys isMacSysExt func() bool // For testing only to force macsys
isSandboxedMacos func() bool // For testing only to force macOS sandbox
} }
var ssd = safesocketDarwin{ var ssd = safesocketDarwin{
isMacSysExt: version.IsMacSysExt, isMacSysExt: version.IsMacSysExt,
checkConn: true, isSandboxedMacos: version.IsSandboxedMacOS,
sharedDir: "/Library/Tailscale", checkConn: true,
sharedDir: "/Library/Tailscale",
} }
// There are three ways a Darwin binary can be run: as the Mac App Store (macOS) // There are three ways a Darwin binary can be run: as the Mac App Store (macOS)
@ -66,6 +68,10 @@ func localTCPPortAndTokenDarwin() (port int, token string, err error) {
ssd.mu.Lock() ssd.mu.Lock()
defer ssd.mu.Unlock() defer ssd.mu.Unlock()
if !ssd.isSandboxedMacos() {
return 0, "", ErrNoTokenOnOS
}
if ssd.port != 0 && ssd.token != "" { if ssd.port != 0 && ssd.token != "" {
return ssd.port, ssd.token, nil return ssd.port, ssd.token, nil
} }

View File

@ -17,6 +17,7 @@ import (
func TestSetCredentials(t *testing.T) { func TestSetCredentials(t *testing.T) {
wantPort := 123 wantPort := 123
wantToken := "token" wantToken := "token"
tstest.Replace(t, &ssd.isSandboxedMacos, func() bool { return true })
SetCredentials(wantToken, wantPort) SetCredentials(wantToken, wantPort)
gotPort, gotToken, err := LocalTCPPortAndToken() gotPort, gotToken, err := LocalTCPPortAndToken()
@ -37,6 +38,8 @@ func TestSetCredentials(t *testing.T) {
// returns a listener and a non-zero port and non-empty token. // returns a listener and a non-zero port and non-empty token.
func TestInitListenerDarwin(t *testing.T) { func TestInitListenerDarwin(t *testing.T) {
temp := t.TempDir() temp := t.TempDir()
tstest.Replace(t, &ssd.isSandboxedMacos, func() bool { return true })
ln, err := InitListenerDarwin(temp) ln, err := InitListenerDarwin(temp)
if err != nil || ln == nil { if err != nil || ln == nil {
t.Fatalf("InitListenerDarwin failed: %v", err) t.Fatalf("InitListenerDarwin failed: %v", err)