sctp: Fix regression introduced by new sctp_connectx api
A new (unrealeased to the user) sctp_connectx api
c6ba68a266
    sctp: support non-blocking version of the new sctp_connectx() API
introduced a regression cought by the user regression test
suite.  In particular, the API requires the user library to
re-allocate the buffer and could potentially trigger a SIGFAULT.
This change corrects that regression by passing the original
address buffer to the kernel unmodified, but still allows for
a returned association id.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
	
	
This commit is contained in:
		
					parent
					
						
							
								409b95aff3
							
						
					
				
			
			
				commit
				
					
						f9c67811eb
					
				
			
		
					 1 changed files with 13 additions and 5 deletions
				
			
		| 
						 | 
					@ -1276,22 +1276,30 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * New (hopefully final) interface for the API.  The option buffer is used
 | 
					 * New (hopefully final) interface for the API.
 | 
				
			||||||
 * both for the returned association id and the addresses.
 | 
					 * We use the sctp_getaddrs_old structure so that use-space library
 | 
				
			||||||
 | 
					 * can avoid any unnecessary allocations.   The only defferent part
 | 
				
			||||||
 | 
					 * is that we store the actual length of the address buffer into the
 | 
				
			||||||
 | 
					 * addrs_num structure member.  That way we can re-use the existing
 | 
				
			||||||
 | 
					 * code.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
 | 
					SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
 | 
				
			||||||
					char __user *optval,
 | 
										char __user *optval,
 | 
				
			||||||
					int __user *optlen)
 | 
										int __user *optlen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct sctp_getaddrs_old param;
 | 
				
			||||||
	sctp_assoc_t assoc_id = 0;
 | 
						sctp_assoc_t assoc_id = 0;
 | 
				
			||||||
	int err = 0;
 | 
						int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (len < sizeof(assoc_id))
 | 
						if (len < sizeof(param))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (copy_from_user(¶m, optval, sizeof(param)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = __sctp_setsockopt_connectx(sk,
 | 
						err = __sctp_setsockopt_connectx(sk,
 | 
				
			||||||
			(struct sockaddr __user *)(optval + sizeof(assoc_id)),
 | 
								(struct sockaddr __user *)param.addrs,
 | 
				
			||||||
			len - sizeof(assoc_id), &assoc_id);
 | 
								param.addr_num, &assoc_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (err == 0 || err == -EINPROGRESS) {
 | 
						if (err == 0 || err == -EINPROGRESS) {
 | 
				
			||||||
		if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))
 | 
							if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue