Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9c67811 authored by Vlad Yasevich's avatar Vlad Yasevich Committed by David S. Miller
Browse files

sctp: Fix regression introduced by new sctp_connectx api



A new (unrealeased to the user) sctp_connectx api

c6ba68a2
    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: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 409b95af
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -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
 * both for the returned association id and the addresses.
 * New (hopefully final) interface for the API.
 * 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,
					char __user *optval,
					int __user *optlen)
{
	struct sctp_getaddrs_old param;
	sctp_assoc_t assoc_id = 0;
	int err = 0;

	if (len < sizeof(assoc_id))
	if (len < sizeof(param))
		return -EINVAL;

	if (copy_from_user(&param, optval, sizeof(param)))
		return -EFAULT;

	err = __sctp_setsockopt_connectx(sk,
			(struct sockaddr __user *)(optval + sizeof(assoc_id)),
			len - sizeof(assoc_id), &assoc_id);
			(struct sockaddr __user *)param.addrs,
			param.addr_num, &assoc_id);

	if (err == 0 || err == -EINPROGRESS) {
		if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))