diff --git a/cve-2023-38403.patch b/0000-cve-2023-38403.patch similarity index 100% rename from cve-2023-38403.patch rename to 0000-cve-2023-38403.patch diff --git a/0001-cve-2023-7250.patch b/0001-cve-2023-7250.patch new file mode 100644 index 0000000..213a42f --- /dev/null +++ b/0001-cve-2023-7250.patch @@ -0,0 +1,129 @@ +From 5e3704dd850a5df2fb2b3eafd117963d017d07b4 Mon Sep 17 00:00:00 2001 +From: "Bruce A. Mah" +Date: Tue, 1 Aug 2023 14:02:54 -0700 +Subject: [PATCH] Implement fixes to make the control connection more robust. + +These include various timeouts in Nread() to guarantee that it will +eventually exit, a 10-second timeout for each attempt to read data +from the network and an approximately 30-second overall timeout per +Nread() call. + +Also the iperf3 server now checks the length of the received session +cookie, and errors out if this happens to be incorrect. + +Reported by Jorge Sancho Larraz - Canonical. +--- + src/iperf_server_api.c | 7 ++++- + src/net.c | 62 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 68 insertions(+), 1 deletion(-) + +diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c +index 5fa1dd7..c528d5f 100644 +--- a/src/iperf_server_api.c ++++ b/src/iperf_server_api.c +@@ -118,7 +118,12 @@ iperf_accept(struct iperf_test *test) + if (test->ctrl_sck == -1) { + /* Server free, accept new client */ + test->ctrl_sck = s; +- if (Nread(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) { ++ if (Nread(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) != COOKIE_SIZE) { ++ /* ++ * Note this error covers both the case of a system error ++ * or the inability to read the correct amount of data ++ * (i.e. timed out). ++ */ + i_errno = IERECVCOOKIE; + return -1; + } +diff --git a/src/net.c b/src/net.c +index fd525ee..8804a39 100644 +--- a/src/net.c ++++ b/src/net.c +@@ -60,10 +60,14 @@ + #include + #endif /* HAVE_POLL_H */ + ++#include "iperf.h" + #include "iperf_util.h" + #include "net.h" + #include "timer.h" + ++static int nread_read_timeout = 10; ++static int nread_overall_timeout = 30; ++ + /* + * Declaration of gerror in iperf_error.c. Most other files in iperf3 can get this + * by including "iperf.h", but net.c lives "below" this layer. Clearly the +@@ -313,6 +317,32 @@ Nread(int fd, char *buf, size_t count, int prot) + { + register ssize_t r; + register size_t nleft = count; ++ struct iperf_time ftimeout = { 0, 0 }; ++ ++ fd_set rfdset; ++ struct timeval timeout = { nread_read_timeout, 0 }; ++ ++ /* ++ * fd might not be ready for reading on entry. Check for this ++ * (with timeout) first. ++ * ++ * This check could go inside the while() loop below, except we're ++ * currently considering whether it might make sense to support a ++ * codepath that bypassese this check, for situations where we ++ * already know that fd has data on it (for example if we'd gotten ++ * to here as the result of a select() call. ++ */ ++ { ++ FD_ZERO(&rfdset); ++ FD_SET(fd, &rfdset); ++ r = select(fd + 1, &rfdset, NULL, NULL, &timeout); ++ if (r < 0) { ++ return NET_HARDERROR; ++ } ++ if (r == 0) { ++ return 0; ++ } ++ } + + while (nleft > 0) { + r = read(fd, buf, nleft); +@@ -326,6 +356,39 @@ Nread(int fd, char *buf, size_t count, int prot) + + nleft -= r; + buf += r; ++ ++ /* ++ * We need some more bytes but don't want to wait around ++ * forever for them. In the case of partial results, we need ++ * to be able to read some bytes every nread_timeout seconds. ++ */ ++ if (nleft > 0) { ++ struct iperf_time now; ++ ++ /* ++ * Also, we have an approximate upper limit for the total time ++ * that a Nread call is supposed to take. We trade off accuracy ++ * of this timeout for a hopefully lower performance impact. ++ */ ++ iperf_time_now(&now); ++ if (ftimeout.secs == 0) { ++ ftimeout = now; ++ iperf_time_add_usecs(&ftimeout, nread_overall_timeout * 1000000L); ++ } ++ if (iperf_time_compare(&ftimeout, &now) < 0) { ++ break; ++ } ++ ++ FD_ZERO(&rfdset); ++ FD_SET(fd, &rfdset); ++ r = select(fd + 1, &rfdset, NULL, NULL, &timeout); ++ if (r < 0) { ++ return NET_HARDERROR; ++ } ++ if (r == 0) { ++ break; ++ } ++ } + } + return count - nleft; + } diff --git a/iperf3.spec b/iperf3.spec index 99b0190..29bbbea 100644 --- a/iperf3.spec +++ b/iperf3.spec @@ -1,12 +1,13 @@ Name: iperf3 Version: 3.9 -Release: 11%{?dist} +Release: 12%{?dist} Summary: Measurement tool for TCP/UDP bandwidth performance License: BSD URL: https://github.com/esnet/iperf Source0: https://github.com/esnet/iperf/archive/%{version}.tar.gz -Patch: cve-2023-38403.patch +Patch0000: 0000-cve-2023-38403.patch +Patch0001: 0001-cve-2023-7250.patch BuildRequires: libuuid-devel BuildRequires: gcc @@ -54,6 +55,9 @@ rm -f %{buildroot}%{_libdir}/libiperf.la %{_libdir}/*.so %changelog +* Tue Jun 04 2024 Michal Ruprich - 3.9-12 +- Resolves: RHEL-39975 - possible denial of service + * Wed Aug 09 2023 Michal Ruprich - 3.9-11 - Related: #2223676 - bumping version for correct update path