unix: set R12 before the ppc64x syscall branch
The four ppc64x syscall trampolines jump to the global entry point of
the generated ABI0 wrapper without setting R12. In a PIE that entry
point derives its TOC from R12, as ELFv2 requires of a caller entering
there, so the callee computes a wrong TOC and every global access
afterwards reads or writes the wrong memory. Any PIE binary that calls
unix.Syscall dies at startup on ppc64le.
Loading the target address into R12 instead of R31 fixes it and keeps
the indirect jump, so this does not reintroduce the linker range
problem that golang/go#81981 reported. In a non-PIE build the wrapper
has no TOC prologue and never reads R12, so nothing changes there.
Measured on a ten line program that calls unix.Syscall once, cross
compiled for ppc64le and run under qemu-user, three runs each:
unpatched -buildmode=pie SIGSEGV 3/3
patched -buildmode=pie ok 3/3
unpatched no -buildmode=pie ok 3/3
Debian's ppc64el buildd hit this on real hardware while building siso,
which is how it was found.
Fixes golang/go#82324
Change-Id: I5f65469083461519f87597065646bf8b10750f72
Reviewed-on: https://go-review.googlesource.com/c/sys/+/850585
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Paul Murphy <paumurph@redhat.com>
Reviewed-by: Paul Murphy <paumurph@redhat.com>
This repository holds supplemental Go packages for low-level interactions with the operating system.
This repository uses Gerrit for code changes. To learn how to submit changes to this repository, see https://go.dev/doc/contribute.
The git repository is https://go.googlesource.com/sys.
The main issue tracker for the sys repository is located at https://go.dev/issues. Prefix your issue with “x/sys:” in the subject line, so it is easy to find.