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:
parent
3daec7ae72
commit
f193c8ce0d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=311392
@ -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 &&
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user