[compiler-rt] [asan] Detect dereferencing zero-alloc as heap buffer overflow (PR #155943)
Thurston Dang via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 28 16:14:21 PDT 2025
https://github.com/thurstond created https://github.com/llvm/llvm-project/pull/155943
When a zero-byte allocation is requested, ASan actually allocates 1-byte for compatibility. This change poisons that byte, to detect dereferences.
Also updates the test from #155933
>From 4b202488d73b3e0ae66040a1f26dd481980c8653 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 28 Aug 2025 22:55:42 +0000
Subject: [PATCH] [asan] Detect dereferencing zero-alloc as heap buffer
overflow
When a zero-byte allocation is requested, ASan actually allocates 1-byte
for compatibility. This change poisons that byte, to detect dereferences.
Also updates the test from #155933
---
compiler-rt/lib/asan/asan_allocator.cpp | 6 ++++++
compiler-rt/test/asan/TestCases/zero_alloc.cpp | 4 ----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp
index 9ebe4d08ec8c1..752ba9ab32c71 100644
--- a/compiler-rt/lib/asan/asan_allocator.cpp
+++ b/compiler-rt/lib/asan/asan_allocator.cpp
@@ -547,6 +547,7 @@ struct Allocator {
ComputeUserRequestedAlignmentLog(alignment);
if (alignment < min_alignment)
alignment = min_alignment;
+ bool upgraded_from_zero = false;
if (size == 0) {
// We'd be happy to avoid allocating memory for zero-size requests, but
// some programs/tests depend on this behavior and assume that malloc
@@ -555,6 +556,7 @@ struct Allocator {
// consecutive "new" calls must be different even if the allocated size
// is zero.
size = 1;
+ upgraded_from_zero = true;
}
CHECK(IsPowerOfTwo(alignment));
uptr rz_log = ComputeRZLog(size);
@@ -637,6 +639,10 @@ struct Allocator {
*shadow = fl.poison_partial ? (size & (ASAN_SHADOW_GRANULARITY - 1)) : 0;
}
+ if (upgraded_from_zero)
+ PoisonShadow(user_beg, ASAN_SHADOW_GRANULARITY,
+ kAsanHeapLeftRedzoneMagic);
+
AsanStats &thread_stats = GetCurrentThreadStats();
thread_stats.mallocs++;
thread_stats.malloced += size;
diff --git a/compiler-rt/test/asan/TestCases/zero_alloc.cpp b/compiler-rt/test/asan/TestCases/zero_alloc.cpp
index d25164a1e2eb9..e843a5a41f429 100644
--- a/compiler-rt/test/asan/TestCases/zero_alloc.cpp
+++ b/compiler-rt/test/asan/TestCases/zero_alloc.cpp
@@ -1,9 +1,5 @@
// RUN: %clang_asan -Wno-alloc-size -fsanitize-recover=address %s -o %t && %env_asan_opts=halt_on_error=0 %run %t 2>&1 | FileCheck %s
-// ASan doesn't catch this because internally it translates 0-byte allocations
-// into 1-byte
-// XFAIL: *
-
#include <malloc.h>
#include <stdio.h>
More information about the llvm-commits
mailing list