Chromium Code Reviews| 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 "components/nacl/loader/nonsfi/nonsfi_error_code.h" | |
| 11 #include "native_client/src/include/elf_auxv.h" | |
| 12 #include "native_client/src/include/nacl_macros.h" | |
| 13 #include "native_client/src/public/secure_service.h" | |
| 14 #include "native_client/src/shared/srpc/nacl_srpc.h" | |
| 15 #include "native_client/src/trusted/desc/nacl_desc_base.h" | |
| 16 #include "native_client/src/trusted/desc/nacl_desc_imc.h" | |
| 17 #include "native_client/src/trusted/desc/nrd_all_modules.h" | |
| 18 #include "native_client/src/trusted/desc/nrd_xfer.h" | |
| 19 #include "native_client/src/trusted/fault_injection/fault_injection.h" | |
|
Mark Seaborn
2013/12/12 04:49:48
This one is not needed (see below)
hidehiko
2013/12/12 09:26:04
Done.
| |
| 20 | |
| 21 namespace nacl { | |
| 22 namespace nonsfi { | |
| 23 namespace { | |
| 24 | |
| 25 struct NaClDescUnrefer { | |
| 26 void operator()(struct NaClDesc* desc) const { | |
| 27 NaClDescUnref(desc); | |
| 28 } | |
| 29 }; | |
| 30 | |
| 31 void LoadModuleRpc(struct NaClSrpcRpc *rpc, | |
|
Mark Seaborn
2013/12/12 04:49:48
Nit: use Chromium's "* " spacing style
hidehiko
2013/12/12 09:26:04
Done.
| |
| 32 struct NaClSrpcArg **in_args, | |
| 33 struct NaClSrpcArg **out_args, | |
| 34 struct NaClSrpcClosure *done_cls) { | |
| 35 UNREFERENCED_PARAMETER(out_args); | |
|
Mark Seaborn
2013/12/12 04:49:48
UNREFERENCED_PARAMETER isn't needed in Chromium co
hidehiko
2013/12/12 09:26:04
So, sometimes I'm a bit confused what style I shou
Mark Seaborn
2013/12/17 21:18:55
Yes, since this is in the Chromium tree, please ig
| |
| 36 VLOG(4) << "LoadModuleRpc: loading module."; | |
|
Mark Seaborn
2013/12/12 04:49:48
As with the other file, can you remove the VLOGs,
hidehiko
2013/12/12 09:26:04
Done.
| |
| 37 | |
| 38 rpc->result = NACL_SRPC_RESULT_INTERNAL; | |
| 39 | |
| 40 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc(in_args[0]->u.hval); | |
| 41 ElfImage image; | |
| 42 if (image.Read(desc.get()) != LOAD_OK) { | |
| 43 LOG(ERROR) << "LoadModuleRpc: Failed to read binary."; | |
| 44 return; | |
| 45 } | |
| 46 | |
| 47 if (image.Load(desc.get()) != LOAD_OK) { | |
| 48 LOG(ERROR) << "LoadModuleRpc: Failed to load the image"; | |
| 49 return; | |
| 50 } | |
| 51 | |
| 52 uintptr_t entry_point = image.entry_point(); | |
| 53 VLOG(4) << "LoadModuleRpc: Load is done " << entry_point; | |
| 54 rpc->result = NACL_SRPC_RESULT_OK; | |
| 55 | |
| 56 // Run for testing. TODO(hidehiko): Remove this. | |
| 57 uintptr_t* info = static_cast<uintptr_t*>(alloca(sizeof(uintptr_t) * 7)); | |
|
Mark Seaborn
2013/12/12 04:49:48
Nit: it would be simpler to use an array:
uintptr_
hidehiko
2013/12/12 09:26:04
Good point. Fixed.
| |
| 58 int i = 0; | |
| 59 info[i++] = 0; // Do not use fini. | |
| 60 info[i++] = 0; // envc. | |
| 61 info[i++] = 0; // argc. | |
| 62 info[i++] = 0; // Null terminate for argv. | |
| 63 info[i++] = 0; // Null terminate for envv. | |
| 64 info[i++] = AT_NULL; | |
| 65 info[i++] = 0; // Null terminate for auxv. | |
| 66 reinterpret_cast<void (*)(uintptr_t *)>(entry_point)(info); | |
| 67 } | |
| 68 | |
| 69 void ReverseSetupRpc(struct NaClSrpcRpc *rpc, | |
| 70 struct NaClSrpcArg **in_args, | |
| 71 struct NaClSrpcArg **out_args, | |
| 72 struct NaClSrpcClosure *done_cls) { | |
| 73 VLOG(4) << "ReverseSetupRpc"; | |
| 74 NOTIMPLEMENTED(); | |
| 75 } | |
| 76 | |
| 77 void StartModuleRpc(struct NaClSrpcRpc *rpc, | |
| 78 struct NaClSrpcArg **in_args, | |
| 79 struct NaClSrpcArg **out_args, | |
| 80 struct NaClSrpcClosure *done_cls) { | |
| 81 VLOG(4) << "StartModuleRpc\n"; | |
| 82 NOTIMPLEMENTED(); | |
| 83 } | |
| 84 | |
| 85 void LogRpc(struct NaClSrpcRpc *rpc, | |
| 86 struct NaClSrpcArg **in_args, | |
| 87 struct NaClSrpcArg **out_args, | |
| 88 struct NaClSrpcClosure *done_cls) { | |
| 89 int severity = in_args[0]->u.ival; | |
| 90 char *msg = in_args[1]->arrays.str; | |
| 91 UNREFERENCED_PARAMETER(out_args); | |
| 92 | |
| 93 VLOG(5) << "LogRpc"; | |
| 94 VLOG(severity) << msg; | |
| 95 VLOG(5) << "LogRpc"; | |
| 96 rpc->result = NACL_SRPC_RESULT_OK; | |
| 97 (*done_cls->Run)(done_cls); | |
| 98 } | |
| 99 | |
| 100 void ShutdownRpc(struct NaClSrpcRpc *rpc, | |
| 101 struct NaClSrpcArg **in_args, | |
| 102 struct NaClSrpcArg **out_args, | |
| 103 struct NaClSrpcClosure *done_cls) { | |
| 104 VLOG(4) << "ShutdownRpc"; | |
| 105 NOTIMPLEMENTED(); | |
| 106 } | |
| 107 | |
| 108 const static struct NaClSrpcHandlerDesc kNonSfiServiceHandlers[] = { | |
| 109 { NACL_SECURE_SERVICE_LOAD_MODULE, LoadModuleRpc, }, | |
|
Mark Seaborn
2013/12/12 04:49:48
"load" is the only method handler that's needed at
hidehiko
2013/12/12 09:26:04
Done.
| |
| 110 { NACL_SECURE_SERVICE_REVERSE_SETUP, ReverseSetupRpc, }, | |
| 111 { NACL_SECURE_SERVICE_START_MODULE, StartModuleRpc, }, | |
| 112 { NACL_SECURE_SERVICE_LOG, LogRpc, }, | |
| 113 { NACL_SECURE_SERVICE_HARD_SHUTDOWN, ShutdownRpc, }, | |
| 114 { (char const *) NULL, (NaClSrpcMethod) NULL, }, | |
| 115 }; | |
| 116 | |
| 117 // Creates two socketpairs to communicate with the host process. | |
| 118 void CreateSecureSocketPair(struct NaClDesc *secure_pair[2], | |
| 119 struct NaClDesc *pair[2]) { | |
| 120 // Set up a secure pair. | |
| 121 VLOG(3) << "Entered CreateSecureSocketPair"; | |
| 122 if (NaClCommonDescMakeBoundSock(secure_pair)) { | |
| 123 LOG(FATAL) << "Cound not create secure service socket\n"; | |
| 124 } | |
| 125 VLOG(4) << "Got bound socket at " << secure_pair[0] | |
| 126 << ", addr at " << secure_pair[1]; | |
| 127 | |
| 128 // Set up a service pair. | |
| 129 if (NaClCommonDescMakeBoundSock(pair)) { | |
| 130 LOG(FATAL) << "Could not create service socket"; | |
| 131 } | |
| 132 VLOG(4) << "Got bound socket at " << pair[0] << ", addr at " << pair[1]; | |
| 133 } | |
| 134 | |
| 135 // Wraps handle by NaClDesc, and sends sercure_service_address and | |
| 136 // service_address via the created descriptor. | |
| 137 struct NaClDesc *SetUpBootstrapChannel(NaClHandle handle, | |
| 138 struct NaClDesc *secure_service_address, | |
| 139 struct NaClDesc *service_address) { | |
| 140 VLOG(3) << "Entered NaClBareMetalSetUpBootstrapChannel\n"; | |
| 141 if (secure_service_address == NULL) { | |
| 142 LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; | |
| 143 } | |
| 144 | |
| 145 if (service_address == NULL) { | |
| 146 LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; | |
| 147 } | |
| 148 | |
| 149 struct NaClDescImcDesc* channel = | |
| 150 static_cast<struct NaClDescImcDesc *>(malloc(sizeof *channel)); | |
| 151 if (channel == NULL) { | |
| 152 LOG(FATAL) << "SetUpBootstrapChannel: no memory"; | |
| 153 } | |
| 154 | |
| 155 if (!NaClDescImcDescCtor(channel, handle)) { | |
| 156 LOG(FATAL) << "SetUpBootstrapChannel: cannot construct IMC descriptor " | |
| 157 << "object for inherited descriptor: " << handle; | |
| 158 } | |
| 159 | |
| 160 // Send the descriptors to the host. | |
| 161 struct NaClDesc* descs[2] = { | |
| 162 secure_service_address, | |
| 163 service_address, | |
| 164 }; | |
| 165 | |
| 166 struct NaClImcTypedMsgHdr hdr; | |
| 167 hdr.iov = static_cast<struct NaClImcMsgIoVec *>(NULL); | |
| 168 hdr.iov_length = 0; | |
| 169 hdr.ndescv = descs; | |
| 170 hdr.ndesc_length = NACL_ARRAY_SIZE(descs); | |
| 171 | |
| 172 ssize_t error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)( | |
| 173 reinterpret_cast<struct NaClDesc *>(channel), &hdr, 0); | |
| 174 VLOG(1) << "SetUpBootstrapChannel: descriptor " << handle | |
| 175 << ", error " << error; | |
| 176 if (error) { | |
| 177 LOG(FATAL) << "SetUpBootstrapChannel: SendMsg failed, error = " << error; | |
| 178 } | |
| 179 return (struct NaClDesc *) channel; | |
|
Mark Seaborn
2013/12/12 04:49:48
Nit: use "NaClDesc*" spacing (Chromium style)
hidehiko
2013/12/12 09:26:04
Done.
| |
| 180 } | |
| 181 | |
| 182 // Starts to listend the port and runs the server loop. | |
|
Mark Seaborn
2013/12/12 04:49:48
"listen to" or "listen on"?
hidehiko
2013/12/12 09:26:04
Done.
| |
| 183 void ServiceAccept(struct NaClDesc *port) { | |
| 184 VLOG(3) << "Entered ServiceAccept"; | |
| 185 struct NaClDesc *connected_desc = NULL; | |
| 186 int status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc); | |
| 187 if (status) { | |
| 188 VLOG(4) << "ServiceAccept: Failed to accept " << status; | |
| 189 return; | |
| 190 } | |
| 191 | |
| 192 VLOG(4) << "ServiceAccept: Start server loop."; | |
| 193 NaClSrpcServerLoop(connected_desc, kNonSfiServiceHandlers, NULL); | |
| 194 } | |
| 195 | |
| 196 void NonSfiAllModulesInit(void) { | |
|
Mark Seaborn
2013/12/12 04:49:48
Nit: "(void)" is not needed in C++
hidehiko
2013/12/12 09:26:04
acknowledged.
| |
| 197 NaClNrdAllModulesInit(); | |
|
Mark Seaborn
2013/12/12 04:49:48
Calling this makes this fail with the following er
hidehiko
2013/12/12 09:26:04
I see. Done.
| |
| 198 NaClFaultInjectionModuleInit(); | |
|
Mark Seaborn
2013/12/12 04:49:48
This one is not needed
hidehiko
2013/12/12 09:26:04
I thought this was needed otherwise FaultInjection
| |
| 199 NaClSrpcModuleInit(); | |
| 200 } | |
| 201 | |
| 202 } // namespace | |
| 203 | |
| 204 void MainStart(NaClHandle imc_bootstrap_handle) { | |
| 205 VLOG(3) << "MainStart"; | |
| 206 | |
| 207 NonSfiAllModulesInit(); | |
| 208 | |
| 209 struct NaClDesc *secure_pair[2] = { NULL, NULL }; | |
| 210 struct NaClDesc *pair[2] = { NULL, NULL }; | |
| 211 CreateSecureSocketPair(secure_pair, pair); | |
| 212 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_port(secure_pair[0]); | |
| 213 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_address( | |
| 214 secure_pair[1]); | |
| 215 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_port(pair[0]); | |
| 216 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_address(pair[1]); | |
| 217 | |
| 218 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> channel( | |
| 219 SetUpBootstrapChannel(imc_bootstrap_handle, | |
| 220 secure_address.get(), service_address.get())); | |
| 221 if (!channel) { | |
| 222 LOG(ERROR) << "MainStart: Failed to set up bootstrap channel."; | |
| 223 return; | |
| 224 } | |
| 225 | |
| 226 // Start the SRPC server loop. | |
| 227 VLOG(4) << "MainStart: Start server loop."; | |
| 228 ServiceAccept(secure_port.get()); | |
| 229 } | |
| 230 | |
| 231 } // namespace nonsfi | |
| 232 } // namespace nacl | |
| OLD | NEW |