| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2008 The Native Client Authors. All rights reserved. | 2 * Copyright 2008 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can | 3 * Use of this source code is governed by a BSD-style license that can |
| 4 * be found in the LICENSE file. | 4 * be found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "native_client/src/trusted/plugin/service_runtime.h" | 7 #include "native_client/src/trusted/plugin/service_runtime.h" |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 // GetSocketAddress implicitly invokes Close(bootstrap_socket). | 62 // GetSocketAddress implicitly invokes Close(bootstrap_socket). |
| 63 // Get service channel descriptor. | 63 // Get service channel descriptor. |
| 64 default_socket_address_ = GetSocketAddress(plugin_, bootstrap_socket); | 64 default_socket_address_ = GetSocketAddress(plugin_, bootstrap_socket); |
| 65 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" | 65 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" |
| 66 " (default_socket_address=%p)\n", | 66 " (default_socket_address=%p)\n", |
| 67 static_cast<void*>(default_socket_address_))); | 67 static_cast<void*>(default_socket_address_))); |
| 68 | 68 |
| 69 if (NULL == default_socket_address_) { | 69 if (NULL == default_socket_address_) { |
| 70 const char* error = "service runtime: no valid socket address"; | 70 const char* error = "service runtime: no valid socket address"; |
| 71 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error)); | 71 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error)); |
| 72 browser_interface_->Alert(plugin()->instance_id(), error); | 72 browser_interface_->AddToConsole(plugin()->instance_id(), error); |
| 73 return false; | 73 return false; |
| 74 } | 74 } |
| 75 // The first connect on the socket address returns the service | 75 // The first connect on the socket address returns the service |
| 76 // runtime command channel. This channel is created before the NaCl | 76 // runtime command channel. This channel is created before the NaCl |
| 77 // module runs, and is private to the service runtime. This channel | 77 // module runs, and is private to the service runtime. This channel |
| 78 // is used for a secure plugin<->service runtime communication path | 78 // is used for a secure plugin<->service runtime communication path |
| 79 // that can be used to forcibly shut down the sel_ldr. | 79 // that can be used to forcibly shut down the sel_ldr. |
| 80 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" | 80 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" |
| 81 " (connecting for SrtSocket)\n")); | 81 " (connecting for SrtSocket)\n")); |
| 82 PortableHandle* portable_socket_address = default_socket_address_->handle(); | 82 PortableHandle* portable_socket_address = default_socket_address_->handle(); |
| 83 ScriptableHandle* raw_channel = portable_socket_address->Connect(); | 83 ScriptableHandle* raw_channel = portable_socket_address->Connect(); |
| 84 if (NULL == raw_channel) { | 84 if (NULL == raw_channel) { |
| 85 const char* error = "service runtime connect failed"; | 85 const char* error = "service runtime connect failed"; |
| 86 PLUGIN_PRINTF(("ServiceRuntime::InitCommuncation (%s)\n", error)); | 86 PLUGIN_PRINTF(("ServiceRuntime::InitCommuncation (%s)\n", error)); |
| 87 browser_interface_->Alert(plugin()->instance_id(), error); | 87 browser_interface_->AddToConsole(plugin()->instance_id(), error); |
| 88 return false; | 88 return false; |
| 89 } | 89 } |
| 90 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" | 90 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" |
| 91 " (constructing runtime channel)\n")); | 91 " (constructing runtime channel)\n")); |
| 92 runtime_channel_ = new(std::nothrow) SrtSocket(raw_channel, | 92 runtime_channel_ = new(std::nothrow) SrtSocket(raw_channel, |
| 93 browser_interface_); | 93 browser_interface_); |
| 94 if (NULL == runtime_channel_) { | 94 if (NULL == runtime_channel_) { |
| 95 raw_channel->Unref(); | 95 raw_channel->Unref(); |
| 96 return false; | 96 return false; |
| 97 } | 97 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 // would prevent the scenario where an evil module is hosted (e.g., | 133 // would prevent the scenario where an evil module is hosted (e.g., |
| 134 // in temporary upload directory that's visible, or as a gmail | 134 // in temporary upload directory that's visible, or as a gmail |
| 135 // attachment URL) at an innocent server to extract confidential | 135 // attachment URL) at an innocent server to extract confidential |
| 136 // info and send it to third party servers. An explict network ACL | 136 // info and send it to third party servers. An explict network ACL |
| 137 // a la /robots.txt might be useful to serve as an ingress filter.z | 137 // a la /robots.txt might be useful to serve as an ingress filter.z |
| 138 | 138 |
| 139 PLUGIN_PRINTF(("ServiceRuntime::InitCommuncation (invoking set_origin)\n")); | 139 PLUGIN_PRINTF(("ServiceRuntime::InitCommuncation (invoking set_origin)\n")); |
| 140 if (!runtime_channel_->SetOrigin(plugin_->nacl_module_origin())) { | 140 if (!runtime_channel_->SetOrigin(plugin_->nacl_module_origin())) { |
| 141 const char* error = "could not set origin"; | 141 const char* error = "could not set origin"; |
| 142 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error)); | 142 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error)); |
| 143 browser_interface_->Alert(plugin()->instance_id(), error); | 143 browser_interface_->AddToConsole(plugin()->instance_id(), error); |
| 144 return false; | 144 return false; |
| 145 } | 145 } |
| 146 | 146 |
| 147 if (shm != NULL) { | 147 if (shm != NULL) { |
| 148 // This code is executed only if NaCl is running as a built-in plugin | 148 // This code is executed only if NaCl is running as a built-in plugin |
| 149 // in Chrome. | 149 // in Chrome. |
| 150 // We now have an open communication channel to the sel_ldr process, | 150 // We now have an open communication channel to the sel_ldr process, |
| 151 // so we can send the nexe bits over | 151 // so we can send the nexe bits over |
| 152 if (!runtime_channel_->LoadModule(shm->desc())) { | 152 if (!runtime_channel_->LoadModule(shm->desc())) { |
| 153 const char* error = "failed to send nexe"; | 153 const char* error = "failed to send nexe"; |
| 154 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error)); | 154 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error)); |
| 155 browser_interface_->Alert(plugin()->instance_id(), error); | 155 browser_interface_->AddToConsole(plugin()->instance_id(), error); |
| 156 shm->Delete(); | 156 shm->Delete(); |
| 157 // TODO(gregoryd): close communication channels | 157 // TODO(gregoryd): close communication channels |
| 158 delete subprocess_; | 158 delete subprocess_; |
| 159 subprocess_ = NULL; | 159 subprocess_ = NULL; |
| 160 return false; | 160 return false; |
| 161 } | 161 } |
| 162 /* LoadModule succeeded, proceed normally */ | 162 /* LoadModule succeeded, proceed normally */ |
| 163 shm->Delete(); | 163 shm->Delete(); |
| 164 #if NACL_WINDOWS && !defined(NACL_STANDALONE) | 164 #if NACL_WINDOWS && !defined(NACL_STANDALONE) |
| 165 // Establish the communication for handle passing protocol | 165 // Establish the communication for handle passing protocol |
| 166 struct NaClDesc* desc = NaClHandlePassBrowserGetSocketAddress(); | 166 struct NaClDesc* desc = NaClHandlePassBrowserGetSocketAddress(); |
| 167 if (!runtime_channel_->InitHandlePassing(desc, subprocess_->child())) { | 167 if (!runtime_channel_->InitHandlePassing(desc, subprocess_->child())) { |
| 168 delete subprocess_; | 168 delete subprocess_; |
| 169 subprocess_ = NULL; | 169 subprocess_ = NULL; |
| 170 return false; | 170 return false; |
| 171 } | 171 } |
| 172 #endif | 172 #endif |
| 173 } | 173 } |
| 174 | 174 |
| 175 // start the module. otherwise we cannot connect for multimedia | 175 // start the module. otherwise we cannot connect for multimedia |
| 176 // subsystem since that is handled by user-level code (not secure!) | 176 // subsystem since that is handled by user-level code (not secure!) |
| 177 // in libsrpc. | 177 // in libsrpc. |
| 178 int load_status; | 178 int load_status; |
| 179 | 179 |
| 180 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" | 180 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" |
| 181 " (invoking start_module RPC)\n")); | 181 " (invoking start_module RPC)\n")); |
| 182 if (!runtime_channel_->StartModule(&load_status)) { | 182 if (!runtime_channel_->StartModule(&load_status)) { |
| 183 const char* error = "could not start nacl module"; | 183 const char* error = "could not start nacl module"; |
| 184 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error)); | 184 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error)); |
| 185 browser_interface_->Alert(plugin()->instance_id(), error); | 185 browser_interface_->AddToConsole(plugin()->instance_id(), error); |
| 186 return false; | 186 return false; |
| 187 } | 187 } |
| 188 PLUGIN_PRINTF((" start_module returned %d\n", load_status)); | 188 PLUGIN_PRINTF((" start_module returned %d\n", load_status)); |
| 189 if (LOAD_OK != load_status) { | 189 if (LOAD_OK != load_status) { |
| 190 nacl::string error = "loading of module failed with status " + load_status; | 190 nacl::string error = "loading of module failed with status " + load_status; |
| 191 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error.c_str())); | 191 PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (%s)\n", error.c_str())); |
| 192 browser_interface_->Alert(plugin()->instance_id(), error.c_str()); | 192 browser_interface_->AddToConsole(plugin()->instance_id(), error.c_str()); |
| 193 return false; | 193 return false; |
| 194 } | 194 } |
| 195 return true; | 195 return true; |
| 196 } | 196 } |
| 197 | 197 |
| 198 bool ServiceRuntime::Start(const char* nacl_file) { | 198 bool ServiceRuntime::Start(const char* nacl_file) { |
| 199 PLUGIN_PRINTF(("ServiceRuntime::Start (nacl_file='%s')\n", nacl_file)); | 199 PLUGIN_PRINTF(("ServiceRuntime::Start (nacl_file='%s')\n", nacl_file)); |
| 200 // The arguments we want to pass to the service runtime are | 200 // The arguments we want to pass to the service runtime are |
| 201 // "-P 5" sets the default SRPC channel to be over descriptor 5. The 5 needs | 201 // "-P 5" sets the default SRPC channel to be over descriptor 5. The 5 needs |
| 202 // to match the 5 in the Launcher invocation below. | 202 // to match the 5 in the Launcher invocation below. |
| 203 // "-X 5" causes the service runtime to create a bound socket and socket | 203 // "-X 5" causes the service runtime to create a bound socket and socket |
| 204 // address at descriptors 3 and 4. The socket address is transferred as | 204 // address at descriptors 3 and 4. The socket address is transferred as |
| 205 // the first IMC message on descriptor 5. This is used when connecting | 205 // the first IMC message on descriptor 5. This is used when connecting |
| 206 // to socket addresses. | 206 // to socket addresses. |
| 207 // "-d" (not default) invokes the service runtime in debug mode. | 207 // "-d" (not default) invokes the service runtime in debug mode. |
| 208 // const char* kSelLdrArgs[] = { "-P", "5", "-X", "5" }; | 208 // const char* kSelLdrArgs[] = { "-P", "5", "-X", "5" }; |
| 209 const char* kSelLdrArgs[] = { "-P", "5", "-X", "5" }; | 209 const char* kSelLdrArgs[] = { "-P", "5", "-X", "5" }; |
| 210 // TODO(sehr): remove -P support and default channels. | 210 // TODO(sehr): remove -P support and default channels. |
| 211 const int kSelLdrArgLength = NACL_ARRAY_SIZE(kSelLdrArgs); | 211 const int kSelLdrArgLength = NACL_ARRAY_SIZE(kSelLdrArgs); |
| 212 vector<nacl::string> kArgv(kSelLdrArgs, kSelLdrArgs + kSelLdrArgLength); | 212 vector<nacl::string> kArgv(kSelLdrArgs, kSelLdrArgs + kSelLdrArgLength); |
| 213 vector<nacl::string> kEmpty; | 213 vector<nacl::string> kEmpty; |
| 214 | 214 |
| 215 PLUGIN_PRINTF(("ServiceRuntime::Start (this=%p, plugin=%p)\n", | 215 PLUGIN_PRINTF(("ServiceRuntime::Start (this=%p, plugin=%p)\n", |
| 216 static_cast<void*>(this), static_cast<void*>(plugin()))); | 216 static_cast<void*>(this), static_cast<void*>(plugin()))); |
| 217 | 217 |
| 218 subprocess_ = new(std::nothrow) nacl::SelLdrLauncher(); | 218 subprocess_ = new(std::nothrow) nacl::SelLdrLauncher(); |
| 219 if (NULL == subprocess_) { | 219 if (NULL == subprocess_) { |
| 220 const char* error = "could not create SelLdrLauncher"; | 220 const char* error = "could not create SelLdrLauncher"; |
| 221 PLUGIN_PRINTF(("ServiceRuntime::Start (%s)\n", error)); | 221 PLUGIN_PRINTF(("ServiceRuntime::Start (%s)\n", error)); |
| 222 browser_interface_->Alert(plugin()->instance_id(), error); | 222 browser_interface_->AddToConsole(plugin()->instance_id(), error); |
| 223 return false; | 223 return false; |
| 224 } | 224 } |
| 225 subprocess_->Init(nacl_file, -1, kArgv, kEmpty); | 225 subprocess_->Init(nacl_file, -1, kArgv, kEmpty); |
| 226 | 226 |
| 227 nacl::Handle receive_handle = subprocess_->ExportImcFD(6); | 227 nacl::Handle receive_handle = subprocess_->ExportImcFD(6); |
| 228 if (receive_handle == nacl::kInvalidHandle) { | 228 if (receive_handle == nacl::kInvalidHandle) { |
| 229 browser_interface_->Alert(plugin()->instance_id(), | 229 browser_interface_->AddToConsole(plugin()->instance_id(), |
| 230 "Failed to create async receive handle"); | 230 "Failed to create async receive handle"); |
| 231 return false; | 231 return false; |
| 232 } | 232 } |
| 233 async_receive_desc = plugin()->wrapper_factory()->MakeImcSock(receive_handle); | 233 async_receive_desc = plugin()->wrapper_factory()->MakeImcSock(receive_handle); |
| 234 | 234 |
| 235 nacl::Handle send_handle = subprocess_->ExportImcFD(7); | 235 nacl::Handle send_handle = subprocess_->ExportImcFD(7); |
| 236 if (send_handle == nacl::kInvalidHandle) { | 236 if (send_handle == nacl::kInvalidHandle) { |
| 237 browser_interface_->Alert(plugin()->instance_id(), | 237 browser_interface_->AddToConsole(plugin()->instance_id(), |
| 238 "Failed to create async send handle"); | 238 "Failed to create async send handle"); |
| 239 return false; | 239 return false; |
| 240 } | 240 } |
| 241 async_send_desc = plugin()->wrapper_factory()->MakeImcSock(send_handle); | 241 async_send_desc = plugin()->wrapper_factory()->MakeImcSock(send_handle); |
| 242 | 242 |
| 243 nacl::Handle bootstrap_socket = subprocess_->ExportImcFD(5); | 243 nacl::Handle bootstrap_socket = subprocess_->ExportImcFD(5); |
| 244 if (bootstrap_socket == nacl::kInvalidHandle) { | 244 if (bootstrap_socket == nacl::kInvalidHandle) { |
| 245 browser_interface_->Alert(plugin()->instance_id(), | 245 browser_interface_->AddToConsole(plugin()->instance_id(), |
| 246 "Failed to create socket handle"); | 246 "Failed to create socket handle"); |
| 247 return false; | 247 return false; |
| 248 } | 248 } |
| 249 | 249 |
| 250 if (!subprocess_->Launch()) { | 250 if (!subprocess_->Launch()) { |
| 251 const char* error = "could not start SelLdrLauncher"; | 251 const char* error = "could not start SelLdrLauncher"; |
| 252 PLUGIN_PRINTF(("ServiceRuntime::Start (%s)\n", error)); | 252 PLUGIN_PRINTF(("ServiceRuntime::Start (%s)\n", error)); |
| 253 browser_interface_->Alert(plugin()->instance_id(), error); | 253 browser_interface_->AddToConsole(plugin()->instance_id(), error); |
| 254 delete subprocess_; | 254 delete subprocess_; |
| 255 subprocess_ = NULL; | 255 subprocess_ = NULL; |
| 256 return false; | 256 return false; |
| 257 } | 257 } |
| 258 | 258 |
| 259 // TODO(gregoryd) - this should deal with buffer and size correctly | 259 // TODO(gregoryd) - this should deal with buffer and size correctly |
| 260 // - do we need to send the load command from here? | 260 // - do we need to send the load command from here? |
| 261 if (!InitCommunication(bootstrap_socket, NULL)) { | 261 if (!InitCommunication(bootstrap_socket, NULL)) { |
| 262 return false; | 262 return false; |
| 263 } | 263 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 retval = browser_interface_->NewScriptableHandle( | 378 retval = browser_interface_->NewScriptableHandle( |
| 379 SocketAddress::New(plugin, descs[0])); | 379 SocketAddress::New(plugin, descs[0])); |
| 380 cleanup: | 380 cleanup: |
| 381 imc_desc->Delete(); | 381 imc_desc->Delete(); |
| 382 PLUGIN_PRINTF(("ServiceRuntime::GetSocketAddress (return %p)\n", | 382 PLUGIN_PRINTF(("ServiceRuntime::GetSocketAddress (return %p)\n", |
| 383 static_cast<void*>(retval))); | 383 static_cast<void*>(retval))); |
| 384 return retval; | 384 return retval; |
| 385 } | 385 } |
| 386 | 386 |
| 387 } // namespace plugin | 387 } // namespace plugin |
| OLD | NEW |