Netdev Archive on lore.kernel.org
 help / color / Atom feed
* do a single memdup_user in sctp_setsockopt
@ 2020-05-21 17:46 Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 01/49] sctp: copy the optval from user space " Christoph Hellwig
                   ` (50 more replies)
  0 siblings, 51 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, David Laight, linux-sctp, netdev

Hi all,

based on the review of Davids patch to do something similar I dusted off
the series I had started a few days ago to move the memdup_user or
copy_from_user from the inidividual sockopts into sctp_setsockopt,
which is done with one patch per option, so it might suit Marcelo's
taste a bit better.  I did not start any work on getsockopt.

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

* [PATCH 01/49] sctp: copy the optval from user space in sctp_setsockopt
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 02/49] sctp: pass a kernel pointer to sctp_setsockopt_bindx Christoph Hellwig
                   ` (49 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 827a9903ee288..ee6a618ee3e8e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4670,6 +4670,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);
@@ -4686,6 +4687,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) {
@@ -4871,6 +4878,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 	}
 
 	release_sock(sk);
+	kfree(kopt);
 
 out_nounlock:
 	return retval;
-- 
2.26.2


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

* [PATCH 02/49] sctp: pass a kernel pointer to sctp_setsockopt_bindx
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 01/49] sctp: copy the optval from user space " Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 03/49] sctp: pass a kernel pointer to __sctp_setsockopt_connectx Christoph Hellwig
                   ` (48 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 | 38 ++++++++++++--------------------------
 1 file changed, 12 insertions(+), 26 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ee6a618ee3e8e..eb08e44c0c57a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -972,42 +972,33 @@ int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
  * 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
  * op        Operation to perform (add or remove, see the flags of
  *           sctp_bindx)
  *
  * Returns 0 if ok, <0 errno code on error.
  */
-static int sctp_setsockopt_bindx(struct sock *sk,
-				 struct sockaddr __user *addrs,
-				 int addrs_size, int op)
+static int sctp_setsockopt_bindx(struct sock *sk, void *addr_buf,
+				  int addrs_size, int op)
 {
-	struct sockaddr *kaddrs;
+	struct sockaddr *kaddrs = addr_buf;
 	int err;
 	int addrcnt = 0;
 	int walk_size = 0;
 	struct sockaddr *sa_addr;
-	void *addr_buf;
 	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;
 
-	kaddrs = memdup_user(addrs, addrs_size);
-	if (IS_ERR(kaddrs))
-		return PTR_ERR(kaddrs);
-
 	/* Walk through the addrs buffer and count the number of addresses. */
-	addr_buf = kaddrs;
 	while (walk_size < addrs_size) {
-		if (walk_size + sizeof(sa_family_t) > addrs_size) {
-			kfree(kaddrs);
+		if (walk_size + sizeof(sa_family_t) > addrs_size)
 			return -EINVAL;
-		}
 
 		sa_addr = addr_buf;
 		af = sctp_get_af_specific(sa_addr->sa_family);
@@ -1015,10 +1006,8 @@ static int sctp_setsockopt_bindx(struct sock *sk,
 		/* If the address family is not supported or if this address
 		 * causes the address buffer to overflow return EINVAL.
 		 */
-		if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
-			kfree(kaddrs);
+		if (!af || (walk_size + af->sockaddr_len) > addrs_size)
 			return -EINVAL;
-		}
 		addrcnt++;
 		addr_buf += af->sockaddr_len;
 		walk_size += af->sockaddr_len;
@@ -1029,8 +1018,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
 	case SCTP_BINDX_ADD_ADDR:
 		/* Allow security module to validate bindx addresses. */
 		err = security_sctp_bind_connect(sk, SCTP_SOCKOPT_BINDX_ADD,
-						 (struct sockaddr *)kaddrs,
-						 addrs_size);
+						 kaddrs, addrs_size);
 		if (err)
 			goto out;
 		err = sctp_bindx_add(sk, kaddrs, addrcnt);
@@ -1052,8 +1040,6 @@ static int sctp_setsockopt_bindx(struct sock *sk,
 	}
 
 out:
-	kfree(kaddrs);
-
 	return err;
 }
 
@@ -4698,14 +4684,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.26.2


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

* [PATCH 03/49] sctp: pass a kernel pointer to __sctp_setsockopt_connectx
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 01/49] sctp: copy the optval from user space " Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 02/49] sctp: pass a kernel pointer to sctp_setsockopt_bindx Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 04/49] sctp: pass a kernel pointer to sctp_setsockopt_disable_fragments Christoph Hellwig
                   ` (47 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 eb08e44c0c57a..f7621ea99340e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1282,36 +1282,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().
@@ -1319,12 +1312,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);
 }
 
 /*
@@ -1332,10 +1320,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);
 }
 
 /*
@@ -1345,13 +1333,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;
@@ -1381,6 +1369,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
@@ -1404,9 +1393,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;
@@ -4696,16 +4688,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.26.2


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

* [PATCH 04/49] sctp: pass a kernel pointer to sctp_setsockopt_disable_fragments
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (2 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 03/49] sctp: pass a kernel pointer to __sctp_setsockopt_connectx Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 05/49] sctp: pass a kernel pointer to sctp_setsockopt_events Christoph Hellwig
                   ` (46 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 f7621ea99340e..0ca8001acfd50 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2180,20 +2180,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;
 }
 
@@ -4697,7 +4689,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.26.2


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

* [PATCH 05/49] sctp: pass a kernel pointer to sctp_setsockopt_events
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (3 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 04/49] sctp: pass a kernel pointer to sctp_setsockopt_disable_fragments Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 06/49] sctp: pass a kernel pointer to sctp_setsockopt_autoclose Christoph Hellwig
                   ` (45 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 0ca8001acfd50..34bd2ce2ddf66 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2189,11 +2189,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;
@@ -2201,9 +2199,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]);
@@ -4693,7 +4688,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.26.2


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

* [PATCH 06/49] sctp: pass a kernel pointer to sctp_setsockopt_autoclose
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (4 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 05/49] sctp: pass a kernel pointer to sctp_setsockopt_events Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 07/49] sctp: pass a kernel pointer to sctp_setsockopt_peer_addr_params Christoph Hellwig
                   ` (44 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 34bd2ce2ddf66..2fb3a5590a12e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2238,7 +2238,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 *autoclose,
 				     unsigned int optlen)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
@@ -2249,11 +2249,11 @@ 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;
-
-	if (sp->autoclose > net->sctp.max_autoclose)
+	
+	if (*autoclose > net->sctp.max_autoclose)
 		sp->autoclose = net->sctp.max_autoclose;
+	else
+		sp->autoclose = *autoclose;
 
 	return 0;
 }
@@ -4692,7 +4692,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.26.2


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

* [PATCH 07/49] sctp: pass a kernel pointer to sctp_setsockopt_peer_addr_params
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (5 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 06/49] sctp: pass a kernel pointer to sctp_setsockopt_autoclose Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 08/49] sctp: pass a kernel pointer to sctp_setsockopt_delayed_ack Christoph Hellwig
                   ` (43 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 2fb3a5590a12e..0498cf21923e8 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2586,48 +2586,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;
 	}
@@ -2636,19 +2630,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);
 
@@ -2661,7 +2655,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);
 		}
@@ -4696,7 +4690,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.26.2


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

* [PATCH 08/49] sctp: pass a kernel pointer to sctp_setsockopt_delayed_ack
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (6 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 07/49] sctp: pass a kernel pointer to sctp_setsockopt_peer_addr_params Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 09/49] sctp: pass a kernel pointer to sctp_setsockopt_partial_delivery_point Christoph Hellwig
                   ` (42 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 0498cf21923e8..3763f124f9fea 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2748,17 +2748,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
@@ -2766,59 +2763,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;
 }
@@ -4694,7 +4689,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.26.2


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

* [PATCH 09/49] sctp: pass a kernel pointer to sctp_setsockopt_partial_delivery_point
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (7 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 08/49] sctp: pass a kernel pointer to sctp_setsockopt_delayed_ack Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 10/49] sctp: pass a kernel pointer to sctp_setsockopt_initmsg Christoph Hellwig
                   ` (41 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 3763f124f9fea..6dd6b0cfcfe03 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3484,24 +3484,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? */
 }
@@ -4692,7 +4687,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.26.2


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

* [PATCH 10/49] sctp: pass a kernel pointer to sctp_setsockopt_initmsg
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (8 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 09/49] sctp: pass a kernel pointer to sctp_setsockopt_partial_delivery_point Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 11/49] sctp: pass a kernel pointer to sctp_setsockopt_default_send_param Christoph Hellwig
                   ` (40 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 6dd6b0cfcfe03..0180b22087c0b 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2829,24 +2829,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;
 }
@@ -4691,7 +4689,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.26.2


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

* [PATCH 11/49] sctp: pass a kernel pointer to sctp_setsockopt_default_send_param
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (9 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 10/49] sctp: pass a kernel pointer to sctp_setsockopt_initmsg Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 12/49] sctp: pass a kernel pointer to sctp_setsockopt_default_sndinfo Christoph Hellwig
                   ` (39 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 | 54 ++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 29 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 0180b22087c0b..acf1484cd62a1 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2864,57 +2864,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))
 		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;
 		}
 	}
 
@@ -4692,8 +4689,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.26.2


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

* [PATCH 12/49] sctp: pass a kernel pointer to sctp_setsockopt_default_sndinfo
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (10 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 11/49] sctp: pass a kernel pointer to sctp_setsockopt_default_send_param Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 13/49] sctp: pass a kernel pointer to sctp_setsockopt_primary_addr Christoph Hellwig
                   ` (38 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 | 47 ++++++++++++++++++++++-------------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index acf1484cd62a1..53bd58a5cc954 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2922,54 +2922,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))
 		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;
 		}
 	}
 
@@ -4692,7 +4689,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.26.2


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

* [PATCH 13/49] sctp: pass a kernel pointer to sctp_setsockopt_primary_addr
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (11 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 12/49] sctp: pass a kernel pointer to sctp_setsockopt_default_sndinfo Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 14/49] sctp: pass a kernel pointer to sctp_setsockopt_peer_primary_addr Christoph Hellwig
                   ` (37 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 53bd58a5cc954..df00342ac74f9 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2979,10 +2979,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;
@@ -2990,21 +2989,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;
 
@@ -4692,7 +4688,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.26.2


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

* [PATCH 14/49] sctp: pass a kernel pointer to sctp_setsockopt_peer_primary_addr
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (12 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 13/49] sctp: pass a kernel pointer to sctp_setsockopt_primary_addr Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 15/49] sctp: pass a kernel pointer to sctp_setsockopt_nodelay Christoph Hellwig
                   ` (36 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 df00342ac74f9..eb01992da7949 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3281,12 +3281,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;
@@ -3299,10 +3299,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;
 
@@ -3315,26 +3312,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;
 
@@ -4691,7 +4688,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.26.2


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

* [PATCH 15/49] sctp: pass a kernel pointer to sctp_setsockopt_nodelay
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (13 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 14/49] sctp: pass a kernel pointer to sctp_setsockopt_peer_primary_addr Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 16/49] sctp: pass a kernel pointer to sctp_setsockopt_rtoinfo Christoph Hellwig
                   ` (35 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 eb01992da7949..99df37bbcb903 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3017,17 +3017,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;
 }
 
@@ -4691,7 +4686,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.26.2


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

* [PATCH 16/49] sctp: pass a kernel pointer to sctp_setsockopt_rtoinfo
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (14 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 15/49] sctp: pass a kernel pointer to sctp_setsockopt_nodelay Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 17/49] sctp: pass a kernel pointer to sctp_setsockopt_associnfo Christoph Hellwig
                   ` (34 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 99df37bbcb903..7998b25a8a271 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3038,9 +3038,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);
@@ -3048,18 +3049,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;
@@ -3075,17 +3073,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;
 	}
@@ -4689,7 +4687,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.26.2


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

* [PATCH 17/49] sctp: pass a kernel pointer to sctp_setsockopt_associnfo
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (15 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 16/49] sctp: pass a kernel pointer to sctp_setsockopt_rtoinfo Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 18/49] sctp: pass a kernel pointer to sctp_setsockopt_mappedv4 Christoph Hellwig
                   ` (33 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 7998b25a8a271..161acd6253e06 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3102,26 +3102,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;
@@ -3138,24 +3137,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;
 }
@@ -4690,7 +4690,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.26.2


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

* [PATCH 18/49] sctp: pass a kernel pointer to sctp_setsockopt_mappedv4
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (16 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 17/49] sctp: pass a kernel pointer to sctp_setsockopt_associnfo Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 19/49] sctp: pass a kernel pointer to sctp_setsockopt_maxseg Christoph Hellwig
                   ` (32 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 161acd6253e06..41407d0ef2eca 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3170,16 +3170,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;
@@ -4693,7 +4691,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.26.2


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

* [PATCH 19/49] sctp: pass a kernel pointer to sctp_setsockopt_maxseg
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (17 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 18/49] sctp: pass a kernel pointer to sctp_setsockopt_mappedv4 Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 20/49] sctp: pass a kernel pointer to sctp_setsockopt_adaptation_layer Christoph Hellwig
                   ` (31 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 41407d0ef2eca..4374d4fff080a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3212,11 +3212,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)) {
@@ -3225,19 +3227,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;
 
@@ -4694,7 +4694,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.26.2


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

* [PATCH 20/49] sctp: pass a kernel pointer to sctp_setsockopt_adaptation_layer
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (18 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 19/49] sctp: pass a kernel pointer to sctp_setsockopt_maxseg Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 21/49] sctp: pass a kernel pointer to sctp_setsockopt_context Christoph Hellwig
                   ` (30 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 4374d4fff080a..b7bf09f86a5e7 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3333,17 +3333,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;
 }
@@ -4697,7 +4694,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.26.2


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

* [PATCH 21/49] sctp: pass a kernel pointer to sctp_setsockopt_context
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (19 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 20/49] sctp: pass a kernel pointer to sctp_setsockopt_adaptation_layer Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 22/49] sctp: pass a kernel pointer to sctp_setsockopt_fragment_interleave Christoph Hellwig
                   ` (29 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 b7bf09f86a5e7..03577684be65f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3359,40 +3359,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;
 }
@@ -4697,7 +4695,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.26.2


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

