diff options
| -rw-r--r-- | arch/x86/kernel/entry_64.S | 48 | ||||
| -rw-r--r-- | kernel/auditsc.c | 3 |
2 files changed, 50 insertions, 1 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index a169225869cc..db7d34a89d2e 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
| @@ -53,6 +53,12 @@ | |||
| 53 | #include <asm/paravirt.h> | 53 | #include <asm/paravirt.h> |
| 54 | #include <asm/ftrace.h> | 54 | #include <asm/ftrace.h> |
| 55 | 55 | ||
| 56 | /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ | ||
| 57 | #include <linux/elf-em.h> | ||
| 58 | #define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) | ||
| 59 | #define __AUDIT_ARCH_64BIT 0x80000000 | ||
| 60 | #define __AUDIT_ARCH_LE 0x40000000 | ||
| 61 | |||
| 56 | .code64 | 62 | .code64 |
| 57 | 63 | ||
| 58 | #ifdef CONFIG_FTRACE | 64 | #ifdef CONFIG_FTRACE |
| @@ -351,6 +357,7 @@ ENTRY(system_call_after_swapgs) | |||
| 351 | GET_THREAD_INFO(%rcx) | 357 | GET_THREAD_INFO(%rcx) |
| 352 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%rcx) | 358 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%rcx) |
| 353 | jnz tracesys | 359 | jnz tracesys |
| 360 | system_call_fastpath: | ||
| 354 | cmpq $__NR_syscall_max,%rax | 361 | cmpq $__NR_syscall_max,%rax |
| 355 | ja badsys | 362 | ja badsys |
| 356 | movq %r10,%rcx | 363 | movq %r10,%rcx |
| @@ -402,6 +409,10 @@ sysret_careful: | |||
| 402 | sysret_signal: | 409 | sysret_signal: |
| 403 | TRACE_IRQS_ON | 410 | TRACE_IRQS_ON |
| 404 | ENABLE_INTERRUPTS(CLBR_NONE) | 411 | ENABLE_INTERRUPTS(CLBR_NONE) |
| 412 | #ifdef CONFIG_AUDITSYSCALL | ||
| 413 | bt $TIF_SYSCALL_AUDIT,%edx | ||
| 414 | jc sysret_audit | ||
| 415 | #endif | ||
| 405 | /* edx: work flags (arg3) */ | 416 | /* edx: work flags (arg3) */ |
| 406 | leaq do_notify_resume(%rip),%rax | 417 | leaq do_notify_resume(%rip),%rax |
| 407 | leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 | 418 | leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 |
| @@ -418,8 +429,45 @@ badsys: | |||
| 418 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) | 429 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) |
| 419 | jmp ret_from_sys_call | 430 | jmp ret_from_sys_call |
| 420 | 431 | ||
| 432 | #ifdef CONFIG_AUDITSYSCALL | ||
| 433 | /* | ||
| 434 | * Fast path for syscall audit without full syscall trace. | ||
| 435 | * We just call audit_syscall_entry() directly, and then | ||
| 436 | * jump back to the normal fast path. | ||
| 437 | */ | ||
| 438 | auditsys: | ||
| 439 | movq %r10,%r9 /* 6th arg: 4th syscall arg */ | ||
| 440 | movq %rdx,%r8 /* 5th arg: 3rd syscall arg */ | ||
| 441 | movq %rsi,%rcx /* 4th arg: 2nd syscall arg */ | ||
| 442 | movq %rdi,%rdx /* 3rd arg: 1st syscall arg */ | ||
| 443 | movq %rax,%rsi /* 2nd arg: syscall number */ | ||
| 444 | movl $AUDIT_ARCH_X86_64,%edi /* 1st arg: audit arch */ | ||
| 445 | call audit_syscall_entry | ||
| 446 | LOAD_ARGS 0 /* reload call-clobbered registers */ | ||
| 447 | jmp system_call_fastpath | ||
| 448 | |||
| 449 | /* | ||
| 450 | * Return fast path for syscall audit. Call audit_syscall_exit() | ||
| 451 | * directly and then jump back to the fast path with TIF_SYSCALL_AUDIT | ||
| 452 | * masked off. | ||
| 453 | */ | ||
| 454 | sysret_audit: | ||
| 455 | movq %rax,%rsi /* second arg, syscall return value */ | ||
| 456 | cmpq $0,%rax /* is it < 0? */ | ||
| 457 | setl %al /* 1 if so, 0 if not */ | ||
| 458 | movzbl %al,%edi /* zero-extend that into %edi */ | ||
| 459 | inc %edi /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */ | ||
| 460 | call audit_syscall_exit | ||
| 461 | movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi | ||
| 462 | jmp sysret_check | ||
| 463 | #endif /* CONFIG_AUDITSYSCALL */ | ||
| 464 | |||
| 421 | /* Do syscall tracing */ | 465 | /* Do syscall tracing */ |
| 422 | tracesys: | 466 | tracesys: |
| 467 | #ifdef CONFIG_AUDITSYSCALL | ||
| 468 | testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%rcx) | ||
| 469 | jz auditsys | ||
| 470 | #endif | ||
| 423 | SAVE_REST | 471 | SAVE_REST |
| 424 | movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ | 472 | movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ |
| 425 | FIXUP_TOP_OF_STACK %rdi | 473 | FIXUP_TOP_OF_STACK %rdi |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index c10e7aae04d7..4699950e65bd 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -1476,7 +1476,8 @@ void audit_syscall_entry(int arch, int major, | |||
| 1476 | struct audit_context *context = tsk->audit_context; | 1476 | struct audit_context *context = tsk->audit_context; |
| 1477 | enum audit_state state; | 1477 | enum audit_state state; |
| 1478 | 1478 | ||
| 1479 | BUG_ON(!context); | 1479 | if (unlikely(!context)) |
| 1480 | return; | ||
| 1480 | 1481 | ||
| 1481 | /* | 1482 | /* |
| 1482 | * This happens only on certain architectures that make system | 1483 | * This happens only on certain architectures that make system |
