1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "components/nacl/loader/nacl_listener.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_POSIX) 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <unistd.h> 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 19a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "components/nacl/common/nacl_messages.h" 20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "components/nacl/loader/nacl_ipc_adapter.h" 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "components/nacl/loader/nacl_validation_db.h" 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "components/nacl/loader/nacl_validation_query.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_handle.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_switches.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_channel.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "native_client/src/public/chrome_main.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "native_client/src/public/nacl_app.h" 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "native_client/src/public/nacl_file_info.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_descriptor_posix.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "components/nacl/loader/nonsfi/irt_random.h" 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/nacl/loader/nonsfi/nonsfi_main.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/child_process_sandbox_support_linux.h" 39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ppapi/nacl_irt/plugin_startup.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <io.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/sandbox_init.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Mac OS X, shm_open() works in the sandbox but does not give us 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an FD that we can map as PROT_EXEC. Rather than doing an IPC to 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// get an executable SHM region when CreateMemoryObject() is called, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we preallocate one on startup, since NaCl's sel_ldr only needs one 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of them. This saves a round trip. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::subtle::Atomic32 g_shm_fd = -1; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CreateMemoryObject(size_t size, int executable) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (executable && size > 0) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result_fd = base::subtle::NoBarrier_AtomicExchange(&g_shm_fd, -1); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_fd != -1) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ftruncate() is disallowed by the Mac OS X sandbox and 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns EPERM. Luckily, we can get the same effect with 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lseek() + write(). 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lseek(result_fd, size - 1, SEEK_SET) == -1) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "lseek() failed: " << errno; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write(result_fd, "", 1) != 1) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "write() failed: " << errno; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_fd; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall back to NaCl's default implementation. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_LINUX) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CreateMemoryObject(size_t size, int executable) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return content::MakeSharedMemorySegmentViaIPC(size, executable); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NaClListener* g_listener; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We wrap the function to convert the bool return value to an int. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BrokerDuplicateHandle(NaClHandle source_handle, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t process_id, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClHandle* target_handle, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t desired_access, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t options) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return content::BrokerDuplicateHandle(source_handle, process_id, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_handle, desired_access, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AttachDebugExceptionHandler(const void* info, size_t info_size) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string info_string(reinterpret_cast<const char*>(info), info_size); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = false; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_listener->Send(new NaClProcessMsg_AttachDebugExceptionHandler( 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_string, &result))) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DebugStubPortSelectedHandler(uint16_t port) { 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) g_listener->Send(new NaClProcessHostMsg_DebugStubPortSelected(port)); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Creates the PPAPI IPC channel between the NaCl IRT and the host 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// (browser/renderer) process, and starts to listen it on the thread where 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the given message_loop_proxy runs. 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Also, creates and sets the corresponding NaClDesc to the given nap with 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the FD #. 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SetUpIPCAdapter(IPC::ChannelHandle* handle, 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct NaClApp* nap, 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int nacl_fd) { 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<NaClIPCAdapter> ipc_adapter( 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new NaClIPCAdapter(*handle, message_loop_proxy.get())); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ipc_adapter->ConnectChannel(); 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_POSIX) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) handle->socket = 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FileDescriptor(ipc_adapter->TakeClientFileDescriptor(), true); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Pass a NaClDesc to the untrusted side. This will hold a ref to the 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // NaClIPCAdapter. 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NaClAppSetDesc(nap, nacl_fd, ipc_adapter->MakeNaClDesc()); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserValidationDBProxy : public NaClValidationDB { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit BrowserValidationDBProxy(NaClListener* listener) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : listener_(listener) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool QueryKnownToValidate(const std::string& signature) OVERRIDE { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize to false so that if the Send fails to write to the return 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value we're safe. For example if the message is (for some reason) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dispatched as an async message the return parameter will not be written. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = false; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listener_->Send(new NaClProcessMsg_QueryKnownToValidate(signature, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &result))) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to query NaCl validation cache."; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = false; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetKnownToValidate(const std::string& signature) OVERRIDE { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Caching is optional: NaCl will still work correctly if the IPC fails. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listener_->Send(new NaClProcessMsg_SetKnownToValidate(signature))) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to update NaCl validation cache."; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual bool ResolveFileToken(struct NaClFileToken* file_token, 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int32* fd, std::string* path) OVERRIDE { 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *fd = -1; 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *path = ""; 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!NaClFileTokenIsValid(file_token)) { 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) IPC::PlatformFileForTransit ipc_fd = IPC::InvalidPlatformFileForTransit(); 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath ipc_path; 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!listener_->Send(new NaClProcessMsg_ResolveFileToken(file_token->lo, 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) file_token->hi, 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &ipc_fd, 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &ipc_path))) { 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (ipc_fd == IPC::InvalidPlatformFileForTransit()) { 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::PlatformFile handle = 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) IPC::PlatformFileForTransitToPlatformFile(ipc_fd); 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN) 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // On Windows, valid handles are 32 bit unsigned integers so this is safe. 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *fd = reinterpret_cast<uintptr_t>(handle); 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *fd = handle; 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // It doesn't matter if the path is invalid UTF8 as long as it's consistent 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // and unforgeable. 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *path = ipc_path.AsUTF8Unsafe(); 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The listener never dies, otherwise this might be a dangling reference. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClListener* listener_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NaClListener::NaClListener() : shutdown_event_(true, false), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_("NaCl_IOThread"), 208e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch uses_nonsfi_mode_(false), 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prereserved_sandbox_size_(0), 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_POSIX) 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch number_of_cores_(-1), // unknown/error 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) main_loop_(NULL) { 216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) io_thread_.StartWithOptions( 217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(g_listener == NULL); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_listener = this; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NaClListener::~NaClListener() { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_event_.Signal(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_listener = NULL; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NaClListener::Send(IPC::Message* msg) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_loop_ != NULL); 234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (base::MessageLoop::current() == main_loop_) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This thread owns the channel. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_->Send(msg); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This thread does not own the channel. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return filter_->Send(msg); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NaClListener::Listen() { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string channel_name = 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kProcessChannelID); 24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel_ = IPC::SyncChannel::Create( 24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, io_thread_.message_loop_proxy().get(), &shutdown_event_); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_ = new IPC::SyncMessageFilter(&shutdown_event_); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->AddFilter(filter_.get()); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->Init(channel_name, IPC::Channel::MODE_CLIENT, true); 252a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) main_loop_ = base::MessageLoop::current(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) main_loop_->Run(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NaClListener::OnMessageReceived(const IPC::Message& msg) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(NaClListener, msg) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NaClListener::OnStart(const nacl::NaClStartParams& params) { 266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (uses_nonsfi_mode_) { 26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) StartNonSfi(params); 26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_LINUX) || defined(OS_MACOSX) 27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int urandom_fd = dup(base::GetUrandomFD()); 27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (urandom_fd < 0) { 27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LOG(ERROR) << "Failed to dup() the urandom FD"; 27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NaClChromeMainSetUrandomFd(urandom_fd); 278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct NaClApp* nap = NULL; 28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NaClChromeMainInit(); 28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) nap = NaClAppCreate(); 28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (nap == NULL) { 28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LOG(ERROR) << "NaClAppCreate() failed"; 28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC::ChannelHandle browser_handle; 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC::ChannelHandle ppapi_renderer_handle; 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params.enable_ipc_proxy) { 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Create the PPAPI IPC channels between the NaCl IRT and the host 29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // (browser/renderer) processes. The IRT uses these channels to 29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // communicate with the host and to initialize the IPC dispatchers. 29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(), 29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) nap, NACL_CHROME_DESC_BASE); 30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(), 30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) nap, NACL_CHROME_DESC_BASE + 1); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::ChannelHandle trusted_renderer_handle = CreateTrustedListener( 30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) io_thread_.message_loop_proxy(), &shutdown_event_); 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( 3070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch browser_handle, ppapi_renderer_handle, 30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) trusted_renderer_handle, IPC::ChannelHandle()))) 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost."; 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<nacl::FileDescriptor> handles = params.handles; 312c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct NaClChromeMainArgs* args = NaClChromeMainArgsCreate(); 313c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (args == NULL) { 314c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) << "NaClChromeMainArgsCreate() failed"; 315c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 316c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 317c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_MACOSX) 319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch args->number_of_cores = number_of_cores_; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->create_memory_object_func = CreateMemoryObject; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if defined(OS_MACOSX) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(handles.size() >= 1); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_shm_fd = nacl::ToNativeHandle(handles[handles.size() - 1]); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handles.pop_back(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (params.uses_irt) { 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(handles.size() >= 1); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NaClHandle irt_handle = nacl::ToNativeHandle(handles[handles.size() - 1]); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handles.pop_back(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args->irt_fd = _open_osfhandle(reinterpret_cast<intptr_t>(irt_handle), 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _O_RDONLY | _O_BINARY); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (args->irt_fd < 0) { 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "_open_osfhandle() failed"; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args->irt_fd = irt_handle; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Otherwise, the IRT handle is not even sent. 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args->irt_fd = -1; 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params.validation_cache_enabled) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SHA256 block size. 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(params.validation_cache_key.length(), (size_t) 64); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The cache structure is not freed and exists until the NaCl process exits. 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->validation_cache = CreateValidationCache( 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new BrowserValidationDBProxy(this), params.validation_cache_key, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.version); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(handles.size() == 1); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->imc_bootstrap_handle = nacl::ToNativeHandle(handles[0]); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->enable_exception_handling = params.enable_exception_handling; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->enable_debug_stub = params.enable_debug_stub; 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args->enable_dyncode_syscalls = params.enable_dyncode_syscalls; 362ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!params.enable_dyncode_syscalls) { 363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Bound the initial nexe's code segment size under PNaCl to 364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // reduce the chance of a code spraying attack succeeding (see 365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // https://code.google.com/p/nativeclient/issues/detail?id=3572). 366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // We assume that !params.enable_dyncode_syscalls is synonymous 367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // with PNaCl. We can't apply this arbitrary limit outside of 368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // PNaCl because it might break existing NaCl apps, and this limit 369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // is only useful if the dyncode syscalls are disabled. 3700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch args->initial_nexe_max_code_bytes = 64 << 20; // 64 MB 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Indicate that this is a PNaCl module. 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(jvoung): Plumb through something indicating that this is PNaCl 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // instead of relying on enable_dyncode_syscalls. 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) args->pnacl_mode = 1; 376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_MACOSX) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->debug_stub_server_bound_socket_fd = nacl::ToNativeHandle( 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.debug_stub_server_bound_socket); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->broker_duplicate_handle_func = BrokerDuplicateHandle; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->attach_debug_exception_handler_func = AttachDebugExceptionHandler; 384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) args->debug_stub_server_port_selected_handler_func = 385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DebugStubPortSelectedHandler; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->prereserved_sandbox_size = prereserved_sandbox_size_; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NaClChromeMainStartApp(nap, args); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void NaClListener::StartNonSfi(const nacl::NaClStartParams& params) { 39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if !defined(OS_LINUX) 39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NOTREACHED() << "Non-SFI NaCl is only supported on Linux"; 39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else 39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Random number source initialization. 40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) nacl::nonsfi::SetUrandomFd(base::GetUrandomFD()); 40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::ChannelHandle browser_handle; 40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::ChannelHandle ppapi_renderer_handle; 40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::ChannelHandle manifest_service_handle; 40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (params.enable_ipc_proxy) { 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); 40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); 40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) manifest_service_handle = 41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::Channel::GenerateVerifiedChannelID("nacl"); 41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // In non-SFI mode, we neither intercept nor rewrite the message using 41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // NaClIPCAdapter, and the channels are connected between the plugin and 41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the hosts directly. So, the IPC::Channel instances will be created in 41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the plugin side, because the IPC::Listener needs to live on the 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // plugin's main thread. However, on initialization (i.e. before loading 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the plugin binary), the FD needs to be passed to the hosts. So, here 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // we create raw FD pairs, and pass the client side FDs to the hosts, 41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // and the server side FDs to the plugin. 42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int browser_server_ppapi_fd; 42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int browser_client_ppapi_fd; 42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int renderer_server_ppapi_fd; 42346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int renderer_client_ppapi_fd; 42446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int manifest_service_server_fd; 42546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int manifest_service_client_fd; 42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!IPC::SocketPair( 42746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &browser_server_ppapi_fd, &browser_client_ppapi_fd) || 42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) !IPC::SocketPair( 42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &renderer_server_ppapi_fd, &renderer_client_ppapi_fd) || 43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) !IPC::SocketPair( 43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &manifest_service_server_fd, &manifest_service_client_fd)) { 43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LOG(ERROR) << "Failed to create sockets for IPC."; 43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Set the plugin IPC channel FDs. 43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ppapi::SetIPCFileDescriptors(browser_server_ppapi_fd, 43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) renderer_server_ppapi_fd, 43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) manifest_service_server_fd); 44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ppapi::StartUpPlugin(); 44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Send back to the client side IPC channel FD to the host. 44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) browser_handle.socket = 44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::FileDescriptor(browser_client_ppapi_fd, true); 44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ppapi_renderer_handle.socket = 44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::FileDescriptor(renderer_client_ppapi_fd, true); 44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) manifest_service_handle.socket = 44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::FileDescriptor(manifest_service_client_fd, true); 44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // TODO(teravest): Do we plan on using this renderer handle for nexe loading 45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // for non-SFI? Right now, passing an empty channel handle instead causes 45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // hangs, so we'll keep it. 45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::ChannelHandle trusted_renderer_handle = CreateTrustedListener( 45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) io_thread_.message_loop_proxy(), &shutdown_event_); 45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( 45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) browser_handle, ppapi_renderer_handle, 45846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) trusted_renderer_handle, manifest_service_handle))) 45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost."; 46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Ensure that the validation cache key (used as an extra input to the 46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // validation cache's hashing) isn't exposed accidentally. 46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(!params.validation_cache_enabled); 46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(params.validation_cache_key.size() == 0); 46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(params.version.size() == 0); 46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Ensure that a debug stub FD isn't passed through accidentally. 46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(!params.enable_debug_stub); 46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(params.debug_stub_server_bound_socket.fd == -1); 46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(!params.uses_irt); 47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CHECK(params.handles.size() == 1); 47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int imc_bootstrap_handle = nacl::ToNativeHandle(params.handles[0]); 47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) nacl::nonsfi::MainStart(imc_bootstrap_handle); 47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif // defined(OS_LINUX) 47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 47746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)IPC::ChannelHandle NaClListener::CreateTrustedListener( 47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoopProxy* message_loop_proxy, 47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::WaitableEvent* shutdown_event) { 48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The argument passed to GenerateVerifiedChannelID() here MUST be "nacl". 48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Using an alternate channel name prevents the pipe from being created on 48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Windows when the sandbox is enabled. 48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::ChannelHandle trusted_renderer_handle = 48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::Channel::GenerateVerifiedChannelID("nacl"); 48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) trusted_listener_ = new NaClTrustedListener( 486f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) trusted_renderer_handle, io_thread_.message_loop_proxy().get()); 48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_POSIX) 48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) trusted_renderer_handle.socket = base::FileDescriptor( 48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) trusted_listener_->TakeClientFileDescriptor(), true); 49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return trusted_renderer_handle; 49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 493