Skip to content

Commit 3c26944

Browse files
narayankandi34
authored andcommitted
Backport changes to whitelist sockets opened by the zygote.
This is the backport of the following commits : Commit c5f27a7cb2ec816f483a65255034a1b57a8aa22: ----------------------------------------------- Reopen whitelisted zygote file descriptors after a fork. We don't want these descriptors to be shared post-fork, so we'll have to close and reopen them when the zygote forks. The set of open descriptors is checked against a whitelist and it is a fatal error if a non whitelisted FD is opened. It is also a fatal error if anything other than a regular file / character device or socket is opened at the time of forking. This work is done in two stages : - An initial list of FDs is constructed and cached prior to the first zygote fork. - On each subsequent fork, we check whether the list of open FDs has changed. We are currently tolerant of changes, but in the longer term, it should be a fatal error if the set of open file descriptors in the zygote changes. - Post fork, we traverse the list of open descriptors and reopen them if necessary. bug: 30963384 Commit 3764a260f0c90dcb323caeda14baf903cc108759: ----------------------------------------------- Add a whitelist of sockets on fork. Maintain a whitelist of AF_UNIX sockets that are permitted to exist at the time of forking. If an open socket does not belong to the whitelist (or is not AF_UNIX), the process will abort. If an open socket is whitelisted, it will be redirected to /dev/null after a sucessful fork. This allows us to unify our handling of the special zygote sockets (/dev/socket/zygote[_secondary]) with the existing whitelist of non socket file descriptors. This change also removes non-fatal ALOGW messages since they have the side effect of reopening the logging socket. bug: 30963384 Commit 0b76d6a28e6978151bf245a775329cdae5e574d5 ----------------------------------------------- fd_utils: Fix broken usage of iterators. There were two separate issues here : - RestatInternal was using an iterator after a call to erase(). This will not work because it will be invalidated. - The "standard" for loop idiom for iterating over a map while making structural changes to it is broken. Switch to a while loop and treat cases where elements are erased differently from cases where they aren't. bug: 31092930 bug: 30963384 Plus additional changes: ----------------------------------------------- - change unordered_map to map. - add /dev/log/* files to the whitelist. - add an exemption for opened netlink sockets. - map.erase(iterator) returns void prior to C++11, so need the kludge of calling erase(it++). bug: 30963384 Change-Id: I21c60358097c54497a8c5f4e75624191cd5c2416 (cherry picked from commit 63545150c216578ba578d6c205cb2835b2c9d75f)
1 parent 98e6ecd commit 3c26944

File tree

2 files changed

+593
-0
lines changed

2 files changed

+593
-0
lines changed

vm/native/dalvik_system_Zygote.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
#include <sys/utsname.h>
4242
#include <sys/capability.h>
4343

44+
#ifdef HAVE_ANDROID_OS
45+
#include "fd_utils-inl.h"
46+
#endif
47+
4448
#if defined(HAVE_PRCTL)
4549
# include <sys/prctl.h>
4650
#endif
@@ -523,6 +527,11 @@ static void detachDescriptors(ArrayObject* fdsToClose) {
523527

524528
#endif
525529

530+
#ifdef HAVE_ANDROID_OS
531+
// The list of open zygote file descriptors.
532+
static FileDescriptorTable* gOpenFdTable = NULL;
533+
#endif
534+
526535
/*
527536
* Utility routine to fork zygote and specialize the child process.
528537
*/
@@ -590,6 +599,27 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l
590599
setSignalHandler();
591600

592601
dvmDumpLoaderStats("zygote");
602+
603+
// Close any logging related FDs before we start evaluating the list of
604+
// file descriptors.
605+
__android_log_close();
606+
607+
#ifdef HAVE_ANDROID_OS
608+
// If this is the first fork for this zygote, create the open FD table.
609+
// If it isn't, we just need to check whether the list of open files
610+
// has changed (and it shouldn't in the normal case).
611+
if (gOpenFdTable == NULL) {
612+
gOpenFdTable = FileDescriptorTable::Create();
613+
if (gOpenFdTable == NULL) {
614+
ALOGE("Unable to construct file descriptor table.");
615+
dvmAbort();
616+
}
617+
} else if (!gOpenFdTable->Restat()) {
618+
ALOGE("Unable to restat file descriptor table.");
619+
dvmAbort();
620+
}
621+
#endif
622+
593623
pid = fork();
594624

595625
if (pid == 0) {
@@ -629,6 +659,12 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l
629659
}
630660
}
631661

662+
// Re-open all remaining open file descriptors so that they aren't
663+
// shared with the zygote across a fork.
664+
if (!gOpenFdTable->ReopenOrDetach()) {
665+
ALOGE("Unable to reopen whitelisted descriptors.");
666+
dvmAbort();
667+
}
632668
#endif /* HAVE_ANDROID_OS */
633669

634670
if (mountMode != MOUNT_EXTERNAL_NONE) {

0 commit comments

Comments
 (0)