iputils/backport-ping-Fix-the-errno-handling-for-strtod.patch

65 lines
2.2 KiB
Diff
Raw Normal View History

2025-02-13 06:19:15 +00:00
From 33e78be2e60ed9ac918dec13271d1bd9dce6e94e Mon Sep 17 00:00:00 2001
From: Jacek Tomasiak <jtomasiak@arista.com>
Date: Mon, 6 Feb 2023 13:39:44 +0100
Subject: [PATCH] ping: Fix the errno handling for strtod
The setlocale(LC_ALL, "") following the strtod() for the '-i' option
can fail if the LC_CTYPE is invalid.
Hence the errno check following the setlocale(LC_ALL, "") thinks
wrongly that strtod() failed with the errno and prints a warning:
$ LC_ALL=XXX ping -i 1.9 -c1 8.8.8.8
ping: option argument contains garbage:
ping: this will become fatal error in the future
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=1.34 ms
The errno got from the execution of strtod() is saved and restored
after setlocale() to be checked for any errors.
The problem is only on Fedora/CentOS/RHEL with applied patch [1]
from 2012 for glibc bug #14247.
[1] https://src.fedoraproject.org/rpms/glibc/blob/rawhide/f/glibc-rh827510.patch
Link: https://sourceware.org/bugzilla/show_bug.cgi?id=14247
Closes: https://github.com/iputils/iputils/pull/450
Reference:https://github.com/iputils/iputils/commit/33e78be2e60ed9ac918dec13271d1bd9dce6e94e
Conflict:NA
Fixes: 918e824 ("ping: add support for sub-second timeouts")
Co-Developed-by: Sriram Rajagopalan <sriramr@arista.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
[ pvorel: mention glibc bug and Fedora/CentOS/RHEL ]
Signed-off-by: Sriram Rajagopalan <sriramr@arista.com>
Signed-off-by: Jacek Tomasiak <jtomasiak@arista.com>
---
ping/ping.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ping/ping.c b/ping/ping.c
index 89b0fa19..8f442037 100644
--- a/ping/ping.c
+++ b/ping/ping.c
@@ -214,6 +214,7 @@ static double ping_strtod(const char *str, const char *err_msg)
{
double num;
char *end = NULL;
+ int strtod_errno = 0;
if (str == NULL || *str == '\0')
goto err;
@@ -225,7 +226,10 @@ static double ping_strtod(const char *str, const char *err_msg)
*/
setlocale(LC_ALL, "C");
num = strtod(str, &end);
+ strtod_errno = errno;
setlocale(LC_ALL, "");
+ /* Ignore setlocale() errno (e.g. invalid locale in env). */
+ errno = strtod_errno;
if (errno || str == end || (end && *end)) {
error(0, 0, _("option argument contains garbage: %s"), end);