15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2012 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define NACL_LOG_MODULE_NAME "Plugin_ServiceRuntime" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/service_runtime.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/portability_io.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/portability_string.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/nacl_macros.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/nacl_scoped_ptr.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/platform/nacl_check.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/platform/nacl_log.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/platform/nacl_sync.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/platform/nacl_sync_checked.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/platform/nacl_sync_raii.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "native_client/src/public/imc_types.h" 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "native_client/src/public/nacl_file_info.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/service_runtime/nacl_error_code.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/core.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/completion_callback.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/plugin.h" 37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/plugin_error.h" 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h" 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/srpc_client.h" 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/native_client/src/trusted/plugin/utility.h" 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/weak_ref/call_on_main_thread.h" 43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace plugin { 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)OpenManifestEntryResource::~OpenManifestEntryResource() { 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginReverseInterface::PluginReverseInterface( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl::WeakRefAnchor* anchor, 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_Instance pp_instance, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceRuntime* service_runtime, 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pp::CompletionCallback init_done_cb) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : anchor_(anchor), 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pp_instance_(pp_instance), 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_runtime_(service_runtime), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutting_down_(false), 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci init_done_cb_(init_done_cb) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClXMutexCtor(&mu_); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClXCondVarCtor(&cv_); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginReverseInterface::~PluginReverseInterface() { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClCondVarDtor(&cv_); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClMutexDtor(&mu_); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginReverseInterface::ShutDown() { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, "PluginReverseInterface::Shutdown: entered\n"); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl::MutexLocker take(&mu_); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutting_down_ = true; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClXCondVarBroadcast(&cv_); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, "PluginReverseInterface::Shutdown: broadcasted, exiting\n"); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PluginReverseInterface::DoPostMessage(std::string message) { 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This feature is no longer used. 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(teravest): Remove this once this is gone from nacl::ReverseInterface. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginReverseInterface::StartupInitializationComplete() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, "PluginReverseInterface::StartupInitializationComplete\n"); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (init_done_cb_.pp_completion_callback().func != NULL) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "PluginReverseInterface::StartupInitializationComplete:" 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " invoking CB\n"); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->core()->CallOnMainThread(0, init_done_cb_, PP_OK); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(1, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "PluginReverseInterface::StartupInitializationComplete:" 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " init_done_cb_ not valid, skipping.\n"); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(bsy): OpenManifestEntry should use the manifest to ResolveKey 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and invoke StreamAsFile with a completion callback that invokes 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetPOSIXFileDesc. 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool PluginReverseInterface::OpenManifestEntry(std::string url_key, 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct NaClFileInfo* info) { 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This method should only ever be called from the PNaCl translator, as the 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // IRT is not available there. 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(teravest): Remove support for OpenManifestEntry here once 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // crbug.com/302078 is resolved. 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (service_runtime_->main_service_runtime()) { 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NaClLog(LOG_ERROR, 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "OpenManifestEntry should only be used by PNaCl translator.\n"); 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool op_complete = false; // NB: mu_ and cv_ also controls access to this! 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The to_open object is owned by the weak ref callback. Because this function 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // waits for the callback to finish, the to_open object will be deallocated on 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the main thread before this function can return. The pointers it contains 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // to stack variables will not leak. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenManifestEntryResource* to_open = 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new OpenManifestEntryResource(url_key, info, &op_complete); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(to_open != NULL); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n", 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_key.c_str()); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This assumes we are not on the main thread. If false, we deadlock. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin::WeakRefCallOnMainThread( 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &plugin::PluginReverseInterface::OpenManifestEntry_MainThreadContinuation, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_open); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "PluginReverseInterface::OpenManifestEntry:" 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " waiting on main thread\n"); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl::MutexLocker take(&mu_); 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (!shutting_down_ && !op_complete) 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NaClXCondVarWait(&cv_, &mu_); 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NaClLog(4, "PluginReverseInterface::OpenManifestEntry: done!\n"); 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (shutting_down_) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "PluginReverseInterface::OpenManifestEntry:" 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " plugin is shutting down\n"); 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // info->desc has the returned descriptor if successful, else -1. 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The caller is responsible for not closing info->desc. If it is 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // closed prematurely, then another open could re-use the OS 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptor, confusing the opened_ map. If the caller is going to 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // want to make a NaClDesc object and transfer it etc., then the 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // caller should DUP the descriptor (but remember the original 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value) for use by the NaClDesc object, which closes when the 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object is destroyed. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "PluginReverseInterface::OpenManifestEntry: info->desc = %d\n", 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) info->desc); 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (info->desc == -1) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(bsy,ncbray): what else should we do with the error? This 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is a runtime error that may simply be a programming error in 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the untrusted code, or it may be something else wrong w/ the 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest. 16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NaClLog(4, "OpenManifestEntry: failed for key %s", url_key.c_str()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Transfer point from OpenManifestEntry() which runs on the main thread 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (Some PPAPI actions -- like StreamAsFile -- can only run on the main thread). 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OpenManifestEntry() is waiting on a condvar for this continuation to 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// complete. We Broadcast and awaken OpenManifestEntry() whenever we are done 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// either here, or in a later MainThreadContinuation step, if there are 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multiple steps. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenManifestEntryResource* p, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t err) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(err); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CallOnMainThread continuations always called with err == PP_OK. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n"); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Because p is owned by the callback of this invocation, so it is necessary 181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // to create another instance. 182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OpenManifestEntryResource* open_cont = new OpenManifestEntryResource(*p); 183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch pp::CompletionCallback stream_cc = WeakRefNewCallback( 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch anchor_, 185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this, 186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &PluginReverseInterface::StreamAsFile_MainThreadContinuation, 187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch open_cont); 188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetNaClInterface()->OpenManifestEntry( 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pp_instance_, 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(!service_runtime_->main_service_runtime()), 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch p->url.c_str(), 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &open_cont->pp_file_info, 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch stream_cc.pp_completion_callback()); 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // p is deleted automatically. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginReverseInterface::StreamAsFile_MainThreadContinuation( 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenManifestEntryResource* p, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result) { 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NaClLog(4, "Entered StreamAsFile_MainThreadContinuation\n"); 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) nacl::MutexLocker take(&mu_); 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result == PP_OK) { 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We downloaded this file to temporary storage for this plugin; it's 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // reasonable to provide a file descriptor with write access. 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) p->file_info->desc = ConvertFileDescriptor(p->pp_file_info.handle, false); 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) p->file_info->file_token.lo = p->pp_file_info.token_lo; 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) p->file_info->file_token.hi = p->pp_file_info.token_hi; 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NaClLog(4, 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n", 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) p->file_info->desc); 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NaClLog( 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 4, 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n"); 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) p->file_info->desc = -1; 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *p->op_complete_ptr = true; 220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NaClXCondVarBroadcast(&cv_); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginReverseInterface::ReportCrash() { 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This is now handled through Chromium IPC. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginReverseInterface::ReportExitStatus(int exit_status) { 22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // We do nothing here; reporting exit status is handled through a separate 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // embedder interface. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64_t PluginReverseInterface::RequestQuotaForWrite( 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string file_id, int64_t offset, int64_t bytes_to_write) { 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return bytes_to_write; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceRuntime::ServiceRuntime(Plugin* plugin, 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_Instance pp_instance, 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool main_service_runtime, 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool uses_nonsfi_mode, 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pp::CompletionCallback init_done_cb) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : plugin_(plugin), 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pp_instance_(pp_instance), 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) main_service_runtime_(main_service_runtime), 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uses_nonsfi_mode_(uses_nonsfi_mode), 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reverse_service_(NULL), 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_(new nacl::WeakRefAnchor()), 249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rev_interface_(new PluginReverseInterface(anchor_, pp_instance, this, 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci init_done_cb)), 25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) start_sel_ldr_done_(false), 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch start_nexe_done_(false), 253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch nexe_started_ok_(false), 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bootstrap_channel_(NACL_INVALID_HANDLE) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClSrpcChannelInitialize(&command_channel_); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClXMutexCtor(&mu_); 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NaClXCondVarCtor(&cond_); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceRuntime::SetupCommandChannel() { 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NaClLog(4, "ServiceRuntime::SetupCommand (this=%p, subprocess=%p)\n", 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<void*>(this), 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<void*>(subprocess_.get())); 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Set up the bootstrap channel in our subprocess so that we can establish 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // SRPC. 266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch subprocess_->set_channel(bootstrap_channel_); 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (uses_nonsfi_mode_) { 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // In non-SFI mode, no SRPC is used. Just skips and returns success. 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!subprocess_->SetupCommand(&command_channel_)) { 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ErrorInfo error_info; 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL, 276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "ServiceRuntime: command channel creation failed"); 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReportLoadError(error_info); 278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceRuntime::InitReverseService() { 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (uses_nonsfi_mode_) { 2850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // In non-SFI mode, no reverse service is set up. Just returns success. 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hook up the reverse service channel. We are the IMC client, but 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provide SRPC service. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClDesc* out_conn_cap; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClSrpcResultCodes rpc_result = 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClSrpcInvokeBySignature(&command_channel_, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "reverse_setup::h", 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &out_conn_cap); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NACL_SRPC_RESULT_OK != rpc_result) { 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorInfo error_info; 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_REV_SETUP, 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "ServiceRuntime: reverse setup rpc failed"); 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReportLoadError(error_info); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get connection capability to service runtime where the IMC 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // server/SRPC client is waiting for a rendezvous. 306bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch NaClLog(4, "ServiceRuntime: got 0x%" NACL_PRIxPTR "\n", 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (uintptr_t) out_conn_cap); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl::DescWrapper* conn_cap = plugin_->wrapper_factory()->MakeGenericCleanup( 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_conn_cap); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (conn_cap == NULL) { 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorInfo error_info; 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_WRAPPER, 313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "ServiceRuntime: wrapper allocation failure"); 314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReportLoadError(error_info); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_conn_cap = NULL; // ownership passed 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NaClLog(4, "ServiceRuntime::InitReverseService: starting reverse service\n"); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reverse_service_ = new nacl::ReverseService(conn_cap, rev_interface_->Ref()); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reverse_service_->Start()) { 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorInfo error_info; 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_REV_SERVICE, 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "ServiceRuntime: starting reverse services failed"); 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReportLoadError(error_info); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceRuntime::StartModule() { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // start the module. otherwise we cannot connect for multimedia 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subsystem since that is handled by user-level code (not secure!) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in libsrpc. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int load_status = -1; 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (uses_nonsfi_mode_) { 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // In non-SFI mode, we don't need to call start_module SRPC to launch 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the plugin. 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) load_status = LOAD_OK; 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NaClSrpcResultCodes rpc_result = 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NaClSrpcInvokeBySignature(&command_channel_, 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "start_module::i", 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &load_status); 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (NACL_SRPC_RESULT_OK != rpc_result) { 346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorInfo error_info; 347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_info.SetReport(PP_NACL_ERROR_SEL_LDR_START_MODULE, 348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "ServiceRuntime: could not start nacl module"); 349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReportLoadError(error_info); 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NaClLog(4, "ServiceRuntime::StartModule (load_status=%d)\n", load_status); 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (main_service_runtime_) { 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (load_status < 0 || load_status > NACL_ERROR_CODE_MAX) 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) load_status = LOAD_STATUS_UNKNOWN; 358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetNaClInterface()->ReportSelLdrStatus(pp_instance_, 35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) load_status, 36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NACL_ERROR_CODE_MAX); 36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LOAD_OK != load_status) { 364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorInfo error_info; 365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_info.SetReport( 366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_NACL_ERROR_SEL_LDR_START_STATUS, 367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NaClErrorString(static_cast<NaClErrorCode>(load_status))); 368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReportLoadError(error_info); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceRuntime::StartSelLdr(const SelLdrStartParams& params, 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::CompletionCallback callback) { 3767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NaClLog(4, "ServiceRuntime::Start\n"); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl::scoped_ptr<SelLdrLauncherChrome> 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_subprocess(new SelLdrLauncherChrome()); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == tmp_subprocess.get()) { 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NaClLog(LOG_ERROR, "ServiceRuntime::Start (subprocess create failed)\n"); 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorInfo error_info; 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_info.SetReport( 384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_NACL_ERROR_SEL_LDR_CREATE_LAUNCHER, 385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "ServiceRuntime: failed to create sel_ldr launcher"); 386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReportLoadError(error_info); 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Module::Get()->core()->CallOnMainThread(0, callback, PP_ERROR_FAILED); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool enable_dev_interfaces = 392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetNaClInterface()->DevInterfacesEnabled(pp_instance_); 393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetNaClInterface()->LaunchSelLdr( 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pp_instance_, 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(main_service_runtime_), 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.url.c_str(), 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ¶ms.file_info, 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(params.uses_irt), 400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(params.uses_ppapi), 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(uses_nonsfi_mode_), 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(enable_dev_interfaces), 403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(params.enable_dyncode_syscalls), 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(params.enable_exception_handling), 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_FromBool(params.enable_crash_throttling), 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &bootstrap_channel_, 407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback.pp_completion_callback()); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subprocess_.reset(tmp_subprocess.release()); 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 411a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool ServiceRuntime::WaitForSelLdrStart() { 412a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Time to wait on condvar (for browser to create a new sel_ldr process on 413a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // our behalf). Use 6 seconds to be *fairly* conservative. 414a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // 415a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // On surfaway, the CallOnMainThread above may never get scheduled 416a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // to unblock this condvar, or the IPC reply from the browser to renderer 417a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // might get canceled/dropped. However, it is currently important to 418a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // avoid waiting indefinitely because ~PnaclCoordinator will attempt to 419a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // join() the PnaclTranslateThread, and the PnaclTranslateThread is waiting 420a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // for the signal before exiting. 421a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch static int64_t const kWaitTimeMicrosecs = 6 * NACL_MICROS_PER_UNIT; 422a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int64_t left_to_wait = kWaitTimeMicrosecs; 423a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int64_t deadline = NaClGetTimeOfDayMicroseconds() + left_to_wait; 4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch nacl::MutexLocker take(&mu_); 425a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch while(!start_sel_ldr_done_ && left_to_wait > 0) { 426a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch struct nacl_abi_timespec left_timespec; 427a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch left_timespec.tv_sec = left_to_wait / NACL_MICROS_PER_UNIT; 428a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch left_timespec.tv_nsec = 429a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (left_to_wait % NACL_MICROS_PER_UNIT) * NACL_NANOS_PER_MICRO; 430a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NaClXCondVarTimedWaitRelative(&cond_, &mu_, &left_timespec); 431a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int64_t now = NaClGetTimeOfDayMicroseconds(); 432a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch left_to_wait = deadline - now; 4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 434a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return start_sel_ldr_done_; 4357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ServiceRuntime::SignalStartSelLdrDone() { 4387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch nacl::MutexLocker take(&mu_); 4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch start_sel_ldr_done_ = true; 4407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NaClXCondVarSignal(&cond_); 4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 443116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ServiceRuntime::WaitForNexeStart() { 44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) nacl::MutexLocker take(&mu_); 445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (!start_nexe_done_) 44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NaClXCondVarWait(&cond_, &mu_); 447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return nexe_started_ok_; 44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 450116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceRuntime::SignalNexeStarted(bool ok) { 45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) nacl::MutexLocker take(&mu_); 452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch start_nexe_done_ = true; 453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch nexe_started_ok_ = ok; 45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NaClXCondVarSignal(&cond_); 45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceRuntime::StartNexe() { 4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool ok = StartNexeInternal(); 459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (ok) { 4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NaClLog(4, "ServiceRuntime::StartNexe (success)\n"); 461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReapLogs(); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // This only matters if a background thread is waiting, but we signal in all 465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // cases to simplify the code. 466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SignalNexeStarted(ok); 467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ServiceRuntime::StartNexeInternal() { 4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!SetupCommandChannel()) 471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!InitReverseService()) 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return StartModule(); 475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceRuntime::ReapLogs() { 4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(teravest): We should allow the NaCl process to crash itself when a 4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // module fails to start, and remove the call to RemoteLog() here. The 4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // reverse channel is no longer needed for crash reporting. 4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The reasoning behind the current code behavior follows: 4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // On a load failure the NaCl process does not crash itself to 484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // avoid a race where the no-more-senders error on the reverse 485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // channel service thread might cause the crash-detection logic to 486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // kick in before the start_module RPC reply has been received. So 4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // we induce a NaCl process crash here. 488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RemoteLog(LOG_FATAL, "reap logs\n"); 4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(teravest): Release subprocess_ here since it's no longer needed. It 4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // was previously kept around to collect crash log output from the bootstrap 4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // channel. 493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 495116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceRuntime::ReportLoadError(const ErrorInfo& error_info) { 496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (main_service_runtime_) { 497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch plugin_->ReportLoadError(error_info); 498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SrpcClient* ServiceRuntime::SetupAppChannel() { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NaClLog(4, "ServiceRuntime::SetupAppChannel (subprocess_=%p)\n", 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<void*>(subprocess_.get())); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl::DescWrapper* connect_desc = subprocess_->socket_addr()->Connect(); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == connect_desc) { 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NaClLog(LOG_ERROR, "ServiceRuntime::SetupAppChannel (connect failed)\n"); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NaClLog(4, "ServiceRuntime::SetupAppChannel (conect_desc=%p)\n", 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<void*>(connect_desc)); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrpcClient* srpc_client = SrpcClient::New(connect_desc); 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NaClLog(4, "ServiceRuntime::SetupAppChannel (srpc_client=%p)\n", 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<void*>(srpc_client)); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete connect_desc; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return srpc_client; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ServiceRuntime::RemoteLog(int severity, const std::string& msg) { 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClSrpcResultCodes rpc_result = 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClSrpcInvokeBySignature(&command_channel_, 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "log:is:", 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) severity, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strdup(msg.c_str())); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NACL_SRPC_RESULT_OK == rpc_result); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServiceRuntime::Shutdown() { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rev_interface_->ShutDown(); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_->Abandon(); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Abandon callbacks, tell service threads to quit if they were 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // blocked waiting for main thread operations to finish. Note that 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // some callbacks must still await their completion event, e.g., 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CallOnMainThread must still wait for the time out, or I/O events 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must finish, so resources associated with pending events cannot 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be deallocated. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this does waitpid() to get rid of any zombie subprocess. 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subprocess_.reset(NULL); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClSrpcDtor(&command_channel_); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subprocess_ has been shut down, but threads waiting on messages 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the service runtime may not have noticed yet. The low-level 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NaClSimpleRevService code takes care to refcount the data objects 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that it needs, and reverse_service_ is also refcounted. We wait 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for the service threads to get their EOF indications. 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reverse_service_ != NULL) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reverse_service_->WaitForServiceThreadsToExit(); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reverse_service_->Unref(); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reverse_service_ = NULL; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceRuntime::~ServiceRuntime() { 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NaClLog(4, "ServiceRuntime::~ServiceRuntime (this=%p)\n", 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<void*>(this)); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do this just in case Shutdown() was not called. 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subprocess_.reset(NULL); 560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (reverse_service_ != NULL) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reverse_service_->Unref(); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rev_interface_->Unref(); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_->Unref(); 5667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NaClCondVarDtor(&cond_); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClMutexDtor(&mu_); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace plugin 571