Commit ce5b2f89 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David S. Miller

sctp: pass a kernel pointer to __sctp_setsockopt_connectx

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8c7517f5
......@@ -1286,36 +1286,29 @@ static int __sctp_connect(struct sock *sk, struct sockaddr *kaddrs,
* it.
*
* sk The sk of the socket
* addrs The pointer to the addresses in user land
* addrs The pointer to the addresses
* addrssize Size of the addrs buffer
*
* Returns >=0 if ok, <0 errno code on error.
*/
static int __sctp_setsockopt_connectx(struct sock *sk,
struct sockaddr __user *addrs,
int addrs_size,
sctp_assoc_t *assoc_id)
static int __sctp_setsockopt_connectx(struct sock *sk, struct sockaddr *kaddrs,
int addrs_size, sctp_assoc_t *assoc_id)
{
struct sockaddr *kaddrs;
int err = 0, flags = 0;
pr_debug("%s: sk:%p addrs:%p addrs_size:%d\n",
__func__, sk, addrs, addrs_size);
__func__, sk, kaddrs, addrs_size);
/* make sure the 1st addr's sa_family is accessible later */
if (unlikely(addrs_size < sizeof(sa_family_t)))
return -EINVAL;
kaddrs = memdup_user(addrs, addrs_size);
if (IS_ERR(kaddrs))
return PTR_ERR(kaddrs);
/* Allow security module to validate connectx addresses. */
err = security_sctp_bind_connect(sk, SCTP_SOCKOPT_CONNECTX,
(struct sockaddr *)kaddrs,
addrs_size);
if (err)
goto out_free;
return err;
/* in-kernel sockets don't generally have a file allocated to them
* if all they do is call sock_create_kern().
......@@ -1323,12 +1316,7 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
if (sk->sk_socket->file)
flags = sk->sk_socket->file->f_flags;
err = __sctp_connect(sk, kaddrs, addrs_size, flags, assoc_id);
out_free:
kfree(kaddrs);
return err;
return __sctp_connect(sk, kaddrs, addrs_size, flags, assoc_id);
}
/*
......@@ -1336,10 +1324,10 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
* to the option that doesn't provide association id.
*/
static int sctp_setsockopt_connectx_old(struct sock *sk,
struct sockaddr __user *addrs,
struct sockaddr *kaddrs,
int addrs_size)
{
return __sctp_setsockopt_connectx(sk, addrs, addrs_size, NULL);
return __sctp_setsockopt_connectx(sk, kaddrs, addrs_size, NULL);
}
/*
......@@ -1349,13 +1337,13 @@ static int sctp_setsockopt_connectx_old(struct sock *sk,
* always positive.
*/
static int sctp_setsockopt_connectx(struct sock *sk,
struct sockaddr __user *addrs,
struct sockaddr *kaddrs,
int addrs_size)
{
sctp_assoc_t assoc_id = 0;
int err = 0;
err = __sctp_setsockopt_connectx(sk, addrs, addrs_size, &assoc_id);
err = __sctp_setsockopt_connectx(sk, kaddrs, addrs_size, &assoc_id);
if (err)
return err;
......@@ -1385,6 +1373,7 @@ static int sctp_getsockopt_connectx3(struct sock *sk, int len,
{
struct sctp_getaddrs_old param;
sctp_assoc_t assoc_id = 0;
struct sockaddr *kaddrs;
int err = 0;
#ifdef CONFIG_COMPAT
......@@ -1408,9 +1397,12 @@ static int sctp_getsockopt_connectx3(struct sock *sk, int len,
return -EFAULT;
}
err = __sctp_setsockopt_connectx(sk, (struct sockaddr __user *)
param.addrs, param.addr_num,
&assoc_id);
kaddrs = memdup_user(param.addrs, param.addr_num);
if (IS_ERR(kaddrs))
return PTR_ERR(kaddrs);
err = __sctp_setsockopt_connectx(sk, kaddrs, param.addr_num, &assoc_id);
kfree(kaddrs);
if (err == 0 || err == -EINPROGRESS) {
if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))
return -EFAULT;
......@@ -4700,16 +4692,12 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
case SCTP_SOCKOPT_CONNECTX_OLD:
/* 'optlen' is the size of the addresses buffer. */
retval = sctp_setsockopt_connectx_old(sk,
(struct sockaddr __user *)optval,
optlen);
retval = sctp_setsockopt_connectx_old(sk, kopt, optlen);
break;
case SCTP_SOCKOPT_CONNECTX:
/* 'optlen' is the size of the addresses buffer. */
retval = sctp_setsockopt_connectx(sk,
(struct sockaddr __user *)optval,
optlen);
retval = sctp_setsockopt_connectx(sk, kopt, optlen);
break;
case SCTP_DISABLE_FRAGMENTS:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment