Skip to content

Commit

Permalink
tests: add a common function to parse and create iio_contexts
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
rgetz committed May 11, 2020
1 parent fcc725d commit 0f7d46a
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 345 deletions.
57 changes: 19 additions & 38 deletions tests/iio_adi_xflow_check.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,13 @@ struct xflow_pthread_data {
};

static const struct option options[] = {
{"help", no_argument, 0, 'h'},
{"network", required_argument, 0, 'n'},
{"uri", required_argument, 0, 'u'},
{"buffer-size", required_argument, 0, 's'},
{"auto", no_argument, 0, 'a'},
{0, 0, 0, 0},
};

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

int main(int argc, char **argv)
{
char **argw;
unsigned int buffer_size = 1024 * 1024;
int c, option_index = 0;
const char *arg_uri = NULL;
const char *arg_ip = NULL;
unsigned int n_tx = 0, n_rx = 0;
static struct iio_context *ctx;
static struct xflow_pthread_data xflow_pthread_data;
bool scan_for_context = false;
unsigned int i, nb_channels;
struct iio_buffer *buffer;
pthread_t monitor_thread;
Expand All @@ -174,12 +166,22 @@ int main(int argc, char **argv)
char unit;
int ret;

while ((c = getopt_long(argc, argv, "+hn:u:s:a",
argw = dup_argv(argc, argv);

ctx = handle_common_opts(MY_NAME, argc, argw, options, options_descriptions);

while ((c = getopt_long(argc, argw, "+" COMMON_OPTIONS "s:a", /* Flawfinder: ignore */
options, &option_index)) != -1) {
switch (c) {
/* All these are handled in the common */
case 'h':
usage(MY_NAME, options, options_descriptions);
return EXIT_SUCCESS;
case 'n':
case 'x':
case 'S':
case 'u':
case 'a':
break;

case 's':
ret = sscanf(optarg, "%u%c", &buffer_size, &unit);
if (ret == 0)
Expand All @@ -191,15 +193,6 @@ int main(int argc, char **argv)
buffer_size *= 1024 * 1024;
}
break;
case 'n':
arg_ip = optarg;
break;
case 'u':
arg_uri = optarg;
break;
case 'a':
scan_for_context = true;
break;
case '?':
return EXIT_FAILURE;
}
Expand All @@ -211,29 +204,17 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}

if (!ctx)
return EXIT_FAILURE;

#ifndef _WIN32
set_handler(SIGHUP, &quit_all);
#endif
set_handler(SIGINT, &quit_all);
set_handler(SIGSEGV, &quit_all);
set_handler(SIGTERM, &quit_all);


if (scan_for_context)
ctx = autodetect_context(true, NULL, MY_NAME);
else if (arg_uri)
ctx = iio_create_context_from_uri(arg_uri);
else if (arg_ip)
ctx = iio_create_network_context(arg_ip);
else
ctx = iio_create_default_context();

if (!ctx) {
fprintf(stderr, "Unable to create IIO context\n");
return EXIT_FAILURE;
}

device_name = argv[optind];
device_name = argw[optind];

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

iio_buffer_destroy(buffer);
iio_context_destroy(ctx);

free_argw(argc, argw);
return 0;
}
107 changes: 41 additions & 66 deletions tests/iio_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,14 +297,9 @@ static void dump_channel_attributes(const struct iio_device *dev,
}

static const struct option options[] = {
/* help */
{"help", no_argument, 0, 'h'},
{"ignore-case", no_argument, 0, 'I'},
{"quiet", no_argument, 0, 'q'},
{"generate-code", required_argument, 0, 'g'},
/* context connection */
{"auto", no_argument, 0, 'a'},
{"uri", required_argument, 0, 'u'},
/* Channel qualifiers */
{"input-channel", no_argument, 0, 'i'},
{"output-channel", no_argument, 0, 'o'},
Expand All @@ -325,13 +320,9 @@ static const char *options_descriptions[] = {
"\t\t\t\t-D [device] [attr] [value]\n"
"\t\t\t\t-C [attr]",
/* help */
"Show this help and quit.",
"Ignore case distinctions.",
"Return result only.",
"Generate code.",
/* context connection */
"Use the first context found.",
"Use the context at the provided URI.",
/* Channel qualifiers */
"Filter Input Channels only.",
"Filter Output Channels only.",
Expand All @@ -346,32 +337,32 @@ static const char *options_descriptions[] = {

int main(int argc, char **argv)
{
char **argw;
struct iio_context *ctx;
int c, option_index = 0;
int device_index = 0, channel_index = 0, attr_index = 0;
const char *arg_uri = NULL, *gen_file = NULL;
enum backend backend = IIO_LOCAL;
bool detect_context = false, search_device = false, ignore_case = false,
const char *gen_file = NULL;
bool search_device = false, ignore_case = false,
search_channel = false, search_buffer = false, search_debug = false,
search_context = false, input_only = false, output_only = false,
scan_only = false, quiet = false, gen_code = false;
unsigned int i;
char *wbuf = NULL;

while ((c = getopt_long(argc, argv, "+hau:g:CdcBDiosIq",
argw = dup_argv(argc, argv);

ctx = handle_common_opts(MY_NAME, argc, argw, options, options_descriptions);

while ((c = getopt_long(argc, argw, "+" COMMON_OPTIONS "g:CdcBDiosIq", /* Flawfinder: ignore */
options, &option_index)) != -1) {
switch (c) {
/* help */
/* All these are handled in the common */
case 'h':
usage(MY_NAME, options, options_descriptions);
return EXIT_SUCCESS;
/* context connection */
case 'a':
detect_context = true;
break;
case 'n':
case 'x':
case 'S':
case 'u':
backend = IIO_AUTO;
arg_uri = optarg;
case 'a':
break;
/* Attribute type
* 'd'evice, 'c'hannel, 'C'ontext, 'B'uffer or 'D'ebug
Expand Down Expand Up @@ -418,6 +409,10 @@ int main(int argc, char **argv)
}
}


if (!ctx)
return EXIT_FAILURE;

if (gen_code) {
if (!gen_test_path(gen_file)) {
fprintf(stderr, "Can't write to %s to generate file\n", gen_file);
Expand Down Expand Up @@ -460,7 +455,7 @@ int main(int argc, char **argv)
if (argc >= optind + 2)
attr_index = optind + 1;
if (argc >= optind + 3)
wbuf = argv[optind + 2];
wbuf = argw[optind + 2];
if (argc >= optind + 4) {
fprintf(stderr, "Too many options for searching for device attributes\n");
return EXIT_FAILURE;
Expand All @@ -479,7 +474,7 @@ int main(int argc, char **argv)
if (argc >= optind + 3)
attr_index = optind + 2;
if (argc >= optind + 4)
wbuf = argv[optind + 3];
wbuf = argw[optind + 3];
if (argc >= optind + 5) {
fprintf(stderr, "Too many options for searching for channel attributes\n");
return EXIT_FAILURE;
Expand All @@ -496,7 +491,7 @@ int main(int argc, char **argv)
if (argc >= optind + 2)
attr_index = optind + 1;
if (argc >= optind + 3)
wbuf = argv[optind + 2];
wbuf = argw[optind + 2];
if (argc >= optind + 4) {
fprintf(stderr, "Too many options for searching for buffer attributes\n");
return EXIT_FAILURE;
Expand All @@ -514,7 +509,7 @@ int main(int argc, char **argv)
if (argc >= optind + 2)
attr_index = optind + 1;
if (argc >= optind + 3)
wbuf = argv[optind + 2];
wbuf = argw[optind + 2];
if (argc >= optind + 4) {
fprintf(stderr, "Too many options for searching for device attributes\n");
return EXIT_FAILURE;
Expand All @@ -529,18 +524,18 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}

if (device_index && !argv[device_index])
if (device_index && !argw[device_index])
return EXIT_FAILURE;
if (channel_index && !argv[channel_index])
if (channel_index && !argw[channel_index])
return EXIT_FAILURE;
if (attr_index && !argv[attr_index])
if (attr_index && !argw[attr_index])
return EXIT_FAILURE;
if ((gen_code || wbuf) && ((device_index && (!strcmp(".", argv[device_index]) ||
strchr(argv[device_index], '*'))) ||
(channel_index && (!strcmp(".", argv[channel_index]) ||
strchr(argv[channel_index], '*'))) ||
(attr_index && (!strcmp(".", argv[attr_index]) ||
strchr(argv[attr_index], '*'))))) {
if ((gen_code || wbuf) && ((device_index && (!strcmp(".", argw[device_index]) ||
strchr(argw[device_index], '*'))) ||
(channel_index && (!strcmp(".", argw[channel_index]) ||
strchr(argw[channel_index], '*'))) ||
(attr_index && (!strcmp(".", argw[attr_index]) ||
strchr(argw[attr_index], '*'))))) {
printf("can't %s with wildcard match\n",
gen_code ? "generate code" : "write value");
return EXIT_FAILURE;
Expand All @@ -550,27 +545,6 @@ int main(int argc, char **argv)
gen_start(gen_file);
}

if (detect_context)
ctx = autodetect_context(true, gen_code, MY_NAME);
else if (backend == IIO_AUTO) {
ctx = iio_create_context_from_uri(arg_uri);
gen_context(arg_uri);
} else
ctx = iio_create_default_context();

if (!ctx) {
if (!detect_context) {
char *buf = xmalloc(BUF_SIZE, MY_NAME);

iio_strerror(errno, buf, BUF_SIZE);
fprintf(stderr, "Unable to create IIO context: %s\n",
buf);
free(buf);
}
gen_context_destroy();
return EXIT_FAILURE;
}

if (search_context) {
unsigned int nb_ctx_attrs = iio_context_get_attrs_count(ctx);
if (!attr_index && nb_ctx_attrs > 0)
Expand All @@ -582,7 +556,7 @@ int main(int argc, char **argv)

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

if (device_index && !str_match(dev_id, argv[device_index], ignore_case)
&& !str_match(name, argv[device_index], ignore_case)) {
if (device_index && !str_match(dev_id, argw[device_index], ignore_case)
&& !str_match(name, argw[device_index], ignore_case)) {
continue;
}

Expand Down Expand Up @@ -651,8 +625,8 @@ int main(int argc, char **argv)
ch_name = iio_channel_get_name(ch);
if (channel_index &&
!str_match(iio_channel_get_id(ch),
argv[channel_index], ignore_case) &&
(!ch_name || !str_match(ch_name,argv[channel_index], ignore_case)))
argw[channel_index], ignore_case) &&
(!ch_name || !str_match(ch_name,argw[channel_index], ignore_case)))
continue;

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

if (attr_index &&
!str_match(attr, argv[attr_index],
!str_match(attr, argw[attr_index],
ignore_case))
continue;
gen_dev(dev);
Expand All @@ -732,7 +706,7 @@ int main(int argc, char **argv)
const char *attr = iio_device_get_attr(dev, j);

if (attr_index &&
!str_match(attr, argv[attr_index], ignore_case))
!str_match(attr, argw[attr_index], ignore_case))
continue;

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

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

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

iio_context_destroy(ctx);

if (gen_code)
if (gen_code)
gen_context_destroy();

free_argw(argc, argw);
return EXIT_SUCCESS;
}
Loading

0 comments on commit 0f7d46a

Please sign in to comment.