Discussion:
[ast-developers] $ clang -fsanitize=integer ... # issues in libast regex code...
Roland Mainz
2013-08-11 01:21:39 UTC
Permalink
Hi!

----

I'm currently experimenting with clang's "integer sanitiser" option
("-fsanitize=integer" , see
http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation)
with ast-ksh.2013-08-07 on a SuSE 12.3/AMD64/64bit build created
with...
-- snip --
$ (export CC='/usr/bin/clang -std=gnu1x -fsanitize=integer -g
-fno-omit-frame-pointer -fno-optimize-sibling-calls -Wno-parentheses
-Wno-logical-op-parentheses' LD="$CC" CCFLAGS="-g"; ksh ./bin/package
make PACKAGE_OPTIONS='map-libc' CC="$CC" CCFLAGS="$CCFLAGS" 2>&1 | tee
-a buildlog.log)
-- snip --

... during testing I found the following integer overflow issues which
_may_ be portability issues:
-- snip --
$ ksh -c 'x="a1a" ; [[ $x == ~(E)([[:alpha:]]|[[:digit:]])+ ]]'
src/lib/libast/aso/asothreadid.c:48:14: runtime error: unsigned
integer overflow: 530404196 * 17109811 cannot be represented in type
'unsigned int'
src/lib/libast/cdt/dtstrhash.c:43:20: runtime error: unsigned integer
overflow: 2166136238 * 16777619 cannot be represented in type
'unsigned int'
src/lib/libast/regex/regnexec.c:258:80: runtime error: unsigned
integer overflow: 18446744073709551615 * 16 cannot be represented in
type 'unsigned long'
src/lib/libast/regex/regnexec.c:258:68: runtime error: unsigned
integer overflow: 32 + 18446744073709551600 cannot be represented in
type 'unsigned long'
-- snip --
(the hits in src/lib/libast/aso/asothreadid.c and
src/lib/libast/cdt/dtstrhash.c happen at shell startup ; |unsigned
long| is an |uint64_t| for 64bit builds)

Erm... Glenn and Michal... what do you think ?

----

Bye,
Roland

P.S.: There are many more of these issus but first I'd like to figure
out if they are a problem... or not...
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Glenn Fowler
2013-08-12 15:44:45 UTC
Permalink
Post by Roland Mainz
I'm currently experimenting with clang's "integer sanitiser" option
("-fsanitize=integer" , see
http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation)
with ast-ksh.2013-08-07 on a SuSE 12.3/AMD64/64bit build created
with...
-- snip --
$ (export CC='/usr/bin/clang -std=gnu1x -fsanitize=integer -g
-fno-omit-frame-pointer -fno-optimize-sibling-calls -Wno-parentheses
-Wno-logical-op-parentheses' LD="$CC" CCFLAGS="-g"; ksh ./bin/package
make PACKAGE_OPTIONS='map-libc' CC="$CC" CCFLAGS="$CCFLAGS" 2>&1 | tee
-a buildlog.log)
-- snip --
... during testing I found the following integer overflow issues which
-- snip --
$ ksh -c 'x="a1a" ; [[ $x == ~(E)([[:alpha:]]|[[:digit:]])+ ]]'
src/lib/libast/aso/asothreadid.c:48:14: runtime error: unsigned
integer overflow: 530404196 * 17109811 cannot be represented in type
'unsigned int'
src/lib/libast/cdt/dtstrhash.c:43:20: runtime error: unsigned integer
overflow: 2166136238 * 16777619 cannot be represented in type
'unsigned int'
src/lib/libast/regex/regnexec.c:258:80: runtime error: unsigned
integer overflow: 18446744073709551615 * 16 cannot be represented in
type 'unsigned long'
src/lib/libast/regex/regnexec.c:258:68: runtime error: unsigned
integer overflow: 32 + 18446744073709551600 cannot be represented in
type 'unsigned long'
-- snip --
(the hits in src/lib/libast/aso/asothreadid.c and
src/lib/libast/cdt/dtstrhash.c happen at shell startup ; |unsigned
long| is an |uint64_t| for 64bit builds)
Erm... Glenn and Michal... what do you think ?
without looking at the code the first 2 are PRNG related
which explicitly expect and allow for integer overflow and
mask off the required bits

the last 2 are allocation related
stkpush(env->mst, sizeof(Match_frame_t) + (num - 1) * sizeof(regmatch_t)))
and involve C?? unsigned escalation rules
looks like (num - 1) escalates to unsigned
in this case num==0 which makes it a large unsigned int
does anyone know how to cast this to the equivalent
int a = sizeof(Match_frame_t);
int b = sizeof(regmatch_t);
a + (num - 1) * b;
is it
sizeof(Match_frame_t) + (num - 1) * (int)sizeof(regmatch_t)
or
(int)sizeof(Match_frame_t) + (num - 1) * (int)sizeof(regmatch_t)
or something worse

Loading...