aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/rfcomm
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2014-02-09 20:59:18 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-02-14 16:39:31 -0500
commit033ace99c444daa4141b84419f670513ce637b77 (patch)
tree6640d710788117d3dbf9c76dd15e870dddbddec5 /net/bluetooth/rfcomm
parent7611fcedd6caae0586397508a2414788d87a231c (diff)
Bluetooth: Serialize RFCOMMCREATEDEV and RFCOMMRELEASEDEV ioctls
At least two different race conditions exist with multiple concurrent RFCOMMCREATEDEV and RFCOMMRELEASEDEV ioctls: * Multiple concurrent RFCOMMCREATEDEVs with RFCOMM_REUSE_DLC can mistakenly share the same DLC. * RFCOMMRELEASEDEV can destruct the rfcomm_dev still being constructed by RFCOMMCREATEDEV. Introduce rfcomm_ioctl_mutex to serialize these add/remove operations. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Tested-By: Alexander Holler <holler@ahsoftware.de> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/rfcomm')
-rw-r--r--net/bluetooth/rfcomm/tty.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 4a38b5454ab0..ef2769553dab 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -40,6 +40,7 @@
40#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */ 40#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
41#define RFCOMM_TTY_MINOR 0 41#define RFCOMM_TTY_MINOR 0
42 42
43static DEFINE_MUTEX(rfcomm_ioctl_mutex);
43static struct tty_driver *rfcomm_tty_driver; 44static struct tty_driver *rfcomm_tty_driver;
44 45
45struct rfcomm_dev { 46struct rfcomm_dev {
@@ -373,7 +374,7 @@ static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size
373 374
374#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP)) 375#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
375 376
376static int rfcomm_create_dev(struct sock *sk, void __user *arg) 377static int __rfcomm_create_dev(struct sock *sk, void __user *arg)
377{ 378{
378 struct rfcomm_dev_req req; 379 struct rfcomm_dev_req req;
379 struct rfcomm_dlc *dlc; 380 struct rfcomm_dlc *dlc;
@@ -423,7 +424,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg)
423 return id; 424 return id;
424} 425}
425 426
426static int rfcomm_release_dev(void __user *arg) 427static int __rfcomm_release_dev(void __user *arg)
427{ 428{
428 struct rfcomm_dev_req req; 429 struct rfcomm_dev_req req;
429 struct rfcomm_dev *dev; 430 struct rfcomm_dev *dev;
@@ -466,6 +467,28 @@ static int rfcomm_release_dev(void __user *arg)
466 return 0; 467 return 0;
467} 468}
468 469
470static int rfcomm_create_dev(struct sock *sk, void __user *arg)
471{
472 int ret;
473
474 mutex_lock(&rfcomm_ioctl_mutex);
475 ret = __rfcomm_create_dev(sk, arg);
476 mutex_unlock(&rfcomm_ioctl_mutex);
477
478 return ret;
479}
480
481static int rfcomm_release_dev(void __user *arg)
482{
483 int ret;
484
485 mutex_lock(&rfcomm_ioctl_mutex);
486 ret = __rfcomm_release_dev(arg);
487 mutex_unlock(&rfcomm_ioctl_mutex);
488
489 return ret;
490}
491
469static int rfcomm_get_dev_list(void __user *arg) 492static int rfcomm_get_dev_list(void __user *arg)
470{ 493{
471 struct rfcomm_dev *dev; 494 struct rfcomm_dev *dev;