forked from mirrors/linux
		
	net/handshake: Unpin sock->file if a handshake is cancelled
If user space never calls DONE, sock->file's reference count remains
elevated. Enable sock->file to be freed eventually in this case.
Reported-by: Jakub Kacinski <kuba@kernel.org>
Fixes: 3b3009ea8a ("net/handshake: Create a NETLINK service for handling handshake requests")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									fc490880e3
								
							
						
					
					
						commit
						1ce77c998f
					
				
					 2 changed files with 5 additions and 0 deletions
				
			
		|  | @ -31,6 +31,7 @@ struct handshake_req { | ||||||
| 	struct list_head		hr_list; | 	struct list_head		hr_list; | ||||||
| 	struct rhash_head		hr_rhash; | 	struct rhash_head		hr_rhash; | ||||||
| 	unsigned long			hr_flags; | 	unsigned long			hr_flags; | ||||||
|  | 	struct file			*hr_file; | ||||||
| 	const struct handshake_proto	*hr_proto; | 	const struct handshake_proto	*hr_proto; | ||||||
| 	struct sock			*hr_sk; | 	struct sock			*hr_sk; | ||||||
| 	void				(*hr_odestruct)(struct sock *sk); | 	void				(*hr_odestruct)(struct sock *sk); | ||||||
|  |  | ||||||
|  | @ -239,6 +239,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req, | ||||||
| 	} | 	} | ||||||
| 	req->hr_odestruct = req->hr_sk->sk_destruct; | 	req->hr_odestruct = req->hr_sk->sk_destruct; | ||||||
| 	req->hr_sk->sk_destruct = handshake_sk_destruct; | 	req->hr_sk->sk_destruct = handshake_sk_destruct; | ||||||
|  | 	req->hr_file = sock->file; | ||||||
| 
 | 
 | ||||||
| 	ret = -EOPNOTSUPP; | 	ret = -EOPNOTSUPP; | ||||||
| 	net = sock_net(req->hr_sk); | 	net = sock_net(req->hr_sk); | ||||||
|  | @ -334,6 +335,9 @@ bool handshake_req_cancel(struct sock *sk) | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/* Request accepted and waiting for DONE */ | ||||||
|  | 	fput(req->hr_file); | ||||||
|  | 
 | ||||||
| out_true: | out_true: | ||||||
| 	trace_handshake_cancel(net, req, sk); | 	trace_handshake_cancel(net, req, sk); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Chuck Lever
						Chuck Lever