svn commit: r294902 - head/sys/netinet

Gleb Smirnoff glebius at FreeBSD.org
Wed Jan 27 07:34:01 UTC 2016


Author: glebius
Date: Wed Jan 27 07:34:00 2016
New Revision: 294902
URL: https://svnweb.freebsd.org/changeset/base/294902

Log:
  Fix issues with TCP_CONGESTION handling after r294540:
  o Return back the buf[TCP_CA_NAME_MAX] for TCP_CONGESTION,
    for TCP_CCALGOOPT use dynamically allocated *pbuf.
  o For SOPT_SET TCP_CONGESTION do NULL terminating of string
    taking from userland.
  o For SOPT_SET TCP_CONGESTION do the search for the algorithm
    keeping the inpcb lock.
  o For SOPT_GET TCP_CONGESTION first strlcpy() the name
    holding the inpcb lock into temporary buffer, then copyout.
  
  Together with:	lstewart

Modified:
  head/sys/netinet/tcp_usrreq.c

Modified: head/sys/netinet/tcp_usrreq.c
==============================================================================
--- head/sys/netinet/tcp_usrreq.c	Wed Jan 27 07:28:55 2016	(r294901)
+++ head/sys/netinet/tcp_usrreq.c	Wed Jan 27 07:34:00 2016	(r294902)
@@ -1479,7 +1479,8 @@ tcp_default_ctloutput(struct socket *so,
 	u_int	ui;
 	struct	tcp_info ti;
 	struct cc_algo *algo;
-	char	*buf;
+	char	*pbuf, buf[TCP_CA_NAME_MAX];
+	size_t	len;
 
 	/*
 	 * For TCP_CCALGOOPT forward the control to CC module, for both
@@ -1488,22 +1489,22 @@ tcp_default_ctloutput(struct socket *so,
 	switch (sopt->sopt_name) {
 	case TCP_CCALGOOPT:
 		INP_WUNLOCK(inp);
-		buf = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK | M_ZERO);
-		error = sooptcopyin(sopt, buf, sopt->sopt_valsize,
+		pbuf = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK | M_ZERO);
+		error = sooptcopyin(sopt, pbuf, sopt->sopt_valsize,
 		    sopt->sopt_valsize);
 		if (error) {
-			free(buf, M_TEMP);
+			free(pbuf, M_TEMP);
 			return (error);
 		}
 		INP_WLOCK_RECHECK(inp);
 		if (CC_ALGO(tp)->ctl_output != NULL)
-			error = CC_ALGO(tp)->ctl_output(tp->ccv, sopt, buf);
+			error = CC_ALGO(tp)->ctl_output(tp->ccv, sopt, pbuf);
 		else
 			error = ENOENT;
 		INP_WUNLOCK(inp);
 		if (error == 0 && sopt->sopt_dir == SOPT_GET)
-			error = sooptcopyout(sopt, buf, sopt->sopt_valsize);
-		free(buf, M_TEMP);
+			error = sooptcopyout(sopt, pbuf, sopt->sopt_valsize);
+		free(pbuf, M_TEMP);
 		return (error);
 	}
 
@@ -1600,24 +1601,22 @@ unlock_and_done:
 
 		case TCP_CONGESTION:
 			INP_WUNLOCK(inp);
-			buf = malloc(TCP_CA_NAME_MAX, M_TEMP, M_WAITOK|M_ZERO);
-			error = sooptcopyin(sopt, buf, TCP_CA_NAME_MAX, 1);
-			if (error) {
-				free(buf, M_TEMP);
+			error = sooptcopyin(sopt, buf, TCP_CA_NAME_MAX - 1, 1);
+			if (error)
 				break;
-			}
+			buf[sopt->sopt_valsize] = '\0';
+			INP_WLOCK_RECHECK(inp);
 			CC_LIST_RLOCK();
 			STAILQ_FOREACH(algo, &cc_list, entries)
 				if (strncmp(buf, algo->name,
 				    TCP_CA_NAME_MAX) == 0)
 					break;
 			CC_LIST_RUNLOCK();
-			free(buf, M_TEMP);
 			if (algo == NULL) {
+				INP_WUNLOCK(inp);
 				error = EINVAL;
 				break;
 			}
-			INP_WLOCK_RECHECK(inp);
 			/*
 			 * We hold a write lock over the tcb so it's safe to
 			 * do these things without ordering concerns.
@@ -1786,9 +1785,9 @@ unlock_and_done:
 			error = sooptcopyout(sopt, &ti, sizeof ti);
 			break;
 		case TCP_CONGESTION:
+			len = strlcpy(buf, CC_ALGO(tp)->name, TCP_CA_NAME_MAX);
 			INP_WUNLOCK(inp);
-			error = sooptcopyout(sopt, CC_ALGO(tp)->name,
-			    TCP_CA_NAME_MAX);
+			error = sooptcopyout(sopt, buf, len + 1);
 			break;
 		case TCP_KEEPIDLE:
 		case TCP_KEEPINTVL:


More information about the svn-src-all mailing list