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/go: go version <binary> fails with -buildmode=pie Linux ELF binaries #31861

Closed
rsc opened this issue May 6, 2019 · 17 comments
Closed

cmd/go: go version <binary> fails with -buildmode=pie Linux ELF binaries #31861

rsc opened this issue May 6, 2019 · 17 comments

Comments

@rsc
Copy link
Contributor

@rsc rsc commented May 6, 2019

$ go build -o /tmp/go.exe
$ go version /tmp/go.exe
/tmp/go.exe: go version not found
$

It's possible I am using too old a tree but I think this is still broken at head.

@rsc rsc added this to the Go1.13 milestone May 6, 2019
@rsc rsc added the release-blocker label May 6, 2019
@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented May 6, 2019

In a -buildmode=pie executable the .go.buildinfo section is deep into the data segment, much farther than the 64K that go version reads. This doesn't actually have anything to do with -buildmode=pie as such; go version fails on ELF systems when using -ldflags=-linkmode=external, and -buildmode=pie currently implies an external link.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented May 6, 2019

It's not clear to me why the .go.buildinfo section is writable.

@dotaheor

This comment has been minimized.

Copy link

@dotaheor dotaheor commented May 7, 2019

A little off topic, is there an option to disable packaging module versions in building?

@rsc

This comment has been minimized.

Copy link
Contributor Author

@rsc rsc commented Jun 6, 2019

We can certainly fall back to reading the ELF binaries to find the right place in non-stripped binaries. We just can't assume that in general.

@rsc

This comment has been minimized.

Copy link
Contributor Author

@rsc rsc commented Jun 6, 2019

@dotaheor, no there's no such option.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jun 6, 2019

But why is the section writable? If it weren't writable, it would be in the text segment, and more likely to be found with the current algorithm.

@bcmills

This comment has been minimized.

Copy link
Member

@bcmills bcmills commented Jun 26, 2019

@ianlancetaylor, just to try to understand the problem I changed cmd/link/sym to mark SBUILDINFO as read-only.

That caused the internal linking of -buildmode=pie tests to crash with a segmentation fault in _dl_relocate_object, so I added a corresponding SBUILDINFORELRO section and tried again.

That made all.bash once again pass, but empirically did not fix go version.

@bcmills

This comment has been minimized.

Copy link
Member

@bcmills bcmills commented Jun 28, 2019

I looked in to this some more, but I'm in way over my head.

I know that the choice to make SBUILDINFO writable was intentional, because the DataStart methods in cmd/go/internal/version/exe.go look for the first writable section specifically. I do not understand why the section must be writable, and I can't figure out what is supposed to ensure the ordering of the writable sections in the final binary.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jun 28, 2019

It sounds like making the section readonly didn't help anyhow.

On ELF I think we can look for the section by opening the file using elf.Open and finding the section using elf.(*File).Section.

@rsc

This comment has been minimized.

Copy link
Contributor Author

@rsc rsc commented Jul 2, 2019

I think the problem with non-writable was that it contains pointers to writable variables so the relocations were simpler if they were in the same section.

@Infinoid

This comment has been minimized.

Copy link
Contributor

@Infinoid Infinoid commented Jul 18, 2019

For ELF binaries, the "go version" command finds the .go.buildinfo data by searching for the first program-header that's read-write, and hoping the version info is near that.

Is there any reason why you don't look for a section header named ".go.buildinfo", instead?

@Infinoid

This comment has been minimized.

Copy link
Contributor

@Infinoid Infinoid commented Jul 18, 2019

The above fix gets "go version exefile" working for me on amd64 ubuntu 18.04, with or without external linking, with or without pie, with or without stripping the binary. I think it should work on all ELF platforms; I don't know about other file formats.

@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Jul 18, 2019

Change https://golang.org/cl/186737 mentions this issue: cmd/go: fix "go version" bug #31861

@odeke-em

This comment has been minimized.

Copy link
Member

@odeke-em odeke-em commented Aug 5, 2019

Hello @Infinoid, thank you for mailing a fix!
Ian left some feedback on your CL some days ago but since we are just about to release Go1.13, I kindly wanted to nudge you to take a look or please let him know if you won't have time to make the update and he can make the update -- apologies for rushing you.

@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Aug 5, 2019

Change https://golang.org/cl/188957 mentions this issue: cmd/go: look for .go.buildinfo section when looking for ELF version

@gopherbot gopherbot closed this in 6c74db4 Aug 5, 2019
@jayconrod

This comment has been minimized.

Copy link
Contributor

@jayconrod jayconrod commented Aug 6, 2019

The updated test fails on darwin. It looks like the only TryBot that runs without -short is on Linux, so we didn't catch this.

I'll prepare a fix for Mach-O.

I don't think we need to fix this for PE binaries, since -buildmode=pie is not supported on Windows. I don't know whether we need to fix XCOFF.

@jayconrod jayconrod reopened this Aug 6, 2019
@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Aug 6, 2019

Change https://golang.org/cl/189159 mentions this issue: cmd/go: look for __go_buildinfo section when looking for Mach-O version

@gopherbot gopherbot closed this in 46f99ce Aug 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants
You can’t perform that action at this time.