diff options
author | Alice Frosi <afrosi@redhat.com> | 2023-03-15 14:08:42 +0100 |
---|---|---|
committer | Alice Frosi <afrosi@redhat.com> | 2023-03-15 14:08:42 +0100 |
commit | a3d47a8356fd96f9c74a7cd3f58e1df850bb4364 (patch) | |
tree | c425d3e7d1a14ee4238501c914d3c320fd4c97b5 | |
parent | 0f4a78ff9e9fcff894044e15373d8348659cb4c3 (diff) | |
download | seitan-a3d47a8356fd96f9c74a7cd3f58e1df850bb4364.tar seitan-a3d47a8356fd96f9c74a7cd3f58e1df850bb4364.tar.gz seitan-a3d47a8356fd96f9c74a7cd3f58e1df850bb4364.tar.bz2 seitan-a3d47a8356fd96f9c74a7cd3f58e1df850bb4364.tar.lz seitan-a3d47a8356fd96f9c74a7cd3f58e1df850bb4364.tar.xz seitan-a3d47a8356fd96f9c74a7cd3f58e1df850bb4364.tar.zst seitan-a3d47a8356fd96f9c74a7cd3f58e1df850bb4364.zip |
seitan: add op_resolvedfd
The op_resolvedfd verifies that the fd points to a path.
Signed-off-by: Alice Frosi <afrosi@redhat.com>
-rw-r--r-- | gluten.h | 9 | ||||
-rw-r--r-- | operations.c | 27 |
2 files changed, 36 insertions, 0 deletions
@@ -53,6 +53,7 @@ enum op_type { OP_COPY_ARGS, OP_END, OP_CMP, + OP_RESOLVEDFD, }; enum value_type { @@ -114,6 +115,13 @@ struct op_cmp { unsigned int jmp; }; +struct op_resolvedfd { + uint16_t fd_off; + uint16_t path_off; + size_t path_size; + unsigned int jmp; +}; + struct op { enum op_type type; union { @@ -124,6 +132,7 @@ struct op { struct op_inject inj; struct op_copy_args copy; struct op_cmp cmp; + struct op_resolvedfd resfd; }; }; #endif /* GLUTEN_H */ diff --git a/operations.c b/operations.c index afc4b00..ed23885 100644 --- a/operations.c +++ b/operations.c @@ -187,6 +187,25 @@ int copy_args(struct seccomp_notif *req, struct op_copy_args *copy, void *data, return 0; } +static int resolve_fd(void *data, struct op_resolvedfd *resfd, pid_t pid) +{ + char fdpath[PATH_MAX], buf[PATH_MAX]; + char *path = (char *)((uint16_t *)data + resfd->path_off); + int *fd = (int *)((uint16_t *)data + resfd->fd_off); + ssize_t nbytes; + + snprintf(fdpath, PATH_MAX, "/proc/%d/fd/%d", pid, *fd); + if ((nbytes = readlink(fdpath, buf, resfd->path_size)) < 0) { + fprintf(stderr, "error reading %s\n", fdpath); + perror("readlink"); + return -1; + } + if (strcmp(path, buf) == 0) + return 0; + else + return 1; +} + int do_call(struct arg_clone *c) { char stack[STACK_SIZE]; @@ -234,6 +253,7 @@ int do_operations(void *data, struct op operations[], struct seccomp_notif *req, struct seccomp_notif_resp resp; struct arg_clone c; unsigned int i; + int ret; for (i = 0; i < n_operations; i++) { switch (operations[i].type) { @@ -320,6 +340,13 @@ int do_operations(void *data, struct op operations[], struct seccomp_notif *req, i = operations[i].cmp.jmp; } break; + case OP_RESOLVEDFD: + ret = resolve_fd(data, &operations[i].resfd, pid); + if (ret == -1) + return -1; + else if (ret == 1) + i = operations[i].resfd.jmp; + break; default: fprintf(stderr, "unknow operation %d \n", operations[i].type); |