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

Eugene Grosbein eugen at FreeBSD.org
Sat Dec 8 00:28:29 UTC 2018


Author: eugen
Date: Sat Dec  8 00:28:27 2018
New Revision: 341713
URL: https://svnweb.freebsd.org/changeset/base/341713

Log:
  MFC r340245: ping(8): improve diagnostics in case of wrong arguments.
  
    For example, in case of super-user:
    $ sudo ping -s -64 127.0.0.1
    PING 127.0.0.1 (127.0.0.1): -64 data bytes
    ping: sendto: Invalid argument
  
    For unprivileged user:
    $ ping -s -64 127.0.0.1
    ping: packet size too large: 18446744073709551552 > 56: Operation not permitted
  
    Fix this by switching from strtoul() to strtol() for integer arguments
    and adding explicit checks for negative values.

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	Fri Dec  7 23:07:51 2018	(r341712)
+++ stable/12/sbin/ping/ping.c	Sat Dec  8 00:28:27 2018	(r341713)
@@ -242,7 +242,8 @@ main(int argc, char *const *argv)
 #endif
 	struct sockaddr_in *to;
 	double t;
-	u_long alarmtimeout, ultmp;
+	u_long alarmtimeout;
+	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 timeval))];
@@ -311,12 +312,12 @@ main(int argc, char *const *argv)
 			options |= F_AUDIBLE;
 			break;
 		case 'c':
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg || ultmp > LONG_MAX || !ultmp)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp > LONG_MAX || ltmp <=0)
 				errx(EX_USAGE,
 				    "invalid count of packets to transmit: `%s'",
 				    optarg);
-			npackets = ultmp;
+			npackets = ltmp;
 			break;
 		case 'D':
 			options |= F_HDRINCL;
@@ -334,46 +335,46 @@ main(int argc, char *const *argv)
 			setbuf(stdout, (char *)NULL);
 			break;
 		case 'G': /* Maximum packet size for ping sweep */
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp <= 0)
 				errx(EX_USAGE, "invalid packet size: `%s'",
 				    optarg);
-			if (uid != 0 && ultmp > DEFDATALEN) {
+			if (uid != 0 && ltmp > DEFDATALEN) {
 				errno = EPERM;
 				err(EX_NOPERM,
-				    "packet size too large: %lu > %u",
-				    ultmp, DEFDATALEN);
+				    "packet size too large: %ld > %u",
+				    ltmp, DEFDATALEN);
 			}
 			options |= F_SWEEP;
-			sweepmax = ultmp;
+			sweepmax = ltmp;
 			break;
 		case 'g': /* Minimum packet size for ping sweep */
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp <= 0)
 				errx(EX_USAGE, "invalid packet size: `%s'",
 				    optarg);
-			if (uid != 0 && ultmp > DEFDATALEN) {
+			if (uid != 0 && ltmp > DEFDATALEN) {
 				errno = EPERM;
 				err(EX_NOPERM,
-				    "packet size too large: %lu > %u",
-				    ultmp, DEFDATALEN);
+				    "packet size too large: %ld > %u",
+				    ltmp, DEFDATALEN);
 			}
 			options |= F_SWEEP;
-			sweepmin = ultmp;
+			sweepmin = ltmp;
 			break;
 		case 'h': /* Packet size increment for ping sweep */
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg || ultmp < 1)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp < 1)
 				errx(EX_USAGE, "invalid increment size: `%s'",
 				    optarg);
-			if (uid != 0 && ultmp > DEFDATALEN) {
+			if (uid != 0 && ltmp > DEFDATALEN) {
 				errno = EPERM;
 				err(EX_NOPERM,
-				    "packet size too large: %lu > %u",
-				    ultmp, DEFDATALEN);
+				    "packet size too large: %ld > %u",
+				    ltmp, DEFDATALEN);
 			}
 			options |= F_SWEEP;
-			sweepincr = ultmp;
+			sweepincr = ltmp;
 			break;
 		case 'I':		/* multicast interface */
 			if (inet_aton(optarg, &ifaddr) == 0)
@@ -399,15 +400,15 @@ main(int argc, char *const *argv)
 			loop = 0;
 			break;
 		case 'l':
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg || ultmp > INT_MAX)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp > INT_MAX || ltmp < 0)
 				errx(EX_USAGE,
 				    "invalid preload value: `%s'", optarg);
 			if (uid) {
 				errno = EPERM;
 				err(EX_NOPERM, "-l flag");
 			}
-			preload = ultmp;
+			preload = ltmp;
 			break;
 		case 'M':
 			switch(optarg[0]) {
@@ -425,10 +426,10 @@ main(int argc, char *const *argv)
 			}
 			break;
 		case 'm':		/* TTL */
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg || ultmp > MAXTTL)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp > MAXTTL || ltmp < 0)
 				errx(EX_USAGE, "invalid TTL: `%s'", optarg);
-			ttl = ultmp;
+			ttl = ltmp;
 			options |= F_TTL;
 			break;
 		case 'n':
@@ -470,24 +471,24 @@ main(int argc, char *const *argv)
 			source = optarg;
 			break;
 		case 's':		/* size of packet to send */
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp < 0)
 				errx(EX_USAGE, "invalid packet size: `%s'",
 				    optarg);
-			if (uid != 0 && ultmp > DEFDATALEN) {
+			if (uid != 0 && ltmp > DEFDATALEN) {
 				errno = EPERM;
 				err(EX_NOPERM,
-				    "packet size too large: %lu > %u",
-				    ultmp, DEFDATALEN);
+				    "packet size too large: %ld > %u",
+				    ltmp, DEFDATALEN);
 			}
-			datalen = ultmp;
+			datalen = ltmp;
 			break;
 		case 'T':		/* multicast TTL */
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg || ultmp > MAXTTL)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp > MAXTTL || ltmp < 0)
 				errx(EX_USAGE, "invalid multicast TTL: `%s'",
 				    optarg);
-			mttl = ultmp;
+			mttl = ltmp;
 			options |= F_MTTL;
 			break;
 		case 't':
@@ -513,10 +514,10 @@ main(int argc, char *const *argv)
 			break;
 		case 'z':
 			options |= F_HDRINCL;
-			ultmp = strtoul(optarg, &ep, 0);
-			if (*ep || ep == optarg || ultmp > MAXTOS)
+			ltmp = strtol(optarg, &ep, 0);
+			if (*ep || ep == optarg || ltmp > MAXTOS || ltmp < 0)
 				errx(EX_USAGE, "invalid TOS: `%s'", optarg);
-			tos = ultmp;
+			tos = ltmp;
 			break;
 		default:
 			usage();


More information about the svn-src-all mailing list