From owner-svn-src-all@freebsd.org Tue Dec 1 15:09:03 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 61FDE4AB64F; Tue, 1 Dec 2020 15:09:03 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Cllqg20Dwz3vFl; Tue, 1 Dec 2020 15:09:03 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3756817A16; Tue, 1 Dec 2020 15:09:03 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0B1F93Ce032230; Tue, 1 Dec 2020 15:09:03 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0B1F93wG032229; Tue, 1 Dec 2020 15:09:03 GMT (envelope-from markj@FreeBSD.org) Message-Id: <202012011509.0B1F93wG032229@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Tue, 1 Dec 2020 15:09:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r368231 - stable/12/sbin/ping X-SVN-Group: stable-12 X-SVN-Commit-Author: markj X-SVN-Commit-Paths: stable/12/sbin/ping X-SVN-Commit-Revision: 368231 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Dec 2020 15:09:03 -0000 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; }