Use strlcpy and snprintf in netstat(1).

Expand inet6name() line buffer to NI_MAXHOST and use strlcpy/snprintf
in various places.

Reported by:	Anton Yuzhaninov <citrin citrin ru>
MFC after:	3 days
Differential Revision:	https://reviews.freebsd.org/D8916
This commit is contained in:
delphij 2017-01-05 09:23:54 +00:00
parent 7da6b42d42
commit 1b12c4f0ad
8 changed files with 101 additions and 70 deletions

View File

@ -393,10 +393,10 @@ intpr(void (*pfunc)(char *), int af)
case AF_LINK:
{
struct sockaddr_dl *sdl;
char linknum[10];
char linknum[sizeof("<Link#32767>")];
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
sprintf(linknum, "<Link#%d>", sdl->sdl_index);
snprintf(linknum, sizeof(linknum), "<Link#%d>", sdl->sdl_index);
xo_emit("{t:network/%-*.*s} ", net_len, net_len,
linknum);
if (sdl->sdl_nlen == 0 &&

View File

@ -84,7 +84,6 @@ __FBSDID("$FreeBSD$");
#include "netstat.h"
#include "nl_defs.h"
char *inetname(struct in_addr *);
void inetprint(const char *, struct in_addr *, int, const char *, int,
const int);
#ifdef INET6
@ -1413,21 +1412,26 @@ inetprint(const char *container, struct in_addr *in, int port,
struct servent *sp = 0;
char line[80], *cp;
int width;
size_t alen, plen;
if (container)
xo_open_container(container);
if (Wflag)
sprintf(line, "%s.", inetname(in));
snprintf(line, sizeof(line), "%s.", inetname(in));
else
sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in));
cp = strchr(line, '\0');
snprintf(line, sizeof(line), "%.*s.",
(Aflag && !num_port) ? 12 : 16, inetname(in));
alen = strlen(line);
cp = line + alen;
if (!num_port && port)
sp = getservbyport((int)port, proto);
if (sp || port == 0)
sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
snprintf(cp, sizeof(line) - alen,
"%.15s ", sp ? sp->s_name : "*");
else
sprintf(cp, "%d ", ntohs((u_short)port));
snprintf(cp, sizeof(line) - alen,
"%d ", ntohs((u_short)port));
width = (Aflag && !Wflag) ? 18 :
((!Wflag || af1 == AF_INET) ? 22 : 45);
if (Wflag)
@ -1435,7 +1439,8 @@ inetprint(const char *container, struct in_addr *in, int port,
else
xo_emit("{d:target/%-*.*s} ", width, width, line);
int alen = cp - line - 1, plen = strlen(cp) - 1;
plen = strlen(cp) - 1;
alen--;
xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
plen, cp);
@ -1481,8 +1486,9 @@ inetname(struct in_addr *inp)
} else {
inp->s_addr = ntohl(inp->s_addr);
#define C(x) ((u_int)((x) & 0xff))
sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
snprintf(line, sizeof(line), "%u.%u.%u.%u",
C(inp->s_addr >> 24), C(inp->s_addr >> 16),
C(inp->s_addr >> 8), C(inp->s_addr));
}
return (line);
}

View File

@ -70,8 +70,6 @@ __FBSDID("$FreeBSD$");
#include <libxo/xo.h>
#include "netstat.h"
char *inet6name(struct in6_addr *);
static char ntop_buf[INET6_ADDRSTRLEN];
static const char *ip6nh[] = {
@ -1270,24 +1268,30 @@ inet6print(const char *container, struct in6_addr *in6, int port,
struct servent *sp = 0;
char line[80], *cp;
int width;
size_t alen, plen;
if (container)
xo_open_container(container);
sprintf(line, "%.*s.", Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
snprintf(line, sizeof(line), "%.*s.",
Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
inet6name(in6));
cp = strchr(line, '\0');
alen = strlen(line);
cp = line + alen;
if (!numeric && port)
GETSERVBYPORT6(port, proto, sp);
if (sp || port == 0)
sprintf(cp, "%.15s", sp ? sp->s_name : "*");
snprintf(cp, sizeof(line) - alen,
"%.15s", sp ? sp->s_name : "*");
else
sprintf(cp, "%d", ntohs((u_short)port));
snprintf(cp, sizeof(line) - alen,
"%d", ntohs((u_short)port));
width = Wflag ? 45 : Aflag ? 18 : 22;
xo_emit("{d:target/%-*.*s} ", width, width, line);
int alen = cp - line - 1, plen = strlen(cp) - 1;
plen = strlen(cp) - 1;
alen--;
xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
plen, cp);
@ -1306,7 +1310,7 @@ inet6name(struct in6_addr *in6p)
{
struct sockaddr_in6 sin6;
char hbuf[NI_MAXHOST], *cp;
static char line[50];
static char line[NI_MAXHOST];
static char domain[MAXHOSTNAMELEN];
static int first = 1;
int flags, error;
@ -1317,9 +1321,9 @@ inet6name(struct in6_addr *in6p)
}
if (first && !numeric_addr) {
first = 0;
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
if (gethostname(domain, sizeof(domain)) == 0 &&
(cp = strchr(domain, '.')))
(void) strcpy(domain, cp + 1);
strlcpy(domain, cp + 1, sizeof(domain));
else
domain[0] = 0;
}
@ -1336,10 +1340,10 @@ inet6name(struct in6_addr *in6p)
(cp = strchr(hbuf, '.')) &&
!strcmp(cp + 1, domain))
*cp = 0;
strcpy(line, hbuf);
strlcpy(line, hbuf, sizeof(line));
} else {
/* XXX: this should not happen. */
sprintf(line, "%s",
snprintf(line, sizeof(line), "%s",
inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
sizeof(ntop_buf)));
}

View File

@ -100,17 +100,19 @@ print_bw_meter(struct bw_meter *bw_meter, int *banner_printed)
/* The measured values */
if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) {
sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_measured.b_packets);
snprintf(s1, sizeof(s1), "%ju",
(uintmax_t)bw_meter->bm_measured.b_packets);
xo_emit("{e:measured-packets/%ju}",
(uintmax_t)bw_meter->bm_measured.b_packets);
} else
sprintf(s1, "?");
strcpy(s1, "?");
if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) {
sprintf(s2, "%ju", (uintmax_t)bw_meter->bm_measured.b_bytes);
snprintf(s2, sizeof(s2), "%ju",
(uintmax_t)bw_meter->bm_measured.b_bytes);
xo_emit("{e:measured-bytes/%ju}",
(uintmax_t)bw_meter->bm_measured.b_bytes);
} else
sprintf(s2, "?");
strcpy(s2, "?");
xo_emit(" {[:-30}{:start-time/%lu.%06lu}|{q:measured-packets/%s}"
"|{q:measured-bytes%s}{]:}",
(u_long)bw_meter->bm_start_time.tv_sec,
@ -122,17 +124,19 @@ print_bw_meter(struct bw_meter *bw_meter, int *banner_printed)
/* The threshold values */
if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) {
sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_threshold.b_packets);
snprintf(s1, sizeof(s1), "%ju",
(uintmax_t)bw_meter->bm_threshold.b_packets);
xo_emit("{e:threshold-packets/%ju}",
(uintmax_t)bw_meter->bm_threshold.b_packets);
} else
sprintf(s1, "?");
strcpy(s1, "?");
if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) {
sprintf(s2, "%ju", (uintmax_t)bw_meter->bm_threshold.b_bytes);
snprintf(s2, sizeof(s2), "%ju",
(uintmax_t)bw_meter->bm_threshold.b_bytes);
xo_emit("{e:threshold-bytes/%ju}",
(uintmax_t)bw_meter->bm_threshold.b_bytes);
} else
sprintf(s2, "?");
strcpy(s2, "?");
xo_emit(" {[:-30}{:threshold-time/%lu.%06lu}|{q:threshold-packets/%s}"
"|{q:threshold-bytes%s}{]:}",
@ -144,13 +148,13 @@ print_bw_meter(struct bw_meter *bw_meter, int *banner_printed)
&bw_meter->bm_threshold.b_time, &end);
if (timercmp(&now, &end, <=)) {
timersub(&end, &now, &delta);
sprintf(s3, "%lu.%06lu",
snprintf(s3, sizeof(s3), "%lu.%06lu",
(u_long)delta.tv_sec,
(u_long)delta.tv_usec);
} else {
/* Negative time */
timersub(&now, &end, &delta);
sprintf(s3, "-%lu.06%lu",
snprintf(s3, sizeof(s3), "-%lu.06%lu",
(u_long)delta.tv_sec,
(u_long)delta.tv_usec);
}

View File

@ -100,7 +100,16 @@ void ah_stats(u_long, const char *, int, int);
void ipcomp_stats(u_long, const char *, int, int);
#endif
#ifdef INET
struct in_addr;
char *inetname(struct in_addr *);
#endif
#ifdef INET6
struct in6_addr;
char *inet6name(struct in6_addr *);
void ip6_stats(u_long, const char *, int, int);
void ip6_ifstats(char *);
void icmp6_stats(u_long, const char *, int, int);

View File

@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <ifaddrs.h>
#include <libutil.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -115,7 +116,7 @@ static const char *fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask,
int flags);
static void p_flags(int, const char *);
static const char *fmt_flags(int f);
static void domask(char *, in_addr_t, u_long);
static void domask(char *, size_t, u_long);
/*
@ -494,12 +495,16 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags)
cq = buf;
slim = sa->sa_len + (u_char *) sa;
cqlim = cq + sizeof(buf) - 6;
cq += sprintf(cq, "(%d)", sa->sa_family);
cqlim = cq + sizeof(buf) - sizeof(" ffff");
snprintf(cq, sizeof(cq), "(%d)", sa->sa_family);
cq += strlen(cq);
while (s < slim && cq < cqlim) {
cq += sprintf(cq, " %02x", *s++);
if (s < slim)
cq += sprintf(cq, "%02x", *s++);
snprintf(cq, sizeof(" ff"), " %02x", *s++);
cq += strlen(cq);
if (s < slim) {
snprintf(cq, sizeof("ff"), "%02x", *s++);
cq += strlen(cq);
}
}
cp = buf;
}
@ -576,7 +581,7 @@ routename(struct sockaddr *sa, int flags)
0)
static void
domask(char *dst, in_addr_t addr __unused, u_long mask)
domask(char *dst, size_t buflen, u_long mask)
{
int b, i;
@ -598,9 +603,9 @@ domask(char *dst, in_addr_t addr __unused, u_long mask)
break;
}
if (i == -1)
sprintf(dst, "&0x%lx", mask);
snprintf(dst, buflen, "&0x%lx", mask);
else
sprintf(dst, "/%d", 32-i);
snprintf(dst, buflen, "/%d", 32-i);
}
/*
@ -631,7 +636,7 @@ static const char *
netname4(in_addr_t in, in_addr_t mask)
{
char *cp = 0;
static char line[MAXHOSTNAMELEN + sizeof("/xx")];
static char line[MAXHOSTNAMELEN + sizeof("&0xffffffff")];
char nline[INET_ADDRSTRLEN];
struct netent *np = 0;
in_addr_t i;
@ -657,7 +662,7 @@ netname4(in_addr_t in, in_addr_t mask)
else {
inet_ntop(AF_INET, &in, nline, sizeof(nline));
strlcpy(line, nline, sizeof(line));
domask(line + strlen(line), i, ntohl(mask));
domask(line + strlen(line), sizeof(line) - strlen(line), ntohl(mask));
}
return (line);
@ -686,7 +691,7 @@ in6_fillscopeid(struct sockaddr_in6 *sa6)
}
/* Mask to length table. To check an invalid value, (length + 1) is used. */
static int masktolen[256] = {
static const u_char masktolen[256] = {
[0xff] = 8 + 1,
[0xfe] = 7 + 1,
[0xfc] = 6 + 1,
@ -704,17 +709,20 @@ netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask)
static char line[NI_MAXHOST + sizeof("/xxx") - 1];
struct sockaddr_in6 addr;
char nline[NI_MAXHOST];
char maskbuf[sizeof("/xxx")];
u_char *p, *lim;
int masklen, illegal = 0, i;
u_char masklen;
int i;
bool illegal = false;
if (mask) {
p = (u_char *)&mask->sin6_addr;
for (masklen = 0, lim = p + 16; p < lim; p++) {
if (masktolen[*p] > 0)
if (masktolen[*p] > 0) {
/* -1 is required. */
masklen += masktolen[*p] - 1;
else
illegal++;
masklen += (masktolen[*p] - 1);
} else
illegal = true;
}
if (illegal)
xo_error("illegal prefixlen\n");
@ -738,8 +746,10 @@ netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask)
else
getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, line,
sizeof(line), NULL, 0, 0);
if (numeric_addr || strcmp(line, nline) == 0)
sprintf(&line[strlen(line)], "/%d", masklen);
if (numeric_addr || strcmp(line, nline) == 0) {
snprintf(maskbuf, sizeof(maskbuf), "/%d", masklen);
strlcat(line, maskbuf, sizeof(line));
}
return (line);
}

View File

@ -104,16 +104,6 @@ struct xraddr_entry {
LIST_ENTRY(xraddr_entry) xraddr_entries;
};
#ifdef INET
char *
inetname(struct in_addr *inp);
#endif
#ifdef INET6
char *
inet6name(struct in6_addr *in6p);
#endif
static void
sctp_print_address(const char *container, union sctp_sockstore *address,
int port, int num_port)
@ -121,6 +111,7 @@ sctp_print_address(const char *container, union sctp_sockstore *address,
struct servent *sp = 0;
char line[80], *cp;
int width;
size_t alen, plen;
if (container)
xo_open_container(container);
@ -128,29 +119,36 @@ sctp_print_address(const char *container, union sctp_sockstore *address,
switch (address->sa.sa_family) {
#ifdef INET
case AF_INET:
sprintf(line, "%.*s.", Wflag ? 39 : 16, inetname(&address->sin.sin_addr));
snprintf(line, sizeof(line), "%.*s.",
Wflag ? 39 : 16, inetname(&address->sin.sin_addr));
break;
#endif
#ifdef INET6
case AF_INET6:
sprintf(line, "%.*s.", Wflag ? 39 : 16, inet6name(&address->sin6.sin6_addr));
snprintf(line, sizeof(line), "%.*s.",
Wflag ? 39 : 16, inet6name(&address->sin6.sin6_addr));
break;
#endif
default:
sprintf(line, "%.*s.", Wflag ? 39 : 16, "");
snprintf(line, sizeof(line), "%.*s.",
Wflag ? 39 : 16, "");
break;
}
cp = strchr(line, '\0');
alen = strlen(line);
cp = line + alen;
if (!num_port && port)
sp = getservbyport((int)port, "sctp");
if (sp || port == 0)
sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
snprintf(cp, sizeof(line) - alen,
"%.15s ", sp ? sp->s_name : "*");
else
sprintf(cp, "%d ", ntohs((u_short)port));
snprintf(cp, sizeof(line) - alen,
"%d ", ntohs((u_short)port));
width = Wflag ? 45 : 22;
xo_emit("{d:target/%-*.*s} ", width, width, line);
int alen = cp - line - 1, plen = strlen(cp) - 1;
plen = strlen(cp) - 1;
alen--;
xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
plen, cp);

View File

@ -75,7 +75,7 @@ pcblist_sysctl(int type, char **bufp)
size_t len;
char mibvar[sizeof "net.local.seqpacket.pcblist"];
sprintf(mibvar, "net.local.%s.pcblist", socktype[type]);
snprintf(mibvar, sizeof(mibvar), "net.local.%s.pcblist", socktype[type]);
len = 0;
if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {