Skip to content

Commit 56e5476

Browse files
committed
runtime: in asan mode unregister root regions on free
CL 651755 introduced registration of root regions when allocating memory. We also need to unregister that memory to avoid the leak sanitizer accessing unmapped memory. Issue #67833 Change-Id: I5d403d66e65a8a003492f4d79dad22d416fd8574 Reviewed-on: https://go-review.googlesource.com/c/go/+/659135 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 1aee4f3 commit 56e5476

File tree

9 files changed

+56
-0
lines changed

9 files changed

+56
-0
lines changed

src/runtime/asan.go

+4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ func asanregisterglobals(addr unsafe.Pointer, n uintptr)
6464
//go:noescape
6565
func lsanregisterrootregion(addr unsafe.Pointer, n uintptr)
6666

67+
//go:noescape
68+
func lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
69+
6770
func lsandoleakcheck()
6871

6972
// These are called from asan_GOARCH.s
@@ -74,4 +77,5 @@ func lsandoleakcheck()
7477
//go:cgo_import_static __asan_poison_go
7578
//go:cgo_import_static __asan_register_globals_go
7679
//go:cgo_import_static __lsan_register_root_region_go
80+
//go:cgo_import_static __lsan_unregister_root_region_go
7781
//go:cgo_import_static __lsan_do_leak_check_go

src/runtime/asan/asan.go

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ void __lsan_register_root_region_go(void *addr, uintptr_t sz) {
3939
__lsan_register_root_region(addr, sz);
4040
}
4141
42+
void __lsan_unregister_root_region_go(void *addr, uintptr_t sz) {
43+
__lsan_unregister_root_region(addr, sz);
44+
}
45+
4246
void __lsan_do_leak_check_go(void) {
4347
__lsan_do_leak_check();
4448
}

src/runtime/asan0.go

+1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ func asanunpoison(addr unsafe.Pointer, sz uintptr) { throw("asan") }
2222
func asanpoison(addr unsafe.Pointer, sz uintptr) { throw("asan") }
2323
func asanregisterglobals(addr unsafe.Pointer, sz uintptr) { throw("asan") }
2424
func lsanregisterrootregion(unsafe.Pointer, uintptr) { throw("asan") }
25+
func lsanunregisterrootregion(unsafe.Pointer, uintptr) { throw("asan") }
2526
func lsandoleakcheck() { throw("asan") }

src/runtime/asan_amd64.s

+8
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16
7777
MOVQ $__lsan_register_root_region_go(SB), AX
7878
JMP asancall<>(SB)
7979

80+
// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
81+
TEXT runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16
82+
MOVQ addr+0(FP), RARG0
83+
MOVQ n+8(FP), RARG1
84+
// void __lsan_unregister_root_region_go(void *addr, uintptr_t sz)
85+
MOVQ $__lsan_unregister_root_region_go(SB), AX
86+
JMP asancall<>(SB)
87+
8088
// func runtime·lsandoleakcheck()
8189
TEXT runtime·lsandoleakcheck(SB), NOSPLIT, $0-0
8290
// void __lsan_do_leak_check_go(void);

src/runtime/asan_arm64.s

+8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16
6666
MOVD $__lsan_register_root_region_go(SB), FARG
6767
JMP asancall<>(SB)
6868

69+
// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
70+
TEXT runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16
71+
MOVD addr+0(FP), RARG0
72+
MOVD n+8(FP), RARG1
73+
// void __lsan_unregister_root_region_go(void *addr, uintptr_t n);
74+
MOVD $__lsan_unregister_root_region_go(SB), FARG
75+
JMP asancall<>(SB)
76+
6977
// func runtime·lsandoleakcheck()
7078
TEXT runtime·lsandoleakcheck(SB), NOSPLIT, $0-0
7179
// void __lsan_do_leak_check_go(void);

src/runtime/asan_loong64.s

+8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16
6666
MOVV $__lsan_register_root_region_go(SB), FARG
6767
JMP asancall<>(SB)
6868

69+
// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
70+
TEXT runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16
71+
MOVV addr+0(FP), RARG0
72+
MOVV n+8(FP), RARG1
73+
// void __lsan_unregister_root_region_go(void *addr, uintptr_t n);
74+
MOVV $__lsan_unregister_root_region_go(SB), FARG
75+
JMP asancall<>(SB)
76+
6977
// func runtime·lsandoleakcheck()
7078
TEXT runtime·lsandoleakcheck(SB), NOSPLIT, $0-0
7179
// void __lsan_do_leak_check_go(void);

src/runtime/asan_ppc64le.s

+8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB),NOSPLIT|NOFRAME,$0-16
6666
MOVD $__lsan_register_root_region_go(SB), FARG
6767
BR asancall<>(SB)
6868

69+
// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
70+
TEXT runtime·lsanunregisterrootregion(SB),NOSPLIT|NOFRAME,$0-16
71+
MOVD addr+0(FP), RARG0
72+
MOVD n+8(FP), RARG1
73+
// void __lsan_unregister_root_region_go(void *addr, uintptr_t n);
74+
MOVD $__lsan_unregister_root_region_go(SB), FARG
75+
BR asancall<>(SB)
76+
6977
// func runtime·lsandoleakcheck()
7078
TEXT runtime·lsandoleakcheck(SB), NOSPLIT|NOFRAME, $0-0
7179
// void __lsan_do_leak_check_go(void);

src/runtime/asan_riscv64.s

+8
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16
6060
MOV $__lsan_register_root_region_go(SB), X14
6161
JMP asancall<>(SB)
6262

63+
// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
64+
TEXT runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16
65+
MOV addr+0(FP), X10
66+
MOV n+8(FP), X11
67+
// void __lsan_unregister_root_region_go(void *addr, uintptr_t n);
68+
MOV $__lsan_unregister_root_region_go(SB), X14
69+
JMP asancall<>(SB)
70+
6371
// func runtime·lsandoleakcheck()
6472
TEXT runtime·lsandoleakcheck(SB), NOSPLIT, $0-0
6573
// void __lsan_do_leak_check_go(void);

src/runtime/mem.go

+7
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ func sysHugePageCollapse(v unsafe.Pointer, n uintptr) {
119119
//
120120
//go:nosplit
121121
func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
122+
// When using ASAN leak detection, the memory being freed is
123+
// known by the sanitizer. We need to unregister it so it's
124+
// not accessed by it.
125+
if asanenabled {
126+
lsanunregisterrootregion(v, n)
127+
}
128+
122129
sysStat.add(-int64(n))
123130
gcController.mappedReady.Add(-int64(n))
124131
sysFreeOS(v, n)

0 commit comments

Comments
 (0)