Bluetooth: ISO: Fix not handling shutdown condition

In order to properly handle shutdown syscall the code shall not assume
that the how argument is always SHUT_RDWR resulting in SHUTDOWN_MASK as
that would result in poll to immediately report EPOLLHUP instead of
properly waiting for disconnect_cfm (Disconnect Complete) which is
rather important for the likes of BAP as the CIG may need to be
reprogrammed.

Fixes: ccf74f2390 ("Bluetooth: Add BTPROTO_ISO socket type")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2022-08-18 14:31:42 -07:00
parent 3cfbc6ac22
commit c572909376

View File

@ -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);