aboutgitcodelistschat:MatrixIRC
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
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>
-rw-r--r--common/gluten.h18
-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
-rw-r--r--operations.c41
7 files changed, 107 insertions, 37 deletions
diff --git a/common/gluten.h b/common/gluten.h
index 198e646..9aa721c 100644
--- a/common/gluten.h
+++ b/common/gluten.h
@@ -65,8 +65,7 @@ enum op_type {
OP_COPY,
OP_BLOCK,
OP_CONT,
- OP_INJECT,
- OP_INJECT_A,
+ OP_FD,
OP_RETURN,
OP_LOAD,
OP_CMP,
@@ -149,6 +148,14 @@ struct syscall_desc {
struct gluten_offset args[];
};
+struct fd_desc {
+ struct gluten_offset srcfd;
+ struct gluten_offset newfd;
+ uint8_t setfd :1;
+ uint8_t cloexec :1;
+ uint8_t do_return :1;
+};
+
struct op_call {
struct gluten_offset desc;
};
@@ -167,9 +174,8 @@ struct op_return {
struct gluten_offset val;
};
-struct op_inject {
- struct gluten_offset new_fd;
- struct gluten_offset old_fd;
+struct op_fd {
+ struct gluten_offset desc; /* struct fd_desc */
};
struct op_load {
@@ -215,7 +221,7 @@ struct op {
struct op_call call;
struct op_block block;
struct op_return ret;
- struct op_inject inject;
+ struct op_fd fd;
struct op_load load;
struct op_cmp cmp;
struct op_resolvedfd resfd;
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 },
diff --git a/operations.c b/operations.c
index 304b39b..e210e2f 100644
--- a/operations.c
+++ b/operations.c
@@ -309,42 +309,39 @@ int op_continue(const struct seccomp_notif *req, int notifier, struct gluten *g,
return 0;
}
-static int do_inject(const struct seccomp_notif *req, int notifier,
- struct gluten *g, struct op_inject *op, bool atomic)
+static int op_fd(const struct seccomp_notif *req, int notifier,
+ struct gluten *g, struct op_fd *op)
{
+ const struct fd_desc *desc = gluten_ptr(&req->data, g, op->desc);
struct seccomp_notif_addfd resp;
+ void *fd;
+
+ if (!desc)
+ return -1;
resp.flags = SECCOMP_ADDFD_FLAG_SETFD;
- resp.newfd_flags = 0;
+ resp.flags |= desc->do_return ? SECCOMP_ADDFD_FLAG_SEND : 0;
+ resp.newfd_flags = desc->cloexec ? O_CLOEXEC : 0;
resp.id = req->id;
- if (gluten_read(&req->data, g, &resp.newfd, op->new_fd,
- sizeof(resp.newfd)) == -1)
- return -1;
- if (gluten_read(&req->data, g, &resp.srcfd, op->old_fd,
- sizeof(resp.srcfd)) == -1)
+ if (!(fd = gluten_ptr(&req->data, g, desc->srcfd)))
return -1;
+ resp.srcfd = *(uint32_t *)fd;
+
+ if (desc->setfd) {
+ if (!(fd = gluten_ptr(&req->data, g, desc->newfd)))
+ return -1;
+ resp.newfd = *(uint32_t *)fd;
+ } else {
+ resp.newfd = 0;
+ }
- if (atomic)
- resp.flags |= SECCOMP_ADDFD_FLAG_SEND;
if (send_inject_target(&resp, notifier) == -1)
return -1;
return 0;
}
-int op_inject(const struct seccomp_notif *req, int notifier, struct gluten *g,
- struct op_inject *op)
-{
- return do_inject(req, notifier, g, op, false);
-}
-
-int op_inject_a(const struct seccomp_notif *req, int notifier, struct gluten *g,
- struct op_inject *op)
-{
- return do_inject(req, notifier, g, op, true);
-}
-
int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_cmp *op)
{