Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(475)

Side by Side Diff: components/nacl/loader/nacl_listener.cc

Issue 301993003: NaCl: Split out Non-SFI logic when starting NaCl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « components/nacl/loader/nacl_listener.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/nacl/loader/nacl_listener.h" 5 #include "components/nacl/loader/nacl_listener.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 9
10 #if defined(OS_POSIX) 10 #if defined(OS_POSIX)
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 bool NaClListener::OnMessageReceived(const IPC::Message& msg) { 256 bool NaClListener::OnMessageReceived(const IPC::Message& msg) {
257 bool handled = true; 257 bool handled = true;
258 IPC_BEGIN_MESSAGE_MAP(NaClListener, msg) 258 IPC_BEGIN_MESSAGE_MAP(NaClListener, msg)
259 IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart) 259 IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart)
260 IPC_MESSAGE_UNHANDLED(handled = false) 260 IPC_MESSAGE_UNHANDLED(handled = false)
261 IPC_END_MESSAGE_MAP() 261 IPC_END_MESSAGE_MAP()
262 return handled; 262 return handled;
263 } 263 }
264 264
265 void NaClListener::OnStart(const nacl::NaClStartParams& params) { 265 void NaClListener::OnStart(const nacl::NaClStartParams& params) {
266 #if !defined(OS_LINUX) 266 if (uses_nonsfi_mode_) {
267 CHECK(!uses_nonsfi_mode_) << "Non-SFI NaCl is only supported on Linux"; 267 StartNonSfi(params);
268 #endif 268 return;
269 }
269 270
270 // Random number source initialization. 271 #if defined(OS_LINUX) || defined(OS_MACOSX)
271 #if defined(OS_LINUX) 272 int urandom_fd = dup(base::GetUrandomFD());
272 if (uses_nonsfi_mode_) { 273 if (urandom_fd < 0) {
273 nacl::nonsfi::SetUrandomFd(base::GetUrandomFD()); 274 LOG(ERROR) << "Failed to dup() the urandom FD";
275 return;
274 } 276 }
275 #endif 277 NaClChromeMainSetUrandomFd(urandom_fd);
276 #if defined(OS_LINUX) || defined(OS_MACOSX)
277 if (!uses_nonsfi_mode_) {
278 int urandom_fd = dup(base::GetUrandomFD());
279 if (urandom_fd < 0) {
280 LOG(ERROR) << "Failed to dup() the urandom FD";
281 return;
282 }
283 NaClChromeMainSetUrandomFd(urandom_fd);
284 }
285 #endif 278 #endif
286 279
287 struct NaClApp* nap = NULL; 280 struct NaClApp* nap = NULL;
288 if (!uses_nonsfi_mode_) { 281 NaClChromeMainInit();
289 NaClChromeMainInit(); 282 nap = NaClAppCreate();
290 nap = NaClAppCreate(); 283 if (nap == NULL) {
291 if (nap == NULL) { 284 LOG(ERROR) << "NaClAppCreate() failed";
292 LOG(ERROR) << "NaClAppCreate() failed"; 285 return;
293 return;
294 }
295 } 286 }
296 287
297 IPC::ChannelHandle browser_handle; 288 IPC::ChannelHandle browser_handle;
298 IPC::ChannelHandle ppapi_renderer_handle; 289 IPC::ChannelHandle ppapi_renderer_handle;
299 IPC::ChannelHandle manifest_service_handle;
300 290
301 if (params.enable_ipc_proxy) { 291 if (params.enable_ipc_proxy) {
302 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); 292 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
303 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); 293 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
304 294
305 #if defined(OS_LINUX) 295 // Create the PPAPI IPC channels between the NaCl IRT and the host
306 if (uses_nonsfi_mode_) { 296 // (browser/renderer) processes. The IRT uses these channels to
307 manifest_service_handle = 297 // communicate with the host and to initialize the IPC dispatchers.
308 IPC::Channel::GenerateVerifiedChannelID("nacl"); 298 SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(),
309 299 nap, NACL_CHROME_DESC_BASE);
310 // In non-SFI mode, we neither intercept nor rewrite the message using 300 SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(),
311 // NaClIPCAdapter, and the channels are connected between the plugin and 301 nap, NACL_CHROME_DESC_BASE + 1);
312 // the hosts directly. So, the IPC::Channel instances will be created in
313 // the plugin side, because the IPC::Listener needs to live on the
314 // plugin's main thread. However, on initialization (i.e. before loading
315 // the plugin binary), the FD needs to be passed to the hosts. So, here
316 // we create raw FD pairs, and pass the client side FDs to the hosts,
317 // and the server side FDs to the plugin.
318 int browser_server_ppapi_fd;
319 int browser_client_ppapi_fd;
320 int renderer_server_ppapi_fd;
321 int renderer_client_ppapi_fd;
322 int manifest_service_server_fd;
323 int manifest_service_client_fd;
324 if (!IPC::SocketPair(
325 &browser_server_ppapi_fd, &browser_client_ppapi_fd) ||
326 !IPC::SocketPair(
327 &renderer_server_ppapi_fd, &renderer_client_ppapi_fd) ||
328 !IPC::SocketPair(
329 &manifest_service_server_fd, &manifest_service_client_fd)) {
330 LOG(ERROR) << "Failed to create sockets for IPC.";
331 return;
332 }
333
334 // Set the plugin IPC channel FDs.
335 ppapi::SetIPCFileDescriptors(browser_server_ppapi_fd,
336 renderer_server_ppapi_fd,
337 manifest_service_server_fd);
338 ppapi::StartUpPlugin();
339
340 // Send back to the client side IPC channel FD to the host.
341 browser_handle.socket =
342 base::FileDescriptor(browser_client_ppapi_fd, true);
343 ppapi_renderer_handle.socket =
344 base::FileDescriptor(renderer_client_ppapi_fd, true);
345 manifest_service_handle.socket =
346 base::FileDescriptor(manifest_service_client_fd, true);
347 } else {
348 #endif
349 // Create the PPAPI IPC channels between the NaCl IRT and the host
350 // (browser/renderer) processes. The IRT uses these channels to
351 // communicate with the host and to initialize the IPC dispatchers.
352 SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(),
353 nap, NACL_CHROME_DESC_BASE);
354 SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(),
355 nap, NACL_CHROME_DESC_BASE + 1);
356 #if defined(OS_LINUX)
357 }
358 #endif
359 } 302 }
360 303
361 // The argument passed to GenerateVerifiedChannelID() here MUST be "nacl". 304 IPC::ChannelHandle trusted_renderer_handle = CreateTrustedListener(
362 // Using an alternate channel name prevents the pipe from being created on 305 io_thread_.message_loop_proxy(), &shutdown_event_);
363 // Windows when the sandbox is enabled. 306
364 IPC::ChannelHandle trusted_renderer_handle =
365 IPC::Channel::GenerateVerifiedChannelID("nacl");
366 trusted_listener_ = new NaClTrustedListener(
367 trusted_renderer_handle, io_thread_.message_loop_proxy(),
368 &shutdown_event_);
369 #if defined(OS_POSIX)
370 trusted_renderer_handle.socket = base::FileDescriptor(
371 trusted_listener_->TakeClientFileDescriptor(), true);
372 #endif
373 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( 307 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated(
374 browser_handle, ppapi_renderer_handle, 308 browser_handle, ppapi_renderer_handle,
375 trusted_renderer_handle, manifest_service_handle))) 309 trusted_renderer_handle, IPC::ChannelHandle())))
376 LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost."; 310 LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost.";
377 311
378 std::vector<nacl::FileDescriptor> handles = params.handles; 312 std::vector<nacl::FileDescriptor> handles = params.handles;
379
380 #if defined(OS_LINUX)
381 if (uses_nonsfi_mode_) {
382 // Ensure that the validation cache key (used as an extra input to the
383 // validation cache's hashing) isn't exposed accidentally.
384 CHECK(!params.validation_cache_enabled);
385 CHECK(params.validation_cache_key.size() == 0);
386 CHECK(params.version.size() == 0);
387 // Ensure that a debug stub FD isn't passed through accidentally.
388 CHECK(!params.enable_debug_stub);
389 CHECK(params.debug_stub_server_bound_socket.fd == -1);
390
391 CHECK(!params.uses_irt);
392 CHECK(handles.size() == 1);
393 int imc_bootstrap_handle = nacl::ToNativeHandle(handles[0]);
394 nacl::nonsfi::MainStart(imc_bootstrap_handle);
395 return;
396 }
397 #endif
398
399 struct NaClChromeMainArgs* args = NaClChromeMainArgsCreate(); 313 struct NaClChromeMainArgs* args = NaClChromeMainArgsCreate();
400 if (args == NULL) { 314 if (args == NULL) {
401 LOG(ERROR) << "NaClChromeMainArgsCreate() failed"; 315 LOG(ERROR) << "NaClChromeMainArgsCreate() failed";
402 return; 316 return;
403 } 317 }
404 318
405 #if defined(OS_LINUX) || defined(OS_MACOSX) 319 #if defined(OS_LINUX) || defined(OS_MACOSX)
406 args->number_of_cores = number_of_cores_; 320 args->number_of_cores = number_of_cores_;
407 args->create_memory_object_func = CreateMemoryObject; 321 args->create_memory_object_func = CreateMemoryObject;
408 # if defined(OS_MACOSX) 322 # if defined(OS_MACOSX)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 args->debug_stub_server_port_selected_handler_func = 385 args->debug_stub_server_port_selected_handler_func =
472 DebugStubPortSelectedHandler; 386 DebugStubPortSelectedHandler;
473 #endif 387 #endif
474 #if defined(OS_LINUX) 388 #if defined(OS_LINUX)
475 args->prereserved_sandbox_size = prereserved_sandbox_size_; 389 args->prereserved_sandbox_size = prereserved_sandbox_size_;
476 #endif 390 #endif
477 391
478 NaClChromeMainStartApp(nap, args); 392 NaClChromeMainStartApp(nap, args);
479 NOTREACHED(); 393 NOTREACHED();
480 } 394 }
395
396 void NaClListener::StartNonSfi(const nacl::NaClStartParams& params) {
397 #if !defined(OS_LINUX)
398 NOTREACHED() << "Non-SFI NaCl is only supported on Linux";
399 #else
400 // Random number source initialization.
401 nacl::nonsfi::SetUrandomFd(base::GetUrandomFD());
402
403 IPC::ChannelHandle browser_handle;
404 IPC::ChannelHandle ppapi_renderer_handle;
405 IPC::ChannelHandle manifest_service_handle;
406
407 if (params.enable_ipc_proxy) {
408 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
Mark Seaborn 2014/05/30 15:36:29 Optional: I think that using GenerateVerifiedChann
409 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
410 manifest_service_handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
411
412 // In non-SFI mode, we neither intercept nor rewrite the message using
413 // NaClIPCAdapter, and the channels are connected between the plugin and
414 // the hosts directly. So, the IPC::Channel instances will be created in
415 // the plugin side, because the IPC::Listener needs to live on the
416 // plugin's main thread. However, on initialization (i.e. before loading
417 // the plugin binary), the FD needs to be passed to the hosts. So, here
418 // we create raw FD pairs, and pass the client side FDs to the hosts,
419 // and the server side FDs to the plugin.
420 int browser_server_ppapi_fd;
421 int browser_client_ppapi_fd;
422 int renderer_server_ppapi_fd;
423 int renderer_client_ppapi_fd;
424 int manifest_service_server_fd;
425 int manifest_service_client_fd;
426 if (!IPC::SocketPair(
427 &browser_server_ppapi_fd, &browser_client_ppapi_fd) ||
428 !IPC::SocketPair(
429 &renderer_server_ppapi_fd, &renderer_client_ppapi_fd) ||
430 !IPC::SocketPair(
431 &manifest_service_server_fd, &manifest_service_client_fd)) {
432 LOG(ERROR) << "Failed to create sockets for IPC.";
433 return;
434 }
435
436 // Set the plugin IPC channel FDs.
437 ppapi::SetIPCFileDescriptors(browser_server_ppapi_fd,
438 renderer_server_ppapi_fd,
439 manifest_service_server_fd);
440 ppapi::StartUpPlugin();
441
442 // Send back to the client side IPC channel FD to the host.
443 browser_handle.socket =
444 base::FileDescriptor(browser_client_ppapi_fd, true);
445 ppapi_renderer_handle.socket =
446 base::FileDescriptor(renderer_client_ppapi_fd, true);
447 manifest_service_handle.socket =
448 base::FileDescriptor(manifest_service_client_fd, true);
449 }
450
451 IPC::ChannelHandle trusted_renderer_handle = CreateTrustedListener(
Mark Seaborn 2014/05/30 15:36:29 I'm not sure what you have planned for NaClTrusted
452 io_thread_.message_loop_proxy(), &shutdown_event_);
453
454 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated(
455 browser_handle, ppapi_renderer_handle,
456 trusted_renderer_handle, manifest_service_handle)))
457 LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost.";
458
459 // Ensure that the validation cache key (used as an extra input to the
460 // validation cache's hashing) isn't exposed accidentally.
461 CHECK(!params.validation_cache_enabled);
462 CHECK(params.validation_cache_key.size() == 0);
463 CHECK(params.version.size() == 0);
464 // Ensure that a debug stub FD isn't passed through accidentally.
465 CHECK(!params.enable_debug_stub);
466 CHECK(params.debug_stub_server_bound_socket.fd == -1);
467
468 CHECK(!params.uses_irt);
469 CHECK(params.handles.size() == 1);
470 int imc_bootstrap_handle = nacl::ToNativeHandle(params.handles[0]);
471 nacl::nonsfi::MainStart(imc_bootstrap_handle);
472 return;
Mark Seaborn 2014/05/30 15:36:29 return statement is not needed.
473 #endif // defined(OS_LINUX)
474 }
475
476 IPC::ChannelHandle NaClListener::CreateTrustedListener(
477 base::MessageLoopProxy* message_loop_proxy,
478 base::WaitableEvent* shutdown_event) {
479 // The argument passed to GenerateVerifiedChannelID() here MUST be "nacl".
480 // Using an alternate channel name prevents the pipe from being created on
481 // Windows when the sandbox is enabled.
482 IPC::ChannelHandle trusted_renderer_handle =
483 IPC::Channel::GenerateVerifiedChannelID("nacl");
484 trusted_listener_ = new NaClTrustedListener(
485 trusted_renderer_handle, io_thread_.message_loop_proxy(),
486 &shutdown_event_);
487 #if defined(OS_POSIX)
488 trusted_renderer_handle.socket = base::FileDescriptor(
489 trusted_listener_->TakeClientFileDescriptor(), true);
490 #endif
491 return trusted_renderer_handle;
492 }
OLDNEW
« no previous file with comments | « components/nacl/loader/nacl_listener.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698