Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}