aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/malloc.go2
-rw-r--r--src/runtime/malloc_generated.go152
-rw-r--r--src/runtime/malloc_stubs.go2
-rw-r--r--src/runtime/mheap.go28
-rw-r--r--src/runtime/secret.go9
-rw-r--r--src/runtime/secret/alloc_test.go39
-rw-r--r--src/runtime/secret_nosecret.go4
7 files changed, 147 insertions, 89 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index fd79356aba..c08bc7574b 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -1213,7 +1213,7 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
if goexperiment.RuntimeSecret && gp.secret > 0 {
// Mark any object allocated while in secret mode as secret.
// This ensures we zero it immediately when freeing it.
- addSecret(x)
+ addSecret(x, size)
}
// Notify sanitizers, if enabled.
diff --git a/src/runtime/malloc_generated.go b/src/runtime/malloc_generated.go
index cf329d2696..2be6a5b6f5 100644
--- a/src/runtime/malloc_generated.go
+++ b/src/runtime/malloc_generated.go
@@ -156,7 +156,7 @@ func mallocgcSmallScanNoHeaderSC1(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -321,7 +321,7 @@ func mallocgcSmallScanNoHeaderSC2(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -486,7 +486,7 @@ func mallocgcSmallScanNoHeaderSC3(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -651,7 +651,7 @@ func mallocgcSmallScanNoHeaderSC4(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -816,7 +816,7 @@ func mallocgcSmallScanNoHeaderSC5(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -981,7 +981,7 @@ func mallocgcSmallScanNoHeaderSC6(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -1146,7 +1146,7 @@ func mallocgcSmallScanNoHeaderSC7(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -1311,7 +1311,7 @@ func mallocgcSmallScanNoHeaderSC8(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -1476,7 +1476,7 @@ func mallocgcSmallScanNoHeaderSC9(size uintptr, typ *_type, needzero bool) unsaf
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -1641,7 +1641,7 @@ func mallocgcSmallScanNoHeaderSC10(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -1806,7 +1806,7 @@ func mallocgcSmallScanNoHeaderSC11(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -1971,7 +1971,7 @@ func mallocgcSmallScanNoHeaderSC12(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -2136,7 +2136,7 @@ func mallocgcSmallScanNoHeaderSC13(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -2301,7 +2301,7 @@ func mallocgcSmallScanNoHeaderSC14(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -2466,7 +2466,7 @@ func mallocgcSmallScanNoHeaderSC15(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -2631,7 +2631,7 @@ func mallocgcSmallScanNoHeaderSC16(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -2796,7 +2796,7 @@ func mallocgcSmallScanNoHeaderSC17(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -2961,7 +2961,7 @@ func mallocgcSmallScanNoHeaderSC18(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -3126,7 +3126,7 @@ func mallocgcSmallScanNoHeaderSC19(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -3291,7 +3291,7 @@ func mallocgcSmallScanNoHeaderSC20(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -3456,7 +3456,7 @@ func mallocgcSmallScanNoHeaderSC21(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -3621,7 +3621,7 @@ func mallocgcSmallScanNoHeaderSC22(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -3786,7 +3786,7 @@ func mallocgcSmallScanNoHeaderSC23(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -3951,7 +3951,7 @@ func mallocgcSmallScanNoHeaderSC24(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -4116,7 +4116,7 @@ func mallocgcSmallScanNoHeaderSC25(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -4281,7 +4281,7 @@ func mallocgcSmallScanNoHeaderSC26(size uintptr, typ *_type, needzero bool) unsa
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -6686,7 +6686,7 @@ func mallocgcSmallNoScanSC2(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -6757,7 +6757,7 @@ func mallocgcSmallNoScanSC2(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -6822,7 +6822,7 @@ func mallocgcSmallNoScanSC3(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -6893,7 +6893,7 @@ func mallocgcSmallNoScanSC3(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -6958,7 +6958,7 @@ func mallocgcSmallNoScanSC4(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7029,7 +7029,7 @@ func mallocgcSmallNoScanSC4(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7094,7 +7094,7 @@ func mallocgcSmallNoScanSC5(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7165,7 +7165,7 @@ func mallocgcSmallNoScanSC5(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7230,7 +7230,7 @@ func mallocgcSmallNoScanSC6(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7301,7 +7301,7 @@ func mallocgcSmallNoScanSC6(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7366,7 +7366,7 @@ func mallocgcSmallNoScanSC7(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7437,7 +7437,7 @@ func mallocgcSmallNoScanSC7(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7502,7 +7502,7 @@ func mallocgcSmallNoScanSC8(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7573,7 +7573,7 @@ func mallocgcSmallNoScanSC8(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7638,7 +7638,7 @@ func mallocgcSmallNoScanSC9(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7709,7 +7709,7 @@ func mallocgcSmallNoScanSC9(size uintptr, typ *_type, needzero bool) unsafe.Poin
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7774,7 +7774,7 @@ func mallocgcSmallNoScanSC10(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7845,7 +7845,7 @@ func mallocgcSmallNoScanSC10(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7910,7 +7910,7 @@ func mallocgcSmallNoScanSC11(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -7981,7 +7981,7 @@ func mallocgcSmallNoScanSC11(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8046,7 +8046,7 @@ func mallocgcSmallNoScanSC12(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8117,7 +8117,7 @@ func mallocgcSmallNoScanSC12(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8182,7 +8182,7 @@ func mallocgcSmallNoScanSC13(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8253,7 +8253,7 @@ func mallocgcSmallNoScanSC13(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8318,7 +8318,7 @@ func mallocgcSmallNoScanSC14(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8389,7 +8389,7 @@ func mallocgcSmallNoScanSC14(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8454,7 +8454,7 @@ func mallocgcSmallNoScanSC15(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8525,7 +8525,7 @@ func mallocgcSmallNoScanSC15(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8590,7 +8590,7 @@ func mallocgcSmallNoScanSC16(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8661,7 +8661,7 @@ func mallocgcSmallNoScanSC16(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8726,7 +8726,7 @@ func mallocgcSmallNoScanSC17(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8797,7 +8797,7 @@ func mallocgcSmallNoScanSC17(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8862,7 +8862,7 @@ func mallocgcSmallNoScanSC18(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8933,7 +8933,7 @@ func mallocgcSmallNoScanSC18(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -8998,7 +8998,7 @@ func mallocgcSmallNoScanSC19(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9069,7 +9069,7 @@ func mallocgcSmallNoScanSC19(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9134,7 +9134,7 @@ func mallocgcSmallNoScanSC20(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9205,7 +9205,7 @@ func mallocgcSmallNoScanSC20(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9270,7 +9270,7 @@ func mallocgcSmallNoScanSC21(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9341,7 +9341,7 @@ func mallocgcSmallNoScanSC21(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9406,7 +9406,7 @@ func mallocgcSmallNoScanSC22(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9477,7 +9477,7 @@ func mallocgcSmallNoScanSC22(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9542,7 +9542,7 @@ func mallocgcSmallNoScanSC23(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9613,7 +9613,7 @@ func mallocgcSmallNoScanSC23(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9678,7 +9678,7 @@ func mallocgcSmallNoScanSC24(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9749,7 +9749,7 @@ func mallocgcSmallNoScanSC24(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9814,7 +9814,7 @@ func mallocgcSmallNoScanSC25(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9885,7 +9885,7 @@ func mallocgcSmallNoScanSC25(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -9950,7 +9950,7 @@ func mallocgcSmallNoScanSC26(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
@@ -10021,7 +10021,7 @@ func mallocgcSmallNoScanSC26(size uintptr, typ *_type, needzero bool) unsafe.Poi
gp := getg()
if goexperiment.RuntimeSecret && gp.secret > 0 {
- addSecret(x)
+ addSecret(x, size)
}
if valgrindenabled {
diff --git a/src/runtime/malloc_stubs.go b/src/runtime/malloc_stubs.go
index 8c424935bf..b395172e4b 100644
--- a/src/runtime/malloc_stubs.go
+++ b/src/runtime/malloc_stubs.go
@@ -101,7 +101,7 @@ func mallocStub(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
if goexperiment.RuntimeSecret && gp.secret > 0 {
// Mark any object allocated while in secret mode as secret.
// This ensures we zero it immediately when freeing it.
- addSecret(x)
+ addSecret(x, size)
}
}
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index 61dc5457fc..68dfca4668 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -2745,6 +2745,14 @@ type specialPinCounter struct {
counter uintptr
}
+// specialSecret tracks whether we need to zero an object immediately
+// upon freeing.
+type specialSecret struct {
+ _ sys.NotInHeap
+ special special
+ size uintptr
+}
+
// specialsIter helps iterate over specials lists.
type specialsIter struct {
pprev **special
@@ -2775,6 +2783,12 @@ func (i *specialsIter) unlinkAndNext() *special {
// freeSpecial performs any cleanup on special s and deallocates it.
// s must already be unlinked from the specials list.
+// TODO(mknyszek): p and size together DO NOT represent a valid allocation.
+// size is the size of the allocation block in the span (mspan.elemsize), and p is
+// whatever pointer the special was attached to, which need not point to the
+// beginning of the block, though it may.
+// Consider passing the arguments differently to avoid giving the impression
+// that p and size together represent an address range.
func freeSpecial(s *special, p unsafe.Pointer, size uintptr) {
switch s.kind {
case _KindSpecialFinalizer:
@@ -2828,7 +2842,19 @@ func freeSpecial(s *special, p unsafe.Pointer, size uintptr) {
mheap_.specialBubbleAlloc.free(unsafe.Pointer(st))
unlock(&mheap_.speciallock)
case _KindSpecialSecret:
- memclrNoHeapPointers(p, size)
+ ss := (*specialSecret)(unsafe.Pointer(s))
+ // p is the actual byte location that the special was
+ // attached to, but the size argument is the span
+ // element size. If we were to zero out using the size
+ // argument, we'd trounce over adjacent memory in cases
+ // where the allocation contains a header. Hence, we use
+ // the user-visible size which we stash in the special itself.
+ //
+ // p always points to the beginning of the user-visible
+ // allocation since the only way to attach a secret special
+ // is via the allocation path. This isn't universal for
+ // tiny allocs, but we avoid them in mallocgc anyway.
+ memclrNoHeapPointers(p, ss.size)
lock(&mheap_.speciallock)
mheap_.specialSecretAlloc.free(unsafe.Pointer(s))
unlock(&mheap_.speciallock)
diff --git a/src/runtime/secret.go b/src/runtime/secret.go
index 4c199d31d0..8aad63b54f 100644
--- a/src/runtime/secret.go
+++ b/src/runtime/secret.go
@@ -55,15 +55,9 @@ func secret_eraseSecrets() {
// Don't put any code here: the stack frame's contents are gone!
}
-// specialSecret tracks whether we need to zero an object immediately
-// upon freeing.
-type specialSecret struct {
- special special
-}
-
// addSecret records the fact that we need to zero p immediately
// when it is freed.
-func addSecret(p unsafe.Pointer) {
+func addSecret(p unsafe.Pointer, size uintptr) {
// TODO(dmo): figure out the cost of these. These are mostly
// intended to catch allocations that happen via the runtime
// that the user has no control over and not big buffers that user
@@ -72,6 +66,7 @@ func addSecret(p unsafe.Pointer) {
lock(&mheap_.speciallock)
s := (*specialSecret)(mheap_.specialSecretAlloc.alloc())
s.special.kind = _KindSpecialSecret
+ s.size = size
unlock(&mheap_.speciallock)
addspecial(p, &s.special, false)
}
diff --git a/src/runtime/secret/alloc_test.go b/src/runtime/secret/alloc_test.go
new file mode 100644
index 0000000000..8f82dad4b5
--- /dev/null
+++ b/src/runtime/secret/alloc_test.go
@@ -0,0 +1,39 @@
+// 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 && (arm64 || amd64) && linux
+
+package secret_test
+
+import (
+ "runtime"
+ "runtime/secret"
+ "testing"
+)
+
+func TestInterleavedAllocFrees(t *testing.T) {
+ // Interleave heap objects that are kept alive beyond secret.Do
+ // with heap objects that do not live past secret.Do.
+ // The intent is for the clearing of one object (with the wrong size)
+ // to clobber the type header of the next slot. If the GC sees a nil type header
+ // when it expects to find one, it can throw.
+ type T struct {
+ p *int
+ x [1024]byte
+ }
+ for range 10 {
+ var s []*T
+ secret.Do(func() {
+ for i := range 100 {
+ t := &T{}
+ if i%2 == 0 {
+ s = append(s, t)
+ }
+ }
+ })
+ runtime.GC()
+ runtime.GC()
+ runtime.KeepAlive(s)
+ }
+}
diff --git a/src/runtime/secret_nosecret.go b/src/runtime/secret_nosecret.go
index bf50fb5a54..0692d6bf70 100644
--- a/src/runtime/secret_nosecret.go
+++ b/src/runtime/secret_nosecret.go
@@ -22,9 +22,7 @@ func secret_dec() {}
//go:linkname secret_eraseSecrets runtime/secret.eraseSecrets
func secret_eraseSecrets() {}
-func addSecret(p unsafe.Pointer) {}
-
-type specialSecret struct{}
+func addSecret(p unsafe.Pointer, size uintptr) {}
//go:linkname secret_getStack runtime/secret.getStack
func secret_getStack() (uintptr, uintptr) { return 0, 0 }