In perl.git, the branch smoke-me/davem/asan_undef2 has been created
<http://perl5.git.perl.org/perl.git/commitdiff/8b1f096d396efac0cf624a35f0ccf1d63cd12d50?hp=0000000000000000000000000000000000000000>
at 8b1f096d396efac0cf624a35f0ccf1d63cd12d50 (commit)
- Log -----------------------------------------------------------------
commit 8b1f096d396efac0cf624a35f0ccf1d63cd12d50
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 02:21:17 2014 +0000
update customized.dat with local 'version' change
M t/porting/customized.dat
commit 84efde25032657aeef693f3c7147c40234bea299
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 02:13:24 2014 +0000
'version': vutil.c: silence overflow warnings
Running 'clang -fsanitize=undefined' on the perl test suite triggers
a number of warnings:
vutil.c:354:9: runtime error: signed integer overflow: 750283776 +
1705032704 cannot be represented in type 'int'
vutil.c:354:25: runtime error: signed integer overflow: 6 * 1000000000
cannot be represented in type 'int'
vutil.c:355:10: runtime error: signed integer overflow: 1000000000 * 10
cannot be represented in type 'int'
This is because the version string parsing code takes a "maybe overflow,
then check to see if we've overflown" approach. Which is perfectly fine,
but clashes with clang.
This commit makes it take the opposite approach of checking each time
*before* doing the += mult*i and mult*=10 steps.
A bit clunky, but ASan only allows you to disable these warnings on a
per-function basis, and it's a reasonably large function.
I suspect that the block of code above this may need similar treatment,
but as it wasn't triggering clang warnings, I didn't look at it.
M vutil.c
commit ec537aa5a606015101ac4bf630aeb1c5e42cd088
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 01:17:44 2014 +0000
Digest-SHA: avoid undefined warning
With 'clang -fsanitize=undefined', (~0 << gap) gives this warning:
src/sha.c:372:41: runtime error: left shift of negative value -1
Fix it by doing (~0U << gap) instead.
NB: this commit modifies a file which appears to be part of a separate
distribution, so may have licensing implications.
M cpan/Digest-SHA/src/sha.c
commit 11877a887cd512bff1fb417196f3397f2dd87280
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 01:07:36 2014 +0000
Compress-Raw-Zlib: avoid undefined warning
With 'clang -fsanitize=undefined', when f==-1, ((f)<<1) gives this warning:
deflate.c:886:54: runtime error: left shift of negative value -1
Fix it by doing ((f)*2) instead. Any half-decent compiler should spot the
'*2' and implement it efficiently underneath as a shift or add or
whatever.
NB: this commit modifies a file which is part of a separate distribution,
libbzip2, so may have licensing implications.
M cpan/Compress-Raw-Zlib/zlib-src/deflate.c
commit 25d976d4eac15ab0484f91e5806a9e2f458a9fbe
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 00:48:21 2014 +0000
Compress-Raw-Bzip2: avoid overflow warning
With 'clang -fsanitize=undefined', (1<<31) gives warnings like these:
blocksort.c:256:7: runtime error: left shift of 1 by 31 places cannot be
represented in type 'int'
Fix it by shifting an unsigned value instead: (1U<<31).
NB: this commit modifies a file which is part of a separate distribution,
libbzip2, so may have licensing implications.
M cpan/Compress-Raw-Bzip2/bzip2-src/blocksort.c
commit 32aeb7b668505dc38de38a7d6c7692e27710af85
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 00:29:53 2014 +0000
Socket.xs: avoid integer overflow
As spotted by 'clang -fsanitize=undefined',
the shifting of the bytes to form an IPv4 address results in an
intermediate signed int, which clang detects as overflowing when <<24.
So ensure all the values to be shifted are unsigned.
Typical clang error:
Socket.xs:796:30: runtime error: left shift of 193 by 24 places cannot be
represented in type 'int'
M cpan/Socket/Socket.xs
commit 48ca6fdcd428912155df3b479e8b1371b4b7af59
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 00:07:38 2014 +0000
List::Util: fix some integer overflows
both sum() and product() didn't handle integers near IV_MIN and IV_MAX
very well. Some of this was spotted by "clang -fsanitize=undefined",
the rest by visual code inspection.
Basically when adding or multiplying two signed IV together, and deciding
when to bail out and use NVs instead, there are more permutations to
consider than was being done. This meant that the bail tests sometimes
had undefined behaviour, and in the worst case, product(...,0,...)
actually raised a divide by zero exception in the bail test
M cpan/Scalar-List-Utils/ListUtil.xs
M cpan/Scalar-List-Utils/t/product.t
M cpan/Scalar-List-Utils/t/sum.t
commit 5d41edc130020402004b88f271c17a586f6ab51b
Author: David Mitchell <[email protected]>
Date: Mon Dec 22 21:36:14 2014 +0000
Configure: silence ASan warnings
When run under -fsanitize=undefined, some of the try.c's that are compiled
and executed give runtime warnings. Since the intent of these particular
executables is to probe beyond certain limits in order to determine those
limits, these warnings can be safely ignored. So file them in /dev/null.
M Configure
commit 23965acdfc710bd8c57473c56be34c13db5e658d
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 19:32:43 2014 +0000
clone PL_cv_has_eval and PL_savebegin
These two boolean vars weren't being cloned in new threads, and in
debugging builds were getting set to 0xab, which -fsanitize=undefined
regarded as no suitable value for a boolean.
M sv.c
commit 7c6df99eae50dbde32123810b81bd3bb7e1cd42d
Author: David Mitchell <[email protected]>
Date: Tue Dec 23 10:38:01 2014 +0000
sv_vcatpvfn_flags() avoid array bounds err
clang -fsanitize=undefined is being a bit too clever for its own good
here.
The code looks something like
U8 vhex[VHEX_SIZE];
...
v = vhex + ...;
if (v < vend) ...
The code itself is safe, but ASan detects if you've added a value
greater than the buffer size to vhex and whines.
I've changed it so that the conditional comes first and is done in such
a way that arbitrary values can't be added to vhex.
To reproduce:
printf "%.1000a\n", 1;
gives
sv.c:12327:34: runtime error: index 1000 out of bounds for type 'U8
[17]'
M sv.c
commit da94667278eec2c0e19db8fb4b22e5569f37bf76
Author: David Mitchell <[email protected]>
Date: Mon Dec 22 20:57:52 2014 +0000
asan_ignore: exclude S_expect_number()
This function numifies the field width string in something like
printf "%10f". It handles integer overflow itself, so suppress
ASan warnings, e.g.
sv.c:10716:26: runtime error: signed integer overflow: 922337203 * 10
cannot be represented in type 'int'
M asan_ignore
commit 3afc24755d9c5f119f5fd2e1f7b76a454a7addf0
Author: David Mitchell <[email protected]>
Date: Mon Dec 22 20:23:28 2014 +0000
fix integer overflow in S_study_chunk().
Don't increment delta if it's "infinity" (SSize_t_MAX)
Found by -fsanitize=undefined:
regcomp.c:4999:11: runtime error: signed integer overflow:
9223372036854775807 + 1 cannot be represented in type 'ssize_t' (aka 'long')
M regcomp.c
commit e54a0d5b4abb442c75a01f3866244f775e769222
Author: David Mitchell <[email protected]>
Date: Mon Dec 22 20:12:22 2014 +0000
pack(): avoid << of negative values
Treat the string as U8* rather than char* when doing all the
bit shifts for uuencode. That stops these warnings under ASan:
pp_pack.c:1890:34: runtime error: left shift of negative value -127
pp_pack.c:1891:34: runtime error: left shift of negative value -126
pp_pack.c:1899:34: runtime error: left shift of negative value -1
pp_pack.c:1900:30: runtime error: left shift of negative value -31
M pp_pack.c
commit 0c90670616240df33d0fef5cb77b98408a6a5ae5
Author: David Mitchell <[email protected]>
Date: Mon Dec 22 20:04:59 2014 +0000
avoid integer overflow in pp_flop()
This;
@a=(0x7ffffffffffffffe..0x7fffffffffffffff);
could produce under ASan:
pp_ctl.c:1212:19: runtime error: signed integer overflow:
9223372036854775807 + 1 cannot be represented in type 'IV' (aka 'long')
so avoid post-incrementing the loop var on the last iteration.
This fix is more to shut ASan up than an actual bug, since the
bad value on the last iteration wouldn't actually be used.
M pp_ctl.c
commit 8a509e6fc256e6d4c2bba8d183a51a857b566bca
Author: David Mitchell <[email protected]>
Date: Mon Dec 22 16:25:59 2014 +0000
fix more -IV_MIN negations
Doing uv = -iv is undefined behaviour if iv happens to be IV_MIN.
This occurs in several places in the perl sources.
These ones were found by visual code inspection rather than
using -fsanitize=undefined, but I've added extra tests so that
-fsanitize could find them now.
M pp.c
M sv.c
M t/op/64bitint.t
M t/opbasic/arith.t
commit c107b30b3b4398042ce33ae4b82d04400a6c18bd
Author: David Mitchell <[email protected]>
Date: Mon Dec 22 09:34:40 2014 +0000
fix undefined float behaviour in pack('f')
The C standard says that the value of the expression (float)double_var is
undefined if 'the value being converted is outside the range of values
that can be represented'.
So to shut up -fsanitize=undefined:
my $p = pack 'f', 1.36514538e67;
giving
runtime error: value 1.36515e+67 is outside the range of representable
values of type 'float'
explicitly handle the out of range values.
Something similar is already done under defined(VMS) && !defined(_IEEE_FP),
except that there it floors to +/- FLT_MAX rather than +/- (float)NV_INF.
I don't know which branch is best, and whether they should be merged.
This fix was suggested by Aaron Crane.
M pp_pack.c
commit d5a148aa5a515fd86c1fac4c2b279f053974039f
Author: David Mitchell <[email protected]>
Date: Sun Dec 21 00:40:13 2014 +0000
avoid integer overflow in Perl_av_extend_guts()
There were two issues; first the 'overextend' algorithm (add a fifth of
the current size to the requested size) could overflow,
and secondly MEM_WRAP_CHECK_1() was being called with newmax+1,
which could overflow if newmax happened to equal SSize_t_MAX.
e.g.
$a[0x7fffffffffffffff] = 1
$a[5] = 1; $a[0x7fffffffffffffff] = 1
could produce under ASan:
av.c:133:16: runtime error: signed integer overflow:
9223372036854775807 + 1 cannot be represented in type 'long'
av.c:170:7: runtime error: signed integer overflow: 9223372036854775807
+ 1 cannot be represented in type 'long'
M av.c
commit c7c5479b4a470849983c04910f3a06b13be26b98
Author: David Mitchell <[email protected]>
Date: Sun Dec 21 00:00:10 2014 +0000
asan_ignore: exclude Perl_pp_left_shift()
<< in perl maps directly to << in C, so don't warn about it when the RHS
is too big.
Fixes e.g.:
print 1 << 64
use integer; print 1 << 63
Typical ASan warning:
pp.c:1893:2: runtime error: left shift of 1 by 63 places cannot be
represented in type 'IV' (aka 'long')
M asan_ignore
commit bbf00d7e939fd996ef09d5c17d688883a3876506
Author: David Mitchell <[email protected]>
Date: Sat Dec 20 16:40:52 2014 +0000
fix -IV_MIN negations
Doing uv = -iv is undefined behaviour if iv happens to be IV_MIN.
This occurs in several places in the perl sources.
Found by -fsanitize=undefined.
Here's a typical message:
sv.c:2864:7: runtime error: negation of -9223372036854775808 cannot be
represented in type 'IV' (aka 'long'); cast to an unsigned type to negate this
value to itself
M pp.c
M pp_hot.c
M sv.c
commit d0a56b6c692215d85c15d1f636a121dedafaad6a
Author: David Mitchell <[email protected]>
Date: Sat Dec 20 15:30:01 2014 +0000
fix integer overflow in S_study_chunk().
It was calculating final_minlen + delta even when delta was already
SSize_t_MAX and final_minlen > 0.
This triggered it: /a(??{}){2}/.
Found by -fsanitize=undefined:
regcomp.c:5623:89: runtime error: signed integer overflow: 1 +
9223372036854775807 cannot be represented in type 'long'
M regcomp.c
-----------------------------------------------------------------------
--
Perl5 Master Repository