Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(569)

Side by Side Diff: src/trusted/service_runtime/nacl_secure_service.c

Issue 10914138: Split secure command channel and untrusted application channel (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: CommandSetup SRPC call added to secure command service. Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "native_client/src/trusted/service_runtime/nacl_secure_service.h"
8
9 #include "native_client/src/shared/platform/nacl_exit.h"
10 #include "native_client/src/shared/platform/nacl_log.h"
11 #include "native_client/src/shared/platform/nacl_sync.h"
12 #include "native_client/src/shared/platform/nacl_sync_checked.h"
13 #include "native_client/src/shared/srpc/nacl_srpc.h"
14
15 #include "native_client/src/trusted/fault_injection/fault_injection.h"
16 #include "native_client/src/trusted/simple_service/nacl_simple_service.h"
17 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
18
19
20 int NaClSecureServiceCtor(struct NaClSecureService *self,
21 struct NaClSrpcHandlerDesc const *srpc_handlers,
22 struct NaClApp *nap,
23 struct NaClDesc *service_port,
24 struct NaClDesc *sock_addr) {
25 NaClLog(4,
26 "Entered NaClSecureServiceCtor: self 0x%"NACL_PRIxPTR"\n",
27 (uintptr_t) self);
28 if (NACL_FI_ERROR_COND(
29 "NaClSecureServiceCtor__NaClSimpleServiceWithSocketCtor",
30 !NaClSimpleServiceWithSocketCtor(
31 &self->base,
32 srpc_handlers,
33 NaClThreadInterfaceThreadFactory,
34 (void *) NULL,
35 service_port,
36 sock_addr))) {
37 goto failure_simple_ctor;
38 }
39 self->nap = nap;
40
41 NACL_VTBL(NaClRefCount, self) =
42 (struct NaClRefCountVtbl *) &kNaClSecureServiceVtbl;
43 return 1;
44 failure_simple_ctor:
45 return 0;
46 }
47
48 void NaClSecureServiceDtor(struct NaClRefCount *vself) {
49 struct NaClSecureService *self = (struct NaClSecureService *) vself;
50
51 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *)
52 &kNaClSimpleServiceVtbl;
53 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
54 }
55
56 int NaClSecureServiceConnectionFactory(
57 struct NaClSimpleService *vself,
58 struct NaClDesc *conn,
59 struct NaClSimpleServiceConnection **out) {
60 struct NaClSecureService *self =
61 (struct NaClSecureService *) vself;
62
63 /* our instance_data is not connection specific */
64 return NaClSimpleServiceConnectionFactoryWithInstanceData(
65 vself, conn, (void *) self->nap, out);
66 }
67
68 int NaClSecureServiceAcceptAndSpawnHandler(struct NaClSimpleService *vself) {
69 int rv;
70
71 NaClLog(4,
72 "NaClSecureServiceAcceptAndSpawnHandler: invoking base class vfn\n");
73 rv = (*kNaClSimpleServiceVtbl.AcceptAndSpawnHandler)(vself);
74 if (0 != rv) {
75 NaClLog(LOG_FATAL,
76 "Secure channel AcceptAndSpawnHandler returned %d\n",
77 rv);
78 }
79 NaClThreadExit(0);
80 /*
81 * NOTREACHED The port is now to be used by untrusted code: all
82 * subsequent connections are handled there.
83 */
84 return rv;
85 }
86
87 void NaClSecureServiceRpcHandler(struct NaClSimpleService *vself,
88 struct NaClSimpleServiceConnection *vconn) {
89 struct NaClSecureService *self =
90 (struct NaClSecureService *) vself;
91
92 NaClLog(4, "NaClSecureChannelThread started\n");
93 NaClSecureChannelCountIncr(self->nap);
94 (*kNaClSimpleServiceVtbl.RpcHandler)(vself, vconn);
95 /*(*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);*/
96 /*NaClRefCountUnref((struct NaClRefCount *) self);*/
97 /*NaClExit(0);*/
98 NaClRefCountUnref((struct NaClRefCount *) vconn);
99 NaClSecureChannelCountDecr(self->nap);
100 NaClLog(4, "NaClSecureChannelThread: channel closed, exiting.\n");
101 NaClThreadExit(0);
102 }
103
104 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl = {
105 {
106 NaClSecureServiceDtor,
107 },
108 NaClSecureServiceConnectionFactory,
109 NaClSimpleServiceAcceptConnection,
110 NaClSecureServiceAcceptAndSpawnHandler,
111 NaClSecureServiceRpcHandler,
112 };
113
114 struct NaClSecureRevClientConnHandler {
115 struct NaClSecureRevClientConnHandler *next;
116
117 /* used by NaClSimpleRevServiceClient's ClientCallback fn */
118 void (*handler)(
119 void *state,
120 struct NaClThreadInterface *tif,
121 struct NaClDesc *conn);
122 void *state;
123 };
124
125 static void NaClSecureReverseClientInternalCallback(
126 void *state,
127 struct NaClThreadInterface *tif,
128 struct NaClDesc *conn) {
129 struct NaClSecureReverseClient *self =
130 (struct NaClSecureReverseClient *) state;
131 struct NaClSecureRevClientConnHandler *hand_ptr;
132
133 UNREFERENCED_PARAMETER(tif);
134 NaClLog(4, "Entered NaClSecureReverseClientInternalCallback\n");
135 hand_ptr = (*NACL_VTBL(NaClSecureReverseClient, self)->RemoveHandler)(self);
136 NaClLog(4, " got callback object %"NACL_PRIxPTR"\n", (uintptr_t) hand_ptr);
137 NaClLog(4,
138 " callback:0x%"NACL_PRIxPTR"(0x%"NACL_PRIxPTR",0x%"NACL_PRIxPTR")\n",
139 (uintptr_t) hand_ptr->handler,
140 (uintptr_t) hand_ptr->state,
141 (uintptr_t) conn);
142 (*hand_ptr->handler)(hand_ptr->state, tif, conn);
143 NaClLog(4, "NaClSecureReverseClientInternalCallback: freeing memory\n");
144 free(hand_ptr);
145 NaClLog(4, "Leaving NaClSecureReverseClientInternalCallback\n");
146 }
147
148 /*
149 * Require an initial connection handler in the Ctor, so that it's
150 * obvious that a reverse client needs to accept an IMC connection
151 * from the server to get things bootstrapped.
152 */
153 int NaClSecureReverseClientCtor(
154 struct NaClSecureReverseClient *self,
155 void (*client_callback)(
156 void *, struct NaClThreadInterface*, struct NaClDesc *),
157 void *state,
158 struct NaClApp *nap) {
159 NaClLog(4,
160 ("Entered NaClSecureReverseClientCtor, self 0x%"NACL_PRIxPTR","
161 " nap 0x%"NACL_PRIxPTR"\n"),
162 (uintptr_t) self,
163 (uintptr_t) nap);
164 if (!NaClSimpleRevClientCtor(&self->base,
165 NaClSecureReverseClientInternalCallback,
166 (void *) self,
167 NaClThreadInterfaceThreadFactory,
168 (void *) NULL)) {
169 goto failure_simple_ctor;
170 }
171 NaClLog(4, "NaClSecureReverseClientCtor: Mutex\n");
172 if (!NaClMutexCtor(&self->mu)) {
173 goto failure_mutex_ctor;
174 }
175 self->nap = nap;
176 self->queue_head = (struct NaClSecureRevClientConnHandler *) NULL;
177 self->queue_insert = &self->queue_head;
178
179 NACL_VTBL(NaClRefCount, self) =
180 (struct NaClRefCountVtbl *) &kNaClSecureReverseClientVtbl;
181
182 NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler\n");
183 if (!(*NACL_VTBL(NaClSecureReverseClient, self)->
184 InsertHandler)(self, client_callback, state)) {
185 goto failure_handler_insert;
186 }
187
188 NaClLog(4, "Leaving NaClSecureReverseClientCtor\n");
189 return 1;
190
191 failure_handler_insert:
192 NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler failed\n");
193 NACL_VTBL(NaClRefCount, self) =
194 (struct NaClRefCountVtbl *) &kNaClSimpleRevClientVtbl;
195
196 self->nap = NULL;
197 self->queue_insert = (struct NaClSecureRevClientConnHandler **) NULL;
198 NaClMutexDtor(&self->mu);
199
200 failure_mutex_ctor:
201 NaClLog(4, "NaClSecureReverseClientCtor: Mutex failed\n");
202 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
203 failure_simple_ctor:
204 NaClLog(4, "Leaving NaClSecureReverseClientCtor\n");
205 return 0;
206 }
207
208 void NaClSecureReverseClientDtor(struct NaClRefCount *vself) {
209 struct NaClSecureReverseClient *self =
210 (struct NaClSecureReverseClient *) vself;
211
212 struct NaClSecureRevClientConnHandler *entry;
213 struct NaClSecureRevClientConnHandler *next;
214
215 for (entry = self->queue_head; NULL != entry; entry = next) {
216 next = entry->next;
217 free(entry);
218 }
219 NaClMutexDtor(&self->mu);
220
221 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *)
222 &kNaClSimpleRevClientVtbl;
223 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
224 }
225
226 /*
227 * Caller must set up handler before issuing connection request RPC on
228 * nap->reverse_channel, since otherwise the connection handler queue
229 * may be empty and the connect code would abort. Because the connect
230 * doesn't wait for a handler, we don't need a condvar.
231 *
232 * We do not need to serialize on the handlers, since the
233 * RPC-server/IMC-client implementation should not distinguish one
234 * connection from another: it is okay for two handlers to be
235 * inserted, and two connection request RPCs to be preformed
236 * (sequentially, since they are over a single channel), and have the
237 * server side spawn threads that asynchronously connect twice, in the
238 * "incorrect" order, etc.
239 */
240 int NaClSecureReverseClientInsertHandler(
241 struct NaClSecureReverseClient *self,
242 void (*handler)(
243 void *handler_state,
244 struct NaClThreadInterface *thread_if,
245 struct NaClDesc *new_conn),
246 void *state) {
247 struct NaClSecureRevClientConnHandler *entry;
248 int retval = 0; /* fail */
249
250 NaClLog(4,
251 ("NaClSecureReverseClientInsertHandler: "
252 "handler 0x%"NACL_PRIxPTR", state 0x%"NACL_PRIxPTR"\n"),
253 (uintptr_t) handler, (uintptr_t) state);
254
255 NaClXMutexLock(&self->mu);
256
257 entry = (struct NaClSecureRevClientConnHandler *) malloc(sizeof *entry);
258 if (NULL == entry) {
259 goto cleanup;
260 }
261 entry->handler = handler;
262 entry->state = state;
263 entry->next = (struct NaClSecureRevClientConnHandler *) NULL;
264 *self->queue_insert = entry;
265 self->queue_insert = &entry->next;
266 retval = 1;
267
268 cleanup:
269 NaClXMutexUnlock(&self->mu);
270 return retval;
271 }
272
273 struct NaClSecureRevClientConnHandler *NaClSecureReverseClientRemoveHandler(
274 struct NaClSecureReverseClient *self) {
275 struct NaClSecureRevClientConnHandler *head;
276
277 NaClLog(4, "Entered NaClSecureReverseClientRemoveHandler, acquiring lock\n");
278 NaClXMutexLock(&self->mu);
279 NaClLog(4, "NaClSecureReverseClientRemoveHandler, got lock\n");
280 head = self->queue_head;
281 if (NULL == head) {
282 NaClLog(LOG_FATAL,
283 "NaClSecureReverseClientRemoveHandler: empty handler queue\n");
284 }
285 if (NULL == (self->queue_head = head->next)) {
286 NaClLog(4, "NaClSecureReverseClientRemoveHandler, last elt patch up\n");
287 self->queue_insert = &self->queue_head;
288 }
289 NaClLog(4, "NaClSecureReverseClientRemoveHandler, unlocking\n");
290 NaClXMutexUnlock(&self->mu);
291
292 head->next = NULL;
293 NaClLog(4,
294 ("Leaving NaClSecureReverseClientRemoveHandler:"
295 " returning %"NACL_PRIxPTR"\n"),
296 (uintptr_t) head);
297 return head;
298 }
299
300 struct NaClSecureReverseClientVtbl const kNaClSecureReverseClientVtbl = {
301 {
302 {
303 NaClSecureReverseClientDtor,
304 },
305 },
306 NaClSecureReverseClientInsertHandler,
307 NaClSecureReverseClientRemoveHandler,
308 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698