void systrace_switch_alias(const char *emulation, const char *name, char *aemul, char *aname) { struct systrace_alias *alias; struct systrace_revalias *reverse; if ((alias = systrace_find_alias(emulation, name)) == NULL) errx(1, "%s: unknown alias %s-%s", __func__, emulation, name); /* Switch to a different alias */ reverse = alias->reverse; TAILQ_REMOVE(&reverse->revl, alias, next); strlcpy(alias->aemul, aemul, sizeof(alias->aemul)); strlcpy(alias->aname, aname, sizeof(alias->aname)); reverse = systrace_reverse(aemul, aname); alias->reverse = reverse; TAILQ_INSERT_TAIL(&reverse->revl, alias, next); }
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); }