diff --git a/compiler-rt/lib/asan/asan_poisoning.cpp b/compiler-rt/lib/asan/asan_poisoning.cpp --- a/compiler-rt/lib/asan/asan_poisoning.cpp +++ b/compiler-rt/lib/asan/asan_poisoning.cpp @@ -354,8 +354,8 @@ uptr old_mid = reinterpret_cast(old_mid_p); uptr new_mid = reinterpret_cast(new_mid_p); uptr granularity = ASAN_SHADOW_GRANULARITY; - if (!(beg <= old_mid && beg <= new_mid && old_mid <= end && new_mid <= end && - IsAligned(beg, granularity))) { + if (!IsAligned(beg, granularity)) return; + if (!(beg <= old_mid && beg <= new_mid && old_mid <= end && new_mid <= end)) { GET_STACK_TRACE_FATAL_HERE; ReportBadParamsToAnnotateContiguousContainer(beg, end, old_mid, new_mid, &stack); @@ -389,6 +389,11 @@ PoisonShadow(b2, c - b2, kAsanContiguousContainerOOBMagic); if (b1 != b2) { CHECK_EQ(b2 - b1, granularity); + // If in [b1; b2) there is not poisoned byte outside of container, + // we cannot modify last granule. + // That may happen for example when object poisons own memory. + uptr accessible = *(u8*)MemToShadow(b1) == 0 ? granularity : *(u8*)MemToShadow(b1); + if(*(u8*)MemToShadow(b1) < granularity && end < (b1 + accessible) ) return; *(u8*)MemToShadow(b1) = static_cast(new_mid - b1); } }