[PATCH] D19653: [tsan] Return 0 from malloc_size for non-malloc'd pointers

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 28 03:30:25 PDT 2016


kubabrecka created this revision.
kubabrecka added reviewers: dvyukov, kcc, glider, samsonov.
kubabrecka added subscribers: llvm-commits, zaks.anna, dcoughlin.
kubabrecka added a project: Sanitizers.
Herald added a subscriber: kubabrecka.

In http://reviews.llvm.org/D19100, I introduced a bug:  On OS X, existing programs rely on malloc_size() to detect whether a pointer comes from heap memory (malloc_size returns non-zero) or not.  We have to distinguish between a zero-sized allocation (where we need to return 1 from malloc_size, due to other binary compatibility reasons, see http://reviews.llvm.org/D19100), and pointers that are not returned from malloc at all.

http://reviews.llvm.org/D19653

Files:
  lib/tsan/rtl/tsan_malloc_mac.cc
  lib/tsan/rtl/tsan_mman.cc
  test/tsan/Darwin/malloc_size.mm

Index: test/tsan/Darwin/malloc_size.mm
===================================================================
--- test/tsan/Darwin/malloc_size.mm
+++ test/tsan/Darwin/malloc_size.mm
@@ -6,18 +6,50 @@
 #import <Foundation/Foundation.h>
 #include <malloc/malloc.h>
 
-int main() {
-  void *p = malloc(0);
-
-  size_t s = malloc_size(p);
-  printf("size = 0x%zx\n", s);
+int some_global;
 
+void describe_zone(void *p) {
   malloc_zone_t *z = malloc_zone_from_ptr(p);
-  if (z)
-    printf("z = %p\n", z);
-  else
-    printf("no zone\n");
+  if (z) {
+    fprintf(stderr, "zone = %p\n", z);
+  }	else {
+  	fprintf(stderr, "zone = no zone\n");
+  }
 }
 
-// CHECK: z = 0x{{[0-9a-f]+}}
-// CHECK-NOT: no zone
+int main() {
+  void *p;
+  size_t s;
+
+  p = malloc(0x40);
+  s = malloc_size(p);
+  fprintf(stderr, "size = 0x%zx\n", s);
+  // CHECK: size = 0x40
+  describe_zone(p);
+  // CHECK: zone = 0x{{[0-9a-f]+}}
+
+  p = malloc(0);
+  s = malloc_size(p);
+  fprintf(stderr, "size = 0x%zx\n", s);
+  // CHECK: size = 0x1
+  describe_zone(p);
+  // CHECK: zone = 0x{{[0-9a-f]+}}
+
+  p = &some_global;
+  s = malloc_size(p);
+  fprintf(stderr, "size = 0x%zx\n", s);
+  // CHECK: size = 0x0
+  describe_zone(p);
+  // CHECK: zone = no zone
+
+  p = mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+  if (!p) {
+  	fprintf(stderr, "mmap failed\n");
+  	exit(1);
+  }
+  s = malloc_size(p);
+  fprintf(stderr, "size = 0x%zx\n", s);
+  // CHECK: size = 0x0
+  describe_zone(p);
+  // CHECK: zone = no zone
+}
Index: lib/tsan/rtl/tsan_mman.cc
===================================================================
--- lib/tsan/rtl/tsan_mman.cc
+++ lib/tsan/rtl/tsan_mman.cc
@@ -164,7 +164,11 @@
   if (p == 0)
     return 0;
   MBlock *b = ctx->metamap.GetBlock((uptr)p);
-  return b ? b->siz : 0;
+  if (!b)
+    return 0;  // Not a valid pointer.
+  if (b->siz == 0)
+    return 1;  // Zero-sized allocations are actually 1 byte.
+  return b->siz;
 }
 
 void invoke_malloc_hook(void *ptr, uptr size) {
Index: lib/tsan/rtl/tsan_malloc_mac.cc
===================================================================
--- lib/tsan/rtl/tsan_malloc_mac.cc
+++ lib/tsan/rtl/tsan_malloc_mac.cc
@@ -53,8 +53,7 @@
   SCOPED_INTERCEPTOR_RAW(free, ptr); \
   user_free(thr, pc, ptr)
 #define COMMON_MALLOC_SIZE(ptr) \
-  uptr size = user_alloc_usable_size(ptr); \
-  if (size == 0) size = 1;
+  uptr size = user_alloc_usable_size(ptr);
 #define COMMON_MALLOC_FILL_STATS(zone, stats)
 #define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \
   (void)zone_name; \


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19653.55395.patch
Type: text/x-patch
Size: 2573 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160428/be0b21c4/attachment.bin>


More information about the llvm-commits mailing list