From: Cherry Zhang Date: Thu, 25 Apr 2019 16:09:42 +0000 (-0400) Subject: cmd/link: avoid writing to read-only memory in addstrdata X-Git-Tag: go1.13beta1~553 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=93fcebaf31965760c3bc8c087cb7e46127397994;p=gostls13.git cmd/link: avoid writing to read-only memory in addstrdata When the linker's -X flag is used, it will overwrite the symbol's content (sym.P) in addstrdata. The symbol's content may be in read-only memory, in which case overwriting it will fault. Do copy-on-write to fix this. Change-Id: I34d583f44c30d187042757e19a14c1ef7d3e613c Reviewed-on: https://go-review.googlesource.com/c/go/+/173937 Run-TryBot: Cherry Zhang Reviewed-by: Brad Fitzpatrick Reviewed-by: Than McIntosh TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 52d33edbbb..b4a76af328 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -939,6 +939,10 @@ func addstrdata(ctxt *Link, name, value string) { s.Size = 0 s.P = s.P[:0] + if s.Attr.ReadOnly() { + s.P = make([]byte, 0, ctxt.Arch.PtrSize*2) + s.Attr.Set(sym.AttrReadOnly, false) + } s.R = s.R[:0] reachable := s.Attr.Reachable() s.AddAddr(ctxt.Arch, sp) diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go index 5ecda58707..a428e758d7 100644 --- a/src/cmd/link/link_test.go +++ b/src/cmd/link/link_test.go @@ -229,3 +229,31 @@ func TestBuildFortvOS(t *testing.T) { t.Fatalf("%v: %v:\n%s", link.Args, err, out) } } + +var testXFlagSrc = ` +package main +var X = "hello" +var Z = [99999]int{99998:12345} // make it large enough to be mmaped +func main() { println(X) } +` + +func TestXFlag(t *testing.T) { + testenv.MustHaveGoBuild(t) + + tmpdir, err := ioutil.TempDir("", "TestXFlag") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + src := filepath.Join(tmpdir, "main.go") + err = ioutil.WriteFile(src, []byte(testXFlagSrc), 0666) + if err != nil { + t.Fatal(err) + } + + cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-X=main.X=meow", "-o", filepath.Join(tmpdir, "main"), src) + if out, err := cmd.CombinedOutput(); err != nil { + t.Errorf("%v: %v:\n%s", cmd.Args, err, out) + } +}