runtime/secret: warn users about allocations, loosen guarantees

The discussion at #76477 warranted some stronger documentation about
what is expected from users of the secret package. In addition, #76764
presented a problem about when a user can expect their secrets to be
deleted.

Fix by loosening the guarantee to when all allocations from within a
secret function have been deemed unreachable. Provide some guidance for
users to steer them away from situations where allocations live on for
long after the secret function has finished executing

Fixes #76764.
Updates #76477.

Change-Id: I0cef3e7275737f32ec48f71355e588b3be26ea32
Reviewed-on: https://go-review.googlesource.com/c/go/+/728921
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Daniel Morsing 2025-12-10 10:13:05 +00:00 committed by David Chase
parent 8c28ab936a
commit 516699848b
2 changed files with 28 additions and 2 deletions

15
src/runtime/secret/doc.go Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build goexperiment.runtimesecret
// Package secret contains helper functions for zeroing out memory
// that is otherwise invisible to a user program in the service of
// forward secrecy. See https://en.wikipedia.org/wiki/Forward_secrecy for
// more information.
//
// This package (runtime/secret) is experimental,
// and not subject to the Go 1 compatibility promise.
// It only exists when building with the GOEXPERIMENT=runtimesecret environment variable set.
package secret

View File

@ -18,12 +18,23 @@ import (
// entire call tree initiated by f.)
// - Any registers used by f are erased before Do returns.
// - Any stack used by f is erased before Do returns.
// - Any heap allocation done by f is erased as soon as the garbage
// collector realizes that it is no longer reachable.
// - Heap allocations done by f are erased as soon as the garbage
// collector realizes that all allocated values are no longer reachable.
// - Do works even if f panics or calls runtime.Goexit. As part of
// that, any panic raised by f will appear as if it originates from
// Do itself.
//
// 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.
// These costs can compound when an allocation is done in the service of growing a value,
// like appending to a slice or inserting into a map. In these cases, the entire new allocation is erased rather
// than just the secret parts of it.
//
// To reduce lifetimes of allocations and avoid unexpected performance issues,
// if a function invoked by Do needs to yield a result that shouldn't be erased,
// it should do so by copying the result into an allocation created by the caller.
//
// Limitations:
// - Currently only supported on linux/amd64 and linux/arm64. On unsupported
// platforms, Do will invoke f directly.