aboutgitcodelistschat:MatrixIRC
diff options
context:
space:
mode:
-rw-r--r--common/gluten.h2
-rw-r--r--cooker/emit.c10
-rw-r--r--cooker/emit.h4
-rw-r--r--cooker/parse.c50
-rw-r--r--operations.c5
5 files changed, 47 insertions, 24 deletions
diff --git a/common/gluten.h b/common/gluten.h
index 57b94f4..5e1fb42 100644
--- a/common/gluten.h
+++ b/common/gluten.h
@@ -168,7 +168,7 @@ struct op_block {
struct return_desc {
struct gluten_offset val;
- int32_t error;
+ struct gluten_offset error;
bool cont;
};
diff --git a/cooker/emit.c b/cooker/emit.c
index a257398..1a7f3a9 100644
--- a/cooker/emit.c
+++ b/cooker/emit.c
@@ -332,12 +332,12 @@ 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: offset of the return value
- * @error: error value
- * @cont if the filtered syscall needs to be executed
+ * @v: Offset of return value
+ * @error: Offset of error value
+ * @cont: Continue syscall execution, if true
*/
-void emit_return(struct gluten_ctx *g, struct gluten_offset v, int32_t error,
- bool cont)
+void emit_return(struct gluten_ctx *g, struct gluten_offset v,
+ struct gluten_offset error, bool cont)
{
struct op *op = (struct op *)gluten_ptr(&g->g, g->ip);
struct op_return *ret = &op->op.ret;
diff --git a/cooker/emit.h b/cooker/emit.h
index b4f1ae7..7413eec 100644
--- a/cooker/emit.h
+++ b/cooker/emit.h
@@ -28,8 +28,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, int32_t error,
- bool cont);
+void emit_return(struct gluten_ctx *g, struct gluten_offset v,
+ struct gluten_offset 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 fb2126e..46ca123 100644
--- a/cooker/parse.c
+++ b/cooker/parse.c
@@ -95,37 +95,57 @@ static void handle_write(struct gluten_ctx *g, JSON_Value *value)
static void handle_return(struct gluten_ctx *g, JSON_Value *value)
{
+ struct gluten_offset data = NULL_OFFSET, error = NULL_OFFSET;
JSON_Object *obj = json_value_get_object(value);
- struct gluten_offset data = NULL_OFFSET;
- const char *tag;
+ union value vv = NO_VALUE, ve = NO_VALUE;
+ const char *tag_error, *tag_value;
JSON_Value *jvalue;
- union value v = { .v_u64 = 0 };
- int32_t error = 0;
bool cont = false;
+ char buf[BUFSIZ];
+ size_t n;
debug(" Parsing \"return\"");
jvalue = json_object_get_value(obj, "error");
- if (json_value_get_type(jvalue) == JSONNumber)
- data = emit_data(g, U64, sizeof(v.v_u64), &v);
- else if ((tag = json_object_get_string(obj, "error")))
- data = gluten_get_tag(g, tag);
+ if (json_value_get_type(jvalue) == JSONNumber) {
+ ve.v_u32 = json_value_get_number(jvalue);
+ error = emit_data(g, U32, sizeof(ve.v_u32), &ve);
+ } else if ((tag_error = json_object_get_string(obj, "error"))) {
+ error = gluten_get_tag(g, tag_error);
+ }
jvalue = json_object_get_value(obj, "value");
- if (json_value_get_type(jvalue) == JSONNumber)
- data = emit_data(g, U64, sizeof(v.v_u64), &v);
- else if ((tag = json_object_get_string(obj, "value")))
- data = gluten_get_tag(g, tag);
+ if (json_value_get_type(jvalue) == JSONNumber) {
+ vv.v_u64 = json_value_get_number(jvalue);
+ data = emit_data(g, U64, sizeof(vv.v_u64), &vv);
+ } else if ((tag_value = json_object_get_string(obj, "value"))) {
+ data = gluten_get_tag(g, tag_value);
+ }
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 || data.offset != OFFSET_NULL))
+ if (cont && (error.offset != 0 || data.offset != OFFSET_NULL))
die(" \"continue\" with non-zero value or error code");
- debug(" emit return: val=%ld errno=%d cont=%s", v.v_u64, error,
- cont ? "true" : "false");
+ if (!cont) {
+ n = snprintf(buf, BUFSIZ, " emit return: value ");
+ if (tag_value)
+ n += snprintf(buf + n, BUFSIZ - n, "tag %s", tag_value);
+ else
+ n += snprintf(buf + n, BUFSIZ - n, "%lu", vv.v_u64);
+
+ n = snprintf(buf, BUFSIZ, " , error ");
+ if (tag_error)
+ n += snprintf(buf + n, BUFSIZ - n, "tag %s", tag_error);
+ else
+ n += snprintf(buf + n, BUFSIZ - n, "%u", ve.v_u32);
+ } else {
+ snprintf(buf, BUFSIZ, " emit return: continue");
+ }
+
+ debug(buf);
emit_return(g, data, error, cont);
}
diff --git a/operations.c b/operations.c
index 70c8f08..bb995df 100644
--- a/operations.c
+++ b/operations.c
@@ -346,10 +346,12 @@ int op_return(const struct seccomp_notif *req, int notifier, struct gluten *g,
} 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;
+ if (gluten_read(&req->data, g, &resp.error, desc->error,
+ sizeof(resp.error)) == -1)
+ return -1;
debug(" op_return: val=%ld errno=%d", resp.val, resp.error);
}
@@ -552,5 +554,6 @@ int eval(struct gluten *g, const struct seccomp_notif *req,
ret_err(-1, "unknown operation %d", op->type);
}
}
+
return 0;
}