diff options
Diffstat (limited to 'operations.c')
-rw-r--r-- | operations.c | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/operations.c b/operations.c index b5e536a..306d1ab 100644 --- a/operations.c +++ b/operations.c @@ -25,6 +25,7 @@ #include <linux/filter.h> #include <linux/audit.h> #include <errno.h> +#include <ctype.h> #include "common/gluten.h" #include "common/util.h" @@ -81,6 +82,60 @@ static int write_syscall_ret(struct gluten *g, struct syscall_desc *s, return 0; } +static void parse_number_string(char *line, char *v, size_t len) +{ + bool first = true; + unsigned int i, k = 0; + + for (i = 0; i < len; i++) { + /* Check until it encounters the first number */ + if(!isdigit(line[i]) && !first) + break; + if (!isdigit(line[i])) + continue; + v[k] = line[i]; + k++; + first = false; + } +} + +static int proc_state(char *field, pid_t pid) +{ + char path[PATH_MAX]; + char v[PATH_MAX] = { '0' }; + char *line = NULL; + size_t len = PATH_MAX; + ssize_t read; + FILE *fp; + + snprintf(path, PATH_MAX, "/proc/%d/status", pid); + if ((fp = fopen(path, "r")) == NULL) + ret_err(-1, "failed reading status for %d", pid); + + while ((read = getline(&line, &len, fp)) != -1) { + if (strstr(line, field) != NULL) + parse_number_string(line, v, len); + } + + fclose(fp); + return atoi(v); +} + +static int get_metadata_value(uint32_t offset, pid_t pid) +{ + switch (offset) { + case UID_TARGET: + return proc_state("Uid", pid); + break; + case GID_TARGET: + return proc_state("Gid", pid); + break; + default: + err("unrecognize metadata type"); + } + 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, @@ -100,7 +155,13 @@ static int prepare_arg_clone(const struct seccomp_notif *req, struct gluten *g, */ if (GET_BIT(s->arg_deref, i) == 1) { c->args[i] = gluten_ptr(NULL, g, s->args[i]); - debug(" read pointer arg%d at offset %d", i, s->args[i].offset); + debug(" read pointer arg%d at offset %d", i, + s->args[i].offset); + } else if (s->args[i].type == OFFSET_METADATA) { + c->args[i] = (void *)(long)get_metadata_value( + s->args[i].offset, req->pid); + 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], sizeof(arg)) == -1) @@ -236,7 +297,7 @@ 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 %ld: ret=%ld errno=%d%s%s", c->nr, c->ret, + 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 : ""); if (c->ret < 0) { perror(" syscall"); @@ -277,7 +338,6 @@ int op_call(const struct seccomp_notif *req, int notifier, struct gluten *g, if (prepare_arg_clone(req, g, s, cdesc, &c) == -1) return -1; - debug(" op_call: execute syscall nr=%ld", c.nr); if (do_call(&c) == -1) { resp.error = -1; if (send_target(&resp, notifier) == -1) |