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

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

Powered by Google App Engine
This is Rietveld 408576698