LCOV - code coverage report
Current view: directory - src/trusted/desc - nacl_desc_base.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 384 157 40.9 %
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                 : /*
       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/public/desc_metadata_types.h"
      21                 : 
      22                 : #include "native_client/src/shared/platform/nacl_host_desc.h"
      23                 : #include "native_client/src/shared/platform/nacl_log.h"
      24                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      25                 : 
      26                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      27                 : #include "native_client/src/trusted/desc/nacl_desc_cond.h"
      28                 : #include "native_client/src/trusted/desc/nacl_desc_conn_cap.h"
      29                 : #include "native_client/src/trusted/desc/nacl_desc_dir.h"
      30                 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
      31                 : #include "native_client/src/trusted/desc/nacl_desc_imc_bound_desc.h"
      32                 : #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h"
      33                 : #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
      34                 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
      35                 : #include "native_client/src/trusted/desc/nacl_desc_mutex.h"
      36                 : #include "native_client/src/trusted/desc/nacl_desc_null.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/bits/mman.h"
      44                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.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            3412 : 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            3412 :   ndp->flags = 0;
      85            3412 :   ndp->metadata_type = NACL_DESC_METADATA_NONE_TYPE;
      86            3412 :   ndp->metadata_num_bytes = 0;
      87            3412 :   ndp->metadata = NULL;
      88            3412 :   return NaClRefCountCtor(&ndp->base);
      89                 : }
      90                 : 
      91            1155 : static void NaClDescDtor(struct NaClRefCount *nrcp) {
      92            1155 :   struct NaClDesc *ndp = (struct NaClDesc *) nrcp;
      93            1155 :   free(ndp->metadata);
      94            1155 :   ndp->metadata = NULL;
      95            1155 :   nrcp->vtbl = &kNaClRefCountVtbl;
      96            1155 :   (*nrcp->vtbl->Dtor)(nrcp);
      97            1155 : }
      98                 : 
      99           85302 : struct NaClDesc *NaClDescRef(struct NaClDesc *ndp) {
     100           85302 :   return (struct NaClDesc *) NaClRefCountRef(&ndp->base);
     101                 : }
     102                 : 
     103           74321 : void NaClDescUnref(struct NaClDesc *ndp) {
     104           74321 :   NaClRefCountUnref(&ndp->base);
     105           74321 : }
     106                 : 
     107           11332 : void NaClDescSafeUnref(struct NaClDesc *ndp) {
     108           11332 :   if (NULL != ndp) {
     109           10159 :     NaClRefCountUnref(&ndp->base);
     110           10159 :   }
     111           11332 : }
     112                 : 
     113              84 : int NaClDescExternalizeSize(struct NaClDesc *self,
     114              84 :                             size_t *nbytes,
     115              84 :                             size_t *nhandles) {
     116              84 :   *nbytes = sizeof self->flags;
     117              84 :   if (0 != (NACL_DESC_FLAGS_HAS_METADATA & self->flags)) {
     118              27 :     *nbytes += (sizeof self->metadata_type +
     119                 :                 sizeof self->metadata_num_bytes + self->metadata_num_bytes);
     120              27 :   }
     121              84 :   *nhandles = 0;
     122              84 :   return 0;
     123                 : }
     124                 : 
     125              84 : int NaClDescExternalize(struct NaClDesc *self,
     126              84 :                         struct NaClDescXferState *xfer) {
     127             252 :   memcpy(xfer->next_byte, &self->flags, sizeof self->flags);
     128              84 :   xfer->next_byte += sizeof self->flags;
     129              84 :   if (0 != (NACL_DESC_FLAGS_HAS_METADATA & self->flags)) {
     130              81 :     memcpy(xfer->next_byte, &self->metadata_type, sizeof self->metadata_type);
     131              27 :     xfer->next_byte += sizeof self->metadata_type;
     132              81 :     memcpy(xfer->next_byte, &self->metadata_num_bytes,
     133                 :            sizeof self->metadata_num_bytes);
     134              27 :     xfer->next_byte += sizeof self->metadata_num_bytes;
     135              81 :     memcpy(xfer->next_byte, self->metadata, self->metadata_num_bytes);
     136              27 :     xfer->next_byte += self->metadata_num_bytes;
     137              27 :   }
     138              84 :   return 0;
     139                 : }
     140                 : 
     141             110 : int NaClDescInternalizeCtor(struct NaClDesc *vself,
     142             110 :                             struct NaClDescXferState *xfer) {
     143             110 :   int rv;
     144             110 :   char *nxt;
     145                 : 
     146             110 :   rv = NaClDescCtor(vself);
     147             110 :   if (0 == rv) {
     148               0 :     return rv;
     149                 :   }
     150             110 :   nxt = xfer->next_byte;
     151             110 :   if (nxt + sizeof vself->flags > xfer->byte_buffer_end) {
     152               0 :     rv = 0;
     153               0 :     goto done;
     154                 :   }
     155             330 :   memcpy(&vself->flags, nxt, sizeof vself->flags);
     156             110 :   nxt += sizeof vself->flags;
     157             110 :   if (0 == (NACL_DESC_FLAGS_HAS_METADATA & vself->flags)) {
     158              83 :     xfer->next_byte = nxt;
     159              83 :     rv = 1;
     160              83 :     goto done;
     161                 :   }
     162              27 :   if (nxt + sizeof vself->metadata_type + sizeof vself->metadata_num_bytes >
     163                 :       xfer->byte_buffer_end) {
     164               0 :     rv = 0;
     165               0 :     goto done;
     166                 :   }
     167              81 :   memcpy(&vself->metadata_type, nxt, sizeof vself->metadata_type);
     168              27 :   nxt += sizeof vself->metadata_type;
     169              81 :   memcpy(&vself->metadata_num_bytes, nxt, sizeof vself->metadata_num_bytes);
     170              27 :   nxt += sizeof vself->metadata_num_bytes;
     171              27 :   if (nxt + vself->metadata_num_bytes > xfer->byte_buffer_end) {
     172               0 :     rv = 0;
     173               0 :     goto done;
     174                 :   }
     175              27 :   if (NULL == (vself->metadata = malloc(vself->metadata_num_bytes))) {
     176               0 :     rv = 0;
     177               0 :     goto done;
     178                 :   }
     179              81 :   memcpy(vself->metadata, nxt, vself->metadata_num_bytes);
     180              27 :   nxt += vself->metadata_num_bytes;
     181              27 :   xfer->next_byte = nxt;
     182              27 :   rv = 1;
     183                 :  done:
     184             110 :   if (!rv) {
     185               0 :     (*NACL_VTBL(NaClRefCount, vself)->Dtor)((struct NaClRefCount *) vself);
     186               0 :   }
     187             110 :   return rv;
     188             110 : }
     189                 : 
     190                 : int (*NaClDescInternalize[NACL_DESC_TYPE_MAX])(
     191                 :     struct NaClDesc **,
     192                 :     struct NaClDescXferState *,
     193                 :     struct NaClDescQuotaInterface *) = {
     194                 :   NaClDescInvalidInternalize,
     195                 :   NaClDescInternalizeNotImplemented,
     196                 :   NaClDescIoInternalize,
     197                 : #if NACL_WINDOWS
     198                 :   NaClDescConnCapInternalize,
     199                 :   NaClDescInternalizeNotImplemented,
     200                 : #else
     201                 :   NaClDescInternalizeNotImplemented,
     202                 :   NaClDescConnCapFdInternalize,
     203                 : #endif
     204                 :   NaClDescInternalizeNotImplemented,  /* bound sockets cannot be transferred */
     205                 :   NaClDescInternalizeNotImplemented,  /* connected abstract base class */
     206                 :   NaClDescImcShmInternalize,
     207                 :   NaClDescInternalizeNotImplemented,  /* mutex */
     208                 :   NaClDescInternalizeNotImplemented,  /* condvar */
     209                 :   NaClDescInternalizeNotImplemented,  /* semaphore */
     210                 :   NaClDescSyncSocketInternalize,
     211                 :   NaClDescXferableDataDescInternalize,
     212                 :   NaClDescInternalizeNotImplemented,  /* imc socket */
     213                 :   NaClDescQuotaInternalize,           /* quota wrapper */
     214                 :   NaClDescRngInternalize,             /* device: rng */
     215                 :   NaClDescInternalizeNotImplemented,  /* device: postmessage */
     216                 :   NaClDescInternalizeNotImplemented,  /* custom */
     217                 :   NaClDescNullInternalize,
     218                 : };
     219                 : 
     220               2 : char const *NaClDescTypeString(enum NaClDescTypeTag type_tag) {
     221                 :   /* default functions for the vtable - return NOT_IMPLEMENTED */
     222               2 :   switch (type_tag) {
     223                 : #define MAP(E) case E: do { return #E; } while (0)
     224               0 :     MAP(NACL_DESC_INVALID);
     225               0 :     MAP(NACL_DESC_DIR);
     226               0 :     MAP(NACL_DESC_HOST_IO);
     227               0 :     MAP(NACL_DESC_CONN_CAP);
     228               0 :     MAP(NACL_DESC_CONN_CAP_FD);
     229               2 :     MAP(NACL_DESC_BOUND_SOCKET);
     230               0 :     MAP(NACL_DESC_CONNECTED_SOCKET);
     231               0 :     MAP(NACL_DESC_SHM);
     232               0 :     MAP(NACL_DESC_MUTEX);
     233               0 :     MAP(NACL_DESC_CONDVAR);
     234               0 :     MAP(NACL_DESC_SEMAPHORE);
     235               0 :     MAP(NACL_DESC_SYNC_SOCKET);
     236               0 :     MAP(NACL_DESC_TRANSFERABLE_DATA_SOCKET);
     237               2 :     MAP(NACL_DESC_IMC_SOCKET);
     238               0 :     MAP(NACL_DESC_QUOTA);
     239               0 :     MAP(NACL_DESC_DEVICE_RNG);
     240               0 :     MAP(NACL_DESC_DEVICE_POSTMESSAGE);
     241               0 :     MAP(NACL_DESC_CUSTOM);
     242               0 :     MAP(NACL_DESC_NULL);
     243               0 :   }
     244               0 :   return "BAD TYPE TAG";
     245               2 : }
     246                 : 
     247                 : 
     248               0 : void NaClDescDtorNotImplemented(struct NaClRefCount  *vself) {
     249               0 :   UNREFERENCED_PARAMETER(vself);
     250                 : 
     251               0 :   NaClLog(LOG_FATAL, "Must implement a destructor!\n");
     252               0 : }
     253                 : 
     254               0 : uintptr_t NaClDescMapNotImplemented(struct NaClDesc         *vself,
     255               0 :                                     struct NaClDescEffector *effp,
     256               0 :                                     void                    *start_addr,
     257               0 :                                     size_t                  len,
     258               0 :                                     int                     prot,
     259               0 :                                     int                     flags,
     260               0 :                                     nacl_off64_t            offset) {
     261               0 :   UNREFERENCED_PARAMETER(effp);
     262               0 :   UNREFERENCED_PARAMETER(start_addr);
     263               0 :   UNREFERENCED_PARAMETER(len);
     264               0 :   UNREFERENCED_PARAMETER(prot);
     265               0 :   UNREFERENCED_PARAMETER(flags);
     266               0 :   UNREFERENCED_PARAMETER(offset);
     267                 : 
     268               0 :   NaClLog(LOG_ERROR,
     269                 :           "Map method is not implemented for object of type %s\n",
     270               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     271                 :                               vself->base.vtbl)->typeTag));
     272               0 :   return -NACL_ABI_EINVAL;
     273                 : }
     274                 : 
     275                 : #if NACL_WINDOWS
     276                 : int NaClDescUnmapUnsafeNotImplemented(struct NaClDesc         *vself,
     277                 :                                       void                    *start_addr,
     278                 :                                       size_t                  len) {
     279                 :   UNREFERENCED_PARAMETER(start_addr);
     280                 :   UNREFERENCED_PARAMETER(len);
     281                 : 
     282                 :   NaClLog(LOG_ERROR,
     283                 :           "Map method is not implemented for object of type %s\n",
     284                 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     285                 :                               vself->base.vtbl)->typeTag));
     286                 :   return -NACL_ABI_EINVAL;
     287                 : }
     288                 : #endif
     289                 : 
     290               0 : ssize_t NaClDescReadNotImplemented(struct NaClDesc          *vself,
     291               0 :                                    void                     *buf,
     292               0 :                                    size_t                   len) {
     293               0 :   UNREFERENCED_PARAMETER(buf);
     294               0 :   UNREFERENCED_PARAMETER(len);
     295                 : 
     296               0 :   NaClLog(LOG_ERROR,
     297                 :           "Read method is not implemented for object of type %s\n",
     298               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     299                 :                               vself->base.vtbl)->typeTag));
     300               0 :   return -NACL_ABI_EINVAL;
     301                 : }
     302                 : 
     303               0 : ssize_t NaClDescWriteNotImplemented(struct NaClDesc         *vself,
     304               0 :                                     void const              *buf,
     305               0 :                                     size_t                  len) {
     306               0 :   UNREFERENCED_PARAMETER(buf);
     307               0 :   UNREFERENCED_PARAMETER(len);
     308                 : 
     309               0 :   NaClLog(LOG_ERROR,
     310                 :           "Write method is not implemented for object of type %s\n",
     311               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     312                 :                               vself->base.vtbl)->typeTag));
     313               0 :   return -NACL_ABI_EINVAL;
     314                 : }
     315                 : 
     316               0 : nacl_off64_t NaClDescSeekNotImplemented(struct NaClDesc          *vself,
     317               0 :                                         nacl_off64_t             offset,
     318               0 :                                         int                      whence) {
     319               0 :   UNREFERENCED_PARAMETER(offset);
     320               0 :   UNREFERENCED_PARAMETER(whence);
     321                 : 
     322               0 :   NaClLog(LOG_ERROR,
     323                 :           "Seek method is not implemented for object of type %s\n",
     324               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     325                 :                               vself->base.vtbl)->typeTag));
     326               0 :   return -NACL_ABI_EINVAL;
     327                 : }
     328                 : 
     329               0 : ssize_t NaClDescPReadNotImplemented(struct NaClDesc *vself,
     330               0 :                                     void *buf,
     331               0 :                                     size_t len,
     332               0 :                                     nacl_off64_t offset) {
     333               0 :   UNREFERENCED_PARAMETER(buf);
     334               0 :   UNREFERENCED_PARAMETER(len);
     335               0 :   UNREFERENCED_PARAMETER(offset);
     336                 : 
     337               0 :   NaClLog(LOG_ERROR,
     338                 :           "PRead method is not implemented for object of type %s\n",
     339               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     340                 :                               vself->base.vtbl)->typeTag));
     341               0 :   return -NACL_ABI_EINVAL;
     342                 : }
     343                 : 
     344               0 : ssize_t NaClDescPWriteNotImplemented(struct NaClDesc *vself,
     345               0 :                                      void const *buf,
     346               0 :                                      size_t len,
     347               0 :                                      nacl_off64_t offset) {
     348               0 :   UNREFERENCED_PARAMETER(buf);
     349               0 :   UNREFERENCED_PARAMETER(len);
     350               0 :   UNREFERENCED_PARAMETER(offset);
     351                 : 
     352               0 :   NaClLog(LOG_ERROR,
     353                 :           "PWrite method is not implemented for object of type %s\n",
     354               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     355                 :                               vself->base.vtbl)->typeTag));
     356               0 :   return -NACL_ABI_EINVAL;
     357                 : }
     358                 : 
     359               0 : int NaClDescFstatNotImplemented(struct NaClDesc         *vself,
     360               0 :                                 struct nacl_abi_stat    *statbuf) {
     361               0 :   UNREFERENCED_PARAMETER(statbuf);
     362                 : 
     363               0 :   NaClLog(LOG_ERROR,
     364                 :           "Fstat method is not implemented for object of type %s\n",
     365               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     366                 :                               vself->base.vtbl)->typeTag));
     367               0 :   return -NACL_ABI_EINVAL;
     368                 : }
     369                 : 
     370               0 : ssize_t NaClDescGetdentsNotImplemented(struct NaClDesc          *vself,
     371               0 :                                        void                     *dirp,
     372               0 :                                        size_t                   count) {
     373               0 :   UNREFERENCED_PARAMETER(dirp);
     374               0 :   UNREFERENCED_PARAMETER(count);
     375                 : 
     376               0 :   NaClLog(LOG_ERROR,
     377                 :           "Getdents method is not implemented for object of type %s\n",
     378               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     379                 :                               vself->base.vtbl)->typeTag));
     380               0 :   return -NACL_ABI_EINVAL;
     381                 : }
     382                 : 
     383               2 : int NaClDescExternalizeSizeNotImplemented(struct NaClDesc *vself,
     384               2 :                                           size_t          *nbytes,
     385               2 :                                           size_t          *nhandles) {
     386               4 :   UNREFERENCED_PARAMETER(nbytes);
     387               4 :   UNREFERENCED_PARAMETER(nhandles);
     388                 : 
     389               2 :   NaClLog(LOG_ERROR,
     390                 :           "ExternalizeSize method is not implemented for object of type %s\n",
     391               2 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     392                 :                               vself->base.vtbl)->typeTag));
     393               2 :   return -NACL_ABI_EINVAL;
     394                 : }
     395                 : 
     396               0 : int NaClDescExternalizeNotImplemented(struct NaClDesc          *vself,
     397               0 :                                       struct NaClDescXferState *xfer) {
     398               0 :   UNREFERENCED_PARAMETER(xfer);
     399                 : 
     400               0 :   NaClLog(LOG_ERROR,
     401                 :           "Externalize method is not implemented for object of type %s\n",
     402               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     403                 :                               vself->base.vtbl)->typeTag));
     404               0 :   return -NACL_ABI_EINVAL;
     405                 : }
     406                 : 
     407               0 : int NaClDescLockNotImplemented(struct NaClDesc  *vself) {
     408               0 :   NaClLog(LOG_ERROR,
     409                 :           "Lock method is not implemented for object of type %s\n",
     410               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     411                 :                               vself->base.vtbl)->typeTag));
     412               0 :   return -NACL_ABI_EINVAL;
     413                 : }
     414                 : 
     415               0 : int NaClDescTryLockNotImplemented(struct NaClDesc *vself) {
     416               0 :   NaClLog(LOG_ERROR,
     417                 :           "TryLock method is not implemented for object of type %s\n",
     418               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     419                 :                               vself->base.vtbl)->typeTag));
     420               0 :   return -NACL_ABI_EINVAL;
     421                 : }
     422                 : 
     423               0 : int NaClDescUnlockNotImplemented(struct NaClDesc  *vself) {
     424               0 :   NaClLog(LOG_ERROR,
     425                 :           "Unlock method is not implemented for object of type %s\n",
     426               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     427                 :                               vself->base.vtbl)->typeTag));
     428               0 :   return -NACL_ABI_EINVAL;
     429                 : }
     430                 : 
     431               0 : int NaClDescWaitNotImplemented(struct NaClDesc  *vself,
     432               0 :                                struct NaClDesc  *mutex) {
     433               0 :   UNREFERENCED_PARAMETER(mutex);
     434                 : 
     435               0 :   NaClLog(LOG_ERROR,
     436                 :           "Wait method is not implemented for object of type %s\n",
     437               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     438                 :                               vself->base.vtbl)->typeTag));
     439               0 :   return -NACL_ABI_EINVAL;
     440                 : }
     441                 : 
     442               0 : int NaClDescTimedWaitAbsNotImplemented(struct NaClDesc                *vself,
     443               0 :                                        struct NaClDesc                *mutex,
     444               0 :                                        struct nacl_abi_timespec const *ts) {
     445               0 :   UNREFERENCED_PARAMETER(mutex);
     446               0 :   UNREFERENCED_PARAMETER(ts);
     447                 : 
     448               0 :   NaClLog(LOG_ERROR,
     449                 :           "TimedWaitAbs method is not implemented for object of type %s\n",
     450               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     451                 :                               vself->base.vtbl)->typeTag));
     452               0 :   return -NACL_ABI_EINVAL;
     453                 : }
     454                 : 
     455               0 : int NaClDescSignalNotImplemented(struct NaClDesc  *vself) {
     456               0 :   NaClLog(LOG_ERROR,
     457                 :           "Signal method is not implemented for object of type %s\n",
     458               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     459                 :                               vself->base.vtbl)->typeTag));
     460               0 :   return -NACL_ABI_EINVAL;
     461                 : }
     462                 : 
     463               0 : int NaClDescBroadcastNotImplemented(struct NaClDesc *vself) {
     464               0 :   NaClLog(LOG_ERROR,
     465                 :           "Broadcast method is not implemented for object of type %s\n",
     466               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     467                 :                               vself->base.vtbl)->typeTag));
     468               0 :   return -NACL_ABI_EINVAL;
     469                 : }
     470                 : 
     471                 : ssize_t NaClDescSendMsgNotImplemented(
     472               0 :     struct NaClDesc                 *vself,
     473               0 :     const struct NaClImcTypedMsgHdr *nitmhp,
     474               0 :     int                             flags) {
     475               0 :   UNREFERENCED_PARAMETER(nitmhp);
     476               0 :   UNREFERENCED_PARAMETER(flags);
     477                 : 
     478               0 :   NaClLog(LOG_ERROR,
     479                 :           "SendMsg method is not implemented for object of type %s\n",
     480               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     481                 :                               vself->base.vtbl)->typeTag));
     482               0 :   return -NACL_ABI_EINVAL;
     483                 : }
     484                 : 
     485                 : ssize_t NaClDescRecvMsgNotImplemented(
     486               0 :     struct NaClDesc                 *vself,
     487               0 :     struct NaClImcTypedMsgHdr       *nitmhp,
     488               0 :     int                             flags,
     489               0 :     struct NaClDescQuotaInterface   *quota_interface) {
     490               0 :   UNREFERENCED_PARAMETER(nitmhp);
     491               0 :   UNREFERENCED_PARAMETER(flags);
     492               0 :   UNREFERENCED_PARAMETER(quota_interface);
     493                 : 
     494               0 :   NaClLog(LOG_ERROR,
     495                 :           "RecvMsg method is not implemented for object of type %s\n",
     496               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     497                 :                               vself->base.vtbl)->typeTag));
     498               0 :   return -NACL_ABI_EINVAL;
     499                 : }
     500                 : 
     501                 : ssize_t NaClDescLowLevelSendMsgNotImplemented(
     502               0 :     struct NaClDesc                *vself,
     503               0 :     struct NaClMessageHeader const *dgram,
     504               0 :     int                            flags) {
     505               0 :   UNREFERENCED_PARAMETER(dgram);
     506               0 :   UNREFERENCED_PARAMETER(flags);
     507                 : 
     508               0 :   NaClLog(LOG_ERROR,
     509                 :           "LowLevelSendMsg method is not implemented for object of type %s\n",
     510               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     511                 :                               vself->base.vtbl)->typeTag));
     512               0 :   return -NACL_ABI_EINVAL;
     513                 : }
     514                 : 
     515                 : ssize_t NaClDescLowLevelRecvMsgNotImplemented(
     516               0 :     struct NaClDesc           *vself,
     517               0 :     struct NaClMessageHeader  *dgram,
     518               0 :     int                       flags) {
     519               0 :   UNREFERENCED_PARAMETER(dgram);
     520               0 :   UNREFERENCED_PARAMETER(flags);
     521                 : 
     522               0 :   NaClLog(LOG_ERROR,
     523                 :           "LowLevelRecvMsg method is not implemented for object of type %s\n",
     524               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     525                 :                               vself->base.vtbl)->typeTag));
     526               0 :   return -NACL_ABI_EINVAL;
     527                 : }
     528                 : 
     529               0 : int NaClDescConnectAddrNotImplemented(struct NaClDesc *vself,
     530               0 :                                       struct NaClDesc **result) {
     531               0 :   UNREFERENCED_PARAMETER(result);
     532                 : 
     533               0 :   NaClLog(LOG_ERROR,
     534                 :           "ConnectAddr method is not implemented for object of type %s\n",
     535               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     536                 :                               vself->base.vtbl)->typeTag));
     537               0 :   return -NACL_ABI_EINVAL;
     538                 : }
     539                 : 
     540               0 : int NaClDescAcceptConnNotImplemented(struct NaClDesc *vself,
     541               0 :                                      struct NaClDesc **result) {
     542               0 :   UNREFERENCED_PARAMETER(result);
     543                 : 
     544               0 :   NaClLog(LOG_ERROR,
     545                 :           "AcceptConn method is not implemented for object of type %s\n",
     546               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     547                 :                               vself->base.vtbl)->typeTag));
     548               0 :   return -NACL_ABI_EINVAL;
     549                 : }
     550                 : 
     551               0 : int NaClDescPostNotImplemented(struct NaClDesc  *vself) {
     552               0 :   NaClLog(LOG_ERROR,
     553                 :           "Post method is not implemented for object of type %s\n",
     554               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     555                 :                               vself->base.vtbl)->typeTag));
     556               0 :   return -NACL_ABI_EINVAL;
     557                 : }
     558                 : 
     559               0 : int NaClDescSemWaitNotImplemented(struct NaClDesc *vself) {
     560               0 :   NaClLog(LOG_ERROR,
     561                 :           "SemWait method is not implemented for object of type %s\n",
     562               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     563                 :                               vself->base.vtbl)->typeTag));
     564               0 :   return -NACL_ABI_EINVAL;
     565                 : }
     566                 : 
     567               0 : int NaClDescGetValueNotImplemented(struct NaClDesc  *vself) {
     568               0 :   NaClLog(LOG_ERROR,
     569                 :           "GetValue method is not implemented for object of type %s\n",
     570               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     571                 :                               vself->base.vtbl)->typeTag));
     572               0 :   return -NACL_ABI_EINVAL;
     573                 : }
     574                 : 
     575                 : int NaClDescInternalizeNotImplemented(
     576               0 :     struct NaClDesc                **out_desc,
     577               0 :     struct NaClDescXferState       *xfer,
     578               0 :     struct NaClDescQuotaInterface  *quota_interface) {
     579               0 :   UNREFERENCED_PARAMETER(out_desc);
     580               0 :   UNREFERENCED_PARAMETER(xfer);
     581               0 :   UNREFERENCED_PARAMETER(quota_interface);
     582                 : 
     583               0 :   NaClLog(LOG_ERROR,
     584                 :           "Attempted transfer of non-transferable descriptor\n");
     585               0 :   return -NACL_ABI_EIO;
     586                 : }
     587                 : 
     588             112 : int NaClSafeCloseNaClHandle(NaClHandle h) {
     589             112 :   if (NACL_INVALID_HANDLE != h) {
     590               2 :     return NaClClose(h);
     591                 :   }
     592             110 :   return 0;
     593             112 : }
     594                 : 
     595              32 : int NaClDescSetMetadata(struct NaClDesc *self,
     596              32 :                         int32_t metadata_type,
     597              32 :                         uint32_t metadata_num_bytes,
     598              32 :                         uint8_t const *metadata_bytes) {
     599              32 :   uint8_t *buffer = NULL;
     600              32 :   int rv;
     601                 : 
     602              32 :   if (metadata_type < 0) {
     603               0 :     return -NACL_ABI_EINVAL;
     604                 :   }
     605              32 :   buffer = malloc(metadata_num_bytes);
     606              32 :   if (NULL == buffer) {
     607               0 :     return -NACL_ABI_ENOMEM;
     608                 :   }
     609                 : 
     610              32 :   NaClRefCountLock(&self->base);
     611              32 :   if (0 != (self->flags & NACL_DESC_FLAGS_HAS_METADATA)) {
     612               0 :     rv = -NACL_ABI_EPERM;
     613               0 :     goto done;
     614                 :   }
     615              96 :   memcpy(buffer, metadata_bytes, metadata_num_bytes);
     616              32 :   self->metadata_type = metadata_type;
     617              32 :   self->metadata_num_bytes = metadata_num_bytes;
     618              32 :   free(self->metadata);
     619              32 :   self->metadata = buffer;
     620              32 :   self->flags = self->flags | NACL_DESC_FLAGS_HAS_METADATA;
     621              32 :   rv = 0;
     622                 :  done:
     623              32 :   NaClRefCountUnlock(&self->base);
     624              32 :   if (rv < 0) {
     625               0 :     free(buffer);
     626               0 :   }
     627              32 :   return rv;
     628              32 : }
     629                 : 
     630             311 : int32_t NaClDescGetMetadata(struct NaClDesc *self,
     631             311 :                             uint32_t *metadata_buffer_bytes_in_out,
     632             311 :                             uint8_t *metadata_buffer) {
     633             311 :   int rv;
     634             311 :   uint32_t bytes_to_copy;
     635                 : 
     636             311 :   NaClRefCountLock(&self->base);
     637             311 :   if (0 == (NACL_DESC_FLAGS_HAS_METADATA & self->flags)) {
     638             275 :     *metadata_buffer_bytes_in_out = 0;
     639             275 :     rv = NACL_DESC_METADATA_NONE_TYPE;
     640             275 :     goto done;
     641                 :   }
     642              36 :   if (NACL_DESC_METADATA_NONE_TYPE == self->metadata_type) {
     643               0 :     *metadata_buffer_bytes_in_out = 0;
     644               0 :     rv = NACL_DESC_METADATA_NONE_TYPE;
     645               0 :     goto done;
     646                 :   }
     647              36 :   bytes_to_copy = *metadata_buffer_bytes_in_out;
     648              36 :   if (bytes_to_copy > self->metadata_num_bytes) {
     649              26 :     bytes_to_copy = self->metadata_num_bytes;
     650              26 :   }
     651              68 :   if (NULL != metadata_buffer && 0 < bytes_to_copy) {
     652              93 :     memcpy(metadata_buffer, self->metadata, bytes_to_copy);
     653              31 :   }
     654              36 :   *metadata_buffer_bytes_in_out = self->metadata_num_bytes;
     655              36 :   rv = self->metadata_type;
     656                 :  done:
     657             311 :   NaClRefCountUnlock(&self->base);
     658             311 :   return rv;
     659                 : }
     660                 : 
     661                 : /*
     662                 :  * Consider switching to atomic word operations.  This should be
     663                 :  * infrequent enought that it should not matter.
     664                 :  */
     665            1945 : void NaClDescSetFlags(struct NaClDesc *self,
     666            1945 :                       uint32_t flags) {
     667            1945 :   NaClRefCountLock(&self->base);
     668            1945 :   self->flags = ((self->flags & ~NACL_DESC_FLAGS_PUBLIC_MASK) |
     669                 :                  (flags & NACL_DESC_FLAGS_PUBLIC_MASK));
     670            1945 :   NaClRefCountUnlock(&self->base);
     671            1945 : }
     672                 : 
     673            1102 : uint32_t NaClDescGetFlags(struct NaClDesc *self) {
     674            1102 :   uint32_t rv;
     675            1102 :   NaClRefCountLock(&self->base);
     676            1102 :   rv = self->flags & NACL_DESC_FLAGS_PUBLIC_MASK;
     677            1102 :   NaClRefCountUnlock(&self->base);
     678            1102 :   return rv;
     679                 : }
     680                 : 
     681             784 : int NaClDescIsSafeForMmap(struct NaClDesc *self) {
     682             784 :   return 0 != (NaClDescGetFlags(self) & NACL_DESC_FLAGS_MMAP_EXEC_OK);
     683                 : }
     684                 : 
     685               2 : void NaClDescMarkSafeForMmap(struct NaClDesc *self) {
     686               4 :   NaClDescSetFlags(self,
     687               2 :                    NACL_DESC_FLAGS_MMAP_EXEC_OK | NaClDescGetFlags(self));
     688               2 : }
     689                 : 
     690             271 : void NaClDescMarkUnsafeForMmap(struct NaClDesc *self) {
     691             542 :   NaClDescSetFlags(self,
     692             271 :                    ~NACL_DESC_FLAGS_MMAP_EXEC_OK & NaClDescGetFlags(self));
     693             271 : }
     694                 : 
     695               0 : int32_t NaClDescIsattyNotImplemented(struct NaClDesc *vself) {
     696               0 :   NaClLog(LOG_ERROR,
     697                 :           "Isatty method is not implemented for object of type %s\n",
     698               0 :           NaClDescTypeString(((struct NaClDescVtbl const *)
     699                 :                               vself->base.vtbl)->typeTag));
     700               0 :   return -NACL_ABI_ENOTTY;
     701                 : }
     702                 : 
     703                 : struct NaClDescVtbl const kNaClDescVtbl = {
     704                 :   {
     705                 :     NaClDescDtor,
     706                 :   },
     707                 :   NaClDescMapNotImplemented,
     708                 :   NACL_DESC_UNMAP_NOT_IMPLEMENTED
     709                 :   NaClDescReadNotImplemented,
     710                 :   NaClDescWriteNotImplemented,
     711                 :   NaClDescSeekNotImplemented,
     712                 :   NaClDescPReadNotImplemented,
     713                 :   NaClDescPWriteNotImplemented,
     714                 :   NaClDescFstatNotImplemented,
     715                 :   NaClDescGetdentsNotImplemented,
     716                 :   NaClDescExternalizeSizeNotImplemented,
     717                 :   NaClDescExternalizeNotImplemented,
     718                 :   NaClDescLockNotImplemented,
     719                 :   NaClDescTryLockNotImplemented,
     720                 :   NaClDescUnlockNotImplemented,
     721                 :   NaClDescWaitNotImplemented,
     722                 :   NaClDescTimedWaitAbsNotImplemented,
     723                 :   NaClDescSignalNotImplemented,
     724                 :   NaClDescBroadcastNotImplemented,
     725                 :   NaClDescSendMsgNotImplemented,
     726                 :   NaClDescRecvMsgNotImplemented,
     727                 :   NaClDescLowLevelSendMsgNotImplemented,
     728                 :   NaClDescLowLevelRecvMsgNotImplemented,
     729                 :   NaClDescConnectAddrNotImplemented,
     730                 :   NaClDescAcceptConnNotImplemented,
     731                 :   NaClDescPostNotImplemented,
     732                 :   NaClDescSemWaitNotImplemented,
     733                 :   NaClDescGetValueNotImplemented,
     734                 :   NaClDescSetMetadata,
     735                 :   NaClDescGetMetadata,
     736                 :   NaClDescSetFlags,
     737                 :   NaClDescGetFlags,
     738                 :   NaClDescIsattyNotImplemented,
     739                 :   (enum NaClDescTypeTag) -1,  /* NaClDesc is an abstract base class */
     740                 : };

Generated by: LCOV version 1.7