aboutgitcodelistschat:MatrixIRC
diff options
context:
space:
mode:
-rw-r--r--common/gluten.h10
-rw-r--r--cooker/emit.c36
-rw-r--r--cooker/emit.h4
-rw-r--r--cooker/parse.c34
-rw-r--r--demo/connect.hjson16
-rw-r--r--demo/ioctl.hjson2
-rw-r--r--operations.c59
-rw-r--r--operations.h4
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 <sbrivio@redhat.com>
+ * Alice Frosi <afrosi@redhat.com>
*/
#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,