Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a63fa9ad authored by Mitch Phillips's avatar Mitch Phillips
Browse files

[GWP-ASan] Enable recoverable GWP-ASan for apps.

Currently, GWP-ASan is opt-in, and requires an app to set
`gwpAsanMode=always` in the manifest. If `gwpAsanMode` is unspecified,
or `gwpAsanMode=default`, then no GWP-ASan is enabled.

Let's flip that to the new recoverable mode, which catches
heap-use-after-free and heap-buffer-overflow using sampled page
allocations (as per normal GWP-ASan), but now doesn't crash the app when
it's detected.

Also, provide a kill switch that we can use if we discover problems in
the field, which can be pushed if necessary with go/android-exp.

Bug: N/A
Test: Build a device with this enabled, use some debugging apps that
trigger a use-after-free to test the mode is working as intended.

Change-Id: I03b1478c148b9f9cfaeaa16ed273f107b55f9057
parent 30eb433a
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -1923,15 +1923,16 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,


    const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
    const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
    android_mallopt_gwp_asan_options_t gwp_asan_options;
    android_mallopt_gwp_asan_options_t gwp_asan_options;
    const char* kGwpAsanAppRecoverableSysprop =
            "persist.device_config.memory_safety_native.gwp_asan_recoverable_apps";
    // The system server doesn't have its nice name set by the time SpecializeCommon is called.
    // The system server doesn't have its nice name set by the time SpecializeCommon is called.
    gwp_asan_options.program_name = nice_name_ptr ?: process_name;
    gwp_asan_options.program_name = nice_name_ptr ?: process_name;
    switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
    switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
        default:
        default:
        case RuntimeFlags::GWP_ASAN_LEVEL_DEFAULT:
        case RuntimeFlags::GWP_ASAN_LEVEL_DEFAULT:
            // TODO(b/247012630): Switch this to Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING once
            gwp_asan_options.desire = GetBoolProperty(kGwpAsanAppRecoverableSysprop, true)
            // performance and syshealth testing is completed, making the default for non-system
                    ? Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING
            // apps that don't specify a `gwpAsanMode` in their manifest to be sampled-recoverable.
                    : Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
            gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
            android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
            android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
            break;
            break;
        case RuntimeFlags::GWP_ASAN_LEVEL_NEVER:
        case RuntimeFlags::GWP_ASAN_LEVEL_NEVER: