If we hold the audit_cmd_mutex, we should never sleep waiting for auditd
to drain the queue since auditd may need the mutex to shut down.

This was first implemented with mutex_trylock(), but since
audit_log_start() can be called in softirq context, that won't work.
Next, owner_running() was used to check audit_cmd_mutex but another
process could have this locked on another cpu.  Use rcu_read_lock() and
ACCESS_ONCE() to check audit_cmd_mutex.

Signed-off-by: Richard Guy Briggs <[email protected]>
---
 kernel/audit.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 02a5ec0..34411af 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1376,12 +1376,15 @@ struct audit_buffer *audit_log_start(struct 
audit_context *ctx, gfp_t gfp_mask,
                return NULL;
 
        if (gfp_mask & __GFP_WAIT) {
-               if (current->tgid == 1 || (audit_pid && audit_pid == 
current->tgid))
+               rcu_read_lock();
+               if (ACCESS_ONCE(audit_cmd_mutex.owner) == current ||
+                   current->tgid == 1 ||
+                   (audit_pid && audit_pid == current->tgid))
                        gfp_mask &= ~__GFP_WAIT;
                else
                        reserve = 0;
+               rcu_read_unlock();
        }
-
        while (audit_backlog_limit
               && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + 
reserve) {
                if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) {
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to