Skip to content
Snippets Groups Projects
Commit 6dd80aba authored by Toshiyuki Okajima's avatar Toshiyuki Okajima Committed by Eric Paris
Browse files

audit: audit_log_start running on auditd should not stop


The backlog cannot be consumed when audit_log_start is running on auditd
even if audit_log_start calls wait_for_auditd to consume it.
The situation is the deadlock because only auditd can consume the backlog.
If the other process needs to send the backlog, it can be also stopped
by the deadlock.

So, audit_log_start running on auditd should not stop.

You can see the deadlock with the following reproducer:
 # auditctl -a exit,always -S all
 # reboot

Signed-off-by: default avatarToshiyuki Okajima <toshi.okajima@jp.fujitsu.com>
Reviewed-by: default avatar <gaofeng@cn.fujitsu.com>
Signed-off-by: default avatarRichard Guy Briggs <rgb@redhat.com>
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent 1b7b533f
No related branches found
No related tags found
No related merge requests found
...@@ -1319,7 +1319,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, ...@@ -1319,7 +1319,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
struct audit_buffer *ab = NULL; struct audit_buffer *ab = NULL;
struct timespec t; struct timespec t;
unsigned int uninitialized_var(serial); unsigned int uninitialized_var(serial);
int reserve; int reserve = 5; /* Allow atomic callers to go up to five
entries over the normal backlog limit */
unsigned long timeout_start = jiffies; unsigned long timeout_start = jiffies;
if (audit_initialized != AUDIT_INITIALIZED) if (audit_initialized != AUDIT_INITIALIZED)
...@@ -1328,11 +1329,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, ...@@ -1328,11 +1329,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
if (unlikely(audit_filter_type(type))) if (unlikely(audit_filter_type(type)))
return NULL; return NULL;
if (gfp_mask & __GFP_WAIT) if (gfp_mask & __GFP_WAIT) {
reserve = 0; if (audit_pid && audit_pid == current->pid)
else gfp_mask &= ~__GFP_WAIT;
reserve = 5; /* Allow atomic callers to go up to five else
entries over the normal backlog limit */ reserve = 0;
}
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) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment