Skip to content

Commit 50ab7a3

Browse files
committed
Do not modify --bind and --client arguments inplace
Do as iperf_parse_hostname()'s comment says already: pass a copy of getopt(3)'s `optarg` aka. to avoid strtok(3) scribbling over `argv[]`. Otherwise arguments like "fe80::1%vport0" appear as "fe80::1" in the process list and cause exact matching of process name and arguments (against what was used) to fail. OpenBSD's net/iperf3 package ships a rc.subr(8) script and the service framework uses pgrep(1) to check for running processes, where this bug causes a mismatch due to the scope identifier being stripped: ``` $ rcctl get iperf3 flags -6 --bind fe80::1%vport0 $ rcctl check iperf3 iperf3(failed) $ pgrep -fl iperf3 33091 /usr/local/bin/iperf3 -s -D -6 -B fe80::1 ``` Pass a copy to avoid modification, thus fixing rcctl(8) reporting: ``` $ rcctl check iperf3 iperf3(ok) $ pgrep -fl iperf3 98863 /usr/local/bin/iperf3 -s -D -6 -B fe80::1%vport0 ```
1 parent 4b370dd commit 50ab7a3

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

src/iperf_api.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,26 +1289,30 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
12891289
}
12901290
iperf_set_test_role(test, 's');
12911291
break;
1292-
case 'c':
1292+
case 'c': {
12931293
if (test->role == 's') {
12941294
i_errno = IESERVCLIENT;
12951295
return -1;
12961296
}
12971297
iperf_set_test_role(test, 'c');
12981298
iperf_set_test_server_hostname(test, optarg);
12991299

1300-
if (iperf_parse_hostname(test, optarg, &p, &p1)) {
1300+
char *arg = strdup(optarg);
1301+
if (iperf_parse_hostname(test, arg, &p, &p1)) {
13011302
#if defined(HAVE_SO_BINDTODEVICE)
13021303
/* Get rid of the hostname we saved earlier. */
13031304
free(iperf_get_test_server_hostname(test));
13041305
iperf_set_test_server_hostname(test, p);
13051306
iperf_set_test_bind_dev(test, p1);
13061307
#else /* HAVE_SO_BINDTODEVICE */
1308+
free(arg);
13071309
i_errno = IEBINDDEVNOSUPPORT;
13081310
return -1;
13091311
#endif /* HAVE_SO_BINDTODEVICE */
13101312
}
1313+
free(arg);
13111314
break;
1315+
}
13121316
case 'u':
13131317
set_protocol(test, Pudp);
13141318
client_flag = 1;
@@ -1441,21 +1445,25 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
14411445
client_flag = 1;
14421446
break;
14431447

1444-
case 'B':
1448+
case 'B': {
14451449
iperf_set_test_bind_address(test, optarg);
14461450

1447-
if (iperf_parse_hostname(test, optarg, &p, &p1)) {
1451+
char *arg = strdup(optarg);
1452+
if (iperf_parse_hostname(test, arg, &p, &p1)) {
14481453
#if defined(HAVE_SO_BINDTODEVICE)
14491454
/* Get rid of the hostname we saved earlier. */
14501455
free(iperf_get_test_bind_address(test));
14511456
iperf_set_test_bind_address(test, p);
14521457
iperf_set_test_bind_dev(test, p1);
14531458
#else /* HAVE_SO_BINDTODEVICE */
1459+
free(arg);
14541460
i_errno = IEBINDDEVNOSUPPORT;
14551461
return -1;
14561462
#endif /* HAVE_SO_BINDTODEVICE */
14571463
}
1464+
free(arg);
14581465
break;
1466+
}
14591467
#if defined (HAVE_SO_BINDTODEVICE)
14601468
case OPT_BIND_DEV:
14611469
iperf_set_test_bind_dev(test, optarg);

0 commit comments

Comments
 (0)