Ejemplo n.º 1
0
int main(void) {
  struct nacl_irt_clock ti;
  int                   errs = 0;

  ShowCurrentDefinitions();

  if (0 == nacl_interface_query(NACL_IRT_CLOCK_v0_1, &ti, sizeof(ti))) {
    fprintf(stderr, "IRT hook is not available\n");
    return 1;
  }

  errs += TimeTest(ti.clock_getres, CLOCK_REALTIME,
                   "clock_getres on realtime clock failed",
                   "Realtime clock resolution");
  errs += TimeTest(ti.clock_getres, CLOCK_MONOTONIC,
                   "clock_getres on monotonic clock failed",
                   "Monotonic clock resolution");
  errs += TimeTest(ti.clock_gettime, CLOCK_REALTIME,
                   "clock_gettime on realtime clock failed",
                   "Realtime clock value");
  errs += TimeTest(ti.clock_gettime, CLOCK_MONOTONIC,
                   "clock_gettime on monotonic clock failed",
                   "Monotonic clock value");
  return errs;
}
int main(void) {
  struct nacl_irt_thread ti;
  if (0 == nacl_interface_query(NACL_IRT_THREAD_v0_1, &ti, sizeof(ti))) {
    fprintf(stderr, "IRT hook is not available\n");
    return 1;
  }

  return 0;
}
Ejemplo n.º 3
0
/*
 * We don't do any locking here, but simultaneous calls are harmless enough.
 * They'll all be writing the same values to the same words.
 */
static void setup_irt_dyncode(void) {
  if (nacl_interface_query(NACL_IRT_DYNCODE_v0_1, &irt_dyncode,
                           sizeof(irt_dyncode)) != sizeof(irt_dyncode)) {
    static const char fail_msg[] =
        "IRT interface query failed for essential interface \""
        NACL_IRT_DYNCODE_v0_1 "\"!\n";
    write(2, fail_msg, sizeof(fail_msg) - 1);
    _exit(-1);
  }
}
Ejemplo n.º 4
0
/*
 * Check that the old version of the memory interface is
 * a prefix of the new version.
 */
void test_memory_interface_prefix(void) {
  struct nacl_irt_memory_v0_1 m1;
  struct nacl_irt_memory m2;
  void *addr;
  int rc;

  rc = nacl_interface_query(NACL_IRT_MEMORY_v0_1, &m1, sizeof m1);
  assert(rc == sizeof m1);

  /* Verify that v0.1 mmap ignores PROT_EXEC  */
  addr = 0;
  rc = m1.mmap(&addr,
               k64Kbytes,
               PROT_READ | PROT_WRITE | PROT_EXEC,
               MAP_PRIVATE | MAP_ANONYMOUS,
               kAnonymousFiledesc,
               0);
  /* Return value is actually new address and not a negative return code.  */
  assert(0xffff0000u > (uint32_t)rc);

  rc = nacl_interface_query(NACL_IRT_MEMORY_v0_2, &m2, sizeof m2);
  assert(rc == sizeof m2);

  /* Verify that v0.2 mmap does not ignore PROT_EXEC  */
  addr = 0;
  rc = m2.mmap(&addr,
               k64Kbytes,
               PROT_READ | PROT_WRITE | PROT_EXEC,
               MAP_PRIVATE | MAP_ANONYMOUS,
               kAnonymousFiledesc,
               0);
  assert(rc = -EINVAL);

  /* mmap is different, everything else should be the same.  */
  m2.mmap = m1.mmap;

  assert(memcmp(&m1, &m2, sizeof m1) == 0);
}
int main(int argc, char **argv) {
  const size_t pagesize = getpagesize();

  if (argc != 2) {
    fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
    return 2;
  }

  const char *filename = argv[1];
  int fd = open(filename, O_RDONLY);
  if (fd < 0) {
    fprintf(stderr, "Cannot open '%s': %s\n", filename, strerror(errno));
    return 2;
  }

  /*
   * This should match the IRT's g_dynamic_text_start and be the first
   * address that allocate_code_data wants to give out.
   */
  void *address = (void *) DYNAMIC_CODE_SEGMENT_START;

  /*
   * Do a PROT_EXEC, MAP_FIXED mapping first thing, before any
   * uses of the allocate_code_data interface.
   */
  try_map("first", fd, address, pagesize);

  struct nacl_irt_code_data_alloc alloc;
  int rc = nacl_interface_query(NACL_IRT_CODE_DATA_ALLOC_v0_1,
                                &alloc, sizeof alloc);
  assert(rc == sizeof alloc);

  uintptr_t alloc_addr;
  rc = alloc.allocate_code_data(0, pagesize, 0, 0, &alloc_addr);
  assert(rc == 0);

  if (alloc_addr == (uintptr_t) address) {
    fprintf(stderr,
            "allocate_code_data returned address already used by mmap!\n");
    return 1;
  }

  try_map("second", fd, (void *) alloc_addr, pagesize);

  return 0;
}
int NaClCrashDumpInit(void) {
  int result;

  assert(g_ExceptionHandlingEnabled == 0);
  if (nacl_interface_query(NACL_IRT_DEV_EXCEPTION_HANDLING_v0_1,
                           &g_ExceptionHandling,
                           sizeof(g_ExceptionHandling)) == 0) {
    return 0;
  }
  result = pthread_key_create(&g_CrashStackKey, NaClCrashDumpThreadDestructor);
  assert(result == 0);
  if (g_ExceptionHandling.exception_handler(CrashHandler, NULL) != 0) {
    return 0;
  }
  g_ExceptionHandlingEnabled = 1;
  if (!NaClCrashDumpInitThread()) {
    g_ExceptionHandlingEnabled = 0;
    return 0;
  }
  return 1;
}
/*
 * We don't do any locking here, but simultaneous calls are harmless enough.
 * They'll all be writing the same values to the same words.
 */
