Merge commit '63cc8c75156462d4b42cbdd76c293b7eee7ddbfe':
[pandora-kernel.git] / arch / x86 / kernel / entry_32.S
index cdfd94c..109792b 100644 (file)
 #include <asm/ftrace.h>
 #include <asm/irq_vectors.h>
 
+/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
+#include <linux/elf-em.h>
+#define AUDIT_ARCH_I386                (EM_386|__AUDIT_ARCH_LE)
+#define __AUDIT_ARCH_LE           0x40000000
+
+#ifndef CONFIG_AUDITSYSCALL
+#define sysenter_audit syscall_trace_entry
+#define sysexit_audit  syscall_exit_work
+#endif
+
 /*
  * We use macros for low-level operations which need to be overridden
  * for paravirtualization.  The following will never clobber any registers:
@@ -333,7 +343,8 @@ sysenter_past_esp:
 
        /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
        testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
-       jnz syscall_trace_entry
+       jnz sysenter_audit
+sysenter_do_call:
        cmpl $(nr_syscalls), %eax
        jae syscall_badsys
        call *sys_call_table(,%eax,4)
@@ -343,7 +354,8 @@ sysenter_past_esp:
        TRACE_IRQS_OFF
        movl TI_flags(%ebp), %ecx
        testw $_TIF_ALLWORK_MASK, %cx
-       jne syscall_exit_work
+       jne sysexit_audit
+sysenter_exit:
 /* if something modifies registers it must also disable sysexit */
        movl PT_EIP(%esp), %edx
        movl PT_OLDESP(%esp), %ecx
@@ -351,6 +363,45 @@ sysenter_past_esp:
        TRACE_IRQS_ON
 1:     mov  PT_FS(%esp), %fs
        ENABLE_INTERRUPTS_SYSEXIT
+
+#ifdef CONFIG_AUDITSYSCALL
+sysenter_audit:
+       testw $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
+       jnz syscall_trace_entry
+       addl $4,%esp
+       CFI_ADJUST_CFA_OFFSET -4
+       /* %esi already in 8(%esp)         6th arg: 4th syscall arg */
+       /* %edx already in 4(%esp)         5th arg: 3rd syscall arg */
+       /* %ecx already in 0(%esp)         4th arg: 2nd syscall arg */
+       movl %ebx,%ecx                  /* 3rd arg: 1st syscall arg */
+       movl %eax,%edx                  /* 2nd arg: syscall number */
+       movl $AUDIT_ARCH_I386,%eax      /* 1st arg: audit arch */
+       call audit_syscall_entry
+       pushl %ebx
+       CFI_ADJUST_CFA_OFFSET 4
+       movl PT_EAX(%esp),%eax          /* reload syscall number */
+       jmp sysenter_do_call
+
+sysexit_audit:
+       testw $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %cx
+       jne syscall_exit_work
+       TRACE_IRQS_ON
+       ENABLE_INTERRUPTS(CLBR_ANY)
+       movl %eax,%edx          /* second arg, syscall return value */
+       cmpl $0,%eax            /* is it < 0? */
+       setl %al                /* 1 if so, 0 if not */
+       movzbl %al,%eax         /* zero-extend that */
+       inc %eax /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */
+       call audit_syscall_exit
+       DISABLE_INTERRUPTS(CLBR_ANY)
+       TRACE_IRQS_OFF
+       movl TI_flags(%ebp), %ecx
+       testw $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %cx
+       jne syscall_exit_work
+       movl PT_EAX(%esp),%eax  /* reload syscall return value */
+       jmp sysenter_exit
+#endif
+
        CFI_ENDPROC
 .pushsection .fixup,"ax"
 2:     movl $0,PT_FS(%esp)