summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_hostcache.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2015-02-10 21:41:56 +0000
committerjhb <jhb@FreeBSD.org>2015-02-10 21:41:56 +0000
commite15ed53e778bc39555abe68c05da61e133ef71a3 (patch)
tree478eb38e853e97773e566f1e4cde4930550ed72d /sys/netinet/tcp_hostcache.c
parentce996f8275261223851a6b6ea0db11df891eb3d0 (diff)
downloadFreeBSD-src-e15ed53e778bc39555abe68c05da61e133ef71a3.zip
FreeBSD-src-e15ed53e778bc39555abe68c05da61e133ef71a3.tar.gz
MFC 277709:
Use an sbuf to generate the output of the net.inet.tcp.hostcache.list sysctl to avoid a possible buffer overflow if the cache grows while the text is being generated. PR: 172675
Diffstat (limited to 'sys/netinet/tcp_hostcache.c')
-rw-r--r--sys/netinet/tcp_hostcache.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c
index 3a53aa4..c34c850 100644
--- a/sys/netinet/tcp_hostcache.c
+++ b/sys/netinet/tcp_hostcache.c
@@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
+#include <sys/sbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
@@ -592,30 +593,27 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
static int
sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
{
- int bufsize;
int linesize = 128;
- char *p, *buf;
- int len, i, error;
+ struct sbuf sb;
+ int i, error;
struct hc_metrics *hc_entry;
#ifdef INET6
char ip6buf[INET6_ADDRSTRLEN];
#endif
- bufsize = linesize * (V_tcp_hostcache.cache_count + 1);
+ sbuf_new(&sb, NULL, linesize * (V_tcp_hostcache.cache_count + 1),
+ SBUF_FIXEDLEN);
- p = buf = (char *)malloc(bufsize, M_TEMP, M_WAITOK|M_ZERO);
-
- len = snprintf(p, linesize,
- "\nIP address MTU SSTRESH RTT RTTVAR BANDWIDTH "
+ sbuf_printf(&sb,
+ "\nIP address MTU SSTRESH RTT RTTVAR BANDWIDTH "
" CWND SENDPIPE RECVPIPE HITS UPD EXP\n");
- p += len;
#define msec(u) (((u) + 500) / 1000)
for (i = 0; i < V_tcp_hostcache.hashsize; i++) {
THC_LOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
TAILQ_FOREACH(hc_entry, &V_tcp_hostcache.hashbase[i].hch_bucket,
rmx_q) {
- len = snprintf(p, linesize,
+ sbuf_printf(&sb,
"%-15s %5lu %8lu %6lums %6lums %9lu %8lu %8lu %8lu "
"%4lu %4lu %4i\n",
hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) :
@@ -637,13 +635,13 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
hc_entry->rmx_hits,
hc_entry->rmx_updates,
hc_entry->rmx_expire);
- p += len;
}
THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
}
#undef msec
- error = SYSCTL_OUT(req, buf, p - buf);
- free(buf, M_TEMP);
+ sbuf_finish(&sb);
+ error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
+ sbuf_delete(&sb);
return(error);
}
OpenPOWER on IntegriCloud