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 <r...@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

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

Reply via email to