]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: in asan mode unregister root regions on free
authorFlorian Zenker <floriank@google.com>
Wed, 19 Mar 2025 10:55:55 +0000 (10:55 +0000)
committerFlorian Zenker <floriank@google.com>
Wed, 19 Mar 2025 14:06:55 +0000 (07:06 -0700)
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/runtime/asan.go
src/runtime/asan/asan.go
src/runtime/asan0.go
src/runtime/asan_amd64.s
src/runtime/asan_arm64.s
src/runtime/asan_loong64.s
src/runtime/asan_ppc64le.s
src/runtime/asan_riscv64.s
src/runtime/mem.go

index adef8fa7bf6f15aefb71d5d7940871475ae66468..32d5f452256f2d1fe1212c5f974eef00f81bf822 100644 (file)
@@ -64,6 +64,9 @@ func asanregisterglobals(addr unsafe.Pointer, n uintptr)
 //go:noescape
 func lsanregisterrootregion(addr unsafe.Pointer, n uintptr)
 
+//go:noescape
+func lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
+
 func lsandoleakcheck()
 
 // These are called from asan_GOARCH.s
@@ -74,4 +77,5 @@ func lsandoleakcheck()
 //go:cgo_import_static __asan_poison_go
 //go:cgo_import_static __asan_register_globals_go
 //go:cgo_import_static __lsan_register_root_region_go
+//go:cgo_import_static __lsan_unregister_root_region_go
 //go:cgo_import_static __lsan_do_leak_check_go
index efdd911f2b10c47c4d61eeed2ebfc20156153cb2..fefc82b2787d337f8c4c66854a36247d51a3266b 100644 (file)
@@ -39,6 +39,10 @@ void __lsan_register_root_region_go(void *addr, uintptr_t sz) {
        __lsan_register_root_region(addr, sz);
 }
 
+void __lsan_unregister_root_region_go(void *addr, uintptr_t sz) {
+       __lsan_unregister_root_region(addr, sz);
+}
+
 void __lsan_do_leak_check_go(void) {
        __lsan_do_leak_check();
 }
index eb70367a2997a749dd57e2dc903b19d1f54241d0..83316539821bdafad0d714b87800b94046fb0490 100644 (file)
@@ -22,4 +22,5 @@ func asanunpoison(addr unsafe.Pointer, sz uintptr)        { throw("asan") }
 func asanpoison(addr unsafe.Pointer, sz uintptr)          { throw("asan") }
 func asanregisterglobals(addr unsafe.Pointer, sz uintptr) { throw("asan") }
 func lsanregisterrootregion(unsafe.Pointer, uintptr)      { throw("asan") }
+func lsanunregisterrootregion(unsafe.Pointer, uintptr)    { throw("asan") }
 func lsandoleakcheck()                                    { throw("asan") }
index 3f9df4fec8b657536f022a977dce33920893b436..30dd477c0700f82541a22ba0c54fde2387b16d1c 100644 (file)
@@ -77,6 +77,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16
        MOVQ    $__lsan_register_root_region_go(SB), AX
        JMP     asancall<>(SB)
 
+// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
+TEXT   runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16
+       MOVQ    addr+0(FP), RARG0
+       MOVQ    n+8(FP), RARG1
+       // void __lsan_unregister_root_region_go(void *addr, uintptr_t sz)
+       MOVQ    $__lsan_unregister_root_region_go(SB), AX
+       JMP     asancall<>(SB)
+
 // func runtime·lsandoleakcheck()
 TEXT   runtime·lsandoleakcheck(SB), NOSPLIT, $0-0
        // void __lsan_do_leak_check_go(void);
index 5447d210e56adcc1a7cfa0f33f829c7ac81994c8..1f089d78d3db6206cd91696c3a6d9125180477c1 100644 (file)
@@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16
        MOVD    $__lsan_register_root_region_go(SB), FARG
        JMP     asancall<>(SB)
 
+// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
+TEXT   runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16
+       MOVD    addr+0(FP), RARG0
+       MOVD    n+8(FP), RARG1
+       // void __lsan_unregister_root_region_go(void *addr, uintptr_t n);
+       MOVD    $__lsan_unregister_root_region_go(SB), FARG
+       JMP     asancall<>(SB)
+
 // func runtime·lsandoleakcheck()
 TEXT   runtime·lsandoleakcheck(SB), NOSPLIT, $0-0
        // void __lsan_do_leak_check_go(void);
index 3abcf889b8eae7123f44be922de42b0e99e20f49..224d16ce2ee33a7ff8f722ebca61ac9b0231a5ea 100644 (file)
@@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16
        MOVV    $__lsan_register_root_region_go(SB), FARG
        JMP     asancall<>(SB)
 
+// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
+TEXT   runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16
+       MOVV    addr+0(FP), RARG0
+       MOVV    n+8(FP), RARG1
+       // void __lsan_unregister_root_region_go(void *addr, uintptr_t n);
+       MOVV    $__lsan_unregister_root_region_go(SB), FARG
+       JMP     asancall<>(SB)
+
 // func runtime·lsandoleakcheck()
 TEXT   runtime·lsandoleakcheck(SB), NOSPLIT, $0-0
        // void __lsan_do_leak_check_go(void);
index 2fc5772a28cd5e15fa834748f9f67448cffc2b94..0c56a81991eb6b37a737e5dbcfbb3fc96ae345e6 100644 (file)
@@ -66,6 +66,14 @@ TEXT runtime·lsanregisterrootregion(SB),NOSPLIT|NOFRAME,$0-16
        MOVD    $__lsan_register_root_region_go(SB), FARG
        BR      asancall<>(SB)
 
+// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
+TEXT   runtime·lsanunregisterrootregion(SB),NOSPLIT|NOFRAME,$0-16
+       MOVD    addr+0(FP), RARG0
+       MOVD    n+8(FP), RARG1
+       // void __lsan_unregister_root_region_go(void *addr, uintptr_t n);
+       MOVD    $__lsan_unregister_root_region_go(SB), FARG
+       BR      asancall<>(SB)
+
 // func runtime·lsandoleakcheck()
 TEXT   runtime·lsandoleakcheck(SB), NOSPLIT|NOFRAME, $0-0
        // void __lsan_do_leak_check_go(void);
index f5ddb21a25cbd53c5c88ba640fe203617ba81702..6c77f66348130ddba14f51b942babc9e12eb69d7 100644 (file)
@@ -60,6 +60,14 @@ TEXT runtime·lsanregisterrootregion(SB), NOSPLIT, $0-16
        MOV     $__lsan_register_root_region_go(SB), X14
        JMP     asancall<>(SB)
 
+// func runtime·lsanunregisterrootregion(addr unsafe.Pointer, n uintptr)
+TEXT   runtime·lsanunregisterrootregion(SB), NOSPLIT, $0-16
+       MOV     addr+0(FP), X10
+       MOV     n+8(FP), X11
+       // void __lsan_unregister_root_region_go(void *addr, uintptr_t n);
+       MOV     $__lsan_unregister_root_region_go(SB), X14
+       JMP     asancall<>(SB)
+
 // func runtime·lsandoleakcheck()
 TEXT   runtime·lsandoleakcheck(SB), NOSPLIT, $0-0
        // void __lsan_do_leak_check_go(void);
index d45a0ccfb864a1e401b708e3600f2e657b7217b6..cd06ea323d8a7c36f3706c65ce6ab5b8809b1308 100644 (file)
@@ -119,6 +119,13 @@ func sysHugePageCollapse(v unsafe.Pointer, n uintptr) {
 //
 //go:nosplit
 func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
+       // When using ASAN leak detection, the memory being freed is
+       // known by the sanitizer. We need to unregister it so it's
+       // not accessed by it.
+       if asanenabled {
+               lsanunregisterrootregion(v, n)
+       }
+
        sysStat.add(-int64(n))
        gcController.mappedReady.Add(-int64(n))
        sysFreeOS(v, n)