diff --git a/.gitignore b/.gitignore index 881f8a1..640a13a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/iperf-3.5.tar.gz +iperf-3.17.1.tar.gz diff --git a/.iperf3.metadata b/.iperf3.metadata deleted file mode 100644 index bbb7bda..0000000 --- a/.iperf3.metadata +++ /dev/null @@ -1 +0,0 @@ -b255fe0905159bcfe2578e4774ab3091f69f898f SOURCES/iperf-3.5.tar.gz diff --git a/SOURCES/0007-cve-2024-53580.patch b/0001-cve-2024-53580.patch similarity index 74% rename from SOURCES/0007-cve-2024-53580.patch rename to 0001-cve-2024-53580.patch index 81f2f00..5a5086c 100644 --- a/SOURCES/0007-cve-2024-53580.patch +++ b/0001-cve-2024-53580.patch @@ -16,11 +16,224 @@ Original version of fix by @dopheide-esnet. src/iperf_util.h | 1 + 4 files changed, 90 insertions(+), 53 deletions(-) +diff --git a/src/iperf_api.c b/src/iperf_api.c +index bad0a63ad..fa06dc830 100644 +--- a/src/iperf_api.c ++++ b/src/iperf_api.c +@@ -2347,72 +2347,72 @@ get_parameters(struct iperf_test *test) + cJSON_free(str); + } + +- if ((j_p = cJSON_GetObjectItem(j, "tcp")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "tcp", cJSON_True)) != NULL) + set_protocol(test, Ptcp); +- if ((j_p = cJSON_GetObjectItem(j, "udp")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "udp", cJSON_True)) != NULL) + set_protocol(test, Pudp); +- if ((j_p = cJSON_GetObjectItem(j, "sctp")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "sctp", cJSON_True)) != NULL) + set_protocol(test, Psctp); +- if ((j_p = cJSON_GetObjectItem(j, "omit")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "omit", cJSON_Number)) != NULL) + test->omit = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "server_affinity")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "server_affinity", cJSON_Number)) != NULL) + test->server_affinity = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "time")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "time", cJSON_Number)) != NULL) + test->duration = j_p->valueint; + test->settings->bytes = 0; +- if ((j_p = cJSON_GetObjectItem(j, "num")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "num", cJSON_Number)) != NULL) + test->settings->bytes = j_p->valueint; + test->settings->blocks = 0; +- if ((j_p = cJSON_GetObjectItem(j, "blockcount")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "blockcount", cJSON_Number)) != NULL) + test->settings->blocks = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "MSS")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "MSS", cJSON_Number)) != NULL) + test->settings->mss = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "nodelay")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "nodelay", cJSON_True)) != NULL) + test->no_delay = 1; +- if ((j_p = cJSON_GetObjectItem(j, "parallel")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "parallel", cJSON_Number)) != NULL) + test->num_streams = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "reverse")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "reverse", cJSON_True)) != NULL) + iperf_set_test_reverse(test, 1); +- if ((j_p = cJSON_GetObjectItem(j, "bidirectional")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "bidirectional", cJSON_True)) != NULL) + iperf_set_test_bidirectional(test, 1); +- if ((j_p = cJSON_GetObjectItem(j, "window")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "window", cJSON_Number)) != NULL) + test->settings->socket_bufsize = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "len")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "len", cJSON_Number)) != NULL) + test->settings->blksize = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "bandwidth")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "bandwidth", cJSON_Number)) != NULL) + test->settings->rate = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "fqrate")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "fqrate", cJSON_Number)) != NULL) + test->settings->fqrate = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "pacing_timer")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "pacing_timer", cJSON_Number)) != NULL) + test->settings->pacing_timer = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "burst")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "burst", cJSON_Number)) != NULL) + test->settings->burst = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "TOS")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "TOS", cJSON_Number)) != NULL) + test->settings->tos = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "flowlabel")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "flowlabel", cJSON_Number)) != NULL) + test->settings->flowlabel = j_p->valueint; +- if ((j_p = cJSON_GetObjectItem(j, "title")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "title", cJSON_String)) != NULL) + test->title = strdup(j_p->valuestring); +- if ((j_p = cJSON_GetObjectItem(j, "extra_data")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "extra_data", cJSON_String)) != NULL) + test->extra_data = strdup(j_p->valuestring); +- if ((j_p = cJSON_GetObjectItem(j, "congestion")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "congestion", cJSON_String)) != NULL) + test->congestion = strdup(j_p->valuestring); +- if ((j_p = cJSON_GetObjectItem(j, "congestion_used")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "congestion_used", cJSON_String)) != NULL) + test->congestion_used = strdup(j_p->valuestring); +- if ((j_p = cJSON_GetObjectItem(j, "get_server_output")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "get_server_output", cJSON_Number)) != NULL) + iperf_set_test_get_server_output(test, 1); +- if ((j_p = cJSON_GetObjectItem(j, "udp_counters_64bit")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "udp_counters_64bit", cJSON_Number)) != NULL) + iperf_set_test_udp_counters_64bit(test, 1); +- if ((j_p = cJSON_GetObjectItem(j, "repeating_payload")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "repeating_payload", cJSON_Number)) != NULL) + test->repeating_payload = 1; +- if ((j_p = cJSON_GetObjectItem(j, "zerocopy")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "zerocopy", cJSON_Number)) != NULL) + test->zerocopy = j_p->valueint; + #if defined(HAVE_DONT_FRAGMENT) +- if ((j_p = cJSON_GetObjectItem(j, "dont_fragment")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "dont_fragment", cJSON_Number)) != NULL) + test->settings->dont_fragment = j_p->valueint; + #endif /* HAVE_DONT_FRAGMENT */ + #if defined(HAVE_SSL) +- if ((j_p = cJSON_GetObjectItem(j, "authtoken")) != NULL) ++ if ((j_p = iperf_cJSON_GetObjectItemType(j, "authtoken", cJSON_String)) != NULL) + test->settings->authtoken = strdup(j_p->valuestring); + #endif //HAVE_SSL + if (test->mode && test->protocol->id == Ptcp && has_tcpinfo_retransmits()) +@@ -2571,10 +2571,10 @@ get_results(struct iperf_test *test) + i_errno = IERECVRESULTS; + r = -1; + } else { +- j_cpu_util_total = cJSON_GetObjectItem(j, "cpu_util_total"); +- j_cpu_util_user = cJSON_GetObjectItem(j, "cpu_util_user"); +- j_cpu_util_system = cJSON_GetObjectItem(j, "cpu_util_system"); +- j_sender_has_retransmits = cJSON_GetObjectItem(j, "sender_has_retransmits"); ++ j_cpu_util_total = iperf_cJSON_GetObjectItemType(j, "cpu_util_total", cJSON_Number); ++ j_cpu_util_user = iperf_cJSON_GetObjectItemType(j, "cpu_util_user", cJSON_Number); ++ j_cpu_util_system = iperf_cJSON_GetObjectItemType(j, "cpu_util_system", cJSON_Number); ++ j_sender_has_retransmits = iperf_cJSON_GetObjectItemType(j, "sender_has_retransmits", cJSON_Number); + if (j_cpu_util_total == NULL || j_cpu_util_user == NULL || j_cpu_util_system == NULL || j_sender_has_retransmits == NULL) { + i_errno = IERECVRESULTS; + r = -1; +@@ -2596,7 +2596,7 @@ get_results(struct iperf_test *test) + else if ( test->mode == BIDIRECTIONAL ) + test->other_side_has_retransmits = result_has_retransmits; + +- j_streams = cJSON_GetObjectItem(j, "streams"); ++ j_streams = iperf_cJSON_GetObjectItemType(j, "streams", cJSON_Array); + if (j_streams == NULL) { + i_errno = IERECVRESULTS; + r = -1; +@@ -2608,16 +2608,16 @@ get_results(struct iperf_test *test) + i_errno = IERECVRESULTS; + r = -1; + } else { +- j_id = cJSON_GetObjectItem(j_stream, "id"); +- j_bytes = cJSON_GetObjectItem(j_stream, "bytes"); +- j_retransmits = cJSON_GetObjectItem(j_stream, "retransmits"); +- j_jitter = cJSON_GetObjectItem(j_stream, "jitter"); +- j_errors = cJSON_GetObjectItem(j_stream, "errors"); +- j_omitted_errors = cJSON_GetObjectItem(j_stream, "omitted_errors"); +- j_packets = cJSON_GetObjectItem(j_stream, "packets"); +- j_omitted_packets = cJSON_GetObjectItem(j_stream, "omitted_packets"); +- j_start_time = cJSON_GetObjectItem(j_stream, "start_time"); +- j_end_time = cJSON_GetObjectItem(j_stream, "end_time"); ++ j_id = iperf_cJSON_GetObjectItemType(j_stream, "id", cJSON_Number); ++ j_bytes = iperf_cJSON_GetObjectItemType(j_stream, "bytes", cJSON_Number); ++ j_retransmits = iperf_cJSON_GetObjectItemType(j_stream, "retransmits", cJSON_Number); ++ j_jitter = iperf_cJSON_GetObjectItemType(j_stream, "jitter", cJSON_Number); ++ j_errors = iperf_cJSON_GetObjectItemType(j_stream, "errors", cJSON_Number); ++ j_omitted_errors = iperf_cJSON_GetObjectItemType(j_stream, "omitted_errors", cJSON_Number); ++ j_packets = iperf_cJSON_GetObjectItemType(j_stream, "packets", cJSON_Number); ++ j_omitted_packets = iperf_cJSON_GetObjectItemType(j_stream, "omitted_packets", cJSON_Number); ++ j_start_time = iperf_cJSON_GetObjectItemType(j_stream, "start_time", cJSON_Number); ++ j_end_time = iperf_cJSON_GetObjectItemType(j_stream, "end_time", cJSON_Number); + if (j_id == NULL || j_bytes == NULL || j_retransmits == NULL || j_jitter == NULL || j_errors == NULL || j_packets == NULL) { + i_errno = IERECVRESULTS; + r = -1; +@@ -2706,7 +2706,7 @@ get_results(struct iperf_test *test) + } + else { + /* No JSON, look for textual output. Make a copy of the text for later. */ +- j_server_output = cJSON_GetObjectItem(j, "server_output_text"); ++ j_server_output = iperf_cJSON_GetObjectItemType(j, "server_output_text", cJSON_String); + if (j_server_output != NULL) { + test->server_output_text = strdup(j_server_output->valuestring); + } +@@ -2715,7 +2715,7 @@ get_results(struct iperf_test *test) + } + } + +- j_remote_congestion_used = cJSON_GetObjectItem(j, "congestion_used"); ++ j_remote_congestion_used = iperf_cJSON_GetObjectItemType(j, "congestion_used", cJSON_String); + if (j_remote_congestion_used != NULL) { + test->remote_congestion_used = strdup(j_remote_congestion_used->valuestring); + } +@@ -4960,7 +4960,7 @@ iperf_json_finish(struct iperf_test *test) + + /* --json-stream, so we print various individual objects */ + if (test->json_stream) { +- cJSON *error = cJSON_GetObjectItem(test->json_top, "error"); ++ cJSON *error = iperf_cJSON_GetObjectItemType(test->json_top, "error", cJSON_String); + if (error) { + JSONStream_Output(test, "error", error); + } +diff --git a/src/iperf_error.c b/src/iperf_error.c +index e06723ba6..fede216bc 100644 +--- a/src/iperf_error.c ++++ b/src/iperf_error.c +@@ -60,11 +60,11 @@ iperf_err(struct iperf_test *test, const char *format, ...) + if (test != NULL && test->json_output && test->json_top != NULL) + cJSON_AddStringToObject(test->json_top, "error", str); + else { +- if (pthread_mutex_lock(&(test->print_mutex)) != 0) { ++ if (test != NULL && pthread_mutex_lock(&(test->print_mutex)) != 0) { + perror("iperf_err: pthread_mutex_lock"); + } + +- if (test && test->outfile && test->outfile != stdout) { ++ if (test != NULL && test->outfile != NULL && test->outfile != stdout) { + if (ct) { + fprintf(test->outfile, "%s", ct); + } +@@ -77,7 +77,7 @@ iperf_err(struct iperf_test *test, const char *format, ...) + fprintf(stderr, "iperf3: %s\n", str); + } + +- if (pthread_mutex_unlock(&(test->print_mutex)) != 0) { ++ if (test != NULL && pthread_mutex_unlock(&(test->print_mutex)) != 0) { + perror("iperf_err: pthread_mutex_unlock"); + } + diff --git a/src/iperf_util.c b/src/iperf_util.c -index 22ff43a..bf2c408 100644 +index 3d0c7831b..b5c661bbc 100644 --- a/src/iperf_util.c +++ b/src/iperf_util.c -@@ -378,6 +378,42 @@ iperf_json_printf(const char *format, ...) +@@ -430,6 +430,42 @@ iperf_json_printf(const char *format, ...) return o; } @@ -55,190 +268,23 @@ index 22ff43a..bf2c408 100644 + break; + default: + iperf_err(NULL, "unsupported type"); -+ } ++ } + + return NULL; +} + /* Debugging routine to dump out an fd_set. */ void - iperf_dump_fdset(FILE *fp, char *str, int nfds, fd_set *fds) + iperf_dump_fdset(FILE *fp, const char *str, int nfds, fd_set *fds) diff --git a/src/iperf_util.h b/src/iperf_util.h -index ee1d58c..0a33214 100644 +index a371cfcaa..02b280ec5 100644 --- a/src/iperf_util.h +++ b/src/iperf_util.h -@@ -51,6 +51,7 @@ const char* get_system_info(void); +@@ -53,6 +53,7 @@ const char* get_system_info(void); const char* get_optional_features(void); cJSON* iperf_json_printf(const char *format, ...); +cJSON * iperf_cJSON_GetObjectItemType(cJSON * j_p, char * item_string, int expected_type); - void iperf_dump_fdset(FILE *fp, char *str, int nfds, fd_set *fds); + void iperf_dump_fdset(FILE *fp, const char *str, int nfds, fd_set *fds); -diff --git a/src/iperf_error.c b/src/iperf_error.c -index 945984e..f90d03f 100644 ---- a/src/iperf_error.c -+++ b/src/iperf_error.c -@@ -45,7 +45,7 @@ iperf_err(struct iperf_test *test, const char *format, ...) - if (test != NULL && test->json_output && test->json_top != NULL) - cJSON_AddStringToObject(test->json_top, "error", str); - else -- if (test && test->outfile && test->outfile != stdout) { -+ if (test != NULL && test->outfile != NULL && test->outfile != stdout) { - fprintf(test->outfile, "iperf3: %s\n", str); - } - else { -diff --git a/src/iperf_api.c b/src/iperf_api.c -index 549ffcc..34b90c2 100755 ---- a/src/iperf_api.c -+++ b/src/iperf_api.c -@@ -1547,58 +1547,58 @@ get_parameters(struct iperf_test *test) - printf("get_parameters:\n%s\n", cJSON_Print(j)); - } - -- if ((j_p = cJSON_GetObjectItem(j, "tcp")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "tcp", cJSON_True)) != NULL) - set_protocol(test, Ptcp); -- if ((j_p = cJSON_GetObjectItem(j, "udp")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "udp", cJSON_True)) != NULL) - set_protocol(test, Pudp); -- if ((j_p = cJSON_GetObjectItem(j, "sctp")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "sctp", cJSON_True)) != NULL) - set_protocol(test, Psctp); -- if ((j_p = cJSON_GetObjectItem(j, "omit")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "omit", cJSON_Number)) != NULL) - test->omit = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "server_affinity")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "server_affinity", cJSON_Number)) != NULL) - test->server_affinity = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "time")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "time", cJSON_Number)) != NULL) - test->duration = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "num")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "num", cJSON_Number)) != NULL) - test->settings->bytes = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "blockcount")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "blockcount", cJSON_Number)) != NULL) - test->settings->blocks = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "MSS")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "MSS", cJSON_Number)) != NULL) - test->settings->mss = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "nodelay")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "nodelay", cJSON_True)) != NULL) - test->no_delay = 1; -- if ((j_p = cJSON_GetObjectItem(j, "parallel")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "parallel", cJSON_Number)) != NULL) - test->num_streams = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "reverse")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "reverse", cJSON_True)) != NULL) - iperf_set_test_reverse(test, 1); -- if ((j_p = cJSON_GetObjectItem(j, "window")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "window", cJSON_Number)) != NULL) - test->settings->socket_bufsize = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "len")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "len", cJSON_Number)) != NULL) - test->settings->blksize = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "bandwidth")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "bandwidth", cJSON_Number)) != NULL) - test->settings->rate = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "fqrate")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "fqrate", cJSON_Number)) != NULL) - test->settings->fqrate = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "pacing_timer")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "pacing_timer", cJSON_Number)) != NULL) - test->settings->pacing_timer = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "burst")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "burst", cJSON_Number)) != NULL) - test->settings->burst = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "TOS")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "TOS", cJSON_Number)) != NULL) - test->settings->tos = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "flowlabel")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "flowlabel", cJSON_Number)) != NULL) - test->settings->flowlabel = j_p->valueint; -- if ((j_p = cJSON_GetObjectItem(j, "title")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "title", cJSON_String)) != NULL) - test->title = strdup(j_p->valuestring); -- if ((j_p = cJSON_GetObjectItem(j, "congestion")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "congestion", cJSON_String)) != NULL) - test->congestion = strdup(j_p->valuestring); -- if ((j_p = cJSON_GetObjectItem(j, "congestion_used")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "congestion_used", cJSON_String)) != NULL) - test->congestion_used = strdup(j_p->valuestring); -- if ((j_p = cJSON_GetObjectItem(j, "get_server_output")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "get_server_output", cJSON_Number)) != NULL) - iperf_set_test_get_server_output(test, 1); -- if ((j_p = cJSON_GetObjectItem(j, "udp_counters_64bit")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "udp_counters_64bit", cJSON_Number)) != NULL) - iperf_set_test_udp_counters_64bit(test, 1); - #if defined(HAVE_SSL) -- if ((j_p = cJSON_GetObjectItem(j, "authtoken")) != NULL) -+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "authtoken", cJSON_String)) != NULL) - test->settings->authtoken = strdup(j_p->valuestring); - #endif //HAVE_SSL - if (test->sender && test->protocol->id == Ptcp && has_tcpinfo_retransmits()) -@@ -1745,10 +1745,10 @@ get_results(struct iperf_test *test) - i_errno = IERECVRESULTS; - r = -1; - } else { -- j_cpu_util_total = cJSON_GetObjectItem(j, "cpu_util_total"); -- j_cpu_util_user = cJSON_GetObjectItem(j, "cpu_util_user"); -- j_cpu_util_system = cJSON_GetObjectItem(j, "cpu_util_system"); -- j_sender_has_retransmits = cJSON_GetObjectItem(j, "sender_has_retransmits"); -+ j_cpu_util_total = iperf_cJSON_GetObjectItemType(j, "cpu_util_total", cJSON_Number); -+ j_cpu_util_user = iperf_cJSON_GetObjectItemType(j, "cpu_util_user", cJSON_Number); -+ j_cpu_util_system = iperf_cJSON_GetObjectItemType(j, "cpu_util_system", cJSON_Number); -+ j_sender_has_retransmits = iperf_cJSON_GetObjectItemType(j, "sender_has_retransmits", cJSON_Number); - if (j_cpu_util_total == NULL || j_cpu_util_user == NULL || j_cpu_util_system == NULL || j_sender_has_retransmits == NULL) { - i_errno = IERECVRESULTS; - r = -1; -@@ -1763,7 +1763,7 @@ get_results(struct iperf_test *test) - result_has_retransmits = j_sender_has_retransmits->valueint; - if (! test->sender) - test->sender_has_retransmits = result_has_retransmits; -- j_streams = cJSON_GetObjectItem(j, "streams"); -+ j_streams = iperf_cJSON_GetObjectItemType(j, "streams", cJSON_Array); - if (j_streams == NULL) { - i_errno = IERECVRESULTS; - r = -1; -@@ -1775,14 +1775,14 @@ get_results(struct iperf_test *test) - i_errno = IERECVRESULTS; - r = -1; - } else { -- j_id = cJSON_GetObjectItem(j_stream, "id"); -- j_bytes = cJSON_GetObjectItem(j_stream, "bytes"); -- j_retransmits = cJSON_GetObjectItem(j_stream, "retransmits"); -- j_jitter = cJSON_GetObjectItem(j_stream, "jitter"); -- j_errors = cJSON_GetObjectItem(j_stream, "errors"); -- j_packets = cJSON_GetObjectItem(j_stream, "packets"); -- j_start_time = cJSON_GetObjectItem(j_stream, "start_time"); -- j_end_time = cJSON_GetObjectItem(j_stream, "end_time"); -+ j_id = iperf_cJSON_GetObjectItemType(j_stream, "id", cJSON_Number); -+ j_bytes = iperf_cJSON_GetObjectItemType(j_stream, "bytes", cJSON_Number); -+ j_retransmits = iperf_cJSON_GetObjectItemType(j_stream, "retransmits", cJSON_Number); -+ j_jitter = iperf_cJSON_GetObjectItemType(j_stream, "jitter", cJSON_Number); -+ j_errors = iperf_cJSON_GetObjectItemType(j_stream, "errors", cJSON_Number); -+ j_packets = iperf_cJSON_GetObjectItemType(j_stream, "packets", cJSON_Number); -+ j_start_time = iperf_cJSON_GetObjectItemType(j_stream, "start_time", cJSON_Number); -+ j_end_time = iperf_cJSON_GetObjectItemType(j_stream, "end_time", cJSON_Number); - if (j_id == NULL || j_bytes == NULL || j_retransmits == NULL || j_jitter == NULL || j_errors == NULL || j_packets == NULL) { - i_errno = IERECVRESULTS; - r = -1; -@@ -1846,7 +1846,7 @@ get_results(struct iperf_test *test) - } - else { - /* No JSON, look for textual output. Make a copy of the text for later. */ -- j_server_output = cJSON_GetObjectItem(j, "server_output_text"); -+ j_server_output = iperf_cJSON_GetObjectItemType(j, "server_output_text", cJSON_String); - if (j_server_output != NULL) { - test->server_output_text = strdup(j_server_output->valuestring); - } -@@ -1855,7 +1855,7 @@ get_results(struct iperf_test *test) - } - } - -- j_remote_congestion_used = cJSON_GetObjectItem(j, "congestion_used"); -+ j_remote_congestion_used = iperf_cJSON_GetObjectItemType(j, "congestion_used", cJSON_String); - if (j_remote_congestion_used != NULL) { - test->remote_congestion_used = strdup(j_remote_congestion_used->valuestring); - } diff --git a/0002-cve-2025-54349.patch b/0002-cve-2025-54349.patch new file mode 100644 index 0000000..268a0fd --- /dev/null +++ b/0002-cve-2025-54349.patch @@ -0,0 +1,90 @@ +From 4e5313bab0b9b3fe03513ab54f722c8a3e4b7bdf Mon Sep 17 00:00:00 2001 +From: Sarah Larsen +Date: Wed, 25 Jun 2025 15:11:03 +0000 +Subject: [PATCH] Fix off-by-one heap overflow in auth. + +Reported by Han Lee (Apple Information Security) +CVE-2025-54349 +--- + src/iperf_auth.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/src/iperf_auth.c b/src/iperf_auth.c +index b9f2bc0f2..632f03d24 100644 +--- a/src/iperf_auth.c ++++ b/src/iperf_auth.c +@@ -286,6 +286,7 @@ int encrypt_rsa_message(const char *plaintext, EVP_PKEY *public_key, unsigned ch + } + + int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedtext_len, EVP_PKEY *private_key, unsigned char **plaintext, int use_pkcs1_padding) { ++ int ret =0; + #if OPENSSL_VERSION_MAJOR >= 3 + EVP_PKEY_CTX *ctx; + #else +@@ -308,7 +309,8 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt + keysize = RSA_size(rsa); + #endif + rsa_buffer = OPENSSL_malloc(keysize * 2); +- *plaintext = (unsigned char*)OPENSSL_malloc(keysize); ++ // Note: +1 for NULL ++ *plaintext = (unsigned char*)OPENSSL_malloc(keysize + 1); + + BIO *bioBuff = BIO_new_mem_buf((void*)encryptedtext, encryptedtext_len); + rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2); +@@ -318,13 +320,15 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt + padding = RSA_PKCS1_PADDING; + } + #if OPENSSL_VERSION_MAJOR >= 3 ++ + plaintext_len = keysize; + EVP_PKEY_decrypt_init(ctx); +- int ret = EVP_PKEY_CTX_set_rsa_padding(ctx, padding); ++ ++ ret = EVP_PKEY_CTX_set_rsa_padding(ctx, padding); + if (ret < 0){ + goto errreturn; + } +- EVP_PKEY_decrypt(ctx, *plaintext, &plaintext_len, rsa_buffer, rsa_buffer_len); ++ ret = EVP_PKEY_decrypt(ctx, *plaintext, &plaintext_len, rsa_buffer, rsa_buffer_len); + EVP_PKEY_CTX_free(ctx); + #else + plaintext_len = RSA_private_decrypt(rsa_buffer_len, rsa_buffer, *plaintext, rsa, padding); +@@ -335,7 +339,7 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt + BIO_free(bioBuff); + + /* Treat a decryption error as an empty string. */ +- if (plaintext_len < 0) { ++ if (plaintext_len <= 0) { + plaintext_len = 0; + } + +@@ -384,24 +388,28 @@ int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *priva + int plaintext_len; + plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_key, &plaintext, use_pkcs1_padding); + free(encrypted_b64); +- if (plaintext_len < 0) { ++ if (plaintext_len <= 0) { + return -1; + } ++ + plaintext[plaintext_len] = '\0'; + + char *s_username, *s_password; + s_username = (char *) calloc(plaintext_len, sizeof(char)); + if (s_username == NULL) { ++ OPENSSL_free(plaintext); + return -1; + } + s_password = (char *) calloc(plaintext_len, sizeof(char)); + if (s_password == NULL) { ++ OPENSSL_free(plaintext); + free(s_username); + return -1; + } + + int rc = sscanf((char *) plaintext, auth_text_format, s_username, s_password, &utc_seconds); + if (rc != 3) { ++ OPENSSL_free(plaintext); + free(s_password); + free(s_username); + return -1; diff --git a/1278-rebase.patch b/1278-rebase.patch new file mode 100644 index 0000000..5bc1107 --- /dev/null +++ b/1278-rebase.patch @@ -0,0 +1,84 @@ +diff -rNu iperf-3.16.orig/iperf-3.16/src/iperf_api.c iperf-3.16/src/iperf_api.c +--- iperf-3.16.orig/iperf-3.16/src/iperf_api.c 2023-11-29 13:46:13.000000000 -0600 ++++ iperf-3.16/src/iperf_api.c 2023-12-06 22:08:09.508869360 -0600 +@@ -3356,6 +3356,8 @@ + + temp.rttvar = get_rttvar(&temp); + temp.pmtu = get_pmtu(&temp); ++ temp.reorder = get_reorder(&temp); ++ rp->stream_reorder = temp.reorder; + } + } + } else { +@@ -3801,7 +3803,7 @@ + if (test->sender_has_retransmits) { + /* Sender summary, TCP and SCTP with retransmits. */ + if (test->json_output) +- cJSON_AddItemToObject(json_summary_stream, report_sender, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d max_snd_cwnd: %d max_snd_wnd: %d max_rtt: %d min_rtt: %d mean_rtt: %d sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans, (int64_t) sp->result->stream_max_snd_cwnd, (int64_t) sp->result->stream_max_snd_wnd, (int64_t) sp->result->stream_max_rtt, (int64_t) sp->result->stream_min_rtt, (int64_t) ((sp->result->stream_count_rtt == 0) ? 0 : sp->result->stream_sum_rtt / sp->result->stream_count_rtt), stream_must_be_sender)); ++ cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d reorder: %d max_snd_cwnd: %d max_snd_wnd: %d max_rtt: %d min_rtt: %d mean_rtt: %d sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans, (int64_t) sp->result->stream_reorder, (int64_t) sp->result->stream_max_snd_cwnd, (int64_t) sp->result->stream_max_snd_wnd, (int64_t) sp->result->stream_max_rtt, (int64_t) sp->result->stream_min_rtt, (int64_t) ((sp->result->stream_count_rtt == 0) ? 0 : sp->result->stream_sum_rtt / sp->result->stream_count_rtt), stream_must_be_sender)); + else + if (test->role == 's' && !sp->sender) { + if (test->verbose) +@@ -4252,7 +4254,7 @@ + if (test->sender_has_retransmits == 1 && sp->sender) { + /* Interval, TCP with retransmits. */ + if (test->json_output) +- cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d snd_cwnd: %d snd_wnd: %d rtt: %d rttvar: %d pmtu: %d omitted: %b sender: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->interval_retrans, (int64_t) irp->snd_cwnd, (int64_t) irp->snd_wnd, (int64_t) irp->rtt, (int64_t) irp->rttvar, (int64_t) irp->pmtu, irp->omitted, sp->sender)); ++ cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d snd_cwnd: %d snd_wnd: %d rtt: %d rttvar: %d pmtu: %d reorder: %d omitted: %b sender: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->interval_retrans, (int64_t) irp->snd_cwnd, (int64_t) irp->snd_wnd, (int64_t) irp->rtt, (int64_t) irp->rttvar, (int64_t) irp->pmtu, (int64_t) irp->reorder, irp->omitted, sp->sender)); + else { + unit_snprintf(cbuf, UNIT_LEN, irp->snd_cwnd, 'A'); + iperf_printf(test, report_bw_retrans_cwnd_format, sp->socket, mbuf, st, et, ubuf, nbuf, irp->interval_retrans, cbuf, irp->omitted?report_omitted:""); +diff -rNu iperf-3.16.orig/iperf-3.16/src/iperf_api.h iperf-3.16/src/iperf_api.h +--- iperf-3.16.orig/iperf-3.16/src/iperf_api.h 2023-11-29 13:46:13.000000000 -0600 ++++ iperf-3.16/src/iperf_api.h 2023-12-06 22:08:36.409418686 -0600 +@@ -316,6 +316,7 @@ + long get_rtt(struct iperf_interval_results *irp); + long get_rttvar(struct iperf_interval_results *irp); + long get_pmtu(struct iperf_interval_results *irp); ++long get_reorder(struct iperf_interval_results *irp); + void print_tcpinfo(struct iperf_test *test); + void build_tcpinfo_message(struct iperf_interval_results *r, char *message); + +diff -rNu iperf-3.16.orig/iperf-3.16/src/iperf.h iperf-3.16/src/iperf.h +--- iperf-3.16.orig/iperf-3.16/src/iperf.h 2023-11-29 13:46:13.000000000 -0600 ++++ iperf-3.16/src/iperf.h 2023-12-06 22:06:35.332454109 -0600 +@@ -125,6 +125,7 @@ + long rtt; + long rttvar; + long pmtu; ++ long reorder; + }; + + struct iperf_stream_result +@@ -136,6 +137,7 @@ + atomic_iperf_size_t bytes_sent_omit; + long stream_prev_total_retrans; + long stream_retrans; ++ long stream_reorder; + long stream_max_rtt; + long stream_min_rtt; + long stream_sum_rtt; +diff -rNu iperf-3.16.orig/iperf-3.16/src/tcp_info.c iperf-3.16/src/tcp_info.c +--- iperf-3.16.orig/iperf-3.16/src/tcp_info.c 2023-11-29 13:46:13.000000000 -0600 ++++ iperf-3.16/src/tcp_info.c 2023-12-06 22:09:45.371252438 -0600 +@@ -218,6 +218,20 @@ + } + + /*************************************************************/ ++/* ++ * Return number of reordering events seen. ++ */ ++long ++get_reorder(struct iperf_interval_results *irp) ++{ ++#if defined(linux) && defined(TCP_REPAIR_ON) ++ return irp->tcpInfo.tcpi_reord_seen; ++#else ++ return -1; ++#endif ++} ++ ++/*************************************************************/ + void + build_tcpinfo_message(struct iperf_interval_results *r, char *message) + { diff --git a/SOURCES/0002-udp-counters-manpage.patch b/SOURCES/0002-udp-counters-manpage.patch deleted file mode 100644 index f78b403..0000000 --- a/SOURCES/0002-udp-counters-manpage.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/src/iperf3.1 b/src/iperf3.1 -index 05483a9..35a0873 100644 ---- a/src/iperf3.1 -+++ b/src/iperf3.1 -@@ -329,6 +329,13 @@ If the client is run with \fB--json\fR, the server output is included - in a JSON object; otherwise it is appended at the bottom of the - human-readable output. - .TP -+.BR --udp-counters-64bit -+Use 64-bit counters in UDP test packets. -+The use of this option can help prevent counter overflows during long -+or high-bitrate UDP tests. Both client and server need to be running -+at least version 3.1 for this option to work. It may become the -+default behavior at some point in the future. -+.TP - .BR --username " \fIusername\fR" - username to use for authentication to the iperf server (if built with - OpenSSL support). diff --git a/SOURCES/0003-covscan-sctp.patch b/SOURCES/0003-covscan-sctp.patch deleted file mode 100644 index 3d18870..0000000 --- a/SOURCES/0003-covscan-sctp.patch +++ /dev/null @@ -1,69 +0,0 @@ -diff --git a/src/iperf_sctp.c b/src/iperf_sctp.c -index a0869a3..13f5cdf 100644 ---- a/src/iperf_sctp.c -+++ b/src/iperf_sctp.c -@@ -130,12 +130,14 @@ iperf_sctp_accept(struct iperf_test * test) - - if (Nread(s, cookie, COOKIE_SIZE, Psctp) < 0) { - i_errno = IERECVCOOKIE; -+ close(s); - return -1; - } - -- if (strcmp(test->cookie, cookie) != 0) { -+ if (strncmp(test->cookie, cookie, COOKIE_SIZE) != 0) { - if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Psctp) < 0) { - i_errno = IESENDMESSAGE; -+ close(s); - return -1; - } - close(s); -@@ -209,9 +211,11 @@ iperf_sctp_listen(struct iperf_test *test) - - /* servers must call sctp_bindx() _instead_ of bind() */ - if (!TAILQ_EMPTY(&test->xbind_addrs)) { -- freeaddrinfo(res); -- if (iperf_sctp_bindx(test, s, IPERF_SCTP_SERVER)) -+ if (iperf_sctp_bindx(test, s, IPERF_SCTP_SERVER)) { -+ close(s); -+ freeaddrinfo(res); - return -1; -+ } - } else - if (bind(s, (struct sockaddr *) res->ai_addr, res->ai_addrlen) < 0) { - saved_errno = errno; -@@ -422,8 +426,11 @@ iperf_sctp_connect(struct iperf_test *test) - - /* clients must call bind() followed by sctp_bindx() before connect() */ - if (!TAILQ_EMPTY(&test->xbind_addrs)) { -- if (iperf_sctp_bindx(test, s, IPERF_SCTP_CLIENT)) -+ if (iperf_sctp_bindx(test, s, IPERF_SCTP_CLIENT)) { -+ freeaddrinfo(server_res); -+ close(s); - return -1; -+ } - } - - /* TODO support sctp_connectx() to avoid heartbeating. */ -@@ -435,12 +442,12 @@ iperf_sctp_connect(struct iperf_test *test) - i_errno = IESTREAMCONNECT; - return -1; - } -- freeaddrinfo(server_res); - - /* Send cookie for verification */ - if (Nwrite(s, test->cookie, COOKIE_SIZE, Psctp) < 0) { - saved_errno = errno; - close(s); -+ freeaddrinfo(server_res); - errno = saved_errno; - i_errno = IESENDCOOKIE; - return -1; -@@ -464,6 +471,7 @@ iperf_sctp_connect(struct iperf_test *test) - return -1; - } - -+ freeaddrinfo(server_res); - return s; - #else - i_errno = IENOSCTP; diff --git a/SOURCES/0004-cve-2023-38403.patch b/SOURCES/0004-cve-2023-38403.patch deleted file mode 100644 index a909d18..0000000 --- a/SOURCES/0004-cve-2023-38403.patch +++ /dev/null @@ -1,45 +0,0 @@ -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 deleted file mode 100644 index 4ab09fb..0000000 --- a/SOURCES/0005-cve-2023-7250.patch +++ /dev/null @@ -1,497 +0,0 @@ -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 deleted file mode 100644 index b8ed1f5..0000000 --- a/SOURCES/0006-cve-2024-26306.patch +++ /dev/null @@ -1,231 +0,0 @@ -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/SOURCES/0008-cve-2025-54349.patch b/SOURCES/0008-cve-2025-54349.patch deleted file mode 100644 index 373cba1..0000000 --- a/SOURCES/0008-cve-2025-54349.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/src/iperf_auth.c b/src/iperf_auth.c -index a268bab..9dbe4d0 100644 ---- a/src/iperf_auth.c -+++ b/src/iperf_auth.c -@@ -247,7 +248,8 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt - - keysize = RSA_size(rsa); - rsa_buffer = OPENSSL_malloc(keysize * 2); -- *plaintext = (unsigned char*)OPENSSL_malloc(keysize); -+ // Note: +1 for NULL -+ *plaintext = (unsigned char*)OPENSSL_malloc(keysize + 1); - - BIO *bioBuff = BIO_new_mem_buf((void*)encryptedtext, encryptedtext_len); - rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2); -@@ -263,7 +265,7 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt - OPENSSL_free(rsa_buffer); - OPENSSL_free(bioBuff); - -- if (plaintext_len < 0) { -+ if (plaintext_len <= 0) { - plaintext_len = 0; - } - -@@ -290,6 +292,11 @@ int decode_auth_setting(int enable_debug, char *authtoken, const char *private_k - unsigned char *plaintext = NULL; - int plaintext_len; - plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_keyfile, &plaintext, use_pkcs1_padding); -+ free(encrypted_b64); -+ if (plaintext_len <= 0) { -+ return -1; -+ } -+ - plaintext[plaintext_len] = '\0'; - - char s_username[20], s_password[20]; diff --git a/SPECS/iperf3.spec b/iperf3.spec similarity index 52% rename from SPECS/iperf3.spec rename to iperf3.spec index 8e05f42..47dc836 100644 --- a/SPECS/iperf3.spec +++ b/iperf3.spec @@ -1,23 +1,22 @@ Name: iperf3 -Version: 3.5 -Release: 12%{?dist} +Version: 3.17.1 +Release: 5%{?dist} Summary: Measurement tool for TCP/UDP bandwidth performance -Group: Applications/Internet -License: BSD -URL: http://github.com/esnet/iperf -Source0: http://downloads.es.net/pub/iperf/iperf-%{version}.tar.gz -BuildRequires: libuuid-devel git-core gcc make +License: BSD-3-Clause-LBNL AND MIT AND dtoa AND BSD-3-Clause AND NCSA AND LicenseRef-Fedora-Public-Domain +URL: https://github.com/esnet/iperf +Source0: %{url}/archive/%{version}/iperf-%{version}.tar.gz +# https://github.com/esnet/iperf/pull/1278 +BuildRequires: libuuid-devel +BuildRequires: gcc BuildRequires: lksctp-tools-devel BuildRequires: openssl-devel +BuildRequires: make +BuildRequires: git-core -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 -Patch0007: 0007-cve-2024-53580.patch -Patch0008: 0008-cve-2025-54349.patch +Patch0000: 1278-rebase.patch +Patch0001: 0001-cve-2024-53580.patch +Patch0002: 0002-cve-2025-54349.patch %description Iperf is a tool to measure maximum TCP bandwidth, allowing the tuning of @@ -26,7 +25,6 @@ jitter, data-gram loss. %package devel Summary: Development files for %{name} -Group: Development/Libraries Requires: %{name}%{?_isa} = %{version}-%{release} %description devel @@ -34,7 +32,7 @@ The %{name}-devel package contains libraries and header files for developing applications that use %{name}. %prep -%autosetup -S git -n iperf-%{version} +%autosetup -S git -n iperf-%{version} -p1 %build %configure --disable-static @@ -49,60 +47,126 @@ mkdir -p %{buildroot}%{_mandir}/man1 rm -f %{buildroot}%{_libdir}/libiperf.la %files -%defattr(-,root,root,-) -%doc README.md LICENSE RELEASE_NOTES +%doc README.md LICENSE RELNOTES.md %{_mandir}/man1/iperf3.1.gz %{_mandir}/man3/libiperf.3.gz %{_bindir}/iperf3 %{_libdir}/*.so.* -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig - %files devel -%defattr(-,root,root,-) %{_includedir}/iperf_api.h %{_libdir}/*.so %changelog -* Fri Jan 23 2026 Michal Ruprich - 3.5-12 -- Resolves: RHEL-136175 - iperf Heap Buffer Overflow (CVE-2025-54349) +* Tue Jan 20 2026 Michal Ruprich - 3.17.1-5 +- Resolves: RHEL-136170 - iperf Heap Buffer Overflow (CVE-2025-54349) -* Wed Jan 08 2025 Michal Ruprich - 3.5-11 -- Resolves: RHEL-72924 - Denial of Service in iperf Due to Improper JSON Handling +* Thu Jan 09 2025 Michal Ruprich - 3.17.1-4 +- Resolves: RHEL-71809 - Denial of Service in iperf Due to Improper JSON Handling -* Tue Jun 11 2024 Michal Ruprich - 3.5-10 -- Resolves: RHEL-29578 - vulnerable to marvin attack if the authentication option is used +* Tue Oct 29 2024 Troy Dawson - 3.17.1-3 +- Bump release for October 2024 mass rebuild: + Resolves: RHEL-64018 -* Tue Jun 04 2024 Michal Ruprich - 3.5-9 -- Resolves: RHEL-17069 - possible denial of service +* Mon Jun 24 2024 Troy Dawson - 3.17.1-2 +- Bump release for June 2024 mass rebuild -* Fri Jul 28 2023 Michal Ruprich - 3.5-8 -- Related: #2222205 - bumping nvr for correct update path +* Fri Jun 07 2024 Michal Ruprich - 3.17.1-1 +- New version 3.17.1 +- Fixes CVE-2024-26306 -* Tue Jul 18 2023 Jonathan Wright - 3.5-7 -- Fixes CVE-2023-38403 - Resolves: rhbz#2223729 +* Thu May 09 2024 Michal Ruprich - 3.16-4 +- Migrated to SPDX license +- Improving testing for RHEL10 -* Tue May 05 2020 Michal Ruprich - 3.5-6 -- Related: #1665142 - Fixing a couple of covscan issues +* Wed Jan 24 2024 Fedora Release Engineering - 3.16-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Fri Mar 13 2020 Michal Ruprich - 3.5-5 -- Related: #1665142 - Removing patch that deletes sctp from manpage +* Sat Jan 20 2024 Fedora Release Engineering - 3.16-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Mon Mar 09 2020 Michal Ruprich - 3.5-4 -- Resolves: #1665142 - [RFE] enable SCTP support in iperf3 -- Resolves: #1656429 - option --udp-counters-64bit shown in --help output but not in man page -- Resolves: #1700497 - [RFE] enable SSL support in iperf3 +* Wed Dec 06 2023 Jonathan Wright - 3.16-1 +- Update to 3.16 rhbz#2252641 -* Sun Dec 16 2018 Michal Ruprich - 3.5-3 -- Related: #1647413 - Removing nstreams and xbind from man since these are SCTP-related options +* Tue Oct 17 2023 Jonathan Wright - 3.15-1 +- Update to 3.15 rhbz#2239199 rhbz#2244708 -* Thu Nov 22 2018 Michal Ruprich - 3.5-2 -- Related: #1647413 - adding some BuildRequires +* Thu Jul 20 2023 Fedora Release Engineering - 3.14-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild -* Thu Nov 22 2018 Michal Ruprich - 3.5-2 -- Resolves: #1647413 - iperf3 with option --sctp in client mode fails with error 'iperf3: unrecognized option --sctp' +* Tue Jul 18 2023 Jonathan Wright - 3.14-2 +- update spec file syntax + +* Tue Jul 18 2023 Jonathan Wright - 3.14-1 +- update to 3.14 rhbz#2183634 +- Security fix for CVE-2023-38403 rhbz#2222204 rhbz#2223495 + +* Mon Feb 20 2023 Jonathan Wright - 3.13-1 +- update to 3.13 rhbz#2170949 + +* Thu Jan 19 2023 Fedora Release Engineering - 3.12-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Mon Dec 12 2022 Jonathan Wright - 3.12-1 +- Update to 3.12 rhbz#2131418 + +* Tue Sep 27 2022 Davide Cavalca - 3.11-3 +- Backport PR#1278: Report number of reorder_seen. Fixes: rhbz#2063959 + +* Thu Jul 21 2022 Fedora Release Engineering - 3.11-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Sun Feb 20 2022 Kevin Fenzi - 3.11-1 +- Update to 3.11. Fixes rhbz#2050303 + +* Thu Jan 20 2022 Fedora Release Engineering - 3.10.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Tue Sep 14 2021 Sahana Prasad - 3.10.1-3 +- Rebuilt with OpenSSL 3.0.0 + +* Thu Jul 22 2021 Fedora Release Engineering - 3.10.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Sat Jun 19 2021 Kevin Fenzi - 3.10.1-1 +- Update to 3.10.1. Fixes rhbz#1965275 + +* Tue Jan 26 2021 Fedora Release Engineering - 3.9-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Sat Oct 31 2020 Kevin Fenzi - 3.9-5 +- Update to 3.9. Fixes bug #1846161 + +* Tue Jul 28 2020 Fedora Release Engineering - 3.7-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Wed Feb 19 2020 Michal Ruprich - 3.7-4 +- Add openssl-devel to BuildRequires to enable authentization of client + +* Wed Jan 29 2020 Fedora Release Engineering - 3.7-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Jul 25 2019 Fedora Release Engineering - 3.7-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Sat Jun 22 2019 Kevin Fenzi - 3.7-1 +- Update to 3.7. Fixes bug #1723020 + +* Tue Feb 26 2019 Tomas Korbar - 3.6-5 +- Add lksctp-tools-devel to BuildRequires +- Fix bug #1647385 + +* Fri Feb 01 2019 Fedora Release Engineering - 3.6-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Fri Jul 20 2018 Kevin Fenzi - 3.6-3 +- Fix FTBFS bug #1604377 by adding BuildRequires: gcc + +* Fri Jul 13 2018 Fedora Release Engineering - 3.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu Jun 28 2018 Kevin Fenzi - 3.6-1 +- Update to 3.6. Fixes bug #1594995 * Sat Mar 03 2018 Kevin Fenzi - 3.5-1 - Update to 3.5. Fixes bug #1551166 diff --git a/sources b/sources new file mode 100644 index 0000000..cf53de8 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (iperf-3.17.1.tar.gz) = 54789c5a63081aa803575ce1df3cb251a3b0bb16313f049f2479ae3a5af39944ace1222d4a086bed0ab34821da73371b2499f8b8283791a953d861da4cfc56f0