static void command_get_context(char * token, Channel * c) { int err = 0; char id[256]; Context * ctx = NULL; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(id); if (ctx == NULL) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); } else { /* Need to stop everything to access context properties. * In particular, proc FS access can fail when process is running. */ GetContextArgs * s = loc_alloc_zero(sizeof(GetContextArgs)); s->c = c; stream_lock(c); strcpy(s->token, token); s->ctx = ctx; context_lock(ctx); id2pid(id, &s->parent); post_safe_event(ctx->mem, event_get_context, s); } }
/* create a reply */ void context_create_reply(context_t *cont, word val, exception_t *excep) { context_lock(cont); if (NULL != excep) { memory_copy(&cont->last_exception, excep, sizeof(exception_t)); } memory_set(&cont->cmd, 0, sizeof(kplugs_command_t)); cont->cmd.val1 = val; cont->cmd.type = KPLUGS_REPLY; cont->has_answer = 1; context_unlock(cont); }
static MemoryCommandArgs * read_command_args(char * token, Channel * c, int cmd) { int err = 0; char id[256]; MemoryCommandArgs buf; memset(&buf, 0, sizeof(buf)); json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); buf.addr = (ContextAddress)json_read_uint64(&c->inp); json_test_char(&c->inp, MARKER_EOA); buf.word_size = (int)json_read_long(&c->inp); json_test_char(&c->inp, MARKER_EOA); buf.size = (int)json_read_long(&c->inp); json_test_char(&c->inp, MARKER_EOA); buf.mode = (int)json_read_long(&c->inp); json_test_char(&c->inp, MARKER_EOA); if (cmd == CMD_GET) json_test_char(&c->inp, MARKER_EOM); buf.ctx = id2ctx(id); if (buf.ctx == NULL) err = ERR_INV_CONTEXT; else if (buf.ctx->exited) err = ERR_ALREADY_EXITED; else if (buf.ctx->mem_access == 0) err = ERR_INV_CONTEXT; if (err != 0) { if (cmd != CMD_GET) { int ch; do ch = read_stream(&c->inp); while (ch != MARKER_EOM && ch != MARKER_EOS); } write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (cmd == CMD_GET) write_stringz(&c->out, "null"); write_errno(&c->out, err); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); return NULL; } else { MemoryCommandArgs * args = (MemoryCommandArgs *)loc_alloc(sizeof(MemoryCommandArgs)); *args = buf; args->c = c; strlcpy(args->token, token, sizeof(args->token)); channel_lock(c); context_lock(buf.ctx); return args; } }
/* add a function to a context */ int context_add_function(context_t *cont, function_t *func) { function_t *check_func = NULL; context_lock(cont); if (func->name != NULL) { /* this is a function with a name */ check_func = LIST_TO_STRUCT(function_t, list, cont->funcs.next); /* check that we don't have this function's name already */ while (check_func != NULL) { if (!string_compare(check_func->name, func->name)) { context_unlock(cont); ERROR(-ERROR_FEXIST); } check_func = LIST_TO_STRUCT(function_t, list, check_func->list.next); } /* add the function to the funcs list */ func->list.next = cont->funcs.next; func->list.prev = &cont->funcs; if (cont->funcs.next != NULL) { cont->funcs.next->prev = &func->list; } cont->funcs.next = &func->list; } else { /* this is a anonymous function */ /* add the function to the anonym list */ func->list.next = cont->anonym.next; func->list.prev = &cont->anonym; if (cont->anonym.next != NULL) { cont->anonym.next->prev = &func->list; } cont->anonym.next = &func->list; } func->cont = cont; context_unlock(cont); return 0; }
/* copy the reply back to the user */ int context_get_reply(context_t *cont, char *buf, word length) { word copy; context_lock(cont); /* return an answer if there is one */ if (cont->has_answer) { copy = (length > sizeof(kplugs_command_t)) ? sizeof(kplugs_command_t) : length; memory_copy(buf, &cont->cmd, copy); cont->has_answer = 0; } else { copy = 0; } context_unlock(cont); return (int)copy; }
/* copy the last exception to inside or outside memory */ int context_get_last_exception(context_t *cont, exception_t *excep) { int ret; context_lock(cont); if (!cont->last_exception.had_exception) { context_unlock(cont); ERROR(-ERROR_PARAM); } ret = safe_memory_copy(excep, &cont->last_exception, sizeof(exception_t), ADDR_UNDEF, ADDR_INSIDE, 0, 0); cont->last_exception.had_exception = 0; context_unlock(cont); return ret; }
/* find an anonymous function by address */ void *context_find_anonymous(context_t *cont, byte *ptr) { function_t *func; context_lock(cont); func = LIST_TO_STRUCT(function_t, list, cont->anonym.next); while (func != NULL) { if (func->func_code == ptr) { function_get(func); context_unlock(cont); return func; } func = LIST_TO_STRUCT(function_t, list, func->list.next); } context_unlock(cont); return NULL; }
/* find a function by name */ void *context_find_function(context_t *cont, byte *name) { function_t *func; context_lock(cont); func = LIST_TO_STRUCT(function_t, list, cont->funcs.next); while (func != NULL) { if (!string_compare(func->name, (char *)name)) { function_get(func); context_unlock(cont); return func; } func = LIST_TO_STRUCT(function_t, list, func->list.next); } context_unlock(cont); return NULL; }
int terminate_debug_context(TCFBroadcastGroup * bcg, Context * ctx) { int err = 0; if (ctx == NULL) { err = ERR_INV_CONTEXT; } else if (ctx->exited) { err = ERR_ALREADY_EXITED; } else { TerminateArgs * args = (TerminateArgs *)loc_alloc(sizeof(TerminateArgs)); args->ctx = ctx; args->bcg = bcg; context_lock(ctx); post_safe_event(ctx->mem, event_terminate, args); } if (err) { errno = err; return -1; } return 0; }
/* remove and delete a function from the context */ void context_free_function(function_t *func) { context_t *cont = func->cont; context_lock(cont); if (NULL == func->list.prev && NULL == func->list.next) { /* This is a race condition! The function was already removed from the context... */ context_unlock(cont); return; } func->list.prev->next = func->list.next; if (func->list.next != NULL) { func->list.next->prev = func->list.prev; } func->list.prev = NULL; func->list.next = NULL; function_put(func); context_unlock(cont); }