diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index f055d8e93bc49240da646fff336def76a6b694ff..b6d7657861d5da35752020bade1308f576873931 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -27,6 +27,7 @@ CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_AUDIT=y CONFIG_HAVE_ARCH_AUDITSYSCALL=y CONFIG_AUDITSYSCALL=y +CONFIG_AUDITSYSCALL_OPTIMIZE=y # # IRQ subsystem diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 9adedd9d615a10af912d64649b5f41d5ac5a52a3..0c12dc66625ef59b7747c2d50479f8b95b788f55 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -41,6 +41,7 @@ CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_AUDIT=y CONFIG_HAVE_ARCH_AUDITSYSCALL=y CONFIG_AUDITSYSCALL=y +CONFIG_AUDITSYSCALL_OPTIMIZE=y # # IRQ subsystem diff --git a/include/linux/audit.h b/include/linux/audit.h index b3d859831a31683cbc48836fba23b67e04af1412..00dcf224ea1a2d3a83fc16b2c82739e84eb40323 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -319,6 +319,26 @@ static inline bool audit_dummy_context(void) void *p = audit_context(); return !p || *(int *)p; } + +#ifdef CONFIG_AUDITSYSCALL_OPTIMIZE +extern int audit_n_rules; +static inline bool audit_get_dummy_context(void) +{ + void *p = audit_context(); + int *dummy = p; + + if (!p) + return true; + + if (!audit_n_rules) { + *dummy = 1; + return true; + } else { + return false; + } +} +#endif + static inline void audit_free(struct task_struct *task) { if (unlikely(task->audit_context)) @@ -328,12 +348,20 @@ static inline void audit_syscall_entry(int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3) { +#ifdef CONFIG_AUDITSYSCALL_OPTIMIZE + if (unlikely(!audit_get_dummy_context())) +#else if (unlikely(audit_context())) +#endif __audit_syscall_entry(major, a0, a1, a2, a3); } static inline void audit_syscall_exit(void *pt_regs) { +#ifdef CONFIG_AUDITSYSCALL_OPTIMIZE + if (unlikely(!audit_get_dummy_context())) { +#else if (unlikely(audit_context())) { +#endif int success = is_syscall_success(pt_regs); long return_code = regs_return_value(pt_regs); diff --git a/init/Kconfig b/init/Kconfig index b7fbf5b9bdf28eed86b774ad474aa1953b9ca2d8..96d664a7541ccf545c674431798dba596f7a2dca 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -437,6 +437,11 @@ config AUDITSYSCALL depends on AUDIT && HAVE_ARCH_AUDITSYSCALL select FSNOTIFY +config AUDITSYSCALL_OPTIMIZE + bool "System call auditing optimize" + def_bool n + depends on AUDITSYSCALL + source "kernel/irq/Kconfig" source "kernel/time/Kconfig" source "kernel/Kconfig.preempt" diff --git a/kernel/entry/common.c b/kernel/entry/common.c index a028b28daed5b587334d5880b1680adfb2ee2625..48bac49a73a720ff3c2fb334a2e164a20b20ae96 100644 --- a/kernel/entry/common.c +++ b/kernel/entry/common.c @@ -77,8 +77,19 @@ __syscall_enter_from_user_work(struct pt_regs *regs, long syscall) unsigned long ti_work; ti_work = READ_ONCE(current_thread_info()->flags); +#ifdef CONFIG_AUDITSYSCALL_OPTIMIZE + if (ti_work == _TIF_SYSCALL_AUDIT) { + if (!audit_get_dummy_context()) { + syscall = syscall_get_nr(current, regs); + syscall_enter_audit(regs, syscall); + } + } else if (ti_work & SYSCALL_ENTER_WORK) { + syscall = syscall_trace_enter(regs, syscall, ti_work); + } +#else if (ti_work & SYSCALL_ENTER_WORK) syscall = syscall_trace_enter(regs, syscall, ti_work); +#endif return syscall; } @@ -269,8 +280,15 @@ static void syscall_exit_to_user_mode_prepare(struct pt_regs *regs) * enabled, we want to run them exactly once per syscall exit with * interrupts enabled. */ +#ifdef CONFIG_AUDITSYSCALL_OPTIMIZE + if (cached_flags == _TIF_SYSCALL_AUDIT) + audit_syscall_exit(regs); + else if (unlikely(cached_flags & SYSCALL_EXIT_WORK)) + syscall_exit_work(regs, cached_flags); +#else if (unlikely(cached_flags & SYSCALL_EXIT_WORK)) syscall_exit_work(regs, cached_flags); +#endif } __visible noinstr void syscall_exit_to_user_mode(struct pt_regs *regs)