static long __trace_req(act_t action, long * const pdata, proc_t * const pproc) { FUNC_BEGIN("%d,%p,%p", action, pdata, pproc); assert(!NO_ACTION(action)); assert(pproc); long res = 0; P(&trace_mutex); /* Wait while an existing action is being performed */ while (trace_info.action != T_NOP) { DBG("waiting for slot"); pthread_cond_wait(&trace_notice, &trace_mutex); } DBG("obtained slot"); /* Propose the request */ trace_info.action = action; trace_info.pproc = pproc; trace_info.data = ((pdata != NULL)?(*pdata):(0)); trace_info.result = 0; /* Wait while the action is being performed */ while (trace_info.action != T_ACK) { DBG("requesting action %s", trace_act_name(trace_info.action)); pthread_cond_broadcast(&trace_notice); pthread_cond_wait(&trace_notice, &trace_mutex); } if (pdata != NULL) { *pdata = trace_info.data; } res = trace_info.result; DBG("collected results"); /* Release slot */ trace_info.action = T_NOP; trace_info.pproc = NULL; trace_info.data = 0; trace_info.result = 0; pthread_cond_broadcast(&trace_notice); DBG("released slot"); V(&trace_mutex); FUNC_RET("%ld", res); }
void stmt_action(struct burm_state *_s, int indent) { struct burm_state *_t; int _ern=burm_decode_stmt[_s->rule.burm_stmt]; NODEPTR *_children; if(_s->rule.burm_stmt==0) NO_ACTION(stmt); switch(_ern){ case 0: _children = GET_KIDS(_s->node); { stmt_action(burm_immed(_s,0),10); } break; case 1: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; disp_action(_s->kids[0],indent+1); reg_action(_s->kids[1],indent+1); } break; case 2: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; reg_action(_s,indent+1); } break; } }
void rc_action(struct burm_state *_s, int indent) { struct burm_state *_t; int _ern=burm_decode_rc[_s->rule.burm_rc]; NODEPTR *_children; if(_s->rule.burm_rc==0) NO_ACTION(rc); switch(_ern){ case 9: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; con_action(_s,indent+1); } break; case 10: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; reg_action(_s,indent+1); } break; } }
void disp_action(struct burm_state *_s, int indent) { struct burm_state *_t; int _ern=burm_decode_disp[_s->rule.burm_disp]; NODEPTR *_children; if(_s->rule.burm_disp==0) NO_ACTION(disp); switch(_ern){ case 7: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; reg_action(_s->kids[0],indent+1); con_action(_s->kids[1],indent+1); } break; case 8: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; } break; } }
void con_action(struct burm_state *_s, int indent) { struct burm_state *_t; int _ern=burm_decode_con[_s->rule.burm_con]; NODEPTR *_children; if(_s->rule.burm_con==0) NO_ACTION(con); switch(_ern){ case 11: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; } break; case 12: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; } break; } }
void reg_action(struct burm_state *_s, int indent) { struct burm_state *_t; int _ern=burm_decode_reg[_s->rule.burm_reg]; NODEPTR *_children; if(_s->rule.burm_reg==0) NO_ACTION(reg); switch(_ern){ case 3: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; reg_action(_s->kids[0],indent+1); rc_action(_s->kids[1],indent+1); } break; case 4: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; disp_action(_s->kids[0]->kids[0],indent+1); } break; case 5: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; } break; case 6: { int i; for (i = 0; i < indent; i++) std::cerr << " "; std::cerr << burm_string[_ern] << "\n"; disp_action(_s,indent+1); } break; } }
void * trace_main(void * const dummy) { FUNC_BEGIN("%p", dummy); assert(dummy); sandbox_t * psbox = (sandbox_t *)dummy; if (psbox == NULL) { FUNC_RET("%p", NULL); } /* Detect and perform actions while the sandbox is running */ bool end = false; P(&trace_mutex); while (!end) { /* Wait for an action request */ if (NO_ACTION(trace_info.action)) { DBG("waiting for new action"); pthread_cond_wait(&trace_notice, &trace_mutex); if (NO_ACTION(trace_info.action)) { continue; } } proc_t * pproc = trace_info.pproc; if (pproc->tflags.trace_id != pthread_self()) { continue; } DBG("received %s", trace_act_name(trace_info.action)); if (trace_info.action == T_END) { end = true; } trace_info.result = __trace_act(trace_info.action, &trace_info.data, trace_info.pproc); /* Notify the trace_*() to collect results */ trace_info.action = T_ACK; while (trace_info.action == T_ACK) { DBG("sending %s", trace_act_name(T_ACK)); pthread_cond_broadcast(&trace_notice); pthread_cond_wait(&trace_notice, &trace_mutex); } DBG("sent %s", trace_act_name(T_ACK)); } V(&trace_mutex); FUNC_RET("%p", (void *)&psbox->result); }
static long __trace_act(act_t action, long * const pdata, proc_t * const pproc) { FUNC_BEGIN("%d,%p,%p", action, pdata, pproc); assert(!NO_ACTION(action)); assert(pproc); assert(pproc->tflags.trace_id == pthread_self()); if (action == T_END) { FUNC_RET("%ld", 0L); } long res = -1; pid_t pid = pproc->pid; if ((pproc->ppid != getpid()) || (toupper(pproc->state) != 'T')) { FUNC_RET("%ld", res); } #ifdef HAVE_PTRACE switch (action) { case T_NEXT: assert(pdata); pproc->tflags.single_step = ((int)(*pdata) == TRACE_SINGLE_STEP); if (pproc->tflags.single_step) { res = ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL); } else { res = ptrace(PTRACE_SYSCALL, pid, NULL, NULL); } break; case T_KILL: assert(pdata); if (pproc->tflags.is_in_syscall) { if (pproc->tflags.single_step) { ptrace(PTRACE_POKEUSER, pid, NAX * sizeof(long), SYS_pause); } else { ptrace(PTRACE_POKEUSER, pid, ORIG_NAX * sizeof(long), SYS_pause); } } res = kill(-pid, (int)(*pdata)); break; case T_GETREGS: res = ptrace(PTRACE_GETREGS, pid, NULL, (void *)&pproc->regs); break; case T_SETREGS: res = ptrace(PTRACE_SETREGS, pid, NULL, (void *)&pproc->regs); break; case T_GETSIGINFO: res = ptrace(PTRACE_GETSIGINFO, pid, NULL, (void *)&pproc->siginfo); break; case T_GETDATA: assert(pdata); *pdata = ptrace(PTRACE_PEEKDATA, pid, (void *)(*pdata), NULL); res = errno; break; default: res = 0; break; } #else #warning "__trace_act() is not implemented for this platform" #endif /* HAVE_PTRACE */ FUNC_RET("%ld", res); }