]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: avoid writing to read-only memory in addstrdata
authorCherry Zhang <cherryyz@google.com>
Thu, 25 Apr 2019 16:09:42 +0000 (12:09 -0400)
committerCherry Zhang <cherryyz@google.com>
Thu, 25 Apr 2019 17:52:31 +0000 (17:52 +0000)
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 <cherryyz@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/link/internal/ld/data.go
src/cmd/link/link_test.go

index 52d33edbbb7d0823c7a0a0a1a5c018059caa534e..b4a76af3284a03b947b17eb1ff55855f84365435 100644 (file)
@@ -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)
index 5ecda58707f2a4111ed631080c44aa47a528f673..a428e758d708a46151df1edbc657a4198648d179 100644 (file)
@@ -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)
+       }
+}