| Index: src/trusted/service_runtime/sel_ldr.c
|
| diff --git a/src/trusted/service_runtime/sel_ldr.c b/src/trusted/service_runtime/sel_ldr.c
|
| index 3fee45cd1d18c7fed55aa2b7ed2b6a8e42b988b6..f649eeab9c79ef039146654576b7c079cdf34b6a 100644
|
| --- a/src/trusted/service_runtime/sel_ldr.c
|
| +++ b/src/trusted/service_runtime/sel_ldr.c
|
| @@ -1260,75 +1260,64 @@ void NaClBlockIfCommandChannelExists(struct NaClApp *nap) {
|
| }
|
| }
|
|
|
| +static void NaClCommandServiceSetupRpc(struct NaClSrpcRpc *rpc,
|
| + struct NaClSrpcArg **in_args,
|
| + struct NaClSrpcArg **out_args,
|
| + struct NaClSrpcClosure *done) {
|
| + struct NaClApp *nap =
|
| + (struct NaClApp *) rpc->channel->server_instance_data;
|
| + struct NaClCommandService *command_server;
|
|
|
| -/*
|
| - * Secure command channels.
|
| - */
|
| -
|
| -struct NaClSecureService {
|
| - struct NaClSimpleService base;
|
| - struct NaClApp *nap;
|
| -};
|
| -
|
| -struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl;
|
| -
|
| -
|
| -struct NaClConnectionHandler {
|
| - struct NaClConnectionHandler *next;
|
| -
|
| - /* used by NaClSimpleRevServiceClient's ClientCallback fn */
|
| - void (*handler)(
|
| - void *state,
|
| - struct NaClThreadInterface *tif,
|
| - struct NaClDesc *conn);
|
| - void *state;
|
| -};
|
| -
|
| -struct NaClSecureReverseClient {
|
| - struct NaClSimpleRevClient base;
|
| - struct NaClApp *nap;
|
| + static struct NaClSrpcHandlerDesc const handlers[] = {
|
| + { "hard_shutdown::", NaClSecureChannelShutdownRpc, },
|
| + { "start_module::i", NaClSecureChannelStartModuleRpc, },
|
| + { "load_module:hs:", NaClLoadModuleRpc, },
|
| + { "load_irt:h:", NaClLoadIrtRpc, },
|
| + { (char const *) NULL, (NaClSrpcMethod) NULL, },
|
| + };
|
|
|
| - struct NaClMutex mu;
|
| + UNREFERENCED_PARAMETER(in_args);
|
|
|
| - struct NaClConnectionHandler *queue_head;
|
| - struct NaClConnectionHandler **queue_insert;
|
| -};
|
| + NaClLog(4, "Entered NaClCommandServiceSetup\n");
|
|
|
| -struct NaClSimpleRevClientVtbl const kNaClSecureReverseClientVtbl;
|
| + NaClXMutexLock(&nap->mu);
|
| + if (NULL != nap->command_service) {
|
| + NaClLog(LOG_FATAL, "Double command setup RPC\n");
|
| + }
|
|
|
| + command_server = (struct NaClCommandService *) malloc(
|
| + sizeof *command_server);
|
| + if (NACL_FI_ERROR_COND("NaClCommandService__malloc",
|
| + NULL == command_server)) {
|
| + NaClLog(LOG_ERROR, "Out of memory for command channel\n");
|
| + rpc->result = NACL_SRPC_RESULT_APP_ERROR;
|
| + goto done;
|
| + }
|
| + if (NACL_FI_ERROR_COND("NaClCommandService__NaClSecureServiceCtor",
|
| + !NaClCommandServiceCtor(command_server,
|
| + handlers, nap))) {
|
| + NaClLog(LOG_FATAL, "NaClCommandServiceCtor failed\n");
|
| + }
|
|
|
| -int NaClSecureServiceCtor(struct NaClSecureService *self,
|
| - struct NaClSrpcHandlerDesc const *srpc_handlers,
|
| - struct NaClApp *nap) {
|
| - NaClLog(4,
|
| - "Entered NaClSecureServiceCtor: self 0x%"NACL_PRIxPTR"\n",
|
| - (uintptr_t) self);
|
| + NaClLog(4, "NaClCommandService: starting service thread\n");
|
| if (NACL_FI_ERROR_COND(
|
| - "NaClSecureServiceCtor__NaClSimpleServiceWithSocketCtor",
|
| - !NaClSimpleServiceWithSocketCtor(
|
| - &self->base,
|
| - srpc_handlers,
|
| - NaClThreadInterfaceThreadFactory,
|
| - (void *) NULL,
|
| - nap->service_port,
|
| - nap->service_address))) {
|
| - goto failure_simple_ctor;
|
| - }
|
| - self->nap = nap;
|
| -
|
| - NACL_VTBL(NaClRefCount, self) =
|
| - (struct NaClRefCountVtbl *) &kNaClSecureServiceVtbl;
|
| - return 1;
|
| - failure_simple_ctor:
|
| - return 0;
|
| -}
|
| -
|
| -void NaClSecureServiceDtor(struct NaClRefCount *vself) {
|
| - struct NaClSecureService *self = (struct NaClSecureService *) vself;
|
| + "NaClCommandService__NaClSimpleServiceStartServiceThread",
|
| + !NaClSimpleServiceStartServiceThread((struct NaClSimpleService *)
|
| + command_server))) {
|
| + NaClLog(LOG_ERROR, "Could not start command channel service thread\n");
|
| + free(command_server);
|
| + rpc->result = NACL_SRPC_RESULT_APP_ERROR;
|
| + goto done;
|
| + }
|
| + nap->command_service = (struct NaClCommandService *) NaClRefCountRef(
|
| + (struct NaClRefCount *) command_server);
|
| + out_args[0]->u.hval = NaClDescRef(command_server->base.bound_and_cap[1]);
|
| + rpc->result = NACL_SRPC_RESULT_OK;
|
|
|
| - NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *)
|
| - &kNaClSimpleServiceVtbl;
|
| - (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
|
| +done:
|
| + NaClXMutexUnlock(&nap->mu);
|
| + (*done->Run)(done);
|
| + NaClLog(4, "Leaving NaClCommandServiceSetup\n");
|
| }
|
|
|
| /*
|
| @@ -1390,14 +1379,6 @@ static void NaClSecureReverseClientCallback(
|
| NaClLog(4, "Leaving NaClSecureReverseClientCallback\n");
|
| }
|
|
|
| -/* fwd */
|
| -int NaClSecureReverseClientCtor(
|
| - struct NaClSecureReverseClient *self,
|
| - void (*client_callback)(
|
| - void *, struct NaClThreadInterface *, struct NaClDesc *),
|
| - void *state,
|
| - struct NaClApp *nap);
|
| -
|
| static void NaClSecureReverseClientSetup(struct NaClSrpcRpc *rpc,
|
| struct NaClSrpcArg **in_args,
|
| struct NaClSrpcArg **out_args,
|
| @@ -1466,255 +1447,6 @@ done:
|
| NaClLog(4, "Leaving NaClSecureReverseClientSetup\n");
|
| }
|
|
|
| -/*
|
| - * Only called at startup and thereafter by the reverse secure
|
| - * channel, with |self| locked.
|
| - */
|
| -static
|
| -int NaClSecureReverseClientInsertHandler_mu(
|
| - struct NaClSecureReverseClient *self,
|
| - void (*h)(void *,
|
| - struct NaClThreadInterface *,
|
| - struct NaClDesc *),
|
| - void *d) {
|
| - struct NaClConnectionHandler *entry;
|
| -
|
| - NaClLog(4,
|
| - ("NaClSecureReverseClientInsertHandler_mu: h 0x%"NACL_PRIxPTR","
|
| - " d 0x%"NACL_PRIxPTR"\n"),
|
| - (uintptr_t) h,
|
| - (uintptr_t) d);
|
| - entry = (struct NaClConnectionHandler *) malloc(sizeof *entry);
|
| - if (NULL == entry) {
|
| - return 0;
|
| - }
|
| - entry->handler = h;
|
| - entry->state = d;
|
| - entry->next = (struct NaClConnectionHandler *) NULL;
|
| - *self->queue_insert = entry;
|
| - self->queue_insert = &entry->next;
|
| -
|
| - return 1;
|
| -}
|
| -
|
| -/*
|
| - * Caller must set up handler before issuing connection request RPC on
|
| - * nap->reverse_channel, since otherwise the connection handler queue
|
| - * may be empty and the connect code would abort. Because the connect
|
| - * doesn't wait for a handler, we don't need a condvar.
|
| - *
|
| - * We do not need to serialize on the handlers, since the
|
| - * RPC-server/IMC-client implementation should not distinguish one
|
| - * connection from another: it is okay for two handlers to be
|
| - * inserted, and two connection request RPCs to be preformed
|
| - * (sequentially, since they are over a single channel), and have the
|
| - * server side spawn threads that asynchronously connect twice, in the
|
| - * "incorrect" order, etc.
|
| - */
|
| -int NaClSecureReverseClientInsertHandler(
|
| - struct NaClSecureReverseClient *self,
|
| - void (*handler)(
|
| - void *handlr_state,
|
| - struct NaClThreadInterface *thread_if,
|
| - struct NaClDesc *new_conn),
|
| - void *handler_state) {
|
| - int retval;
|
| -
|
| - NaClXMutexLock(&self->mu);
|
| - retval = NaClSecureReverseClientInsertHandler_mu(self,
|
| - handler, handler_state);
|
| - NaClXMutexUnlock(&self->mu);
|
| - return retval;
|
| -}
|
| -
|
| -static
|
| -struct NaClConnectionHandler *NaClSecureReverseClientPopHandler(
|
| - struct NaClSecureReverseClient *self) {
|
| - struct NaClConnectionHandler *head;
|
| -
|
| - NaClLog(4, "Entered NaClSecureReverseClientPopHandler, acquiring lock\n");
|
| - NaClXMutexLock(&self->mu);
|
| - NaClLog(4, "NaClSecureReverseClientPopHandler, got lock\n");
|
| - head = self->queue_head;
|
| - if (NULL == head) {
|
| - NaClLog(LOG_FATAL,
|
| - "NaClSecureReverseClientPopHandler: empty handler queue\n");
|
| - }
|
| - if (NULL == (self->queue_head = head->next)) {
|
| - NaClLog(4, "NaClSecureReverseClientPopHandler, last elt patch up\n");
|
| - self->queue_insert = &self->queue_head;
|
| - }
|
| - NaClLog(4, "NaClSecureReverseClientPopHandler, unlocking\n");
|
| - NaClXMutexUnlock(&self->mu);
|
| -
|
| - head->next = NULL;
|
| - NaClLog(4,
|
| - ("Leaving NaClSecureReverseClientPopHandler:"
|
| - " returning %"NACL_PRIxPTR"\n"),
|
| - (uintptr_t) head);
|
| - return head;
|
| -}
|
| -
|
| -static
|
| -void NaClSecureReverseClientInternalCallback(
|
| - void *state,
|
| - struct NaClThreadInterface *tif,
|
| - struct NaClDesc *conn) {
|
| - struct NaClSecureReverseClient *self =
|
| - (struct NaClSecureReverseClient *) state;
|
| - struct NaClConnectionHandler *hand_ptr;
|
| -
|
| - UNREFERENCED_PARAMETER(tif);
|
| - NaClLog(4, "Entered NaClSecureReverseClientInternalCallback\n");
|
| - hand_ptr = NaClSecureReverseClientPopHandler(self);
|
| - NaClLog(4, " got callback object %"NACL_PRIxPTR"\n", (uintptr_t) hand_ptr);
|
| - NaClLog(4,
|
| - " callback:0x%"NACL_PRIxPTR"(0x%"NACL_PRIxPTR",0x%"NACL_PRIxPTR")\n",
|
| - (uintptr_t) hand_ptr->handler,
|
| - (uintptr_t) hand_ptr->state,
|
| - (uintptr_t) conn);
|
| - (*hand_ptr->handler)(hand_ptr->state, tif, conn);
|
| - NaClLog(4, "NaClSecureReverseClientInternalCallback: freeing memory\n");
|
| - free(hand_ptr);
|
| - NaClLog(4, "Leaving NaClSecureReverseClientInternalCallback\n");
|
| -}
|
| -
|
| -/*
|
| - * Require an initial connection handler in the Ctor, so that it's
|
| - * obvious that a reverse client needs to accept an IMC connection
|
| - * from the server to get things bootstrapped.
|
| - */
|
| -int NaClSecureReverseClientCtor(
|
| - struct NaClSecureReverseClient *self,
|
| - void (*client_callback)(
|
| - void *, struct NaClThreadInterface*, struct NaClDesc *),
|
| - void *state,
|
| - struct NaClApp *nap) {
|
| - NaClLog(4,
|
| - ("Entered NaClSecureReverseClientCtor, self 0x%"NACL_PRIxPTR","
|
| - " nap 0x%"NACL_PRIxPTR"\n"),
|
| - (uintptr_t) self,
|
| - (uintptr_t) nap);
|
| - if (!NaClSimpleRevClientCtor(&self->base,
|
| - NaClSecureReverseClientInternalCallback,
|
| - (void *) self,
|
| - NaClThreadInterfaceThreadFactory,
|
| - (void *) NULL)) {
|
| - goto failure_simple_ctor;
|
| - }
|
| - NaClLog(4, "NaClSecureReverseClientCtor: Mutex\n");
|
| - if (!NaClMutexCtor(&self->mu)) {
|
| - goto failure_mutex_ctor;
|
| - }
|
| - self->nap = nap;
|
| - self->queue_head = (struct NaClConnectionHandler *) NULL;
|
| - self->queue_insert = &self->queue_head;
|
| -
|
| - NACL_VTBL(NaClRefCount, self) =
|
| - (struct NaClRefCountVtbl *) &kNaClSecureReverseClientVtbl;
|
| -
|
| - NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler\n");
|
| - if (!NaClSecureReverseClientInsertHandler(self,
|
| - client_callback,
|
| - state)) {
|
| - goto failure_handler_insert;
|
| - }
|
| -
|
| - NaClLog(4, "Leaving NaClSecureReverseClientCtor\n");
|
| - return 1;
|
| -
|
| - failure_handler_insert:
|
| - NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler failed\n");
|
| - NACL_VTBL(NaClRefCount, self) =
|
| - (struct NaClRefCountVtbl *) &kNaClSimpleRevClientVtbl;
|
| -
|
| - self->nap = NULL;
|
| - self->queue_insert = (struct NaClConnectionHandler **) NULL;
|
| - NaClMutexDtor(&self->mu);
|
| -
|
| - failure_mutex_ctor:
|
| - NaClLog(4, "NaClSecureReverseClientCtor: Mutex failed\n");
|
| - (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
|
| - failure_simple_ctor:
|
| - NaClLog(4, "Leaving NaClSecureReverseClientCtor\n");
|
| - return 0;
|
| -}
|
| -
|
| -void NaClSecureReverseClientDtor(struct NaClRefCount *vself) {
|
| - struct NaClSecureReverseClient *self =
|
| - (struct NaClSecureReverseClient *) vself;
|
| -
|
| - struct NaClConnectionHandler *entry;
|
| - struct NaClConnectionHandler *next;
|
| -
|
| - for (entry = self->queue_head; NULL != entry; entry = next) {
|
| - next = entry->next;
|
| - free(entry);
|
| - }
|
| - NaClMutexDtor(&self->mu);
|
| -
|
| - NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *)
|
| - &kNaClSimpleRevClientVtbl;
|
| - (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
|
| -}
|
| -
|
| -int NaClSecureServiceConnectionFactory(
|
| - struct NaClSimpleService *vself,
|
| - struct NaClDesc *conn,
|
| - struct NaClSimpleServiceConnection **out) {
|
| - struct NaClSecureService *self =
|
| - (struct NaClSecureService *) vself;
|
| -
|
| - /* our instance_data is not connection specific */
|
| - return NaClSimpleServiceConnectionFactoryWithInstanceData(
|
| - vself, conn, (void *) self->nap, out);
|
| -}
|
| -
|
| -int NaClSecureServiceAcceptAndSpawnHandler(struct NaClSimpleService *vself) {
|
| - int rv;
|
| -
|
| - NaClLog(4,
|
| - "NaClSecureServiceAcceptAndSpawnHandler: invoking base class vfn\n");
|
| - rv = (*kNaClSimpleServiceVtbl.AcceptAndSpawnHandler)(vself);
|
| - if (0 != rv) {
|
| - NaClLog(LOG_FATAL,
|
| - "Secure channel AcceptAndSpawnHandler returned %d\n",
|
| - rv);
|
| - }
|
| - NaClThreadExit(0);
|
| - /*
|
| - * NOTREACHED The port is now to be used by untrusted code: all
|
| - * subsequent connections are handled there.
|
| - */
|
| - return rv;
|
| -}
|
| -
|
| -void NaClSecureServiceRpcHandler(struct NaClSimpleService *vself,
|
| - struct NaClSimpleServiceConnection *vconn) {
|
| -
|
| - NaClLog(4, "NaClSecureChannelThread started\n");
|
| - (*kNaClSimpleServiceVtbl.RpcHandler)(vself, vconn);
|
| - NaClLog(4, "NaClSecureChannelThread: channel closed, exiting.\n");
|
| - NaClExit(0);
|
| -}
|
| -
|
| -struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl = {
|
| - {
|
| - NaClSecureServiceDtor,
|
| - },
|
| - NaClSecureServiceConnectionFactory,
|
| - NaClSimpleServiceAcceptConnection,
|
| - NaClSecureServiceAcceptAndSpawnHandler,
|
| - NaClSecureServiceRpcHandler,
|
| -};
|
| -
|
| -struct NaClSimpleRevClientVtbl const kNaClSecureReverseClientVtbl = {
|
| - {
|
| - NaClSecureReverseClientDtor,
|
| - },
|
| -};
|
| -
|
| -
|
| void NaClSecureCommandChannel(struct NaClApp *nap) {
|
| struct NaClSecureService *secure_command_server;
|
|
|
| @@ -1724,6 +1456,7 @@ void NaClSecureCommandChannel(struct NaClApp *nap) {
|
| { "log:is:", NaClSecureChannelLog, },
|
| { "load_module:hs:", NaClLoadModuleRpc, },
|
| { "load_irt:h:", NaClLoadIrtRpc, },
|
| + { "command_setup::h", NaClCommandServiceSetupRpc, },
|
| { "reverse_setup::h", NaClSecureReverseClientSetup, },
|
| /* add additional calls here. upcall set up? start module signal? */
|
| { (char const *) NULL, (NaClSrpcMethod) NULL, },
|
|
|