static int set_up_irt_exception_handling(void) {
  return nacl_interface_query(NACL_IRT_EXCEPTION_HANDLING_v0_1,
                              &irt_exception_handling,
                              sizeof(irt_exception_handling))
         == sizeof(irt_exception_handling);
}
Ejemplo n.º 8
0
static void chainload(const char *program, const char *interp_prefix,
                      int argc, char **argv, int envc, char **envp) {
  if (nacl_interface_query(NACL_IRT_RESOURCE_OPEN_v0_1, &resource_open,
                           sizeof(resource_open)) != sizeof(resource_open))
    resource_open.open_resource = NULL;
  if (nacl_interface_query(NACL_IRT_CODE_DATA_ALLOC_v0_1, &code_data_alloc,
                           sizeof(code_data_alloc)) !=
      sizeof(code_data_alloc)) {
    fprintf(stderr, "Failed to find necessary IRT interface %s!\n",
            NACL_IRT_CODE_DATA_ALLOC_v0_1);
    exit(1);
  }

  const size_t pagesize = NACL_MAP_PAGESIZE;
  const TYPE_nacl_irt_query irt_query = __nacl_irt_query;

  /*
   * Populate our own info array on the stack.  We do not assume that the
   * argv and envp arrays are in their usual layout, since the caller could
   * be passing different values.
   */
  uint32_t info[NACL_STARTUP_ARGV + argc + 1 + envc + 1 + (kAuxvCount * 2)];
  info[NACL_STARTUP_FINI] = 0;
  info[NACL_STARTUP_ENVC] = envc;
  info[NACL_STARTUP_ARGC] = argc;
  memcpy(nacl_startup_argv(info), argv, (argc + 1) * sizeof(argv[0]));
  memcpy(nacl_startup_envp(info), envp, (envc + 1) * sizeof(envp[0]));
  Elf32_auxv_t *auxv = nacl_startup_auxv(info);

  /*
   * Populate the auxiliary vector with the values dynamic linkers expect.
   */
  auxv[kPhdr].a_type = AT_PHDR;
  auxv[kPhent].a_type = AT_PHENT;
  auxv[kPhent].a_un.a_val = sizeof(Elf32_Phdr);
  auxv[kPhnum].a_type = AT_PHNUM;
  auxv[kBase].a_type = AT_BASE;
  auxv[kEntry].a_type = AT_ENTRY;
  auxv[kSysinfo].a_type = AT_SYSINFO;
  auxv[kSysinfo].a_un.a_val = (uint32_t) irt_query;
  auxv[kNull].a_type = AT_NULL;
  auxv[kNull].a_un.a_val = 0;

  /*
   * Load the program and point the auxv elements at its phdrs and entry.
   */
  const char *interp = NULL;
  uint32_t entry = load_elf_file(program,
                                 pagesize,
                                 &auxv[kBase].a_un.a_val,
                                 &auxv[kPhdr].a_un.a_val,
                                 &auxv[kPhnum].a_un.a_val,
                                 &interp);
  auxv[kEntry].a_un.a_val = entry;

  if (auxv[kPhdr].a_un.a_val == 0)
    auxv[kPhdr].a_type = AT_IGNORE;

  DEBUG_PRINTF("XXX loaded %s, entry %#x, interp %s\n", program, entry, interp);

  if (interp != NULL) {
    /*
     * There was a PT_INTERP, so we have a dynamic linker to load.
     */

    char interp_buf[PATH_MAX];
    if (interp_prefix != NULL) {
      /*
       * Apply the command-line-specified prefix to the embedded file name.
       */
      snprintf(interp_buf, sizeof(interp_buf), "%s%s", interp_prefix, interp);
      interp = interp_buf;
    }

    entry = load_elf_file(interp, pagesize, NULL, NULL, NULL, NULL);

    DEBUG_PRINTF("XXX loaded PT_INTERP %s, entry %#x\n", interp, entry);
  }

  for (uint32_t *p = info; p < (uint32_t *) &auxv[kNull + 1]; ++p)
    DEBUG_PRINTF("XXX info[%d] = %#x\n", p - info, *p);

  /*
   * Off to the races!
   * The application's entry point should not return.  Crash if it does.
   */
  DEBUG_PRINTF("XXX user entry point: %#x(%#x)\n", entry, (uintptr_t) info);
  (*(void (*)(uint32_t[])) entry)(info);
  while (1)
    __builtin_trap();
}