OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/nacl/loader/nonsfi/nonsfi_main.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "components/nacl/loader/nonsfi/elf_loader.h" | |
10 #include "native_client/src/include/elf_auxv.h" | |
11 #include "native_client/src/include/nacl_macros.h" | |
12 #include "native_client/src/public/secure_service.h" | |
13 #include "native_client/src/shared/srpc/nacl_srpc.h" | |
14 #include "native_client/src/trusted/desc/nacl_desc_base.h" | |
15 #include "native_client/src/trusted/desc/nacl_desc_imc.h" | |
16 #include "native_client/src/trusted/desc/nrd_all_modules.h" | |
17 #include "native_client/src/trusted/desc/nrd_xfer.h" | |
18 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" | |
19 | |
20 namespace nacl { | |
21 namespace nonsfi { | |
22 namespace { | |
23 | |
24 struct NaClDescUnrefer { | |
25 void operator()(struct NaClDesc* desc) const { | |
26 NaClDescUnref(desc); | |
27 } | |
28 }; | |
29 | |
30 void LoadModuleRpc(struct NaClSrpcRpc* rpc, | |
31 struct NaClSrpcArg** in_args, | |
32 struct NaClSrpcArg** out_args, | |
33 struct NaClSrpcClosure* done_cls) { | |
34 rpc->result = NACL_SRPC_RESULT_INTERNAL; | |
35 | |
36 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc(in_args[0]->u.hval); | |
37 ElfImage image; | |
38 if (image.Read(desc.get()) != LOAD_OK) { | |
39 LOG(ERROR) << "LoadModuleRpc: Failed to read binary."; | |
40 return; | |
41 } | |
42 | |
43 if (image.Load(desc.get()) != LOAD_OK) { | |
44 LOG(ERROR) << "LoadModuleRpc: Failed to load the image"; | |
45 return; | |
46 } | |
47 | |
48 uintptr_t entry_point = image.entry_point(); | |
49 rpc->result = NACL_SRPC_RESULT_OK; | |
50 | |
51 // Run for testing. TODO(hidehiko): Remove this. | |
52 uintptr_t info[] = { | |
53 0, // Do not use fini. | |
54 0, // envc. | |
55 0, // argc. | |
56 0, // Null terminate for argv. | |
57 0, // Null terminate for envv. | |
58 AT_NULL, | |
59 0, // Null terminate for auxv. | |
60 }; | |
61 reinterpret_cast<void (*)(uintptr_t*)>(entry_point)(info); | |
62 } | |
63 | |
64 const static struct NaClSrpcHandlerDesc kNonSfiServiceHandlers[] = { | |
65 { NACL_SECURE_SERVICE_LOAD_MODULE, LoadModuleRpc, }, | |
66 { static_cast<const char*>(NULL), static_cast<NaClSrpcMethod>(NULL), }, | |
67 }; | |
68 | |
69 // Creates two socketpairs to communicate with the host process. | |
70 void CreateSecureSocketPair(struct NaClDesc* secure_pair[2], | |
71 struct NaClDesc* pair[2]) { | |
72 // Set up a secure pair. | |
73 if (NaClCommonDescMakeBoundSock(secure_pair)) { | |
74 LOG(FATAL) << "Cound not create secure service socket\n"; | |
75 } | |
76 | |
77 // Set up a service pair. | |
78 if (NaClCommonDescMakeBoundSock(pair)) { | |
79 LOG(FATAL) << "Could not create service socket"; | |
80 } | |
81 } | |
82 | |
83 // Wraps handle by NaClDesc, and sends sercure_service_address and | |
Mark Seaborn
2013/12/17 21:18:55
Typo: "sercure"
hidehiko
2013/12/18 08:38:03
Done.
| |
84 // service_address via the created descriptor. | |
85 struct NaClDesc* SetUpBootstrapChannel(NaClHandle handle, | |
86 struct NaClDesc* secure_service_address, | |
87 struct NaClDesc* service_address) { | |
88 if (secure_service_address == NULL) { | |
89 LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; | |
90 } | |
91 | |
92 if (service_address == NULL) { | |
93 LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set"; | |
94 } | |
95 | |
96 struct NaClDescImcDesc* channel = | |
97 static_cast<struct NaClDescImcDesc*>(malloc(sizeof *channel)); | |
98 if (channel == NULL) { | |
99 LOG(FATAL) << "SetUpBootstrapChannel: no memory"; | |
100 } | |
101 | |
102 if (!NaClDescImcDescCtor(channel, handle)) { | |
103 LOG(FATAL) << "SetUpBootstrapChannel: cannot construct IMC descriptor " | |
104 << "object for inherited descriptor: " << handle; | |
105 } | |
106 | |
107 // Send the descriptors to the host. | |
108 struct NaClDesc* descs[2] = { | |
109 secure_service_address, | |
110 service_address, | |
111 }; | |
112 | |
113 struct NaClImcTypedMsgHdr hdr; | |
Mark Seaborn
2013/12/17 21:18:55
You've missed initialising "hdr.flags = 0;"
hidehiko
2013/12/18 08:38:03
Good catch. Fixed.
| |
114 hdr.iov = static_cast<struct NaClImcMsgIoVec*>(NULL); | |
115 hdr.iov_length = 0; | |
116 hdr.ndescv = descs; | |
117 hdr.ndesc_length = NACL_ARRAY_SIZE(descs); | |
118 | |
119 ssize_t error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)( | |
120 reinterpret_cast<struct NaClDesc*>(channel), &hdr, 0); | |
121 if (error) { | |
122 LOG(FATAL) << "SetUpBootstrapChannel: SendMsg failed, error = " << error; | |
123 } | |
124 return reinterpret_cast<struct NaClDesc*>(channel); | |
125 } | |
126 | |
127 // Starts to listen to the port and runs the server loop. | |
128 void ServiceAccept(struct NaClDesc* port) { | |
129 struct NaClDesc* connected_desc = NULL; | |
130 int status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc); | |
131 if (status) { | |
132 LOG(ERROR) << "ServiceAccept: Failed to accept " << status; | |
133 return; | |
134 } | |
135 | |
136 NaClSrpcServerLoop(connected_desc, kNonSfiServiceHandlers, NULL); | |
137 } | |
138 | |
139 } // namespace | |
140 | |
141 void MainStart(NaClHandle imc_bootstrap_handle) { | |
142 NaClSrpcModuleInit(); | |
143 | |
144 struct NaClDesc* secure_pair[2] = { NULL, NULL }; | |
145 struct NaClDesc* pair[2] = { NULL, NULL }; | |
146 CreateSecureSocketPair(secure_pair, pair); | |
147 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_port(secure_pair[0]); | |
148 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_address( | |
149 secure_pair[1]); | |
150 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_port(pair[0]); | |
151 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_address(pair[1]); | |
152 | |
153 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> channel( | |
154 SetUpBootstrapChannel(imc_bootstrap_handle, | |
155 secure_address.get(), service_address.get())); | |
156 if (!channel) { | |
157 LOG(ERROR) << "MainStart: Failed to set up bootstrap channel."; | |
158 return; | |
159 } | |
160 | |
161 // Start the SRPC server loop. | |
162 ServiceAccept(secure_port.get()); | |
163 } | |
164 | |
165 } // namespace nonsfi | |
166 } // namespace nacl | |
OLD | NEW |