From c4b7a7755f91081e430bbd58fec77194b05f834b Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Wed, 13 Jan 2016 09:15:18 -0500 Subject: audit: don't needlessly reset valid wait time After auditd has recovered from an overflowed queue, the first process that doesn't use reserves to make it through the queue checks should reset the audit backlog wait time to the configured value. After that, there is no need to keep resetting it. Signed-off-by: Richard Guy Briggs Signed-off-by: Paul Moore --- kernel/audit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/audit.c b/kernel/audit.c index 5ffcbd354a52..6d00bd1ff249 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1400,7 +1400,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, return NULL; } - if (!reserve) + if (!reserve && !audit_backlog_wait_time) audit_backlog_wait_time = audit_backlog_wait_time_master; ab = audit_buffer_alloc(ctx, gfp_mask, type); -- cgit From eb8baf6aa3ba1fcb1c1fd2cc57e31195a42689fd Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Wed, 13 Jan 2016 09:15:18 -0500 Subject: audit: remove audit_backlog_wait_overflow It seems much more obvious and readable to simply use "0". Signed-off-by: Paul Moore --- kernel/audit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/audit.c b/kernel/audit.c index 6d00bd1ff249..07d60e4b2af8 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -110,7 +110,6 @@ static u32 audit_backlog_limit = 64; #define AUDIT_BACKLOG_WAIT_TIME (60 * HZ) static u32 audit_backlog_wait_time_master = AUDIT_BACKLOG_WAIT_TIME; static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; -static u32 audit_backlog_wait_overflow = 0; /* The identity of the user shutting down the audit system. */ kuid_t audit_sig_uid = INVALID_UID; @@ -1395,7 +1394,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, skb_queue_len(&audit_skb_queue), audit_backlog_limit); audit_log_lost("backlog limit exceeded"); - audit_backlog_wait_time = audit_backlog_wait_overflow; + audit_backlog_wait_time = 0; wake_up(&audit_backlog_wait); return NULL; } -- cgit From f48a942926c58e4b2dfc3f21c58579d5435841ef Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Wed, 13 Jan 2016 09:15:19 -0500 Subject: audit: include auditd's threads in audit_log_start() wait exception Should auditd spawn threads, allow all members of its thread group to use the audit_backlog_limit reserves to bypass the queue limits too. Signed-off-by: Richard Guy Briggs [PM: minor upstream merge tweaks] Signed-off-by: Paul Moore --- kernel/audit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/audit.c b/kernel/audit.c index 07d60e4b2af8..60c9c5adc5be 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1371,7 +1371,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, return NULL; if (gfp_mask & __GFP_DIRECT_RECLAIM) { - if (audit_pid && audit_pid == current->pid) + if (audit_pid && audit_pid == current->tgid) gfp_mask &= ~__GFP_DIRECT_RECLAIM; else reserve = 0; -- cgit From 1194b994bec308433cc84ffdb92fd668713b8f93 Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Wed, 13 Jan 2016 09:18:54 -0500 Subject: audit: wake up threads if queue switched from limited to unlimited If the audit_backlog_limit is changed from a limited value to an unlimited value (zero) while the queue was overflowed, wake up the audit_backlog_wait queue to allow those processes to continue. Signed-off-by: Richard Guy Briggs Signed-off-by: Paul Moore --- kernel/audit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/audit.c b/kernel/audit.c index 60c9c5adc5be..d7b675781934 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -523,7 +523,8 @@ static int kauditd_thread(void *dummy) skb = skb_dequeue(&audit_skb_queue); if (skb) { - if (skb_queue_len(&audit_skb_queue) <= audit_backlog_limit) + if (!audit_backlog_limit || + (skb_queue_len(&audit_skb_queue) <= audit_backlog_limit)) wake_up(&audit_backlog_wait); if (audit_pid) kauditd_send_skb(skb); -- cgit From d865e573b8a4f30fbb74fa7666ca81e3132eb547 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 13 Jan 2016 09:18:55 -0500 Subject: audit: Delete unnecessary checks before two function calls The functions consume_skb() and kfree_skb() test whether their argument is NULL and then return immediately. Thus the tests around their calls are not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring [PM: tweak patch prefix] Signed-off-by: Paul Moore --- kernel/audit.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/kernel/audit.c b/kernel/audit.c index d7b675781934..d6dd95cc59e6 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -508,8 +508,7 @@ static void flush_hold_queue(void) * if auditd just disappeared but we * dequeued an skb we need to drop ref */ - if (skb) - consume_skb(skb); + consume_skb(skb); } static int kauditd_thread(void *dummy) @@ -1232,9 +1231,7 @@ static void audit_buffer_free(struct audit_buffer *ab) if (!ab) return; - if (ab->skb) - kfree_skb(ab->skb); - + kfree_skb(ab->skb); spin_lock_irqsave(&audit_freelist_lock, flags); if (audit_freelist_count > AUDIT_MAXFREE) kfree(ab); -- cgit From 96368701e1c89057bbf39222e965161c68a85b4b Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Wed, 13 Jan 2016 09:18:55 -0500 Subject: audit: force seccomp event logging to honor the audit_enabled flag Previously we were emitting seccomp audit records regardless of the audit_enabled setting, a deparature from the rest of audit. This patch makes seccomp auditing consistent with the rest of the audit record generation code in that when audit_enabled=0 nothing is logged by the audit subsystem. The bulk of this patch is moving the CONFIG_AUDIT block ahead of the CONFIG_AUDITSYSCALL block in include/linux/audit.h; the only real code change was in the audit_seccomp() definition. Signed-off-by: Tony Jones Signed-off-by: Paul Moore --- include/linux/audit.h | 204 +++++++++++++++++++++++++------------------------- 1 file changed, 104 insertions(+), 100 deletions(-) diff --git a/include/linux/audit.h b/include/linux/audit.h index 20eba1eb0a3c..476bc1237ec2 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -113,6 +113,107 @@ struct filename; extern void audit_log_session_info(struct audit_buffer *ab); +#ifdef CONFIG_AUDIT +/* These are defined in audit.c */ + /* Public API */ +extern __printf(4, 5) +void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, + const char *fmt, ...); + +extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type); +extern __printf(2, 3) +void audit_log_format(struct audit_buffer *ab, const char *fmt, ...); +extern void audit_log_end(struct audit_buffer *ab); +extern bool audit_string_contains_control(const char *string, + size_t len); +extern void audit_log_n_hex(struct audit_buffer *ab, + const unsigned char *buf, + size_t len); +extern void audit_log_n_string(struct audit_buffer *ab, + const char *buf, + size_t n); +extern void audit_log_n_untrustedstring(struct audit_buffer *ab, + const char *string, + size_t n); +extern void audit_log_untrustedstring(struct audit_buffer *ab, + const char *string); +extern void audit_log_d_path(struct audit_buffer *ab, + const char *prefix, + const struct path *path); +extern void audit_log_key(struct audit_buffer *ab, + char *key); +extern void audit_log_link_denied(const char *operation, + struct path *link); +extern void audit_log_lost(const char *message); +#ifdef CONFIG_SECURITY +extern void audit_log_secctx(struct audit_buffer *ab, u32 secid); +#else +static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) +{ } +#endif + +extern int audit_log_task_context(struct audit_buffer *ab); +extern void audit_log_task_info(struct audit_buffer *ab, + struct task_struct *tsk); + +extern int audit_update_lsm_rules(void); + + /* Private API (for audit.c only) */ +extern int audit_filter_user(int type); +extern int audit_filter_type(int type); +extern int audit_rule_change(int type, __u32 portid, int seq, + void *data, size_t datasz); +extern int audit_list_rules_send(struct sk_buff *request_skb, int seq); + +extern u32 audit_enabled; +#else /* CONFIG_AUDIT */ +static inline __printf(4, 5) +void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, + const char *fmt, ...) +{ } +static inline struct audit_buffer *audit_log_start(struct audit_context *ctx, + gfp_t gfp_mask, int type) +{ + return NULL; +} +static inline __printf(2, 3) +void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) +{ } +static inline void audit_log_end(struct audit_buffer *ab) +{ } +static inline void audit_log_n_hex(struct audit_buffer *ab, + const unsigned char *buf, size_t len) +{ } +static inline void audit_log_n_string(struct audit_buffer *ab, + const char *buf, size_t n) +{ } +static inline void audit_log_n_untrustedstring(struct audit_buffer *ab, + const char *string, size_t n) +{ } +static inline void audit_log_untrustedstring(struct audit_buffer *ab, + const char *string) +{ } +static inline void audit_log_d_path(struct audit_buffer *ab, + const char *prefix, + const struct path *path) +{ } +static inline void audit_log_key(struct audit_buffer *ab, char *key) +{ } +static inline void audit_log_link_denied(const char *string, + const struct path *link) +{ } +static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) +{ } +static inline int audit_log_task_context(struct audit_buffer *ab) +{ + return 0; +} +static inline void audit_log_task_info(struct audit_buffer *ab, + struct task_struct *tsk) +{ } +#define audit_enabled 0 +#endif /* CONFIG_AUDIT */ + #ifdef CONFIG_AUDIT_COMPAT_GENERIC #define audit_is_compat(arch) (!((arch) & __AUDIT_ARCH_64BIT)) #else @@ -212,6 +313,9 @@ void audit_core_dumps(long signr); static inline void audit_seccomp(unsigned long syscall, long signr, int code) { + if (!audit_enabled) + return; + /* Force a record to be reported if a signal was delivered. */ if (signr || unlikely(!audit_dummy_context())) __audit_seccomp(syscall, signr, code); @@ -446,106 +550,6 @@ static inline bool audit_loginuid_set(struct task_struct *tsk) return uid_valid(audit_get_loginuid(tsk)); } -#ifdef CONFIG_AUDIT -/* These are defined in audit.c */ - /* Public API */ -extern __printf(4, 5) -void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, - const char *fmt, ...); - -extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type); -extern __printf(2, 3) -void audit_log_format(struct audit_buffer *ab, const char *fmt, ...); -extern void audit_log_end(struct audit_buffer *ab); -extern bool audit_string_contains_control(const char *string, - size_t len); -extern void audit_log_n_hex(struct audit_buffer *ab, - const unsigned char *buf, - size_t len); -extern void audit_log_n_string(struct audit_buffer *ab, - const char *buf, - size_t n); -extern void audit_log_n_untrustedstring(struct audit_buffer *ab, - const char *string, - size_t n); -extern void audit_log_untrustedstring(struct audit_buffer *ab, - const char *string); -extern void audit_log_d_path(struct audit_buffer *ab, - const char *prefix, - const struct path *path); -extern void audit_log_key(struct audit_buffer *ab, - char *key); -extern void audit_log_link_denied(const char *operation, - struct path *link); -extern void audit_log_lost(const char *message); -#ifdef CONFIG_SECURITY -extern void audit_log_secctx(struct audit_buffer *ab, u32 secid); -#else -static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) -{ } -#endif - -extern int audit_log_task_context(struct audit_buffer *ab); -extern void audit_log_task_info(struct audit_buffer *ab, - struct task_struct *tsk); - -extern int audit_update_lsm_rules(void); - - /* Private API (for audit.c only) */ -extern int audit_filter_user(int type); -extern int audit_filter_type(int type); -extern int audit_rule_change(int type, __u32 portid, int seq, - void *data, size_t datasz); -extern int audit_list_rules_send(struct sk_buff *request_skb, int seq); - -extern u32 audit_enabled; -#else /* CONFIG_AUDIT */ -static inline __printf(4, 5) -void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, - const char *fmt, ...) -{ } -static inline struct audit_buffer *audit_log_start(struct audit_context *ctx, - gfp_t gfp_mask, int type) -{ - return NULL; -} -static inline __printf(2, 3) -void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) -{ } -static inline void audit_log_end(struct audit_buffer *ab) -{ } -static inline void audit_log_n_hex(struct audit_buffer *ab, - const unsigned char *buf, size_t len) -{ } -static inline void audit_log_n_string(struct audit_buffer *ab, - const char *buf, size_t n) -{ } -static inline void audit_log_n_untrustedstring(struct audit_buffer *ab, - const char *string, size_t n) -{ } -static inline void audit_log_untrustedstring(struct audit_buffer *ab, - const char *string) -{ } -static inline void audit_log_d_path(struct audit_buffer *ab, - const char *prefix, - const struct path *path) -{ } -static inline void audit_log_key(struct audit_buffer *ab, char *key) -{ } -static inline void audit_log_link_denied(const char *string, - const struct path *link) -{ } -static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) -{ } -static inline int audit_log_task_context(struct audit_buffer *ab) -{ - return 0; -} -static inline void audit_log_task_info(struct audit_buffer *ab, - struct task_struct *tsk) -{ } -#define audit_enabled 0 -#endif /* CONFIG_AUDIT */ static inline void audit_log_string(struct audit_buffer *ab, const char *buf) { audit_log_n_string(ab, buf, strlen(buf)); -- cgit From cb74ed278f8054fddf79ed930495b9e214f7c7b2 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Wed, 13 Jan 2016 09:18:55 -0500 Subject: audit: always enable syscall auditing when supported and audit is enabled To the best of our knowledge, everyone who enables audit at compile time also enables syscall auditing; this patch simplifies the Kconfig menus by removing the option to disable syscall auditing when audit is selected and the target arch supports it. Signed-off-by: Paul Moore --- init/Kconfig | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index 235c7a2c0d20..a9b4c85c036b 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -299,20 +299,15 @@ config AUDIT help Enable auditing infrastructure that can be used with another kernel subsystem, such as SELinux (which requires this for - logging of avc messages output). Does not do system-call - auditing without CONFIG_AUDITSYSCALL. + logging of avc messages output). System call auditing is included + on architectures which support it. config HAVE_ARCH_AUDITSYSCALL bool config AUDITSYSCALL - bool "Enable system-call auditing support" + def_bool y depends on AUDIT && HAVE_ARCH_AUDITSYSCALL - default y if SECURITY_SELINUX - help - Enable low-overhead system-call auditing infrastructure that - can be used independently or with another kernel subsystem, - such as SELinux. config AUDIT_WATCH def_bool y -- cgit