#include "native_client/src/trusted/desc_cacheability/desc_cacheability.h"
#include "native_client/src/trusted/fault_injection/fault_injection.h"
#include "native_client/src/trusted/fault_injection/test_injection.h"
-#include "native_client/src/trusted/gio/gio_nacl_desc.h"
-#include "native_client/src/trusted/gio/gio_shm.h"
#include "native_client/src/trusted/interval_multiset/nacl_interval_range_tree_intern.h"
#include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h"
#include "native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h"
#include "native_client/src/trusted/service_runtime/nacl_syscall_common.h"
#include "native_client/src/trusted/service_runtime/nacl_syscall_handlers.h"
#include "native_client/src/trusted/service_runtime/nacl_valgrind_hooks.h"
-#include "native_client/src/trusted/service_runtime/name_service/default_name_service.h"
#include "native_client/src/trusted/service_runtime/name_service/name_service.h"
#include "native_client/src/trusted/service_runtime/sel_addrspace.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#include "native_client/src/trusted/simple_service/nacl_simple_rservice.h"
#include "native_client/src/trusted/simple_service/nacl_simple_service.h"
#include "native_client/src/trusted/threading/nacl_thread_interface.h"
+#include "native_client/src/trusted/validator/rich_file_info.h"
#include "native_client/src/trusted/validator/validation_cache.h"
static int IsEnvironmentVariableSet(char const *env_name) {
nap->desc_quota_interface = NULL;
nap->module_initialization_state = NACL_MODULE_UNINITIALIZED;
- nap->module_load_status = LOAD_STATUS_UNKNOWN;
+ nap->module_load_status = LOAD_OK;
nap->name_service = (struct NaClNameService *) malloc(
sizeof *nap->name_service);
}
nap->name_service_conn_cap = NaClDescRef(nap->name_service->
base.base.bound_and_cap[1]);
- if (!NaClDefaultNameServiceInit(nap->name_service)) {
- goto cleanup_name_service;
- }
nap->ignore_validator_result = 0;
nap->skip_validator = 0;
}
}
+enum NaClModuleInitializationState NaClGetInitState(struct NaClApp *nap) {
+ enum NaClModuleInitializationState state;
+ NaClXMutexLock(&nap->mu);
+ state = nap->module_initialization_state;
+ NaClXMutexUnlock(&nap->mu);
+ return state;
+}
+
+void NaClSetInitState(struct NaClApp *nap,
+ enum NaClModuleInitializationState state) {
+ NaClXMutexLock(&nap->mu);
+ /* The initialization state should be increasing monotonically. */
+ CHECK(state > nap->module_initialization_state);
+ nap->module_initialization_state = state;
+ NaClXCondVarBroadcast(&nap->cv);
+ NaClXMutexUnlock(&nap->mu);
+}
+
NaClErrorCode NaClWaitForLoadModuleCommand(struct NaClApp *nap) {
NaClErrorCode status;
return status;
}
-NaClErrorCode NaClWaitForLoadModuleStatus(struct NaClApp *nap) {
- NaClErrorCode status;
-
- NaClLog(4, "NaClWaitForLoadModuleStatus started\n");
+void NaClRememberLoadStatus(struct NaClApp *nap, NaClErrorCode status) {
NaClXMutexLock(&nap->mu);
- while (LOAD_STATUS_UNKNOWN == (status = nap->module_load_status)) {
- NaClXCondVarWait(&nap->cv, &nap->mu);
+ /* Remember the first error we encountered. */
+ if (nap->module_load_status == LOAD_OK) {
+ nap->module_load_status = status;
}
NaClXMutexUnlock(&nap->mu);
- NaClLog(4, "NaClWaitForLoadModuleStatus finished\n");
+}
+
+NaClErrorCode NaClGetLoadStatus(struct NaClApp *nap) {
+ NaClErrorCode status;
+ NaClXMutexLock(&nap->mu);
+ status = nap->module_load_status;
+ NaClXMutexUnlock(&nap->mu);
return status;
}
NaClErrorCode status),
void *instance_data) {
NaClErrorCode status = LOAD_OK;
+ int is_double_init = NaClGetInitState(nap) != NACL_MODULE_UNINITIALIZED;
NaClLog(4,
("Entered NaClAppLoadModule: nap 0x%"NACL_PRIxPTR","
" nexe 0x%"NACL_PRIxPTR"\n"),
(uintptr_t) nap, (uintptr_t) nexe);
+
+ if (NULL != load_cb) {
+ NaClErrorCode cb_status;
+ if (is_double_init) {
+ cb_status = LOAD_DUP_LOAD_MODULE;
+ } else {
+ cb_status = LOAD_OK;
+ }
+ (*load_cb)(instance_data, cb_status);
+ }
+
+ if (is_double_init) {
+ NaClLog(LOG_ERROR, "NaClAppLoadModule: repeated invocation\n");
+ return;
+ }
+
+ NaClSetInitState(nap, NACL_MODULE_LOADING);
+
/*
* Ref was passed by value into |nexe| parameter, so up the refcount.
* Be sure to unref when the parameter's copy goes out of scope
*/
NaClDescRef(nexe);
- /*
- * TODO(bsy): consider doing the processing below after sending the
- * RPC reply to increase parallelism.
- */
- NaClXMutexLock(&nap->mu);
- if (nap->module_initialization_state != NACL_MODULE_UNINITIALIZED) {
- NaClLog(LOG_ERROR, "NaClAppLoadModule: repeated invocation\n");
- status = LOAD_DUP_LOAD_MODULE;
- NaClXMutexUnlock(&nap->mu);
- if (NULL != load_cb) {
- (*load_cb)(instance_data, status);
- }
- NaClDescUnref(nexe);
- return;
- }
- nap->module_initialization_state = NACL_MODULE_LOADING;
- NaClXCondVarBroadcast(&nap->cv);
- NaClXMutexUnlock(&nap->mu);
-
- if (NULL != load_cb) {
- (*load_cb)(instance_data, status);
- }
-
NaClXMutexLock(&nap->mu);
/*
- * Check and possibly mark the nexe binary as OK to attempt memory
- * mapping. We first clear the safe-for-mmap flag -- if we do not
- * trust the renderer to really send us a safe-to-mmap descriptor
- * and have to query the validation cache, then we also do not want
- * to trust the metadata flag value that originated from the
- * renderer.
+ * TODO(teravest): Remove this when file tokens are no longer used in |nexe|.
*/
- NaClDescMarkUnsafeForMmap(nexe);
NaClReplaceDescIfValidationCacheAssertsMappable(&nexe,
nap->validation_cache);
+
/* Transfer ownership from nexe to nap->main_nexe_desc. */
CHECK(nap->main_nexe_desc == NULL);
nap->main_nexe_desc = nexe;
NaClAppLoadFile(nap->main_nexe_desc, nap));
if (LOAD_OK != status) {
- nap->module_load_status = status;
- nap->module_initialization_state = NACL_MODULE_ERROR;
- NaClXCondVarBroadcast(&nap->cv);
+ NaClDescUnref(nap->main_nexe_desc);
+ nap->main_nexe_desc = NULL;
}
NaClXMutexUnlock(&nap->mu); /* NaClAppPrepareToLaunch takes mu */
+
if (LOAD_OK != status) {
- NaClDescUnref(nap->main_nexe_desc);
- nap->main_nexe_desc = NULL;
+ NaClRememberLoadStatus(nap, status);
+ NaClSetInitState(nap, NACL_MODULE_ERROR);
return;
}
* Finish setting up the NaCl App.
*/
status = NaClAppPrepareToLaunch(nap);
-
- NaClXMutexLock(&nap->mu);
- nap->module_load_status = status;
- nap->module_initialization_state = NACL_MODULE_LOADED;
- NaClXCondVarBroadcast(&nap->cv);
- NaClXMutexUnlock(&nap->mu);
+ NaClRememberLoadStatus(nap, status);
+ NaClSetInitState(nap, NACL_MODULE_LOADED);
/* Give debuggers a well known point at which xlate_base is known. */
NaClGdbHook(nap);
*/
NaClXMutexLock(&nap->mu);
if (NACL_MODULE_LOADING == nap->module_initialization_state) {
- while (NACL_MODULE_LOADED != nap->module_initialization_state) {
+ while (NACL_MODULE_LOADING == nap->module_initialization_state) {
NaClXCondVarWait(&nap->cv, &nap->mu);
}
}
+ status = nap->module_load_status;
if (nap->module_initialization_state != NACL_MODULE_LOADED) {
if (NACL_MODULE_ERROR == nap->module_initialization_state) {
NaClLog(LOG_ERROR, "NaClAppStartModule: error loading module\n");
- status = nap->module_load_status;
} else if (nap->module_initialization_state > NACL_MODULE_LOADED) {
NaClLog(LOG_ERROR, "NaClAppStartModule: repeated invocation\n");
status = LOAD_DUP_START_MODULE;
}
return;
}
- status = nap->module_load_status;
- nap->module_initialization_state = NACL_MODULE_STARTING;
- NaClXCondVarBroadcast(&nap->cv);
NaClXMutexUnlock(&nap->mu);
+ NaClSetInitState(nap, NACL_MODULE_STARTING);
+
NaClLog(4, "NaClSecureChannelStartModule: load status %d\n", status);
/*
(*start_cb)(instance_data, status);
}
- NaClXMutexLock(&nap->mu);
- nap->module_initialization_state = NACL_MODULE_STARTED;
- NaClXCondVarBroadcast(&nap->cv);
- NaClXMutexUnlock(&nap->mu);
+ NaClSetInitState(nap, NACL_MODULE_STARTED);
}
void NaClAppShutdown(struct NaClApp *nap,