1
0
mirror of https://github.com/golang/go synced 2024-11-23 05:50:05 -07:00

cmd/internal/buildid: update Mach-O code signature when rewriting buildid

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>
This commit is contained in:
Cherry Zhang 2020-11-21 21:24:57 -05:00
parent 6f84993e90
commit 8cd35e00bd
3 changed files with 32 additions and 11 deletions

View File

@ -62,7 +62,7 @@ func main() {
return return
} }
f, err = os.OpenFile(file, os.O_WRONLY, 0) f, err = os.OpenFile(file, os.O_RDWR, 0)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -647,7 +647,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error {
} }
if rewrite { if rewrite {
w, err := os.OpenFile(target, os.O_WRONLY, 0) w, err := os.OpenFile(target, os.O_RDWR, 0)
if err != nil { if err != nil {
return err return err
} }

View File

@ -94,19 +94,27 @@ func Rewrite(w io.WriterAt, pos []int64, id string) error {
return err 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 return nil
} }
func excludeMachoCodeSignature(r io.Reader) io.Reader { func excludeMachoCodeSignature(r io.Reader) io.Reader {
ra, ok := r.(io.ReaderAt) _, cmd, ok := findMachoCodeSignature(r)
if !ok {
return r
}
f, err := macho.NewFile(ra)
if err != nil {
return r
}
cmd, ok := codesign.FindCodeSigCmd(f)
if !ok { if !ok {
return r return r
} }
@ -139,3 +147,16 @@ func (r *excludedReader) Read(p []byte) (int, error) {
r.off += int64(n) r.off += int64(n)
return n, err 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
}