aboutgitcodelistschat:MatrixIRC
path: root/cooker
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2023-06-02 16:48:29 +0200
committerStefano Brivio <sbrivio@redhat.com>2023-06-02 16:49:48 +0200
commit6455b9dff0554adc11e8dbe8027d134c8584bc5d (patch)
tree2c403f9e2cdb7e864ecea449f6fb7375ed5416e5 /cooker
parentfb2a89cbfc5049d360bb734b4896946e9963e39a (diff)
downloadseitan-6455b9dff0554adc11e8dbe8027d134c8584bc5d.tar
seitan-6455b9dff0554adc11e8dbe8027d134c8584bc5d.tar.gz
seitan-6455b9dff0554adc11e8dbe8027d134c8584bc5d.tar.bz2
seitan-6455b9dff0554adc11e8dbe8027d134c8584bc5d.tar.lz
seitan-6455b9dff0554adc11e8dbe8027d134c8584bc5d.tar.xz
seitan-6455b9dff0554adc11e8dbe8027d134c8584bc5d.tar.zst
seitan-6455b9dff0554adc11e8dbe8027d134c8584bc5d.zip
cooker, seitan: OP_FD
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'cooker')
-rw-r--r--cooker/call.c4
-rw-r--r--cooker/emit.c25
-rw-r--r--cooker/emit.h1
-rw-r--r--cooker/example.hjson5
-rw-r--r--cooker/parse.c50
5 files changed, 76 insertions, 9 deletions
diff --git a/cooker/call.c b/cooker/call.c
index 9561568..05e0e55 100644
--- a/cooker/call.c
+++ b/cooker/call.c
@@ -215,8 +215,8 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
f_value = json_object_get_value(tmp1, f_inner->name);
if (!f_value)
continue;
- parse_field(g, args, &struct_start, index, f_inner, f_value,
- false, add);
+ parse_field(g, args, &struct_start, index, f_inner,
+ f_value, false, add);
}
break;
default:
diff --git a/cooker/emit.c b/cooker/emit.c
index 05e3f81..b518ff9 100644
--- a/cooker/emit.c
+++ b/cooker/emit.c
@@ -53,6 +53,31 @@ void emit_nr(struct gluten_ctx *g, struct gluten_offset number)
}
/**
+ * emit_fd() - Emit OP_FD instruction: add/set file descriptor in target
+ * @g: gluten context
+ * @desc: Pointer to file descriptors specification
+ */
+void emit_fd(struct gluten_ctx *g, struct fd_desc *desc)
+{
+ struct op *op = (struct op *)gluten_ptr(&g->g, g->ip);
+ struct op_fd *fd = &op->op.fd;
+ struct gluten_offset o;
+ struct fd_desc *dst;
+
+ op->type = OP_FD;
+
+ o = gluten_ro_alloc(g, sizeof(struct fd_desc));
+ dst = (struct fd_desc *)gluten_ptr(&g->g, o);
+ memcpy(dst, desc, sizeof(struct fd_desc));
+ fd->desc = o;
+
+ debug(" %i: OP_FD: ...", g->ip.offset);
+
+ if (++g->ip.offset > INST_MAX)
+ die("Too many instructions");
+}
+
+/**
* emit_call() - Emit OP_CALL instruction: execute a system call
* @g: gluten context
* @ns: NS_SPEC_NONE-terminated array of namespaces references
diff --git a/cooker/emit.h b/cooker/emit.h
index d98789a..70997fc 100644
--- a/cooker/emit.h
+++ b/cooker/emit.h
@@ -7,6 +7,7 @@
#define EMIT_H
void emit_nr(struct gluten_ctx *g, struct gluten_offset number);
+void emit_fd(struct gluten_ctx *g, struct fd_desc *desc);
void emit_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
unsigned count, bool is_ptr[6],
struct gluten_offset offset[6], struct gluten_offset ret_offset);
diff --git a/cooker/example.hjson b/cooker/example.hjson
index 7fec039..f445418 100644
--- a/cooker/example.hjson
+++ b/cooker/example.hjson
@@ -1,13 +1,13 @@
[
{
"match": [ /* qemu-pr-helper and similar */
- { "connect": { "addr": { "family": "unix", "path": "/var/run/pr-helper.sock" }, "fd": { "tag": "fd" } } }
+ { "connect": { "addr": { "family": "unix", "path": "/var/run/pr-helper.sock" }, "fd": { "tag": "orig_fd" } } }
],
"call": [
{ "socket": { "family": "unix", "type": "stream", "flags": 0, "protocol": 0 }, "ret": "new_fd" },
{ "connect": { "fd": { "tag": { "get": "new_fd" } }, "addr": { "family": "unix", "path": "/var/run/pr-helper.sock" } }, "ret": "y" }
],
- "inject": { "what": "fd", "new": { "tag": "y" }, "old": { "tag": "fd" }, "return": 0 }
+ "fd": { "src": { "tag": "new_fd" }, "new": { "tag": "orig_fd" }, "return": true, "close_on_exec": false }
},
{
"match": [ /* qemu creates a tap interface */
@@ -38,7 +38,6 @@
"ret": "x",
"context": { "user": "init", "mnt": "caller" }
},
- "inject": { "what": "fd", "new": { "tag": "x" } },
"return": { "tag": "x" }
}
]
diff --git a/cooker/parse.c b/cooker/parse.c
index 64901f5..46134b5 100644
--- a/cooker/parse.c
+++ b/cooker/parse.c
@@ -17,10 +17,52 @@
#include "emit.h"
#include "util.h"
-static void handle_inject(struct gluten_ctx *g, JSON_Value *value)
+static void handle_fd(struct gluten_ctx *g, JSON_Value *value)
{
- (void)g;
- (void)value;
+ JSON_Object *obj = json_value_get_object(value), *tmp;
+ struct fd_desc desc = { .cloexec = 1 };
+ JSON_Value *jvalue;
+ const char *tag;
+
+ debug(" Parsing \"fd\"");
+
+ jvalue = json_object_get_value(obj, "src");
+ if (json_value_get_type(jvalue) == JSONObject) {
+ tmp = json_object_get_object(obj, "src");
+ if (!tmp || !(tag = json_object_get_string(tmp, "tag")))
+ die("invalid tag specification");
+ desc.srcfd = gluten_get_tag(g, tag);
+ } else if (json_value_get_type(jvalue) == JSONNumber) {
+ union value v = { .v_num = json_value_get_number(jvalue) };
+ desc.srcfd = emit_data(g, U32, 0, &v);
+ } else {
+ die("no valid \"src\" in \"fd\"");
+ }
+
+ jvalue = json_object_get_value(obj, "new");
+ if (!jvalue) {
+ ;
+ } else if (json_value_get_type(jvalue) == JSONObject) {
+ tmp = json_object_get_object(obj, "new");
+ if (!tmp || !(tag = json_object_get_string(tmp, "tag")))
+ die("invalid tag specification");
+ desc.newfd = gluten_get_tag(g, tag);
+ desc.setfd = 1;
+ } else if (json_value_get_type(jvalue) == JSONNumber) {
+ union value v = { .v_num = json_value_get_number(jvalue) };
+ desc.newfd = emit_data(g, U32, 0, &v);
+ desc.setfd = 1;
+ } else {
+ die("invalid \"new\" in \"fd\"");
+ }
+
+ if (json_object_get_boolean(obj, "return"))
+ desc.do_return = 1;
+
+ if (json_object_get_value(obj, "close_on_exec"))
+ desc.cloexec = json_object_get_boolean(obj, "close_on_exec");
+
+ emit_fd(g, &desc);
}
static void handle_limit(struct gluten_ctx *g, JSON_Value *value)
@@ -58,7 +100,7 @@ struct rule_parser {
} parsers[] = {
{ "match", handle_matches },
{ "call", handle_calls },
- { "inject", handle_inject },
+ { "fd", handle_fd },
{ "limit", handle_limit },
{ "return", handle_return },
{ "block", handle_block },