Skip to content

Commit af0575b

Browse files
author
Roland McGrath
committed
i386 syscall audit fast-path
This adds fast paths for 32-bit syscall entry and exit when TIF_SYSCALL_AUDIT is set, but no other kind of syscall tracing. These paths does not need to save and restore all registers as the general case of tracing does. Avoiding the iret return path when syscall audit is enabled helps performance a lot. Signed-off-by: Roland McGrath <[email protected]>
1 parent 5cbf156 commit af0575b

File tree

1 file changed

+53
-2
lines changed

1 file changed

+53
-2
lines changed

arch/x86/kernel/entry_32.S

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@
5454
#include <asm/ftrace.h>
5555
#include <asm/irq_vectors.h>
5656

57+
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
58+
#include <linux/elf-em.h>
59+
#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
60+
#define __AUDIT_ARCH_LE 0x40000000
61+
62+
#ifndef CONFIG_AUDITSYSCALL
63+
#define sysenter_audit syscall_trace_entry
64+
#define sysexit_audit syscall_exit_work
65+
#endif
66+
5767
/*
5868
* We use macros for low-level operations which need to be overridden
5969
* for paravirtualization. The following will never clobber any registers:
@@ -333,7 +343,8 @@ sysenter_past_esp:
333343

334344
/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
335345
testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
336-
jnz syscall_trace_entry
346+
jnz sysenter_audit
347+
sysenter_do_call:
337348
cmpl $(nr_syscalls), %eax
338349
jae syscall_badsys
339350
call *sys_call_table(,%eax,4)
@@ -343,14 +354,54 @@ sysenter_past_esp:
343354
TRACE_IRQS_OFF
344355
movl TI_flags(%ebp), %ecx
345356
testw $_TIF_ALLWORK_MASK, %cx
346-
jne syscall_exit_work
357+
jne sysexit_audit
358+
sysenter_exit:
347359
/* if something modifies registers it must also disable sysexit */
348360
movl PT_EIP(%esp), %edx
349361
movl PT_OLDESP(%esp), %ecx
350362
xorl %ebp,%ebp
351363
TRACE_IRQS_ON
352364
1: mov PT_FS(%esp), %fs
353365
ENABLE_INTERRUPTS_SYSEXIT
366+
367+
#ifdef CONFIG_AUDITSYSCALL
368+
sysenter_audit:
369+
testw $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
370+
jnz syscall_trace_entry
371+
addl $4,%esp
372+
CFI_ADJUST_CFA_OFFSET -4
373+
/* %esi already in 8(%esp) 6th arg: 4th syscall arg */
374+
/* %edx already in 4(%esp) 5th arg: 3rd syscall arg */
375+
/* %ecx already in 0(%esp) 4th arg: 2nd syscall arg */
376+
movl %ebx,%ecx /* 3rd arg: 1st syscall arg */
377+
movl %eax,%edx /* 2nd arg: syscall number */
378+
movl $AUDIT_ARCH_I386,%eax /* 1st arg: audit arch */
379+
call audit_syscall_entry
380+
pushl %ebx
381+
CFI_ADJUST_CFA_OFFSET 4
382+
movl PT_EAX(%esp),%eax /* reload syscall number */
383+
jmp sysenter_do_call
384+
385+
sysexit_audit:
386+
testw $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %cx
387+
jne syscall_exit_work
388+
TRACE_IRQS_ON
389+
ENABLE_INTERRUPTS(CLBR_ANY)
390+
movl %eax,%edx /* second arg, syscall return value */
391+
cmpl $0,%eax /* is it < 0? */
392+
setl %al /* 1 if so, 0 if not */
393+
movzbl %al,%eax /* zero-extend that */
394+
inc %eax /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */
395+
call audit_syscall_exit
396+
DISABLE_INTERRUPTS(CLBR_ANY)
397+
TRACE_IRQS_OFF
398+
movl TI_flags(%ebp), %ecx
399+
testw $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %cx
400+
jne syscall_exit_work
401+
movl PT_EAX(%esp),%eax /* reload syscall return value */
402+
jmp sysenter_exit
403+
#endif
404+
354405
CFI_ENDPROC
355406
.pushsection .fixup,"ax"
356407
2: movl $0,PT_FS(%esp)

0 commit comments

Comments
 (0)