| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/nonsfi/nonsfi_main.h" | 5 #include "components/nacl/loader/nonsfi/nonsfi_main.h" |
| 6 | 6 |
| 7 #include "base/debug/leak_annotations.h" | |
| 8 #include "base/logging.h" | 7 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/threading/platform_thread.h" | 9 #include "base/threading/platform_thread.h" |
| 11 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
| 12 #include "components/nacl/loader/nonsfi/elf_loader.h" | 11 #include "components/nacl/loader/nonsfi/elf_loader.h" |
| 13 #include "components/nacl/loader/nonsfi/irt_interfaces.h" | 12 #include "components/nacl/loader/nonsfi/irt_interfaces.h" |
| 14 #include "native_client/src/include/elf_auxv.h" | 13 #include "native_client/src/include/elf_auxv.h" |
| 15 #include "native_client/src/include/nacl_macros.h" | 14 #include "native_client/src/include/nacl_macros.h" |
| 16 #include "native_client/src/public/secure_service.h" | |
| 17 #include "native_client/src/shared/srpc/nacl_srpc.h" | |
| 18 #include "native_client/src/trusted/desc/nacl_desc_base.h" | 15 #include "native_client/src/trusted/desc/nacl_desc_base.h" |
| 19 #include "native_client/src/trusted/desc/nacl_desc_imc.h" | |
| 20 #include "native_client/src/trusted/desc/nrd_all_modules.h" | |
| 21 #include "native_client/src/trusted/desc/nrd_xfer.h" | |
| 22 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" | |
| 23 #include "ppapi/nacl_irt/plugin_startup.h" | |
| 24 | 16 |
| 25 namespace nacl { | 17 namespace nacl { |
| 26 namespace nonsfi { | 18 namespace nonsfi { |
| 27 namespace { | 19 namespace { |
| 28 | 20 |
| 29 typedef void (*EntryPointType)(uintptr_t*); | 21 typedef void (*EntryPointType)(uintptr_t*); |
| 30 | 22 |
| 31 class PluginMainDelegate : public base::PlatformThread::Delegate { | 23 class PluginMainDelegate : public base::PlatformThread::Delegate { |
| 32 public: | 24 public: |
| 33 explicit PluginMainDelegate(EntryPointType entry_point) | 25 explicit PluginMainDelegate(EntryPointType entry_point) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 63 | 55 |
| 64 // Default stack size of the plugin main thread. We heuristically chose 16M. | 56 // Default stack size of the plugin main thread. We heuristically chose 16M. |
| 65 const size_t kStackSize = (16 << 20); | 57 const size_t kStackSize = (16 << 20); |
| 66 | 58 |
| 67 struct NaClDescUnrefer { | 59 struct NaClDescUnrefer { |
| 68 void operator()(struct NaClDesc* desc) const { | 60 void operator()(struct NaClDesc* desc) const { |
| 69 NaClDescUnref(desc); | 61 NaClDescUnref(desc); |
| 70 } | 62 } |
| 71 }; | 63 }; |
| 72 | 64 |
| 73 void LoadModuleRpc(struct NaClSrpcRpc* rpc, | 65 } // namespace |
| 74 struct NaClSrpcArg** in_args, | |
| 75 struct NaClSrpcArg** out_args, | |
| 76 struct NaClSrpcClosure* done_cls) { | |
| 77 rpc->result = NACL_SRPC_RESULT_INTERNAL; | |
| 78 | 66 |
| 79 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc(in_args[0]->u.hval); | 67 void MainStart(NaClDesc* nexe_file) { |
| 68 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc(nexe_file); |
| 80 ElfImage image; | 69 ElfImage image; |
| 81 if (image.Read(desc.get()) != LOAD_OK) { | 70 if (image.Read(desc.get()) != LOAD_OK) { |
| 82 LOG(ERROR) << "LoadModuleRpc: Failed to read binary."; | 71 LOG(ERROR) << "LoadModuleRpc: Failed to read binary."; |
| 83 return; | 72 return; |
| 84 } | 73 } |
| 85 | 74 |
| 86 if (image.Load(desc.get()) != LOAD_OK) { | 75 if (image.Load(desc.get()) != LOAD_OK) { |
| 87 LOG(ERROR) << "LoadModuleRpc: Failed to load the image"; | 76 LOG(ERROR) << "LoadModuleRpc: Failed to load the image"; |
| 88 return; | 77 return; |
| 89 } | 78 } |
| 90 | 79 |
| 91 EntryPointType entry_point = | 80 EntryPointType entry_point = |
| 92 reinterpret_cast<EntryPointType>(image.entry_point()); | 81 reinterpret_cast<EntryPointType>(image.entry_point()); |
| 93 if (!base::PlatformThread::CreateNonJoinable( | 82 if (!base::PlatformThread::CreateNonJoinable( |
| 94 kStackSize, new PluginMainDelegate(entry_point))) { | 83 kStackSize, new PluginMainDelegate(entry_point))) { |
| 95 LOG(ERROR) << "LoadModuleRpc: Failed to create plugin main thread."; | 84 LOG(ERROR) << "LoadModuleRpc: Failed to create plugin main thread."; |
| 96 return; | 85 return; |
| 97 } | 86 } |
| 98 | |
| 99 rpc->result = NACL_SRPC_RESULT_OK; | |
| 100 (*done_cls->Run)(done_cls); | |
| 101 } | |
| 102 | |
| 103 const static struct NaClSrpcHandlerDesc kNonSfiServiceHandlers[] = { | |
| 104 { NACL_SECURE_SERVICE_LOAD_MODULE, LoadModuleRpc, }, | |
| 105 { static_cast<const char*>(NULL), static_cast<NaClSrpcMethod>(NULL), }, | |
| 106 }; | |
| 107 | |
| 108 // Creates two socketpairs to communicate with the host process. | |
| 109 void CreateSecureSocketPair(struct NaClDesc* secure_pair[2], | |
| 110 struct NaClDesc* pair[2]) { | |
| 111 // Set up a secure pair. | |
| 112 if (NaClCommonDescMakeBoundSock(secure_pair)) { | |
| 113 LOG(FATAL) << "Cound not create secure service socket\n"; | |
| 114 } | |
| 115 | |
| 116 // Set up a service pair. | |
| 117 if (NaClCommonDescMakeBoundSock(pair)) { | |
| 118 LOG(FATAL) << "Could not create service socket"; | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 // Wraps handle by NaClDesc, and sends secure_service_address and | |
| 123 // service_address via the created descriptor. | |
| 124 struct NaClDesc* SetUpBootstrapChannel(NaClHandle handle, | |
| 125 struct NaClDesc* secure_service_address, | |
| 126 struct NaClDesc* service_address) { | |
| 127 if (secure_service_address == NULL) { | |
| 128 LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; | |
| 129 } | |
| 130 | |
| 131 if (service_address == NULL) { | |
| 132 LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; | |
| 133 } | |
| 134 | |
| 135 struct NaClDescImcDesc* channel = | |
| 136 static_cast<struct NaClDescImcDesc*>(malloc(sizeof *channel)); | |
| 137 if (channel == NULL) { | |
| 138 LOG(FATAL) << "SetUpBootstrapChannel: no memory"; | |
| 139 } | |
| 140 | |
| 141 if (!NaClDescImcDescCtor(channel, handle)) { | |
| 142 LOG(FATAL) << "SetUpBootstrapChannel: cannot construct IMC descriptor " | |
| 143 << "object for inherited descriptor: " << handle; | |
| 144 } | |
| 145 | |
| 146 // Send the descriptors to the host. | |
| 147 struct NaClDesc* descs[2] = { | |
| 148 secure_service_address, | |
| 149 service_address, | |
| 150 }; | |
| 151 | |
| 152 struct NaClImcTypedMsgHdr hdr; | |
| 153 hdr.iov = static_cast<struct NaClImcMsgIoVec*>(NULL); | |
| 154 hdr.iov_length = 0; | |
| 155 hdr.ndescv = descs; | |
| 156 hdr.ndesc_length = NACL_ARRAY_SIZE(descs); | |
| 157 hdr.flags = 0; | |
| 158 | |
| 159 ssize_t error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)( | |
| 160 reinterpret_cast<struct NaClDesc*>(channel), &hdr, 0); | |
| 161 if (error) { | |
| 162 LOG(FATAL) << "SetUpBootstrapChannel: SendMsg failed, error = " << error; | |
| 163 } | |
| 164 return reinterpret_cast<struct NaClDesc*>(channel); | |
| 165 } | |
| 166 | |
| 167 // Starts to listen to the port and runs the server loop. | |
| 168 void ServiceAccept(struct NaClDesc* port) { | |
| 169 struct NaClDesc* connected_desc = NULL; | |
| 170 int status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc); | |
| 171 if (status) { | |
| 172 LOG(ERROR) << "ServiceAccept: Failed to accept " << status; | |
| 173 return; | |
| 174 } | |
| 175 | |
| 176 NaClSrpcServerLoop(connected_desc, kNonSfiServiceHandlers, NULL); | |
| 177 } | |
| 178 | |
| 179 } // namespace | |
| 180 | |
| 181 void MainStart(NaClHandle imc_bootstrap_handle) { | |
| 182 NaClSrpcModuleInit(); | |
| 183 | |
| 184 struct NaClDesc* secure_pair[2] = { NULL, NULL }; | |
| 185 struct NaClDesc* pair[2] = { NULL, NULL }; | |
| 186 CreateSecureSocketPair(secure_pair, pair); | |
| 187 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_port(secure_pair[0]); | |
| 188 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_address( | |
| 189 secure_pair[1]); | |
| 190 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_port(pair[0]); | |
| 191 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_address(pair[1]); | |
| 192 | |
| 193 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> channel( | |
| 194 SetUpBootstrapChannel(imc_bootstrap_handle, | |
| 195 secure_address.get(), service_address.get())); | |
| 196 if (!channel) { | |
| 197 LOG(ERROR) << "MainStart: Failed to set up bootstrap channel."; | |
| 198 return; | |
| 199 } | |
| 200 | |
| 201 // Start the SRPC server loop. | |
| 202 ServiceAccept(secure_port.get()); | |
| 203 } | 87 } |
| 204 | 88 |
| 205 } // namespace nonsfi | 89 } // namespace nonsfi |
| 206 } // namespace nacl | 90 } // namespace nacl |
| OLD | NEW |