From 1c1a9da7a4f9c4c1990192e14763ebf423d812a9 Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Wed, 7 Jun 2023 16:54:53 +0200 Subject: seitan, cooker: refactor op_return Refactor OP_RETURN: - merged OP_BLOCK and OP_CONT into OP_RETURN - add desc field for op_return - updated the demo files --- common/gluten.h | 10 ++++++--- cooker/emit.c | 36 +++++++++++++++------------------ cooker/emit.h | 4 ++-- cooker/parse.c | 34 ++++++++++++++++++++++++------- demo/connect.hjson | 16 +++++++-------- demo/ioctl.hjson | 2 +- operations.c | 59 ++++++++++++++---------------------------------------- operations.h | 4 ---- 8 files changed, 76 insertions(+), 89 deletions(-) diff --git a/common/gluten.h b/common/gluten.h index a50687f..2f82509 100644 --- a/common/gluten.h +++ b/common/gluten.h @@ -63,8 +63,6 @@ enum op_type { OP_NR, OP_CALL, OP_COPY, - OP_BLOCK, - OP_CONT, OP_FD, OP_RETURN, OP_LOAD, @@ -171,8 +169,14 @@ struct op_block { int32_t error; }; -struct op_return { +struct return_desc { struct gluten_offset val; + int32_t error; + bool cont; +}; + +struct op_return { + struct gluten_offset desc; }; struct op_fd { diff --git a/cooker/emit.c b/cooker/emit.c index 7b1b14d..506a561 100644 --- a/cooker/emit.c +++ b/cooker/emit.c @@ -304,36 +304,32 @@ void emit_cmp_field(struct gluten_ctx *g, enum op_cmp_type cmp, /** * emit_return() - Emit OP_RETURN instruction: return value * @g: gluten context - * @v: Pointer to return value + * @v: offset of the return value + * @error: error value + * @cont if the filtered syscall needs to be executed */ -void emit_return(struct gluten_ctx *g, struct gluten_offset v) +void emit_return(struct gluten_ctx *g, struct gluten_offset v, int32_t error, + bool cont) { struct op *op = (struct op *)gluten_ptr(&g->g, g->ip); struct op_return *ret = &op->op.ret; + struct gluten_offset o; + struct return_desc *desc; op->type = OP_RETURN; - ret->val = v; - - debug(" %i: OP_RETURN:", g->ip.offset); - if (++g->ip.offset > INST_MAX) - die("Too many instructions"); -} + o = gluten_ro_alloc(g, sizeof(struct return_desc)); + desc = (struct return_desc *)gluten_ptr(&g->g, o); -/** - * emit_block() - Emit OP_BLOCK instruction: return error value - * @g: gluten context - * @error: Error value - */ -void emit_block(struct gluten_ctx *g, int32_t error) -{ - struct op *op = (struct op *)gluten_ptr(&g->g, g->ip); - struct op_block *block = &op->op.block; + desc->val = v; + desc->error = error; + desc->cont = cont; - op->type = OP_BLOCK; - block->error = error; + ret->desc = o; - debug(" %i: OP_BLOCK: %d", g->ip.offset, error); + debug(" %i: OP_RETURN:", g->ip.offset); + debug(" \t val=(%s %d) errno=%d cont=%s", gluten_offset_name[v.type], + v.offset, error, cont ? "true" : "false"); if (++g->ip.offset > INST_MAX) die("Too many instructions"); diff --git a/cooker/emit.h b/cooker/emit.h index 18618ee..81f947e 100644 --- a/cooker/emit.h +++ b/cooker/emit.h @@ -24,8 +24,8 @@ void emit_cmp_field(struct gluten_ctx *g, enum op_cmp_type cmp, struct field *field, struct gluten_offset base, struct gluten_offset match, enum jump_type jmp); -void emit_return(struct gluten_ctx *g, struct gluten_offset v); -void emit_block(struct gluten_ctx *g, int32_t error); +void emit_return(struct gluten_ctx *g, struct gluten_offset v, int32_t error, + bool cont); 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, diff --git a/cooker/parse.c b/cooker/parse.c index 81ad159..353947e 100644 --- a/cooker/parse.c +++ b/cooker/parse.c @@ -6,6 +6,7 @@ * * Copyright 2023 Red Hat GmbH * Author: Stefano Brivio + * Alice Frosi */ #include "parson.h" @@ -73,14 +74,34 @@ static void handle_limit(struct gluten_ctx *g, JSON_Value *value) static void handle_return(struct gluten_ctx *g, JSON_Value *value) { - union value v = { .v_u64 = json_value_get_number(value) }; + JSON_Object *obj = json_value_get_object(value); + JSON_Value *jvalue; + union value v = { .v_u64 = 0 }; + int32_t error = 0; + bool cont = false; - emit_return(g, emit_data(g, U64, sizeof(v.v_u64), &v)); -} + debug(" Parsing \"return\""); -static void handle_block(struct gluten_ctx *g, JSON_Value *value) -{ - emit_block(g, json_value_get_number(value)); + jvalue = json_object_get_value(obj, "error"); + if (json_value_get_type(jvalue) == JSONNumber) { + error = json_value_get_number(jvalue); + } + + jvalue = json_object_get_value(obj, "value"); + if (json_value_get_type(jvalue) == JSONNumber) { + v.v_u64 = json_value_get_number(jvalue); + } + + jvalue = json_object_get_value(obj, "continue"); + if (json_value_get_type(jvalue) == JSONBoolean) { + cont = json_value_get_boolean(jvalue); + } + if (cont && (v.v_u64 != 0 || error != 0)) + die(" if continue is true, error and value needs to be zero"); + + debug(" emit return: val=%ld errno=%d cont=%s", v.v_u64, error, + cont ? "true" : "false"); + emit_return(g, emit_data(g, U64, sizeof(v.v_u64), &v), error, cont); } static void handle_context(struct gluten_ctx *g, JSON_Value *value) @@ -103,7 +124,6 @@ struct rule_parser { { "fd", handle_fd }, { "limit", handle_limit }, { "return", handle_return }, - { "block", handle_block }, { "context", handle_context }, { NULL, NULL }, }; diff --git a/demo/connect.hjson b/demo/connect.hjson index f3a9ad8..3bf0747 100644 --- a/demo/connect.hjson +++ b/demo/connect.hjson @@ -1,10 +1,4 @@ [ - { /* fake connect syscall */ - "match": [ - { "connect": { "addr": { "family": "unix", "path": "/fake.sock" } } } - ], - "return": 0 - }, { /* connect to another path (/var/run/pr-helper.sock -> /tmp/demo.sock) */ "match": [ { "connect": { "addr": { "family": "unix", "path": "/var/run/pr-helper.sock" }, "fd": { "tag": "fd" } } } @@ -14,12 +8,18 @@ { "connect": { "fd": { "tag": { "get": "new_fd" } }, "addr": { "family": "unix", "path": "/tmp/demo.sock" } }, "ret": "y" } ], "fd": { "src": { "tag": "fd" }, "new": { "tag": "new_fd" }, "close_on_exec": false }, - "return": 0 + "return": { "value": 0, "error": 0 } + }, + { /* fake connect syscall */ + "match": [ + { "connect": { "addr": { "family": "unix", "path": "/fake.sock" } } } + ], + "return": { "value": 0, "error": 0 } }, { /* Inject permission denied error */ "match": [ { "connect": { "addr": { "family": "unix", "path": "/error.sock" } } } ], - "block": -1 + "return": { "value": 0, "error": -1 } } ] diff --git a/demo/ioctl.hjson b/demo/ioctl.hjson index 53b59f5..b8d2de0 100644 --- a/demo/ioctl.hjson +++ b/demo/ioctl.hjson @@ -3,6 +3,6 @@ "match": [ { "ioctl": { "path": "/dev/net/tun", "request": "TUNSETIFF" } } ], - "return": 0 + "return": { "value": 0 } } ] diff --git a/operations.c b/operations.c index 50fdcfb..eefc746 100644 --- a/operations.c +++ b/operations.c @@ -261,54 +261,27 @@ out: return ret; } -int op_block(const struct seccomp_notif *req, int notifier, struct gluten *g, - struct op_block *op) -{ - struct seccomp_notif_resp resp; - - (void)g; - resp.id = req->id; - resp.val = 0; - resp.flags = 0; - resp.error = op->error; - - if (send_target(&resp, notifier) == -1) - return -1; - - return 0; -} - int op_return(const struct seccomp_notif *req, int notifier, struct gluten *g, struct op_return *op) { + const struct return_desc *desc = gluten_ptr(&req->data, g, op->desc); struct seccomp_notif_resp resp; resp.id = req->id; - resp.flags = 0; - resp.error = 0; - - if (gluten_read(&req->data, g, &resp.val, op->val, sizeof(resp.val)) == - -1) - return -1; - - if (send_target(&resp, notifier) == -1) - return -1; - - return 0; -} - -int op_continue(const struct seccomp_notif *req, int notifier, struct gluten *g, - void *op) -{ - struct seccomp_notif_resp resp; - - (void)g; - (void)op; - - resp.id = req->id; - resp.flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE; - resp.error = 0; - resp.val = 0; + if (desc->cont) { + resp.flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE; + resp.error = 0; + resp.val = 0; + debug(" op_return: continue the syscall"); + } else { + resp.id = req->id; + resp.flags = 0; + resp.error = desc->error; + if (gluten_read(&req->data, g, &resp.val, desc->val, + sizeof(resp.val)) == -1) + return -1; + debug(" op_return: val=%ld errno=%d", resp.val, resp.error); + } if (send_target(&resp, notifier) == -1) return -1; @@ -489,9 +462,7 @@ int eval(struct gluten *g, const struct seccomp_notif *req, debug("at instruction %i", op - (struct op *)g->inst); switch (op->type) { HANDLE_OP(OP_CALL, op_call, call, g); - HANDLE_OP(OP_BLOCK, op_block, block, g); HANDLE_OP(OP_RETURN, op_return, ret, g); - HANDLE_OP(OP_CONT, op_continue, NO_FIELD, g); HANDLE_OP(OP_FD, op_fd, fd, g); HANDLE_OP(OP_LOAD, op_load, load, g); HANDLE_OP(OP_MASK, op_mask, mask, g); diff --git a/operations.h b/operations.h index 2f26fc6..f07b86f 100644 --- a/operations.h +++ b/operations.h @@ -44,12 +44,8 @@ int do_call(struct arg_clone *c); int eval(struct gluten *g, const struct seccomp_notif *req, int notifier); int op_call(const struct seccomp_notif *req, int notifier, struct gluten *g, struct op_call *op); -int op_block(const struct seccomp_notif *req, int notifier, struct gluten *g, - struct op_block *op); int op_return(const struct seccomp_notif *req, int notifier, struct gluten *g, struct op_return *op); -int op_continue(const struct seccomp_notif *req, int notifier, struct gluten *g, - void *); 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, -- cgit v1.2.3