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

Commit 5b22a826 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Zygote: Add fdsToIgnore"

parents 619d6282 8dfa178e
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -85,6 +85,9 @@ public final class Zygote {
     * file descriptor numbers that are to be closed by the child
     * file descriptor numbers that are to be closed by the child
     * (and replaced by /dev/null) after forking.  An integer value
     * (and replaced by /dev/null) after forking.  An integer value
     * of -1 in any entry in the array means "ignore this one".
     * of -1 in any entry in the array means "ignore this one".
     * @param fdsToIgnore null-ok an array of ints, either null or holding
     * one or more POSIX file descriptor numbers that are to be ignored
     * in the file descriptor table check.
     * @param instructionSet null-ok the instruction set to use.
     * @param instructionSet null-ok the instruction set to use.
     * @param appDataDir null-ok the data directory of the app.
     * @param appDataDir null-ok the data directory of the app.
     *
     *
@@ -93,11 +96,11 @@ public final class Zygote {
     */
     */
    public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
    public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
          String instructionSet, String appDataDir) {
          int[] fdsToIgnore, String instructionSet, String appDataDir) {
        VM_HOOKS.preFork();
        VM_HOOKS.preFork();
        int pid = nativeForkAndSpecialize(
        int pid = nativeForkAndSpecialize(
                  uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                  uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                  instructionSet, appDataDir);
                  fdsToIgnore, instructionSet, appDataDir);
        // Enable tracing as soon as possible for the child process.
        // Enable tracing as soon as possible for the child process.
        if (pid == 0) {
        if (pid == 0) {
            Trace.setTracingEnabled(true);
            Trace.setTracingEnabled(true);
@@ -111,7 +114,7 @@ public final class Zygote {


    native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
    native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
          String instructionSet, String appDataDir);
          int[] fdsToIgnore, String instructionSet, String appDataDir);


    /**
    /**
     * Special method to start the system server process. In addition to the
     * Special method to start the system server process. In addition to the
+4 −1
Original line number Original line Diff line number Diff line
@@ -193,11 +193,14 @@ class ZygoteConnection {
                rlimits = parsedArgs.rlimits.toArray(intArray2d);
                rlimits = parsedArgs.rlimits.toArray(intArray2d);
            }
            }


            int[] fdsToIgnore = null;

            if (parsedArgs.invokeWith != null) {
            if (parsedArgs.invokeWith != null) {
                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                childPipeFd = pipeFds[1];
                childPipeFd = pipeFds[1];
                serverPipeFd = pipeFds[0];
                serverPipeFd = pipeFds[0];
                Os.fcntlInt(childPipeFd, F_SETFD, 0);
                Os.fcntlInt(childPipeFd, F_SETFD, 0);
                fdsToIgnore = new int[] { childPipeFd.getInt$(), serverPipeFd.getInt$() };
            }
            }


            /**
            /**
@@ -230,7 +233,7 @@ class ZygoteConnection {


            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
                    parsedArgs.appDataDir);
        } catch (ErrnoException ex) {
        } catch (ErrnoException ex) {
            logAndPrintError(newStderr, "Exception creating pipe", ex);
            logAndPrintError(newStderr, "Exception creating pipe", ex);
+28 −6
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@
#include <sys/wait.h>
#include <sys/wait.h>
#include <unistd.h>
#include <unistd.h>


#include "android-base/logging.h"
#include <cutils/fs.h>
#include <cutils/fs.h>
#include <cutils/multiuser.h>
#include <cutils/multiuser.h>
#include <cutils/sched_policy.h>
#include <cutils/sched_policy.h>
@@ -440,6 +441,22 @@ void SetThreadName(const char* thread_name) {
// The list of open zygote file descriptors.
// The list of open zygote file descriptors.
static FileDescriptorTable* gOpenFdTable = NULL;
static FileDescriptorTable* gOpenFdTable = NULL;


static void FillFileDescriptorVector(JNIEnv* env,
                                     jintArray java_fds,
                                     std::vector<int>* fds) {
  CHECK(fds != nullptr);
  if (java_fds != nullptr) {
    ScopedIntArrayRO ar(env, java_fds);
    if (ar.get() == nullptr) {
      RuntimeAbort(env, __LINE__, "Bad fd array");
    }
    fds->reserve(ar.size());
    for (size_t i = 0; i < ar.size(); ++i) {
      fds->push_back(ar[i]);
    }
  }
}

// Utility routine to fork zygote and specialize the child process.
// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
                                     jint debug_flags, jobjectArray javaRlimits,
                                     jint debug_flags, jobjectArray javaRlimits,
@@ -447,6 +464,7 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
                                     jint mount_external,
                                     jint mount_external,
                                     jstring java_se_info, jstring java_se_name,
                                     jstring java_se_info, jstring java_se_name,
                                     bool is_system_server, jintArray fdsToClose,
                                     bool is_system_server, jintArray fdsToClose,
                                     jintArray fdsToIgnore,
                                     jstring instructionSet, jstring dataDir) {
                                     jstring instructionSet, jstring dataDir) {
  SetSigChldHandler();
  SetSigChldHandler();


@@ -457,12 +475,14 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
  // If this is the first fork for this zygote, create the open FD table.
  // If this is the first fork for this zygote, create the open FD table.
  // If it isn't, we just need to check whether the list of open files has
  // If it isn't, we just need to check whether the list of open files has
  // changed (and it shouldn't in the normal case).
  // changed (and it shouldn't in the normal case).
  std::vector<int> fds_to_ignore;
  FillFileDescriptorVector(env, fdsToIgnore, &fds_to_ignore);
  if (gOpenFdTable == NULL) {
  if (gOpenFdTable == NULL) {
    gOpenFdTable = FileDescriptorTable::Create();
    gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore);
    if (gOpenFdTable == NULL) {
    if (gOpenFdTable == NULL) {
      RuntimeAbort(env, __LINE__, "Unable to construct file descriptor table.");
      RuntimeAbort(env, __LINE__, "Unable to construct file descriptor table.");
    }
    }
  } else if (!gOpenFdTable->Restat()) {
  } else if (!gOpenFdTable->Restat(fds_to_ignore)) {
    RuntimeAbort(env, __LINE__, "Unable to restat file descriptor table.");
    RuntimeAbort(env, __LINE__, "Unable to restat file descriptor table.");
  }
  }


@@ -621,7 +641,9 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
        JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
        JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits,
        jint debug_flags, jobjectArray rlimits,
        jint mount_external, jstring se_info, jstring se_name,
        jint mount_external, jstring se_info, jstring se_name,
        jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
        jintArray fdsToClose,
        jintArray fdsToIgnore,
        jstring instructionSet, jstring appDataDir) {
    jlong capabilities = 0;
    jlong capabilities = 0;


    // Grant CAP_WAKE_ALARM to the Bluetooth process.
    // Grant CAP_WAKE_ALARM to the Bluetooth process.
@@ -656,7 +678,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(


    return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
    return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
            rlimits, capabilities, capabilities, mount_external, se_info,
            rlimits, capabilities, capabilities, mount_external, se_info,
            se_name, false, fdsToClose, instructionSet, appDataDir);
            se_name, false, fdsToClose, fdsToIgnore, instructionSet, appDataDir);
}
}


static jint com_android_internal_os_Zygote_nativeForkSystemServer(
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
@@ -667,7 +689,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
                                      debug_flags, rlimits,
                                      debug_flags, rlimits,
                                      permittedCapabilities, effectiveCapabilities,
                                      permittedCapabilities, effectiveCapabilities,
                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                      NULL, NULL);
                                      NULL, NULL, NULL);
  if (pid > 0) {
  if (pid > 0) {
      // The zygote process checks whether the child process has died or not.
      // The zygote process checks whether the child process has died or not.
      ALOGI("System server process %d has been created", pid);
      ALOGI("System server process %d has been created", pid);
@@ -734,7 +756,7 @@ static void com_android_internal_os_Zygote_nativeUnmountStorageOnInit(JNIEnv* en


static const JNINativeMethod gMethods[] = {
static const JNINativeMethod gMethods[] = {
    { "nativeForkAndSpecialize",
    { "nativeForkAndSpecialize",
      "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I",
      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I",
      (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
      (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
    { "nativeForkSystemServer", "(II[II[[IJJ)I",
    { "nativeForkSystemServer", "(II[II[[IJJ)I",
      (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
      (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
+10 −2
Original line number Original line Diff line number Diff line
@@ -381,7 +381,7 @@ bool FileDescriptorInfo::DetachSocket() const {
}
}


// static
// static
FileDescriptorTable* FileDescriptorTable::Create() {
FileDescriptorTable* FileDescriptorTable::Create(const std::vector<int>& fds_to_ignore) {
  DIR* d = opendir(kFdPath);
  DIR* d = opendir(kFdPath);
  if (d == NULL) {
  if (d == NULL) {
    ALOGE("Unable to open directory %s: %s", kFdPath, strerror(errno));
    ALOGE("Unable to open directory %s: %s", kFdPath, strerror(errno));
@@ -396,6 +396,10 @@ FileDescriptorTable* FileDescriptorTable::Create() {
    if (fd == -1) {
    if (fd == -1) {
      continue;
      continue;
    }
    }
    if (std::find(fds_to_ignore.begin(), fds_to_ignore.end(), fd) != fds_to_ignore.end()) {
      ALOGI("Ignoring open file descriptor %d", fd);
      continue;
    }


    FileDescriptorInfo* info = FileDescriptorInfo::CreateFromFd(fd);
    FileDescriptorInfo* info = FileDescriptorInfo::CreateFromFd(fd);
    if (info == NULL) {
    if (info == NULL) {
@@ -414,7 +418,7 @@ FileDescriptorTable* FileDescriptorTable::Create() {
  return new FileDescriptorTable(open_fd_map);
  return new FileDescriptorTable(open_fd_map);
}
}


bool FileDescriptorTable::Restat() {
bool FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore) {
  std::set<int> open_fds;
  std::set<int> open_fds;


  // First get the list of open descriptors.
  // First get the list of open descriptors.
@@ -431,6 +435,10 @@ bool FileDescriptorTable::Restat() {
    if (fd == -1) {
    if (fd == -1) {
      continue;
      continue;
    }
    }
    if (std::find(fds_to_ignore.begin(), fds_to_ignore.end(), fd) != fds_to_ignore.end()) {
      ALOGI("Ignoring open file descriptor %d", fd);
      continue;
    }


    open_fds.insert(fd);
    open_fds.insert(fd);
  }
  }
+2 −2
Original line number Original line Diff line number Diff line
@@ -122,9 +122,9 @@ class FileDescriptorTable {
  // Creates a new FileDescriptorTable. This function scans
  // Creates a new FileDescriptorTable. This function scans
  // /proc/self/fd for the list of open file descriptors and collects
  // /proc/self/fd for the list of open file descriptors and collects
  // information about them. Returns NULL if an error occurs.
  // information about them. Returns NULL if an error occurs.
  static FileDescriptorTable* Create();
  static FileDescriptorTable* Create(const std::vector<int>& fds_to_ignore);


  bool Restat();
  bool Restat(const std::vector<int>& fds_to_ignore);


  // Reopens all file descriptors that are contained in the table. Returns true
  // Reopens all file descriptors that are contained in the table. Returns true
  // if all descriptors were successfully re-opened or detached, and false if an
  // if all descriptors were successfully re-opened or detached, and false if an