summaryrefslogtreecommitdiffstats
path: root/chrome/nacl/nacl_helper_linux.cc
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-31 01:46:38 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-31 01:46:38 +0000
commit4451feeb191113651cb1a82862d2bece91290b8d (patch)
treebac56ba575c66e240b9cd2c0959a7f25d902b1a9 /chrome/nacl/nacl_helper_linux.cc
parent12274721df2f935cc1147964492ab87edbb3acee (diff)
downloadchromium_src-4451feeb191113651cb1a82862d2bece91290b8d.zip
chromium_src-4451feeb191113651cb1a82862d2bece91290b8d.tar.gz
chromium_src-4451feeb191113651cb1a82862d2bece91290b8d.tar.bz2
Revert 98909 - Use chain-loading for Linux nacl_helper
This replaces the nacl_helper_bootstrap program, dynamically-linked against nacl_helper.so, with a standalone, statically-linked nacl_helper_bootstrap program that loads the dynamic linker, instructing it in turn to load the nacl_helper program (now a PIE rather than a DSO). This avoids two problems with the old scheme: 1. The nacl_helper_bootstrap program remained in the dynamic linker's list of loaded objects, as the main executable, even though the memory where its .dynamic section had been was overwritten with the NaCl untrusted address space. Code that traverses the list of all loaded objects could thus attempt to look at pointers into this part of memory, and be led astray. 2. nacl_helper_bootstrap's large (~1G) bss segment could cause the kernel to refuse to load the program because it didn't think there was enough free memory in the system for so large an allocation of anonymous memory. The bootstrap program is kept very small by avoiding all use of libc (except for memset and integer division routines needed on ARM). It has its own custom start-up code hand-written in assembly and its own custom system call stubs done with hand-written GCC inline asm statements. To avoid the second problem, the bootstrap program no longer has a large bss. Instead, it has a special ELF segment (i.e. PT_LOAD header) that specifies no memory access, and a large (~1G) mapping size from the file. This mapping is way off the end of the file, but the kernel doesn't mind that, and since it's all a file mapping, the kernel does not do its normal memory accounting for consuming a large amount of anonymous memory. Unfortunately, it's impossible to get the linker to produce exactly the right PT_LOAD header by itself. Using a custom linker script, we get the layout exactly how we want it and a PT_LOAD header that is almost right. We then use a build-time helper program to munge one field of the PT_LOAD to make it exactly what we need. BUG= http://code.google.com/p/chromium/issues/detail?id=94147 TEST= hand-tested chromium build, invoked with --nacl-linux-helper R=bradchen@google.com,mseaborn@chromium.org Review URL: http://codereview.chromium.org/7795010 TBR=mcgrathr@chromium.org Review URL: http://codereview.chromium.org/7811013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98910 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/nacl/nacl_helper_linux.cc')
-rw-r--r--chrome/nacl/nacl_helper_linux.cc26
1 files changed, 19 insertions, 7 deletions
diff --git a/chrome/nacl/nacl_helper_linux.cc b/chrome/nacl/nacl_helper_linux.cc
index 7ffeadb..b53cf8d 100644
--- a/chrome/nacl/nacl_helper_linux.cc
+++ b/chrome/nacl/nacl_helper_linux.cc
@@ -23,7 +23,6 @@
#include "content/common/main_function_params.h"
#include "content/common/unix_domain_socket_posix.h"
#include "ipc/ipc_switches.h"
-#include "native_client/src/trusted/service_runtime/sel_memory.h"
namespace {
@@ -117,20 +116,33 @@ void HandleForkRequest(const std::vector<int>& child_fds) {
} // namespace
-static const char kNaClHelperAtZero[] = "at-zero";
+static const void* g_nacl_reserved_space = NULL;
+extern "C" __attribute__((visibility("default")))
+const void* nacl_helper_get_1G_address() {
+ return g_nacl_reserved_space;
+}
-int main(int argc, char *argv[]) {
+// nacl_helper_init does the real work of this module. It is invoked as
+// a static constructor and never returns, preventing main() from the
+// nacl_helper_bootstrap program from being called.
+//
+// NOTE This routine must not return.
+extern "C" __attribute__((visibility("default")))
+void nacl_helper_init(int argc, char *argv[],
+ const char *nacl_reserved_space) {
CommandLine::Init(argc, argv);
base::AtExitManager exit_manager;
base::RandUint64(); // acquire /dev/urandom fd before sandbox is raised
std::vector<int> empty; // for SendMsg() calls
g_suid_sandbox_active = (NULL != getenv("SBX_D"));
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(kNaClHelperAtZero)) {
- g_nacl_prereserved_sandbox_addr = (void *) (uintptr_t) 0x10000;
+ g_nacl_reserved_space = nacl_reserved_space;
+ if (!nacl_reserved_space) {
+ VLOG(1) << "nacl_reserved_space is NULL";
+ } else {
+ VLOG(1) << "nacl_reserved_space is at "
+ << (void *)nacl_reserved_space;
}
-
// Send the zygote a message to let it know we are ready to help
if (!UnixDomainSocket::SendMsg(kNaClZygoteDescriptor,
kNaClHelperStartupAck,