Skip to content

Commit ec5fa71

Browse files
tasakcopybara-github
authored andcommitted
[PA] Propose "ExternalMetadata" synthetic finch trials if enabled
If `enable_move_metadata_outside_gigacage_trial`(gn var) is true, propose synthetic finch trials: 10% enabled and 10% disabled(control). Design Doc: https://docs.google.com/document/d/1Mn-qRAWuDhS_gRL_OG2TYL-EW5D8yljaCyM40S0ocVc/edit?tab=t.0 Bug: crbug.com/435341877 Change-Id: Ib0987efc576d4ba797bed119e18dd595e4d807f7 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6795727 Reviewed-by: Yuki Shiino <[email protected]> Commit-Queue: Takashi Sakamoto <[email protected]> Cr-Commit-Position: refs/heads/main@{#1495230} NOKEYCHECK=True GitOrigin-RevId: a322032394786af17da7fac775932f9050440707
1 parent f5c8626 commit ec5fa71

File tree

6 files changed

+173
-13
lines changed

6 files changed

+173
-13
lines changed

partition_alloc.gni

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,16 @@ declare_args() {
343343
move_metadata_outside_gigacage = false && has_64_bit_pointers && !is_ios
344344
}
345345

346+
declare_args() {
347+
enable_move_metadata_outside_gigacage_trial =
348+
false && move_metadata_outside_gigacage
349+
}
350+
351+
assert(!enable_move_metadata_outside_gigacage_trial ||
352+
move_metadata_outside_gigacage,
353+
"Can't enable PartitionAllocExternalMetadata synthetic trial " +
354+
"without move_metadata_outside_gigacage=true.")
355+
346356
declare_args() {
347357
# Use full MTE protection available by changing the feature flag default
348358
# values. So sync mode on all processes. Also disables permissive MTE.

src/partition_alloc/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ pa_buildflag_header("buildflags") {
156156
"ENABLE_POINTER_COMPRESSION=$enable_pointer_compression",
157157
"ENABLE_POINTER_SUBTRACTION_CHECK=$enable_pointer_subtraction_check",
158158
"MOVE_METADATA_OUT_OF_GIGACAGE_FOR_64_BITS_POINTERS=$move_metadata_outside_gigacage",
159+
"ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL=$enable_move_metadata_outside_gigacage_trial",
159160
"ENABLE_THREAD_ISOLATION=$enable_pkeys",
160161
"EXPENSIVE_DCHECKS_ARE_ON=$enable_expensive_dchecks",
161162
"FORCE_DISABLE_BACKUP_REF_PTR_FEATURE=$force_disable_backup_ref_ptr_feature",
@@ -400,6 +401,8 @@ if (is_clang_or_gcc) {
400401
"address_space_stats.h",
401402
"allocation_guard.cc",
402403
"allocation_guard.h",
404+
"allocator_config.cc",
405+
"allocator_config.h",
403406
"bucket_lookup.h",
404407
"compressed_pointer.cc",
405408
"compressed_pointer.h",
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2025 The Chromium Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "partition_alloc/allocator_config.h"
6+
7+
#include <limits>
8+
9+
#include "partition_alloc/random.h"
10+
11+
namespace partition_alloc {
12+
13+
#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) && \
14+
PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
15+
namespace {
16+
17+
enum ExternalMetadataTrialGroupPercentage {
18+
kEnabled = 10, // 10%
19+
kDisabled = 10, // 10%
20+
};
21+
22+
ExternalMetadataTrialGroup s_externalMetadataJoinedGroup =
23+
ExternalMetadataTrialGroup::kUndefined;
24+
25+
void SetExternalMetadataTrialGroup(ExternalMetadataTrialGroup group) {
26+
s_externalMetadataJoinedGroup = group;
27+
}
28+
29+
} // namespace
30+
31+
namespace internal {
32+
33+
ExternalMetadataTrialGroup SelectExternalMetadataTrialGroup() {
34+
uint32_t random = internal::RandomValue() /
35+
static_cast<double>(std::numeric_limits<uint32_t>::max()) *
36+
100.0;
37+
38+
ExternalMetadataTrialGroup group;
39+
if (random < ExternalMetadataTrialGroupPercentage::kEnabled) {
40+
group = ExternalMetadataTrialGroup::kEnabled;
41+
} else if (random < ExternalMetadataTrialGroupPercentage::kEnabled +
42+
ExternalMetadataTrialGroupPercentage::kDisabled) {
43+
group = ExternalMetadataTrialGroup::kDisabled;
44+
} else {
45+
group = ExternalMetadataTrialGroup::kDefault;
46+
}
47+
SetExternalMetadataTrialGroup(group);
48+
return group;
49+
}
50+
51+
} // namespace internal
52+
53+
ExternalMetadataTrialGroup GetExternalMetadataTrialGroup() {
54+
return s_externalMetadataJoinedGroup;
55+
}
56+
57+
#endif // PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) &&
58+
// PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
59+
60+
} // namespace partition_alloc
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2025 The Chromium Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef PARTITION_ALLOC_ALLOCATOR_CONFIG_H_
6+
#define PARTITION_ALLOC_ALLOCATOR_CONFIG_H_
7+
8+
#include "partition_alloc/buildflags.h"
9+
#include "partition_alloc/partition_alloc_base/compiler_specific.h"
10+
#include "partition_alloc/partition_alloc_base/component_export.h"
11+
#include "partition_alloc/partition_alloc_config.h"
12+
13+
namespace partition_alloc {
14+
15+
// partition_alloc_support.cc will see the configuration and invoke
16+
// RegisterSyntheticTrialGroup().
17+
#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) && \
18+
PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
19+
20+
inline constexpr const char kExternalMetadataTrialName[] =
21+
"PartitionAllocExternalMetadata";
22+
inline constexpr const char kExternalMetadataTrialGroup_Enabled[] = "Enabled";
23+
inline constexpr const char kExternalMetadataTrialGroup_Disabled[] = "Disabled";
24+
25+
// For synthetic field trial: PartitionAllocExternalMetadata
26+
enum ExternalMetadataTrialGroup {
27+
kUndefined = 0,
28+
kDefault,
29+
kDisabled,
30+
kEnabled,
31+
};
32+
33+
PA_COMPONENT_EXPORT(PARTITION_ALLOC)
34+
ExternalMetadataTrialGroup GetExternalMetadataTrialGroup();
35+
36+
namespace internal {
37+
38+
ExternalMetadataTrialGroup SelectExternalMetadataTrialGroup();
39+
40+
} // namespace internal
41+
42+
#endif // PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) &&
43+
// PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
44+
45+
} // namespace partition_alloc
46+
47+
#endif // PARTITION_ALLOC_ALLOCATOR_CONFIG_H_

src/partition_alloc/hardening_unittest.cc

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <string>
77
#include <vector>
88

9+
#include "partition_alloc/allocator_config.h"
910
#include "partition_alloc/build_config.h"
1011
#include "partition_alloc/partition_alloc_config.h"
1112
#include "partition_alloc/partition_alloc_for_testing.h"
@@ -81,17 +82,29 @@ TEST(HardeningTest, MetadataPointerCrashing) {
8182
uintptr_t slot_start = root.ObjectToSlotStart(data);
8283
auto* metadata = SlotSpanMetadata::FromSlotStart(slot_start, &root);
8384

84-
#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
85-
// Crashes, because `metadata` points outside of giga cage.
86-
// `GetPoolInfo()` will hit NOTREACHED().
85+
#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) && \
86+
!PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
8787
EXPECT_DEATH(FreelistEntry::EmplaceAndInitForTest(slot_start, metadata, true),
8888
"");
89-
#else
90-
FreelistEntry::EmplaceAndInitForTest(slot_start, metadata, true);
89+
#endif
9190

92-
// Crashes, because |metadata| points inside the metadata area.
93-
EXPECT_DEATH(root.Alloc(kAllocSize), "");
91+
#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) && \
92+
PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
93+
if (ExternalMetadataTrialGroup::kEnabled == GetExternalMetadataTrialGroup()) {
94+
EXPECT_DEATH(
95+
FreelistEntry::EmplaceAndInitForTest(slot_start, metadata, true), "");
96+
} else
9497
#endif
98+
#if !PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) || \
99+
PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
100+
{
101+
FreelistEntry::EmplaceAndInitForTest(slot_start, metadata, true);
102+
103+
// Crashes, because |metadata| points inside the metadata area.
104+
EXPECT_DEATH(root.Alloc(kAllocSize), "");
105+
}
106+
#endif // !PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) ||
107+
// PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
95108
}
96109
#endif // PA_USE_DEATH_TESTS() && PA_CONFIG(HAS_FREELIST_SHADOW_ENTRY)
97110

@@ -169,15 +182,28 @@ TEST(HardeningTest, PoolOffsetMetadataPointerCrashing) {
169182
uintptr_t slot_start = root.ObjectToSlotStart(data);
170183
auto* metadata = SlotSpanMetadata::FromSlotStart(slot_start, &root);
171184

172-
#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
185+
#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) && \
186+
!PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
173187
EXPECT_DEATH(FreelistEntry::EmplaceAndInitForTest(slot_start, metadata, true),
174188
"");
175-
#else
176-
FreelistEntry::EmplaceAndInitForTest(slot_start, metadata, true);
177-
178-
// Crashes, because |metadata| points inside the metadata area.
179-
EXPECT_DEATH(root.Alloc(kAllocSize), "");
180189
#endif
190+
#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) && \
191+
PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
192+
if (ExternalMetadataTrialGroup::kEnabled == GetExternalMetadataTrialGroup()) {
193+
EXPECT_DEATH(
194+
FreelistEntry::EmplaceAndInitForTest(slot_start, metadata, true), "");
195+
} else
196+
#endif
197+
#if !PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) || \
198+
PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
199+
{
200+
FreelistEntry::EmplaceAndInitForTest(slot_start, metadata, true);
201+
202+
// Crashes, because |metadata| points inside the metadata area.
203+
EXPECT_DEATH(root.Alloc(kAllocSize), "");
204+
}
205+
#endif // !PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE) ||
206+
// PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
181207
}
182208
#endif // PA_USE_DEATH_TESTS() && PA_CONFIG(HAS_FREELIST_SHADOW_ENTRY)
183209

src/partition_alloc/partition_address_space.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <string>
1313

1414
#include "partition_alloc/address_pool_manager.h"
15+
#include "partition_alloc/allocator_config.h"
1516
#include "partition_alloc/build_config.h"
1617
#include "partition_alloc/buildflags.h"
1718
#include "partition_alloc/compressed_pointer.h"
@@ -400,6 +401,19 @@ void PartitionAddressSpace::InitMetadataRegionAndOffsets() {
400401
return;
401402
}
402403

404+
#if PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
405+
if (ExternalMetadataTrialGroup::kUndefined ==
406+
GetExternalMetadataTrialGroup()) {
407+
if (SelectExternalMetadataTrialGroup() !=
408+
ExternalMetadataTrialGroup::kEnabled) {
409+
for (size_t i = 0; i < kMaxPoolHandle; ++i) {
410+
offsets_to_metadata_[i] = SystemPageSize();
411+
}
412+
return;
413+
}
414+
}
415+
#endif // PA_BUILDFLAG(ENABLE_MOVE_METADATA_OUT_OF_GIGACAGE_TRIAL)
416+
403417
#if PA_CONFIG(DYNAMICALLY_SELECT_POOL_SIZE)
404418
metadata_region_size_ = std::max(kConfigurablePoolMaxSize, CorePoolSize());
405419
#endif // PA_CONFIG(DYNAMICALLY_SELECT_POOL_SIZE)

0 commit comments

Comments
 (0)