From 0d8fa1dab6e82bb1a799a7f3695b715fef7786c3 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 3 Jul 2024 11:48:17 +0300 Subject: [PATCH] Import from CS git --- SOURCES/0004-cve-2023-38403.patch | 45 +++ SOURCES/0005-cve-2023-7250.patch | 497 ++++++++++++++++++++++++++++++ SOURCES/0006-cve-2024-26306.patch | 231 ++++++++++++++ SPECS/iperf3.spec | 18 +- 4 files changed, 790 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0004-cve-2023-38403.patch create mode 100644 SOURCES/0005-cve-2023-7250.patch create mode 100644 SOURCES/0006-cve-2024-26306.patch diff --git a/SOURCES/0004-cve-2023-38403.patch b/SOURCES/0004-cve-2023-38403.patch new file mode 100644 index 0000000..a909d18 --- /dev/null +++ b/SOURCES/0004-cve-2023-38403.patch @@ -0,0 +1,45 @@ +From 41f5129d402bcd14ec4d2cde875203ab51076352 Mon Sep 17 00:00:00 2001 +From: "Bruce A. Mah" +Date: Fri, 7 Jul 2023 11:03:43 -0700 +Subject: [PATCH] Fix memory allocation hazard (#1542). + +Reported by: @someusername123 on GitHub +--- + src/iperf_api.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/iperf_api.c b/src/iperf_api.c +index f2d416214..a95e02418 100644 +--- a/src/iperf_api.c ++++ b/src/iperf_api.c +@@ -2670,6 +2670,7 @@ static cJSON * + JSON_read(int fd) + { + uint32_t hsize, nsize; ++ size_t strsize; + char *str; + cJSON *json = NULL; + int rc; +@@ -2682,7 +2683,9 @@ JSON_read(int fd) + if (Nread(fd, (char*) &nsize, sizeof(nsize), Ptcp) >= 0) { + hsize = ntohl(nsize); + /* Allocate a buffer to hold the JSON */ +- str = (char *) calloc(sizeof(char), hsize+1); /* +1 for trailing null */ ++ strsize = hsize + 1; /* +1 for trailing NULL */ ++ if (strsize) { ++ str = (char *) calloc(sizeof(char), strsize); + if (str != NULL) { + rc = Nread(fd, str, hsize, Ptcp); + if (rc >= 0) { +@@ -2701,6 +2704,10 @@ JSON_read(int fd) + } + } + free(str); ++ } ++ else { ++ printf("WARNING: Data length overflow\n"); ++ } + } + return json; + } + diff --git a/SOURCES/0005-cve-2023-7250.patch b/SOURCES/0005-cve-2023-7250.patch new file mode 100644 index 0000000..4ab09fb --- /dev/null +++ b/SOURCES/0005-cve-2023-7250.patch @@ -0,0 +1,497 @@ +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/iperf_time.c b/src/iperf_time.c +new file mode 100644 +index 0000000..a435dd3 +--- /dev/null ++++ b/src/iperf_time.c +@@ -0,0 +1,156 @@ ++/* ++ * iperf, Copyright (c) 2014-2018, The Regents of the University of ++ * California, through Lawrence Berkeley National Laboratory (subject ++ * to receipt of any required approvals from the U.S. Dept. of ++ * Energy). All rights reserved. ++ * ++ * If you have questions about your rights to use or distribute this ++ * software, please contact Berkeley Lab's Technology Transfer ++ * Department at TTD@lbl.gov. ++ * ++ * NOTICE. This software is owned by the U.S. Department of Energy. ++ * As such, the U.S. Government has been granted for itself and others ++ * acting on its behalf a paid-up, nonexclusive, irrevocable, ++ * worldwide license in the Software to reproduce, prepare derivative ++ * works, and perform publicly and display publicly. Beginning five ++ * (5) years after the date permission to assert copyright is obtained ++ * from the U.S. Department of Energy, and subject to any subsequent ++ * five (5) year renewals, the U.S. Government is granted for itself ++ * and others acting on its behalf a paid-up, nonexclusive, ++ * irrevocable, worldwide license in the Software to reproduce, ++ * prepare derivative works, distribute copies to the public, perform ++ * publicly and display publicly, and to permit others to do so. ++ * ++ * This code is distributed under a BSD style license, see the LICENSE ++ * file for complete information. ++ */ ++ ++ ++#include ++ ++#include "iperf_config.h" ++#include "iperf_time.h" ++ ++#ifdef HAVE_CLOCK_GETTIME ++ ++#include ++ ++int ++iperf_time_now(struct iperf_time *time1) ++{ ++ struct timespec ts; ++ int result; ++ result = clock_gettime(CLOCK_MONOTONIC, &ts); ++ if (result == 0) { ++ time1->secs = (uint32_t) ts.tv_sec; ++ time1->usecs = (uint32_t) ts.tv_nsec / 1000; ++ } ++ return result; ++} ++ ++#else ++ ++#include ++ ++int ++iperf_time_now(struct iperf_time *time1) ++{ ++ struct timeval tv; ++ int result; ++ result = gettimeofday(&tv, NULL); ++ time1->secs = tv.tv_sec; ++ time1->usecs = tv.tv_usec; ++ return result; ++} ++ ++#endif ++ ++/* iperf_time_add_usecs ++ * ++ * Add a number of microseconds to a iperf_time. ++ */ ++void ++iperf_time_add_usecs(struct iperf_time *time1, uint64_t usecs) ++{ ++ time1->secs += usecs / 1000000L; ++ time1->usecs += usecs % 1000000L; ++ if ( time1->usecs >= 1000000L ) { ++ time1->secs += time1->usecs / 1000000L; ++ time1->usecs %= 1000000L; ++ } ++} ++ ++uint64_t ++iperf_time_in_usecs(struct iperf_time *time) ++{ ++ return time->secs * 1000000LL + time->usecs; ++} ++ ++double ++iperf_time_in_secs(struct iperf_time *time) ++{ ++ return time->secs + time->usecs / 1000000.0; ++} ++ ++/* iperf_time_compare ++ * ++ * Compare two timestamps ++ * ++ * Returns -1 if time1 is earlier, 1 if time1 is later, ++ * or 0 if the timestamps are equal. ++ */ ++int ++iperf_time_compare(struct iperf_time *time1, struct iperf_time *time2) ++{ ++ if (time1->secs < time2->secs) ++ return -1; ++ if (time1->secs > time2->secs) ++ return 1; ++ if (time1->usecs < time2->usecs) ++ return -1; ++ if (time1->usecs > time2->usecs) ++ return 1; ++ return 0; ++} ++ ++/* iperf_time_diff ++ * ++ * Calculates the time from time2 to time1, assuming time1 is later than time2. ++ * The diff will always be positive, so the return value should be checked ++ * to determine if time1 was earlier than time2. ++ * ++ * Returns 1 if the time1 is less than or equal to time2, otherwise 0. ++ */ ++int ++iperf_time_diff(struct iperf_time *time1, struct iperf_time *time2, struct iperf_time *diff) ++{ ++ int past = 0; ++ int cmp = 0; ++ ++ cmp = iperf_time_compare(time1, time2); ++ if (cmp == 0) { ++ diff->secs = 0; ++ diff->usecs = 0; ++ past = 1; ++ } ++ else if (cmp == 1) { ++ diff->secs = time1->secs - time2->secs; ++ diff->usecs = time1->usecs; ++ if (diff->usecs < time2->usecs) { ++ diff->secs -= 1; ++ diff->usecs += 1000000; ++ } ++ diff->usecs = diff->usecs - time2->usecs; ++ } else { ++ diff->secs = time2->secs - time1->secs; ++ diff->usecs = time2->usecs; ++ if (diff->usecs < time1->usecs) { ++ diff->secs -= 1; ++ diff->usecs += 1000000; ++ } ++ diff->usecs = diff->usecs - time1->usecs; ++ past = 1; ++ } ++ ++ return past; ++} +diff --git a/src/iperf_time.h b/src/iperf_time.h +new file mode 100644 +index 0000000..588ee26 +--- /dev/null ++++ b/src/iperf_time.h +@@ -0,0 +1,49 @@ ++/* ++ * iperf, Copyright (c) 2014-2018, The Regents of the University of ++ * California, through Lawrence Berkeley National Laboratory (subject ++ * to receipt of any required approvals from the U.S. Dept. of ++ * Energy). All rights reserved. ++ * ++ * If you have questions about your rights to use or distribute this ++ * software, please contact Berkeley Lab's Technology Transfer ++ * Department at TTD@lbl.gov. ++ * ++ * NOTICE. This software is owned by the U.S. Department of Energy. ++ * As such, the U.S. Government has been granted for itself and others ++ * acting on its behalf a paid-up, nonexclusive, irrevocable, ++ * worldwide license in the Software to reproduce, prepare derivative ++ * works, and perform publicly and display publicly. Beginning five ++ * (5) years after the date permission to assert copyright is obtained ++ * from the U.S. Department of Energy, and subject to any subsequent ++ * five (5) year renewals, the U.S. Government is granted for itself ++ * and others acting on its behalf a paid-up, nonexclusive, ++ * irrevocable, worldwide license in the Software to reproduce, ++ * prepare derivative works, distribute copies to the public, perform ++ * publicly and display publicly, and to permit others to do so. ++ * ++ * This code is distributed under a BSD style license, see the LICENSE ++ * file for complete information. ++ */ ++#ifndef __IPERF_TIME_H ++#define __IPERF_TIME_H ++ ++#include ++ ++struct iperf_time { ++ uint32_t secs; ++ uint32_t usecs; ++}; ++ ++int iperf_time_now(struct iperf_time *time1); ++ ++void iperf_time_add_usecs(struct iperf_time *time1, uint64_t usecs); ++ ++int iperf_time_compare(struct iperf_time *time1, struct iperf_time *time2); ++ ++int iperf_time_diff(struct iperf_time *time1, struct iperf_time *time2, struct iperf_time *diff); ++ ++uint64_t iperf_time_in_usecs(struct iperf_time *time); ++ ++double iperf_time_in_secs(struct iperf_time *time); ++ ++#endif +diff --git a/src/iperf.h b/src/iperf.h +index f55994f..f137b07 100755 +--- a/src/iperf.h ++++ b/src/iperf.h +@@ -61,6 +61,7 @@ + #include "timer.h" + #include "queue.h" + #include "cjson.h" ++#include "iperf_time.h" + + typedef uint64_t iperf_size_t; + +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; ++ + /* + * timeout_connect adapted from netcat, via OpenBSD and FreeBSD + * Copyright (c) 2001 Eric Jackson +@@ -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/src/Makefile.am b/src/Makefile.am +index 9184e84..1c24b62 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -21,6 +21,8 @@ libiperf_la_SOURCES = \ + iperf_server_api.c \ + iperf_tcp.c \ + iperf_tcp.h \ ++ iperf_time.c \ ++ iperf_time.h \ + iperf_udp.c \ + iperf_udp.h \ + iperf_sctp.c \ +diff --git a/src/Makefile.in b/src/Makefile.in +index 714f601..6e75194 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -142,7 +142,8 @@ libiperf_la_LIBADD = + am_libiperf_la_OBJECTS = cjson.lo iperf_api.lo iperf_error.lo \ + iperf_auth.lo iperf_client_api.lo iperf_locale.lo \ + iperf_server_api.lo iperf_tcp.lo iperf_udp.lo iperf_sctp.lo \ +- iperf_util.lo dscp.lo net.lo tcp_info.lo timer.lo units.lo ++ iperf_util.lo iperf_time.lo dscp.lo net.lo tcp_info.lo \ ++ timer.lo units.lo + libiperf_la_OBJECTS = $(am_libiperf_la_OBJECTS) + AM_V_lt = $(am__v_lt_@AM_V@) + am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +@@ -165,6 +166,7 @@ am__objects_1 = iperf3_profile-cjson.$(OBJEXT) \ + iperf3_profile-iperf_udp.$(OBJEXT) \ + iperf3_profile-iperf_sctp.$(OBJEXT) \ + iperf3_profile-iperf_util.$(OBJEXT) \ ++ iperf3_profile-iperf_time.$(OBJEXT) \ + iperf3_profile-dscp.$(OBJEXT) iperf3_profile-net.$(OBJEXT) \ + iperf3_profile-tcp_info.$(OBJEXT) \ + iperf3_profile-timer.$(OBJEXT) iperf3_profile-units.$(OBJEXT) +@@ -220,6 +222,7 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \ + ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po \ + ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po \ + ./$(DEPDIR)/iperf3_profile-iperf_tcp.Po \ ++ ./$(DEPDIR)/iperf3_profile-iperf_time.Po \ + ./$(DEPDIR)/iperf3_profile-iperf_udp.Po \ + ./$(DEPDIR)/iperf3_profile-iperf_util.Po \ + ./$(DEPDIR)/iperf3_profile-main.Po \ +@@ -230,11 +233,12 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \ + ./$(DEPDIR)/iperf_auth.Plo ./$(DEPDIR)/iperf_client_api.Plo \ + ./$(DEPDIR)/iperf_error.Plo ./$(DEPDIR)/iperf_locale.Plo \ + ./$(DEPDIR)/iperf_sctp.Plo ./$(DEPDIR)/iperf_server_api.Plo \ +- ./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_udp.Plo \ +- ./$(DEPDIR)/iperf_util.Plo ./$(DEPDIR)/net.Plo \ +- ./$(DEPDIR)/t_timer-t_timer.Po ./$(DEPDIR)/t_units-t_units.Po \ +- ./$(DEPDIR)/t_uuid-t_uuid.Po ./$(DEPDIR)/tcp_info.Plo \ +- ./$(DEPDIR)/timer.Plo ./$(DEPDIR)/units.Plo ++ ./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_time.Plo \ ++ ./$(DEPDIR)/iperf_udp.Plo ./$(DEPDIR)/iperf_util.Plo \ ++ ./$(DEPDIR)/net.Plo ./$(DEPDIR)/t_timer-t_timer.Po \ ++ ./$(DEPDIR)/t_units-t_units.Po ./$(DEPDIR)/t_uuid-t_uuid.Po \ ++ ./$(DEPDIR)/tcp_info.Plo ./$(DEPDIR)/timer.Plo \ ++ ./$(DEPDIR)/units.Plo + am__mv = mv -f + COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +@@ -613,6 +613,8 @@ libiperf_la_SOURCES = \ + iperf_server_api.c \ + iperf_tcp.c \ + iperf_tcp.h \ ++ iperf_time.c \ ++ iperf_time.h \ + iperf_udp.c \ + iperf_udp.h \ + iperf_sctp.c \ +@@ -850,6 +854,7 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_sctp.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_server_api.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_tcp.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_time.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_udp.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_util.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-main.Po@am__quote@ # am--include-marker +@@ -865,6 +870,7 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_sctp.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_server_api.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_tcp.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_time.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_udp.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_util.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Plo@am__quote@ # am--include-marker +@@ -1084,6 +1090,20 @@ iperf3_profile-iperf_util.obj: iperf_util.c + @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_util.obj `if test -f 'iperf_util.c'; then $(CYGPATH_W) 'iperf_util.c'; else $(CYGPATH_W) '$(srcdir)/iperf_util.c'; fi` + ++iperf3_profile-iperf_time.o: iperf_time.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-iperf_time.o -MD -MP -MF $(DEPDIR)/iperf3_profile-iperf_time.Tpo -c -o iperf3_profile-iperf_time.o `test -f 'iperf_time.c' || echo '$(srcdir)/'`iperf_time.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-iperf_time.Tpo $(DEPDIR)/iperf3_profile-iperf_time.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iperf_time.c' object='iperf3_profile-iperf_time.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_time.o `test -f 'iperf_time.c' || echo '$(srcdir)/'`iperf_time.c ++ ++iperf3_profile-iperf_time.obj: iperf_time.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-iperf_time.obj -MD -MP -MF $(DEPDIR)/iperf3_profile-iperf_time.Tpo -c -o iperf3_profile-iperf_time.obj `if test -f 'iperf_time.c'; then $(CYGPATH_W) 'iperf_time.c'; else $(CYGPATH_W) '$(srcdir)/iperf_time.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-iperf_time.Tpo $(DEPDIR)/iperf3_profile-iperf_time.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iperf_time.c' object='iperf3_profile-iperf_time.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_time.obj `if test -f 'iperf_time.c'; then $(CYGPATH_W) 'iperf_time.c'; else $(CYGPATH_W) '$(srcdir)/iperf_time.c'; fi` ++ + iperf3_profile-dscp.o: dscp.c + @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-dscp.o -MD -MP -MF $(DEPDIR)/iperf3_profile-dscp.Tpo -c -o iperf3_profile-dscp.o `test -f 'dscp.c' || echo '$(srcdir)/'`dscp.c + @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-dscp.Tpo $(DEPDIR)/iperf3_profile-dscp.Po +@@ -1634,6 +1654,7 @@ distclean: distclean-am + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_tcp.Po ++ -rm -f ./$(DEPDIR)/iperf3_profile-iperf_time.Po + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_udp.Po + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po + -rm -f ./$(DEPDIR)/iperf3_profile-main.Po +@@ -1649,6 +1670,7 @@ distclean: distclean-am + -rm -f ./$(DEPDIR)/iperf_sctp.Plo + -rm -f ./$(DEPDIR)/iperf_server_api.Plo + -rm -f ./$(DEPDIR)/iperf_tcp.Plo ++ -rm -f ./$(DEPDIR)/iperf_time.Plo + -rm -f ./$(DEPDIR)/iperf_udp.Plo + -rm -f ./$(DEPDIR)/iperf_util.Plo + -rm -f ./$(DEPDIR)/net.Plo +@@ -1716,6 +1738,7 @@ maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_tcp.Po ++ -rm -f ./$(DEPDIR)/iperf3_profile-iperf_time.Po + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_udp.Po + -rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po + -rm -f ./$(DEPDIR)/iperf3_profile-main.Po +@@ -1731,6 +1754,7 @@ maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/iperf_sctp.Plo + -rm -f ./$(DEPDIR)/iperf_server_api.Plo + -rm -f ./$(DEPDIR)/iperf_tcp.Plo ++ -rm -f ./$(DEPDIR)/iperf_time.Plo + -rm -f ./$(DEPDIR)/iperf_udp.Plo + -rm -f ./$(DEPDIR)/iperf_util.Plo + -rm -f ./$(DEPDIR)/net.Plo diff --git a/SOURCES/0006-cve-2024-26306.patch b/SOURCES/0006-cve-2024-26306.patch new file mode 100644 index 0000000..b8ed1f5 --- /dev/null +++ b/SOURCES/0006-cve-2024-26306.patch @@ -0,0 +1,231 @@ +From 299b356df6939f71619bf45bf7a7d2222e17d840 Mon Sep 17 00:00:00 2001 +From: Sarah Larsen +Date: Wed, 20 Mar 2024 17:02:31 -0700 +Subject: [PATCH] Using OAEP padding instead of PKCS1 padding for OpenSSL. Fix + for CVE-2024-26306. + +Special thanks to Hubert Kario at Red Hat for finding the vulnerability. + +diff --git a/src/iperf.h b/src/iperf.h +index f137b07..f6c0313 100755 +--- a/src/iperf.h ++++ b/src/iperf.h +@@ -260,6 +260,7 @@ struct iperf_test + int ctrl_sck_mss; /* MSS for the control channel */ + char *server_rsa_private_key; + char *server_authorized_users; ++ int use_pkcs1_padding; + + /* boolean variables for Options */ + int daemon; /* -D option */ +diff --git a/src/iperf_api.c b/src/iperf_api.c +index d40561c10..7fb741e77 100644 +--- a/src/iperf_api.c ++++ b/src/iperf_api.c +@@ -1137,6 +1137,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) + {"rsa-public-key-path", required_argument, NULL, OPT_CLIENT_RSA_PUBLIC_KEY}, + {"rsa-private-key-path", required_argument, NULL, OPT_SERVER_RSA_PRIVATE_KEY}, + {"authorized-users-path", required_argument, NULL, OPT_SERVER_AUTHORIZED_USERS}, ++ {"use-pkcs1-padding", no_argument, NULL, OPT_USE_PKCS1_PADDING}, + #endif /* HAVE_SSL */ + {"fq-rate", required_argument, NULL, OPT_FQ_RATE}, + {"pacing-timer", required_argument, NULL, OPT_PACING_TIMER}, +@@ -1630,6 +1631,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) + case OPT_SERVER_AUTHORIZED_USERS: + test->server_authorized_users = strdup(optarg); + break; ++ case OPT_USE_PKCS1_PADDING: ++ test->use_pkcs1_padding = 1; ++ break; + #endif /* HAVE_SSL */ + case OPT_PACING_TIMER: + test->settings->pacing_timer = unit_atoi(optarg); +@@ -1100,7 +1104,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) + i_errno = IESETCLIENTAUTH; + return -1; + } +- encode_auth_setting(client_username, client_password, client_rsa_public_key, &test->settings->authtoken); ++ encode_auth_setting(client_username, client_password, client_rsa_public_key, &test->settings->authtoken, test->use_pkcs1_padding); + } + + if (test->role == 'c' && (test->server_rsa_private_key || test->server_authorized_users)){ +@@ -1346,7 +1350,7 @@ int test_is_authorized(struct iperf_test *test){ + if (test->settings->authtoken){ + char *username = NULL, *password = NULL; + time_t ts; +- decode_auth_setting(test->debug, test->settings->authtoken, test->server_rsa_private_key, &username, &password, &ts); ++ decode_auth_setting(test->debug, test->settings->authtoken, test->server_rsa_private_key, &username, &password, &ts, test->use_pkcs1_padding); + int ret = check_authentication(username, password, ts, test->server_authorized_users); + if (ret == 0){ + iperf_printf(test, report_authetication_successed, username, ts); +diff --git a/src/iperf_locale.c b/src/iperf_locale.c +index d5a5354..3b6860d 100644 +--- a/src/iperf_locale.c ++++ b/src/iperf_locale.c +@@ -128,6 +128,7 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" + " authentication credentials\n" + " --authorized-users-path path to the configuration file containing user\n" + " credentials\n" ++ " --use-pkcs1-padding use pkcs1 padding at your own risk\n" + #endif //HAVE_SSL + "Client specific:\n" + " -c, --client run in client mode, connecting to \n" +diff --git a/src/iperf_api.h b/src/iperf_api.h +index 3a5df03..255227c 100755 +--- a/src/iperf_api.h ++++ b/src/iperf_api.h +@@ -68,6 +68,7 @@ struct iperf_stream; + #define OPT_SERVER_AUTHORIZED_USERS 15 + #define OPT_PACING_TIMER 16 + #define OPT_CONNECT_TIMEOUT 17 ++#define OPT_USE_PKCS1_PADDING 30 + + /* states */ + #define TEST_START 1 +diff --git a/src/iperf_auth.h b/src/iperf_auth.h +index 38971d8..1f78699 100644 +--- a/src/iperf_auth.h ++++ b/src/iperf_auth.h +@@ -30,7 +30,7 @@ + + int test_load_pubkey(const char *public_keyfile); + int test_load_private_key(const char *private_keyfile); +-int encode_auth_setting(const char *username, const char *password, const char *public_keyfile, char **authtoken); +-int decode_auth_setting(int enable_debug, const char *authtoken, const char *private_keyfile, char **username, char **password, time_t *ts); ++int encode_auth_setting(const char *username, const char *password, const char *public_keyfile, char **authtoken, int use_pkcs1_padding); ++int decode_auth_setting(int enable_debug, const char *authtoken, const char *private_keyfile, char **username, char **password, time_t *ts, int use_pkcs1_padding); + int check_authentication(const char *username, const char *password, const time_t ts, const char *filename); + ssize_t iperf_getpass (char **lineptr, size_t *n, FILE *stream); +diff --git a/src/iperf3.1 b/src/iperf3.1 +index 1be8cc3..87c3e02 100644 +--- a/src/iperf3.1 ++++ b/src/iperf3.1 +@@ -155,6 +155,15 @@ send output to a log file. + force flushing output at every interval. + Used to avoid buffering when sending output to pipe. + .TP ++.BR --use-pkcs1-padding ++This option is only meaningful when using iperf3's authentication ++features. Versions of iperf3 prior to 3.17 used PCKS1 padding in the ++RSA-encrypted credentials, which was vulnerable to a side-channel ++attack that could reveal a server's private key. Beginning with ++iperf-3.17, OAEP padding is used, however this is a breaking change ++that is not compatible with older iperf3 versions. Use this option to ++preserve the less secure, but more compatible, behavior. ++.TP + .BR -d ", " --debug " " + emit debugging output. + Primarily (perhaps exclusively) of use to developers. +diff --git a/src/iperf_auth.c b/src/iperf_auth.c +index f8d2b0a..2d7d519 100644 +--- a/src/iperf_auth.c ++++ b/src/iperf_auth.c +@@ -194,11 +194,12 @@ int test_load_private_key(const char *file){ + return 0; + } + +-int encrypt_rsa_message(const char *plaintext, const char *public_keyfile, unsigned char **encryptedtext) { ++int encrypt_rsa_message(const char *plaintext, const char *public_keyfile, unsigned char **encryptedtext, int use_pkcs1_padding) { + EVP_PKEY *public_key = NULL; + RSA *rsa = NULL; +- unsigned char *rsa_buffer = NULL, pad = RSA_PKCS1_PADDING; +- int keysize, encryptedtext_len, rsa_buffer_len; ++ unsigned char *rsa_buffer = NULL; ++ size_t encryptedtext_len = 0; ++ int rsa_buffer_len, keysize; + + public_key = load_pubkey(public_keyfile); + rsa = EVP_PKEY_get1_RSA(public_key); +@@ -210,20 +211,35 @@ int encrypt_rsa_message(const char *plaintext, const char *public_keyfile, unsig + + BIO *bioBuff = BIO_new_mem_buf((void*)plaintext, (int)strlen(plaintext)); + rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2); +- encryptedtext_len = RSA_public_encrypt(rsa_buffer_len, rsa_buffer, *encryptedtext, rsa, pad); ++ ++ int padding = RSA_PKCS1_OAEP_PADDING; ++ if (use_pkcs1_padding){ ++ padding = RSA_PKCS1_PADDING; ++ } ++ ++ encryptedtext_len = RSA_public_encrypt(rsa_buffer_len, rsa_buffer, *encryptedtext, rsa, padding); + + RSA_free(rsa); + OPENSSL_free(rsa_buffer); +- OPENSSL_free(bioBuff); ++ OPENSSL_free(bioBuff); ++ ++ if (encryptedtext_len < 0) { ++ goto errreturn; ++ } ++ ++ return encryptedtext_len; + +- return encryptedtext_len; ++ errreturn: ++ fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL)); ++ return 0; + } + +-int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedtext_len, const char *private_keyfile, unsigned char **plaintext) { ++int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedtext_len, const char *private_keyfile, unsigned char **plaintext, int use_pkcs1_padding) { + EVP_PKEY *private_key = NULL; + RSA *rsa = NULL; +- unsigned char *rsa_buffer = NULL, pad = RSA_PKCS1_PADDING; +- int plaintext_len, rsa_buffer_len, keysize; ++ unsigned char *rsa_buffer = NULL; ++ size_t plaintext_len = 0; ++ int rsa_buffer_len, keysize; + + private_key = load_key(private_keyfile); + rsa = EVP_PKEY_get1_RSA(private_key); +@@ -235,35 +250,45 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt + + BIO *bioBuff = BIO_new_mem_buf((void*)encryptedtext, encryptedtext_len); + rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2); +- plaintext_len = RSA_private_decrypt(rsa_buffer_len, rsa_buffer, *plaintext, rsa, pad); ++ ++ int padding = RSA_PKCS1_OAEP_PADDING; ++ if (use_pkcs1_padding){ ++ padding = RSA_PKCS1_PADDING; ++ } ++ ++ plaintext_len = RSA_private_decrypt(rsa_buffer_len, rsa_buffer, *plaintext, rsa, padding); + + RSA_free(rsa); + OPENSSL_free(rsa_buffer); + OPENSSL_free(bioBuff); + ++ if (plaintext_len < 0) { ++ plaintext_len = 0; ++ } ++ + return plaintext_len; + } + +-int encode_auth_setting(const char *username, const char *password, const char *public_keyfile, char **authtoken){ ++int encode_auth_setting(const char *username, const char *password, const char *public_keyfile, char **authtoken, int use_pkcs1_padding){ + time_t t = time(NULL); + time_t utc_seconds = mktime(localtime(&t)); + char text[150]; + sprintf (text, "user: %s\npwd: %s\nts: %ld", username, password, utc_seconds); + unsigned char *encrypted = NULL; + int encrypted_len; +- encrypted_len = encrypt_rsa_message(text, public_keyfile, &encrypted); ++ encrypted_len = encrypt_rsa_message(text, public_keyfile, &encrypted, use_pkcs1_padding); + Base64Encode(encrypted, encrypted_len, authtoken); + return (0); //success + } + +-int decode_auth_setting(int enable_debug, char *authtoken, const char *private_keyfile, char **username, char **password, time_t *ts){ ++int decode_auth_setting(int enable_debug, char *authtoken, const char *private_keyfile, char **username, char **password, time_t *ts, int use_pkcs1_padding){ + unsigned char *encrypted_b64 = NULL; + size_t encrypted_len_b64; + Base64Decode(authtoken, &encrypted_b64, &encrypted_len_b64); + + unsigned char *plaintext = NULL; + int plaintext_len; +- plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_keyfile, &plaintext); ++ plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_keyfile, &plaintext, use_pkcs1_padding); + plaintext[plaintext_len] = '\0'; + + char s_username[20], s_password[20]; diff --git a/SPECS/iperf3.spec b/SPECS/iperf3.spec index 9d3453f..f55616d 100644 --- a/SPECS/iperf3.spec +++ b/SPECS/iperf3.spec @@ -1,6 +1,6 @@ Name: iperf3 Version: 3.5 -Release: 6%{?dist} +Release: 10%{?dist} Summary: Measurement tool for TCP/UDP bandwidth performance Group: Applications/Internet @@ -13,6 +13,9 @@ BuildRequires: openssl-devel Patch0002: 0002-udp-counters-manpage.patch Patch0003: 0003-covscan-sctp.patch +Patch0004: 0004-cve-2023-38403.patch +Patch0005: 0005-cve-2023-7250.patch +Patch0006: 0006-cve-2024-26306.patch %description Iperf is a tool to measure maximum TCP bandwidth, allowing the tuning of @@ -60,6 +63,19 @@ rm -f %{buildroot}%{_libdir}/libiperf.la %{_libdir}/*.so %changelog +* Tue Jun 11 2024 Michal Ruprich - 3.5-10 +- Resolves: RHEL-29578 - vulnerable to marvin attack if the authentication option is used + +* Tue Jun 04 2024 Michal Ruprich - 3.5-9 +- Resolves: RHEL-17069 - possible denial of service + +* Fri Jul 28 2023 Michal Ruprich - 3.5-8 +- Related: #2222205 - bumping nvr for correct update path + +* Tue Jul 18 2023 Jonathan Wright - 3.5-7 +- Fixes CVE-2023-38403 + Resolves: rhbz#2223729 + * Tue May 05 2020 Michal Ruprich - 3.5-6 - Related: #1665142 - Fixing a couple of covscan issues