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

Side by Side Diff: src/trusted/service_runtime/sel_ldr.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: Dropped Command Service. 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
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 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 if (NULL != nap->secure_service) { 1253 if (NULL != nap->secure_service) {
1254 for (;;) { 1254 for (;;) {
1255 struct nacl_abi_timespec req; 1255 struct nacl_abi_timespec req;
1256 req.tv_sec = 1000; 1256 req.tv_sec = 1000;
1257 req.tv_nsec = 0; 1257 req.tv_nsec = 0;
1258 NaClNanosleep(&req, (struct nacl_abi_timespec *) NULL); 1258 NaClNanosleep(&req, (struct nacl_abi_timespec *) NULL);
1259 } 1259 }
1260 } 1260 }
1261 } 1261 }
1262 1262
1263
1264 /*
1265 * Secure command channels.
1266 */
1267
1268 struct NaClSecureService {
1269 struct NaClSimpleService base;
1270 struct NaClApp *nap;
1271 };
1272
1273 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl;
1274
1275
1276 struct NaClConnectionHandler {
1277 struct NaClConnectionHandler *next;
1278
1279 /* used by NaClSimpleRevServiceClient's ClientCallback fn */
1280 void (*handler)(
1281 void *state,
1282 struct NaClThreadInterface *tif,
1283 struct NaClDesc *conn);
1284 void *state;
1285 };
1286
1287 struct NaClSecureReverseClient {
1288 struct NaClSimpleRevClient base;
1289 struct NaClApp *nap;
1290
1291 struct NaClMutex mu;
1292
1293 struct NaClConnectionHandler *queue_head;
1294 struct NaClConnectionHandler **queue_insert;
1295 };
1296
1297 struct NaClSimpleRevClientVtbl const kNaClSecureReverseClientVtbl;
1298
1299
1300 int NaClSecureServiceCtor(struct NaClSecureService *self,
1301 struct NaClSrpcHandlerDesc const *srpc_handlers,
1302 struct NaClApp *nap) {
1303 NaClLog(4,
1304 "Entered NaClSecureServiceCtor: self 0x%"NACL_PRIxPTR"\n",
1305 (uintptr_t) self);
1306 if (NACL_FI_ERROR_COND(
1307 "NaClSecureServiceCtor__NaClSimpleServiceWithSocketCtor",
1308 !NaClSimpleServiceWithSocketCtor(
1309 &self->base,
1310 srpc_handlers,
1311 NaClThreadInterfaceThreadFactory,
1312 (void *) NULL,
1313 nap->service_port,
1314 nap->service_address))) {
1315 goto failure_simple_ctor;
1316 }
1317 self->nap = nap;
1318
1319 NACL_VTBL(NaClRefCount, self) =
1320 (struct NaClRefCountVtbl *) &kNaClSecureServiceVtbl;
1321 return 1;
1322 failure_simple_ctor:
1323 return 0;
1324 }
1325
1326 void NaClSecureServiceDtor(struct NaClRefCount *vself) {
1327 struct NaClSecureService *self = (struct NaClSecureService *) vself;
1328
1329 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *)
1330 &kNaClSimpleServiceVtbl;
1331 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
1332 }
1333
1334 /* 1263 /*
1335 * The first connection is performed by this callback handler. This 1264 * The first connection is performed by this callback handler. This
1336 * spawns a client thread that will bootstrap the other connections by 1265 * spawns a client thread that will bootstrap the other connections by
1337 * stashing the connection represented by |conn| to make reverse RPCs 1266 * stashing the connection represented by |conn| to make reverse RPCs
1338 * to ask the peer to connect to us. No thread is spawned; we just 1267 * to ask the peer to connect to us. No thread is spawned; we just
1339 * wrap access to the connection with a lock. 1268 * wrap access to the connection with a lock.
1340 * 1269 *
1341 * Subsequent connection callbacks will pass the connection to the 1270 * Subsequent connection callbacks will pass the connection to the
1342 * actual thread that made the connection request using |conn| 1271 * actual thread that made the connection request using |conn|
1343 * received in the first connection. 1272 * received in the first connection.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 NaClLog(LOG_FATAL, "Reverse quota interface Ctor failed\n"); 1312 NaClLog(LOG_FATAL, "Reverse quota interface Ctor failed\n");
1384 } 1313 }
1385 nap->reverse_channel_initialization_state = NACL_REVERSE_CHANNEL_INITIALIZED; 1314 nap->reverse_channel_initialization_state = NACL_REVERSE_CHANNEL_INITIALIZED;
1386 1315
1387 NaClXCondVarBroadcast(&nap->cv); 1316 NaClXCondVarBroadcast(&nap->cv);
1388 NaClXMutexUnlock(&nap->mu); 1317 NaClXMutexUnlock(&nap->mu);
1389 1318
1390 NaClLog(4, "Leaving NaClSecureReverseClientCallback\n"); 1319 NaClLog(4, "Leaving NaClSecureReverseClientCallback\n");
1391 } 1320 }
1392 1321
1393 /* fwd */
1394 int NaClSecureReverseClientCtor(
1395 struct NaClSecureReverseClient *self,
1396 void (*client_callback)(
1397 void *, struct NaClThreadInterface *, struct NaClDesc *),
1398 void *state,
1399 struct NaClApp *nap);
1400
1401 static void NaClSecureReverseClientSetup(struct NaClSrpcRpc *rpc, 1322 static void NaClSecureReverseClientSetup(struct NaClSrpcRpc *rpc,
1402 struct NaClSrpcArg **in_args, 1323 struct NaClSrpcArg **in_args,
1403 struct NaClSrpcArg **out_args, 1324 struct NaClSrpcArg **out_args,
1404 struct NaClSrpcClosure *done) { 1325 struct NaClSrpcClosure *done) {
1405 struct NaClApp *nap = 1326 struct NaClApp *nap =
1406 (struct NaClApp *) rpc->channel->server_instance_data; 1327 (struct NaClApp *) rpc->channel->server_instance_data;
1407 struct NaClSecureReverseClient *rev; 1328 struct NaClSecureReverseClient *rev;
1408 1329
1409 UNREFERENCED_PARAMETER(in_args); 1330 UNREFERENCED_PARAMETER(in_args);
1410 NaClLog(4, "Entered NaClSecureReverseClientSetup\n"); 1331 NaClLog(4, "Entered NaClSecureReverseClientSetup\n");
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 if (!NaClSimpleRevClientStartServiceThread(&rev->base)) { 1380 if (!NaClSimpleRevClientStartServiceThread(&rev->base)) {
1460 NaClLog(LOG_FATAL, "Could not start reverse service thread\n"); 1381 NaClLog(LOG_FATAL, "Could not start reverse service thread\n");
1461 } 1382 }
1462 1383
1463 done: 1384 done:
1464 NaClXMutexUnlock(&nap->mu); 1385 NaClXMutexUnlock(&nap->mu);
1465 (*done->Run)(done); 1386 (*done->Run)(done);
1466 NaClLog(4, "Leaving NaClSecureReverseClientSetup\n"); 1387 NaClLog(4, "Leaving NaClSecureReverseClientSetup\n");
1467 } 1388 }
1468 1389
1469 /*
1470 * Only called at startup and thereafter by the reverse secure
1471 * channel, with |self| locked.
1472 */
1473 static
1474 int NaClSecureReverseClientInsertHandler_mu(
1475 struct NaClSecureReverseClient *self,
1476 void (*h)(void *,
1477 struct NaClThreadInterface *,
1478 struct NaClDesc *),
1479 void *d) {
1480 struct NaClConnectionHandler *entry;
1481
1482 NaClLog(4,
1483 ("NaClSecureReverseClientInsertHandler_mu: h 0x%"NACL_PRIxPTR","
1484 " d 0x%"NACL_PRIxPTR"\n"),
1485 (uintptr_t) h,
1486 (uintptr_t) d);
1487 entry = (struct NaClConnectionHandler *) malloc(sizeof *entry);
1488 if (NULL == entry) {
1489 return 0;
1490 }
1491 entry->handler = h;
1492 entry->state = d;
1493 entry->next = (struct NaClConnectionHandler *) NULL;
1494 *self->queue_insert = entry;
1495 self->queue_insert = &entry->next;
1496
1497 return 1;
1498 }
1499
1500 /*
1501 * Caller must set up handler before issuing connection request RPC on
1502 * nap->reverse_channel, since otherwise the connection handler queue
1503 * may be empty and the connect code would abort. Because the connect
1504 * doesn't wait for a handler, we don't need a condvar.
1505 *
1506 * We do not need to serialize on the handlers, since the
1507 * RPC-server/IMC-client implementation should not distinguish one
1508 * connection from another: it is okay for two handlers to be
1509 * inserted, and two connection request RPCs to be preformed
1510 * (sequentially, since they are over a single channel), and have the
1511 * server side spawn threads that asynchronously connect twice, in the
1512 * "incorrect" order, etc.
1513 */
1514 int NaClSecureReverseClientInsertHandler(
1515 struct NaClSecureReverseClient *self,
1516 void (*handler)(
1517 void *handlr_state,
1518 struct NaClThreadInterface *thread_if,
1519 struct NaClDesc *new_conn),
1520 void *handler_state) {
1521 int retval;
1522
1523 NaClXMutexLock(&self->mu);
1524 retval = NaClSecureReverseClientInsertHandler_mu(self,
1525 handler, handler_state);
1526 NaClXMutexUnlock(&self->mu);
1527 return retval;
1528 }
1529
1530 static
1531 struct NaClConnectionHandler *NaClSecureReverseClientPopHandler(
1532 struct NaClSecureReverseClient *self) {
1533 struct NaClConnectionHandler *head;
1534
1535 NaClLog(4, "Entered NaClSecureReverseClientPopHandler, acquiring lock\n");
1536 NaClXMutexLock(&self->mu);
1537 NaClLog(4, "NaClSecureReverseClientPopHandler, got lock\n");
1538 head = self->queue_head;
1539 if (NULL == head) {
1540 NaClLog(LOG_FATAL,
1541 "NaClSecureReverseClientPopHandler: empty handler queue\n");
1542 }
1543 if (NULL == (self->queue_head = head->next)) {
1544 NaClLog(4, "NaClSecureReverseClientPopHandler, last elt patch up\n");
1545 self->queue_insert = &self->queue_head;
1546 }
1547 NaClLog(4, "NaClSecureReverseClientPopHandler, unlocking\n");
1548 NaClXMutexUnlock(&self->mu);
1549
1550 head->next = NULL;
1551 NaClLog(4,
1552 ("Leaving NaClSecureReverseClientPopHandler:"
1553 " returning %"NACL_PRIxPTR"\n"),
1554 (uintptr_t) head);
1555 return head;
1556 }
1557
1558 static
1559 void NaClSecureReverseClientInternalCallback(
1560 void *state,
1561 struct NaClThreadInterface *tif,
1562 struct NaClDesc *conn) {
1563 struct NaClSecureReverseClient *self =
1564 (struct NaClSecureReverseClient *) state;
1565 struct NaClConnectionHandler *hand_ptr;
1566
1567 UNREFERENCED_PARAMETER(tif);
1568 NaClLog(4, "Entered NaClSecureReverseClientInternalCallback\n");
1569 hand_ptr = NaClSecureReverseClientPopHandler(self);
1570 NaClLog(4, " got callback object %"NACL_PRIxPTR"\n", (uintptr_t) hand_ptr);
1571 NaClLog(4,
1572 " callback:0x%"NACL_PRIxPTR"(0x%"NACL_PRIxPTR",0x%"NACL_PRIxPTR")\n",
1573 (uintptr_t) hand_ptr->handler,
1574 (uintptr_t) hand_ptr->state,
1575 (uintptr_t) conn);
1576 (*hand_ptr->handler)(hand_ptr->state, tif, conn);
1577 NaClLog(4, "NaClSecureReverseClientInternalCallback: freeing memory\n");
1578 free(hand_ptr);
1579 NaClLog(4, "Leaving NaClSecureReverseClientInternalCallback\n");
1580 }
1581
1582 /*
1583 * Require an initial connection handler in the Ctor, so that it's
1584 * obvious that a reverse client needs to accept an IMC connection
1585 * from the server to get things bootstrapped.
1586 */
1587 int NaClSecureReverseClientCtor(
1588 struct NaClSecureReverseClient *self,
1589 void (*client_callback)(
1590 void *, struct NaClThreadInterface*, struct NaClDesc *),
1591 void *state,
1592 struct NaClApp *nap) {
1593 NaClLog(4,
1594 ("Entered NaClSecureReverseClientCtor, self 0x%"NACL_PRIxPTR","
1595 " nap 0x%"NACL_PRIxPTR"\n"),
1596 (uintptr_t) self,
1597 (uintptr_t) nap);
1598 if (!NaClSimpleRevClientCtor(&self->base,
1599 NaClSecureReverseClientInternalCallback,
1600 (void *) self,
1601 NaClThreadInterfaceThreadFactory,
1602 (void *) NULL)) {
1603 goto failure_simple_ctor;
1604 }
1605 NaClLog(4, "NaClSecureReverseClientCtor: Mutex\n");
1606 if (!NaClMutexCtor(&self->mu)) {
1607 goto failure_mutex_ctor;
1608 }
1609 self->nap = nap;
1610 self->queue_head = (struct NaClConnectionHandler *) NULL;
1611 self->queue_insert = &self->queue_head;
1612
1613 NACL_VTBL(NaClRefCount, self) =
1614 (struct NaClRefCountVtbl *) &kNaClSecureReverseClientVtbl;
1615
1616 NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler\n");
1617 if (!NaClSecureReverseClientInsertHandler(self,
1618 client_callback,
1619 state)) {
1620 goto failure_handler_insert;
1621 }
1622
1623 NaClLog(4, "Leaving NaClSecureReverseClientCtor\n");
1624 return 1;
1625
1626 failure_handler_insert:
1627 NaClLog(4, "NaClSecureReverseClientCtor: InsertHandler failed\n");
1628 NACL_VTBL(NaClRefCount, self) =
1629 (struct NaClRefCountVtbl *) &kNaClSimpleRevClientVtbl;
1630
1631 self->nap = NULL;
1632 self->queue_insert = (struct NaClConnectionHandler **) NULL;
1633 NaClMutexDtor(&self->mu);
1634
1635 failure_mutex_ctor:
1636 NaClLog(4, "NaClSecureReverseClientCtor: Mutex failed\n");
1637 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
1638 failure_simple_ctor:
1639 NaClLog(4, "Leaving NaClSecureReverseClientCtor\n");
1640 return 0;
1641 }
1642
1643 void NaClSecureReverseClientDtor(struct NaClRefCount *vself) {
1644 struct NaClSecureReverseClient *self =
1645 (struct NaClSecureReverseClient *) vself;
1646
1647 struct NaClConnectionHandler *entry;
1648 struct NaClConnectionHandler *next;
1649
1650 for (entry = self->queue_head; NULL != entry; entry = next) {
1651 next = entry->next;
1652 free(entry);
1653 }
1654 NaClMutexDtor(&self->mu);
1655
1656 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *)
1657 &kNaClSimpleRevClientVtbl;
1658 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
1659 }
1660
1661 int NaClSecureServiceConnectionFactory(
1662 struct NaClSimpleService *vself,
1663 struct NaClDesc *conn,
1664 struct NaClSimpleServiceConnection **out) {
1665 struct NaClSecureService *self =
1666 (struct NaClSecureService *) vself;
1667
1668 /* our instance_data is not connection specific */
1669 return NaClSimpleServiceConnectionFactoryWithInstanceData(
1670 vself, conn, (void *) self->nap, out);
1671 }
1672
1673 int NaClSecureServiceAcceptAndSpawnHandler(struct NaClSimpleService *vself) {
1674 int rv;
1675
1676 NaClLog(4,
1677 "NaClSecureServiceAcceptAndSpawnHandler: invoking base class vfn\n");
1678 rv = (*kNaClSimpleServiceVtbl.AcceptAndSpawnHandler)(vself);
1679 if (0 != rv) {
1680 NaClLog(LOG_FATAL,
1681 "Secure channel AcceptAndSpawnHandler returned %d\n",
1682 rv);
1683 }
1684 NaClThreadExit(0);
1685 /*
1686 * NOTREACHED The port is now to be used by untrusted code: all
1687 * subsequent connections are handled there.
1688 */
1689 return rv;
1690 }
1691
1692 void NaClSecureServiceRpcHandler(struct NaClSimpleService *vself,
1693 struct NaClSimpleServiceConnection *vconn) {
1694
1695 NaClLog(4, "NaClSecureChannelThread started\n");
1696 (*kNaClSimpleServiceVtbl.RpcHandler)(vself, vconn);
1697 NaClLog(4, "NaClSecureChannelThread: channel closed, exiting.\n");
1698 NaClExit(0);
1699 }
1700
1701 struct NaClSimpleServiceVtbl const kNaClSecureServiceVtbl = {
1702 {
1703 NaClSecureServiceDtor,
1704 },
1705 NaClSecureServiceConnectionFactory,
1706 NaClSimpleServiceAcceptConnection,
1707 NaClSecureServiceAcceptAndSpawnHandler,
1708 NaClSecureServiceRpcHandler,
1709 };
1710
1711 struct NaClSimpleRevClientVtbl const kNaClSecureReverseClientVtbl = {
1712 {
1713 NaClSecureReverseClientDtor,
1714 },
1715 };
1716
1717
1718 void NaClSecureCommandChannel(struct NaClApp *nap) { 1390 void NaClSecureCommandChannel(struct NaClApp *nap) {
1719 struct NaClSecureService *secure_command_server; 1391 struct NaClSecureService *secure_command_server;
1720 1392
1721 static struct NaClSrpcHandlerDesc const secure_handlers[] = { 1393 static struct NaClSrpcHandlerDesc const secure_handlers[] = {
1722 { "hard_shutdown::", NaClSecureChannelShutdownRpc, }, 1394 { "hard_shutdown::", NaClSecureChannelShutdownRpc, },
1723 { "start_module::i", NaClSecureChannelStartModuleRpc, }, 1395 { "start_module::i", NaClSecureChannelStartModuleRpc, },
1724 { "log:is:", NaClSecureChannelLog, }, 1396 { "log:is:", NaClSecureChannelLog, },
1725 { "load_module:hs:", NaClLoadModuleRpc, }, 1397 { "load_module:hs:", NaClLoadModuleRpc, },
1726 { "load_irt:h:", NaClLoadIrtRpc, }, 1398 { "load_irt:h:", NaClLoadIrtRpc, },
1727 { "reverse_setup::h", NaClSecureReverseClientSetup, }, 1399 { "reverse_setup::h", NaClSecureReverseClientSetup, },
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 nacl_global_xlate_base = mem_start; 1501 nacl_global_xlate_base = mem_start;
1830 1502
1831 NaClSandboxMemoryStartForValgrind(mem_start); 1503 NaClSandboxMemoryStartForValgrind(mem_start);
1832 1504
1833 _ovly_debug_event(); 1505 _ovly_debug_event();
1834 } 1506 }
1835 1507
1836 void NaClGdbHook(struct NaClApp const *nap) { 1508 void NaClGdbHook(struct NaClApp const *nap) {
1837 StopForDebuggerInit(nap->mem_start); 1509 StopForDebuggerInit(nap->mem_start);
1838 } 1510 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698