@ -64,20 +64,13 @@ static void do_audit_syscall_entry(struct pt_regs *regs, u32 arch)
}
/*
* We can return 0 to resume the syscall or anything else to go to phase
* 2. If we resume the syscall , we need to put something appropriate in
* regs - > orig_ax .
*
* NB : We don ' t have full pt_regs here , but regs - > orig_ax and regs - > ax
* are fully functional .
*
* For phase 2 ' s benefit , our return value is :
* 0 : resume the syscall
* 1 : go to phase 2 ; no seccomp phase 2 needed
* anything else : go to phase 2 ; pass return value to seccomp
* Returns the syscall nr to run ( which should match regs - > orig_ax ) or - 1
* to skip the syscall .
*/
unsigned long syscall_trace_enter_phase1 ( struct pt_regs * regs , u32 arch )
static long syscall_trace_enter ( struct pt_regs * regs )
{
u32 arch = in_ia32_syscall ( ) ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64 ;
struct thread_info * ti = pt_regs_to_thread_info ( regs ) ;
unsigned long ret = 0 ;
u32 work ;
@ -118,59 +111,9 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
sd . args [ 5 ] = regs - > bp ;
}
BUILD_BUG_ON ( SECCOMP_PHASE1_OK ! = 0 ) ;
BUILD_BUG_ON ( SECCOMP_PHASE1_SKIP ! = 1 ) ;
ret = seccomp_phase1 ( & sd ) ;
if ( ret = = SECCOMP_PHASE1_SKIP ) {
regs - > orig_ax = - 1 ;
ret = 0 ;
} else if ( ret ! = SECCOMP_PHASE1_OK ) {
return ret ; /* Go directly to phase 2 */
}
work & = ~ _TIF_SECCOMP ;
}
# endif
/* Do our best to finish without phase 2. */
if ( work = = 0 )
return ret ; /* seccomp and/or nohz only (ret == 0 here) */
# ifdef CONFIG_AUDITSYSCALL
if ( work = = _TIF_SYSCALL_AUDIT ) {
/*
* If there is no more work to be done except auditing ,
* then audit in phase 1. Phase 2 always audits , so , if
* we audit here , then we can ' t go on to phase 2.
*/
do_audit_syscall_entry ( regs , arch ) ;
return 0 ;
}
# endif
return 1 ; /* Something is enabled that we can't handle in phase 1 */
}
/* Returns the syscall nr to run (which should match regs->orig_ax). */
long syscall_trace_enter_phase2 ( struct pt_regs * regs , u32 arch ,
unsigned long phase1_result )
{
struct thread_info * ti = pt_regs_to_thread_info ( regs ) ;
long ret = 0 ;
u32 work = ACCESS_ONCE ( ti - > flags ) & _TIF_WORK_SYSCALL_ENTRY ;
if ( IS_ENABLED ( CONFIG_DEBUG_ENTRY ) )
BUG_ON ( regs ! = task_pt_regs ( current ) ) ;
# ifdef CONFIG_SECCOMP
/*
* Call seccomp_phase2 before running the other hooks so that
* they can see any changes made by a seccomp tracer .
*/
if ( phase1_result > 1 & & seccomp_phase2 ( phase1_result ) ) {
/* seccomp failures shouldn't expose any additional code. */
return - 1 ;
ret = __secure_computing ( & sd ) ;
if ( ret = = - 1 )
return ret ;
}
# endif
@ -189,17 +132,6 @@ long syscall_trace_enter_phase2(struct pt_regs *regs, u32 arch,
return ret ? : regs - > orig_ax ;
}
long syscall_trace_enter ( struct pt_regs * regs )
{
u32 arch = in_ia32_syscall ( ) ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64 ;
unsigned long phase1_result = syscall_trace_enter_phase1 ( regs , arch ) ;
if ( phase1_result = = 0 )
return regs - > orig_ax ;
else
return syscall_trace_enter_phase2 ( regs , arch , phase1_result ) ;
}
# define EXIT_TO_USERMODE_LOOP_FLAGS \
( _TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
_TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY )