int main(int ac,
         char **av) {
  struct NaClDescIoDesc *src;
  struct NaClDescIoDesc *dst;
  struct NaClGioNaClDesc gsrc;
  struct NaClGioNaClDesc gdst;
  int num_errors = 0;

  if (ac != 3) {
    Usage();
    return -1;
  }

  NaClLogModuleInit();
  NaClTimeInit();
  NaClSecureRngModuleInit();
  NaClGlobalSecureRngInit();

  src = NaClDescIoDescOpen(av[1], NACL_ABI_O_RDONLY, 0);
  if (NULL == src) {
    fprintf(stderr, "could not open %s for read\n", av[1]);
    Usage();
    return -2;
  }
  dst = NaClDescIoDescOpen(av[2],
                           NACL_ABI_O_WRONLY|
                           NACL_ABI_O_TRUNC|
                           NACL_ABI_O_CREAT,
                           0666);
  if (NULL == dst) {
    fprintf(stderr, "could not open %s for write\n", av[2]);
    Usage();
    return -3;
  }
  if (!NaClGioNaClDescCtor(&gsrc, (struct NaClDesc *) src)) {
    fprintf(stderr, "NaClGioNaClDescCtor faied for source file\n");
    return -4;
  }
  if (!NaClGioNaClDescCtor(&gdst, (struct NaClDesc *) dst)) {
    fprintf(stderr, "NaClGioNaClDescCtor faied for destination file\n");
    return -5;
  }

  num_errors += GioCopy((struct Gio *) &gsrc, (struct Gio *) &gdst);
  num_errors += ComparePosixFiles(av[1], av[2]);

  (*NACL_VTBL(Gio, &gdst)->Close)(&gdst.base);
  (*NACL_VTBL(Gio, &gdst)->Dtor)(&gdst.base);

  if (0 < num_errors) {
    return num_errors;
  }

  RemoveFile(av[2]);

  /* reverse copy; reuse gsrc */

  dst = NaClDescIoDescOpen(av[2],
                           NACL_ABI_O_WRONLY|
                           NACL_ABI_O_TRUNC|
                           NACL_ABI_O_CREAT,
                           0666);
  if (NULL == dst) {
    fprintf(stderr, "could not open %s for write\n", av[2]);
    Usage();
    return -6;
  }
  if (!NaClGioNaClDescCtor(&gdst, (struct NaClDesc *) dst)) {
    fprintf(stderr, "NaClGioNaClDescCtor faied for destination file\n");
    return -7;
  }

  /*
   * We run GioRevCopy twice because if Seek failed to move the file
   * pointer but reported the file size correctly, it would still
   * result in a correct output.  By running it twice, the destination
   * data is just overwritten if the implementation is correct, and if
   * it isn't, we would end up with a file that is twice the source
   * file size.
   */
  num_errors += GioRevCopy((struct Gio *) &gsrc, (struct Gio *) &gdst);
  num_errors += GioRevCopy((struct Gio *) &gsrc, (struct Gio *) &gdst);
  num_errors += ComparePosixFiles(av[1], av[2]);

  (*NACL_VTBL(Gio, &gdst)->Close)((struct Gio *) &gdst);
  (*NACL_VTBL(Gio, &gdst)->Dtor)((struct Gio *) &gdst);

  (*NACL_VTBL(Gio, &gsrc)->Close)((struct Gio *) &gsrc);
  (*NACL_VTBL(Gio, &gsrc)->Dtor)((struct Gio *) &gsrc);

  if (0 < num_errors) {
    return num_errors;
  }

  RemoveFile(av[2]);

  return num_errors;
}
예제 #2
0
파일: sel_main.c 프로젝트: vi4m/zerovm
int main(int argc, char **argv)
{
  struct NaClApp state, *nap = &state;
  struct SystemManifest sys_mft;
  struct GioMemoryFileSnapshot main_file;
  struct NaClPerfCounter time_all_main;

  /* zerovm initialization */
  memset(nap, 0, sizeof *nap);
  nap->system_manifest = &sys_mft;
  memset(nap->system_manifest, 0, sizeof *nap->system_manifest);
  gnap = nap;

  ParseCommandLine(nap, argc, argv);
  NaClSignalHandlerInit();
  NaClTimeInit();
  NaClSyscallTableInit();
  NaClPerfCounterCtor(&time_all_main, "SelMain");

  /* initialize mem_map and set nap fields to default values */
  ZLOGFAIL(NaClAppCtor(nap) == 0, EFAULT, "Error while constructing app state");

  /* We use the signal handler to verify a signal took place. */
  if(nap->skip_qualification == 0) NaClRunSelQualificationTests();

  /* Remove the signal handler if we are not using it. */
  if(nap->handle_signals == 0)
  {
    NaClSignalHandlerFini();
    NaClSignalAssertNoHandlers(); /* Sanity check. */
  }

#define PERF_CNT(str) \
  NaClPerfCounterMark(&time_all_main, str);\
  NaClPerfCounterIntervalLast(&time_all_main);

  /* read nexe into memory */
  ZLOGFAIL(0 == GioMemoryFileSnapshotCtor(&main_file, nap->system_manifest->nexe),
      ENOENT, "Cannot open '%s'. %s", nap->system_manifest->nexe, strerror(errno));

  PERF_CNT("SnapshotNaclFile");

  /* validate given nexe (ensure that text segment is safe) */
  ValidateNexe(nap);

  /* validate nexe structure (check elf header and segments) */
  ZLOGS(LOG_DEBUG, "Loading nacl file %s", nap->system_manifest->nexe);
  NaClAppLoadFile((struct Gio *) &main_file, nap);
  PERF_CNT("AppLoadEnd");

  if(-1 == (*((struct Gio *)&main_file)->vtbl->Close)((struct Gio *)&main_file))
    ZLOG(LOG_ERROR, "Error while closing '%s'", nap->system_manifest->nexe);

  (*((struct Gio *) &main_file)->vtbl->Dtor)((struct Gio *) &main_file);
  if(nap->quit_after_load) NaClExit(0);

  /* setup zerovm from manifest */
  SystemManifestCtor(nap); /* needs dyn_array initialized */

  /* "defence in depth" call */
  LastDefenseLine(nap);

  /* start accounting */
  AccountingCtor(nap);

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

  /* set user code trap() exit location and switch to the user code */
  PERF_CNT("CreateMainThread");
  if(setjmp(user_exit) == 0)
    ZLOGFAIL(!NaClCreateMainThread(nap), EFAULT, "switching to nexe failed");
  SetExitState(OK_STATE);
  PERF_CNT("WaitForMainThread");
  PERF_CNT("SelMainEnd");

  /* zerovm exit with finalization, report and stuff */
  NaClExit(0);

  /* Unreachable, but having the return prevents a compiler error. */
  return -1;
}