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, ...@@ -1286,36 +1286,29 @@ static int __sctp_connect(struct sock *sk, struct sockaddr *kaddrs,
* it. * it.
* *
* sk The sk of the socket * 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 * addrssize Size of the addrs buffer
* *
* Returns >=0 if ok, <0 errno code on error. * Returns >=0 if ok, <0 errno code on error.
*/ */
static int __sctp_setsockopt_connectx(struct sock *sk, static int __sctp_setsockopt_connectx(struct sock *sk, struct sockaddr *kaddrs,
struct sockaddr __user *addrs, int addrs_size, sctp_assoc_t *assoc_id)
int addrs_size,
sctp_assoc_t *assoc_id)
{ {
struct sockaddr *kaddrs;
int err = 0, flags = 0; int err = 0, flags = 0;
pr_debug("%s: sk:%p addrs:%p addrs_size:%d\n", 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 */ /* make sure the 1st addr's sa_family is accessible later */
if (unlikely(addrs_size < sizeof(sa_family_t))) if (unlikely(addrs_size < sizeof(sa_family_t)))
return -EINVAL; return -EINVAL;
kaddrs = memdup_user(addrs, addrs_size);
if (IS_ERR(kaddrs))
return PTR_ERR(kaddrs);
/* Allow security module to validate connectx addresses. */ /* Allow security module to validate connectx addresses. */
err = security_sctp_bind_connect(sk, SCTP_SOCKOPT_CONNECTX, err = security_sctp_bind_connect(sk, SCTP_SOCKOPT_CONNECTX,
(struct sockaddr *)kaddrs, (struct sockaddr *)kaddrs,
addrs_size); addrs_size);
if (err) if (err)
goto out_free; return err;
/* in-kernel sockets don't generally have a file allocated to them /* in-kernel sockets don't generally have a file allocated to them
* if all they do is call sock_create_kern(). * if all they do is call sock_create_kern().
...@@ -1323,12 +1316,7 @@ static int __sctp_setsockopt_connectx(struct sock *sk, ...@@ -1323,12 +1316,7 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
if (sk->sk_socket->file) if (sk->sk_socket->file)
flags = sk->sk_socket->file->f_flags; flags = sk->sk_socket->file->f_flags;
err = __sctp_connect(sk, kaddrs, addrs_size, flags, assoc_id); return __sctp_connect(sk, kaddrs, addrs_size, flags, assoc_id);
out_free:
kfree(kaddrs);
return err;
} }
/* /*
...@@ -1336,10 +1324,10 @@ static int __sctp_setsockopt_connectx(struct sock *sk, ...@@ -1336,10 +1324,10 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
* to the option that doesn't provide association id. * to the option that doesn't provide association id.
*/ */
static int sctp_setsockopt_connectx_old(struct sock *sk, static int sctp_setsockopt_connectx_old(struct sock *sk,
struct sockaddr __user *addrs, struct sockaddr *kaddrs,
int addrs_size) 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, ...@@ -1349,13 +1337,13 @@ static int sctp_setsockopt_connectx_old(struct sock *sk,
* always positive. * always positive.
*/ */
static int sctp_setsockopt_connectx(struct sock *sk, static int sctp_setsockopt_connectx(struct sock *sk,
struct sockaddr __user *addrs, struct sockaddr *kaddrs,
int addrs_size) int addrs_size)
{ {
sctp_assoc_t assoc_id = 0; sctp_assoc_t assoc_id = 0;
int err = 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) if (err)
return err; return err;
...@@ -1385,6 +1373,7 @@ static int sctp_getsockopt_connectx3(struct sock *sk, int len, ...@@ -1385,6 +1373,7 @@ static int sctp_getsockopt_connectx3(struct sock *sk, int len,
{ {
struct sctp_getaddrs_old param; struct sctp_getaddrs_old param;
sctp_assoc_t assoc_id = 0; sctp_assoc_t assoc_id = 0;
struct sockaddr *kaddrs;
int err = 0; int err = 0;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
...@@ -1408,9 +1397,12 @@ static int sctp_getsockopt_connectx3(struct sock *sk, int len, ...@@ -1408,9 +1397,12 @@ static int sctp_getsockopt_connectx3(struct sock *sk, int len,
return -EFAULT; return -EFAULT;
} }
err = __sctp_setsockopt_connectx(sk, (struct sockaddr __user *) kaddrs = memdup_user(param.addrs, param.addr_num);
param.addrs, param.addr_num, if (IS_ERR(kaddrs))
&assoc_id); return PTR_ERR(kaddrs);
err = __sctp_setsockopt_connectx(sk, kaddrs, param.addr_num, &assoc_id);
kfree(kaddrs);
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)))
return -EFAULT; return -EFAULT;
...@@ -4700,16 +4692,12 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, ...@@ -4700,16 +4692,12 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
case SCTP_SOCKOPT_CONNECTX_OLD: case SCTP_SOCKOPT_CONNECTX_OLD:
/* 'optlen' is the size of the addresses buffer. */ /* 'optlen' is the size of the addresses buffer. */
retval = sctp_setsockopt_connectx_old(sk, retval = sctp_setsockopt_connectx_old(sk, kopt, optlen);
(struct sockaddr __user *)optval,
optlen);
break; break;
case SCTP_SOCKOPT_CONNECTX: case SCTP_SOCKOPT_CONNECTX:
/* 'optlen' is the size of the addresses buffer. */ /* 'optlen' is the size of the addresses buffer. */
retval = sctp_setsockopt_connectx(sk, retval = sctp_setsockopt_connectx(sk, kopt, optlen);
(struct sockaddr __user *)optval,
optlen);
break; break;
case SCTP_DISABLE_FRAGMENTS: 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