2525#include " sanitizer_common/sanitizer_array_ref.h"
2626#include " sanitizer_common/sanitizer_common.h"
2727#include " sanitizer_common/sanitizer_flags.h"
28+ #include " sanitizer_common/sanitizer_internal_defs.h"
2829#include " sanitizer_common/sanitizer_mutex.h"
2930#include " sanitizer_common/sanitizer_report_decorator.h"
3031#include " sanitizer_common/sanitizer_stackdepot.h"
@@ -321,56 +322,61 @@ static uptr GetGlobalSizeFromDescriptor(uptr ptr) {
321322
322323void ReportStats () {}
323324
324- static void PrintTagInfoAroundAddr (tag_t *tag_ptr, uptr num_rows,
325- void (*print_tag)(InternalScopedString &s,
326- tag_t *tag)) {
325+ template <typename PrintTag>
326+ static void PrintTagInfoAroundAddr (uptr addr, uptr num_rows,
327+ InternalScopedString &s,
328+ PrintTag print_tag) {
327329 const uptr row_len = 16 ; // better be power of two.
328- tag_t *center_row_beg = reinterpret_cast <tag_t *>(
329- RoundDownTo (reinterpret_cast <uptr>(tag_ptr), row_len));
330- tag_t *beg_row = center_row_beg - row_len * (num_rows / 2 );
331- tag_t *end_row = center_row_beg + row_len * ((num_rows + 1 ) / 2 );
332- InternalScopedString s;
333- for (tag_t *row = beg_row; row < end_row; row += row_len) {
330+ uptr center_row_beg = RoundDownTo (addr, row_len);
331+ uptr beg_row = center_row_beg - row_len * (num_rows / 2 );
332+ uptr end_row = center_row_beg + row_len * ((num_rows + 1 ) / 2 );
333+ for (uptr row = beg_row; row < end_row; row += row_len) {
334334 s.Append (row == center_row_beg ? " =>" : " " );
335- s.AppendF (" %p:" , (void *)ShadowToMem (reinterpret_cast <uptr>( row) ));
335+ s.AppendF (" %p:" , (void *)ShadowToMem (row));
336336 for (uptr i = 0 ; i < row_len; i++) {
337- s.Append (row + i == tag_ptr ? " [" : " " );
338- print_tag (s, & row[i] );
339- s.Append (row + i == tag_ptr ? " ]" : " " );
337+ s.Append (row + i == addr ? " [" : " " );
338+ print_tag (s, row + i );
339+ s.Append (row + i == addr ? " ]" : " " );
340340 }
341341 s.AppendF (" \n " );
342342 }
343- Printf (" %s" , s.data ());
344343}
345344
346- static void PrintTagsAroundAddr (tag_t *tag_ptr) {
347- Printf (
345+ template <typename GetTag, typename GetShortTag>
346+ static void PrintTagsAroundAddr (uptr addr, GetTag get_tag,
347+ GetShortTag get_short_tag) {
348+ InternalScopedString s;
349+ addr = MemToShadow (addr);
350+ s.AppendF (
348351 " Memory tags around the buggy address (one tag corresponds to %zd "
349352 " bytes):\n " ,
350353 kShadowAlignment );
351- PrintTagInfoAroundAddr (tag_ptr, 17 , [](InternalScopedString &s, tag_t *tag) {
352- s.AppendF (" %02x" , *tag);
353- });
354+ PrintTagInfoAroundAddr (addr, 17 , s,
355+ [&](InternalScopedString &s, uptr tag_addr) {
356+ tag_t tag = get_tag (tag_addr);
357+ s.AppendF (" %02x" , tag);
358+ });
354359
355- Printf (
360+ s. AppendF (
356361 " Tags for short granules around the buggy address (one tag corresponds "
357362 " to %zd bytes):\n " ,
358363 kShadowAlignment );
359- PrintTagInfoAroundAddr (tag_ptr , 3 , [](InternalScopedString &s, tag_t *tag) {
360- uptr granule_addr = ShadowToMem ( reinterpret_cast < uptr>(tag));
361- if (*tag >= 1 && * tag <= kShadowAlignment &&
362- IsAccessibleMemoryRange (granule_addr, kShadowAlignment ) ) {
363- s. AppendF ( " %02x " ,
364- * reinterpret_cast < u8 *>(granule_addr + kShadowAlignment - 1 ) );
365- } else {
366- s.AppendF (" .." );
367- }
368- });
369- Printf (
364+ PrintTagInfoAroundAddr (addr , 3 , s,
365+ [&](InternalScopedString &s, uptr tag_addr) {
366+ tag_t tag = get_tag (tag_addr);
367+ if (tag >= 1 && tag <= kShadowAlignment ) {
368+ tag_t short_tag = get_short_tag (tag_addr);
369+ s. AppendF ( " %02x " , short_tag );
370+ } else {
371+ s.AppendF (" .." );
372+ }
373+ });
374+ s. AppendF (
370375 " See "
371376 " https://clang.llvm.org/docs/"
372377 " HardwareAssistedAddressSanitizerDesign.html#short-granules for a "
373378 " description of short granule tags\n " );
379+ Printf (" %s" , s.data ());
374380}
375381
376382static uptr GetTopPc (const StackTrace *stack) {
@@ -390,7 +396,8 @@ class BaseReport {
390396 ptr_tag(GetTagFromPointer(tagged_addr)),
391397 heap(CopyHeapChunk()),
392398 allocations(CopyAllocations()),
393- candidate(FindBufferOverflowCandidate()) {}
399+ candidate(FindBufferOverflowCandidate()),
400+ shadow(CopyShadow()) {}
394401
395402 protected:
396403 struct OverflowCandidate {
@@ -428,6 +435,15 @@ class BaseReport {
428435 bool is_allocated = false ;
429436 };
430437
438+ struct Shadow {
439+ uptr addr = 0 ;
440+ tag_t tags[512 ] = {};
441+ tag_t short_tags[ARRAY_SIZE(tags)] = {};
442+ };
443+
444+ Shadow CopyShadow () const ;
445+ tag_t GetTagCopy (uptr addr) const ;
446+ tag_t GetShortTagCopy (uptr addr) const ;
431447 HeapChunk CopyHeapChunk () const ;
432448 Allocations CopyAllocations ();
433449 OverflowCandidate FindBufferOverflowCandidate () const ;
@@ -447,8 +463,45 @@ class BaseReport {
447463 const HeapChunk heap;
448464 const Allocations allocations;
449465 const OverflowCandidate candidate;
466+
467+ const Shadow shadow;
450468};
451469
470+ BaseReport::Shadow BaseReport::CopyShadow () const {
471+ Shadow result;
472+ if (!MemIsApp (untagged_addr))
473+ return result;
474+
475+ result.addr = MemToShadow (untagged_addr) - ARRAY_SIZE (result.tags ) / 2 ;
476+ for (uptr i = 0 ; i < ARRAY_SIZE (result.tags ); ++i) {
477+ uptr tag_addr = result.addr + i;
478+ if (!MemIsShadow (tag_addr))
479+ continue ;
480+ result.tags [i] = *reinterpret_cast <tag_t *>(tag_addr);
481+ uptr granule_addr = ShadowToMem (tag_addr);
482+ if (1 <= result.tags [i] && result.tags [i] <= kShadowAlignment &&
483+ IsAccessibleMemoryRange (granule_addr, kShadowAlignment )) {
484+ result.short_tags [i] =
485+ *reinterpret_cast <tag_t *>(granule_addr + kShadowAlignment - 1 );
486+ }
487+ }
488+ return result;
489+ }
490+
491+ tag_t BaseReport::GetTagCopy (uptr addr) const {
492+ CHECK_GE (addr, shadow.addr );
493+ uptr idx = addr - shadow.addr ;
494+ CHECK_LT (idx, ARRAY_SIZE (shadow.tags ));
495+ return shadow.tags [idx];
496+ }
497+
498+ tag_t BaseReport::GetShortTagCopy (uptr addr) const {
499+ CHECK_GE (addr, shadow.addr );
500+ uptr idx = addr - shadow.addr ;
501+ CHECK_LT (idx, ARRAY_SIZE (shadow.short_tags ));
502+ return shadow.short_tags [idx];
503+ }
504+
452505BaseReport::HeapChunk BaseReport::CopyHeapChunk () const {
453506 HeapChunk result = {};
454507 if (MemIsShadow (untagged_addr))
@@ -721,15 +774,6 @@ class InvalidFreeReport : public BaseReport {
721774};
722775
723776InvalidFreeReport::~InvalidFreeReport () {
724- tag_t *tag_ptr = nullptr ;
725- tag_t mem_tag = 0 ;
726- if (MemIsApp (untagged_addr)) {
727- tag_ptr = reinterpret_cast <tag_t *>(MemToShadow (untagged_addr));
728- if (MemIsShadow (reinterpret_cast <uptr>(tag_ptr)))
729- mem_tag = *tag_ptr;
730- else
731- tag_ptr = nullptr ;
732- }
733777 Decorator d;
734778 Printf (" %s" , d.Error ());
735779 uptr pc = GetTopPc (stack);
@@ -743,16 +787,21 @@ InvalidFreeReport::~InvalidFreeReport() {
743787 SanitizerToolName, bug_type, untagged_addr, pc);
744788 }
745789 Printf (" %s" , d.Access ());
746- if (tag_ptr)
747- Printf (" tags: %02x/%02x (ptr/mem)\n " , ptr_tag, mem_tag);
790+ if (shadow.addr ) {
791+ Printf (" tags: %02x/%02x (ptr/mem)\n " , ptr_tag,
792+ GetTagCopy (MemToShadow (untagged_addr)));
793+ }
748794 Printf (" %s" , d.Default ());
749795
750796 stack->Print ();
751797
752798 PrintAddressDescription ();
753799
754- if (tag_ptr)
755- PrintTagsAroundAddr (tag_ptr);
800+ if (shadow.addr ) {
801+ PrintTagsAroundAddr (
802+ untagged_addr, [&](uptr addr) { return GetTagCopy (addr); },
803+ [&](uptr addr) { return GetShortTagCopy (addr); });
804+ }
756805
757806 MaybePrintAndroidHelpUrl ();
758807 ReportErrorSummary (bug_type, stack);
@@ -834,8 +883,9 @@ TailOverwrittenReport::~TailOverwrittenReport() {
834883 Printf (" %s" , s.data ());
835884 GetCurrentThread ()->Announce ();
836885
837- tag_t *tag_ptr = reinterpret_cast <tag_t *>(MemToShadow (untagged_addr));
838- PrintTagsAroundAddr (tag_ptr);
886+ PrintTagsAroundAddr (
887+ untagged_addr, [&](uptr addr) { return GetTagCopy (addr); },
888+ [&](uptr addr) { return GetShortTagCopy (addr); });
839889
840890 MaybePrintAndroidHelpUrl ();
841891 ReportErrorSummary (bug_type, stack);
@@ -912,7 +962,9 @@ TagMismatchReport::~TagMismatchReport() {
912962 PrintAddressDescription ();
913963 t->Announce ();
914964
915- PrintTagsAroundAddr (tag_ptr);
965+ PrintTagsAroundAddr (
966+ untagged_addr + offset, [&](uptr addr) { return GetTagCopy (addr); },
967+ [&](uptr addr) { return GetShortTagCopy (addr); });
916968
917969 if (registers_frame)
918970 ReportRegisters (registers_frame, pc);
0 commit comments