summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc15
-rw-r--r--chrome/nacl/nacl_listener.cc18
-rw-r--r--chrome/renderer/chrome_ppapi_interfaces.cc19
-rw-r--r--content/common/sandbox_policy.cc12
-rw-r--r--content/public/common/sandbox_init.h9
-rw-r--r--ppapi/c/private/ppb_nacl_private.h20
-rw-r--r--ppapi/native_client/src/trusted/plugin/module_ppapi.cc8
-rw-r--r--ppapi/native_client/src/trusted/plugin/service_runtime.cc33
8 files changed, 99 insertions, 35 deletions
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index 4bf5b40..a804c8c 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -50,6 +50,7 @@
#include "base/threading/thread.h"
#include "base/process_util.h"
#include "chrome/browser/nacl_host/nacl_broker_service_win.h"
+#include "content/public/common/sandbox_init.h"
#include "native_client/src/trusted/service_runtime/win/debug_exception_handler.h"
#endif
@@ -918,6 +919,9 @@ bool NaClProcessHost::SendStart() {
const ChildProcessData& data = process_->GetData();
#if defined(OS_WIN)
// Copy the process handle into the renderer process.
+ // TODO(mseaborn): Remove this. The renderer process uses this
+ // handle with NaCl's handle_pass module, but we are replacing
+ // handle_pass with Chrome's BrokerDuplicateHandle() function.
if (!DuplicateHandle(base::GetCurrentProcessHandle(),
data.handle,
chrome_render_message_filter_->peer_handle(),
@@ -928,6 +932,17 @@ bool NaClProcessHost::SendStart() {
DLOG(ERROR) << "DuplicateHandle() failed";
return false;
}
+ // If we are on 64-bit Windows, the NaCl process's sandbox is
+ // managed by a different process from the renderer's sandbox. We
+ // need to inform the renderer's sandbox about the NaCl process so
+ // that the renderer can send handles to the NaCl process using
+ // BrokerDuplicateHandle().
+ if (RunningOnWOW64()) {
+ if (!content::BrokerAddTargetPeer(data.handle)) {
+ DLOG(ERROR) << "Failed to add NaCl process PID";
+ return false;
+ }
+ }
#else
// We use pid as process handle on Posix
nacl_process_handle = data.handle;
diff --git a/chrome/nacl/nacl_listener.cc b/chrome/nacl/nacl_listener.cc
index d0e0a8a..b82ca0f 100644
--- a/chrome/nacl/nacl_listener.cc
+++ b/chrome/nacl/nacl_listener.cc
@@ -26,6 +26,8 @@
#if defined(OS_WIN)
#include <fcntl.h>
#include <io.h>
+
+#include "content/public/common/sandbox_init.h"
#endif
namespace {
@@ -67,6 +69,19 @@ int CreateMemoryObject(size_t size, int executable) {
return content::MakeSharedMemorySegmentViaIPC(size, executable);
}
+#elif defined(OS_WIN)
+
+// We wrap the function to convert the bool return value to an int.
+int BrokerDuplicateHandle(NaClHandle source_handle,
+ uint32_t process_id,
+ NaClHandle* target_handle,
+ uint32_t desired_access,
+ uint32_t options) {
+ return content::BrokerDuplicateHandle(source_handle, process_id,
+ target_handle, desired_access,
+ options);
+}
+
#endif
// Use an env var because command line args are eaten by nacl_helper.
@@ -203,6 +218,9 @@ void NaClListener::OnStartSelLdr(std::vector<nacl::FileDescriptor> handles,
args->imc_bootstrap_handle = nacl::ToNativeHandle(handles[0]);
args->enable_exception_handling = enable_exception_handling;
args->enable_debug_stub = debug_enabled_;
+#if defined(OS_WIN)
+ args->broker_duplicate_handle_func = BrokerDuplicateHandle;
+#endif
NaClChromeMainStart(args);
NOTREACHED();
}
diff --git a/chrome/renderer/chrome_ppapi_interfaces.cc b/chrome/renderer/chrome_ppapi_interfaces.cc
index 321f86b..2430391 100644
--- a/chrome/renderer/chrome_ppapi_interfaces.cc
+++ b/chrome/renderer/chrome_ppapi_interfaces.cc
@@ -23,6 +23,10 @@
#include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h"
#endif
+#if defined(OS_WIN)
+#include "content/public/common/sandbox_init.h"
+#endif
+
using content::RenderThread;
namespace chrome {
@@ -78,11 +82,26 @@ void EnableBackgroundSelLdrLaunch() {
RenderThread::Get()->GetSyncMessageFilter();
}
+int BrokerDuplicateHandle(void* source_handle,
+ unsigned int process_id,
+ void** target_handle,
+ unsigned int desired_access,
+ unsigned int options) {
+#if defined(OS_WIN)
+ return content::BrokerDuplicateHandle(source_handle, process_id,
+ target_handle, desired_access,
+ options);
+#else
+ return 0;
+#endif
+}
+
const PPB_NaCl_Private ppb_nacl = {
&LaunchSelLdr,
&UrandomFD,
&Are3DInterfacesDisabled,
&EnableBackgroundSelLdrLaunch,
+ &BrokerDuplicateHandle,
};
class PPB_NaCl_Impl {
diff --git a/content/common/sandbox_policy.cc b/content/common/sandbox_policy.cc
index 756da45..a4b182e 100644
--- a/content/common/sandbox_policy.cc
+++ b/content/common/sandbox_policy.cc
@@ -407,6 +407,14 @@ bool AddPolicyForRenderer(sandbox::TargetPolicy* policy) {
if (result != sandbox::SBOX_ALL_OK)
return false;
+ // Renderers need to send named pipe handles and shared memory
+ // segment handles to NaCl loader processes.
+ result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
+ sandbox::TargetPolicy::HANDLES_DUP_ANY,
+ L"File");
+ if (result != sandbox::SBOX_ALL_OK)
+ return false;
+
policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED;
@@ -696,4 +704,8 @@ bool BrokerDuplicateHandle(HANDLE source_handle,
return false;
}
+bool BrokerAddTargetPeer(HANDLE peer_process) {
+ return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK;
+}
+
} // namespace content
diff --git a/content/public/common/sandbox_init.h b/content/public/common/sandbox_init.h
index 8952323..24da5a9 100644
--- a/content/public/common/sandbox_init.h
+++ b/content/public/common/sandbox_init.h
@@ -42,6 +42,15 @@ CONTENT_EXPORT bool BrokerDuplicateHandle(HANDLE source_handle,
DWORD desired_access,
DWORD options);
+// Inform the current process's sandbox broker (e.g. the broker for
+// 32-bit processes) about a process created under a different sandbox
+// broker (e.g. the broker for 64-bit processes). This allows
+// BrokerDuplicateHandle() to send handles to a process managed by
+// another broker. For example, it allows the 32-bit renderer to send
+// handles to 64-bit NaCl processes. This returns true on success,
+// false otherwise.
+CONTENT_EXPORT bool BrokerAddTargetPeer(HANDLE peer_process);
+
#elif defined(OS_MACOSX)
// Initialize the sandbox of the given |sandbox_type|, optionally specifying a
diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h
index e275a90..939f37f 100644
--- a/ppapi/c/private/ppb_nacl_private.h
+++ b/ppapi/c/private/ppb_nacl_private.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,7 +8,7 @@
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_stdint.h"
-#define PPB_NACL_PRIVATE_INTERFACE "PPB_NaCl(Private);0.2"
+#define PPB_NACL_PRIVATE_INTERFACE "PPB_NaCl(Private);0.3"
struct PPB_NaCl_Private {
// This function launches NaCl's sel_ldr process. On success, the function
@@ -33,6 +33,22 @@ struct PPB_NaCl_Private {
// Enables the creation of sel_ldr processes from other than the main thread.
void (*EnableBackgroundSelLdrLaunch)();
+
+ // This is Windows-specific. This is a replacement for
+ // DuplicateHandle() for use inside the Windows sandbox. Note that
+ // we provide this via dependency injection only to avoid the
+ // linkage problems that occur because the NaCl plugin is built as a
+ // separate DLL/DSO (see
+ // http://code.google.com/p/chromium/issues/detail?id=114439#c8).
+ // We use void* rather than the Windows HANDLE type to avoid an
+ // #ifdef here. We use int rather than PP_Bool/bool so that this is
+ // usable with NaClSetBrokerDuplicateHandleFunc() without further
+ // wrapping.
+ int (*BrokerDuplicateHandle)(void* source_handle,
+ uint32_t process_id,
+ void** target_handle,
+ uint32_t desired_access,
+ uint32_t options);
};
#endif // PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
diff --git a/ppapi/native_client/src/trusted/plugin/module_ppapi.cc b/ppapi/native_client/src/trusted/plugin/module_ppapi.cc
index bb2acfd..d292121 100644
--- a/ppapi/native_client/src/trusted/plugin/module_ppapi.cc
+++ b/ppapi/native_client/src/trusted/plugin/module_ppapi.cc
@@ -4,6 +4,7 @@
* found in the LICENSE file.
*/
+#include "native_client/src/shared/imc/nacl_imc_c.h"
#include "native_client/src/shared/platform/nacl_time.h"
#include "native_client/src/trusted/desc/nrd_all_modules.h"
#include "native_client/src/trusted/handle_pass/browser_handle.h"
@@ -56,8 +57,15 @@ class ModulePpapi : public pp::Module {
NaClSrpcModuleInit();
#if NACL_WINDOWS && !defined(NACL_STANDALONE)
+ // TODO(mseaborn): Remove this call because NaCl's handle_pass
+ // module is replaced by Chrome's BrokerDuplicateHandle()
+ // function. The call to NaClHandlePassBrowserRememberHandle() on
+ // the NaCl side will have to be removed first.
NaClHandlePassBrowserInit();
+
+ NaClSetBrokerDuplicateHandleFunc(private_interface_->BrokerDuplicateHandle);
#endif
+
init_was_successful_ = true;
return true;
}
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
index af78722b..dc0eee7 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
@@ -595,39 +595,6 @@ bool ServiceRuntime::InitCommunication(nacl::DescWrapper* nacl_desc,
return false;
}
-#if NACL_WINDOWS && !defined(NACL_STANDALONE)
- // Establish the communication for handle passing protocol
- struct NaClDesc* desc = NaClHandlePassBrowserGetSocketAddress();
-
- DWORD my_pid = GetCurrentProcessId();
- nacl::Handle my_handle = GetCurrentProcess();
- nacl::Handle my_handle_in_selldr;
-
- if (!DuplicateHandle(GetCurrentProcess(),
- my_handle,
- subprocess_->child_process(),
- &my_handle_in_selldr,
- PROCESS_DUP_HANDLE,
- FALSE,
- 0)) {
- error_info->SetReport(ERROR_SEL_LDR_HANDLE_PASSING,
- "ServiceRuntime: failed handle passing protocol");
- return false;
- }
-
- rpc_result =
- NaClSrpcInvokeBySignature(&command_channel_,
- "init_handle_passing:hii:",
- desc,
- my_pid,
- reinterpret_cast<int>(my_handle_in_selldr));
-
- if (NACL_SRPC_RESULT_OK != rpc_result) {
- error_info->SetReport(ERROR_SEL_LDR_HANDLE_PASSING,
- "ServiceRuntime: failed handle passing protocol");
- return false;
- }
-#endif
// start the module. otherwise we cannot connect for multimedia
// subsystem since that is handled by user-level code (not secure!)
// in libsrpc.