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; }
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; }