Skip to content

Commit 22d5fc1

Browse files
[AUTO-CHERRYPICK] iperf3: address CVE-2024-53580 - branch 3.0-dev (#11869)
Co-authored-by: Kanishk Bansal <103916909+Kanishk-Bansal@users.noreply.github.com>
1 parent e495db5 commit 22d5fc1

2 files changed

Lines changed: 292 additions & 1 deletion

File tree

SPECS/iperf3/CVE-2024-53580.patch

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
From 837c1f9389fc64938a6081517c34a749a11692b0 Mon Sep 17 00:00:00 2001
2+
From: Kanishk-Bansal <kbkanishk975@gmail.com>
3+
Date: Tue, 31 Dec 2024 09:23:23 +0000
4+
Subject: [PATCH] Fix CVE-2024-53580
5+
6+
---
7+
src/iperf_api.c | 98 +++++++++++++++++++++++------------------------
8+
src/iperf_error.c | 6 +--
9+
src/iperf_util.c | 36 +++++++++++++++++
10+
src/iperf_util.h | 1 +
11+
4 files changed, 89 insertions(+), 52 deletions(-)
12+
13+
diff --git a/src/iperf_api.c b/src/iperf_api.c
14+
index 7fb741e..bb3be92 100644
15+
--- a/src/iperf_api.c
16+
+++ b/src/iperf_api.c
17+
@@ -2308,72 +2308,72 @@ get_parameters(struct iperf_test *test)
18+
cJSON_free(str);
19+
}
20+
21+
- if ((j_p = cJSON_GetObjectItem(j, "tcp")) != NULL)
22+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "tcp", cJSON_True)) != NULL)
23+
set_protocol(test, Ptcp);
24+
- if ((j_p = cJSON_GetObjectItem(j, "udp")) != NULL)
25+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "udp", cJSON_True)) != NULL)
26+
set_protocol(test, Pudp);
27+
- if ((j_p = cJSON_GetObjectItem(j, "sctp")) != NULL)
28+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "sctp", cJSON_True)) != NULL)
29+
set_protocol(test, Psctp);
30+
- if ((j_p = cJSON_GetObjectItem(j, "omit")) != NULL)
31+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "omit", cJSON_Number)) != NULL)
32+
test->omit = j_p->valueint;
33+
- if ((j_p = cJSON_GetObjectItem(j, "server_affinity")) != NULL)
34+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "server_affinity", cJSON_Number)) != NULL)
35+
test->server_affinity = j_p->valueint;
36+
- if ((j_p = cJSON_GetObjectItem(j, "time")) != NULL)
37+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "time", cJSON_Number)) != NULL)
38+
test->duration = j_p->valueint;
39+
test->settings->bytes = 0;
40+
- if ((j_p = cJSON_GetObjectItem(j, "num")) != NULL)
41+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "num", cJSON_Number)) != NULL)
42+
test->settings->bytes = j_p->valueint;
43+
test->settings->blocks = 0;
44+
- if ((j_p = cJSON_GetObjectItem(j, "blockcount")) != NULL)
45+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "blockcount", cJSON_Number)) != NULL)
46+
test->settings->blocks = j_p->valueint;
47+
- if ((j_p = cJSON_GetObjectItem(j, "MSS")) != NULL)
48+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "MSS", cJSON_Number)) != NULL)
49+
test->settings->mss = j_p->valueint;
50+
- if ((j_p = cJSON_GetObjectItem(j, "nodelay")) != NULL)
51+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "nodelay", cJSON_True)) != NULL)
52+
test->no_delay = 1;
53+
- if ((j_p = cJSON_GetObjectItem(j, "parallel")) != NULL)
54+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "parallel", cJSON_Number)) != NULL)
55+
test->num_streams = j_p->valueint;
56+
- if ((j_p = cJSON_GetObjectItem(j, "reverse")) != NULL)
57+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "reverse", cJSON_True)) != NULL)
58+
iperf_set_test_reverse(test, 1);
59+
- if ((j_p = cJSON_GetObjectItem(j, "bidirectional")) != NULL)
60+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "bidirectional", cJSON_True)) != NULL)
61+
iperf_set_test_bidirectional(test, 1);
62+
- if ((j_p = cJSON_GetObjectItem(j, "window")) != NULL)
63+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "window", cJSON_Number)) != NULL)
64+
test->settings->socket_bufsize = j_p->valueint;
65+
- if ((j_p = cJSON_GetObjectItem(j, "len")) != NULL)
66+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "len", cJSON_Number)) != NULL)
67+
test->settings->blksize = j_p->valueint;
68+
- if ((j_p = cJSON_GetObjectItem(j, "bandwidth")) != NULL)
69+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "bandwidth", cJSON_Number)) != NULL)
70+
test->settings->rate = j_p->valueint;
71+
- if ((j_p = cJSON_GetObjectItem(j, "fqrate")) != NULL)
72+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "fqrate", cJSON_Number)) != NULL)
73+
test->settings->fqrate = j_p->valueint;
74+
- if ((j_p = cJSON_GetObjectItem(j, "pacing_timer")) != NULL)
75+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "pacing_timer", cJSON_Number)) != NULL)
76+
test->settings->pacing_timer = j_p->valueint;
77+
- if ((j_p = cJSON_GetObjectItem(j, "burst")) != NULL)
78+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "burst", cJSON_Number)) != NULL)
79+
test->settings->burst = j_p->valueint;
80+
- if ((j_p = cJSON_GetObjectItem(j, "TOS")) != NULL)
81+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "TOS", cJSON_Number)) != NULL)
82+
test->settings->tos = j_p->valueint;
83+
- if ((j_p = cJSON_GetObjectItem(j, "flowlabel")) != NULL)
84+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "flowlabel", cJSON_Number)) != NULL)
85+
test->settings->flowlabel = j_p->valueint;
86+
- if ((j_p = cJSON_GetObjectItem(j, "title")) != NULL)
87+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "title", cJSON_String)) != NULL)
88+
test->title = strdup(j_p->valuestring);
89+
- if ((j_p = cJSON_GetObjectItem(j, "extra_data")) != NULL)
90+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "extra_data", cJSON_String)) != NULL)
91+
test->extra_data = strdup(j_p->valuestring);
92+
- if ((j_p = cJSON_GetObjectItem(j, "congestion")) != NULL)
93+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "congestion", cJSON_String)) != NULL)
94+
test->congestion = strdup(j_p->valuestring);
95+
- if ((j_p = cJSON_GetObjectItem(j, "congestion_used")) != NULL)
96+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "congestion_used", cJSON_String)) != NULL)
97+
test->congestion_used = strdup(j_p->valuestring);
98+
- if ((j_p = cJSON_GetObjectItem(j, "get_server_output")) != NULL)
99+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "get_server_output", cJSON_Number)) != NULL)
100+
iperf_set_test_get_server_output(test, 1);
101+
- if ((j_p = cJSON_GetObjectItem(j, "udp_counters_64bit")) != NULL)
102+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "udp_counters_64bit", cJSON_Number)) != NULL)
103+
iperf_set_test_udp_counters_64bit(test, 1);
104+
- if ((j_p = cJSON_GetObjectItem(j, "repeating_payload")) != NULL)
105+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "repeating_payload", cJSON_Number)) != NULL)
106+
test->repeating_payload = 1;
107+
- if ((j_p = cJSON_GetObjectItem(j, "zerocopy")) != NULL)
108+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "zerocopy", cJSON_Number)) != NULL)
109+
test->zerocopy = j_p->valueint;
110+
#if defined(HAVE_DONT_FRAGMENT)
111+
- if ((j_p = cJSON_GetObjectItem(j, "dont_fragment")) != NULL)
112+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "dont_fragment", cJSON_Number)) != NULL)
113+
test->settings->dont_fragment = j_p->valueint;
114+
#endif /* HAVE_DONT_FRAGMENT */
115+
#if defined(HAVE_SSL)
116+
- if ((j_p = cJSON_GetObjectItem(j, "authtoken")) != NULL)
117+
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "authtoken", cJSON_String)) != NULL)
118+
test->settings->authtoken = strdup(j_p->valuestring);
119+
#endif //HAVE_SSL
120+
if (test->mode && test->protocol->id == Ptcp && has_tcpinfo_retransmits())
121+
@@ -2532,10 +2532,10 @@ get_results(struct iperf_test *test)
122+
i_errno = IERECVRESULTS;
123+
r = -1;
124+
} else {
125+
- j_cpu_util_total = cJSON_GetObjectItem(j, "cpu_util_total");
126+
- j_cpu_util_user = cJSON_GetObjectItem(j, "cpu_util_user");
127+
- j_cpu_util_system = cJSON_GetObjectItem(j, "cpu_util_system");
128+
- j_sender_has_retransmits = cJSON_GetObjectItem(j, "sender_has_retransmits");
129+
+ j_cpu_util_total = iperf_cJSON_GetObjectItemType(j, "cpu_util_total", cJSON_Number);
130+
+ j_cpu_util_user = iperf_cJSON_GetObjectItemType(j, "cpu_util_user", cJSON_Number);
131+
+ j_cpu_util_system = iperf_cJSON_GetObjectItemType(j, "cpu_util_system", cJSON_Number);
132+
+ j_sender_has_retransmits = iperf_cJSON_GetObjectItemType(j, "sender_has_retransmits", cJSON_Number);
133+
if (j_cpu_util_total == NULL || j_cpu_util_user == NULL || j_cpu_util_system == NULL || j_sender_has_retransmits == NULL) {
134+
i_errno = IERECVRESULTS;
135+
r = -1;
136+
@@ -2557,7 +2557,7 @@ get_results(struct iperf_test *test)
137+
else if ( test->mode == BIDIRECTIONAL )
138+
test->other_side_has_retransmits = result_has_retransmits;
139+
140+
- j_streams = cJSON_GetObjectItem(j, "streams");
141+
+ j_streams = iperf_cJSON_GetObjectItemType(j, "streams", cJSON_Array);
142+
if (j_streams == NULL) {
143+
i_errno = IERECVRESULTS;
144+
r = -1;
145+
@@ -2569,16 +2569,16 @@ get_results(struct iperf_test *test)
146+
i_errno = IERECVRESULTS;
147+
r = -1;
148+
} else {
149+
- j_id = cJSON_GetObjectItem(j_stream, "id");
150+
- j_bytes = cJSON_GetObjectItem(j_stream, "bytes");
151+
- j_retransmits = cJSON_GetObjectItem(j_stream, "retransmits");
152+
- j_jitter = cJSON_GetObjectItem(j_stream, "jitter");
153+
- j_errors = cJSON_GetObjectItem(j_stream, "errors");
154+
- j_omitted_errors = cJSON_GetObjectItem(j_stream, "omitted_errors");
155+
- j_packets = cJSON_GetObjectItem(j_stream, "packets");
156+
- j_omitted_packets = cJSON_GetObjectItem(j_stream, "omitted_packets");
157+
- j_start_time = cJSON_GetObjectItem(j_stream, "start_time");
158+
- j_end_time = cJSON_GetObjectItem(j_stream, "end_time");
159+
+ j_id = iperf_cJSON_GetObjectItemType(j_stream, "id", cJSON_Number);
160+
+ j_bytes = iperf_cJSON_GetObjectItemType(j_stream, "bytes", cJSON_Number);
161+
+ j_retransmits = iperf_cJSON_GetObjectItemType(j_stream, "retransmits", cJSON_Number);
162+
+ j_jitter = iperf_cJSON_GetObjectItemType(j_stream, "jitter", cJSON_Number);
163+
+ j_errors = iperf_cJSON_GetObjectItemType(j_stream, "errors", cJSON_Number);
164+
+ j_omitted_errors = iperf_cJSON_GetObjectItemType(j_stream, "omitted_errors", cJSON_Number);
165+
+ j_packets = iperf_cJSON_GetObjectItemType(j_stream, "packets", cJSON_Number);
166+
+ j_omitted_packets = iperf_cJSON_GetObjectItemType(j_stream, "omitted_packets", cJSON_Number);
167+
+ j_start_time = iperf_cJSON_GetObjectItemType(j_stream, "start_time", cJSON_Number);
168+
+ j_end_time = iperf_cJSON_GetObjectItemType(j_stream, "end_time", cJSON_Number);
169+
if (j_id == NULL || j_bytes == NULL || j_retransmits == NULL || j_jitter == NULL || j_errors == NULL || j_packets == NULL) {
170+
i_errno = IERECVRESULTS;
171+
r = -1;
172+
@@ -2667,7 +2667,7 @@ get_results(struct iperf_test *test)
173+
}
174+
else {
175+
/* No JSON, look for textual output. Make a copy of the text for later. */
176+
- j_server_output = cJSON_GetObjectItem(j, "server_output_text");
177+
+ j_server_output = iperf_cJSON_GetObjectItemType(j, "server_output_text", cJSON_String);
178+
if (j_server_output != NULL) {
179+
test->server_output_text = strdup(j_server_output->valuestring);
180+
}
181+
@@ -2676,7 +2676,7 @@ get_results(struct iperf_test *test)
182+
}
183+
}
184+
185+
- j_remote_congestion_used = cJSON_GetObjectItem(j, "congestion_used");
186+
+ j_remote_congestion_used = iperf_cJSON_GetObjectItemType(j, "congestion_used", cJSON_String);
187+
if (j_remote_congestion_used != NULL) {
188+
test->remote_congestion_used = strdup(j_remote_congestion_used->valuestring);
189+
}
190+
@@ -4878,7 +4878,7 @@ iperf_json_finish(struct iperf_test *test)
191+
192+
/* --json-stream, so we print various individual objects */
193+
if (test->json_stream) {
194+
- cJSON *error = cJSON_GetObjectItem(test->json_top, "error");
195+
+ cJSON *error = iperf_cJSON_GetObjectItemType(test->json_top, "error", cJSON_String);
196+
if (error) {
197+
JSONStream_Output(test, "error", error);
198+
}
199+
diff --git a/src/iperf_error.c b/src/iperf_error.c
200+
index 0fedf31..3cb9b45 100644
201+
--- a/src/iperf_error.c
202+
+++ b/src/iperf_error.c
203+
@@ -60,11 +60,11 @@ iperf_err(struct iperf_test *test, const char *format, ...)
204+
if (test != NULL && test->json_output && test->json_top != NULL)
205+
cJSON_AddStringToObject(test->json_top, "error", str);
206+
else {
207+
- if (pthread_mutex_lock(&(test->print_mutex)) != 0) {
208+
+ if (test != NULL && pthread_mutex_lock(&(test->print_mutex)) != 0) {
209+
perror("iperf_err: pthread_mutex_lock");
210+
}
211+
212+
- if (test && test->outfile && test->outfile != stdout) {
213+
+ if (test != NULL && test->outfile != NULL && test->outfile != stdout) {
214+
if (ct) {
215+
fprintf(test->outfile, "%s", ct);
216+
}
217+
@@ -77,7 +77,7 @@ iperf_err(struct iperf_test *test, const char *format, ...)
218+
fprintf(stderr, "iperf3: %s\n", str);
219+
}
220+
221+
- if (pthread_mutex_unlock(&(test->print_mutex)) != 0) {
222+
+ if (test != NULL && pthread_mutex_unlock(&(test->print_mutex)) != 0) {
223+
perror("iperf_err: pthread_mutex_unlock");
224+
}
225+
226+
diff --git a/src/iperf_util.c b/src/iperf_util.c
227+
index 81e8da1..a8a32e1 100644
228+
--- a/src/iperf_util.c
229+
+++ b/src/iperf_util.c
230+
@@ -430,6 +430,42 @@ iperf_json_printf(const char *format, ...)
231+
return o;
232+
}
233+
234+
+/********************** cJSON GetObjectItem w/ Type Helper ********************/
235+
+cJSON * iperf_cJSON_GetObjectItemType(cJSON * j, char * item_string, int expected_type){
236+
+ cJSON *j_p;
237+
+ if((j_p = cJSON_GetObjectItem(j, item_string)) != NULL)
238+
+ switch(expected_type){
239+
+ case cJSON_True:
240+
+ if(cJSON_IsBool(j_p))
241+
+ return j_p;
242+
+ else
243+
+ iperf_err(NULL, "iperf_cJSON_GetObjectItemType mismatch %s", item_string);
244+
+ break;
245+
+ case cJSON_String:
246+
+ if(cJSON_IsString(j_p))
247+
+ return j_p;
248+
+ else
249+
+ iperf_err(NULL, "iperf_cJSON_GetObjectItemType mismatch %s", item_string);
250+
+ break;
251+
+ case cJSON_Number:
252+
+ if(cJSON_IsNumber(j_p))
253+
+ return j_p;
254+
+ else
255+
+ iperf_err(NULL, "iperf_cJSON_GetObjectItemType mismatch %s", item_string);
256+
+ break;
257+
+ case cJSON_Array:
258+
+ if(cJSON_IsArray(j_p))
259+
+ return j_p;
260+
+ else
261+
+ iperf_err(NULL, "iperf_cJSON_GetObjectItemType mismatch %s", item_string);
262+
+ break;
263+
+ default:
264+
+ iperf_err(NULL, "unsupported type");
265+
+ }
266+
+
267+
+ return NULL;
268+
+}
269+
+
270+
/* Debugging routine to dump out an fd_set. */
271+
void
272+
iperf_dump_fdset(FILE *fp, const char *str, int nfds, fd_set *fds)
273+
diff --git a/src/iperf_util.h b/src/iperf_util.h
274+
index b109af2..c39a1f7 100644
275+
--- a/src/iperf_util.h
276+
+++ b/src/iperf_util.h
277+
@@ -53,6 +53,7 @@ const char* get_system_info(void);
278+
const char* get_optional_features(void);
279+
280+
cJSON* iperf_json_printf(const char *format, ...);
281+
+cJSON * iperf_cJSON_GetObjectItemType(cJSON * j_p, char * item_string, int expected_type);
282+
283+
void iperf_dump_fdset(FILE *fp, const char *str, int nfds, fd_set *fds);
284+
285+
--
286+
2.45.2
287+

SPECS/iperf3/iperf3.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
Summary: A network performance benchmark tool.
22
Name: iperf3
33
Version: 3.17.1
4-
Release: 1%{?dist}
4+
Release: 2%{?dist}
55
License: BSD and MIT and Public Domain
66
Vendor: Microsoft Corporation
77
Distribution: Azure Linux
88
Group: Applications/System
99
URL: https://github.com/esnet/iperf
1010
Source0: https://github.com/esnet/iperf/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz
1111
Patch1: disablepg.patch
12+
Patch2: CVE-2024-53580.patch
1213
BuildRequires: autoconf >= 2.71
1314
BuildRequires: automake
1415

@@ -66,6 +67,9 @@ make %{?_smp_mflags} check
6667
%{_mandir}/man3/libiperf.3.gz
6768

6869
%changelog
70+
* Tue Dec 31 2024 Kanishk Bansal <kanbansal@microsoft.com> - 3.17.1-2
71+
- Address CVE-2024-53580 using an upstream patch.
72+
6973
* Fri Aug 09 2024 Muhammad Falak <mwani@microsoft.com> - 3.17.1-1
7074
- Update version to 3.17.1 to address CVE-2024-26306
7175

0 commit comments

Comments
 (0)