svn commit: r368231 - stable/12/sbin/ping

Mark Johnston markj at FreeBSD.org
Tue Dec 1 15:09:03 UTC 2020


Author: markj
Date: Tue Dec  1 15:09:02 2020
New Revision: 368231
URL: https://svnweb.freebsd.org/changeset/base/368231

Log:
  MFC r367988:
  ping(8): Improve parameter validation
  
  PR:	239974, 239977, 239978

Modified:
  stable/12/sbin/ping/ping.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sbin/ping/ping.c
==============================================================================
--- stable/12/sbin/ping/ping.c	Tue Dec  1 15:01:10 2020	(r368230)
+++ stable/12/sbin/ping/ping.c	Tue Dec  1 15:09:02 2020	(r368231)
@@ -236,6 +236,7 @@ main(int argc, char *const *argv)
 	struct sigaction si_sa;
 	size_t sz;
 	u_char *datap, packet[IP_MAXPACKET] __aligned(4);
+	const char *errstr;
 	char *ep, *source, *target, *payload;
 	struct hostent *hp;
 #ifdef IPSEC_POLICY_IPSEC
@@ -244,7 +245,7 @@ main(int argc, char *const *argv)
 	struct sockaddr_in *to;
 	double t;
 	u_long alarmtimeout;
-	long ltmp;
+	long long ltmp;
 	int almost_done, ch, df, hold, i, icmp_len, mib[4], preload;
 	int ssend_errno, srecv_errno, tos, ttl;
 	char ctrl[CMSG_SPACE(sizeof(struct timespec))];
@@ -315,12 +316,12 @@ main(int argc, char *const *argv)
 			options |= F_AUDIBLE;
 			break;
 		case 'c':
-			ltmp = strtol(optarg, &ep, 0);
-			if (*ep || ep == optarg || ltmp <= 0)
+			ltmp = strtonum(optarg, 1, LONG_MAX, &errstr);
+			if (errstr != NULL)
 				errx(EX_USAGE,
 				    "invalid count of packets to transmit: `%s'",
 				    optarg);
-			npackets = ltmp;
+			npackets = (long)ltmp;
 			break;
 		case 'D':
 			options |= F_HDRINCL;
@@ -338,46 +339,46 @@ main(int argc, char *const *argv)
 			setbuf(stdout, (char *)NULL);
 			break;
 		case 'G': /* Maximum packet size for ping sweep */
-			ltmp = strtol(optarg, &ep, 0);
-			if (*ep || ep == optarg || ltmp <= 0)
+			ltmp = strtonum(optarg, 1, INT_MAX, &errstr);
+			if (errstr != NULL) {
 				errx(EX_USAGE, "invalid packet size: `%s'",
 				    optarg);
-			if (uid != 0 && ltmp > DEFDATALEN) {
-				errno = EPERM;
-				err(EX_NOPERM,
-				    "packet size too large: %ld > %u",
-				    ltmp, DEFDATALEN);
 			}
+			sweepmax = (int)ltmp;
+			if (uid != 0 && sweepmax > DEFDATALEN) {
+				errc(EX_NOPERM, EPERM,
+				    "packet size too large: %d > %u",
+				    sweepmax, DEFDATALEN);
+			}
 			options |= F_SWEEP;
-			sweepmax = ltmp;
 			break;
 		case 'g': /* Minimum packet size for ping sweep */
-			ltmp = strtol(optarg, &ep, 0);
-			if (*ep || ep == optarg || ltmp <= 0)
+			ltmp = strtonum(optarg, 1, INT_MAX, &errstr);
+			if (errstr != NULL) {
 				errx(EX_USAGE, "invalid packet size: `%s'",
 				    optarg);
-			if (uid != 0 && ltmp > DEFDATALEN) {
-				errno = EPERM;
-				err(EX_NOPERM,
-				    "packet size too large: %ld > %u",
-				    ltmp, DEFDATALEN);
 			}
+			sweepmin = (int)ltmp;
+			if (uid != 0 && sweepmin > DEFDATALEN) {
+				errc(EX_NOPERM, EPERM,
+				    "packet size too large: %d > %u",
+				    sweepmin, DEFDATALEN);
+			}
 			options |= F_SWEEP;
-			sweepmin = ltmp;
 			break;
 		case 'h': /* Packet size increment for ping sweep */
-			ltmp = strtol(optarg, &ep, 0);
-			if (*ep || ep == optarg || ltmp < 1)
-				errx(EX_USAGE, "invalid increment size: `%s'",
+			ltmp = strtonum(optarg, 1, INT_MAX, &errstr);
+			if (errstr != NULL) {
+				errx(EX_USAGE, "invalid packet size: `%s'",
 				    optarg);
-			if (uid != 0 && ltmp > DEFDATALEN) {
-				errno = EPERM;
-				err(EX_NOPERM,
-				    "packet size too large: %ld > %u",
-				    ltmp, DEFDATALEN);
 			}
+			sweepincr = (int)ltmp;
+			if (uid != 0 && sweepincr > DEFDATALEN) {
+				errc(EX_NOPERM, EPERM,
+				    "packet size too large: %d > %u",
+				    sweepincr, DEFDATALEN);
+			}
 			options |= F_SWEEP;
-			sweepincr = ltmp;
 			break;
 		case 'I':		/* multicast interface */
 			if (inet_aton(optarg, &ifaddr) == 0)
@@ -403,15 +404,15 @@ main(int argc, char *const *argv)
 			loop = 0;
 			break;
 		case 'l':
-			ltmp = strtol(optarg, &ep, 0);
-			if (*ep || ep == optarg || ltmp > INT_MAX || ltmp < 0)
+			ltmp = strtonum(optarg, 0, INT_MAX, &errstr);
+			if (errstr != NULL)
 				errx(EX_USAGE,
 				    "invalid preload value: `%s'", optarg);
 			if (uid) {
 				errno = EPERM;
 				err(EX_NOPERM, "-l flag");
 			}
-			preload = ltmp;
+			preload = (int)ltmp;
 			break;
 		case 'M':
 			switch(optarg[0]) {
@@ -429,10 +430,10 @@ main(int argc, char *const *argv)
 			}
 			break;
 		case 'm':		/* TTL */
-			ltmp = strtol(optarg, &ep, 0);
-			if (*ep || ep == optarg || ltmp > MAXTTL || ltmp < 0)
+			ltmp = strtonum(optarg, 0, MAXTTL, &errstr);
+			if (errstr != NULL)
 				errx(EX_USAGE, "invalid TTL: `%s'", optarg);
-			ttl = ltmp;
+			ttl = (int)ltmp;
 			options |= F_TTL;
 			break;
 		case 'n':
@@ -474,24 +475,24 @@ main(int argc, char *const *argv)
 			source = optarg;
 			break;
 		case 's':		/* size of packet to send */
-			ltmp = strtol(optarg, &ep, 0);
-			if (*ep || ep == optarg || ltmp > INT_MAX || ltmp < 0)
+			ltmp = strtonum(optarg, 0, INT_MAX, &errstr);
+			if (errstr != NULL)
 				errx(EX_USAGE, "invalid packet size: `%s'",
 				    optarg);
-			if (uid != 0 && ltmp > DEFDATALEN) {
+			datalen = (int)ltmp;
+			if (uid != 0 && datalen > DEFDATALEN) {
 				errno = EPERM;
 				err(EX_NOPERM,
-				    "packet size too large: %ld > %u",
-				    ltmp, DEFDATALEN);
+				    "packet size too large: %d > %u",
+				    datalen, DEFDATALEN);
 			}
-			datalen = ltmp;
 			break;
 		case 'T':		/* multicast TTL */
-			ltmp = strtol(optarg, &ep, 0);
-			if (*ep || ep == optarg || ltmp > MAXTTL || ltmp < 0)
+			ltmp = strtonum(optarg, 0, MAXTTL, &errstr);
+			if (errstr != NULL)
 				errx(EX_USAGE, "invalid multicast TTL: `%s'",
 				    optarg);
-			mttl = ltmp;
+			mttl = (unsigned char)ltmp;
 			options |= F_MTTL;
 			break;
 		case 't':
@@ -645,7 +646,7 @@ main(int argc, char *const *argv)
 	if (datalen >= TIMEVAL_LEN)	/* can we time transfer */
 		timing = 1;
 
-	if (!(options & F_PINGFILLED))
+	if ((options & (F_PINGFILLED | F_SWEEP)) == 0)
 		for (i = TIMEVAL_LEN; i < datalen; ++i)
 			*datap++ = i;
 
@@ -794,10 +795,15 @@ main(int argc, char *const *argv)
 #endif
 	if (sweepmax) {
 		if (sweepmin > sweepmax)
-			errx(EX_USAGE, "Maximum packet size must be no less than the minimum packet size");
+			errx(EX_USAGE,
+	    "Maximum packet size must be no less than the minimum packet size");
 
+		if (sweepmax > maxpayload - TIMEVAL_LEN)
+			errx(EX_USAGE, "Invalid sweep maximum");
+
 		if (datalen != DEFDATALEN)
-			errx(EX_USAGE, "Packet size and ping sweep are mutually exclusive");
+			errx(EX_USAGE,
+		    "Packet size and ping sweep are mutually exclusive");
 
 		if (npackets > 0) {
 			snpackets = npackets;
@@ -962,11 +968,11 @@ main(int argc, char *const *argv)
 		}
 		if (n == 0 || options & F_FLOOD) {
 			if (sweepmax && sntransmitted == snpackets) {
-				for (i = 0; i < sweepincr ; ++i)
+				if (datalen + sweepincr > sweepmax)
+					break;
+				for (i = 0; i < sweepincr; i++)
 					*datap++ = i;
 				datalen += sweepincr;
-				if (datalen > sweepmax)
-					break;
 				send_len = icmp_len + datalen;
 				sntransmitted = 0;
 			}


More information about the svn-src-all mailing list