LCOV - code coverage report
Current view: directory - src/trusted/desc - nacl_desc_imc.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 157 55 35.0 %
Date: 2014-09-25 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.
       9                 :  */
      10                 : 
      11                 : #include <stdlib.h>
      12                 : #include <string.h>
      13                 : #include <errno.h>
      14                 : 
      15                 : #include "native_client/src/include/portability.h"
      16                 : 
      17                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      18                 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
      19                 : #include "native_client/src/trusted/desc/nrd_xfer.h"
      20                 : 
      21                 : #include "native_client/src/shared/platform/nacl_log.h"
      22                 : #include "native_client/src/shared/platform/nacl_sync.h"
      23                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      24                 : 
      25                 : #if NACL_WINDOWS
      26                 : # include "native_client/src/shared/platform/win/xlate_system_error.h"
      27                 : #endif
      28                 : 
      29                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      30                 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
      31                 : 
      32                 : /*
      33                 :  * This file contains the implementation of the NaClDescImcDesc
      34                 :  * subclass of NaClDesc.
      35                 :  *
      36                 :  * NaClDescImcDesc is the subclass that wraps IMC socket descriptors.
      37                 :  */
      38                 : 
      39                 : /* fwd */
      40                 : static struct NaClDescVtbl const kNaClDescImcConnectedDescVtbl;
      41                 : static struct NaClDescVtbl const kNaClDescImcDescVtbl;
      42                 : static struct NaClDescVtbl const kNaClDescXferableDataDescVtbl;
      43                 : 
      44                 : static int NaClDescImcConnectedDescSubclassCtor(
      45                 :     struct NaClDescImcConnectedDesc  *self,
      46               4 :     NaClHandle                       h) {
      47               4 :   struct NaClDesc *basep = (struct NaClDesc *) self;
      48                 : 
      49               4 :   self->h = h;
      50                 :   basep->base.vtbl = (struct NaClRefCountVtbl const *)
      51               4 :       &kNaClDescImcConnectedDescVtbl;
      52                 : 
      53               4 :   return 1;
      54               4 : }
      55                 : 
      56                 : int NaClDescImcConnectedDescCtor(struct NaClDescImcConnectedDesc  *self,
      57               4 :                                  NaClHandle                       h) {
      58               4 :   struct NaClDesc *basep = (struct NaClDesc *) self;
      59                 :   int rv;
      60                 : 
      61               4 :   basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
      62                 : 
      63               4 :   if (!NaClDescCtor(basep)) {
      64               0 :     return 0;
      65                 :   }
      66               4 :   rv = NaClDescImcConnectedDescSubclassCtor(self, h);
      67               4 :   if (!rv) {
      68               0 :     (*NACL_VTBL(NaClRefCount, basep)->Dtor)((struct NaClRefCount *) basep);
      69                 :   }
      70                 : 
      71               4 :   return rv;
      72               4 : }
      73                 : 
      74               2 : static void NaClDescImcConnectedDescDtor(struct NaClRefCount *vself) {
      75                 :   struct NaClDescImcConnectedDesc *self = ((struct NaClDescImcConnectedDesc *)
      76               2 :                                            vself);
      77               2 :   if (self->h != NACL_INVALID_HANDLE) {
      78               2 :     (void) NaClClose(self->h);
      79                 :   }
      80               2 :   self->h = NACL_INVALID_HANDLE;
      81               2 :   vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
      82               2 :   (*vself->vtbl->Dtor)(vself);
      83               2 : }
      84                 : 
      85                 : int NaClDescImcDescCtor(struct NaClDescImcDesc  *self,
      86               4 :                         NaClHandle              h) {
      87                 :   int retval;
      88                 : 
      89               4 :   retval = NaClDescImcConnectedDescCtor(&self->base, h);
      90               4 :   if (!retval) {
      91               0 :     return 0;
      92                 :   }
      93               4 :   if (!NaClMutexCtor(&self->sendmsg_mu)) {
      94               0 :     NaClDescUnref((struct NaClDesc *) self);
      95               0 :     return 0;
      96                 :   }
      97               4 :   if (!NaClMutexCtor(&self->recvmsg_mu)) {
      98               0 :     NaClMutexDtor(&self->sendmsg_mu);
      99               0 :     NaClDescUnref((struct NaClDesc *) self);
     100               0 :     return 0;
     101                 :   }
     102                 :   self->base.base.base.vtbl = (struct NaClRefCountVtbl const *)
     103               4 :       &kNaClDescImcDescVtbl;
     104                 : 
     105               4 :   return retval;
     106               4 : }
     107                 : 
     108               2 : static void NaClDescImcDescDtor(struct NaClRefCount *vself) {
     109                 :   struct NaClDescImcDesc *self = ((struct NaClDescImcDesc *)
     110               2 :                                   vself);
     111               2 :   NaClMutexDtor(&self->sendmsg_mu);
     112               2 :   NaClMutexDtor(&self->recvmsg_mu);
     113                 : 
     114                 :   vself->vtbl = (struct NaClRefCountVtbl const *)
     115               2 :       &kNaClDescImcConnectedDescVtbl;
     116               2 :   (*vself->vtbl->Dtor)(vself);
     117               2 : }
     118                 : 
     119                 : /*
     120                 :  * Construct NaclDescImcConnectedDesc then NaClDescXferableDataDesc,
     121                 :  * assuming NaClDesc construction in |*self| has already occurred.
     122                 :  */
     123                 : static int NaClDescXferableDataDescSubclassesCtor(
     124                 :     struct NaClDescXferableDataDesc  *self,
     125               0 :     NaClHandle                       h) {
     126                 :   int retval;
     127                 : 
     128               0 :   retval = NaClDescImcConnectedDescSubclassCtor(&self->base, h);
     129               0 :   if (!retval) {
     130               0 :     return 0;
     131                 :   }
     132                 :   self->base.base.base.vtbl = (struct NaClRefCountVtbl const *)
     133               0 :       &kNaClDescXferableDataDescVtbl;
     134                 : 
     135               0 :   return retval;
     136               0 : }
     137                 : 
     138                 : int NaClDescXferableDataDescCtor(struct NaClDescXferableDataDesc  *self,
     139               0 :                                  NaClHandle                       h) {
     140                 :   int retval;
     141                 : 
     142               0 :   retval = NaClDescImcConnectedDescCtor(&self->base, h);
     143               0 :   if (!retval) {
     144               0 :     return 0;
     145                 :   }
     146                 :   self->base.base.base.vtbl = (struct NaClRefCountVtbl const *)
     147               0 :       &kNaClDescXferableDataDescVtbl;
     148                 : 
     149               0 :   return retval;
     150               0 : }
     151                 : 
     152               0 : static void NaClDescXferableDataDescDtor(struct NaClRefCount *vself) {
     153                 :   vself->vtbl = (struct NaClRefCountVtbl const *)
     154               0 :       &kNaClDescImcConnectedDescVtbl;
     155               0 :   (*vself->vtbl->Dtor)(vself);
     156               0 : }
     157                 : 
     158                 : int NaClDescImcDescFstat(struct NaClDesc          *vself,
     159               0 :                          struct nacl_abi_stat     *statbuf) {
     160                 :   UNREFERENCED_PARAMETER(vself);
     161                 : 
     162               0 :   memset(statbuf, 0, sizeof *statbuf);
     163                 :   statbuf->nacl_abi_st_mode = (NACL_ABI_S_IFSOCK |
     164                 :                                NACL_ABI_S_IRUSR |
     165               0 :                                NACL_ABI_S_IWUSR);
     166               0 :   return 0;
     167               0 : }
     168                 : 
     169                 : static int NaClDescXferableDataDescFstat(struct NaClDesc          *vself,
     170               0 :                                          struct nacl_abi_stat     *statbuf) {
     171                 :   UNREFERENCED_PARAMETER(vself);
     172                 : 
     173               0 :   memset(statbuf, 0, sizeof *statbuf);
     174               0 :   statbuf->nacl_abi_st_mode = NACL_ABI_S_IFDSOCK;
     175               0 :   return 0;
     176               0 : }
     177                 : 
     178                 : static int NaClDescXferableDataDescExternalizeSize(struct NaClDesc  *vself,
     179                 :                                                    size_t           *nbytes,
     180               0 :                                                    size_t           *nhandles) {
     181                 :   int rv;
     182                 : 
     183                 :   UNREFERENCED_PARAMETER(vself);
     184               0 :   NaClLog(4, "Entered NaClDescXferableDataDescExternalizeSize\n");
     185               0 :   rv = NaClDescExternalizeSize(vself, nbytes, nhandles);
     186               0 :   if (0 != rv) {
     187               0 :     return rv;
     188                 :   }
     189               0 :   *nhandles += 1;
     190               0 :   return 0;
     191               0 : }
     192                 : 
     193                 : static int NaClDescXferableDataDescExternalize(struct NaClDesc          *vself,
     194               0 :                                                struct NaClDescXferState *xfer) {
     195                 :   struct NaClDescXferableDataDesc *self = ((struct NaClDescXferableDataDesc *)
     196               0 :                                            vself);
     197                 :   int rv;
     198                 : 
     199               0 :   NaClLog(4, "Entered NaClDescXferableDataDescExternalize\n");
     200               0 :   rv = NaClDescExternalize(vself, xfer);
     201               0 :   if (0 != rv) {
     202               0 :     return rv;
     203                 :   }
     204               0 :   *xfer->next_handle++ = self->base.h;
     205               0 :   return 0;
     206               0 : }
     207                 : 
     208                 : 
     209                 : /*
     210                 :  * In the level of NaClDescImcDescLowLevelSendMsg, we do not know what
     211                 :  * protocol is implemented by NaClSendDatagram (and indeed, in the
     212                 :  * Windows implementation, the access rights transfer involves a more
     213                 :  * complex protocol to get the peer process id).  Because the
     214                 :  * underlying low-level IMC implementation does not provide thread
     215                 :  * safety, this is the source of race conditions: two simultaneous
     216                 :  * imc_sendmsg syscalls to the same descriptor could get their various
     217                 :  * protcol bits interleaved, so the receiver will get garbled data
     218                 :  * that cause the wrong underlying host OS descriptor to be made
     219                 :  * available to the NaCl module.
     220                 :  *
     221                 :  * In order to address this issue, we (1) make descriptors that can
     222                 :  * transfer other descriptors non-transferable, and (2) we use locking
     223                 :  * so that only one thread can be performing (the low level bits of)
     224                 :  * imc_msgsend at a time.  The non-transferability of such descriptors
     225                 :  * addresses the multi-module scenario, as opposed to the
     226                 :  * multi-threaded scenario, where a sender race cause receiver
     227                 :  * confusion.
     228                 :  */
     229                 : static ssize_t NaClDescImcDescLowLevelSendMsg(
     230                 :     struct NaClDesc                *vself,
     231                 :     struct NaClMessageHeader const *dgram,
     232               4 :     int                            flags) {
     233                 :   struct NaClDescImcDesc *self = ((struct NaClDescImcDesc *)
     234               4 :                                   vself);
     235                 :   int result;
     236                 : 
     237               4 :   NaClXMutexLock(&self->sendmsg_mu);
     238               4 :   result = NaClSendDatagram(self->base.h, dgram, flags);
     239               4 :   NaClXMutexUnlock(&self->sendmsg_mu);
     240                 : 
     241               4 :   if (-1 == result) {
     242                 : #if NACL_WINDOWS
     243               0 :     return -NaClXlateSystemError(GetLastError());
     244                 : #elif NACL_LINUX || NACL_OSX
     245                 :     return -NaClXlateErrno(errno);
     246                 : #else
     247                 : # error "Unknown target platform: cannot translate error code(s) from SendMsg"
     248                 : #endif
     249                 :   }
     250               4 :   return result;
     251               4 : }
     252                 : 
     253                 : 
     254                 : /*
     255                 :  * NaClDescXferableDataDescLowLevelSendMsg implements imc_sendmsg For
     256                 :  * data-only descriptors.  We assume that whatever protocol exists at
     257                 :  * the NaClSendDatagram level is still not thread safe, but that the
     258                 :  * lack of thread safety will not have a significant impact on
     259                 :  * security.  This is still somewhat brittle: the low-level Windows
     260                 :  * IMC code can be convinced to do the wrong thing still via sender
     261                 :  * races, but the receiver, because it expects zero handles, will have
     262                 :  * called ReceiveDatagram in such a way that any "received handles"
     263                 :  * are closed.  This implies that arbitrary Windows handles can be
     264                 :  * made to be closed, including those not accessible by NaCl modules,
     265                 :  * but fortunately this should only result in a denial of service as
     266                 :  * the error caused by the use of an invalid handle is detected by the
     267                 :  * service runtime and cause an abort.
     268                 :  *
     269                 :  * Note that it is still an application error to send or receive data
     270                 :  * with a transferable data-only descriptor from two threads (or two
     271                 :  * modules) simultaneously.
     272                 :  */
     273                 : static ssize_t
     274                 : NaClDescXferableDataDescLowLevelSendMsg(struct NaClDesc                *vself,
     275                 :                                         struct NaClMessageHeader const *dgram,
     276               0 :                                         int                            flags) {
     277                 :   struct NaClDescXferableDataDesc *self = ((struct NaClDescXferableDataDesc *)
     278               0 :                                            vself);
     279                 :   int result;
     280                 : 
     281               0 :   if (0 != dgram->handle_count) {
     282                 :     /*
     283                 :      * A transferable descriptor cannot be used to transfer other
     284                 :      * descriptors.
     285                 :      */
     286                 :     NaClLog(2,
     287                 :             ("NaClDescXferableDataDescLowLevelSendMsg: tranferable and"
     288               0 :              " non-zero handle_count\n"));
     289               0 :     return -NACL_ABI_EINVAL;
     290                 :   }
     291                 : 
     292               0 :   result = NaClSendDatagram(self->base.h, dgram, flags);
     293                 : 
     294               0 :   if (-1 == result) {
     295                 : #if NACL_WINDOWS
     296               0 :     return -NaClXlateSystemError(GetLastError());
     297                 : #elif NACL_LINUX || NACL_OSX
     298                 :     return -NaClXlateErrno(errno);
     299                 : #else
     300                 : # error "Unknown target platform: cannot translate error code(s) from SendMsg"
     301                 : #endif
     302                 :   }
     303               0 :   return result;
     304               0 : }
     305                 : 
     306                 : 
     307                 : /*
     308                 :  * See discussion at NaClDescImcDescLowLevelSendMsg for details.  An
     309                 :  * imc_recvmsg race is not substantively different from an imc_sendmsg
     310                 :  * race.
     311                 :  */
     312                 : static ssize_t NaClDescImcDescLowLevelRecvMsg(struct NaClDesc          *vself,
     313                 :                                               struct NaClMessageHeader *dgram,
     314               4 :                                               int                      flags) {
     315                 :   struct NaClDescImcDesc *self = ((struct NaClDescImcDesc *)
     316               4 :                                   vself);
     317                 :   int result;
     318                 : 
     319               4 :   NaClLog(4, "Entered NaClDescImcDescLowLevelRecvMsg, h=%d\n", self->base.h);
     320               4 :   NaClXMutexLock(&self->recvmsg_mu);
     321               4 :   result = NaClReceiveDatagram(self->base.h, dgram, flags);
     322               4 :   NaClXMutexUnlock(&self->recvmsg_mu);
     323                 : 
     324               4 :   if (-1 == result) {
     325                 : #if NACL_WINDOWS
     326               2 :     return -NaClXlateSystemError(GetLastError());
     327                 : #elif NACL_LINUX || NACL_OSX
     328                 :     return -errno;
     329                 : #else
     330                 : # error "Unknown target platform: cannot translate error code(s) from RecvMsg"
     331                 : #endif
     332                 :   }
     333               4 :   return result;
     334               4 : }
     335                 : 
     336                 : 
     337                 : /*
     338                 :  * See discussion at NaClDescXferableDataDescLowLevelSendMsg for details.  An
     339                 :  * imc_recvmsg race is not substantively different from an imc_sendmsg
     340                 :  * race.
     341                 :  */
     342                 : static ssize_t NaClDescXferableDataDescLowLevelRecvMsg(
     343                 :     struct NaClDesc          *vself,
     344                 :     struct NaClMessageHeader *dgram,
     345               0 :     int                      flags) {
     346                 :   struct NaClDescXferableDataDesc *self = ((struct NaClDescXferableDataDesc *)
     347               0 :                                            vself);
     348                 :   int                             result;
     349                 : 
     350                 :   NaClLog(4, "Entered NaClDescXferableDataDescLowLevelRecvMsg, h = %d\n",
     351               0 :           self->base.h);
     352               0 :   if (0 != dgram->handle_count) {
     353                 :     /*
     354                 :      * A transferable descriptor is data-only, and it is an error to
     355                 :      * try to receive any I/O descriptors with it.
     356                 :      */
     357                 :     NaClLog(2,
     358                 :             "NaClDescXferableDataDescLowLevelRecvMsg:"
     359               0 :             " tranferable and non-zero handle_count\n");
     360               0 :     return -NACL_ABI_EINVAL;
     361                 :   }
     362                 : 
     363               0 :   result = NaClReceiveDatagram(self->base.h, dgram, flags);
     364                 : 
     365               0 :   if (-1 == result) {
     366                 : #if NACL_WINDOWS
     367               0 :     return -NaClXlateSystemError(GetLastError());
     368                 : #elif NACL_LINUX || NACL_OSX
     369                 :     return -errno;
     370                 : #else
     371                 : # error "Unknown target platform: cannot translate error code(s) from RecvMsg"
     372                 : #endif
     373                 :   }
     374               0 :   return result;
     375               0 : }
     376                 : 
     377                 : 
     378                 : static struct NaClDescVtbl const kNaClDescImcConnectedDescVtbl = {
     379                 :   {
     380                 :     NaClDescImcConnectedDescDtor,
     381                 :   },
     382                 :   NaClDescMapNotImplemented,
     383                 :   NACL_DESC_UNMAP_NOT_IMPLEMENTED
     384                 :   NaClDescReadNotImplemented,
     385                 :   NaClDescWriteNotImplemented,
     386                 :   NaClDescSeekNotImplemented,
     387                 :   NaClDescPReadNotImplemented,
     388                 :   NaClDescPWriteNotImplemented,
     389                 :   NaClDescFstatNotImplemented,
     390                 :   NaClDescGetdentsNotImplemented,
     391                 :   NaClDescExternalizeSizeNotImplemented,
     392                 :   NaClDescExternalizeNotImplemented,
     393                 :   NaClDescLockNotImplemented,
     394                 :   NaClDescTryLockNotImplemented,
     395                 :   NaClDescUnlockNotImplemented,
     396                 :   NaClDescWaitNotImplemented,
     397                 :   NaClDescTimedWaitAbsNotImplemented,
     398                 :   NaClDescSignalNotImplemented,
     399                 :   NaClDescBroadcastNotImplemented,
     400                 :   NaClDescSendMsgNotImplemented,
     401                 :   NaClDescRecvMsgNotImplemented,
     402                 :   NaClDescLowLevelSendMsgNotImplemented,
     403                 :   NaClDescLowLevelRecvMsgNotImplemented,
     404                 :   NaClDescConnectAddrNotImplemented,
     405                 :   NaClDescAcceptConnNotImplemented,
     406                 :   NaClDescPostNotImplemented,
     407                 :   NaClDescSemWaitNotImplemented,
     408                 :   NaClDescGetValueNotImplemented,
     409                 :   NaClDescSetMetadata,
     410                 :   NaClDescGetMetadata,
     411                 :   NaClDescSetFlags,
     412                 :   NaClDescGetFlags,
     413                 :   NaClDescIsattyNotImplemented,
     414                 :   NACL_DESC_CONNECTED_SOCKET,
     415                 : };
     416                 : 
     417                 : 
     418                 : static struct NaClDescVtbl const kNaClDescImcDescVtbl = {
     419                 :   {
     420                 :     NaClDescImcDescDtor,  /* diff */
     421                 :   },
     422                 :   NaClDescMapNotImplemented,
     423                 :   NACL_DESC_UNMAP_NOT_IMPLEMENTED
     424                 :   NaClDescReadNotImplemented,
     425                 :   NaClDescWriteNotImplemented,
     426                 :   NaClDescSeekNotImplemented,
     427                 :   NaClDescPReadNotImplemented,
     428                 :   NaClDescPWriteNotImplemented,
     429                 :   NaClDescImcDescFstat,  /* diff */
     430                 :   NaClDescGetdentsNotImplemented,
     431                 :   NaClDescExternalizeSizeNotImplemented,
     432                 :   NaClDescExternalizeNotImplemented,
     433                 :   NaClDescLockNotImplemented,
     434                 :   NaClDescTryLockNotImplemented,
     435                 :   NaClDescUnlockNotImplemented,
     436                 :   NaClDescWaitNotImplemented,
     437                 :   NaClDescTimedWaitAbsNotImplemented,
     438                 :   NaClDescSignalNotImplemented,
     439                 :   NaClDescBroadcastNotImplemented,
     440                 :   NaClImcSendTypedMessage,  /* diff */
     441                 :   NaClImcRecvTypedMessage,  /* diff */
     442                 :   NaClDescImcDescLowLevelSendMsg,  /* diff */
     443                 :   NaClDescImcDescLowLevelRecvMsg,  /* diff */
     444                 :   NaClDescConnectAddrNotImplemented,
     445                 :   NaClDescAcceptConnNotImplemented,
     446                 :   NaClDescPostNotImplemented,
     447                 :   NaClDescSemWaitNotImplemented,
     448                 :   NaClDescGetValueNotImplemented,
     449                 :   NaClDescSetMetadata,
     450                 :   NaClDescGetMetadata,
     451                 :   NaClDescSetFlags,
     452                 :   NaClDescGetFlags,
     453                 :   NaClDescIsattyNotImplemented,
     454                 :   NACL_DESC_IMC_SOCKET,  /* diff */
     455                 : };
     456                 : 
     457                 : 
     458                 : static struct NaClDescVtbl const kNaClDescXferableDataDescVtbl = {
     459                 :   {
     460                 :     NaClDescXferableDataDescDtor,  /* diff */
     461                 :   },
     462                 :   NaClDescMapNotImplemented,
     463                 :   NACL_DESC_UNMAP_NOT_IMPLEMENTED
     464                 :   NaClDescReadNotImplemented,
     465                 :   NaClDescWriteNotImplemented,
     466                 :   NaClDescSeekNotImplemented,
     467                 :   NaClDescPReadNotImplemented,
     468                 :   NaClDescPWriteNotImplemented,
     469                 :   NaClDescXferableDataDescFstat,  /* diff */
     470                 :   NaClDescGetdentsNotImplemented,
     471                 :   NaClDescXferableDataDescExternalizeSize,  /* diff */
     472                 :   NaClDescXferableDataDescExternalize,  /* diff */
     473                 :   NaClDescLockNotImplemented,
     474                 :   NaClDescTryLockNotImplemented,
     475                 :   NaClDescUnlockNotImplemented,
     476                 :   NaClDescWaitNotImplemented,
     477                 :   NaClDescTimedWaitAbsNotImplemented,
     478                 :   NaClDescSignalNotImplemented,
     479                 :   NaClDescBroadcastNotImplemented,
     480                 :   NaClImcSendTypedMessage,  /* diff */
     481                 :   NaClImcRecvTypedMessage,  /* diff */
     482                 :   NaClDescXferableDataDescLowLevelSendMsg,  /* diff */
     483                 :   NaClDescXferableDataDescLowLevelRecvMsg,  /* diff */
     484                 :   NaClDescConnectAddrNotImplemented,
     485                 :   NaClDescAcceptConnNotImplemented,
     486                 :   NaClDescPostNotImplemented,
     487                 :   NaClDescSemWaitNotImplemented,
     488                 :   NaClDescGetValueNotImplemented,
     489                 :   NaClDescSetMetadata,
     490                 :   NaClDescGetMetadata,
     491                 :   NaClDescSetFlags,
     492                 :   NaClDescGetFlags,
     493                 :   NaClDescIsattyNotImplemented,
     494                 :   NACL_DESC_TRANSFERABLE_DATA_SOCKET,  /* diff */
     495                 : };
     496                 : 
     497                 : 
     498                 : int NaClDescXferableDataDescInternalize(
     499                 :     struct NaClDesc               **baseptr,
     500                 :     struct NaClDescXferState      *xfer,
     501               0 :     struct NaClDescQuotaInterface *quota_interface) {
     502                 :   int                             rv;
     503                 :   struct NaClDescXferableDataDesc *ndxdp;
     504                 : 
     505                 :   UNREFERENCED_PARAMETER(quota_interface);
     506               0 :   NaClLog(4, "Entered NaClDescXferableDataDescInternalize\n");
     507                 : 
     508               0 :   ndxdp = malloc(sizeof *ndxdp);
     509               0 :   if (NULL == ndxdp) {
     510                 :     NaClLog(LOG_ERROR,
     511               0 :             "NaClXferableDataDescInternalize: no memory\n");
     512               0 :     rv = -NACL_ABI_ENOMEM;
     513               0 :     goto cleanup;
     514                 :   }
     515               0 :   rv = NaClDescInternalizeCtor((struct NaClDesc *) ndxdp, xfer);
     516               0 :   if (!rv) {
     517               0 :     free(ndxdp);
     518               0 :     ndxdp = NULL;
     519               0 :     goto cleanup;
     520                 :   }
     521                 : 
     522               0 :   if (xfer->next_handle == xfer->handle_buffer_end) {
     523                 :     NaClLog(LOG_ERROR,
     524                 :             ("NaClXferableDataDescInternalize: no descriptor"
     525               0 :              " left in xfer state\n"));
     526               0 :     rv = -NACL_ABI_EIO;
     527               0 :     goto cleanup;
     528                 :   }
     529                 :   if (!NaClDescXferableDataDescSubclassesCtor(ndxdp,
     530               0 :                                               *xfer->next_handle)) {
     531                 :     NaClLog(LOG_ERROR,
     532               0 :             "NaClXferableDataDescInternalize: descriptor ctor error\n");
     533               0 :     rv = -NACL_ABI_EIO;
     534               0 :     goto cleanup;
     535                 :   }
     536               0 :   *xfer->next_handle++ = NACL_INVALID_HANDLE;
     537               0 :   *baseptr = (struct NaClDesc *) ndxdp;
     538               0 :   rv = 0;
     539                 : 
     540                 : cleanup:
     541               0 :   if (rv < 0) {
     542               0 :     NaClDescSafeUnref((struct NaClDesc *) ndxdp);
     543                 :   }
     544               0 :   return rv;
     545               0 : }

Generated by: LCOV version 1.7