Compare commits

..

1 Commits
c8 ... c10-beta

Author SHA1 Message Date
ae12a0dc68 import RHEL 10 Beta iputils-20240117-6.el10 2024-11-20 13:41:17 +00:00
18 changed files with 380 additions and 563 deletions

4
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/ifenslave.tar.gz
SOURCES/iputils-s20180629.tar.gz
ifenslave.tar.gz
iputils-20240117.tar.gz

View File

@ -1,2 +0,0 @@
1e2652cb1d1e29a8ebed1209131924a6eb864daf SOURCES/ifenslave.tar.gz
353df20691bf027ad35fcaaf6894b122c39d8f2d SOURCES/iputils-s20180629.tar.gz

View File

@ -0,0 +1,88 @@
From a38091c8eb0c515441080806975856ee09d2edc7 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 23 Mar 2021 08:10:10 +0100
Subject: [PATCH] ifenslave: fix CWE-170: Improper Null Termination
---
ifenslave.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/ifenslave.c b/ifenslave.c
index ddd82ec..1efe4f1 100644
--- a/ifenslave.c
+++ b/ifenslave.c
@@ -509,21 +509,24 @@ static int if_getconfig(char *ifname)
struct sockaddr dstaddr, broadaddr, netmask;
unsigned char *hwaddr;
- strcpy(ifr.ifr_name, ifname);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
return -1;
mif_flags = ifr.ifr_flags;
printf("The result of SIOCGIFFLAGS on %s is %x.\n",
ifname, ifr.ifr_flags);
- strcpy(ifr.ifr_name, ifname);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0)
return -1;
printf("The result of SIOCGIFADDR is %2.2x.%2.2x.%2.2x.%2.2x.\n",
ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3],
ifr.ifr_addr.sa_data[4], ifr.ifr_addr.sa_data[5]);
- strcpy(ifr.ifr_name, ifname);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
return -1;
@@ -534,33 +537,38 @@ static int if_getconfig(char *ifname)
ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
- strcpy(ifr.ifr_name, ifname);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) {
metric = 0;
} else
metric = ifr.ifr_metric;
printf("The result of SIOCGIFMETRIC is %d\n", metric);
- strcpy(ifr.ifr_name, ifname);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0)
mtu = 0;
else
mtu = ifr.ifr_mtu;
printf("The result of SIOCGIFMTU is %d\n", mtu);
- strcpy(ifr.ifr_name, ifname);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0) {
memset(&dstaddr, 0, sizeof(struct sockaddr));
} else
dstaddr = ifr.ifr_dstaddr;
- strcpy(ifr.ifr_name, ifname);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) < 0) {
memset(&broadaddr, 0, sizeof(struct sockaddr));
} else
broadaddr = ifr.ifr_broadaddr;
- strcpy(ifr.ifr_name, ifname);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
if (ioctl(skfd, SIOCGIFNETMASK, &ifr) < 0) {
memset(&netmask, 0, sizeof(struct sockaddr));
} else
--
2.29.2

View File

@ -0,0 +1,154 @@
From bea19fd9a86dd2c601681ff2ef4a9c1afab1e34d Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 8 Jun 2021 15:41:58 +0200
Subject: [PATCH] ifenslave: fix CWE-170: Improper Null Termination
Resolves: #1938746
---
ifenslave.c | 43 +++++++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 16 deletions(-)
diff --git a/ifenslave.c b/ifenslave.c
index 1efe4f1..59bce4c 100644
--- a/ifenslave.c
+++ b/ifenslave.c
@@ -619,7 +619,7 @@ static int get_drv_info(char *master_ifname)
char *endptr;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+ strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ - 1);
ifr.ifr_data = (caddr_t)&info;
info.cmd = ETHTOOL_GDRVINFO;
@@ -664,8 +664,9 @@ static int change_active(char *master_ifname, char *slave_ifname)
return 1;
}
- strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
- strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ - 1);
+ strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ - 1);
if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &ifr) < 0) &&
(ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &ifr) < 0)) {
saved_errno = errno;
@@ -806,8 +807,9 @@ static int enslave(char *master_ifname, char *slave_ifname)
}
/* Do the real thing */
- strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
- strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ - 1);
+ strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ - 1);
if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) &&
(ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) {
saved_errno = errno;
@@ -847,8 +849,9 @@ static int release(char *master_ifname, char *slave_ifname)
return 1;
}
- strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
- strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ - 1);
+ strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ - 1);
if ((ioctl(skfd, SIOCBONDRELEASE, &ifr) < 0) &&
(ioctl(skfd, BOND_RELEASE_OLD, &ifr) < 0)) {
saved_errno = errno;
@@ -880,7 +883,8 @@ static int get_if_settings(char *ifname, struct dev_ifr ifra[])
int res = 0;
for (i = 0; ifra[i].req_ifr; i++) {
- strncpy(ifra[i].req_ifr->ifr_name, ifname, IFNAMSIZ);
+ strncpy(ifra[i].req_ifr->ifr_name, ifname, IFNAMSIZ - 1);
+ ifra[i].req_ifr->ifr_name[IFNAMSIZ - 1] = '\0';
res = ioctl(skfd, ifra[i].req_type, ifra[i].req_ifr);
if (res < 0) {
saved_errno = errno;
@@ -899,7 +903,8 @@ static int get_slave_flags(char *slave_ifname)
{
int res = 0;
- strncpy(slave_flags.ifr_name, slave_ifname, IFNAMSIZ);
+ strncpy(slave_flags.ifr_name, slave_ifname, IFNAMSIZ - 1);
+ slave_flags.ifr_name[IFNAMSIZ - 1] = '\0';
res = ioctl(skfd, SIOCGIFFLAGS, &slave_flags);
if (res < 0) {
saved_errno = errno;
@@ -919,7 +924,8 @@ static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr)
struct ifreq ifr;
int res = 0;
- strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ - 1);
memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));
res = ioctl(skfd, SIOCSIFHWADDR, &ifr);
if (res < 0) {
@@ -943,7 +949,8 @@ static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr)
struct ifreq ifr;
int res = 0;
- strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ - 1);
memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));
res = ioctl(skfd, SIOCSIFHWADDR, &ifr);
if (res < 0) {
@@ -980,8 +987,9 @@ static int set_slave_mtu(char *slave_ifname, int mtu)
struct ifreq ifr;
int res = 0;
+ memset(&ifr, 0, sizeof(ifr));
ifr.ifr_mtu = mtu;
- strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
+ strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ - 1);
res = ioctl(skfd, SIOCSIFMTU, &ifr);
if (res < 0) {
@@ -1000,8 +1008,9 @@ static int set_if_flags(char *ifname, short flags)
struct ifreq ifr;
int res = 0;
+ memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = flags;
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
res = ioctl(skfd, SIOCSIFFLAGS, &ifr);
if (res < 0) {
@@ -1030,7 +1039,8 @@ static int clear_if_addr(char *ifname)
struct ifreq ifr;
int res = 0;
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
ifr.ifr_addr.sa_family = AF_INET;
memset(ifr.ifr_addr.sa_data, 0, sizeof(ifr.ifr_addr.sa_data));
@@ -1065,8 +1075,9 @@ static int set_if_addr(char *master_ifname, char *slave_ifname)
{NULL, NULL, 0, 0},
};
+ memset(&ifr, 0, sizeof(ifr));
for (i = 0; ifra[i].req_name; i++) {
- strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+ strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ - 1);
res = ioctl(skfd, ifra[i].g_ioctl, &ifr);
if (res < 0) {
int saved_errno = errno;
@@ -1080,7 +1091,7 @@ static int set_if_addr(char *master_ifname, char *slave_ifname)
sizeof(ifr.ifr_addr.sa_data));
}
- strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
+ strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ - 1);
res = ioctl(skfd, ifra[i].s_ioctl, &ifr);
if (res < 0) {
int saved_errno = errno;
--
2.31.1

View File

@ -1,20 +0,0 @@
--- iputils-s20160308/Makefile 2016-03-08 13:58:56.000000000 +0100
+++ iputils-s20160308-new/Makefile 2016-03-09 10:09:02.295409179 +0100
@@ -36,7 +36,7 @@ WITHOUT_IFADDRS=no
ARPING_DEFAULT_DEVICE=
# nettle library for ipv6 ping [yes|no|static]
-USE_NETTLE=yes
+USE_NETTLE=no
# libgcrypt library for ipv6 ping [no|yes|static]
USE_GCRYPT=no
# Crypto library for ping6 [shared|static|no]
@@ -53,7 +53,7 @@ ENABLE_RDISC_SERVER=no
# What a pity, all new gccs are buggy and -Werror does not work. Sigh.
# CFLAGS+=-fno-strict-aliasing -Wstrict-prototypes -Wall -Werror -g
CFLAGS?=-O3 -g
-CFLAGS+=-fno-strict-aliasing -Wstrict-prototypes -Wall
+CFLAGS+=$(RPM_OPT_FLAGS) -fno-strict-aliasing -Wstrict-prototypes -Wall
CPPFLAGS+=-D_GNU_SOURCE
LDLIB=

View File

@ -1,14 +0,0 @@
--- a/ping.c 2018-06-29 20:00:46.000000000 +0200
+++ b/ping.c 2019-07-10 09:50:06.653039073 +0200
@@ -589,8 +589,10 @@ int ping4_run(int argc, char **argv, str
strncpy(hnamebuf, ai->ai_canonname, sizeof hnamebuf - 1);
hostname = hnamebuf;
- if (result)
+ if (result) {
freeaddrinfo(result);
+ ai = NULL;
+ }
}
if (argc > 1)
route[nroute++] = whereto.sin_addr.s_addr;

View File

@ -1,25 +0,0 @@
From 445826446c32035b3c8e8a7780c4e4b885f0f98f Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Mon, 7 Dec 2020 15:08:14 +0100
Subject: [PATCH] ping: Fix incorrect statistics
---
ping_common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ping_common.c b/ping_common.c
index 040bf23..02cb5e1 100644
--- a/ping_common.c
+++ b/ping_common.c
@@ -934,7 +934,7 @@ void finish(void)
printf(", %g%% packet loss",
(float) ((((long long)(ntransmitted - nreceived)) * 100.0) /
ntransmitted));
- printf(", time %ldms", (1000*tv.tv_sec+tv.tv_usec+500)/1000);
+ printf(", time %ldms", 1000*tv.tv_sec+(tv.tv_usec+500)/1000);
}
putchar('\n');
--
2.28.0

View File

@ -1,38 +0,0 @@
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

@ -1,48 +0,0 @@
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

@ -1,113 +0,0 @@
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

@ -1,131 +0,0 @@
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,11 +0,0 @@
[Unit]
Description=Node Information Query Daemon
After=network.target
Documentation=man:ninfod
[Service]
Type=forking
ExecStart=/usr/sbin/ninfod
[Install]
WantedBy=multi-user.target

View File

@ -1,11 +0,0 @@
[Unit]
Description=rdisc daemon which discovers routers on the local subnet
After=network.target
Documentation=man:rdisc
[Service]
Type=forking
ExecStart=/sbin/rdisc -s
[Install]
WantedBy=multi-user.target

View File

@ -2,49 +2,37 @@
Summary: Network monitoring tools including ping
Name: iputils
Version: 20180629
Release: 11%{?dist}
Version: 20240117
Release: 6%{?dist}
# some parts are under the original BSD (ping.c)
# some are under GPLv2+ (tracepath.c)
License: BSD and GPLv2+
License: BSD-4-Clause-UC AND GPL-2.0-or-later
URL: https://github.com/iputils/iputils
Group: System Environment/Daemons
Source0: https://github.com/iputils/iputils/archive/s%{version}.tar.gz#/%{name}-s%{version}.tar.gz
Source0: https://github.com/iputils/iputils/archive/%{version}/%{name}-%{version}.tar.gz
Source1: ifenslave.tar.gz
Source2: rdisc.service
Source3: ninfod.service
# Taken from ping.c on 2014-07-12
Source4: bsd.txt
Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
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
Patch100: 100-iputils-ifenslave.patch
Patch101: 101-iputils-ifenslave-CWE-170.patch
Patch102: 102-iputils-ifenslave-CWE-170-2.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
%endif
BuildRequires: gcc
BuildRequires: meson
BuildRequires: gettext
BuildRequires: glibc-kernheaders >= 2.4-8.19
BuildRequires: libidn2-devel
BuildRequires: openssl-devel
BuildRequires: libcap-devel
BuildRequires: libxslt docbook-style-xsl
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
BuildRequires: libxslt docbook5-style-xsl
BuildRequires: systemd
BuildRequires: iproute
%{?systemd_ordering}
Provides: /bin/ping
Provides: /bin/ping6
Provides: /sbin/arping
Provides: /sbin/rdisc
%description
The iputils package contains basic utilities for monitoring a network,
@ -52,162 +40,160 @@ including ping. The ping command sends a series of ICMP protocol
ECHO_REQUEST packets to a specified network host to discover whether
the target machine is alive and receiving network traffic.
%package ninfod
Group: System Environment/Daemons
Summary: Node Information Query Daemon
Requires: %{name} = %{version}-%{release}
Provides: %{_sbindir}/ninfod
%description ninfod
Node Information Query (RFC4620) daemon. Responds to IPv6 Node Information
Queries.
%prep
%setup -q -a 1 -n %{name}-s%{version}
%autosetup -a 1 -n %{name}-%{version}
cp %{SOURCE4} %{SOURCE5} .
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%build
%ifarch s390 s390x
export CFLAGS="-fPIE"
%else
export CFLAGS="-fpie"
%endif
export LDFLAGS="-pie -Wl,-z,relro,-z,now"
make %{?_smp_mflags} arping clockdiff ping rdisc tracepath ninfod
gcc -Wall $RPM_OPT_FLAGS $CFLAGS $LDFLAGS ifenslave.c -o ifenslave
%if ! 0%{?_module_build}
make -C doc man
%endif
%meson
%meson_build
gcc $RPM_OPT_FLAGS $CFLAGS $RPM_LD_FLAGS $LDFLAGS ifenslave.c -o ifenslave
%install
%meson_install
%find_lang %{name}
mkdir -p ${RPM_BUILD_ROOT}%{_sbindir}
mkdir -p ${RPM_BUILD_ROOT}%{_bindir}
mkdir -p $RPM_BUILD_ROOT/%{_unitdir}
install -c clockdiff ${RPM_BUILD_ROOT}%{_sbindir}/
install -cp arping ${RPM_BUILD_ROOT}%{_sbindir}/
install -cp ping ${RPM_BUILD_ROOT}%{_bindir}/
install -cp ifenslave ${RPM_BUILD_ROOT}%{_sbindir}/
install -cp rdisc ${RPM_BUILD_ROOT}%{_sbindir}/
install -cp tracepath ${RPM_BUILD_ROOT}%{_bindir}/
install -cp ninfod/ninfod ${RPM_BUILD_ROOT}%{_sbindir}/
mkdir -p ${RPM_BUILD_ROOT}%{_bindir}
ln -sf ../bin/ping ${RPM_BUILD_ROOT}%{_sbindir}/ping
ln -sf ../bin/ping ${RPM_BUILD_ROOT}%{_sbindir}/ping6
ln -sf ../bin/tracepath ${RPM_BUILD_ROOT}%{_sbindir}/tracepath
ln -sf ../bin/tracepath ${RPM_BUILD_ROOT}%{_sbindir}/tracepath6
mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/man8
%if ! 0%{?_module_build}
install -cp doc/clockdiff.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/
install -cp doc/arping.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/
install -cp doc/ping.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/
install -cp doc/rdisc.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/
install -cp doc/tracepath.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/
install -cp doc/ninfod.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/
ln -sf ../bin/arping ${RPM_BUILD_ROOT}%{_sbindir}/arping
echo ".so man8/ping.8" > ${RPM_BUILD_ROOT}%{_mandir}/man8/ping6.8
echo ".so man8/tracepath.8" > ${RPM_BUILD_ROOT}%{_mandir}/man8/tracepath6.8
install -cp ifenslave ${RPM_BUILD_ROOT}%{_sbindir}/
install -cp ifenslave.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/
ln -s ping.8.gz ${RPM_BUILD_ROOT}%{_mandir}/man8/ping6.8.gz
ln -s tracepath.8.gz ${RPM_BUILD_ROOT}%{_mandir}/man8/tracepath6.8.gz
%endif
install -dp ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d
install -m 644 %SOURCE2 ${RPM_BUILD_ROOT}/%{_unitdir}
install -m 644 %SOURCE3 ${RPM_BUILD_ROOT}/%{_unitdir}
%post
%systemd_post rdisc.service
%preun
%systemd_preun rdisc.service
%postun
%systemd_postun_with_restart rdisc.service
%post ninfod
%systemd_post ninfod.service
%preun ninfod
%systemd_preun ninfod.service
%postun ninfod
%systemd_postun_with_restart ninfod.service
%files
%files -f %{name}.lang
%doc README.bonding
%{!?_licensedir:%global license %%doc}
%license bsd.txt gpl-2.0.txt
%{_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) %{_bindir}/clockdiff
%attr(0755,root,root) %caps(cap_net_raw=p) %{_bindir}/arping
%attr(0755,root,root) %{_bindir}/ping
%{_sbindir}/ifenslave
%{_sbindir}/rdisc
%{_bindir}/tracepath
%{_sbindir}/ping
%{_sbindir}/ping6
%{_sbindir}/tracepath
%{_sbindir}/tracepath6
%if ! 0%{?_module_build}
%attr(644,root,root) %{_mandir}/man8/clockdiff.8.gz
%attr(644,root,root) %{_mandir}/man8/arping.8.gz
%attr(644,root,root) %{_mandir}/man8/ping.8.gz
%{_mandir}/man8/ping6.8.gz
%attr(644,root,root) %{_mandir}/man8/rdisc.8.gz
%attr(644,root,root) %{_mandir}/man8/tracepath.8.gz
%{_mandir}/man8/tracepath6.8.gz
%attr(644,root,root) %{_mandir}/man8/ifenslave.8.gz
%endif
%files ninfod
%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/ninfod
%{_unitdir}/ninfod.service
%if ! 0%{?_module_build}
%attr(644,root,root) %{_mandir}/man8/ninfod.8.gz
%endif
%{_sbindir}/arping
%attr(644,root,root) %{_mandir}/man8/clockdiff.8*
%attr(644,root,root) %{_mandir}/man8/arping.8*
%attr(644,root,root) %{_mandir}/man8/ping.8*
%{_mandir}/man8/ping6.8*
%attr(644,root,root) %{_mandir}/man8/tracepath.8*
%{_mandir}/man8/tracepath6.8*
%attr(644,root,root) %{_mandir}/man8/ifenslave.8*
%changelog
* Thu Jun 08 2023 Jan Macku <jamacku@redhat.com> - 20180629-11
- Add support for VRF with ping command (#2208409)
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 20240117-6
- Bump release for June 2024 mass rebuild
* Tue Mar 22 2022 Jan Macku <jamacku@redhat.com> - 20180629-10
- Fix regression of output when pinging unreachable IPv6 host (#2057570)
* Tue May 28 2024 Jan Macku <jamacku@redhat.com> - 20240117-5
- Fix ifenslave defects detected by Coverity
* Thu Feb 03 2022 Jan Macku <jamacku@redhat.com> - 20180629-9
- Fix copying input IPv6 address (#2047659)
* Sun Feb 11 2024 Kevin Fenzi <kevin@scrye.com> - 20240117-4
- Fix sources. Fixes rhbz#2263028
* Mon Jan 03 2022 Jan Macku <jamacku@redhat.com> - 20180629-8
- Make ping unprivileged (#2030107)
* Mon Jan 29 2024 Fedora Release Engineering <releng@fedoraproject.org> - 20240117-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Wed Feb 17 2021 Jan Macku <jamacku@redhat.com> - 20180629-7
- Revert patch introduced by #1852638 (#1928179)
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 20240117-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Tue Dec 15 2020 Jan Macku <jamacku@redhat.com> - 20180629-6
- Exit on error (#1852638)
* Sun Jan 21 2024 Kevin Fenzi <kevin@scrye.com> - 20240117-1
- Update to 20240117. Fixes rhbz#2258910
* Thu Dec 10 2020 Jan Macku <jamacku@redhat.com> - 20180629-5
- Change error() -> fprintf() reported by covscan (#1852638)
* Sat Jan 20 2024 Fedora Release Engineering <releng@fedoraproject.org> - 20231222-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Wed Dec 09 2020 Jan Macku <jamacku@redhat.com> - 20180629-4
- Fix infinite loop caused by subsecond timeouts (#1852638)
* Wed Dec 27 2023 Kevin Fenzi <kevin@scrye.com> - 20231222-1
- Update to 20231222. Fixes rhbz#2255687
- Fix PatchN warnings
* Tue Dec 08 2020 Jan Macku <jamacku@redhat.com> - 20180629-3
- Fix incorrect ping statistics (#1901780)
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 20221126-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Wed Jul 10 2019 Jan Synáček <jsynacek@redhat.com> - 20180629-2
- covscan fix (#1606968)
* Wed Apr 12 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20221126-3
- migrate to SPDX license format
* Tue Jul 03 2018 Jan Synáček <jsynacek@redhat.com> - 20180629-1
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 20221126-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Sun Nov 27 2022 Kevin Fenzi <kevin@scrye.com> - 20221126-1
- Update to 20221126. Fixes rhbz#2148690
* Fri Nov 25 2022 Jan Macku <jamacku@redhat.com> - 20211215-4
- Build iputils and ifenslave with correct flags provided by Fedora
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 20211215-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 20211215-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Thu Dec 16 2021 Kevin Fenzi <kevin@scrye.com> - 20211215-1
- Update to 20211215. Fixes rhbz#2033161
* Sun Jul 25 2021 Kevin Fenzi <kevin@scrye.com> - 20210722-1
- Update to 20210722. Fixes rhbz#1985117
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 20210202-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Tue Mar 23 2021 Jan Macku <jamacku@redhat.com> - 20210202-3
- ifenslave: fix CWE-170 (related to rhbz#1938746)
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 20210202-2
- Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
* Tue Feb 02 2021 Kevin Fenzi <kevin@scrye.com> - 20210202-1
- Update to 20210202. Fixes rhbz#1923917
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 20200821-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Sat Oct 31 2020 Kevin Fenzi <kevin@scrye.com> - 20200821-1
- Update to 20200821 release. Fixes bug #1871310
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 20190515-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon May 18 2020 Jan Synáček <jsynacek@redhat.com> - 20190515-7
- arping exits with error when should not (#1836607)
* Mon Mar 2 2020 Jan Synáček <jsynacek@redhat.com> - 20190515-6
- Make ping unprivileged (#1699497)
* Mon Feb 3 2020 Jan Synáček <jsynacek@redhat.com> - 20190515-5
- Symlink arping to /usr/sbin/arping to maintain backward compatibility (#1797525)
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 20190515-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 20190515-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Wed May 22 2019 Jan Synáček <jsynacek@redhat.com> - 20190515-2
- Mark localization files correctly (#1712514)
* Wed May 22 2019 Jan Synáček <jsynacek@redhat.com> - 20190515-1
- Update to s20190515 (#1710647)
* Thu Mar 28 2019 Jan Synáček <jsynacek@redhat.com> - 20190324-1
- Update to s20190324 (#1692136)
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 20180629-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Wed Jan 23 2019 Bogdan Dobrelya <bdobreli@redhat.com> - 20180629-3
- Use systemd_ordering macro
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 20180629-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Jul 3 2018 Jan Synáček <jsynacek@redhat.com> - 20180629-1
- update to s20180629 (#1596893)
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 20161105-9

2
sources Normal file
View File

@ -0,0 +1,2 @@
SHA512 (ifenslave.tar.gz) = 117e4552486f07190e606174dea7666ed6ea0e2bd90d4f389d41f1a5bee31fcec785f18c5e9c281a5c7b71307377eca37f9e461e187e1149820cab5c9e07676a
SHA512 (iputils-20240117.tar.gz) = 1755de6adb509418507c3f10521715ff3bf7ba38d3bbd9a102a48ae0a9f88fcb1f457bcb38624dce2281912e0e0ffc3fbf74e0e618ed2d21014710e967c7dad3