--- x/net/bluetooth/rfcomm/core.c +++ y/net/bluetooth/rfcomm/core.c @@ -490,8 +490,8 @@ static int __rfcomm_dlc_close(struct rfc rfcomm_dlc_lock(d); d->state = BT_CLOSED; - d->state_change(d, err); rfcomm_dlc_unlock(d); + d->state_change(d, err); skb_queue_purge(&d->tx_queue); rfcomm_dlc_unlink(d); --- x/net/bluetooth/rfcomm/sock.c +++ y/net/bluetooth/rfcomm/sock.c @@ -876,9 +876,7 @@ static int rfcomm_sock_ioctl(struct sock if (err == -ENOIOCTLCMD) { #ifdef CONFIG_BT_RFCOMM_TTY - lock_sock(sk); err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg); - release_sock(sk); #else err = -EOPNOTSUPP; #endif --- x/net/bluetooth/rfcomm/tty.c +++ y/net/bluetooth/rfcomm/tty.c @@ -403,9 +403,12 @@ static int __rfcomm_create_dev(struct so return -EPERM; if (req.flags & (1 << RFCOMM_REUSE_DLC)) { + lock_sock(sk); /* Socket must be connected */ - if (sk->sk_state != BT_CONNECTED) + if (sk->sk_state != BT_CONNECTED) { + release_sock(sk); return -EBADFD; + } dlc = rfcomm_pi(sk)->dlc; rfcomm_dlc_hold(dlc); @@ -422,13 +425,13 @@ static int __rfcomm_create_dev(struct so } id = rfcomm_dev_add(&req, dlc); - if (id < 0) - return id; if (req.flags & (1 << RFCOMM_REUSE_DLC)) { /* DLC is now used by device. * Socket must be disconnected */ - sk->sk_state = BT_CLOSED; + if (!(id < 0)) + sk->sk_state = BT_CLOSED; + release_sock(sk); } return id;