aboutgitcodelistschat:MatrixIRC
path: root/cooker/parse.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2023-05-16 03:19:01 +0200
committerStefano Brivio <sbrivio@redhat.com>2023-05-16 07:20:25 +0200
commit7ab2bda2e69d4a862572be4b5e389a6aa864470d (patch)
treefa9653204a4ab9581b76499c95d76d16d467301d /cooker/parse.c
parent049bd1ca828da835f2903b88adcf9ce0bdacd6e4 (diff)
downloadseitan-7ab2bda2e69d4a862572be4b5e389a6aa864470d.tar
seitan-7ab2bda2e69d4a862572be4b5e389a6aa864470d.tar.gz
seitan-7ab2bda2e69d4a862572be4b5e389a6aa864470d.tar.bz2
seitan-7ab2bda2e69d4a862572be4b5e389a6aa864470d.tar.lz
seitan-7ab2bda2e69d4a862572be4b5e389a6aa864470d.tar.xz
seitan-7ab2bda2e69d4a862572be4b5e389a6aa864470d.tar.zst
seitan-7ab2bda2e69d4a862572be4b5e389a6aa864470d.zip
cooker, seitan: Now with 100% more gluten
Pseudorandom changes and progress around cooker and seitan: - cooker: - rename matching functions, split match.c - fix up SELECT semantics - add some form of handling for all syscalls in the example (some stubs) - OP_CMP for all basic and compound types except for flags - link jumps to next block and next match - completed implementation of tags - gluten write - filter clean-ups, write filters (probably not working) - seitan: - load gluten and source instructions and data from there $ ./seitan-cooker cooker/example.hjson example.gluten example.bpf Parsing block 0 Parsing match 0: connect Found description for connect 0: OP_NR: if syscall number is not 0, jump to next block Parsing match argument fd setting tag reference 'fd' tag 'fd' now refers to seccomp data at 0 Parsing match argument addr allocating 128 at offset 0 1: OP_LOAD: #0 < args[1] (size: 128) C#0: (INT) 1 2: OP_CMP: if temporary data: #0 NE (size: 4) read-only data: #0, jump to next block C#4: (STRING:24) /var/run/pr-helper.sock 3: OP_CMP: if temporary data: #0 NE (size: 24) read-only data: #4, jump to next block Linking match... Linking block... linked jump of instruction #0 to #4 linked jump of instruction #2 to #4 linked jump of instruction #3 to #4 Parsing block 1 Parsing match 0: ioctl Found description for ioctl 4: OP_NR: if syscall number is not 112, jump to next block Parsing match argument path Parsing match argument request C#28: (INT) 1074025674 5: OP_CMP: if seccomp data: #1 NE (size: 4) read-only data: #28, jump to next block Parsing match argument ifr allocating 40 at offset 128 6: OP_LOAD: #128 < args[2] (size: 40) C#32: (STRING:5) tap0 7: OP_CMP: if temporary data: #128 NE (size: 5) read-only data: #32, jump to next block C#37: (INT) 1 8: OP_CMP: if temporary data: #128 NE (size: 4) read-only data: #37, jump to next block Linking match... Linking block... linked jump of instruction #4 to #9 linked jump of instruction #5 to #9 linked jump of instruction #7 to #9 linked jump of instruction #8 to #9 Parsing block 2 Parsing match 0: unshare Found description for unshare 9: OP_NR: if syscall number is not 164, jump to next block Parsing match argument flags Linking match... Linking block... linked jump of instruction #9 to #10 Parsing block 3 Parsing match 0: unshare Found description for unshare 10: OP_NR: if syscall number is not 164, jump to next block Parsing match argument flags Linking match... Linking block... linked jump of instruction #10 to #11 Parsing block 4 Parsing match 0: mknod Found description for mknod 11: OP_NR: if syscall number is not 164, jump to next block Parsing match argument path allocating 1 at offset 168 12: OP_LOAD: #168 < args[0] (size: 1) setting tag reference 'path' tag 'path' now refers to temporary data at 168 Parsing match argument mode Parsing match argument major Parsing match argument minor setting tag reference 'minor' tag 'minor' now refers to seccomp data at 2 Linking match... Linking block... linked jump of instruction #11 to #13 Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'cooker/parse.c')
-rw-r--r--cooker/parse.c273
1 files changed, 48 insertions, 225 deletions
diff --git a/cooker/parse.c b/cooker/parse.c
index 0a87088..09b1e46 100644
--- a/cooker/parse.c
+++ b/cooker/parse.c
@@ -12,260 +12,80 @@
#include "calls.h"
#include "cooker.h"
#include "gluten.h"
+#include "match.h"
#include "emit.h"
#include "util.h"
#include "calls/net.h"
-struct rule_parser {
- const char *type;
- int (*fn)(struct gluten_ctx *g, JSON_Value *value);
-};
-
-static int parse_match_load(struct gluten_ctx *g, struct arg *a)
-{
- if (!a->size || g->match_dst[a->pos].len)
- return 0;
-
- g->match_dst[a->pos].offset = gluten_alloc(g, a->size);
- g->match_dst[a->pos].len = a->size;
-
- emit_load(g, g->match_dst[a->pos].offset, a->pos, a->size);
-
- return 0;
-}
-
-static long long parse_match_expr_num(struct num *desc, JSON_Value *value)
+static void handle_call(struct gluten_ctx *g, JSON_Value *value)
{
- const char *s = NULL;
- long long n;
-
- if (desc) {
- s = json_value_get_string(value);
- for (; desc->name && s && strcmp(s, desc->name); desc++);
- if (s && !desc->name)
- die(" Invalid value %s", s);
-
- n = desc->value;
- }
-
- if (!s) {
- if (json_value_get_type(value) != JSONNumber)
- die(" Invalid value type");
-
- n = json_value_get_number(value);
- }
-
- return n;
-}
-
-static void parse_match_expr_value(union desc desc, enum type type,
- JSON_Value *value, union value *out)
-{
- if (TYPE_IS_NUM(type))
- out->v_num = parse_match_expr_num(desc.d_num, value);
-}
-
-/**
- * parse_match_select() - Get description and type for selected value
- * @s: Possible selection choices
- * @v: Selector value
- * @type: Type of selected value, set on return
- * @desc: Description of selected value, set on return
- */
-static void parse_match_select(struct select *s, union value v,
- enum type *type, union desc *desc)
-{
- if (TYPE_IS_NUM(s->field->type)) {
- struct select_num *d_num;
-
- for (d_num = s->desc.d_num; d_num->type; d_num++) {
- if (d_num->value == v.v_num) {
- *type = d_num->type;
- *desc = d_num->desc;
- return;
- }
- }
-
- if (!d_num->type)
- die(" No match for numeric selector %i", v.v_num);
- }
-
- die(" not supported yet");
-}
-
-/*
- * parse_match_arg()
- * load argument
- * parse_match_key()
- * compound types? demux, parse_match_expr
- * parse_match_expr
- * in/all/not/false-true array: demux, parse_match_expr_{num,string}
- * parse_match_expr_{num,string}
- *
- * at terminal values
- * store ref *pointers*! no copies
- * emit additional bpf statement if syscall arg is also terminal
-*/
-static int parse_match_key(struct gluten_ctx *g, int index, enum type type,
- union desc desc, JSON_Value *value)
-{
- JSON_Object *tmp;
- const char *ref;
-
- if (type == SELECT) {
- struct gluten_offset base_offset, const_offset;
- struct select *select = desc.d_select;
- struct field *field = select->field;
- JSON_Value *selector;
- union value v;
-
- if (!(tmp = json_value_get_object(value)))
- die(" no object for compound value");
-
- if (!(selector = json_object_get_value(tmp, field->name)))
- die(" missing selector for '%s'", field->name);
-
- parse_match_expr_value(field->desc, field->type, selector, &v);
-
- base_offset = g->match_dst[index].offset;
- const_offset = emit_data(g, field->type, &v);
- emit_cmp_field(g, CMP_NE, field, base_offset, const_offset,
- NEXT_BLOCK);
-
- parse_match_select(select, v, &type, &desc);
- }
-
- if (json_value_get_type(value) == JSONObject &&
- (tmp = json_value_get_object(value)) &&
- (ref = json_object_get_string(tmp, "ref"))) {
- if (TYPE_IS_COMPOUND(type))
- die("Reference '%s' to compound value");
-
- debug(" setting reference '%s'", ref);
- value = json_object_get_value(tmp, "value");
-
- emit_load(g, gluten_alloc_type(g, type), index, type);
- }
-
- /* Nothing to match on: just store as reference */
- if (!value)
- return 0;
-
- switch (type) {
- case INTFLAGS:
- case LONGFLAGS:
- case U32FLAGS:
- /* fetch/combine expr algebra loop */
- case INTMASK:
- /* calculate mask first */
- case INT:
- case LONG:
- case U32:
- parse_match_expr_num(desc.d_num, value);
- //emit_cmp(...);
- default:
- ;
- }
-
- return 0;
+ (void)g;
+ (void)value;
}
-static int parse_match_arg(struct gluten_ctx *g, const char *name,
- JSON_Value *value, struct arg *a)
+static void handle_inject(struct gluten_ctx *g, JSON_Value *value)
{
- debug(" Parsing match argument %s", name);
-
- parse_match_load(g, a);
- parse_match_key(g, a->pos, a->type, a->desc, value);
-
- return 0;
+ (void)g;
+ (void)value;
}
-static int parse_match(struct gluten_ctx *g, JSON_Object *obj, struct arg *args)
+static void handle_limit(struct gluten_ctx *g, JSON_Value *value)
{
- unsigned count = 0;
- struct arg *a;
-
- for (a = args; a->name; a++) {
- JSON_Value *value;
-
- if ((value = json_object_get_value(obj, a->name))) {
- count++;
- parse_match_arg(g, a->name, value, a);
- }
- }
-
- if (count != json_object_get_count(obj))
- die(" Stray elements in match");
-
- return 0;
+ (void)g;
+ (void)value;
}
-static int parse_matches(struct gluten_ctx *g, JSON_Value *value)
+static void handle_return(struct gluten_ctx *g, JSON_Value *value)
{
- JSON_Array *matches = json_value_get_array(value);
- unsigned i;
-
- for (i = 0; i < json_array_get_count(matches); i++) {
- JSON_Object *match, *args;
- struct call **set, *call;
- const char *name;
-
- g->lr = g->ip;
-
- match = json_array_get_object(matches, i);
- name = json_object_get_name(match, 0);
- args = json_object_get_object(match, name);
- debug(" Parsing match %i: %s", i, name);
-
- for (set = call_sets, call = set[0]; *set; call++) {
- if (!call->name) {
- set++;
- continue;
- }
-
- if (!strcmp(name, call->name)) {
- debug(" Found handler for %s", name);
- emit_nr(g, call->number);
-
- parse_match(g, args, call->args);
- break;
- }
- }
-
- if (!*set)
- die(" Unknown system call: %s", name);
- }
-
- return 0;
+ (void)g;
+ (void)value;
}
-static int parse_call(struct gluten_ctx *g, JSON_Value *value)
+static void handle_block(struct gluten_ctx *g, JSON_Value *value)
{
(void)g;
(void)value;
- return 0;
}
-static int parse_inject(struct gluten_ctx *g, JSON_Value *value)
+static void handle_context(struct gluten_ctx *g, JSON_Value *value)
{
(void)g;
(void)value;
- return 0;
}
-struct rule_parser parsers[] = {
- { "match", parse_matches },
- { "call", parse_call },
- { "inject", parse_inject },
+/**
+ * struct rule_parser - Parsing handler for JSON rule type
+ * @type: JSON key name
+ * @fn: Parsing function
+ */
+struct rule_parser {
+ const char *type;
+ void (*fn)(struct gluten_ctx *g, JSON_Value *value);
+} parsers[] = {
+ { "match", handle_matches },
+ { "call", handle_call },
+ { "inject", handle_inject },
+ { "limit", handle_limit },
+ { "return", handle_return },
+ { "block", handle_block },
+ { "context", handle_context },
{ NULL, NULL },
};
-static int parse_block(struct gluten_ctx *g, JSON_Object *block)
+/**
+ * parse_block() - Parse a transformation block with rules
+ * @g: gluten context
+ * @block: Array of rules in block
+ */
+static void parse_block(struct gluten_ctx *g, JSON_Object *block)
{
unsigned i;
+ memset(g->selected_arg, 0, sizeof(g->selected_arg));
+ memset(g->tags, 0, sizeof(g->tags));
+ g->lr = g->ip;
+
for (i = 0; i < json_object_get_count(block); i++) {
struct rule_parser *parser;
JSON_Value *rule;
@@ -285,10 +105,15 @@ static int parse_block(struct gluten_ctx *g, JSON_Object *block)
die(" Invalid rule type: \"%s\"", type);
}
- return 0;
+ link_block(g);
}
-int parse_file(struct gluten_ctx *g, const char *path)
+/**
+ * parse_file() - Entry point for parsing of a JSON input file
+ * @g: gluten context
+ * @path: Input file path
+ */
+void parse_file(struct gluten_ctx *g, const char *path)
{
JSON_Array *blocks;
JSON_Value *root;
@@ -306,6 +131,4 @@ int parse_file(struct gluten_ctx *g, const char *path)
debug("Parsing block %i", i);
parse_block(g, obj);
}
-
- return 0;
}