From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755430AbbJAKWC (ORCPT ); Thu, 1 Oct 2015 06:22:02 -0400 Received: from terminus.zytor.com ([198.137.202.10]:46782 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751547AbbJAKV7 (ORCPT ); Thu, 1 Oct 2015 06:21:59 -0400 Date: Thu, 1 Oct 2015 03:21:37 -0700 From: tip-bot for Ben Hutchings Message-ID: Cc: tglx@linutronix.de, linux-kernel@vger.kernel.org, mingo@kernel.org, hpa@zytor.com, ben@decadent.org.uk Reply-To: hpa@zytor.com, mingo@kernel.org, ben@decadent.org.uk, linux-kernel@vger.kernel.org, tglx@linutronix.de In-Reply-To: <1443266636.2004.2.camel@decadent.org.uk> References: <1443266636.2004.2.camel@decadent.org.uk> To: linux-tip-commits@vger.kernel.org Subject: [tip:irq/urgent] genirq: Fix race in register_irq_proc() Git-Commit-ID: 95c2b17534654829db428f11bcf4297c059a2a7e X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 95c2b17534654829db428f11bcf4297c059a2a7e Gitweb: http://git.kernel.org/tip/95c2b17534654829db428f11bcf4297c059a2a7e Author: Ben Hutchings AuthorDate: Sat, 26 Sep 2015 12:23:56 +0100 Committer: Thomas Gleixner CommitDate: Thu, 1 Oct 2015 12:18:13 +0200 genirq: Fix race in register_irq_proc() Per-IRQ directories in procfs are created only when a handler is first added to the irqdesc, not when the irqdesc is created. In the case of a shared IRQ, multiple tasks can race to create a directory. This race condition seems to have been present forever, but is easier to hit with async probing. Signed-off-by: Ben Hutchings Link: http://lkml.kernel.org/r/1443266636.2004.2.camel@decadent.org.uk Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org --- kernel/irq/proc.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index e3a8c95..a50ddc9 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "internals.h" @@ -323,18 +324,29 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) void register_irq_proc(unsigned int irq, struct irq_desc *desc) { + static DEFINE_MUTEX(register_lock); char name [MAX_NAMELEN]; - if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip) || desc->dir) + if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) return; + /* + * irq directories are registered only when a handler is + * added, not when the descriptor is created, so multiple + * tasks might try to register at the same time. + */ + mutex_lock(®ister_lock); + + if (desc->dir) + goto out_unlock; + memset(name, 0, MAX_NAMELEN); sprintf(name, "%d", irq); /* create /proc/irq/1234 */ desc->dir = proc_mkdir(name, root_irq_dir); if (!desc->dir) - return; + goto out_unlock; #ifdef CONFIG_SMP /* create /proc/irq//smp_affinity */ @@ -355,6 +367,9 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) proc_create_data("spurious", 0444, desc->dir, &irq_spurious_proc_fops, (void *)(long)irq); + +out_unlock: + mutex_unlock(®ister_lock); } void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)