mirror of https://github.com/golang/go.git
cmd/link: enable ASLR on windows binaries built with -buildmode=c-shared
Windows binaries built with -buildmode=c-shared set will have IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag set, and IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag set for windows/amd64. ASLR can be disabled on windows by using the new linker -aslr flag. RELNOTE=yes Fixes #41421 Change-Id: I62bd88c6d7e0f87173b093a0ad8e1a4d269ec790 Reviewed-on: https://go-review.googlesource.com/c/go/+/255259 Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Reviewed-by: Cherry Zhang <cherryyz@google.com> Trust: Alex Brainman <alex.brainman@gmail.com> Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
7347907164
commit
56dac60074
|
|
@ -5,6 +5,7 @@
|
|||
package ld
|
||||
|
||||
import (
|
||||
"debug/pe"
|
||||
"fmt"
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
|
|
@ -167,3 +168,72 @@ func TestPPC64LargeTextSectionSplitting(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWindowsBuildmodeCSharedASLR(t *testing.T) {
|
||||
platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
switch platform {
|
||||
case "windows/amd64", "windows/386":
|
||||
default:
|
||||
t.Skip("skipping windows amd64/386 only test")
|
||||
}
|
||||
|
||||
t.Run("aslr", func(t *testing.T) {
|
||||
testWindowsBuildmodeCSharedASLR(t, true)
|
||||
})
|
||||
t.Run("no-aslr", func(t *testing.T) {
|
||||
testWindowsBuildmodeCSharedASLR(t, false)
|
||||
})
|
||||
}
|
||||
|
||||
func testWindowsBuildmodeCSharedASLR(t *testing.T, useASLR bool) {
|
||||
t.Parallel()
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
dir, err := ioutil.TempDir("", "go-build")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
srcfile := filepath.Join(dir, "test.go")
|
||||
objfile := filepath.Join(dir, "test.dll")
|
||||
if err := ioutil.WriteFile(srcfile, []byte(`package main; func main() { print("hello") }`), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
argv := []string{"build", "-buildmode=c-shared"}
|
||||
if !useASLR {
|
||||
argv = append(argv, "-ldflags", "-aslr=false")
|
||||
}
|
||||
argv = append(argv, "-o", objfile, srcfile)
|
||||
out, err := exec.Command(testenv.GoToolPath(t), argv...).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("build failure: %s\n%s\n", err, string(out))
|
||||
}
|
||||
|
||||
f, err := pe.Open(objfile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
var dc uint16
|
||||
switch oh := f.OptionalHeader.(type) {
|
||||
case *pe.OptionalHeader32:
|
||||
dc = oh.DllCharacteristics
|
||||
case *pe.OptionalHeader64:
|
||||
dc = oh.DllCharacteristics
|
||||
hasHEVA := (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) != 0
|
||||
if useASLR && !hasHEVA {
|
||||
t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set")
|
||||
} else if !useASLR && hasHEVA {
|
||||
t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag should not be set")
|
||||
}
|
||||
default:
|
||||
t.Fatalf("unexpected optional header type of %T", f.OptionalHeader)
|
||||
}
|
||||
hasASLR := (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) != 0
|
||||
if useASLR && !hasASLR {
|
||||
t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
|
||||
} else if !useASLR && hasASLR {
|
||||
t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag should not be set")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1290,6 +1290,17 @@ func (ctxt *Link) hostlink() {
|
|||
argv = append(argv, "-Wl,-bbigtoc")
|
||||
}
|
||||
|
||||
// Enable ASLR on Windows.
|
||||
addASLRargs := func(argv []string) []string {
|
||||
// Enable ASLR.
|
||||
argv = append(argv, "-Wl,--dynamicbase")
|
||||
// enable high-entropy ASLR on 64-bit.
|
||||
if ctxt.Arch.PtrSize >= 8 {
|
||||
argv = append(argv, "-Wl,--high-entropy-va")
|
||||
}
|
||||
return argv
|
||||
}
|
||||
|
||||
switch ctxt.BuildMode {
|
||||
case BuildModeExe:
|
||||
if ctxt.HeadType == objabi.Hdarwin {
|
||||
|
|
@ -1302,12 +1313,7 @@ func (ctxt *Link) hostlink() {
|
|||
switch ctxt.HeadType {
|
||||
case objabi.Hdarwin, objabi.Haix:
|
||||
case objabi.Hwindows:
|
||||
// Enable ASLR.
|
||||
argv = append(argv, "-Wl,--dynamicbase")
|
||||
// enable high-entropy ASLR on 64-bit.
|
||||
if ctxt.Arch.PtrSize >= 8 {
|
||||
argv = append(argv, "-Wl,--high-entropy-va")
|
||||
}
|
||||
argv = addASLRargs(argv)
|
||||
// Work around binutils limitation that strips relocation table for dynamicbase.
|
||||
// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
|
||||
argv = append(argv, "-Wl,--export-all-symbols")
|
||||
|
|
@ -1331,7 +1337,11 @@ func (ctxt *Link) hostlink() {
|
|||
argv = append(argv, "-Wl,-z,relro")
|
||||
}
|
||||
argv = append(argv, "-shared")
|
||||
if ctxt.HeadType != objabi.Hwindows {
|
||||
if ctxt.HeadType == objabi.Hwindows {
|
||||
if *flagAslr {
|
||||
argv = addASLRargs(argv)
|
||||
}
|
||||
} else {
|
||||
// Pass -z nodelete to mark the shared library as
|
||||
// non-closeable: a dlclose will do nothing.
|
||||
argv = append(argv, "-Wl,-z,nodelete")
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ var (
|
|||
flagDumpDep = flag.Bool("dumpdep", false, "dump symbol dependency graph")
|
||||
flagRace = flag.Bool("race", false, "enable race detector")
|
||||
flagMsan = flag.Bool("msan", false, "enable MSan interface")
|
||||
flagAslr = flag.Bool("aslr", true, "enable ASLR for buildmode=c-shared on windows")
|
||||
|
||||
flagFieldTrack = flag.String("k", "", "set field tracking `symbol`")
|
||||
flagLibGCC = flag.String("libgcc", "", "compiler support lib for internal linking; use \"none\" to disable")
|
||||
|
|
@ -157,6 +158,11 @@ func Main(arch *sys.Arch, theArch Arch) {
|
|||
ctxt.HeadType.Set(objabi.GOOS)
|
||||
}
|
||||
|
||||
if !*flagAslr && ctxt.BuildMode != BuildModeCShared {
|
||||
Errorf(nil, "-aslr=false is only allowed for -buildmode=c-shared")
|
||||
usage()
|
||||
}
|
||||
|
||||
checkStrictDups = *FlagStrictDups
|
||||
|
||||
startProfile()
|
||||
|
|
|
|||
Loading…
Reference in New Issue