Set memory of flag values read-only on initialization

When freezing flags, not only remember this in a global variable, but
also actually memory-protect the memory that holds the flag values.

R=cbruni@chromium.org
CC=​sroettger@chromium.org

Bug: v8:12887
Cq-Include-Trybots: luci.v8.try:v8_linux_blink_rel
Change-Id: I2ae638790d1f08f4bcc1b7e6cb5970e4e7463aad
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3811286
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82478}
This commit is contained in:
Clemens Backes 2022-08-10 16:04:29 +02:00 committed by V8 LUCI CQ
parent 8f207e3073
commit 0a6d955e85
2 changed files with 27 additions and 0 deletions

View File

@ -770,6 +770,7 @@ int FlagList::SetFlagsFromString(const char* str, size_t len) {
// static
void FlagList::FreezeFlags() {
flags_frozen.store(true, std::memory_order_relaxed);
base::OS::SetDataReadOnly(&v8_flags, sizeof(v8_flags));
}
// static

View File

@ -194,5 +194,31 @@ TEST_F(FlagDefinitionsTest, FlagsJitlessImplications) {
}
}
TEST_F(FlagDefinitionsTest, FreezeFlags) {
// Before freezing, we can arbitrarily change values.
CHECK_EQ(13, FLAG_testing_int_flag); // Initial (default) value.
FLAG_testing_int_flag = 27;
CHECK_EQ(27, FLAG_testing_int_flag);
// Get a direct pointer to the flag storage.
static_assert(sizeof(FLAG_testing_int_flag) == sizeof(int));
int* direct_testing_int_ptr = reinterpret_cast<int*>(&FLAG_testing_int_flag);
CHECK_EQ(27, *direct_testing_int_ptr);
*direct_testing_int_ptr = 42;
CHECK_EQ(42, FLAG_testing_int_flag);
// Now freeze flags. Accesses via the API and via the direct pointer should
// both crash.
FlagList::FreezeFlags();
// Accessing via the API fails with a CHECK.
ASSERT_DEATH_IF_SUPPORTED(FLAG_testing_int_flag = 41,
"Check failed: !IsFrozen\\(\\)");
// Writing to the memory directly results in a segfault.
ASSERT_DEATH_IF_SUPPORTED(*direct_testing_int_ptr = 41, "");
// We can still read the old value.
CHECK_EQ(42, FLAG_testing_int_flag);
CHECK_EQ(42, *direct_testing_int_ptr);
}
} // namespace internal
} // namespace v8