Skip to content

Commit 8112c4f

Browse files
committed
seccomp: remove 2-phase API
Since nothing is using the 2-phase API, and it adds more complexity than benefit, remove it. Signed-off-by: Kees Cook <[email protected]> Cc: Andy Lutomirski <[email protected]>
1 parent c87a851 commit 8112c4f

File tree

2 files changed

+41
-94
lines changed

2 files changed

+41
-94
lines changed

include/linux/seccomp.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,6 @@ static inline int secure_computing(const struct seccomp_data *sd)
3535
return __secure_computing(sd);
3636
return 0;
3737
}
38-
39-
#define SECCOMP_PHASE1_OK 0
40-
#define SECCOMP_PHASE1_SKIP 1
41-
42-
extern u32 seccomp_phase1(struct seccomp_data *sd);
43-
int seccomp_phase2(u32 phase1_result);
4438
#else
4539
extern void secure_computing_strict(int this_syscall);
4640
#endif

kernel/seccomp.c

Lines changed: 41 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ static int seccomp_check_filter(struct sock_filter *filter, unsigned int flen)
173173
*
174174
* Returns valid seccomp BPF response codes.
175175
*/
176-
static u32 seccomp_run_filters(struct seccomp_data *sd)
176+
static u32 seccomp_run_filters(const struct seccomp_data *sd)
177177
{
178178
struct seccomp_data sd_local;
179179
u32 ret = SECCOMP_RET_ALLOW;
@@ -554,20 +554,9 @@ void secure_computing_strict(int this_syscall)
554554
BUG();
555555
}
556556
#else
557-
int __secure_computing(const struct seccomp_data *sd)
558-
{
559-
u32 phase1_result = seccomp_phase1(sd);
560-
561-
if (likely(phase1_result == SECCOMP_PHASE1_OK))
562-
return 0;
563-
else if (likely(phase1_result == SECCOMP_PHASE1_SKIP))
564-
return -1;
565-
else
566-
return seccomp_phase2(phase1_result);
567-
}
568557

569558
#ifdef CONFIG_SECCOMP_FILTER
570-
static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
559+
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
571560
{
572561
u32 filter_ret, action;
573562
int data;
@@ -599,10 +588,33 @@ static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
599588
goto skip;
600589

601590
case SECCOMP_RET_TRACE:
602-
return filter_ret; /* Save the rest for phase 2. */
591+
/* ENOSYS these calls if there is no tracer attached. */
592+
if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
593+
syscall_set_return_value(current,
594+
task_pt_regs(current),
595+
-ENOSYS, 0);
596+
goto skip;
597+
}
598+
599+
/* Allow the BPF to provide the event message */
600+
ptrace_event(PTRACE_EVENT_SECCOMP, data);
601+
/*
602+
* The delivery of a fatal signal during event
603+
* notification may silently skip tracer notification.
604+
* Terminating the task now avoids executing a system
605+
* call that may not be intended.
606+
*/
607+
if (fatal_signal_pending(current))
608+
do_exit(SIGSYS);
609+
/* Check if the tracer forced the syscall to be skipped. */
610+
this_syscall = syscall_get_nr(current, task_pt_regs(current));
611+
if (this_syscall < 0)
612+
goto skip;
613+
614+
return 0;
603615

604616
case SECCOMP_RET_ALLOW:
605-
return SECCOMP_PHASE1_OK;
617+
return 0;
606618

607619
case SECCOMP_RET_KILL:
608620
default:
@@ -614,96 +626,37 @@ static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
614626

615627
skip:
616628
audit_seccomp(this_syscall, 0, action);
617-
return SECCOMP_PHASE1_SKIP;
629+
return -1;
630+
}
631+
#else
632+
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd)
633+
{
634+
BUG();
618635
}
619636
#endif
620637

