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 */
NaClDescInvalidExternalizeSize(struct NaClDesc * vself,size_t * nbytes,size_t * nhandles)32 static int NaClDescInvalidExternalizeSize(struct NaClDesc *vself,
33 size_t *nbytes,
34 size_t *nhandles) {
35 UNREFERENCED_PARAMETER(vself);
36 *nbytes = 0;
37 *nhandles = 0;
38 return 0;
39 }
40
NaClDescInvalidExternalize(struct NaClDesc * vself,struct NaClDescXferState * xfer)41 static int NaClDescInvalidExternalize(struct NaClDesc *vself,
42 struct NaClDescXferState *xfer) {
43 UNREFERENCED_PARAMETER(vself);
44 UNREFERENCED_PARAMETER(xfer);
45 return 0;
46 }
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 NaClDescReadNotImplemented,
58 NaClDescWriteNotImplemented,
59 NaClDescSeekNotImplemented,
60 NaClDescPReadNotImplemented,
61 NaClDescPWriteNotImplemented,
62 NaClDescFstatNotImplemented,
63 NaClDescFchdirNotImplemented,
64 NaClDescFchmodNotImplemented,
65 NaClDescFsyncNotImplemented,
66 NaClDescFdatasyncNotImplemented,
67 NaClDescFtruncateNotImplemented,
68 NaClDescGetdentsNotImplemented,
69 NaClDescInvalidExternalizeSize,
70 NaClDescInvalidExternalize,
71 NaClDescLockNotImplemented,
72 NaClDescTryLockNotImplemented,
73 NaClDescUnlockNotImplemented,
74 NaClDescWaitNotImplemented,
75 NaClDescTimedWaitAbsNotImplemented,
76 NaClDescSignalNotImplemented,
77 NaClDescBroadcastNotImplemented,
78 NaClDescSendMsgNotImplemented,
79 NaClDescRecvMsgNotImplemented,
80 NaClDescLowLevelSendMsgNotImplemented,
81 NaClDescLowLevelRecvMsgNotImplemented,
82 NaClDescConnectAddrNotImplemented,
83 NaClDescAcceptConnNotImplemented,
84 NaClDescPostNotImplemented,
85 NaClDescSemWaitNotImplemented,
86 NaClDescGetValueNotImplemented,
87 NaClDescSetMetadata,
88 NaClDescGetMetadata,
89 NaClDescSetFlags,
90 NaClDescGetFlags,
91 NaClDescIsattyNotImplemented,
92 NACL_DESC_INVALID,
93 };
94
95 static struct NaClMutex *mutex = NULL;
96 static struct NaClDescInvalid *singleton;
97
NaClDescInvalidInit(void)98 void NaClDescInvalidInit(void) {
99 mutex = (struct NaClMutex *) malloc(sizeof(*mutex));
100 if (NULL == mutex) {
101 NaClLog(LOG_FATAL, "Cannot allocate NaClDescInvalid mutex\n");
102 }
103 if (!NaClMutexCtor(mutex)) {
104 free(mutex);
105 mutex = NULL;
106 NaClLog(LOG_FATAL, "Cannot construct NaClDescInvalid mutex\n");
107 }
108 }
109
NaClDescInvalidFini(void)110 void NaClDescInvalidFini(void) {
111 if (NULL != mutex) {
112 NaClMutexDtor(mutex);
113 free(mutex);
114 mutex = NULL;
115 }
116 }
117
NaClDescInvalidMake(void)118 struct NaClDescInvalid const *NaClDescInvalidMake(void) {
119 NaClXMutexLock(mutex);
120 if (NULL == singleton) {
121 do {
122 /* Allocate an instance. */
123 singleton = (struct NaClDescInvalid *) malloc(sizeof(*singleton));
124 if (NULL == singleton) {
125 break;
126 }
127 /* Do the base class construction. */
128 if (!NaClDescCtor(&(singleton->base))) {
129 free(singleton);
130 singleton = NULL;
131 break;
132 }
133 /* Construct the derived class (simply set the vtbl). */
134 singleton->base.base.vtbl =
135 (struct NaClRefCountVtbl const *) &kNaClDescInvalidVtbl;
136 } while (0);
137 }
138 NaClXMutexUnlock(mutex);
139 /* If we reached this point and still have NULL == singleton there was an
140 * error in allocation or construction. Return NULL to indicate error.
141 */
142 if (NULL == singleton) {
143 return NULL;
144 }
145
146 return (struct NaClDescInvalid *) NaClDescRef(&(singleton->base));
147 }
148
NaClDescInvalidInternalize(struct NaClDesc ** baseptr,struct NaClDescXferState * xfer)149 int NaClDescInvalidInternalize(struct NaClDesc **baseptr,
150 struct NaClDescXferState *xfer) {
151 UNREFERENCED_PARAMETER(xfer);
152
153 *baseptr = (struct NaClDesc *) NaClDescInvalidMake();
154
155 return 0;
156 }
157