diff options
| author | 2020-02-19 17:59:54 -0800 | |
|---|---|---|
| committer | 2020-04-03 11:04:51 -0700 | |
| commit | f78e085068639b98f9d6cc0549bfdd6677a8f6d1 (patch) | |
| tree | 939a66e491ab0f76fe479b758d4826676ebe08d5 | |
| parent | 49fa6ba37ff9e71a61e601ab8c1cde3735727223 (diff) | |
Implement initial policy for memory tag checks.
System apps and the system_server receive async tag checks, while all other
app processes have it disabled. Developers may enable async tag checks
per application with:
$ adb shell am compat 135772972 <app.name>
Bug: 135772972
Change-Id: I154623941eec8e79af347453fbca1b062346c85b
Merged-In: I154623941eec8e79af347453fbca1b062346c85b
| -rw-r--r-- | core/java/com/android/internal/os/Zygote.java | 5 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/ZygoteInit.java | 12 | ||||
| -rw-r--r-- | core/jni/Android.bp | 6 | ||||
| -rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 53 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ProcessList.java | 24 |
5 files changed, 95 insertions, 5 deletions
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 5f196a0e4c1c..f7ac8e801f36 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -977,4 +977,9 @@ public final class Zygote { */ @FastNative public static native int nativeParseSigChld(byte[] in, int length, int[] out); + + /** + * Returns whether the hardware supports memory tagging (ARM MTE). + */ + public static native boolean nativeSupportsMemoryTagging(); } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 300f71af5dd5..9d7d9625a944 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -781,9 +781,15 @@ public class ZygoteInit { Zygote.applyDebuggerSystemProperty(parsedArgs); Zygote.applyInvokeWithSystemProperty(parsedArgs); - /* Enable pointer tagging in the system server unconditionally. Hardware support for - * this is present in all ARMv8 CPUs; this flag has no effect on other platforms. */ - parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI; + if (Zygote.nativeSupportsMemoryTagging()) { + /* The system server is more privileged than regular app processes, so it has async + * tag checks enabled on hardware that supports memory tagging. */ + parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC; + } else { + /* Enable pointer tagging in the system server. Hardware support for this is present + * in all ARMv8 CPUs; this flag has no effect on other platforms. */ + parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI; + } if (shouldProfileSystemServer()) { parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER; diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 43df2e444932..0b044ad01235 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -323,4 +323,10 @@ cc_library_shared { // GraphicsJNI.h includes hwui headers "libhwui", ], + + product_variables: { + experimental_mte: { + cflags: ["-DANDROID_EXPERIMENTAL_MTE"], + }, + }, } diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index ea58cbd99179..fda71545de24 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -51,6 +51,7 @@ #include <paths.h> #include <signal.h> #include <stdlib.h> +#include <sys/auxv.h> #include <sys/capability.h> #include <sys/cdefs.h> #include <sys/eventfd.h> @@ -72,6 +73,8 @@ #include <android-base/stringprintf.h> #include <android-base/unique_fd.h> #include <bionic/malloc.h> +#include <bionic/mte.h> +#include <bionic/mte_kernel.h> #include <cutils/fs.h> #include <cutils/multiuser.h> #include <private/android_filesystem_config.h> @@ -317,6 +320,8 @@ enum RuntimeFlags : uint32_t { PROFILE_FROM_SHELL = 1 << 15, MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20), MEMORY_TAG_LEVEL_TBI = 1 << 19, + MEMORY_TAG_LEVEL_ASYNC = 2 << 19, + MEMORY_TAG_LEVEL_SYNC = 3 << 19, }; enum UnsolicitedZygoteMessageTypes : uint32_t { @@ -1048,6 +1053,28 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server, return pid; } +#ifdef ANDROID_EXPERIMENTAL_MTE +static void SetTagCheckingLevel(int level) { +#ifdef __aarch64__ + if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) { + return; + } + + int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0); + if (tagged_addr_ctrl < 0) { + ALOGE("prctl(PR_GET_TAGGED_ADDR_CTRL) failed: %s", strerror(errno)); + return; + } + + tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | level; + if (prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) < 0) { + ALOGE("prctl(PR_SET_TAGGED_ADDR_CTRL, %d) failed: %s", tagged_addr_ctrl, + strerror(errno)); + } +#endif +} +#endif + // Utility routine to specialize a zygote child process. static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, @@ -1160,7 +1187,23 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, case RuntimeFlags::MEMORY_TAG_LEVEL_TBI: heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI; break; + case RuntimeFlags::MEMORY_TAG_LEVEL_ASYNC: +#ifdef ANDROID_EXPERIMENTAL_MTE + SetTagCheckingLevel(PR_MTE_TCF_ASYNC); +#endif + heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC; + break; + case RuntimeFlags::MEMORY_TAG_LEVEL_SYNC: +#ifdef ANDROID_EXPERIMENTAL_MTE + SetTagCheckingLevel(PR_MTE_TCF_SYNC); +#endif + // TODO(pcc): Use SYNC here once the allocator supports it. + heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC; + break; default: +#ifdef ANDROID_EXPERIMENTAL_MTE + SetTagCheckingLevel(PR_MTE_TCF_NONE); +#endif heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE; } android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &heap_tagging_level, sizeof(heap_tagging_level)); @@ -1843,6 +1886,14 @@ static jint com_android_internal_os_Zygote_nativeParseSigChld(JNIEnv* env, jclas return -1; } +static jboolean com_android_internal_os_Zygote_nativeSupportsMemoryTagging(JNIEnv* env, jclass) { +#if defined(__aarch64__) + return mte_supported(); +#else + return false; +#endif +} + static const JNINativeMethod gMethods[] = { { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I", @@ -1880,6 +1931,8 @@ static const JNINativeMethod gMethods[] = { (void* ) com_android_internal_os_Zygote_nativeBoostUsapPriority }, {"nativeParseSigChld", "([BI[I)I", (void* ) com_android_internal_os_Zygote_nativeParseSigChld}, + { "nativeSupportsMemoryTagging", "()Z", + (void *) com_android_internal_os_Zygote_nativeSupportsMemoryTagging }, }; int register_com_android_internal_os_Zygote(JNIEnv* env) { diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 8520cb7c30b8..5353d39abcd6 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -53,6 +53,7 @@ import android.app.AppProtoEnums; import android.app.IApplicationThread; import android.app.IUidObserver; import android.compat.annotation.ChangeId; +import android.compat.annotation.Disabled; import android.compat.annotation.EnabledAfter; import android.content.ComponentName; import android.content.Context; @@ -95,6 +96,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ProcessMap; import com.android.internal.app.procstats.ProcessStats; +import com.android.internal.os.RuntimeInit; import com.android.internal.os.Zygote; import com.android.internal.util.ArrayUtils; import com.android.internal.util.MemInfoReader; @@ -293,6 +295,14 @@ public final class ProcessList { @EnabledAfter(targetSdkVersion = VersionCodes.Q) private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id. + /** + * Enable memory tag checks in non-system apps. This flag will only have an effect on + * hardware supporting the ARM Memory Tagging Extension (MTE). + */ + @ChangeId + @Disabled + private static final long NATIVE_MEMORY_TAGGING = 135772972; // This is a bug id. + ActivityManagerService mService = null; // To kill process groups asynchronously @@ -1666,8 +1676,18 @@ public final class ProcessList { runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE; } - if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) { - runtimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI; + if (Zygote.nativeSupportsMemoryTagging()) { + // System apps are generally more privileged than regular apps, and don't have the + // same app compat concerns as regular apps, so we enable async tag checks for all + // of their processes. + if ((app.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0 + || mPlatformCompat.isChangeEnabled(NATIVE_MEMORY_TAGGING, app.info)) { + runtimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC; + } + } else { + if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) { + runtimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI; + } } String invokeWith = null; |