| 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 <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 /* | 9 /* |
| 10 * NaCl Simple/secure ELF loader (NaCl SEL). | 10 * NaCl Simple/secure ELF loader (NaCl SEL). |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 nap->num_dynamic_regions = 0; | 149 nap->num_dynamic_regions = 0; |
| 150 nap->dynamic_regions_allocated = 0; | 150 nap->dynamic_regions_allocated = 0; |
| 151 nap->dynamic_delete_generation = 0; | 151 nap->dynamic_delete_generation = 0; |
| 152 | 152 |
| 153 nap->dynamic_mapcache_offset = 0; | 153 nap->dynamic_mapcache_offset = 0; |
| 154 nap->dynamic_mapcache_size = 0; | 154 nap->dynamic_mapcache_size = 0; |
| 155 nap->dynamic_mapcache_ret = 0; | 155 nap->dynamic_mapcache_ret = 0; |
| 156 | 156 |
| 157 nap->service_port = NULL; | 157 nap->service_port = NULL; |
| 158 nap->service_address = NULL; | 158 nap->service_address = NULL; |
| 159 nap->secure_service_port = NULL; |
| 160 nap->secure_service_address = NULL; |
| 159 nap->bootstrap_channel = NULL; | 161 nap->bootstrap_channel = NULL; |
| 160 nap->secure_service = NULL; | 162 nap->secure_service = NULL; |
| 163 |
| 161 nap->manifest_proxy = NULL; | 164 nap->manifest_proxy = NULL; |
| 162 nap->kernel_service = NULL; | 165 nap->kernel_service = NULL; |
| 163 nap->resource_phase = NACL_RESOURCE_PHASE_START; | 166 nap->resource_phase = NACL_RESOURCE_PHASE_START; |
| 164 if (!NaClResourceNaClAppInit(&nap->resources, nap)) { | 167 if (!NaClResourceNaClAppInit(&nap->resources, nap)) { |
| 165 goto cleanup_dynamic_load_mutex; | 168 goto cleanup_dynamic_load_mutex; |
| 166 } | 169 } |
| 167 nap->reverse_client = NULL; | 170 nap->reverse_client = NULL; |
| 168 nap->reverse_channel_initialization_state = | 171 nap->reverse_channel_initialization_state = |
| 169 NACL_REVERSE_CHANNEL_UNINITIALIZED; | 172 NACL_REVERSE_CHANNEL_UNINITIALIZED; |
| 170 | 173 |
| (...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 ("NaClAppDescriptorHookupCheck: I/O redirection for %s => %s" | 791 ("NaClAppDescriptorHookupCheck: I/O redirection for %s => %s" |
| 789 " failed\n"), | 792 " failed\n"), |
| 790 g_nacl_redir_control[ix].env_name, env); | 793 g_nacl_redir_control[ix].env_name, env); |
| 791 } | 794 } |
| 792 NaClDescUnref(ndp); | 795 NaClDescUnref(ndp); |
| 793 } | 796 } |
| 794 } | 797 } |
| 795 } | 798 } |
| 796 | 799 |
| 797 void NaClCreateServiceSocket(struct NaClApp *nap) { | 800 void NaClCreateServiceSocket(struct NaClApp *nap) { |
| 801 struct NaClDesc *secure_pair[2]; |
| 798 struct NaClDesc *pair[2]; | 802 struct NaClDesc *pair[2]; |
| 799 | 803 |
| 800 NaClLog(3, "Entered NaClCreateServiceSocket\n"); | 804 NaClLog(3, "Entered NaClCreateServiceSocket\n"); |
| 805 |
| 806 if (NACL_FI_ERROR_COND("NaClCreateServiceSocket__secure_boundsock", |
| 807 0 != NaClCommonDescMakeBoundSock(secure_pair))) { |
| 808 NaClLog(LOG_FATAL, "Cound not create secure service socket\n"); |
| 809 } |
| 810 NaClLog(4, |
| 811 "got bound socket at 0x%08"NACL_PRIxPTR", " |
| 812 "addr at 0x%08"NACL_PRIxPTR"\n", |
| 813 (uintptr_t) secure_pair[0], |
| 814 (uintptr_t) secure_pair[1]); |
| 815 |
| 816 NaClDescSafeUnref(nap->secure_service_port); |
| 817 nap->secure_service_port = secure_pair[0]; |
| 818 |
| 819 NaClDescSafeUnref(nap->secure_service_address); |
| 820 nap->secure_service_address = secure_pair[1]; |
| 821 |
| 801 if (NACL_FI_ERROR_COND("NaClCreateServiceSocket__boundsock", | 822 if (NACL_FI_ERROR_COND("NaClCreateServiceSocket__boundsock", |
| 802 0 != NaClCommonDescMakeBoundSock(pair))) { | 823 0 != NaClCommonDescMakeBoundSock(pair))) { |
| 803 NaClLog(LOG_FATAL, "Cound not create service socket\n"); | 824 NaClLog(LOG_FATAL, "Cound not create service socket\n"); |
| 804 } | 825 } |
| 805 NaClLog(4, | 826 NaClLog(4, |
| 806 "got bound socket at 0x%08"NACL_PRIxPTR", " | 827 "got bound socket at 0x%08"NACL_PRIxPTR", " |
| 807 "addr at 0x%08"NACL_PRIxPTR"\n", | 828 "addr at 0x%08"NACL_PRIxPTR"\n", |
| 808 (uintptr_t) pair[0], | 829 (uintptr_t) pair[0], |
| 809 (uintptr_t) pair[1]); | 830 (uintptr_t) pair[1]); |
| 810 NaClSetDesc(nap, NACL_SERVICE_PORT_DESCRIPTOR, pair[0]); | 831 NaClSetDesc(nap, NACL_SERVICE_PORT_DESCRIPTOR, pair[0]); |
| 811 NaClSetDesc(nap, NACL_SERVICE_ADDRESS_DESCRIPTOR, pair[1]); | 832 NaClSetDesc(nap, NACL_SERVICE_ADDRESS_DESCRIPTOR, pair[1]); |
| 812 | 833 |
| 813 NaClDescSafeUnref(nap->service_port); | 834 NaClDescSafeUnref(nap->service_port); |
| 814 | 835 |
| 815 nap->service_port = pair[0]; | 836 nap->service_port = pair[0]; |
| 816 NaClDescRef(nap->service_port); | 837 NaClDescRef(nap->service_port); |
| 817 | 838 |
| 818 NaClDescSafeUnref(nap->service_address); | 839 NaClDescSafeUnref(nap->service_address); |
| 819 | 840 |
| 820 nap->service_address = pair[1]; | 841 nap->service_address = pair[1]; |
| 821 NaClDescRef(nap->service_address); | 842 NaClDescRef(nap->service_address); |
| 843 |
| 822 NaClLog(4, "Leaving NaClCreateServiceSocket\n"); | 844 NaClLog(4, "Leaving NaClCreateServiceSocket\n"); |
| 823 } | 845 } |
| 824 | 846 |
| 825 /* | 847 /* |
| 826 * Import the |inherited_desc| descriptor as an IMC handle, save a | 848 * Import the |inherited_desc| descriptor as an IMC handle, save a |
| 827 * reference to it at nap->bootstrap_channel, then send the | 849 * reference to it at nap->bootstrap_channel, then send the |
| 828 * service_address over that channel. | 850 * service_address over that channel. |
| 829 */ | 851 */ |
| 830 void NaClSetUpBootstrapChannel(struct NaClApp *nap, | 852 void NaClSetUpBootstrapChannel(struct NaClApp *nap, |
| 831 NaClHandle inherited_desc) { | 853 NaClHandle inherited_desc) { |
| 832 struct NaClDescImcDesc *channel; | 854 struct NaClDescImcDesc *channel; |
| 833 struct NaClImcTypedMsgHdr hdr; | 855 struct NaClImcTypedMsgHdr hdr; |
| 856 struct NaClDesc *descs[2]; |
| 834 ssize_t rv; | 857 ssize_t rv; |
| 835 | 858 |
| 836 NaClLog(4, | 859 NaClLog(4, |
| 837 "NaClSetUpBootstrapChannel(0x%08"NACL_PRIxPTR", %"NACL_PRIdPTR")\n", | 860 "NaClSetUpBootstrapChannel(0x%08"NACL_PRIxPTR", %"NACL_PRIdPTR")\n", |
| 838 (uintptr_t) nap, | 861 (uintptr_t) nap, |
| 839 (uintptr_t) inherited_desc); | 862 (uintptr_t) inherited_desc); |
| 840 | 863 |
| 841 channel = (struct NaClDescImcDesc *) malloc(sizeof *channel); | 864 channel = (struct NaClDescImcDesc *) malloc(sizeof *channel); |
| 842 if (NULL == channel) { | 865 if (NULL == channel) { |
| 843 NaClLog(LOG_FATAL, "NaClSetUpBootstrapChannel: no memory\n"); | 866 NaClLog(LOG_FATAL, "NaClSetUpBootstrapChannel: no memory\n"); |
| 844 } | 867 } |
| 845 if (!NaClDescImcDescCtor(channel, inherited_desc)) { | 868 if (!NaClDescImcDescCtor(channel, inherited_desc)) { |
| 846 NaClLog(LOG_FATAL, | 869 NaClLog(LOG_FATAL, |
| 847 ("NaClSetUpBootstrapChannel: cannot construct IMC descriptor" | 870 ("NaClSetUpBootstrapChannel: cannot construct IMC descriptor" |
| 848 " object for inherited descriptor %"NACL_PRIdPTR"\n"), | 871 " object for inherited descriptor %"NACL_PRIdPTR"\n"), |
| 849 (uintptr_t) inherited_desc); | 872 (uintptr_t) inherited_desc); |
| 873 return; |
| 874 } |
| 875 if (NULL == nap->secure_service_address) { |
| 876 NaClLog(LOG_FATAL, |
| 877 "NaClSetUpBootstrapChannel: secure service address not set\n"); |
| 878 return; |
| 850 } | 879 } |
| 851 if (NULL == nap->service_address) { | 880 if (NULL == nap->service_address) { |
| 852 NaClLog(LOG_FATAL, | 881 NaClLog(LOG_FATAL, |
| 853 "NaClSetUpBootstrapChannel: service address not set\n"); | 882 "NaClSetUpBootstrapChannel: service address not set\n"); |
| 854 return; | 883 return; |
| 855 } | 884 } |
| 856 /* | 885 /* |
| 857 * service_address and service_port are set together. | 886 * service_address and service_port are set together. |
| 858 */ | 887 */ |
| 888 descs[0] = nap->secure_service_address; |
| 889 descs[1] = nap->service_address; |
| 859 | 890 |
| 860 hdr.iov = (struct NaClImcMsgIoVec *) NULL; | 891 hdr.iov = (struct NaClImcMsgIoVec *) NULL; |
| 861 hdr.iov_length = 0; | 892 hdr.iov_length = 0; |
| 862 hdr.ndescv = &nap->service_address; | 893 hdr.ndescv = descs; |
| 863 hdr.ndesc_length = 1; | 894 hdr.ndesc_length = NACL_ARRAY_SIZE(descs); |
| 864 | 895 |
| 865 rv = (*NACL_VTBL(NaClDesc, channel)->SendMsg)((struct NaClDesc *) channel, | 896 rv = (*NACL_VTBL(NaClDesc, channel)->SendMsg)((struct NaClDesc *) channel, |
| 866 &hdr, 0); | 897 &hdr, 0); |
| 867 NaClXMutexLock(&nap->mu); | 898 NaClXMutexLock(&nap->mu); |
| 868 if (NULL != nap->bootstrap_channel) { | 899 if (NULL != nap->bootstrap_channel) { |
| 869 NaClLog(LOG_FATAL, | 900 NaClLog(LOG_FATAL, |
| 870 "NaClSetUpBootstrapChannel: cannot have two bootstrap channels\n"); | 901 "NaClSetUpBootstrapChannel: cannot have two bootstrap channels\n"); |
| 871 } | 902 } |
| 872 nap->bootstrap_channel = (struct NaClDesc *) channel; | 903 nap->bootstrap_channel = (struct NaClDesc *) channel; |
| 873 channel = NULL; | 904 channel = NULL; |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 if (NULL != nap->secure_service) { | 1305 if (NULL != nap->secure_service) { |
| 1275 for (;;) { | 1306 for (;;) { |
| 1276 struct nacl_abi_timespec req; | 1307 struct nacl_abi_timespec req; |
| 1277 req.tv_sec = 1000; | 1308 req.tv_sec = 1000; |
| 1278 req.tv_nsec = 0; | 1309 req.tv_nsec = 0; |
| 1279 NaClNanosleep(&req, (struct nacl_abi_timespec *) NULL); | 1310 NaClNanosleep(&req, (struct nacl_abi_timespec *) NULL); |
| 1280 } | 1311 } |
| 1281 } | 1312 } |
| 1282 } | 1313 } |
| 1283 | 1314 |
| 1284 | |
| 1285 /* | |
| 1286 * Secure command channels. | |
| 1287 */ | |
| 1288 | |
| 1289 struct NaClSecureService { | |
| 1290 struct NaClSimpleService base; | |
| 1291 struct NaClApp *nap; | |
| 1292 }; | |
| 1293 | |
| 1294 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl; | |
| 1295 | |
| 1296 | |
| 1297 struct NaClConnectionHandler { | |
| 1298 struct NaClConnectionHandler *next; | |
| 1299 | |
| 1300 /* used by NaClSimpleRevServiceClient's ClientCallback fn */ | |
| 1301 void (*handler)( | |
| 1302 void *state, | |
| 1303 struct NaClThreadInterface *tif, | |
| 1304 struct NaClDesc *conn); | |
| 1305 void *state; | |
| 1306 }; | |
| 1307 | |
| 1308 struct NaClSecureReverseClient { | |
| 1309 struct NaClSimpleRevClient base; | |
| 1310 struct NaClApp *nap; | |
| 1311 | |
| 1312 struct NaClMutex mu; | |
| 1313 | |
| 1314 struct NaClConnectionHandler *queue_head; | |
| 1315 struct NaClConnectionHandler **queue_insert; | |
| 1316 }; | |
| 1317 | |
| 1318 struct NaClSimpleRevClientVtbl const kNaClSecureReverseClientVtbl; | |
| 1319 | |
| 1320 | |
| 1321 int NaClSecureServiceCtor(struct NaClSecureService *self, | |
| 1322 struct NaClSrpcHandlerDesc const *srpc_handlers, | |
| 1323 struct NaClApp *nap) { | |
| 1324 NaClLog(4, | |
| 1325 "Entered NaClSecureServiceCtor: self 0x%"NACL_PRIxPTR"\n", | |
| 1326 (uintptr_t) self); | |
| 1327 if (NACL_FI_ERROR_COND( | |
| 1328 "NaClSecureServiceCtor__NaClSimpleServiceWithSocketCtor", | |
| 1329 !NaClSimpleServiceWithSocketCtor( | |
| 1330 &self->base, | |
| 1331 srpc_handlers, | |
| 1332 NaClThreadInterfaceThreadFactory, | |
| 1333 (void *) NULL, | |
| 1334 nap->service_port, | |
| 1335 nap->service_address))) { | |
| 1336 goto failure_simple_ctor; | |
| 1337 } | |
| 1338 self->nap = nap; | |
| 1339 | |
| 1340 NACL_VTBL(NaClRefCount, self) = | |
| 1341 (struct NaClRefCountVtbl *) &kNaClSecureServiceVtbl; | |
| 1342 return 1; | |
| 1343 failure_simple_ctor: | |
| 1344 return 0; | |
| 1345 } | |
| 1346 | |
| 1347 void NaClSecureServiceDtor(struct NaClRefCount *vself) { | |
| 1348 struct NaClSecureService *self = (struct NaClSecureService *) vself; | |
| 1349 | |
| 1350 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *) | |
| 1351 &kNaClSimpleServiceVtbl; | |
| 1352 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); | |
| 1353 } | |
| 1354 | |
| 1355 /* | 1315 /* |
| 1356 * The first connection is performed by this callback handler. This | 1316 * The first connection is performed by this callback handler. This |
| 1357 * spawns a client thread that will bootstrap the other connections by | 1317 * spawns a client thread that will bootstrap the other connections by |
| 1358 * stashing the connection represented by |conn| to make reverse RPCs | 1318 * stashing the connection represented by |conn| to make reverse RPCs |
| 1359 * to ask the peer to connect to us. No thread is spawned; we just | 1319 * to ask the peer to connect to us. No thread is spawned; we just |
| 1360 * wrap access to the connection with a lock. | 1320 * wrap access to the connection with a lock. |
| 1361 * | 1321 * |
| 1362 * Subsequent connection callbacks will pass the connection to the | 1322 * Subsequent connection callbacks will pass the connection to the |
| 1363 * actual thread that made the connection request using |conn| | 1323 * actual thread that made the connection request using |conn| |
| 1364 * received in the first connection. | 1324 * received in the first connection. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1404 NaClLog(LOG_FATAL, "Reverse quota interface Ctor failed\n"); | 1364 NaClLog(LOG_FATAL, "Reverse quota interface Ctor failed\n"); |
| 1405 } | 1365 } |
| 1406 nap->reverse_channel_initialization_state = NACL_REVERSE_CHANNEL_INITIALIZED; | 1366 nap->reverse_channel_initialization_state = NACL_REVERSE_CHANNEL_INITIALIZED; |
| 1407 | 1367 |
| 1408 NaClXCondVarBroadcast(&nap->cv); | 1368 NaClXCondVarBroadcast(&nap->cv); |
| 1409 NaClXMutexUnlock(&nap->mu); | 1369 NaClXMutexUnlock(&nap->mu); |
| 1410 | 1370 |
| 1411 NaClLog(4, "Leaving NaClSecureReverseClientCallback\n"); | 1371 NaClLog(4, "Leaving NaClSecureReverseClientCallback\n"); |
| 1412 } | 1372 } |
| 1413 | 1373 |
| 1414 /* fwd */ | |
| 1415 int NaClSecureReverseClientCtor( | |
| 1416 struct NaClSecureReverseClient *self, | |
| 1417 void (*client_callback)( | |
| 1418 void *, struct NaClThreadInterface *, struct NaClDesc *), | |
| 1419 void *state, | |
| 1420 struct NaClApp *nap); | |
| 1421 | |
| 1422 static void NaClSecureReverseClientSetup(struct NaClSrpcRpc *rpc, | 1374 static void NaClSecureReverseClientSetup(struct NaClSrpcRpc *rpc, |
| 1423 struct NaClSrpcArg **in_args, | 1375 struct NaClSrpcArg **in_args, |
| 1424 struct NaClSrpcArg **out_args, | 1376 struct NaClSrpcArg **out_args, |
| 1425 struct NaClSrpcClosure *done) { | 1377 struct NaClSrpcClosure *done) { |
| 1426 struct NaClApp *nap = | 1378 struct NaClApp *nap = |
| 1427 (struct NaClApp *) rpc->channel->server_instance_data; | 1379 (struct NaClApp *) rpc->channel->server_instance_data; |
| 1428 struct NaClSecureReverseClient *rev; | 1380 struct NaClSecureReverseClient *rev; |
| 1429 | 1381 |
| 1430 UNREFERENCED_PARAMETER(in_args); | 1382 UNREFERENCED_PARAMETER(in_args); |
| 1431 NaClLog(4, "Entered NaClSecureReverseClientSetup\n"); | 1383 NaClLog(4, "Entered NaClSecureReverseClientSetup\n"); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1480 if (!NaClSimpleRevClientStartServiceThread(&rev->base)) { | 1432 if (!NaClSimpleRevClientStartServiceThread(&rev->base)) { |
| 1481 NaClLog(LOG_FATAL, "Could not start reverse service thread\n"); | 1433 NaClLog(LOG_FATAL, "Could not start reverse service thread\n"); |
| 1482 } | 1434 } |
| 1483 | 1435 |
| 1484 done: | 1436 done: |
| 1485 NaClXMutexUnlock(&nap->mu); | 1437 NaClXMutexUnlock(&nap->mu); |
| 1486 (*done->Run)(done); | 1438 (*done->Run)(done); |
| 1487 NaClLog(4, "Leaving NaClSecureReverseClientSetup\n"); | 1439 NaClLog(4, "Leaving NaClSecureReverseClientSetup\n"); |
| 1488 } | 1440 } |
| 1489 | 1441 |
| 1490 /* | 1442 struct NaClSrpcHandlerDesc const secure_handlers[]; /* fwd */ |
| 1491 * Only called at startup and thereafter by the reverse secure | |
| 1492 * channel, with |self| locked. | |
| 1493 */ | |
| 1494 static | |
| 1495 int NaClSecureReverseClientInsertHandler_mu( | |
| 1496 struct NaClSecureReverseClient *self, | |
| 1497 void (*h)(void *, | |
| 1498 struct NaClThreadInterface *, | |
| 1499 struct NaClDesc *), | |
| 1500 void *d) { | |
| 1501 struct NaClConnectionHandler *entry; | |
| 1502 | |
| 1503 NaClLog(4, | |
| 1504 ("NaClSecureReverseClientInsertHandler_mu: h 0x%"NACL_PRIxPTR"," | |
| 1505 " d 0x%"NACL_PRIxPTR"\n"), | |
| 1506 (uintptr_t) h, | |
| 1507 (uintptr_t) d); | |
| 1508 entry = (struct NaClConnectionHandler *) malloc(sizeof *entry); | |
| 1509 if (NULL == entry) { | |
| 1510 return 0; | |
| 1511 } | |
| 1512 entry->handler = h; | |
| 1513 entry->state = d; | |
| 1514 entry->next = (struct NaClConnectionHandler *) NULL; | |
| 1515 *self->queue_insert = entry; | |
| 1516 self->queue_insert = &entry->next; | |
| 1517 | |
| 1518 return 1; | |
| 1519 } | |
| 1520 | |
| 1521 /* | |
| 1522 * Caller must set up handler before issuing connection request RPC on | |
| 1523 * nap->reverse_channel, since otherwise the connection handler queue | |
| 1524 * may be empty and the connect code would abort. Because the connect | |
| 1525 * doesn't wait for a handler, we don't need a condvar. | |
| 1526 * | |
| 1527 * We do not need to serialize on the handlers, since the | |
| 1528 * RPC-server/IMC-client implementation should not distinguish one | |
| 1529 * connection from another: it is okay for two handlers to be | |
| 1530 * inserted, and two connection request RPCs to be preformed | |
| 1531 * (sequentially, since they are over a single channel), and have the | |
| 1532 * server side spawn threads that asynchronously connect twice, in the | |
| 1533 * "incorrect" order, etc. | |
| 1534 */ | |
| 1535 int NaClSecureReverseClientInsertHandler( | |
| 1536 struct NaClSecureReverseClient *self, | |
| 1537 void (*handler)( | |
| 1538 void *handlr_state, | |
| 1539 struct NaClThreadInterface *thread_if, | |
| 1540 struct NaClDesc *new_conn), | |
| 1541 void *handler_state) { | |
| 1542 int retval; | |
| 1543 | |
| 1544 NaClXMutexLock(&self->mu); | |
| 1545 retval = NaClSecureReverseClientInsertHandler_mu(self, | |
| 1546 handler, handler_state); | |
| 1547 NaClXMutexUnlock(&self->mu); | |
| 1548 return retval; | |
| 1549 } | |
| 1550 | |
| 1551 static | |
| 1552 struct NaClConnectionHandler *NaClSecureReverseClientPopHandler( | |
| 1553 struct NaClSecureReverseClient *self) { | |
| 1554 struct NaClConnectionHandler *head; | |
| 1555 | |
| 1556 NaClLog(4, "Entered NaClSecureReverseClientPopHandler, acquiring lock\n"); | |
| 1557 NaClXMutexLock(&self->mu); | |
| 1558 NaClLog(4, "NaClSecureReverseClientPopHandler, got lock\n"); | |
| 1559 head = self->queue_head; | |
| 1560 if (NULL == head) { | |
| 1561 NaClLog(LOG_FATAL, | |
| 1562 "NaClSecureReverseClientPopHandler: empty handler queue\n"); | |
| 1563 } | |
| 1564 if (NULL == (self->queue_head = head->next)) { | |
| 1565 NaClLog(4, "NaClSecureReverseClientPopHandler, last elt patch up\n"); | |
| 1566 self->queue_insert = &self->queue_head; | |
| 1567 } | |
| 1568 NaClLog(4, "NaClSecureReverseClientPopHandler, unlocking\n"); | |
| 1569 NaClXMutexUnlock(&self->mu); | |
| 1570 | |
| 1571 head->next = NULL; | |
| 1572 NaClLog(4, | |
| 1573 ("Leaving NaClSecureReverseClientPopHandler:" | |
| 1574 " returning %"NACL_PRIxPTR"\n"), | |
| 1575 (uintptr_t) head); | |
| 1576 return head; | |
| 1577 } | |
| 1578 | |
| 1579 static | |
| 1580 void NaClSecureReverseClientInternalCallback( | |
| 1581 void *state, | |
| 1582 struct NaClThreadInterface *tif, | |
| 1583 struct NaClDesc *conn) { | |
| 1584 struct NaClSecureReverseClient *self = | |
| 1585 (struct NaClSecureReverseClient *) state; | |
| 1586 struct NaClConnectionHandler *hand_ptr; | |
| 1587 | |
| 1588 UNREFERENCED_PARAMETER(tif); | |
| 1589 NaClLog(4, "Entered NaClSecureReverseClientInternalCallback\n"); | |
| 1590 hand_ptr = NaClSecureReverseClientPopHandler(self); | |
| 1591 NaClLog(4, " got callback object %"NACL_PRIxPTR"\n", (uintptr_t) hand_ptr); | |
| 1592 NaClLog(4, | |
| 1593 " callback:0x%"NACL_PRIxPTR"(0x%"NACL_PRIxPTR",0x%"NACL_PRIxPTR")\n", | |
| 1594 (uintptr_t) hand_ptr->handler, | |
| 1595 (uintptr_t) hand_ptr->state, | |
| 1596 (uintptr_t) conn); | |
| 1597 (*hand_ptr->handler)(hand_ptr->state, tif, conn); | |
| 1598 NaClLog(4, "NaClSecureReverseClientInternalCallback: freeing memory\n"); | |
| 1599 free(hand_ptr); | |
| 1600 NaClLog(4, "Leaving NaClSecureReverseClientInternalCallback\n"); | |
| 1601 } | |
| 1602 | |
| 1603 /* | |
| 1604 * Require an initial connection handler in the Ctor, so that it's | |
| 1605 * obvious that a reverse client needs to accept an IMC connection | |
| 1606 * from the server to get things bootstrapped. | |
| 1607 */ | |
| 1608 int NaClSecureReverseClientCtor( | |
| 1609 struct NaClSecureReverseClient *self, | |
| 1610 void (*client_callback)( | |
| 1611 void *, struct NaClThreadInterface*, struct NaClDesc *), | |
| 1612 void *state, | |
| 1613 struct NaClApp *nap) { | |
| 1614 NaClLog(4, | |
| 1615 ("Entered NaClSecureReverseClientCtor, self 0x%"NACL_PRIxPTR"," | |
| 1616 " nap 0x%"NACL_PRIxPTR"\n"), | |
| 1617 (uintptr_t) self, | |
| 1618 (uintptr_t) nap); | |
| 1619 if (!NaClSimpleRevClientCtor(&self->base, | |
| 1620 NaClSecureReverseClientInternalCallback, | |
| 1621 (void *) self, | |
| 1622 NaClThreadInterfaceThreadFactory, | |
| 1623 (void *) NULL)) { | |
| 1624 goto failure_simple_ctor; | |
| 1625 } | |
| 1626 NaClLog(4, "NaClSecureReverseClientCtor: Mutex\n"); | |
| 1627 if (!NaClMutexCtor(&self->mu)) { | |
| 1628 goto failure_mutex_ctor; | |
| 1629 } | |
| 1630 self->nap = nap; | |
| 1631 self->queue_head = (struct NaClConnectionHandler *) NULL; | |
| 1632 self->queue_insert = &self->queue_head; | |
| 1633 | |
| 1634 NACL_VTBL(NaClRefCount, self) = | |
| 1635 (struct NaClRefCountVtbl *) &kNaClSecureReverseClientVtbl; | |
| 1636 | |
| 1637 NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler\n"); | |
| 1638 if (!NaClSecureReverseClientInsertHandler(self, | |
| 1639 client_callback, | |
| 1640 state)) { | |
| 1641 goto failure_handler_insert; | |
| 1642 } | |
| 1643 | |
| 1644 NaClLog(4, "Leaving NaClSecureReverseClientCtor\n"); | |
| 1645 return 1; | |
| 1646 | |
| 1647 failure_handler_insert: | |
| 1648 NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler failed\n"); | |
| 1649 NACL_VTBL(NaClRefCount, self) = | |
| 1650 (struct NaClRefCountVtbl *) &kNaClSimpleRevClientVtbl; | |
| 1651 | |
| 1652 self->nap = NULL; | |
| 1653 self->queue_insert = (struct NaClConnectionHandler **) NULL; | |
| 1654 NaClMutexDtor(&self->mu); | |
| 1655 | |
| 1656 failure_mutex_ctor: | |
| 1657 NaClLog(4, "NaClSecureReverseClientCtor: Mutex failed\n"); | |
| 1658 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self); | |
| 1659 failure_simple_ctor: | |
| 1660 NaClLog(4, "Leaving NaClSecureReverseClientCtor\n"); | |
| 1661 return 0; | |
| 1662 } | |
| 1663 | |
| 1664 void NaClSecureReverseClientDtor(struct NaClRefCount *vself) { | |
| 1665 struct NaClSecureReverseClient *self = | |
| 1666 (struct NaClSecureReverseClient *) vself; | |
| 1667 | |
| 1668 struct NaClConnectionHandler *entry; | |
| 1669 struct NaClConnectionHandler *next; | |
| 1670 | |
| 1671 for (entry = self->queue_head; NULL != entry; entry = next) { | |
| 1672 next = entry->next; | |
| 1673 free(entry); | |
| 1674 } | |
| 1675 NaClMutexDtor(&self->mu); | |
| 1676 | |
| 1677 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *) | |
| 1678 &kNaClSimpleRevClientVtbl; | |
| 1679 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); | |
| 1680 } | |
| 1681 | |
| 1682 int NaClSecureServiceConnectionFactory( | |
| 1683 struct NaClSimpleService *vself, | |
| 1684 struct NaClDesc *conn, | |
| 1685 struct NaClSimpleServiceConnection **out) { | |
| 1686 struct NaClSecureService *self = | |
| 1687 (struct NaClSecureService *) vself; | |
| 1688 | |
| 1689 /* our instance_data is not connection specific */ | |
| 1690 return NaClSimpleServiceConnectionFactoryWithInstanceData( | |
| 1691 vself, conn, (void *) self->nap, out); | |
| 1692 } | |
| 1693 | |
| 1694 int NaClSecureServiceAcceptAndSpawnHandler(struct NaClSimpleService *vself) { | |
| 1695 int rv; | |
| 1696 | |
| 1697 NaClLog(4, | |
| 1698 "NaClSecureServiceAcceptAndSpawnHandler: invoking base class vfn\n"); | |
| 1699 rv = (*kNaClSimpleServiceVtbl.AcceptAndSpawnHandler)(vself); | |
| 1700 if (0 != rv) { | |
| 1701 NaClLog(LOG_FATAL, | |
| 1702 "Secure channel AcceptAndSpawnHandler returned %d\n", | |
| 1703 rv); | |
| 1704 } | |
| 1705 NaClThreadExit(0); | |
| 1706 /* | |
| 1707 * NOTREACHED The port is now to be used by untrusted code: all | |
| 1708 * subsequent connections are handled there. | |
| 1709 */ | |
| 1710 return rv; | |
| 1711 } | |
| 1712 | |
| 1713 void NaClSecureServiceRpcHandler(struct NaClSimpleService *vself, | |
| 1714 struct NaClSimpleServiceConnection *vconn) { | |
| 1715 | |
| 1716 NaClLog(4, "NaClSecureChannelThread started\n"); | |
| 1717 (*kNaClSimpleServiceVtbl.RpcHandler)(vself, vconn); | |
| 1718 NaClLog(4, "NaClSecureChannelThread: channel closed, exiting.\n"); | |
| 1719 NaClExit(0); | |
| 1720 } | |
| 1721 | |
| 1722 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl = { | |
| 1723 { | |
| 1724 NaClSecureServiceDtor, | |
| 1725 }, | |
| 1726 NaClSecureServiceConnectionFactory, | |
| 1727 NaClSimpleServiceAcceptConnection, | |
| 1728 NaClSecureServiceAcceptAndSpawnHandler, | |
| 1729 NaClSecureServiceRpcHandler, | |
| 1730 }; | |
| 1731 | |
| 1732 struct NaClSimpleRevClientVtbl const kNaClSecureReverseClientVtbl = { | |
| 1733 { | |
| 1734 NaClSecureReverseClientDtor, | |
| 1735 }, | |
| 1736 }; | |
| 1737 | 1443 |
| 1738 void NaClSecureCommandChannel(struct NaClApp *nap) { | 1444 void NaClSecureCommandChannel(struct NaClApp *nap) { |
| 1739 struct NaClSecureService *secure_command_server; | 1445 struct NaClSecureService *secure_command_server; |
| 1740 | 1446 |
| 1741 static struct NaClSrpcHandlerDesc const secure_handlers[] = { | |
| 1742 { "hard_shutdown::", NaClSecureChannelShutdownRpc, }, | |
| 1743 { "start_module::i", NaClSecureChannelStartModuleRpc, }, | |
| 1744 { "log:is:", NaClSecureChannelLog, }, | |
| 1745 { "load_module:hs:", NaClLoadModuleRpc, }, | |
| 1746 { "load_irt:h:", NaClLoadIrtRpc, }, | |
| 1747 { "reverse_setup::h", NaClSecureReverseClientSetup, }, | |
| 1748 /* add additional calls here. upcall set up? start module signal? */ | |
| 1749 { (char const *) NULL, (NaClSrpcMethod) NULL, }, | |
| 1750 }; | |
| 1751 | |
| 1752 NaClLog(4, "Entered NaClSecureCommandChannel\n"); | 1447 NaClLog(4, "Entered NaClSecureCommandChannel\n"); |
| 1753 | 1448 |
| 1754 secure_command_server = (struct NaClSecureService *) malloc( | 1449 secure_command_server = (struct NaClSecureService *) malloc( |
| 1755 sizeof *secure_command_server); | 1450 sizeof *secure_command_server); |
| 1756 if (NACL_FI_ERROR_COND("NaClSecureCommandChannel__malloc", | 1451 if (NACL_FI_ERROR_COND("NaClSecureCommandChannel__malloc", |
| 1757 NULL == secure_command_server)) { | 1452 NULL == secure_command_server)) { |
| 1758 NaClLog(LOG_FATAL, "Out of memory for secure command channel\n"); | 1453 NaClLog(LOG_FATAL, "Out of memory for secure command channel\n"); |
| 1759 } | 1454 } |
| 1760 if (NACL_FI_ERROR_COND("NaClSecureCommandChannel__NaClSecureServiceCtor", | 1455 if (NACL_FI_ERROR_COND("NaClSecureCommandChannel__NaClSecureServiceCtor", |
| 1761 !NaClSecureServiceCtor(secure_command_server, | 1456 !NaClSecureServiceCtor(secure_command_server, |
| 1762 secure_handlers, nap))) { | 1457 secure_handlers, |
| 1458 nap, |
| 1459 nap->secure_service_port, |
| 1460 nap->secure_service_address))) { |
| 1763 NaClLog(LOG_FATAL, "NaClSecureServiceCtor failed\n"); | 1461 NaClLog(LOG_FATAL, "NaClSecureServiceCtor failed\n"); |
| 1764 } | 1462 } |
| 1765 nap->secure_service = secure_command_server; | 1463 nap->secure_service = secure_command_server; |
| 1766 | 1464 |
| 1767 NaClLog(4, "NaClSecureCommandChannel: starting service thread\n"); | 1465 NaClLog(4, "NaClSecureCommandChannel: starting service thread\n"); |
| 1768 if (NACL_FI_ERROR_COND( | 1466 if (NACL_FI_ERROR_COND( |
| 1769 "NaClSecureCommandChannel__NaClSimpleServiceStartServiceThread", | 1467 "NaClSecureCommandChannel__NaClSimpleServiceStartServiceThread", |
| 1770 !NaClSimpleServiceStartServiceThread((struct NaClSimpleService *) | 1468 !NaClSimpleServiceStartServiceThread((struct NaClSimpleService *) |
| 1771 secure_command_server))) { | 1469 secure_command_server))) { |
| 1772 NaClLog(LOG_FATAL, | 1470 NaClLog(LOG_FATAL, |
| 1773 "Could not start secure command channel service thread\n"); | 1471 "Could not start secure command channel service thread\n"); |
| 1774 } | 1472 } |
| 1775 | 1473 |
| 1776 NaClLog(4, "Leaving NaClSecureCommandChannel\n"); | 1474 NaClLog(4, "Leaving NaClSecureCommandChannel\n"); |
| 1777 } | 1475 } |
| 1778 | 1476 |
| 1477 struct NaClSrpcHandlerDesc const secure_handlers[] = { |
| 1478 { "hard_shutdown::", NaClSecureChannelShutdownRpc, }, |
| 1479 { "start_module::i", NaClSecureChannelStartModuleRpc, }, |
| 1480 { "log:is:", NaClSecureChannelLog, }, |
| 1481 { "load_module:hs:", NaClLoadModuleRpc, }, |
| 1482 { "load_irt:h:", NaClLoadIrtRpc, }, |
| 1483 { "reverse_setup::h", NaClSecureReverseClientSetup, }, |
| 1484 /* add additional calls here. upcall set up? start module signal? */ |
| 1485 { (char const *) NULL, (NaClSrpcMethod) NULL, }, |
| 1486 }; |
| 1779 | 1487 |
| 1780 /* | 1488 /* |
| 1781 * It is fine to have multiple I/O operations read from memory in Write | 1489 * It is fine to have multiple I/O operations read from memory in Write |
| 1782 * or SendMsg like operations. | 1490 * or SendMsg like operations. |
| 1783 */ | 1491 */ |
| 1784 void NaClVmIoWillStart(struct NaClApp *nap, | 1492 void NaClVmIoWillStart(struct NaClApp *nap, |
| 1785 uint32_t addr_first_usr, | 1493 uint32_t addr_first_usr, |
| 1786 uint32_t addr_last_usr) { | 1494 uint32_t addr_last_usr) { |
| 1787 NaClXMutexLock(&nap->mu); | 1495 NaClXMutexLock(&nap->mu); |
| 1788 (*nap->mem_io_regions->vtbl->AddInterval)(nap->mem_io_regions, | 1496 (*nap->mem_io_regions->vtbl->AddInterval)(nap->mem_io_regions, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 nacl_global_xlate_base = mem_start; | 1557 nacl_global_xlate_base = mem_start; |
| 1850 | 1558 |
| 1851 NaClSandboxMemoryStartForValgrind(mem_start); | 1559 NaClSandboxMemoryStartForValgrind(mem_start); |
| 1852 | 1560 |
| 1853 _ovly_debug_event(); | 1561 _ovly_debug_event(); |
| 1854 } | 1562 } |
| 1855 | 1563 |
| 1856 void NaClGdbHook(struct NaClApp const *nap) { | 1564 void NaClGdbHook(struct NaClApp const *nap) { |
| 1857 StopForDebuggerInit(nap->mem_start); | 1565 StopForDebuggerInit(nap->mem_start); |
| 1858 } | 1566 } |
| OLD | NEW |