Skip to content

cmd/link: LC_UUID not generated by go linker, resulting in failure to access local network on macOS 15 #68678

Closed
@torarnv

Description

@torarnv

Go version

go version go1.22.5 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/torarne/Library/Caches/go-build'
GOENV='/Users/torarne/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/var/folders/7w/09x_jw654938vd439254v6r80000gn/T//gomodcache'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/torarne/.go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.22.5/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.22.5/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.5'
GCCGO='gccgo'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/7w/09x_jw654938vd439254v6r80000gn/T/go-build1376446515=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Go binaries built with the default linker for macOS do not have a LC_UUID load command. This UUID seems important to the network privacy machinery on macOS, that in macOS 15 now includes local network access.

Running a small go binary that does a HTTP request to a local network HTTP server results in a permission request from the OS, but accepting this does not result in the go process being able to access the server.

The logs show:
nehelper +[NEProcessInfo copyUUIDsForExecutable:]_block_invoke: failed to get UUIDs for /Users/foo/FetchGo

So it seems the nehelper relies on the binary having a UUID to allow network requests through.

I can work around this by passing -ldflags="-linkmode=external" when building the go binary, which does produce a UUID:

❯ dwarfdump -u FetchGo
UUID: C7B47B23-54A7-3F52-837D-E455B57855A1 (arm64) FetchGo

And in this case the HTTP request works after accepting the privacy dialog. But I don't think this will work when cross-compiling darwin binaries on Linux e.g.

Note that for testing this, the binary must be run as an app bundle, or launch agent -- not via SSH/Terminal, as in the latter case the permission to access the network is inherited by those processes, and they have an UUID.

What did you see happen?

Network request fails to route

What did you expect to see?

Network request succeeds

Metadata

Metadata

Assignees

Labels

DocumentationIssues describing a change to documentation.NeedsFixThe path to resolution is known, but the work has not been done.OS-Darwincompiler/runtimeIssues related to the Go compiler and/or runtime.release-blocker

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions