266 lines
12 KiB
Diff
266 lines
12 KiB
Diff
From: uazo <uazo@users.noreply.github.com>
|
|
Date: Fri, 12 Jan 2024 15:04:40 +0000
|
|
Subject: Enable gwp asan on Android
|
|
|
|
the patch enables gwp asan in android and changes the activation
|
|
conditions to 50% for all build configs.
|
|
in android there is a test function accessible in the developer settings.
|
|
---
|
|
android_webview/lib/aw_main_delegate.cc | 2 +-
|
|
build/config/compiler/compiler.gni | 3 +-
|
|
chrome/android/java/AndroidManifest.xml | 1 +
|
|
.../java/res/xml/developer_preferences.xml | 3 ++
|
|
.../tracing/settings/DeveloperSettings.java | 20 +++++++++++
|
|
chrome/app/chrome_main_delegate.cc | 2 +-
|
|
chrome/browser/platform_util_android.cc | 33 +++++++++++++++++++
|
|
.../chrome/browser/util/PlatformUtil.java | 10 ++++++
|
|
components/gwp_asan/client/gwp_asan.cc | 10 +++---
|
|
components/memory_system/memory_system.cc | 1 +
|
|
10 files changed, 77 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc
|
|
--- a/android_webview/lib/aw_main_delegate.cc
|
|
+++ b/android_webview/lib/aw_main_delegate.cc
|
|
@@ -387,7 +387,7 @@ void AwMainDelegate::InitializeMemorySystem(const bool is_browser_process) {
|
|
const std::string process_type =
|
|
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
|
|
switches::kProcessType);
|
|
- const bool gwp_asan_boost_sampling = is_canary_dev || is_browser_process;
|
|
+ const bool gwp_asan_boost_sampling = ((true)) || is_canary_dev || is_browser_process;
|
|
|
|
// Add PoissonAllocationSampler. On Android WebView we do not have obvious
|
|
// observers of PoissonAllocationSampler. Unfortunately, some potential
|
|
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
|
|
--- a/build/config/compiler/compiler.gni
|
|
+++ b/build/config/compiler/compiler.gni
|
|
@@ -268,10 +268,11 @@ if (is_chromeos || (enable_cast_receiver && is_linux)) {
|
|
enable_frame_pointers = true
|
|
}
|
|
} else if (is_android) {
|
|
- enable_frame_pointers =
|
|
+ enable_frame_pointers = true ||
|
|
enable_profiling ||
|
|
# Ensure that stacks from arm64 crash dumps are usable (crbug.com/391706).
|
|
current_cpu == "arm64" ||
|
|
+ current_cpu == "x86" ||
|
|
# For x86 Android, unwind tables are huge without frame pointers
|
|
# (crbug.com/762629). Enabling frame pointers grows the code size slightly
|
|
# but overall shrinks binaries considerably by avoiding huge unwind
|
|
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
|
|
--- a/chrome/android/java/AndroidManifest.xml
|
|
+++ b/chrome/android/java/AndroidManifest.xml
|
|
@@ -196,6 +196,7 @@ by a child template that "extends" this file.
|
|
<!-- Set android:largeHeap to "true" to allow more than the default
|
|
Java heap limit (32Mb on Nexus S, 48Mb on Xoom). -->
|
|
<application android:name="{% block application_name %}org.chromium.chrome.browser.base.SplitChromeApplication{% endblock %}"
|
|
+ android:gwpAsanMode="always"
|
|
android:icon="@drawable/ic_launcher"
|
|
android:roundIcon="@drawable/ic_launcher_round"
|
|
android:label="Cromite"
|
|
diff --git a/chrome/android/java/res/xml/developer_preferences.xml b/chrome/android/java/res/xml/developer_preferences.xml
|
|
--- a/chrome/android/java/res/xml/developer_preferences.xml
|
|
+++ b/chrome/android/java/res/xml/developer_preferences.xml
|
|
@@ -12,6 +12,9 @@ found in the LICENSE file.
|
|
android:fragment="org.chromium.chrome.browser.tracing.settings.TracingSettings"
|
|
android:key="tracing"
|
|
android:title="Tracing" />
|
|
+ <Preference
|
|
+ android:key="test_gwp_asan"
|
|
+ android:title="Test Gwp Asan"/>
|
|
<org.chromium.components.browser_ui.settings.TextMessagePreference
|
|
android:layout_width="match_parent"
|
|
android:layout_height="wrap_content"
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java
|
|
@@ -6,7 +6,9 @@ package org.chromium.chrome.browser.tracing.settings;
|
|
|
|
import android.content.Context;
|
|
import android.os.Bundle;
|
|
+import android.widget.Toast;
|
|
|
|
+import androidx.preference.Preference;
|
|
import org.chromium.base.ResettersForTesting;
|
|
import org.chromium.base.supplier.MonotonicObservableSupplier;
|
|
import org.chromium.base.supplier.NonNullObservableSupplier;
|
|
@@ -24,11 +26,13 @@ import org.chromium.chrome.browser.settings.search.ChromeBaseSearchIndexProvider
|
|
import org.chromium.components.browser_ui.settings.EmbeddableSettingsPage;
|
|
import org.chromium.components.browser_ui.settings.SettingsUtils;
|
|
import org.chromium.components.browser_ui.settings.search.SettingsIndexData;
|
|
+import org.chromium.chrome.browser.util.PlatformUtil;
|
|
|
|
/** Settings fragment containing preferences aimed at Chrome and web developers. */
|
|
@NullMarked
|
|
public class DeveloperSettings extends ChromeBaseSettingsFragment implements EmbeddableSettingsPage {
|
|
private static final String UI_PREF_BETA_STABLE_HINT = "beta_stable_hint";
|
|
+ private static final String TEST_GWP_ASAN_KEY = "test_gwp_asan";
|
|
|
|
// Non-translated strings:
|
|
private static final String MSG_DEVELOPER_OPTIONS_TITLE = "Developer options";
|
|
@@ -64,6 +68,22 @@ public class DeveloperSettings extends ChromeBaseSettingsFragment implements Emb
|
|
if (shouldRemoveBetaStableHint()) {
|
|
getPreferenceScreen().removePreference(findPreference(UI_PREF_BETA_STABLE_HINT));
|
|
}
|
|
+
|
|
+ Preference mStartUpdate = findPreference(TEST_GWP_ASAN_KEY);
|
|
+ mStartUpdate.setOnPreferenceClickListener(preference -> {
|
|
+ Toast toast = Toast.makeText(getContext(),
|
|
+ "Test Gwp Asan in progress. Browser should crash.", Toast.LENGTH_LONG);
|
|
+ toast.show();
|
|
+
|
|
+ PlatformUtil.launchTestGwpAsan();
|
|
+
|
|
+ toast = Toast.makeText(getContext(),
|
|
+ "Test Gwp Asan done. Try again, it didn't work.", Toast.LENGTH_LONG);
|
|
+ toast.show();
|
|
+
|
|
+ // handle the click so the default action isn't triggered.
|
|
+ return true;
|
|
+ });
|
|
}
|
|
|
|
private static boolean shouldRemoveBetaStableHint() {
|
|
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
|
|
--- a/chrome/app/chrome_main_delegate.cc
|
|
+++ b/chrome/app/chrome_main_delegate.cc
|
|
@@ -1713,7 +1713,7 @@ void ChromeMainDelegate::InitializeMemorySystem() {
|
|
const std::string process_type =
|
|
command_line->GetSwitchValueASCII(switches::kProcessType);
|
|
const bool is_browser_process = process_type.empty();
|
|
- const bool gwp_asan_boost_sampling = is_browser_process || IsCanaryDev();
|
|
+ const bool gwp_asan_boost_sampling = ((true)) || is_browser_process || IsCanaryDev();
|
|
const memory_system::DispatcherParameters::AllocationTraceRecorderInclusion
|
|
allocation_recorder_inclusion =
|
|
is_browser_process ? memory_system::DispatcherParameters::
|
|
diff --git a/chrome/browser/platform_util_android.cc b/chrome/browser/platform_util_android.cc
|
|
--- a/chrome/browser/platform_util_android.cc
|
|
+++ b/chrome/browser/platform_util_android.cc
|
|
@@ -10,6 +10,7 @@
|
|
#include "base/android/jni_string.h"
|
|
#include "base/files/file_path.h"
|
|
#include "base/files/file_util.h"
|
|
+#include "base/logging.h"
|
|
#include "base/notimplemented.h"
|
|
#include "chrome/browser/platform_util_internal.h"
|
|
#include "ui/android/view_android.h"
|
|
@@ -85,4 +86,36 @@ bool IsVisible(gfx::NativeView view) {
|
|
|
|
} // namespace platform_util
|
|
|
|
+namespace {
|
|
+
|
|
+jstring native_get_string(JNIEnv* env) {
|
|
+#pragma GCC diagnostic ignored "-Wdangling-gsl"
|
|
+ std::string s = "Hellooooooooooooooo ";
|
|
+ std::string_view sv = s + "World\n";
|
|
+
|
|
+ // BUG: Use-after-free. `sv` holds a dangling reference to the ephemeral
|
|
+ // string created by `s + "World\n"`. Accessing the data here is a
|
|
+ // use-after-free.
|
|
+ return env->NewStringUTF(sv.data());
|
|
+}
|
|
+
|
|
+}
|
|
+
|
|
+static base::android::ScopedJavaLocalRef<jstring> JNI_PlatformUtil_TestGwpAsan(JNIEnv* env) {
|
|
+ // Repeat the buggy code a few thousand times. GWP-ASan has a small chance
|
|
+ // of detecting the use-after-free every time it happens. A single user who
|
|
+ // triggers the use-after-free thousands of times will catch the bug once.
|
|
+ // Alternatively, if a few thousand users each trigger the bug a single time,
|
|
+ // you'll also get one report (this is the assumed model).
|
|
+ jstring return_string;
|
|
+ for (unsigned i = 0; i < 0x10000; ++i) {
|
|
+ return_string = native_get_string(env);
|
|
+ LOG(INFO) << "Testing GwpAsan " << return_string;
|
|
+ }
|
|
+
|
|
+ base::android::ScopedJavaGlobalRef<jstring> obj;
|
|
+ obj.Reset(env, jni_zero::JavaRef<jstring>::CreateLeaky(env, return_string));
|
|
+ return ScopedJavaLocalRef<jstring>(obj);
|
|
+}
|
|
+
|
|
DEFINE_JNI(PlatformUtil)
|
|
diff --git a/chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/PlatformUtil.java b/chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/PlatformUtil.java
|
|
--- a/chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/PlatformUtil.java
|
|
+++ b/chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/PlatformUtil.java
|
|
@@ -11,6 +11,7 @@ import android.net.Uri;
|
|
|
|
import org.jni_zero.CalledByNative;
|
|
import org.jni_zero.JniType;
|
|
+import org.jni_zero.NativeMethods;
|
|
|
|
import org.chromium.base.ContextUtils;
|
|
import org.chromium.base.Log;
|
|
@@ -47,4 +48,13 @@ public class PlatformUtil {
|
|
Log.e(TAG, "cannot find activity to launch %s", url, e);
|
|
}
|
|
}
|
|
+
|
|
+ public static String launchTestGwpAsan() {
|
|
+ return PlatformUtilJni.get().testGwpAsan();
|
|
+ }
|
|
+
|
|
+ @NativeMethods
|
|
+ interface Natives {
|
|
+ String testGwpAsan();
|
|
+ }
|
|
}
|
|
diff --git a/components/gwp_asan/client/gwp_asan.cc b/components/gwp_asan/client/gwp_asan.cc
|
|
--- a/components/gwp_asan/client/gwp_asan.cc
|
|
+++ b/components/gwp_asan/client/gwp_asan.cc
|
|
@@ -87,21 +87,21 @@ constexpr int kDefaultMaxMetadata = 210;
|
|
constexpr int kDefaultTotalPages = kCpuIs64Bit ? 2048 : kDefaultMaxMetadata * 2;
|
|
constexpr int kDefaultAllocationSamplingMultiplier = 1500;
|
|
constexpr int kDefaultAllocationSamplingRange = 16;
|
|
-constexpr double kDefaultProcessSamplingProbability = 0.01;
|
|
+constexpr double kDefaultProcessSamplingProbability = 0.5;
|
|
#elif BUILDFLAG(IS_ANDROID)
|
|
constexpr int kDefaultMaxAllocations = 70;
|
|
constexpr int kDefaultMaxMetadata = 255;
|
|
constexpr int kDefaultTotalPages = 512;
|
|
constexpr int kDefaultAllocationSamplingMultiplier = 2000;
|
|
constexpr int kDefaultAllocationSamplingRange = 20;
|
|
-constexpr double kDefaultProcessSamplingProbability = 0.015;
|
|
+constexpr double kDefaultProcessSamplingProbability = 0.5;
|
|
#else
|
|
constexpr int kDefaultMaxAllocations = 70;
|
|
constexpr int kDefaultMaxMetadata = 255;
|
|
constexpr int kDefaultTotalPages = kCpuIs64Bit ? 2048 : kDefaultMaxMetadata * 2;
|
|
constexpr int kDefaultAllocationSamplingMultiplier = 1000;
|
|
constexpr int kDefaultAllocationSamplingRange = 16;
|
|
-constexpr double kDefaultProcessSamplingProbability = 0.015;
|
|
+constexpr double kDefaultProcessSamplingProbability = 0.5;
|
|
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
|
|
// BUILDFLAG(IS_FUCHSIA)
|
|
constexpr int kDefaultProcessSamplingBoost2 = 10;
|
|
@@ -534,7 +534,7 @@ void EnableForMalloc(bool boost_sampling, std::string_view process_type) {
|
|
std::ignore = init_once;
|
|
#else
|
|
std::ignore = internal::kGwpAsanMalloc;
|
|
- DLOG(WARNING) << "base::allocator shims are unavailable for GWP-ASan.";
|
|
+ LOG(WARNING) << "MemorySystem: base::allocator shims are unavailable for GWP-ASan.";
|
|
#endif // PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
|
|
}
|
|
|
|
@@ -558,7 +558,7 @@ void EnableForPartitionAlloc(bool boost_sampling,
|
|
std::ignore = init_once;
|
|
#else
|
|
std::ignore = internal::kGwpAsanPartitionAlloc;
|
|
- DLOG(WARNING) << "PartitionAlloc hooks are unavailable for GWP-ASan.";
|
|
+ LOG(WARNING) << "MemorySystem: PartitionAlloc hooks are unavailable for GWP-ASan.";
|
|
#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC)
|
|
}
|
|
|
|
diff --git a/components/memory_system/memory_system.cc b/components/memory_system/memory_system.cc
|
|
--- a/components/memory_system/memory_system.cc
|
|
+++ b/components/memory_system/memory_system.cc
|
|
@@ -197,6 +197,7 @@ void MemorySystem::Impl::Initialize(
|
|
|
|
if (gwp_asan_parameters) {
|
|
InitializeGwpASan(*gwp_asan_parameters, initialization_data);
|
|
+ DLOG(INFO) << "MemorySystem: Gwp Asan Initialized.";
|
|
}
|
|
|
|
if (profiling_client_parameters) {
|
|
--
|