| 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..39e1a1c28370500049193996377677f7dccd3c10
|
| --- /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_util.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"
|
| +
|
| +namespace nacl {
|
| +namespace nonsfi {
|
| +namespace {
|
| +
|
| +struct NaClDescUnrefer {
|
| + void operator()(struct NaClDesc* desc) const {
|
| + NaClDescUnref(desc);
|
| + }
|
| +};
|
| +
|
| +void LoadModuleRpc(struct NaClSrpcRpc *rpc,
|
| + struct NaClSrpcArg **in_args,
|
| + struct NaClSrpcArg **out_args,
|
| + struct NaClSrpcClosure *done_cls) {
|
| + UNREFERENCED_PARAMETER(out_args);
|
| + VLOG(4) << "LoadModuleRpc: loading module.";
|
| +
|
| + 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));
|
| + 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, },
|
| + { 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;
|
| +}
|
| +
|
| +// Starts to listend the port and runs the server loop.
|
| +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) {
|
| + NaClNrdAllModulesInit();
|
| + NaClFaultInjectionModuleInit();
|
| + 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
|
|
|