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:
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to