diff options
-rw-r--r-- | cooker/call.c | 7 | ||||
-rw-r--r-- | cooker/emit.c | 8 | ||||
-rw-r--r-- | operations.c | 37 | ||||
-rw-r--r-- | seitan.c | 3 |
4 files changed, 34 insertions, 21 deletions
diff --git a/cooker/call.c b/cooker/call.c index db2d6b8..9561568 100644 --- a/cooker/call.c +++ b/cooker/call.c @@ -57,7 +57,7 @@ Examples of arguments: parse_arg() passes ro_data offset - STRUCT: 1, 2 write struct to ro_data, and pointer to it - parse_tag() passes ro_data offset + parse_arg() passes ro_data offset - STRUCT: "get" <tag> write pointer to tag parse_arg() passes null offset @@ -208,14 +208,14 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args, break; case STRUCT: for (f_inner = f->desc.d_struct; f_inner->name; f_inner++) { + struct gluten_offset struct_start = offset; JSON_Value *f_value; tmp1 = json_value_get_object(jvalue); f_value = json_object_get_value(tmp1, f_inner->name); if (!f_value) continue; - - parse_field(g, args, &offset, index, f_inner, f_value, + parse_field(g, args, &struct_start, index, f_inner, f_value, false, add); } break; @@ -323,7 +323,6 @@ static struct gluten_offset parse_arg(struct gluten_ctx *g, struct arg *args, offset = gluten_rw_alloc(g, a->f.size); else if (a->f.size && !top_level_tag) offset = gluten_ro_alloc(g, a->f.size); - parse_field(g, args, &offset, a->pos, &a->f, jvalue, false, false); return offset; diff --git a/cooker/emit.c b/cooker/emit.c index 705df4b..05e3f81 100644 --- a/cooker/emit.c +++ b/cooker/emit.c @@ -73,6 +73,7 @@ void emit_call(struct gluten_ctx *g, struct ns_spec *ns, long nr, unsigned ns_count, i; struct ns_spec *ctx; + op->type = OP_CALL; for (ns_count = 0; ns[ns_count].spec != NS_SPEC_NONE; ns_count++); if (ns_count) { @@ -92,14 +93,16 @@ void emit_call(struct gluten_ctx *g, struct ns_spec *ns, long nr, desc->arg_deref |= BIT(i) * is_ptr[i]; desc->context = o1; memcpy(desc->args, offset, sizeof(struct gluten_offset) * count); - desc->args[count + 1] = ret_offset; + desc->args[count] = ret_offset; debug(" %i: OP_CALL: %i, arguments:", g->ip.offset, nr); for (i = 0; i < count; i++) { debug("\t%i: %s %s%i", i, gluten_offset_name[offset[i].type], is_ptr[i] ? "*" : "", offset[i].offset); } - + if (desc->has_ret) + debug("\treturn: %s %i", gluten_offset_name[ret_offset.type], + offset[i].offset); call->desc = o2; if (++g->ip.offset > INST_MAX) @@ -298,6 +301,7 @@ static struct gluten_offset emit_data_do(struct gluten_ctx *g, } break; + case LONG: case U64: if (add) { *(uint64_t *)p |= value->v_num; diff --git a/operations.c b/operations.c index 2fb4053..304b39b 100644 --- a/operations.c +++ b/operations.c @@ -59,8 +59,8 @@ static struct gluten_offset *get_syscall_ret(struct syscall_desc *s) if (s->has_ret == 0) return NULL; if (s->arg_count == 0) - return s->args; - return s->args + s->arg_count + 1; + return &s->args[0]; + return &s->args[s->arg_count]; } static int write_syscall_ret(struct gluten *g, struct syscall_desc *s, @@ -68,8 +68,11 @@ static int write_syscall_ret(struct gluten *g, struct syscall_desc *s, { struct gluten_offset *p = get_syscall_ret(s); - if (p != NULL) - return gluten_write(g, *p, &c->ret, sizeof(c->ret)); + if (p != NULL) { + debug(" op_call: write return value=%ld",c->ret); + if (gluten_write(g, *p, &c->ret, sizeof(c->ret)) == -1) + ret_err(-1, " failed writing return value at %d", p->offset); + } return 0; } @@ -78,7 +81,6 @@ static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g, struct syscall_desc *s, struct ns_spec *ctx, struct arg_clone *c) { - struct gluten_offset x; unsigned int i, n = 0; long arg; @@ -87,23 +89,27 @@ static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g, c->nr = s->nr; for (i = 0; i < s->arg_count; i++) { - if (gluten_read(NULL, g, &arg, s->args[i], sizeof(arg)) == -1) - return -1; /* If arg is a pointer then need to calculate the absolute * address and the value of arg is the relative offset of the actual * value. */ if (GET_BIT(s->arg_deref, i) == 1) { - x.type = s->args[i].type; - x.offset = arg; - if (gluten_read(NULL, g, &c->args[i], x, - sizeof(c->args[i])) == -1) - return -1; + c->args[i] = gluten_ptr(NULL, g, s->args[i]); + debug(" read pointer arg%d at offset %d", i, s->args[i].offset); } else { + if (gluten_read(NULL, g, &arg, s->args[i], + sizeof(arg)) == -1) + ret_err(-1, " failed reading arg %d", i); + debug(" read arg%d at offset %d v=%ld", i, + s->args[i].offset, arg); c->args[i] = (void *)arg; } } + /* TODO: add proper check when there is no context */ + if (ctx == NULL) + return 0; + for (; ctx->spec != NS_SPEC_NONE; ctx++) { enum ns_spec_type spec = ctx->spec; enum ns_type ns = ctx->ns; @@ -219,6 +225,8 @@ int op_load(const struct seccomp_notif *req, int notifier, struct gluten *g, char path[PATH_MAX]; int fd, ret = 0; + debug(" op_load: argument %d", load->src.offset); + snprintf(path, sizeof(path), "/proc/%d/mem", req->pid); if ((fd = open(path, O_RDONLY | O_CLOEXEC)) < 0) ret_err(-1, "error opening mem for %d", req->pid); @@ -358,13 +366,13 @@ int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g, (res < 0 && (cmp == CMP_LT || cmp == CMP_LE)) || (res > 0 && (cmp == CMP_GT || cmp == CMP_GE)) || (res != 0 && (cmp == CMP_NE))) { - debug(" execute op_cmp: successful comparison"); + debug(" op_cmp: successful comparison"); return 0; } if (gluten_read(NULL, g, &jmp, op->jmp, sizeof(jmp)) == -1) return -1; - debug(" execute op_cmp: jump to %d", jmp); + debug(" op_cmp: jump to %d", jmp); return jmp; } @@ -403,6 +411,7 @@ int op_nr(const struct seccomp_notif *req, int notifier, struct gluten *g, return -1; if (gluten_read(NULL, g, &jmp, op->no_match, sizeof(jmp)) == -1) return -1; + debug(" op_nr: checking syscall=%ld"); if (nr == req->data.nr) return jmp; @@ -238,7 +238,8 @@ int main(int argc, char **argv) /* The notifier fd was closed by the target */ running = false; } else if (notifier == events[i].data.fd) { - eval(&g, req, notifier); + if (eval(&g, req, notifier) == -1 ) + err(" an error occured during the evaluation"); } } } |