diff options
author | Jakub Kicinski <kuba@kernel.org> | 2022-08-27 02:13:25 +0200 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-08-27 02:13:25 +0200 |
commit | 037c97b2886e1b0bcdd14f96bb595f843faa07da (patch) | |
tree | 0944e139c225a6302905af407dba4ab32b0758e8 /net/bluetooth/iso.c | |
parent | Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf (diff) | |
parent | Bluetooth: hci_sync: hold hdev->lock when cleanup hci_conn (diff) | |
download | linux-037c97b2886e1b0bcdd14f96bb595f843faa07da.tar.xz linux-037c97b2886e1b0bcdd14f96bb595f843faa07da.zip |
Merge tag 'for-net-2022-08-25' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says:
====================
bluetooth pull request for net:
- Fix handling of duplicate connection handle
- Fix handling of HCI vendor opcode
- Fix suspend performance regression
- Fix build errors
- Fix not handling shutdown condition on ISO sockets
- Fix double free issue
* tag 'for-net-2022-08-25' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
Bluetooth: hci_sync: hold hdev->lock when cleanup hci_conn
Bluetooth: move from strlcpy with unused retval to strscpy
Bluetooth: hci_event: Fix checking conn for le_conn_complete_evt
Bluetooth: ISO: Fix not handling shutdown condition
Bluetooth: hci_sync: fix double mgmt_pending_free() in remove_adv_monitor()
Bluetooth: MGMT: Fix Get Device Flags
Bluetooth: L2CAP: Fix build errors in some archs
Bluetooth: hci_sync: Fix suspend performance regression
Bluetooth: hci_event: Fix vendor (unknown) opcode status handling
====================
Link: https://lore.kernel.org/r/20220825234559.1837409-1-luiz.dentz@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/bluetooth/iso.c')
-rw-r--r-- | net/bluetooth/iso.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index ced8ad4fed4f..613039ba5dbf 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -1309,7 +1309,7 @@ static int iso_sock_shutdown(struct socket *sock, int how) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %p, sk %p, how %d", sock, sk, how); if (!sk) return 0; @@ -1317,17 +1317,32 @@ static int iso_sock_shutdown(struct socket *sock, int how) sock_hold(sk); lock_sock(sk); - if (!sk->sk_shutdown) { - sk->sk_shutdown = SHUTDOWN_MASK; - iso_sock_clear_timer(sk); - __iso_sock_close(sk); - - if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && - !(current->flags & PF_EXITING)) - err = bt_sock_wait_state(sk, BT_CLOSED, - sk->sk_lingertime); + switch (how) { + case SHUT_RD: + if (sk->sk_shutdown & RCV_SHUTDOWN) + goto unlock; + sk->sk_shutdown |= RCV_SHUTDOWN; + break; + case SHUT_WR: + if (sk->sk_shutdown & SEND_SHUTDOWN) + goto unlock; + sk->sk_shutdown |= SEND_SHUTDOWN; + break; + case SHUT_RDWR: + if (sk->sk_shutdown & SHUTDOWN_MASK) + goto unlock; + sk->sk_shutdown |= SHUTDOWN_MASK; + break; } + iso_sock_clear_timer(sk); + __iso_sock_close(sk); + + if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && + !(current->flags & PF_EXITING)) + err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); + +unlock: release_sock(sk); sock_put(sk); |