aboutgitcodelistschat:MatrixIRC
path: root/operations.c
diff options
context:
space:
mode:
authorAlice Frosi <afrosi@redhat.com>2023-05-22 17:03:08 +0200
committerStefano Brivio <sbrivio@redhat.com>2023-06-01 11:10:27 +0200
commitbb47d77d316137c9deddd46135b22dc144ae1ea9 (patch)
tree3e92e7ba5f912c3a384804d3f99128ddc1cf0bc8 /operations.c
parent6b1cb05624ad0f419fda5ab001ed3051273e1d4b (diff)
downloadseitan-bb47d77d316137c9deddd46135b22dc144ae1ea9.tar
seitan-bb47d77d316137c9deddd46135b22dc144ae1ea9.tar.gz
seitan-bb47d77d316137c9deddd46135b22dc144ae1ea9.tar.bz2
seitan-bb47d77d316137c9deddd46135b22dc144ae1ea9.tar.lz
seitan-bb47d77d316137c9deddd46135b22dc144ae1ea9.tar.xz
seitan-bb47d77d316137c9deddd46135b22dc144ae1ea9.tar.zst
seitan-bb47d77d316137c9deddd46135b22dc144ae1ea9.zip
ops: adjust op_call
Diffstat (limited to 'operations.c')
-rw-r--r--operations.c137
1 files changed, 88 insertions, 49 deletions
diff --git a/operations.c b/operations.c
index c751919..d28c4b8 100644
--- a/operations.c
+++ b/operations.c
@@ -84,27 +84,70 @@ static void proc_ns_name(unsigned i, char *ns)
}
}
+static struct gluten_offset *get_syscall_ret(struct syscall_desc *s)
+{
+ if (s == NULL)
+ return NULL;
+ if (s->has_ret == 0)
+ return NULL;
+ if (s->arg_count == 0)
+ return s->data;
+ return s->data + s->arg_count + 1;
+}
+
+static int write_syscall_ret(struct gluten *g, struct syscall_desc *s,
+ const struct arg_clone *c)
+{
+ struct gluten_offset *p = get_syscall_ret(s);
+
+ if (p != NULL)
+ return gluten_write(g, *p, &c->ret, sizeof(c->ret));
+
+ return 0;
+}
+
static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g,
- const struct op_call *op, struct arg_clone *c)
+ const struct op_call *op, struct syscall_desc *s,
+ struct arg_clone *c)
{
char ns_name[PATH_MAX / 2];
const struct ns_spec *ns;
+ struct op_context context;
char p[PATH_MAX];
+ struct gluten_offset x;
unsigned int i;
+ long arg;
pid_t pid;
+ if (gluten_read(NULL, g, s, op->syscall, sizeof(struct syscall_desc)) == -1)
+ return -1;
+ if (gluten_read(NULL, g, &context, op->context, sizeof(context)) == -1)
+ return -1;
+
c->err = 0;
c->ret = -1;
+ c->nr = s-> nr;
- if (gluten_read(NULL, g, &c->nr, op->nr, sizeof(c->nr)) == -1)
- return -1;
- for (i = 0; i < 6; i++)
- if (gluten_read(NULL, g, &c->args[i], op->args[i],
- sizeof(c->args[i])) == -1)
+ for (i = 0; i < s->arg_count; i++) {
+ if (gluten_read(NULL, g, &arg, s->data[i], sizeof(arg)) == -1)
return -1;
+ /* If arg is a pointer then need to calculate the absolute
+ * address and the value of arg is the relative offset of the actual
+ * value.
+ */
+ if (GET_BIT(s->arg_deref, i) == 1) {
+ x.type = s->data[i].type;
+ x.offset = arg;
+ if (gluten_read(NULL, g, &c->args[i], x,
+ sizeof(c->args[i])) == -1)
+ return -1;
+ } else {
+ c->args[i] = (void *)arg;
+ }
+ }
- for (i = 0; i < sizeof(enum ns_type); i++) {
- ns = &op->context.ns[i];
+ for (i = 0; i < NS_NUM; i++) {
+ ns = &context.ns[i];
proc_ns_name(i, ns_name);
switch (ns->type) {
case NS_NONE:
@@ -127,6 +170,7 @@ static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g,
break;
}
}
+
return 0;
}
@@ -165,40 +209,6 @@ static int execute_syscall(void *args)
exit(0);
}
-int op_load(const struct seccomp_notif *req, int notifier, struct gluten *g,
- struct op_load *load)
-{
- const long unsigned int *src = gluten_ptr(&req->data, g, load->src);
- char path[PATH_MAX];
- int fd, ret = 0;
-
- snprintf(path, sizeof(path), "/proc/%d/mem", req->pid);
- if ((fd = open(path, O_RDONLY | O_CLOEXEC)) < 0)
- ret_err(-1, "error opening mem for %d", req->pid);
-
- /*
- * Avoid the TOCTOU and check if the read mappings are still valid
- */
- if (!is_cookie_valid(notifier, req->id)) {
- err("the seccomp request isn't valid anymore");
- ret = -1;
- goto out;
- }
- if (!check_gluten_limits(load->dst, load->size)) {
- ret = -1;
- goto out;
- }
- if (pread(fd, gluten_write_ptr(g, load->dst), load->size, *src) < 0) {
- err("pread");
- ret = -1;
- goto out;
- }
-
-out:
- close(fd);
- return ret;
-}
-
int do_call(struct arg_clone *c)
{
char stack[STACK_SIZE];
@@ -216,6 +226,7 @@ int op_call(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_call *op)
{
struct seccomp_notif_resp resp;
+ struct syscall_desc s;
struct arg_clone c;
resp.id = req->id;
@@ -223,7 +234,7 @@ int op_call(const struct seccomp_notif *req, int notifier, struct gluten *g,
resp.flags = 0;
resp.error = 0;
- if (prepare_arg_clone(req, g, op, &c) == -1)
+ if (prepare_arg_clone(req, g, op, &s, &c) == -1)
return -1;
debug(" op_call: execute syscall nr=%ld", c.nr);
if (do_call(&c) == -1) {
@@ -237,14 +248,42 @@ int op_call(const struct seccomp_notif *req, int notifier, struct gluten *g,
if (send_target(&resp, notifier) == -1)
return -1;
}
+
+ return write_syscall_ret(g, &s, &c);
+}
+
+int op_load(const struct seccomp_notif *req, int notifier, struct gluten *g,
+ struct op_load *load)
+{
+ const long unsigned int *src = gluten_ptr(&req->data, g, load->src);
+ char path[PATH_MAX];
+ int fd, ret = 0;
+
+ snprintf(path, sizeof(path), "/proc/%d/mem", req->pid);
+ if ((fd = open(path, O_RDONLY | O_CLOEXEC)) < 0)
+ ret_err(-1, "error opening mem for %d", req->pid);
+
/*
- * The result of the call needs to be save as
- * reference
- */
- if (op->has_ret)
- return gluten_write(g, op->ret, &c.ret, sizeof(c.ret));
+ * Avoid the TOCTOU and check if the read mappings are still valid
+ */
+ if (!is_cookie_valid(notifier, req->id)) {
+ err("the seccomp request isn't valid anymore");
+ ret = -1;
+ goto out;
+ }
+ if (!check_gluten_limits(load->dst, load->size)) {
+ ret = -1;
+ goto out;
+ }
+ if (pread(fd, gluten_write_ptr(g, load->dst), load->size, *src) < 0) {
+ err("pread");
+ ret = -1;
+ goto out;
+ }
- return 0;
+out:
+ close(fd);
+ return ret;
}
int op_block(const struct seccomp_notif *req, int notifier, struct gluten *g,