1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : #include <assert.h>
8 :
9 : #include <algorithm>
10 : #include <iterator>
11 : #include <vector>
12 :
13 : #if NACL_OSX
14 : #include <crt_externs.h>
15 : #endif
16 :
17 : #include "native_client/src/include/nacl_macros.h"
18 : #include "native_client/src/include/nacl_scoped_ptr.h"
19 : #include "native_client/src/include/nacl_string.h"
20 : #include "native_client/src/shared/srpc/nacl_srpc.h"
21 : #include "native_client/src/shared/platform/nacl_check.h"
22 : #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
23 : #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
24 : #include "native_client/src/trusted/service_runtime/env_cleanser.h"
25 : #include "native_client/src/trusted/service_runtime/nacl_error_code.h"
26 :
27 : using std::vector;
28 :
29 :
30 : namespace nacl {
31 :
32 : SelLdrLauncherStandalone::SelLdrLauncherStandalone()
33 : : child_process_(NACL_INVALID_HANDLE),
34 144 : sel_ldr_locator_(new PluginSelLdrLocator()) {
35 16 : }
36 :
37 0 : void SelLdrLauncherStandalone::GetPluginDirectory(char* buffer, size_t len) {
38 0 : sel_ldr_locator_->GetDirectory(buffer, len);
39 0 : }
40 :
41 : /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */
42 : extern "C" char **environ;
43 :
44 : static char **GetEnviron() {
45 : #if NACL_OSX
46 : /* Mac dynamic libraries cannot access the environ variable directly. */
47 0 : return *_NSGetEnviron();
48 : #else
49 : return environ;
50 : #endif
51 : }
52 :
53 0 : void SelLdrLauncherStandalone::BuildCommandLine(vector<nacl::string>* command) {
54 0 : assert(sel_ldr_ != NACL_NO_FILE_PATH); // Set by InitCommandLine().
55 0 : if (!command_prefix_.empty())
56 0 : command->insert(command->end(),
57 0 : command_prefix_.begin(), command_prefix_.end());
58 0 : if (!sel_ldr_bootstrap_.empty())
59 0 : command->push_back(sel_ldr_bootstrap_);
60 0 : command->push_back(sel_ldr_);
61 0 : if (!sel_ldr_bootstrap_.empty()) {
62 0 : command->push_back("--r_debug=0xXXXXXXXXXXXXXXXX");
63 0 : command->push_back("--reserved_at_zero=0xXXXXXXXXXXXXXXXX");
64 0 : }
65 0 : command->push_back("-R"); // RPC will be used to point to the nexe.
66 :
67 0 : command->insert(command->end(), sel_ldr_argv_.begin(), sel_ldr_argv_.end());
68 :
69 0 : struct NaClEnvCleanser env_cleanser;
70 0 : NaClEnvCleanserCtor(&env_cleanser, 1);
71 0 : if (!NaClEnvCleanserInit(&env_cleanser, GetEnviron(), NULL)) {
72 0 : NaClLog(LOG_FATAL, "Failed to initialise env cleanser\n");
73 0 : }
74 0 : for (const char* const* env = NaClEnvCleanserEnvironment(&env_cleanser);
75 : *env != NULL;
76 0 : ++env) {
77 0 : command->push_back("-E");
78 0 : command->push_back(*env);
79 0 : }
80 0 : NaClEnvCleanserDtor(&env_cleanser);
81 :
82 0 : if (application_argv_.size() > 0) {
83 : // Separator between sel_universal and app args.
84 0 : command->push_back("--");
85 0 : command->insert(command->end(),
86 0 : application_argv_.begin(), application_argv_.end());
87 0 : }
88 0 : }
89 :
90 : void SelLdrLauncherStandalone::InitCommandLine(
91 0 : const vector<nacl::string>& prefix,
92 0 : const vector<nacl::string>& sel_ldr_argv,
93 0 : const vector<nacl::string>& app_argv) {
94 0 : assert(sel_ldr_ == NACL_NO_FILE_PATH); // Make sure we don't call this twice.
95 :
96 0 : char* var = getenv("NACL_SEL_LDR");
97 0 : if (var != NULL) {
98 0 : sel_ldr_ = var;
99 0 : } else {
100 0 : sel_ldr_ = GetSelLdrPathName();
101 : }
102 0 : char *bootstrap_var = getenv("NACL_SEL_LDR_BOOTSTRAP");
103 0 : if (bootstrap_var != NULL) {
104 0 : sel_ldr_bootstrap_ = bootstrap_var;
105 0 : } else {
106 0 : sel_ldr_bootstrap_ = GetSelLdrBootstrapPathName();
107 : }
108 : // Add an emulator, if there is one.
109 0 : copy(prefix.begin(), prefix.end(), back_inserter(command_prefix_));
110 0 : command_prefix_ = prefix;
111 : // Copy the respective parameters.
112 0 : copy(sel_ldr_argv.begin(), sel_ldr_argv.end(), back_inserter(sel_ldr_argv_));
113 0 : copy(app_argv.begin(), app_argv.end(), back_inserter(application_argv_));
114 0 : nacl::string dest_fd;
115 0 : channel_ = CreateBootstrapSocket(&dest_fd);
116 : // Set up the bootstrap channel.
117 : // The arguments we want to pass to the service runtime are
118 : // "-X" causes the service runtime to create a bound socket and socket
119 : // address at descriptors 3 and 4 in the untrusted code for the nexe or
120 : // IRT to use. The argument to "-X" is the inherited file
121 : // descriptor over which the internal representation of the sock addr
122 : // is sent in order to bootstrap communications with the untrusted
123 : // NaCl module.
124 0 : sel_ldr_argv_.push_back("-X");
125 0 : sel_ldr_argv_.push_back(nacl::string(dest_fd));
126 0 : }
127 :
128 : void SelLdrLauncherStandalone::CloseHandlesAfterLaunch() {
129 26 : for (size_t i = 0; i < close_after_launch_.size(); i++) {
130 0 : NaClClose(close_after_launch_[i]);
131 0 : }
132 13 : close_after_launch_.clear();
133 13 : }
134 :
135 0 : bool SelLdrLauncherStandalone::Start(const char* url) {
136 0 : UNREFERENCED_PARAMETER(url);
137 0 : vector<nacl::string> prefix;
138 0 : vector<nacl::string> args_for_sel_ldr;
139 0 : vector<nacl::string> args_for_nexe;
140 0 : const char* irt_library_path = getenv("NACL_IRT_LIBRARY");
141 0 : if (NULL != irt_library_path) {
142 0 : args_for_sel_ldr.push_back("-B");
143 0 : args_for_sel_ldr.push_back(irt_library_path);
144 0 : }
145 0 : if (!StartViaCommandLine(prefix, args_for_sel_ldr, args_for_nexe)) {
146 0 : return false;
147 : }
148 0 : return true;
149 0 : }
150 :
151 : } // namespace nacl
|