OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "components/nacl/loader/nonsfi/nonsfi_main.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "components/nacl/loader/nonsfi/elf_loader.h" |
| 10 #include "native_client/src/include/elf_auxv.h" |
| 11 #include "native_client/src/include/nacl_macros.h" |
| 12 #include "native_client/src/public/secure_service.h" |
| 13 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 14 #include "native_client/src/trusted/desc/nacl_desc_base.h" |
| 15 #include "native_client/src/trusted/desc/nacl_desc_imc.h" |
| 16 #include "native_client/src/trusted/desc/nrd_all_modules.h" |
| 17 #include "native_client/src/trusted/desc/nrd_xfer.h" |
| 18 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" |
| 19 |
| 20 namespace nacl { |
| 21 namespace nonsfi { |
| 22 namespace { |
| 23 |
| 24 struct NaClDescUnrefer { |
| 25 void operator()(struct NaClDesc* desc) const { |
| 26 NaClDescUnref(desc); |
| 27 } |
| 28 }; |
| 29 |
| 30 void LoadModuleRpc(struct NaClSrpcRpc* rpc, |
| 31 struct NaClSrpcArg** in_args, |
| 32 struct NaClSrpcArg** out_args, |
| 33 struct NaClSrpcClosure* done_cls) { |
| 34 rpc->result = NACL_SRPC_RESULT_INTERNAL; |
| 35 |
| 36 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc(in_args[0]->u.hval); |
| 37 ElfImage image; |
| 38 if (image.Read(desc.get()) != LOAD_OK) { |
| 39 LOG(ERROR) << "LoadModuleRpc: Failed to read binary."; |
| 40 return; |
| 41 } |
| 42 |
| 43 if (image.Load(desc.get()) != LOAD_OK) { |
| 44 LOG(ERROR) << "LoadModuleRpc: Failed to load the image"; |
| 45 return; |
| 46 } |
| 47 |
| 48 uintptr_t entry_point = image.entry_point(); |
| 49 rpc->result = NACL_SRPC_RESULT_OK; |
| 50 |
| 51 // Run for testing. TODO(hidehiko): Remove this. |
| 52 uintptr_t info[] = { |
| 53 0, // Do not use fini. |
| 54 0, // envc. |
| 55 0, // argc. |
| 56 0, // Null terminate for argv. |
| 57 0, // Null terminate for envv. |
| 58 AT_NULL, |
| 59 0, // Null terminate for auxv. |
| 60 }; |
| 61 reinterpret_cast<void (*)(uintptr_t*)>(entry_point)(info); |
| 62 } |
| 63 |
| 64 const static struct NaClSrpcHandlerDesc kNonSfiServiceHandlers[] = { |
| 65 { NACL_SECURE_SERVICE_LOAD_MODULE, LoadModuleRpc, }, |
| 66 { static_cast<const char*>(NULL), static_cast<NaClSrpcMethod>(NULL), }, |
| 67 }; |
| 68 |
| 69 // Creates two socketpairs to communicate with the host process. |
| 70 void CreateSecureSocketPair(struct NaClDesc* secure_pair[2], |
| 71 struct NaClDesc* pair[2]) { |
| 72 // Set up a secure pair. |
| 73 if (NaClCommonDescMakeBoundSock(secure_pair)) { |
| 74 LOG(FATAL) << "Cound not create secure service socket\n"; |
| 75 } |
| 76 |
| 77 // Set up a service pair. |
| 78 if (NaClCommonDescMakeBoundSock(pair)) { |
| 79 LOG(FATAL) << "Could not create service socket"; |
| 80 } |
| 81 } |
| 82 |
| 83 // Wraps handle by NaClDesc, and sends secure_service_address and |
| 84 // service_address via the created descriptor. |
| 85 struct NaClDesc* SetUpBootstrapChannel(NaClHandle handle, |
| 86 struct NaClDesc* secure_service_address, |
| 87 struct NaClDesc* service_address) { |
| 88 if (secure_service_address == NULL) { |
| 89 LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; |
| 90 } |
| 91 |
| 92 if (service_address == NULL) { |
| 93 LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; |
| 94 } |
| 95 |
| 96 struct NaClDescImcDesc* channel = |
| 97 static_cast<struct NaClDescImcDesc*>(malloc(sizeof *channel)); |
| 98 if (channel == NULL) { |
| 99 LOG(FATAL) << "SetUpBootstrapChannel: no memory"; |
| 100 } |
| 101 |
| 102 if (!NaClDescImcDescCtor(channel, handle)) { |
| 103 LOG(FATAL) << "SetUpBootstrapChannel: cannot construct IMC descriptor " |
| 104 << "object for inherited descriptor: " << handle; |
| 105 } |
| 106 |
| 107 // Send the descriptors to the host. |
| 108 struct NaClDesc* descs[2] = { |
| 109 secure_service_address, |
| 110 service_address, |
| 111 }; |
| 112 |
| 113 struct NaClImcTypedMsgHdr hdr; |
| 114 hdr.iov = static_cast<struct NaClImcMsgIoVec*>(NULL); |
| 115 hdr.iov_length = 0; |
| 116 hdr.ndescv = descs; |
| 117 hdr.ndesc_length = NACL_ARRAY_SIZE(descs); |
| 118 hdr.flags = 0; |
| 119 |
| 120 ssize_t error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)( |
| 121 reinterpret_cast<struct NaClDesc*>(channel), &hdr, 0); |
| 122 if (error) { |
| 123 LOG(FATAL) << "SetUpBootstrapChannel: SendMsg failed, error = " << error; |
| 124 } |
| 125 return reinterpret_cast<struct NaClDesc*>(channel); |
| 126 } |
| 127 |
| 128 // Starts to listen to the port and runs the server loop. |
| 129 void ServiceAccept(struct NaClDesc* port) { |
| 130 struct NaClDesc* connected_desc = NULL; |
| 131 int status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc); |
| 132 if (status) { |
| 133 LOG(ERROR) << "ServiceAccept: Failed to accept " << status; |
| 134 return; |
| 135 } |
| 136 |
| 137 NaClSrpcServerLoop(connected_desc, kNonSfiServiceHandlers, NULL); |
| 138 } |
| 139 |
| 140 } // namespace |
| 141 |
| 142 void MainStart(NaClHandle imc_bootstrap_handle) { |
| 143 NaClSrpcModuleInit(); |
| 144 |
| 145 struct NaClDesc* secure_pair[2] = { NULL, NULL }; |
| 146 struct NaClDesc* pair[2] = { NULL, NULL }; |
| 147 CreateSecureSocketPair(secure_pair, pair); |
| 148 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_port(secure_pair[0]); |
| 149 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_address( |
| 150 secure_pair[1]); |
| 151 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_port(pair[0]); |
| 152 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_address(pair[1]); |
| 153 |
| 154 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> channel( |
| 155 SetUpBootstrapChannel(imc_bootstrap_handle, |
| 156 secure_address.get(), service_address.get())); |
| 157 if (!channel) { |
| 158 LOG(ERROR) << "MainStart: Failed to set up bootstrap channel."; |
| 159 return; |
| 160 } |
| 161 |
| 162 // Start the SRPC server loop. |
| 163 ServiceAccept(secure_port.get()); |
| 164 } |
| 165 |
| 166 } // namespace nonsfi |
| 167 } // namespace nacl |
OLD | NEW |