Resolves: RHEL-39975 - possible denial of service
This commit is contained in:
parent
a45fe1eda6
commit
04d91429ed
129
0001-cve-2023-7250.patch
Normal file
129
0001-cve-2023-7250.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From 5e3704dd850a5df2fb2b3eafd117963d017d07b4 Mon Sep 17 00:00:00 2001
|
||||
From: "Bruce A. Mah" <bmah@es.net>
|
||||
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 <poll.h>
|
||||
#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;
|
||||
}
|
@ -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 <mruprich@redhat.com> - 3.9-12
|
||||
- Resolves: RHEL-39975 - possible denial of service
|
||||
|
||||
* Wed Aug 09 2023 Michal Ruprich <mruprich@redhat.com> - 3.9-11
|
||||
- Related: #2223676 - bumping version for correct update path
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user