LCOV - code coverage report
Current view: directory - src/trusted/desc - nacl_desc_base.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 155 27 17.4 %
Date: 2012-02-16 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright 2008 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can
       4                 :  * be found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl Service Runtime.  I/O Descriptor / Handle abstraction.  Memory
       9                 :  * mapping using descriptors.
      10                 :  */
      11                 : 
      12                 : #include <stdlib.h>
      13                 : #include <string.h>
      14                 : #include <sys/types.h>
      15                 : #include <sys/stat.h>
      16                 : 
      17                 : #include "native_client/src/include/portability.h"
      18                 : #include "native_client/src/include/nacl_platform.h"
      19                 : 
      20                 : #include "native_client/src/shared/platform/nacl_host_desc.h"
      21                 : #include "native_client/src/shared/platform/nacl_log.h"
      22                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      23                 : 
      24                 : #if NACL_LINUX
      25                 : #include "native_client/src/trusted/desc/linux/nacl_desc_sysv_shm.h"
      26                 : #endif  /* NACL_LINUX */
      27                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      28                 : #include "native_client/src/trusted/desc/nacl_desc_cond.h"
      29                 : #include "native_client/src/trusted/desc/nacl_desc_conn_cap.h"
      30                 : #include "native_client/src/trusted/desc/nacl_desc_dir.h"
      31                 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
      32                 : #include "native_client/src/trusted/desc/nacl_desc_imc_bound_desc.h"
      33                 : #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h"
      34                 : #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
      35                 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
      36                 : #include "native_client/src/trusted/desc/nacl_desc_mutex.h"
      37                 : #include "native_client/src/trusted/desc/nacl_desc_rng.h"
      38                 : #include "native_client/src/trusted/desc/nacl_desc_quota.h"
      39                 : #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h"
      40                 : 
      41                 : #include "native_client/src/trusted/nacl_base/nacl_refcount.h"
      42                 : 
      43                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      44                 : #include "native_client/src/trusted/service_runtime/include/sys/mman.h"
      45                 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
      46                 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
      47                 : #include "native_client/src/trusted/service_runtime/sel_util.h"
      48                 : 
      49                 : /*
      50                 :  * This file contains base class code for NaClDesc.
      51                 :  *
      52                 :  * The implementation for following subclasses are elsewhere, but here
      53                 :  * is an enumeration of them with a brief description:
      54                 :  *
      55                 :  * NaClDescIoDesc is the subclass that wraps host-OS descriptors
      56                 :  * provided by NaClHostDesc (which gives an OS-independent abstraction
      57                 :  * for host-OS descriptors).
      58                 :  *
      59                 :  * NaClDescImcDesc is the subclass that wraps IMC descriptors.
      60                 :  *
      61                 :  * NaClDescMutex and NaClDescCondVar are the subclasses that
      62                 :  * wrap the non-transferrable synchronization objects.
      63                 :  *
      64                 :  * These NaClDesc objects are impure in that they know about the
      65                 :  * virtual memory subsystem restriction of requiring mappings to occur
      66                 :  * in NACL_MAP_PAGESIZE (64KB) chunks, so the Map and Unmap virtual
      67                 :  * functions, at least, will enforce this restriction.
      68                 :  */
      69                 : 
      70                 : /*
      71                 :  * TODO(bsy): remove when we put SIZE_T_MAX in a common header file.
      72                 :  */
      73                 : #if !defined(SIZE_T_MAX)
      74                 : # define SIZE_T_MAX ((size_t) -1)
      75                 : #endif
      76                 : 
      77             315 : int NaClDescCtor(struct NaClDesc *ndp) {
      78                 :   /* this should be a compile-time test */
      79                 :   if (0 != (sizeof(struct NaClInternalHeader) & 0xf)) {
      80                 :     NaClLog(LOG_FATAL,
      81                 :             "Internal error.  NaClInternalHeader size not a"
      82                 :             " multiple of 16\n");
      83                 :   }
      84             315 :   return NaClRefCountCtor(&ndp->base);
      85                 : }
      86                 : 
      87             155 : static void NaClDescDtor(struct NaClRefCount *nrcp) {
      88             155 :   nrcp->vtbl = &kNaClRefCountVtbl;
      89             155 :   (*nrcp->vtbl->Dtor)(nrcp);
      90             155 : }
      91                 : 
      92            1350 : struct NaClDesc *NaClDescRef(struct NaClDesc *ndp) {
      93            1350 :   return (struct NaClDesc *) NaClRefCountRef(&ndp->base);
      94                 : }
      95                 : 
      96             306 : void NaClDescUnref(struct NaClDesc *ndp) {
      97             306 :   NaClRefCountUnref(&ndp->base);
      98             306 : }
      99                 : 
     100             167 : void NaClDescSafeUnref(struct NaClDesc *ndp) {
     101             167 :   if (NULL != ndp) {
     102             109 :     NaClRefCountUnref(&ndp->base);
     103                 :   }
     104             167 : }
     105                 : 
     106                 : int (*NaClDescInternalize[NACL_DESC_TYPE_MAX])(
     107                 :     struct NaClDesc **,
     108                 :     struct NaClDescXferState *,
     109                 :     struct NaClDescQuotaInterface *) = {
     110                 :   NaClDescInvalidInternalize,
     111                 :   NaClDescDirInternalize,
     112                 :   NaClDescIoInternalize,
     113                 : #if NACL_WINDOWS
     114                 :   NaClDescConnCapInternalize,
     115                 :   NaClDescInternalizeNotImplemented,
     116                 : #else
     117                 :   NaClDescInternalizeNotImplemented,
     118                 :   NaClDescConnCapFdInternalize,
     119                 : #endif
     120                 :   NaClDescInternalizeNotImplemented,  /* bound sockets cannot be transferred */
     121                 :   NaClDescInternalizeNotImplemented,  /* connected abstract base class */
     122                 :   NaClDescImcShmInternalize,
     123                 : #if NACL_LINUX
     124                 :   NaClDescSysvShmInternalize,
     125                 : #else
     126                 :   NULL,
     127                 : #endif  /* NACL_LINUX */
     128                 :   NaClDescInternalizeNotImplemented,  /* mutex */
     129                 :   NaClDescInternalizeNotImplemented,  /* condvar */
     130                 :   NaClDescInternalizeNotImplemented,  /* semaphore */
     131                 :   NaClDescSyncSocketInternalize,
     132                 :   NaClDescXferableDataDescInternalize,
     133                 :   NaClDescInternalizeNotImplemented,  /* imc socket */
     134                 :   NaClDescQuotaInternalize,           /* quota wrapper */
     135                 :   NaClDescRngInternalize,             /* device: rng */
     136                 :   NaClDescInternalizeNotImplemented   /* device: postmessage */
     137                 : };
     138                 : 
     139               2 : char const *NaClDescTypeString(enum NaClDescTypeTag type_tag) {
     140                 :   /* default functions for the vtable - return NOT_IMPLEMENTED */
     141               2 :   switch (type_tag) {
     142                 : #define MAP(E) case E: do { return #E; } while (0)
     143               0 :     MAP(NACL_DESC_INVALID);
     144               0 :     MAP(NACL_DESC_DIR);
     145               0 :     MAP(NACL_DESC_HOST_IO);
     146               0 :     MAP(NACL_DESC_CONN_CAP);
     147               0 :     MAP(NACL_DESC_CONN_CAP_FD);
     148               0 :     MAP(NACL_DESC_BOUND_SOCKET);
     149               0 :     MAP(NACL_DESC_CONNECTED_SOCKET);
     150               0 :     MAP(NACL_DESC_SHM);
     151               0 :     MAP(NACL_DESC_SYSV_SHM);
     152               0 :     MAP(NACL_DESC_MUTEX);
     153               0 :     MAP(NACL_DESC_CONDVAR);
     154               0 :     MAP(NACL_DESC_SEMAPHORE);
     155               0 :     MAP(NACL_DESC_SYNC_SOCKET);
     156               0 :     MAP(NACL_DESC_TRANSFERABLE_DATA_SOCKET);
     157               2 :     MAP(NACL_DESC_IMC_SOCKET);
     158               0 :     MAP(NACL_DESC_QUOTA);
     159               0 :     MAP(NACL_DESC_DEVICE_RNG);
     160               0 :     MAP(NACL_DESC_DEVICE_POSTMESSAGE);
     161                 :   }
     162               0 :   return "BAD TYPE TAG";
     163                 : }
     164                 : 
     165                 : 
     166               0 : void NaClDescDtorNotImplemented(struct NaClRefCount  *vself) {
     167                 :   UNREFERENCED_PARAMETER(vself);
     168                 : 
     169               0 :   NaClLog(LOG_FATAL, "Must implement a destructor!\n");
     170               0 : }
     171                 : 
     172                 : uintptr_t NaClDescMapNotImplemented(struct NaClDesc         *vself,
     173                 :                                     struct NaClDescEffector *effp,
     174                 :                                     void                    *start_addr,
     175                 :                                     size_t                  len,
     176                 :                                     int                     prot,
     177                 :                                     int                     flags,
     178               0 :                                     nacl_off64_t            offset) {
     179                 :   UNREFERENCED_PARAMETER(effp);
     180                 :   UNREFERENCED_PARAMETER(start_addr);
     181                 :   UNREFERENCED_PARAMETER(len);
     182                 :   UNREFERENCED_PARAMETER(prot);
     183                 :   UNREFERENCED_PARAMETER(flags);
     184                 :   UNREFERENCED_PARAMETER(offset);
     185                 : 
     186               0 :   NaClLog(LOG_ERROR,
     187                 :           "Map method is not implemented for object of type %s\n",
     188                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     189                 :                               vself->base.vtbl)->typeTag));
     190               0 :   return -NACL_ABI_EINVAL;
     191                 : }
     192                 : 
     193                 : int NaClDescUnmapUnsafeNotImplemented(struct NaClDesc         *vself,
     194                 :                                       struct NaClDescEffector *effp,
     195                 :                                       void                    *start_addr,
     196               0 :                                       size_t                  len) {
     197                 :   UNREFERENCED_PARAMETER(effp);
     198                 :   UNREFERENCED_PARAMETER(start_addr);
     199                 :   UNREFERENCED_PARAMETER(len);
     200                 : 
     201               0 :   NaClLog(LOG_ERROR,
     202                 :           "Map method is not implemented for object of type %s\n",
     203                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     204                 :                               vself->base.vtbl)->typeTag));
     205               0 :   return -NACL_ABI_EINVAL;
     206                 : }
     207                 : 
     208                 : int NaClDescUnmapNotImplemented(struct NaClDesc         *vself,
     209                 :                                 struct NaClDescEffector *effp,
     210                 :                                 void                    *start_addr,
     211               0 :                                 size_t                  len) {
     212                 :   UNREFERENCED_PARAMETER(effp);
     213                 :   UNREFERENCED_PARAMETER(start_addr);
     214                 :   UNREFERENCED_PARAMETER(len);
     215                 : 
     216               0 :   NaClLog(LOG_ERROR,
     217                 :           "Unmap method is not implemented for object of type %s\n",
     218                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     219                 :                               vself->base.vtbl)->typeTag));
     220               0 :   return -NACL_ABI_EINVAL;
     221                 : }
     222                 : 
     223                 : ssize_t NaClDescReadNotImplemented(struct NaClDesc          *vself,
     224                 :                                    void                     *buf,
     225               0 :                                    size_t                   len) {
     226                 :   UNREFERENCED_PARAMETER(buf);
     227                 :   UNREFERENCED_PARAMETER(len);
     228                 : 
     229               0 :   NaClLog(LOG_ERROR,
     230                 :           "Read method is not implemented for object of type %s\n",
     231                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     232                 :                               vself->base.vtbl)->typeTag));
     233               0 :   return -NACL_ABI_EINVAL;
     234                 : }
     235                 : 
     236                 : ssize_t NaClDescWriteNotImplemented(struct NaClDesc         *vself,
     237                 :                                     void const              *buf,
     238               0 :                                     size_t                  len) {
     239                 :   UNREFERENCED_PARAMETER(buf);
     240                 :   UNREFERENCED_PARAMETER(len);
     241                 : 
     242               0 :   NaClLog(LOG_ERROR,
     243                 :           "Write method is not implemented for object of type %s\n",
     244                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     245                 :                               vself->base.vtbl)->typeTag));
     246               0 :   return -NACL_ABI_EINVAL;
     247                 : }
     248                 : 
     249                 : nacl_off64_t NaClDescSeekNotImplemented(struct NaClDesc          *vself,
     250                 :                                         nacl_off64_t             offset,
     251               0 :                                         int                      whence) {
     252                 :   UNREFERENCED_PARAMETER(offset);
     253                 :   UNREFERENCED_PARAMETER(whence);
     254                 : 
     255               0 :   NaClLog(LOG_ERROR,
     256                 :           "Seek method is not implemented for object of type %s\n",
     257                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     258                 :                               vself->base.vtbl)->typeTag));
     259               0 :   return -NACL_ABI_EINVAL;
     260                 : }
     261                 : 
     262                 : int NaClDescIoctlNotImplemented(struct NaClDesc         *vself,
     263                 :                                 int                     request,
     264               0 :                                 void                    *arg) {
     265                 :   UNREFERENCED_PARAMETER(request);
     266                 :   UNREFERENCED_PARAMETER(arg);
     267                 : 
     268               0 :   NaClLog(LOG_ERROR,
     269                 :           "Ioctl method is not implemented for object of type %s\n",
     270                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     271                 :                               vself->base.vtbl)->typeTag));
     272               0 :   return -NACL_ABI_EINVAL;
     273                 : }
     274                 : 
     275                 : int NaClDescFstatNotImplemented(struct NaClDesc         *vself,
     276               0 :                                 struct nacl_abi_stat    *statbuf) {
     277                 :   UNREFERENCED_PARAMETER(statbuf);
     278                 : 
     279               0 :   NaClLog(LOG_ERROR,
     280                 :           "Fstat method is not implemented for object of type %s\n",
     281                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     282                 :                               vself->base.vtbl)->typeTag));
     283               0 :   return -NACL_ABI_EINVAL;
     284                 : }
     285                 : 
     286                 : ssize_t NaClDescGetdentsNotImplemented(struct NaClDesc          *vself,
     287                 :                                        void                     *dirp,
     288               0 :                                        size_t                   count) {
     289                 :   UNREFERENCED_PARAMETER(dirp);
     290                 :   UNREFERENCED_PARAMETER(count);
     291                 : 
     292               0 :   NaClLog(LOG_ERROR,
     293                 :           "Getdents method is not implemented for object of type %s\n",
     294                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     295                 :                               vself->base.vtbl)->typeTag));
     296               0 :   return -NACL_ABI_EINVAL;
     297                 : }
     298                 : 
     299                 : int NaClDescExternalizeSizeNotImplemented(struct NaClDesc *vself,
     300                 :                                           size_t          *nbytes,
     301               0 :                                           size_t          *nhandles) {
     302                 :   UNREFERENCED_PARAMETER(nbytes);
     303                 :   UNREFERENCED_PARAMETER(nhandles);
     304                 : 
     305               0 :   NaClLog(LOG_ERROR,
     306                 :           "ExternalizeSize method is not implemented for object of type %s\n",
     307                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     308                 :                               vself->base.vtbl)->typeTag));
     309               0 :   return -NACL_ABI_EINVAL;
     310                 : }
     311                 : 
     312                 : int NaClDescExternalizeNotImplemented(struct NaClDesc          *vself,
     313               0 :                                       struct NaClDescXferState *xfer) {
     314                 :   UNREFERENCED_PARAMETER(xfer);
     315                 : 
     316               0 :   NaClLog(LOG_ERROR,
     317                 :           "Externalize method is not implemented for object of type %s\n",
     318                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     319                 :                               vself->base.vtbl)->typeTag));
     320               0 :   return -NACL_ABI_EINVAL;
     321                 : }
     322                 : 
     323               0 : int NaClDescLockNotImplemented(struct NaClDesc  *vself) {
     324               0 :   NaClLog(LOG_ERROR,
     325                 :           "Lock method is not implemented for object of type %s\n",
     326                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     327                 :                               vself->base.vtbl)->typeTag));
     328               0 :   return -NACL_ABI_EINVAL;
     329                 : }
     330                 : 
     331               0 : int NaClDescTryLockNotImplemented(struct NaClDesc *vself) {
     332               0 :   NaClLog(LOG_ERROR,
     333                 :           "TryLock method is not implemented for object of type %s\n",
     334                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     335                 :                               vself->base.vtbl)->typeTag));
     336               0 :   return -NACL_ABI_EINVAL;
     337                 : }
     338                 : 
     339               0 : int NaClDescUnlockNotImplemented(struct NaClDesc  *vself) {
     340               0 :   NaClLog(LOG_ERROR,
     341                 :           "Unlock method is not implemented for object of type %s\n",
     342                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     343                 :                               vself->base.vtbl)->typeTag));
     344               0 :   return -NACL_ABI_EINVAL;
     345                 : }
     346                 : 
     347                 : int NaClDescWaitNotImplemented(struct NaClDesc  *vself,
     348               0 :                                struct NaClDesc  *mutex) {
     349                 :   UNREFERENCED_PARAMETER(mutex);
     350                 : 
     351               0 :   NaClLog(LOG_ERROR,
     352                 :           "Wait method is not implemented for object of type %s\n",
     353                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     354                 :                               vself->base.vtbl)->typeTag));
     355               0 :   return -NACL_ABI_EINVAL;
     356                 : }
     357                 : 
     358                 : int NaClDescTimedWaitAbsNotImplemented(struct NaClDesc                *vself,
     359                 :                                        struct NaClDesc                *mutex,
     360               0 :                                        struct nacl_abi_timespec const *ts) {
     361                 :   UNREFERENCED_PARAMETER(mutex);
     362                 :   UNREFERENCED_PARAMETER(ts);
     363                 : 
     364               0 :   NaClLog(LOG_ERROR,
     365                 :           "TimedWaitAbs method is not implemented for object of type %s\n",
     366                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     367                 :                               vself->base.vtbl)->typeTag));
     368               0 :   return -NACL_ABI_EINVAL;
     369                 : }
     370                 : 
     371               0 : int NaClDescSignalNotImplemented(struct NaClDesc  *vself) {
     372               0 :   NaClLog(LOG_ERROR,
     373                 :           "Signal method is not implemented for object of type %s\n",
     374                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     375                 :                               vself->base.vtbl)->typeTag));
     376               0 :   return -NACL_ABI_EINVAL;
     377                 : }
     378                 : 
     379               0 : int NaClDescBroadcastNotImplemented(struct NaClDesc *vself) {
     380               0 :   NaClLog(LOG_ERROR,
     381                 :           "Broadcast method is not implemented for object of type %s\n",
     382                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     383                 :                               vself->base.vtbl)->typeTag));
     384               0 :   return -NACL_ABI_EINVAL;
     385                 : }
     386                 : 
     387                 : ssize_t NaClDescSendMsgNotImplemented(struct NaClDesc                *vself,
     388                 :                                       struct NaClMessageHeader const *dgram,
     389               0 :                                       int                            flags) {
     390                 :   UNREFERENCED_PARAMETER(dgram);
     391                 :   UNREFERENCED_PARAMETER(flags);
     392                 : 
     393               0 :   NaClLog(LOG_ERROR,
     394                 :           "SendMsg method is not implemented for object of type %s\n",
     395                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     396                 :                               vself->base.vtbl)->typeTag));
     397               0 :   return -NACL_ABI_EINVAL;
     398                 : }
     399                 : 
     400                 : ssize_t NaClDescRecvMsgNotImplemented(struct NaClDesc           *vself,
     401                 :                                       struct NaClMessageHeader  *dgram,
     402               0 :                                       int                       flags) {
     403                 :   UNREFERENCED_PARAMETER(dgram);
     404                 :   UNREFERENCED_PARAMETER(flags);
     405                 : 
     406               0 :   NaClLog(LOG_ERROR,
     407                 :           "RecvMsg method is not implemented for object of type %s\n",
     408                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     409                 :                               vself->base.vtbl)->typeTag));
     410               0 :   return -NACL_ABI_EINVAL;
     411                 : }
     412                 : 
     413                 : int NaClDescConnectAddrNotImplemented(struct NaClDesc *vself,
     414               1 :                                       struct NaClDesc **result) {
     415                 :   UNREFERENCED_PARAMETER(result);
     416                 : 
     417               1 :   NaClLog(LOG_ERROR,
     418                 :           "ConnectAddr method is not implemented for object of type %s\n",
     419                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     420                 :                               vself->base.vtbl)->typeTag));
     421               1 :   return -NACL_ABI_EINVAL;
     422                 : }
     423                 : 
     424                 : int NaClDescAcceptConnNotImplemented(struct NaClDesc *vself,
     425               1 :                                      struct NaClDesc **result) {
     426                 :   UNREFERENCED_PARAMETER(result);
     427                 : 
     428               1 :   NaClLog(LOG_ERROR,
     429                 :           "AcceptConn method is not implemented for object of type %s\n",
     430                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     431                 :                               vself->base.vtbl)->typeTag));
     432               1 :   return -NACL_ABI_EINVAL;
     433                 : }
     434                 : 
     435               0 : int NaClDescPostNotImplemented(struct NaClDesc  *vself) {
     436               0 :   NaClLog(LOG_ERROR,
     437                 :           "Post method is not implemented for object of type %s\n",
     438                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     439                 :                               vself->base.vtbl)->typeTag));
     440               0 :   return -NACL_ABI_EINVAL;
     441                 : }
     442                 : 
     443               0 : int NaClDescSemWaitNotImplemented(struct NaClDesc *vself) {
     444               0 :   NaClLog(LOG_ERROR,
     445                 :           "SemWait method is not implemented for object of type %s\n",
     446                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     447                 :                               vself->base.vtbl)->typeTag));
     448               0 :   return -NACL_ABI_EINVAL;
     449                 : }
     450                 : 
     451               0 : int NaClDescGetValueNotImplemented(struct NaClDesc  *vself) {
     452               0 :   NaClLog(LOG_ERROR,
     453                 :           "GetValue method is not implemented for object of type %s\n",
     454                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     455                 :                               vself->base.vtbl)->typeTag));
     456               0 :   return -NACL_ABI_EINVAL;
     457                 : }
     458                 : 
     459                 : int NaClDescInternalizeNotImplemented(
     460                 :     struct NaClDesc                **out_desc,
     461                 :     struct NaClDescXferState       *xfer,
     462               0 :     struct NaClDescQuotaInterface  *quota_interface) {
     463                 :   UNREFERENCED_PARAMETER(out_desc);
     464                 :   UNREFERENCED_PARAMETER(xfer);
     465                 :   UNREFERENCED_PARAMETER(quota_interface);
     466                 : 
     467               0 :   NaClLog(LOG_ERROR,
     468                 :           "Attempted transfer of non-transferable descriptor\n");
     469               0 :   return -NACL_ABI_EIO;
     470                 : }
     471                 : 
     472                 : int NaClDescMapDescriptor(struct NaClDesc         *desc,
     473                 :                           struct NaClDescEffector *effector,
     474                 :                           void                    **addr,
     475               0 :                           size_t                  *size) {
     476                 :   struct nacl_abi_stat  st;
     477               0 :   size_t                rounded_size = 0;
     478               0 :   const int             kMaxTries = 10;
     479               0 :   int                   tries = 0;
     480               0 :   void                  *map_addr = NULL;
     481                 :   int                   rval;
     482                 :   uintptr_t             rval_ptr;
     483                 : 
     484               0 :   *addr = NULL;
     485               0 :   *size = 0;
     486                 : 
     487               0 :   rval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->Fstat)(desc, &st);
     488               0 :   if (0 != rval) {
     489                 :     /* Failed to get the size - return failure. */
     490               0 :     return rval;
     491                 :   }
     492                 : 
     493                 :   /*
     494                 :    * on sane systems, sizef(size_t) <= sizeof(nacl_abi_off_t) must hold.
     495                 :    */
     496               0 :   if (st.nacl_abi_st_size < 0) {
     497               0 :     return -NACL_ABI_ENOMEM;
     498                 :   }
     499                 :   if (sizeof(size_t) < sizeof(nacl_abi_off_t)) {
     500               0 :     if ((nacl_abi_off_t) SIZE_T_MAX < st.nacl_abi_st_size) {
     501               0 :       return -NACL_ABI_ENOMEM;
     502                 :     }
     503                 :   }
     504                 :   /*
     505                 :    * size_t and uintptr_t and void * should have the same number of
     506                 :    * bits (well, void * could be smaller than uintptr_t, and on weird
     507                 :    * architectures one could imagine the maximum size is smaller than
     508                 :    * all addr bits, but we're talking sane architectures...).
     509                 :    */
     510                 : 
     511                 :   /*
     512                 :    * When probing by VirtualAlloc/mmap, use the same granularity
     513                 :    * as the Map virtual function (64KB).
     514                 :    */
     515               0 :   rounded_size = NaClRoundAllocPage((size_t) st.nacl_abi_st_size);
     516                 : 
     517                 :   /* Find an address range to map the object into. */
     518                 :   do {
     519               0 :     ++tries;
     520                 : #if NACL_WINDOWS
     521                 :     map_addr = VirtualAlloc(NULL, rounded_size, MEM_RESERVE, PAGE_READWRITE);
     522                 :     if (NULL == map_addr ||!VirtualFree(map_addr, 0, MEM_RELEASE)) {
     523                 :       continue;
     524                 :     }
     525                 : #else
     526               0 :     map_addr = mmap(NULL,
     527                 :                     rounded_size,
     528                 :                     PROT_READ | PROT_WRITE,
     529                 :                     MAP_SHARED | MAP_ANONYMOUS,
     530                 :                     0,
     531                 :                     0);
     532               0 :     if (MAP_FAILED == map_addr || munmap(map_addr, rounded_size)) {
     533               0 :       map_addr = NULL;
     534               0 :       continue;
     535                 :     }
     536                 : #endif
     537               0 :     NaClLog(4,
     538                 :             "NaClDescMapDescriptor: mapping to address %"NACL_PRIxPTR"\n",
     539                 :             (uintptr_t) map_addr);
     540               0 :     rval_ptr = (*((struct NaClDescVtbl const *)
     541                 :                   desc->base.vtbl)->Map)
     542                 :         (desc,
     543                 :          effector,
     544                 :          map_addr,
     545                 :          rounded_size,
     546                 :          NACL_ABI_PROT_READ | NACL_ABI_PROT_WRITE,
     547                 :          NACL_ABI_MAP_SHARED | NACL_ABI_MAP_FIXED,
     548                 :          0);
     549               0 :     NaClLog(4,
     550                 :             "NaClDescMapDescriptor: result is %"NACL_PRIxPTR"\n",
     551                 :             rval_ptr);
     552               0 :     if (NaClPtrIsNegErrno(&rval_ptr)) {
     553                 :       /*
     554                 :        * A nonzero return from NaClIsNegErrno
     555                 :        * indicates that the value is within the range
     556                 :        * reserved for errors, which is representable
     557                 :        * with 32 bits.
     558                 :        */
     559               0 :       rval = (int) rval_ptr;
     560                 :     } else {
     561                 :       /*
     562                 :        * Map() did not return an error, so set our
     563                 :        * return code to 0 (success)
     564                 :        */
     565               0 :       rval = 0;
     566               0 :       map_addr = (void*) rval_ptr;
     567               0 :       break;
     568                 :     }
     569                 : 
     570               0 :   } while (NULL == map_addr && tries < kMaxTries);
     571                 : 
     572               0 :   if (NULL == map_addr) {
     573               0 :     return rval;
     574                 :   }
     575                 : 
     576               0 :   *addr = map_addr;
     577               0 :   *size = rounded_size;
     578               0 :   return 0;
     579                 : }
     580                 : 
     581              92 : int NaClSafeCloseNaClHandle(NaClHandle h) {
     582              92 :   if (NACL_INVALID_HANDLE != h) {
     583               0 :     return NaClClose(h);
     584                 :   }
     585              92 :   return 0;
     586                 : }
     587                 : 
     588                 : 
     589                 : struct NaClDescVtbl const kNaClDescVtbl = {
     590                 :   {
     591                 :     NaClDescDtor,
     592                 :   },
     593                 :   NaClDescMapNotImplemented,
     594                 :   NaClDescUnmapUnsafeNotImplemented,
     595                 :   NaClDescUnmapNotImplemented,
     596                 :   NaClDescReadNotImplemented,
     597                 :   NaClDescWriteNotImplemented,
     598                 :   NaClDescSeekNotImplemented,
     599                 :   NaClDescIoctlNotImplemented,
     600                 :   NaClDescFstatNotImplemented,
     601                 :   NaClDescGetdentsNotImplemented,
     602                 :   (enum NaClDescTypeTag) -1,  /* NaClDesc is an abstract base class */
     603                 :   NaClDescExternalizeSizeNotImplemented,
     604                 :   NaClDescExternalizeNotImplemented,
     605                 :   NaClDescLockNotImplemented,
     606                 :   NaClDescTryLockNotImplemented,
     607                 :   NaClDescUnlockNotImplemented,
     608                 :   NaClDescWaitNotImplemented,
     609                 :   NaClDescTimedWaitAbsNotImplemented,
     610                 :   NaClDescSignalNotImplemented,
     611                 :   NaClDescBroadcastNotImplemented,
     612                 :   NaClDescSendMsgNotImplemented,
     613                 :   NaClDescRecvMsgNotImplemented,
     614                 :   NaClDescConnectAddrNotImplemented,
     615                 :   NaClDescAcceptConnNotImplemented,
     616                 :   NaClDescPostNotImplemented,
     617                 :   NaClDescSemWaitNotImplemented,
     618                 :   NaClDescGetValueNotImplemented,
     619                 : };

Generated by: LCOV version 1.7