]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/buildid: update Mach-O code signature when rewriting buildid
authorCherry Zhang <cherryyz@google.com>
Sun, 22 Nov 2020 02:24:57 +0000 (21:24 -0500)
committerCherry Zhang <cherryyz@google.com>
Tue, 1 Dec 2020 23:37:58 +0000 (23:37 +0000)
As the code signature contains hashes of the entire file (except
the signature itself), rewriting buildid will invalidate the
signature. This CL makes it regenerate the signature when
rewriting the buildid. It only does it when the file already has
a code signature, with proper size (darwin/arm64 binaries
generated by the Go linker should have).

Updates #38485, #42684.

Change-Id: I082d9e5808b0ee6a35f9c362d7262aadd9113c81
Reviewed-on: https://go-review.googlesource.com/c/go/+/272257
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/buildid/buildid.go
src/cmd/go/internal/work/buildid.go
src/cmd/internal/buildid/rewrite.go

index 699d9779508f0b0bc0e1ace2832929827db1ecd0..8e02a7ae109611488417ab480cd47288de45d81a 100644 (file)
@@ -62,7 +62,7 @@ func main() {
                return
        }
 
-       f, err = os.OpenFile(file, os.O_WRONLY, 0)
+       f, err = os.OpenFile(file, os.O_RDWR, 0)
        if err != nil {
                log.Fatal(err)
        }
index a88544e1af97c80bf30d179e9df283e916b37203..3c7be5a3e34bb559a464de3c3b3afdce7a5b8536 100644 (file)
@@ -647,7 +647,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error {
        }
 
        if rewrite {
-               w, err := os.OpenFile(target, os.O_WRONLY, 0)
+               w, err := os.OpenFile(target, os.O_RDWR, 0)
                if err != nil {
                        return err
                }
index d3d2009d1ce570b61ec0cca8cfc8cab1cbc03ecf..a7928959c483da9f467fefb6209030c8d34b030d 100644 (file)
@@ -94,19 +94,27 @@ func Rewrite(w io.WriterAt, pos []int64, id string) error {
                        return err
                }
        }
+
+       // Update Mach-O code signature, if any.
+       if f, cmd, ok := findMachoCodeSignature(w); ok {
+               if codesign.Size(int64(cmd.Dataoff), "a.out") == int64(cmd.Datasize) {
+                       // Update the signature if the size matches, so we don't need to
+                       // fix up headers. Binaries generated by the Go linker should have
+                       // the expected size. Otherwise skip.
+                       text := f.Segment("__TEXT")
+                       cs := make([]byte, cmd.Datasize)
+                       codesign.Sign(cs, w.(io.Reader), "a.out", int64(cmd.Dataoff), int64(text.Offset), int64(text.Filesz), f.Type == macho.TypeExec)
+                       if _, err := w.WriteAt(cs, int64(cmd.Dataoff)); err != nil {
+                               return err
+                       }
+               }
+       }
+
        return nil
 }
 
 func excludeMachoCodeSignature(r io.Reader) io.Reader {
-       ra, ok := r.(io.ReaderAt)
-       if !ok {
-               return r
-       }
-       f, err := macho.NewFile(ra)
-       if err != nil {
-               return r
-       }
-       cmd, ok := codesign.FindCodeSigCmd(f)
+       _, cmd, ok := findMachoCodeSignature(r)
        if !ok {
                return r
        }
@@ -139,3 +147,16 @@ func (r *excludedReader) Read(p []byte) (int, error) {
        r.off += int64(n)
        return n, err
 }
+
+func findMachoCodeSignature(r interface{}) (*macho.File, codesign.CodeSigCmd, bool) {
+       ra, ok := r.(io.ReaderAt)
+       if !ok {
+               return nil, codesign.CodeSigCmd{}, false
+       }
+       f, err := macho.NewFile(ra)
+       if err != nil {
+               return nil, codesign.CodeSigCmd{}, false
+       }
+       cmd, ok := codesign.FindCodeSigCmd(f)
+       return f, cmd, ok
+}