static PyObject * catbox_canonical(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "path", "follow", "pid", NULL }; char *path; char *canonical; PyObject *follow = NULL; int dont_follow = 0; pid_t pid = -1; PyObject *ret; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi", kwlist, &path, &follow, &pid)) return NULL; if (follow && !PyObject_IsTrue(follow)) dont_follow = 1; if (pid == -1) pid = getpid(); canonical = catbox_paths_canonical(pid, path, dont_follow); if (!canonical) { return NULL; } ret = PyString_FromString(canonical); return ret; }
static int path_arg_writable(struct trace_context *ctx, pid_t pid, char *path, const char *name, int dont_follow) { char *canonical; int ret; int mkdir_case; int err = 0; canonical = catbox_paths_canonical(pid, path, dont_follow); if (canonical) { mkdir_case = strcmp("mkdir", name) == 0; ret = path_writable(ctx->pathlist, canonical, mkdir_case); if (ret == 0) { catbox_retval_add_violation(ctx, name, path, canonical); err = -EACCES; } else if (ret == -1) { err = -EEXIST; } free(canonical); } else { if (errno == ENAMETOOLONG) err = -ENAMETOOLONG; else if (errno == ENOENT) err = -ENOENT; else err = -EACCES; } return err; }
static int path_arg_writable(struct trace_context *ctx, pid_t pid, char *path, const char *name, int dont_follow) { char *canonical; int ret; int mkdir_case; int err = 0; canonical = catbox_paths_canonical(pid, path, dont_follow); if (canonical) { mkdir_case = strcmp("mkdir", name) == 0; ret = path_writable(ctx->pathlist, canonical, mkdir_case); if (ret == 0) { if (strcmp("open", name) == 0) { // Special case for kernel build unsigned int flags; struct stat st; flags = ptrace(PTRACE_PEEKUSER, pid, REG_ARG2, 0); if ((flags & O_CREAT) == 0 && stat(canonical, &st) == -1 && errno == ENOENT) { free(canonical); return ENOENT; } } catbox_retval_add_violation(ctx, name, path, canonical); err = -EACCES; } else if (ret == -1) { err = -EEXIST; } free(canonical); } else { if (errno == ENAMETOOLONG) err = -ENAMETOOLONG; else if (errno == ENOENT) err = -ENOENT; else err = -EACCES; } return err; }