summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peter Collingbourne <pcc@google.com> 2020-04-08 18:32:33 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2020-04-08 18:32:33 +0000
commit6e478ee41da0b7dbba81c1d4ccceaead17b10135 (patch)
tree8e0144abdefb1d8ffe77c9860883db0f42c51043
parent9f95dad19ba94b4bd9159fe097a567f00b6ec4eb (diff)
parentf78e085068639b98f9d6cc0549bfdd6677a8f6d1 (diff)
Merge "Implement initial policy for memory tag checks."
-rw-r--r--core/java/com/android/internal/os/Zygote.java5
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java12
-rw-r--r--core/jni/Android.bp6
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp53
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java24
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 d047415aacfb..35b76053f8d3 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -983,4 +983,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 021f48746889..631f2e5b078f 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -748,9 +748,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 872f26d1a143..9bc4adca1402 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -326,4 +326,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 22f0478ce841..99e8ecaa8276 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>
@@ -313,6 +316,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 {
@@ -1058,6 +1063,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,
@@ -1173,7 +1200,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));
@@ -1848,6 +1891,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;Z)I",
@@ -1885,6 +1936,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 f5cefb3ff1ea..83c1b024180a 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.AppGlobals;
import android.app.AppProtoEnums;
import android.app.IApplicationThread;
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;
@@ -292,6 +294,14 @@ public final class ProcessList {
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.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
@@ -1664,8 +1674,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;