Skip to content

Commit ce6526e

Browse files
committed
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: Kees Cook <[email protected]> Cc: Andy Lutomirski <[email protected]>
1 parent 8112c4f commit ce6526e

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

kernel/seccomp.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ void secure_computing_strict(int this_syscall)
556556
#else
557557

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

590591
case SECCOMP_RET_TRACE:
592+
/* We've been put in this state by the ptracer already. */
593+
if (recheck_after_trace)
594+
return 0;
595+
591596
/* ENOSYS these calls if there is no tracer attached. */
592597
if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
593598
syscall_set_return_value(current,
@@ -611,6 +616,15 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
611616
if (this_syscall < 0)
612617
goto skip;
613618

619+
/*
620+
* Recheck the syscall, since it may have changed. This
621+
* intentionally uses a NULL struct seccomp_data to force
622+
* a reload of all registers. This does not goto skip since
623+
* a skip would have already been reported.
624+
*/
625+
if (__seccomp_filter(this_syscall, NULL, true))
626+
return -1;
627+
614628
return 0;
615629

616630
case SECCOMP_RET_ALLOW:
@@ -629,7 +643,8 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
629643
return -1;
630644
}
631645
#else
632-
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
646+
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
647+
const bool recheck_after_trace)
633648
{
634649
BUG();
635650
}
@@ -652,7 +667,7 @@ int __secure_computing(const struct seccomp_data *sd)
652667
__secure_computing_strict(this_syscall); /* may call do_exit */
653668
return 0;
654669
case SECCOMP_MODE_FILTER:
655-
return __seccomp_filter(this_syscall, sd);
670+
return __seccomp_filter(this_syscall, sd, false);
656671
default:
657672
BUG();
658673
}

0 commit comments

Comments
 (0)