Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce6526e8 authored by Kees Cook's avatar Kees Cook
Browse files

seccomp: recheck the syscall after RET_TRACE



When RET_TRACE triggers, a tracer may change a syscall into something that
should be filtered by seccomp. This re-runs seccomp after a trace event
to make sure things continue to pass.

Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@kernel.org>
parent 8112c4f1
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -556,7 +556,8 @@ void secure_computing_strict(int this_syscall)
#else

#ifdef CONFIG_SECCOMP_FILTER
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
			    const bool recheck_after_trace)
{
	u32 filter_ret, action;
	int data;
@@ -588,6 +589,10 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
		goto skip;

	case SECCOMP_RET_TRACE:
		/* We've been put in this state by the ptracer already. */
		if (recheck_after_trace)
			return 0;

		/* ENOSYS these calls if there is no tracer attached. */
		if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
			syscall_set_return_value(current,
@@ -611,6 +616,15 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
		if (this_syscall < 0)
			goto skip;

		/*
		 * Recheck the syscall, since it may have changed. This
		 * intentionally uses a NULL struct seccomp_data to force
		 * a reload of all registers. This does not goto skip since
		 * a skip would have already been reported.
		 */
		if (__seccomp_filter(this_syscall, NULL, true))
			return -1;

		return 0;

	case SECCOMP_RET_ALLOW:
@@ -629,7 +643,8 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
	return -1;
}
#else
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
			    const bool recheck_after_trace)
{
	BUG();
}
@@ -652,7 +667,7 @@ int __secure_computing(const struct seccomp_data *sd)
		__secure_computing_strict(this_syscall);  /* may call do_exit */
		return 0;
	case SECCOMP_MODE_FILTER:
		return __seccomp_filter(this_syscall, sd);
		return __seccomp_filter(this_syscall, sd, false);
	default:
		BUG();
	}