Commit b5e1acea authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz
Browse files

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: ccf74f23 ("Bluetooth: Add BTPROTO_ISO socket type")
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 029bde79
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -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;
	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);
	}
		err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);

unlock:
	release_sock(sk);
	sock_put(sk);