Go: cmd/go: default to -buildmode=pie on Windows

Created on 27 Oct 2019  路  22Comments  路  Source: golang/go

It's 2019. ASLR has been well supported in Windows for a while. We should enable this by default or all the time and address any weird Go bugs that come up as a result. So far I haven't seen any.

ARM on Windows has had ASLR since its inception, so I imagine things are probably fine.

Personally, I'd prefer only allowing ASLR and not having the option in there to avoid it. I think that'd make things a bit simpler and less confusing too, a la v1 of the aslr cl: https://go.googlesource.com/go/+/c04035be04c3a0ef0e44c1e3674485048df5d327%5E%21/

CC @alexbrainman @ianlancetaylor @bradfitz @FiloSottile

NeedsFix Proposal Proposal-Accepted

Most helpful comment

I am not convinced by the idea of overloading -buildmode with fundamental security features. Compiling with -buildmode=exe is currently the default, so it's reasonable to expect it to be a no-op, not a security downgrade.

I think we should just turn on ASLR everywhere, becoming consistent with arm. Losing the distinction between -buildmode=exe and -buildmode=pie sounds much more natural than making -buildmode=exe a security switch: features move into default modes making explicit switches no-ops all the time.

If we are concerned about encountering bugs, I think we should go about it as we go about everything else: testing during the freeze, and making a GODEBUG (or equivalent) opt-out (or temporary opt-in). Likewise, if we need to make it possible to disable ASLR to debug, that sounds like it should be a scary, debug-branded ldflag, not -buildmode=exe. How necessary is it, though?

All 22 comments

Change https://golang.org/cl/203606 mentions this issue: cmd/link: enable ASLR by default on Windows

I would also like to add that this proposal assumes that #27144 is implemented as -buildmode=pie. So this current proposal is effectively means that -buildmode=pie will become default on Windows (as suggested by @ianlancetaylor at https://github.com/golang/go/issues/27144#issuecomment-546633412).

Alex

I am not convinced by the idea of overloading -buildmode with fundamental security features. Compiling with -buildmode=exe is currently the default, so it's reasonable to expect it to be a no-op, not a security downgrade.

I think we should just turn on ASLR everywhere, becoming consistent with arm. Losing the distinction between -buildmode=exe and -buildmode=pie sounds much more natural than making -buildmode=exe a security switch: features move into default modes making explicit switches no-ops all the time.

If we are concerned about encountering bugs, I think we should go about it as we go about everything else: testing during the freeze, and making a GODEBUG (or equivalent) opt-out (or temporary opt-in). Likewise, if we need to make it possible to disable ASLR to debug, that sounds like it should be a scary, debug-branded ldflag, not -buildmode=exe. How necessary is it, though?

I am not convinced by the idea of overloading -buildmode with fundamental security features. Compiling with -buildmode=exe is currently the default, so it's reasonable to expect it to be a no-op, not a security downgrade.

I think we should just turn on ASLR everywhere, becoming consistent with arm. Losing the distinction between -buildmode=exe and -buildmode=pie sounds much more natural than making -buildmode=exe a security switch: features move into default modes making explicit switches no-ops all the time.

Fully agree.

If we are concerned about encountering bugs, I think we should go about it as we go about everything else: testing during the freeze, and making a GODEBUG (or equivalent) opt-out (or temporary opt-in). Likewise, if we need to make it possible to disable ASLR to debug, that sounds like it should be a scary, debug-branded ldflag, not -buildmode=exe. How necessary is it, though?

All the debuggers I use have no problem dynamically rebasing. Otherwise, how would I possibly debug any real world applications or reverse engineer stuff?

Perhaps we should indeed make -buildmode=exe be a synonym for -buildmode=pie on Windows, but we still must have a way to generate a non-PIE binary. I have seen far too many cases where non-PIE executables are required, albeit on non-Windows systems. How should people select a non-PIE binary? This should not be a scary, debug-branded, flag. There are legitimate choices here. The added security of ASLR, which in my personal opinion is quite small for a language like Go, can be reasonably traded off against the costs of ASLR.

All the debuggers I use have no problem dynamically rebasing. Otherwise, how would I possibly debug any real world applications or reverse engineer stuff?

