[compiler-rt] [asan] Add test for deferencing zero-sized malloc/calloc (PR #155933)

Thurston Dang via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 28 15:24:52 PDT 2025


https://github.com/thurstond updated https://github.com/llvm/llvm-project/pull/155933

>From 82444c222a4eea225d986d757a008ad9718fb21e Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 28 Aug 2025 22:14:33 +0000
Subject: [PATCH 1/3] [asan] Add test for deferencing zero-sized malloc/calloc

ASan fails to catch this, because 0-byte allocations are converted into
1-byte allocations.

Bug originally reported by dvyukov
---
 .../test/asan/TestCases/zero_alloc.cpp        | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 compiler-rt/test/asan/TestCases/zero_alloc.cpp

diff --git a/compiler-rt/test/asan/TestCases/zero_alloc.cpp b/compiler-rt/test/asan/TestCases/zero_alloc.cpp
new file mode 100644
index 0000000000000..3decd5acb7bae
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/zero_alloc.cpp
@@ -0,0 +1,37 @@
+// 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
+
+// XFAIL: *
+
+#include <malloc.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  {
+     char* p1 = (char*)calloc(1, 0);
+     printf ("p1 is %p\n", p1);
+     printf ("Content of p1 is: %d\n", *p1);
+     // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
+     // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
+     free(p1);
+  }
+
+  {
+     char* p2 = (char*)calloc(0, 1);
+     printf ("p2 is %p\n", p2);
+     printf ("Content of p2 is: %d\n", *p2);
+     // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
+     // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
+     free(p2);
+  }
+
+  {
+     char* p3 = (char*)malloc(0);
+     printf ("p3 is %p\n", p3);
+     printf ("Content of p2 is: %d\n", *p3);
+     // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
+     // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
+     free(p3);
+  }
+
+  return 0;
+}

>From b4f3a7ec73dfa0cd1336379fe37de4f4b74f47da Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 28 Aug 2025 22:22:47 +0000
Subject: [PATCH 2/3] clang-format

---
 .../test/asan/TestCases/zero_alloc.cpp        | 36 +++++++++----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/compiler-rt/test/asan/TestCases/zero_alloc.cpp b/compiler-rt/test/asan/TestCases/zero_alloc.cpp
index 3decd5acb7bae..832b35395bc93 100644
--- a/compiler-rt/test/asan/TestCases/zero_alloc.cpp
+++ b/compiler-rt/test/asan/TestCases/zero_alloc.cpp
@@ -7,30 +7,30 @@
 
 int main(int argc, char **argv) {
   {
-     char* p1 = (char*)calloc(1, 0);
-     printf ("p1 is %p\n", p1);
-     printf ("Content of p1 is: %d\n", *p1);
-     // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
-     // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
-     free(p1);
+    char *p1 = (char *)calloc(1, 0);
+    printf("p1 is %p\n", p1);
+    printf("Content of p1 is: %d\n", *p1);
+    // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
+    // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
+    free(p1);
   }
 
   {
-     char* p2 = (char*)calloc(0, 1);
-     printf ("p2 is %p\n", p2);
-     printf ("Content of p2 is: %d\n", *p2);
-     // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
-     // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
-     free(p2);
+    char *p2 = (char *)calloc(0, 1);
+    printf("p2 is %p\n", p2);
+    printf("Content of p2 is: %d\n", *p2);
+    // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
+    // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
+    free(p2);
   }
 
   {
-     char* p3 = (char*)malloc(0);
-     printf ("p3 is %p\n", p3);
-     printf ("Content of p2 is: %d\n", *p3);
-     // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
-     // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
-     free(p3);
+    char *p3 = (char *)malloc(0);
+    printf("p3 is %p\n", p3);
+    printf("Content of p2 is: %d\n", *p3);
+    // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
+    // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]]
+    free(p3);
   }
 
   return 0;

>From 58ae9a9190289704b84ec916342c16df261cda67 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 28 Aug 2025 22:24:32 +0000
Subject: [PATCH 3/3] Add note on bad compilers

---
 compiler-rt/test/asan/TestCases/zero_alloc.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/compiler-rt/test/asan/TestCases/zero_alloc.cpp b/compiler-rt/test/asan/TestCases/zero_alloc.cpp
index 832b35395bc93..d25164a1e2eb9 100644
--- a/compiler-rt/test/asan/TestCases/zero_alloc.cpp
+++ b/compiler-rt/test/asan/TestCases/zero_alloc.cpp
@@ -1,5 +1,7 @@
 // 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>



More information about the llvm-commits mailing list