Tue Jul 11 21:15:23 2017 UTC ()
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.


(snj)
diff -r1.102 -r1.102.8.1 src/sbin/ping/ping.c

cvs diff -r1.102 -r1.102.8.1 src/sbin/ping/ping.c (expand / switch to unified diff)

--- src/sbin/ping/ping.c 2012/01/04 16:09:42 1.102
+++ src/sbin/ping/ping.c 2017/07/11 21:15:23 1.102.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ping.c,v 1.102 2012/01/04 16:09:42 drochner Exp $ */ 1/* $NetBSD: ping.c,v 1.102.8.1 2017/07/11 21:15:23 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1993 4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Mike Muuss. 8 * Mike Muuss.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -48,27 +48,27 @@ @@ -48,27 +48,27 @@
48 * ttl, duplicate detection - Cliff Frost, UCB, April 1989 48 * ttl, duplicate detection - Cliff Frost, UCB, April 1989
49 * Pad pattern - Cliff Frost (from Tom Ferrin, UCSF), April 1989 49 * Pad pattern - Cliff Frost (from Tom Ferrin, UCSF), April 1989
50 * 50 *
51 * Status - 51 * Status -
52 * Public Domain. Distribution Unlimited. 52 * Public Domain. Distribution Unlimited.
53 * 53 *
54 * Bugs - 54 * Bugs -
55 * More statistics could always be gathered. 55 * More statistics could always be gathered.
56 * This program has to run SUID to ROOT to access the ICMP socket. 56 * This program has to run SUID to ROOT to access the ICMP socket.
57 */ 57 */
58 58
59#include <sys/cdefs.h> 59#include <sys/cdefs.h>
60#ifndef lint 60#ifndef lint
61__RCSID("$NetBSD: ping.c,v 1.102 2012/01/04 16:09:42 drochner Exp $"); 61__RCSID("$NetBSD: ping.c,v 1.102.8.1 2017/07/11 21:15:23 snj Exp $");
62#endif 62#endif
63 63
64#include <stdio.h> 64#include <stdio.h>
65#include <stddef.h> 65#include <stddef.h>
66#include <errno.h> 66#include <errno.h>
67#include <signal.h> 67#include <signal.h>
68#include <sys/time.h> 68#include <sys/time.h>
69#include <sys/types.h> 69#include <sys/types.h>
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/socket.h> 71#include <sys/socket.h>
72#include <sys/file.h> 72#include <sys/file.h>
73#include <termios.h> 73#include <termios.h>
74#include <stdlib.h> 74#include <stdlib.h>
@@ -281,52 +281,76 @@ main(int argc, char *argv[]) @@ -281,52 +281,76 @@ main(int argc, char *argv[])
281#endif /*IPSEC_POLICY_IPSEC*/ 281#endif /*IPSEC_POLICY_IPSEC*/
282#endif 282#endif
283 while ((c = getopt(argc, argv, 283 while ((c = getopt(argc, argv,
284 "ac:CdDfg:h:i:I:l:Lnop:PqQrRs:t:T:vw:" IPSECOPT)) != -1) { 284 "ac:CdDfg:h:i:I:l:Lnop:PqQrRs:t:T:vw:" IPSECOPT)) != -1) {
285#undef IPSECOPT 285#undef IPSECOPT
286 switch (c) { 286 switch (c) {
287 case 'a': 287 case 'a':
288 pingflags |= F_AUDIBLE; 288 pingflags |= F_AUDIBLE;
289 break; 289 break;
290 case 'C': 290 case 'C':
291 compat = 1; 291 compat = 1;
292 break; 292 break;
293 case 'c': 293 case 'c':
294 npackets = strtol(optarg, &p, 0); 294 l = strtol(optarg, &p, 0);
295 if (*p != '\0' || npackets <= 0) 295 if (*p != '\0' || l <= 0)
296 errx(1, "Bad/invalid number of packets"); 296 errx(EXIT_FAILURE,
 297 "Bad/invalid number of packets: %s",
 298 optarg);
 299#if INT_MAX < LONG_MAX
 300 if (l > INT_MAX)
 301 errx(EXIT_FAILURE,
 302 "Too many packets to count: %ld", l);
 303#endif
 304 npackets = l;
297 break; 305 break;
298 case 'D': 306 case 'D':
299 pingflags |= F_DF; 307 pingflags |= F_DF;
300 break; 308 break;
301 case 'd': 309 case 'd':
302 options |= SO_DEBUG; 310 options |= SO_DEBUG;
303 break; 311 break;
304 case 'f': 312 case 'f':
305 pingflags |= F_FLOOD; 313 pingflags |= F_FLOOD;
306 break; 314 break;
307 case 'h': 315 case 'h':
308 hostind = optind-1; 316 hostind = optind-1;
309 break; 317 break;
310 case 'i': /* wait between sending packets */ 318 case 'i': /* wait between sending packets */
311 interval = strtod(optarg, &p); 319 interval = strtod(optarg, &p);
312 if (*p != '\0' || interval <= 0) 320 if (*p != '\0' || interval <= 0)
313 errx(1, "Bad/invalid interval %s", optarg); 321 errx(EXIT_FAILURE, "Bad/invalid interval: %s",
 322 optarg);
 323 /*
 324 * In order to avoid overflowing the microseconds
 325 * argument of poll() the interval must be less than
 326 * INT_MAX/1000. Limit it to one second less than
 327 * that to be safe.
 328 */
 329 if (interval >= INT_MAX/1000.0 - 1.0)
 330 errx(EXIT_FAILURE,
 331 "Timing interval %g too large", interval);
314 break; 332 break;
315 case 'l': 333 case 'l':
316 preload = strtol(optarg, &p, 0); 334 l = strtol(optarg, &p, 0);
317 if (*p != '\0' || preload < 0) 335 if (*p != '\0' || l < 0)
318 errx(1, "Bad/invalid preload value %s", 336 errx(EXIT_FAILURE, "Bad/invalid preload value: "
319 optarg); 337 "%s", optarg);
 338#if INT_MAX < LONG_MAX
 339 if (l > INT_MAX)
 340 errx(EXIT_FAILURE,
 341 "Too many preload packets: %ld", l);
 342#endif
 343 preload = l;
320 break; 344 break;
321 case 'n': 345 case 'n':
322 pingflags |= F_NUMERIC; 346 pingflags |= F_NUMERIC;
323 break; 347 break;
324 case 'o': 348 case 'o':
325 pingflags |= F_ONCE; 349 pingflags |= F_ONCE;
326 break; 350 break;
327 case 'p': /* fill buffer with user pattern */ 351 case 'p': /* fill buffer with user pattern */
328 if (pingflags & F_PING_RANDOM) 352 if (pingflags & F_PING_RANDOM)
329 errx(1, "Only one of -P and -p allowed"); 353 errx(1, "Only one of -P and -p allowed");
330 pingflags |= F_PING_FILLED; 354 pingflags |= F_PING_FILLED;
331 fill_pat = optarg; 355 fill_pat = optarg;
332 break; 356 break;