Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Jan 2017 09:23:54 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r311392 - head/usr.bin/netstat
Message-ID:  <201701050923.v059NsCS098294@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Thu Jan  5 09:23:54 2017
New Revision: 311392
URL: https://svnweb.freebsd.org/changeset/base/311392

Log:
  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

Modified:
  head/usr.bin/netstat/if.c
  head/usr.bin/netstat/inet.c
  head/usr.bin/netstat/inet6.c
  head/usr.bin/netstat/mroute.c
  head/usr.bin/netstat/netstat.h
  head/usr.bin/netstat/route.c
  head/usr.bin/netstat/sctp.c
  head/usr.bin/netstat/unix.c

Modified: head/usr.bin/netstat/if.c
==============================================================================
--- head/usr.bin/netstat/if.c	Thu Jan  5 08:57:49 2017	(r311391)
+++ head/usr.bin/netstat/if.c	Thu Jan  5 09:23:54 2017	(r311392)
@@ -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 &&

Modified: head/usr.bin/netstat/inet.c
==============================================================================
--- head/usr.bin/netstat/inet.c	Thu Jan  5 08:57:49 2017	(r311391)
+++ head/usr.bin/netstat/inet.c	Thu Jan  5 09:23:54 2017	(r311392)
@@ -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 
 	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 
 	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);
 }

Modified: head/usr.bin/netstat/inet6.c
==============================================================================
--- head/usr.bin/netstat/inet6.c	Thu Jan  5 08:57:49 2017	(r311391)
+++ head/usr.bin/netstat/inet6.c	Thu Jan  5 09:23:54 2017	(r311392)
@@ -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
 	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)));
 	}

Modified: head/usr.bin/netstat/mroute.c
==============================================================================
--- head/usr.bin/netstat/mroute.c	Thu Jan  5 08:57:49 2017	(r311391)
+++ head/usr.bin/netstat/mroute.c	Thu Jan  5 09:23:54 2017	(r311392)
@@ -100,17 +100,19 @@ print_bw_meter(struct bw_meter *bw_meter
 
 	/* 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
 
 	/* 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
 		 &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);
 	}

Modified: head/usr.bin/netstat/netstat.h
==============================================================================
--- head/usr.bin/netstat/netstat.h	Thu Jan  5 08:57:49 2017	(r311391)
+++ head/usr.bin/netstat/netstat.h	Thu Jan  5 09:23:54 2017	(r311392)
@@ -100,7 +100,16 @@ void	ah_stats(u_long, const char *, 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);

Modified: head/usr.bin/netstat/route.c
==============================================================================
--- head/usr.bin/netstat/route.c	Thu Jan  5 08:57:49 2017	(r311391)
+++ head/usr.bin/netstat/route.c	Thu Jan  5 09:23:54 2017	(r311392)
@@ -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 s
     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
 
 		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 __unuse
 			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, struc
 	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, struc
 	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);
 }

Modified: head/usr.bin/netstat/sctp.c
==============================================================================
--- head/usr.bin/netstat/sctp.c	Thu Jan  5 08:57:49 2017	(r311391)
+++ head/usr.bin/netstat/sctp.c	Thu Jan  5 09:23:54 2017	(r311392)
@@ -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
 	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
 	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);
 

Modified: head/usr.bin/netstat/unix.c
==============================================================================
--- head/usr.bin/netstat/unix.c	Thu Jan  5 08:57:49 2017	(r311391)
+++ head/usr.bin/netstat/unix.c	Thu Jan  5 09:23:54 2017	(r311392)
@@ -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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701050923.v059NsCS098294>