[HWASan] Print short tags in tag mismatch description.
I recently spent some extra time debugging a false positive because I didn't realize the "real" tag was in the short granule. Adding the short tag here makes it more obvious that we could be dealing with a short granule. Reviewed By: hctim, eugenis Differential Revision: https://reviews.llvm.org/D112949
This commit is contained in:
parent
8c60e0b632
commit
498a4c2fd7
|
|
@ -702,17 +702,15 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size,
|
||||||
tag_t mem_tag = *tag_ptr;
|
tag_t mem_tag = *tag_ptr;
|
||||||
|
|
||||||
Printf("%s", d.Access());
|
Printf("%s", d.Access());
|
||||||
Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem) in thread T%zd\n",
|
|
||||||
is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag,
|
|
||||||
mem_tag, t->unique_id());
|
|
||||||
if (mem_tag && mem_tag < kShadowAlignment) {
|
if (mem_tag && mem_tag < kShadowAlignment) {
|
||||||
tag_t *granule_ptr = reinterpret_cast<tag_t *>((untagged_addr + offset) &
|
tag_t *granule_ptr = reinterpret_cast<tag_t *>((untagged_addr + offset) &
|
||||||
~(kShadowAlignment - 1));
|
~(kShadowAlignment - 1));
|
||||||
// If offset is 0, (untagged_addr + offset) is not aligned to granules.
|
// If offset is 0, (untagged_addr + offset) is not aligned to granules.
|
||||||
// This is the offset of the leftmost accessed byte within the bad granule.
|
// This is the offset of the leftmost accessed byte within the bad granule.
|
||||||
u8 in_granule_offset = (untagged_addr + offset) & (kShadowAlignment - 1);
|
u8 in_granule_offset = (untagged_addr + offset) & (kShadowAlignment - 1);
|
||||||
|
tag_t short_tag = granule_ptr[kShadowAlignment - 1];
|
||||||
// The first mismatch was a short granule that matched the ptr_tag.
|
// The first mismatch was a short granule that matched the ptr_tag.
|
||||||
if (granule_ptr[kShadowAlignment - 1] == ptr_tag) {
|
if (short_tag == ptr_tag) {
|
||||||
// If the access starts after the end of the short granule, then the first
|
// If the access starts after the end of the short granule, then the first
|
||||||
// bad byte is the first byte of the access; otherwise it is the first
|
// bad byte is the first byte of the access; otherwise it is the first
|
||||||
// byte past the end of the short granule
|
// byte past the end of the short granule
|
||||||
|
|
@ -720,6 +718,14 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size,
|
||||||
offset += mem_tag - in_granule_offset;
|
offset += mem_tag - in_granule_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Printf(
|
||||||
|
"%s of size %zu at %p tags: %02x/%02x(%02x) (ptr/mem) in thread T%zd\n",
|
||||||
|
is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag,
|
||||||
|
mem_tag, short_tag, t->unique_id());
|
||||||
|
} else {
|
||||||
|
Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem) in thread T%zd\n",
|
||||||
|
is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag,
|
||||||
|
mem_tag, t->unique_id());
|
||||||
}
|
}
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
Printf("Invalid access starting at offset %zu\n", offset);
|
Printf("Invalid access starting at offset %zu\n", offset);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ int main(int argc, char **argv) {
|
||||||
// CHECKM: Cause: heap-buffer-overflow
|
// CHECKM: Cause: heap-buffer-overflow
|
||||||
// CHECKM: is located 0 bytes to the right of 1000000-byte region
|
// CHECKM: is located 0 bytes to the right of 1000000-byte region
|
||||||
//
|
//
|
||||||
// CHECK31: tags: [[TAG:..]]/0e (ptr/mem)
|
// CHECK31: tags: [[TAG:..]]/0e([[TAG]]) (ptr/mem)
|
||||||
// CHECK31-NOT: Invalid access starting at offset
|
// CHECK31-NOT: Invalid access starting at offset
|
||||||
// CHECK31: Cause: heap-buffer-overflow
|
// CHECK31: Cause: heap-buffer-overflow
|
||||||
// CHECK31: is located 1 bytes to the right of 30-byte region
|
// CHECK31: is located 1 bytes to the right of 30-byte region
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue