[RFC][Draft patch] Introduce IntegerSanitizer in GCC.
Maxim Ostapenko
m.ostapenko@samsung.com
Tue Jul 5 07:31:00 GMT 2016
CC'ing Jakub, Marek and Kostya, sanitizer maintainers in GCC.
On 04/07/16 14:12, Maxim Ostapenko wrote:
> Hi!
>
> Although in languages like C and C++ unsigned integer overflow
> reliably wraps around and well defined, sometimes it may indicate an
> error in code and lead to undesirable consequences and even security
> vulnerabilities
> (https://android-developers.blogspot.ru/2016/05/hardening-media-stack.html).
> Clang has corresponding '-fsanitize=unsigned-integer-overflow' option
> that may catch some of these errors (but misses some important cases
> such as pointers overflow), GCC has not and instruments only signed
> integer operations (S = S {+, -, *} S).
>
> Although GCC has a nice framework for instrumenting even "mixed"
> binary operations (e.g. S = U + S) in middle end, implemented by Jakub
> some time ago (see expand_addsub_overflow, expand_mul_overflow etc in
> internal-fn.c), adding support for sanitizing unsigned and "mixed"
> binary operations seems to be quite problematic in terms of huge
> amount of false positive reports that may pop up in following cases:
>
> 1) Some code intentionally relies on overflows, e.g. when computing
> hash codes. Unfortunately, it seems that we cannot do anything with it
> on compiler side, programmer will need to do some filtering here by
> himself.
>
> 2) Unfortunately, it seems that C and C++ FEs don't provide suitable
> interfaces to get *LHS* real type when building binary expressions, so
> *build_binary_op* doesn't know about *LHS* real type and we can easily
> end up with false positive report e.g. in such code:
>
> int
> cmp (const char *s1, const char *s2)
> {
> return strlen (s1) - strlen (s2);
> }
>
> because in gimple we would have something like this:
>
> unsigned int tmp, len1, len2;
> int result;
> .........
> tmp = len1 - len2; <===== FP here if len1 < len2
> result = (int) tmp;
> return result;
>
> 3) GCC relies on unsigned integer overflows when constructing
> POINTER_PLUS expressions. We need a special treatment for this case,
> because it's quite common to have a negative offset from a given
> pointer and we don't want have false reports here.
>
> This very draft patch (of course we would need more testcases,
> changelog entry etc) adds support for
> '-fsanitize=unsigned-integer-overflow' to GCC for PLUS, MINUS and MULT
> operations, extending its functionality to support pointers overflow
> and binary operations with different signess of theirs operands
> ("mixed" binary operations, say, S = U + S). It simply replaces all +,
> - and * by new ISAN_CHECK_{ADD, SUB, MUL} intrinsics in C and C++ FEs
> to be lowered later during intrinsics expansion. For example, if we
> have a + b expression, it would be replaced in FE by following call:
>
> a + b -> ISAN_CHECK_ADD (a, b, a_unsiged_p, b_unsigned_p,
> result_unsigned_p)
>
> where *a_unsiged_p* is 1 if *a* is unsigned and 0 otherwise. The same
> rule applies for *b_unsigned_p*. The *result_unsigned_p* value should
> reflect result type signess, but as mentioned in 2), we don't know it
> when building binary expression, so we can only guess it from
> arguments types and maybe change it (in a very hackish way) later (see
> *isan_maybe_change_ifn_sign_arg* function) in order to reduce number
> of FPs (in fact, these hacks can significantly reduce FPs ratio, ~
> 30%). These values will be used in *expand_addsub_overflow* and
> *expand_mul_overflow* functions to compute overflow correctly.
>
> This patch survives GCC bootstrap, I've also managed to build Firefox
> and Chromium with '-fsanitize=unsigned-integer-overflow' enabled. The
> tool found several bugs in opensource software:
>
> 1) Integer overflow when computing len parameter in "file" utility
> (http://bugs.gw.com/view.php?id=555)
> 2) Pointer overflow (nullptr - 1) in Google's skia library
> (https://bugs.chromium.org/p/skia/issues/detail?id=5415)
> 3) Unsigned integer overflow in HAL component in Firefox
> (https://bugzilla.mozilla.org/show_bug.cgi?id=1280514)
>
> Is community interested in such a tool? Any feedback would be greatly
> appreciated, especially some points how we can figure out real result
> type for *LHS* of binary expressions in
> *build_binary_op* in order to avoid unnecessary FPs and ugly hacks in
> FEs.
>
> Thanks,
> -Maxim
-------------- next part --------------
A non-text attachment was scrubbed...
Name: isan-upstream-1.diff
Type: text/x-diff
Size: 49134 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20160705/863641a5/attachment.bin>
More information about the Gcc
mailing list