mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
AUDIT: Stop waiting for backlog after audit_panic() happens
We force a rate-limit on auditable events by making them wait for space on the backlog queue. However, if auditd really is AWOL then this could potentially bring the entire system to a halt, depending on the audit rules in effect. Firstly, make sure the wait time is honoured correctly -- it's the maximum time the process should wait, rather than the time to wait _each_ time round the loop. We were getting re-woken _each_ time a packet was dequeued, and the timeout was being restarted each time. Secondly, reset the wait time after audit_panic() is called. In general this will be reset to zero, to allow progress to be made. If the system is configured to _actually_ panic on audit_panic() then that will already have happened; otherwise we know that audit records are being lost anyway. These two tunables can't be exposed via AUDIT_GET and AUDIT_SET because those aren't particularly well-designed. It probably should have been done by sysctls or sysfs anyway -- one for a later patch. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
This commit is contained in:
parent
7b430437c0
commit
ac4cec443a
1 changed files with 10 additions and 5 deletions
|
@ -79,6 +79,8 @@ static int audit_rate_limit;
|
||||||
|
|
||||||
/* Number of outstanding audit_buffers allowed. */
|
/* Number of outstanding audit_buffers allowed. */
|
||||||
static int audit_backlog_limit = 64;
|
static int audit_backlog_limit = 64;
|
||||||
|
static int audit_backlog_wait_time = 60 * HZ;
|
||||||
|
static int audit_backlog_wait_overflow = 0;
|
||||||
|
|
||||||
/* The identity of the user shutting down the audit system. */
|
/* The identity of the user shutting down the audit system. */
|
||||||
uid_t audit_sig_uid = -1;
|
uid_t audit_sig_uid = -1;
|
||||||
|
@ -655,6 +657,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
|
||||||
struct timespec t;
|
struct timespec t;
|
||||||
unsigned int serial;
|
unsigned int serial;
|
||||||
int reserve;
|
int reserve;
|
||||||
|
unsigned long timeout_start = jiffies;
|
||||||
|
|
||||||
if (!audit_initialized)
|
if (!audit_initialized)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -667,8 +670,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
|
||||||
|
|
||||||
while (audit_backlog_limit
|
while (audit_backlog_limit
|
||||||
&& skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
|
&& skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
|
||||||
if (gfp_mask & __GFP_WAIT) {
|
if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time
|
||||||
int ret = 1;
|
&& time_before(jiffies, timeout_start + audit_backlog_wait_time)) {
|
||||||
|
|
||||||
/* Wait for auditd to drain the queue a little */
|
/* Wait for auditd to drain the queue a little */
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
@ -676,12 +680,11 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
|
||||||
|
|
||||||
if (audit_backlog_limit &&
|
if (audit_backlog_limit &&
|
||||||
skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
|
skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
|
||||||
ret = schedule_timeout(HZ * 60);
|
schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies);
|
||||||
|
|
||||||
__set_current_state(TASK_RUNNING);
|
__set_current_state(TASK_RUNNING);
|
||||||
remove_wait_queue(&audit_backlog_wait, &wait);
|
remove_wait_queue(&audit_backlog_wait, &wait);
|
||||||
if (ret)
|
continue;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (audit_rate_check())
|
if (audit_rate_check())
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
|
@ -690,6 +693,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
|
||||||
skb_queue_len(&audit_skb_queue),
|
skb_queue_len(&audit_skb_queue),
|
||||||
audit_backlog_limit);
|
audit_backlog_limit);
|
||||||
audit_log_lost("backlog limit exceeded");
|
audit_log_lost("backlog limit exceeded");
|
||||||
|
audit_backlog_wait_time = audit_backlog_wait_overflow;
|
||||||
|
wake_up(&audit_backlog_wait);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue