Compare commits

...

No commits in common. "imports/c8s/iputils-20180629-6.el8" and "c8" have entirely different histories.

10 changed files with 360 additions and 153 deletions

View File

@ -0,0 +1,38 @@
From e0baf20067a75f093d690bd51a6db3f5afabca77 Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Tue, 17 Jul 2018 17:56:10 +0200
Subject: [PATCH] tracepath: Fix copying input IPv6 address
Commit e669c86 broke copying input IPv6 address.
tracepath recover from it, but it's slower.
Previously was address too short:
strace ./tracepath -6 fe80::8895:e2af:e96e:fd8f
sendto(3, "\1\0\0\0\0\0\0\0\307\36N[\0\0\0\0w_\f\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 127952, 0, {sa_family=AF_INET6, sin6_port=htons(44444), inet_pton(AF_INET6, "fe80::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = -1 EMSGSIZE (Message too long)
After fix is correct:
sendto(3, "\1\0\0\0\0\0\0\0\300\36N[\0\0\0\0'B\3\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 127952, 0, {sa_family=AF_INET6, sin6_port=htons(44444), inet_pton(AF_INET6, "fe80::8895:e2af:e96e:fd8f", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = -1 EMSGSIZE (Message too long)
Bug found by LTP test.
Fixes: e669c86 tracepath: fix heap-buffer-overflow [asan]
Fixes: #137
---
tracepath.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tracepath.c b/tracepath.c
index 53bda16f..539a7a11 100644
--- a/tracepath.c
+++ b/tracepath.c
@@ -475,7 +475,7 @@ int main(int argc, char **argv)
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (fd < 0)
continue;
- memcpy(&target, ai->ai_addr, sizeof(*ai->ai_addr));
+ memcpy(&target, ai->ai_addr, ai->ai_addrlen);
targetlen = ai->ai_addrlen;
break;
}

View File

@ -0,0 +1,48 @@
From 18f9a84e0e702841d6cc4d5f593de4fbd1348e83 Mon Sep 17 00:00:00 2001
From: Sami Kerola <kerolasa@iki.fi>
Date: Sat, 28 Dec 2019 17:16:27 +0000
Subject: [PATCH] ninfod: change variable name to avoid colliding with function
name
The sys/capability.h header has 'extern int cap_setuid(uid_t uid);'
function prototype.
Addresses: https://github.com/iputils/iputils/issues/246
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
ninfod/ninfod.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ninfod/ninfod.c b/ninfod/ninfod.c
index 26112d0d..95583de4 100644
--- a/ninfod/ninfod.c
+++ b/ninfod/ninfod.c
@@ -455,7 +455,7 @@ static void do_daemonize(void)
/* --------- */
#ifdef HAVE_LIBCAP
static const cap_value_t cap_net_raw = CAP_NET_RAW;
-static const cap_value_t cap_setuid = CAP_SETUID;
+static const cap_value_t cap_setuserid = CAP_SETUID;
static cap_flag_value_t cap_ok;
#else
static uid_t euid;
@@ -487,7 +487,7 @@ static void limit_capabilities(void)
cap_get_flag(cap_cur_p, CAP_SETUID, CAP_PERMITTED, &cap_ok);
if (cap_ok != CAP_CLEAR)
- cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_setuid, CAP_SET);
+ cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_setuserid, CAP_SET);
if (cap_set_proc(cap_p) < 0) {
DEBUG(LOG_ERR, "cap_set_proc: %s\n", strerror(errno));
@@ -520,8 +520,8 @@ static void drop_capabilities(void)
/* setuid / setuid */
if (cap_ok != CAP_CLEAR) {
- cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_setuid, CAP_SET);
- cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &cap_setuid, CAP_SET);
+ cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_setuserid, CAP_SET);
+ cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &cap_setuserid, CAP_SET);
if (cap_set_proc(cap_p) < 0) {
DEBUG(LOG_ERR, "cap_set_proc: %s\n", strerror(errno));

View File

@ -0,0 +1,113 @@
From dc4f836759887a6edf141aa55adbdb9bc63f5e69 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 22 Mar 2022 12:59:21 +0100
Subject: [PATCH] ping: Fix unwanted bell on unreachable address
Commit 4471ac629cf2603f4b8b45e042e072c992ce25a5 caused regression for IPv6
that ping -a IP6_ADDR beeps also on wrong address (i.e. when "Address
unreachable"):
$ ping -a -c1 fd00:1:1:1::15
PING fd00:1:1:1::15(fd00:1:1:1::15) 56 data bytes
From fd00:1:1:1::2 icmp_seq=1 Destination unreachable: Address unreachable
--- fd00:1:1:1::15 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0m
It should only bell when ping returns correctly.
Another (fixed) regression was that ping after exit printed error "pipe N",
where N is number of counts. Error was result of code from ping_common.c:
printf("%spipe %d", comma, pipesize);
4471ac6 was wrong that code for sock->working_recverr == 1 should stay,
sock->working_recverr should be removed.
Thus changes:
* ping.c: put back "stronger filter" for raw socket but (unlike before
4471ac6) exit with 2 if setsockopt(ICMP_FILTER) fails
* ping6_common.c: put back setsockopt(IPV6_RECVERR), but (unlike before
4471ac6) exit with 2 if it fails
* ping6_common.c: remove ICMP6_FILTER_SETPASS calls. These caused error "pipe N".
* ping6_common.c: return 0 after acknowledge() in ping6_parse_reply
Fixes: 4471ac6 ("ping: Remove workaround for bug in IP_RECVERR on raw sockets")
Fixes: https://github.com/iputils/iputils/issues/182
Reported-by: Luiz Angelo Daros de Luca <luizluca@tre-sc.jus.br>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Sami Kerola <kerolasa@iki.fi>
---
Patch has been adjusted to be applicable to RHEL8 codebase
Resolves: #2057570
---
ping.c | 11 +++++++++++
ping6_common.c | 15 +++------------
2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/ping.c b/ping.c
index d9a3f5d..c870390 100644
--- a/ping.c
+++ b/ping.c
@@ -949,6 +949,17 @@ int ping4_receive_error_msg(socket_st *sock)
acknowledge(ntohs(icmph.un.echo.sequence));
+ if (sock->socktype == SOCK_RAW)
+ {
+ struct icmp_filter filt;
+
+ filt.data = ~((1 << ICMP_SOURCE_QUENCH) |
+ (1 << ICMP_REDIRECT) |
+ (1 << ICMP_ECHOREPLY));
+ if (setsockopt(sock->fd, SOL_RAW, ICMP_FILTER, (const void *)&filt,
+ sizeof(filt)) == -1)
+ error(2, errno, "setsockopt(ICMP_FILTER)");
+ }
net_errors++;
nerrors++;
if (options & F_QUIET)
diff --git a/ping6_common.c b/ping6_common.c
index 5991c2a..1181341 100644
--- a/ping6_common.c
+++ b/ping6_common.c
@@ -879,6 +879,8 @@ int ping6_run(int argc, char **argv, struct addrinfo *ai, struct socket_st *sock
}
hold = 1;
+ if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVERR, (const void *)&hold, sizeof hold))
+ error(2, errno, "IPV6_RECVERR");
/* Estimate memory eaten by single packet. It is rough estimate.
* Actually, for small datalen's it depends on kernel side a lot. */
@@ -906,11 +908,6 @@ int ping6_run(int argc, char **argv, struct addrinfo *ai, struct socket_st *sock
ICMP6_FILTER_SETBLOCKALL(&filter);
- ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &filter);
- ICMP6_FILTER_SETPASS(ICMP6_PACKET_TOO_BIG, &filter);
- ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &filter);
- ICMP6_FILTER_SETPASS(ICMP6_PARAM_PROB, &filter);
-
if (niquery_is_enabled())
ICMP6_FILTER_SETPASS(ICMPV6_NI_REPLY, &filter);
else
@@ -1437,13 +1434,7 @@ ping6_parse_reply(socket_st *sock, struct msghdr *msg, int cc, void *addr, struc
!is_ours(sock, icmph1->icmp6_id))
return 1;
acknowledge(ntohs(icmph1->icmp6_seq));
- nerrors++;
- if (options & F_FLOOD) {
- write_stdout("\bE", 2);
- return 0;
- }
- print_timestamp();
- printf("From %s: icmp_seq=%u ", pr_addr(from, sizeof *from), ntohs(icmph1->icmp6_seq));
+ return 0;
} else {
/* We've got something other than an ECHOREPLY */
if (!(options & F_VERBOSE) || uid)
--
2.35.1

View File

@ -0,0 +1,131 @@
From 2cc34ea408602f84fe102598ca258126531736c9 Mon Sep 17 00:00:00 2001
From: Jon Harrison <jon.harrison@metaswitch.com>
Date: Tue, 9 Jul 2019 16:48:07 +0100
Subject: [PATCH] ping: allow user to specify VRF and source IP
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Without this, the options for sending a ping in the context of a VRF are
limited.
We can send a ping with a specific source IP address. For example:
ping 10.1.1.3 -I 10.1.1.2
We can send a ping in the context of a Linux VRF. For example:
ping 10.1.1.3 -I vrf_red
However, when pinging in the context of a VRF, Linux does not always choose
a sensible source IP address the source IP might not belong to the VRF.
As a result, the ping wont get a response. As a result, we want to be able
to specify both a VRF and a source IP address when initiating a ping. For
example:
ping 10.1.1.3 -I vrf_red -I 10.1.1.2
Ping reads in the command line parameters fine and sets up the 'source' and
'device' variables, but currently ignores the device if the source IP
address is non-zero. This commit adds a branch to ping.c that does the
socket bind to the device even in the case where the source IP is non-zero.
This branch is based on the existing case where source IP is zero, but
simplified a bit because we've already got a source IP address to use.
(cherry picked from commit 9e08707d743b29e853df81bd7def1729e3afe55d)
---
doc/ping.xml | 15 ++++++++++-----
ping.c | 44 +++++++++++++++++++++++++++++++++++++++++---
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/doc/ping.xml b/doc/ping.xml
index bdf07b3..034e40c 100644
--- a/doc/ping.xml
+++ b/doc/ping.xml
@@ -158,11 +158,16 @@ to values less than 0.2 seconds.</para>
<varlistentry>
<term><option>-I </option><emphasis remap='I'>interface</emphasis></term>
<listitem>
-<para><emphasis remap='I'>interface</emphasis> is either an address, or an interface name.
-If <emphasis remap='I'>interface</emphasis> is an address, it sets source address
-to specified interface address.
-If <emphasis remap='I'>interface</emphasis> in an interface name, it sets
-source interface to specified interface.
+<para><emphasis remap='I'>interface</emphasis> is either an
+address, an interface name or a VRF name. If
+<emphasis remap="I">interface</emphasis> is an address, it
+sets source address to specified interface address. If
+<emphasis remap="I">interface</emphasis> is an interface
+name, it sets source interface to specified interface.
+If <emphasis remap="I">interface</emphasis> is a VRF
+name, each packet is routed using the corresponding
+routing table; in this case, the <option>-I</option> option
+can be repeated to specify a source address.
NOTE: For IPv6, when doing ping to a link-local scope
address, link specification (by the '%'-notation in
<emphasis remap='I'>destination</emphasis>, or by this option)
diff --git a/ping.c b/ping.c
index c870390..0f87723 100644
--- a/ping.c
+++ b/ping.c
@@ -705,7 +705,43 @@ int ping4_run(int argc, char **argv, struct addrinfo *ai, socket_st *sock)
}
#endif
close(probe_fd);
- } while (0);
+
+ } else if (device) {
+ struct sockaddr_in dst = whereto;
+ struct ifreq ifr;
+ int fd = sock->fd;
+ int rc;
+ int errno_save;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
+
+ enable_capability_raw();
+ rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1);
+ errno_save = errno;
+ disable_capability_raw();
+
+ if (rc == -1) {
+ if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
+ struct ip_mreqn imr;
+
+ if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
+ fprintf(stderr, "ping: %s: %s\n", "(\"unknown interface\")", device);
+ exit(2);
+ }
+ memset(&imr, 0, sizeof(imr));
+ imr.imr_ifindex = ifr.ifr_ifindex;
+ if (setsockopt(fd, SOL_IP, IP_MULTICAST_IF,
+ &imr, sizeof(imr)) == -1) {
+ fprintf(stderr, "ping: IP_MULTICAST_IF: %s\n", strerror(errno));
+ exit(2);
+ }
+ } else {
+ fprintf(stderr, "ping: SO_BINDTODEVICE %s: %s\n", device, strerror(errno_save));
+ exit(2);
+ }
+ }
+ }
if (whereto.sin_addr.s_addr == 0)
whereto.sin_addr.s_addr = source.sin_addr.s_addr;
@@ -957,8 +993,10 @@ int ping4_receive_error_msg(socket_st *sock)
(1 << ICMP_REDIRECT) |
(1 << ICMP_ECHOREPLY));
if (setsockopt(sock->fd, SOL_RAW, ICMP_FILTER, (const void *)&filt,
- sizeof(filt)) == -1)
- error(2, errno, "setsockopt(ICMP_FILTER)");
+ sizeof(filt)) == -1) {
+ fprintf(stderr, "ping: setsockopt(ICMP_FILTER): %s\n", strerror(errno));
+ exit(2);
+ }
}
net_errors++;
nerrors++;
--
2.40.1

