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

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

Merge "Implement initial policy for memory tag checks."

parents 1d1fb687 d1a6917c
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1060,4 +1060,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();
}
+9 −3
Original line number Diff line number Diff line
@@ -750,9 +750,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. */
            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;
            }

            /* Enable gwp-asan on the system server with a small probability. This is the same
             * policy as applied to native processes and system apps. */
+6 −0
Original line number Diff line number Diff line
@@ -307,4 +307,10 @@ cc_library_shared {
            enabled: true,
        },
    },

    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>
@@ -355,6 +358,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,
@@ -1586,6 +1591,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,
@@ -1715,7 +1742,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));
@@ -2405,6 +2448,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/"
@@ -2440,6 +2491,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) {
+24 −5
Original line number Diff line number Diff line
@@ -109,6 +109,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;
@@ -341,6 +342,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>.
@@ -1845,12 +1854,22 @@ public final class ProcessList {
                runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
            }

            // Enable heap pointer tagging, unless disabled by the app manifest, target sdk level,
            // or the compat feature.
            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 {
                // Enable heap pointer tagging, unless disabled by the app manifest, target sdk
                // level, or the compat feature.
                if (app.info.allowsNativeHeapPointerTagging()
                        && mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) {
                    runtimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
                }
            }

            runtimeFlags |= decideGwpAsanLevel(app);