Chromium Code Reviews| Index: components/nacl/loader/nonsfi/nonsfi_main.cc |
| diff --git a/components/nacl/loader/nonsfi/nonsfi_main.cc b/components/nacl/loader/nonsfi/nonsfi_main.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..545c1adedfd13de7fa5d7ff475a084f054a8e9db |
| --- /dev/null |
| +++ b/components/nacl/loader/nonsfi/nonsfi_main.cc |
| @@ -0,0 +1,232 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/nacl/loader/nonsfi/nonsfi_main.h" |
| + |
| +#include "base/logging.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "components/nacl/loader/nonsfi/elf_loader.h" |
| +#include "components/nacl/loader/nonsfi/nonsfi_error_code.h" |
| +#include "native_client/src/include/elf_auxv.h" |
| +#include "native_client/src/include/nacl_macros.h" |
| +#include "native_client/src/public/secure_service.h" |
| +#include "native_client/src/shared/srpc/nacl_srpc.h" |
| +#include "native_client/src/trusted/desc/nacl_desc_base.h" |
| +#include "native_client/src/trusted/desc/nacl_desc_imc.h" |
| +#include "native_client/src/trusted/desc/nrd_all_modules.h" |
| +#include "native_client/src/trusted/desc/nrd_xfer.h" |
| +#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.
|
| + |
| +namespace nacl { |
| +namespace nonsfi { |
| +namespace { |
| + |
| +struct NaClDescUnrefer { |
| + void operator()(struct NaClDesc* desc) const { |
| + NaClDescUnref(desc); |
| + } |
| +}; |
| + |
| +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.
|
| + struct NaClSrpcArg **in_args, |
| + struct NaClSrpcArg **out_args, |
| + struct NaClSrpcClosure *done_cls) { |
| + 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
|
| + 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.
|
| + |
| + rpc->result = NACL_SRPC_RESULT_INTERNAL; |
| + |
| + ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc(in_args[0]->u.hval); |
| + ElfImage image; |
| + if (image.Read(desc.get()) != LOAD_OK) { |
| + LOG(ERROR) << "LoadModuleRpc: Failed to read binary."; |
| + return; |
| + } |
| + |
| + if (image.Load(desc.get()) != LOAD_OK) { |
| + LOG(ERROR) << "LoadModuleRpc: Failed to load the image"; |
| + return; |
| + } |
| + |
| + uintptr_t entry_point = image.entry_point(); |
| + VLOG(4) << "LoadModuleRpc: Load is done " << entry_point; |
| + rpc->result = NACL_SRPC_RESULT_OK; |
| + |
| + // Run for testing. TODO(hidehiko): Remove this. |
| + 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.
|
| + int i = 0; |
| + info[i++] = 0; // Do not use fini. |
| + info[i++] = 0; // envc. |
| + info[i++] = 0; // argc. |
| + info[i++] = 0; // Null terminate for argv. |
| + info[i++] = 0; // Null terminate for envv. |
| + info[i++] = AT_NULL; |
| + info[i++] = 0; // Null terminate for auxv. |
| + reinterpret_cast<void (*)(uintptr_t *)>(entry_point)(info); |
| +} |
| + |
| +void ReverseSetupRpc(struct NaClSrpcRpc *rpc, |
| + struct NaClSrpcArg **in_args, |
| + struct NaClSrpcArg **out_args, |
| + struct NaClSrpcClosure *done_cls) { |
| + VLOG(4) << "ReverseSetupRpc"; |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void StartModuleRpc(struct NaClSrpcRpc *rpc, |
| + struct NaClSrpcArg **in_args, |
| + struct NaClSrpcArg **out_args, |
| + struct NaClSrpcClosure *done_cls) { |
| + VLOG(4) << "StartModuleRpc\n"; |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void LogRpc(struct NaClSrpcRpc *rpc, |
| + struct NaClSrpcArg **in_args, |
| + struct NaClSrpcArg **out_args, |
| + struct NaClSrpcClosure *done_cls) { |
| + int severity = in_args[0]->u.ival; |
| + char *msg = in_args[1]->arrays.str; |
| + UNREFERENCED_PARAMETER(out_args); |
| + |
| + VLOG(5) << "LogRpc"; |
| + VLOG(severity) << msg; |
| + VLOG(5) << "LogRpc"; |
| + rpc->result = NACL_SRPC_RESULT_OK; |
| + (*done_cls->Run)(done_cls); |
| +} |
| + |
| +void ShutdownRpc(struct NaClSrpcRpc *rpc, |
| + struct NaClSrpcArg **in_args, |
| + struct NaClSrpcArg **out_args, |
| + struct NaClSrpcClosure *done_cls) { |
| + VLOG(4) << "ShutdownRpc"; |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +const static struct NaClSrpcHandlerDesc kNonSfiServiceHandlers[] = { |
| + { 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.
|
| + { NACL_SECURE_SERVICE_REVERSE_SETUP, ReverseSetupRpc, }, |
| + { NACL_SECURE_SERVICE_START_MODULE, StartModuleRpc, }, |
| + { NACL_SECURE_SERVICE_LOG, LogRpc, }, |
| + { NACL_SECURE_SERVICE_HARD_SHUTDOWN, ShutdownRpc, }, |
| + { (char const *) NULL, (NaClSrpcMethod) NULL, }, |
| +}; |
| + |
| +// Creates two socketpairs to communicate with the host process. |
| +void CreateSecureSocketPair(struct NaClDesc *secure_pair[2], |
| + struct NaClDesc *pair[2]) { |
| + // Set up a secure pair. |
| + VLOG(3) << "Entered CreateSecureSocketPair"; |
| + if (NaClCommonDescMakeBoundSock(secure_pair)) { |
| + LOG(FATAL) << "Cound not create secure service socket\n"; |
| + } |
| + VLOG(4) << "Got bound socket at " << secure_pair[0] |
| + << ", addr at " << secure_pair[1]; |
| + |
| + // Set up a service pair. |
| + if (NaClCommonDescMakeBoundSock(pair)) { |
| + LOG(FATAL) << "Could not create service socket"; |
| + } |
| + VLOG(4) << "Got bound socket at " << pair[0] << ", addr at " << pair[1]; |
| +} |
| + |
| +// Wraps handle by NaClDesc, and sends sercure_service_address and |
| +// service_address via the created descriptor. |
| +struct NaClDesc *SetUpBootstrapChannel(NaClHandle handle, |
| + struct NaClDesc *secure_service_address, |
| + struct NaClDesc *service_address) { |
| + VLOG(3) << "Entered NaClBareMetalSetUpBootstrapChannel\n"; |
| + if (secure_service_address == NULL) { |
| + LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; |
| + } |
| + |
| + if (service_address == NULL) { |
| + LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; |
| + } |
| + |
| + struct NaClDescImcDesc* channel = |
| + static_cast<struct NaClDescImcDesc *>(malloc(sizeof *channel)); |
| + if (channel == NULL) { |
| + LOG(FATAL) << "SetUpBootstrapChannel: no memory"; |
| + } |
| + |
| + if (!NaClDescImcDescCtor(channel, handle)) { |
| + LOG(FATAL) << "SetUpBootstrapChannel: cannot construct IMC descriptor " |
| + << "object for inherited descriptor: " << handle; |
| + } |
| + |
| + // Send the descriptors to the host. |
| + struct NaClDesc* descs[2] = { |
| + secure_service_address, |
| + service_address, |
| + }; |
| + |
| + struct NaClImcTypedMsgHdr hdr; |
| + hdr.iov = static_cast<struct NaClImcMsgIoVec *>(NULL); |
| + hdr.iov_length = 0; |
| + hdr.ndescv = descs; |
| + hdr.ndesc_length = NACL_ARRAY_SIZE(descs); |
| + |
| + ssize_t error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)( |
| + reinterpret_cast<struct NaClDesc *>(channel), &hdr, 0); |
| + VLOG(1) << "SetUpBootstrapChannel: descriptor " << handle |
| + << ", error " << error; |
| + if (error) { |
| + LOG(FATAL) << "SetUpBootstrapChannel: SendMsg failed, error = " << error; |
| + } |
| + 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.
|
| +} |
| + |
| +// 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.
|
| +void ServiceAccept(struct NaClDesc *port) { |
| + VLOG(3) << "Entered ServiceAccept"; |
| + struct NaClDesc *connected_desc = NULL; |
| + int status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc); |
| + if (status) { |
| + VLOG(4) << "ServiceAccept: Failed to accept " << status; |
| + return; |
| + } |
| + |
| + VLOG(4) << "ServiceAccept: Start server loop."; |
| + NaClSrpcServerLoop(connected_desc, kNonSfiServiceHandlers, NULL); |
| +} |
| + |
| +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.
|
| + 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.
|
| + 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
|
| + NaClSrpcModuleInit(); |
| +} |
| + |
| +} // namespace |
| + |
| +void MainStart(NaClHandle imc_bootstrap_handle) { |
| + VLOG(3) << "MainStart"; |
| + |
| + NonSfiAllModulesInit(); |
| + |
| + struct NaClDesc *secure_pair[2] = { NULL, NULL }; |
| + struct NaClDesc *pair[2] = { NULL, NULL }; |
| + CreateSecureSocketPair(secure_pair, pair); |
| + ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_port(secure_pair[0]); |
| + ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_address( |
| + secure_pair[1]); |
| + ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_port(pair[0]); |
| + ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_address(pair[1]); |
| + |
| + ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> channel( |
| + SetUpBootstrapChannel(imc_bootstrap_handle, |
| + secure_address.get(), service_address.get())); |
| + if (!channel) { |
| + LOG(ERROR) << "MainStart: Failed to set up bootstrap channel."; |
| + return; |
| + } |
| + |
| + // Start the SRPC server loop. |
| + VLOG(4) << "MainStart: Start server loop."; |
| + ServiceAccept(secure_port.get()); |
| +} |
| + |
| +} // namespace nonsfi |
| +} // namespace nacl |