forked from OSchip/llvm-project
[ASan] Don't die with internal ASan error on large buffer overflows
Summary: Out-of-bound access may touch not-yet allocated or already freed and recycled from quarantine chunks. We should treat this situation as a "free-range memory access" and avoid printing any data about that irrelevant chunk (which may be inconsistent). This should fix https://code.google.com/p/address-sanitizer/issues/detail?id=183 Reviewers: kcc Reviewed By: kcc CC: timurrrr, llvm-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1893 llvm-svn: 192581
This commit is contained in:
parent
421e884b31
commit
df6e6569c0
|
@ -35,10 +35,11 @@ void InitializeAllocator();
|
|||
class AsanChunkView {
|
||||
public:
|
||||
explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {}
|
||||
bool IsValid() { return chunk_ != 0; }
|
||||
uptr Beg(); // first byte of user memory.
|
||||
uptr End(); // last byte of user memory.
|
||||
uptr UsedSize(); // size requested by the user.
|
||||
bool IsValid(); // Checks if AsanChunkView points to a valid allocated
|
||||
// or quarantined chunk.
|
||||
uptr Beg(); // First byte of user memory.
|
||||
uptr End(); // Last byte of user memory.
|
||||
uptr UsedSize(); // Size requested by the user.
|
||||
uptr AllocTid();
|
||||
uptr FreeTid();
|
||||
void GetAllocStack(StackTrace *stack);
|
||||
|
|
|
@ -218,6 +218,9 @@ struct AsanChunk: ChunkBase {
|
|||
}
|
||||
};
|
||||
|
||||
bool AsanChunkView::IsValid() {
|
||||
return chunk_ != 0 && chunk_->chunk_state != CHUNK_AVAILABLE;
|
||||
}
|
||||
uptr AsanChunkView::Beg() { return chunk_->Beg(); }
|
||||
uptr AsanChunkView::End() { return Beg() + UsedSize(); }
|
||||
uptr AsanChunkView::UsedSize() { return chunk_->UsedSize(); }
|
||||
|
@ -228,9 +231,8 @@ static void GetStackTraceFromId(u32 id, StackTrace *stack) {
|
|||
CHECK(id);
|
||||
uptr size = 0;
|
||||
const uptr *trace = StackDepotGet(id, &size);
|
||||
CHECK_LT(size, kStackTraceMax);
|
||||
internal_memcpy(stack->trace, trace, sizeof(uptr) * size);
|
||||
stack->size = size;
|
||||
CHECK(trace);
|
||||
stack->CopyFrom(trace, size);
|
||||
}
|
||||
|
||||
void AsanChunkView::GetAllocStack(StackTrace *stack) {
|
||||
|
|
|
@ -414,7 +414,11 @@ static void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr,
|
|||
|
||||
void DescribeHeapAddress(uptr addr, uptr access_size) {
|
||||
AsanChunkView chunk = FindHeapChunkByAddress(addr);
|
||||
if (!chunk.IsValid()) return;
|
||||
if (!chunk.IsValid()) {
|
||||
Printf("AddressSanitizer can not describe address in more detail "
|
||||
"(wild memory access suspected).\n");
|
||||
return;
|
||||
}
|
||||
DescribeAccessToHeapChunk(chunk, addr, access_size);
|
||||
CHECK(chunk.AllocTid() != kInvalidTid);
|
||||
asanThreadRegistry().CheckLocked();
|
||||
|
@ -564,9 +568,9 @@ void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) {
|
|||
(void*)addr, (void*)pc, (void*)sp, (void*)bp,
|
||||
GetCurrentTidOrInvalid());
|
||||
Printf("%s", d.EndWarning());
|
||||
Printf("AddressSanitizer can not provide additional info.\n");
|
||||
GET_STACK_TRACE_FATAL(pc, bp);
|
||||
PrintStack(&stack);
|
||||
Printf("AddressSanitizer can not provide additional info.\n");
|
||||
ReportSummary("SEGV", &stack);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// Regression test for
|
||||
// https://code.google.com/p/address-sanitizer/issues/detail?id=183
|
||||
|
||||
// RUN: %clangxx_asan -O2 %s -o %t
|
||||
// RUN: not %t 12 2>&1 | FileCheck %s
|
||||
// RUN: not %t 100 2>&1 | FileCheck %s
|
||||
// RUN: not %t 10000 2>&1 | FileCheck %s
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int *x = new int[5];
|
||||
memset(x, 0, sizeof(x[0]) * 5);
|
||||
int index = atoi(argv[1]);
|
||||
int res = x[index];
|
||||
// CHECK: AddressSanitizer: {{(heap-buffer-overflow|SEGV)}}
|
||||
// CHECK: #0 0x{{.*}} in main {{.*}}heap-overflow-large.cc:[[@LINE-2]]
|
||||
// CHECK: AddressSanitizer can not {{(provide additional info|describe address in more detail \(wild memory access suspected\))}}
|
||||
// CHECK: SUMMARY: AddressSanitizer: {{(heap-buffer-overflow|SEGV)}}
|
||||
delete[] x;
|
||||
return res;
|
||||
}
|
|
@ -11,7 +11,6 @@ __attribute__((noinline))
|
|||
static void NullDeref(int *ptr) {
|
||||
// CHECK: ERROR: AddressSanitizer: SEGV on unknown address
|
||||
// CHECK: {{0x0*00028 .*pc 0x.*}}
|
||||
// CHECK: {{AddressSanitizer can not provide additional info.}}
|
||||
ptr[10]++; // BOOM
|
||||
// atos on Mac cannot extract the symbol name correctly.
|
||||
// CHECK-Linux: {{ #0 0x.* in NullDeref.*null_deref.cc:}}[[@LINE-2]]
|
||||
|
@ -20,4 +19,5 @@ static void NullDeref(int *ptr) {
|
|||
int main() {
|
||||
NullDeref((int*)0);
|
||||
// CHECK: {{ #1 0x.* in main.*null_deref.cc:}}[[@LINE-1]]
|
||||
// CHECK: {{AddressSanitizer can not provide additional info.}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue