From 1d55c2b52afcaf327ce8b96a524684acfcfe3bf9 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Fri, 15 Nov 2024 10:32:38 -0800 Subject: [PATCH] Migrate sanitizer related macros from port_def into internal functions in port.h. This reduces the cost of port_def.inc includes. PiperOrigin-RevId: 696931317 --- .../Reflection/FeatureSetDescriptor.g.cs | 17 ------ src/google/protobuf/BUILD.bazel | 2 + src/google/protobuf/arena.cc | 12 ++-- src/google/protobuf/arena_unittest.cc | 31 +++++----- .../protobuf/generated_message_reflection.cc | 2 +- .../generated_message_tctable_lite_test.cc | 9 +-- .../protobuf/io/zero_copy_stream_unittest.cc | 1 + src/google/protobuf/map_field.h | 3 +- src/google/protobuf/message.h | 12 ++-- src/google/protobuf/parse_context.h | 12 ++-- src/google/protobuf/port.h | 57 +++++++++++++++++-- src/google/protobuf/port_def.inc | 53 +---------------- src/google/protobuf/port_undef.inc | 5 -- src/google/protobuf/proto3_arena_unittest.cc | 10 ++-- src/google/protobuf/repeated_field.h | 4 +- .../protobuf/repeated_field_unittest.cc | 16 +++--- .../protobuf/repeated_ptr_field_unittest.cc | 1 + src/google/protobuf/serial_arena.h | 10 ++-- 18 files changed, 121 insertions(+), 136 deletions(-) delete mode 100644 csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs diff --git a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs b/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs deleted file mode 100644 index 208ce1fcb631..000000000000 --- a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs +++ /dev/null @@ -1,17 +0,0 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd -#endregion - -namespace Google.Protobuf.Reflection; - -internal sealed partial class FeatureSetDescriptor -{ - // Canonical serialized form of the edition defaults, generated by embed_edition_defaults. - private const string DefaultsBase64 = - "ChMYhAciACoMCAEQAhgCIAMoATACChMY5wciACoMCAIQARgBIAIoATABChMY6AciDAgBEAEYASACKAEwASoAIOYHKOgH"; -} diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index c75dfa8bfade..057c674265db 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -661,6 +661,7 @@ cc_library( "//third_party/utf8_range:utf8_validity", "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/base", + "@com_google_absl//absl/base:config", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:dynamic_annotations", "@com_google_absl//absl/cleanup", @@ -1965,6 +1966,7 @@ cc_test( "//src/google/protobuf/stubs", "//src/google/protobuf/testing", "//src/google/protobuf/testing:file", + "@com_google_absl//absl/base:config", "@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/numeric:bits", "@com_google_absl//absl/random", diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 9e74480b77e9..d250b24ac015 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -338,7 +338,7 @@ void SerialArena::AllocateNewBlock(size_t n) { // Previous writes must take effect before writing new head. head_.store(new_head, std::memory_order_release); - PROTOBUF_POISON_MEMORY_REGION(ptr(), limit_ - ptr()); + internal::PoisonMemoryRegion(ptr(), limit_ - ptr()); } uint64_t SerialArena::SpaceUsed() const { @@ -716,7 +716,7 @@ void ThreadSafeArena::UnpoisonAllArenaBlocks() const { VisitSerialArena([](const SerialArena* serial) { for (const auto* b = serial->head(); b != nullptr && !b->IsSentry(); b = b->next) { - PROTOBUF_UNPOISON_MEMORY_REGION(b, b->size); + internal::UnpoisonMemoryRegion(b, b->size); } }); } @@ -746,7 +746,7 @@ ThreadSafeArena::~ThreadSafeArena() { auto mem = Free(); if (alloc_policy_.is_user_owned_initial_block()) { // Unpoison the initial block, now that it's going back to the user. - PROTOBUF_UNPOISON_MEMORY_REGION(mem.p, mem.n); + internal::UnpoisonMemoryRegion(mem.p, mem.n); } else if (mem.n > 0) { GetDeallocator(alloc_policy_.get())(mem); } @@ -922,9 +922,9 @@ template void* ThreadSafeArena::AllocateAlignedFallback(size_t); void ThreadSafeArena::CleanupList() { -#ifdef PROTOBUF_ASAN - UnpoisonAllArenaBlocks(); -#endif + if constexpr (HasMemoryPoisoning()) { + UnpoisonAllArenaBlocks(); + } WalkSerialArenaChunk([](SerialArenaChunk* chunk) { absl::Span> span = chunk->arenas(); diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index ca04704a56f4..272e6b268ab2 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -1539,13 +1539,13 @@ TEST(ArenaTest, ClearOneofMessageOnArena) { child->set_moo_int(100); message->clear_foo_message(); -#ifndef PROTOBUF_ASAN - EXPECT_NE(child->moo_int(), 100); -#else + if (internal::HasMemoryPoisoning()) { #if GTEST_HAS_DEATH_TEST - EXPECT_DEATH(EXPECT_EQ(child->moo_int(), 0), "use-after-poison"); + EXPECT_DEATH(EXPECT_EQ(child->moo_int(), 0), "use-after-poison"); #endif // !GTEST_HAS_DEATH_TEST -#endif // !PROTOBUF_ASAN + } else { + EXPECT_NE(child->moo_int(), 100); + } } TEST(ArenaTest, CopyValuesWithinOneof) { @@ -1840,7 +1840,10 @@ TEST(ArenaTest, SpaceReuseForArraysSizeChecks) { } TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) { -#ifdef PROTOBUF_ASAN + if constexpr (!internal::HasMemoryPoisoning()) { + GTEST_SKIP() << "Memory poisoning not enabled."; + } + char buf[1024]{}; constexpr int kSize = 32; { @@ -1849,19 +1852,21 @@ TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) { for (int i = 0; i < 100; ++i) { void* p = Arena::CreateArray(&arena, kSize); // Simulate other ASan client managing shadow memory. - ASAN_POISON_MEMORY_REGION(p, kSize); - ASAN_UNPOISON_MEMORY_REGION(p, kSize - 4); + internal::PoisonMemoryRegion(p, kSize); + internal::UnpoisonMemoryRegion(p, kSize - 4); pointers.push_back(p); } for (void* p : pointers) { internal::ArenaTestPeer::ReturnArrayMemory(&arena, p, kSize); // The first one is not poisoned because it becomes the freelist. - if (p != pointers[0]) EXPECT_TRUE(__asan_address_is_poisoned(p)); + if (p != pointers[0]) { + EXPECT_TRUE(internal::IsMemoryPoisoned(p)); + } } bool found_poison = false; for (char& c : buf) { - if (__asan_address_is_poisoned(&c)) { + if (internal::IsMemoryPoisoned(&c)) { found_poison = true; break; } @@ -1871,12 +1876,8 @@ TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) { // Should not be poisoned after destruction. for (char& c : buf) { - ASSERT_FALSE(__asan_address_is_poisoned(&c)); + ASSERT_FALSE(internal::IsMemoryPoisoned(&c)); } - -#else // PROTOBUF_ASAN - GTEST_SKIP(); -#endif // PROTOBUF_ASAN } diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 1db1433c145f..d6a68da7fda4 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -1374,7 +1374,7 @@ void Reflection::MaybePoisonAfterClear(Message& root) const { for (auto it : nodes) { (void)it; - PROTOBUF_POISON_MEMORY_REGION(it.ptr, it.size); + internal::PoisonMemoryRegion(it.ptr, it.size); } } diff --git a/src/google/protobuf/generated_message_tctable_lite_test.cc b/src/google/protobuf/generated_message_tctable_lite_test.cc index 1e4b40f572ab..5f098f8696cb 100644 --- a/src/google/protobuf/generated_message_tctable_lite_test.cc +++ b/src/google/protobuf/generated_message_tctable_lite_test.cc @@ -25,6 +25,7 @@ #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/message_lite.h" #include "google/protobuf/parse_context.h" +#include "google/protobuf/port.h" #include "google/protobuf/unittest.pb.h" #include "google/protobuf/wire_format_lite.h" @@ -916,10 +917,10 @@ TEST(GeneratedMessageTctableLiteTest, PackedEnumSmallRange) { // This test checks that the parser doesn't overflow an int32 when computing the // array's new length. TEST(GeneratedMessageTctableLiteTest, PackedEnumSmallRangeLargeSize) { -#ifdef PROTOBUF_MSAN - // This test attempts to allocate 8GB of memory, which OOMs MSAN. - return; -#endif + if constexpr (internal::HasAnySanitizer()) { + GTEST_SKIP() << "This test attempts to allocate 8GB of memory, which OOMs " + "in sanitizer mode."; + } #ifdef _WIN32 // This test OOMs on Windows. I think this is because Windows is committing diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index 0525882c284b..45656d38e0e3 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -57,6 +57,7 @@ #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/io_win32.h" #include "google/protobuf/io/zero_copy_stream_impl.h" +#include "google/protobuf/port.h" #include "google/protobuf/test_util2.h" #if HAVE_ZLIB diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 987ee23b358f..81d8d64168f6 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -17,6 +17,7 @@ #include #include "absl/base/attributes.h" +#include "absl/base/config.h" #include "absl/hash/hash.h" #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" @@ -437,7 +438,7 @@ class PROTOBUF_EXPORT MapFieldBase : public MapFieldBaseForParse { // thread calls either ConstAccess() or MutableAccess(), on the same // MapFieldBase-derived object, and there is no synchronization going // on between them, tsan will alert. -#if defined(PROTOBUF_TSAN) +#if defined(ABSL_HAVE_THREAD_SANITIZER) void ConstAccess() const { ABSL_CHECK_EQ(seq1_, seq2_); } void MutableAccess() { if (seq1_ & 1) { diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 65d6b32c22d4..4f378484a1f1 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -1604,12 +1604,12 @@ bool SplitFieldHasExtraIndirectionStatic(const FieldDescriptor* field) { inline void MaybePoisonAfterClear(Message* root) { if (root == nullptr) return; -#ifndef PROTOBUF_ASAN - root->Clear(); -#else - const Reflection* reflection = root->GetReflection(); - reflection->MaybePoisonAfterClear(*root); -#endif + if constexpr (HasMemoryPoisoning()) { + const Reflection* reflection = root->GetReflection(); + reflection->MaybePoisonAfterClear(*root); + } else { + root->Clear(); + } } } // namespace internal diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h index 83fe53843bbc..167164b8260f 100644 --- a/src/google/protobuf/parse_context.h +++ b/src/google/protobuf/parse_context.h @@ -123,10 +123,10 @@ class PROTOBUF_EXPORT EpsCopyInputStream { // __asan_address_is_poisoned is allowed to have false negatives. class LimitToken { public: - LimitToken() { PROTOBUF_POISON_MEMORY_REGION(&token_, sizeof(token_)); } + LimitToken() { internal::PoisonMemoryRegion(&token_, sizeof(token_)); } explicit LimitToken(int token) : token_(token) { - PROTOBUF_UNPOISON_MEMORY_REGION(&token_, sizeof(token_)); + internal::UnpoisonMemoryRegion(&token_, sizeof(token_)); } LimitToken(const LimitToken&) = delete; @@ -135,17 +135,17 @@ class PROTOBUF_EXPORT EpsCopyInputStream { LimitToken(LimitToken&& other) { *this = std::move(other); } LimitToken& operator=(LimitToken&& other) { - PROTOBUF_UNPOISON_MEMORY_REGION(&token_, sizeof(token_)); + internal::UnpoisonMemoryRegion(&token_, sizeof(token_)); token_ = other.token_; - PROTOBUF_POISON_MEMORY_REGION(&other.token_, sizeof(token_)); + internal::PoisonMemoryRegion(&other.token_, sizeof(token_)); return *this; } - ~LimitToken() { PROTOBUF_UNPOISON_MEMORY_REGION(&token_, sizeof(token_)); } + ~LimitToken() { internal::UnpoisonMemoryRegion(&token_, sizeof(token_)); } int token() && { int t = token_; - PROTOBUF_POISON_MEMORY_REGION(&token_, sizeof(token_)); + internal::PoisonMemoryRegion(&token_, sizeof(token_)); return t; } diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h index 8931d4363372..52fe22dbcd54 100644 --- a/src/google/protobuf/port.h +++ b/src/google/protobuf/port.h @@ -29,6 +29,10 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#if defined(ABSL_HAVE_ADDRESS_SANITIZER) +#include +#endif + // must be last #include "google/protobuf/port_def.inc" @@ -258,9 +262,18 @@ inline constexpr bool DebugHardenClearOneofMessageOnArena() { #endif } +constexpr bool HasAnySanitizer() { +#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ + defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER) + return true; +#else + return false; +#endif +} + constexpr bool PerformDebugChecks() { -#if defined(NDEBUG) && !defined(PROTOBUF_ASAN) && !defined(PROTOBUF_MSAN) && \ - !defined(PROTOBUF_TSAN) + if (HasAnySanitizer()) return true; +#if defined(NDEBUG) return false; #else return true; @@ -355,13 +368,45 @@ PROTOBUF_ALWAYS_INLINE void Prefetch5LinesFrom1Line(const void* ptr) { } #endif -#ifdef PROTOBUF_TSAN +constexpr bool HasMemoryPoisoning() { +#if defined(ABSL_HAVE_ADDRESS_SANITIZER) + return true; +#else + return false; +#endif +} + +// Poison memory region when supported by sanitizer config. +inline void PoisonMemoryRegion(const void* p, size_t n) { +#if defined(ABSL_HAVE_ADDRESS_SANITIZER) + ASAN_POISON_MEMORY_REGION(p, n); +#else + // Nothing +#endif +} + +inline void UnpoisonMemoryRegion(const void* p, size_t n) { +#if defined(ABSL_HAVE_ADDRESS_SANITIZER) + ASAN_UNPOISON_MEMORY_REGION(p, n); +#else + // Nothing +#endif +} + +inline bool IsMemoryPoisoned(const void* p) { +#if defined(ABSL_HAVE_ADDRESS_SANITIZER) + return __asan_address_is_poisoned(p); +#else + return false; +#endif +} + +#if defined(ABSL_HAVE_THREAD_SANITIZER) // TODO: it would be preferable to use __tsan_external_read/ // __tsan_external_write, but they can cause dlopen issues. template PROTOBUF_ALWAYS_INLINE void TSanRead(const T* impl) { - char protobuf_tsan_dummy = - *reinterpret_cast(&impl->_tsan_detect_race); + char protobuf_tsan_dummy = impl->_tsan_detect_race; asm volatile("" : "+r"(protobuf_tsan_dummy)); } @@ -370,7 +415,7 @@ PROTOBUF_ALWAYS_INLINE void TSanRead(const T* impl) { // correctness of the rest of the class. template PROTOBUF_ALWAYS_INLINE void TSanWrite(T* impl) { - *reinterpret_cast(&impl->_tsan_detect_race) = 0; + impl->_tsan_detect_race = 0; } #else PROTOBUF_ALWAYS_INLINE void TSanRead(const void*) {} diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 290321ce4811..69220b310c96 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -503,56 +503,9 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #define PROTOBUF_HAVE_ATTRIBUTE_WEAK 0 #endif -// Macros to detect sanitizers. -#ifdef PROTOBUF_ASAN -#error PROTOBUF_ASAN was previously defined -#endif -#ifdef PROTOBUF_MSAN -#error PROTOBUF_MSAN was previously defined -#endif -#ifdef PROTOBUF_TSAN -#error PROTOBUF_TSAN was previously defined -#endif -#if defined(__clang__) -#if ABSL_HAVE_FEATURE(address_sanitizer) -# define PROTOBUF_ASAN 1 -# endif -#if ABSL_HAVE_FEATURE(thread_sanitizer) -# define PROTOBUF_TSAN 1 -# endif -#if ABSL_HAVE_FEATURE(memory_sanitizer) -# define PROTOBUF_MSAN 1 -# endif -#elif defined(__GNUC__) -// Double-guard is needed for -Wundef: -# ifdef __SANITIZE_ADDRESS__ -# if __SANITIZE_ADDRESS__ -# define PROTOBUF_ASAN 1 -# endif -# endif -# ifdef __SANITIZE_THREAD__ -# if __SANITIZE_THREAD__ -# define PROTOBUF_TSAN 1 -# endif -# endif -# ifdef __SANITIZE_MEMORY__ -# if __SANITIZE_MEMORY__ -# define PROTOBUF_ASAN 1 -# endif -# endif -#endif - -#ifdef PROTOBUF_ASAN -#include -#define PROTOBUF_POISON_MEMORY_REGION(p, n) ASAN_POISON_MEMORY_REGION(p, n) -#define PROTOBUF_UNPOISON_MEMORY_REGION(p, n) ASAN_UNPOISON_MEMORY_REGION(p, n) -#else // PROTOBUF_ASAN -#define PROTOBUF_POISON_MEMORY_REGION(p, n) -#define PROTOBUF_UNPOISON_MEMORY_REGION(p, n) -#endif // PROTOBUF_ASAN - -#ifdef PROTOBUF_TSAN -#define PROTOBUF_TSAN_DECLARE_MEMBER ::uint32_t _tsan_detect_race = 0; +// Variable used to inject artificial language races to detect API level races. +#if defined(ABSL_HAVE_THREAD_SANITIZER) +#define PROTOBUF_TSAN_DECLARE_MEMBER char _tsan_detect_race = 0; #else #define PROTOBUF_TSAN_DECLARE_MEMBER #endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 4a2481a6aa4b..f2f112222d20 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -14,8 +14,6 @@ #endif #undef PROTOBUF_PORT_ -#undef PROTOBUF_POISON_MEMORY_REGION -#undef PROTOBUF_UNPOISON_MEMORY_REGION #undef PROTOBUF_BUILTIN_ATOMIC #undef PROTOBUF_GNUC_MIN #undef PROTOBUF_CLANG_MIN @@ -52,9 +50,6 @@ #undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 #undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 #undef PROTOBUF_PRAGMA_INIT_SEG -#undef PROTOBUF_ASAN -#undef PROTOBUF_MSAN -#undef PROTOBUF_TSAN #undef PROTOBUF_TSAN_DECLARE_MEMBER #undef PROTOBUF_BUILTIN_CONSTANT_P #undef PROTOBUF_CUSTOM_VTABLE diff --git a/src/google/protobuf/proto3_arena_unittest.cc b/src/google/protobuf/proto3_arena_unittest.cc index c27e7cda8563..5cfba9f1abbc 100644 --- a/src/google/protobuf/proto3_arena_unittest.cc +++ b/src/google/protobuf/proto3_arena_unittest.cc @@ -287,13 +287,13 @@ TEST(Proto3ArenaTest, CheckOneofMessageFieldIsCleared) { child->set_bb(100); msg->Clear(); -#ifndef PROTOBUF_ASAN - EXPECT_EQ(child->bb(), 0); -#else + if (internal::HasMemoryPoisoning()) { #if GTEST_HAS_DEATH_TEST - EXPECT_DEATH(EXPECT_EQ(child->bb(), 100), "use-after-poison"); + EXPECT_DEATH(EXPECT_EQ(child->bb(), 100), "use-after-poison"); #endif // !GTEST_HAS_DEATH_TEST -#endif // !PROTOBUF_ASAN + } else { + EXPECT_EQ(child->bb(), 0); + } } TEST(Proto3OptionalTest, OptionalFieldDescriptor) { diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index aafc6cb91d83..0c886fe0dd5a 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -560,8 +560,8 @@ class RepeatedField final // We need to manually unpoison the SOO buffer because in reflection for // split repeated fields, we poison the whole SOO buffer even when we // don't actually use the whole SOO buffer (e.g. for RepeatedField). - PROTOBUF_UNPOISON_MEMORY_REGION(soo_rep_.short_rep.data, - sizeof(soo_rep_.short_rep.data)); + internal::UnpoisonMemoryRegion(soo_rep_.short_rep.data, + sizeof(soo_rep_.short_rep.data)); } } diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index c1b3eff93c14..2b5448ff1359 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -30,6 +30,7 @@ #include #include +#include "absl/base/config.h" #include "absl/numeric/bits.h" #include "absl/strings/cord.h" #include "absl/types/span.h" @@ -38,6 +39,7 @@ #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/parse_context.h" +#include "google/protobuf/port.h" // TODO: Remove. #include "google/protobuf/repeated_ptr_field.h" #include "google/protobuf/unittest.pb.h" @@ -474,9 +476,9 @@ TEST(RepeatedField, ReserveLarge) { } TEST(RepeatedField, ReserveHuge) { -#if defined(PROTOBUF_ASAN) || defined(PROTOBUF_MSAN) - GTEST_SKIP() << "Disabled because sanitizer is active"; -#endif + if (internal::HasAnySanitizer()) { + GTEST_SKIP() << "Disabled because sanitizer is active"; + } // Largest value that does not clamp to the large limit: constexpr int non_clamping_limit = (std::numeric_limits::max() - sizeof(Arena*)) / 2; @@ -1134,17 +1136,17 @@ TEST(RepeatedField, HardenAgainstBadTruncate) { } } -#if defined(GTEST_HAS_DEATH_TEST) && \ - (defined(PROTOBUF_ASAN) || defined(PROTOBUF_MSAN)) +#if defined(GTEST_HAS_DEATH_TEST) && (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ + defined(ABSL_HAVE_MEMORY_SANITIZER)) // This function verifies that the code dies under ASAN or MSAN trying to both // read and write the reserved element directly beyond the last element. void VerifyDeathOnWriteAndReadAccessBeyondEnd(RepeatedField& field) { auto* end = field.Mutable(field.size() - 1) + 1; -#if defined(PROTOBUF_ASAN) +#if defined(ABSL_HAVE_ADDRESS_SANITIZER) EXPECT_DEATH(*end = 1, "container-overflow"); EXPECT_DEATH(EXPECT_NE(*end, 1), "container-overflow"); -#elif defined(PROTOBUF_MSAN) +#elif defined(ABSL_HAVE_MEMORY_SANITIZER) EXPECT_DEATH(EXPECT_NE(*end, 1), "use-of-uninitialized-value"); #endif diff --git a/src/google/protobuf/repeated_ptr_field_unittest.cc b/src/google/protobuf/repeated_ptr_field_unittest.cc index 6b439e3646f8..0957651a9368 100644 --- a/src/google/protobuf/repeated_ptr_field_unittest.cc +++ b/src/google/protobuf/repeated_ptr_field_unittest.cc @@ -22,6 +22,7 @@ #include #include +#include "absl/base/config.h" #include "absl/log/absl_check.h" #include "absl/numeric/bits.h" #include "absl/strings/str_cat.h" diff --git a/src/google/protobuf/serial_arena.h b/src/google/protobuf/serial_arena.h index 19e0cd73dfa1..acd1b159d3ec 100644 --- a/src/google/protobuf/serial_arena.h +++ b/src/google/protobuf/serial_arena.h @@ -100,7 +100,7 @@ class PROTOBUF_EXPORT SerialArena { if (cached_head == nullptr) return nullptr; void* ret = cached_head; - PROTOBUF_UNPOISON_MEMORY_REGION(ret, size); + internal::UnpoisonMemoryRegion(ret, size); cached_head = cached_head->next; return ret; } @@ -174,7 +174,7 @@ class PROTOBUF_EXPORT SerialArena { // We need to unpoison this memory before filling it in case it has been // poisoned by another sanitizer client. - PROTOBUF_UNPOISON_MEMORY_REGION( + internal::UnpoisonMemoryRegion( new_list + cached_block_length_, (new_size - cached_block_length_) * sizeof(CachedBlock*)); @@ -193,7 +193,7 @@ class PROTOBUF_EXPORT SerialArena { auto* new_node = static_cast(p); new_node->next = cached_head; cached_head = new_node; - PROTOBUF_POISON_MEMORY_REGION(p, size); + internal::PoisonMemoryRegion(p, size); } public: @@ -209,7 +209,7 @@ class PROTOBUF_EXPORT SerialArena { reinterpret_cast(limit_))) { return false; } - PROTOBUF_UNPOISON_MEMORY_REGION(ret, n); + internal::UnpoisonMemoryRegion(ret, n); *out = ret; char* next = ret + n; set_ptr(next); @@ -235,7 +235,7 @@ class PROTOBUF_EXPORT SerialArena { reinterpret_cast(limit_))) { return AllocateAlignedWithCleanupFallback(n, align, destructor); } - PROTOBUF_UNPOISON_MEMORY_REGION(ret, n); + internal::UnpoisonMemoryRegion(ret, n); char* next = ret + n; set_ptr(next); AddCleanup(ret, destructor);