[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1391997564-1805-6-git-send-email-peter@hurleysoftware.com>
Date: Sun, 9 Feb 2014 20:59:05 -0500
From: Peter Hurley <peter@...leysoftware.com>
To: Marcel Holtmann <marcel@...tmann.org>
Cc: Gustavo Padovan <gustavo@...ovan.org>,
Johan Hedberg <johan.hedberg@...il.com>,
Gianluca Anzolin <gianluca@...tospazio.it>,
Alexander Holler <holler@...oftware.de>,
Andrey Vihrov <andrey.vihrov@...il.com>,
Sander Eikelenboom <linux@...elenboom.it>,
linux-bluetooth@...r.kernel.org, linux-kernel@...r.kernel.org,
Peter Hurley <peter@...leysoftware.com>,
Jiri Slaby <jslaby@...e.cz>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: [PATCH 05/24] Bluetooth: Fix racy acquire of rfcomm_dev reference
rfcomm_dev_get() can return a rfcomm_dev reference for a
device for which destruction may be commencing. This can happen
on tty destruction, which calls rfcomm_tty_cleanup(), the last
port reference may have been released but RFCOMM_TTY_RELEASED
was not set. The following race is also possible:
CPU 0 | CPU 1
| rfcomm_release_dev
rfcomm_dev_get | .
spin_lock | .
dev = __rfcomm_dev_get | .
if dev | .
if test_bit(TTY_RELEASED) | .
| !test_and_set_bit(TTY_RELEASED)
| tty_port_put <<<< last reference
else |
tty_port_get |
The reference acquire is bogus because destruction will commence
with the release of the last reference.
Ignore the external state change of TTY_RELEASED and instead rely
on the reference acquire itself to determine if the reference is
valid.
Cc: Jiri Slaby <jslaby@...e.cz>
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Signed-off-by: Peter Hurley <peter@...leysoftware.com>
---
net/bluetooth/rfcomm/tty.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index a535ef1..7cf193f 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -157,12 +157,8 @@ static struct rfcomm_dev *rfcomm_dev_get(int id)
dev = __rfcomm_dev_get(id);
- if (dev) {
- if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
- dev = NULL;
- else
- tty_port_get(&dev->port);
- }
+ if (dev && !tty_port_get(&dev->port))
+ dev = NULL;
spin_unlock(&rfcomm_dev_lock);
--
1.8.1.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists