diff options
author | Dave Platt <dplatt@google.com> | 2014-02-05 17:06:42 -0800 |
---|---|---|
committer | Dave Platt <dplatt@google.com> | 2014-02-06 13:24:38 -0800 |
commit | 89d4c897a0e1bc06688bcb1fd39913ece81fe05f (patch) | |
tree | db0f9ae9a706d1aae9bf708d06b5202c6d274049 | |
parent | f5294ed57cf388973a1db29b062b1577966f90d1 (diff) | |
download | frameworks_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.java | 36 | ||||
-rw-r--r-- | core/java/com/android/internal/os/ZygoteInit.java | 10 |
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; |