This source file includes following definitions.
- ThreadMain
- LoadModuleRpc
- CreateSecureSocketPair
- SetUpBootstrapChannel
- ServiceAccept
- MainStart
#include "components/nacl/loader/nonsfi/nonsfi_main.h"
#include "base/debug/leak_annotations.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_restrictions.h"
#include "components/nacl/loader/nonsfi/elf_loader.h"
#include "components/nacl/loader/nonsfi/irt_interfaces.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/service_runtime/nacl_error_code.h"
namespace nacl {
namespace nonsfi {
namespace {
typedef void (*EntryPointType)(uintptr_t*);
class PluginMainDelegate : public base::PlatformThread::Delegate {
public:
explicit PluginMainDelegate(EntryPointType entry_point)
: entry_point_(entry_point) {
}
virtual ~PluginMainDelegate() {
}
virtual void ThreadMain() OVERRIDE {
base::PlatformThread::SetName("NaClMainThread");
base::ThreadRestrictions::SetSingletonAllowed(true);
uintptr_t info[] = {
0,
0,
0,
0,
0,
AT_SYSINFO,
reinterpret_cast<uintptr_t>(&NaClIrtInterface),
AT_NULL,
0,
};
entry_point_(info);
}
private:
EntryPointType entry_point_;
};
const size_t kStackSize = (16 << 20);
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) {
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;
}
EntryPointType entry_point =
reinterpret_cast<EntryPointType>(image.entry_point());
if (!base::PlatformThread::CreateNonJoinable(
kStackSize, new PluginMainDelegate(entry_point))) {
LOG(ERROR) << "LoadModuleRpc: Failed to create plugin main thread.";
return;
}
rpc->result = NACL_SRPC_RESULT_OK;
(*done_cls->Run)(done_cls);
}
const static struct NaClSrpcHandlerDesc kNonSfiServiceHandlers[] = {
{ NACL_SECURE_SERVICE_LOAD_MODULE, LoadModuleRpc, },
{ static_cast<const char*>(NULL), static_cast<NaClSrpcMethod>(NULL), },
};
void CreateSecureSocketPair(struct NaClDesc* secure_pair[2],
struct NaClDesc* pair[2]) {
if (NaClCommonDescMakeBoundSock(secure_pair)) {
LOG(FATAL) << "Cound not create secure service socket\n";
}
if (NaClCommonDescMakeBoundSock(pair)) {
LOG(FATAL) << "Could not create service socket";
}
}
struct NaClDesc* SetUpBootstrapChannel(NaClHandle handle,
struct NaClDesc* secure_service_address,
struct NaClDesc* service_address) {
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;
}
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);
hdr.flags = 0;
ssize_t error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)(
reinterpret_cast<struct NaClDesc*>(channel), &hdr, 0);
if (error) {
LOG(FATAL) << "SetUpBootstrapChannel: SendMsg failed, error = " << error;
}
return reinterpret_cast<struct NaClDesc*>(channel);
}
void ServiceAccept(struct NaClDesc* port) {
struct NaClDesc* connected_desc = NULL;
int status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc);
if (status) {
LOG(ERROR) << "ServiceAccept: Failed to accept " << status;
return;
}
NaClSrpcServerLoop(connected_desc, kNonSfiServiceHandlers, NULL);
}
}
void MainStart(NaClHandle imc_bootstrap_handle) {
NaClSrpcModuleInit();
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;
}
ServiceAccept(secure_port.get());
}
}
}