diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/malloc.go | 2 | ||||
| -rw-r--r-- | src/runtime/malloc_generated.go | 152 | ||||
| -rw-r--r-- | src/runtime/malloc_stubs.go | 2 | ||||
| -rw-r--r-- | src/runtime/mheap.go | 28 | ||||
| -rw-r--r-- | src/runtime/secret.go | 9 | ||||
| -rw-r--r-- | src/runtime/secret/alloc_test.go | 39 | ||||
| -rw-r--r-- | src/runtime/secret_nosecret.go | 4 |
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 } |
