From ef403b6687ec5739933f9f215093e1ea5c923666 Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Wed, 17 May 2023 15:46:57 +0200 Subject: cooker, seitan: simple working example parser: - add OP_BLOCK and OP_RETURN to the parser seitan: - fix op_cmp in seitan, it was jmp when comparison was true Working example: demo.json: [ { "match": [ /* qemu-pr-helper and similar */ { "connect": { "addr": { "family": "unix", "path": "/tmp/test.sock" } } } ], "return": 0 } ] Create gluten and the bpf filter: $ seitan-cooker demo.hjson demo.gluten demo.bpf Launch the seitan eater with the target program: $ seitan-eater -i demo.bpf -- strace -e connect tests-utils/test-syscalls connect Start seitan with gluten: $ seitan -i demo.gluten -p $(pgrep seitan-eater) Seitan mocks the connect syscall and `connect` returns successfully: $ seitan-eater -i demo.bpf -- strace -e connect tests-utils/test-syscalls connect Test syscall: connect connect(4, {sa_family=AF_UNIX, sun_path="/tmp/test.sock"}, 108) = 0 --- cooker/cooker.h | 1 + cooker/emit.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ cooker/emit.h | 2 ++ cooker/parse.c | 8 ++++---- operations.c | 4 ++-- operations.h | 2 +- 6 files changed, 58 insertions(+), 7 deletions(-) diff --git a/cooker/cooker.h b/cooker/cooker.h index 82b24f7..8dcf93e 100644 --- a/cooker/cooker.h +++ b/cooker/cooker.h @@ -46,6 +46,7 @@ union desc { union value { int v_int; uint32_t v_u32; + uint64_t v_u64; long long v_num; const char *v_str; }; diff --git a/cooker/emit.c b/cooker/emit.c index c233b0a..3fcddba 100644 --- a/cooker/emit.c +++ b/cooker/emit.c @@ -6,6 +6,7 @@ * * Copyright 2023 Red Hat GmbH * Author: Stefano Brivio + * Alice Frosi */ #include "cooker.h" @@ -136,6 +137,43 @@ void emit_cmp_field(struct gluten_ctx *g, enum op_cmp_type cmp, jmp); } +/** + * emit_return() - Emit OP_RETURN instruction: return value + * @g: gluten context + * @v: Pointer to return value + */ +void emit_return(struct gluten_ctx *g, struct gluten_offset v) +{ + struct op *op = (struct op *)gluten_ptr(&g->g, g->ip); + struct op_return *ret = &op->op.ret; + + op->type = OP_RETURN; + ret->val = v; + + debug(" %i: OP_RETURN:", g->ip.offset); + + if (++g->ip.offset > INST_MAX) + die("Too many instructions"); +} +/** + * 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; + + op->type = OP_BLOCK; + block->error = error; + + debug(" %i: OP_BLOCK: %d", g->ip.offset, error); + + if (++g->ip.offset > INST_MAX) + die("Too many instructions"); +} + struct gluten_offset emit_data(struct gluten_ctx *g, enum type type, size_t str_len, union value *value) { @@ -153,6 +191,16 @@ struct gluten_offset emit_data(struct gluten_ctx *g, enum type type, g->cp.offset += sizeof(int); break; + case U64: + if (g->cp.offset + sizeof(uint64_t) > RO_DATA_SIZE) + die(" Read-only data section exceeded"); + + *(uint64_t *)p = value->v_u64; + debug(" C#%i: (%s) %i", g->cp.offset, type_str[type], + value->v_u64); + + g->cp.offset += sizeof(uint64_t); + break; case STRING: if (g->cp.offset + str_len > RO_DATA_SIZE) die(" Read-only data section exceeded"); diff --git a/cooker/emit.h b/cooker/emit.h index 2135052..5d15b1b 100644 --- a/cooker/emit.h +++ b/cooker/emit.h @@ -16,6 +16,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); struct gluten_offset emit_data(struct gluten_ctx *g, enum type type, size_t str_len, union value *value); void link_block(struct gluten_ctx *g); diff --git a/cooker/parse.c b/cooker/parse.c index 09b1e46..acb6810 100644 --- a/cooker/parse.c +++ b/cooker/parse.c @@ -38,14 +38,14 @@ static void handle_limit(struct gluten_ctx *g, JSON_Value *value) static void handle_return(struct gluten_ctx *g, JSON_Value *value) { - (void)g; - (void)value; + union value v = { .v_u64 = json_value_get_number(value) }; + + emit_return(g, emit_data(g, U64, sizeof(v.v_u64), &v)); } static void handle_block(struct gluten_ctx *g, JSON_Value *value) { - (void)g; - (void)value; + emit_block(g, json_value_get_number(value)); } static void handle_context(struct gluten_ctx *g, JSON_Value *value) diff --git a/operations.c b/operations.c index f79c41c..60c8410 100644 --- a/operations.c +++ b/operations.c @@ -357,9 +357,9 @@ 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))) - return op->jmp.offset; /* TODO: check boundaries */ + return 0; - return 0; + return op->jmp.offset; } int op_resolve_fd(const struct seccomp_notif *req, int notifier, diff --git a/operations.h b/operations.h index 9d017e0..b1d0ac2 100644 --- a/operations.h +++ b/operations.h @@ -21,7 +21,7 @@ if (res == 0) \ (op)++; \ else if (res == -1) \ - return -1; \ + return -1; \ else \ (op) += res; \ } while (0); \ -- cgit v1.2.3