[go/release-branch.go1.25] [release-branch.go1.25] runtime: add sysUnreserve to undo sysReserve

0 views
Skip to first unread message

Carlos Amedee (Gerrit)

unread,
Apr 23, 2026, 4:40:30 PM (2 days ago) Apr 23
to Michael Pratt, Mark Freeman, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, golang...@luci-project-accounts.iam.gserviceaccount.com, golang-co...@googlegroups.com

Carlos Amedee submitted the change

Change information

Commit message:
[release-branch.go1.25] runtime: add sysUnreserve to undo sysReserve

This is inspired by CL 724560 by Bobby Powers, particularly their great
commit message.

When using address sanitizer with leak detection, sysReserve registers
memory regions with LSAN via lsanregisterrootregion. However, several
code paths release this memory using sysFreeOS without first
unregistering from LSAN. This leaves LSAN with stale root region entries
pointing to memory that has been unmapped and may be reallocated for
other purposes.

This bug was latent until glibc 2.42, which changed pthread stack guard
pages from mprotect(PROT_NONE) to madvise(MADV_GUARD_INSTALL). The
difference matters because LSAN filters root region scanning by
intersecting registered regions with readable mappings from
/proc/self/maps:

- mprotect(PROT_NONE) splits the VMA, creating a separate entry with
---p permissions. LSAN's IsReadable() check excludes it from scanning.

- MADV_GUARD_INSTALL operates at the page table level without modifying
the VMA. The region still appears as rw-p in /proc/self/maps, so LSAN
includes it in the scan and crashes with SIGSEGV when accessing the
guard pages.

Address this by adding sysUnreserve to undo sysReserve. sysUnreserve
unregisters the region from LSAN and frees the mapping.

With the addition of sysUnreserve, we have complete coverage of LSAN
unregister in the mem.go abstract: sysFree unregisters Ready memory.
sysUnreserve unregisters Reserved memory. And there is no way to free
Prepared memory at all (it must transition to Ready or Reserved first).

The implementation of lsanunregisterrootregion [1] finds the region by
exact match of start and end address. It therefore does not support
splitting a region, and we must extend this requirement to sysUnreserve
and sysFree. I am not completely confident that we always pass the full
region to sysFree, but LSAN aborts if it can't find the region, so we
must not be blatantly violating this.

sysReserveAligned does need to unreserve a subset of a region, so it
cannot use sysUnreserve directly. Rather than breaking the mem.go
abstract, move sysReserveAligned into mem.go, adding it to the
abstraction.

We should not have any calls to sysFreeOS outside of the mem.go
abstraction. That is now true with this CL.

Fixes #78510.

[1] https://github.com/llvm/llvm-project/blob/3e3e362648fa062038b90ccc21f46a09d6902288/compiler-rt/lib/lsan/lsan_common.cpp#L1157

Change-Id: I8c46a62154b2f23456ffd5086a7b91156a6a6964
Reviewed-on: https://go-review.googlesource.com/c/go/+/762381
Reviewed-by: Michael Knyszek <mkny...@google.com>
Reviewed-by: Cherry Mui <cher...@google.com>
LUCI-TryBot-Result: Go LUCI <golang...@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit 40ec033c33802cf6e1236ea8030d882338a457d5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/767021
TryBot-Bypass: Carlos Amedee <car...@golang.org>
Reviewed-by: Carlos Amedee <car...@golang.org>
Files:
  • M src/runtime/export_test.go
  • M src/runtime/malloc.go
  • M src/runtime/mem.go
Change size: M
Delta: 3 files changed, 119 insertions(+), 68 deletions(-)
Branch: refs/heads/release-branch.go1.25
Submit Requirements:
Open in Gerrit
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: merged
Gerrit-Project: go
Gerrit-Branch: release-branch.go1.25
Gerrit-Change-Id: I8c46a62154b2f23456ffd5086a7b91156a6a6964
Gerrit-Change-Number: 767021
Gerrit-PatchSet: 2
Gerrit-Owner: Mark Freeman <markf...@google.com>
Gerrit-Reviewer: Carlos Amedee <car...@golang.org>
Gerrit-Reviewer: Mark Freeman <markf...@google.com>
Gerrit-CC: Michael Pratt <mpr...@google.com>
open
diffy
satisfied_requirement

Carlos Amedee (Gerrit)

unread,
Apr 23, 2026, 4:40:34 PM (2 days ago) Apr 23
to Michael Pratt, Mark Freeman, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, golang...@luci-project-accounts.iam.gserviceaccount.com, golang-co...@googlegroups.com

Carlos Amedee submitted the change

Change information

Commit message:
[release-branch.go1.26] runtime: add sysUnreserve to undo sysReserve
Fixes #78511.


[1] https://github.com/llvm/llvm-project/blob/3e3e362648fa062038b90ccc21f46a09d6902288/compiler-rt/lib/lsan/lsan_common.cpp#L1157

Change-Id: I8c46a62154b2f23456ffd5086a7b91156a6a6964
Reviewed-on: https://go-review.googlesource.com/c/go/+/762381
Reviewed-by: Michael Knyszek <mkny...@google.com>
Reviewed-by: Cherry Mui <cher...@google.com>
LUCI-TryBot-Result: Go LUCI <golang...@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit 40ec033c33802cf6e1236ea8030d882338a457d5)

TryBot-Bypass: Carlos Amedee <car...@golang.org>
Reviewed-by: Carlos Amedee <car...@golang.org>
Files:
  • M src/runtime/export_test.go
  • M src/runtime/malloc.go
  • M src/runtime/mem.go
Change size: M
Delta: 3 files changed, 119 insertions(+), 68 deletions(-)
Branch: refs/heads/release-branch.go1.26
Submit Requirements:
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: merged
Gerrit-Project: go
Gerrit-Branch: release-branch.go1.26
Gerrit-Change-Id: I8c46a62154b2f23456ffd5086a7b91156a6a6964
Gerrit-Change-Number: 767022
open
diffy
satisfied_requirement
Reply all
Reply to author
Forward
0 new messages