diff options
| author | Alex Shlyapnikov <alekseys@google.com> | 2017-10-25 17:21:37 +0000 |
|---|---|---|
| committer | Alex Shlyapnikov <alekseys@google.com> | 2017-10-25 17:21:37 +0000 |
| commit | a53b55f66ca46597294005fec276359ab7c37018 (patch) | |
| tree | a147b52bd6bbdb90c676f6d0965beea7baa5eebe /compiler-rt/lib/asan/asan_errors.cc | |
| parent | 6391458e9c52e3cf287fcd44a57c5752b47f1613 (diff) | |
| download | bcm5719-llvm-a53b55f66ca46597294005fec276359ab7c37018.tar.gz bcm5719-llvm-a53b55f66ca46597294005fec276359ab7c37018.zip | |
[Sanitizers] ASan: detect new/delete calls with mismatched alignment.
ASan allocator stores the requested alignment for new and new[] calls
and on delete and delete[] verifies that alignments do match.
The representable alignments are: default alignment, 8, 16, 32, 64, 128,
256 and 512 bytes. Alignments > 512 are stored as 512, hence two
different alignments > 512 will pass the check (possibly masking the bug),
but limited memory requirements deemed to be a resonable tradeoff for
relaxed conditions.
The feature is controlled by new_delete_type_mismatch flag, the same one
protecting new/delete matching size check.
Differential revision: https://reviews.llvm.org/D38574
Issue: https://github.com/google/sanitizers/issues/799
llvm-svn: 316595
Diffstat (limited to 'compiler-rt/lib/asan/asan_errors.cc')
| -rw-r--r-- | compiler-rt/lib/asan/asan_errors.cc | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/compiler-rt/lib/asan/asan_errors.cc b/compiler-rt/lib/asan/asan_errors.cc index dee666d54ff..6413b987b24 100644 --- a/compiler-rt/lib/asan/asan_errors.cc +++ b/compiler-rt/lib/asan/asan_errors.cc @@ -63,7 +63,7 @@ void ErrorDoubleFree::Print() { ReportErrorSummary(scariness.GetDescription(), &stack); } -void ErrorNewDeleteSizeMismatch::Print() { +void ErrorNewDeleteTypeMismatch::Print() { Decorator d; Printf("%s", d.Warning()); char tname[128]; @@ -73,10 +73,28 @@ void ErrorNewDeleteSizeMismatch::Print() { scariness.GetDescription(), addr_description.addr, tid, ThreadNameWithParenthesis(tid, tname, sizeof(tname))); Printf("%s object passed to delete has wrong type:\n", d.Default()); - Printf( - " size of the allocated type: %zd bytes;\n" - " size of the deallocated type: %zd bytes.\n", - addr_description.chunk_access.chunk_size, delete_size); + if (delete_size != 0) { + Printf( + " size of the allocated type: %zd bytes;\n" + " size of the deallocated type: %zd bytes.\n", + addr_description.chunk_access.chunk_size, delete_size); + } + const uptr user_alignment = + addr_description.chunk_access.user_requested_alignment; + if (delete_alignment != user_alignment) { + char user_alignment_str[32]; + char delete_alignment_str[32]; + internal_snprintf(user_alignment_str, sizeof(user_alignment_str), + "%zd bytes", user_alignment); + internal_snprintf(delete_alignment_str, sizeof(delete_alignment_str), + "%zd bytes", delete_alignment); + static const char *kDefaultAlignment = "default-aligned"; + Printf( + " alignment of the allocated type: %s;\n" + " alignment of the deallocated type: %s.\n", + user_alignment > 0 ? user_alignment_str : kDefaultAlignment, + delete_alignment > 0 ? delete_alignment_str : kDefaultAlignment); + } CHECK_GT(free_stack->size, 0); scariness.Print(); GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); |

