Skip to content
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/dist: build cmd with CGO_ENABLED=0, so cmd/go uses pure Go net resolver #57007

Closed
rsc opened this issue Nov 30, 2022 · 12 comments
Closed

cmd/dist: build cmd with CGO_ENABLED=0, so cmd/go uses pure Go net resolver #57007

rsc opened this issue Nov 30, 2022 · 12 comments
Assignees
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Linux
Milestone

Comments

@rsc
Copy link
Contributor

rsc commented Nov 30, 2022

Now that we've removed the .a files from the distribution, the only possible leakage of the host build environment into Go Linux releases is the dynamic libc.so.6 path embedded in the command binaries that use the network (only bin/go and pkg/tool/goos_goarch/pprof, I believe).

I wonder whether we should build cmd with CGO_ENABLED=0 so that we end up with purely static cmd/go and cmd/pprof binaries. This would apply to all systems, but since we are planning to cross-compile non-Linux distributions and Mac and Windows don't use cgo anyway for net, the only effect would be on Linux.

We default to the cgo-based net so that people with strange /etc/resolv.conf can still resolve the names they need to resolve. But perhaps that is more for local names like mDNS and such rather than the standard internet names that cmd/go needs.

Does anyone see anything that would break if we made the go command always use the pure Go net resolver?

@rsc rsc changed the title cmd/dist: build cmd with CGO_ENABLED=0 cmd/dist: build cmd with CGO_ENABLED=0, so cmd/go uses pure Go net resolver Nov 30, 2022
@bcmills
Copy link
Member

bcmills commented Dec 1, 2022

Would this cause go install cmd to install a different cmd/go from what make.bash produces?
That might be ok, but we would probably at least have to update some tests that assume it is a no-op.

(But it also might provide a reasonable workaround for folks who want a cmd/go that uses the C resolver.)

@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 1, 2022
@bcmills bcmills added this to the Backlog milestone Dec 1, 2022
@rsc
Copy link
Contributor Author

rsc commented Dec 2, 2022

Would this cause go install cmd to install a different cmd/go from what make.bash produces?
That might be ok, but we would probably at least have to update some tests that assume it is a no-op.

Yes, and agreed.

@rsc rsc self-assigned this Dec 2, 2022
@rsc rsc modified the milestones: Backlog, Go1.21 Dec 2, 2022
@rsc
Copy link
Contributor Author

rsc commented Dec 3, 2022

With a little more work this lets us build completely reproducible distributions, where it doesn't matter which OS the distribution was built on at all. In particular they could all be built on a single trusted system. CL 454836 does this.

@gopherbot
Copy link

Change https://go.dev/cl/454836 mentions this issue: cmd/dist: make toolchain build reproducible

@mateusz834
Copy link
Contributor

mateusz834 commented Dec 4, 2022

We default to the cgo-based net so that people with strange /etc/resolv.conf can still resolve the names they need to resolve. But perhaps that is more for local names like mDNS and such rather than the standard internet names that cmd/go needs.

I don't think that resolv.conf might be a problem, go 1.20 supports most options that are used in the wild.

Does anyone see anything that would break if we made the go command always use the pure Go net resolver?

Some users might have problem because of /etc/nsswitch.conf, when we compiled without cgo we default to files,dns order, we don't even parse that file.

Recently the nsswitch.conf (hosts database) on glibc-based linux systems becomes more and more bloated. We should be careful with this.

@rsc
Copy link
Contributor Author

rsc commented Dec 5, 2022

In what circumstances would nsswitch.conf be needed to resolve public internet names like github.com or proxy.golang.org?

@mateusz834
Copy link
Contributor

mateusz834 commented Dec 5, 2022

In what circumstances would nsswitch.conf be needed to resolve public internet names like github.com or proxy.golang.org?

Glibc uses nsswitch.conf to resolve all names. Recently linux distros (desktop) started adopting systemd-resolve nss module, instead of a dns one, so that the dns module is not even used to resolve hostnames, the dns queries are send by the systemd-resolved deamon.
I mean if we change the go binary to use netgo by default, then probably nothing will break, but we don't know how the nsswitch.conf configurations might evolve in the future.

Edit: but on non-glibc systems (without nsswitch.conf support in libc) the go resolver will be fine, so for alpine and other musl based distros.

@rsc
Copy link
Contributor Author

rsc commented Dec 5, 2022

I guess we will find out - there are enough upsides to this change, including cross-compiled reproducible builds, that I think we owe it to ourselves to try it in Go 1.21 and find out whether there are any show-stoppers.

@bcmills
Copy link
Member

bcmills commented Dec 15, 2022

#57328 is an interesting data point here too. There, a user is reporting that building a cgo-enabled dynamically-linked binary on an Ubuntu with a newer glibc causes that binary to fail to run on a system with an older glibc.

That seems to imply that if we build a cgo-enabled cmd/go against a recent glibc and include it in a Go release, it will similarly fail to run on an older system. But we probably also don't want to build our releases on ancient versions of our supported platforms just to improve the glibc compatibility of the resulting binaries.

Building the release with CGO_ENABLED=0 nicely sidesteps that problem, allowing Go releases to be built on more up-to-date platforms.

@seankhliao
Copy link
Member

failures due to glibc versions were also seen a long time ago in #5203

@gopherbot
Copy link

Change https://go.dev/cl/461689 mentions this issue: cmd/go: do not attempt to install cmd/addr2line in TestScript/mod_outside

gopherbot pushed a commit that referenced this issue Jan 18, 2023
…side

Tests must not write to GOROOT: it might not writable (for example, if
it is owned by root and the user is non-root), and in general we can't
assume that the configuration in which the test is run matches the
configuration with which the installed tools were built.

In this specific case, CL 454836 (for #57007) installs 'cmd' with
CGO_ENABLED=0, but most builders still run the tests with CGO_ENABLED
unset.

Updates #57007.

Change-Id: I2795fcd3ff61c164dc730b62f697f307ab3a167b
Reviewed-on: https://go-review.googlesource.com/c/go/+/461689
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@gopherbot
Copy link

Change https://go.dev/cl/463739 mentions this issue: cmd/dist: leave cgo enabled if external linking is required

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Linux
Projects
None yet
Development

No branches or pull requests

5 participants