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
4 * found in the LICENSE file.
14 #include "native_client/src/public/chrome_main.h"
15 #include "native_client/src/public/nacl_app.h"
16 #include "native_client/src/shared/platform/nacl_check.h"
17 #include "native_client/src/shared/platform/nacl_threads.h"
18 #include "native_client/src/shared/srpc/nacl_srpc.h"
19 #include "native_client/src/trusted/desc/nacl_desc_custom.h"
20 #include "native_client/src/trusted/desc_cacheability/desc_cacheability.h"
21 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
22 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
23 #include "native_client/src/trusted/service_runtime/nacl_all_modules.h"
24 #include "native_client/src/trusted/service_runtime/nacl_config.h"
25 #include "native_client/src/trusted/service_runtime/nacl_valgrind_hooks.h"
26 #include "native_client/src/trusted/service_runtime/sel_addrspace.h"
27 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
28 #include "native_client/src/trusted/validator/nacl_file_info.h"
29 #include "native_client/src/trusted/validator/validation_cache.h"
32 int OpenFileReadOnly(const char *filename) {
34 return _open(filename, _O_RDONLY);
36 return open(filename, O_RDONLY);
40 int32_t OpenFileHandleReadExec(const char *filename) {
42 HANDLE h = CreateFileA(filename,
43 GENERIC_READ | GENERIC_EXECUTE,
47 FILE_ATTRIBUTE_NORMAL,
49 // On Windows, valid handles are 32 bit unsigned integers so this is safe.
50 return reinterpret_cast<int32_t>(h);
52 return open(filename, O_RDONLY);
56 // This launcher class does not actually launch a process, but we
57 // reuse SelLdrLauncherBase in order to use its helper methods.
58 class DummyLauncher : public nacl::SelLdrLauncherBase {
60 explicit DummyLauncher(NaClHandle channel) {
64 virtual bool Start(const char *url) {
65 UNREFERENCED_PARAMETER(url);
70 // Fake validation cache methods for testing.
71 struct TestValidationHandle {
72 uint64_t expected_token_lo;
73 uint64_t expected_token_hi;
74 int32_t expected_file_handle;
75 char *expected_file_path;
78 struct TestValidationQuery {
79 bool known_to_validate;
82 static void *TestCreateQuery(void *handle) {
83 UNREFERENCED_PARAMETER(handle);
84 return static_cast<void *>(new TestValidationQuery());
87 static void TestAddData(void *query, const unsigned char *data,
89 UNREFERENCED_PARAMETER(query);
90 UNREFERENCED_PARAMETER(data);
91 UNREFERENCED_PARAMETER(length);
94 static int TestQueryKnownToValidate(void *query) {
95 TestValidationQuery *s = static_cast<TestValidationQuery *>(query);
96 return s->known_to_validate;
99 static void TestSetKnownToValidate(void *query) {
100 TestValidationQuery *s = static_cast<TestValidationQuery *>(query);
101 s->known_to_validate = 1;
104 static void TestDestroyQuery(void *query) {
105 delete static_cast<TestValidationQuery *>(query);
108 static int TestCachingIsInexpensive(const struct NaClValidationMetadata *m) {
109 UNREFERENCED_PARAMETER(m);
113 static int TestResolveFileToken(void *handle, struct NaClFileToken *file_token,
114 int32_t *fd, char **file_path,
115 uint32_t *file_path_length) {
116 TestValidationHandle *h = static_cast<TestValidationHandle *>(handle);
117 CHECK(h->expected_token_lo == file_token->lo);
118 CHECK(h->expected_token_hi == file_token->hi);
119 *fd = h->expected_file_handle;
120 *file_path = h->expected_file_path;
121 *file_path_length = static_cast<uint32_t>(strlen(h->expected_file_path));
128 NaClFileToken nexe_token;
131 void WINAPI DummyRendererThread(void *thread_arg) {
132 struct ThreadArgs *args = (struct ThreadArgs *) thread_arg;
134 nacl::DescWrapperFactory desc_wrapper_factory;
135 nacl::DescWrapper *nexe_desc =
136 desc_wrapper_factory.MakeFileDesc(args->nexe_fd, NACL_ABI_O_RDONLY);
137 CHECK(nexe_desc != NULL);
138 if (args->nexe_token.lo != 0 && args->nexe_token.hi != 0) {
139 int token_res = NaClDescSetFileToken(nexe_desc->desc(), &args->nexe_token);
140 CHECK(token_res != 0);
143 DummyLauncher launcher(args->channel);
144 NaClSrpcChannel trusted_channel;
145 NaClSrpcChannel untrusted_channel;
146 CHECK(launcher.SetupCommandAndLoad(&trusted_channel, nexe_desc));
147 CHECK(launcher.StartModuleAndSetupAppChannel(&trusted_channel,
148 &untrusted_channel));
151 void ExampleDescDestroy(void *handle) {
152 UNREFERENCED_PARAMETER(handle);
155 ssize_t ExampleDescSendMsg(void *handle,
156 const struct NaClImcTypedMsgHdr *msg,
158 UNREFERENCED_PARAMETER(handle);
159 UNREFERENCED_PARAMETER(msg);
160 UNREFERENCED_PARAMETER(flags);
162 NaClLog(LOG_FATAL, "ExampleDescSendMsg: Not implemented\n");
166 ssize_t ExampleDescRecvMsg(void *handle,
167 struct NaClImcTypedMsgHdr *msg,
169 UNREFERENCED_PARAMETER(handle);
170 UNREFERENCED_PARAMETER(msg);
171 UNREFERENCED_PARAMETER(flags);
173 NaClLog(LOG_FATAL, "ExampleDescRecvMsg: Not implemented\n");
177 struct NaClDesc *MakeExampleDesc() {
178 struct NaClDescCustomFuncs funcs = NACL_DESC_CUSTOM_FUNCS_INITIALIZER;
179 funcs.Destroy = ExampleDescDestroy;
180 funcs.SendMsg = ExampleDescSendMsg;
181 funcs.RecvMsg = ExampleDescRecvMsg;
182 return NaClDescMakeCustomDesc(NULL, &funcs);
185 int main(int argc, char **argv) {
186 // Note that we deliberately do not call NaClAllModulesInit() here,
187 // in order to mimic what we expect the Chromium side to do.
188 NaClChromeMainInit();
189 struct NaClChromeMainArgs *args = NaClChromeMainArgsCreate();
190 struct NaClApp *nap = NaClAppCreate();
191 struct ThreadArgs thread_args;
193 NaClHandleBootstrapArgs(&argc, &argv);
195 args->prereserved_sandbox_size = g_prereserved_sandbox_size;
198 CHECK(argc == 3 || argc == 4);
200 args->irt_fd = OpenFileReadOnly(argv[1]);
201 CHECK(args->irt_fd >= 0);
203 thread_args.nexe_fd = OpenFileReadOnly(argv[2]);
204 CHECK(thread_args.nexe_fd >= 0);
205 NaClFileNameForValgrind(argv[2]);
207 NaClHandle socketpair[2];
208 CHECK(NaClSocketPair(socketpair) == 0);
209 args->imc_bootstrap_handle = socketpair[0];
210 thread_args.channel = socketpair[1];
212 // Check that NaClDescMakeCustomDesc() works when called in this context.
213 NaClAppSetDesc(nap, NACL_CHROME_DESC_BASE, MakeExampleDesc());
215 // Set up mock validation cache.
216 struct TestValidationHandle test_handle;
217 struct NaClValidationCache test_cache;
219 CHECK(strcmp(argv[3], "-vcache") == 0);
220 test_handle.expected_token_lo = 0xabcdef123456789LL;
221 test_handle.expected_token_hi = 0x101010101010101LL;
222 test_handle.expected_file_handle = OpenFileHandleReadExec(argv[2]);
223 test_handle.expected_file_path = strdup(argv[2]);
224 test_cache.handle = &test_handle;
225 test_cache.CreateQuery = &TestCreateQuery;
226 test_cache.AddData = &TestAddData;
227 test_cache.QueryKnownToValidate = &TestQueryKnownToValidate;
228 test_cache.SetKnownToValidate = &TestSetKnownToValidate;
229 test_cache.DestroyQuery = &TestDestroyQuery;
230 test_cache.CachingIsInexpensive = &TestCachingIsInexpensive;
231 test_cache.ResolveFileToken = &TestResolveFileToken;
232 args->validation_cache = &test_cache;
233 thread_args.nexe_token.lo = test_handle.expected_token_lo;
234 thread_args.nexe_token.hi = test_handle.expected_token_hi;
236 thread_args.nexe_token.lo = 0;
237 thread_args.nexe_token.hi = 0;
241 CHECK(NaClThreadCtor(&thread, DummyRendererThread, &thread_args,
242 NACL_KERN_STACK_SIZE));
244 NaClChromeMainStartApp(nap, args);
245 NaClLog(LOG_FATAL, "NaClChromeMainStartApp() should never return\n");