aboutgitcodelistschat:MatrixIRC
path: root/operations.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2023-12-21 12:06:05 +0100
committerStefano Brivio <sbrivio@redhat.com>2023-12-21 12:45:36 +0100
commitbdbec30a849807fb5e6841a38cfe0d168e5962b9 (patch)
tree210949d96b4d764235c1c5b81ad2eebb61681f95 /operations.c
parentc72c2493de8990c3a3b4780ec1429a3c359c121e (diff)
downloadseitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.gz
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.bz2
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.lz
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.xz
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.zst
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.zip
seitan: Add netlink, sendto()/sendmsg(), iovec handling, demo with routes
A bit rough at the moment, but it does the trick. Bonus: setsockopt() (with magic values only, not used in any demo yet). Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'operations.c')
-rw-r--r--operations.c73
1 files changed, 69 insertions, 4 deletions
diff --git a/operations.c b/operations.c
index 33596aa..507a2f7 100644
--- a/operations.c
+++ b/operations.c
@@ -20,6 +20,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/uio.h>
#include <pwd.h>
#include <linux/seccomp.h>
#include <linux/filter.h>
@@ -31,6 +32,8 @@
#include "common/util.h"
#include "operations.h"
+#include "cooker/calls.h"
+
static bool is_cookie_valid(int notifyFd, uint64_t id)
{
return ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_ID_VALID, &id) == 0;
@@ -301,12 +304,13 @@ static int execute_syscall(void *args)
c->ret = syscall(c->nr, c->args[0], c->args[1], c->args[2], c->args[3],
c->args[4], c->args[5]);
c->err = errno;
- debug(" execute syscall %s: ret=%ld errno=%d%s%s", syscall_name_str[c->nr], c->ret,
- c->err, *c->cwd ? " cwd=" : "", *c->cwd ? c->cwd : "");
+ debug(" execute syscall %s: ret=%ld errno=%d%s%s", syscall_name(c->nr),
+ c->ret, c->err, *c->cwd ? " cwd=" : "", *c->cwd ? c->cwd : "");
if (c->ret < 0) {
perror(" syscall");
exit(EXIT_FAILURE);
}
+
exit(0);
}
@@ -398,6 +402,65 @@ out:
return ret;
}
+int op_iovload(const struct seccomp_notif *req, int notifier, struct gluten *g,
+ struct op_iovload *load)
+{
+ const long unsigned int *iovptr = gluten_ptr(&req->data, g, load->iov);
+ const size_t *iovlen = gluten_ptr(&req->data, g, load->iovlen);
+ unsigned char *dst = gluten_write_ptr(g, load->dst);
+ struct iovec iovbuf[UIO_MAXIOV], *iov = iovbuf;
+ char path[PATH_MAX];
+ char dbuf[BUFSIZ];
+ unsigned i, count;
+ int fd;
+
+ if (!*iovlen || *iovlen >= UIO_MAXIOV)
+ ret_err(EINVAL, "bad iovlen: %lu", *iovlen);
+
+ debug(" op_iovload: vector at (%s %d) to (%s %d) iovlen=%zu, size=%zu",
+ gluten_offset_name[load->iov.type], load->iov.offset,
+ gluten_offset_name[load->dst.type], load->dst.offset, *iovlen,
+ load->size);
+
+ 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);
+
+ if (!is_cookie_valid(notifier, req->id))
+ ret_err(EIO, "expired seccomp notification");
+
+ if (!check_gluten_limits(load->dst, load->size))
+ ret_err(EINVAL, "destination out of range");
+
+ if (pread(fd, iov, *iovlen * sizeof(struct iovec), *iovptr) <= 0)
+ ret_err(EIO, "pread");
+
+ for (i = 0, count = 0; i < *iovlen && count < load->size; i++, iov++) {
+ unsigned j, dn = 0;
+ ssize_t n;
+
+ n = pread(fd, dst + count,
+ MIN(load->size - count, iov->iov_len),
+ (intptr_t)iov->iov_base);
+
+ if (n < 0)
+ ret_err(EIO, "pread");
+
+ for (j = 0; j < n; j++) {
+ dn += snprintf(dbuf + dn, BUFSIZ - dn, "%02x ",
+ dst[count + j]);
+ }
+
+ count += n;
+ }
+
+ debug(" %s", dbuf);
+
+ close(fd);
+
+ return 0;
+}
+
int op_store(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_store *store)
{
@@ -672,11 +735,12 @@ int op_nr(const struct seccomp_notif *req, int notifier, struct gluten *g,
if (gluten_read(NULL, g, &nr, op->nr, sizeof(nr)) == -1)
return -1;
- debug(" op_nr: checking syscall %s", syscall_name_str[nr]);
+
+ debug(" op_nr: checking syscall %s (%li)", syscall_name(nr), nr);
if (nr == req->data.nr)
return 0;
- debug(" op_nr: jmp to instr %d", op->no_match.offset);
+ debug(" op_nr: no match: jump to #%d", op->no_match.offset);
return op->no_match.offset;
}
@@ -702,6 +766,7 @@ int eval(struct gluten *g, const struct seccomp_notif *req,
HANDLE_OP(OP_FD, op_fd, fd, g);
HANDLE_OP(OP_LOAD, op_load, load, g);
HANDLE_OP(OP_STORE, op_store, store, g);
+ HANDLE_OP(OP_IOVLOAD, op_iovload, iovload, g);
HANDLE_OP(OP_BITWISE, op_bitwise, bitwise, g);
HANDLE_OP(OP_CMP, op_cmp, cmp, g);
HANDLE_OP(OP_RESOLVEDFD, op_resolve_fd, resfd, g);