Bug 1151607 - Step 1: Add Linux sandboxing hook for when child processes are still single-threaded. r=kang r=bent

This means that B2G plugin-container must (dynamically) link against
libmozsandbox in order to call into it before initializing Binder.
(Desktop Linux plugin-container already contains the sandbox code.)
This commit is contained in:
Jed Davis 2015-04-10 18:05:19 -07:00
Родитель cf24e12150
Коммит 32cb9ee32d
10 изменённых файлов: 142 добавлений и 2 удалений

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

@ -2913,6 +2913,9 @@ NS_EXPORT void
AfterNuwaFork() AfterNuwaFork()
{ {
SetCurrentProcessPrivileges(base::PRIVILEGES_DEFAULT); SetCurrentProcessPrivileges(base::PRIVILEGES_DEFAULT);
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
mozilla::SandboxEarlyInit(XRE_GetProcessType(), /* isNuwa: */ false);
#endif
} }
#endif // MOZ_NUWA_PROCESS #endif // MOZ_NUWA_PROCESS

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

@ -62,7 +62,7 @@ if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
'sha256.c', 'sha256.c',
] ]
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] == 'Linux': if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] in ('Linux', 'Android'):
USE_LIBS += [ USE_LIBS += [
'mozsandbox', 'mozsandbox',
] ]

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

@ -52,7 +52,11 @@
"Gecko:MozillaRntimeMain", __VA_ARGS__)) \ "Gecko:MozillaRntimeMain", __VA_ARGS__)) \
: (void)0 ) : (void)0 )
#endif # ifdef MOZ_CONTENT_SANDBOX
# include "mozilla/Sandbox.h"
# endif
#endif // MOZ_WIDGET_GONK
#ifdef MOZ_NUWA_PROCESS #ifdef MOZ_NUWA_PROCESS
#include <binder/ProcessState.h> #include <binder/ProcessState.h>
@ -166,6 +170,16 @@ content_process_main(int argc, char* argv[])
} }
#endif #endif
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
// This has to happen while we're still single-threaded, and on
// B2G that means before the Android Binder library is
// initialized. Additional special handling is needed for Nuwa:
// the Nuwa process itself needs to be unsandboxed, and the same
// single-threadedness condition applies to its children; see also
// AfterNuwaFork().
mozilla::SandboxEarlyInit(XRE_GetProcessType(), isNuwa);
#endif
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK
// This creates a ThreadPool for binder ipc. A ThreadPool is necessary to // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
// receive binder calls, though not necessary to send binder calls. // receive binder calls, though not necessary to send binder calls.

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

@ -8,6 +8,7 @@
#include "SandboxFilter.h" #include "SandboxFilter.h"
#include "SandboxInternal.h" #include "SandboxInternal.h"
#include "SandboxLogging.h" #include "SandboxLogging.h"
#include "SandboxUtil.h"
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
@ -421,6 +422,12 @@ SetCurrentProcessSandbox(SandboxType aType)
BroadcastSetThreadSandbox(aType); BroadcastSetThreadSandbox(aType);
} }
void
SandboxEarlyInit(GeckoProcessType aType, bool aIsNuwa)
{
MOZ_RELEASE_ASSERT(IsSingleThreaded());
}
#ifdef MOZ_CONTENT_SANDBOX #ifdef MOZ_CONTENT_SANDBOX
/** /**
* Starts the seccomp sandbox for a content process. Should be called * Starts the seccomp sandbox for a content process. Should be called

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

@ -8,6 +8,7 @@
#define mozilla_Sandbox_h #define mozilla_Sandbox_h
#include "mozilla/Types.h" #include "mozilla/Types.h"
#include "nsXULAppAPI.h"
// This defines the entry points for a content process to start // This defines the entry points for a content process to start
// sandboxing itself. See also common/SandboxInfo.h for what parts of // sandboxing itself. See also common/SandboxInfo.h for what parts of
@ -23,6 +24,9 @@
namespace mozilla { namespace mozilla {
// This must be called early, while the process is still single-threaded.
MOZ_SANDBOX_EXPORT void SandboxEarlyInit(GeckoProcessType aType, bool aIsNuwa);
#ifdef MOZ_CONTENT_SANDBOX #ifdef MOZ_CONTENT_SANDBOX
// Call only if SandboxInfo::CanSandboxContent() returns true. // Call only if SandboxInfo::CanSandboxContent() returns true.
// (No-op if MOZ_DISABLE_CONTENT_SANDBOX is set.) // (No-op if MOZ_DISABLE_CONTENT_SANDBOX is set.)

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

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SandboxUtil.h"
#include "SandboxLogging.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "mozilla/Assertions.h"
namespace mozilla {
bool
IsSingleThreaded()
{
// This detects the thread count indirectly. /proc/<pid>/task has a
// subdirectory for each thread in <pid>'s thread group, and the
// link count on the "task" directory follows Unix expectations: the
// link from its parent, the "." link from itself, and the ".." link
// from each subdirectory; thus, 2+N links for N threads.
struct stat sb;
if (stat("/proc/self/task", &sb) < 0) {
MOZ_DIAGNOSTIC_ASSERT(false, "Couldn't access /proc/self/task!");
return false;
}
MOZ_DIAGNOSTIC_ASSERT(sb.st_nlink >= 3);
return sb.st_nlink == 3;
}
} // namespace mozilla

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

@ -0,0 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_SandboxUtil_h
#define mozilla_SandboxUtil_h
namespace mozilla {
bool IsSingleThreaded();
} // namespace mozilla
#endif // mozilla_SandboxUtil_h

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

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "SandboxUtil.h"
#include <pthread.h>
namespace mozilla {
// In order to test IsSingleThreaded when the test-running process is
// single-threaded, before assorted XPCOM components have created many
// additional threads, a static initializer is used.
namespace {
struct EarlyTest {
bool mWasSingleThreaded;
EarlyTest()
: mWasSingleThreaded(IsSingleThreaded())
{ }
};
static const EarlyTest gEarlyTest;
} // namespace
TEST(SandboxUtil, IsSingleThreaded)
{
EXPECT_TRUE(gEarlyTest.mWasSingleThreaded);
EXPECT_FALSE(IsSingleThreaded());
}
} // namespace mozilla

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

@ -0,0 +1,20 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
FAIL_ON_WARNINGS = True
Library('sandboxtest')
SOURCES = [
'../SandboxUtil.cpp',
'TestSandboxUtil.cpp',
]
LOCAL_INCLUDES += [
'/security/sandbox/linux',
]
FINAL_LIBRARY = 'xul-gtest'

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

@ -57,6 +57,7 @@ SOURCES += [
'Sandbox.cpp', 'Sandbox.cpp',
'SandboxAssembler.cpp', 'SandboxAssembler.cpp',
'SandboxFilter.cpp', 'SandboxFilter.cpp',
'SandboxUtil.cpp',
] ]
# gcc lto likes to put the top level asm in syscall.cc in a different partition # gcc lto likes to put the top level asm in syscall.cc in a different partition
@ -82,4 +83,5 @@ if CONFIG['OS_TARGET'] != 'Android':
DIRS += [ DIRS += [
'common', 'common',
'glue', 'glue',
'gtest',
] ]