/* todo(d'b): remove the patch after reworking zvm signals */ static void SpecSignals() { if(strstr(zvm_state, "Signal 14") != NULL) SetExitState("session timeout"); else if(strstr(zvm_state, "Signal 25") != NULL) SetExitState("disk quota exceeded"); }
/* exit zerovm with "interrupted syscall" code and the message */ static enum SignalResult SignalHandleAll(int signum, void *ctx) { struct SignalContext sigCtx; char msg[SIGNAL_STRLEN]; /* TODO(d'b): is it a proper solution? */ static int busy = 0; if(busy) return NACL_SIGNAL_RETURN; busy = 1; /* * Return an 8 bit error code which is -signal to * simulate normal OS behavior */ SignalContextFromHandler(&sigCtx, ctx); /* set zerovm state */ if(signum == SIGALRM) g_snprintf(msg, SIGNAL_STRLEN, "session timeout"); else if(signum == SIGXFSZ) g_snprintf(msg, SIGNAL_STRLEN, "disk quota exceeded"); else g_snprintf(msg, SIGNAL_STRLEN, "Signal %d from %strusted code: Halting at 0x%012lX", signum, SignalContextIsUntrusted(&sigCtx) ? "un" : "", sigCtx.prog_ctr); SetExitState(msg); ReportDtor(EINTR); return NACL_SIGNAL_RETURN; /* unreachable */ }
/* user exit. session is finished */ static void ZVMExitHandle(struct NaClApp *nap, int32_t code) { assert(nap != NULL); SetUserCode(code); if(GetExitCode() == 0) SetExitState(OK_STATE); ZLOGS(LOG_DEBUG, "SESSION %d RETURNED %d", nap->manifest->node, code); ReportDtor(0); }
/* user exit. session is finished */ static int32_t ZVMExitHandle(struct NaClApp *nap, int32_t code) { assert(nap != NULL); nap->system_manifest->user_ret_code = code; ZLOGS(LOG_DEBUG, "SESSION RETURNED %d", code); SetExitState(OK_STATE); NaClExit(0); return 0; /* unreachable */ }
void MailThread::Run() { FILE *pipe = popen(Config->SendMailPath.c_str(), "w"); if (!pipe) { SetExitState(); return; } fprintf(pipe, "From: %s\n", Config->SendFrom.c_str()); if (this->DontQuoteAddresses) fprintf(pipe, "To: %s <%s>\n", MailTo.c_str(), Addr.c_str()); else fprintf(pipe, "To: \"%s\" <%s>\n", MailTo.c_str(), Addr.c_str()); fprintf(pipe, "Subject: %s\n", Subject.c_str()); fprintf(pipe, "%s", Message.c_str()); fprintf(pipe, "\n.\n"); pclose(pipe); Success = true; SetExitState(); }
void Mail::Message::Run() { FILE *pipe = popen(sendmail_path.c_str(), "w"); if (!pipe) { SetExitState(); return; } fprintf(pipe, "From: %s\n", send_from.c_str()); if (this->dont_quote_addresses) fprintf(pipe, "To: %s <%s>\n", mail_to.c_str(), addr.c_str()); else fprintf(pipe, "To: \"%s\" <%s>\n", mail_to.c_str(), addr.c_str()); fprintf(pipe, "Subject: %s\n", subject.c_str()); fprintf(pipe, "%s", message.c_str()); fprintf(pipe, "\n.\n"); pclose(pipe); success = true; SetExitState(); }
/* * A basic handler which will exit with -signal_number when * a signal is encountered. */ static enum NaClSignalResult NaClSignalHandleAll(int signum, void *ctx) { struct NaClSignalContext sigCtx; char msg[SIGNAL_STRLEN]; /* todo(d'b): is it proper solution? */ static int busy = 0; if(busy) return NACL_SIGNAL_RETURN; busy = 1; /* * Return an 8 bit error code which is -signal to * simulate normal OS behavior */ NaClSignalContextFromHandler(&sigCtx, ctx); /* set zvm state */ g_snprintf(msg, SIGNAL_STRLEN, "Signal %d from %strusted code: Halting at 0x%012lX", signum, NaClSignalContextIsUntrusted(&sigCtx) ? "un" : "", sigCtx.prog_ctr); SetExitState(msg); NaClExit(EINTR); return NACL_SIGNAL_RETURN; /* unreachable */ }
int PrefetchChannelDtor(struct ChannelDesc *channel) { char url[BIG_ENOUGH_STRING]; /* debug purposes only */ assert(channel != NULL); assert(channel->socket != NULL); /* log parameters and channel internals */ MakeURL(url, BIG_ENOUGH_STRING, channel, GetChannelConnectionInfo(channel)); ZLOGS(LOG_DEBUG, "%s has url %s", channel->alias, url); /* close "PUT" channel */ if(channel->limits[PutsLimit] && channel->limits[PutSizeLimit]) { int size = CHANNELS_ETAG_ENABLED ? TAG_DIGEST_SIZE - 1 : 0; /* prepare digest */ if(TagEngineEnabled()) { TagDigest(channel->tag, channel->digest); TagDtor(channel->tag); } /* send eof */ channel->eof = 1; SendMessage(channel, channel->digest, size); ZLOGS(LOG_DEBUG, "%s closed with tag %s, putsize %ld", channel->alias, channel->digest, channel->counters[PutSizeLimit]); } /* close "GET" channel */ if(channel->limits[GetsLimit] && channel->limits[GetSizeLimit]) { /* wind the channel to the end */ while(channel->eof == 0) { char buf[NET_BUFFER_SIZE]; int32_t size = FetchMessage(channel, buf, NET_BUFFER_SIZE); ++channel->counters[GetsLimit]; channel->counters[GetSizeLimit] += size; /* update tag if enabled */ if(TagEngineEnabled()) TagUpdate(channel->tag, buf, size); } /* test integrity (if etag enabled) */ if(TagEngineEnabled()) { /* prepare digest */ TagDigest(channel->tag, channel->digest); TagDtor(channel->tag); /* raise the error if the data corrupted */ if(memcmp(channel->control, channel->digest, TAG_DIGEST_SIZE) != 0) { ZLOG(LOG_ERROR, "%s corrupted, control: %s, local: %s", channel->alias, channel->control, channel->digest); SetExitState("data corrupted"); SetExitCode(EPIPE); } ZLOGS(LOG_DEBUG, "%s closed with tag %s, getsize %ld", channel->alias, channel->digest, channel->counters[GetSizeLimit]); } zmq_msg_close(&channel->msg); zmq_close(channel->socket); } /* will destroy context and netlist after all network channels closed */ NetDtor(); return 0; }
int main(int argc, char **argv) { struct NaClApp state, *nap = &state; struct SystemManifest sys_mft; struct GioMemoryFileSnapshot main_file; GTimer *timer; /* 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(); NaClSyscallTableInit(); /* 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. */ } /* read nexe into memory */ timer = g_timer_new(); ZLOGFAIL(0 == GioMemoryFileSnapshotCtor(&main_file, nap->system_manifest->nexe), ENOENT, "Cannot open '%s'. %s", nap->system_manifest->nexe, strerror(errno)); #define TIMER_REPORT(msg) \ do {\ ZLOGS(LOG_DEBUG, msg " took %.3f milliseconds",\ g_timer_elapsed(timer, NULL) * NACL_MICROS_PER_MILLI);\ g_timer_start(timer);\ } while(0) TIMER_REPORT("GioMemoryFileSnapshotCtor()"); /* validate given nexe (ensure that text segment is safe) */ ValidateNexe(nap); TIMER_REPORT("ValidateNexe()"); /* 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); TIMER_REPORT("NaClAppLoadFile()"); 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); /* quit if fuzz testing specified */ if(nap->quit_after_load) { SetExitState(OK_STATE); NaClExit(0); } /* setup zerovm from manifest */ SystemManifestCtor(nap); /* "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); TIMER_REPORT("nexe start preparation"); /* set user code trap() exit location and switch to the user code */ if(setjmp(user_exit) == 0) ZLOGFAIL(!NaClCreateMainThread(nap), EFAULT, "switching to nexe failed"); SetExitState(OK_STATE); TIMER_REPORT("NaClCreateMainThread()"); /* zerovm exit with finalization, report and stuff */ NaClExit(0); /* Unreachable, but having the return prevents a compiler error. */ return -1; }
/* if condition is true, log and abort */ void FailIf(int cond, int err, char const *fmt, ...) { ZLO(!cond); SetExitState(msg); NaClExit(err); }
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; }
void FailIf(int cond, int err, char const *fmt, ...) { ZLO(!cond); SetExitState(msg); ReportDtor(err); }