View File

@ -1,146 +0,0 @@
From 9633d828e8166e47af733cbc6563ac93e5e06a30 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
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 <gitmail@zeuz.ch>
93dfb95d48977d151dbe94983e4998959e748aee Rosen Penev <rosenp@gmail.com>
---
ping.c | 89 ++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 58 insertions(+), 31 deletions(-)
diff --git a/ping.c b/ping.c
index d9a3f5d..33f7d45 100644
--- a/ping.c
+++ b/ping.c
@@ -57,6 +57,7 @@
#ifndef WITHOUT_IFADDRS
#include <ifaddrs.h>
#endif
+#include <math.h>
#ifndef ICMP_FILTER
#define ICMP_FILTER 1
@@ -192,6 +193,38 @@ 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:
+ fprintf(stderr, "%s: %s", err_msg, str);
+ exit(2);
+}
+
int
main(int argc, char **argv)
{
@@ -298,30 +331,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 +482,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.29.2

View File

@ -3,7 +3,7 @@
Summary: Network monitoring tools including ping
Name: iputils
Version: 20180629
Release: 6%{?dist}
Release: 11%{?dist}
# some parts are under the original BSD (ping.c)
# some are under GPLv2+ (tracepath.c)
License: BSD and GPLv2+
@ -18,11 +18,16 @@ Source3: ninfod.service
Source4: bsd.txt
Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
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
Patch0: 0000-iputils-rh.patch
Patch1: 0001-iputils-ifenslave.patch
Patch2: 0002-iputils-freeaddrinfo.patch
Patch3: 0003-fix-incorrect-statistics.patch
Patch4: 0004-tracepath-fix-copying-input-ipv6-address.patch
Patch5: 0005-ninfod-change-variable-name-to-avoid-colliding-with-function-name.patch
Patch6: 0006-ping-Fix-unwanted-bell-on-unreachable-address.patch
# bz2208409 - [RFE] support VRF with ping command
Patch7: 0007-ping-allow-user-to-specify-VRF-and-source-IP.patch
%if ! 0%{?_module_build}
BuildRequires: docbook-utils perl-SGMLSpm
@ -66,6 +71,9 @@ cp %{SOURCE4} %{SOURCE5} .
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%build
%ifarch s390 s390x
@ -142,7 +150,7 @@ install -m 644 %SOURCE3 ${RPM_BUILD_ROOT}/%{_unitdir}
%{_unitdir}/rdisc.service
%attr(0755,root,root) %caps(cap_net_raw=p) %{_sbindir}/clockdiff
%attr(0755,root,root) %caps(cap_net_raw=p) %{_sbindir}/arping
%attr(0755,root,root) %caps(cap_net_raw=p cap_net_admin=p) %{_bindir}/ping
%attr(0755,root,root) %{_bindir}/ping
%{_sbindir}/ifenslave
%{_sbindir}/rdisc
%{_bindir}/tracepath
@ -169,6 +177,21 @@ install -m 644 %SOURCE3 ${RPM_BUILD_ROOT}/%{_unitdir}
%endif
%changelog
* Thu Jun 08 2023 Jan Macku <jamacku@redhat.com> - 20180629-11
- Add support for VRF with ping command (#2208409)
* Tue Mar 22 2022 Jan Macku <jamacku@redhat.com> - 20180629-10
- Fix regression of output when pinging unreachable IPv6 host (#2057570)
* Thu Feb 03 2022 Jan Macku <jamacku@redhat.com> - 20180629-9
- Fix copying input IPv6 address (#2047659)
* Mon Jan 03 2022 Jan Macku <jamacku@redhat.com> - 20180629-8
- Make ping unprivileged (#2030107)
* Wed Feb 17 2021 Jan Macku <jamacku@redhat.com> - 20180629-7
- Revert patch introduced by #1852638 (#1928179)
* Tue Dec 15 2020 Jan Macku <jamacku@redhat.com> - 20180629-6
- Exit on error (#1852638)