]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/secret: warn users about allocations, loosen guarantees
authorDaniel Morsing <daniel.morsing@gmail.com>
Wed, 10 Dec 2025 10:13:05 +0000 (10:13 +0000)
committerDavid Chase <drchase@google.com>
Wed, 17 Dec 2025 15:29:24 +0000 (07:29 -0800)
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>
src/runtime/secret/doc.go [new file with mode: 0644]
src/runtime/secret/secret.go

diff --git a/src/runtime/secret/doc.go b/src/runtime/secret/doc.go
new file mode 100644 (file)
index 0000000..c0dd4f9
--- /dev/null
@@ -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
index 9eae22605fba0b1ee967b6307ee59f6bff4dd6b2..00a03b2d50ee71c490cc929d2a09684399d791e5 100644 (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.