I guess I should point out that debug_frame is broken on macOS with buildmode=pie. I haven't checked the state of debug symbols on windows with buildmode=pie.

I have seen far too many cases where non-PIE executables are required, albeit on non-Windows systems.

Can you point out a Windows case where non-PIE executables are required? Seems like we should base this on real actual cases. With auditors mechanically searching for them and flagging them in reports, they have been moving toward extinction for a long time now.

Let's please take the conservative approach here. We know how to generate a non-PIE. If we change the default to be PIE, I see no reason at all to make it hard to generate a non-PIE.

I am not convinced by the idea of overloading -buildmode with fundamental security features.

I am not married to making -buildmode=pie default idea. If you have better suggestion I am fine with that. -buildmode=pie will not require us to add any new flags.

I think we should just turn on ASLR everywhere, becoming consistent with arm.

I doubt we have many windows-arm Go users. We don't even have windows-arm builder. So we should treat ASLR as completely new feature.

I haven't checked the state of debug symbols on windows with buildmode=pie.

I agree, we should make sure Delve works with ASLR enabled windows binaries. We might discover that "build non ASLR executable" flag will get handy with Delve. Thank you @aarzilli for reminding us about Delve.

Let's please take the conservative approach here. We know how to generate a non-PIE. If we change the default to be PIE, I see no reason at all to make it hard to generate a non-PIE.

I completely agree.

Alex

Out of curiosity, when was buildmode=pie support added to windows? It wasn't in Go 1.11 because I remember I couldn't test Delve with it but I can't find mention of it in either 1.12 or 1.13 release notes.

@aarzilli As far as I know -buildmode=pie does not yet work on Windows. This discussion seems to be about adding it.

In that case I don't understand how https://go-review.googlesource.com/c/go/+/203606 is passing trybots.

Those CLs are changes to the linker to make it generate PIE. They don't add support for go - buildmode=pie. They also don't change cmd/dist to test PIE.

On various Android systems we already set the default buildmode to pie in cmd/go.
Setting the default to pie on Windows too would be consistent with that.

@FiloSottile, I hear what you are saying, but this is an implementation mechanism _and_ a security detail. I would argue it is not primarily about security. The bug says ASLR but really this is just about making a position-independent binary. There are other reasons to have one of those besides ASLR.

Does anyone object to changing the default buildmode for Windows to pie in Go 1.15?
(It seems too late in the cycle for Go 1.14.)

Hasn't this been working for a while? I think 1.14 is a reasonable target, esp as it's a security improvement. There's the whole freeze period to turn up any problems.

EDIT: sorry, got this mixed up with #27144

Does anyone object to changing the default buildmode for Windows to pie in Go 1.15?
(It seems too late in the cycle for Go 1.14.)

How about we will make -buildmode=pie work on Windows (issue #27144) for Go 1.14? Then in Go 1.14 release notes we will announce the change and declare that -buildmode=pie will become default in Go 1.15. Gives everyone plenty of time to prepare for the change.

If this suggestion is accepted, I ask for dispensation to implement #27144 after Go 1.14 freeze. It should not be hard to implement, but there are only few days left.

Alex

I think that's OK although it needs to be complete by the week after the freeze.

It looks very much like -buildmode=pie will not be working, reviewed, and submitted by Friday, so we should hold off on implementation until next cycle. Sorry, but we are being extra strict about the freeze to try to make sure we spend November getting the beta ready, not doing more development.

Given that it won't be in Go 1.14, assuming it is ready for the start of the Go 1.15 cycle, it seems fine, as I said last week, to implement -buildmode=pie and make that the default, in the same cycle.

No one has objected to changing the default (once the code works), so this proposal seems like a likely accept.

Leaving open for a week for final comments.

Relevant CLs: https://golang.org/cl/203602 & https://golang.org/cl/203606

EDIT: Alas, the first is unfinished and the second turned out to be wrong :-(

Accepted.

Change https://golang.org/cl/214397 mentions this issue: cmd/go, cmd/link: implement -buildmode=pie on windows

Change https://golang.org/cl/230217 mentions this issue: cmd/go: use -buildmode=pie as default on window

Was this page helpful?
0 / 5 - 0 ratings