LCOV - code coverage report
Current view: directory - src/trusted/sel_universal - rpc_universal_system.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 174 6 3.4 %
Date: 2012-02-16 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2011 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 <fcntl.h>
       8                 : #include <string.h>
       9                 : #if (NACL_LINUX)
      10                 : // for shmem cleanup
      11                 : #include <sys/ipc.h>
      12                 : #include <sys/shm.h>
      13                 : #include "native_client/src/trusted/desc/linux/nacl_desc_sysv_shm.h"
      14                 : #endif
      15                 : 
      16                 : #include <map>
      17                 : #include <string>
      18                 : #include <sstream>
      19                 : 
      20                 : using std::stringstream;
      21                 : #include "native_client/src/shared/imc/nacl_imc.h"
      22                 : #include "native_client/src/shared/platform/nacl_log.h"
      23                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      24                 : #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h"
      25                 : #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
      26                 : #include "native_client/src/trusted/sel_universal/parsing.h"
      27                 : #include "native_client/src/trusted/sel_universal/rpc_universal.h"
      28                 : #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
      29                 : 
      30                 : 
      31                 : namespace {
      32                 : 
      33                 : const uintptr_t k64KBytes = 0x10000;
      34                 : 
      35                 : // The main point of this class is to ensure automatic cleanup.
      36                 : // If the destructor is not invoked you need to manually cleanup
      37                 : // the shared memory descriptors via "ipcs -m" and "ipcrm -m <id>"
      38                 : class AddressMap {
      39                 :  public:
      40              11 :   AddressMap() {}
      41                 : 
      42              11 :   ~AddressMap() {
      43                 :     // NOTE: you CANNOT call NaClLog - this is called too late
      44                 :     // NaClLog(1, "cleanup\n");
      45                 : #if (NACL_LINUX)
      46                 :     typedef map<NaClDesc*, uintptr_t>::iterator IT;
      47                 :     for (IT it = map_.begin(); it != map_.end(); ++it) {
      48                 :       shmctl(reinterpret_cast<NaClDescSysvShm*>(it->first)->id, IPC_RMID, NULL);
      49                 :     }
      50                 : #endif
      51              11 :   }
      52                 : 
      53               0 :   void Add(NaClDesc* desc, uintptr_t addr) { map_[desc] = addr; }
      54                 : 
      55                 :   uintptr_t Get(NaClDesc* desc) { return map_[desc]; }
      56                 : 
      57                 :  private:
      58                 :   map<NaClDesc*, uintptr_t> map_;
      59                 : };
      60                 : 
      61              22 : AddressMap GlobalAddressMap;
      62                 : 
      63                 : 
      64               0 : uintptr_t MapShmem(nacl::DescWrapper* desc) {
      65                 :   void* addr;
      66                 :   size_t dummy_size;
      67               0 :   int result = desc->Map(&addr, &dummy_size);
      68               0 :   if (0 > result) {
      69               0 :     NaClLog(LOG_ERROR, "error mapping shmem area\n");
      70               0 :     return 0;
      71                 :   }
      72                 : 
      73               0 :   GlobalAddressMap.Add(desc->desc(), reinterpret_cast<uintptr_t>(addr));
      74               0 :   return reinterpret_cast<uintptr_t>(addr);
      75                 : }
      76                 : 
      77                 : }  // namespace
      78                 : 
      79                 : bool HandlerSyncSocketCreate(NaClCommandLoop* ncl,
      80               0 :                              const vector<string>& args) {
      81               0 :   if (args.size() < 3) {
      82               0 :     NaClLog(LOG_ERROR, "not enough args\n");
      83               0 :     return false;
      84                 :   }
      85                 : 
      86               0 :   nacl::Handle handles[2] = {nacl::kInvalidHandle, nacl::kInvalidHandle};
      87               0 :   if (NaClSocketPair(handles) != 0) {
      88               0 :     return false;
      89                 :   }
      90                 : 
      91               0 :   nacl::DescWrapperFactory factory;
      92               0 :   nacl::DescWrapper* desc1 = factory.ImportSyncSocketHandle(handles[0]);
      93               0 :   ncl->AddDesc(desc1->desc(), args[1]);
      94                 : 
      95               0 :   nacl::DescWrapper* desc2 = factory.ImportSyncSocketHandle(handles[1]);
      96               0 :   ncl->AddDesc(desc2->desc(), args[2]);
      97               0 :   return true;
      98                 : }
      99                 : 
     100                 : bool HandlerSyncSocketWrite(NaClCommandLoop* ncl,
     101               0 :                             const vector<string>& args) {
     102               0 :   if (args.size() < 3) {
     103               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     104               0 :     return false;
     105                 :   }
     106                 : 
     107               0 :   NaClDesc* raw_desc = ExtractDesc(args[1], ncl);
     108               0 :   if (raw_desc == NULL) {
     109               0 :     NaClLog(LOG_ERROR, "cannot find desciptor %s\n", args[1].c_str());
     110               0 :     return false;
     111                 :   }
     112                 : 
     113               0 :   const int value = ExtractInt32(args[2]);
     114               0 :   nacl::DescWrapperFactory factory;
     115                 :   // TODO(robertm): eliminate use of NaClDesc in sel_universal and standardize
     116                 :   //       on DescWrapper to eliminate the memory leak here
     117               0 :   factory.MakeGeneric(raw_desc)->Write(&value, sizeof value);
     118               0 :   return true;
     119                 : }
     120                 : 
     121               0 : bool HandlerShmem(NaClCommandLoop* ncl, const vector<string>& args) {
     122               0 :   if (args.size() < 4) {
     123               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     124               0 :     return false;
     125                 :   }
     126                 : 
     127               0 :   const int size = ExtractInt32(args[3]);
     128               0 :   nacl::DescWrapperFactory factory;
     129               0 :   nacl::DescWrapper* desc = factory.MakeShm(size);
     130               0 :   if (desc == NULL) {
     131               0 :     NaClLog(LOG_ERROR, "could not create shm\n");
     132               0 :     return false;
     133                 :   }
     134                 : 
     135               0 :   ncl->AddDesc(desc->desc(), args[1]);
     136                 : 
     137               0 :   uintptr_t addr = MapShmem(desc);
     138               0 :   if (addr == 0) {
     139               0 :     return false;
     140                 :   }
     141               0 :   stringstream str;
     142               0 :   str << "0x" << std::hex << addr;
     143               0 :   ncl->SetVariable(args[2], str.str());
     144               0 :   return true;
     145                 : }
     146                 : 
     147                 : 
     148                 : // create a descriptor representing a readonly file
     149               0 : bool HandlerReadonlyFile(NaClCommandLoop* ncl, const vector<string>& args) {
     150               0 :   if (args.size() < 3) {
     151               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     152               0 :     return false;
     153                 :   }
     154                 : 
     155               0 :   nacl::DescWrapperFactory factory;
     156                 :   nacl::DescWrapper* desc = factory.OpenHostFile(args[2].c_str(),
     157               0 :                                                  NACL_ABI_O_RDONLY, 0);
     158               0 :   if (NULL == desc) {
     159               0 :     NaClLog(LOG_ERROR, "cound not create file desc for %s\n", args[2].c_str());
     160               0 :     return false;
     161                 :   }
     162               0 :   ncl->AddDesc(desc->desc(), args[1]);
     163               0 :   return true;
     164                 : }
     165                 : 
     166                 : // create a descriptor representing a read-write file.
     167                 : // Used for temporary files created by the pnacl translator.
     168               0 : bool HandlerReadwriteFile(NaClCommandLoop* ncl, const vector<string>& args) {
     169               0 :   if (args.size() < 3) {
     170               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     171               0 :     return false;
     172                 :   }
     173                 : 
     174               0 :   nacl::DescWrapperFactory factory;
     175                 :   nacl::DescWrapper* desc =
     176                 :       factory.OpenHostFile(args[2].c_str(),
     177               0 :                            NACL_ABI_O_RDWR | NACL_ABI_O_CREAT, 0666);
     178               0 :   if (NULL == desc) {
     179               0 :     NaClLog(LOG_ERROR, "cound not create file desc for %s\n", args[2].c_str());
     180               0 :     return false;
     181                 :   }
     182               0 :   ncl->AddDesc(desc->desc(), args[1]);
     183               0 :   return true;
     184                 : }
     185                 : 
     186                 : // create a descriptor representing a read-write file with quota management.
     187                 : bool HandlerReadwriteFileQuota(NaClCommandLoop* ncl,
     188               0 :                                const vector<string>& args) {
     189               0 :   if (args.size() < 3) {
     190               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     191               0 :     return false;
     192                 :   }
     193                 : 
     194                 :   static const uint8_t kFileId[] = "SelUniversal000";
     195               0 :   nacl::DescWrapperFactory factory;
     196                 :   nacl::DescWrapper* desc =
     197                 :       factory.OpenHostFileQuota(args[2].c_str(),
     198                 :                                 NACL_ABI_O_RDWR | NACL_ABI_O_CREAT, 0666,
     199               0 :                                 kFileId);
     200               0 :   if (NULL == desc) {
     201               0 :     NaClLog(LOG_ERROR, "cound not create file desc for %s\n", args[2].c_str());
     202               0 :     return false;
     203                 :   }
     204               0 :   ncl->AddDesc(desc->desc(), args[1]);
     205               0 :   return true;
     206                 : }
     207                 : 
     208                 : // sleep for a given number of seconds
     209               0 : bool HandlerSleep(NaClCommandLoop* ncl, const vector<string>& args) {
     210                 :   UNREFERENCED_PARAMETER(ncl);
     211               0 :   if (args.size() < 2) {
     212               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     213               0 :     return false;
     214                 :   }
     215               0 :   const int secs = ExtractInt32(args[1]);
     216                 : #if (NACL_LINUX || NACL_OSX)
     217               0 :   sleep(secs);
     218                 : #elif NACL_WINDOWS
     219                 :   Sleep(secs * 1000);
     220                 : #else
     221                 : #error "Please specify platform as NACL_LINUX, NACL_OSX or NACL_WINDOWS"
     222                 : #endif
     223               0 :   return true;
     224                 : }
     225                 : 
     226                 : // save a memory region to a file
     227               0 : bool HandlerSaveToFile(NaClCommandLoop* ncl, const vector<string>& args) {
     228                 :   UNREFERENCED_PARAMETER(ncl);
     229               0 :   if (args.size() < 5) {
     230               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     231               0 :     return false;
     232                 :   }
     233                 : 
     234               0 :   const char* filename = args[1].c_str();
     235               0 :   const char* start = reinterpret_cast<char*>(ExtractInt64(args[2]));
     236               0 :   const int offset = ExtractInt32(args[3]);
     237               0 :   const int size = ExtractInt32(args[4]);
     238                 : 
     239               0 :   NaClLog(1, "opening %s\n", filename);
     240               0 :   FILE* fp = fopen(filename, "wb");
     241               0 :   if (fp == NULL) {
     242               0 :      NaClLog(LOG_ERROR, "cannot open %s\n", filename);
     243               0 :      return false;
     244                 :   }
     245                 : 
     246                 : 
     247               0 :   NaClLog(1, "writing %d bytes from %p\n", (int) size, start + offset);
     248               0 :   const size_t n = fwrite(start + offset, 1, size, fp);
     249               0 :   if (static_cast<int>(n) != size) {
     250                 :     NaClLog(LOG_ERROR, "wrote %d bytes, expected %d\n",
     251               0 :             static_cast<int>(n), size);
     252               0 :     fclose(fp);
     253               0 :     return false;
     254                 :   }
     255               0 :   fclose(fp);
     256               0 :   return true;
     257                 : }
     258                 : 
     259                 : // map a shared mem descriptor into memory and save address into var
     260               0 : bool HandlerMap(NaClCommandLoop* ncl, const vector<string>& args) {
     261                 :   UNREFERENCED_PARAMETER(ncl);
     262               0 :   if (args.size() < 3) {
     263               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     264               0 :     return false;
     265                 :   }
     266                 : 
     267               0 :   NaClDesc* raw_desc = ExtractDesc(args[1], ncl);
     268               0 :   if (raw_desc == NULL) {
     269               0 :     NaClLog(LOG_ERROR, "cannot find desciptor %s\n", args[1].c_str());
     270               0 :     return false;
     271                 :   }
     272                 : 
     273               0 :   nacl::DescWrapperFactory factory;
     274               0 :   nacl::DescWrapper* desc = factory.MakeGeneric(raw_desc);
     275                 : 
     276               0 :   uintptr_t addr = MapShmem(desc);
     277               0 :   if (addr == 0) {
     278               0 :     return false;
     279                 :   }
     280                 : 
     281               0 :   NaClLog(1, "region mapped at %p\n", reinterpret_cast<void*>(addr));
     282               0 :   stringstream str;
     283               0 :   str << "0x" << std::hex << addr;
     284               0 :   ncl->SetVariable(args[2], str.str());
     285               0 :   return true;
     286                 : }
     287                 : 
     288                 : // load file into memory region
     289               0 : bool HandlerLoadFromFile(NaClCommandLoop* ncl, const vector<string>& args) {
     290                 :   UNREFERENCED_PARAMETER(ncl);
     291               0 :   if (args.size() < 5) {
     292               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     293               0 :     return false;
     294                 :   }
     295                 : 
     296               0 :   const char* filename = args[1].c_str();
     297               0 :   char* start = reinterpret_cast<char*>(ExtractInt64(args[2]));
     298               0 :   const int offset = ExtractInt32(args[3]);
     299               0 :   const int size = ExtractInt32(args[4]);
     300                 : 
     301               0 :   NaClLog(1, "opening %s\n", filename);
     302               0 :   FILE* fp = fopen(filename, "rb");
     303               0 :   if (fp == NULL) {
     304               0 :      NaClLog(LOG_ERROR, "cannot open %s\n", filename);
     305               0 :      return false;
     306                 :   }
     307                 : 
     308               0 :   NaClLog(1, "loading %d bytes to %p\n", (int) size, start + offset);
     309               0 :   const size_t n = fread(start + offset, 1, size, fp);
     310               0 :   if (static_cast<int>(n) != size) {
     311                 :     NaClLog(LOG_ERROR, "read %d bytes, expected %d\n",
     312               0 :             static_cast<int>(n), size);
     313               0 :     fclose(fp);
     314               0 :     return false;
     315                 :   }
     316               0 :   fclose(fp);
     317               0 :   return true;
     318                 : }
     319                 : 
     320                 : // Determine filesize and write it into a variable
     321               0 : bool HandlerFileSize(NaClCommandLoop* ncl, const vector<string>& args) {
     322                 :   UNREFERENCED_PARAMETER(ncl);
     323               0 :   if (args.size() < 3) {
     324               0 :     NaClLog(LOG_ERROR, "not enough args\n");
     325               0 :     return false;
     326                 :   }
     327                 : 
     328               0 :   const char* filename = args[1].c_str();
     329               0 :   FILE* fp = fopen(filename, "rb");
     330               0 :   if (fp == NULL) {
     331               0 :     NaClLog(LOG_ERROR, "cannot open %s\n", filename);
     332               0 :     return false;
     333                 :   }
     334               0 :   fseek(fp, 0, SEEK_END);
     335               0 :   int size = static_cast<int>(ftell(fp));
     336               0 :   fclose(fp);
     337                 : 
     338               0 :   NaClLog(1, "filesize is %d\n", size);
     339                 : 
     340               0 :   stringstream str;
     341               0 :   str << size;
     342               0 :   ncl->SetVariable(args[2], str.str());
     343               0 :   return true;
     344              22 : }

Generated by: LCOV version 1.7