OLD | NEW |
1 //===-- asan_allocator.cc ------------*- C++ -*-===// | 1 //===-- asan_allocator.cc ------------*- C++ -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file is a part of AddressSanitizer, an address sanity checker. | 10 // This file is a part of AddressSanitizer, an address sanity checker. |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 res = Log2(rounded); | 112 res = Log2(rounded); |
113 } else { | 113 } else { |
114 res = ((size + kMallocSizeClassStep - 1) / kMallocSizeClassStep) | 114 res = ((size + kMallocSizeClassStep - 1) / kMallocSizeClassStep) |
115 + kMallocSizeClassStepLog; | 115 + kMallocSizeClassStepLog; |
116 } | 116 } |
117 CHECK(res < kNumberOfSizeClasses); | 117 CHECK(res < kNumberOfSizeClasses); |
118 CHECK(size <= SizeClassToSize(res)); | 118 CHECK(size <= SizeClassToSize(res)); |
119 return res; | 119 return res; |
120 } | 120 } |
121 | 121 |
122 static void PoisonShadow(uintptr_t mem, size_t size, uint8_t poison) { | |
123 CHECK(IsAligned(mem, SHADOW_GRANULARITY)); | |
124 CHECK(IsAligned(mem + size, SHADOW_GRANULARITY)); | |
125 uintptr_t shadow_beg = MemToShadow(mem); | |
126 uintptr_t shadow_end = MemToShadow(mem + size); | |
127 real_memset((void*)shadow_beg, poison, shadow_end - shadow_beg); | |
128 } | |
129 | |
130 // Given REDZONE bytes, we need to mark first size bytes | 122 // Given REDZONE bytes, we need to mark first size bytes |
131 // as addressable and the rest REDZONE-size bytes as unaddressable. | 123 // as addressable and the rest REDZONE-size bytes as unaddressable. |
132 static void PoisonMemoryPartialRightRedzone(uintptr_t mem, size_t size) { | 124 static void PoisonHeapPartialRightRedzone(uintptr_t mem, size_t size) { |
133 CHECK(size <= REDZONE); | 125 CHECK(size <= REDZONE); |
134 CHECK(IsAligned(mem, REDZONE)); | 126 CHECK(IsAligned(mem, REDZONE)); |
135 CHECK(IsPowerOfTwo(SHADOW_GRANULARITY)); | 127 CHECK(IsPowerOfTwo(SHADOW_GRANULARITY)); |
136 CHECK(IsPowerOfTwo(REDZONE)); | 128 CHECK(IsPowerOfTwo(REDZONE)); |
137 CHECK(REDZONE >= SHADOW_GRANULARITY); | 129 CHECK(REDZONE >= SHADOW_GRANULARITY); |
138 uint8_t *shadow = (uint8_t*)MemToShadow(mem); | 130 PoisonShadowPartialRightRedzone(mem, size, REDZONE, |
139 PoisonShadowPartialRightRedzone(shadow, size, | |
140 REDZONE, SHADOW_GRANULARITY, | |
141 kAsanHeapRightRedzoneMagic); | 131 kAsanHeapRightRedzoneMagic); |
142 } | 132 } |
143 | 133 |
144 static uint8_t *MmapNewPagesAndPoisonShadow(size_t size) { | 134 static uint8_t *MmapNewPagesAndPoisonShadow(size_t size) { |
145 CHECK(IsAligned(size, kPageSize)); | 135 CHECK(IsAligned(size, kPageSize)); |
146 uint8_t *res = (uint8_t*)asan_mmap(0, size, | 136 uint8_t *res = (uint8_t*)asan_mmap(0, size, |
147 PROT_READ | PROT_WRITE, | 137 PROT_READ | PROT_WRITE, |
148 MAP_PRIVATE | MAP_ANON, -1, 0); | 138 MAP_PRIVATE | MAP_ANON, -1, 0); |
149 if (res == (uint8_t*)-1) { | 139 if (res == (uint8_t*)-1) { |
150 OutOfMemoryMessage(__FUNCTION__, size); | 140 OutOfMemoryMessage(__FUNCTION__, size); |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 CHECK(m == PtrToChunk(addr)); | 670 CHECK(m == PtrToChunk(addr)); |
681 m->used_size = size; | 671 m->used_size = size; |
682 m->offset = addr - (uintptr_t)m; | 672 m->offset = addr - (uintptr_t)m; |
683 CHECK(m->beg() == addr); | 673 CHECK(m->beg() == addr); |
684 m->alloc_tid = t ? t->tid() : 0; | 674 m->alloc_tid = t ? t->tid() : 0; |
685 m->free_tid = AsanThread::kInvalidTid; | 675 m->free_tid = AsanThread::kInvalidTid; |
686 AsanStackTrace::CompressStack(stack, m->compressed_alloc_stack(), | 676 AsanStackTrace::CompressStack(stack, m->compressed_alloc_stack(), |
687 m->compressed_alloc_stack_size()); | 677 m->compressed_alloc_stack_size()); |
688 PoisonShadow(addr, rounded_size, 0); | 678 PoisonShadow(addr, rounded_size, 0); |
689 if (size < rounded_size) { | 679 if (size < rounded_size) { |
690 PoisonMemoryPartialRightRedzone(addr + rounded_size - REDZONE, | 680 PoisonHeapPartialRightRedzone(addr + rounded_size - REDZONE, |
691 size & (REDZONE - 1)); | 681 size & (REDZONE - 1)); |
692 } | 682 } |
693 if (size <= FLAG_max_malloc_fill_size) { | 683 if (size <= FLAG_max_malloc_fill_size) { |
694 real_memset((void*)addr, 0, rounded_size); | 684 real_memset((void*)addr, 0, rounded_size); |
695 } | 685 } |
696 return (uint8_t*)addr; | 686 return (uint8_t*)addr; |
697 } | 687 } |
698 | 688 |
699 static void Deallocate(uint8_t *ptr, AsanStackTrace *stack) { | 689 static void Deallocate(uint8_t *ptr, AsanStackTrace *stack) { |
700 if (!ptr) return; | 690 if (!ptr) return; |
701 CHECK(stack); | 691 CHECK(stack); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 if (p == NULL) return 0; | 1040 if (p == NULL) return 0; |
1051 size_t allocated_size = malloc_info.AllocationSize((uintptr_t)p); | 1041 size_t allocated_size = malloc_info.AllocationSize((uintptr_t)p); |
1052 // Die if p is not malloced or if it is already freed. | 1042 // Die if p is not malloced or if it is already freed. |
1053 if (allocated_size == 0) { | 1043 if (allocated_size == 0) { |
1054 Printf("__asan_get_allocated_size failed, ptr=%p is not owned\n", p); | 1044 Printf("__asan_get_allocated_size failed, ptr=%p is not owned\n", p); |
1055 PRINT_CURRENT_STACK(); | 1045 PRINT_CURRENT_STACK(); |
1056 ShowStatsAndAbort(); | 1046 ShowStatsAndAbort(); |
1057 } | 1047 } |
1058 return allocated_size; | 1048 return allocated_size; |
1059 } | 1049 } |
OLD | NEW |