LCOV - code coverage report
Current view: directory - src/trusted/nonnacl_util - sel_ldr_launcher_base.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 131 78 59.5 %
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                 : #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
       8                 : 
       9                 : #include "native_client/src/include/nacl_macros.h"
      10                 : #include "native_client/src/public/secure_service.h"
      11                 : #include "native_client/src/shared/platform/nacl_check.h"
      12                 : #include "native_client/src/shared/srpc/nacl_srpc.h"
      13                 : 
      14                 : 
      15                 : namespace nacl {
      16                 : 
      17                 : SelLdrLauncherBase::SelLdrLauncherBase()
      18                 :   : channel_(NACL_INVALID_HANDLE),
      19                 :     bootstrap_socket_(NULL),
      20                 :     secure_socket_addr_(NULL),
      21              60 :     socket_addr_(NULL) {
      22              20 : }
      23                 : 
      24              13 : SelLdrLauncherBase::~SelLdrLauncherBase() {
      25              13 :   if (NACL_INVALID_HANDLE != channel_) {
      26               0 :     NaClClose(channel_);
      27               0 :   }
      28              52 : }
      29                 : 
      30                 : bool SelLdrLauncherBase::ConnectBootstrapSocket() {
      31              60 :   CHECK(factory_ == NULL);
      32              40 :   factory_.reset(new DescWrapperFactory);
      33              60 :   CHECK(channel_ != NACL_INVALID_HANDLE);
      34              20 :   bootstrap_socket_.reset(factory_->MakeImcSock(channel_));
      35              20 :   if (bootstrap_socket_ == NULL) {
      36               0 :     return false;
      37                 :   }
      38                 :   // bootstrap_socket_ now has ownership of channel_, so we get rid of
      39                 :   // our "reference" to it.
      40              20 :   channel_ = NACL_INVALID_HANDLE;
      41                 : 
      42              20 :   return true;
      43              20 : }
      44                 : 
      45                 : bool SelLdrLauncherBase::RetrieveSockAddr() {
      46              20 :   DescWrapper::MsgHeader   header;
      47              20 :   DescWrapper::MsgIoVec    iovec[1];
      48              20 :   DescWrapper*             descs[NACL_ABI_IMC_USER_DESC_MAX];
      49              20 :   scoped_array<unsigned char> bytes(
      50                 :       new unsigned char[NACL_ABI_IMC_USER_BYTES_MAX]);
      51              40 :   if (bytes.get() == NULL) {
      52               0 :     return false;
      53                 :   }
      54                 : 
      55                 :   // Set up to receive a message.
      56              40 :   iovec[0].base = bytes.get();
      57              20 :   iovec[0].length = NACL_ABI_IMC_USER_BYTES_MAX;
      58              20 :   header.iov = iovec;
      59              20 :   header.iov_length = NACL_ARRAY_SIZE(iovec);
      60              20 :   header.ndescv = descs;
      61              20 :   header.ndescv_length = NACL_ARRAY_SIZE(descs);
      62              20 :   header.flags = 0;
      63                 :   // Receive the message.
      64              60 :   ssize_t received = bootstrap_socket_->RecvMsg(&header, 0, NULL);
      65              20 :   if (0 != received) {
      66               0 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::RetrieveSockAddr: "
      67                 :             "RecvMsg() returned %d\n", static_cast<int>(received));
      68               0 :     return false;
      69                 :   }
      70                 :   // Check that there were exactly two descriptors passed.
      71              20 :   if (2 != header.ndescv_length) {
      72               0 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::RetrieveSockAddr: "
      73                 :             "got desc count %d, expected 2\n",
      74                 :             static_cast<int>(header.ndescv_length));
      75               0 :     return false;
      76                 :   }
      77              20 :   secure_socket_addr_.reset(descs[0]);
      78              20 :   socket_addr_.reset(descs[1]);
      79                 : 
      80              40 :   return true;
      81              20 : }
      82                 : 
      83              18 : bool SelLdrLauncherBase::SetupCommand(NaClSrpcChannel* command) {
      84                 :   // Get the bootstrap socket.
      85              18 :   if (!ConnectBootstrapSocket()) {
      86               0 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::SetupCommand: "
      87                 :             "getting bootstrap socket failed\n");
      88               0 :     return false;
      89                 :   }
      90                 :   // Get the socket address from the descriptor.
      91              18 :   if (!RetrieveSockAddr()) {
      92               0 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::SetupCommand: "
      93                 :             "getting sel_ldr socket address failed\n");
      94               0 :     return false;
      95                 :   }
      96                 :   // Connect to the trusted command channel.
      97              18 :   scoped_ptr<DescWrapper> command_desc(secure_socket_addr_->Connect());
      98              36 :   if (command_desc == NULL) {
      99               0 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::SetupCommand: Connect() failed\n");
     100               0 :     return false;
     101                 :   }
     102                 :   // Start the SRPC client to communicate with the trusted command channel.
     103                 :   // SRPC client takes an additional reference to command_desc.
     104              72 :   if (!NaClSrpcClientCtor(command, command_desc->desc())) {
     105               0 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::SetupCommand: "
     106                 :             "NaClSrpcClientCtor failed\n");
     107               0 :     return false;
     108                 :   }
     109              18 :   return true;
     110              36 : }
     111                 : 
     112              16 : bool SelLdrLauncherBase::LoadModule(NaClSrpcChannel* command,
     113              16 :                                     DescWrapper* nexe) {
     114              48 :   CHECK(nexe != NULL);
     115                 :   // Load module over command channel.
     116              16 :   NaClSrpcResultCodes rpc_result =
     117              32 :       NaClSrpcInvokeBySignature(command,
     118                 :                                 NACL_SECURE_SERVICE_LOAD_MODULE,
     119              16 :                                 nexe->desc());
     120              16 :   if (NACL_SRPC_RESULT_OK != rpc_result) {
     121               0 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::LoadModule: "
     122                 :             "rpc_result=%d is not successful\n",
     123                 :             static_cast<int>(rpc_result));
     124               0 :     NaClSrpcDtor(command);
     125               0 :     return false;
     126                 :   }
     127              16 :   return true;
     128              16 : }
     129                 : 
     130               2 : bool SelLdrLauncherBase::SetupCommandAndLoad(NaClSrpcChannel* command,
     131               2 :                                              DescWrapper* nexe) {
     132               2 :   if (!SetupCommand(command)) {
     133               0 :     return false;
     134                 :   }
     135               2 :   if (nexe != NULL) {
     136               2 :     if (!LoadModule(command, nexe)) {
     137               0 :       return false;
     138                 :     }
     139               2 :   }
     140               2 :   return true;
     141               2 : }
     142                 : 
     143              18 : bool SelLdrLauncherBase::StartModule(NaClSrpcChannel* command) {
     144                 :   // Start untrusted code module.
     145              18 :   int start_result;
     146              18 :   NaClSrpcResultCodes rpc_result = NaClSrpcInvokeBySignature(
     147                 :       command,
     148                 :       NACL_SECURE_SERVICE_START_MODULE,
     149                 :       &start_result);
     150              18 :   NaClLog(4, "SelLdrLauncher::StartModule rpc result %d\n",
     151                 :           static_cast<int>(rpc_result));
     152              36 :   if (NACL_SRPC_RESULT_OK != rpc_result || LOAD_OK != start_result) {
     153               0 :     NaClSrpcDtor(command);
     154               0 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::StartModule: "
     155                 :             "start_module failed: rpc_result=%d, start_result=%d (%s)\n",
     156                 :             static_cast<int>(rpc_result), start_result,
     157               0 :             NaClErrorString(static_cast<NaClErrorCode>(start_result)));
     158               0 :     return false;
     159                 :   }
     160              18 :   return true;
     161              18 : }
     162                 : 
     163              11 : bool SelLdrLauncherBase::SetupAppChannel(NaClSrpcChannel* out_app_chan) {
     164                 :   // Connect to the untrusted service itself.
     165              11 :   scoped_ptr<DescWrapper> untrusted_desc(socket_addr_->Connect());
     166              22 :   if (untrusted_desc == NULL) {
     167               0 :     NaClLog(LOG_ERROR, "SelLdrLauncher::StartModuleAndSetupAppChannel: "
     168                 :             "Connect failed\n");
     169               0 :     return false;
     170                 :   }
     171                 :   // Start the SRPC client to communicate with the untrusted service
     172                 :   // SRPC client takes an additional reference to untrusted_desc.
     173              44 :   if (!NaClSrpcClientCtor(out_app_chan, untrusted_desc->desc())) {
     174               1 :     NaClLog(LOG_ERROR, "SelLdrLauncherBase::SetupAppChannel: "
     175                 :             "NaClSrpcClientCtor failed\n");
     176               1 :     return false;
     177                 :   }
     178              21 :   return true;
     179              11 : }
     180                 : 
     181                 : // Sends the SRPC to start the nexe over |command| and sets up the application
     182                 : // SRPC chanel |out_app_chan|.
     183                 : bool SelLdrLauncherBase::StartModuleAndSetupAppChannel(
     184               4 :     NaClSrpcChannel* command,
     185               4 :     NaClSrpcChannel* out_app_chan) {
     186               4 :   if (!StartModule(command)) {
     187               0 :     return false;
     188                 :   }
     189               0 :   if (!SetupAppChannel(out_app_chan)) {
     190               0 :     return false;
     191                 :   }
     192               0 :   return true;
     193               0 : }
     194                 : 
     195               0 : DescWrapper* SelLdrLauncherBase::Wrap(NaClDesc* raw_desc) {
     196               0 :   CHECK(factory_ != NULL);
     197               0 :   return factory_->MakeGeneric(raw_desc);
     198                 : }
     199                 : 
     200               5 : DescWrapper* SelLdrLauncherBase::WrapCleanup(NaClDesc* raw_desc) {
     201              15 :   CHECK(factory_ != NULL);
     202               5 :   return factory_->MakeGenericCleanup(raw_desc);
     203                 : }
     204                 : 
     205                 : nacl::string SelLdrLauncherBase::GetCrashLogOutput() {
     206               0 :   DescWrapper::MsgHeader hdr;
     207               0 :   DescWrapper::MsgIoVec iov;
     208               0 :   char msg_buf[1024];
     209               0 :   ssize_t nbytes = 0;
     210                 : 
     211               0 :   iov.base = msg_buf;
     212               0 :   iov.length = sizeof msg_buf;
     213               0 :   hdr.iov = &iov;
     214               0 :   hdr.iov_length = 1;
     215               0 :   hdr.ndescv = NULL;
     216               0 :   hdr.ndescv_length = 0;
     217               0 :   hdr.flags = 0;
     218               0 :   if (NULL != bootstrap_socket_.get()) {
     219               0 :     nbytes = bootstrap_socket_->RecvMsg(&hdr, 0, NULL);
     220               0 :   }
     221               0 :   if (nbytes > 0) {
     222               0 :     return nacl::string(msg_buf, nbytes);
     223                 :   }
     224               0 :   return "";
     225               0 : }
     226                 : 
     227                 : }  // namespace nacl

Generated by: LCOV version 1.7