aboutgitcodelistschat:MatrixIRC
path: root/operations.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2024-05-15 08:49:56 +0200
committerStefano Brivio <sbrivio@redhat.com>2024-05-15 08:49:56 +0200
commit5a9302bab9c9bb3d1577f04678d074fb7af4115f (patch)
tree21d04573dfa733e020315d08853c00fc119fb959 /operations.c
parentbdbec30a849807fb5e6841a38cfe0d168e5962b9 (diff)
downloadseitan-5a9302bab9c9bb3d1577f04678d074fb7af4115f.tar
seitan-5a9302bab9c9bb3d1577f04678d074fb7af4115f.tar.gz
seitan-5a9302bab9c9bb3d1577f04678d074fb7af4115f.tar.bz2
seitan-5a9302bab9c9bb3d1577f04678d074fb7af4115f.tar.lz
seitan-5a9302bab9c9bb3d1577f04678d074fb7af4115f.tar.xz
seitan-5a9302bab9c9bb3d1577f04678d074fb7af4115f.tar.zst
seitan-5a9302bab9c9bb3d1577f04678d074fb7af4115f.zip
Add fsetxattr(), fremovexattr(), open_by_handle_at(), and "virtiofsd demo"HEADmaster
Mostly assorted fixes, a new FDGET operation (get a copy of the target file descriptor via pidfd_getfd()) and a new "FD" flag that means we have to do that on direct tag reference. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'operations.c')
-rw-r--r--operations.c83
1 files changed, 73 insertions, 10 deletions
diff --git a/operations.c b/operations.c
index 507a2f7..eb8d614 100644
--- a/operations.c
+++ b/operations.c
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
+#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/uio.h>
@@ -160,7 +161,7 @@ static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g,
* value.
*/
if (GET_BIT(s->arg_deref, i) == 1) {
- c->args[i] = gluten_ptr(NULL, g, s->args[i]);
+ c->args[i] = gluten_ptr(&req->data, g, s->args[i]);
debug(" read pointer arg%d at offset %d", i,
s->args[i].offset);
} else if (s->args[i].type == OFFSET_METADATA) {
@@ -169,7 +170,7 @@ static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g,
debug(" read metadata value %s: %d",
metadata_type_str[s->args[i].offset], (int *)c->args[i]);
} else {
- if (gluten_read(NULL, g, &arg, s->args[i],
+ if (gluten_read(&req->data, g, &arg, s->args[i],
sizeof(arg)) == -1)
ret_err(-1, " failed reading arg %d", i);
debug(" read arg%d at offset %d v=%ld", i,
@@ -566,6 +567,27 @@ int op_fd(const struct seccomp_notif *req, int notifier,
return 0;
}
+int op_fdget(const struct seccomp_notif *req, int notifier,
+ struct gluten *g, struct op_fdget *op)
+{
+ int pidfd, fd, n;
+
+ (void)notifier;
+
+ if (gluten_read(&req->data, g, &n, op->src, sizeof(n)) == -1)
+ return -1;
+
+ if ((pidfd = syscall(SYS_pidfd_open, req->pid, 0)) < 0)
+ die(" pidfd_open");
+
+ if ((fd = syscall(SYS_pidfd_getfd, pidfd, n, 0)) < 0)
+ die(" pidfd_getfd");
+
+ close(pidfd);
+
+ return gluten_write(g, op->dst, &fd, sizeof(fd));
+}
+
int op_bitwise(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_bitwise *op)
{
@@ -702,13 +724,14 @@ int op_resolve_fd(const struct seccomp_notif *req, int notifier,
struct gluten *g, struct op_resolvefd *op)
{
const struct resolvefd_desc *desc = gluten_ptr(&req->data, g, op->desc);
- char fdpath[PATH_MAX], buf[PATH_MAX];
+ char fdpath[PATH_MAX], buf[BUFSIZ], *p = NULL;
ssize_t nbytes;
int fd;
(void)notifier;
- debug(" op_resolvefd: fd=(%s %d) path=(%s %d) path_max=%d",
+ debug(" op_resolvefd: %s fd=(%s %d) path=(%s %d) path_max=%d",
+ resolvefd_type_str[desc->type],
gluten_offset_name[desc->fd.type], desc->fd.offset,
gluten_offset_name[desc->path.type], desc->path.offset,
desc->path_max);
@@ -716,12 +739,51 @@ int op_resolve_fd(const struct seccomp_notif *req, int notifier,
if (gluten_read(&req->data, g, &fd, desc->fd, sizeof(fd)) == -1)
return -1;
- snprintf(fdpath, PATH_MAX, "/proc/%d/fd/%d", req->pid, fd);
- if ((nbytes = readlink(fdpath, buf, desc->path_max)) < 0)
- ret_err(-1, "error reading %s", buf);
+ if (desc->type == RESOLVEFD_PATH) {
+ snprintf(fdpath, PATH_MAX, "/proc/%d/fd/%d", req->pid, fd);
+ if ((nbytes = readlink(fdpath, buf, desc->path_max)) < 0)
+ ret_err(-1, "error reading %s", buf);
+
+ p = buf;
+ } else if (desc->type == RESOLVEFD_MOUNT) {
+ FILE *fp;
+
+ snprintf(fdpath, PATH_MAX, "/proc/%d/mountinfo", req->pid);
+ if (!(fp = fopen(fdpath, "r"))) {
+ err("Couldn't open %s", fdpath);
+ return -1;
+ }
+
+ while (fgets(buf, BUFSIZ, fp)) {
+ long n;
+
+ errno = 0;
+ n = strtoul(buf, NULL, 0);
+ if (errno) {
+ fclose(fp);
+ return -errno;
+ }
+
+ if (n == fd) {
+ int i;
+
+ for (i = 0; i < 5; i++)
+ p = strtok(i ? NULL : buf, " ");
+
+ break;
+ }
+ }
+
+ fclose(fp);
+
+ if (!p) {
+ err("No mountpoint for mount_fd %i", fd);
+ return -1;
+ }
+ }
- debug(" op_resolvefd: fd %d -> path: %s", fd, buf);
- gluten_write(g, desc->path, &buf, desc->path_max);
+ debug(" op_resolvefd: fd %d -> path: %s", fd, p);
+ gluten_write(g, desc->path, p, desc->path_max);
return 0;
}
@@ -764,12 +826,13 @@ int eval(struct gluten *g, const struct seccomp_notif *req,
HANDLE_OP(OP_CALL, op_call, call, g);
HANDLE_OP(OP_RETURN, op_return, ret, g);
HANDLE_OP(OP_FD, op_fd, fd, g);
+ HANDLE_OP(OP_FDGET, op_fdget, fdget, 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);
+ HANDLE_OP(OP_RESOLVEFD, op_resolve_fd, resfd, g);
HANDLE_OP(OP_NR, op_nr, nr, g);
HANDLE_OP(OP_COPY, op_copy, copy, g);
default: