-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/link: LC_UUID not generated by go linker, resulting in failure to access local network on macOS 15 #68678
Comments
Thanks @seankhliao :) |
Sample reproducer. Change |
CC @cherrymui |
See also https://forums.developer.apple.com/forums/thread/737416 for a description of the UUID mechanism. |
Also ran into this; this now affects all existing Go applications that are launched via Go application on the new OS simply has an error: Minimal example: package main
import (
"fmt"
"net"
"os"
"time"
)
func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: <address:port>")
return
}
for {
if conn, err := net.Dial("tcp", os.Args[1]); err == nil {
buf := make([]byte, 1024)
n, _ := conn.Read(buf)
fmt.Println("Connected, response:", string(buf[:n]))
conn.Close()
} else {
fmt.Println("Error:", err, "Retrying...")
}
time.Sleep(1 * time.Second)
}
} Build:
Config for auto start and restart:
Start:
Monitor failures:
Network is fine:
Reported this to Apple as:
|
Change https://go.dev/cl/618595 mentions this issue: |
Change https://go.dev/cl/618597 mentions this issue: |
Change https://go.dev/cl/618598 mentions this issue: |
Change https://go.dev/cl/618596 mentions this issue: |
Change https://go.dev/cl/618599 mentions this issue: |
Currently, on Mach-O, the Go linker doesn't generate LC_UUID in internal linking mode. This causes some macOS system tools unable to track the binary, as well as in some cases the binary unable to access local network on macOS 15. This CL makes the linker start generate LC_UUID. Currently, the UUID is generated if the -B flag is specified. And we'll make it generate UUID by default in a later CL. The -B flag is currently for generating GNU build ID on ELF, which is a similar concept to Mach-O's UUID. Instead of introducing another flag, we just use the same flag and the same setting. Specifically, "-B gobuildid" will generate a UUID based on the Go build ID. For #68678. Cq-Include-Trybots: luci.golang.try:gotip-darwin-amd64_14,gotip-darwin-arm64_13 Change-Id: I90089a78ba144110bf06c1c6836daf2d737ff10a Reviewed-on: https://go-review.googlesource.com/c/go/+/618595 Reviewed-by: Michael Knyszek <[email protected]> Reviewed-by: Ingo Oeser <[email protected]> Reviewed-by: Than McIntosh <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
Currently the linker has some code handling and manipulating Mach-O files. Specifically, it augments the debug/macho package with file offset and length, so the content can be handled or updated easily with the file. Move this code to an internal package, so it can be used by other part of the toolchain, e.g. buildid computation. For #68678. Cq-Include-Trybots: luci.golang.try:gotip-darwin-amd64_14,gotip-darwin-arm64_13 Change-Id: I2311af0a06441b7fd887ca5c6ed9e6fc44670a16 Reviewed-on: https://go-review.googlesource.com/c/go/+/618596 Reviewed-by: Than McIntosh <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
With the "-B gobuildid" linker option (which will be the default on some platforms), the host build ID (GNU build ID, Mach-O UUID) depends on the Go buildid. If the host build ID is included in the Go buildid computation, it will lead to convergence problem for the toolchain binaries. So ignore the host build ID in the buildid computation. This CL only handles Mach-O UUID. ELF GNU build ID will be handled later. For #68678. For #63934. Cq-Include-Trybots: luci.golang.try:gotip-darwin-amd64_14,gotip-darwin-arm64_13 Change-Id: Ie8ff20402a1c6083246d25dea391140c75be40d0 Reviewed-on: https://go-review.googlesource.com/c/go/+/618597 Reviewed-by: Michael Knyszek <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Than McIntosh <[email protected]>
Currently, on Mach-O, the -B UUID setting is only applied in internal linking mode, whereas in external linking mode the UUID is always rewritten to a hash of Go build ID. This CL makes it apply to external linking as well. This makes the behavior consistent on both linkmodes, and also consistent with the -B flag's behavior for GNU build ID on ELF. Add tests. Updates #68678. Cq-Include-Trybots: luci.golang.try:gotip-darwin-amd64_14,gotip-darwin-arm64_13 Change-Id: I276a5930e231141440cdba16e8812df28ac4237b Reviewed-on: https://go-review.googlesource.com/c/go/+/618599 Reviewed-by: Than McIntosh <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
@gopherbot please backport this. This causes programs fail to access local network on macOS 15. The full fix would be backporting CL 618595, CL 618596, CL 618597, and CL 618598, which may be too complex for backport. A simpler alternative is backporting just CL 618595, which enables generating LC_UUID with a flag. It still needs a flag, but not the C toolchain, therefore helpful for cross compilation. We might be able to do a hacky way to enable it by default except for the toolchain binaries. I'll look into that. |
Backport issue(s) opened: #69991 (for 1.22), #69992 (for 1.23). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
Change https://go.dev/cl/622595 mentions this issue: |
Change https://go.dev/cl/622596 mentions this issue: |
…s specified Currently, on Mach-O, the Go linker doesn't generate LC_UUID in internal linking mode. This causes some macOS system tools unable to track the binary, as well as in some cases the binary unable to access local network on macOS 15. This CL makes the linker start generate LC_UUID. Currently, the UUID is generated if the -B flag is specified. And we'll make it generate UUID by default in a later CL. The -B flag is currently for generating GNU build ID on ELF, which is a similar concept to Mach-O's UUID. Instead of introducing another flag, we just use the same flag and the same setting. Specifically, "-B gobuildid" will generate a UUID based on the Go build ID. Updates #68678. Fixes #69991. Cq-Include-Trybots: luci.golang.try:go1.22-darwin-amd64_14,go1.22-darwin-arm64_13 Change-Id: I90089a78ba144110bf06c1c6836daf2d737ff10a Reviewed-on: https://go-review.googlesource.com/c/go/+/618595 Reviewed-by: Michael Knyszek <[email protected]> Reviewed-by: Ingo Oeser <[email protected]> Reviewed-by: Than McIntosh <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> (cherry picked from commit 20ed603) Reviewed-on: https://go-review.googlesource.com/c/go/+/622596 Auto-Submit: Michael Pratt <[email protected]> Reviewed-by: Michael Pratt <[email protected]> TryBot-Bypass: Michael Pratt <[email protected]>
…s specified Currently, on Mach-O, the Go linker doesn't generate LC_UUID in internal linking mode. This causes some macOS system tools unable to track the binary, as well as in some cases the binary unable to access local network on macOS 15. This CL makes the linker start generate LC_UUID. Currently, the UUID is generated if the -B flag is specified. And we'll make it generate UUID by default in a later CL. The -B flag is currently for generating GNU build ID on ELF, which is a similar concept to Mach-O's UUID. Instead of introducing another flag, we just use the same flag and the same setting. Specifically, "-B gobuildid" will generate a UUID based on the Go build ID. Updates #68678. Fixes #69992. Cq-Include-Trybots: luci.golang.try:go1.23-darwin-amd64_14,go1.23-darwin-arm64_13 Change-Id: I90089a78ba144110bf06c1c6836daf2d737ff10a Reviewed-on: https://go-review.googlesource.com/c/go/+/618595 Reviewed-by: Michael Knyszek <[email protected]> Reviewed-by: Ingo Oeser <[email protected]> Reviewed-by: Than McIntosh <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> (cherry picked from commit 20ed603) Reviewed-on: https://go-review.googlesource.com/c/go/+/622595 Reviewed-by: Michael Pratt <[email protected]>
Just give an update: This is fixed on tip (to be released in Go 1.24), by generating LC_UUID by default. For previous releases (Go 1.22 and 1.23), we did a simpler backport, which requires a Go linker flag ( |
This change is now breaking our macOS builds: #70380 |
A comment on the CL suggested that this change should be mentioned in Go 1.24 release notes. Reopening this as a release blocker to track that. |
Change https://go.dev/cl/633875 mentions this issue: |
Go version
go version go1.22.5 darwin/arm64
Output of
go env
in your module/workspace: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: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
The text was updated successfully, but these errors were encountered: