From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965783AbbJVS4D (ORCPT ); Thu, 22 Oct 2015 14:56:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41407 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965781AbbJVSyH (ORCPT ); Thu, 22 Oct 2015 14:54:07 -0400 From: Richard Guy Briggs To: linux-audit@redhat.com, linux-kernel@vger.kernel.org Cc: Richard Guy Briggs , sgrubb@redhat.com, pmoore@redhat.com, eparis@redhat.com, v.rathor@gmail.com, ctcard@hotmail.com Subject: [RFC PATCH 5/7] audit: allow audit_cmd_mutex holders to use reserves Date: Thu, 22 Oct 2015 14:53:18 -0400 Message-Id: <7f62a8c1d8cf031dda3c41bdf39ee4902e6f897e.1445539473.git.rgb@redhat.com> In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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