Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / nacl / loader / nacl_listener.cc
index b5ee5f7..e7b8f4c 100644 (file)
 #endif
 
 #if defined(OS_LINUX)
+#include "components/nacl/loader/nonsfi/irt_random.h"
 #include "components/nacl/loader/nonsfi/nonsfi_main.h"
 #include "content/public/common/child_process_sandbox_support_linux.h"
-#include "ppapi/proxy/plugin_main_irt.h"
+#include "ppapi/nacl_irt/plugin_startup.h"
 #endif
 
 #if defined(OS_WIN)
@@ -200,6 +201,7 @@ class BrowserValidationDBProxy : public NaClValidationDB {
 
 NaClListener::NaClListener() : shutdown_event_(true, false),
                                io_thread_("NaCl_IOThread"),
+                               uses_nonsfi_mode_(false),
 #if defined(OS_LINUX)
                                prereserved_sandbox_size_(0),
 #endif
@@ -257,37 +259,50 @@ bool NaClListener::OnMessageReceived(const IPC::Message& msg) {
 }
 
 void NaClListener::OnStart(const nacl::NaClStartParams& params) {
-#if defined(OS_LINUX) || defined(OS_MACOSX)
-  int urandom_fd = dup(base::GetUrandomFD());
-  if (urandom_fd < 0) {
-    LOG(ERROR) << "Failed to dup() the urandom FD";
-    return;
-  }
-  NaClChromeMainSetUrandomFd(urandom_fd);
+#if !defined(OS_LINUX)
+  CHECK(!uses_nonsfi_mode_) << "Non-SFI NaCl is only supported on Linux";
 #endif
 
-  NaClChromeMainInit();
-  struct NaClChromeMainArgs *args = NaClChromeMainArgsCreate();
-  if (args == NULL) {
-    LOG(ERROR) << "NaClChromeMainArgsCreate() failed";
-    return;
+  // Random number source initialization.
+#if defined(OS_LINUX)
+  if (uses_nonsfi_mode_) {
+    nacl::nonsfi::SetUrandomFd(base::GetUrandomFD());
+  }
+#endif
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+  if (!uses_nonsfi_mode_) {
+    int urandom_fd = dup(base::GetUrandomFD());
+    if (urandom_fd < 0) {
+      LOG(ERROR) << "Failed to dup() the urandom FD";
+      return;
+    }
+    NaClChromeMainSetUrandomFd(urandom_fd);
   }
+#endif
 
-  struct NaClApp *nap = NaClAppCreate();
-  if (nap == NULL) {
-    LOG(ERROR) << "NaClAppCreate() failed";
-    return;
+  struct NaClApp* nap = NULL;
+  if (!uses_nonsfi_mode_) {
+    NaClChromeMainInit();
+    nap = NaClAppCreate();
+    if (nap == NULL) {
+      LOG(ERROR) << "NaClAppCreate() failed";
+      return;
+    }
   }
 
   IPC::ChannelHandle browser_handle;
   IPC::ChannelHandle ppapi_renderer_handle;
+  IPC::ChannelHandle manifest_service_handle;
 
   if (params.enable_ipc_proxy) {
     browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
     ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
 
 #if defined(OS_LINUX)
-    if (params.uses_nonsfi_mode) {
+    if (uses_nonsfi_mode_) {
+      manifest_service_handle =
+          IPC::Channel::GenerateVerifiedChannelID("nacl");
+
       // In non-SFI mode, we neither intercept nor rewrite the message using
       // NaClIPCAdapter, and the channels are connected between the plugin and
       // the hosts directly. So, the IPC::Channel instances will be created in
@@ -300,23 +315,31 @@ void NaClListener::OnStart(const nacl::NaClStartParams& params) {
       int browser_client_ppapi_fd;
       int renderer_server_ppapi_fd;
       int renderer_client_ppapi_fd;
+      int manifest_service_server_fd;
+      int manifest_service_client_fd;
       if (!IPC::SocketPair(
               &browser_server_ppapi_fd, &browser_client_ppapi_fd) ||
           !IPC::SocketPair(
-              &renderer_server_ppapi_fd, &renderer_client_ppapi_fd)) {
+              &renderer_server_ppapi_fd, &renderer_client_ppapi_fd) ||
+          !IPC::SocketPair(
+              &manifest_service_server_fd, &manifest_service_client_fd)) {
         LOG(ERROR) << "Failed to create sockets for IPC.";
         return;
       }
 
       // Set the plugin IPC channel FDs.
-      SetIPCFileDescriptors(
-          browser_server_ppapi_fd, renderer_server_ppapi_fd);
+      ppapi::SetIPCFileDescriptors(browser_server_ppapi_fd,
+                                   renderer_server_ppapi_fd,
+                                   manifest_service_server_fd);
+      ppapi::StartUpPlugin();
 
       // Send back to the client side IPC channel FD to the host.
       browser_handle.socket =
           base::FileDescriptor(browser_client_ppapi_fd, true);
       ppapi_renderer_handle.socket =
           base::FileDescriptor(renderer_client_ppapi_fd, true);
+      manifest_service_handle.socket =
+          base::FileDescriptor(manifest_service_client_fd, true);
     } else {
 #endif
       // Create the PPAPI IPC channels between the NaCl IRT and the host
@@ -344,11 +367,37 @@ void NaClListener::OnStart(const nacl::NaClStartParams& params) {
       trusted_listener_->TakeClientFileDescriptor(), true);
 #endif
   if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated(
-          browser_handle, ppapi_renderer_handle, trusted_renderer_handle)))
+          browser_handle, ppapi_renderer_handle,
+          trusted_renderer_handle, manifest_service_handle)))
     LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost.";
 
   std::vector<nacl::FileDescriptor> handles = params.handles;
 
+#if defined(OS_LINUX)
+  if (uses_nonsfi_mode_) {
+    // Ensure that the validation cache key (used as an extra input to the
+    // validation cache's hashing) isn't exposed accidentally.
+    CHECK(!params.validation_cache_enabled);
+    CHECK(params.validation_cache_key.size() == 0);
+    CHECK(params.version.size() == 0);
+    // Ensure that a debug stub FD isn't passed through accidentally.
+    CHECK(!params.enable_debug_stub);
+    CHECK(params.debug_stub_server_bound_socket.fd == -1);
+
+    CHECK(!params.uses_irt);
+    CHECK(handles.size() == 1);
+    int imc_bootstrap_handle = nacl::ToNativeHandle(handles[0]);
+    nacl::nonsfi::MainStart(imc_bootstrap_handle);
+    return;
+  }
+#endif
+
+  struct NaClChromeMainArgs* args = NaClChromeMainArgsCreate();
+  if (args == NULL) {
+    LOG(ERROR) << "NaClChromeMainArgsCreate() failed";
+    return;
+  }
+
 #if defined(OS_LINUX) || defined(OS_MACOSX)
   args->number_of_cores = number_of_cores_;
   args->create_memory_object_func = CreateMemoryObject;
@@ -401,7 +450,7 @@ void NaClListener::OnStart(const nacl::NaClStartParams& params) {
     // with PNaCl.  We can't apply this arbitrary limit outside of
     // PNaCl because it might break existing NaCl apps, and this limit
     // is only useful if the dyncode syscalls are disabled.
-    args->initial_nexe_max_code_bytes = 32 << 20;  // 32 MB
+    args->initial_nexe_max_code_bytes = 64 << 20;  // 64 MB
 
     // Indicate that this is a PNaCl module.
     // TODO(jvoung): Plumb through something indicating that this is PNaCl
@@ -420,12 +469,6 @@ void NaClListener::OnStart(const nacl::NaClStartParams& params) {
   args->prereserved_sandbox_size = prereserved_sandbox_size_;
 #endif
 
-#if defined(OS_LINUX)
-  if (params.uses_nonsfi_mode) {
-    nacl::nonsfi::MainStart(args->imc_bootstrap_handle);
-    return;
-  }
-#endif
   NaClChromeMainStartApp(nap, args);
   NOTREACHED();
 }