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 MFC after: 2 weeks
This commit is contained in:
parent
4fa545cb14
commit
002d455873
@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/sbuf.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
@ -595,30 +596,27 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
|
|||||||
static int
|
static int
|
||||||
sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
|
sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
int bufsize;
|
|
||||||
int linesize = 128;
|
int linesize = 128;
|
||||||
char *p, *buf;
|
struct sbuf sb;
|
||||||
int len, i, error;
|
int i, error;
|
||||||
struct hc_metrics *hc_entry;
|
struct hc_metrics *hc_entry;
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
char ip6buf[INET6_ADDRSTRLEN];
|
char ip6buf[INET6_ADDRSTRLEN];
|
||||||
#endif
|
#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);
|
sbuf_printf(&sb,
|
||||||
|
"\nIP address MTU SSTRESH RTT RTTVAR BANDWIDTH "
|
||||||
len = snprintf(p, linesize,
|
|
||||||
"\nIP address MTU SSTRESH RTT RTTVAR BANDWIDTH "
|
|
||||||
" CWND SENDPIPE RECVPIPE HITS UPD EXP\n");
|
" CWND SENDPIPE RECVPIPE HITS UPD EXP\n");
|
||||||
p += len;
|
|
||||||
|
|
||||||
#define msec(u) (((u) + 500) / 1000)
|
#define msec(u) (((u) + 500) / 1000)
|
||||||
for (i = 0; i < V_tcp_hostcache.hashsize; i++) {
|
for (i = 0; i < V_tcp_hostcache.hashsize; i++) {
|
||||||
THC_LOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
|
THC_LOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
|
||||||
TAILQ_FOREACH(hc_entry, &V_tcp_hostcache.hashbase[i].hch_bucket,
|
TAILQ_FOREACH(hc_entry, &V_tcp_hostcache.hashbase[i].hch_bucket,
|
||||||
rmx_q) {
|
rmx_q) {
|
||||||
len = snprintf(p, linesize,
|
sbuf_printf(&sb,
|
||||||
"%-15s %5lu %8lu %6lums %6lums %9lu %8lu %8lu %8lu "
|
"%-15s %5lu %8lu %6lums %6lums %9lu %8lu %8lu %8lu "
|
||||||
"%4lu %4lu %4i\n",
|
"%4lu %4lu %4i\n",
|
||||||
hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) :
|
hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) :
|
||||||
@ -640,13 +638,13 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
|
|||||||
hc_entry->rmx_hits,
|
hc_entry->rmx_hits,
|
||||||
hc_entry->rmx_updates,
|
hc_entry->rmx_updates,
|
||||||
hc_entry->rmx_expire);
|
hc_entry->rmx_expire);
|
||||||
p += len;
|
|
||||||
}
|
}
|
||||||
THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
|
THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
|
||||||
}
|
}
|
||||||
#undef msec
|
#undef msec
|
||||||
error = SYSCTL_OUT(req, buf, p - buf);
|
sbuf_finish(&sb);
|
||||||
free(buf, M_TEMP);
|
error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
|
||||||
|
sbuf_delete(&sb);
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user