forked from OSchip/llvm-project
Asan: utility function to determine first wrongly poisoned byte in
container. Differential Revision: http://reviews.llvm.org/D14341 llvm-svn: 252071
This commit is contained in:
parent
a895aa635c
commit
1e41784f20
|
@ -105,6 +105,12 @@ extern "C" {
|
|||
int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
|
||||
const void *end);
|
||||
|
||||
// Similar to __sanitizer_verify_contiguous_container but returns the address
|
||||
// of the first improperly poisoned byte otherwise. Returns null if the area
|
||||
// is poisoned properly.
|
||||
const void *__sanitizer_contiguous_container_find_bad_address(
|
||||
const void *beg, const void *mid, const void *end);
|
||||
|
||||
// Print the stack trace leading to this call. Useful for debugging user code.
|
||||
void __sanitizer_print_stack_trace();
|
||||
|
||||
|
|
|
@ -375,10 +375,10 @@ void __sanitizer_annotate_contiguous_container(const void *beg_p,
|
|||
}
|
||||
}
|
||||
|
||||
int __sanitizer_verify_contiguous_container(const void *beg_p,
|
||||
const void *mid_p,
|
||||
const void *end_p) {
|
||||
if (!flags()->detect_container_overflow) return 1;
|
||||
const void *__sanitizer_contiguous_container_find_bad_address(
|
||||
const void *beg_p, const void *mid_p, const void *end_p) {
|
||||
if (!flags()->detect_container_overflow)
|
||||
return nullptr;
|
||||
uptr beg = reinterpret_cast<uptr>(beg_p);
|
||||
uptr end = reinterpret_cast<uptr>(end_p);
|
||||
uptr mid = reinterpret_cast<uptr>(mid_p);
|
||||
|
@ -395,17 +395,24 @@ int __sanitizer_verify_contiguous_container(const void *beg_p,
|
|||
uptr r3_end = end;
|
||||
for (uptr i = r1_beg; i < r1_end; i++)
|
||||
if (AddressIsPoisoned(i))
|
||||
return 0;
|
||||
return reinterpret_cast<const void *>(i);
|
||||
for (uptr i = r2_beg; i < mid; i++)
|
||||
if (AddressIsPoisoned(i))
|
||||
return 0;
|
||||
return reinterpret_cast<const void *>(i);
|
||||
for (uptr i = mid; i < r2_end; i++)
|
||||
if (!AddressIsPoisoned(i))
|
||||
return 0;
|
||||
return reinterpret_cast<const void *>(i);
|
||||
for (uptr i = r3_beg; i < r3_end; i++)
|
||||
if (!AddressIsPoisoned(i))
|
||||
return 0;
|
||||
return 1;
|
||||
return reinterpret_cast<const void *>(i);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int __sanitizer_verify_contiguous_container(const void *beg_p,
|
||||
const void *mid_p,
|
||||
const void *end_p) {
|
||||
return __sanitizer_contiguous_container_find_bad_address(beg_p, mid_p,
|
||||
end_p) == nullptr;
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
|
|
|
@ -53,6 +53,9 @@ extern "C" {
|
|||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
|
||||
const void *end);
|
||||
} // extern "C"
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
const void *__sanitizer_contiguous_container_find_bad_address(
|
||||
const void *beg, const void *mid, const void *end);
|
||||
} // extern "C"
|
||||
|
||||
#endif // SANITIZER_INTERFACE_INTERNAL_H
|
||||
|
|
|
@ -26,10 +26,18 @@ void TestContainer(size_t capacity) {
|
|||
for (size_t idx = size; idx < capacity; idx++)
|
||||
assert(__asan_address_is_poisoned(beg + idx));
|
||||
assert(__sanitizer_verify_contiguous_container(beg, mid, end));
|
||||
if (mid != beg)
|
||||
assert(NULL ==
|
||||
__sanitizer_contiguous_container_find_bad_address(beg, mid, end));
|
||||
if (mid != beg) {
|
||||
assert(!__sanitizer_verify_contiguous_container(beg, mid - 1, end));
|
||||
if (mid != end)
|
||||
assert(mid - 1 == __sanitizer_contiguous_container_find_bad_address(
|
||||
beg, mid - 1, end));
|
||||
}
|
||||
if (mid != end) {
|
||||
assert(!__sanitizer_verify_contiguous_container(beg, mid + 1, end));
|
||||
assert(mid == __sanitizer_contiguous_container_find_bad_address(
|
||||
beg, mid + 1, end));
|
||||
}
|
||||
}
|
||||
|
||||
// Don't forget to unpoison the whole thing before destroing/reallocating.
|
||||
|
|
Loading…
Reference in New Issue