diff --git a/SOURCES/ping-add-support-for-sub-second-timeouts.patch b/SOURCES/ping-add-support-for-sub-second-timeouts.patch new file mode 100644 index 0000000..d5ee6b1 --- /dev/null +++ b/SOURCES/ping-add-support-for-sub-second-timeouts.patch @@ -0,0 +1,148 @@ +From 1308c7679307e80e638bccce2a6e5eb721fa9d27 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Wed, 9 Dec 2020 10:23:09 +0100 +Subject: [PATCH] ping: add support for sub-second timeouts + +Timeouts (-W) were previously silently rounded down to the next lower +integral number. Subsecond values were rounded to zero which resulted in +infinite timeouts, therefore ping never exited if there were no responses +and timeouts below 1s. This commit fixes this issue. + +[Sami: I changed ping_strtod() to return double. Claudius did updated +needed value by pointer reference, and had multiplication by 1000 in +wrapper function. I think that made understanding the code unnecessarily +difficult, so implementation was slightly changed.] + +Backported from upstream PATCH: + 918e824dc13a39e4d68fcd82fd2d248c9fba6bbd Claudius Zingerli + 93dfb95d48977d151dbe94983e4998959e748aee Rosen Penev +--- + ping.c | 91 ++++++++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 60 insertions(+), 31 deletions(-) + +diff --git a/ping.c b/ping.c +index d9a3f5d..fec2453 100644 +--- a/ping.c ++++ b/ping.c +@@ -57,6 +57,7 @@ + #ifndef WITHOUT_IFADDRS + #include + #endif ++#include + + #ifndef ICMP_FILTER + #define ICMP_FILTER 1 +@@ -192,6 +193,40 @@ static void set_socket_option(socket_st *sock, int level, int optname, const voi + } + } + ++/* Much like stdtod(3, but will fails if str is not valid number. */ ++static double ping_strtod(const char *str, const char *err_msg) ++{ ++ double num; ++ char *end = NULL; ++ ++ if (str == NULL || *str == '\0') ++ goto err; ++ errno = 0; ++#ifdef USE_IDN ++ setlocale(LC_ALL, "C"); ++#endif ++ num = strtod(str, &end); ++#ifdef USE_IDN ++ setlocale(LC_ALL, ""); ++#endif ++ if (errno || str == end || (end && *end)) ++ goto err; ++ switch (fpclassify(num)) { ++ case FP_NORMAL: ++ case FP_ZERO: ++ break; ++ default: ++ errno = ERANGE; ++ goto err; ++ } ++ return num; ++err: ++ if (errno == ERANGE) ++ error(2, errno, "%s: %s", err_msg, str); ++ error(2, 0, "%s: %s", err_msg, str); ++ return num; ++} ++ + int + main(int argc, char **argv) + { +@@ -298,30 +333,19 @@ main(int argc, char **argv) + options |= F_PTIMEOFDAY; + break; + case 'i': +- { +- double dbl; +- char *ep; +- +- errno = 0; +-#ifdef USE_IDN +- setlocale(LC_ALL, "C"); +-#endif +- dbl = strtod(optarg, &ep); +-#ifdef USE_IDN +- setlocale(LC_ALL, ""); +-#endif +- +- if (errno || *ep != '\0' || +- !finite(dbl) || dbl < 0.0 || dbl >= (double)INT_MAX / 1000 - 1.0) { +- fprintf(stderr, "ping: bad timing interval\n"); +- exit(2); +- } +- +- interval = (int)(dbl * 1000); +- +- options |= F_INTERVAL; +- break; +- } ++ { ++ double optval; ++ ++ optval = ping_strtod(optarg, "bad timing interval"); ++ if (isgreater(optval, (double)INT_MAX / 1000)) { ++ fprintf(stderr, "ping: bad timing interval\n"); ++ exit(2); ++ } ++ ++ interval = (int)(optval * 1000); ++ options |= F_INTERVAL; ++ } ++ break; + case 'I': + /* IPv6 */ + if (strchr(optarg, ':')) { +@@ -460,13 +484,18 @@ main(int argc, char **argv) + } + break; + case 'W': +- lingertime = atoi(optarg); +- if (lingertime < 0 || lingertime > INT_MAX/1000000) { +- fprintf(stderr, "ping: bad linger time.\n"); +- exit(2); +- } +- lingertime *= 1000; +- break; ++ { ++ double optval; ++ ++ optval = ping_strtod(optarg, "bad linger time"); ++ if (isless(optval, 0.001) || isgreater(optval, (double)INT_MAX / 1000)) { ++ fprintf(stderr, "ping: bad linger time.\n"); ++ exit(2); ++ } ++ /* lingertime will be converted to usec later */ ++ lingertime = (int)(optval * 1000); ++ } ++ break; + default: + usage(); + break; +-- +2.28.0 + diff --git a/SPECS/iputils.spec b/SPECS/iputils.spec index 4bda4ad..43e74f7 100644 --- a/SPECS/iputils.spec +++ b/SPECS/iputils.spec @@ -3,7 +3,7 @@ Summary: Network monitoring tools including ping Name: iputils Version: 20180629 -Release: 3%{?dist} +Release: 4%{?dist} # some parts are under the original BSD (ping.c) # some are under GPLv2+ (tracepath.c) License: BSD and GPLv2+ @@ -22,6 +22,7 @@ Patch0: iputils-rh.patch Patch1: iputils-ifenslave.patch Patch2: iputils-freeaddrinfo.patch Patch3: fix-incorrect-statistics.patch +Patch4: ping-add-support-for-sub-second-timeouts.patch %if ! 0%{?_module_build} BuildRequires: docbook-utils perl-SGMLSpm @@ -64,6 +65,7 @@ cp %{SOURCE4} %{SOURCE5} . %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 %build %ifarch s390 s390x @@ -167,6 +169,9 @@ install -m 644 %SOURCE3 ${RPM_BUILD_ROOT}/%{_unitdir} %endif %changelog +* Wed Dec 09 2020 Jan Macku - 20180629-4 +- Fix infinite loop caused by subsecond timeouts (#1852638) + * Tue Dec 08 2020 Jan Macku - 20180629-3 - Fix incorrect ping statistics (#1901780)