621-
/**
622-
* seccomp_phase1() - run fast path seccomp checks on the current syscall
623-
* @arg sd: The seccomp_data or NULL
624-
*
625-
* This only reads pt_regs via the syscall_xyz helpers. The only change
626-
* it will make to pt_regs is via syscall_set_return_value, and it will
627-
* only do that if it returns SECCOMP_PHASE1_SKIP.
628-
*
629-
* If sd is provided, it will not read pt_regs at all.
630-
*
631-
* It may also call do_exit or force a signal; these actions must be
632-
* safe.
633-
*
634-
* If it returns SECCOMP_PHASE1_OK, the syscall passes checks and should
635-
* be processed normally.
636-
*
637-
* If it returns SECCOMP_PHASE1_SKIP, then the syscall should not be
638-
* invoked. In this case, seccomp_phase1 will have set the return value
639-
* using syscall_set_return_value.
640-
*
641-
* If it returns anything else, then the return value should be passed
642-
* to seccomp_phase2 from a context in which ptrace hooks are safe.
643-
*/
644-
u32 seccomp_phase1(struct seccomp_data *sd)
638+
int __secure_computing(const struct seccomp_data *sd)
645639
{
646640
int mode = current->seccomp.mode;
647-
int this_syscall = sd ? sd->nr :
648-
syscall_get_nr(current, task_pt_regs(current));
641+
int this_syscall;
649642

650643
if (config_enabled(CONFIG_CHECKPOINT_RESTORE) &&
651644
unlikely(current->ptrace & PT_SUSPEND_SECCOMP))
652-
return SECCOMP_PHASE1_OK;
645+
return 0;
646+
647+
this_syscall = sd ? sd->nr :
648+
syscall_get_nr(current, task_pt_regs(current));
653649

654650
switch (mode) {
655651
case SECCOMP_MODE_STRICT:
656652
__secure_computing_strict(this_syscall); /* may call do_exit */
657-
return SECCOMP_PHASE1_OK;
658-
#ifdef CONFIG_SECCOMP_FILTER
653+
return 0;
659654
case SECCOMP_MODE_FILTER:
660-
return __seccomp_phase1_filter(this_syscall, sd);
661-
#endif
655+
return __seccomp_filter(this_syscall, sd);
662656
default:
663657
BUG();
664658
}
665659
}
666-
667-
/**
668-
* seccomp_phase2() - finish slow path seccomp work for the current syscall
669-
* @phase1_result: The return value from seccomp_phase1()
670-
*
671-
* This must be called from a context in which ptrace hooks can be used.
672-
*
673-
* Returns 0 if the syscall should be processed or -1 to skip the syscall.
674-
*/
675-
int seccomp_phase2(u32 phase1_result)
676-
{
677-
struct pt_regs *regs = task_pt_regs(current);
678-
u32 action = phase1_result & SECCOMP_RET_ACTION;
679-
int data = phase1_result & SECCOMP_RET_DATA;
680-
681-
BUG_ON(action != SECCOMP_RET_TRACE);
682-
683-
audit_seccomp(syscall_get_nr(current, regs), 0, action);
684-
685-
/* Skip these calls if there is no tracer. */
686-
if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
687-
syscall_set_return_value(current, regs,
688-
-ENOSYS, 0);
689-
return -1;
690-
}
691-
692-
/* Allow the BPF to provide the event message */
693-
ptrace_event(PTRACE_EVENT_SECCOMP, data);
694-
/*
695-
* The delivery of a fatal signal during event
696-
* notification may silently skip tracer notification.
697-
* Terminating the task now avoids executing a system
698-
* call that may not be intended.
699-
*/
700-
if (fatal_signal_pending(current))
701-
do_exit(SIGSYS);
702-
if (syscall_get_nr(current, regs) < 0)
703-
return -1; /* Explicit request to skip. */
704-
705-
return 0;
706-
}
707660
#endif /* CONFIG_HAVE_ARCH_SECCOMP_FILTER */
708661

709662
long prctl_get_seccomp(void)

0 commit comments

Comments
 (0)