mirror of
https://github.com/golang/go.git
synced 2026-06-27 19:30:52 +00:00
runtime/secret: implement goroutine inheriting secret state
Updates #76477. Change-Id: I58726393363f0dc5a83b8a215a9d854d1e0e2c78 Reviewed-on: https://go-review.googlesource.com/c/go/+/728922 Reviewed-by: Junyang Shao <shaojunyang@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
parent
e73e73470e
commit
e26a373785
3 changed files with 35 additions and 2 deletions
|
|
@ -5442,6 +5442,18 @@ func newproc1(fn *funcval, callergp *g, callerpc uintptr, parked bool, waitreaso
|
|||
// dit bubble
|
||||
newg.ditWanted = callergp.ditWanted
|
||||
|
||||
if goexperiment.RuntimeSecret && callergp.secret > 0 {
|
||||
// while it might seem weird to have a non-zero gp.secret value
|
||||
// with no calls to secret.Do on the stack, this case is handled
|
||||
// just fine by the cleanup logic in goexit0
|
||||
// TODO: secret mode is invisible to the user if they don't ask about it via secret.Enabled
|
||||
// and can have severe performance penalties (at time of writing, wrapping the entire
|
||||
// tls handshake resulted in a 30% slowdown of the benchmarks).
|
||||
// Whether a goroutine is running in secret mode should be more visible,
|
||||
// maybe with a stack frame or some sort of bubble inspecting mechanism
|
||||
newg.secret = 1
|
||||
}
|
||||
|
||||
// Set up race context.
|
||||
if raceenabled {
|
||||
newg.racectx = racegostart(callerpc)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ import (
|
|||
// that, any panic raised by f will appear as if it originates from
|
||||
// Do itself.
|
||||
//
|
||||
// Any goroutine spawned while executing f will act as if the entire goroutine
|
||||
// is wrapped inside another call to Do.
|
||||
//
|
||||
// Users should be cautious of allocating inside Do.
|
||||
// Erasing heap memory after Do returns may increase garbage collector sweep times and
|
||||
// requires additional memory to keep track of allocations until they are to be erased.
|
||||
|
|
@ -39,7 +42,6 @@ import (
|
|||
// - Currently only supported on linux/amd64 and linux/arm64. On unsupported
|
||||
// platforms, Do will invoke f directly.
|
||||
// - Protection does not extend to any global variables written by f.
|
||||
// - Protection does not extend to any new goroutines made by f.
|
||||
// - If f calls runtime.Goexit, erasure can be delayed by defers
|
||||
// higher up on the call stack.
|
||||
// - Heap allocations will only be erased if the program drops all
|
||||
|
|
@ -119,7 +121,10 @@ func doHelper(f func()) (p any) {
|
|||
return
|
||||
}
|
||||
|
||||
// Enabled reports whether [Do] appears anywhere on the call stack.
|
||||
// Enabled reports whether the current goroutine
|
||||
// is running in secret mode. This is usually through a call to
|
||||
// [Do], but can also occur when a goroutine already running in
|
||||
// secret mode launches another goroutine.
|
||||
func Enabled() bool {
|
||||
return count() > 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,6 +284,22 @@ func TestRegisters(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSecretInheritance(t *testing.T) {
|
||||
ch := make(chan bool, 2)
|
||||
Do(func() {
|
||||
ch <- Enabled()
|
||||
go func() {
|
||||
ch <- Enabled()
|
||||
close(ch)
|
||||
}()
|
||||
})
|
||||
for enabled := range ch {
|
||||
if !enabled {
|
||||
t.Error("secret mode not enabled for child goroutine")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignalStacks(t *testing.T) {
|
||||
Do(func() {
|
||||
s := makeS()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue