netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* do a single memdup_user in sctp_setsockopt v2
@ 2020-07-19  7:21 Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 01/51] sctp: copy the optval from user space in sctp_setsockopt Christoph Hellwig
                   ` (51 more replies)
  0 siblings, 52 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Hi all,

here is a resend of my series to lift the copy_from_user out of the
individual sctp sockopt handlers into the main sctp_setsockopt
routine.


Changes since v1:
 - fixes a few sizeof calls.
 - use memzero_explicit in sctp_setsockopt_auth_key instead of special
   casing it for a kzfree in the caller
 - remove some minor cleanups from sctp_setsockopt_autoclose to keep
   it closer to the existing version
 - add another little only vaguely related cleanup patch

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH 01/51] sctp: copy the optval from user space in sctp_setsockopt
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 02/51] sctp: pass a kernel pointer to sctp_setsockopt_bindx Christoph Hellwig
                   ` (50 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Prepare for for moving the copy_from_user from the individual sockopts
to the main setsockopt helper.  As of this commit the kopt variable
is not used yet, but the following commits will start using it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d57e1a002ffc8f..af1ebc8313d303 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4677,6 +4677,7 @@ static int sctp_setsockopt_pf_expose(struct sock *sk,
 static int sctp_setsockopt(struct sock *sk, int level, int optname,
 			   char __user *optval, unsigned int optlen)
 {
+	void *kopt = NULL;
 	int retval = 0;
 
 	pr_debug("%s: sk:%p, optname:%d\n", __func__, sk, optname);
@@ -4693,6 +4694,12 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		goto out_nounlock;
 	}
 
+	if (optlen > 0) {
+		kopt = memdup_user(optval, optlen);
+		if (IS_ERR(kopt))
+			return PTR_ERR(kopt);
+	}
+
 	lock_sock(sk);
 
 	switch (optname) {
@@ -4878,6 +4885,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 	}
 
 	release_sock(sk);
+	kfree(kopt);
 
 out_nounlock:
 	return retval;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 02/51] sctp: pass a kernel pointer to sctp_setsockopt_bindx
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 01/51] sctp: copy the optval from user space in sctp_setsockopt Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 03/51] sctp: pass a kernel pointer to __sctp_setsockopt_connectx Christoph Hellwig
                   ` (49 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Rename sctp_setsockopt_bindx_kernel back to sctp_setsockopt_bindx,
and use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer in the old sctp_setsockopt_bindx.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 33 ++++++++-------------------------
 1 file changed, 8 insertions(+), 25 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index af1ebc8313d303..85ba5155b177b1 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -979,9 +979,8 @@ int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
  *
  * Returns 0 if ok, <0 errno code on error.
  */
-static int sctp_setsockopt_bindx_kernel(struct sock *sk,
-					struct sockaddr *addrs, int addrs_size,
-					int op)
+static int sctp_setsockopt_bindx(struct sock *sk, struct sockaddr *addrs,
+				 int addrs_size, int op)
 {
 	int err;
 	int addrcnt = 0;
@@ -991,7 +990,7 @@ static int sctp_setsockopt_bindx_kernel(struct sock *sk,
 	struct sctp_af *af;
 
 	pr_debug("%s: sk:%p addrs:%p addrs_size:%d opt:%d\n",
-		 __func__, sk, addrs, addrs_size, op);
+		 __func__, sk, addr_buf, addrs_size, op);
 
 	if (unlikely(addrs_size <= 0))
 		return -EINVAL;
@@ -1037,29 +1036,13 @@ static int sctp_setsockopt_bindx_kernel(struct sock *sk,
 	}
 }
 
-static int sctp_setsockopt_bindx(struct sock *sk,
-				 struct sockaddr __user *addrs,
-				 int addrs_size, int op)
-{
-	struct sockaddr *kaddrs;
-	int err;
-
-	kaddrs = memdup_user(addrs, addrs_size);
-	if (IS_ERR(kaddrs))
-		return PTR_ERR(kaddrs);
-	err = sctp_setsockopt_bindx_kernel(sk, kaddrs, addrs_size, op);
-	kfree(kaddrs);
-	return err;
-}
-
 static int sctp_bind_add(struct sock *sk, struct sockaddr *addrs,
 		int addrlen)
 {
 	int err;
 
 	lock_sock(sk);
-	err = sctp_setsockopt_bindx_kernel(sk, addrs, addrlen,
-					   SCTP_BINDX_ADD_ADDR);
+	err = sctp_setsockopt_bindx(sk, addrs, addrlen, SCTP_BINDX_ADD_ADDR);
 	release_sock(sk);
 	return err;
 }
@@ -4705,14 +4688,14 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 	switch (optname) {
 	case SCTP_SOCKOPT_BINDX_ADD:
 		/* 'optlen' is the size of the addresses buffer. */
-		retval = sctp_setsockopt_bindx(sk, (struct sockaddr __user *)optval,
-					       optlen, SCTP_BINDX_ADD_ADDR);
+		retval = sctp_setsockopt_bindx(sk, kopt, optlen,
+					       SCTP_BINDX_ADD_ADDR);
 		break;
 
 	case SCTP_SOCKOPT_BINDX_REM:
 		/* 'optlen' is the size of the addresses buffer. */
-		retval = sctp_setsockopt_bindx(sk, (struct sockaddr __user *)optval,
-					       optlen, SCTP_BINDX_REM_ADDR);
+		retval = sctp_setsockopt_bindx(sk, kopt, optlen,
+					       SCTP_BINDX_REM_ADDR);
 		break;
 
 	case SCTP_SOCKOPT_CONNECTX_OLD:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 03/51] sctp: pass a kernel pointer to __sctp_setsockopt_connectx
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 01/51] sctp: copy the optval from user space in sctp_setsockopt Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 02/51] sctp: pass a kernel pointer to sctp_setsockopt_bindx Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 04/51] sctp: pass a kernel pointer to sctp_setsockopt_disable_fragments Christoph Hellwig
                   ` (48 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 50 ++++++++++++++++++-----------------------------
 1 file changed, 19 insertions(+), 31 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 85ba5155b177b1..44cf2848146a91 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -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:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 04/51] sctp: pass a kernel pointer to sctp_setsockopt_disable_fragments
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 03/51] sctp: pass a kernel pointer to __sctp_setsockopt_connectx Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 05/51] sctp: pass a kernel pointer to sctp_setsockopt_events Christoph Hellwig
                   ` (47 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 44cf2848146a91..b259ea94aeddef 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2184,20 +2184,12 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
  * exceeds the current PMTU size, the message will NOT be sent and
  * instead a error will be indicated to the user.
  */
-static int sctp_setsockopt_disable_fragments(struct sock *sk,
-					     char __user *optval,
+static int sctp_setsockopt_disable_fragments(struct sock *sk, int *val,
 					     unsigned int optlen)
 {
-	int val;
-
 	if (optlen < sizeof(int))
 		return -EINVAL;
-
-	if (get_user(val, (int __user *)optval))
-		return -EFAULT;
-
-	sctp_sk(sk)->disable_fragments = (val == 0) ? 0 : 1;
-
+	sctp_sk(sk)->disable_fragments = (*val == 0) ? 0 : 1;
 	return 0;
 }
 
@@ -4701,7 +4693,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case SCTP_DISABLE_FRAGMENTS:
-		retval = sctp_setsockopt_disable_fragments(sk, optval, optlen);
+		retval = sctp_setsockopt_disable_fragments(sk, kopt, optlen);
 		break;
 
 	case SCTP_EVENTS:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 05/51] sctp: pass a kernel pointer to sctp_setsockopt_events
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 04/51] sctp: pass a kernel pointer to sctp_setsockopt_disable_fragments Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 06/51] sctp: pass a kernel pointer to sctp_setsockopt_autoclose Christoph Hellwig
                   ` (46 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b259ea94aeddef..bc37174bd71af0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2193,11 +2193,9 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, int *val,
 	return 0;
 }
 
