Bug 1603998 - Close leaking FDs of the fork server. r=gsvelto

* Close leaking FDs of the fork server.
* Init the fork server before the initialization of the leak checker  to avoid log files from taking lower file descriptor numbers.

Differential Revision: https://phabricator.services.mozilla.com/D57216

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Thinker Li 2019-12-16 17:35:39 +00:00
Родитель 942507de3e
Коммит add9a45b8a
4 изменённых файлов: 25 добавлений и 6 удалений

Просмотреть файл

@ -24,6 +24,9 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/ipc/ForkServiceChild.h"
#include "mozilla/Unused.h"
#include "mozilla/ScopeExit.h"
using namespace mozilla::ipc;
#endif
@ -78,6 +81,13 @@ ReplaceEnviroment(const LaunchOptions& options) {
bool
AppProcessBuilder::ForkProcess(const std::vector<std::string>& argv,
const LaunchOptions& options, ProcessHandle* process_handle) {
auto cleanFDs = mozilla::MakeScopeExit([&] {
for (auto& elt : options.fds_to_remap) {
auto fd = std::get<0>(elt);
close(fd);
}
});
argv_ = argv;
if (!shuffle_.Init(options.fds_to_remap)) {
return false;
@ -104,6 +114,7 @@ AppProcessBuilder::ForkProcess(const std::vector<std::string>& argv,
}
if (pid == 0) {
cleanFDs.release();
ReplaceEnviroment(options);
} else {
gProcessLog.print("==> process %d launched child process %d\n",
@ -178,7 +189,7 @@ ReserveFileDescriptors() {
// out any confliction with mapping passing from the parent process.
int fd = open("/dev/null", O_RDONLY);
for (int i = 1; i < 10; i++) {
dup(fd);
mozilla::Unused << dup(fd);
}
}

Просмотреть файл

@ -262,14 +262,16 @@ ForkServer::RunForkServer(int* aArgc, char*** aArgv) {
bool sleep_newproc = !!getenv("MOZ_FORKSERVER_WAIT_GDB_NEWPROC");
#endif
// Do this before NS_LogInit() to avoid log files taking lower
// FDs.
ForkServer forkserver;
forkserver.InitProcess(aArgc, aArgv);
XRE_SetProcessType("forkserver");
NS_LogInit();
mozilla::LogModule::Init(0, nullptr);
MOZ_LOG(gForkServiceLog, LogLevel::Verbose, ("Start a fork server"));
ForkServer forkserver;
{
forkserver.InitProcess(aArgc, aArgv);
DebugOnly<base::ProcessHandle> forkserver_pid = base::GetCurrentProcId();
if (forkserver.HandleMessages()) {
// In the fork server process

Просмотреть файл

@ -8,6 +8,8 @@
#include "base/eintr_wrapper.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Sprintf.h"
#include "mozilla/ScopeExit.h"
#include "nsDebug.h"
#include <sys/types.h>
@ -109,6 +111,10 @@ MiniTransceiver::Send(IPC::Message& aMsg) {
mState = STATE_SENDING;
#endif
auto clean_fdset = MakeScopeExit([&] {
aMsg.file_descriptor_set()->CommitAll();
});
int num_fds = aMsg.file_descriptor_set()->size();
msghdr hdr;
InitMsgHdr(&hdr, kMaxIOVecSize, num_fds);
@ -122,7 +128,7 @@ MiniTransceiver::Send(IPC::Message& aMsg) {
if (bytes_written < 0) {
char error[128];
snprintf(error, sizeof(error), "sendmsg: %s", strerror(errno));
SprintfLiteral(error, "sendmsg: %s", strerror(errno));
NS_WARNING(error);
return false;
}

Просмотреть файл

@ -37,7 +37,7 @@ public:
* \param aClearDataBuf is true to clear data buffers after
* receiving a message.
*/
MiniTransceiver(int aFd, DataBufferClear aDataBufClear = DataBufferClear::None);
explicit MiniTransceiver(int aFd, DataBufferClear aDataBufClear = DataBufferClear::None);
bool Send(IPC::Message& aMsg);
inline bool SendInfallible(IPC::Message& aMsg, const char* aCrashMessage) {