コード例 #1
0
ファイル: nacl_signal_common.c プロジェクト: bortoq/zerovm
void NaClSignalHandlerInit() {
  int a;

  /* Build the free list */
  for (a = 0; a < MAX_NACL_HANDLERS; a++) {
    s_SignalNodes[a].next = s_FreeList;
    s_SignalNodes[a].id = a + 1;
    s_FreeList = &s_SignalNodes[a];
  }

  NaClSignalHandlerInitPlatform();
#ifdef NACL_STANDALONE
  /* In stand-alone mode (sel_ldr) we handle all signals. */
  NaClSignalHandlerAdd(NaClSignalHandleAll);
#else
  /*
   * When run in Chrome we handle only signals in untrusted code.
   * Signals in trusted code are allowed to pass back to Chrome so
   * that Breakpad can create a minidump when applicable.
   */
  NaClSignalHandlerAdd(NaClSignalHandleUntrusted);
#endif
  if (getenv("NACL_CRASH_TEST") != NULL) {
    NaClSignalErrorMessage("[CRASH_TEST] Causing crash in NaCl "
                           "trusted code...\n");
    /* Clang removes non-volatile NULL pointer references. */
    *(volatile int *) 0 = 0;
  }
}
コード例 #2
0
ファイル: nacl_signal_common.c プロジェクト: clatour/zerovm
void NaClSignalHandlerInit()
{
  int a;

  /* return if signals handling is not enabled */
  if(!handle_signals) return;

  /* Build the free list */
  for(a = 0; a < MAX_NACL_HANDLERS; a++)
  {
    s_SignalNodes[a].next = s_FreeList;
    s_SignalNodes[a].id = a + 1;
    s_FreeList = &s_SignalNodes[a];
  }

  NaClSignalHandlerInitPlatform();

  /* In stand-alone mode (sel_ldr) we handle all signals. */
  NaClSignalHandlerAdd(NaClSignalHandleAll);
}
コード例 #3
0
int NaClMainForChromium(int handle_count, const NaClHandle *handles,
                        int debug) {
  char *av[1];
  int ac = 1;
  const char **envp;
  struct NaClApp state;
  int main_thread_only = 1;
  int export_addr_to = kSrpcFd; /* Used to be set by -X. */
  struct NaClApp *nap;
  NaClErrorCode errcode;
  int ret_code = 1;
  struct NaClEnvCleanser env_cleanser;

#if NACL_OSX
  /* Mac dynamic libraries cannot access the environ variable directly. */
  envp = (const char **) *_NSGetEnviron();
#else
  /* Overzealous code style check is overzealous. */
  /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */
  extern char **environ;
  envp = (const char **) environ;
#endif

  NaClAllModulesInit();

  /* Add a handler to catch untrusted errors only */
  NaClSignalHandlerAdd(NaClSignalHandleUntrusted);

  /* to be passed to NaClMain, eventually... */
  av[0] = "NaClMain";

  if (!NaClAppCtor(&state)) {
    fprintf(stderr, "Error while constructing app state\n");
    goto done;
  }

  state.restrict_to_main_thread = main_thread_only;

  nap = &state;
  errcode = LOAD_OK;

  /* import IMC handle - used to be "-i" */
  CHECK(handle_count == 3);
  NaClAddImcHandle(nap, handles[0], export_addr_to);
  NaClAddImcHandle(nap, handles[1], 6); /* async_receive_desc */
  NaClAddImcHandle(nap, handles[2], 7); /* async_send_desc */

  /*
   * in order to report load error to the browser plugin through the
   * secure command channel, we do not immediate jump to cleanup code
   * on error.  rather, we continue processing (assuming earlier
   * errors do not make it inappropriate) until the secure command
   * channel is set up, and then bail out.
   */

  /*
   * Ensure this operating system platform is supported.
   */
  errcode = NaClRunSelQualificationTests();
  if (LOAD_OK != errcode) {
    nap->module_load_status = errcode;
    fprintf(stderr, "Error while loading in SelMain: %s\n",
            NaClErrorString(errcode));
  }

  /* Give debuggers a well known point at which xlate_base is known.  */
  NaClGdbHook(&state);

  /*
   * If export_addr_to is set to a non-negative integer, we create a
   * bound socket and socket address pair and bind the former to
   * descriptor 3 and the latter to descriptor 4.  The socket address
   * is written out to the export_addr_to descriptor.
   *
   * The service runtime also accepts a connection on the bound socket
   * and spawns a secure command channel thread to service it.
   *
   * If export_addr_to is -1, we only create the bound socket and
   * socket address pair, and we do not export to an IMC socket.  This
   * use case is typically only used in testing, where we only "dump"
   * the socket address to stdout or similar channel.
   */
  if (-2 < export_addr_to) {
    NaClCreateServiceSocket(nap);
    if (0 <= export_addr_to) {
      NaClSendServiceAddressTo(nap, export_addr_to);
      /*
       * NB: spawns a thread that uses the command channel.  we do
       * this after NaClAppLoadFile so that NaClApp object is more
       * fully populated.  Hereafter any changes to nap should be done
       * while holding locks.
       */
      NaClSecureCommandChannel(nap);
    }
  }

  if (NULL != nap->secure_channel && LOAD_OK == errcode) {
    /*
     * wait for start_module RPC call on secure channel thread.
     */
    errcode = NaClWaitForStartModuleCommand(nap);
  }

  /*
   * error reporting done; can quit now if there was an error earlier.
   */
  if (LOAD_OK != errcode) {
    goto done;
  }


  /*
   * Enable debugging if requested.
   */
  if (debug) NaClDebugSetAllow(1);

  NaClEnvCleanserCtor(&env_cleanser);
  if (!NaClEnvCleanserInit(&env_cleanser, envp)) {
    NaClLog(LOG_FATAL, "Failed to initialise env cleanser\n");
  }

  /*
   * only nap->ehdrs.e_entry is usable, no symbol table is
   * available.
   */
  if (!NaClCreateMainThread(nap, ac, av,
                            NaClEnvCleanserEnvironment(&env_cleanser))) {
    fprintf(stderr, "creating main thread failed\n");
    goto done;
  }

  NaClEnvCleanserDtor(&env_cleanser);

  ret_code = NaClWaitForMainThreadToExit(nap);

  /*
   * exit_group or equiv kills any still running threads while module
   * addr space is still valid.  otherwise we'd have to kill threads
   * before we clean up the address space.
   */
  return ret_code;

 done:
  fflush(stdout);

  NaClAllModulesFini();

  return ret_code;
}
コード例 #4
0
int NaClMainForChromium(int handle_count, const NaClHandle *handles,
                        int debug) {
  char *av[1];
  int ac = 1;
  const char **envp;
  struct NaClApp state;
  int main_thread_only = 1;
  char                          *nacl_file = "test_nexe/hello_ppapi.nexe";
  struct NaClApp *nap;
  enum NaClAbiCheckOption       check_abi = NACL_ABI_CHECK_OPTION_CHECK;
  struct GioFile                gout;
  struct GioMemoryFileSnapshot  gf;
  NaClErrorCode errcode;
  int ret_code = 1;
  struct NaClEnvCleanser env_cleanser;

#if NACL_OSX
  /* Mac dynamic libraries cannot access the environ variable directly. */
  envp = (const char **) *_NSGetEnviron();
#else
  /* Overzealous code style check is overzealous. */
  /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */
  extern char **environ;
  envp = (const char **) environ;
#endif

  NaClAllModulesInit();

  /* Add a handler to catch untrusted errors only */
  NaClSignalHandlerAdd(NaClSignalHandleUntrusted);

  /* to be passed to NaClMain, eventually... */
  av[0] = "NaClMain";

  if (!NaClAppCtor(&state)) {
    fprintf(stderr, "Error while constructing app state\n");
    goto done;
  }

  state.restrict_to_main_thread = main_thread_only;

  nap = &state;
  errcode = LOAD_OK;
  /*
   * in order to report load error to the browser plugin through the
   * secure command channel, we do not immediate jump to cleanup code
   * on error.  rather, we continue processing (assuming earlier
   * errors do not make it inappropriate) until the secure command
   * channel is set up, and then bail out.
   */

  /*
   * Ensure this operating system platform is supported.
   */
  errcode = NaClRunSelQualificationTests();
  if (LOAD_OK != errcode) {
    nap->module_load_status = errcode;
    fprintf(stderr, "Error while loading in SelMain: %s\n",
            NaClErrorString(errcode));
  }

  /* Give debuggers a well known point at which xlate_base is known.  */
  NaClGdbHook(&state);

  if (0 == GioMemoryFileSnapshotCtor(&gf, nacl_file)) {
    perror("sel_main");
    fprintf(stderr, "Cannot open \"%s\".\n", nacl_file);
    errcode = LOAD_OPEN_ERROR;
  }

  if (LOAD_OK == errcode) {
    errcode = NaClAppLoadFile((struct Gio *) &gf, nap, check_abi);
    if (LOAD_OK != errcode) {
      fprintf(stderr, "Error while loading \"%s\": %s\n",
              nacl_file,
              NaClErrorString(errcode));
      fprintf(stderr,
              ("Using the wrong type of nexe (nacl-x86-32"
               " on an x86-64 or vice versa)\n"
               "or a corrupt nexe file may be"
               " responsible for this error.\n"));
    }

    NaClXMutexLock(&nap->mu);
    nap->module_load_status = errcode;
    NaClXCondVarBroadcast(&nap->cv);
    NaClXMutexUnlock(&nap->mu);
  }

   if (LOAD_OK == errcode) {
     if (verbosity) {
       gprintf((struct Gio *) &gout, "printing NaClApp details\n");
       NaClAppPrintDetails(nap, (struct Gio *) &gout);
     }

     /*
      * Finish setting up the NaCl App.  This includes dup'ing
      * descriptors 0-2 and making them available to the NaCl App.
      */
     errcode = NaClAppPrepareToLaunch(nap,
                                      0,
                                      1,
                                      2);
     if (LOAD_OK != errcode) {
       nap->module_load_status = errcode;
       fprintf(stderr, "NaClAppPrepareToLaunch returned %d", errcode);
     }
   }

   if (-1 == (*((struct Gio *) &gf)->vtbl->Close)((struct Gio *) &gf)) {
     fprintf(stderr, "Error while closing \"%s\".\n", nacl_file);
   }
   (*((struct Gio *) &gf)->vtbl->Dtor)((struct Gio *) &gf);

 /*
  * Print out a marker for scripts to use to mark the start of app
  * output.
  */
 NaClLog(1, "NACL: Application output follows\n");

 /*
  * Make sure all the file buffers are flushed before entering
  * the application code.
  */
 fflush((FILE *) NULL);

  /*
   * Enable debugging if requested.
   */
  if (debug) NaClDebugSetAllow(1);

  NaClEnvCleanserCtor(&env_cleanser);
  if (!NaClEnvCleanserInit(&env_cleanser, envp)) {
    NaClLog(LOG_FATAL, "Failed to initialise env cleanser\n");
  }

  /*
   * only nap->ehdrs.e_entry is usable, no symbol table is
   * available.
   */
  if (!NaClCreateMainThread(nap, ac, av,
                            NaClEnvCleanserEnvironment(&env_cleanser))) {
    fprintf(stderr, "creating main thread failed\n");
    goto done;
  }

  NaClEnvCleanserDtor(&env_cleanser);

  ret_code = NaClWaitForMainThreadToExit(nap);

  /*
   * exit_group or equiv kills any still running threads while module
   * addr space is still valid.  otherwise we'd have to kill threads
   * before we clean up the address space.
   */
  return ret_code;

 done:
  fflush(stdout);

  NaClAllModulesFini();

  return ret_code;
}