diff options
| author | 2017-01-11 02:20:36 +0000 | |
|---|---|---|
| committer | 2017-01-11 02:20:37 +0000 | |
| commit | 5b22a826d561be3d416eb4491738eda492e8631b (patch) | |
| tree | fe1c75fc721468e4ea81f2fe8872f9304e007468 | |
| parent | 619d6282c3c263672113efee8e1e386de480e119 (diff) | |
| parent | 8dfa178efbbb155657639bd526e9a8579fce3886 (diff) | |
Merge "Zygote: Add fdsToIgnore"
| -rw-r--r-- | core/java/com/android/internal/os/Zygote.java | 9 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/ZygoteConnection.java | 5 | ||||
| -rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 34 | ||||
| -rw-r--r-- | core/jni/fd_utils.cpp | 12 | ||||
| -rw-r--r-- | core/jni/fd_utils.h | 4 |
5 files changed, 50 insertions, 14 deletions
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 293de3d71332..e1e0a21eb7f5 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -85,6 +85,9 @@ public final class Zygote { * file descriptor numbers that are to be closed by the child * (and replaced by /dev/null) after forking. An integer value * 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 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, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, - String instructionSet, String appDataDir) { + int[] fdsToIgnore, String instructionSet, String appDataDir) { VM_HOOKS.preFork(); int pid = nativeForkAndSpecialize( uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, - instructionSet, appDataDir); + fdsToIgnore, instructionSet, appDataDir); // Enable tracing as soon as possible for the child process. if (pid == 0) { Trace.setTracingEnabled(true); @@ -111,7 +114,7 @@ public final class Zygote { native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags, 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 diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 44c6e8557c2c..ec80303f714a 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -193,11 +193,14 @@ class ZygoteConnection { rlimits = parsedArgs.rlimits.toArray(intArray2d); } + int[] fdsToIgnore = null; + if (parsedArgs.invokeWith != null) { FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC); childPipeFd = pipeFds[1]; serverPipeFd = pipeFds[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, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, - parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, + parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet, parsedArgs.appDataDir); } catch (ErrnoException ex) { logAndPrintError(newStderr, "Exception creating pipe", ex); diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 94935cc5c144..a32dbad7838f 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -43,6 +43,7 @@ #include <sys/wait.h> #include <unistd.h> +#include "android-base/logging.h" #include <cutils/fs.h> #include <cutils/multiuser.h> #include <cutils/sched_policy.h> @@ -440,6 +441,22 @@ void SetThreadName(const char* thread_name) { // The list of open zygote file descriptors. 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. static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids, 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, jstring java_se_info, jstring java_se_name, bool is_system_server, jintArray fdsToClose, + jintArray fdsToIgnore, jstring instructionSet, jstring dataDir) { 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 it isn't, we just need to check whether the list of open files has // changed (and it shouldn't in the normal case). + std::vector<int> fds_to_ignore; + FillFileDescriptorVector(env, fdsToIgnore, &fds_to_ignore); if (gOpenFdTable == NULL) { - gOpenFdTable = FileDescriptorTable::Create(); + gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore); if (gOpenFdTable == NULL) { 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."); } @@ -621,7 +641,9 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, jint debug_flags, jobjectArray rlimits, 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; // 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, 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( @@ -667,7 +689,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL, - NULL, NULL); + NULL, NULL, NULL); if (pid > 0) { // The zygote process checks whether the child process has died or not. 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[] = { { "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 }, { "nativeForkSystemServer", "(II[II[[IJJ)I", (void *) com_android_internal_os_Zygote_nativeForkSystemServer }, diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp index 969d336f3cad..59a536b1b001 100644 --- a/core/jni/fd_utils.cpp +++ b/core/jni/fd_utils.cpp @@ -381,7 +381,7 @@ bool FileDescriptorInfo::DetachSocket() const { } // static -FileDescriptorTable* FileDescriptorTable::Create() { +FileDescriptorTable* FileDescriptorTable::Create(const std::vector<int>& fds_to_ignore) { DIR* d = opendir(kFdPath); if (d == NULL) { ALOGE("Unable to open directory %s: %s", kFdPath, strerror(errno)); @@ -396,6 +396,10 @@ FileDescriptorTable* FileDescriptorTable::Create() { if (fd == -1) { 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); if (info == NULL) { @@ -414,7 +418,7 @@ FileDescriptorTable* FileDescriptorTable::Create() { return new FileDescriptorTable(open_fd_map); } -bool FileDescriptorTable::Restat() { +bool FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore) { std::set<int> open_fds; // First get the list of open descriptors. @@ -431,6 +435,10 @@ bool FileDescriptorTable::Restat() { if (fd == -1) { 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); } diff --git a/core/jni/fd_utils.h b/core/jni/fd_utils.h index 9e3afd910914..03298c38dca9 100644 --- a/core/jni/fd_utils.h +++ b/core/jni/fd_utils.h @@ -122,9 +122,9 @@ class FileDescriptorTable { // Creates a new FileDescriptorTable. This function scans // /proc/self/fd for the list of open file descriptors and collects // 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 // if all descriptors were successfully re-opened or detached, and false if an |