[ARCHIVE DEBUG 12/13] audit_debug: list processes and frequencies waiting for auditd

Richard Guy Briggs rgb at redhat.com
Thu Oct 22 18:58:58 UTC 2015


Debug to list each process, its first call time and how many times it is
called while waiting for auditd upon queue overflow.  It is reported and
cleared when the queue is drained sufficiently to clear the condition.

Signed-off-by: Richard Guy Briggs <rgb at redhat.com>
---
 kernel/audit.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 76b6878..e4be6f3 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1498,6 +1498,11 @@ static long wait_for_auditd(long sleep_time)
  * will be written at syscall exit.  If there is no associated task, then
  * task context (ctx) should be NULL.
  */
+#define PIDS_WAITING_MAX 1024
+pid_t pids_waiting[PIDS_WAITING_MAX];
+int pids_waiting_c[PIDS_WAITING_MAX];
+char pids_waiting_comm[PIDS_WAITING_MAX][16];
+unsigned long pids_waiting_j[PIDS_WAITING_MAX];
 struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 				     int type)
 {
@@ -1539,6 +1544,19 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 
 	while (audit_backlog_limit
 	       && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
+		int c = 0;
+		while (pids_waiting[c] && pids_waiting[c] != current->pid)
+			c++;
+		if (c < PIDS_WAITING_MAX) {
+			if (!pids_waiting[c]) {
+				pids_waiting[c] = current->pid;
+				memcpy(pids_waiting_comm[c], current->comm, 16);
+				pids_waiting_j[c] = jiffies;
+			}
+			pids_waiting_c[c]++;
+		} else
+			pr_warn("overflowed pids_waiting counter\n");
+		
 		if (!overflow_counted) {
 			atomic_inc(&audit_overflows);
 			overflow_counted = 1;
@@ -1572,6 +1590,20 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 				}
 			}
 		}
+		if (audit_backlog_wait_time) {
+			int c = 0;
+			if (pids_waiting[0]) {
+				pr_warn("pids_waiting:");
+				while (pids_waiting[c]) {
+					printk(" %d\"%s\"(%lu:%d)", pids_waiting[c], pids_waiting_comm[c], pids_waiting_j[c], pids_waiting_c[c]);
+					pids_waiting[c] = pids_waiting_c[c] = 0;
+					if (c++ >= PIDS_WAITING_MAX) {
+						break;
+						printk("\n");
+					}
+				}
+			}
+		}
 		if (audit_rate_check() && printk_ratelimit())
 			pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",
 				skb_queue_len(&audit_skb_queue),
-- 
1.7.1




More information about the Linux-audit mailing list