1 // RUN: %clang_asan -O2 %s -o %t 2 // RUN: %run %t 2>&1 | FileCheck --check-prefix=CHECK-NOSCRIBBLE %s 3 // RUN: %env MallocScribble=1 MallocPreScribble=1 %run %t 2>&1 | FileCheck --check-prefix=CHECK-SCRIBBLE %s 4 // RUN: %env_asan_opts=max_free_fill_size=4096 %run %t 2>&1 | FileCheck --check-prefix=CHECK-SCRIBBLE %s 5 6 #include <stdint.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 struct Isa { 12 const char *class_name; 13 }; 14 15 struct MyClass { 16 // User memory and `ChunkHeader` overlap. In particular the `free_context_id` 17 // is stored at the beginning of user memory when it is freed. That part of 18 // user memory is not scribbled and is changed when the memory is freed. This 19 // test relies on `isa` being scribbled or unmodified after memory is freed. 20 // In order for this to work the start of `isa` must come after whatever is in 21 // `ChunkHeader` (currently the 64-bit `free_context_id`). The padding here is 22 // to ensure this is the case. 23 uint64_t padding; 24 Isa *isa; 25 long data; 26 27 void print_my_class_name(); 28 }; 29 30 __attribute__((no_sanitize("address"))) 31 void MyClass::print_my_class_name() { 32 fprintf(stderr, "this = %p\n", this); 33 fprintf(stderr, "padding = 0x%lx\n", this->padding); 34 fprintf(stderr, "isa = %p\n", this->isa); 35 36 if ((uint32_t)(uintptr_t)this->isa != 0x55555555) { 37 fprintf(stderr, "class name: %s\n", this->isa->class_name); 38 } 39 } 40 41 int main() { 42 Isa *my_class_isa = (Isa *)malloc(sizeof(Isa)); 43 memset(my_class_isa, 0x77, sizeof(Isa)); 44 my_class_isa->class_name = "MyClass"; 45 46 MyClass *my_object = (MyClass *)malloc(sizeof(MyClass)); 47 memset(my_object, 0x88, sizeof(MyClass)); 48 my_object->isa = my_class_isa; 49 my_object->data = 42; 50 51 my_object->print_my_class_name(); 52 // CHECK-SCRIBBLE: class name: MyClass 53 // CHECK-NOSCRIBBLE: class name: MyClass 54 55 free(my_object); 56 57 my_object->print_my_class_name(); 58 // CHECK-NOSCRIBBLE: class name: MyClass 59 // CHECK-SCRIBBLE: isa = {{(0x)?}}{{5555555555555555|55555555}} 60 61 fprintf(stderr, "okthxbai!\n"); 62 // CHECK-SCRIBBLE: okthxbai! 63 // CHECK-NOSCRIBBLE: okthxbai! 64 free(my_class_isa); 65 } 66