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

Side by Side Diff: src/trusted/service_runtime/sel_main_chrome.c

Issue 141413007: NaCl: Expose NaClApp to the embedding layer. (Closed) Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@embedding_api
Patch Set: Expose LoadModule status for UMA tracking. Created 6 years, 10 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
« no previous file with comments | « src/trusted/service_runtime/sel_main_chrome.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "native_client/src/trusted/service_runtime/sel_main_chrome.h" 7 #include "native_client/src/trusted/service_runtime/sel_main_chrome.h"
8 8
9 #include "native_client/src/include/portability.h" 9 #include "native_client/src/include/portability.h"
10 #include "native_client/src/include/portability_io.h" 10 #include "native_client/src/include/portability_io.h"
(...skipping 25 matching lines...) Expand all
36 #include "native_client/src/trusted/service_runtime/nacl_globals.h" 36 #include "native_client/src/trusted/service_runtime/nacl_globals.h"
37 #include "native_client/src/trusted/service_runtime/nacl_debug_init.h" 37 #include "native_client/src/trusted/service_runtime/nacl_debug_init.h"
38 #include "native_client/src/trusted/service_runtime/nacl_signal.h" 38 #include "native_client/src/trusted/service_runtime/nacl_signal.h"
39 #include "native_client/src/trusted/service_runtime/osx/mach_exception_handler.h " 39 #include "native_client/src/trusted/service_runtime/osx/mach_exception_handler.h "
40 #include "native_client/src/trusted/service_runtime/sel_addrspace.h" 40 #include "native_client/src/trusted/service_runtime/sel_addrspace.h"
41 #include "native_client/src/trusted/service_runtime/sel_ldr.h" 41 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
42 #include "native_client/src/trusted/service_runtime/sel_qualify.h" 42 #include "native_client/src/trusted/service_runtime/sel_qualify.h"
43 #include "native_client/src/trusted/service_runtime/win/exception_patch/ntdll_pa tch.h" 43 #include "native_client/src/trusted/service_runtime/win/exception_patch/ntdll_pa tch.h"
44 #include "native_client/src/trusted/validator/validation_metadata.h" 44 #include "native_client/src/trusted/validator/validation_metadata.h"
45 45
46 static void NaClCleanupAndExit(struct NaClApp *nap, NaClErrorCode errcode);
47
46 struct NaClChromeMainArgs *NaClChromeMainArgsCreate(void) { 48 struct NaClChromeMainArgs *NaClChromeMainArgsCreate(void) {
47 struct NaClChromeMainArgs *args = malloc(sizeof(*args)); 49 struct NaClChromeMainArgs *args = malloc(sizeof(*args));
48 if (args == NULL) 50 if (args == NULL)
49 return NULL; 51 return NULL;
50 args->imc_bootstrap_handle = NACL_INVALID_HANDLE; 52 args->imc_bootstrap_handle = NACL_INVALID_HANDLE;
51 args->irt_fd = -1; 53 args->irt_fd = -1;
52 args->initial_ipc_desc = NULL; 54 args->initial_ipc_desc = NULL;
53 args->enable_exception_handling = 0; 55 args->enable_exception_handling = 0;
54 args->enable_debug_stub = 0; 56 args->enable_debug_stub = 0;
55 args->enable_dyncode_syscalls = 1; 57 args->enable_dyncode_syscalls = 1;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 if (errcode != LOAD_OK) { 119 if (errcode != LOAD_OK) {
118 NaClLog(LOG_FATAL, 120 NaClLog(LOG_FATAL,
119 "NaClLoadIrt: Failed to load the integrated runtime (IRT): %s\n", 121 "NaClLoadIrt: Failed to load the integrated runtime (IRT): %s\n",
120 NaClErrorString(errcode)); 122 NaClErrorString(errcode));
121 } 123 }
122 124
123 NaClMetadataDtor(&metadata); 125 NaClMetadataDtor(&metadata);
124 NaClDescUnref(nd); 126 NaClDescUnref(nd);
125 } 127 }
126 128
127 void NaClChromeMainStart(struct NaClChromeMainArgs *args) { 129 struct NaClApp *NaClChromeMainCreateApp(struct NaClChromeMainArgs *args) {
128 char *av[1]; 130 struct NaClApp *nap = (struct NaClApp *)malloc(sizeof(struct NaClApp));
129 int ac = 1;
130 const char **envp;
131 struct NaClApp state;
132 struct NaClApp *nap = &state;
133 NaClErrorCode errcode = LOAD_INTERNAL; 131 NaClErrorCode errcode = LOAD_INTERNAL;
134 int ret_code = 1;
135 struct NaClEnvCleanser env_cleanser;
136 int skip_qualification; 132 int skip_qualification;
137 133
138 #if NACL_OSX
139 /* Mac dynamic libraries cannot access the environ variable directly. */
140 envp = (const char **) *_NSGetEnviron();
141 #else
142 /* Overzealous code style check is overzealous. */
143 /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */
144 extern char **environ;
145 envp = (const char **) environ;
146 #endif
147
148 #if NACL_LINUX || NACL_OSX 134 #if NACL_LINUX || NACL_OSX
149 /* This needs to happen before NaClAllModulesInit(). */ 135 /* This needs to happen before NaClAllModulesInit(). */
150 if (args->urandom_fd != -1) 136 if (args->urandom_fd != -1)
151 NaClSecureRngModuleSetUrandomFd(args->urandom_fd); 137 NaClSecureRngModuleSetUrandomFd(args->urandom_fd);
152 #endif 138 #endif
153 139
154 /* 140 /*
155 * Clear state so that NaClBootstrapChannelErrorReporter will be 141 * Clear state so that NaClBootstrapChannelErrorReporter will be
156 * able to know if the bootstrap channel is available or not. 142 * able to know if the bootstrap channel is available or not.
157 */ 143 */
158 memset(&state, 0, sizeof state); 144 memset(nap, 0, sizeof(struct NaClApp));
159 NaClAllModulesInit(); 145 NaClAllModulesInit();
160 NaClBootstrapChannelErrorReporterInit(); 146 NaClBootstrapChannelErrorReporterInit();
161 NaClErrorLogHookInit(NaClBootstrapChannelErrorReporter, &state); 147 NaClErrorLogHookInit(NaClBootstrapChannelErrorReporter, nap);
162 148
163 /* to be passed to NaClMain, eventually... */ 149 if (NACL_FI_ERROR_COND("AppCtor", !NaClAppCtor(nap))) {
164 av[0] = "NaClMain";
165
166 if (NACL_FI_ERROR_COND("AppCtor", !NaClAppCtor(&state))) {
167 NaClLog(LOG_FATAL, "Error while constructing app state\n"); 150 NaClLog(LOG_FATAL, "Error while constructing app state\n");
168 goto done; 151 NaClCleanupAndExit(nap, errcode);
152 free(nap);
153 return NULL;
169 } 154 }
170 155
171 errcode = LOAD_OK; 156 errcode = LOAD_OK;
172 157
173 /* Allow or disallow dyncode API based on args. */ 158 /* Allow or disallow dyncode API based on args. */
174 nap->enable_dyncode_syscalls = args->enable_dyncode_syscalls; 159 nap->enable_dyncode_syscalls = args->enable_dyncode_syscalls;
175 nap->initial_nexe_max_code_bytes = args->initial_nexe_max_code_bytes; 160 nap->initial_nexe_max_code_bytes = args->initial_nexe_max_code_bytes;
176 161
177 #if NACL_LINUX 162 #if NACL_LINUX
178 g_prereserved_sandbox_size = args->prereserved_sandbox_size; 163 g_prereserved_sandbox_size = args->prereserved_sandbox_size;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 args->attach_debug_exception_handler_func; 247 args->attach_debug_exception_handler_func;
263 #else 248 #else
264 # error Unknown host OS 249 # error Unknown host OS
265 #endif 250 #endif
266 } 251 }
267 #if NACL_LINUX 252 #if NACL_LINUX
268 NaClSignalHandlerInit(); 253 NaClSignalHandlerInit();
269 #endif 254 #endif
270 255
271 /* Give debuggers a well known point at which xlate_base is known. */ 256 /* Give debuggers a well known point at which xlate_base is known. */
272 NaClGdbHook(&state); 257 NaClGdbHook(nap);
273 258
274 NaClCreateServiceSocket(nap); 259 NaClCreateServiceSocket(nap);
275 /* 260 /*
276 * LOG_FATAL errors that occur before NaClSetUpBootstrapChannel will 261 * LOG_FATAL errors that occur before NaClSetUpBootstrapChannel will
277 * not be reported via the crash log mechanism (for Chromium 262 * not be reported via the crash log mechanism (for Chromium
278 * embedding of NaCl, shown in the JavaScript console). 263 * embedding of NaCl, shown in the JavaScript console).
279 * 264 *
280 * Some errors, such as due to NaClRunSelQualificationTests, do not 265 * Some errors, such as due to NaClRunSelQualificationTests, do not
281 * trigger a LOG_FATAL but instead set module_load_status to be sent 266 * trigger a LOG_FATAL but instead set module_load_status to be sent
282 * in the start_module RPC reply. Log messages associated with such 267 * in the start_module RPC reply. Log messages associated with such
283 * errors would be seen, since NaClSetUpBootstrapChannel will get 268 * errors would be seen, since NaClSetUpBootstrapChannel will get
284 * called. 269 * called.
285 */ 270 */
286 NaClSetUpBootstrapChannel(nap, args->imc_bootstrap_handle); 271 NaClSetUpBootstrapChannel(nap, args->imc_bootstrap_handle);
287 272
288 NACL_FI_FATAL("BeforeSecureCommandChannel"); 273 NACL_FI_FATAL("BeforeSecureCommandChannel");
289 /* 274 /*
290 * NB: Spawns a thread that uses the command channel. We do this 275 * NB: Spawns a thread that uses the command channel. We do this
291 * after NaClAppLoadFile so that the NaClApp object is more fully 276 * after NaClAppLoadFile so that the NaClApp object is more fully
292 * populated. Hereafter any changes to nap should be done while 277 * populated. Hereafter any changes to nap should be done while
293 * holding locks. 278 * holding locks.
294 */ 279 */
295 NaClSecureCommandChannel(nap); 280 NaClSecureCommandChannel(nap);
296 281
297 NaClLog(4, "NaClSecureCommandChannel has spawned channel\n"); 282 NaClLog(4, "NaClSecureCommandChannel has spawned channel\n");
298 283
299 NaClLog(4, "secure service = %"NACL_PRIxPTR"\n", 284 NaClLog(4, "secure service = %"NACL_PRIxPTR"\n",
300 (uintptr_t) nap->secure_service); 285 (uintptr_t) nap->secure_service);
301 NACL_FI_FATAL("BeforeWaitForStartModule");
302 286
303 if (NULL != nap->secure_service) { 287 if (args->enable_debug_stub) {
304 NaClErrorCode start_result; 288 #if NACL_LINUX || NACL_OSX
305 /* 289 if (args->debug_stub_server_bound_socket_fd != NACL_INVALID_SOCKET) {
306 * wait for start_module RPC call on secure channel thread. 290 NaClDebugSetBoundSocket(args->debug_stub_server_bound_socket_fd);
307 */ 291 }
308 start_result = NaClWaitForStartModuleCommand(nap); 292 #endif
309 if (LOAD_OK == errcode) { 293 if (!NaClDebugInit(nap)) {
310 errcode = start_result; 294 NaClCleanupAndExit(nap, errcode);
295 free(nap);
296 return NULL;
311 } 297 }
312 } 298 }
313 299
314 NACL_FI_FATAL("BeforeLoadIrt"); 300 free(args);
301 return nap;
302 }
315 303
316 /* 304 NaClErrorCode NaClChromeMainLoadModule(struct NaClApp *nap,
317 * error reporting done; can quit now if there was an error earlier. 305 struct NaClDesc *nexe_desc) {
318 */ 306 NaClAppLoadModule(nap, nexe_desc, NULL, NULL);
319 if (LOAD_OK != errcode) { 307 return nap->module_load_status;
320 goto done; 308 }
309
310 void NaClChromeMainStartModule(struct NaClApp *nap, int irt_fd) {
311 char *av[1];
312 int ac = 1;
313 int ret_code = 1;
314 struct NaClEnvCleanser env_cleanser;
315 const char **envp;
316 enum NaClModuleInitializationState state;
317
318 #if NACL_OSX
319 /* Mac dynamic libraries cannot access the environ variable directly. */
320 envp = (const char **) *_NSGetEnviron();
321 #else
322 /* Overzealous code style check is overzealous. */
323 /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */
324 extern char **environ;
325 envp = (const char **) environ;
326 #endif
327
328 NACL_FI_FATAL("BeforeWaitForStartModule");
329
330 /* When using SRPC, the module is already started for us.
331 * When using Chromium IPC, we have to expliticlty start the module here. */
332 NaClXMutexLock(&nap->mu);
333 state = nap->module_initialization_state;
334 NaClXMutexUnlock(&nap->mu);
335 if (state != NACL_MODULE_STARTED) {
336 NaClAppStartModule(nap, NULL, NULL);
337 }
338 NaClXMutexLock(&nap->mu);
339 state = nap->module_initialization_state;
340 NaClXMutexUnlock(&nap->mu);
341 /* If we haven't started the module now, cleanup and exit. */
342 if (state != NACL_MODULE_STARTED) {
343 NaClCleanupAndExit(nap, LOAD_OK);
344 return;
321 } 345 }
322 346
347 NACL_FI_FATAL("BeforeLoadIrt");
323 /* 348 /*
324 * Load the integrated runtime (IRT) library. 349 * Load the integrated runtime (IRT) library.
325 */ 350 */
326 if (args->irt_fd != -1 && !nap->irt_loaded) { 351 if (irt_fd != -1 && !nap->irt_loaded) {
327 NaClLoadIrt(nap, args->irt_fd); 352 NaClLoadIrt(nap, irt_fd);
328 nap->irt_loaded = 1; 353 nap->irt_loaded = 1;
329 } 354 }
330 355
331 NACL_FI_FATAL("BeforeEnvCleanserCtor"); 356 NACL_FI_FATAL("BeforeEnvCleanserCtor");
332 357
333 NaClEnvCleanserCtor(&env_cleanser, 1); 358 NaClEnvCleanserCtor(&env_cleanser, 1);
334 if (!NaClEnvCleanserInit(&env_cleanser, envp, NULL)) { 359 if (!NaClEnvCleanserInit(&env_cleanser, envp, NULL)) {
335 NaClLog(LOG_FATAL, "Failed to initialise env cleanser\n"); 360 NaClLog(LOG_FATAL, "Failed to initialise env cleanser\n");
336 } 361 }
337 362
338 if (NACL_FI_ERROR_COND("LaunchServiceThreads", 363 if (NACL_FI_ERROR_COND("LaunchServiceThreads",
339 !NaClAppLaunchServiceThreads(nap))) { 364 !NaClAppLaunchServiceThreads(nap))) {
340 NaClLog(LOG_FATAL, "Launch service threads failed\n"); 365 NaClLog(LOG_FATAL, "Launch service threads failed\n");
341 } 366 }
342 367
343 if (args->enable_debug_stub) { 368 /* to be passed to NaClMain, eventually... */
344 #if NACL_LINUX || NACL_OSX 369 av[0] = "NaClMain";
345 if (args->debug_stub_server_bound_socket_fd != NACL_INVALID_SOCKET) {
346 NaClDebugSetBoundSocket(args->debug_stub_server_bound_socket_fd);
347 }
348 #endif
349 if (!NaClDebugInit(nap)) {
350 goto done;
351 }
352 }
353
354 free(args);
355 args = NULL;
356 370
357 if (NACL_FI_ERROR_COND( 371 if (NACL_FI_ERROR_COND(
358 "CreateMainThread", 372 "CreateMainThread",
359 !NaClCreateMainThread(nap, ac, av, 373 !NaClCreateMainThread(nap, ac, av,
360 NaClEnvCleanserEnvironment(&env_cleanser)))) { 374 NaClEnvCleanserEnvironment(&env_cleanser)))) {
361 NaClLog(LOG_FATAL, "creating main thread failed\n"); 375 NaClLog(LOG_FATAL, "creating main thread failed\n");
362 } 376 }
363 NACL_FI_FATAL("BeforeEnvCleanserDtor"); 377 NACL_FI_FATAL("BeforeEnvCleanserDtor");
364
365 NaClEnvCleanserDtor(&env_cleanser); 378 NaClEnvCleanserDtor(&env_cleanser);
366 379
367 ret_code = NaClWaitForMainThreadToExit(nap); 380 ret_code = NaClWaitForMainThreadToExit(nap);
368 381
369 if (NACL_ABI_WIFEXITED(nap->exit_status)) { 382 if (NACL_ABI_WIFEXITED(nap->exit_status)) {
370 /* 383 /*
371 * Under Chrome, a call to _exit() often indicates that something 384 * Under Chrome, a call to _exit() often indicates that something
372 * has gone awry, so we report it here to aid debugging. 385 * has gone awry, so we report it here to aid debugging.
373 * 386 *
374 * This conditional does not run if the NaCl process was 387 * This conditional does not run if the NaCl process was
375 * terminated forcibly, which is the normal case under Chrome. 388 * terminated forcibly, which is the normal case under Chrome.
376 * This forcible exit is triggered by the renderer closing the 389 * This forcible exit is triggered by the renderer closing the
377 * trusted SRPC channel, which we record as NACL_ABI_SIGKILL 390 * trusted SRPC channel, which we record as NACL_ABI_SIGKILL
378 * internally. 391 * internally.
379 */ 392 */
380 NaClLog(LOG_INFO, "NaCl untrusted code called _exit(0x%x)\n", ret_code); 393 NaClLog(LOG_INFO, "NaCl untrusted code called _exit(0x%x)\n", ret_code);
381 } 394 }
382 395
383 /* 396 /*
384 * exit_group or equiv kills any still running threads while module 397 * exit_group or equiv kills any still running threads while module
385 * addr space is still valid. otherwise we'd have to kill threads 398 * addr space is still valid. otherwise we'd have to kill threads
386 * before we clean up the address space. 399 * before we clean up the address space.
387 */ 400 */
388 NaClExit(ret_code); 401 NaClExit(ret_code);
402 }
389 403
390 done: 404 static void NaClCleanupAndExit(struct NaClApp *nap, NaClErrorCode errcode) {
391 fflush(stdout); 405 fflush(stdout);
392 406
393 /* 407 /*
394 * If there is a secure command channel, we sent an RPC reply with 408 * If there is a secure command channel, we sent an RPC reply with
395 * the reason that the nexe was rejected. If we exit now, that 409 * the reason that the nexe was rejected. If we exit now, that
396 * reply may still be in-flight and the various channel closure (esp 410 * reply may still be in-flight and the various channel closure (esp
397 * reverse channel) may be detected first. This would result in a 411 * reverse channel) may be detected first. This would result in a
398 * crash being reported, rather than the error in the RPC reply. 412 * crash being reported, rather than the error in the RPC reply.
399 * Instead, we wait for the hard-shutdown on the command channel. 413 * Instead, we wait for the hard-shutdown on the command channel.
400 */ 414 */
401 if (LOAD_OK != errcode) { 415 if (LOAD_OK != errcode) {
402 NaClBlockIfCommandChannelExists(nap); 416 NaClBlockIfCommandChannelExists(nap);
403 } 417 }
404 418
405 NaClAllModulesFini(); 419 NaClAllModulesFini();
406 420
407 NaClExit(ret_code); 421 NaClExit(1);
408 } 422 }
423
424 void NaClChromeMainStart(struct NaClChromeMainArgs *args) {
425 int irt_fd = args->irt_fd;
426 struct NaClApp *nap = NaClChromeMainCreateApp(args);
427 if (NULL != nap) {
428 if (NULL != nap->secure_service) {
429 NaClErrorCode errcode;
430 /*
431 * wait for start_module RPC call on secure channel thread.
432 */
433 errcode = NaClWaitForStartModuleCommand(nap);
434 if (LOAD_OK != errcode) {
435 NaClCleanupAndExit(nap, errcode);
436 return;
437 }
438 /* Assume the module has already been loaded. */
439 NaClChromeMainStartModule(nap, irt_fd);
440 }
441 }
442 }
OLDNEW
« no previous file with comments | « src/trusted/service_runtime/sel_main_chrome.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698