From: uazo 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 | 32 +++++++++++++++++++ .../chrome/browser/util/PlatformUtil.java | 10 ++++++ components/gwp_asan/client/gwp_asan.cc | 10 +++--- components/memory_system/memory_system.cc | 1 + 10 files changed, 76 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 @@ -391,7 +391,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 @@ -191,10 +191,11 @@ if (is_chromeos) { 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 @@ -169,6 +169,7 @@ by a child template that "extends" this file. + { + 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; + }); } } 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 @@ -1982,7 +1982,7 @@ void ChromeMainDelegate::InitializeMemorySystem() { const version_info::Channel channel = chrome::GetChannel(); const bool is_canary_dev = (channel == version_info::Channel::CANARY || channel == version_info::Channel::DEV); - 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; memory_system::Initializer() .SetGwpAsanParameters(gwp_asan_boost_sampling, process_type) 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 @@ -62,3 +62,35 @@ 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 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 obj; + obj.Reset(env, return_string); + return ScopedJavaLocalRef(obj); +} 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 @@ -10,6 +10,7 @@ import android.content.Intent; import android.net.Uri; import org.jni_zero.CalledByNative; +import org.jni_zero.NativeMethods; import org.chromium.base.ContextUtils; import org.chromium.base.Log; @@ -30,4 +31,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 @@ -77,21 +77,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; @@ -458,7 +458,7 @@ void EnableForMalloc(bool boost_sampling, const char* 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 // BUILDFLAG(USE_ALLOCATOR_SHIM) } @@ -478,7 +478,7 @@ void EnableForPartitionAlloc(bool boost_sampling, const char* process_type) { 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 // 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 @@ -196,6 +196,7 @@ void MemorySystem::Impl::Initialize( if (gwp_asan_parameters) { InitializeGwpASan(*gwp_asan_parameters, initialization_data); + LOG(INFO) << "MemorySystem: Gwp Asan Initialized."; } if (profiling_client_parameters) { --