Chromium Code Reviews| 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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->bootstrap_channel = NULL; | 159 nap->bootstrap_channel = NULL; |
| 160 nap->secure_service = NULL; | 160 nap->secure_service = NULL; |
| 161 | |
| 162 nap->num_secure_channel = 0; | |
| 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 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1260 if (NULL != nap->secure_service) { | 1263 if (NULL != nap->secure_service) { |
| 1261 for (;;) { | 1264 for (;;) { |
| 1262 struct nacl_abi_timespec req; | 1265 struct nacl_abi_timespec req; |
| 1263 req.tv_sec = 1000; | 1266 req.tv_sec = 1000; |
| 1264 req.tv_nsec = 0; | 1267 req.tv_nsec = 0; |
| 1265 NaClNanosleep(&req, (struct nacl_abi_timespec *) NULL); | 1268 NaClNanosleep(&req, (struct nacl_abi_timespec *) NULL); |
| 1266 } | 1269 } |
| 1267 } | 1270 } |
| 1268 } | 1271 } |
| 1269 | 1272 |
| 1270 | |
| 1271 /* | |
| 1272 * Secure command channels. | |
| 1273 */ | |
| 1274 | |
| 1275 struct NaClSecureService { | |
| 1276 struct NaClSimpleService base; | |
| 1277 struct NaClApp *nap; | |
| 1278 }; | |
| 1279 | |
| 1280 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl; | |
| 1281 | |
| 1282 | |
| 1283 struct NaClConnectionHandler { | |
| 1284 struct NaClConnectionHandler *next; | |
| 1285 | |
| 1286 /* used by NaClSimpleRevServiceClient's ClientCallback fn */ | |
| 1287 void (*handler)( | |
| 1288 void *state, | |
| 1289 struct NaClThreadInterface *tif, | |
| 1290 struct NaClDesc *conn); | |
| 1291 void *state; | |
| 1292 }; | |
| 1293 | |
| 1294 struct NaClSecureReverseClient { | |
| 1295 struct NaClSimpleRevClient base; | |
| 1296 struct NaClApp *nap; | |
| 1297 | |
| 1298 struct NaClMutex mu; | |
| 1299 | |
| 1300 struct NaClConnectionHandler *queue_head; | |
| 1301 struct NaClConnectionHandler **queue_insert; | |
| 1302 }; | |
| 1303 | |
| 1304 struct NaClSimpleRevClientVtbl const kNaClSecureReverseClientVtbl; | |
| 1305 | |
| 1306 | |
| 1307 int NaClSecureServiceCtor(struct NaClSecureService *self, | |
| 1308 struct NaClSrpcHandlerDesc const *srpc_handlers, | |
| 1309 struct NaClApp *nap) { | |
| 1310 NaClLog(4, | |
| 1311 "Entered NaClSecureServiceCtor: self 0x%"NACL_PRIxPTR"\n", | |
| 1312 (uintptr_t) self); | |
| 1313 if (NACL_FI_ERROR_COND( | |
| 1314 "NaClSecureServiceCtor__NaClSimpleServiceWithSocketCtor", | |
| 1315 !NaClSimpleServiceWithSocketCtor( | |
| 1316 &self->base, | |
| 1317 srpc_handlers, | |
| 1318 NaClThreadInterfaceThreadFactory, | |
| 1319 (void *) NULL, | |
| 1320 nap->service_port, | |
| 1321 nap->service_address))) { | |
| 1322 goto failure_simple_ctor; | |
| 1323 } | |
| 1324 self->nap = nap; | |
| 1325 | |
| 1326 NACL_VTBL(NaClRefCount, self) = | |
| 1327 (struct NaClRefCountVtbl *) &kNaClSecureServiceVtbl; | |
| 1328 return 1; | |
| 1329 failure_simple_ctor: | |
| 1330 return 0; | |
| 1331 } | |
| 1332 | |
| 1333 void NaClSecureServiceDtor(struct NaClRefCount *vself) { | |
| 1334 struct NaClSecureService *self = (struct NaClSecureService *) vself; | |
| 1335 | |
| 1336 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *) | |
| 1337 &kNaClSimpleServiceVtbl; | |
| 1338 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); | |
| 1339 } | |
| 1340 | |
| 1341 /* | 1273 /* |
| 1342 * The first connection is performed by this callback handler. This | 1274 * The first connection is performed by this callback handler. This |
| 1343 * spawns a client thread that will bootstrap the other connections by | 1275 * spawns a client thread that will bootstrap the other connections by |
| 1344 * stashing the connection represented by |conn| to make reverse RPCs | 1276 * stashing the connection represented by |conn| to make reverse RPCs |
| 1345 * to ask the peer to connect to us. No thread is spawned; we just | 1277 * to ask the peer to connect to us. No thread is spawned; we just |
| 1346 * wrap access to the connection with a lock. | 1278 * wrap access to the connection with a lock. |
| 1347 * | 1279 * |
| 1348 * Subsequent connection callbacks will pass the connection to the | 1280 * Subsequent connection callbacks will pass the connection to the |
| 1349 * actual thread that made the connection request using |conn| | 1281 * actual thread that made the connection request using |conn| |
| 1350 * received in the first connection. | 1282 * received in the first connection. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1390 NaClLog(LOG_FATAL, "Reverse quota interface Ctor failed\n"); | 1322 NaClLog(LOG_FATAL, "Reverse quota interface Ctor failed\n"); |
| 1391 } | 1323 } |
| 1392 nap->reverse_channel_initialization_state = NACL_REVERSE_CHANNEL_INITIALIZED; | 1324 nap->reverse_channel_initialization_state = NACL_REVERSE_CHANNEL_INITIALIZED; |
| 1393 | 1325 |
| 1394 NaClXCondVarBroadcast(&nap->cv); | 1326 NaClXCondVarBroadcast(&nap->cv); |
| 1395 NaClXMutexUnlock(&nap->mu); | 1327 NaClXMutexUnlock(&nap->mu); |
| 1396 | 1328 |
| 1397 NaClLog(4, "Leaving NaClSecureReverseClientCallback\n"); | 1329 NaClLog(4, "Leaving NaClSecureReverseClientCallback\n"); |
| 1398 } | 1330 } |
| 1399 | 1331 |
| 1400 /* fwd */ | |
| 1401 int NaClSecureReverseClientCtor( | |
| 1402 struct NaClSecureReverseClient *self, | |
| 1403 void (*client_callback)( | |
| 1404 void *, struct NaClThreadInterface *, struct NaClDesc *), | |
| 1405 void *state, | |
| 1406 struct NaClApp *nap); | |
| 1407 | |
| 1408 static void NaClSecureReverseClientSetup(struct NaClSrpcRpc *rpc, | 1332 static void NaClSecureReverseClientSetup(struct NaClSrpcRpc *rpc, |
| 1409 struct NaClSrpcArg **in_args, | 1333 struct NaClSrpcArg **in_args, |
| 1410 struct NaClSrpcArg **out_args, | 1334 struct NaClSrpcArg **out_args, |
| 1411 struct NaClSrpcClosure *done) { | 1335 struct NaClSrpcClosure *done) { |
| 1412 struct NaClApp *nap = | 1336 struct NaClApp *nap = |
| 1413 (struct NaClApp *) rpc->channel->server_instance_data; | 1337 (struct NaClApp *) rpc->channel->server_instance_data; |
| 1414 struct NaClSecureReverseClient *rev; | 1338 struct NaClSecureReverseClient *rev; |
| 1415 | 1339 |
| 1416 UNREFERENCED_PARAMETER(in_args); | 1340 UNREFERENCED_PARAMETER(in_args); |
| 1417 NaClLog(4, "Entered NaClSecureReverseClientSetup\n"); | 1341 NaClLog(4, "Entered NaClSecureReverseClientSetup\n"); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1466 if (!NaClSimpleRevClientStartServiceThread(&rev->base)) { | 1390 if (!NaClSimpleRevClientStartServiceThread(&rev->base)) { |
| 1467 NaClLog(LOG_FATAL, "Could not start reverse service thread\n"); | 1391 NaClLog(LOG_FATAL, "Could not start reverse service thread\n"); |
| 1468 } | 1392 } |
| 1469 | 1393 |
| 1470 done: | 1394 done: |
| 1471 NaClXMutexUnlock(&nap->mu); | 1395 NaClXMutexUnlock(&nap->mu); |
| 1472 (*done->Run)(done); | 1396 (*done->Run)(done); |
| 1473 NaClLog(4, "Leaving NaClSecureReverseClientSetup\n"); | 1397 NaClLog(4, "Leaving NaClSecureReverseClientSetup\n"); |
| 1474 } | 1398 } |
| 1475 | 1399 |
| 1476 /* | 1400 struct NaClSrpcHandlerDesc const secure_handlers[]; /* fwd */ |
| 1477 * Only called at startup and thereafter by the reverse secure | |
| 1478 * channel, with |self| locked. | |
| 1479 */ | |
| 1480 static | |
| 1481 int NaClSecureReverseClientInsertHandler_mu( | |
| 1482 struct NaClSecureReverseClient *self, | |
| 1483 void (*h)(void *, | |
| 1484 struct NaClThreadInterface *, | |
| 1485 struct NaClDesc *), | |
| 1486 void *d) { | |
| 1487 struct NaClConnectionHandler *entry; | |
| 1488 | 1401 |
| 1402 static void NaClSecureCommandServiceSetupRpc(struct NaClSrpcRpc *rpc, | |
| 1403 struct NaClSrpcArg **in_args, | |
| 1404 struct NaClSrpcArg **out_args, | |
| 1405 struct NaClSrpcClosure *done) { | |
| 1406 struct NaClApp *nap = | |
| 1407 (struct NaClApp *) rpc->channel->server_instance_data; | |
| 1408 struct NaClSecureService *secure_service; | |
| 1409 struct NaClDesc *pair[2]; | |
|
bsy
2012/09/25 18:37:10
plz make the pair be part of the NaClApp object as
Petr Hosek
2012/09/25 23:09:11
Separated secure command channel and untrusted app
| |
| 1410 | |
| 1411 UNREFERENCED_PARAMETER(in_args); | |
| 1412 NaClLog(4, "Entered NaClSecureCommandServiceSetupRpc\n"); | |
| 1413 | |
| 1414 if (0 != NaClCommonDescMakeBoundSock(pair)) { | |
| 1415 NaClLog(LOG_FATAL, "Cound not create service socket\n"); | |
| 1416 } | |
| 1489 NaClLog(4, | 1417 NaClLog(4, |
| 1490 ("NaClSecureReverseClientInsertHandler_mu: h 0x%"NACL_PRIxPTR"," | 1418 "got bound socket at 0x%08"NACL_PRIxPTR", " |
| 1491 " d 0x%"NACL_PRIxPTR"\n"), | 1419 "addr at 0x%08"NACL_PRIxPTR"\n", |
| 1492 (uintptr_t) h, | 1420 (uintptr_t) pair[0], |
| 1493 (uintptr_t) d); | 1421 (uintptr_t) pair[1]); |
| 1494 entry = (struct NaClConnectionHandler *) malloc(sizeof *entry); | 1422 |
| 1495 if (NULL == entry) { | 1423 secure_service = (struct NaClSecureService *) malloc( |
| 1496 return 0; | 1424 sizeof *secure_service); |
| 1425 if (NULL == secure_service) { | |
| 1426 NaClLog(LOG_ERROR, "Out of memory for secure command channel\n"); | |
| 1427 rpc->result = NACL_SRPC_RESULT_APP_ERROR; | |
| 1428 goto done; | |
| 1497 } | 1429 } |
| 1498 entry->handler = h; | 1430 if (!NaClSecureServiceCtor(secure_service, |
| 1499 entry->state = d; | 1431 secure_handlers, |
| 1500 entry->next = (struct NaClConnectionHandler *) NULL; | 1432 nap, |
| 1501 *self->queue_insert = entry; | 1433 pair[0], |
| 1502 self->queue_insert = &entry->next; | 1434 pair[1])) { |
| 1435 NaClLog(LOG_ERROR, "NaClSecureServiceCtor failed\n"); | |
| 1436 free(secure_service); | |
| 1437 rpc->result = NACL_SRPC_RESULT_APP_ERROR; | |
| 1438 goto done; | |
| 1439 } | |
| 1440 out_args[0]->u.hval = NaClDescRef(pair[1]); | |
| 1441 rpc->result = NACL_SRPC_RESULT_OK; | |
| 1503 | 1442 |
| 1504 return 1; | 1443 NaClLog(4, "NaClSecureCommandChannel: starting service thread\n"); |
| 1505 } | 1444 if (!NaClSimpleServiceStartServiceThread((struct NaClSimpleService *) |
| 1506 | 1445 secure_service)) { |
| 1507 /* | |
| 1508 * Caller must set up handler before issuing connection request RPC on | |
| 1509 * nap->reverse_channel, since otherwise the connection handler queue | |
| 1510 * may be empty and the connect code would abort. Because the connect | |
| 1511 * doesn't wait for a handler, we don't need a condvar. | |
| 1512 * | |
| 1513 * We do not need to serialize on the handlers, since the | |
| 1514 * RPC-server/IMC-client implementation should not distinguish one | |
| 1515 * connection from another: it is okay for two handlers to be | |
| 1516 * inserted, and two connection request RPCs to be preformed | |
| 1517 * (sequentially, since they are over a single channel), and have the | |
| 1518 * server side spawn threads that asynchronously connect twice, in the | |
| 1519 * "incorrect" order, etc. | |
| 1520 */ | |
| 1521 int NaClSecureReverseClientInsertHandler( | |
| 1522 struct NaClSecureReverseClient *self, | |
| 1523 void (*handler)( | |
| 1524 void *handlr_state, | |
| 1525 struct NaClThreadInterface *thread_if, | |
| 1526 struct NaClDesc *new_conn), | |
| 1527 void *handler_state) { | |
| 1528 int retval; | |
| 1529 | |
| 1530 NaClXMutexLock(&self->mu); | |
| 1531 retval = NaClSecureReverseClientInsertHandler_mu(self, | |
| 1532 handler, handler_state); | |
| 1533 NaClXMutexUnlock(&self->mu); | |
| 1534 return retval; | |
| 1535 } | |
| 1536 | |
| 1537 static | |
| 1538 struct NaClConnectionHandler *NaClSecureReverseClientPopHandler( | |
| 1539 struct NaClSecureReverseClient *self) { | |
| 1540 struct NaClConnectionHandler *head; | |
| 1541 | |
| 1542 NaClLog(4, "Entered NaClSecureReverseClientPopHandler, acquiring lock\n"); | |
| 1543 NaClXMutexLock(&self->mu); | |
| 1544 NaClLog(4, "NaClSecureReverseClientPopHandler, got lock\n"); | |
| 1545 head = self->queue_head; | |
| 1546 if (NULL == head) { | |
| 1547 NaClLog(LOG_FATAL, | 1446 NaClLog(LOG_FATAL, |
| 1548 "NaClSecureReverseClientPopHandler: empty handler queue\n"); | 1447 "Could not start secure command channel service thread\n"); |
| 1549 } | |
| 1550 if (NULL == (self->queue_head = head->next)) { | |
| 1551 NaClLog(4, "NaClSecureReverseClientPopHandler, last elt patch up\n"); | |
| 1552 self->queue_insert = &self->queue_head; | |
| 1553 } | |
| 1554 NaClLog(4, "NaClSecureReverseClientPopHandler, unlocking\n"); | |
| 1555 NaClXMutexUnlock(&self->mu); | |
| 1556 | |
| 1557 head->next = NULL; | |
| 1558 NaClLog(4, | |
| 1559 ("Leaving NaClSecureReverseClientPopHandler:" | |
| 1560 " returning %"NACL_PRIxPTR"\n"), | |
| 1561 (uintptr_t) head); | |
| 1562 return head; | |
| 1563 } | |
| 1564 | |
| 1565 static | |
| 1566 void NaClSecureReverseClientInternalCallback( | |
| 1567 void *state, | |
| 1568 struct NaClThreadInterface *tif, | |
| 1569 struct NaClDesc *conn) { | |
| 1570 struct NaClSecureReverseClient *self = | |
| 1571 (struct NaClSecureReverseClient *) state; | |
| 1572 struct NaClConnectionHandler *hand_ptr; | |
| 1573 | |
| 1574 UNREFERENCED_PARAMETER(tif); | |
| 1575 NaClLog(4, "Entered NaClSecureReverseClientInternalCallback\n"); | |
| 1576 hand_ptr = NaClSecureReverseClientPopHandler(self); | |
| 1577 NaClLog(4, " got callback object %"NACL_PRIxPTR"\n", (uintptr_t) hand_ptr); | |
| 1578 NaClLog(4, | |
| 1579 " callback:0x%"NACL_PRIxPTR"(0x%"NACL_PRIxPTR",0x%"NACL_PRIxPTR")\n", | |
| 1580 (uintptr_t) hand_ptr->handler, | |
| 1581 (uintptr_t) hand_ptr->state, | |
| 1582 (uintptr_t) conn); | |
| 1583 (*hand_ptr->handler)(hand_ptr->state, tif, conn); | |
| 1584 NaClLog(4, "NaClSecureReverseClientInternalCallback: freeing memory\n"); | |
| 1585 free(hand_ptr); | |
| 1586 NaClLog(4, "Leaving NaClSecureReverseClientInternalCallback\n"); | |
| 1587 } | |
| 1588 | |
| 1589 /* | |
| 1590 * Require an initial connection handler in the Ctor, so that it's | |
| 1591 * obvious that a reverse client needs to accept an IMC connection | |
| 1592 * from the server to get things bootstrapped. | |
| 1593 */ | |
| 1594 int NaClSecureReverseClientCtor( | |
| 1595 struct NaClSecureReverseClient *self, | |
| 1596 void (*client_callback)( | |
| 1597 void *, struct NaClThreadInterface*, struct NaClDesc *), | |
| 1598 void *state, | |
| 1599 struct NaClApp *nap) { | |
| 1600 NaClLog(4, | |
| 1601 ("Entered NaClSecureReverseClientCtor, self 0x%"NACL_PRIxPTR"," | |
| 1602 " nap 0x%"NACL_PRIxPTR"\n"), | |
| 1603 (uintptr_t) self, | |
| 1604 (uintptr_t) nap); | |
| 1605 if (!NaClSimpleRevClientCtor(&self->base, | |
| 1606 NaClSecureReverseClientInternalCallback, | |
| 1607 (void *) self, | |
| 1608 NaClThreadInterfaceThreadFactory, | |
| 1609 (void *) NULL)) { | |
| 1610 goto failure_simple_ctor; | |
| 1611 } | |
| 1612 NaClLog(4, "NaClSecureReverseClientCtor: Mutex\n"); | |
| 1613 if (!NaClMutexCtor(&self->mu)) { | |
| 1614 goto failure_mutex_ctor; | |
| 1615 } | |
| 1616 self->nap = nap; | |
| 1617 self->queue_head = (struct NaClConnectionHandler *) NULL; | |
| 1618 self->queue_insert = &self->queue_head; | |
| 1619 | |
| 1620 NACL_VTBL(NaClRefCount, self) = | |
| 1621 (struct NaClRefCountVtbl *) &kNaClSecureReverseClientVtbl; | |
| 1622 | |
| 1623 NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler\n"); | |
| 1624 if (!NaClSecureReverseClientInsertHandler(self, | |
| 1625 client_callback, | |
| 1626 state)) { | |
| 1627 goto failure_handler_insert; | |
| 1628 } | 1448 } |
| 1629 | 1449 |
| 1630 NaClLog(4, "Leaving NaClSecureReverseClientCtor\n"); | 1450 done: |
| 1631 return 1; | 1451 (*done->Run)(done); |
| 1632 | 1452 NaClLog(4, "Leaving NaClSecureCommandServiceSetupRpc\n"); |
| 1633 failure_handler_insert: | |
| 1634 NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler failed\n"); | |
| 1635 NACL_VTBL(NaClRefCount, self) = | |
| 1636 (struct NaClRefCountVtbl *) &kNaClSimpleRevClientVtbl; | |
| 1637 | |
| 1638 self->nap = NULL; | |
| 1639 self->queue_insert = (struct NaClConnectionHandler **) NULL; | |
| 1640 NaClMutexDtor(&self->mu); | |
| 1641 | |
| 1642 failure_mutex_ctor: | |
| 1643 NaClLog(4, "NaClSecureReverseClientCtor: Mutex failed\n"); | |
| 1644 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self); | |
| 1645 failure_simple_ctor: | |
| 1646 NaClLog(4, "Leaving NaClSecureReverseClientCtor\n"); | |
| 1647 return 0; | |
| 1648 } | 1453 } |
| 1649 | 1454 |
| 1650 void NaClSecureReverseClientDtor(struct NaClRefCount *vself) { | |
| 1651 struct NaClSecureReverseClient *self = | |
| 1652 (struct NaClSecureReverseClient *) vself; | |
| 1653 | |
| 1654 struct NaClConnectionHandler *entry; | |
| 1655 struct NaClConnectionHandler *next; | |
| 1656 | |
| 1657 for (entry = self->queue_head; NULL != entry; entry = next) { | |
| 1658 next = entry->next; | |
| 1659 free(entry); | |
| 1660 } | |
| 1661 NaClMutexDtor(&self->mu); | |
| 1662 | |
| 1663 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *) | |
| 1664 &kNaClSimpleRevClientVtbl; | |
| 1665 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); | |
| 1666 } | |
| 1667 | |
| 1668 int NaClSecureServiceConnectionFactory( | |
| 1669 struct NaClSimpleService *vself, | |
| 1670 struct NaClDesc *conn, | |
| 1671 struct NaClSimpleServiceConnection **out) { | |
| 1672 struct NaClSecureService *self = | |
| 1673 (struct NaClSecureService *) vself; | |
| 1674 | |
| 1675 /* our instance_data is not connection specific */ | |
| 1676 return NaClSimpleServiceConnectionFactoryWithInstanceData( | |
| 1677 vself, conn, (void *) self->nap, out); | |
| 1678 } | |
| 1679 | |
| 1680 int NaClSecureServiceAcceptAndSpawnHandler(struct NaClSimpleService *vself) { | |
| 1681 int rv; | |
| 1682 | |
| 1683 NaClLog(4, | |
| 1684 "NaClSecureServiceAcceptAndSpawnHandler: invoking base class vfn\n"); | |
| 1685 rv = (*kNaClSimpleServiceVtbl.AcceptAndSpawnHandler)(vself); | |
| 1686 if (0 != rv) { | |
| 1687 NaClLog(LOG_FATAL, | |
| 1688 "Secure channel AcceptAndSpawnHandler returned %d\n", | |
| 1689 rv); | |
| 1690 } | |
| 1691 NaClThreadExit(0); | |
| 1692 /* | |
| 1693 * NOTREACHED The port is now to be used by untrusted code: all | |
| 1694 * subsequent connections are handled there. | |
| 1695 */ | |
| 1696 return rv; | |
| 1697 } | |
| 1698 | |
| 1699 void NaClSecureServiceRpcHandler(struct NaClSimpleService *vself, | |
| 1700 struct NaClSimpleServiceConnection *vconn) { | |
| 1701 | |
| 1702 NaClLog(4, "NaClSecureChannelThread started\n"); | |
| 1703 (*kNaClSimpleServiceVtbl.RpcHandler)(vself, vconn); | |
| 1704 NaClLog(4, "NaClSecureChannelThread: channel closed, exiting.\n"); | |
| 1705 NaClExit(0); | |
| 1706 } | |
| 1707 | |
| 1708 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl = { | |
| 1709 { | |
| 1710 NaClSecureServiceDtor, | |
| 1711 }, | |
| 1712 NaClSecureServiceConnectionFactory, | |
| 1713 NaClSimpleServiceAcceptConnection, | |
| 1714 NaClSecureServiceAcceptAndSpawnHandler, | |
| 1715 NaClSecureServiceRpcHandler, | |
| 1716 }; | |
| 1717 | |
| 1718 struct NaClSimpleRevClientVtbl const kNaClSecureReverseClientVtbl = { | |
| 1719 { | |
| 1720 NaClSecureReverseClientDtor, | |
| 1721 }, | |
| 1722 }; | |
| 1723 | |
| 1724 | |
| 1725 void NaClSecureCommandChannel(struct NaClApp *nap) { | 1455 void NaClSecureCommandChannel(struct NaClApp *nap) { |
| 1726 struct NaClSecureService *secure_command_server; | 1456 struct NaClSecureService *secure_command_server; |
| 1727 | 1457 |
| 1728 static struct NaClSrpcHandlerDesc const secure_handlers[] = { | |
| 1729 { "hard_shutdown::", NaClSecureChannelShutdownRpc, }, | |
| 1730 { "start_module::i", NaClSecureChannelStartModuleRpc, }, | |
| 1731 { "log:is:", NaClSecureChannelLog, }, | |
| 1732 { "load_module:hs:", NaClLoadModuleRpc, }, | |
| 1733 { "load_irt:h:", NaClLoadIrtRpc, }, | |
| 1734 { "reverse_setup::h", NaClSecureReverseClientSetup, }, | |
| 1735 /* add additional calls here. upcall set up? start module signal? */ | |
| 1736 { (char const *) NULL, (NaClSrpcMethod) NULL, }, | |
| 1737 }; | |
| 1738 | |
| 1739 NaClLog(4, "Entered NaClSecureCommandChannel\n"); | 1458 NaClLog(4, "Entered NaClSecureCommandChannel\n"); |
| 1740 | 1459 |
| 1741 secure_command_server = (struct NaClSecureService *) malloc( | 1460 secure_command_server = (struct NaClSecureService *) malloc( |
| 1742 sizeof *secure_command_server); | 1461 sizeof *secure_command_server); |
| 1743 if (NACL_FI_ERROR_COND("NaClSecureCommandChannel__malloc", | 1462 if (NACL_FI_ERROR_COND("NaClSecureCommandChannel__malloc", |
| 1744 NULL == secure_command_server)) { | 1463 NULL == secure_command_server)) { |
| 1745 NaClLog(LOG_FATAL, "Out of memory for secure command channel\n"); | 1464 NaClLog(LOG_FATAL, "Out of memory for secure command channel\n"); |
| 1746 } | 1465 } |
| 1747 if (NACL_FI_ERROR_COND("NaClSecureCommandChannel__NaClSecureServiceCtor", | 1466 if (NACL_FI_ERROR_COND("NaClSecureCommandChannel__NaClSecureServiceCtor", |
| 1748 !NaClSecureServiceCtor(secure_command_server, | 1467 !NaClSecureServiceCtor(secure_command_server, |
| 1749 secure_handlers, nap))) { | 1468 secure_handlers, |
| 1469 nap, | |
| 1470 nap->service_port, | |
| 1471 nap->service_address))) { | |
| 1750 NaClLog(LOG_FATAL, "NaClSecureServiceCtor failed\n"); | 1472 NaClLog(LOG_FATAL, "NaClSecureServiceCtor failed\n"); |
| 1751 } | 1473 } |
| 1752 nap->secure_service = secure_command_server; | 1474 nap->secure_service = secure_command_server; |
| 1753 | 1475 |
| 1754 NaClLog(4, "NaClSecureCommandChannel: starting service thread\n"); | 1476 NaClLog(4, "NaClSecureCommandChannel: starting service thread\n"); |
| 1755 if (NACL_FI_ERROR_COND( | 1477 if (NACL_FI_ERROR_COND( |
| 1756 "NaClSecureCommandChannel__NaClSimpleServiceStartServiceThread", | 1478 "NaClSecureCommandChannel__NaClSimpleServiceStartServiceThread", |
| 1757 !NaClSimpleServiceStartServiceThread((struct NaClSimpleService *) | 1479 !NaClSimpleServiceStartServiceThread((struct NaClSimpleService *) |
| 1758 secure_command_server))) { | 1480 secure_command_server))) { |
| 1759 NaClLog(LOG_FATAL, | 1481 NaClLog(LOG_FATAL, |
| 1760 "Could not start secure command channel service thread\n"); | 1482 "Could not start secure command channel service thread\n"); |
| 1761 } | 1483 } |
| 1762 | 1484 |
| 1763 NaClLog(4, "Leaving NaClSecureCommandChannel\n"); | 1485 NaClLog(4, "Leaving NaClSecureCommandChannel\n"); |
| 1764 } | 1486 } |
| 1765 | 1487 |
| 1488 struct NaClSrpcHandlerDesc const secure_handlers[] = { | |
| 1489 { "hard_shutdown::", NaClSecureChannelShutdownRpc, }, | |
| 1490 { "start_module::i", NaClSecureChannelStartModuleRpc, }, | |
| 1491 { "log:is:", NaClSecureChannelLog, }, | |
| 1492 { "load_module:hs:", NaClLoadModuleRpc, }, | |
| 1493 { "load_irt:h:", NaClLoadIrtRpc, }, | |
| 1494 { "reverse_setup::h", NaClSecureReverseClientSetup, }, | |
| 1495 { "command_setup::h", NaClSecureCommandServiceSetupRpc, }, | |
| 1496 /* add additional calls here. upcall set up? start module signal? */ | |
| 1497 { (char const *) NULL, (NaClSrpcMethod) NULL, }, | |
| 1498 }; | |
| 1499 | |
| 1500 void NaClSecureChannelCountIncr(struct NaClApp *nap) { | |
| 1501 NaClLog(4, "NaClSecureChannelCountIncr\n"); | |
| 1502 NaClXMutexLock(&nap->mu); | |
| 1503 if (0 == ++nap->num_secure_channel) { | |
| 1504 NaClLog(LOG_FATAL, | |
| 1505 "NaClSecureChannelCountIncr: " | |
| 1506 "secure channel count overflow!\n"); | |
| 1507 } | |
| 1508 NaClXMutexUnlock(&nap->mu); | |
| 1509 } | |
| 1510 | |
| 1511 void NaClSecureChannelCountDecr(struct NaClApp *nap) { | |
| 1512 NaClLog(4, "NaClSecureChannelCountDecr\n"); | |
| 1513 NaClXMutexLock(&nap->mu); | |
| 1514 if (0 == nap->num_secure_channel) { | |
| 1515 NaClLog(4, | |
| 1516 "NaClSecureChannelCountDecr: " | |
| 1517 "no more secure channels, exiting.\n"); | |
| 1518 NaClExit(0); | |
| 1519 } | |
| 1520 if (0 == --nap->num_secure_channel) { | |
| 1521 NaClXCondVarBroadcast(&nap->cv); | |
| 1522 } | |
| 1523 NaClXMutexUnlock(&nap->mu); | |
| 1524 } | |
| 1766 | 1525 |
| 1767 /* | 1526 /* |
| 1768 * It is fine to have multiple I/O operations read from memory in Write | 1527 * It is fine to have multiple I/O operations read from memory in Write |
| 1769 * or SendMsg like operations. | 1528 * or SendMsg like operations. |
| 1770 */ | 1529 */ |
| 1771 void NaClVmIoWillStart(struct NaClApp *nap, | 1530 void NaClVmIoWillStart(struct NaClApp *nap, |
| 1772 uint32_t addr_first_usr, | 1531 uint32_t addr_first_usr, |
| 1773 uint32_t addr_last_usr) { | 1532 uint32_t addr_last_usr) { |
| 1774 NaClXMutexLock(&nap->mu); | 1533 NaClXMutexLock(&nap->mu); |
| 1775 (*nap->mem_io_regions->vtbl->AddInterval)(nap->mem_io_regions, | 1534 (*nap->mem_io_regions->vtbl->AddInterval)(nap->mem_io_regions, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1836 nacl_global_xlate_base = mem_start; | 1595 nacl_global_xlate_base = mem_start; |
| 1837 | 1596 |
| 1838 NaClSandboxMemoryStartForValgrind(mem_start); | 1597 NaClSandboxMemoryStartForValgrind(mem_start); |
| 1839 | 1598 |
| 1840 _ovly_debug_event(); | 1599 _ovly_debug_event(); |
| 1841 } | 1600 } |
| 1842 | 1601 |
| 1843 void NaClGdbHook(struct NaClApp const *nap) { | 1602 void NaClGdbHook(struct NaClApp const *nap) { |
| 1844 StopForDebuggerInit(nap->mem_start); | 1603 StopForDebuggerInit(nap->mem_start); |
| 1845 } | 1604 } |
| OLD | NEW |