mirror of
https://github.com/golang/go
synced 2024-11-18 08:14:41 -07:00
cmd/link: turn ASLR off for netbsd+race
The race detector can't handle ASLR (adddress space layout randomization). On some platforms it can re-exec the binary with ASLR off. But not NetBSD. For NetBSD we have to introduce a special ELF header note that tells the kernel not to use ASLR. This works fine for internal linking. For external linking it also works, but "readelf -n" shows multiple notes in the resulting binary. Maybe the last one wins? Not sure, but it appears to work. Change-Id: I5fe6dd861e42a8293f64d0dacb166631ea670fcc Reviewed-on: https://go-review.googlesource.com/c/go/+/227864 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
parent
df15eaedd0
commit
fd18f3ba50
@ -883,6 +883,25 @@ func elfwritenetbsdsig(out *OutBuf) int {
|
||||
return int(sh.size)
|
||||
}
|
||||
|
||||
// The race detector can't handle ASLR (address space layout randomization).
|
||||
// ASLR is on by default for NetBSD, so we turn the ASLR off eplicitly
|
||||
// using a magic elf Note when building race binaries.
|
||||
|
||||
func elfnetbsdpax(sh *ElfShdr, startva uint64, resoff uint64) int {
|
||||
n := int(Rnd(4, 4) + Rnd(4, 4))
|
||||
return elfnote(sh, startva, resoff, n)
|
||||
}
|
||||
|
||||
func elfwritenetbsdpax(out *OutBuf) int {
|
||||
sh := elfwritenotehdr(out, ".note.netbsd.pax", 4 /* length of PaX\x00 */, 4 /* length of flags */, 0x03 /* PaX type */)
|
||||
if sh == nil {
|
||||
return 0
|
||||
}
|
||||
out.Write([]byte("PaX\x00"))
|
||||
out.Write32(0x20) // 0x20 = Force disable ASLR
|
||||
return int(sh.size)
|
||||
}
|
||||
|
||||
// OpenBSD Signature
|
||||
const (
|
||||
ELF_NOTE_OPENBSD_NAMESZ = 8
|
||||
@ -1484,6 +1503,9 @@ func (ctxt *Link) doelf() {
|
||||
}
|
||||
if ctxt.IsNetbsd() {
|
||||
shstrtab.Addstring(".note.netbsd.ident")
|
||||
if *flagRace {
|
||||
shstrtab.Addstring(".note.netbsd.pax")
|
||||
}
|
||||
}
|
||||
if ctxt.IsOpenbsd() {
|
||||
shstrtab.Addstring(".note.openbsd.ident")
|
||||
@ -1821,6 +1843,14 @@ func Asmbelf(ctxt *Link, symo int64) {
|
||||
|
||||
var pph *ElfPhdr
|
||||
var pnote *ElfPhdr
|
||||
if *flagRace && ctxt.IsNetbsd() {
|
||||
sh := elfshname(".note.netbsd.pax")
|
||||
resoff -= int64(elfnetbsdpax(sh, uint64(startva), uint64(resoff)))
|
||||
pnote = newElfPhdr()
|
||||
pnote.type_ = PT_NOTE
|
||||
pnote.flags = PF_R
|
||||
phsh(pnote, sh)
|
||||
}
|
||||
if ctxt.LinkMode == LinkExternal {
|
||||
/* skip program headers */
|
||||
eh.phoff = 0
|
||||
@ -2298,6 +2328,9 @@ elfobj:
|
||||
a += int64(elfwritegobuildid(ctxt.Out))
|
||||
}
|
||||
}
|
||||
if *flagRace && ctxt.IsNetbsd() {
|
||||
a += int64(elfwritenetbsdpax(ctxt.Out))
|
||||
}
|
||||
|
||||
if a > elfreserve {
|
||||
Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
|
||||
|
Loading…
Reference in New Issue
Block a user