0

Documentation says GWP-ASan is available on apps that target Android 11 (API level 30) or higher but doesn't mention any requirements on the device.

Similarly, the manifest documentation for gwpAsanMode says Added in API level 30 but doesn't mention any requirements on device.

I'm targeting API level 30 and have enabled GWP-Asan and I'm trying to trigger it just to prove that it's working. I'm following the pattern in the example in the doc of doing thousands of use-after-free, but it's not triggering. I'm wondering if that's because I'm testing on an Android 7 device (I don't have an Android 11 device to hand).

Columbo
  • 6,648
  • 4
  • 19
  • 30

2 Answers2

0

An Android 11 device is required: source

GWP-ASan is only available on Android 11 devices. So - for an app to have GWP-ASan, you need: (1) A device with Android 11, (2) android:gwpAsanMode="always" specified in your manifest. Additionally, you'll need to build your app using the Android 11 SDK, as the flag in (2) isn't defined in older SDKs and will fail to build.

Columbo
  • 6,648
  • 4
  • 19
  • 30
0

Doesn't work for me too, I am trying to test GWP-Asan on Google Pixel 2 XL with Android 11.

Update: It worked, for some reason, when Android Studio debugger is set to Dual, app starts and functions normally. Running without debugger attached, made GWP Asan work, additionally you might want to filter logcat with tag "DEBUG" as that's where it prints logs

Created Android app with JNI from Android Studio, build.gradle looks like:

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.example.gwpadresssanitizer"
        minSdkVersion 16
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

Manifest looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.gwpadresssanitizer">

    <application
        android:gwpAsanMode="always"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.GWPAdressSanitizer">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Using code:

jstring native_get_string(JNIEnv* env) {
    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());
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_gwpadresssanitizer_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {

    jstring return_string;
    for (unsigned i = 0; i < 0x10000; ++i) {
        return_string = native_get_string(env);
    }

    return reinterpret_cast<jstring>(env->NewGlobalRef(return_string));
}
TomUser
  • 21
  • 2