mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Bluetooth: fix repeated calls to sco_sock_kill
In commit4e1a720d03("Bluetooth: avoid killing an already killed socket"), a check was added to sco_sock_kill to skip killing a socket if the SOCK_DEAD flag was set. This was done after a trace for a use-after-free bug showed that the same sock pointer was being killed twice. Unfortunately, this check prevents sco_sock_kill from running on any socket. sco_sock_kill kills a socket only if it's zapped and orphaned, however sock_orphan announces that the socket is dead before detaching it. i.e., orphaned sockets have the SOCK_DEAD flag set. To fix this, we remove the check for SOCK_DEAD, and avoid repeated calls to sco_sock_kill by removing incorrect calls in: 1. sco_sock_timeout. The socket should not be killed on timeout as further processing is expected to be done. For example, sco_sock_connect sets the timer then waits for the socket to be connected or for an error to be returned. 2. sco_conn_del. This function should clean up resources for the connection, but the socket itself should be cleaned up in sco_sock_release. 3. sco_sock_close. Calls to sco_sock_close in sco_sock_cleanup_listen and sco_sock_release are followed by sco_sock_kill. Hence the duplicated call should be removed. Fixes:4e1a720d03("Bluetooth: avoid killing an already killed socket") Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
		
							parent
							
								
									b7ce436a5d
								
							
						
					
					
						commit
						e1dee2c1de
					
				
					 1 changed files with 1 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -97,8 +97,6 @@ static void sco_sock_timeout(struct work_struct *work)
 | 
			
		|||
	sk->sk_err = ETIMEDOUT;
 | 
			
		||||
	sk->sk_state_change(sk);
 | 
			
		||||
	release_sock(sk);
 | 
			
		||||
 | 
			
		||||
	sco_sock_kill(sk);
 | 
			
		||||
	sock_put(sk);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +195,6 @@ static void sco_conn_del(struct hci_conn *hcon, int err)
 | 
			
		|||
		sco_sock_clear_timer(sk);
 | 
			
		||||
		sco_chan_del(sk, err);
 | 
			
		||||
		release_sock(sk);
 | 
			
		||||
		sco_sock_kill(sk);
 | 
			
		||||
		sock_put(sk);
 | 
			
		||||
 | 
			
		||||
		/* Ensure no more work items will run before freeing conn. */
 | 
			
		||||
| 
						 | 
				
			
			@ -404,8 +401,7 @@ static void sco_sock_cleanup_listen(struct sock *parent)
 | 
			
		|||
 */
 | 
			
		||||
static void sco_sock_kill(struct sock *sk)
 | 
			
		||||
{
 | 
			
		||||
	if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket ||
 | 
			
		||||
	    sock_flag(sk, SOCK_DEAD))
 | 
			
		||||
	if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	BT_DBG("sk %p state %d", sk, sk->sk_state);
 | 
			
		||||
| 
						 | 
				
			
			@ -457,7 +453,6 @@ static void sco_sock_close(struct sock *sk)
 | 
			
		|||
	sco_sock_clear_timer(sk);
 | 
			
		||||
	__sco_sock_close(sk);
 | 
			
		||||
	release_sock(sk);
 | 
			
		||||
	sco_sock_kill(sk);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sco_skb_put_cmsg(struct sk_buff *skb, struct msghdr *msg,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue