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. Directory descriptor abstraction.
9 : */
10 :
11 : #include "native_client/src/include/portability.h"
12 :
13 : #include <stdlib.h>
14 : #include <string.h>
15 :
16 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
17 : #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
18 :
19 : #include "native_client/src/shared/platform/nacl_log.h"
20 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
21 :
22 : #include "native_client/src/trusted/service_runtime/internal_errno.h"
23 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
24 :
25 : /*
26 : * Externalizing the invalid descriptor -- which shows up in untrusted
27 : * user code as -1 -- loses flags and metadata. No operations are
28 : * ever be allowed for the invalid descriptor (the vtable entries are
29 : * all *Unimplemented), so there is no opportunity for code to look at
30 : * flags/metadata.
31 : */
32 : static int NaClDescInvalidExternalizeSize(struct NaClDesc *vself,
33 : size_t *nbytes,
34 1 : size_t *nhandles) {
35 : UNREFERENCED_PARAMETER(vself);
36 1 : *nbytes = 0;
37 1 : *nhandles = 0;
38 1 : return 0;
39 1 : }
40 :
41 : static int NaClDescInvalidExternalize(struct NaClDesc *vself,
42 1 : struct NaClDescXferState *xfer) {
43 : UNREFERENCED_PARAMETER(vself);
44 : UNREFERENCED_PARAMETER(xfer);
45 1 : return 0;
46 1 : }
47 :
48 : /*
49 : * NaClDescInvalid is the subclass for the singleton invalid descriptor.
50 : */
51 :
52 : static struct NaClDescVtbl const kNaClDescInvalidVtbl = {
53 : {
54 : NaClDescDtorNotImplemented,
55 : },
56 : NaClDescMapNotImplemented,
57 : NACL_DESC_UNMAP_NOT_IMPLEMENTED
58 : NaClDescReadNotImplemented,
59 : NaClDescWriteNotImplemented,
60 : NaClDescSeekNotImplemented,
61 : NaClDescPReadNotImplemented,
62 : NaClDescPWriteNotImplemented,
63 : NaClDescFstatNotImplemented,
64 : NaClDescGetdentsNotImplemented,
65 : NaClDescInvalidExternalizeSize,
66 : NaClDescInvalidExternalize,
67 : NaClDescLockNotImplemented,
68 : NaClDescTryLockNotImplemented,
69 : NaClDescUnlockNotImplemented,
70 : NaClDescWaitNotImplemented,
71 : NaClDescTimedWaitAbsNotImplemented,
72 : NaClDescSignalNotImplemented,
73 : NaClDescBroadcastNotImplemented,
74 : NaClDescSendMsgNotImplemented,
75 : NaClDescRecvMsgNotImplemented,
76 : NaClDescLowLevelSendMsgNotImplemented,
77 : NaClDescLowLevelRecvMsgNotImplemented,
78 : NaClDescConnectAddrNotImplemented,
79 : NaClDescAcceptConnNotImplemented,
80 : NaClDescPostNotImplemented,
81 : NaClDescSemWaitNotImplemented,
82 : NaClDescGetValueNotImplemented,
83 : NaClDescSetMetadata,
84 : NaClDescGetMetadata,
85 : NaClDescSetFlags,
86 : NaClDescGetFlags,
87 : NaClDescIsattyNotImplemented,
88 : NACL_DESC_INVALID,
89 : };
90 :
91 : static struct NaClMutex *mutex = NULL;
92 : static struct NaClDescInvalid *singleton;
93 :
94 3 : void NaClDescInvalidInit(void) {
95 3 : mutex = (struct NaClMutex *) malloc(sizeof(*mutex));
96 3 : if (NULL == mutex) {
97 0 : NaClLog(LOG_FATAL, "Cannot allocate NaClDescInvalid mutex\n");
98 : }
99 3 : if (!NaClMutexCtor(mutex)) {
100 0 : free(mutex);
101 0 : mutex = NULL;
102 0 : NaClLog(LOG_FATAL, "Cannot construct NaClDescInvalid mutex\n");
103 : }
104 3 : }
105 :
106 0 : void NaClDescInvalidFini(void) {
107 0 : if (NULL != mutex) {
108 0 : NaClMutexDtor(mutex);
109 0 : free(mutex);
110 0 : mutex = NULL;
111 : }
112 0 : }
113 :
114 1 : struct NaClDescInvalid const *NaClDescInvalidMake(void) {
115 1 : NaClXMutexLock(mutex);
116 1 : if (NULL == singleton) {
117 : do {
118 : /* Allocate an instance. */
119 1 : singleton = (struct NaClDescInvalid *) malloc(sizeof(*singleton));
120 1 : if (NULL == singleton) {
121 0 : break;
122 : }
123 : /* Do the base class construction. */
124 1 : if (!NaClDescCtor(&(singleton->base))) {
125 0 : free(singleton);
126 0 : singleton = NULL;
127 0 : break;
128 : }
129 : /* Construct the derived class (simply set the vtbl). */
130 : singleton->base.base.vtbl =
131 1 : (struct NaClRefCountVtbl const *) &kNaClDescInvalidVtbl;
132 1 : } while (0);
133 : }
134 1 : NaClXMutexUnlock(mutex);
135 : /* If we reached this point and still have NULL == singleton there was an
136 : * error in allocation or construction. Return NULL to indicate error.
137 : */
138 1 : if (NULL == singleton) {
139 0 : return NULL;
140 : }
141 :
142 1 : return (struct NaClDescInvalid *) NaClDescRef(&(singleton->base));
143 1 : }
144 :
145 : int NaClDescInvalidInternalize(struct NaClDesc **baseptr,
146 : struct NaClDescXferState *xfer,
147 1 : struct NaClDescQuotaInterface *quota_interface) {
148 : UNREFERENCED_PARAMETER(xfer);
149 : UNREFERENCED_PARAMETER(quota_interface);
150 :
151 1 : *baseptr = (struct NaClDesc *) NaClDescInvalidMake();
152 :
153 1 : return 0;
154 1 : }
|