LCOV - code coverage report
Current view: directory - src/trusted/reverse_service - reverse_service_c.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 359 230 64.1 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : #define NACL_LOG_MODULE_NAME "reverse_service_c"
       7                 : 
       8                 : #include "native_client/src/trusted/reverse_service/reverse_service_c.h"
       9                 : 
      10                 : #include <limits.h>
      11                 : #include <string.h>
      12                 : 
      13                 : #include "native_client/src/include/nacl_compiler_annotations.h"
      14                 : #include "native_client/src/include/portability_io.h"
      15                 : 
      16                 : #include "native_client/src/public/nacl_file_info.h"
      17                 : 
      18                 : #include "native_client/src/shared/platform/nacl_check.h"
      19                 : #include "native_client/src/shared/platform/nacl_host_desc.h"
      20                 : #include "native_client/src/shared/platform/nacl_log.h"
      21                 : #include "native_client/src/shared/platform/nacl_sync.h"
      22                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      23                 : #include "native_client/src/shared/platform/nacl_threads.h"
      24                 : 
      25                 : #include "native_client/src/shared/srpc/nacl_srpc.h"
      26                 : 
      27                 : #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
      28                 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
      29                 : 
      30                 : #include "native_client/src/trusted/reverse_service/manifest_rpc.h"
      31                 : #include "native_client/src/trusted/reverse_service/reverse_control_rpc.h"
      32                 : 
      33                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      34                 : #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
      35                 : 
      36                 : struct NaClSrpcHandlerDesc const kNaClReverseServiceHandlers[]; /* fwd */
      37                 : 
      38                 : int NaClReverseThreadIfFactoryFn(
      39                 :     void                        *factory_data,
      40                 :     NaClThreadIfStartFunction   fn_ptr,
      41                 :     void                        *thread_data,
      42                 :     size_t                      thread_stack_size,
      43                 :     struct NaClThreadInterface  **out_new_thread); /* fwd */
      44                 : 
      45               5 : int NaClReverseServiceCtor(struct NaClReverseService    *self,
      46               5 :                            struct NaClReverseInterface  *iface,
      47               5 :                            struct NaClDesc              *conn_cap) {
      48               5 :   int retval = 0; /* fail */
      49                 : 
      50              15 :   CHECK(iface != NULL);
      51                 : 
      52              10 :   NaClLog(4, "Entered NaClReverseServiceCtor\n");
      53               5 :   if (!NaClSimpleRevServiceCtor(&self->base,
      54                 :                                 conn_cap,
      55                 :                                 kNaClReverseServiceHandlers,
      56                 :                                 NaClReverseThreadIfFactoryFn,
      57                 :                                 (void *) self)) {
      58               0 :     NaClLog(4, "NaClReverseServiceCtor: NaClSimpleRevServiceCtor failed\n");
      59               0 :     goto done;
      60                 :   }
      61               5 :   NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl *)
      62                 :       &kNaClReverseServiceVtbl;
      63               5 :   if (!NaClMutexCtor(&self->mu)) {
      64               0 :     NaClLog(4, "NaClMutexCtor failed\n");
      65               0 :     goto mutex_ctor_fail;
      66                 :   }
      67               5 :   if (!NaClCondVarCtor(&self->cv)) {
      68               0 :     NaClLog(4, "NaClCondVar failed\n");
      69               0 :     goto condvar_ctor_fail;
      70                 :   }
      71                 :   /* success return path */
      72               5 :   self->iface = (struct NaClReverseInterface *) NaClRefCountRef(
      73                 :       (struct NaClRefCount *) iface);
      74               5 :   self->thread_count = 0;
      75                 : 
      76               5 :   retval = 1;
      77               5 :   goto done;
      78                 : 
      79                 :   /* cleanup unwind */
      80                 :  condvar_ctor_fail:
      81               0 :   NaClMutexDtor(&self->mu);
      82                 :  mutex_ctor_fail:
      83               0 :   (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
      84                 :  done:
      85               5 :   return retval;
      86                 : }
      87                 : 
      88               5 : void NaClReverseServiceDtor(struct NaClRefCount *vself) {
      89               5 :   struct NaClReverseService *self = (struct NaClReverseService *) vself;
      90                 : 
      91               5 :   if (0 != self->thread_count) {
      92               0 :     NaClLog(LOG_FATAL,
      93                 :             "ReverseService dtor when thread count is nonzero\n");
      94               0 :   }
      95               5 :   self->thread_count = 0;
      96               5 :   NaClRefCountUnref((struct NaClRefCount *) self->iface);
      97               5 :   NaClCondVarDtor(&self->cv);
      98               5 :   NaClMutexDtor(&self->mu);
      99                 : 
     100               5 :   NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl *)
     101                 :       &kNaClSimpleRevServiceVtbl;
     102               5 :   (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
     103               5 : }
     104                 : 
     105                 : static void NaClReverseServiceAddChannelRpc(
     106               3 :     struct NaClSrpcRpc      *rpc,
     107               3 :     struct NaClSrpcArg      **in_args,
     108               3 :     struct NaClSrpcArg      **out_args,
     109               3 :     struct NaClSrpcClosure  *done_cls) {
     110               3 :   struct NaClReverseService *nrsp =
     111                 :     (struct NaClReverseService *) rpc->channel->server_instance_data;
     112               6 :   UNREFERENCED_PARAMETER(in_args);
     113                 : 
     114               6 :   NaClLog(4, "Entered AddChannel\n");
     115               3 :   out_args[0]->u.ival = (uint32_t)(*NACL_VTBL(NaClSimpleRevService, nrsp)->
     116                 :       ConnectAndSpawnHandlerCb)(&nrsp->base, NULL, (void *) nrsp);
     117               6 :   NaClLog(4, "Leaving AddChannel\n");
     118               3 :   rpc->result = NACL_SRPC_RESULT_OK;
     119               3 :   (*done_cls->Run)(done_cls);
     120               3 : }
     121                 : 
     122                 : static void NaClReverseServiceModuleInitDoneRpc(
     123               1 :     struct NaClSrpcRpc      *rpc,
     124               1 :     struct NaClSrpcArg      **in_args,
     125               1 :     struct NaClSrpcArg      **out_args,
     126               1 :     struct NaClSrpcClosure  *done_cls) {
     127               1 :   struct NaClReverseService *nrsp =
     128                 :     (struct NaClReverseService *) rpc->channel->server_instance_data;
     129               2 :   UNREFERENCED_PARAMETER(in_args);
     130               2 :   UNREFERENCED_PARAMETER(out_args);
     131                 : 
     132               2 :   NaClLog(4, "Entered ModuleInitDone: service 0x%08"NACL_PRIxPTR"\n",
     133                 :           (uintptr_t) nrsp);
     134               2 :   NaClLog(4, "ModuleInitDone: invoking StartupInitializationComplete\n");
     135               1 :   (*NACL_VTBL(NaClReverseInterface, nrsp->iface)->
     136                 :    StartupInitializationComplete)(nrsp->iface);
     137               2 :   NaClLog(4, "Leaving ModuleInitDoneRpc\n");
     138               1 :   rpc->result = NACL_SRPC_RESULT_OK;
     139               1 :   (*done_cls->Run)(done_cls);
     140               1 : }
     141                 : 
     142                 : static void NaClReverseServiceModuleExitRpc(
     143               2 :     struct NaClSrpcRpc      *rpc,
     144               2 :     struct NaClSrpcArg      **in_args,
     145               2 :     struct NaClSrpcArg      **out_args,
     146               2 :     struct NaClSrpcClosure  *done_cls) {
     147               2 :   struct NaClReverseService *nrsp =
     148                 :     (struct NaClReverseService *) rpc->channel->server_instance_data;
     149               2 :   int                       exit_status = in_args[0]->u.ival;
     150               4 :   UNREFERENCED_PARAMETER(out_args);
     151                 : 
     152               4 :   NaClLog(4,
     153                 :           ("Entered ModuleExitRpc: service 0x%08"NACL_PRIxPTR
     154                 :            ", exit_status 0x%d\n"),
     155                 :           (uintptr_t) nrsp, exit_status);
     156               4 :   NaClLog(4, "ModuleExitRpc: invoking ReportExitStatus\n");
     157               2 :   (*NACL_VTBL(NaClReverseInterface, nrsp->iface)->
     158                 :    ReportExitStatus)(nrsp->iface, exit_status);
     159               4 :   NaClLog(4, "Leaving ModuleExitRpc\n");
     160               2 :   rpc->result = NACL_SRPC_RESULT_OK;
     161               2 :   (*done_cls->Run)(done_cls);
     162               2 : }
     163                 : 
     164                 : static void NaClReverseServicePostMessageRpc(
     165               0 :     struct NaClSrpcRpc      *rpc,
     166               0 :     struct NaClSrpcArg      **in_args,
     167               0 :     struct NaClSrpcArg      **out_args,
     168               0 :     struct NaClSrpcClosure  *done_cls) {
     169               0 :   struct NaClReverseService *nrsp =
     170                 :     (struct NaClReverseService *) rpc->channel->server_instance_data;
     171               0 :   char                      *msg = in_args[0]->arrays.carr;
     172               0 :   nacl_abi_size_t           nbytes = in_args[0]->u.count;
     173                 : 
     174               0 :   NaClLog(4, "Entered PostMessageRpc: service 0x%08"NACL_PRIxPTR"\n",
     175                 :           (uintptr_t) nrsp);
     176               0 :   (*NACL_VTBL(NaClReverseInterface, nrsp->iface)->
     177                 :    DoPostMessage)(nrsp->iface, msg, nbytes);
     178               0 :   out_args[0]->u.ival = nbytes;
     179               0 :   NaClLog(4, "Leaving PostMessageRpc\n");
     180               0 :   rpc->result = NACL_SRPC_RESULT_OK;
     181               0 :   (*done_cls->Run)(done_cls);
     182               0 : }
     183                 : 
     184                 : static void NaClReverseServiceCreateProcessRpc(
     185               0 :     struct NaClSrpcRpc      *rpc,
     186               0 :     struct NaClSrpcArg      **in_args,
     187               0 :     struct NaClSrpcArg      **out_args,
     188               0 :     struct NaClSrpcClosure  *done_cls) {
     189               0 :   struct NaClReverseService *nrsp =
     190                 :     (struct NaClReverseService *) rpc->channel->server_instance_data;
     191               0 :   struct NaClDesc           *sock_addr;
     192               0 :   struct NaClDesc           *app_addr;
     193               0 :   int                       status;
     194               0 :   UNREFERENCED_PARAMETER(in_args);
     195                 : 
     196               0 :   NaClLog(4,
     197                 :           "Entered NaClReverseServiceCreateProcessRpc: 0x%08"NACL_PRIxPTR"\n",
     198                 :           (uintptr_t) nrsp);
     199               0 :   status = (*NACL_VTBL(NaClReverseInterface, nrsp->iface)->
     200                 :             CreateProcess)(nrsp->iface, &sock_addr, &app_addr);
     201               0 :   out_args[0]->u.ival = status;
     202               0 :   out_args[1]->u.hval = (0 == status)
     203                 :       ? sock_addr
     204               0 :       : (struct NaClDesc *) NaClDescInvalidMake();
     205               0 :   out_args[2]->u.hval = (0 == status)
     206                 :       ? app_addr
     207               0 :       : (struct NaClDesc *) NaClDescInvalidMake();
     208               0 :   NaClLog(4, "Leaving NaClReverseServiceCreateProcessRpc\n");
     209               0 :   rpc->result = NACL_SRPC_RESULT_OK;
     210               0 :   (*done_cls->Run)(done_cls);
     211               0 : }
     212                 : 
     213                 : struct CreateProcessFunctorState {
     214                 :   struct NaClDesc **out_sock_addr;
     215                 :   struct NaClDesc **out_app_addr;
     216                 :   int32_t *out_pid;
     217                 :   struct NaClSrpcClosure *cls;
     218                 : };
     219                 : 
     220               2 : static void CreateProcessFunctor(void *functor_state,
     221               2 :                                  struct NaClDesc *sock_addr,
     222               2 :                                  struct NaClDesc *app_addr,
     223               2 :                                  int32_t pid) {
     224               2 :   struct CreateProcessFunctorState *state =
     225                 :       (struct CreateProcessFunctorState *) functor_state;
     226               2 :   if (NULL == sock_addr) {
     227               0 :     sock_addr = (struct NaClDesc *) NaClDescInvalidMake();
     228               0 :   }
     229               2 :   if (NULL == app_addr) {
     230               0 :     app_addr = (struct NaClDesc *) NaClDescInvalidMake();
     231               0 :   }
     232               2 :   *state->out_sock_addr = sock_addr;
     233               2 :   *state->out_app_addr = app_addr;
     234               2 :   *state->out_pid = pid;
     235               2 :   (*state->cls->Run)(state->cls);
     236               2 : }
     237                 : 
     238                 : static void NaClReverseServiceCreateProcessFunctorResultRpc(
     239               2 :     struct NaClSrpcRpc      *rpc,
     240               2 :     struct NaClSrpcArg      **in_args,
     241               2 :     struct NaClSrpcArg      **out_args,
     242               2 :     struct NaClSrpcClosure  *done_cls) {
     243               2 :   struct NaClReverseService *nrsp =
     244                 :     (struct NaClReverseService *) rpc->channel->server_instance_data;
     245               2 :   struct CreateProcessFunctorState functor_state;
     246                 : 
     247               4 :   UNREFERENCED_PARAMETER(in_args);
     248                 : 
     249               4 :   NaClLog(4,
     250                 :           "Entered NaClReverseServiceCreateProcessFunctorResultRpc: 0x%08"
     251                 :           NACL_PRIxPTR"\n",
     252                 :           (uintptr_t) nrsp);
     253               2 :   functor_state.out_sock_addr = &out_args[0]->u.hval;
     254               2 :   functor_state.out_app_addr = &out_args[1]->u.hval;
     255               2 :   functor_state.out_pid = &out_args[2]->u.ival;
     256               2 :   functor_state.cls = done_cls;
     257                 : 
     258               2 :   rpc->result = NACL_SRPC_RESULT_OK;
     259               2 :   (*NACL_VTBL(NaClReverseInterface, nrsp->iface)->
     260                 :    CreateProcessFunctorResult)(nrsp->iface,
     261                 :                                CreateProcessFunctor, &functor_state);
     262               4 :   NaClLog(4, "Leaving NaClReverseServiceCreateProcessFunctorResultRpc\n");
     263               2 : }
     264                 : 
     265                 : /*
     266                 :  * Manifest name service, internal APIs.
     267                 :  *
     268                 :  * Manifest file lookups result in read-only file descriptors with a
     269                 :  * handle.  When the descriptor is closed, the service runtime must
     270                 :  * inform the plugin of this using the handle, so that the File object
     271                 :  * reference can be closed (thereby allowing the browser to delete or
     272                 :  * otherwise garbage collect the file).  Files, being from the
     273                 :  * manifest, cannot be deleted.  The manifest is also a read-only
     274                 :  * object, so no new entries can be made to it.
     275                 :  *
     276                 :  * Read-only proxies do not require quota support per se, since we do
     277                 :  * not limit read bandwidth.  Quota support is needed for storage
     278                 :  * limits, though could also be used to limit write bandwidth (prevent
     279                 :  * disk output saturation, limit malicious code's ability to cause
     280                 :  * disk failures, especially with flash disks with limited write
     281                 :  * cycles).
     282                 :  */
     283                 : 
     284                 : /*
     285                 :  * Look up by string name, resulting in a handle (if name is in the
     286                 :  * preimage), a object proxy handle, and an error code.
     287                 :  */
     288                 : static void NaClReverseServiceManifestLookupRpc(
     289               2 :     struct NaClSrpcRpc      *rpc,
     290               2 :     struct NaClSrpcArg      **in_args,
     291               2 :     struct NaClSrpcArg      **out_args,
     292               2 :     struct NaClSrpcClosure  *done_cls) {
     293               2 :   struct NaClReverseService *nrsp =
     294                 :     (struct NaClReverseService *) rpc->channel->server_instance_data;
     295               2 :   char                      *url_key = in_args[0]->arrays.str;
     296               2 :   int                       flags = in_args[0]->u.ival;
     297               2 :   struct NaClFileInfo       info;
     298               2 :   struct NaClHostDesc       *host_desc;
     299               2 :   struct NaClDescIoDesc     *io_desc = NULL;
     300               2 :   struct NaClDesc           *nacl_desc = NULL;
     301                 : 
     302               2 :   memset(&info, 0, sizeof(info));
     303                 : 
     304               4 :   NaClLog(4, "Entered ManifestLookupRpc: 0x%08"NACL_PRIxPTR", %s, %d\n",
     305                 :           (uintptr_t) nrsp, url_key, flags);
     306                 : 
     307               4 :   NaClLog(4, "ManifestLookupRpc: invoking OpenManifestEntry\n");
     308               4 :   if (!(*NACL_VTBL(NaClReverseInterface, nrsp->iface)->
     309                 :         OpenManifestEntry)(nrsp->iface, url_key, &info)
     310                 :       || -1 == info.desc) {
     311               0 :     NaClLog(1, "ManifestLookupRpc: OpenManifestEntry failed.\n");
     312               0 :     out_args[0]->u.ival = NACL_ABI_ENOENT; /* failed */
     313               0 :     out_args[1]->u.hval = (struct NaClDesc *) NaClDescInvalidMake();
     314               0 :     out_args[2]->u.lval = 0;
     315               0 :     out_args[3]->u.lval = 0;
     316               0 :     out_args[4]->u.count = 0;
     317               0 :     goto done;
     318                 :   }
     319               4 :   NaClLog(4, "ManifestLookupRpc: OpenManifestEntry returned desc %d.\n",
     320                 :           info.desc);
     321               2 :   host_desc = (struct NaClHostDesc *) malloc(sizeof *host_desc);
     322               6 :   CHECK(host_desc != NULL);
     323               6 :   CHECK(NaClHostDescPosixTake(host_desc, info.desc, NACL_ABI_O_RDONLY) == 0);
     324               2 :   io_desc = NaClDescIoDescMake(host_desc);
     325               6 :   CHECK(io_desc != NULL);
     326               2 :   nacl_desc = (struct NaClDesc *) io_desc;
     327                 : 
     328               2 :   out_args[0]->u.ival = 0;  /* OK */
     329               2 :   out_args[1]->u.hval = nacl_desc;
     330               2 :   out_args[2]->u.lval = (int64_t) info.file_token.lo;
     331               2 :   out_args[3]->u.lval = (int64_t) info.file_token.hi;
     332               2 :   out_args[4]->u.count = 10;
     333               6 :   strncpy(out_args[4]->arrays.carr, "123456789", 10);
     334                 :   /*
     335                 :    * TODO(phosek): the array should be an object reference (issue 3035).
     336                 :    */
     337                 : 
     338                 :  done:
     339               2 :   rpc->result = NACL_SRPC_RESULT_OK;
     340               2 :   (*done_cls->Run)(done_cls);
     341               2 :   NaClDescSafeUnref((struct NaClDesc *) io_desc);
     342               2 : }
     343                 : 
     344                 : static void NaClReverseServiceRequestQuotaForWriteRpc(
     345               0 :     struct NaClSrpcRpc      *rpc,
     346               0 :     struct NaClSrpcArg      **in_args,
     347               0 :     struct NaClSrpcArg      **out_args,
     348               0 :     struct NaClSrpcClosure  *done_cls) {
     349               0 :   struct NaClReverseService *nrsp =
     350                 :     (struct NaClReverseService *) rpc->channel->server_instance_data;
     351               0 :   char                      *file_id = in_args[0]->arrays.carr;
     352               0 :   int64_t                   offset = in_args[1]->u.lval;
     353               0 :   int64_t                   length = in_args[2]->u.lval;
     354                 : 
     355               0 :   NaClLog(4, "Entered RequestQuotaForWriteRpc: 0x%08"NACL_PRIxPTR"\n",
     356                 :           (uintptr_t) nrsp);
     357               0 :   out_args[0]->u.lval = (*NACL_VTBL(NaClReverseInterface, nrsp->iface)->
     358                 :       RequestQuotaForWrite)(nrsp->iface, file_id, offset, length);
     359               0 :   NaClLog(4, "Leaving RequestQuotaForWriteRpc\n");
     360               0 :   rpc->result = NACL_SRPC_RESULT_OK;
     361               0 :   (*done_cls->Run)(done_cls);
     362               0 : }
     363                 : 
     364                 : struct NaClReverseCountingThreadInterface {
     365                 :   struct NaClThreadInterface  base NACL_IS_REFCOUNT_SUBCLASS;
     366                 :   struct NaClReverseService   *reverse_service;
     367                 : };
     368                 : 
     369                 : extern struct NaClThreadInterfaceVtbl
     370                 :   const kNaClReverseThreadInterfaceVtbl; /* fwd */
     371                 : 
     372                 : int NaClReverseThreadIfCtor_protected(
     373               8 :     struct NaClReverseCountingThreadInterface   *self,
     374               8 :     void                                        *factory_data,
     375               8 :     NaClThreadIfStartFunction                   fn_ptr,
     376               8 :     void                                        *thread_data,
     377               8 :     size_t                                      thread_stack_size) {
     378               8 :   struct NaClReverseService *nrsp = (struct NaClReverseService *) factory_data;
     379                 : 
     380              16 :   NaClLog(3, "Entered NaClReverseThreadIfCtor_protected\n");
     381              16 :   if (!NaClThreadInterfaceCtor_protected(
     382                 :           (struct NaClThreadInterface *) self,
     383                 :           NaClReverseThreadIfFactoryFn,
     384               8 :           NaClRefCountRef((struct NaClRefCount *) nrsp),
     385                 :           fn_ptr,
     386                 :           thread_data,
     387                 :           thread_stack_size)) {
     388               0 :     NaClLog(4, "NaClThreadInterfaceCtor_protected failed\n");
     389               0 :     NaClRefCountUnref((struct NaClRefCount *) nrsp);
     390               0 :     return 0;
     391                 :   }
     392                 : 
     393               8 :   self->reverse_service = nrsp;
     394               8 :   (*NACL_VTBL(NaClReverseService, nrsp)->ThreadCountIncr)(nrsp);
     395                 : 
     396               8 :   NACL_VTBL(NaClRefCount, self) =
     397                 :       (struct NaClRefCountVtbl *) &kNaClReverseThreadInterfaceVtbl;
     398                 : 
     399              16 :   NaClLog(3, "Leaving NaClAddrSpSquattingThreadIfCtor_protected\n");
     400               8 :   return 1;
     401               8 : }
     402                 : 
     403                 : /*
     404                 :  * Takes ownership of rev reference.  Caller should Ref() the argument
     405                 :  * and Unref on failure if caller does not wish to pass ownership.
     406                 :  */
     407                 : int NaClReverseThreadIfFactoryFn(
     408               8 :     void                        *factory_data,
     409               8 :     NaClThreadIfStartFunction   fn_ptr,
     410               8 :     void                        *thread_data,
     411               8 :     size_t                      thread_stack_size,
     412               8 :     struct NaClThreadInterface  **out_new_thread) {
     413               8 :   struct NaClReverseCountingThreadInterface *new_thread;
     414               8 :   int                                       rv = 1;
     415                 : 
     416              16 :   NaClLog(3, "Entered NaClReverseThreadIfFactoryFn\n");
     417                 :   new_thread = (struct NaClReverseCountingThreadInterface *)
     418               8 :       malloc(sizeof *new_thread);
     419               8 :   if (NULL == new_thread) {
     420               0 :     rv = 0;
     421               0 :     goto cleanup;
     422                 :   }
     423                 : 
     424                 :   if (!(rv =
     425               8 :         NaClReverseThreadIfCtor_protected(new_thread,
     426                 :                                           factory_data,
     427                 :                                           fn_ptr,
     428                 :                                           thread_data,
     429                 :                                           thread_stack_size))) {
     430               0 :     goto cleanup;
     431                 :   }
     432                 : 
     433               8 :   *out_new_thread = (struct NaClThreadInterface *) new_thread;
     434               8 :   new_thread = NULL;
     435                 : 
     436                 :  cleanup:
     437               8 :   free(new_thread);
     438              16 :   NaClLog(3,
     439                 :           "Leaving NaClReverseThreadIfFactoryFn, rv %d\n",
     440                 :           rv);
     441               8 :   return rv;
     442                 : }
     443                 : 
     444               8 : void NaClReverseThreadIfDtor(struct NaClRefCount *vself) {
     445               8 :   struct NaClReverseCountingThreadInterface *self =
     446                 :       (struct NaClReverseCountingThreadInterface *) vself;
     447                 : 
     448               8 :   NaClRefCountUnref((struct NaClRefCount *) self->reverse_service);
     449               8 :   self->reverse_service = NULL;
     450               8 :   NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
     451               8 :   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
     452               8 : }
     453                 : 
     454               8 : void NaClReverseThreadIfLaunchCallback(struct NaClThreadInterface *self) {
     455              16 :   NaClLog(4,
     456                 :           ("NaClReverseThreadIfLaunchCallback: thread 0x%"NACL_PRIxPTR
     457                 :            " is launching\n"),
     458                 :           (uintptr_t) self);
     459               8 : }
     460                 : 
     461               8 : void NaClReverseThreadIfExit(struct NaClThreadInterface   *vself,
     462               8 :                              void                         *exit_code) {
     463               8 :   struct NaClReverseCountingThreadInterface *self =
     464                 :       (struct NaClReverseCountingThreadInterface *) vself;
     465              16 :   UNREFERENCED_PARAMETER(exit_code);
     466              16 :   NaClLog(4,
     467                 :           ("NaClReverseThreadIfExit: thread 0x%"NACL_PRIxPTR
     468                 :            " is exiting\n"),
     469                 :           (uintptr_t) vself);
     470                 : 
     471               8 :   (*NACL_VTBL(NaClReverseService, self->reverse_service)->ThreadCountDecr)(
     472                 :       self->reverse_service);
     473                 : 
     474               8 :   NaClRefCountUnref((struct NaClRefCount *) self);
     475               8 :   NaClThreadExit();
     476               8 : }
     477                 : 
     478                 : struct NaClSrpcHandlerDesc const kNaClReverseServiceHandlers[] = {
     479                 :   { NACL_REVERSE_CONTROL_ADD_CHANNEL, NaClReverseServiceAddChannelRpc, },
     480                 :   { NACL_REVERSE_CONTROL_INIT_DONE, NaClReverseServiceModuleInitDoneRpc, },
     481                 :   { NACL_REVERSE_CONTROL_REPORT_STATUS, NaClReverseServiceModuleExitRpc, },
     482                 :   { NACL_REVERSE_CONTROL_POST_MESSAGE, NaClReverseServicePostMessageRpc, },
     483                 :   { NACL_REVERSE_CONTROL_CREATE_PROCESS, NaClReverseServiceCreateProcessRpc, },
     484                 :   { NACL_REVERSE_CONTROL_CREATE_PROCESS_INTERLOCKED,
     485                 :     NaClReverseServiceCreateProcessFunctorResultRpc, },
     486                 :   { NACL_MANIFEST_LOOKUP, NaClReverseServiceManifestLookupRpc, },
     487                 :   { NACL_REVERSE_REQUEST_QUOTA_FOR_WRITE, NaClReverseServiceRequestQuotaForWriteRpc, },
     488                 :   { (char const *) NULL, (NaClSrpcMethod) NULL, },
     489                 : };
     490                 : 
     491                 : struct NaClThreadInterfaceVtbl const kNaClReverseThreadInterfaceVtbl = {
     492                 :   {
     493                 :     NaClReverseThreadIfDtor,
     494                 :   },
     495                 :   NaClThreadInterfaceStartThread,
     496                 :   NaClReverseThreadIfLaunchCallback,
     497                 :   NaClReverseThreadIfExit,
     498                 : };
     499                 : 
     500               5 : static void NaClReverseServiceCbBinder(void   *state,
     501               5 :                                        int    server_loop_ret) {
     502               5 :   struct NaClReverseService *self = (struct NaClReverseService *) state;
     503              10 :   UNREFERENCED_PARAMETER(server_loop_ret);
     504                 : 
     505               5 :   (*NACL_VTBL(NaClReverseInterface, self->iface)->ReportCrash)(
     506                 :       self->iface);
     507               5 : }
     508                 : 
     509               5 : int NaClStartServiceCb(struct NaClReverseService *self,
     510               5 :                        void (*exit_cb)(void *server_instance_data,
     511                 :                                        int  server_loop_ret),
     512               5 :                        void *instance_data) {
     513               5 :   int retval = 0; /* fail */
     514                 : 
     515              10 :   NaClLog(4, "Entered ReverseSocket::StartService\n");
     516                 : 
     517              10 :   NaClLog(4, "StartService: invoking ConnectAndSpawnHandler\n");
     518               5 :   if (0 != (*NACL_VTBL(NaClSimpleRevService, self)->
     519                 :             ConnectAndSpawnHandlerCb)((struct NaClSimpleRevService *) self,
     520                 :                                       exit_cb,
     521                 :                                       instance_data)) {
     522               0 :     NaClLog(LOG_ERROR, "StartServiceCb: ConnectAndSpawnHandlerCb failed\n.");
     523               0 :     goto done;
     524                 :   }
     525               5 :   retval = 1;
     526                 : 
     527                 :  done:
     528              10 :   NaClLog(4, "Leaving ReverseSocket::StartService\n");
     529               5 :   return retval;
     530                 : }
     531                 : 
     532               5 : int NaClReverseServiceStart(struct NaClReverseService   *self,
     533               5 :                             int                         crash_report) {
     534              10 :   NaClLog(4, "NaClReverseServiceStart: starting service\n");
     535               5 :   if (0 != crash_report) {
     536               5 :     return NaClStartServiceCb(self, NaClReverseServiceCbBinder, (void *) self);
     537                 :   } else {
     538               0 :     return NaClStartServiceCb(self, NULL, (void *) self);
     539                 :   }
     540                 :   return 0;
     541               5 : }
     542                 : 
     543                 : void NaClReverseServiceWaitForServiceThreadsToExit(
     544               5 :     struct NaClReverseService *self) {
     545              10 :   NaClLog(4, "NaClReverseServiceWaitForServiceThreadsToExit\n");
     546               5 :   NaClXMutexLock(&self->mu);
     547              13 :   while (0 != self->thread_count) {
     548               6 :     NaClLog(4, "NaClReverseServiceWaitForServiceThreadsToExit: %d left\n",
     549                 :             self->thread_count);
     550               3 :     NaClXCondVarWait(&self->cv, &self->mu);
     551               6 :     NaClLog(5, "NaClReverseServiceWaitForServiceThreadsToExit: woke up\n");
     552               3 :   }
     553               5 :   NaClXMutexUnlock(&self->mu);
     554              10 :   NaClLog(4, "NaClReverseServiceWaitForServiceThreadsToExit: all done\n");
     555               5 : }
     556                 : 
     557                 : void NaClReverseServiceThreadCountIncr(
     558               8 :     struct NaClReverseService *self) {
     559              16 :   NaClLog(5, "NaClReverseServiceThreadCountIncr\n");
     560               8 :   NaClXMutexLock(&self->mu);
     561               8 :   if (0 == ++self->thread_count) {
     562               0 :     NaClLog(LOG_FATAL,
     563                 :             "NaClReverseServiceThreadCountIncr: "
     564                 :             "thread count overflow!\n");
     565               0 :   }
     566               8 :   NaClXMutexUnlock(&self->mu);
     567               8 : }
     568                 : 
     569                 : void NaClReverseServiceThreadCountDecr(
     570               8 :     struct NaClReverseService *self) {
     571              16 :   NaClLog(5, "NaClReverseServiceThreadCountDecr\n");
     572               8 :   NaClXMutexLock(&self->mu);
     573               8 :   if (0 == self->thread_count) {
     574               0 :     NaClLog(LOG_FATAL,
     575                 :             "NaClReverseServiceThreadCountDecr: "
     576                 :             "decrementing thread count when count is zero\n");
     577               0 :   }
     578               8 :   if (0 == --self->thread_count) {
     579               5 :     NaClXCondVarBroadcast(&self->cv);
     580               5 :   }
     581               8 :   NaClXMutexUnlock(&self->mu);
     582               8 : }
     583                 : 
     584                 : struct NaClReverseServiceVtbl const kNaClReverseServiceVtbl = {
     585                 :   {
     586                 :     {
     587                 :       NaClReverseServiceDtor,
     588                 :     },
     589                 :     NaClSimpleRevServiceConnectAndSpawnHandler,
     590                 :     NaClSimpleRevServiceConnectAndSpawnHandlerCb,
     591                 :     NaClSimpleRevServiceConnectionFactory,
     592                 :     NaClSimpleRevServiceRpcHandler,
     593                 :   },
     594                 :   NaClReverseServiceStart,
     595                 :   NaClReverseServiceWaitForServiceThreadsToExit,
     596                 :   NaClReverseServiceThreadCountIncr,
     597                 :   NaClReverseServiceThreadCountDecr,
     598                 : };
     599                 : 
     600                 : int NaClReverseInterfaceCtor_protected(
     601               5 :     struct NaClReverseInterface   *self) {
     602              10 :   NaClLog(4, "Entered NaClReverseInterfaceCtor_protected\n");
     603               5 :   if (!NaClRefCountCtor((struct NaClRefCount *) self)) {
     604               0 :     NaClLog(4,
     605                 :             "NaClReverseInterfaceCtor_protected: "
     606                 :             "NaClRefCountCtor base class ctor failed\n");
     607               0 :     return 0;
     608                 :   }
     609               5 :   NACL_VTBL(NaClRefCount, self) =
     610                 :       (struct NaClRefCountVtbl const *) &kNaClReverseInterfaceVtbl;
     611              10 :   NaClLog(4,
     612                 :           "Leaving NaClReverseInterfaceCtor_protected, returning 1\n");
     613               5 :   return 1;
     614               5 : }
     615                 : 
     616               0 : void NaClReverseInterfaceDtor(struct NaClRefCount *vself) {
     617               0 :   struct NaClReverseInterface *self =
     618                 :       (struct NaClReverseInterface *) vself;
     619                 : 
     620               0 :   NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
     621               0 :   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
     622               0 : }
     623                 : 
     624                 : void NaClReverseInterfaceStartupInitializationComplete(
     625               0 :     struct NaClReverseInterface *self) {
     626               0 :   NaClLog(3,
     627                 :           ("NaClReverseInterfaceStartupInitializationComplete(0x%08"
     628                 :            NACL_PRIxPTR")\n"),
     629                 :           (uintptr_t) self);
     630               0 : }
     631                 : 
     632                 : int NaClReverseInterfaceOpenManifestEntry(
     633               0 :     struct NaClReverseInterface   *self,
     634               0 :     char const                    *url_key,
     635               0 :     struct NaClFileInfo           *info) {
     636               0 :   NaClLog(3,
     637                 :           ("NaClReverseInterfaceOpenManifestEntry(0x%08"NACL_PRIxPTR", %s"
     638                 :            ", 0x%08"NACL_PRIxPTR")\n"),
     639                 :           (uintptr_t) self, url_key, (uintptr_t) info);
     640               0 :   return 0;
     641                 : }
     642                 : 
     643                 : void NaClReverseInterfaceReportCrash(
     644               0 :     struct NaClReverseInterface *self) {
     645               0 :   NaClLog(3,
     646                 :           "NaClReverseInterfaceReportCrash(0x%08"NACL_PRIxPTR")\n",
     647                 :           (uintptr_t) self);
     648               0 : }
     649                 : 
     650                 : void NaClReverseInterfaceReportExitStatus(
     651               0 :     struct NaClReverseInterface   *self,
     652               0 :     int                           exit_status) {
     653               0 :   NaClLog(3,
     654                 :           "NaClReverseInterfaceReportExitStatus(0x%08"NACL_PRIxPTR", 0x%x)\n",
     655                 :           (uintptr_t) self, exit_status);
     656               0 : }
     657                 : 
     658                 : void NaClReverseInterfaceDoPostMessage(
     659               0 :     struct NaClReverseInterface   *self,
     660               0 :     char const                    *message,
     661               0 :     size_t                        message_bytes) {
     662               0 :   NaClLog(3,
     663                 :           ("NaClReverseInterfaceDoPostMessage(0x%08"NACL_PRIxPTR", %s"
     664                 :            ", %08"NACL_PRIuS")\n"),
     665                 :           (uintptr_t) self, message, message_bytes);
     666               0 : }
     667                 : 
     668                 : int NaClReverseInterfaceCreateProcess(
     669               0 :     struct NaClReverseInterface   *self,
     670               0 :     struct NaClDesc               **out_sock_addr,
     671               0 :     struct NaClDesc               **out_app_addr) {
     672               0 :   NaClLog(3,
     673                 :           ("NaClReverseInterfaceCreateProcess(0x%08"NACL_PRIxPTR
     674                 :            ", 0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR")\n"),
     675                 :           (uintptr_t) self,
     676                 :           (uintptr_t) out_sock_addr,
     677                 :           (uintptr_t) out_app_addr);
     678               0 :   return -NACL_ABI_EAGAIN;
     679                 : }
     680                 : 
     681                 : int64_t NaClReverseInterfaceRequestQuotaForWrite(
     682               0 :     struct NaClReverseInterface   *self,
     683               0 :     char const                    *file_id,
     684               0 :     int64_t                       offset,
     685               0 :     int64_t                       length) {
     686               0 :   NaClLog(3,
     687                 :           ("NaClReverseInterfaceRequestQuotaForWrite(0x%08"NACL_PRIxPTR", %s"
     688                 :            ", %08"NACL_PRId64", %08"NACL_PRId64")\n"),
     689                 :           (uintptr_t) self, file_id, offset, length);
     690               0 :   return 0;
     691                 : }
     692                 : 
     693                 : void NaClReverseInterfaceCreateProcessFunctorResult(
     694               0 :     struct NaClReverseInterface *self,
     695               0 :     void (*result_functor)(void *functor_state,
     696                 :                            struct NaClDesc *out_sock_addr,
     697                 :                            struct NaClDesc *out_app_addr,
     698                 :                            int32_t out_pid_or_errno),
     699               0 :     void *functor_state) {
     700               0 :   NaClLog(3,
     701                 :           ("NaClReverseInterfaceCreateProcessFunctorResult(0x%08"NACL_PRIxPTR
     702                 :            ", 0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR")\n"),
     703                 :           (uintptr_t) self,
     704                 :           (uintptr_t) result_functor,
     705                 :           (uintptr_t) functor_state);
     706               0 : }
     707                 : 
     708               0 : void NaClReverseInterfaceFinalizeProcess(struct NaClReverseInterface *self,
     709               0 :                                          int32_t pid) {
     710               0 :   NaClLog(3,
     711                 :           ("NaClReverseInterfaceFinalizeProcess(0x%08"NACL_PRIxPTR", %d)\n"),
     712                 :           (uintptr_t) self, pid);
     713               0 : }
     714                 : 
     715                 : struct NaClReverseInterfaceVtbl const kNaClReverseInterfaceVtbl = {
     716                 :   {
     717                 :     NaClReverseInterfaceDtor,
     718                 :   },
     719                 :   NaClReverseInterfaceStartupInitializationComplete,
     720                 :   NaClReverseInterfaceOpenManifestEntry,
     721                 :   NaClReverseInterfaceReportCrash,
     722                 :   NaClReverseInterfaceReportExitStatus,
     723                 :   NaClReverseInterfaceDoPostMessage,
     724                 :   NaClReverseInterfaceCreateProcess,
     725                 :   NaClReverseInterfaceCreateProcessFunctorResult,
     726                 :   NaClReverseInterfaceFinalizeProcess,
     727                 :   NaClReverseInterfaceRequestQuotaForWrite,
     728                 : };

Generated by: LCOV version 1.7