Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / tests / sel_main_chrome / sel_main_chrome_test.cc
1 /*
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.
5  */
6
7 #include <fcntl.h>
8 #include <cstring>
9
10 #if NACL_WINDOWS
11 # include <io.h>
12 #endif
13
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"
30
31
32 int OpenFileReadOnly(const char *filename) {
33 #if NACL_WINDOWS
34   return _open(filename, _O_RDONLY);
35 #else
36   return open(filename, O_RDONLY);
37 #endif
38 }
39
40 int32_t OpenFileHandleReadExec(const char *filename) {
41 #if NACL_WINDOWS
42   HANDLE h = CreateFileA(filename,
43                          GENERIC_READ | GENERIC_EXECUTE,
44                          FILE_SHARE_READ,
45                          NULL,
46                          OPEN_EXISTING,
47                          FILE_ATTRIBUTE_NORMAL,
48                          NULL);
49   // On Windows, valid handles are 32 bit unsigned integers so this is safe.
50   return reinterpret_cast<int32_t>(h);
51 #else
52   return open(filename, O_RDONLY);
53 #endif
54 }
55
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 {
59  public:
60   explicit DummyLauncher(NaClHandle channel) {
61     channel_ = channel;
62   }
63
64   virtual bool Start(const char *url) {
65     UNREFERENCED_PARAMETER(url);
66     return true;
67   }
68 };
69
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;
76 };
77
78 struct TestValidationQuery {
79   bool known_to_validate;
80 };
81
82 static void *TestCreateQuery(void *handle) {
83   UNREFERENCED_PARAMETER(handle);
84   return static_cast<void *>(new TestValidationQuery());
85 }
86
87 static void TestAddData(void *query, const unsigned char *data,
88                         size_t length) {
89   UNREFERENCED_PARAMETER(query);
90   UNREFERENCED_PARAMETER(data);
91   UNREFERENCED_PARAMETER(length);
92 }
93
94 static int TestQueryKnownToValidate(void *query) {
95   TestValidationQuery *s = static_cast<TestValidationQuery *>(query);
96   return s->known_to_validate;
97 }
98
99 static void TestSetKnownToValidate(void *query) {
100   TestValidationQuery *s = static_cast<TestValidationQuery *>(query);
101   s->known_to_validate = 1;
102 }
103
104 static void TestDestroyQuery(void *query) {
105   delete static_cast<TestValidationQuery *>(query);
106 }
107
108 static int TestCachingIsInexpensive(const struct NaClValidationMetadata *m) {
109   UNREFERENCED_PARAMETER(m);
110   return 1;
111 }
112
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));
122   return 1;
123 }
124
125 struct ThreadArgs {
126   NaClHandle channel;
127   int nexe_fd;
128   NaClFileToken nexe_token;
129 };
130
131 void WINAPI DummyRendererThread(void *thread_arg) {
132   struct ThreadArgs *args = (struct ThreadArgs *) thread_arg;
133
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);
141   }
142
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));
149 }
150
151 void ExampleDescDestroy(void *handle) {
152   UNREFERENCED_PARAMETER(handle);
153 }
154
155 ssize_t ExampleDescSendMsg(void *handle,
156                            const struct NaClImcTypedMsgHdr *msg,
157                            int flags) {
158   UNREFERENCED_PARAMETER(handle);
159   UNREFERENCED_PARAMETER(msg);
160   UNREFERENCED_PARAMETER(flags);
161
162   NaClLog(LOG_FATAL, "ExampleDescSendMsg: Not implemented\n");
163   return 0;
164 }
165
166 ssize_t ExampleDescRecvMsg(void *handle,
167                            struct NaClImcTypedMsgHdr *msg,
168                            int flags) {
169   UNREFERENCED_PARAMETER(handle);
170   UNREFERENCED_PARAMETER(msg);
171   UNREFERENCED_PARAMETER(flags);
172
173   NaClLog(LOG_FATAL, "ExampleDescRecvMsg: Not implemented\n");
174   return 0;
175 }
176
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);
183 }
184
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;
192
193   NaClHandleBootstrapArgs(&argc, &argv);
194 #if NACL_LINUX
195   args->prereserved_sandbox_size = g_prereserved_sandbox_size;
196 #endif
197
198   CHECK(argc == 3 || argc == 4);
199
200   args->irt_fd = OpenFileReadOnly(argv[1]);
201   CHECK(args->irt_fd >= 0);
202
203   thread_args.nexe_fd = OpenFileReadOnly(argv[2]);
204   CHECK(thread_args.nexe_fd >= 0);
205   NaClFileNameForValgrind(argv[2]);
206
207   NaClHandle socketpair[2];
208   CHECK(NaClSocketPair(socketpair) == 0);
209   args->imc_bootstrap_handle = socketpair[0];
210   thread_args.channel = socketpair[1];
211
212   // Check that NaClDescMakeCustomDesc() works when called in this context.
213   NaClAppSetDesc(nap, NACL_CHROME_DESC_BASE, MakeExampleDesc());
214
215   // Set up mock validation cache.
216   struct TestValidationHandle test_handle;
217   struct NaClValidationCache test_cache;
218   if (argc == 4) {
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;
235   } else {
236     thread_args.nexe_token.lo = 0;
237     thread_args.nexe_token.hi = 0;
238   }
239
240   NaClThread thread;
241   CHECK(NaClThreadCtor(&thread, DummyRendererThread, &thread_args,
242                        NACL_KERN_STACK_SIZE));
243
244   NaClChromeMainStartApp(nap, args);
245   NaClLog(LOG_FATAL, "NaClChromeMainStartApp() should never return\n");
246   return 1;
247 }