From 54bca55ae5212002f8b5178f3d427cb4f54be233 Mon Sep 17 00:00:00 2001
From: Stefano Brivio <sbrivio@redhat.com>
Date: Wed, 14 Jun 2023 13:32:15 +0200
Subject: cooker: Fix up debugging messages for "return"

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
 common/gluten.h |  2 +-
 cooker/emit.c   | 10 +++++-----
 cooker/emit.h   |  4 ++--
 cooker/parse.c  | 50 +++++++++++++++++++++++++++++++++++---------------
 operations.c    |  5 ++++-
 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;
 }
-- 
cgit v1.2.3