Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-6]: src/sbin/ping Pull up following revision(s) (requested by dho...



details:   https://anonhg.NetBSD.org/src/rev/3106df4095b8
branches:  netbsd-6
changeset: 777179:3106df4095b8
user:      snj <snj%NetBSD.org@localhost>
date:      Tue Jul 11 21:16:07 2017 +0000

description:
Pull up following revision(s) (requested by dholland in ticket #1424):
        sbin/ping/ping.c: revision 1.113 via patch
PR bin/36997 Zafer Aydogan: ping doesn't validate numeric inputs enough.
Check for values between INT_MAX and LONG_MAX (if they're different)
when using strtol to get an int. This applies to the -c and -l options;
the other uses were already checked.
Also limit the inter-packet interval given with -i to values that
don't cause integer overflow calling poll() with milliseconds.
Really large intervals (the number is read as floating point) can
produce positive poll() values but negative integers when converted to
struct timespec; this produces behavior akin to using -l at first and
could be construed as a local DoS vulnerability.

diffstat:

 sbin/ping/ping.c |  44 ++++++++++++++++++++++++++++++++++----------
 1 files changed, 34 insertions(+), 10 deletions(-)

diffs (74 lines):

diff -r e42f689aaf11 -r 3106df4095b8 sbin/ping/ping.c
--- a/sbin/ping/ping.c  Tue Jul 11 21:09:29 2017 +0000
+++ b/sbin/ping/ping.c  Tue Jul 11 21:16:07 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ping.c,v 1.102.2.1 2012/10/23 19:44:44 riz Exp $       */
+/*     $NetBSD: ping.c,v 1.102.2.2 2017/07/11 21:16:07 snj Exp $       */
 
 /*
  * Copyright (c) 1989, 1993
@@ -58,7 +58,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ping.c,v 1.102.2.1 2012/10/23 19:44:44 riz Exp $");
+__RCSID("$NetBSD: ping.c,v 1.102.2.2 2017/07/11 21:16:07 snj Exp $");
 #endif
 
 #include <stdio.h>
@@ -291,9 +291,17 @@
                        compat = 1;
                        break;
                case 'c':
-                       npackets = strtol(optarg, &p, 0);
-                       if (*p != '\0' || npackets <= 0)
-                               errx(1, "Bad/invalid number of packets");
+                       l = strtol(optarg, &p, 0);
+                       if (*p != '\0' || l <= 0)
+                               errx(EXIT_FAILURE,
+                                   "Bad/invalid number of packets: %s",
+                                   optarg);
+#if INT_MAX < LONG_MAX
+                       if (l > INT_MAX)
+                               errx(EXIT_FAILURE,
+                                   "Too many packets to count: %ld", l);
+#endif
+                       npackets = l;
                        break;
                case 'D':
                        pingflags |= F_DF;
@@ -310,13 +318,29 @@
                case 'i':               /* wait between sending packets */
                        interval = strtod(optarg, &p);
                        if (*p != '\0' || interval <= 0)
-                               errx(1, "Bad/invalid interval %s", optarg);
+                               errx(EXIT_FAILURE, "Bad/invalid interval: %s",
+                                   optarg);
+                       /*
+                        * In order to avoid overflowing the microseconds
+                        * argument of poll() the interval must be less than
+                        * INT_MAX/1000. Limit it to one second less than
+                        * that to be safe.
+                        */
+                       if (interval >= INT_MAX/1000.0 - 1.0)
+                               errx(EXIT_FAILURE,
+                                   "Timing interval %g too large", interval);
                        break;
                case 'l':
-                       preload = strtol(optarg, &p, 0);
-                       if (*p != '\0' || preload < 0)
-                               errx(1, "Bad/invalid preload value %s",
-                                    optarg);
+                       l = strtol(optarg, &p, 0);
+                       if (*p != '\0' || l < 0)
+                               errx(EXIT_FAILURE, "Bad/invalid preload value: "
+                                   "%s", optarg);
+#if INT_MAX < LONG_MAX
+                       if (l > INT_MAX)
+                               errx(EXIT_FAILURE,
+                                   "Too many preload packets: %ld", l);
+#endif
+                       preload = l;
                        break;
                case 'n':
                        pingflags |= F_NUMERIC;



Home | Main Index | Thread Index | Old Index