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

Commit e4ea6dd8 authored by Daniel Kiss's avatar Daniel Kiss Committed by Elliott Hughes
Browse files

Zygote: Add Arm pointer authentication keychange support.

After fork the pointer authentication keys remain the same therefore
all children of Zygote would use the same keys. Patch changes the keys
after the fork in the child process.

Test: Boot PAuth enabled build on FVP.

Change-Id: Idef451eaf88f52d9fdccc735f24917b0c3ce1fb0
parent 65530b75
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -95,6 +95,19 @@

#include "nativebridge/native_bridge.h"

/* Functions in the callchain during the fork shall not be protected with
   Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */
#ifdef __ARM_FEATURE_PAC_DEFAULT
#ifdef __ARM_FEATURE_BTI_DEFAULT
#define NO_PAC_FUNC __attribute__((target("branch-protection=bti")))
#else
#define NO_PAC_FUNC __attribute__((target("branch-protection=none")))
#endif /* __ARM_FEATURE_BTI_DEFAULT */
#else /* !__ARM_FEATURE_PAC_DEFAULT */
#define NO_PAC_FUNC
#endif /* __ARM_FEATURE_PAC_DEFAULT */


namespace {

// TODO (chriswailes): Add a function to initialize native Zygote data.
@@ -985,7 +998,23 @@ static void ClearUsapTable() {
  gUsapPoolCount = 0;
}

NO_PAC_FUNC
static void PAuthKeyChange(JNIEnv* env) {
#ifdef __aarch64__
  unsigned long int hwcaps = getauxval(AT_HWCAP);
  if (hwcaps & HWCAP_PACA) {
    const unsigned long key_mask = PR_PAC_APIAKEY | PR_PAC_APIBKEY |
                                   PR_PAC_APDAKEY | PR_PAC_APDBKEY | PR_PAC_APGAKEY;
    if (prctl(PR_PAC_RESET_KEYS, key_mask, 0, 0, 0) != 0) {
      ALOGE("Failed to change the PAC keys: %s", strerror(errno));
      RuntimeAbort(env, __LINE__, "PAC key change failed.");
    }
  }
#endif
}

// Utility routine to fork a process from the zygote.
NO_PAC_FUNC
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                        const std::vector<int>& fds_to_close,
                        const std::vector<int>& fds_to_ignore,
@@ -1036,6 +1065,7 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
    }

    // The child process.
    PAuthKeyChange(env);
    PreApplicationInit();

    // Clean up any descriptors which must be closed immediately
@@ -1486,6 +1516,7 @@ static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jcl
  PreApplicationInit();
}

NO_PAC_FUNC
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
        JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
        jint runtime_flags, jobjectArray rlimits,
@@ -1533,6 +1564,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
    return pid;
}

NO_PAC_FUNC
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
@@ -1600,6 +1632,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
 * @param is_priority_fork  Controls the nice level assigned to the newly created process
 * @return
 */
NO_PAC_FUNC
static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env,
                                                          jclass,
                                                          jint read_pipe_fd,