void execres_cb(int fd, pid_t pid, int policynr, const char *emulation, const char *name, void *arg) { struct policy *policy; if (policynr != -1) { struct intercept_pid *ipid; ipid = intercept_getpid(pid); if (ipid->uflags & PROCESS_DETACH) { if (intercept_detach(fd, pid) == -1) err(1, "%s: intercept_detach", __func__); return; } if (inherit) return; if (ipid->uflags & PROCESS_INHERIT_POLICY) return; } if ((policy = systrace_newpolicy(emulation, name)) == NULL) goto error; /* See if this policies runs without interactive feedback */ if (automatic) policy->flags |= POLICY_UNSUPERVISED; policynr = policy->policynr; /* Try to find existing policy in file system */ if (policynr == -1 && TAILQ_FIRST(&policy->prefilters) == NULL) systrace_addpolicy(name); if (policy->flags & POLICY_DETACHED) { if (intercept_detach(fd, pid) == -1) err(1, "intercept_detach"); return; } if (policynr == -1) { policynr = systrace_newpolicynr(fd, policy); if (policynr == -1) goto error; } if (intercept_assignpolicy(fd, pid, policynr) == -1) goto error; if (TAILQ_FIRST(&policy->prefilters) != NULL) filter_prepolicy(fd, policy); return; error: kill(pid, SIGKILL); fprintf(stderr, "Terminating %d: %s\n", pid, name); }
static struct intercept_pid * linux_getpid(pid_t pid) { struct intercept_pid *icpid; icpid = intercept_getpid(pid); if (icpid == NULL) return (NULL); /* no data to attach yet */ return (icpid); }
static int obsd_set_emulation(pid_t pidnr, const char *name) { struct emulation *tmp; struct intercept_pid *pid; struct obsd_data *data; if ((tmp = obsd_find_emulation(name)) == NULL) return (-1); pid = intercept_getpid(pidnr); if (pid == NULL) return (-1); data = pid->data; data->commit = tmp; return (0); }
static struct intercept_pid * obsd_getpid(pid_t pid) { struct intercept_pid *icpid; struct obsd_data *data; icpid = intercept_getpid(pid); if (icpid == NULL) return (NULL); if (icpid->data != NULL) return (icpid); if ((icpid->data = malloc(sizeof(struct obsd_data))) == NULL) err(1, "%s:%d: malloc", __func__, __LINE__); data = icpid->data; data->current = &emulations[0]; data->commit = NULL; return (icpid); }
short gen_cb(int fd, pid_t pid, int policynr, const char *name, int code, const char *emulation, void *args, int argsize, void *cbarg) { char output[_POSIX2_LINE_MAX]; struct policy *policy; struct intercept_pid *ipid; struct filterq *pflq = NULL; short action = ICPOLICY_PERMIT; short future; int off, done = 0, dolog = 0; size_t len; if (policynr == -1) goto out; if ((policy = systrace_findpolnr(policynr)) == NULL) errx(1, "%s:%d: find %d", __func__, __LINE__, policynr); ipid = intercept_getpid(pid); ipid->uflags = 0; make_output(output, sizeof(output), ipid->name != NULL ? ipid->name : policy->name, pid, ipid->ppid, policynr, policy->name, policy->nfilters, emulation, name, code, NULL, NULL); off = strlen(output); len = sizeof(output) - off; if (len > 0) snprintf(output + off, len, ", args: %d", argsize); if ((pflq = systrace_policyflq(policy, emulation, name)) == NULL) errx(1, "%s:%d: no filter queue", __func__, __LINE__); do { /* Fast-path checking */ if ((action = policy->kerneltable[code]) != ICPOLICY_ASK) goto out; action = filter_evaluate(NULL, pflq, ipid); if (action != ICPOLICY_ASK) goto haveresult; /* * At this point, we have to ask the user, but we may check * if the policy has been updated in the meanwhile. */ if (systrace_updatepolicy(fd, policy) == -1) done = 1; } while (!done); if (policy->flags & POLICY_UNSUPERVISED) { action = ICPOLICY_NEVER; dolog = 1; goto haveresult; } action = filter_ask(fd, NULL, pflq, policynr, emulation, name, output, &future, ipid); if (future != ICPOLICY_ASK) systrace_modifypolicy(fd, policynr, name, future); if (policy->flags & POLICY_DETACHED) { if (intercept_detach(fd, pid) == -1) err(1, "intercept_detach"); } else if (action == ICPOLICY_KILL) { kill(pid, SIGKILL); return (ICPOLICY_NEVER); } haveresult: if (ipid->uflags & SYSCALL_LOG) dolog = 1; if (dolog) log_msg(LOG_WARNING, "%s user: %s, prog: %s", action < ICPOLICY_NEVER ? "permit" : "deny", ipid->username, output); out: return (action); }
short trans_cb(int fd, pid_t pid, int policynr, const char *name, int code, const char *emulation, void *args, int argsize, struct intercept_replace *repl, struct intercept_tlq *tls, void *cbarg) { short action, future; struct policy *policy; struct intercept_pid *ipid; struct intercept_tlq alitls; struct intercept_translate alitl[SYSTRACE_MAXALIAS]; struct systrace_alias *alias = NULL; struct filterq *pflq = NULL; const char *binname = NULL; char output[_POSIX2_LINE_MAX]; pid_t ppid; int done = 0, dolog = 0; action = ICPOLICY_PERMIT; if (policynr == -1) goto out; if ((policy = systrace_findpolnr(policynr)) == NULL) errx(1, "%s:%d: find %d", __func__, __LINE__, policynr); ipid = intercept_getpid(pid); ipid->uflags = 0; binname = ipid->name != NULL ? ipid->name : policy->name; ppid = ipid->ppid; /* Required to set up replacements */ do { make_output(output, sizeof(output), binname, pid, ppid, policynr, policy->name, policy->nfilters, emulation, name, code, tls, repl); /* Fast-path checking */ if ((action = policy->kerneltable[code]) != ICPOLICY_ASK) goto out; pflq = systrace_policyflq(policy, emulation, name); if (pflq == NULL) errx(1, "%s:%d: no filter queue", __func__, __LINE__); action = filter_evaluate(tls, pflq, ipid); if (action != ICPOLICY_ASK) goto done; /* Do aliasing here */ if (!noalias) alias = systrace_find_alias(emulation, name); if (alias != NULL) { int i; /* Set up variables for further filter actions */ tls = &alitls; emulation = alias->aemul; name = alias->aname; /* Create an aliased list for filter_evaluate */ TAILQ_INIT(tls); for (i = 0; i < alias->nargs; i++) { memcpy(&alitl[i], alias->arguments[i], sizeof(struct intercept_translate)); TAILQ_INSERT_TAIL(tls, &alitl[i], next); } if ((pflq = systrace_policyflq(policy, alias->aemul, alias->aname)) == NULL) errx(1, "%s:%d: no filter queue", __func__, __LINE__); action = filter_evaluate(tls, pflq, ipid); if (action != ICPOLICY_ASK) goto done; make_output(output, sizeof(output), binname, pid, ppid, policynr, policy->name, policy->nfilters, alias->aemul, alias->aname, code, tls, NULL); } /* * At this point, we have to ask the user, but we may check * if the policy has been updated in the meanwhile. */ if (systrace_updatepolicy(fd, policy) == -1) done = 1; } while (!done); if (policy->flags & POLICY_UNSUPERVISED) { action = ICPOLICY_NEVER; dolog = 1; goto out; } action = filter_ask(fd, tls, pflq, policynr, emulation, name, output, &future, ipid); if (future != ICPOLICY_ASK) filter_modifypolicy(fd, policynr, emulation, name, future); if (policy->flags & POLICY_DETACHED) { if (intercept_detach(fd, pid) == -1) err(1, "intercept_detach"); return (action); } else if (action == ICPOLICY_KILL) { kill(pid, SIGKILL); return (ICPOLICY_NEVER); } done: if (ipid->uflags & SYSCALL_LOG) dolog = 1; out: if (dolog) log_msg(LOG_WARNING, "%s user: %s, prog: %s", action < ICPOLICY_NEVER ? "permit" : "deny", ipid->username, output); /* Argument replacement in intercept might still fail */ return (action); }