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

Commit 575d4935 authored by Peter Collingbourne's avatar Peter Collingbourne Committed by Android (Google) Code Review
Browse files

Merge "Implement initial policy for memory tag checks." into rvc-dev-plus-aosp

parents d2389bf2 1c71f8a9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1078,6 +1078,11 @@ 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();

    /**
     * Returns whether the kernel supports tagged pointers. Present in the
     * Android Common Kernel from 4.14 and up. By default, you should prefer
+5 −1
Original line number Diff line number Diff line
@@ -757,7 +757,11 @@ public class ZygoteInit {
            Zygote.applyDebuggerSystemProperty(parsedArgs);
            Zygote.applyInvokeWithSystemProperty(parsedArgs);

            if (Zygote.nativeSupportsTaggedPointers()) {
            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 if (Zygote.nativeSupportsTaggedPointers()) {
                /* Enable pointer tagging in the system server. Hardware support for this is present
                 * in all ARMv8 CPUs. */
                parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
+6 −0
Original line number Diff line number Diff line
@@ -304,4 +304,10 @@ cc_library_shared {
            ],
        },
    },

    product_variables: {
        experimental_mte: {
            cflags: ["-DANDROID_EXPERIMENTAL_MTE"],
        },
    },
}
+53 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/auxv.h>
#include <sys/capability.h>
#include <sys/cdefs.h>
#include <sys/eventfd.h>
@@ -76,6 +77,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 <cutils/sockets.h>
@@ -342,6 +345,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,
    GWP_ASAN_LEVEL_MASK = (1 << 21) | (1 << 22),
    GWP_ASAN_LEVEL_NEVER = 0 << 21,
    GWP_ASAN_LEVEL_LOTTERY = 1 << 21,
@@ -1604,6 +1609,28 @@ static void BindMountStorageDirs(JNIEnv* env, jobjectArray pkg_data_info_list,
  }
}

#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,
@@ -1735,7 +1762,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));
@@ -2430,6 +2473,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 jboolean com_android_internal_os_Zygote_nativeSupportsTaggedPointers(JNIEnv* env, jclass) {
#ifdef __aarch64__
  int res = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
@@ -2474,6 +2525,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},
        {"nativeSupportsTaggedPointers", "()Z",
         (void*)com_android_internal_os_Zygote_nativeSupportsTaggedPointers},
};
+18 −1
Original line number Diff line number Diff line
@@ -110,6 +110,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.FrameworkStatsLog;
@@ -343,6 +344,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.

    /**
     * Enable sampled memory bug detection in the app.
     * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>.
@@ -1847,7 +1856,15 @@ public final class ProcessList {
                runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
            }

            if (Zygote.nativeSupportsTaggedPointers()) {
            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 (Zygote.nativeSupportsTaggedPointers()) {
                // Enable heap pointer tagging if supported by the kernel, unless disabled by the
                // app manifest, target sdk level, or compat feature.
                if (app.info.allowsNativeHeapPointerTagging()