Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: memory corruption from stack-allocated defer on 32-bit [1.14 backport] #41796

Closed
gopherbot opened this issue Oct 5, 2020 · 3 comments
Labels
CherryPickApproved Used during the release process for point releases FrozenDueToAge
Milestone

Comments

@gopherbot
Copy link

@aclements requested issue #41795 to be considered for backport to the next 1.14 minor release.

@gopherbot, please open backports to Go 1.15 and 1.14.

This can cause random memory corruption on 32-bit architectures. The circumstances for it happening are incredibly narrow, but the fix is also trivial.

@gopherbot gopherbot added the CherryPickCandidate Used during the release process for point releases label Oct 5, 2020
@gopherbot gopherbot added this to the Go1.14.10 milestone Oct 5, 2020
@gopherbot
Copy link
Author

Change https://golang.org/cl/259597 mentions this issue: [release-branch.go1.14] runtime: correct signature of call16

@dmitshur dmitshur added CherryPickApproved Used during the release process for point releases and removed CherryPickCandidate Used during the release process for point releases labels Oct 8, 2020
@dmitshur
Copy link
Contributor

dmitshur commented Oct 8, 2020

Approving per discussion in a release meeting. This is a serious issue and the fix is trivial. This backport applies to both 1.15 (#41797) and 1.14 (this issue).

@gopherbot
Copy link
Author

Closed by merging 0bf9410 to release-branch.go1.14.

gopherbot pushed a commit that referenced this issue Oct 14, 2020
The signature of call16 is currently missing the "typ" parameter. This
CL fixes this. This wasn't caught by vet because call16 is defined by
macro expansion (see #17544), and we didn't notice the mismatch with
the other call* functions because call16 is defined only on 32-bit
architectures and lives alone in stubs32.go.

Unfortunately, this means its GC signature is also wrong: the "arg"
parameter is treated as a scalar rather than a pointer, so GC won't
trace it and stack copying won't adjust it. This turns out to matter
in exactly one case right now: on 32-bit architectures (which are the
only architectures where call16 is defined), a stack-allocated defer
of a function with a 16-byte or smaller argument frame including a
non-empty result area can corrupt memory if the deferred function
grows the stack and is invoked during a panic. Whew. All other current
uses of reflectcall pass a heap-allocated "arg" frame (which happens
to be reachable from other stack roots, so tracing isn't a problem).

Curiously, in 2016, the signatures of all call* functions were wrong
in exactly this way. CL 31654 fixed all of them in stubs.go, but
missed the one in stubs32.go.

Updates #41795.
Fixes #41796.

Change-Id: I31e3c0df201f79ee5707eeb8dc4ff0d13fc10ada
Reviewed-on: https://go-review.googlesource.com/c/go/+/259338
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/259597
@golang golang locked and limited conversation to collaborators Oct 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
CherryPickApproved Used during the release process for point releases FrozenDueToAge
Projects
None yet
Development

No branches or pull requests

2 participants