| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 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 | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "native_client/src/trusted/service_runtime/nacl_secure_service.h" | 7 #include "native_client/src/trusted/service_runtime/nacl_secure_service.h" |
| 8 | 8 |
| 9 #include "native_client/src/shared/platform/nacl_exit.h" | 9 #include "native_client/src/shared/platform/nacl_exit.h" |
| 10 #include "native_client/src/shared/platform/nacl_log.h" | 10 #include "native_client/src/shared/platform/nacl_log.h" |
| 11 #include "native_client/src/shared/platform/nacl_sync.h" | 11 #include "native_client/src/shared/platform/nacl_sync.h" |
| 12 #include "native_client/src/shared/platform/nacl_sync_checked.h" | 12 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
| 13 #include "native_client/src/shared/srpc/nacl_srpc.h" | 13 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 14 | 14 |
| 15 #include "native_client/src/trusted/fault_injection/fault_injection.h" | 15 #include "native_client/src/trusted/fault_injection/fault_injection.h" |
| 16 #include "native_client/src/trusted/simple_service/nacl_simple_service.h" | 16 #include "native_client/src/trusted/simple_service/nacl_simple_service.h" |
| 17 #include "native_client/src/trusted/service_runtime/sel_ldr.h" | 17 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |
| 18 | 18 |
| 19 | 19 |
| 20 int NaClSecureThreadIfFactoryFn( | |
| 21 void *factory_data, | |
| 22 NaClThreadIfStartFunction fn_ptr, | |
| 23 void *thread_data, | |
| 24 size_t thread_stack_size, | |
| 25 struct NaClThreadInterface **out_new_thread); | |
| 26 | |
| 27 int NaClSecureServiceCtor(struct NaClSecureService *self, | 20 int NaClSecureServiceCtor(struct NaClSecureService *self, |
| 28 struct NaClSrpcHandlerDesc const *srpc_handlers, | 21 struct NaClSrpcHandlerDesc const *srpc_handlers, |
| 29 struct NaClApp *nap, | 22 struct NaClApp *nap, |
| 30 struct NaClDesc *service_port, | 23 struct NaClDesc *service_port, |
| 31 struct NaClDesc *sock_addr) { | 24 struct NaClDesc *sock_addr) { |
| 32 NaClLog(4, | 25 NaClLog(4, |
| 33 "Entered NaClSecureServiceCtor: self 0x%"NACL_PRIxPTR"\n", | 26 "Entered NaClSecureServiceCtor: self 0x%"NACL_PRIxPTR"\n", |
| 34 (uintptr_t) self); | 27 (uintptr_t) self); |
| 35 if (NACL_FI_ERROR_COND( | 28 if (NACL_FI_ERROR_COND( |
| 36 "NaClSecureServiceCtor__NaClSimpleServiceWithSocketCtor", | 29 "NaClSecureServiceCtor__NaClSimpleServiceWithSocketCtor", |
| 37 !NaClSimpleServiceWithSocketCtor( | 30 !NaClSimpleServiceWithSocketCtor( |
| 38 &self->base, | 31 &self->base, |
| 39 srpc_handlers, | 32 srpc_handlers, |
| 40 NaClSecureThreadIfFactoryFn, | 33 NaClThreadInterfaceThreadFactory, |
| 41 (void *) self, | 34 (void *) self, |
| 42 service_port, | 35 service_port, |
| 43 sock_addr))) { | 36 sock_addr))) { |
| 44 goto done; | 37 goto done; |
| 45 } | 38 } |
| 46 if (!NaClMutexCtor(&self->mu)) { | 39 if (!NaClMutexCtor(&self->mu)) { |
| 47 NaClLog(4, "NaClMutexCtor failed\n"); | 40 NaClLog(4, "NaClMutexCtor failed\n"); |
| 48 goto failure_mutex_ctor; | 41 goto failure_mutex_ctor; |
| 49 } | 42 } |
| 50 self->nap = nap; | 43 self->nap = nap; |
| 51 self->thread_count = 0; | 44 self->conn_count = 0; |
| 52 NACL_VTBL(NaClRefCount, self) = | 45 NACL_VTBL(NaClRefCount, self) = |
| 53 (struct NaClRefCountVtbl *) &kNaClSecureServiceVtbl; | 46 (struct NaClRefCountVtbl *) &kNaClSecureServiceVtbl; |
| 54 return 1; | 47 return 1; |
| 55 | 48 |
| 56 failure_mutex_ctor: | 49 failure_mutex_ctor: |
| 57 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self); | 50 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self); |
| 58 done: | 51 done: |
| 59 return 0; | 52 return 0; |
| 60 } | 53 } |
| 61 | 54 |
| 62 void NaClSecureServiceDtor(struct NaClRefCount *vself) { | 55 void NaClSecureServiceDtor(struct NaClRefCount *vself) { |
| 63 struct NaClSecureService *self = (struct NaClSecureService *) vself; | 56 struct NaClSecureService *self = (struct NaClSecureService *) vself; |
| 64 | 57 |
| 65 if (0 != self->thread_count) { | 58 if (0 != self->conn_count) { |
| 66 NaClLog(LOG_FATAL, | 59 NaClLog(LOG_FATAL, |
| 67 "SecureService dtor when thread count is nonzero\n"); | 60 "SecureService dtor when connection count is nonzero\n"); |
| 68 } | 61 } |
| 69 NaClMutexDtor(&self->mu); | 62 NaClMutexDtor(&self->mu); |
| 70 | 63 |
| 71 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *) | 64 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *) |
| 72 &kNaClSimpleServiceVtbl; | 65 &kNaClSimpleServiceVtbl; |
| 73 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); | 66 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); |
| 74 } | 67 } |
| 75 | 68 |
| 76 int NaClSecureServiceConnectionFactory( | 69 int NaClSecureServiceConnectionFactory( |
| 77 struct NaClSimpleService *vself, | 70 struct NaClSimpleService *vself, |
| 78 struct NaClDesc *conn, | 71 struct NaClDesc *conn, |
| 79 struct NaClSimpleServiceConnection **out) { | 72 struct NaClSimpleServiceConnection **out) { |
| 80 struct NaClSecureService *self = | 73 struct NaClSecureService *self = |
| 81 (struct NaClSecureService *) vself; | 74 (struct NaClSecureService *) vself; |
| 82 | 75 |
| 83 /* our instance_data is not connection specific */ | 76 /* our instance_data is not connection specific */ |
| 84 return NaClSimpleServiceConnectionFactoryWithInstanceData( | 77 return NaClSimpleServiceConnectionFactoryWithInstanceData( |
| 85 vself, conn, (void *) self->nap, out); | 78 vself, conn, (void *) self->nap, out); |
| 86 } | 79 } |
| 87 | 80 |
| 88 static void NaClSecureServiceThreadCountIncr( | 81 static void NaClSecureServiceConnectionCountIncr( |
| 89 struct NaClSecureService *self) { | 82 struct NaClSecureService *self) { |
| 90 NaClLog(5, "NaClSecureServiceThreadCountIncr\n"); | 83 NaClLog(5, "NaClSecureServiceThreadCountIncr\n"); |
| 91 NaClXMutexLock(&self->mu); | 84 NaClXMutexLock(&self->mu); |
| 92 if (0 == ++self->thread_count) { | 85 if (0 == ++self->conn_count) { |
| 93 NaClLog(LOG_FATAL, | 86 NaClLog(LOG_FATAL, |
| 94 "NaClSecureServiceThreadCountIncr: " | 87 "NaClSecureServiceThreadCountIncr: " |
| 95 "thread count overflow!\n"); | 88 "thread count overflow!\n"); |
| 96 } | 89 } |
| 97 NaClXMutexUnlock(&self->mu); | 90 NaClXMutexUnlock(&self->mu); |
| 98 } | 91 } |
| 99 | 92 |
| 100 static void NaClSecureServiceThreadCountDecr( | 93 static void NaClSecureServiceConnectionCountDecr( |
| 101 struct NaClSecureService *self) { | 94 struct NaClSecureService *self) { |
| 102 NaClLog(5, "NaClSecureServiceThreadCountDecr\n"); | 95 NaClLog(5, "NaClSecureServiceThreadCountDecr\n"); |
| 103 NaClXMutexLock(&self->mu); | 96 NaClXMutexLock(&self->mu); |
| 104 if (0 == self->thread_count) { | 97 if (0 == self->conn_count) { |
| 105 NaClLog(LOG_FATAL, | 98 NaClLog(LOG_FATAL, |
| 106 "NaClSecureServiceThreadCountDecr: " | 99 "NaClSecureServiceThreadCountDecr: " |
| 107 "decrementing thread count when count is zero\n"); | 100 "decrementing thread count when count is zero\n"); |
| 108 } | 101 } |
| 109 if (0 == --self->thread_count) { | 102 if (0 == --self->conn_count) { |
| 110 NaClLog(4, "NaClSecureServiceThread: channel closed, exiting.\n"); | 103 NaClLog(4, "NaClSecureServiceThread: all channels closed, exiting.\n"); |
| 111 NaClExit(0); | 104 NaClExit(0); |
| 112 } | 105 } |
| 113 NaClXMutexUnlock(&self->mu); | 106 NaClXMutexUnlock(&self->mu); |
| 114 } | 107 } |
| 115 | 108 |
| 116 struct NaClSecureThreadInterface { | 109 int NaClSecureServiceAcceptConnection( |
| 117 struct NaClThreadInterface base NACL_IS_REFCOUNT_SUBCLASS; | 110 struct NaClSimpleService *vself, |
| 118 struct NaClSecureService *secure_service; | 111 struct NaClSimpleServiceConnection **vconn) { |
| 119 }; | 112 struct NaClSecureService *self = |
| 113 (struct NaClSecureService *) vself; |
| 114 int status; |
| 120 | 115 |
| 121 extern struct NaClThreadInterfaceVtbl | 116 NaClLog(4, "NaClSecureServiceAcceptConnection\n"); |
| 122 const kNaClSecureThreadInterfaceVtbl; /* fwd */ | 117 status = (*kNaClSimpleServiceVtbl.AcceptConnection)(vself, vconn); |
| 123 | 118 if (0 == status) { |
| 124 int NaClReverseThreadIfCtor_protected( | 119 NaClSecureServiceConnectionCountIncr(self); |
| 125 struct NaClSecureThreadInterface *self, | |
| 126 void *factory_data, | |
| 127 NaClThreadIfStartFunction fn_ptr, | |
| 128 void *thread_data, | |
| 129 size_t thread_stack_size) { | |
| 130 struct NaClSecureService *service = (struct NaClSecureService *) factory_data; | |
| 131 | |
| 132 NaClLog(3, "Entered NaClSecureThreadIfCtor_protected\n"); | |
| 133 if (!NaClThreadInterfaceCtor_protected( | |
| 134 (struct NaClThreadInterface *) self, | |
| 135 NaClSecureThreadIfFactoryFn, | |
| 136 NaClRefCountRef((struct NaClRefCount *) service), | |
| 137 fn_ptr, | |
| 138 thread_data, | |
| 139 thread_stack_size)) { | |
| 140 NaClLog(4, "NaClThreadInterfaceCtor_protected failed\n"); | |
| 141 NaClRefCountUnref((struct NaClRefCount *) service); | |
| 142 return 0; | |
| 143 } | 120 } |
| 144 | 121 NaClLog(4, "Leaving NaClSecureServiceAcceptConnection, status %d.\n", status); |
| 145 self->secure_service = service; | 122 return status; |
| 146 NaClSecureServiceThreadCountIncr(service); | |
| 147 | |
| 148 NACL_VTBL(NaClRefCount, self) = | |
| 149 (struct NaClRefCountVtbl *) &kNaClSecureThreadInterfaceVtbl; | |
| 150 | |
| 151 NaClLog(3, "Leaving NaClSecureThreadIfCtor_protected\n"); | |
| 152 return 1; | |
| 153 } | 123 } |
| 154 | 124 |
| 155 int NaClSecureThreadIfFactoryFn( | 125 void NaClSecureServiceRpcHandler(struct NaClSimpleService *vself, |
| 156 void *factory_data, | 126 struct NaClSimpleServiceConnection *vconn) { |
| 157 NaClThreadIfStartFunction fn_ptr, | 127 struct NaClSecureService *self = |
| 158 void *thread_data, | 128 (struct NaClSecureService *) vself; |
| 159 size_t thread_stack_size, | |
| 160 struct NaClThreadInterface **out_new_thread) { | |
| 161 struct NaClSecureThreadInterface *new_thread; | |
| 162 int retval = 0; /* fail */ | |
| 163 | 129 |
| 164 NaClLog(3, "Entered NaClSecureThreadIfFactoryFn\n"); | 130 NaClLog(4, "NaClSecureChannelThread started\n"); |
| 165 new_thread = (struct NaClSecureThreadInterface *) | 131 (*kNaClSimpleServiceVtbl.RpcHandler)(vself, vconn); |
| 166 malloc(sizeof *new_thread); | 132 NaClLog(4, "NaClSecureChannelThread closed.\n"); |
| 167 if (NULL == new_thread) { | 133 NaClSecureServiceConnectionCountDecr(self); |
| 168 goto cleanup; | |
| 169 } | |
| 170 | |
| 171 if (!(retval = | |
| 172 NaClReverseThreadIfCtor_protected(new_thread, | |
| 173 factory_data, | |
| 174 fn_ptr, | |
| 175 thread_data, | |
| 176 thread_stack_size))) { | |
| 177 goto cleanup; | |
| 178 } | |
| 179 | |
| 180 *out_new_thread = (struct NaClThreadInterface *) new_thread; | |
| 181 new_thread = NULL; | |
| 182 | |
| 183 cleanup: | |
| 184 free(new_thread); | |
| 185 NaClLog(3, | |
| 186 "Leaving NaClSecureThreadIfFactoryFn, rv %d\n", | |
| 187 retval); | |
| 188 return retval; | |
| 189 } | 134 } |
| 190 | 135 |
| 191 void NaClSecureThreadIfDtor(struct NaClRefCount *vself) { | |
| 192 struct NaClSecureThreadInterface *self = | |
| 193 (struct NaClSecureThreadInterface *) vself; | |
| 194 | |
| 195 NaClRefCountUnref((struct NaClRefCount *) self->secure_service); | |
| 196 self->secure_service = NULL; | |
| 197 NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl; | |
| 198 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); | |
| 199 } | |
| 200 | |
| 201 void NaClSecureThreadIfLaunchCallback(struct NaClThreadInterface *self) { | |
| 202 NaClLog(4, | |
| 203 ("NaClSecureThreadIfLaunchCallback: thread 0x%"NACL_PRIxPTR | |
| 204 " is launching\n"), | |
| 205 (uintptr_t) self); | |
| 206 } | |
| 207 | |
| 208 void NaClSecureThreadIfExit(struct NaClThreadInterface *vself, | |
| 209 void *exit_code) { | |
| 210 struct NaClSecureThreadInterface *self = | |
| 211 (struct NaClSecureThreadInterface *) vself; | |
| 212 NaClLog(4, | |
| 213 ("NaClSecureThreadIfExit: thread 0x%"NACL_PRIxPTR | |
| 214 " is exiting\n"), | |
| 215 (uintptr_t) vself); | |
| 216 | |
| 217 NaClSecureServiceThreadCountDecr(self->secure_service); | |
| 218 NaClRefCountUnref((struct NaClRefCount *) self); | |
| 219 NaClThreadExit((int)(uintptr_t) exit_code); | |
| 220 } | |
| 221 | |
| 222 struct NaClThreadInterfaceVtbl const kNaClSecureThreadInterfaceVtbl = { | |
| 223 { | |
| 224 NaClSecureThreadIfDtor, | |
| 225 }, | |
| 226 NaClThreadInterfaceStartThread, | |
| 227 NaClSecureThreadIfLaunchCallback, | |
| 228 NaClSecureThreadIfExit, | |
| 229 }; | |
| 230 | |
| 231 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl = { | 136 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl = { |
| 232 { | 137 { |
| 233 NaClSecureServiceDtor, | 138 NaClSecureServiceDtor, |
| 234 }, | 139 }, |
| 235 NaClSecureServiceConnectionFactory, | 140 NaClSecureServiceConnectionFactory, |
| 236 NaClSimpleServiceAcceptConnection, | 141 NaClSecureServiceAcceptConnection, |
| 237 NaClSimpleServiceAcceptAndSpawnHandler, | 142 NaClSimpleServiceAcceptAndSpawnHandler, |
| 238 NaClSimpleServiceRpcHandler, | 143 NaClSecureServiceRpcHandler, |
| 239 }; | 144 }; |
| 240 | 145 |
| 241 struct NaClSecureRevClientConnHandler { | 146 struct NaClSecureRevClientConnHandler { |
| 242 struct NaClSecureRevClientConnHandler *next; | 147 struct NaClSecureRevClientConnHandler *next; |
| 243 | 148 |
| 244 /* used by NaClSimpleRevServiceClient's ClientCallback fn */ | 149 /* used by NaClSimpleRevServiceClient's ClientCallback fn */ |
| 245 void (*handler)( | 150 void (*handler)( |
| 246 void *state, | 151 void *state, |
| 247 struct NaClThreadInterface *tif, | 152 struct NaClThreadInterface *tif, |
| 248 struct NaClDesc *conn); | 153 struct NaClDesc *conn); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 | 330 |
| 426 struct NaClSecureReverseClientVtbl const kNaClSecureReverseClientVtbl = { | 331 struct NaClSecureReverseClientVtbl const kNaClSecureReverseClientVtbl = { |
| 427 { | 332 { |
| 428 { | 333 { |
| 429 NaClSecureReverseClientDtor, | 334 NaClSecureReverseClientDtor, |
| 430 }, | 335 }, |
| 431 }, | 336 }, |
| 432 NaClSecureReverseClientInsertHandler, | 337 NaClSecureReverseClientInsertHandler, |
| 433 NaClSecureReverseClientRemoveHandler, | 338 NaClSecureReverseClientRemoveHandler, |
| 434 }; | 339 }; |
| OLD | NEW |