Files
cromite/build/patches/Supporting-Dangling-Ptr-Detection-via-BackupRefPtr.patch

303 lines
15 KiB
Diff

From: uazo <uazo@users.noreply.github.com>
Date: Thu, 11 Dec 2025 09:53:13 +0000
Subject: Supporting Dangling Ptr Detection via BackupRefPtr
Enable Dangling Ptr Detection (DPD) via BackupRefPtr (BRP) (disabled by default)
and additional safety checks that are too expensive to have on by default.
Enable checking raw_ptr do not become dangling during their lifetime.
Write a fixed cookie pattern at the end of each allocation to ensure there is no OOB write.
Enable MTE activation in Android for enabled devices (flag disabled by default)
BRP and MTE activate additional checks related to memory usage at the expense of
performance and increased memory usage, but guarantee the user that the browser
will not suffer from development errors related to memory management.
License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
---
base/allocator/partition_alloc_features.cc | 5 +++-
base/allocator/partition_alloc_support.cc | 30 ++++++++++++++-----
.../partition_allocator/partition_alloc.gni | 6 ++--
base/observer_list_types.cc | 11 +++++++
build_overrides/partition_alloc.gni | 3 +-
.../java/res/xml/privacy_preferences.xml | 5 ++++
.../compositor/CompositorViewHolder.java | 2 +-
.../layouts/LayoutManagerChromeTablet.java | 12 ++++----
...ngling-Ptr-Detection-via-BackupRefPtr.grdp | 9 ++++++
.../Enable-Partition-Alloc-BRP-Checks.inc | 11 +++++++
.../platform/wtf/allocator/partitions.cc | 10 +------
11 files changed, 76 insertions(+), 28 deletions(-)
create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Supporting-Dangling-Ptr-Detection-via-BackupRefPtr.grdp
create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Enable-Partition-Alloc-BRP-Checks.inc
diff --git a/base/allocator/partition_alloc_features.cc b/base/allocator/partition_alloc_features.cc
--- a/base/allocator/partition_alloc_features.cc
+++ b/base/allocator/partition_alloc_features.cc
@@ -100,6 +100,7 @@ BASE_FEATURE_PARAM(int,
partition_alloc::internal::SlotSpanRingMaxSize::kMedium);
BASE_FEATURE(kPartitionAllocWithAdvancedChecks, FEATURE_DISABLED_BY_DEFAULT);
+SET_CROMITE_FEATURE_ENABLED(kPartitionAllocWithAdvancedChecks);
constexpr FeatureParam<PartitionAllocWithAdvancedChecksEnabledProcesses>::Option
kPartitionAllocWithAdvancedChecksEnabledProcessesOptions[] = {
{PartitionAllocWithAdvancedChecksEnabledProcesses::kBrowserOnly,
@@ -176,6 +177,7 @@ BASE_FEATURE(kPartitionAllocBackupRefPtr,
FEATURE_DISABLED_BY_DEFAULT
#endif
);
+SET_CROMITE_FEATURE_ENABLED(kPartitionAllocBackupRefPtr);
constexpr FeatureParam<BackupRefPtrEnabledProcesses>::Option
kBackupRefPtrEnabledProcessesOptions[] = {
@@ -190,7 +192,7 @@ BASE_FEATURE_ENUM_PARAM(BackupRefPtrEnabledProcesses,
&kPartitionAllocBackupRefPtr,
kPAFeatureEnabledProcessesStr,
// Exception for IS_DESKTOP_ANDROID approved in crbug.com/482155132.
-#if BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_DESKTOP_ANDROID)
+#if BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_DESKTOP_ANDROID_CROMITE)
BackupRefPtrEnabledProcesses::kNonRenderer,
#else
BackupRefPtrEnabledProcesses::kAllProcesses,
@@ -231,6 +233,7 @@ BASE_FEATURE(kPartitionAllocMemoryTagging,
FEATURE_DISABLED_BY_DEFAULT
#endif
);
+SET_CROMITE_FEATURE_DISABLED(kPartitionAllocMemoryTagging);
constexpr FeatureParam<MemtagMode>::Option kMemtagModeOptions[] = {
{MemtagMode::kSync, "sync"},
diff --git a/base/allocator/partition_alloc_support.cc b/base/allocator/partition_alloc_support.cc
--- a/base/allocator/partition_alloc_support.cc
+++ b/base/allocator/partition_alloc_support.cc
@@ -286,6 +286,20 @@ void StartMemoryReclaimer(scoped_refptr<SequencedTaskRunner> task_runner) {
std::map<std::string, std::string> ProposeSyntheticFinchTrials() {
std::map<std::string, std::string> trials;
+#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
+ trials.emplace("BackupRefPtrSupport", "Enabled");
+ if (base::FeatureList::IsEnabled(base::features::kPartitionAllocBackupRefPtr)) {
+ trials.emplace("BackupRefPtrFlag", "Enabled");
+ } else {
+ trials.emplace("BackupRefPtrFlag", "Disabled");
+ }
+ if (base::FeatureList::IsEnabled(base::features::kPartitionAllocWithAdvancedChecks)) {
+ trials.emplace("PAAdvancedChecks", "Enabled");
+ } else {
+ trials.emplace("PAAdvancedChecks", "Disabled");
+ }
+#endif
+
#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)
trials.emplace("DanglingPointerDetector", "Enabled");
#else
@@ -297,13 +311,18 @@ std::map<std::string, std::string> ProposeSyntheticFinchTrials() {
trials.emplace("VectorRawPtrExperiment", "Disabled");
#if PA_BUILDFLAG(HAS_MEMORY_TAGGING)
+ bool has_mte = base::CPU::GetInstanceNoAllocation().has_mte();
+ if (has_mte) {
+ trials.emplace("MteOnDevice", "Supported");
+ } else {
+ trials.emplace("MteOnDevice", "Not Supported");
+ }
if (base::FeatureList::IsEnabled(
base::features::kPartitionAllocMemoryTagging)) {
- bool has_mte = base::CPU::GetInstanceNoAllocation().has_mte();
if (has_mte) {
- trials.emplace("MemoryTaggingDogfood", "Enabled");
+ trials.emplace("MemoryTagging", "Enabled");
} else {
- trials.emplace("MemoryTaggingDogfood", "Disabled");
+ trials.emplace("MemoryTagging", "Mte unsupported on device");
}
#if BUILDFLAG(IS_ANDROID)
BootloaderOverride bootloader_override = GetBootloaderOverride();
@@ -939,10 +958,7 @@ bool PartitionAllocSupport::ShouldEnablePartitionAllocWithAdvancedChecks(
base::features::kPartitionAllocWithAdvancedChecks)) {
return false;
}
- return ShouldEnableFeatureOnProcess(
- base::features::kPartitionAllocWithAdvancedChecksEnabledProcessesParam
- .Get(),
- process_type);
+ return true;
#endif // !PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
}
diff --git a/base/allocator/partition_allocator/partition_alloc.gni b/base/allocator/partition_allocator/partition_alloc.gni
--- a/base/allocator/partition_allocator/partition_alloc.gni
+++ b/base/allocator/partition_allocator/partition_alloc.gni
@@ -221,8 +221,8 @@ declare_args() {
# This will write a fixed cookie pattern at the end of each allocation, and
# later verify the pattern remain unchanged to ensure there is no OOB write.
# It comes with performance and memory cost, hence enabled only in debug.
- use_partition_cookie =
- partition_alloc_is_debug || partition_alloc_dcheck_always_on
+ use_partition_cookie = true
+ #partition_alloc_is_debug || partition_alloc_dcheck_always_on
# This will change partition cookie size to 4B or 8B, whichever equivalent to
# size of InSlotMetadata. This option is useful for InSlotMetadata corruption
@@ -373,7 +373,7 @@ declare_args() {
# This is meant to be used primarily on bots. It is much easier to override
# the feature flags using a binary flag instead of updating multiple bots's
# scripts to pass command line arguments.
- use_full_mte = false
+ use_full_mte = true
}
# We want to provide assertions that guard against inconsistent build
diff --git a/base/observer_list_types.cc b/base/observer_list_types.cc
--- a/base/observer_list_types.cc
+++ b/base/observer_list_types.cc
@@ -3,11 +3,22 @@
// found in the LICENSE file.
#include "base/observer_list_types.h"
+#include "base/logging.h"
+#include "base/debug/stack_trace.h"
namespace base {
CheckedObserver::CheckedObserver() = default;
CheckedObserver::~CheckedObserver() = default;
+ // If weak_ptr was invalidated then this attempt to iterate over the
+ // pointer is a UAF. Tip: If it's unclear where the `delete` occurred, try
+ // adding CHECK(!IsInObserverList()) to the ~CheckedObserver() (destructor)
+ // override. However, note that this is not always a bug: a destroyed
+ // observer can exist in an ObserverList so long as nothing iterates over
+ // the ObserverList before the list itself is destroyed.
+ // if(IsInObserverList()) {
+ // LOG(INFO) << "--- ~CheckedObserver " << base::debug::StackTrace();
+ // }
bool CheckedObserver::IsInObserverList() const {
return factory_.HasWeakPtrs();
diff --git a/build_overrides/partition_alloc.gni b/build_overrides/partition_alloc.gni
--- a/build_overrides/partition_alloc.gni
+++ b/build_overrides/partition_alloc.gni
@@ -106,7 +106,7 @@ use_partition_alloc_as_malloc_default =
enable_backup_ref_ptr_support_default = use_partition_alloc_as_malloc_default
-enable_backup_ref_ptr_slow_checks_default = false
+enable_backup_ref_ptr_slow_checks_default = true
enable_dangling_raw_ptr_checks_default =
# The DanglingPointerDetector relies on BackupRefPtr:
@@ -133,6 +133,7 @@ enable_dangling_raw_ptr_checks_default =
# Only the `android-rel` CQ bot has enforced DanglingPointerDetector checks
# at the moment. The other Android bots are not ready for it yet.
!is_android
+enable_dangling_raw_ptr_checks_default = true
raw_ptr_zero_on_construct_default = true
raw_ptr_zero_on_move_default = true
diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
--- a/chrome/android/java/res/xml/privacy_preferences.xml
+++ b/chrome/android/java/res/xml/privacy_preferences.xml
@@ -98,6 +98,11 @@ found in the LICENSE file.
android:summary="@string/throttle_main_thread_to_60hz_summary"
app:featureName="throttle-main-thread-to-60hz"
app:needRestart="true" />
+ <org.chromium.components.browser_ui.settings.ChromeSwitchPreference
+ android:title="@string/dangling_pointer_detector_title"
+ android:summary="@string/dangling_pointer_detector_summary"
+ app:featureName="enable-dangling-pointer-detector"
+ app:needRestart="true" />
<PreferenceCategory
android:key="security_section"
android:title="@string/security_section_title" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -722,8 +722,8 @@ public class CompositorViewHolder extends FrameLayout
mApplicationBottomInsetSupplier.getSupplier().removeObserver(mOnViewportInsetsChanged);
}
- mCompositorView.shutDown();
if (mLayoutManager != null) mLayoutManager.destroy();
+ mCompositorView.shutDown();
if (mOnscreenContentProvider != null) mOnscreenContentProvider.destroy();
if (mContentView != null) {
mContentView.removeOnHierarchyChangeListener(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
@@ -178,18 +178,18 @@ public class LayoutManagerChromeTablet extends LayoutManagerChrome {
@Override
@SuppressWarnings("NullAway")
public void destroy() {
- super.destroy();
+ if (mTabStripLayoutHelperManager != null) {
+ removeObserver(mTabStripLayoutHelperManager.getTabSwitcherObserver());
+ mTabStripLayoutHelperManager.destroy();
+ mTabStripLayoutHelperManager = null;
+ }
if (mLayerTitleCache != null) {
mLayerTitleCache.shutDown();
mLayerTitleCache = null;
}
- if (mTabStripLayoutHelperManager != null) {
- removeObserver(mTabStripLayoutHelperManager.getTabSwitcherObserver());
- mTabStripLayoutHelperManager.destroy();
- mTabStripLayoutHelperManager = null;
- }
+ super.destroy();
}
@Override
diff --git a/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Supporting-Dangling-Ptr-Detection-via-BackupRefPtr.grdp b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Supporting-Dangling-Ptr-Detection-via-BackupRefPtr.grdp
new file mode 100644
--- /dev/null
+++ b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Supporting-Dangling-Ptr-Detection-via-BackupRefPtr.grdp
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <message name="IDS_DANGLING_POINTER_DETECTOR_TITLE" desc="Text for 'dangling pointer detector' settings option.">
+ Enable Dangling Ptr Detection (DPD) via BackupRefPtr (BRP)
+ </message>
+ <message name="IDS_DANGLING_POINTER_DETECTOR_SUMMARY" desc="Summary text for 'dangling pointer detector' settings option.">
+ Enable checking raw pointer do not become dangling during their lifetime to prevent UAF and write a fixed cookie pattern at the end of each allocation to ensure there is no OOB write.
+ </message>
+</grit-part>
diff --git a/cromite_flags/chrome/browser/about_flags_cc/Enable-Partition-Alloc-BRP-Checks.inc b/cromite_flags/chrome/browser/about_flags_cc/Enable-Partition-Alloc-BRP-Checks.inc
new file mode 100644
--- /dev/null
+++ b/cromite_flags/chrome/browser/about_flags_cc/Enable-Partition-Alloc-BRP-Checks.inc
@@ -0,0 +1,11 @@
+#ifdef FLAG_SECTION
+
+ {"enable-dangling-pointer-detector",
+ "Enable Dangling Pointer Detector",
+ "Enable Dangling Ptr Detection (DPD) via BackupRefPtr (BRP). "
+ "Enable additional safety checks that are too expensive to have on by default. "
+ "Enable checking raw_ptr do not become dangling during their lifetime. "
+ "Write a fixed cookie pattern at the end of each allocation to ensure there is no OOB write.", kOsAll,
+ FEATURE_VALUE_TYPE(base::features::kPartitionAllocBackupRefPtr)},
+
+#endif
diff --git a/third_party/blink/renderer/platform/wtf/allocator/partitions.cc b/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
--- a/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
+++ b/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
@@ -86,16 +86,8 @@ partition_alloc::PartitionOptions PartitionOptionsFromFeatures() {
using partition_alloc::PartitionOptions;
#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
- const auto brp_mode = base::features::kBackupRefPtrModeParam.Get();
- const bool process_affected_by_brp_flag =
- base::features::kBackupRefPtrEnabledProcessesParam.Get() ==
- BackupRefPtrEnabledProcesses::kAllProcesses ||
- base::features::kBackupRefPtrEnabledProcessesParam.Get() ==
- BackupRefPtrEnabledProcesses::kBrowserAndRenderer;
const bool enable_brp = base::FeatureList::IsEnabled(
- base::features::kPartitionAllocBackupRefPtr) &&
- (brp_mode == BackupRefPtrMode::kEnabled) &&
- process_affected_by_brp_flag;
+ base::features::kPartitionAllocBackupRefPtr);
#else // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
const bool enable_brp = false;
#endif
--