From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752749AbbIZLYQ (ORCPT ); Sat, 26 Sep 2015 07:24:16 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:55400 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752694AbbIZLYP (ORCPT ); Sat, 26 Sep 2015 07:24:15 -0400 Message-ID: <1443266636.2004.2.camel@decadent.org.uk> Subject: [PATCH] genirq: Fix race in register_irq_proc() From: Ben Hutchings To: Thomas Gleixner Cc: LKML , stable Date: Sat, 26 Sep 2015 12:23:56 +0100 Content-Type: multipart/signed; micalg="pgp-sha512"; protocol="application/pgp-signature"; boundary="=-BC5l2llm+4k12A+/uroG" X-Mailer: Evolution 3.16.5-1 Mime-Version: 1.0 X-SA-Exim-Connect-IP: 192.168.4.247 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --=-BC5l2llm+4k12A+/uroG Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 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 =20 #include "internals.h" =20 @@ -323,18 +324,29 @@ void register_handler_proc(unsigned int irq, struct i= rqaction *action) =20 void register_irq_proc(unsigned int irq, struct irq_desc *desc) { + static DEFINE_MUTEX(register_lock); char name [MAX_NAMELEN]; =20 - if (!root_irq_dir || (desc->irq_data.chip =3D=3D &no_irq_chip) || desc->d= ir) + if (!root_irq_dir || (desc->irq_data.chip =3D=3D &no_irq_chip)) return; =20 + /* + * 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); =20 /* create /proc/irq/1234 */ desc->dir =3D proc_mkdir(name, root_irq_dir); if (!desc->dir) - return; + goto out_unlock; =20 #ifdef CONFIG_SMP /* create /proc/irq//smp_affinity */ @@ -355,6 +367,9 @@ void register_irq_proc(unsigned int irq, struct irq_des= c *desc) =20 proc_create_data("spurious", 0444, desc->dir, &irq_spurious_proc_fops, (void *)(long)irq); + +out_unlock: + mutex_unlock(®ister_lock); } =20 void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) --=20 Ben Hutchings Any smoothly functioning technology is indistinguishable from a rigged demo= . --=-BC5l2llm+4k12A+/uroG Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUAVgaATOe/yOyVhhEJAQqEoQ//axBXYv9/dj4hMXS+xbsjH80BKbailJO9 hGVMbFbdtPvfZDayHqgqwWIutxW1v7UNk9L0Fc59aNdgbSqIm0Y8GN4BevvlvM6m W5k7hcFKFyDbxQ82vuS9MysTt5fGLoLyywNUNJDraCeZFfxAp74RsXBIR4DhcS04 0urlaydPpsXLk9aizRY3YftHWVEmiB2d1uvRmWD9qWSbVJ8GOz1/81fyiFaO6UXK s7mb4kkMHqjldRl5uqTbMWxj+pL47hXnqU6vxUoIR+zIZqc77o7tSVycjizqLfXx ozqFXaixY8UTW5X+r61su66jvfscOgtvmqf1cCTGV0i6tcO43hI8UZXO8ZM/crqX J0KQ8C5kWrWASR1TrWPl09PAWrtq8vstgX3FSBtAb6+VpSYg/Gjinds2JNN/646q 7lh5FR7GjflYSjFL3FFN0qHZkBOGohfhpT0wV3wcR3Vea3Z2YQeA9P2jUBTpY8GJ fadTRj6E+pVBDbkyFBOR3mf5KFrEkdY0aBopbKD26WexLs72J2b+E1aKfRjFH5ol J3RUazG23ueDA78RyV2N99lyIZXYo9QZ4ElT+U2REivBW+gGml5pauW0PVWMnZrm 2YAMhtMZq2xf0b7B1tUs2xcixo8mEBRMBLfOt3UsVo4rpMQ/MkyMLp6M1Xri4A3B xEAORrksSxw= =2J8E -----END PGP SIGNATURE----- --=-BC5l2llm+4k12A+/uroG--