* [PATCH 22/49] sctp: pass a kernel pointer to sctp_setsockopt_fragment_interleave
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (20 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 21/49] sctp: pass a kernel pointer to sctp_setsockopt_context Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 23/49] sctp: pass a kernel pointer to sctp_setsockopt_maxburst Christoph Hellwig
                   ` (28 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 03577684be65f..249a87014e879 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3419,18 +3419,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;
@@ -4698,7 +4693,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.26.2


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

* [PATCH 23/49] sctp: pass a kernel pointer to sctp_setsockopt_maxburst
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (21 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 22/49] sctp: pass a kernel pointer to sctp_setsockopt_fragment_interleave Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:46 ` [PATCH 24/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_chunk Christoph Hellwig
                   ` (27 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 249a87014e879..e62e8dbe961ec 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3479,12 +3479,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
@@ -3492,37 +3493,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;
 }
@@ -4696,7 +4693,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.26.2


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

* [PATCH 24/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_chunk
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (22 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 23/49] sctp: pass a kernel pointer to sctp_setsockopt_maxburst Christoph Hellwig
@ 2020-05-21 17:46 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 25/49] sctp: pass a kernel pointer to sctp_setsockopt_hmac_ident Christoph Hellwig
                   ` (26 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:46 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 e62e8dbe961ec..aa06affcd66e0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3532,21 +3532,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:
@@ -3555,7 +3552,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);
 }
 
 /*
@@ -4696,7 +4693,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.26.2


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

* [PATCH 25/49] sctp: pass a kernel pointer to sctp_setsockopt_hmac_ident
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (23 preceding siblings ...)
  2020-05-21 17:46 ` [PATCH 24/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_chunk Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 26/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_key Christoph Hellwig
                   ` (25 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 aa06affcd66e0..88edf5413fd22 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3562,13 +3562,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;
@@ -3578,21 +3576,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);
 }
 
 /*
@@ -4696,7 +4685,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.26.2


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

* [PATCH 26/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_key
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (24 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 25/49] sctp: pass a kernel pointer to sctp_setsockopt_hmac_ident Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 27/49] sctp: pass a kernel pointer to sctp_setsockopt_active_key Christoph Hellwig
                   ` (24 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 88edf5413fd22..d3442dcd49aa8 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3591,11 +3591,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;
 
@@ -3606,10 +3605,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;
 
@@ -3646,7 +3641,6 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
 	}
 
 out:
-	kzfree(authkey);
 	return ret;
 }
 
@@ -4688,7 +4682,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);
@@ -4771,7 +4765,10 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 	}
 
 	release_sock(sk);
-	kfree(kopt);
+	if (optname == SCTP_AUTH_KEY)
+		kzfree(kopt);
+	else
+		kfree(kopt);
 
 out_nounlock:
 	return retval;
-- 
2.26.2


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

* [PATCH 27/49] sctp: pass a kernel pointer to sctp_setsockopt_active_key
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (25 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 26/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_key Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 28/49] sctp: pass a kernel pointer to sctp_setsockopt_del_key Christoph Hellwig
                   ` (23 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 d3442dcd49aa8..88514a17654a7 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3651,42 +3651,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;
@@ -4685,7 +4682,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.26.2


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

* [PATCH 28/49] sctp: pass a kernel pointer to sctp_setsockopt_del_key
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (26 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 27/49] sctp: pass a kernel pointer to sctp_setsockopt_active_key Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 29/49] sctp: pass a kernel pointer to sctp_setsockopt_deactivate_key Christoph Hellwig
                   ` (22 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 88514a17654a7..a664e9eb323fb 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3699,42 +3699,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;
@@ -4685,7 +4682,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.26.2


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

* [PATCH 29/49] sctp: pass a kernel pointer to sctp_setsockopt_deactivate_key
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (27 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 28/49] sctp: pass a kernel pointer to sctp_setsockopt_del_key Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 30/49] sctp: pass a kernel pointer to sctp_setsockopt_auto_asconf Christoph Hellwig
                   ` (21 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 a664e9eb323fb..1631760e4b0af 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3746,42 +3746,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;
@@ -4685,7 +4683,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.26.2


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

* [PATCH 30/49] sctp: pass a kernel pointer to sctp_setsockopt_auto_asconf
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (28 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 29/49] sctp: pass a kernel pointer to sctp_setsockopt_deactivate_key Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 31/49] sctp: pass a kernel pointer to sctp_setsockopt_paddr_thresholds Christoph Hellwig
                   ` (20 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 1631760e4b0af..04eac086831f0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3803,26 +3803,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;
@@ -4686,7 +4683,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.26.2


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

* [PATCH 31/49] sctp: pass a kernel pointer to sctp_setsockopt_paddr_thresholds
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (29 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 30/49] sctp: pass a kernel pointer to sctp_setsockopt_auto_asconf Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 32/49] sctp: pass a kernel pointer to sctp_setsockopt_recvrcvinfo Christoph Hellwig
                   ` (19 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 | 53 ++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 28 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 04eac086831f0..a2aa1e309d595 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3836,10 +3836,9 @@ 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;
@@ -3847,55 +3846,53 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
 	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;
@@ -4686,11 +4683,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.26.2


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

* [PATCH 32/49] sctp: pass a kernel pointer to sctp_setsockopt_recvrcvinfo
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (30 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 31/49] sctp: pass a kernel pointer to sctp_setsockopt_paddr_thresholds Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 33/49] sctp: pass a kernel pointer to sctp_setsockopt_recvnxtinfo Christoph Hellwig
                   ` (18 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 a2aa1e309d595..e4b537e6d61da 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3898,18 +3898,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;
 }
@@ -4691,7 +4686,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.26.2


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

* [PATCH 33/49] sctp: pass a kernel pointer to sctp_setsockopt_recvnxtinfo
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (31 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 32/49] sctp: pass a kernel pointer to sctp_setsockopt_recvrcvinfo Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 34/49] sctp: pass a kernel pointer to sctp_setsockopt_pr_supported Christoph Hellwig
                   ` (17 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 e4b537e6d61da..fe8d1ea7d9c35 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3909,18 +3909,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;
 }
@@ -4689,7 +4684,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.26.2


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

* [PATCH 34/49] sctp: pass a kernel pointer to sctp_setsockopt_pr_supported
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (32 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 33/49] sctp: pass a kernel pointer to sctp_setsockopt_recvnxtinfo Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 35/49] sctp: pass a kernel pointer to sctp_setsockopt_default_prinfo Christoph Hellwig
                   ` (16 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 fe8d1ea7d9c35..fb7ed11382af1 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3921,24 +3921,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;
 }
@@ -4687,7 +4683,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.26.2


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

* [PATCH 35/49] sctp: pass a kernel pointer to sctp_setsockopt_default_prinfo
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (33 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 34/49] sctp: pass a kernel pointer to sctp_setsockopt_pr_supported Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 36/49] sctp: pass a kernel pointer to sctp_setsockopt_reconfig_supported Christoph Hellwig
                   ` (15 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 fb7ed11382af1..6136f863095ef 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3940,55 +3940,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;
 		}
 	}
 
@@ -4686,7 +4681,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.26.2


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

* [PATCH 36/49] sctp: pass a kernel pointer to sctp_setsockopt_reconfig_supported
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (34 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 35/49] sctp: pass a kernel pointer to sctp_setsockopt_default_prinfo Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 37/49] sctp: pass a kernel pointer to sctp_setsockopt_enable_strreset Christoph Hellwig
                   ` (14 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 6136f863095ef..9173b1b80ee17 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3992,27 +3992,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;
 
@@ -4684,7 +4678,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.26.2


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

* [PATCH 37/49] sctp: pass a kernel pointer to sctp_setsockopt_enable_strreset
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (35 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 36/49] sctp: pass a kernel pointer to sctp_setsockopt_reconfig_supported Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 38/49] sctp: pass a kernel pointer to sctp_setsockopt_reset_streams Christoph Hellwig
                   ` (13 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 9173b1b80ee17..c5a4e9375bb55 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4015,48 +4015,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;
@@ -4681,7 +4675,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.26.2


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

* [PATCH 38/49] sctp: pass a kernel pointer to sctp_setsockopt_reset_streams
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (36 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 37/49] sctp: pass a kernel pointer to sctp_setsockopt_enable_strreset Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 39/49] sctp: pass a kernel pointer to sctp_setsockopt_reset_assoc Christoph Hellwig
                   ` (12 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 c5a4e9375bb55..70451a9177407 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4057,12 +4057,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;
@@ -4070,23 +4068,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,
@@ -4678,7 +4668,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.26.2


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

* [PATCH 39/49] sctp: pass a kernel pointer to sctp_setsockopt_reset_assoc
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (37 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 38/49] sctp: pass a kernel pointer to sctp_setsockopt_reset_streams Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 40/49] sctp: pass a kernel pointer to sctp_setsockopt_add_streams Christoph Hellwig
                   ` (11 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 70451a9177407..185c07916281c 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4079,30 +4079,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,
@@ -4671,7 +4660,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.26.2


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

* [PATCH 40/49] sctp: pass a kernel pointer to sctp_setsockopt_add_streams
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (38 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 39/49] sctp: pass a kernel pointer to sctp_setsockopt_reset_assoc Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 41/49] sctp: pass a kernel pointer to sctp_setsockopt_scheduler Christoph Hellwig
                   ` (10 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 185c07916281c..84881913dbc7f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4095,29 +4095,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,
@@ -4663,7 +4653,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.26.2


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

* [PATCH 41/49] sctp: pass a kernel pointer to sctp_setsockopt_scheduler
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (39 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 40/49] sctp: pass a kernel pointer to sctp_setsockopt_add_streams Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 42/49] sctp: pass a kernel pointer to sctp_setsockopt_scheduler_value Christoph Hellwig
                   ` (9 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 84881913dbc7f..122e6b95a8f0d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4111,44 +4111,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;
@@ -4656,7 +4651,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.26.2


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

* [PATCH 42/49] sctp: pass a kernel pointer to sctp_setsockopt_scheduler_value
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (40 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 41/49] sctp: pass a kernel pointer to sctp_setsockopt_scheduler Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 43/49] sctp: pass a kernel pointer to sctp_setsockopt_interleaving_supported Christoph Hellwig
                   ` (8 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 122e6b95a8f0d..4d61c2885f8f2 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4154,38 +4154,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;
 	}
@@ -4654,7 +4648,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.26.2


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

* [PATCH 43/49] sctp: pass a kernel pointer to sctp_setsockopt_interleaving_supported
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (41 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 42/49] sctp: pass a kernel pointer to sctp_setsockopt_scheduler_value Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 44/49] sctp: pass a kernel pointer to sctp_setsockopt_reuse_port Christoph Hellwig
                   ` (7 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 4d61c2885f8f2..48229ffabbaee 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4189,39 +4189,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,
@@ -4651,7 +4637,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.26.2


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

* [PATCH 44/49] sctp: pass a kernel pointer to sctp_setsockopt_reuse_port
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (42 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 43/49] sctp: pass a kernel pointer to sctp_setsockopt_interleaving_supported Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 45/49] sctp: pass a kernel pointer to sctp_setsockopt_event Christoph Hellwig
                   ` (6 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 48229ffabbaee..c2abf3ab544c3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4210,11 +4210,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;
 
@@ -4224,10 +4222,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;
 }
@@ -4641,7 +4636,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.26.2


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

* [PATCH 45/49] sctp: pass a kernel pointer to sctp_setsockopt_event
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (43 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 44/49] sctp: pass a kernel pointer to sctp_setsockopt_reuse_port Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 46/49] " Christoph Hellwig
                   ` (5 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 c2abf3ab544c3..9b22bb4817830 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4248,45 +4248,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;
@@ -4639,7 +4634,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.26.2


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

* [PATCH 46/49] sctp: pass a kernel pointer to sctp_setsockopt_event
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (44 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 45/49] sctp: pass a kernel pointer to sctp_setsockopt_event Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 47/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_supported Christoph Hellwig
                   ` (4 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 9b22bb4817830..0aa7265c9c9a0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4292,29 +4292,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);
@@ -4637,7 +4631,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.26.2


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

* [PATCH 47/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_supported
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (45 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 46/49] " Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 48/49] sctp: pass a kernel pointer to sctp_setsockopt_ecn_supported Christoph Hellwig
                   ` (3 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 0aa7265c9c9a0..755bb23ffa3c9 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4322,29 +4322,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;
@@ -4354,7 +4348,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:
@@ -4634,7 +4628,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.26.2


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

* [PATCH 48/49] sctp: pass a kernel pointer to sctp_setsockopt_ecn_supported
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (46 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 47/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_supported Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-21 17:47 ` [PATCH 49/49] sctp: pass a kernel pointer to sctp_setsockopt_pf_expose Christoph Hellwig
                   ` (2 subsequent siblings)
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 755bb23ffa3c9..f9f4776b0bbfd 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4356,27 +4356,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:
@@ -4631,7 +4625,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.26.2


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

* [PATCH 49/49] sctp: pass a kernel pointer to sctp_setsockopt_pf_expose
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (47 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 48/49] sctp: pass a kernel pointer to sctp_setsockopt_ecn_supported Christoph Hellwig
@ 2020-05-21 17:47 ` Christoph Hellwig
  2020-05-22  8:02 ` do a single memdup_user in sctp_setsockopt David Laight
  2020-05-22 23:11 ` David Miller
  50 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-05-21 17:47 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 f9f4776b0bbfd..ec87ac9965a01 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4378,33 +4378,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:
@@ -4628,7 +4622,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.26.2


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

* RE: do a single memdup_user in sctp_setsockopt
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (48 preceding siblings ...)
  2020-05-21 17:47 ` [PATCH 49/49] sctp: pass a kernel pointer to sctp_setsockopt_pf_expose Christoph Hellwig
@ 2020-05-22  8:02 ` David Laight
  2020-05-22 14:36   ` Marcelo Ricardo Leitner
  2020-05-22 23:11 ` David Miller
  50 siblings, 1 reply; 58+ messages in thread
From: David Laight @ 2020-05-22  8:02 UTC (permalink / raw)
  To: 'Christoph Hellwig',
	Vlad Yasevich, Neil Horman, Marcelo Ricardo Leitner
  Cc: David S. Miller, Jakub Kicinski, linux-sctp, netdev

From: Christoph Hellwig
> Sent: 21 May 2020 18:47
> based on the review of Davids patch to do something similar I dusted off
> the series I had started a few days ago to move the memdup_user or
> copy_from_user from the inidividual sockopts into sctp_setsockopt,
> which is done with one patch per option, so it might suit Marcelo's
> taste a bit better.  I did not start any work on getsockopt.

I'm not sure that 49 patches is actually any easier to review.
Most of the patches are just repetitions of the same change.
If they were in different files it might be different.

If you try to do getsockopt() the same way it will be much
more complicated - you have to know whether the called function
did the copy_to_user() and then suppress it.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


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

* Re: do a single memdup_user in sctp_setsockopt
  2020-05-22  8:02 ` do a single memdup_user in sctp_setsockopt David Laight
@ 2020-05-22 14:36   ` Marcelo Ricardo Leitner
  2020-05-22 15:52     ` David Laight
  2020-05-23  7:19     ` 'Christoph Hellwig'
  0 siblings, 2 replies; 58+ messages in thread
From: Marcelo Ricardo Leitner @ 2020-05-22 14:36 UTC (permalink / raw)
  To: David Laight
  Cc: 'Christoph Hellwig',
	Vlad Yasevich, Neil Horman, David S. Miller, Jakub Kicinski,
	linux-sctp, netdev

On Fri, May 22, 2020 at 08:02:09AM +0000, David Laight wrote:
> From: Christoph Hellwig
> > Sent: 21 May 2020 18:47
> > based on the review of Davids patch to do something similar I dusted off
> > the series I had started a few days ago to move the memdup_user or
> > copy_from_user from the inidividual sockopts into sctp_setsockopt,
> > which is done with one patch per option, so it might suit Marcelo's
> > taste a bit better.  I did not start any work on getsockopt.
> 
> I'm not sure that 49 patches is actually any easier to review.
> Most of the patches are just repetitions of the same change.
> If they were in different files it might be different.

It's subjective, yes, but we hardly have patches over 5k lines.
In the case here, as changing the functions also requires changing
their call later on the file, it helps to be able to check that is was
properly updated. Ditto for chained functions.

For example, I can spot things like this easier (from
[PATCH 26/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_key)

@@ -3646,7 +3641,6 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
        }

 out:
-       kzfree(authkey);
        return ret;
 }
...
@@ -4771,7 +4765,10 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
        }

        release_sock(sk);
-       kfree(kopt);
+       if (optname == SCTP_AUTH_KEY)
+               kzfree(kopt);
+       else
+               kfree(kopt);

 out_nounlock:
        return retval;

these are 1k lines apart.

Yet, your implementation around this is better:

@@ -3733,7 +3624,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
        }

 out:
-       kzfree(authkey);
+       memset(authkey, 0, optlen);
        return ret;
 }

so that sctp_setsockopt() doesn't have to handle it specially.

What if you two work on a joint patchset for this? The proposals are
quite close. The differences around the setsockopt handling are
minimal already. It is basically variable naming, indentation and one
or another small change like:

From Christoph's to David's:
@@ -2249,11 +2248,11 @@ static int sctp_setsockopt_autoclose(struct sock *sk, u32 *autoclose,
                return -EOPNOTSUPP;
        if (optlen != sizeof(int))
                return -EINVAL;
-
-       if (*autoclose > net->sctp.max_autoclose)
+
+       sp->autoclose = *optval;
+
+       if (sp->autoclose > net->sctp.max_autoclose)
                sp->autoclose = net->sctp.max_autoclose;
-       else
-               sp->autoclose = *autoclose;

        return 0;
 }

> 
> If you try to do getsockopt() the same way it will be much
> more complicated - you have to know whether the called function
> did the copy_to_user() and then suppress it.

If it is not possible, then the setsockopt one already splited half of
the lines of the patch. :-)

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

* RE: do a single memdup_user in sctp_setsockopt
  2020-05-22 14:36   ` Marcelo Ricardo Leitner
@ 2020-05-22 15:52     ` David Laight
  2020-05-23  7:19     ` 'Christoph Hellwig'
  1 sibling, 0 replies; 58+ messages in thread
From: David Laight @ 2020-05-22 15:52 UTC (permalink / raw)
  To: 'Marcelo Ricardo Leitner'
  Cc: 'Christoph Hellwig',
	Vlad Yasevich, Neil Horman, David S. Miller, Jakub Kicinski,
	linux-sctp, netdev

From: Marcelo Ricardo Leitner
> Sent: 22 May 2020 15:36
> 
> On Fri, May 22, 2020 at 08:02:09AM +0000, David Laight wrote:
> > From: Christoph Hellwig
> > > Sent: 21 May 2020 18:47
> > > based on the review of Davids patch to do something similar I dusted off
> > > the series I had started a few days ago to move the memdup_user or
> > > copy_from_user from the inidividual sockopts into sctp_setsockopt,
> > > which is done with one patch per option, so it might suit Marcelo's
> > > taste a bit better.  I did not start any work on getsockopt.
> >
> > I'm not sure that 49 patches is actually any easier to review.
> > Most of the patches are just repetitions of the same change.
> > If they were in different files it might be different.
> 
> It's subjective, yes, but we hardly have patches over 5k lines.
> In the case here, as changing the functions also requires changing
> their call later on the file, it helps to be able to check that is was
> properly updated. Ditto for chained functions.

Between them sparse and the compiler rather force you to find everything.
The main danger was failing to change sizeof(param) to sizeof(*param)
and I double-checked all the relevant lines/

...
> What if you two work on a joint patchset for this? The proposals are
> quite close. The differences around the setsockopt handling are
> minimal already. It is basically variable naming, indentation and one
> or another small change like:

If the changes match then the subfunctions are probably fine.

Because I've got at least 64 bytes I can convert in-situ and assume
(in getsockopt()) that I can action the request (if it only only a read)
and check the length later.
With only a memdup_user() you can't make those changes.


> From Christoph's to David's:
> @@ -2249,11 +2248,11 @@ static int sctp_setsockopt_autoclose(struct sock *sk, u32 *autoclose,
>                 return -EOPNOTSUPP;
>         if (optlen != sizeof(int))
>                 return -EINVAL;
> -
> -       if (*autoclose > net->sctp.max_autoclose)
> +
> +       sp->autoclose = *optval;
> +
> +       if (sp->autoclose > net->sctp.max_autoclose)
>                 sp->autoclose = net->sctp.max_autoclose;
> -       else
> -               sp->autoclose = *autoclose;

I was trying not to make extra changes.
(Apart from error path ones.)
Clearly that should be:
	sp->autoclose = min(*optval, net->sctp.max_autoclose);
But that requires additional thought.

> > If you try to do getsockopt() the same way it will be much
> > more complicated - you have to know whether the called function
> > did the copy_to_user() and then suppress it.
> 
> If it is not possible, then the setsockopt one already splited half of
> the lines of the patch. :-)

Apart from the getsockopt() that is really a setsockopt() (CONNECTX3).
That might tie you in real knots.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


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

* Re: do a single memdup_user in sctp_setsockopt
  2020-05-21 17:46 do a single memdup_user in sctp_setsockopt Christoph Hellwig
                   ` (49 preceding siblings ...)
  2020-05-22  8:02 ` do a single memdup_user in sctp_setsockopt David Laight
@ 2020-05-22 23:11 ` David Miller
  50 siblings, 0 replies; 58+ messages in thread
From: David Miller @ 2020-05-22 23:11 UTC (permalink / raw)
  To: hch
  Cc: vyasevich, nhorman, marcelo.leitner, kuba, David.Laight,
	linux-sctp, netdev

From: Christoph Hellwig <hch@lst.de>
Date: Thu, 21 May 2020 19:46:35 +0200

> based on the review of Davids patch to do something similar I dusted off
> the series I had started a few days ago to move the memdup_user or
> copy_from_user from the inidividual sockopts into sctp_setsockopt,
> which is done with one patch per option, so it might suit Marcelo's
> taste a bit better.  I did not start any work on getsockopt.

I think you and David still need to discuss how to move forward here,
there doesn't seem to be consensus yet.

Thanks.

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

* Re: do a single memdup_user in sctp_setsockopt
  2020-05-22 14:36   ` Marcelo Ricardo Leitner
  2020-05-22 15:52     ` David Laight
@ 2020-05-23  7:19     ` 'Christoph Hellwig'
  2020-05-25 19:37       ` David Laight
  2020-05-25 21:18       ` Marcelo Ricardo Leitner
  1 sibling, 2 replies; 58+ messages in thread
From: 'Christoph Hellwig' @ 2020-05-23  7:19 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: David Laight, 'Christoph Hellwig',
	Vlad Yasevich, Neil Horman, David S. Miller, Jakub Kicinski,
	linux-sctp, netdev

On Fri, May 22, 2020 at 11:36:23AM -0300, Marcelo Ricardo Leitner wrote:
> It's subjective, yes, but we hardly have patches over 5k lines.
> In the case here, as changing the functions also requires changing
> their call later on the file, it helps to be able to check that is was
> properly updated. Ditto for chained functions.
> 
> For example, I can spot things like this easier (from
> [PATCH 26/49] sctp: pass a kernel pointer to sctp_setsockopt_auth_key)
> 
> @@ -3646,7 +3641,6 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
>         }
> 
>  out:
> -       kzfree(authkey);
>         return ret;
>  }
> ...
> @@ -4771,7 +4765,10 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
>         }
> 
>         release_sock(sk);
> -       kfree(kopt);
> +       if (optname == SCTP_AUTH_KEY)
> +               kzfree(kopt);
> +       else
> +               kfree(kopt);
> 
>  out_nounlock:
>         return retval;
> 
> these are 1k lines apart.
> 
> Yet, your implementation around this is better:
> 
> @@ -3733,7 +3624,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
>         }
> 
>  out:
> -       kzfree(authkey);
> +       memset(authkey, 0, optlen);
>         return ret;
>  }
> 
> so that sctp_setsockopt() doesn't have to handle it specially.

Actually that implementation is wrong, if you want to move to a plain
kfree it would have to be a memzero_explicit.

> What if you two work on a joint patchset for this? The proposals are
> quite close. The differences around the setsockopt handling are
> minimal already. It is basically variable naming, indentation and one
> or another small change like:

I don't really want to waste too much time on this, as what I really
need is to get the kernel_setsockopt removal series in ASAP.  I'm happy
to respin this once or twice with clear maintainer guidance (like the
memzero_explicit), but I have no idea what you even meant with your
other example or naming.  Tell me what exact changes you want, and
I can do a quick spin, but I don't really want a huge open ended
discussion on how to paint the bikeshed..

Alternatively I'll also happily only do a partial conversion for what
I need for the kernel_setsockopt removal and let you and Dave decided
what you guys prefer for the rest.

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

* RE: do a single memdup_user in sctp_setsockopt
  2020-05-23  7:19     ` 'Christoph Hellwig'
@ 2020-05-25 19:37       ` David Laight
  2020-05-25 20:59         ` Marcelo Ricardo Leitner
  2020-05-25 21:18       ` Marcelo Ricardo Leitner
  1 sibling, 1 reply; 58+ messages in thread
From: David Laight @ 2020-05-25 19:37 UTC (permalink / raw)
  To: 'Christoph Hellwig', Marcelo Ricardo Leitner
  Cc: Vlad Yasevich, Neil Horman, David S. Miller, Jakub Kicinski,
	linux-sctp, netdev

From: 'Christoph Hellwig'
> Sent: 23 May 2020 08:19
...
> Alternatively I'll also happily only do a partial conversion for what
> I need for the kernel_setsockopt removal and let you and Dave decided
> what you guys prefer for the rest.

I presume the justification for removing kernel_[sg]etsockopt()
is that you want to get rid of set_fs(KERNEL_DS).
(Which I believe is only a flag to access_ok()?)
In any case I'm not against that at all.

To do that you also need to solve the problem of the BPF 'hook'
in setsockopt() that can also need to pass a kernel buffer through.

I don't see a rush to remove kernel_[sg]etsockopt() until you
have a solution for the BPF hook.
Especially since, until set_fs() is removed, any driver can
(and probably will) just implement their own version.

I think you may end up with the protocols being able to export
either [sg]etsockopt() functions or kernel_[sg]setsockopt()
functions and some paths erroring if the required function is absent.

But even that isn't trivial given the broken nature of one
sctp option - where the returned length has to be invalid!

I'm going to post a V3 of my big patch - I spotted an error.
I'll include a different (smaller) patch in 0/1 that generates
exactly the same object code but is easier to review.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


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

* Re: do a single memdup_user in sctp_setsockopt
  2020-05-25 19:37       ` David Laight
@ 2020-05-25 20:59         ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 58+ messages in thread
From: Marcelo Ricardo Leitner @ 2020-05-25 20:59 UTC (permalink / raw)
  To: David Laight
  Cc: 'Christoph Hellwig',
	Vlad Yasevich, Neil Horman, David S. Miller, Jakub Kicinski,
	linux-sctp, netdev

On Mon, May 25, 2020 at 07:37:49PM +0000, David Laight wrote:
> I'm going to post a V3 of my big patch - I spotted an error.
> I'll include a different (smaller) patch in 0/1 that generates
> exactly the same object code but is easier to review.

Please make sure to split at least setsockopt and getsockopt changes
into different patches. That will help quite a lot already.
And to adopt the memset at the end of sctp_setsockopt_auth_key(), to
avoid special handling later on.

Thanks,
Marcelo

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

* Re: do a single memdup_user in sctp_setsockopt
  2020-05-23  7:19     ` 'Christoph Hellwig'
  2020-05-25 19:37       ` David Laight
@ 2020-05-25 21:18       ` Marcelo Ricardo Leitner
  1 sibling, 0 replies; 58+ messages in thread
From: Marcelo Ricardo Leitner @ 2020-05-25 21:18 UTC (permalink / raw)
  To: 'Christoph Hellwig'
  Cc: David Laight, Vlad Yasevich, Neil Horman, David S. Miller,
	Jakub Kicinski, linux-sctp, netdev

On Sat, May 23, 2020 at 09:19:29AM +0200, 'Christoph Hellwig' wrote:
> On Fri, May 22, 2020 at 11:36:23AM -0300, Marcelo Ricardo Leitner wrote:
...
> > What if you two work on a joint patchset for this? The proposals are
> > quite close. The differences around the setsockopt handling are
> > minimal already. It is basically variable naming, indentation and one
> > or another small change like:
> 
> I don't really want to waste too much time on this, as what I really
> need is to get the kernel_setsockopt removal series in ASAP.  I'm happy
> to respin this once or twice with clear maintainer guidance (like the
> memzero_explicit), but I have no idea what you even meant with your
> other example or naming.  Tell me what exact changes you want, and
> I can do a quick spin, but I don't really want a huge open ended
> discussion on how to paint the bikeshed..

What I meant is that the 2 proposals were very close already, with
only minimal differences. As David had posted his set first and you
didn't add a RFC tag nor stated that you were just sharing the
patches, I understood it was an alternative approach to David's, which
is not optimal here. This topic is far from being that polemic, that
could benefit from having 2 competing approaches. So first I wanted a
joint approach, and then build on it.

For now lets see how David's new patchset will look like. It was
almost there already.

> 
> Alternatively I'll also happily only do a partial conversion for what
> I need for the kernel_setsockopt removal and let you and Dave decided
> what you guys prefer for the rest.

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

end of thread, back to index

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

Netdev Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/netdev/0 netdev/git/0.git
	git clone --mirror https://lore.kernel.org/netdev/1 netdev/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 netdev netdev/ https://lore.kernel.org/netdev \
		netdev@vger.kernel.org
	public-inbox-index netdev

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.netdev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git