|
@@ -53,6 +53,12 @@
|
|
|
#include <asm/paravirt.h>
|
|
|
#include <asm/ftrace.h>
|
|
|
|
|
|
+/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
|
|
|
+#include <linux/elf-em.h>
|
|
|
+#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
|
|
|
+#define __AUDIT_ARCH_64BIT 0x80000000
|
|
|
+#define __AUDIT_ARCH_LE 0x40000000
|
|
|
+
|
|
|
.code64
|
|
|
|
|
|
#ifdef CONFIG_FTRACE
|
|
@@ -351,6 +357,7 @@ ENTRY(system_call_after_swapgs)
|
|
|
GET_THREAD_INFO(%rcx)
|
|
|
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%rcx)
|
|
|
jnz tracesys
|
|
|
+system_call_fastpath:
|
|
|
cmpq $__NR_syscall_max,%rax
|
|
|
ja badsys
|
|
|
movq %r10,%rcx
|
|
@@ -402,6 +409,10 @@ sysret_careful:
|
|
|
sysret_signal:
|
|
|
TRACE_IRQS_ON
|
|
|
ENABLE_INTERRUPTS(CLBR_NONE)
|
|
|
+#ifdef CONFIG_AUDITSYSCALL
|
|
|
+ bt $TIF_SYSCALL_AUDIT,%edx
|
|
|
+ jc sysret_audit
|
|
|
+#endif
|
|
|
/* edx: work flags (arg3) */
|
|
|
leaq do_notify_resume(%rip),%rax
|
|
|
leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
|
|
@@ -418,8 +429,45 @@ badsys:
|
|
|
movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
|
|
|
jmp ret_from_sys_call
|
|
|
|
|
|
+#ifdef CONFIG_AUDITSYSCALL
|
|
|
+ /*
|
|
|
+ * Fast path for syscall audit without full syscall trace.
|
|
|
+ * We just call audit_syscall_entry() directly, and then
|
|
|
+ * jump back to the normal fast path.
|
|
|
+ */
|
|
|
+auditsys:
|
|
|
+ movq %r10,%r9 /* 6th arg: 4th syscall arg */
|
|
|
+ movq %rdx,%r8 /* 5th arg: 3rd syscall arg */
|
|
|
+ movq %rsi,%rcx /* 4th arg: 2nd syscall arg */
|
|
|
+ movq %rdi,%rdx /* 3rd arg: 1st syscall arg */
|
|
|
+ movq %rax,%rsi /* 2nd arg: syscall number */
|
|
|
+ movl $AUDIT_ARCH_X86_64,%edi /* 1st arg: audit arch */
|
|
|
+ call audit_syscall_entry
|
|
|
+ LOAD_ARGS 0 /* reload call-clobbered registers */
|
|
|
+ jmp system_call_fastpath
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Return fast path for syscall audit. Call audit_syscall_exit()
|
|
|
+ * directly and then jump back to the fast path with TIF_SYSCALL_AUDIT
|
|
|
+ * masked off.
|
|
|
+ */
|
|
|
+sysret_audit:
|
|
|
+ movq %rax,%rsi /* second arg, syscall return value */
|
|
|
+ cmpq $0,%rax /* is it < 0? */
|
|
|
+ setl %al /* 1 if so, 0 if not */
|
|
|
+ movzbl %al,%edi /* zero-extend that into %edi */
|
|
|
+ inc %edi /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */
|
|
|
+ call audit_syscall_exit
|
|
|
+ movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
|
|
|
+ jmp sysret_check
|
|
|
+#endif /* CONFIG_AUDITSYSCALL */
|
|
|
+
|
|
|
/* Do syscall tracing */
|
|
|
tracesys:
|
|
|
+#ifdef CONFIG_AUDITSYSCALL
|
|
|
+ testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%rcx)
|
|
|
+ jz auditsys
|
|
|
+#endif
|
|
|
SAVE_REST
|
|
|
movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
|
|
|
FIXUP_TOP_OF_STACK %rdi
|