summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Platt <dplatt@google.com>2014-02-05 17:06:42 -0800
committerDave Platt <dplatt@google.com>2014-02-06 13:24:38 -0800
commit89d4c897a0e1bc06688bcb1fd39913ece81fe05f (patch)
treedb0f9ae9a706d1aae9bf708d06b5202c6d274049
parentf5294ed57cf388973a1db29b062b1577966f90d1 (diff)
downloadframeworks_base-89d4c897a0e1bc06688bcb1fd39913ece81fe05f.zip
frameworks_base-89d4c897a0e1bc06688bcb1fd39913ece81fe05f.tar.gz
frameworks_base-89d4c897a0e1bc06688bcb1fd39913ece81fe05f.tar.bz2
Finish fixing Zygote descriptor leakage problem
In order to prevent Zygote descriptors from leaking into the child environment, they should be closed by the forked-off child process before the child switches to the application UID. These changes close the descriptors via dup2(), substituting a descriptor open to /dev/null in their place; this allows the Zygote Java code to close the FileDescriptor objects cleanly. This is a multi-project change: dalvik, art, libcore, frameworks/base, and external/sepolicy are affected. The CLs need to be approved together, lest the build break or the software fail to boot. Round 2: indent change Bug: 12114500 Change-Id: I090402136a8a8b7d6aad6eb153026e85d7cf6ad3
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java36
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java10
2 files changed, 45 insertions, 1 deletions
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 4f3b5b3..f9a1f89 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -224,9 +224,37 @@ class ZygoteConnection {
ZygoteInit.setCloseOnExec(serverPipeFd, true);
}
+ /**
+ * In order to avoid leaking descriptors to the Zygote child,
+ * the native code must close the two Zygote socket descriptors
+ * in the child process before it switches from Zygote-root to
+ * the UID and privileges of the application being launched.
+ *
+ * In order to avoid "bad file descriptor" errors when the
+ * two LocalSocket objects are closed, the Posix file
+ * descriptors are released via a dup2() call which closes
+ * the socket and substitutes an open descriptor to /dev/null.
+ */
+
+ int [] fdsToClose = { -1, -1 };
+
+ FileDescriptor fd = mSocket.getFileDescriptor();
+
+ if (fd != null) {
+ fdsToClose[0] = fd.getInt$();
+ }
+
+ fd = ZygoteInit.getServerSocketFileDescriptor();
+
+ if (fd != null) {
+ fdsToClose[1] = fd.getInt$();
+ }
+
+ fd = null;
+
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
- parsedArgs.niceName);
+ parsedArgs.niceName, fdsToClose);
} catch (IOException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (ErrnoException ex) {
@@ -814,6 +842,12 @@ class ZygoteConnection {
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
+ /**
+ * By the time we get here, the native code has closed the two actual Zygote
+ * socket connections, and substituted /dev/null in their place. The LocalSocket
+ * objects still need to be closed properly.
+ */
+
closeSocket();
ZygoteInit.closeServerSocket();
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 25118e8..cc24ff7 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -201,6 +201,16 @@ public class ZygoteInit {
sServerSocket = null;
}
+ /**
+ * Return the server socket's underlying file descriptor, so that
+ * ZygoteConnection can pass it to the native code for proper
+ * closure after a child process is forked off.
+ */
+
+ static FileDescriptor getServerSocketFileDescriptor() {
+ return sServerSocket.getFileDescriptor();
+ }
+
private static final int UNPRIVILEGED_UID = 9999;
private static final int UNPRIVILEGED_GID = 9999;