Messages in this thread Patch in this message | | | Date | Wed, 7 Mar 2018 11:32:52 +0100 (CET) | From | Jiri Kosina <> | Subject | [PATCH] audit: set TIF_AUDIT_SYSCALL only if audit filter has been populated |
| |
From: Jiri Kosina <jkosina@suse.cz>
There is no point going through all the audit slow path syscall entry/exit in case the audit daemon is running, but hasn't populated the audit filter with any rules whatsoever.
Only set TIF_AUDIT_SYSCALL in case the number of populated audit rules is non-zero.
Originally-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz> ---
This is basically resurrection / rebase of patch Andi Lutomirski sent some time back in 2014 or so. Andi, is there any reason this hasn't been pursued further? I think we still want to get some of the slow path performance back.
Thanks.
include/linux/audit.h | 15 +++++++++++++-- kernel/auditfilter.c | 4 ++-- kernel/auditsc.c | 45 ++++++++++++++++++++++++++++++++++++++++----- kernel/fork.c | 2 +- 4 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h index af410d9fbf2d..3d5e96f96be5 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -451,8 +451,10 @@ static inline void audit_fanotify(unsigned int response) __audit_fanotify(response); } -extern int audit_n_rules; extern int audit_signals; +extern void audit_populate(struct task_struct *tsk); +extern void audit_inc_n_rules(void); +extern void audit_dec_n_rules(void); #else /* CONFIG_AUDITSYSCALL */ static inline int audit_alloc(struct task_struct *task) { @@ -572,7 +574,16 @@ static inline void audit_fanotify(unsigned int response) static inline void audit_ptrace(struct task_struct *t) { } -#define audit_n_rules 0 + +static inline void audit_populate(struct task_struct *tsk) +{ } + +static inline void audit_inc_n_rules(void) +{ } + +static inline void audit_dec_n_rules(void) +{ } + #define audit_signals 0 #endif /* CONFIG_AUDITSYSCALL */ diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 4a1758adb222..46ad138d8ba2 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -991,7 +991,7 @@ static inline int audit_add_rule(struct audit_entry *entry) } #ifdef CONFIG_AUDITSYSCALL if (!dont_count) - audit_n_rules++; + audit_inc_n_rules(); if (!audit_match_signal(entry)) audit_signals++; @@ -1038,7 +1038,7 @@ int audit_del_rule(struct audit_entry *entry) #ifdef CONFIG_AUDITSYSCALL if (!dont_count) - audit_n_rules--; + audit_dec_n_rules(); if (!audit_match_signal(entry)) audit_signals--; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index e80459f7e132..642dd856e716 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -91,7 +91,7 @@ #define MAX_PROCTITLE_AUDIT_LEN 128 /* number of audit rules */ -int audit_n_rules; +static int audit_n_rules; /* determines whether we collect data for signals sent */ int audit_signals; @@ -919,6 +919,36 @@ static inline struct audit_context *audit_alloc_context(enum audit_state state) return context; } +void audit_inc_n_rules() +{ + struct task_struct *p, *g; + unsigned long flags; + + read_lock_irqsave(&tasklist_lock, flags); + if (!audit_n_rules++) { + do_each_thread(g, p) { + if (p->audit_context) + set_tsk_thread_flag(p, TIF_SYSCALL_AUDIT); + } while_each_thread(g, p); + } + read_unlock_irqrestore(&tasklist_lock, flags); +} + +void audit_dec_n_rules() +{ + struct task_struct *p, *g; + unsigned long flags; + + read_lock_irqsave(&tasklist_lock, flags); + audit_n_rules--; + if (!audit_n_rules) { + do_each_thread(g, p) { + clear_tsk_thread_flag(p, TIF_SYSCALL_AUDIT); + } while_each_thread(g, p); + } + read_unlock_irqrestore(&tasklist_lock, flags); +} + /** * audit_alloc - allocate an audit context block for a task * @tsk: task @@ -938,10 +968,8 @@ int audit_alloc(struct task_struct *tsk) return 0; /* Return if not auditing. */ state = audit_filter_task(tsk, &key); - if (state == AUDIT_DISABLED) { - clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); + if (state == AUDIT_DISABLED) return 0; - } if (!(context = audit_alloc_context(state))) { kfree(key); @@ -951,7 +979,6 @@ int audit_alloc(struct task_struct *tsk) context->filterkey = key; tsk->audit_context = context; - set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); return 0; } @@ -967,6 +994,14 @@ static inline void audit_free_context(struct audit_context *context) kfree(context); } +void audit_populate(struct task_struct *tsk) +{ + if (tsk->audit_context && audit_n_rules) + set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); + else + clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); +} + static int audit_log_pid_context(struct audit_context *context, pid_t pid, kuid_t auid, kuid_t uid, unsigned int sessionid, u32 sid, char *comm) diff --git a/kernel/fork.c b/kernel/fork.c index e5d9d405ae4e..79c828746d24 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1955,7 +1955,7 @@ static __latent_entropy struct task_struct *copy_process( attach_pid(p, PIDTYPE_PID); nr_threads++; } - + audit_populate(p); total_forks++; spin_unlock(¤t->sighand->siglock); syscall_tracepoint_update(p); -- Jiri Kosina SUSE Labs
| |