LCOV - code coverage report
Current view: directory - src/trusted/manifest_name_service_proxy - manifest_proxy.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 178 124 69.7 %
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                 : 
       7                 : #define NACL_LOG_MODULE_NAME "manifest_proxy"
       8                 : 
       9                 : #include <string.h>
      10                 : 
      11                 : #include "native_client/src/trusted/manifest_name_service_proxy/manifest_proxy.h"
      12                 : 
      13                 : #include "native_client/src/public/name_service.h"
      14                 : #include "native_client/src/public/nacl_file_info.h"
      15                 : #include "native_client/src/shared/platform/nacl_log.h"
      16                 : #include "native_client/src/shared/platform/nacl_sync.h"
      17                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      18                 : #include "native_client/src/shared/srpc/nacl_srpc.h"
      19                 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
      20                 : #include "native_client/src/trusted/desc_cacheability/desc_cacheability.h"
      21                 : #include "native_client/src/trusted/reverse_service/manifest_rpc.h"
      22                 : #include "native_client/src/trusted/reverse_service/reverse_control_rpc.h"
      23                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      24                 : #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
      25                 : #include "native_client/src/trusted/service_runtime/nacl_secure_service.h"
      26                 : #include "native_client/src/trusted/validator/rich_file_info.h"
      27                 : #include "native_client/src/trusted/validator/validation_cache.h"
      28                 : 
      29                 : static void NaClManifestWaitForChannel_yield_mu(
      30               1 :     struct NaClManifestProxyConnection *self) {
      31               2 :   NaClLog(4, "Entered NaClManifestWaitForChannel_yield_mu\n");
      32               1 :   NaClXMutexLock(&self->mu);
      33               2 :   NaClLog(4, "NaClManifestWaitForChannel_yield_mu: checking channel\n");
      34               2 :   while (!self->channel_initialized) {
      35               0 :     NaClLog(4, "NaClManifestWaitForChannel_yield_mu: waiting\n");
      36               0 :     NaClXCondVarWait(&self->cv, &self->mu);
      37               0 :   }
      38               2 :   NaClLog(4, "Leaving NaClManifestWaitForChannel_yield_mu\n");
      39               1 : }
      40                 : 
      41                 : static void NaClManifestReleaseChannel_release_mu(
      42               1 :     struct NaClManifestProxyConnection *self) {
      43               2 :   NaClLog(4, "NaClManifestReleaseChannel_release_mu\n");
      44               1 :   NaClXMutexUnlock(&self->mu);
      45               1 : }
      46                 : 
      47                 : static void NaClManifestNameServiceInsertRpc(
      48               0 :     struct NaClSrpcRpc      *rpc,
      49               0 :     struct NaClSrpcArg      **in_args,
      50               0 :     struct NaClSrpcArg      **out_args,
      51               0 :     struct NaClSrpcClosure  *done_cls) {
      52                 : 
      53               0 :   UNREFERENCED_PARAMETER(in_args);
      54               0 :   NaClLog(4, "NaClManifestNameServiceInsertRpc\n");
      55               0 :   out_args[0]->u.ival = NACL_NAME_SERVICE_PERMISSION_DENIED;
      56                 :   /* cannot add names to the manifest! */
      57               0 :   rpc->result = NACL_SRPC_RESULT_OK;
      58               0 :   (*done_cls->Run)(done_cls);
      59               0 : }
      60                 : 
      61                 : static void NaClManifestNameServiceLookupRpc(
      62               1 :     struct NaClSrpcRpc      *rpc,
      63               1 :     struct NaClSrpcArg      **in_args,
      64               1 :     struct NaClSrpcArg      **out_args,
      65               1 :     struct NaClSrpcClosure  *done_cls) {
      66               1 :   struct NaClManifestProxyConnection  *proxy_conn =
      67                 :       (struct NaClManifestProxyConnection *) rpc->channel->server_instance_data;
      68               1 :   char                                *name = in_args[0]->arrays.str;
      69               1 :   int                                 flags = in_args[1]->u.ival;
      70               1 :   char                                cookie[20];
      71               1 :   uint32_t                            cookie_size = sizeof cookie;
      72               1 :   int                                 status;
      73               1 :   struct NaClDesc                     *desc;
      74               1 :   struct NaClFileToken                file_token;
      75               1 :   NaClSrpcError                       srpc_error;
      76                 : 
      77               2 :   NaClLog(4, "NaClManifestNameServiceLookupRpc\n");
      78                 : 
      79               1 :   NaClManifestWaitForChannel_yield_mu(proxy_conn);
      80                 : 
      81               2 :   NaClLog(4,
      82                 :           "NaClManifestNameServiceLookupRpc: name %s, flags %d\n",
      83                 :           name, flags);
      84               2 :   NaClLog(4,
      85                 :           "NaClManifestNameServiceLookupRpc: invoking %s\n",
      86                 :           NACL_MANIFEST_LOOKUP);
      87                 : 
      88                 :   if (NACL_SRPC_RESULT_OK !=
      89                 :       (srpc_error =
      90               1 :        NaClSrpcInvokeBySignature(&proxy_conn->client_channel,
      91                 :                                  NACL_MANIFEST_LOOKUP,
      92                 :                                  name,
      93                 :                                  flags,
      94                 :                                  &status,
      95                 :                                  &desc,
      96                 :                                  &file_token.lo,
      97                 :                                  &file_token.hi,
      98                 :                                  &cookie_size,
      99                 :                                  cookie))) {
     100               0 :     NaClLog(LOG_ERROR,
     101                 :             ("Manifest lookup via channel 0x%"NACL_PRIxPTR" with RPC "
     102                 :              NACL_MANIFEST_LOOKUP" failed: %d\n"),
     103                 :             (uintptr_t) &proxy_conn->client_channel,
     104                 :             srpc_error);
     105               0 :     rpc->result = srpc_error;
     106               0 :   } else {
     107               1 :     struct NaClManifestProxy *proxy =
     108                 :         (struct NaClManifestProxy *) proxy_conn->base.server;
     109               1 :     struct NaClValidationCache *validation_cache =
     110                 :         proxy->server->nap->validation_cache;
     111               1 :     struct NaClDesc *replacement_desc;
     112                 : 
     113                 :     /*
     114                 :      * The cookie is used to release renderer-side pepper file handle.
     115                 :      * For now, we leak.  We need on-close callbacks on NaClDesc
     116                 :      * objects to do this properly, but even that is insufficient
     117                 :      * since the manifest NaClDesc could, in principle, be transferred
     118                 :      * to another process -- we would need distributed garbage
     119                 :      * protection.  If Pepper could take advantage of host-OS-side
     120                 :      * reference counting that is already done, this wouldn't be a
     121                 :      * problem.
     122                 :      */
     123               2 :     NaClLog(4,
     124                 :             "NaClManifestNameServiceLookupRpc: got cookie %.*s\n",
     125                 :             cookie_size, cookie);
     126               1 :     replacement_desc = NaClExchangeFileTokenForMappableDesc(&file_token,
     127                 :                                                             validation_cache);
     128               1 :     if (NULL != replacement_desc) {
     129               0 :       NaClDescUnref(desc);
     130               0 :       desc = replacement_desc;
     131               0 :     }
     132                 : 
     133               1 :     out_args[0]->u.ival = status;
     134               1 :     out_args[1]->u.hval = desc;
     135               1 :     rpc->result = NACL_SRPC_RESULT_OK;
     136                 :   }
     137               1 :   (*done_cls->Run)(done_cls);
     138               1 :   NaClDescUnref(desc);
     139               1 :   NaClManifestReleaseChannel_release_mu(proxy_conn);
     140               1 : }
     141                 : 
     142                 : static void NaClManifestNameServiceDeleteRpc(
     143               0 :     struct NaClSrpcRpc      *rpc,
     144               0 :     struct NaClSrpcArg      **in_args,
     145               0 :     struct NaClSrpcArg      **out_args,
     146               0 :     struct NaClSrpcClosure  *done_cls) {
     147                 : 
     148               0 :   UNREFERENCED_PARAMETER(in_args);
     149               0 :   NaClLog(4, "NaClManifestNameServiceDeleteRpc\n");
     150               0 :   out_args[0]->u.ival = NACL_NAME_SERVICE_PERMISSION_DENIED;
     151               0 :   rpc->result = NACL_SRPC_RESULT_OK;
     152               0 :   (*done_cls->Run)(done_cls);
     153               0 : }
     154                 : 
     155                 : struct NaClSrpcHandlerDesc const kNaClManifestProxyHandlers[] = {
     156                 :   { NACL_NAME_SERVICE_INSERT, NaClManifestNameServiceInsertRpc, },
     157                 :   { NACL_NAME_SERVICE_LOOKUP, NaClManifestNameServiceLookupRpc, },
     158                 :   { NACL_NAME_SERVICE_DELETE, NaClManifestNameServiceDeleteRpc, },
     159                 :   { (char const *) NULL, (NaClSrpcMethod) NULL, },
     160                 : };
     161                 : 
     162                 : 
     163               3 : int NaClManifestProxyCtor(struct NaClManifestProxy        *self,
     164               3 :                           NaClThreadIfFactoryFunction     thread_factory_fn,
     165               3 :                           void                            *thread_factory_data,
     166               3 :                           struct NaClSecureService        *server) {
     167               6 :   NaClLog(4,
     168                 :           ("Entered NaClManifestProxyCtor: self 0x%"NACL_PRIxPTR
     169                 :            ", client 0x%"NACL_PRIxPTR"\n"),
     170                 :           (uintptr_t) self,
     171                 :           (uintptr_t) server);
     172               3 :   if (!NaClSimpleServiceCtor(&self->base,
     173                 :                              kNaClManifestProxyHandlers,
     174                 :                              thread_factory_fn,
     175                 :                              thread_factory_data)) {
     176               0 :     return 0;
     177                 :   }
     178                 :   self->server = (struct NaClSecureService *)
     179               3 :       NaClRefCountRef((struct NaClRefCount *) server);
     180               3 :   NACL_VTBL(NaClRefCount, self) =
     181                 :       (struct NaClRefCountVtbl *) &kNaClManifestProxyVtbl;
     182               3 :   return 1;
     183               3 : }
     184                 : 
     185               0 : static void NaClManifestProxyDtor(struct NaClRefCount *vself) {
     186               0 :   struct NaClManifestProxy *self =
     187                 :       (struct NaClManifestProxy *) vself;
     188                 : 
     189               0 :   NaClRefCountUnref((struct NaClRefCount *) self->server);
     190                 : 
     191               0 :   NACL_VTBL(NaClRefCount, self) =
     192                 :       (struct NaClRefCountVtbl *) &kNaClSimpleServiceVtbl;
     193               0 :   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
     194               0 : }
     195                 : 
     196               1 : int NaClManifestProxyConnectionCtor(struct NaClManifestProxyConnection  *self,
     197               1 :                                     struct NaClManifestProxy            *server,
     198               1 :                                     struct NaClDesc                     *conn) {
     199               2 :   NaClLog(4,
     200                 :           "Entered NaClManifestProxyConnectionCtor, self 0x%"NACL_PRIxPTR"\n",
     201                 :           (uintptr_t) self);
     202               1 :   if (!NaClSimpleServiceConnectionCtor(
     203                 :           &self->base,
     204                 :           (struct NaClSimpleService *) server,
     205                 :           conn,
     206                 :           (void *) self)) {
     207               0 :     NaClLog(4,
     208                 :             ("NaClManifestProxyConnectionCtor: base class ctor"
     209                 :              " NaClSimpleServiceConnectionCtor failed\n"));
     210               0 :     return 0;
     211                 :   }
     212               1 :   NaClXMutexCtor(&self->mu);
     213               1 :   NaClXCondVarCtor(&self->cv);
     214               1 :   self->channel_initialized = 0;
     215               1 :   NACL_VTBL(NaClRefCount, self) =
     216                 :       (struct NaClRefCountVtbl *) &kNaClManifestProxyConnectionVtbl;
     217               1 :   return 1;
     218               1 : }
     219                 : 
     220                 : void NaClManifestProxyConnectionRevHandleConnect(
     221               1 :     struct NaClManifestProxyConnection  *self,
     222               1 :     struct NaClDesc                     *rev) {
     223               2 :   NaClLog(4, "Entered NaClManifestProxyConnectionRevHandleConnect\n");
     224               1 :   NaClXMutexLock(&self->mu);
     225               1 :   if (self->channel_initialized) {
     226               0 :     NaClLog(LOG_FATAL,
     227                 :             "NaClManifestProxyConnectionRevHandleConnect: double connect?\n");
     228               0 :   }
     229                 :   /*
     230                 :    * If NaClSrpcClientCtor proves to take too long, we should spin off
     231                 :    * another thread to do the initialization so that the reverse
     232                 :    * client can accept additional reverse channels.
     233                 :    */
     234               2 :   NaClLog(4,
     235                 :           "NaClManifestProxyConnectionRevHandleConnect: Creating SrpcClient\n");
     236               1 :   if (NaClSrpcClientCtor(&self->client_channel, rev)) {
     237               2 :     NaClLog(4,
     238                 :             ("NaClManifestProxyConnectionRevHandleConnect: SrpcClientCtor"
     239                 :              " succeded, announcing.\n"));
     240               1 :     self->channel_initialized = 1;
     241               1 :     NaClXCondVarBroadcast(&self->cv);
     242                 :     /* ownership of rev taken */
     243               1 :   } else {
     244               0 :     NaClLog(4,
     245                 :             ("NaClManifestProxyConnectionRevHandleConnect: NaClSrpcClientCtor"
     246                 :              " failed\n"));
     247                 :   }
     248               1 :   NaClXMutexUnlock(&self->mu);
     249               2 :   NaClLog(4, "Leaving NaClManifestProxyConnectionRevHandleConnect\n");
     250               1 : }
     251                 : 
     252               1 : static void NaClManifestProxyConnectionDtor(struct NaClRefCount *vself) {
     253               1 :   struct NaClManifestProxyConnection *self =
     254                 :       (struct NaClManifestProxyConnection *) vself;
     255               2 :   NaClLog(4,
     256                 :           "Entered NaClManifestProxyConnectionDtor: self 0x%"NACL_PRIxPTR"\n",
     257                 :           (uintptr_t) self);
     258               1 :   NaClXMutexLock(&self->mu);
     259               2 :   while (!self->channel_initialized) {
     260               0 :     NaClLog(4,
     261                 :             "NaClManifestProxyConnectionDtor:"
     262                 :             " waiting for connection initialization\n");
     263               0 :     NaClXCondVarWait(&self->cv, &self->mu);
     264               0 :   }
     265               1 :   NaClXMutexUnlock(&self->mu);
     266                 : 
     267               2 :   NaClLog(4, "NaClManifestProxyConnectionDtor: dtoring\n");
     268                 : 
     269               1 :   NaClCondVarDtor(&self->cv);
     270               1 :   NaClMutexDtor(&self->mu);
     271                 : 
     272               1 :   NaClSrpcDtor(&self->client_channel);
     273               1 :   NACL_VTBL(NaClSimpleServiceConnection, self) =
     274                 :       &kNaClSimpleServiceConnectionVtbl;
     275               1 :   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
     276               1 : }
     277                 : 
     278                 : /*
     279                 :  * NaClManifestProxyConnection is a NaClSimpleServiceConnection
     280                 :  */
     281                 : struct NaClSimpleServiceConnectionVtbl
     282                 :   const kNaClManifestProxyConnectionVtbl = {
     283                 :   {
     284                 :     NaClManifestProxyConnectionDtor,
     285                 :   },
     286                 :   NaClSimpleServiceConnectionServerLoop,
     287                 : };
     288                 : 
     289                 : static void NaClManifestReverseClientCallback(
     290               1 :     void                        *state,
     291               1 :     struct NaClThreadInterface  *tif,
     292               1 :     struct NaClDesc             *new_conn) {
     293               1 :   struct NaClManifestProxyConnection *mconn =
     294                 :       (struct NaClManifestProxyConnection *) state;
     295                 : 
     296               2 :   UNREFERENCED_PARAMETER(tif);
     297               2 :   NaClLog(4, "Entered NaClManifestReverseClientCallback\n");
     298               1 :   NaClManifestProxyConnectionRevHandleConnect(mconn, new_conn);
     299               1 : }
     300                 : 
     301                 : int NaClManifestProxyConnectionFactory(
     302               1 :     struct NaClSimpleService            *vself,
     303               1 :     struct NaClDesc                     *conn,
     304               1 :     struct NaClSimpleServiceConnection  **out) {
     305               1 :   struct NaClManifestProxy            *self =
     306                 :       (struct NaClManifestProxy *) vself;
     307               1 :   struct NaClManifestProxyConnection  *mconn;
     308               1 :   NaClSrpcError                       rpc_result;
     309               1 :   int                                 bool_status;
     310                 : 
     311               2 :   NaClLog(4,
     312                 :           ("Entered NaClManifestProxyConnectionFactory, self 0x%"NACL_PRIxPTR
     313                 :            "\n"),
     314                 :           (uintptr_t) self);
     315               1 :   mconn = (struct NaClManifestProxyConnection *) malloc(sizeof *mconn);
     316               1 :   if (NULL == mconn) {
     317               0 :     NaClLog(4, "NaClManifestProxyConnectionFactory: no memory\n");
     318               0 :     return -NACL_ABI_ENOMEM;
     319                 :   }
     320               2 :   NaClLog(4, "NaClManifestProxyConnectionFactory: creating connection obj\n");
     321               1 :   if (!NaClManifestProxyConnectionCtor(mconn, self, conn)) {
     322               0 :     free(mconn);
     323               0 :     return -NACL_ABI_EIO;
     324                 :   }
     325                 : 
     326                 :   /*
     327                 :    * Construct via NaClSecureReverseClientCtor with a callback to
     328                 :    * process the new reverse connection -- which should be stored in
     329                 :    * the mconn object.
     330                 :    *
     331                 :    * Make reverse RPC to obtain a new reverse RPC connection.
     332                 :    */
     333               2 :   NaClLog(4, "NaClManifestProxyConnectionFactory: locking reverse channel\n");
     334               2 :   NaClLog(4, "NaClManifestProxyConnectionFactory: client 0x%"NACL_PRIxPTR"\n",
     335                 :           (uintptr_t) self->server);
     336               1 :   NaClXMutexLock(&self->server->mu);
     337               1 :   if (NACL_REVERSE_CHANNEL_INITIALIZED !=
     338                 :       self->server->reverse_channel_initialization_state) {
     339               0 :     NaClLog(LOG_FATAL,
     340                 :             "NaClManifestProxyConnectionFactory invoked w/o reverse channel\n");
     341               0 :   }
     342               2 :   NaClLog(4, "NaClManifestProxyConnectionFactory: inserting handler\n");
     343               1 :   if (!(*NACL_VTBL(NaClSecureReverseClient, self->server->reverse_client)->
     344                 :         InsertHandler)(self->server->reverse_client,
     345                 :                        NaClManifestReverseClientCallback,
     346                 :                        (void *) mconn)) {
     347               0 :     NaClLog(LOG_FATAL,
     348                 :             ("NaClManifestProxyConnectionFactory:"
     349                 :              " NaClSecureReverseClientInsertHandler failed\n"));
     350               0 :   }
     351                 :   /*
     352                 :    * NaClSrpcInvokeBySignature(""); tell plugin to connect and create
     353                 :    * a reverse channel
     354                 :    */
     355               2 :   NaClLog(4,
     356                 :           ("NaClManifestProxyConnectionFactory: making RPC"
     357                 :            " to set up connection\n"));
     358               1 :   rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
     359                 :                                          NACL_REVERSE_CONTROL_ADD_CHANNEL,
     360                 :                                          &bool_status);
     361               1 :   if (NACL_SRPC_RESULT_OK != rpc_result) {
     362               0 :     NaClLog(LOG_FATAL,
     363                 :             "NaClManifestProxyConnectionFactory: add channel RPC failed: %d",
     364                 :             rpc_result);
     365               0 :   }
     366               2 :   NaClLog(4,
     367                 :           "NaClManifestProxyConnectionFactory: Start status %d\n", bool_status);
     368                 : 
     369               1 :   NaClXMutexUnlock(&self->server->mu);
     370                 : 
     371               1 :   *out = (struct NaClSimpleServiceConnection *) mconn;
     372               1 :   return 0;
     373               1 : }
     374                 : 
     375                 : struct NaClSimpleServiceVtbl const kNaClManifestProxyVtbl = {
     376                 :   {
     377                 :     NaClManifestProxyDtor,
     378                 :   },
     379                 :   NaClManifestProxyConnectionFactory,
     380                 :   /* see name_service.c vtbl for connection factory and ownership */
     381                 :   /*
     382                 :    * The NaClManifestProxyConnectionFactory creates a subclass of a
     383                 :    * NaClSimpleServiceConnectionFactory object that uses the reverse
     384                 :    * connection object self->server to obtain a new RPC channel
     385                 :    * with each manifest connection.
     386                 :    */
     387                 :   NaClSimpleServiceAcceptConnection,
     388                 :   NaClSimpleServiceAcceptAndSpawnHandler,
     389                 :   NaClSimpleServiceRpcHandler,
     390                 : };

Generated by: LCOV version 1.7