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 #ifndef NATIVE_CLIENT_SRC_TRUSTED_DESC_NACL_DESC_BASE_H_
12 #define NATIVE_CLIENT_SRC_TRUSTED_DESC_NACL_DESC_BASE_H_
13 
14 #include <limits.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 
18 #include "native_client/src/include/build_config.h"
19 #include "native_client/src/include/nacl_base.h"
20 #include "native_client/src/include/portability.h"
21 
22 #include "native_client/src/public/nacl_desc.h"
23 
24 /* For NaClHandle */
25 #include "native_client/src/shared/imc/nacl_imc_c.h"
26 
27 /* for nacl_off64_t */
28 #include "native_client/src/shared/platform/nacl_host_desc.h"
29 #include "native_client/src/shared/platform/nacl_sync.h"
30 
31 #include "native_client/src/trusted/desc/desc_metadata_types.h"
32 #include "native_client/src/trusted/nacl_base/nacl_refcount.h"
33 
34 EXTERN_C_BEGIN
35 
36 struct NaClDesc;
37 struct nacl_abi_stat;
38 struct nacl_abi_timespec;
39 struct NaClDescEffector;
40 struct NaClImcTypedMsgHdr;
41 struct NaClMessageHeader;
42 
43 /*
44  * Externalization / internalization state, used by
45  * Externalize/Internalize functions.  Externalize convert the
46  * descriptor represented by the self (this) object to an entry in the
47  * handles table in a NaClMessageHeader, and the Internalize function
48  * is a factory that takes a dgram and NaClDescXferState and
49  * constructs a vector of NaClDesc objects.
50  *
51  * This is essentially a pair of input/output iterators.  The *_end
52  * values are not needed during externalization, since the SendMsg
53  * code will have queried ExternalizeSize to ensure that there is
54  * enough space.  During internalization, however, we try to be more
55  * paranoid and check that we do not overrun our buffers.
56  *
57  * NB: we must assume that the NaClHandle values passed are the right
58  * type; if not, it is possible to violate invariant properties
59  * required by the various subclasses of NaClDesc.
60  */
61 struct NaClDescXferState {
62   /*
63    * In/out value, used for both serialization and deserialization.
64    * The Externalize method read/write type tags that are part of the
65    * message header as well as data-based capabilities in a
66    * self-describing format.
67    */
68   char        *next_byte;
69   char        *byte_buffer_end;
70 
71   /*
72    * In/out value.  Next handle to work on.
73    */
74   NaClHandle  *next_handle;
75   NaClHandle  *handle_buffer_end;
76 };
77 
78 enum NaClDescTypeTag {
79   NACL_DESC_INVALID,
80   NACL_DESC_DIR,
81   NACL_DESC_HOST_IO,
82   NACL_DESC_CONN_CAP,
83   NACL_DESC_CONN_CAP_FD,
84   NACL_DESC_BOUND_SOCKET,
85   NACL_DESC_CONNECTED_SOCKET,
86   NACL_DESC_SHM,
87   NACL_DESC_SHM_MACH,
88   NACL_DESC_MUTEX,
89   NACL_DESC_CONDVAR,
90   NACL_DESC_SEMAPHORE,
91   NACL_DESC_SYNC_SOCKET,
92   NACL_DESC_TRANSFERABLE_DATA_SOCKET,
93   NACL_DESC_IMC_SOCKET,
94   NACL_DESC_QUOTA,
95   NACL_DESC_CUSTOM,
96   NACL_DESC_NULL
97   /*
98    * Add new NaClDesc subclasses here.
99    *
100    * NB: when we add new tag types, NaClDescInternalize[] **MUST**
101    * also be updated to add new internalization functions.
102    */
103 };
104 #define NACL_DESC_TYPE_MAX      (NACL_DESC_NULL + 1)
105 #define NACL_DESC_TYPE_END_TAG  (0xff)
106 
107 struct NaClInternalRealHeader {
108   uint32_t  xfer_protocol_version;
109   uint32_t  descriptor_data_bytes;
110 };
111 
112 struct NaClInternalHeader {
113   struct NaClInternalRealHeader h;
114   /*
115    * We add 0x10 here because pad must have at least one element.
116    * This unfortunately also means that if NaClInternalRealHeader is
117    * already a multiple of 16 in size, we will add in an unnecessary
118    * 16-byte pad.  The preprocessor does not have access to sizeof
119    * information, so we cannot just get rid of the pad.
120    */
121   char      pad[((sizeof(struct NaClInternalRealHeader) + 0x10) & ~0xf)
122                 - sizeof(struct NaClInternalRealHeader)];
123   /* total size is a multiple of 16 bytes */
124 };
125 
126 #define NACL_HANDLE_TRANSFER_PROTOCOL 0xd3c0de01
127 /* incr from here */
128 
129 /*
130  * Array of function pointers, indexed by NaClDescTypeTag, any one of
131  * which will extract an externalized representation of the NaClDesc
132  * subclass object from the message, as referenced via
133  * NaClDescXferState, and when successful return the internalized
134  * representation -- a newl created NaClDesc subclass object -- to the
135  * caller via an out parameter.  Returns 0 on success, negative errno
136  * value on failure.
137  *
138  * NB: we should have atomic failures.  The caller is expected to
139  * allocate an array of NaClDesc pointers, and insert into the open
140  * file table of the receiving NaClApp (via the NaClDescEffector
141  * interface) only when all internalizations succeed.  Since even the
142  * insertion can fail, the caller must keep track of the descriptor
143  * numbers in case it has to back out and report that the message is
144  * dropped.
145  *
146  * Also, when the NaClDesc object is constructed, the NaClHandle
147  * consumed (from the NaClDescXferState) MUST BE replaced with
148  * NACL_INVALID_HANDLE.
149  */
150 extern int
151 (*NaClDescInternalize[NACL_DESC_TYPE_MAX])(struct NaClDesc **,
152                                            struct NaClDescXferState *);
153 
154 extern char const *NaClDescTypeString(enum NaClDescTypeTag type_tag);
155 
156 /*
157  * The virtual function table for NaClDesc and its subclasses.
158  *
159  * This interface will change when non-blocking I/O and epoll is
160  * added.
161  */
162 
163 struct NaClDescVtbl {
164   struct NaClRefCountVtbl vbase;
165 
166   /*
167    * Essentially mmap.  Note that untrusted code should always use
168    * NACL_ABI_MAP_FIXED, sice NaClDesc object have no idea where the
169    * untrusted NaCl module's address space is located.  When non-fixed
170    * mapping is used (by trusted code), the Map virtual function uses
171    * an address space hole algorithm that may be subject to race
172    * between two threads, and may thus fail.  In all cases, if
173    * successful, the memory mapping may be unmapped at
174    * NACL_MAP_PAGESIZE granularities.  (Trusted code should use
175    * UnmapUnsafe, since refilling the unmapped address space with
176    * inaccessible memory is probably not desirable.)
177    */
178   uintptr_t (*Map)(struct NaClDesc          *vself,
179                    struct NaClDescEffector  *effp,
180                    void                     *start_addr,
181                    size_t                   len,
182                    int                      prot,
183                    int                      flags,
184                    nacl_off64_t             offset) NACL_WUR;
185 
186   ssize_t (*Read)(struct NaClDesc *vself,
187                   void            *buf,
188                   size_t          len) NACL_WUR;
189 
190   ssize_t (*Write)(struct NaClDesc  *vself,
191                    void const       *buf,
192                    size_t           len) NACL_WUR;
193 
194   nacl_off64_t (*Seek)(struct NaClDesc  *vself,
195                        nacl_off64_t     offset,
196                        int              whence) NACL_WUR;
197 
198   ssize_t (*PRead)(struct NaClDesc *vself,
199                    void *buf,
200                    size_t len,
201                    nacl_off64_t offset) NACL_WUR;
202 
203   ssize_t (*PWrite)(struct NaClDesc *vself,
204                     void const *buf,
205                     size_t len,
206                     nacl_off64_t offset) NACL_WUR;
207 
208   int (*Fstat)(struct NaClDesc      *vself,
209                struct nacl_abi_stat *statbuf);
210 
211   int (*Fchdir)(struct NaClDesc *vself) NACL_WUR;
212 
213   int (*Fchmod)(struct NaClDesc *vself,
214                 int             mode) NACL_WUR;
215 
216   int (*Fsync)(struct NaClDesc *vself) NACL_WUR;
217 
218   int (*Fdatasync)(struct NaClDesc *vself) NACL_WUR;
219 
220   int (*Ftruncate)(struct NaClDesc  *vself,
221                    nacl_abi_off_t   length) NACL_WUR;
222 
223   /*
224    * Directory access support.  Directories require support for getdents.
225    */
226   ssize_t (*Getdents)(struct NaClDesc *vself,
227                       void            *dirp,
228                       size_t          count) NACL_WUR;
229 
230   /*
231    * Externalization queries this for how many data bytes and how many
232    * handles are needed to transfer the "this" or "self" descriptor
233    * via IMC.  If the descriptor is not transferrable, this should
234    * return -NACL_ABI_EINVAL.  Success is indicated by 0, and other
235    * kinds of failure should be the usual negative errno.  Should
236    * never have to put the calling thread to sleep or otherwise
237    * manipulate thread or process state.
238    *
239    * The nbytes returned do not include any kind of type tag.  The
240    * type tag overhead is computed by the MsgSend code, since tagging
241    * format need not be known by the per-descriptor externalization
242    * code.
243    */
244   int (*ExternalizeSize)(struct NaClDesc  *vself,
245                          size_t           *nbytes,
246                          size_t           *nhandles) NACL_WUR;
247 
248   /*
249    * Externalize the "this" or "self" descriptor: this will take an
250    * IMC datagram object to which the Nrd will be appended, either as
251    * special control data or as a descriptor/handle to be passed to
252    * the recipient.  Should never have to put the calling thread to
253    * sleep or otherwise manipulate thread or process state.
254    */
255   int (*Externalize)(struct NaClDesc          *vself,
256                      struct NaClDescXferState *xfer) NACL_WUR;
257 
258   /*
259    * Lock and similar syscalls cannot just indefintely block,
260    * since address space move will require that all other threads are
261    * stopped and in a known
262    */
263   int (*Lock)(struct NaClDesc *vself) NACL_WUR;
264 
265   int (*TryLock)(struct NaClDesc  *vself) NACL_WUR;
266 
267   int (*Unlock)(struct NaClDesc *vself) NACL_WUR;
268 
269   int (*Wait)(struct NaClDesc *vself,
270               struct NaClDesc *mutex) NACL_WUR;
271 
272   int (*TimedWaitAbs)(struct NaClDesc                *vself,
273                       struct NaClDesc                *mutex,
274                       struct nacl_abi_timespec const *ts) NACL_WUR;
275 
276   int (*Signal)(struct NaClDesc *vself) NACL_WUR;
277 
278   int (*Broadcast)(struct NaClDesc  *vself) NACL_WUR;
279 
280   ssize_t (*SendMsg)(struct NaClDesc                 *vself,
281                      const struct NaClImcTypedMsgHdr *nitmhp,
282                      int                             flags) NACL_WUR;
283 
284   ssize_t (*RecvMsg)(struct NaClDesc               *vself,
285                      struct NaClImcTypedMsgHdr     *nitmhp,
286                      int                           flags) NACL_WUR;
287 
288   ssize_t (*LowLevelSendMsg)(struct NaClDesc                *vself,
289                              struct NaClMessageHeader const *dgram,
290                              int                            flags) NACL_WUR;
291 
292   ssize_t (*LowLevelRecvMsg)(struct NaClDesc          *vself,
293                              struct NaClMessageHeader *dgram,
294                              int                      flags) NACL_WUR;
295 
296   /*
297    * ConnectAddr() and AcceptConn():
298    * On success, returns 0 and a descriptor via *result.
299    * On error, returns a negative errno value.
300    */
301   int (*ConnectAddr)(struct NaClDesc  *vself,
302                      struct NaClDesc  **result) NACL_WUR;
303 
304   int (*AcceptConn)(struct NaClDesc *vself,
305                     struct NaClDesc **result) NACL_WUR;
306 
307   int (*Post)(struct NaClDesc *vself) NACL_WUR;
308 
309   int (*SemWait)(struct NaClDesc  *vself) NACL_WUR;
310 
311   int (*GetValue)(struct NaClDesc *vself) NACL_WUR;
312 
313   /*
314    * Descriptor attributes setters and getters.  These are virtual
315    * functions because the NaClDescQuota subclass wraps other NaClDesc
316    * subclasses, and the quota descriptors should not have attributes
317    * separate from that of the wrapped descriptor -- the
318    * setters/getters of the NaClDescQuota just use the corresponding
319    * methods of the wrapped descriptor.
320    */
321 
322   /*
323    * Save a copy of the |metadata_size| bytes located at |metadata|
324    * with the descriptor |self|.  The |metadata_type| argument should
325    * be a non-negative integer and should be unique for each use of
326    * the metadata interface.  Only one set of metadata may be saved
327    * with a descriptor, and it is an error to try to set metadata on a
328    * descriptor which already has metadata.
329    *
330    * Syscall-style function: returns 0 for success and negated errno
331    * (-NACL_ABI_ENOMEM if memory allocation for making a copy of the
332    * metadata fails, -NACL_ABI_EPERM if metadata already set,
333    * -NACL_ABI_EINVAL of metadata_type is negative).
334    */
335   int (*SetMetadata)(struct NaClDesc *self,
336                      int32_t metadata_type,
337                      uint32_t metadata_num_bytes,
338                      uint8_t const *metadata_bytes) NACL_WUR;
339 
340   /*
341    * GetMetadata writes at most |*metadata_buffer_num_bytes_in_out|
342    * bytes of the metadata associated with the descriptor using
343    * SetMetaData to the buffer located at |metadata_buffer|.  It
344    * returns the metadata_type associated with the descriptor.  On
345    * return, the value at |*metadata_buffer_num_bytes_in_out| contains
346    * the total number of bytes that would be written if there were no
347    * size limit, i.e., the actual number of bytes written if the
348    * buffer was large enough, or the number of bytes that would have
349    * been written if the buffer were not.  Thus, on return, if the
350    * value is less than or equal to the original value at
351    * |*metadata_buffer_num_bytes_in_out|, the contents of
352    * |metadata_buffer| contains all of the metadata.
353    *
354    * To query the size of the metadata without doing any copying, call
355    * GetMetadata with |*metadata_buffer_num_bytes_in_out| equal to
356    * zero, in which case |metadata_buffer| can be NULL.
357    *
358    * Callers should always check the return value of GetMetadata to
359    * ensure that the metadata_type is the expected value.  If the type
360    * is wrong, do not process the metadata -- treat the descriptor as
361    * if it has no metadata.  To do otherwise would expose us to type
362    * confusion attacks.
363    *
364    * Returns NACL_DESC_METADATA_NONE_TYPE if no metadata is associated
365    * with the descriptor.
366    */
367   int32_t (*GetMetadata)(struct NaClDesc *self,
368                          uint32_t *metadata_buffer_num_bytes_in_out,
369                          uint8_t *metadata_buffer) NACL_WUR;
370 
371 
372   void (*SetFlags)(struct NaClDesc *self,
373                    uint32_t flags);
374 
375   uint32_t (*GetFlags)(struct NaClDesc *self);
376 
377   int32_t (*Isatty)(struct NaClDesc *self);
378 
379   /*
380    * Inappropriate methods for the subclass will just return
381    * -NACL_ABI_EINVAL.
382    */
383 
384   /*
385    * typeTag is one of the enumeration values from NaClDescTypeTag.
386    *
387    * This is not a class variable, since one must access it through an
388    * instance.  Having a value in the vtable is not allowed in C++;
389    * instead, we would implement this as a const virtual function that
390    * returns the type tag, or RTTI which would typically be done via
391    * examining the vtable pointer.  This is potentially cheaper, since
392    * one could choose bit patterns for the type tags that make
393    * subclass relationships easier to compute (we don't do this, since
394    * we only ever need exact type checks).
395    *
396    * We put this at the end of the vtable so that when we add new
397    * virtual functions above it, we are guaranteed to get a type
398    * mismatch if any subclass implemention did not have its vtable
399    * properly extended -- even when -Wmissing-field-initializers was
400    * omitted.
401    */
402   enum NaClDescTypeTag typeTag;
403 };
404 
405 struct NaClDesc {
406   struct NaClRefCount base NACL_IS_REFCOUNT_SUBCLASS;
407   uint32_t flags;
408 
409   /* "public" flags -- settable by users of NaClDesc interface */
410 
411   /*
412    * It is okay to try to use this descriptor with PROT_EXEC in mmap.
413    * This is just a hint to the service runtime to try direct mmap --
414    * the validator cache can still disallow the operation.
415    */
416 #define NACL_DESC_FLAGS_MMAP_EXEC_OK 0x1000
417 
418   /* private flags -- used internally by NaClDesc */
419 #define NACL_DESC_FLAGS_PUBLIC_MASK 0xffff
420 
421 #define NACL_DESC_FLAGS_HAS_METADATA 0x10000
422   /*
423    * We could have used two uint16_t variables too, but that just
424    * makes the serialization (externalization) and deserialization
425    * (internalization) more complex; here, only the SetFlags and
426    * GetFlags need to be messy.
427    *
428    * We do not encode the presence of metadata using metadata type, so
429    * we do not have to transfer the 4 type bytes when metadata is
430    * absent.  Since the interface only allows setting the metadata
431    * once, we don't worry about
432    */
433   int32_t metadata_type;
434   uint32_t metadata_num_bytes;
435   uint8_t *metadata;
436 };
437 
438 /*
439  * Placement new style ctor; creates w/ ref_count of 1.
440  *
441  * The subclasses' ctor must call this base class ctor during their
442  * contruction.
443  */
444 int NaClDescCtor(struct NaClDesc *ndp) NACL_WUR;
445 
446 extern struct NaClDescVtbl const kNaClDescVtbl;
447 
448 /*
449  * NaClDescSafeUnref is just like NaCDescUnref, except that ndp may be
450  * NULL (in which case this is a noop).
451  *
452  * Used in failure cleanup of initialization code, esp in Ctors that
453  * can fail.
454  */
455 void NaClDescSafeUnref(struct NaClDesc *ndp);
456 
457 /*
458  * USE THE VIRTUAL FUNCTION.  THIS DECLARATION IS FOR SUBCLASSES.
459  */
460 int NaClDescSetMetadata(struct NaClDesc *self,
461                         int32_t metadata_type,
462                         uint32_t metadata_num_bytes,
463                         uint8_t const *metadata_bytes) NACL_WUR;
464 
465 /*
466  * USE THE VIRTUAL FUNCTION.  THIS DECLARATION IS FOR SUBCLASSES.
467  */
468 int32_t NaClDescGetMetadata(struct NaClDesc *self,
469                             uint32_t *metadata_buffer_num_bytes_in_out,
470                             uint8_t *metadata_buffer) NACL_WUR;
471 
472 /*
473  * USE THE VIRTUAL FUNCTION.  THIS DECLARATION IS FOR SUBCLASSES.
474  */
475 void NaClDescSetFlags(struct NaClDesc *self,
476                       uint32_t flags);
477 
478 /*
479  * USE THE VIRTUAL FUNCTION.  THIS DECLARATION IS FOR SUBCLASSES.
480  */
481 uint32_t NaClDescGetFlags(struct NaClDesc *self);
482 
483 int32_t NaClDescIsattyNotImplemented(struct NaClDesc *vself);
484 
485 /*
486  * Base class externalize functions; all subclass externalize
487  * functions should invoke these, up the class hierarchy, and add to
488  * the sizes or the NaClDescXferState.
489  */
490 int NaClDescExternalizeSize(struct NaClDesc *self,
491                             size_t *nbytes,
492                             size_t *nhandles);
493 
494 int NaClDescExternalize(struct NaClDesc *self,
495                         struct NaClDescXferState *xfer);
496 
497 /*
498  * The top level internalize interface are factories: they allocate
499  * space, then run the internalize-in-place ctor code.  Ideally, these
500  * would be two separate functions -- the memory allocation could, in
501  * most cases, be simplified to be simply an attribute containing the
502  * desired memory size and a generic allocator used, though of course
503  * we would like to permit subclasses that contains variable size
504  * arrays (at end of struct), etc.  For base (super) classes, the
505  * memory allocation is not necessary, since the subclass internalize
506  * function will have handled it.
507  */
508 int NaClDescInternalizeCtor(struct NaClDesc *vself,
509                             struct NaClDescXferState *xfer);
510 
511 
512 /*
513  * subclasses are in their own header files.
514  */
515 
516 
517 /* utility routines */
518 
519 int32_t NaClAbiStatHostDescStatXlateCtor(struct nacl_abi_stat    *dst,
520                                          nacl_host_stat_t const  *src);
521 
522 /*
523  * The following two functions are not part of the exported public
524  * API.
525  *
526  * Read/write to a NaClHandle, much like how read/write syscalls work.
527  */
528 ssize_t NaClDescReadFromHandle(NaClHandle handle,
529                                void       *buf,
530                                size_t     length);
531 
532 ssize_t NaClDescWriteToHandle(NaClHandle handle,
533                               void const *buf,
534                               size_t     length);
535 
536 /*
537  * Default functions for the vtable for when the functionality is
538  * inappropriate for the descriptor type -- they just return
539  * -NACL_ABI_EINVAL
540  */
541 void NaClDescDtorNotImplemented(struct NaClRefCount  *vself);
542 
543 uintptr_t NaClDescMapNotImplemented(struct NaClDesc         *vself,
544                                     struct NaClDescEffector *effp,
545                                     void                    *start_addr,
546                                     size_t                  len,
547                                     int                     prot,
548                                     int                     flags,
549                                     nacl_off64_t            offset);
550 
551 ssize_t NaClDescReadNotImplemented(struct NaClDesc  *vself,
552                                    void             *buf,
553                                    size_t           len);
554 
555 ssize_t NaClDescWriteNotImplemented(struct NaClDesc         *vself,
556                                     void const              *buf,
557                                     size_t                  len);
558 
559 nacl_off64_t NaClDescSeekNotImplemented(struct NaClDesc *vself,
560                                         nacl_off64_t    offset,
561                                         int             whence);
562 
563 ssize_t NaClDescPReadNotImplemented(struct NaClDesc *vself,
564                                     void *buf,
565                                     size_t len,
566                                     nacl_off64_t offset);
567 
568 ssize_t NaClDescPWriteNotImplemented(struct NaClDesc *vself,
569                                      void const *buf,
570                                      size_t len,
571                                      nacl_off64_t offset);
572 
573 int NaClDescFstatNotImplemented(struct NaClDesc       *vself,
574                                 struct nacl_abi_stat  *statbuf);
575 
576 int NaClDescFchdirNotImplemented(struct NaClDesc *vself);
577 
578 int NaClDescFchmodNotImplemented(struct NaClDesc *vself,
579                                  int             mode);
580 
581 int NaClDescFsyncNotImplemented(struct NaClDesc *vself);
582 
583 int NaClDescFdatasyncNotImplemented(struct NaClDesc *vself);
584 
585 int NaClDescFtruncateNotImplemented(struct NaClDesc  *vself,
586                                     nacl_abi_off_t   length);
587 
588 ssize_t NaClDescGetdentsNotImplemented(struct NaClDesc  *vself,
589                                        void             *dirp,
590                                        size_t           count);
591 
592 int NaClDescExternalizeSizeNotImplemented(struct NaClDesc *vself,
593                                           size_t          *nbytes,
594                                           size_t          *nhandles);
595 
596 int NaClDescExternalizeNotImplemented(struct NaClDesc          *vself,
597                                       struct NaClDescXferState *xfer);
598 
599 int NaClDescLockNotImplemented(struct NaClDesc  *vself);
600 
601 int NaClDescTryLockNotImplemented(struct NaClDesc *vself);
602 
603 int NaClDescUnlockNotImplemented(struct NaClDesc  *vself);
604 
605 int NaClDescWaitNotImplemented(struct NaClDesc  *vself,
606                                struct NaClDesc  *mutex);
607 
608 int NaClDescTimedWaitAbsNotImplemented(struct NaClDesc                *vself,
609                                        struct NaClDesc                *mutex,
610                                        struct nacl_abi_timespec const *ts);
611 
612 int NaClDescSignalNotImplemented(struct NaClDesc  *vself);
613 
614 int NaClDescBroadcastNotImplemented(struct NaClDesc *vself);
615 
616 ssize_t NaClDescSendMsgNotImplemented(
617     struct NaClDesc                 *vself,
618     const struct NaClImcTypedMsgHdr *nitmhp,
619     int                             flags);
620 
621 ssize_t NaClDescRecvMsgNotImplemented(
622     struct NaClDesc               *vself,
623     struct NaClImcTypedMsgHdr     *nitmhp,
624     int                           flags);
625 
626 ssize_t NaClDescLowLevelSendMsgNotImplemented(
627     struct NaClDesc                *vself,
628     struct NaClMessageHeader const *dgram,
629     int                            flags);
630 
631 ssize_t NaClDescLowLevelRecvMsgNotImplemented(
632     struct NaClDesc           *vself,
633     struct NaClMessageHeader  *dgram,
634     int                       flags);
635 
636 int NaClDescConnectAddrNotImplemented(struct NaClDesc *vself,
637                                       struct NaClDesc **out_desc);
638 
639 int NaClDescAcceptConnNotImplemented(struct NaClDesc  *vself,
640                                      struct NaClDesc  **out_desc);
641 
642 int NaClDescPostNotImplemented(struct NaClDesc  *vself);
643 
644 int NaClDescSemWaitNotImplemented(struct NaClDesc *vself);
645 
646 int NaClDescGetValueNotImplemented(struct NaClDesc  *vself);
647 
648 int NaClDescInternalizeNotImplemented(
649     struct NaClDesc                **out_desc,
650     struct NaClDescXferState       *xfer);
651 
652 
653 int NaClSafeCloseNaClHandle(NaClHandle h);
654 
655 int NaClDescIsSafeForMmap(struct NaClDesc *self);
656 
657 void NaClDescMarkSafeForMmap(struct NaClDesc *self);
658 
659 EXTERN_C_END
660 
661 #endif  // NATIVE_CLIENT_SRC_TRUSTED_DESC_NACL_DESC_BASE_H_
662