Skip to content

Commit 5d8750f

Browse files
committed
[TSan] Make Shadow/Meta region inclusive-exclusive
This commit changes the interval shadow/meta address check from inclusive-inclusive ( [start, end] ) to inclusive-exclusive ( [start, end) ), to resolve the ambiguity of the end point address. This also aligns the logic with the check for `isAppMem`, ensuring consistent behavior across all memory classifications. 1. The `isShadowMem` and `isMetaMem` checks previously used an inclusive-inclusive interval, i.e., [start, end], which could lead to a boundary address being incorrectly classified as both Shadow and Meta memory, e.g., 0x3000_0000_0000 in `Mapping48AddressSpace`. - What's more, even when Shadow doesn't border Meta, `ShadowMem::end` cannot be considered a legal shadow address, as TSan protects the gap, i.e., `ProtectRange(ShadowEnd(), MetaShadowBeg());` 2. `ShadowMem`/`MetaMem` addresses are derived from `AppMem` using an affine-like transformation (`* factor + bias`). This transformation includes two extra modifications: high- and low-order bits are masked out, and for Shadow Memory, an optional XOR operation may be applied to prevent conflicts with certain AppMem regions. - Given that all AppMem regions are defined as inclusive-exclusive intervals, $[\mathrm{start}, \mathrm{end})$, the resulting Shadow/Meta regions should logically also be inclusive-exclusive. Note: This change is purely for improving code consistency and should have no functional impact. In practice, the exact endpoint addresses of the Shadow/Meta regions are generally not reached.
1 parent 64bd4d9 commit 5d8750f

File tree

2 files changed

+5
-5
lines changed

2 files changed

+5
-5
lines changed

compiler-rt/lib/tsan/rtl/tsan_platform.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(mem); }
931931
struct IsShadowMemImpl {
932932
template <typename Mapping>
933933
static bool Apply(uptr mem) {
934-
return mem >= Mapping::kShadowBeg && mem <= Mapping::kShadowEnd;
934+
return mem >= Mapping::kShadowBeg && mem < Mapping::kShadowEnd;
935935
}
936936
};
937937

@@ -943,7 +943,7 @@ bool IsShadowMem(RawShadow *p) {
943943
struct IsMetaMemImpl {
944944
template <typename Mapping>
945945
static bool Apply(uptr mem) {
946-
return mem >= Mapping::kMetaShadowBeg && mem <= Mapping::kMetaShadowEnd;
946+
return mem >= Mapping::kMetaShadowBeg && mem < Mapping::kMetaShadowEnd;
947947
}
948948
};
949949

compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ ALWAYS_INLINE USED void UnalignedMemoryAccess(ThreadState* thr, uptr pc,
525525
void ShadowSet(RawShadow* p, RawShadow* end, RawShadow v) {
526526
DCHECK_LE(p, end);
527527
DCHECK(IsShadowMem(p));
528-
DCHECK(IsShadowMem(end));
528+
DCHECK(p == end || IsShadowMem(end - 1));
529529
UNUSED const uptr kAlign = kShadowCnt * kShadowSize;
530530
DCHECK_EQ(reinterpret_cast<uptr>(p) % kAlign, 0);
531531
DCHECK_EQ(reinterpret_cast<uptr>(end) % kAlign, 0);
@@ -675,7 +675,7 @@ void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) {
675675
Printf("Access to non app mem start: %p\n", (void*)addr);
676676
DCHECK(IsAppMem(addr));
677677
}
678-
if (!IsAppMem(addr + size - 1)) {
678+
if (size > 0 && !IsAppMem(addr + size - 1)) {
679679
Printf("Access to non app mem end: %p\n", (void*)(addr + size - 1));
680680
DCHECK(IsAppMem(addr + size - 1));
681681
}
@@ -686,7 +686,7 @@ void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) {
686686

687687
RawShadow* shadow_mem_end = reinterpret_cast<RawShadow*>(
688688
reinterpret_cast<uptr>(shadow_mem) + size * kShadowMultiplier - 1);
689-
if (!IsShadowMem(shadow_mem_end)) {
689+
if (size > 0 && !IsShadowMem(shadow_mem_end)) {
690690
Printf("Bad shadow end addr: %p (%p)\n", shadow_mem_end,
691691
(void*)(addr + size - 1));
692692
Printf(

0 commit comments

Comments
 (0)