Hello,
There are over 30 uses of strtol in libvirt, and they all can silently
accept invalid input. The invalid string might range from an outlandish
domain ID like 4294967298 to strings of digits followed by bogus alpha.
Maybe not worth worrying about, you say? But what if they indicate user
confusion, e.g., 1,000 vs 1000? Silently interpreting "1,000" as "1"
would leave the poor user even more confused :-) IMHO, they should all
be diagnosed.
Fixing them properly requires some infrastructure,
so that you don't end up duplicating too much logic.
This patch adds part of that infrastructure and fixes only a single
instance, to start with. I'll fix the others once we're all agreed
on the form of the infrastructure. I've fixed the bug that would make
this command:
echo domname $(echo 2^32+2|bc)|src/virsh ...
act just like this one:
echo domname 2|src/virsh ...
Now, it does this:
$ echo domname 4294967298|src/virsh --quiet --connect test://$PWD/docs/testnode.xml
virsh > error: failed to get domain '4294967298'
virsh >
The new test script, tests/int-overflow demonstrates
precisely that before/after behavior.
This change adds some other new files.
src/xstrtol.c and .h contain the first of a few new
strtol-like functions. This first one, xstrtol_i,
converts to an "int". Other wrappers will convert to wider types.
The goal is to put the tedious tests into the wrappers so that
applications can be robust without all the duplicated gore.
It is important (from type-safety and maintainability standpoints) to
ensure that the resulting integral value be "returned" via an argument
pointer, not a return value. With the former, you're guaranteed to have
matching types. Simply getting the value via "return", it is too easy
to mistakenly change width or signedness.
Here's the new function's description and signature:
/* Like strtol, but produce an "int" result, and check more carefully.
Return 0 upon success; return -1 to indicate failure.
When END_PTR is NULL, the byte after the final valid digit must be NUL.
Otherwise, it's like strtol and lets the caller check any suffix for
validity. This function is careful to return -1 when the string S
represents a number that is not representable as an "int". */
int xstrtol_i(char const *s, char **end_ptr, int base, int *result)
My first attempt put the definition of xstrtol_i in
the logical place: util.c. But that would have required linking
virsh with util.c, and that fails due to an unsatisfied reference
to __virRaiseError. So instead, it's in its own file, now.
If you want it in some other file, just tell me where.
BTW, I have no strong preference for the name xstrtol_i. Bear in mind
that the name tells you that it's based on (and limited to) strtol's
"long" type, and produces an 'i'nt value. It happens to be the same
one
used in at least one other project, and closely resembles the xstrto*
functions in gnulib. Note that there are almost certainly places in the
code where we'll want to use a variant that targets an unsigned type like
"size_t" or a wider type like long long. In addition to other uses of
strtol that I plan to fix, there are three uses of strtoll, too.
Patch attached below.
If you apply it with plain-old-patch, remember to run this:
chmod a+x tests/int-overflow
Thu Nov 8 09:59:43 CET 2007 Jim Meyering <meyering(a)redhat.com>
Diagnose an invalid domain ID number.
* src/virsh.c: Include "xstrtol.h"
(vshCommandOptDomainBy): Detect integer overflow in domain ID number.
* tests/int-overflow: New script. Test for the above-fixed bug.
* tests/Makefile.am (TESTS): Add int-overflow.
(TESTS_ENVIRONMENT): Define, to propagate $abs_top_* variables
into the int-overflow script.
(valgrind): Adapt rule not to clobber new TESTS_ENVIRONMENT.
* src/xstrtol.h, src/xstrtol.c: New files.
* src/Makefile.am (virsh_SOURCES): Add xstrtol.c and xstrtol.h.
---
src/Makefile.am | 2 +-
src/virsh.c | 10 ++++------
src/xstrtol.c | 33 +++++++++++++++++++++++++++++++++
src/xstrtol.h | 7 +++++++
tests/Makefile.am | 10 ++++++++--
tests/int-overflow | 22 ++++++++++++++++++++++
6 files changed, 75 insertions(+), 9 deletions(-)
create mode 100644 src/xstrtol.c
create mode 100644 src/xstrtol.h
create mode 100755 tests/int-overflow