From b2e31a6e7493c56f923cb7d86f7a8a32940393ec Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Wed, 7 Jun 2023 14:07:23 +0200 Subject: seitan,cooker: op_resolvefd ops: - update resolvefd with the description - add debug prints cooker: - add emit_resolvefd when match has type FDPATH --- common/gluten.h | 15 +++++++++------ cooker/call.c | 1 + cooker/emit.c | 41 ++++++++++++++++++++++++++++++++++++++++- cooker/emit.h | 3 +++ cooker/match.c | 13 ++++++++++++- demo/ioctl.hjson | 8 ++++++++ operations.c | 23 ++++++++++++++--------- operations.h | 2 +- 8 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 demo/ioctl.hjson diff --git a/common/gluten.h b/common/gluten.h index edb447c..a50687f 100644 --- a/common/gluten.h +++ b/common/gluten.h @@ -217,11 +217,14 @@ struct op_mask { struct gluten_offset desc; /* struct mask_desc */ }; -struct op_resolvedfd { - struct gluten_offset fd; - struct gluten_offset path; - size_t path_size; - unsigned int jmp; +struct resolvefd_desc { + struct gluten_offset fd; + struct gluten_offset path; + size_t path_max; +}; + +struct op_resolvefd { + struct gluten_offset desc; }; struct op_copy { @@ -241,7 +244,7 @@ struct op { struct op_load load; struct op_mask mask; struct op_cmp cmp; - struct op_resolvedfd resfd; + struct op_resolvefd resfd; struct op_copy copy; } op; }; diff --git a/cooker/call.c b/cooker/call.c index 289a0cb..7aef157 100644 --- a/cooker/call.c +++ b/cooker/call.c @@ -275,6 +275,7 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue, return arg_needs_temp(f, pos, jvalue, NULL, level + 1); return false; + case FDPATH: case STRING: return false; case STRUCT: diff --git a/cooker/emit.c b/cooker/emit.c index d0928e3..7b1b14d 100644 --- a/cooker/emit.c +++ b/cooker/emit.c @@ -163,6 +163,40 @@ void emit_load(struct gluten_ctx *g, struct gluten_offset dst, die("Too many instructions"); } +/** + * emit_resolved() - Emit OP_RESOLVEFD instruction: resolve file descriptor with path + * @g: gluten context + * @fd: offset of the file descriptor value + * @path: offset of the path + * @path_size: size of the path + */ +void emit_resolvefd(struct gluten_ctx *g, struct gluten_offset fd, + struct gluten_offset path, size_t path_size) +{ + struct op *op = (struct op *)gluten_ptr(&g->g, g->ip); + struct op_resolvefd *resfd = &op->op.resfd; + struct gluten_offset o; + struct resolvefd_desc *desc; + + op->type = OP_RESOLVEDFD; + o = gluten_ro_alloc(g, sizeof(struct resolvefd_desc)); + desc = (struct resolvefd_desc *)gluten_ptr(&g->g, o); + + desc->fd = fd; + desc->path = path; + desc->path_max = path_size; + + resfd->desc = o; + + debug(" %i: OP_RESOLVEDFD:", g->ip.offset); + debug(" \tfd: %s offset=%d", gluten_offset_name[fd.type], fd.offset); + debug(" \tpath: %s offset=%d size=%d", gluten_offset_name[path.type], + path.offset, path_size); + + if (++g->ip.offset > INST_MAX) + die("Too many instructions"); +} + /** * emit_mask(): Emit OP_MASK instruction: mask and store * @g: gluten context @@ -422,7 +456,7 @@ static struct gluten_offset emit_data_do(struct gluten_ctx *g, break; case STRING: strncpy(p, value->v_str, str_len); - debug(" C#%i: (%s:%i) %s", g->cp.offset, type_str[type], + debug(" C#%i: (%s:%i) %s", ret.offset, type_str[type], str_len, value->v_str); break; @@ -459,6 +493,11 @@ struct gluten_offset emit_data_or(struct gluten_ctx *g, true); } +struct gluten_offset emit_seccomp_data(int index) { + struct gluten_offset o = { OFFSET_SECCOMP_DATA, index }; + return o; +} + static void gluten_link(struct gluten_ctx *g, enum jump_type type, struct op *start) { diff --git a/cooker/emit.h b/cooker/emit.h index 9ec64e0..18618ee 100644 --- a/cooker/emit.h +++ b/cooker/emit.h @@ -16,6 +16,7 @@ void emit_load(struct gluten_ctx *g, struct gluten_offset dst, struct gluten_offset emit_mask(struct gluten_ctx *g, enum type type, struct gluten_offset src, struct gluten_offset mask); +struct gluten_offset emit_seccomp_data(int index); void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp, struct gluten_offset x, struct gluten_offset y, size_t size, enum jump_type jmp); @@ -29,6 +30,8 @@ void emit_copy(struct gluten_ctx *g, struct gluten_offset dst, struct gluten_offset src, size_t size); void emit_copy_field(struct gluten_ctx *g, struct field *field, struct gluten_offset dst, struct gluten_offset src); +void emit_resolvefd(struct gluten_ctx *g, struct gluten_offset fd, + struct gluten_offset path, size_t path_size); void emit_end(struct gluten_ctx *g); struct gluten_offset emit_data(struct gluten_ctx *g, enum type type, size_t str_len, union value *value); diff --git a/cooker/match.c b/cooker/match.c index e9aed16..3c7650c 100644 --- a/cooker/match.c +++ b/cooker/match.c @@ -78,13 +78,14 @@ static union value parse_field(struct gluten_ctx *g, enum op_cmp_type cmp, enum jump_type jump, int index, struct field *f, JSON_Value *jvalue) { - struct gluten_offset const_offset, mask_offset, data_offset; + struct gluten_offset const_offset, mask_offset, data_offset, seccomp_offset; union value v = { .v_num = 0 }; struct field *f_inner; const char *tag_name; JSON_Object *tmp; JSON_Array *set; JSON_Value *sel; + size_t size; if (f->name) debug(" parsing field name %s", f->name); @@ -202,6 +203,16 @@ xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx emit_cmp(g, CMP_NE, offset, const_offset, strlen(v.v_str) + 1, JUMP_NEXT_BLOCK); break; + case FDPATH: + v.v_str = json_value_get_string(jvalue); + size = strlen(v.v_str) + 1; + offset = gluten_rw_alloc(g, size); + const_offset = emit_data(g, STRING, size, &v); + seccomp_offset = emit_seccomp_data(index); + emit_resolvefd(g, seccomp_offset, offset, size); + emit_cmp(g, CMP_NE, offset, const_offset, size, + JUMP_NEXT_BLOCK); + break; case STRUCT: for (f_inner = f->desc.d_struct; f_inner->name; f_inner++) { JSON_Value *field_value; diff --git a/demo/ioctl.hjson b/demo/ioctl.hjson new file mode 100644 index 0000000..53b59f5 --- /dev/null +++ b/demo/ioctl.hjson @@ -0,0 +1,8 @@ +[ + { + "match": [ + { "ioctl": { "path": "/dev/net/tun", "request": "TUNSETIFF" } } + ], + "return": 0 + } +] diff --git a/operations.c b/operations.c index 78206bd..50fdcfb 100644 --- a/operations.c +++ b/operations.c @@ -427,24 +427,29 @@ int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g, } int op_resolve_fd(const struct seccomp_notif *req, int notifier, - struct gluten *g, struct op_resolvedfd *op) + struct gluten *g, struct op_resolvefd *op) { - char fdpath[PATH_MAX], buf[PATH_MAX], path[PATH_MAX]; + const struct resolvefd_desc *desc = gluten_ptr(&req->data, g, op->desc); + char fdpath[PATH_MAX], buf[PATH_MAX]; ssize_t nbytes; int fd; (void)notifier; - if (gluten_read(NULL, g, &path, op->path, sizeof(op->path_size)) == -1) - return -1; - if (gluten_read(&req->data, g, &fd, op->fd, sizeof(fd)) == -1) + debug(" op_resolvefd: fd=(%s %d) path=(%s %d) path_max=%d", + gluten_offset_name[desc->fd.type], desc->fd.offset, + gluten_offset_name[desc->path.type], desc->path.offset, + desc->path_max); + + if (gluten_read(&req->data, g, &fd, desc->fd, sizeof(fd)) == -1) return -1; snprintf(fdpath, PATH_MAX, "/proc/%d/fd/%d", req->pid, fd); - if ((nbytes = readlink(fdpath, buf, op->path_size)) < 0) - ret_err(-1, "error reading %s", fdpath); - if (strcmp(path, buf) == 0) - return op->jmp; + if ((nbytes = readlink(fdpath, buf, desc->path_max)) < 0) + ret_err(-1, "error reading %s", buf); + + debug(" op_resolvefd: fd %d -> path: %s", fd, buf); + gluten_write(g, desc->path, &buf, desc->path_max); return 0; } diff --git a/operations.h b/operations.h index f543d7a..2f26fc6 100644 --- a/operations.h +++ b/operations.h @@ -53,7 +53,7 @@ int op_continue(const struct seccomp_notif *req, int notifier, struct gluten *g, int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g, struct op_cmp *op); int op_resolve_fd(const struct seccomp_notif *req, int notifier, - struct gluten *g, struct op_resolvedfd *op); + struct gluten *g, struct op_resolvefd *op); int op_load(const struct seccomp_notif *req, int notifier, struct gluten *g, struct op_load *load); int op_copy(const struct seccomp_notif *req, int notifier, struct gluten *g, -- cgit v1.2.3