[PATCH][RFC] audit: set wait time to zero when audit failed

Li RongQing lirongqing at baidu.com
Thu Sep 12 03:19:45 UTC 2019


if audit_log_start failed because queue is full, kauditd is waiting
the receiving queue empty, but no receiver, a task will be forced to
wait 60 seconds for each audited syscall, and it will be hang for a
very long time

so at this condition, set the wait time to zero to reduce wait, and
restore wait time when audit works again

it partially restore the commit 3197542482df ("audit: rework
audit_log_start()")

Signed-off-by: Li RongQing <lirongqing at baidu.com>
Signed-off-by: Liang ZhiCheng <liangzhicheng at baidu.com>
---
reboot is taking a very long time on my machine(centos 6u4 +kernel 5.3)
since TIF_SYSCALL_AUDIT is set by default, and when reboot, userspace process
which receiver audit message , will be killed, and lead to that no user
drain the audit queue

git bitsect show it is caused by 3197542482df ("audit: rework audit_log_start()")

 kernel/audit.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index da8dc0db5bd3..6de23599fd43 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -119,6 +119,7 @@ static u32	audit_rate_limit;
  * When set to zero, this means unlimited. */
 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;
 
 /* The identity of the user shutting down the audit system. */
@@ -435,7 +436,7 @@ static int audit_set_backlog_limit(u32 limit)
 static int audit_set_backlog_wait_time(u32 timeout)
 {
 	return audit_do_config_change("audit_backlog_wait_time",
-				      &audit_backlog_wait_time, timeout);
+				      &audit_backlog_wait_time_master, timeout);
 }
 
 static int audit_set_enabled(u32 state)
@@ -1202,7 +1203,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 		s.lost			= atomic_read(&audit_lost);
 		s.backlog		= skb_queue_len(&audit_queue);
 		s.feature_bitmap	= AUDIT_FEATURE_BITMAP_ALL;
-		s.backlog_wait_time	= audit_backlog_wait_time;
+		s.backlog_wait_time	= audit_backlog_wait_time_master;
 		audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s));
 		break;
 	}
@@ -1785,11 +1786,15 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 						skb_queue_len(&audit_queue),
 						audit_backlog_limit);
 				audit_log_lost("backlog limit exceeded");
+				audit_backlog_wait_time = 0;
 				return NULL;
 			}
 		}
 	}
 
+	if (audit_backlog_wait_time != audit_backlog_wait_time_master)
+		audit_backlog_wait_time = audit_backlog_wait_time_master;
+
 	ab = audit_buffer_alloc(ctx, gfp_mask, type);
 	if (!ab) {
 		audit_log_lost("out of memory in audit_log_start");
-- 
2.16.2




More information about the Linux-audit mailing list