Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/ping PR bin/36997 Zafer Aydogan: ping doesn't validate ...
details: https://anonhg.NetBSD.org/src/rev/51a01dc9de7c
branches: trunk
changeset: 819802:51a01dc9de7c
user: dholland <dholland%NetBSD.org@localhost>
date: Sun Dec 18 01:19:34 2016 +0000
description:
PR bin/36997 Zafer Aydogan: ping doesn't validate numeric inputs enough.
Reject packet intervals < 1 ns as they lead to infinite loops adding
zero timespecs.
Fix the behind-schedule behavior so it doesn't spend all its time in
that loop adding very small timespecs. Try ping -c 500 -i 0.000000001
to see this in action with the old ping.
diffstat:
sbin/ping/ping.c | 39 +++++++++++++++++++++++++++++++++------
1 files changed, 33 insertions(+), 6 deletions(-)
diffs (74 lines):
diff -r b5c53145e6aa -r 51a01dc9de7c sbin/ping/ping.c
--- a/sbin/ping/ping.c Sun Dec 18 00:21:33 2016 +0000
+++ b/sbin/ping/ping.c Sun Dec 18 01:19:34 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ping.c,v 1.113 2016/12/18 00:21:33 dholland Exp $ */
+/* $NetBSD: ping.c,v 1.114 2016/12/18 01:19:34 dholland Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -58,7 +58,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: ping.c,v 1.113 2016/12/18 00:21:33 dholland Exp $");
+__RCSID("$NetBSD: ping.c,v 1.114 2016/12/18 01:19:34 dholland Exp $");
#endif
#include <stdio.h>
@@ -461,6 +461,9 @@
errx(EXIT_FAILURE, "Must be superuser to use -l");
#endif
sec_to_timespec(interval, &interval_tv);
+ if (interval_tv.tv_sec == 0 && interval_tv.tv_nsec == 0) {
+ errx(EXIT_FAILURE, "Packet interval must be at least 1 ns");
+ }
if ((pingflags & (F_AUDIBLE|F_FLOOD)) == (F_AUDIBLE|F_FLOOD))
warnx("Sorry, no audible output for flood pings");
@@ -893,6 +896,8 @@
{
struct tv32 tv32;
int i, cc, sw;
+ double waittime;
+ long numskip;
opack_icmp.icmp_code = 0;
opack_icmp.icmp_seq = htons((u_int16_t)(ntransmitted));
@@ -976,10 +981,32 @@
* If we are at most 100 ms behind, send extras to get caught up.
* Otherwise, skip packets we were too slow to send.
*/
- if (diffsec(&next_tx, &now) <= interval) {
- do {
- timespecadd(&next_tx, &interval_tv, &next_tx);
- } while (diffsec(&next_tx, &now) < -0.1);
+ waittime = diffsec(&next_tx, &now);
+ if (waittime < -1.0) {
+ /* very behind - forget about being precise */
+ next_tx.tv_sec += (int)(-waittime);
+ } else if (waittime < -0.1) {
+ /* behind - skip a few */
+ if (interval_tv.tv_sec == 0) {
+ numskip = (long)(-waittime / interval_tv.tv_nsec);
+ next_tx.tv_nsec += numskip * interval_tv.tv_nsec;
+ /*
+ * We can add at most one second's worth, but allow
+ * for tv_nsec reaching 2 billion just in case FP
+ * issues strike.
+ */
+ while (next_tx.tv_nsec >= 1000000000) {
+ next_tx.tv_sec++;
+ next_tx.tv_nsec -= 1000000000;
+ }
+ } else {
+ do {
+ timespecadd(&next_tx, &interval_tv, &next_tx);
+ } while (diffsec(&next_tx, &now) < -0.1);
+ }
+
+ } else if (waittime <= interval) {
+ timespecadd(&next_tx, &interval_tv, &next_tx);
}
if (pingflags & F_FLOOD)
Home |
Main Index |
Thread Index |
Old Index