diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2023-06-28 17:45:36 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2023-06-28 17:47:35 +0200 |
commit | beeefb214a2dc8917b5a31945e740ecce4536764 (patch) | |
tree | f0dcb124e3d1c3763842c4119daf786fd222fce3 /operations.c | |
parent | 7c783a3b82b27033b86f75c018f991ffa59fa548 (diff) | |
download | seitan-beeefb214a2dc8917b5a31945e740ecce4536764.tar seitan-beeefb214a2dc8917b5a31945e740ecce4536764.tar.gz seitan-beeefb214a2dc8917b5a31945e740ecce4536764.tar.bz2 seitan-beeefb214a2dc8917b5a31945e740ecce4536764.tar.lz seitan-beeefb214a2dc8917b5a31945e740ecce4536764.tar.xz seitan-beeefb214a2dc8917b5a31945e740ecce4536764.tar.zst seitan-beeefb214a2dc8917b5a31945e740ecce4536764.zip |
cooker, seitan: Add support for GID/UID in context
Similarly to namespace specifications, the special value "caller", as
well as login/group names and numeric UID/GIDs are supported.
Example of usage in demo/mknod.hjson. Light on checks and with some
TODOs left behind at the moment.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'operations.c')
-rw-r--r-- | operations.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/operations.c b/operations.c index 97c4730..5a882d9 100644 --- a/operations.c +++ b/operations.c @@ -14,11 +14,13 @@ #include <stdlib.h> #include <string.h> #include <fcntl.h> -#include <limits.h> #include <sched.h> #include <unistd.h> #include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> #include <sys/wait.h> +#include <pwd.h> #include <linux/seccomp.h> #include <linux/filter.h> #include <linux/audit.h> @@ -79,6 +81,7 @@ static int write_syscall_ret(struct gluten *g, struct syscall_desc *s, return 0; } +/* TODO: Move all "context" stuff to separate file */ static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g, struct syscall_desc *s, struct context_desc *cdesc, struct arg_clone *c) @@ -130,26 +133,57 @@ static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g, if (type == CWD) { snprintf(c->cwd, PATH_MAX, "/proc/%d/root", req->pid); + } else if (type == UID || type == GID) { + /* TODO: Move into its own function */ + struct stat st = { 0 }; + char path[PATH_MAX]; + + snprintf(path, PATH_MAX, "/proc/%d", req->pid); + if (stat(path, &st)) + return errno; + + if (type == UID) + c->uid = st.st_uid; + else if (type == GID) + c->gid = st.st_gid; } else { snprintf(*dst, PATH_MAX, "/proc/%d/ns/%s", - req->pid, context_type_name[type]); + req->pid, context_type_name[type]); } + break; - case CONTEXT_SPEC_PID: + case CONTEXT_SPEC_NUM: if (type == CWD) { snprintf(c->cwd, PATH_MAX, "/proc/%d/root", cdesc->target.pid); + } else if (type == UID) { + c->uid = cdesc->target.uid; + } else if (type == GID) { + c->gid = cdesc->target.gid; } else { snprintf(*dst, PATH_MAX, "/proc/%d/ns/%s", cdesc->target.pid, context_type_name[type]); } + break; - case CONTEXT_SPEC_PATH: - if (type == CWD) + case CONTEXT_SPEC_NAME: + if (type == CWD) { strncpy(c->cwd, cdesc->target.path, PATH_MAX); - else + } else if (type == UID || type == GID) { + struct passwd *pw; + + if (!(pw = getpwnam(cdesc->target.name))) + return errno; + + if (type == UID) + c->uid = pw->pw_uid; + else if (type == GID) + c->gid = pw->pw_gid; + } else { strncpy(*dst, cdesc->target.path, PATH_MAX); + } + break; default: break; @@ -183,6 +217,15 @@ static int execute_syscall(void *args) { struct arg_clone *c = (struct arg_clone *)args; + /* We can use 0 as "unspecified" value because we can't switch from a + * non-zero UID/GID to zero. + */ + if (c->uid && setuid(c->uid)) + exit(EXIT_FAILURE); + + if (c->gid && setgid(c->gid)) + exit(EXIT_FAILURE); + if (*c->cwd && chdir(c->cwd) < 0) exit(EXIT_FAILURE); |