Skip to content

Commit 7654992

Browse files
committed
tests: add a common function to parse and create iio_contexts
Some (older) implementations of getopt_long) do not protect against internal buffer overflows, so copy argv to a temp str array, and parse most in a common function. (-u -h -x -n, and -S). -h, --help Show this help and quit. -x, --xml Use the XML backend with the provided XML file. -u, --uri Use the context at the provided URI. -S, --scan Scan for available backends. -a, --auto Scan for available contexts and if only one is available use it. The "default" for scan is "S", since "s" is used for many apps as sample size. This means that iio_info now takes -s and -S as scan. This also fixes both CWE-120 and CWE-20 https://cwe.mitre.org/data/definitions/120.html https://cwe.mitre.org/data/definitions/20.html and almost is a net decrease (348 insertions, 345 deletions over 9 files). Signed-off-by: Robin Getz <[email protected]>
1 parent fcc725d commit 7654992

File tree

9 files changed

+350
-345
lines changed

9 files changed

+350
-345
lines changed

tests/iio_adi_xflow_check.c

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,13 @@ struct xflow_pthread_data {
3939
};
4040

4141
static const struct option options[] = {
42-
{"help", no_argument, 0, 'h'},
43-
{"network", required_argument, 0, 'n'},
44-
{"uri", required_argument, 0, 'u'},
4542
{"buffer-size", required_argument, 0, 's'},
4643
{"auto", no_argument, 0, 'a'},
4744
{0, 0, 0, 0},
4845
};
4946

5047
static const char *options_descriptions[] = {
5148
"[-n <hostname>] [-u <uri>] [-a ] [-s <size>] <iio_device>",
52-
"Show this help and quit.",
53-
"Use the network backend with the provided hostname.",
54-
"Use the context with the provided URI.",
5549
"Size of the buffer in sample sets. Default is 1Msample",
5650
"Scan for available contexts and if only one is available use it.",
5751
};
@@ -158,14 +152,12 @@ static void *monitor_thread_fn(void *data)
158152

159153
int main(int argc, char **argv)
160154
{
155+
char **argw;
161156
unsigned int buffer_size = 1024 * 1024;
162157
int c, option_index = 0;
163-
const char *arg_uri = NULL;
164-
const char *arg_ip = NULL;
165158
unsigned int n_tx = 0, n_rx = 0;
166159
static struct iio_context *ctx;
167160
static struct xflow_pthread_data xflow_pthread_data;
168-
bool scan_for_context = false;
169161
unsigned int i, nb_channels;
170162
struct iio_buffer *buffer;
171163
pthread_t monitor_thread;
@@ -174,12 +166,22 @@ int main(int argc, char **argv)
174166
char unit;
175167
int ret;
176168

177-
while ((c = getopt_long(argc, argv, "+hn:u:s:a",
169+
argw = dup_argv(argc, argv);
170+
171+
ctx = handle_common_opts(MY_NAME, argc, argw, options, options_descriptions);
172+
173+
while ((c = getopt_long(argc, argw, "+" COMMON_OPTIONS "s:a", /* Flawfinder: ignore */
178174
options, &option_index)) != -1) {
179175
switch (c) {
176+
/* All these are handled in the common */
180177
case 'h':
181-
usage(MY_NAME, options, options_descriptions);
182-
return EXIT_SUCCESS;
178+
case 'n':
179+
case 'x':
180+
case 'S':
181+
case 'u':
182+
case 'a':
183+
break;
184+
183185
case 's':
184186
ret = sscanf(optarg, "%u%c", &buffer_size, &unit);
185187
if (ret == 0)
@@ -191,15 +193,6 @@ int main(int argc, char **argv)
191193
buffer_size *= 1024 * 1024;
192194
}
193195
break;
194-
case 'n':
195-
arg_ip = optarg;
196-
break;
197-
case 'u':
198-
arg_uri = optarg;
199-
break;
200-
case 'a':
201-
scan_for_context = true;
202-
break;
203196
case '?':
204197
return EXIT_FAILURE;
205198
}
@@ -211,29 +204,17 @@ int main(int argc, char **argv)
211204
return EXIT_FAILURE;
212205
}
213206

207+
if (!ctx)
208+
return EXIT_FAILURE;
209+
214210
#ifndef _WIN32
215211
set_handler(SIGHUP, &quit_all);
216212
#endif
217213
set_handler(SIGINT, &quit_all);
218214
set_handler(SIGSEGV, &quit_all);
219215
set_handler(SIGTERM, &quit_all);
220216

221-
222-
if (scan_for_context)
223-
ctx = autodetect_context(true, NULL, MY_NAME);
224-
else if (arg_uri)
225-
ctx = iio_create_context_from_uri(arg_uri);
226-
else if (arg_ip)
227-
ctx = iio_create_network_context(arg_ip);
228-
else
229-
ctx = iio_create_default_context();
230-
231-
if (!ctx) {
232-
fprintf(stderr, "Unable to create IIO context\n");
233-
return EXIT_FAILURE;
234-
}
235-
236-
device_name = argv[optind];
217+
device_name = argw[optind];
237218

238219
dev = get_device(ctx, device_name);
239220
if (!dev) {
@@ -302,6 +283,6 @@ int main(int argc, char **argv)
302283

303284
iio_buffer_destroy(buffer);
304285
iio_context_destroy(ctx);
305-
286+
free_argw(argc, argw);
306287
return 0;
307288
}

tests/iio_attr.c

Lines changed: 41 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,9 @@ static void dump_channel_attributes(const struct iio_device *dev,
297297
}
298298

299299
static const struct option options[] = {
300-
/* help */
301-
{"help", no_argument, 0, 'h'},
302300
{"ignore-case", no_argument, 0, 'I'},
303301
{"quiet", no_argument, 0, 'q'},
304302
{"generate-code", required_argument, 0, 'g'},
305-
/* context connection */
306-
{"auto", no_argument, 0, 'a'},
307-
{"uri", required_argument, 0, 'u'},
308303
/* Channel qualifiers */
309304
{"input-channel", no_argument, 0, 'i'},
310305
{"output-channel", no_argument, 0, 'o'},
@@ -325,13 +320,9 @@ static const char *options_descriptions[] = {
325320
"\t\t\t\t-D [device] [attr] [value]\n"
326321
"\t\t\t\t-C [attr]",
327322
/* help */
328-
"Show this help and quit.",
329323
"Ignore case distinctions.",
330324
"Return result only.",
331325
"Generate code.",
332-
/* context connection */
333-
"Use the first context found.",
334-
"Use the context at the provided URI.",
335326
/* Channel qualifiers */
336327
"Filter Input Channels only.",
337328
"Filter Output Channels only.",
@@ -346,32 +337,32 @@ static const char *options_descriptions[] = {
346337

347338
int main(int argc, char **argv)
348339
{
340+
char **argw;
349341
struct iio_context *ctx;
350342
int c, option_index = 0;
351343
int device_index = 0, channel_index = 0, attr_index = 0;
352-
const char *arg_uri = NULL, *gen_file = NULL;
353-
enum backend backend = IIO_LOCAL;
354-
bool detect_context = false, search_device = false, ignore_case = false,
344+
const char *gen_file = NULL;
345+
bool search_device = false, ignore_case = false,
355346
search_channel = false, search_buffer = false, search_debug = false,
356347
search_context = false, input_only = false, output_only = false,
357348
scan_only = false, quiet = false, gen_code = false;
358349
unsigned int i;
359350
char *wbuf = NULL;
360351

361-
while ((c = getopt_long(argc, argv, "+hau:g:CdcBDiosIq",
352+
argw = dup_argv(argc, argv);
353+
354+
ctx = handle_common_opts(MY_NAME, argc, argw, options, options_descriptions);
355+
356+
while ((c = getopt_long(argc, argw, "+" COMMON_OPTIONS "g:CdcBDiosIq", /* Flawfinder: ignore */
362357
options, &option_index)) != -1) {
363358
switch (c) {
364-
/* help */
359+
/* All these are handled in the common */
365360
case 'h':
366-
usage(MY_NAME, options, options_descriptions);
367-
return EXIT_SUCCESS;
368-
/* context connection */
369-
case 'a':
370-
detect_context = true;
371-
break;
361+
case 'n':
362+
case 'x':
363+
case 'S':
372364
case 'u':
373-
backend = IIO_AUTO;
374-
arg_uri = optarg;
365+
case 'a':
375366
break;
376367
/* Attribute type
377368
* 'd'evice, 'c'hannel, 'C'ontext, 'B'uffer or 'D'ebug
@@ -418,6 +409,10 @@ int main(int argc, char **argv)
418409
}
419410
}
420411

412+
413+
if (!ctx)
414+
return EXIT_FAILURE;
415+
421416
if (gen_code) {
422417
if (!gen_test_path(gen_file)) {
423418
fprintf(stderr, "Can't write to %s to generate file\n", gen_file);
@@ -460,7 +455,7 @@ int main(int argc, char **argv)
460455
if (argc >= optind + 2)
461456
attr_index = optind + 1;
462457
if (argc >= optind + 3)
463-
wbuf = argv[optind + 2];
458+
wbuf = argw[optind + 2];
464459
if (argc >= optind + 4) {
465460
fprintf(stderr, "Too many options for searching for device attributes\n");
466461
return EXIT_FAILURE;
@@ -479,7 +474,7 @@ int main(int argc, char **argv)
479474
if (argc >= optind + 3)
480475
attr_index = optind + 2;
481476
if (argc >= optind + 4)
482-
wbuf = argv[optind + 3];
477+
wbuf = argw[optind + 3];
483478
if (argc >= optind + 5) {
484479
fprintf(stderr, "Too many options for searching for channel attributes\n");
485480
return EXIT_FAILURE;
@@ -496,7 +491,7 @@ int main(int argc, char **argv)
496491
if (argc >= optind + 2)
497492
attr_index = optind + 1;
498493
if (argc >= optind + 3)
499-
wbuf = argv[optind + 2];
494+
wbuf = argw[optind + 2];
500495
if (argc >= optind + 4) {
501496
fprintf(stderr, "Too many options for searching for buffer attributes\n");
502497
return EXIT_FAILURE;
@@ -514,7 +509,7 @@ int main(int argc, char **argv)
514509
if (argc >= optind + 2)
515510
attr_index = optind + 1;
516511
if (argc >= optind + 3)
517-
wbuf = argv[optind + 2];
512+
wbuf = argw[optind + 2];
518513
if (argc >= optind + 4) {
519514
fprintf(stderr, "Too many options for searching for device attributes\n");
520515
return EXIT_FAILURE;
@@ -529,18 +524,18 @@ int main(int argc, char **argv)
529524
return EXIT_FAILURE;
530525
}
531526

532-
if (device_index && !argv[device_index])
527+
if (device_index && !argw[device_index])
533528
return EXIT_FAILURE;
534-
if (channel_index && !argv[channel_index])
529+
if (channel_index && !argw[channel_index])
535530
return EXIT_FAILURE;
536-
if (attr_index && !argv[attr_index])
531+
if (attr_index && !argw[attr_index])
537532
return EXIT_FAILURE;
538-
if ((gen_code || wbuf) && ((device_index && (!strcmp(".", argv[device_index]) ||
539-
strchr(argv[device_index], '*'))) ||
540-
(channel_index && (!strcmp(".", argv[channel_index]) ||
541-
strchr(argv[channel_index], '*'))) ||
542-
(attr_index && (!strcmp(".", argv[attr_index]) ||
543-
strchr(argv[attr_index], '*'))))) {
533+
if ((gen_code || wbuf) && ((device_index && (!strcmp(".", argw[device_index]) ||
534+
strchr(argw[device_index], '*'))) ||
535+
(channel_index && (!strcmp(".", argw[channel_index]) ||
536+
strchr(argw[channel_index], '*'))) ||
537+
(attr_index && (!strcmp(".", argw[attr_index]) ||
538+
strchr(argw[attr_index], '*'))))) {
544539
printf("can't %s with wildcard match\n",
545540
gen_code ? "generate code" : "write value");
546541
return EXIT_FAILURE;
@@ -550,27 +545,6 @@ int main(int argc, char **argv)
550545
gen_start(gen_file);
551546
}
552547

553-
if (detect_context)
554-
ctx = autodetect_context(true, gen_code, MY_NAME);
555-
else if (backend == IIO_AUTO) {
556-
ctx = iio_create_context_from_uri(arg_uri);
557-
gen_context(arg_uri);
558-
} else
559-
ctx = iio_create_default_context();
560-
561-
if (!ctx) {
562-
if (!detect_context) {
563-
char *buf = xmalloc(BUF_SIZE, MY_NAME);
564-
565-
iio_strerror(errno, buf, BUF_SIZE);
566-
fprintf(stderr, "Unable to create IIO context: %s\n",
567-
buf);
568-
free(buf);
569-
}
570-
gen_context_destroy();
571-
return EXIT_FAILURE;
572-
}
573-
574548
if (search_context) {
575549
unsigned int nb_ctx_attrs = iio_context_get_attrs_count(ctx);
576550
if (!attr_index && nb_ctx_attrs > 0)
@@ -582,7 +556,7 @@ int main(int argc, char **argv)
582556

583557
ret = iio_context_get_attr(ctx, i, &key, &value);
584558
if (!ret) {
585-
if (!attr_index || str_match(key, argv[attr_index], ignore_case)) {
559+
if (!attr_index || str_match(key, argw[attr_index], ignore_case)) {
586560
printf("%s: %s\n", key, value);
587561
gen_context_attr(key);
588562
}
@@ -609,8 +583,8 @@ int main(int argc, char **argv)
609583
const char *dev_id = iio_device_get_id(dev);
610584
unsigned int nb_attrs, nb_channels, j;
611585

612-
if (device_index && !str_match(dev_id, argv[device_index], ignore_case)
613-
&& !str_match(name, argv[device_index], ignore_case)) {
586+
if (device_index && !str_match(dev_id, argw[device_index], ignore_case)
587+
&& !str_match(name, argw[device_index], ignore_case)) {
614588
continue;
615589
}
616590

@@ -651,8 +625,8 @@ int main(int argc, char **argv)
651625
ch_name = iio_channel_get_name(ch);
652626
if (channel_index &&
653627
!str_match(iio_channel_get_id(ch),
654-
argv[channel_index], ignore_case) &&
655-
(!ch_name || !str_match(ch_name,argv[channel_index], ignore_case)))
628+
argw[channel_index], ignore_case) &&
629+
(!ch_name || !str_match(ch_name,argw[channel_index], ignore_case)))
656630
continue;
657631

658632
if ((!scan_only && !channel_index) ||
@@ -712,7 +686,7 @@ int main(int argc, char **argv)
712686
iio_channel_get_attr(ch, k);
713687

714688
if (attr_index &&
715-
!str_match(attr, argv[attr_index],
689+
!str_match(attr, argw[attr_index],
716690
ignore_case))
717691
continue;
718692
gen_dev(dev);
@@ -732,7 +706,7 @@ int main(int argc, char **argv)
732706
const char *attr = iio_device_get_attr(dev, j);
733707

734708
if (attr_index &&
735-
!str_match(attr, argv[attr_index], ignore_case))
709+
!str_match(attr, argw[attr_index], ignore_case))
736710
continue;
737711

738712
gen_dev(dev);
@@ -752,7 +726,7 @@ int main(int argc, char **argv)
752726
for (j = 0; j < nb_attrs; j++) {
753727
const char *attr = iio_device_get_buffer_attr(dev, j);
754728

755-
if ((attr_index && str_match(attr, argv[attr_index],
729+
if ((attr_index && str_match(attr, argw[attr_index],
756730
ignore_case)) || !attr_index) {
757731
gen_dev(dev);
758732
dump_buffer_attributes(dev, attr, wbuf,
@@ -773,7 +747,7 @@ int main(int argc, char **argv)
773747
for (j = 0; j < nb_attrs; j++) {
774748
const char *attr = iio_device_get_debug_attr(dev, j);
775749

776-
if ((attr_index && str_match(attr, argv[attr_index],
750+
if ((attr_index && str_match(attr, argw[attr_index],
777751
ignore_case)) || !attr_index) {
778752
gen_dev(dev);
779753
dump_debug_attributes(dev, attr, wbuf,
@@ -788,8 +762,9 @@ int main(int argc, char **argv)
788762

789763
iio_context_destroy(ctx);
790764

791-
if (gen_code)
765+
if (gen_code)
792766
gen_context_destroy();
793767

768+
free_argw(argc, argw);
794769
return EXIT_SUCCESS;
795770
}

0 commit comments

Comments
 (0)