-static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_events(struct sock *sk, __u8 *sn_type,
 				  unsigned int optlen)
 {
-	struct sctp_event_subscribe subscribe;
-	__u8 *sn_type = (__u8 *)&subscribe;
 	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_association *asoc;
 	int i;
@@ -2205,9 +2203,6 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
 	if (optlen > sizeof(struct sctp_event_subscribe))
 		return -EINVAL;
 
-	if (copy_from_user(&subscribe, optval, optlen))
-		return -EFAULT;
-
 	for (i = 0; i < optlen; i++)
 		sctp_ulpevent_type_set(&sp->subscribe, SCTP_SN_TYPE_BASE + i,
 				       sn_type[i]);
@@ -4697,7 +4692,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case SCTP_EVENTS:
-		retval = sctp_setsockopt_events(sk, optval, optlen);
+		retval = sctp_setsockopt_events(sk, kopt, optlen);
 		break;
 
 	case SCTP_AUTOCLOSE:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 06/51] sctp: pass a kernel pointer to sctp_setsockopt_autoclose
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 05/51] sctp: pass a kernel pointer to sctp_setsockopt_events Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 07/51] sctp: pass a kernel pointer to sctp_setsockopt_peer_addr_params Christoph Hellwig
                   ` (45 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index bc37174bd71af0..d7ed8c6ea3754f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2242,7 +2242,7 @@ static int sctp_setsockopt_events(struct sock *sk, __u8 *sn_type,
  * integer defining the number of seconds of idle time before an
  * association is closed.
  */
-static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_autoclose(struct sock *sk, u32 *optval,
 				     unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
@@ -2253,9 +2253,8 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
 		return -EOPNOTSUPP;
 	if (optlen != sizeof(int))
 		return -EINVAL;
-	if (copy_from_user(&sp->autoclose, optval, optlen))
-		return -EFAULT;
 
+	sp->autoclose = *optval;
 	if (sp->autoclose > net->sctp.max_autoclose)
 		sp->autoclose = net->sctp.max_autoclose;
 
@@ -4696,7 +4695,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case SCTP_AUTOCLOSE:
-		retval = sctp_setsockopt_autoclose(sk, optval, optlen);
+		retval = sctp_setsockopt_autoclose(sk, kopt, optlen);
 		break;
 
 	case SCTP_PEER_ADDR_PARAMS:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 07/51] sctp: pass a kernel pointer to sctp_setsockopt_peer_addr_params
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 06/51] sctp: pass a kernel pointer to sctp_setsockopt_autoclose Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 08/51] sctp: pass a kernel pointer to sctp_setsockopt_delayed_ack Christoph Hellwig
                   ` (44 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 44 +++++++++++++++++++-------------------------
 1 file changed, 19 insertions(+), 25 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d7ed8c6ea3754f..19308c327b6d2f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2589,48 +2589,42 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
 }
 
 static int sctp_setsockopt_peer_addr_params(struct sock *sk,
-					    char __user *optval,
+					    struct sctp_paddrparams *params,
 					    unsigned int optlen)
 {
-	struct sctp_paddrparams  params;
 	struct sctp_transport   *trans = NULL;
 	struct sctp_association *asoc = NULL;
 	struct sctp_sock        *sp = sctp_sk(sk);
 	int error;
 	int hb_change, pmtud_change, sackdelay_change;
 
-	if (optlen == sizeof(params)) {
-		if (copy_from_user(&params, optval, optlen))
-			return -EFAULT;
-	} else if (optlen == ALIGN(offsetof(struct sctp_paddrparams,
+	if (optlen == ALIGN(offsetof(struct sctp_paddrparams,
 					    spp_ipv6_flowlabel), 4)) {
-		if (copy_from_user(&params, optval, optlen))
-			return -EFAULT;
-		if (params.spp_flags & (SPP_DSCP | SPP_IPV6_FLOWLABEL))
+		if (params->spp_flags & (SPP_DSCP | SPP_IPV6_FLOWLABEL))
 			return -EINVAL;
-	} else {
+	} else if (optlen != sizeof(*params)) {
 		return -EINVAL;
 	}
 
 	/* Validate flags and value parameters. */
-	hb_change        = params.spp_flags & SPP_HB;
-	pmtud_change     = params.spp_flags & SPP_PMTUD;
-	sackdelay_change = params.spp_flags & SPP_SACKDELAY;
+	hb_change        = params->spp_flags & SPP_HB;
+	pmtud_change     = params->spp_flags & SPP_PMTUD;
+	sackdelay_change = params->spp_flags & SPP_SACKDELAY;
 
 	if (hb_change        == SPP_HB ||
 	    pmtud_change     == SPP_PMTUD ||
 	    sackdelay_change == SPP_SACKDELAY ||
-	    params.spp_sackdelay > 500 ||
-	    (params.spp_pathmtu &&
-	     params.spp_pathmtu < SCTP_DEFAULT_MINSEGMENT))
+	    params->spp_sackdelay > 500 ||
+	    (params->spp_pathmtu &&
+	     params->spp_pathmtu < SCTP_DEFAULT_MINSEGMENT))
 		return -EINVAL;
 
 	/* If an address other than INADDR_ANY is specified, and
 	 * no transport is found, then the request is invalid.
 	 */
-	if (!sctp_is_any(sk, (union sctp_addr *)&params.spp_address)) {
-		trans = sctp_addr_id2transport(sk, &params.spp_address,
-					       params.spp_assoc_id);
+	if (!sctp_is_any(sk, (union sctp_addr *)&params->spp_address)) {
+		trans = sctp_addr_id2transport(sk, &params->spp_address,
+					       params->spp_assoc_id);
 		if (!trans)
 			return -EINVAL;
 	}
@@ -2639,19 +2633,19 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
 	 * socket is a one to many style socket, and an association
 	 * was not found, then the id was invalid.
 	 */
-	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
-	if (!asoc && params.spp_assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->spp_assoc_id);
+	if (!asoc && params->spp_assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	/* Heartbeat demand can only be sent on a transport or
 	 * association, but not a socket.
 	 */
-	if (params.spp_flags & SPP_HB_DEMAND && !trans && !asoc)
+	if (params->spp_flags & SPP_HB_DEMAND && !trans && !asoc)
 		return -EINVAL;
 
 	/* Process parameters. */
-	error = sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+	error = sctp_apply_peer_addr_params(params, trans, asoc, sp,
 					    hb_change, pmtud_change,
 					    sackdelay_change);
 
@@ -2664,7 +2658,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
 	if (!trans && asoc) {
 		list_for_each_entry(trans, &asoc->peer.transport_addr_list,
 				transports) {
-			sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+			sctp_apply_peer_addr_params(params, trans, asoc, sp,
 						    hb_change, pmtud_change,
 						    sackdelay_change);
 		}
@@ -4699,7 +4693,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case SCTP_PEER_ADDR_PARAMS:
-		retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
+		retval = sctp_setsockopt_peer_addr_params(sk, kopt, optlen);
 		break;
 
 	case SCTP_DELAYED_SACK:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 08/51] sctp: pass a kernel pointer to sctp_setsockopt_delayed_ack
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 07/51] sctp: pass a kernel pointer to sctp_setsockopt_peer_addr_params Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 09/51] sctp: pass a kernel pointer to sctp_setsockopt_partial_delivery_point Christoph Hellwig
                   ` (43 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 49 +++++++++++++++++++++--------------------------
 1 file changed, 22 insertions(+), 27 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 19308c327b6d2f..2dfbd7f8799114 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2751,17 +2751,14 @@ static void sctp_apply_asoc_delayed_ack(struct sctp_sack_info *params,
  */
 
 static int sctp_setsockopt_delayed_ack(struct sock *sk,
-				       char __user *optval, unsigned int optlen)
+				       struct sctp_sack_info *params,
+				       unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_association *asoc;
-	struct sctp_sack_info params;
 
 	if (optlen == sizeof(struct sctp_sack_info)) {
-		if (copy_from_user(&params, optval, optlen))
-			return -EFAULT;
-
-		if (params.sack_delay == 0 && params.sack_freq == 0)
+		if (params->sack_delay == 0 && params->sack_freq == 0)
 			return 0;
 	} else if (optlen == sizeof(struct sctp_assoc_value)) {
 		pr_warn_ratelimited(DEPRECATED
@@ -2769,59 +2766,57 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
 				    "Use of struct sctp_assoc_value in delayed_ack socket option.\n"
 				    "Use struct sctp_sack_info instead\n",
 				    current->comm, task_pid_nr(current));
-		if (copy_from_user(&params, optval, optlen))
-			return -EFAULT;
 
-		if (params.sack_delay == 0)
-			params.sack_freq = 1;
+		if (params->sack_delay == 0)
+			params->sack_freq = 1;
 		else
-			params.sack_freq = 0;
+			params->sack_freq = 0;
 	} else
 		return -EINVAL;
 
 	/* Validate value parameter. */
-	if (params.sack_delay > 500)
+	if (params->sack_delay > 500)
 		return -EINVAL;
 
 	/* Get association, if sack_assoc_id != SCTP_FUTURE_ASSOC and the
 	 * socket is a one to many style socket, and an association
 	 * was not found, then the id was invalid.
 	 */
-	asoc = sctp_id2assoc(sk, params.sack_assoc_id);
-	if (!asoc && params.sack_assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->sack_assoc_id);
+	if (!asoc && params->sack_assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc) {
-		sctp_apply_asoc_delayed_ack(&params, asoc);
+		sctp_apply_asoc_delayed_ack(params, asoc);
 
 		return 0;
 	}
 
 	if (sctp_style(sk, TCP))
-		params.sack_assoc_id = SCTP_FUTURE_ASSOC;
+		params->sack_assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (params.sack_assoc_id == SCTP_FUTURE_ASSOC ||
-	    params.sack_assoc_id == SCTP_ALL_ASSOC) {
-		if (params.sack_delay) {
-			sp->sackdelay = params.sack_delay;
+	if (params->sack_assoc_id == SCTP_FUTURE_ASSOC ||
+	    params->sack_assoc_id == SCTP_ALL_ASSOC) {
+		if (params->sack_delay) {
+			sp->sackdelay = params->sack_delay;
 			sp->param_flags =
 				sctp_spp_sackdelay_enable(sp->param_flags);
 		}
-		if (params.sack_freq == 1) {
+		if (params->sack_freq == 1) {
 			sp->param_flags =
 				sctp_spp_sackdelay_disable(sp->param_flags);
-		} else if (params.sack_freq > 1) {
-			sp->sackfreq = params.sack_freq;
+		} else if (params->sack_freq > 1) {
+			sp->sackfreq = params->sack_freq;
 			sp->param_flags =
 				sctp_spp_sackdelay_enable(sp->param_flags);
 		}
 	}
 
-	if (params.sack_assoc_id == SCTP_CURRENT_ASSOC ||
-	    params.sack_assoc_id == SCTP_ALL_ASSOC)
+	if (params->sack_assoc_id == SCTP_CURRENT_ASSOC ||
+	    params->sack_assoc_id == SCTP_ALL_ASSOC)
 		list_for_each_entry(asoc, &sp->ep->asocs, asocs)
-			sctp_apply_asoc_delayed_ack(&params, asoc);
+			sctp_apply_asoc_delayed_ack(params, asoc);
 
 	return 0;
 }
@@ -4697,7 +4692,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case SCTP_DELAYED_SACK:
-		retval = sctp_setsockopt_delayed_ack(sk, optval, optlen);
+		retval = sctp_setsockopt_delayed_ack(sk, kopt, optlen);
 		break;
 	case SCTP_PARTIAL_DELIVERY_POINT:
 		retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 09/51] sctp: pass a kernel pointer to sctp_setsockopt_partial_delivery_point
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 08/51] sctp: pass a kernel pointer to sctp_setsockopt_delayed_ack Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 10/51] sctp: pass a kernel pointer to sctp_setsockopt_initmsg Christoph Hellwig
                   ` (42 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 2dfbd7f8799114..deccfe54d2fc7d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3487,24 +3487,19 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk,
  * call as long as the user provided buffer is large enough to hold the
  * message.
  */
-static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
-						  char __user *optval,
+static int sctp_setsockopt_partial_delivery_point(struct sock *sk, u32 *val,
 						  unsigned int optlen)
 {
-	u32 val;
-
 	if (optlen != sizeof(u32))
 		return -EINVAL;
-	if (get_user(val, (int __user *)optval))
-		return -EFAULT;
 
 	/* Note: We double the receive buffer from what the user sets
 	 * it to be, also initial rwnd is based on rcvbuf/2.
 	 */
-	if (val > (sk->sk_rcvbuf >> 1))
+	if (*val > (sk->sk_rcvbuf >> 1))
 		return -EINVAL;
 
-	sctp_sk(sk)->pd_point = val;
+	sctp_sk(sk)->pd_point = *val;
 
 	return 0; /* is this the right error code? */
 }
@@ -4695,7 +4690,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_delayed_ack(sk, kopt, optlen);
 		break;
 	case SCTP_PARTIAL_DELIVERY_POINT:
-		retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen);
+		retval = sctp_setsockopt_partial_delivery_point(sk, kopt, optlen);
 		break;
 
 	case SCTP_INITMSG:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 10/51] sctp: pass a kernel pointer to sctp_setsockopt_initmsg
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (8 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 09/51] sctp: pass a kernel pointer to sctp_setsockopt_partial_delivery_point Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 11/51] sctp: pass a kernel pointer to sctp_setsockopt_default_send_param Christoph Hellwig
                   ` (41 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index deccfe54d2fc7d..d62c02d0b79346 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2832,24 +2832,22 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
  * by the change).  With TCP-style sockets, this option is inherited by
  * sockets derived from a listener socket.
  */
-static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, unsigned int optlen)
+static int sctp_setsockopt_initmsg(struct sock *sk, struct sctp_initmsg *sinit,
+				   unsigned int optlen)
 {
-	struct sctp_initmsg sinit;
 	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (optlen != sizeof(struct sctp_initmsg))
 		return -EINVAL;
-	if (copy_from_user(&sinit, optval, optlen))
-		return -EFAULT;
 
-	if (sinit.sinit_num_ostreams)
-		sp->initmsg.sinit_num_ostreams = sinit.sinit_num_ostreams;
-	if (sinit.sinit_max_instreams)
-		sp->initmsg.sinit_max_instreams = sinit.sinit_max_instreams;
-	if (sinit.sinit_max_attempts)
-		sp->initmsg.sinit_max_attempts = sinit.sinit_max_attempts;
-	if (sinit.sinit_max_init_timeo)
-		sp->initmsg.sinit_max_init_timeo = sinit.sinit_max_init_timeo;
+	if (sinit->sinit_num_ostreams)
+		sp->initmsg.sinit_num_ostreams = sinit->sinit_num_ostreams;
+	if (sinit->sinit_max_instreams)
+		sp->initmsg.sinit_max_instreams = sinit->sinit_max_instreams;
+	if (sinit->sinit_max_attempts)
+		sp->initmsg.sinit_max_attempts = sinit->sinit_max_attempts;
+	if (sinit->sinit_max_init_timeo)
+		sp->initmsg.sinit_max_init_timeo = sinit->sinit_max_init_timeo;
 
 	return 0;
 }
@@ -4694,7 +4692,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case SCTP_INITMSG:
-		retval = sctp_setsockopt_initmsg(sk, optval, optlen);
+		retval = sctp_setsockopt_initmsg(sk, kopt, optlen);
 		break;
 	case SCTP_DEFAULT_SEND_PARAM:
 		retval = sctp_setsockopt_default_send_param(sk, optval,
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 11/51] sctp: pass a kernel pointer to sctp_setsockopt_default_send_param
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (9 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 10/51] sctp: pass a kernel pointer to sctp_setsockopt_initmsg Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 12/51] sctp: pass a kernel pointer to sctp_setsockopt_default_sndinfo Christoph Hellwig
                   ` (40 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 56 ++++++++++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 30 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d62c02d0b79346..9bcbb065cf9e1f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2867,57 +2867,54 @@ static int sctp_setsockopt_initmsg(struct sock *sk, struct sctp_initmsg *sinit,
  *   to this call if the caller is using the UDP model.
  */
 static int sctp_setsockopt_default_send_param(struct sock *sk,
-					      char __user *optval,
+					      struct sctp_sndrcvinfo *info,
 					      unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_association *asoc;
-	struct sctp_sndrcvinfo info;
 
-	if (optlen != sizeof(info))
+	if (optlen != sizeof(*info))
 		return -EINVAL;
-	if (copy_from_user(&info, optval, optlen))
-		return -EFAULT;
-	if (info.sinfo_flags &
+	if (info->sinfo_flags &
 	    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
 	      SCTP_ABORT | SCTP_EOF))
 		return -EINVAL;
 
-	asoc = sctp_id2assoc(sk, info.sinfo_assoc_id);
-	if (!asoc && info.sinfo_assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, info->sinfo_assoc_id);
+	if (!asoc && info->sinfo_assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc) {
-		asoc->default_stream = info.sinfo_stream;
-		asoc->default_flags = info.sinfo_flags;
-		asoc->default_ppid = info.sinfo_ppid;
-		asoc->default_context = info.sinfo_context;
-		asoc->default_timetolive = info.sinfo_timetolive;
+		asoc->default_stream = info->sinfo_stream;
+		asoc->default_flags = info->sinfo_flags;
+		asoc->default_ppid = info->sinfo_ppid;
+		asoc->default_context = info->sinfo_context;
+		asoc->default_timetolive = info->sinfo_timetolive;
 
 		return 0;
 	}
 
 	if (sctp_style(sk, TCP))
-		info.sinfo_assoc_id = SCTP_FUTURE_ASSOC;
+		info->sinfo_assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (info.sinfo_assoc_id == SCTP_FUTURE_ASSOC ||
-	    info.sinfo_assoc_id == SCTP_ALL_ASSOC) {
-		sp->default_stream = info.sinfo_stream;
-		sp->default_flags = info.sinfo_flags;
-		sp->default_ppid = info.sinfo_ppid;
-		sp->default_context = info.sinfo_context;
-		sp->default_timetolive = info.sinfo_timetolive;
+	if (info->sinfo_assoc_id == SCTP_FUTURE_ASSOC ||
+	    info->sinfo_assoc_id == SCTP_ALL_ASSOC) {
+		sp->default_stream = info->sinfo_stream;
+		sp->default_flags = info->sinfo_flags;
+		sp->default_ppid = info->sinfo_ppid;
+		sp->default_context = info->sinfo_context;
+		sp->default_timetolive = info->sinfo_timetolive;
 	}
 
-	if (info.sinfo_assoc_id == SCTP_CURRENT_ASSOC ||
-	    info.sinfo_assoc_id == SCTP_ALL_ASSOC) {
+	if (info->sinfo_assoc_id == SCTP_CURRENT_ASSOC ||
+	    info->sinfo_assoc_id == SCTP_ALL_ASSOC) {
 		list_for_each_entry(asoc, &sp->ep->asocs, asocs) {
-			asoc->default_stream = info.sinfo_stream;
-			asoc->default_flags = info.sinfo_flags;
-			asoc->default_ppid = info.sinfo_ppid;
-			asoc->default_context = info.sinfo_context;
-			asoc->default_timetolive = info.sinfo_timetolive;
+			asoc->default_stream = info->sinfo_stream;
+			asoc->default_flags = info->sinfo_flags;
+			asoc->default_ppid = info->sinfo_ppid;
+			asoc->default_context = info->sinfo_context;
+			asoc->default_timetolive = info->sinfo_timetolive;
 		}
 	}
 
@@ -4695,8 +4692,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_initmsg(sk, kopt, optlen);
 		break;
 	case SCTP_DEFAULT_SEND_PARAM:
-		retval = sctp_setsockopt_default_send_param(sk, optval,
-							    optlen);
+		retval = sctp_setsockopt_default_send_param(sk, kopt, optlen);
 		break;
 	case SCTP_DEFAULT_SNDINFO:
 		retval = sctp_setsockopt_default_sndinfo(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 12/51] sctp: pass a kernel pointer to sctp_setsockopt_default_sndinfo
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (10 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 11/51] sctp: pass a kernel pointer to sctp_setsockopt_default_send_param Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 13/51] sctp: pass a kernel pointer to sctp_setsockopt_primary_addr Christoph Hellwig
                   ` (39 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 49 ++++++++++++++++++++++-------------------------
 1 file changed, 23 insertions(+), 26 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9bcbb065cf9e1f..6695fa1cb0ca8f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2925,54 +2925,51 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
  * (SCTP_DEFAULT_SNDINFO)
  */
 static int sctp_setsockopt_default_sndinfo(struct sock *sk,
-					   char __user *optval,
+					   struct sctp_sndinfo *info,
 					   unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_association *asoc;
-	struct sctp_sndinfo info;
 
-	if (optlen != sizeof(info))
+	if (optlen != sizeof(*info))
 		return -EINVAL;
-	if (copy_from_user(&info, optval, optlen))
-		return -EFAULT;
-	if (info.snd_flags &
+	if (info->snd_flags &
 	    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
 	      SCTP_ABORT | SCTP_EOF))
 		return -EINVAL;
 
-	asoc = sctp_id2assoc(sk, info.snd_assoc_id);
-	if (!asoc && info.snd_assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, info->snd_assoc_id);
+	if (!asoc && info->snd_assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc) {
-		asoc->default_stream = info.snd_sid;
-		asoc->default_flags = info.snd_flags;
-		asoc->default_ppid = info.snd_ppid;
-		asoc->default_context = info.snd_context;
+		asoc->default_stream = info->snd_sid;
+		asoc->default_flags = info->snd_flags;
+		asoc->default_ppid = info->snd_ppid;
+		asoc->default_context = info->snd_context;
 
 		return 0;
 	}
 
 	if (sctp_style(sk, TCP))
-		info.snd_assoc_id = SCTP_FUTURE_ASSOC;
+		info->snd_assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (info.snd_assoc_id == SCTP_FUTURE_ASSOC ||
-	    info.snd_assoc_id == SCTP_ALL_ASSOC) {
-		sp->default_stream = info.snd_sid;
-		sp->default_flags = info.snd_flags;
-		sp->default_ppid = info.snd_ppid;
-		sp->default_context = info.snd_context;
+	if (info->snd_assoc_id == SCTP_FUTURE_ASSOC ||
+	    info->snd_assoc_id == SCTP_ALL_ASSOC) {
+		sp->default_stream = info->snd_sid;
+		sp->default_flags = info->snd_flags;
+		sp->default_ppid = info->snd_ppid;
+		sp->default_context = info->snd_context;
 	}
 
-	if (info.snd_assoc_id == SCTP_CURRENT_ASSOC ||
-	    info.snd_assoc_id == SCTP_ALL_ASSOC) {
+	if (info->snd_assoc_id == SCTP_CURRENT_ASSOC ||
+	    info->snd_assoc_id == SCTP_ALL_ASSOC) {
 		list_for_each_entry(asoc, &sp->ep->asocs, asocs) {
-			asoc->default_stream = info.snd_sid;
-			asoc->default_flags = info.snd_flags;
-			asoc->default_ppid = info.snd_ppid;
-			asoc->default_context = info.snd_context;
+			asoc->default_stream = info->snd_sid;
+			asoc->default_flags = info->snd_flags;
+			asoc->default_ppid = info->snd_ppid;
+			asoc->default_context = info->snd_context;
 		}
 	}
 
@@ -4695,7 +4692,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_default_send_param(sk, kopt, optlen);
 		break;
 	case SCTP_DEFAULT_SNDINFO:
-		retval = sctp_setsockopt_default_sndinfo(sk, optval, optlen);
+		retval = sctp_setsockopt_default_sndinfo(sk, kopt, optlen);
 		break;
 	case SCTP_PRIMARY_ADDR:
 		retval = sctp_setsockopt_primary_addr(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 13/51] sctp: pass a kernel pointer to sctp_setsockopt_primary_addr
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (11 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 12/51] sctp: pass a kernel pointer to sctp_setsockopt_default_sndinfo Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 14/51] sctp: pass a kernel pointer to sctp_setsockopt_peer_primary_addr Christoph Hellwig
                   ` (38 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6695fa1cb0ca8f..abdec7b412bcbc 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2982,10 +2982,9 @@ static int sctp_setsockopt_default_sndinfo(struct sock *sk,
  * the association primary.  The enclosed address must be one of the
  * association peer's addresses.
  */
-static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_primary_addr(struct sock *sk, struct sctp_prim *prim,
 					unsigned int optlen)
 {
-	struct sctp_prim prim;
 	struct sctp_transport *trans;
 	struct sctp_af *af;
 	int err;
@@ -2993,21 +2992,18 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
 	if (optlen != sizeof(struct sctp_prim))
 		return -EINVAL;
 
-	if (copy_from_user(&prim, optval, sizeof(struct sctp_prim)))
-		return -EFAULT;
-
 	/* Allow security module to validate address but need address len. */
-	af = sctp_get_af_specific(prim.ssp_addr.ss_family);
+	af = sctp_get_af_specific(prim->ssp_addr.ss_family);
 	if (!af)
 		return -EINVAL;
 
 	err = security_sctp_bind_connect(sk, SCTP_PRIMARY_ADDR,
-					 (struct sockaddr *)&prim.ssp_addr,
+					 (struct sockaddr *)&prim->ssp_addr,
 					 af->sockaddr_len);
 	if (err)
 		return err;
 
-	trans = sctp_addr_id2transport(sk, &prim.ssp_addr, prim.ssp_assoc_id);
+	trans = sctp_addr_id2transport(sk, &prim->ssp_addr, prim->ssp_assoc_id);
 	if (!trans)
 		return -EINVAL;
 
@@ -4695,7 +4691,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_default_sndinfo(sk, kopt, optlen);
 		break;
 	case SCTP_PRIMARY_ADDR:
-		retval = sctp_setsockopt_primary_addr(sk, optval, optlen);
+		retval = sctp_setsockopt_primary_addr(sk, kopt, optlen);
 		break;
 	case SCTP_SET_PEER_PRIMARY_ADDR:
 		retval = sctp_setsockopt_peer_primary_addr(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 14/51] sctp: pass a kernel pointer to sctp_setsockopt_peer_primary_addr
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (12 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 13/51] sctp: pass a kernel pointer to sctp_setsockopt_primary_addr Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 15/51] sctp: pass a kernel pointer to sctp_setsockopt_nodelay Christoph Hellwig
                   ` (37 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index abdec7b412bcbc..ff3b720eab0aa2 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3284,12 +3284,12 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned
  *   locally bound addresses. The following structure is used to make a
  *   set primary request:
  */
-static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_peer_primary_addr(struct sock *sk,
+					     struct sctp_setpeerprim *prim,
 					     unsigned int optlen)
 {
 	struct sctp_sock	*sp;
 	struct sctp_association	*asoc = NULL;
-	struct sctp_setpeerprim	prim;
 	struct sctp_chunk	*chunk;
 	struct sctp_af		*af;
 	int 			err;
@@ -3302,10 +3302,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
 	if (optlen != sizeof(struct sctp_setpeerprim))
 		return -EINVAL;
 
-	if (copy_from_user(&prim, optval, optlen))
-		return -EFAULT;
-
-	asoc = sctp_id2assoc(sk, prim.sspp_assoc_id);
+	asoc = sctp_id2assoc(sk, prim->sspp_assoc_id);
 	if (!asoc)
 		return -EINVAL;
 
@@ -3318,26 +3315,26 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
 	if (!sctp_state(asoc, ESTABLISHED))
 		return -ENOTCONN;
 
-	af = sctp_get_af_specific(prim.sspp_addr.ss_family);
+	af = sctp_get_af_specific(prim->sspp_addr.ss_family);
 	if (!af)
 		return -EINVAL;
 
-	if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL))
+	if (!af->addr_valid((union sctp_addr *)&prim->sspp_addr, sp, NULL))
 		return -EADDRNOTAVAIL;
 
-	if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
+	if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim->sspp_addr))
 		return -EADDRNOTAVAIL;
 
 	/* Allow security module to validate address. */
 	err = security_sctp_bind_connect(sk, SCTP_SET_PEER_PRIMARY_ADDR,
-					 (struct sockaddr *)&prim.sspp_addr,
+					 (struct sockaddr *)&prim->sspp_addr,
 					 af->sockaddr_len);
 	if (err)
 		return err;
 
 	/* Create an ASCONF chunk with SET_PRIMARY parameter	*/
 	chunk = sctp_make_asconf_set_prim(asoc,
-					  (union sctp_addr *)&prim.sspp_addr);
+					  (union sctp_addr *)&prim->sspp_addr);
 	if (!chunk)
 		return -ENOMEM;
 
@@ -4694,7 +4691,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_primary_addr(sk, kopt, optlen);
 		break;
 	case SCTP_SET_PEER_PRIMARY_ADDR:
-		retval = sctp_setsockopt_peer_primary_addr(sk, optval, optlen);
+		retval = sctp_setsockopt_peer_primary_addr(sk, kopt, optlen);
 		break;
 	case SCTP_NODELAY:
 		retval = sctp_setsockopt_nodelay(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 15/51] sctp: pass a kernel pointer to sctp_setsockopt_nodelay
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (13 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 14/51] sctp: pass a kernel pointer to sctp_setsockopt_peer_primary_addr Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 16/51] sctp: pass a kernel pointer to sctp_setsockopt_rtoinfo Christoph Hellwig
                   ` (36 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ff3b720eab0aa2..f9fe93e865b970 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3020,17 +3020,12 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, struct sctp_prim *prim,
  * introduced, at the cost of more packets in the network.  Expects an
  *  integer boolean flag.
  */
-static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_nodelay(struct sock *sk, int *val,
 				   unsigned int optlen)
 {
-	int val;
-
 	if (optlen < sizeof(int))
 		return -EINVAL;
-	if (get_user(val, (int __user *)optval))
-		return -EFAULT;
-
-	sctp_sk(sk)->nodelay = (val == 0) ? 0 : 1;
+	sctp_sk(sk)->nodelay = (*val == 0) ? 0 : 1;
 	return 0;
 }
 
@@ -4694,7 +4689,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_peer_primary_addr(sk, kopt, optlen);
 		break;
 	case SCTP_NODELAY:
-		retval = sctp_setsockopt_nodelay(sk, optval, optlen);
+		retval = sctp_setsockopt_nodelay(sk, kopt, optlen);
 		break;
 	case SCTP_RTOINFO:
 		retval = sctp_setsockopt_rtoinfo(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 16/51] sctp: pass a kernel pointer to sctp_setsockopt_rtoinfo
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (14 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 15/51] sctp: pass a kernel pointer to sctp_setsockopt_nodelay Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 17/51] sctp: pass a kernel pointer to sctp_setsockopt_associnfo Christoph Hellwig
                   ` (35 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f9fe93e865b970..6339a08b62dd2b 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3041,9 +3041,10 @@ static int sctp_setsockopt_nodelay(struct sock *sk, int *val,
  * be changed.
  *
  */
-static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigned int optlen)
+static int sctp_setsockopt_rtoinfo(struct sock *sk,
+				   struct sctp_rtoinfo *rtoinfo,
+				   unsigned int optlen)
 {
-	struct sctp_rtoinfo rtoinfo;
 	struct sctp_association *asoc;
 	unsigned long rto_min, rto_max;
 	struct sctp_sock *sp = sctp_sk(sk);
@@ -3051,18 +3052,15 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
 	if (optlen != sizeof (struct sctp_rtoinfo))
 		return -EINVAL;
 
-	if (copy_from_user(&rtoinfo, optval, optlen))
-		return -EFAULT;
-
-	asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id);
+	asoc = sctp_id2assoc(sk, rtoinfo->srto_assoc_id);
 
 	/* Set the values to the specific association */
-	if (!asoc && rtoinfo.srto_assoc_id != SCTP_FUTURE_ASSOC &&
+	if (!asoc && rtoinfo->srto_assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
-	rto_max = rtoinfo.srto_max;
-	rto_min = rtoinfo.srto_min;
+	rto_max = rtoinfo->srto_max;
+	rto_min = rtoinfo->srto_min;
 
 	if (rto_max)
 		rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max;
@@ -3078,17 +3076,17 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
 		return -EINVAL;
 
 	if (asoc) {
-		if (rtoinfo.srto_initial != 0)
+		if (rtoinfo->srto_initial != 0)
 			asoc->rto_initial =
-				msecs_to_jiffies(rtoinfo.srto_initial);
+				msecs_to_jiffies(rtoinfo->srto_initial);
 		asoc->rto_max = rto_max;
 		asoc->rto_min = rto_min;
 	} else {
 		/* If there is no association or the association-id = 0
 		 * set the values to the endpoint.
 		 */
-		if (rtoinfo.srto_initial != 0)
-			sp->rtoinfo.srto_initial = rtoinfo.srto_initial;
+		if (rtoinfo->srto_initial != 0)
+			sp->rtoinfo.srto_initial = rtoinfo->srto_initial;
 		sp->rtoinfo.srto_max = rto_max;
 		sp->rtoinfo.srto_min = rto_min;
 	}
@@ -4692,7 +4690,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_nodelay(sk, kopt, optlen);
 		break;
 	case SCTP_RTOINFO:
-		retval = sctp_setsockopt_rtoinfo(sk, optval, optlen);
+		retval = sctp_setsockopt_rtoinfo(sk, kopt, optlen);
 		break;
 	case SCTP_ASSOCINFO:
 		retval = sctp_setsockopt_associnfo(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 17/51] sctp: pass a kernel pointer to sctp_setsockopt_associnfo
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (15 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 16/51] sctp: pass a kernel pointer to sctp_setsockopt_rtoinfo Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 18/51] sctp: pass a kernel pointer to sctp_setsockopt_mappedv4 Christoph Hellwig
                   ` (34 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6339a08b62dd2b..2a655c65e2943d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3105,26 +3105,25 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk,
  * See [SCTP] for more information.
  *
  */
-static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsigned int optlen)
+static int sctp_setsockopt_associnfo(struct sock *sk,
+				     struct sctp_assocparams *assocparams,
+				     unsigned int optlen)
 {
 
-	struct sctp_assocparams assocparams;
 	struct sctp_association *asoc;
 
 	if (optlen != sizeof(struct sctp_assocparams))
 		return -EINVAL;
-	if (copy_from_user(&assocparams, optval, optlen))
-		return -EFAULT;
 
-	asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id);
+	asoc = sctp_id2assoc(sk, assocparams->sasoc_assoc_id);
 
-	if (!asoc && assocparams.sasoc_assoc_id != SCTP_FUTURE_ASSOC &&
+	if (!asoc && assocparams->sasoc_assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	/* Set the values to the specific association */
 	if (asoc) {
-		if (assocparams.sasoc_asocmaxrxt != 0) {
+		if (assocparams->sasoc_asocmaxrxt != 0) {
 			__u32 path_sum = 0;
 			int   paths = 0;
 			struct sctp_transport *peer_addr;
@@ -3141,24 +3140,25 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsig
 			 * then one path.
 			 */
 			if (paths > 1 &&
-			    assocparams.sasoc_asocmaxrxt > path_sum)
+			    assocparams->sasoc_asocmaxrxt > path_sum)
 				return -EINVAL;
 
-			asoc->max_retrans = assocparams.sasoc_asocmaxrxt;
+			asoc->max_retrans = assocparams->sasoc_asocmaxrxt;
 		}
 
-		if (assocparams.sasoc_cookie_life != 0)
-			asoc->cookie_life = ms_to_ktime(assocparams.sasoc_cookie_life);
+		if (assocparams->sasoc_cookie_life != 0)
+			asoc->cookie_life =
+				ms_to_ktime(assocparams->sasoc_cookie_life);
 	} else {
 		/* Set the values to the endpoint */
 		struct sctp_sock *sp = sctp_sk(sk);
 
-		if (assocparams.sasoc_asocmaxrxt != 0)
+		if (assocparams->sasoc_asocmaxrxt != 0)
 			sp->assocparams.sasoc_asocmaxrxt =
-						assocparams.sasoc_asocmaxrxt;
-		if (assocparams.sasoc_cookie_life != 0)
+						assocparams->sasoc_asocmaxrxt;
+		if (assocparams->sasoc_cookie_life != 0)
 			sp->assocparams.sasoc_cookie_life =
-						assocparams.sasoc_cookie_life;
+						assocparams->sasoc_cookie_life;
 	}
 	return 0;
 }
@@ -4693,7 +4693,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_rtoinfo(sk, kopt, optlen);
 		break;
 	case SCTP_ASSOCINFO:
-		retval = sctp_setsockopt_associnfo(sk, optval, optlen);
+		retval = sctp_setsockopt_associnfo(sk, kopt, optlen);
 		break;
 	case SCTP_I_WANT_MAPPED_V4_ADDR:
 		retval = sctp_setsockopt_mappedv4(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 18/51] sctp: pass a kernel pointer to sctp_setsockopt_mappedv4
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (16 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 17/51] sctp: pass a kernel pointer to sctp_setsockopt_associnfo Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 19/51] sctp: pass a kernel pointer to sctp_setsockopt_maxseg Christoph Hellwig
                   ` (33 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 2a655c65e2943d..5007af318e134e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3173,16 +3173,14 @@ static int sctp_setsockopt_associnfo(struct sock *sk,
  * addresses and a user will receive both PF_INET6 and PF_INET type
  * addresses on the socket.
  */
-static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsigned int optlen)
+static int sctp_setsockopt_mappedv4(struct sock *sk, int *val,
+				    unsigned int optlen)
 {
-	int val;
 	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (optlen < sizeof(int))
 		return -EINVAL;
-	if (get_user(val, (int __user *)optval))
-		return -EFAULT;
-	if (val)
+	if (*val)
 		sp->v4mapped = 1;
 	else
 		sp->v4mapped = 0;
@@ -4696,7 +4694,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_associnfo(sk, kopt, optlen);
 		break;
 	case SCTP_I_WANT_MAPPED_V4_ADDR:
-		retval = sctp_setsockopt_mappedv4(sk, optval, optlen);
+		retval = sctp_setsockopt_mappedv4(sk, kopt, optlen);
 		break;
 	case SCTP_MAXSEG:
 		retval = sctp_setsockopt_maxseg(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 19/51] sctp: pass a kernel pointer to sctp_setsockopt_maxseg
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (17 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 18/51] sctp: pass a kernel pointer to sctp_setsockopt_mappedv4 Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 20/51] sctp: pass a kernel pointer to sctp_setsockopt_adaptation_layer Christoph Hellwig
                   ` (32 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5007af318e134e..cc7d5430ad8858 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3215,11 +3215,13 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, int *val,
  *    changed (effecting future associations only).
  * assoc_value:  This parameter specifies the maximum size in bytes.
  */
-static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen)
+static int sctp_setsockopt_maxseg(struct sock *sk,
+				  struct sctp_assoc_value *params,
+				  unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
+	sctp_assoc_t assoc_id;
 	int val;
 
 	if (optlen == sizeof(int)) {
@@ -3228,19 +3230,17 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned
 				    "Use of int in maxseg socket option.\n"
 				    "Use struct sctp_assoc_value instead\n",
 				    current->comm, task_pid_nr(current));
-		if (copy_from_user(&val, optval, optlen))
-			return -EFAULT;
-		params.assoc_id = SCTP_FUTURE_ASSOC;
+		assoc_id = SCTP_FUTURE_ASSOC;
+		val = *(int *)params;
 	} else if (optlen == sizeof(struct sctp_assoc_value)) {
-		if (copy_from_user(&params, optval, optlen))
-			return -EFAULT;
-		val = params.assoc_value;
+		assoc_id = params->assoc_id;
+		val = params->assoc_value;
 	} else {
 		return -EINVAL;
 	}
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, assoc_id);
+	if (!asoc && assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
@@ -4697,7 +4697,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_mappedv4(sk, kopt, optlen);
 		break;
 	case SCTP_MAXSEG:
-		retval = sctp_setsockopt_maxseg(sk, optval, optlen);
+		retval = sctp_setsockopt_maxseg(sk, kopt, optlen);
 		break;
 	case SCTP_ADAPTATION_LAYER:
 		retval = sctp_setsockopt_adaptation_layer(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 20/51] sctp: pass a kernel pointer to sctp_setsockopt_adaptation_layer
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (18 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 19/51] sctp: pass a kernel pointer to sctp_setsockopt_maxseg Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 21/51] sctp: pass a kernel pointer to sctp_setsockopt_context Christoph Hellwig
                   ` (31 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index cc7d5430ad8858..b29452f58ff988 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3336,17 +3336,14 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk,
 	return err;
 }
 
-static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_adaptation_layer(struct sock *sk,
+					    struct sctp_setadaptation *adapt,
 					    unsigned int optlen)
 {
-	struct sctp_setadaptation adaptation;
-
 	if (optlen != sizeof(struct sctp_setadaptation))
 		return -EINVAL;
-	if (copy_from_user(&adaptation, optval, optlen))
-		return -EFAULT;
 
-	sctp_sk(sk)->adaptation_ind = adaptation.ssb_adaptation_ind;
+	sctp_sk(sk)->adaptation_ind = adapt->ssb_adaptation_ind;
 
 	return 0;
 }
@@ -4700,7 +4697,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_maxseg(sk, kopt, optlen);
 		break;
 	case SCTP_ADAPTATION_LAYER:
-		retval = sctp_setsockopt_adaptation_layer(sk, optval, optlen);
+		retval = sctp_setsockopt_adaptation_layer(sk, kopt, optlen);
 		break;
 	case SCTP_CONTEXT:
 		retval = sctp_setsockopt_context(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 21/51] sctp: pass a kernel pointer to sctp_setsockopt_context
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (19 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 20/51] sctp: pass a kernel pointer to sctp_setsockopt_adaptation_layer Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:21 ` [PATCH 22/51] sctp: pass a kernel pointer to sctp_setsockopt_fragment_interleave Christoph Hellwig
                   ` (30 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b29452f58ff988..2862047054d55a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3362,40 +3362,38 @@ static int sctp_setsockopt_adaptation_layer(struct sock *sk,
  * received messages from the peer and does not effect the value that is
  * saved with outbound messages.
  */
-static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_context(struct sock *sk,
+				   struct sctp_assoc_value *params,
 				   unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
 
 	if (optlen != sizeof(struct sctp_assoc_value))
 		return -EINVAL;
-	if (copy_from_user(&params, optval, optlen))
-		return -EFAULT;
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc) {
-		asoc->default_rcv_context = params.assoc_value;
+		asoc->default_rcv_context = params->assoc_value;
 
 		return 0;
 	}
 
 	if (sctp_style(sk, TCP))
-		params.assoc_id = SCTP_FUTURE_ASSOC;
+		params->assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (params.assoc_id == SCTP_FUTURE_ASSOC ||
-	    params.assoc_id == SCTP_ALL_ASSOC)
-		sp->default_rcv_context = params.assoc_value;
+	if (params->assoc_id == SCTP_FUTURE_ASSOC ||
+	    params->assoc_id == SCTP_ALL_ASSOC)
+		sp->default_rcv_context = params->assoc_value;
 
-	if (params.assoc_id == SCTP_CURRENT_ASSOC ||
-	    params.assoc_id == SCTP_ALL_ASSOC)
+	if (params->assoc_id == SCTP_CURRENT_ASSOC ||
+	    params->assoc_id == SCTP_ALL_ASSOC)
 		list_for_each_entry(asoc, &sp->ep->asocs, asocs)
-			asoc->default_rcv_context = params.assoc_value;
+			asoc->default_rcv_context = params->assoc_value;
 
 	return 0;
 }
@@ -4700,7 +4698,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_adaptation_layer(sk, kopt, optlen);
 		break;
 	case SCTP_CONTEXT:
-		retval = sctp_setsockopt_context(sk, optval, optlen);
+		retval = sctp_setsockopt_context(sk, kopt, optlen);
 		break;
 	case SCTP_FRAGMENT_INTERLEAVE:
 		retval = sctp_setsockopt_fragment_interleave(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 22/51] sctp: pass a kernel pointer to sctp_setsockopt_fragment_interleave
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (20 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 21/51] sctp: pass a kernel pointer to sctp_setsockopt_context Christoph Hellwig
@ 2020-07-19  7:21 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 23/51] sctp: pass a kernel pointer to sctp_setsockopt_maxburst Christoph Hellwig
                   ` (29 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:21 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 2862047054d55a..874cec73153052 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3422,18 +3422,13 @@ static int sctp_setsockopt_context(struct sock *sk,
  * application using the one to many model may become confused and act
  * incorrectly.
  */
-static int sctp_setsockopt_fragment_interleave(struct sock *sk,
-					       char __user *optval,
+static int sctp_setsockopt_fragment_interleave(struct sock *sk, int *val,
 					       unsigned int optlen)
 {
-	int val;
-
 	if (optlen != sizeof(int))
 		return -EINVAL;
-	if (get_user(val, (int __user *)optval))
-		return -EFAULT;
 
-	sctp_sk(sk)->frag_interleave = !!val;
+	sctp_sk(sk)->frag_interleave = !!*val;
 
 	if (!sctp_sk(sk)->frag_interleave)
 		sctp_sk(sk)->ep->intl_enable = 0;
@@ -4701,7 +4696,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_context(sk, kopt, optlen);
 		break;
 	case SCTP_FRAGMENT_INTERLEAVE:
-		retval = sctp_setsockopt_fragment_interleave(sk, optval, optlen);
+		retval = sctp_setsockopt_fragment_interleave(sk, kopt, optlen);
 		break;
 	case SCTP_MAX_BURST:
 		retval = sctp_setsockopt_maxburst(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 23/51] sctp: pass a kernel pointer to sctp_setsockopt_maxburst
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (21 preceding siblings ...)
  2020-07-19  7:21 ` [PATCH 22/51] sctp: pass a kernel pointer to sctp_setsockopt_fragment_interleave Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 24/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_chunk Christoph Hellwig
                   ` (28 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 35 ++++++++++++++++-------------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 874cec73153052..ac7dff849290dc 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3482,12 +3482,13 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk, u32 *val,
  * future associations inheriting the socket value.
  */
 static int sctp_setsockopt_maxburst(struct sock *sk,
-				    char __user *optval,
+				    struct sctp_assoc_value *params,
 				    unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
+	sctp_assoc_t assoc_id;
+	u32 assoc_value;
 
 	if (optlen == sizeof(int)) {
 		pr_warn_ratelimited(DEPRECATED
@@ -3495,37 +3496,33 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
 				    "Use of int in max_burst socket option deprecated.\n"
 				    "Use struct sctp_assoc_value instead\n",
 				    current->comm, task_pid_nr(current));
-		if (copy_from_user(&params.assoc_value, optval, optlen))
-			return -EFAULT;
-		params.assoc_id = SCTP_FUTURE_ASSOC;
+		assoc_id = SCTP_FUTURE_ASSOC;
+		assoc_value = *((int *)params);
 	} else if (optlen == sizeof(struct sctp_assoc_value)) {
-		if (copy_from_user(&params, optval, optlen))
-			return -EFAULT;
+		assoc_id = params->assoc_id;
+		assoc_value = params->assoc_value;
 	} else
 		return -EINVAL;
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id > SCTP_ALL_ASSOC &&
-	    sctp_style(sk, UDP))
+	asoc = sctp_id2assoc(sk, assoc_id);
+	if (!asoc && assoc_id > SCTP_ALL_ASSOC && sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc) {
-		asoc->max_burst = params.assoc_value;
+		asoc->max_burst = assoc_value;
 
 		return 0;
 	}
 
 	if (sctp_style(sk, TCP))
-		params.assoc_id = SCTP_FUTURE_ASSOC;
+		assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (params.assoc_id == SCTP_FUTURE_ASSOC ||
-	    params.assoc_id == SCTP_ALL_ASSOC)
-		sp->max_burst = params.assoc_value;
+	if (assoc_id == SCTP_FUTURE_ASSOC || assoc_id == SCTP_ALL_ASSOC)
+		sp->max_burst = assoc_value;
 
-	if (params.assoc_id == SCTP_CURRENT_ASSOC ||
-	    params.assoc_id == SCTP_ALL_ASSOC)
+	if (assoc_id == SCTP_CURRENT_ASSOC || assoc_id == SCTP_ALL_ASSOC)
 		list_for_each_entry(asoc, &sp->ep->asocs, asocs)
-			asoc->max_burst = params.assoc_value;
+			asoc->max_burst = assoc_value;
 
 	return 0;
 }
@@ -4699,7 +4696,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_fragment_interleave(sk, kopt, optlen);
 		break;
 	case SCTP_MAX_BURST:
-		retval = sctp_setsockopt_maxburst(sk, optval, optlen);
+		retval = sctp_setsockopt_maxburst(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_CHUNK:
 		retval = sctp_setsockopt_auth_chunk(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 24/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_chunk
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (22 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 23/51] sctp: pass a kernel pointer to sctp_setsockopt_maxburst Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 25/51] sctp: pass a kernel pointer to sctp_setsockopt_hmac_ident Christoph Hellwig
                   ` (27 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ac7dff849290dc..f68aa3936df3f3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3535,21 +3535,18 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
  * will only effect future associations on the socket.
  */
 static int sctp_setsockopt_auth_chunk(struct sock *sk,
-				      char __user *optval,
+				      struct sctp_authchunk *val,
 				      unsigned int optlen)
 {
 	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
-	struct sctp_authchunk val;
 
 	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (optlen != sizeof(struct sctp_authchunk))
 		return -EINVAL;
-	if (copy_from_user(&val, optval, optlen))
-		return -EFAULT;
 
-	switch (val.sauth_chunk) {
+	switch (val->sauth_chunk) {
 	case SCTP_CID_INIT:
 	case SCTP_CID_INIT_ACK:
 	case SCTP_CID_SHUTDOWN_COMPLETE:
@@ -3558,7 +3555,7 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
 	}
 
 	/* add this chunk id to the endpoint */
-	return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk);
+	return sctp_auth_ep_add_chunkid(ep, val->sauth_chunk);
 }
 
 /*
@@ -4699,7 +4696,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_maxburst(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_CHUNK:
-		retval = sctp_setsockopt_auth_chunk(sk, optval, optlen);
+		retval = sctp_setsockopt_auth_chunk(sk, kopt, optlen);
 		break;
 	case SCTP_HMAC_IDENT:
 		retval = sctp_setsockopt_hmac_ident(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 25/51] sctp: pass a kernel pointer to sctp_setsockopt_hmac_ident
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (23 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 24/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_chunk Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 26/51] sctp: switch sctp_setsockopt_auth_key to use memzero_explicit Christoph Hellwig
                   ` (26 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f68aa3936df3f3..a573af7dfe41f5 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3565,13 +3565,11 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
  * endpoint requires the peer to use.
  */
 static int sctp_setsockopt_hmac_ident(struct sock *sk,
-				      char __user *optval,
+				      struct sctp_hmacalgo *hmacs,
 				      unsigned int optlen)
 {
 	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
-	struct sctp_hmacalgo *hmacs;
 	u32 idents;
-	int err;
 
 	if (!ep->auth_enable)
 		return -EACCES;
@@ -3581,21 +3579,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
 	optlen = min_t(unsigned int, optlen, sizeof(struct sctp_hmacalgo) +
 					     SCTP_AUTH_NUM_HMACS * sizeof(u16));
 
-	hmacs = memdup_user(optval, optlen);
-	if (IS_ERR(hmacs))
-		return PTR_ERR(hmacs);
-
 	idents = hmacs->shmac_num_idents;
 	if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS ||
-	    (idents * sizeof(u16)) > (optlen - sizeof(struct sctp_hmacalgo))) {
-		err = -EINVAL;
-		goto out;
-	}
+	    (idents * sizeof(u16)) > (optlen - sizeof(struct sctp_hmacalgo)))
+		return -EINVAL;
 
-	err = sctp_auth_ep_set_hmacs(ep, hmacs);
-out:
-	kfree(hmacs);
-	return err;
+	return sctp_auth_ep_set_hmacs(ep, hmacs);
 }
 
 /*
@@ -4699,7 +4688,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_auth_chunk(sk, kopt, optlen);
 		break;
 	case SCTP_HMAC_IDENT:
-		retval = sctp_setsockopt_hmac_ident(sk, optval, optlen);
+		retval = sctp_setsockopt_hmac_ident(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_KEY:
 		retval = sctp_setsockopt_auth_key(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 26/51] sctp: switch sctp_setsockopt_auth_key to use memzero_explicit
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (24 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 25/51] sctp: pass a kernel pointer to sctp_setsockopt_hmac_ident Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 27/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_key Christoph Hellwig
                   ` (25 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Switch from kzfree to sctp_setsockopt_auth_key + kfree to prepare for
moving the kfree to common code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index a573af7dfe41f5..365145746b559d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3649,7 +3649,8 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
 	}
 
 out:
-	kzfree(authkey);
+	memzero_explicit(authkey, optlen);
+	kfree(authkey);
 	return ret;
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 27/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_key
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (25 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 26/51] sctp: switch sctp_setsockopt_auth_key to use memzero_explicit Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 28/51] sctp: pass a kernel pointer to sctp_setsockopt_active_key Christoph Hellwig
                   ` (24 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.  Adapt sctp_setsockopt to use a
kzfree for this case.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 365145746b559d..b4dcccba5787e3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3594,11 +3594,10 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
  * association shared key.
  */
 static int sctp_setsockopt_auth_key(struct sock *sk,
-				    char __user *optval,
+				    struct sctp_authkey *authkey,
 				    unsigned int optlen)
 {
 	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
-	struct sctp_authkey *authkey;
 	struct sctp_association *asoc;
 	int ret = -EINVAL;
 
@@ -3609,10 +3608,6 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
 	 */
 	optlen = min_t(unsigned int, optlen, USHRT_MAX + sizeof(*authkey));
 
-	authkey = memdup_user(optval, optlen);
-	if (IS_ERR(authkey))
-		return PTR_ERR(authkey);
-
 	if (authkey->sca_keylength > optlen - sizeof(*authkey))
 		goto out;
 
@@ -3650,7 +3645,6 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
 
 out:
 	memzero_explicit(authkey, optlen);
-	kfree(authkey);
 	return ret;
 }
 
@@ -4692,7 +4686,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_hmac_ident(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_KEY:
-		retval = sctp_setsockopt_auth_key(sk, optval, optlen);
+		retval = sctp_setsockopt_auth_key(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_ACTIVE_KEY:
 		retval = sctp_setsockopt_active_key(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 28/51] sctp: pass a kernel pointer to sctp_setsockopt_active_key
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (26 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 27/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_key Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 29/51] sctp: pass a kernel pointer to sctp_setsockopt_del_key Christoph Hellwig
                   ` (23 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b4dcccba5787e3..02153f243683ea 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3655,42 +3655,39 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
  * the association shared key.
  */
 static int sctp_setsockopt_active_key(struct sock *sk,
-				      char __user *optval,
+				      struct sctp_authkeyid *val,
 				      unsigned int optlen)
 {
 	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_association *asoc;
-	struct sctp_authkeyid val;
 	int ret = 0;
 
 	if (optlen != sizeof(struct sctp_authkeyid))
 		return -EINVAL;
-	if (copy_from_user(&val, optval, optlen))
-		return -EFAULT;
 
-	asoc = sctp_id2assoc(sk, val.scact_assoc_id);
-	if (!asoc && val.scact_assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, val->scact_assoc_id);
+	if (!asoc && val->scact_assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc)
-		return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber);
+		return sctp_auth_set_active_key(ep, asoc, val->scact_keynumber);
 
 	if (sctp_style(sk, TCP))
-		val.scact_assoc_id = SCTP_FUTURE_ASSOC;
+		val->scact_assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (val.scact_assoc_id == SCTP_FUTURE_ASSOC ||
-	    val.scact_assoc_id == SCTP_ALL_ASSOC) {
-		ret = sctp_auth_set_active_key(ep, asoc, val.scact_keynumber);
+	if (val->scact_assoc_id == SCTP_FUTURE_ASSOC ||
+	    val->scact_assoc_id == SCTP_ALL_ASSOC) {
+		ret = sctp_auth_set_active_key(ep, asoc, val->scact_keynumber);
 		if (ret)
 			return ret;
 	}
 
-	if (val.scact_assoc_id == SCTP_CURRENT_ASSOC ||
-	    val.scact_assoc_id == SCTP_ALL_ASSOC) {
+	if (val->scact_assoc_id == SCTP_CURRENT_ASSOC ||
+	    val->scact_assoc_id == SCTP_ALL_ASSOC) {
 		list_for_each_entry(asoc, &ep->asocs, asocs) {
 			int res = sctp_auth_set_active_key(ep, asoc,
-							   val.scact_keynumber);
+							   val->scact_keynumber);
 
 			if (res && !ret)
 				ret = res;
@@ -4689,7 +4686,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_auth_key(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_ACTIVE_KEY:
-		retval = sctp_setsockopt_active_key(sk, optval, optlen);
+		retval = sctp_setsockopt_active_key(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_DELETE_KEY:
 		retval = sctp_setsockopt_del_key(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 29/51] sctp: pass a kernel pointer to sctp_setsockopt_del_key
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (27 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 28/51] sctp: pass a kernel pointer to sctp_setsockopt_active_key Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 30/51] sctp: pass a kernel pointer to sctp_setsockopt_deactivate_key Christoph Hellwig
                   ` (22 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 02153f243683ea..b692b9376d9d60 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3703,42 +3703,39 @@ static int sctp_setsockopt_active_key(struct sock *sk,
  * This set option will delete a shared secret key from use.
  */
 static int sctp_setsockopt_del_key(struct sock *sk,
-				   char __user *optval,
+				   struct sctp_authkeyid *val,
 				   unsigned int optlen)
 {
 	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_association *asoc;
-	struct sctp_authkeyid val;
 	int ret = 0;
 
 	if (optlen != sizeof(struct sctp_authkeyid))
 		return -EINVAL;
-	if (copy_from_user(&val, optval, optlen))
-		return -EFAULT;
 
-	asoc = sctp_id2assoc(sk, val.scact_assoc_id);
-	if (!asoc && val.scact_assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, val->scact_assoc_id);
+	if (!asoc && val->scact_assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc)
-		return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber);
+		return sctp_auth_del_key_id(ep, asoc, val->scact_keynumber);
 
 	if (sctp_style(sk, TCP))
-		val.scact_assoc_id = SCTP_FUTURE_ASSOC;
+		val->scact_assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (val.scact_assoc_id == SCTP_FUTURE_ASSOC ||
-	    val.scact_assoc_id == SCTP_ALL_ASSOC) {
-		ret = sctp_auth_del_key_id(ep, asoc, val.scact_keynumber);
+	if (val->scact_assoc_id == SCTP_FUTURE_ASSOC ||
+	    val->scact_assoc_id == SCTP_ALL_ASSOC) {
+		ret = sctp_auth_del_key_id(ep, asoc, val->scact_keynumber);
 		if (ret)
 			return ret;
 	}
 
-	if (val.scact_assoc_id == SCTP_CURRENT_ASSOC ||
-	    val.scact_assoc_id == SCTP_ALL_ASSOC) {
+	if (val->scact_assoc_id == SCTP_CURRENT_ASSOC ||
+	    val->scact_assoc_id == SCTP_ALL_ASSOC) {
 		list_for_each_entry(asoc, &ep->asocs, asocs) {
 			int res = sctp_auth_del_key_id(ep, asoc,
-						       val.scact_keynumber);
+						       val->scact_keynumber);
 
 			if (res && !ret)
 				ret = res;
@@ -4689,7 +4686,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_active_key(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_DELETE_KEY:
-		retval = sctp_setsockopt_del_key(sk, optval, optlen);
+		retval = sctp_setsockopt_del_key(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_DEACTIVATE_KEY:
 		retval = sctp_setsockopt_deactivate_key(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 30/51] sctp: pass a kernel pointer to sctp_setsockopt_deactivate_key
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (28 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 29/51] sctp: pass a kernel pointer to sctp_setsockopt_del_key Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 31/51] sctp: pass a kernel pointer to sctp_setsockopt_auto_asconf Christoph Hellwig
                   ` (21 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b692b9376d9d60..ab155c15939ee8 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3750,42 +3750,40 @@ static int sctp_setsockopt_del_key(struct sock *sk,
  *
  * This set option will deactivate a shared secret key.
  */
-static int sctp_setsockopt_deactivate_key(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_deactivate_key(struct sock *sk,
+					  struct sctp_authkeyid *val,
 					  unsigned int optlen)
 {
 	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_association *asoc;
-	struct sctp_authkeyid val;
 	int ret = 0;
 
 	if (optlen != sizeof(struct sctp_authkeyid))
 		return -EINVAL;
-	if (copy_from_user(&val, optval, optlen))
-		return -EFAULT;
 
-	asoc = sctp_id2assoc(sk, val.scact_assoc_id);
-	if (!asoc && val.scact_assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, val->scact_assoc_id);
+	if (!asoc && val->scact_assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc)
-		return sctp_auth_deact_key_id(ep, asoc, val.scact_keynumber);
+		return sctp_auth_deact_key_id(ep, asoc, val->scact_keynumber);
 
 	if (sctp_style(sk, TCP))
-		val.scact_assoc_id = SCTP_FUTURE_ASSOC;
+		val->scact_assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (val.scact_assoc_id == SCTP_FUTURE_ASSOC ||
-	    val.scact_assoc_id == SCTP_ALL_ASSOC) {
-		ret = sctp_auth_deact_key_id(ep, asoc, val.scact_keynumber);
+	if (val->scact_assoc_id == SCTP_FUTURE_ASSOC ||
+	    val->scact_assoc_id == SCTP_ALL_ASSOC) {
+		ret = sctp_auth_deact_key_id(ep, asoc, val->scact_keynumber);
 		if (ret)
 			return ret;
 	}
 
-	if (val.scact_assoc_id == SCTP_CURRENT_ASSOC ||
-	    val.scact_assoc_id == SCTP_ALL_ASSOC) {
+	if (val->scact_assoc_id == SCTP_CURRENT_ASSOC ||
+	    val->scact_assoc_id == SCTP_ALL_ASSOC) {
 		list_for_each_entry(asoc, &ep->asocs, asocs) {
 			int res = sctp_auth_deact_key_id(ep, asoc,
-							 val.scact_keynumber);
+							 val->scact_keynumber);
 
 			if (res && !ret)
 				ret = res;
@@ -4689,7 +4687,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_del_key(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_DEACTIVATE_KEY:
-		retval = sctp_setsockopt_deactivate_key(sk, optval, optlen);
+		retval = sctp_setsockopt_deactivate_key(sk, kopt, optlen);
 		break;
 	case SCTP_AUTO_ASCONF:
 		retval = sctp_setsockopt_auto_asconf(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 31/51] sctp: pass a kernel pointer to sctp_setsockopt_auto_asconf
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (29 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 30/51] sctp: pass a kernel pointer to sctp_setsockopt_deactivate_key Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 32/51] sctp: pass a kernel pointer to sctp_setsockopt_paddr_thresholds Christoph Hellwig
                   ` (20 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ab155c15939ee8..64f2a967ddf5d3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3807,26 +3807,23 @@ static int sctp_setsockopt_deactivate_key(struct sock *sk,
  * Note. In this implementation, socket operation overrides default parameter
  * being set by sysctl as well as FreeBSD implementation
  */
-static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_auto_asconf(struct sock *sk, int *val,
 					unsigned int optlen)
 {
-	int val;
 	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (optlen < sizeof(int))
 		return -EINVAL;
-	if (get_user(val, (int __user *)optval))
-		return -EFAULT;
-	if (!sctp_is_ep_boundall(sk) && val)
+	if (!sctp_is_ep_boundall(sk) && *val)
 		return -EINVAL;
-	if ((val && sp->do_auto_asconf) || (!val && !sp->do_auto_asconf))
+	if ((*val && sp->do_auto_asconf) || (!*val && !sp->do_auto_asconf))
 		return 0;
 
 	spin_lock_bh(&sock_net(sk)->sctp.addr_wq_lock);
-	if (val == 0 && sp->do_auto_asconf) {
+	if (*val == 0 && sp->do_auto_asconf) {
 		list_del(&sp->auto_asconf_list);
 		sp->do_auto_asconf = 0;
-	} else if (val && !sp->do_auto_asconf) {
+	} else if (*val && !sp->do_auto_asconf) {
 		list_add_tail(&sp->auto_asconf_list,
 		    &sock_net(sk)->sctp.auto_asconf_splist);
 		sp->do_auto_asconf = 1;
@@ -4690,7 +4687,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_deactivate_key(sk, kopt, optlen);
 		break;
 	case SCTP_AUTO_ASCONF:
-		retval = sctp_setsockopt_auto_asconf(sk, optval, optlen);
+		retval = sctp_setsockopt_auto_asconf(sk, kopt, optlen);
 		break;
 	case SCTP_PEER_ADDR_THLDS:
 		retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen,
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 32/51] sctp: pass a kernel pointer to sctp_setsockopt_paddr_thresholds
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (30 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 31/51] sctp: pass a kernel pointer to sctp_setsockopt_auto_asconf Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 33/51] sctp: pass a kernel pointer to sctp_setsockopt_recvrcvinfo Christoph Hellwig
                   ` (19 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 55 ++++++++++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 29 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 64f2a967ddf5d3..ea027ea74ba557 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3840,66 +3840,63 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, int *val,
  * http://www.ietf.org/id/draft-nishida-tsvwg-sctp-failover-05.txt
  */
 static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
-					    char __user *optval,
+					    struct sctp_paddrthlds_v2 *val,
 					    unsigned int optlen, bool v2)
 {
-	struct sctp_paddrthlds_v2 val;
 	struct sctp_transport *trans;
 	struct sctp_association *asoc;
 	int len;
 
-	len = v2 ? sizeof(val) : sizeof(struct sctp_paddrthlds);
+	len = v2 ? sizeof(*val) : sizeof(struct sctp_paddrthlds);
 	if (optlen < len)
 		return -EINVAL;
-	if (copy_from_user(&val, optval, len))
-		return -EFAULT;
 
-	if (v2 && val.spt_pathpfthld > val.spt_pathcpthld)
+	if (v2 && val->spt_pathpfthld > val->spt_pathcpthld)
 		return -EINVAL;
 
-	if (!sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
-		trans = sctp_addr_id2transport(sk, &val.spt_address,
-					       val.spt_assoc_id);
+	if (!sctp_is_any(sk, (const union sctp_addr *)&val->spt_address)) {
+		trans = sctp_addr_id2transport(sk, &val->spt_address,
+					       val->spt_assoc_id);
 		if (!trans)
 			return -ENOENT;
 
-		if (val.spt_pathmaxrxt)
-			trans->pathmaxrxt = val.spt_pathmaxrxt;
+		if (val->spt_pathmaxrxt)
+			trans->pathmaxrxt = val->spt_pathmaxrxt;
 		if (v2)
-			trans->ps_retrans = val.spt_pathcpthld;
-		trans->pf_retrans = val.spt_pathpfthld;
+			trans->ps_retrans = val->spt_pathcpthld;
+		trans->pf_retrans = val->spt_pathpfthld;
 
 		return 0;
 	}
 
-	asoc = sctp_id2assoc(sk, val.spt_assoc_id);
-	if (!asoc && val.spt_assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, val->spt_assoc_id);
+	if (!asoc && val->spt_assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc) {
 		list_for_each_entry(trans, &asoc->peer.transport_addr_list,
 				    transports) {
-			if (val.spt_pathmaxrxt)
-				trans->pathmaxrxt = val.spt_pathmaxrxt;
+			if (val->spt_pathmaxrxt)
+				trans->pathmaxrxt = val->spt_pathmaxrxt;
 			if (v2)
-				trans->ps_retrans = val.spt_pathcpthld;
-			trans->pf_retrans = val.spt_pathpfthld;
+				trans->ps_retrans = val->spt_pathcpthld;
+			trans->pf_retrans = val->spt_pathpfthld;
 		}
 
-		if (val.spt_pathmaxrxt)
-			asoc->pathmaxrxt = val.spt_pathmaxrxt;
+		if (val->spt_pathmaxrxt)
+			asoc->pathmaxrxt = val->spt_pathmaxrxt;
 		if (v2)
-			asoc->ps_retrans = val.spt_pathcpthld;
-		asoc->pf_retrans = val.spt_pathpfthld;
+			asoc->ps_retrans = val->spt_pathcpthld;
+		asoc->pf_retrans = val->spt_pathpfthld;
 	} else {
 		struct sctp_sock *sp = sctp_sk(sk);
 
-		if (val.spt_pathmaxrxt)
-			sp->pathmaxrxt = val.spt_pathmaxrxt;
+		if (val->spt_pathmaxrxt)
+			sp->pathmaxrxt = val->spt_pathmaxrxt;
 		if (v2)
-			sp->ps_retrans = val.spt_pathcpthld;
-		sp->pf_retrans = val.spt_pathpfthld;
+			sp->ps_retrans = val->spt_pathcpthld;
+		sp->pf_retrans = val->spt_pathpfthld;
 	}
 
 	return 0;
@@ -4690,11 +4687,11 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_auto_asconf(sk, kopt, optlen);
 		break;
 	case SCTP_PEER_ADDR_THLDS:
-		retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen,
+		retval = sctp_setsockopt_paddr_thresholds(sk, kopt, optlen,
 							  false);
 		break;
 	case SCTP_PEER_ADDR_THLDS_V2:
-		retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen,
+		retval = sctp_setsockopt_paddr_thresholds(sk, kopt, optlen,
 							  true);
 		break;
 	case SCTP_RECVRCVINFO:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 33/51] sctp: pass a kernel pointer to sctp_setsockopt_recvrcvinfo
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (31 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 32/51] sctp: pass a kernel pointer to sctp_setsockopt_paddr_thresholds Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 34/51] sctp: pass a kernel pointer to sctp_setsockopt_recvnxtinfo Christoph Hellwig
                   ` (18 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ea027ea74ba557..ac56fb7eb394f9 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3902,18 +3902,13 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
 	return 0;
 }
 
-static int sctp_setsockopt_recvrcvinfo(struct sock *sk,
-				       char __user *optval,
+static int sctp_setsockopt_recvrcvinfo(struct sock *sk, int *val,
 				       unsigned int optlen)
 {
-	int val;
-
 	if (optlen < sizeof(int))
 		return -EINVAL;
-	if (get_user(val, (int __user *) optval))
-		return -EFAULT;
 
-	sctp_sk(sk)->recvrcvinfo = (val == 0) ? 0 : 1;
+	sctp_sk(sk)->recvrcvinfo = (*val == 0) ? 0 : 1;
 
 	return 0;
 }
@@ -4695,7 +4690,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 							  true);
 		break;
 	case SCTP_RECVRCVINFO:
-		retval = sctp_setsockopt_recvrcvinfo(sk, optval, optlen);
+		retval = sctp_setsockopt_recvrcvinfo(sk, kopt, optlen);
 		break;
 	case SCTP_RECVNXTINFO:
 		retval = sctp_setsockopt_recvnxtinfo(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 34/51] sctp: pass a kernel pointer to sctp_setsockopt_recvnxtinfo
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (32 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 33/51] sctp: pass a kernel pointer to sctp_setsockopt_recvrcvinfo Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 35/51] sctp: pass a kernel pointer to sctp_setsockopt_pr_supported Christoph Hellwig
                   ` (17 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ac56fb7eb394f9..7beb26e5749d7e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3913,18 +3913,13 @@ static int sctp_setsockopt_recvrcvinfo(struct sock *sk, int *val,
 	return 0;
 }
 
-static int sctp_setsockopt_recvnxtinfo(struct sock *sk,
-				       char __user *optval,
+static int sctp_setsockopt_recvnxtinfo(struct sock *sk, int *val,
 				       unsigned int optlen)
 {
-	int val;
-
 	if (optlen < sizeof(int))
 		return -EINVAL;
-	if (get_user(val, (int __user *) optval))
-		return -EFAULT;
 
-	sctp_sk(sk)->recvnxtinfo = (val == 0) ? 0 : 1;
+	sctp_sk(sk)->recvnxtinfo = (*val == 0) ? 0 : 1;
 
 	return 0;
 }
@@ -4693,7 +4688,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_recvrcvinfo(sk, kopt, optlen);
 		break;
 	case SCTP_RECVNXTINFO:
-		retval = sctp_setsockopt_recvnxtinfo(sk, optval, optlen);
+		retval = sctp_setsockopt_recvnxtinfo(sk, kopt, optlen);
 		break;
 	case SCTP_PR_SUPPORTED:
 		retval = sctp_setsockopt_pr_supported(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 35/51] sctp: pass a kernel pointer to sctp_setsockopt_pr_supported
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (33 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 34/51] sctp: pass a kernel pointer to sctp_setsockopt_recvnxtinfo Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 36/51] sctp: pass a kernel pointer to sctp_setsockopt_default_prinfo Christoph Hellwig
                   ` (16 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 7beb26e5749d7e..245186327896b3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3925,24 +3925,20 @@ static int sctp_setsockopt_recvnxtinfo(struct sock *sk, int *val,
 }
 
 static int sctp_setsockopt_pr_supported(struct sock *sk,
-					char __user *optval,
+					struct sctp_assoc_value *params,
 					unsigned int optlen)
 {
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
 
-	if (optlen != sizeof(params))
+	if (optlen != sizeof(*params))
 		return -EINVAL;
 
-	if (copy_from_user(&params, optval, optlen))
-		return -EFAULT;
-
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
-	sctp_sk(sk)->ep->prsctp_enable = !!params.assoc_value;
+	sctp_sk(sk)->ep->prsctp_enable = !!params->assoc_value;
 
 	return 0;
 }
@@ -4691,7 +4687,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_recvnxtinfo(sk, kopt, optlen);
 		break;
 	case SCTP_PR_SUPPORTED:
-		retval = sctp_setsockopt_pr_supported(sk, optval, optlen);
+		retval = sctp_setsockopt_pr_supported(sk, kopt, optlen);
 		break;
 	case SCTP_DEFAULT_PRINFO:
 		retval = sctp_setsockopt_default_prinfo(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 36/51] sctp: pass a kernel pointer to sctp_setsockopt_default_prinfo
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (34 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 35/51] sctp: pass a kernel pointer to sctp_setsockopt_pr_supported Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 37/51] sctp: pass a kernel pointer to sctp_setsockopt_reconfig_supported Christoph Hellwig
                   ` (15 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 45 ++++++++++++++++++++-------------------------
 1 file changed, 20 insertions(+), 25 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 245186327896b3..0eeb6e6162ad61 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3944,55 +3944,50 @@ static int sctp_setsockopt_pr_supported(struct sock *sk,
 }
 
 static int sctp_setsockopt_default_prinfo(struct sock *sk,
-					  char __user *optval,
+					  struct sctp_default_prinfo *info,
 					  unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
-	struct sctp_default_prinfo info;
 	struct sctp_association *asoc;
 	int retval = -EINVAL;
 
-	if (optlen != sizeof(info))
-		goto out;
-
-	if (copy_from_user(&info, optval, sizeof(info))) {
-		retval = -EFAULT;
+	if (optlen != sizeof(*info))
 		goto out;
-	}
 
-	if (info.pr_policy & ~SCTP_PR_SCTP_MASK)
+	if (info->pr_policy & ~SCTP_PR_SCTP_MASK)
 		goto out;
 
-	if (info.pr_policy == SCTP_PR_SCTP_NONE)
-		info.pr_value = 0;
+	if (info->pr_policy == SCTP_PR_SCTP_NONE)
+		info->pr_value = 0;
 
-	asoc = sctp_id2assoc(sk, info.pr_assoc_id);
-	if (!asoc && info.pr_assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, info->pr_assoc_id);
+	if (!asoc && info->pr_assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		goto out;
 
 	retval = 0;
 
 	if (asoc) {
-		SCTP_PR_SET_POLICY(asoc->default_flags, info.pr_policy);
-		asoc->default_timetolive = info.pr_value;
+		SCTP_PR_SET_POLICY(asoc->default_flags, info->pr_policy);
+		asoc->default_timetolive = info->pr_value;
 		goto out;
 	}
 
 	if (sctp_style(sk, TCP))
-		info.pr_assoc_id = SCTP_FUTURE_ASSOC;
+		info->pr_assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (info.pr_assoc_id == SCTP_FUTURE_ASSOC ||
-	    info.pr_assoc_id == SCTP_ALL_ASSOC) {
-		SCTP_PR_SET_POLICY(sp->default_flags, info.pr_policy);
-		sp->default_timetolive = info.pr_value;
+	if (info->pr_assoc_id == SCTP_FUTURE_ASSOC ||
+	    info->pr_assoc_id == SCTP_ALL_ASSOC) {
+		SCTP_PR_SET_POLICY(sp->default_flags, info->pr_policy);
+		sp->default_timetolive = info->pr_value;
 	}
 
-	if (info.pr_assoc_id == SCTP_CURRENT_ASSOC ||
-	    info.pr_assoc_id == SCTP_ALL_ASSOC) {
+	if (info->pr_assoc_id == SCTP_CURRENT_ASSOC ||
+	    info->pr_assoc_id == SCTP_ALL_ASSOC) {
 		list_for_each_entry(asoc, &sp->ep->asocs, asocs) {
-			SCTP_PR_SET_POLICY(asoc->default_flags, info.pr_policy);
-			asoc->default_timetolive = info.pr_value;
+			SCTP_PR_SET_POLICY(asoc->default_flags,
+					   info->pr_policy);
+			asoc->default_timetolive = info->pr_value;
 		}
 	}
 
@@ -4690,7 +4685,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_pr_supported(sk, kopt, optlen);
 		break;
 	case SCTP_DEFAULT_PRINFO:
-		retval = sctp_setsockopt_default_prinfo(sk, optval, optlen);
+		retval = sctp_setsockopt_default_prinfo(sk, kopt, optlen);
 		break;
 	case SCTP_RECONFIG_SUPPORTED:
 		retval = sctp_setsockopt_reconfig_supported(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 37/51] sctp: pass a kernel pointer to sctp_setsockopt_reconfig_supported
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (35 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 36/51] sctp: pass a kernel pointer to sctp_setsockopt_default_prinfo Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 38/51] sctp: pass a kernel pointer to sctp_setsockopt_enable_strreset Christoph Hellwig
                   ` (14 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 0eeb6e6162ad61..270c5d53fbf7c3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3996,27 +3996,21 @@ static int sctp_setsockopt_default_prinfo(struct sock *sk,
 }
 
 static int sctp_setsockopt_reconfig_supported(struct sock *sk,
-					      char __user *optval,
+					      struct sctp_assoc_value *params,
 					      unsigned int optlen)
 {
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
 	int retval = -EINVAL;
 
-	if (optlen != sizeof(params))
-		goto out;
-
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
+	if (optlen != sizeof(*params))
 		goto out;
-	}
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		goto out;
 
-	sctp_sk(sk)->ep->reconf_enable = !!params.assoc_value;
+	sctp_sk(sk)->ep->reconf_enable = !!params->assoc_value;
 
 	retval = 0;
 
@@ -4688,7 +4682,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_default_prinfo(sk, kopt, optlen);
 		break;
 	case SCTP_RECONFIG_SUPPORTED:
-		retval = sctp_setsockopt_reconfig_supported(sk, optval, optlen);
+		retval = sctp_setsockopt_reconfig_supported(sk, kopt, optlen);
 		break;
 	case SCTP_ENABLE_STREAM_RESET:
 		retval = sctp_setsockopt_enable_strreset(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 38/51] sctp: pass a kernel pointer to sctp_setsockopt_enable_strreset
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (36 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 37/51] sctp: pass a kernel pointer to sctp_setsockopt_reconfig_supported Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 39/51] sctp: pass a kernel pointer to sctp_setsockopt_reset_streams Christoph Hellwig
                   ` (13 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 34 ++++++++++++++--------------------
 1 file changed, 14 insertions(+), 20 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 270c5d53fbf7c3..9899d208f40f8d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4019,48 +4019,42 @@ static int sctp_setsockopt_reconfig_supported(struct sock *sk,
 }
 
 static int sctp_setsockopt_enable_strreset(struct sock *sk,
-					   char __user *optval,
+					   struct sctp_assoc_value *params,
 					   unsigned int optlen)
 {
 	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
 	int retval = -EINVAL;
 
-	if (optlen != sizeof(params))
-		goto out;
-
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
+	if (optlen != sizeof(*params))
 		goto out;
-	}
 
-	if (params.assoc_value & (~SCTP_ENABLE_STRRESET_MASK))
+	if (params->assoc_value & (~SCTP_ENABLE_STRRESET_MASK))
 		goto out;
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		goto out;
 
 	retval = 0;
 
 	if (asoc) {
-		asoc->strreset_enable = params.assoc_value;
+		asoc->strreset_enable = params->assoc_value;
 		goto out;
 	}
 
 	if (sctp_style(sk, TCP))
-		params.assoc_id = SCTP_FUTURE_ASSOC;
+		params->assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (params.assoc_id == SCTP_FUTURE_ASSOC ||
-	    params.assoc_id == SCTP_ALL_ASSOC)
-		ep->strreset_enable = params.assoc_value;
+	if (params->assoc_id == SCTP_FUTURE_ASSOC ||
+	    params->assoc_id == SCTP_ALL_ASSOC)
+		ep->strreset_enable = params->assoc_value;
 
-	if (params.assoc_id == SCTP_CURRENT_ASSOC ||
-	    params.assoc_id == SCTP_ALL_ASSOC)
+	if (params->assoc_id == SCTP_CURRENT_ASSOC ||
+	    params->assoc_id == SCTP_ALL_ASSOC)
 		list_for_each_entry(asoc, &ep->asocs, asocs)
-			asoc->strreset_enable = params.assoc_value;
+			asoc->strreset_enable = params->assoc_value;
 
 out:
 	return retval;
@@ -4685,7 +4679,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_reconfig_supported(sk, kopt, optlen);
 		break;
 	case SCTP_ENABLE_STREAM_RESET:
-		retval = sctp_setsockopt_enable_strreset(sk, optval, optlen);
+		retval = sctp_setsockopt_enable_strreset(sk, kopt, optlen);
 		break;
 	case SCTP_RESET_STREAMS:
 		retval = sctp_setsockopt_reset_streams(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 39/51] sctp: pass a kernel pointer to sctp_setsockopt_reset_streams
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (37 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 38/51] sctp: pass a kernel pointer to sctp_setsockopt_enable_strreset Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 40/51] sctp: pass a kernel pointer to sctp_setsockopt_reset_assoc Christoph Hellwig
                   ` (12 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9899d208f40f8d..1365351fd2c86a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4061,12 +4061,10 @@ static int sctp_setsockopt_enable_strreset(struct sock *sk,
 }
 
 static int sctp_setsockopt_reset_streams(struct sock *sk,
-					 char __user *optval,
+					 struct sctp_reset_streams *params,
 					 unsigned int optlen)
 {
-	struct sctp_reset_streams *params;
 	struct sctp_association *asoc;
-	int retval = -EINVAL;
 
 	if (optlen < sizeof(*params))
 		return -EINVAL;
@@ -4074,23 +4072,15 @@ static int sctp_setsockopt_reset_streams(struct sock *sk,
 	optlen = min_t(unsigned int, optlen, USHRT_MAX +
 					     sizeof(__u16) * sizeof(*params));
 
-	params = memdup_user(optval, optlen);
-	if (IS_ERR(params))
-		return PTR_ERR(params);
-
 	if (params->srs_number_streams * sizeof(__u16) >
 	    optlen - sizeof(*params))
-		goto out;
+		return -EINVAL;
 
 	asoc = sctp_id2assoc(sk, params->srs_assoc_id);
 	if (!asoc)
-		goto out;
-
-	retval = sctp_send_reset_streams(asoc, params);
+		return -EINVAL;
 
-out:
-	kfree(params);
-	return retval;
+	return sctp_send_reset_streams(asoc, params);
 }
 
 static int sctp_setsockopt_reset_assoc(struct sock *sk,
@@ -4682,7 +4672,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_enable_strreset(sk, kopt, optlen);
 		break;
 	case SCTP_RESET_STREAMS:
-		retval = sctp_setsockopt_reset_streams(sk, optval, optlen);
+		retval = sctp_setsockopt_reset_streams(sk, kopt, optlen);
 		break;
 	case SCTP_RESET_ASSOC:
 		retval = sctp_setsockopt_reset_assoc(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 40/51] sctp: pass a kernel pointer to sctp_setsockopt_reset_assoc
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (38 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 39/51] sctp: pass a kernel pointer to sctp_setsockopt_reset_streams Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 41/51] sctp: pass a kernel pointer to sctp_setsockopt_add_streams Christoph Hellwig
                   ` (11 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 1365351fd2c86a..f190f59f29595a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4083,30 +4083,19 @@ static int sctp_setsockopt_reset_streams(struct sock *sk,
 	return sctp_send_reset_streams(asoc, params);
 }
 
-static int sctp_setsockopt_reset_assoc(struct sock *sk,
-				       char __user *optval,
+static int sctp_setsockopt_reset_assoc(struct sock *sk, sctp_assoc_t *associd,
 				       unsigned int optlen)
 {
 	struct sctp_association *asoc;
-	sctp_assoc_t associd;
-	int retval = -EINVAL;
-
-	if (optlen != sizeof(associd))
-		goto out;
 
-	if (copy_from_user(&associd, optval, optlen)) {
-		retval = -EFAULT;
-		goto out;
-	}
+	if (optlen != sizeof(*associd))
+		return -EINVAL;
 
-	asoc = sctp_id2assoc(sk, associd);
+	asoc = sctp_id2assoc(sk, *associd);
 	if (!asoc)
-		goto out;
-
-	retval = sctp_send_reset_assoc(asoc);
+		return -EINVAL;
 
-out:
-	return retval;
+	return sctp_send_reset_assoc(asoc);
 }
 
 static int sctp_setsockopt_add_streams(struct sock *sk,
@@ -4675,7 +4664,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_reset_streams(sk, kopt, optlen);
 		break;
 	case SCTP_RESET_ASSOC:
-		retval = sctp_setsockopt_reset_assoc(sk, optval, optlen);
+		retval = sctp_setsockopt_reset_assoc(sk, kopt, optlen);
 		break;
 	case SCTP_ADD_STREAMS:
 		retval = sctp_setsockopt_add_streams(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 41/51] sctp: pass a kernel pointer to sctp_setsockopt_add_streams
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (39 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 40/51] sctp: pass a kernel pointer to sctp_setsockopt_reset_assoc Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 42/51] sctp: pass a kernel pointer to sctp_setsockopt_scheduler Christoph Hellwig
                   ` (10 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f190f59f29595a..4dedb94bca7714 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4099,29 +4099,19 @@ static int sctp_setsockopt_reset_assoc(struct sock *sk, sctp_assoc_t *associd,
 }
 
 static int sctp_setsockopt_add_streams(struct sock *sk,
-				       char __user *optval,
+				       struct sctp_add_streams *params,
 				       unsigned int optlen)
 {
 	struct sctp_association *asoc;
-	struct sctp_add_streams params;
-	int retval = -EINVAL;
-
-	if (optlen != sizeof(params))
-		goto out;
 
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
-		goto out;
-	}
+	if (optlen != sizeof(*params))
+		return -EINVAL;
 
-	asoc = sctp_id2assoc(sk, params.sas_assoc_id);
+	asoc = sctp_id2assoc(sk, params->sas_assoc_id);
 	if (!asoc)
-		goto out;
-
-	retval = sctp_send_add_streams(asoc, &params);
+		return -EINVAL;
 
-out:
-	return retval;
+	return sctp_send_add_streams(asoc, params);
 }
 
 static int sctp_setsockopt_scheduler(struct sock *sk,
@@ -4667,7 +4657,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_reset_assoc(sk, kopt, optlen);
 		break;
 	case SCTP_ADD_STREAMS:
-		retval = sctp_setsockopt_add_streams(sk, optval, optlen);
+		retval = sctp_setsockopt_add_streams(sk, kopt, optlen);
 		break;
 	case SCTP_STREAM_SCHEDULER:
 		retval = sctp_setsockopt_scheduler(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 42/51] sctp: pass a kernel pointer to sctp_setsockopt_scheduler
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (40 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 41/51] sctp: pass a kernel pointer to sctp_setsockopt_add_streams Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 43/51] sctp: pass a kernel pointer to sctp_setsockopt_scheduler_value Christoph Hellwig
                   ` (9 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 4dedb94bca7714..a7d6a66fbe2113 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4115,44 +4115,39 @@ static int sctp_setsockopt_add_streams(struct sock *sk,
 }
 
 static int sctp_setsockopt_scheduler(struct sock *sk,
-				     char __user *optval,
+				     struct sctp_assoc_value *params,
 				     unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_association *asoc;
-	struct sctp_assoc_value params;
 	int retval = 0;
 
-	if (optlen < sizeof(params))
+	if (optlen < sizeof(*params))
 		return -EINVAL;
 
-	optlen = sizeof(params);
-	if (copy_from_user(&params, optval, optlen))
-		return -EFAULT;
-
-	if (params.assoc_value > SCTP_SS_MAX)
+	if (params->assoc_value > SCTP_SS_MAX)
 		return -EINVAL;
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc)
-		return sctp_sched_set_sched(asoc, params.assoc_value);
+		return sctp_sched_set_sched(asoc, params->assoc_value);
 
 	if (sctp_style(sk, TCP))
-		params.assoc_id = SCTP_FUTURE_ASSOC;
+		params->assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (params.assoc_id == SCTP_FUTURE_ASSOC ||
-	    params.assoc_id == SCTP_ALL_ASSOC)
-		sp->default_ss = params.assoc_value;
+	if (params->assoc_id == SCTP_FUTURE_ASSOC ||
+	    params->assoc_id == SCTP_ALL_ASSOC)
+		sp->default_ss = params->assoc_value;
 
-	if (params.assoc_id == SCTP_CURRENT_ASSOC ||
-	    params.assoc_id == SCTP_ALL_ASSOC) {
+	if (params->assoc_id == SCTP_CURRENT_ASSOC ||
+	    params->assoc_id == SCTP_ALL_ASSOC) {
 		list_for_each_entry(asoc, &sp->ep->asocs, asocs) {
 			int ret = sctp_sched_set_sched(asoc,
-						       params.assoc_value);
+						       params->assoc_value);
 
 			if (ret && !retval)
 				retval = ret;
@@ -4660,7 +4655,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_add_streams(sk, kopt, optlen);
 		break;
 	case SCTP_STREAM_SCHEDULER:
-		retval = sctp_setsockopt_scheduler(sk, optval, optlen);
+		retval = sctp_setsockopt_scheduler(sk, kopt, optlen);
 		break;
 	case SCTP_STREAM_SCHEDULER_VALUE:
 		retval = sctp_setsockopt_scheduler_value(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 43/51] sctp: pass a kernel pointer to sctp_setsockopt_scheduler_value
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (41 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 42/51] sctp: pass a kernel pointer to sctp_setsockopt_scheduler Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 44/51] sctp: pass a kernel pointer to sctp_setsockopt_interleaving_supported Christoph Hellwig
                   ` (8 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index a7d6a66fbe2113..4b660e6bf3bb54 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4158,38 +4158,32 @@ static int sctp_setsockopt_scheduler(struct sock *sk,
 }
 
 static int sctp_setsockopt_scheduler_value(struct sock *sk,
-					   char __user *optval,
+					   struct sctp_stream_value *params,
 					   unsigned int optlen)
 {
-	struct sctp_stream_value params;
 	struct sctp_association *asoc;
 	int retval = -EINVAL;
 
-	if (optlen < sizeof(params))
-		goto out;
-
-	optlen = sizeof(params);
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
+	if (optlen < sizeof(*params))
 		goto out;
-	}
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_CURRENT_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id != SCTP_CURRENT_ASSOC &&
 	    sctp_style(sk, UDP))
 		goto out;
 
 	if (asoc) {
-		retval = sctp_sched_set_value(asoc, params.stream_id,
-					      params.stream_value, GFP_KERNEL);
+		retval = sctp_sched_set_value(asoc, params->stream_id,
+					      params->stream_value, GFP_KERNEL);
 		goto out;
 	}
 
 	retval = 0;
 
 	list_for_each_entry(asoc, &sctp_sk(sk)->ep->asocs, asocs) {
-		int ret = sctp_sched_set_value(asoc, params.stream_id,
-					       params.stream_value, GFP_KERNEL);
+		int ret = sctp_sched_set_value(asoc, params->stream_id,
+					       params->stream_value,
+					       GFP_KERNEL);
 		if (ret && !retval) /* try to return the 1st error. */
 			retval = ret;
 	}
@@ -4658,7 +4652,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_scheduler(sk, kopt, optlen);
 		break;
 	case SCTP_STREAM_SCHEDULER_VALUE:
-		retval = sctp_setsockopt_scheduler_value(sk, optval, optlen);
+		retval = sctp_setsockopt_scheduler_value(sk, kopt, optlen);
 		break;
 	case SCTP_INTERLEAVING_SUPPORTED:
 		retval = sctp_setsockopt_interleaving_supported(sk, optval,
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 44/51] sctp: pass a kernel pointer to sctp_setsockopt_interleaving_supported
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (42 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 43/51] sctp: pass a kernel pointer to sctp_setsockopt_scheduler_value Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 45/51] sctp: pass a kernel pointer to sctp_setsockopt_reuse_port Christoph Hellwig
                   ` (7 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 34 ++++++++++------------------------
 1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 4b660e6bf3bb54..6232e46c4cdebd 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4193,39 +4193,25 @@ static int sctp_setsockopt_scheduler_value(struct sock *sk,
 }
 
 static int sctp_setsockopt_interleaving_supported(struct sock *sk,
-						  char __user *optval,
+						  struct sctp_assoc_value *p,
 						  unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
-	int retval = -EINVAL;
 
-	if (optlen < sizeof(params))
-		goto out;
-
-	optlen = sizeof(params);
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
-		goto out;
-	}
+	if (optlen < sizeof(*p))
+		return -EINVAL;
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
-	    sctp_style(sk, UDP))
-		goto out;
+	asoc = sctp_id2assoc(sk, p->assoc_id);
+	if (!asoc && p->assoc_id != SCTP_FUTURE_ASSOC && sctp_style(sk, UDP))
+		return -EINVAL;
 
 	if (!sock_net(sk)->sctp.intl_enable || !sp->frag_interleave) {
-		retval = -EPERM;
-		goto out;
+		return -EPERM;
 	}
 
-	sp->ep->intl_enable = !!params.assoc_value;
-
-	retval = 0;
-
-out:
-	return retval;
+	sp->ep->intl_enable = !!p->assoc_value;
+	return 0;
 }
 
 static int sctp_setsockopt_reuse_port(struct sock *sk, char __user *optval,
@@ -4655,7 +4641,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_scheduler_value(sk, kopt, optlen);
 		break;
 	case SCTP_INTERLEAVING_SUPPORTED:
-		retval = sctp_setsockopt_interleaving_supported(sk, optval,
+		retval = sctp_setsockopt_interleaving_supported(sk, kopt,
 								optlen);
 		break;
 	case SCTP_REUSE_PORT:
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 45/51] sctp: pass a kernel pointer to sctp_setsockopt_reuse_port
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (43 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 44/51] sctp: pass a kernel pointer to sctp_setsockopt_interleaving_supported Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 46/51] sctp: pass a kernel pointer to sctp_setsockopt_event Christoph Hellwig
                   ` (6 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6232e46c4cdebd..a5b95e68cc129f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4214,11 +4214,9 @@ static int sctp_setsockopt_interleaving_supported(struct sock *sk,
 	return 0;
 }
 
-static int sctp_setsockopt_reuse_port(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_reuse_port(struct sock *sk, int *val,
 				      unsigned int optlen)
 {
-	int val;
-
 	if (!sctp_style(sk, TCP))
 		return -EOPNOTSUPP;
 
@@ -4228,10 +4226,7 @@ static int sctp_setsockopt_reuse_port(struct sock *sk, char __user *optval,
 	if (optlen < sizeof(int))
 		return -EINVAL;
 
-	if (get_user(val, (int __user *)optval))
-		return -EFAULT;
-
-	sctp_sk(sk)->reuse = !!val;
+	sctp_sk(sk)->reuse = !!*val;
 
 	return 0;
 }
@@ -4645,7 +4640,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 								optlen);
 		break;
 	case SCTP_REUSE_PORT:
-		retval = sctp_setsockopt_reuse_port(sk, optval, optlen);
+		retval = sctp_setsockopt_reuse_port(sk, kopt, optlen);
 		break;
 	case SCTP_EVENT:
 		retval = sctp_setsockopt_event(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 46/51] sctp: pass a kernel pointer to sctp_setsockopt_event
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (44 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 45/51] sctp: pass a kernel pointer to sctp_setsockopt_reuse_port Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 47/51] " Christoph Hellwig
                   ` (5 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index a5b95e68cc129f..12a33fc42eeeb2 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4252,45 +4252,40 @@ static int sctp_assoc_ulpevent_type_set(struct sctp_event *param,
 	return 0;
 }
 
-static int sctp_setsockopt_event(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_event(struct sock *sk, struct sctp_event *param,
 				 unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_association *asoc;
-	struct sctp_event param;
 	int retval = 0;
 
-	if (optlen < sizeof(param))
+	if (optlen < sizeof(*param))
 		return -EINVAL;
 
-	optlen = sizeof(param);
-	if (copy_from_user(&param, optval, optlen))
-		return -EFAULT;
-
-	if (param.se_type < SCTP_SN_TYPE_BASE ||
-	    param.se_type > SCTP_SN_TYPE_MAX)
+	if (param->se_type < SCTP_SN_TYPE_BASE ||
+	    param->se_type > SCTP_SN_TYPE_MAX)
 		return -EINVAL;
 
-	asoc = sctp_id2assoc(sk, param.se_assoc_id);
-	if (!asoc && param.se_assoc_id > SCTP_ALL_ASSOC &&
+	asoc = sctp_id2assoc(sk, param->se_assoc_id);
+	if (!asoc && param->se_assoc_id > SCTP_ALL_ASSOC &&
 	    sctp_style(sk, UDP))
 		return -EINVAL;
 
 	if (asoc)
-		return sctp_assoc_ulpevent_type_set(&param, asoc);
+		return sctp_assoc_ulpevent_type_set(param, asoc);
 
 	if (sctp_style(sk, TCP))
-		param.se_assoc_id = SCTP_FUTURE_ASSOC;
+		param->se_assoc_id = SCTP_FUTURE_ASSOC;
 
-	if (param.se_assoc_id == SCTP_FUTURE_ASSOC ||
-	    param.se_assoc_id == SCTP_ALL_ASSOC)
+	if (param->se_assoc_id == SCTP_FUTURE_ASSOC ||
+	    param->se_assoc_id == SCTP_ALL_ASSOC)
 		sctp_ulpevent_type_set(&sp->subscribe,
-				       param.se_type, param.se_on);
+				       param->se_type, param->se_on);
 
-	if (param.se_assoc_id == SCTP_CURRENT_ASSOC ||
-	    param.se_assoc_id == SCTP_ALL_ASSOC) {
+	if (param->se_assoc_id == SCTP_CURRENT_ASSOC ||
+	    param->se_assoc_id == SCTP_ALL_ASSOC) {
 		list_for_each_entry(asoc, &sp->ep->asocs, asocs) {
-			int ret = sctp_assoc_ulpevent_type_set(&param, asoc);
+			int ret = sctp_assoc_ulpevent_type_set(param, asoc);
 
 			if (ret && !retval)
 				retval = ret;
@@ -4643,7 +4638,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_reuse_port(sk, kopt, optlen);
 		break;
 	case SCTP_EVENT:
-		retval = sctp_setsockopt_event(sk, optval, optlen);
+		retval = sctp_setsockopt_event(sk, kopt, optlen);
 		break;
 	case SCTP_ASCONF_SUPPORTED:
 		retval = sctp_setsockopt_asconf_supported(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 47/51] sctp: pass a kernel pointer to sctp_setsockopt_event
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (45 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 46/51] sctp: pass a kernel pointer to sctp_setsockopt_event Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 48/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_supported Christoph Hellwig
                   ` (4 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 12a33fc42eeeb2..b52acbf231ab9e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4296,29 +4296,23 @@ static int sctp_setsockopt_event(struct sock *sk, struct sctp_event *param,
 }
 
 static int sctp_setsockopt_asconf_supported(struct sock *sk,
-					    char __user *optval,
+					    struct sctp_assoc_value *params,
 					    unsigned int optlen)
 {
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
 	struct sctp_endpoint *ep;
 	int retval = -EINVAL;
 
-	if (optlen != sizeof(params))
-		goto out;
-
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
+	if (optlen != sizeof(*params))
 		goto out;
-	}
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		goto out;
 
 	ep = sctp_sk(sk)->ep;
-	ep->asconf_enable = !!params.assoc_value;
+	ep->asconf_enable = !!params->assoc_value;
 
 	if (ep->asconf_enable && ep->auth_enable) {
 		sctp_auth_ep_add_chunkid(ep, SCTP_CID_ASCONF);
@@ -4641,7 +4635,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_event(sk, kopt, optlen);
 		break;
 	case SCTP_ASCONF_SUPPORTED:
-		retval = sctp_setsockopt_asconf_supported(sk, optval, optlen);
+		retval = sctp_setsockopt_asconf_supported(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_SUPPORTED:
 		retval = sctp_setsockopt_auth_supported(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 48/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_supported
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (46 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 47/51] " Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 49/51] sctp: pass a kernel pointer to sctp_setsockopt_ecn_supported Christoph Hellwig
                   ` (3 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b52acbf231ab9e..ca369447237a77 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4326,29 +4326,23 @@ static int sctp_setsockopt_asconf_supported(struct sock *sk,
 }
 
 static int sctp_setsockopt_auth_supported(struct sock *sk,
-					  char __user *optval,
+					  struct sctp_assoc_value *params,
 					  unsigned int optlen)
 {
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
 	struct sctp_endpoint *ep;
 	int retval = -EINVAL;
 
-	if (optlen != sizeof(params))
-		goto out;
-
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
+	if (optlen != sizeof(*params))
 		goto out;
-	}
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		goto out;
 
 	ep = sctp_sk(sk)->ep;
-	if (params.assoc_value) {
+	if (params->assoc_value) {
 		retval = sctp_auth_init(ep, GFP_KERNEL);
 		if (retval)
 			goto out;
@@ -4358,7 +4352,7 @@ static int sctp_setsockopt_auth_supported(struct sock *sk,
 		}
 	}
 
-	ep->auth_enable = !!params.assoc_value;
+	ep->auth_enable = !!params->assoc_value;
 	retval = 0;
 
 out:
@@ -4638,7 +4632,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_asconf_supported(sk, kopt, optlen);
 		break;
 	case SCTP_AUTH_SUPPORTED:
-		retval = sctp_setsockopt_auth_supported(sk, optval, optlen);
+		retval = sctp_setsockopt_auth_supported(sk, kopt, optlen);
 		break;
 	case SCTP_ECN_SUPPORTED:
 		retval = sctp_setsockopt_ecn_supported(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 49/51] sctp: pass a kernel pointer to sctp_setsockopt_ecn_supported
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (47 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 48/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_supported Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 50/51] sctp: pass a kernel pointer to sctp_setsockopt_pf_expose Christoph Hellwig
                   ` (2 subsequent siblings)
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ca369447237a77..9f7f9aa50d4bd7 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4360,27 +4360,21 @@ static int sctp_setsockopt_auth_supported(struct sock *sk,
 }
 
 static int sctp_setsockopt_ecn_supported(struct sock *sk,
-					 char __user *optval,
+					 struct sctp_assoc_value *params,
 					 unsigned int optlen)
 {
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
 	int retval = -EINVAL;
 
-	if (optlen != sizeof(params))
-		goto out;
-
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
+	if (optlen != sizeof(*params))
 		goto out;
-	}
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		goto out;
 
-	sctp_sk(sk)->ep->ecn_enable = !!params.assoc_value;
+	sctp_sk(sk)->ep->ecn_enable = !!params->assoc_value;
 	retval = 0;
 
 out:
@@ -4635,7 +4629,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_auth_supported(sk, kopt, optlen);
 		break;
 	case SCTP_ECN_SUPPORTED:
-		retval = sctp_setsockopt_ecn_supported(sk, optval, optlen);
+		retval = sctp_setsockopt_ecn_supported(sk, kopt, optlen);
 		break;
 	case SCTP_EXPOSE_POTENTIALLY_FAILED_STATE:
 		retval = sctp_setsockopt_pf_expose(sk, optval, optlen);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 50/51] sctp: pass a kernel pointer to sctp_setsockopt_pf_expose
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (48 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 49/51] sctp: pass a kernel pointer to sctp_setsockopt_ecn_supported Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-19  7:22 ` [PATCH 51/51] sctp: remove the out_nounlock label in sctp_setsockopt Christoph Hellwig
  2020-07-20  1:27 ` do a single memdup_user in sctp_setsockopt v2 David Miller
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Use the kernel pointer that sctp_setsockopt has available instead of
directly handling the user pointer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9f7f9aa50d4bd7..f2d4f8a0c426bb 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4382,33 +4382,27 @@ static int sctp_setsockopt_ecn_supported(struct sock *sk,
 }
 
 static int sctp_setsockopt_pf_expose(struct sock *sk,
-				     char __user *optval,
+				     struct sctp_assoc_value *params,
 				     unsigned int optlen)
 {
-	struct sctp_assoc_value params;
 	struct sctp_association *asoc;
 	int retval = -EINVAL;
 
-	if (optlen != sizeof(params))
-		goto out;
-
-	if (copy_from_user(&params, optval, optlen)) {
-		retval = -EFAULT;
+	if (optlen != sizeof(*params))
 		goto out;
-	}
 
-	if (params.assoc_value > SCTP_PF_EXPOSE_MAX)
+	if (params->assoc_value > SCTP_PF_EXPOSE_MAX)
 		goto out;
 
-	asoc = sctp_id2assoc(sk, params.assoc_id);
-	if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
+	asoc = sctp_id2assoc(sk, params->assoc_id);
+	if (!asoc && params->assoc_id != SCTP_FUTURE_ASSOC &&
 	    sctp_style(sk, UDP))
 		goto out;
 
 	if (asoc)
-		asoc->pf_expose = params.assoc_value;
+		asoc->pf_expose = params->assoc_value;
 	else
-		sctp_sk(sk)->pf_expose = params.assoc_value;
+		sctp_sk(sk)->pf_expose = params->assoc_value;
 	retval = 0;
 
 out:
@@ -4632,7 +4626,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 		retval = sctp_setsockopt_ecn_supported(sk, kopt, optlen);
 		break;
 	case SCTP_EXPOSE_POTENTIALLY_FAILED_STATE:
-		retval = sctp_setsockopt_pf_expose(sk, optval, optlen);
+		retval = sctp_setsockopt_pf_expose(sk, kopt, optlen);
 		break;
 	default:
 		retval = -ENOPROTOOPT;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 51/51] sctp: remove the out_nounlock label in sctp_setsockopt
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (49 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 50/51] sctp: pass a kernel pointer to sctp_setsockopt_pf_expose Christoph Hellwig
@ 2020-07-19  7:22 ` Christoph Hellwig
  2020-07-20  1:27 ` do a single memdup_user in sctp_setsockopt v2 David Miller
  51 siblings, 0 replies; 54+ messages in thread
From: Christoph Hellwig @ 2020-07-19  7:22 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

This is just used once, and a direct return for the redirect to the AF
case is much easier to follow than jumping to the end of a very long
function.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 net/sctp/socket.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f2d4f8a0c426bb..9a767f35971865 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4444,8 +4444,8 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 	 */
 	if (level != SOL_SCTP) {
 		struct sctp_af *af = sctp_sk(sk)->pf->af;
-		retval = af->setsockopt(sk, level, optname, optval, optlen);
-		goto out_nounlock;
+
+		return af->setsockopt(sk, level, optname, optval, optlen);
 	}
 
 	if (optlen > 0) {
@@ -4635,8 +4635,6 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 
 	release_sock(sk);
 	kfree(kopt);
-
-out_nounlock:
 	return retval;
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: do a single memdup_user in sctp_setsockopt v2
  2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
                   ` (50 preceding siblings ...)
  2020-07-19  7:22 ` [PATCH 51/51] sctp: remove the out_nounlock label in sctp_setsockopt Christoph Hellwig
@ 2020-07-20  1:27 ` David Miller
  2020-07-20 13:08   ` Marcelo Ricardo Leitner
  51 siblings, 1 reply; 54+ messages in thread
From: David Miller @ 2020-07-20  1:27 UTC (permalink / raw)
  To: hch
  Cc: vyasevich, nhorman, marcelo.leitner, kuba, David.Laight,
	linux-sctp, netdev

From: Christoph Hellwig <hch@lst.de>
Date: Sun, 19 Jul 2020 09:21:37 +0200

> here is a resend of my series to lift the copy_from_user out of the
> individual sctp sockopt handlers into the main sctp_setsockopt
> routine.
> 
> Changes since v1:
>  - fixes a few sizeof calls.
>  - use memzero_explicit in sctp_setsockopt_auth_key instead of special
>    casing it for a kzfree in the caller
>  - remove some minor cleanups from sctp_setsockopt_autoclose to keep
>    it closer to the existing version
>  - add another little only vaguely related cleanup patch

This is all very mechanical and contained to the sockopt code of SCTP,
so I reviewed this a few times and applied it to net-next.

Thanks Christoph!

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: do a single memdup_user in sctp_setsockopt v2
  2020-07-20  1:27 ` do a single memdup_user in sctp_setsockopt v2 David Miller
@ 2020-07-20 13:08   ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 54+ messages in thread
From: Marcelo Ricardo Leitner @ 2020-07-20 13:08 UTC (permalink / raw)
  To: David Miller
  Cc: hch, vyasevich, nhorman, kuba, David.Laight, linux-sctp, netdev

On Sun, Jul 19, 2020 at 06:27:27PM -0700, David Miller wrote:
> From: Christoph Hellwig <hch@lst.de>
> Date: Sun, 19 Jul 2020 09:21:37 +0200
> 
> > here is a resend of my series to lift the copy_from_user out of the
> > individual sctp sockopt handlers into the main sctp_setsockopt
> > routine.
> > 
> > Changes since v1:
> >  - fixes a few sizeof calls.
> >  - use memzero_explicit in sctp_setsockopt_auth_key instead of special
> >    casing it for a kzfree in the caller
> >  - remove some minor cleanups from sctp_setsockopt_autoclose to keep
> >    it closer to the existing version
> >  - add another little only vaguely related cleanup patch
> 
> This is all very mechanical and contained to the sockopt code of SCTP,
> so I reviewed this a few times and applied it to net-next.
> 
> Thanks Christoph!

Yep! And way easier to work with, function by function.

Just for the records,
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Thanks.

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2020-07-20 13:08 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-19  7:21 do a single memdup_user in sctp_setsockopt v2 Christoph Hellwig
2020-07-19  7:21 ` [PATCH 01/51] sctp: copy the optval from user space in sctp_setsockopt Christoph Hellwig
2020-07-19  7:21 ` [PATCH 02/51] sctp: pass a kernel pointer to sctp_setsockopt_bindx Christoph Hellwig
2020-07-19  7:21 ` [PATCH 03/51] sctp: pass a kernel pointer to __sctp_setsockopt_connectx Christoph Hellwig
2020-07-19  7:21 ` [PATCH 04/51] sctp: pass a kernel pointer to sctp_setsockopt_disable_fragments Christoph Hellwig
2020-07-19  7:21 ` [PATCH 05/51] sctp: pass a kernel pointer to sctp_setsockopt_events Christoph Hellwig
2020-07-19  7:21 ` [PATCH 06/51] sctp: pass a kernel pointer to sctp_setsockopt_autoclose Christoph Hellwig
2020-07-19  7:21 ` [PATCH 07/51] sctp: pass a kernel pointer to sctp_setsockopt_peer_addr_params Christoph Hellwig
2020-07-19  7:21 ` [PATCH 08/51] sctp: pass a kernel pointer to sctp_setsockopt_delayed_ack Christoph Hellwig
2020-07-19  7:21 ` [PATCH 09/51] sctp: pass a kernel pointer to sctp_setsockopt_partial_delivery_point Christoph Hellwig
2020-07-19  7:21 ` [PATCH 10/51] sctp: pass a kernel pointer to sctp_setsockopt_initmsg Christoph Hellwig
2020-07-19  7:21 ` [PATCH 11/51] sctp: pass a kernel pointer to sctp_setsockopt_default_send_param Christoph Hellwig
2020-07-19  7:21 ` [PATCH 12/51] sctp: pass a kernel pointer to sctp_setsockopt_default_sndinfo Christoph Hellwig
2020-07-19  7:21 ` [PATCH 13/51] sctp: pass a kernel pointer to sctp_setsockopt_primary_addr Christoph Hellwig
2020-07-19  7:21 ` [PATCH 14/51] sctp: pass a kernel pointer to sctp_setsockopt_peer_primary_addr Christoph Hellwig
2020-07-19  7:21 ` [PATCH 15/51] sctp: pass a kernel pointer to sctp_setsockopt_nodelay Christoph Hellwig
2020-07-19  7:21 ` [PATCH 16/51] sctp: pass a kernel pointer to sctp_setsockopt_rtoinfo Christoph Hellwig
2020-07-19  7:21 ` [PATCH 17/51] sctp: pass a kernel pointer to sctp_setsockopt_associnfo Christoph Hellwig
2020-07-19  7:21 ` [PATCH 18/51] sctp: pass a kernel pointer to sctp_setsockopt_mappedv4 Christoph Hellwig
2020-07-19  7:21 ` [PATCH 19/51] sctp: pass a kernel pointer to sctp_setsockopt_maxseg Christoph Hellwig
2020-07-19  7:21 ` [PATCH 20/51] sctp: pass a kernel pointer to sctp_setsockopt_adaptation_layer Christoph Hellwig
2020-07-19  7:21 ` [PATCH 21/51] sctp: pass a kernel pointer to sctp_setsockopt_context Christoph Hellwig
2020-07-19  7:21 ` [PATCH 22/51] sctp: pass a kernel pointer to sctp_setsockopt_fragment_interleave Christoph Hellwig
2020-07-19  7:22 ` [PATCH 23/51] sctp: pass a kernel pointer to sctp_setsockopt_maxburst Christoph Hellwig
2020-07-19  7:22 ` [PATCH 24/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_chunk Christoph Hellwig
2020-07-19  7:22 ` [PATCH 25/51] sctp: pass a kernel pointer to sctp_setsockopt_hmac_ident Christoph Hellwig
2020-07-19  7:22 ` [PATCH 26/51] sctp: switch sctp_setsockopt_auth_key to use memzero_explicit Christoph Hellwig
2020-07-19  7:22 ` [PATCH 27/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_key Christoph Hellwig
2020-07-19  7:22 ` [PATCH 28/51] sctp: pass a kernel pointer to sctp_setsockopt_active_key Christoph Hellwig
2020-07-19  7:22 ` [PATCH 29/51] sctp: pass a kernel pointer to sctp_setsockopt_del_key Christoph Hellwig
2020-07-19  7:22 ` [PATCH 30/51] sctp: pass a kernel pointer to sctp_setsockopt_deactivate_key Christoph Hellwig
2020-07-19  7:22 ` [PATCH 31/51] sctp: pass a kernel pointer to sctp_setsockopt_auto_asconf Christoph Hellwig
2020-07-19  7:22 ` [PATCH 32/51] sctp: pass a kernel pointer to sctp_setsockopt_paddr_thresholds Christoph Hellwig
2020-07-19  7:22 ` [PATCH 33/51] sctp: pass a kernel pointer to sctp_setsockopt_recvrcvinfo Christoph Hellwig
2020-07-19  7:22 ` [PATCH 34/51] sctp: pass a kernel pointer to sctp_setsockopt_recvnxtinfo Christoph Hellwig
2020-07-19  7:22 ` [PATCH 35/51] sctp: pass a kernel pointer to sctp_setsockopt_pr_supported Christoph Hellwig
2020-07-19  7:22 ` [PATCH 36/51] sctp: pass a kernel pointer to sctp_setsockopt_default_prinfo Christoph Hellwig
2020-07-19  7:22 ` [PATCH 37/51] sctp: pass a kernel pointer to sctp_setsockopt_reconfig_supported Christoph Hellwig
2020-07-19  7:22 ` [PATCH 38/51] sctp: pass a kernel pointer to sctp_setsockopt_enable_strreset Christoph Hellwig
2020-07-19  7:22 ` [PATCH 39/51] sctp: pass a kernel pointer to sctp_setsockopt_reset_streams Christoph Hellwig
2020-07-19  7:22 ` [PATCH 40/51] sctp: pass a kernel pointer to sctp_setsockopt_reset_assoc Christoph Hellwig
2020-07-19  7:22 ` [PATCH 41/51] sctp: pass a kernel pointer to sctp_setsockopt_add_streams Christoph Hellwig
2020-07-19  7:22 ` [PATCH 42/51] sctp: pass a kernel pointer to sctp_setsockopt_scheduler Christoph Hellwig
2020-07-19  7:22 ` [PATCH 43/51] sctp: pass a kernel pointer to sctp_setsockopt_scheduler_value Christoph Hellwig
2020-07-19  7:22 ` [PATCH 44/51] sctp: pass a kernel pointer to sctp_setsockopt_interleaving_supported Christoph Hellwig
2020-07-19  7:22 ` [PATCH 45/51] sctp: pass a kernel pointer to sctp_setsockopt_reuse_port Christoph Hellwig
2020-07-19  7:22 ` [PATCH 46/51] sctp: pass a kernel pointer to sctp_setsockopt_event Christoph Hellwig
2020-07-19  7:22 ` [PATCH 47/51] " Christoph Hellwig
2020-07-19  7:22 ` [PATCH 48/51] sctp: pass a kernel pointer to sctp_setsockopt_auth_supported Christoph Hellwig
2020-07-19  7:22 ` [PATCH 49/51] sctp: pass a kernel pointer to sctp_setsockopt_ecn_supported Christoph Hellwig
2020-07-19  7:22 ` [PATCH 50/51] sctp: pass a kernel pointer to sctp_setsockopt_pf_expose Christoph Hellwig
2020-07-19  7:22 ` [PATCH 51/51] sctp: remove the out_nounlock label in sctp_setsockopt Christoph Hellwig
2020-07-20  1:27 ` do a single memdup_user in sctp_setsockopt v2 David Miller
2020-07-20 13:08   ` Marcelo Ricardo Leitner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).