Exemplo n.º 1
0
static int32_t TestSyscall(struct NaClAppThread *natp) {
  NaClCopyInDropLock(natp->nap);

  NaClTlsSetIdx(0);

  return 0;
}
NORETURN void NaClSyscallCSegHook(int32_t tls_idx) {
  struct NaClAppThread      *natp;
  struct NaClApp            *nap;
  uintptr_t                 tramp_ret;
  size_t                    sysnum;
  uintptr_t                 sp_user;
  uint32_t                  sysret;

  /*
   * Mark the thread as running on a trusted stack as soon as possible
   * so that we can report any crashes that occur after this point.
   */
  NaClStackSafetyNowOnTrustedStack();

  natp = nacl_thread[tls_idx];

  HandleStackContext(natp, &tramp_ret, &sp_user);

  /*
   * Before this call, the thread could be suspended, so we should not
   * lock any mutexes before this, otherwise it could cause a
   * deadlock.
   */
  NaClAppThreadSetSuspendState(natp, NACL_APP_THREAD_UNTRUSTED,
                               NACL_APP_THREAD_TRUSTED);

  nap = natp->nap;

  NaClLog(4, "Entered NaClSyscallCSegHook\n");
  NaClLog(4, "user sp %"NACL_PRIxPTR"\n", sp_user);

  NaClCopyInTakeLock(nap);
  /*
   * held until syscall args are copied, which occurs in the generated
   * code.
   */

  sysnum = (tramp_ret - (nap->mem_start + NACL_SYSCALL_START_ADDR))
      >> NACL_SYSCALL_BLOCK_SHIFT;

  NaClLog(4, "system call %"NACL_PRIuS"\n", sysnum);

  /*
   * usr_syscall_args is used by Decoder functions in
   * nacl_syscall_handlers.c which is automatically generated file and
   * placed in the
   * scons-out/.../gen/native_client/src/trusted/service_runtime/
   * directory.  usr_syscall_args must point to the first argument of
   * a system call. System call arguments are placed on the untrusted
   * user stack.
   *
   * We save the user address for user syscall arguments fetching and
   * for VM range locking.
   */
  natp->usr_syscall_args = NaClRawUserStackAddrNormalize(sp_user +
                                                         NACL_SYSARGS_FIX);

  if (sysnum >= NACL_MAX_SYSCALLS) {
    NaClLog(2, "INVALID system call %"NACL_PRIdS"\n", sysnum);
    sysret = -NACL_ABI_EINVAL;
    NaClCopyInDropLock(nap);
  } else {
    NaClLog(4, "making system call %"NACL_PRIdS", "
            "handler 0x%08"NACL_PRIxPTR"\n",
            sysnum, (uintptr_t) nap->syscall_table[sysnum].handler);
    sysret = (*(nap->syscall_table[sysnum].handler))(natp);
    /* Implicitly drops lock */
  }
  NaClLog(4,
          ("returning from system call %"NACL_PRIdS", return value %"NACL_PRId32
           " (0x%"NACL_PRIx32")\n"),
          sysnum, sysret, sysret);
  natp->user.sysret = sysret;

  NaClLog(4, "return target 0x%08"NACL_PRIxNACL_REG"\n",
          natp->user.new_prog_ctr);
  NaClLog(4, "user sp %"NACL_PRIxPTR"\n", sp_user);

  /*
   * After this NaClAppThreadSetSuspendState() call, we should not
   * claim any mutexes, otherwise we risk deadlock.  Note that if
   * NACLVERBOSITY is set high enough to enable the NaClLog() calls in
   * NaClSwitchToApp(), these calls could deadlock.
   */
  NaClAppThreadSetSuspendState(natp, NACL_APP_THREAD_TRUSTED,
                               NACL_APP_THREAD_UNTRUSTED);
  NaClStackSafetyNowOnUntrustedStack();

  NaClSwitchToApp(natp);
  /* NOTREACHED */

  fprintf(stderr, "NORETURN NaClSwitchToApp returned!?!\n");
  NaClAbort();
}