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 <lirongq...@baidu.com>
Signed-off-by: Liang ZhiCheng <liangzhich...@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

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit

Reply via email to