@@ -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
615627skip :
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
709662long prctl_get_seccomp (void )
0 commit comments