summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2016-01-27 07:34:00 +0000
committerglebius <glebius@FreeBSD.org>2016-01-27 07:34:00 +0000
commit2af1c82fc1f9ccdd73b6255b84c1a1667f7ce818 (patch)
tree537515fae0126aaa737326862dfa7dc2b88d7929 /sys/netinet
parentc07f0f872d21c891ec351eccf996f445a63a30e7 (diff)
downloadFreeBSD-src-2af1c82fc1f9ccdd73b6255b84c1a1667f7ce818.zip
FreeBSD-src-2af1c82fc1f9ccdd73b6255b84c1a1667f7ce818.tar.gz
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
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/tcp_usrreq.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 0a87a62..204db39 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1479,7 +1479,8 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
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, struct sockopt *sopt, struct inpcb *inp
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:
OpenPOWER on IntegriCloud