2

LLVM's Sanitizer documentation says:

Use clang++ to compile and link your program with -fsanitize=undefined flag. Make sure to use clang++ (not ld) as a linker, so that your executable is linked with proper UBSan runtime libraries. You can use clang instead of clang++ if you’re compiling/linking C code. ... You can enable only a subset of checks offered by UBSan, and define the desired behavior for each kind of check: ...

Does it mean that the subset of checks are by default included?

For example, is -fsanitize=undefined,alignment redundant by having alignment?

I have the same question about -fsanitize=address and also about GCC sanitizer.

I would like to enable as much sanitizers simultaneously as possible but I don't want to have unnecessary options in the command line or CMake line. That is, I don't want to have -fsanitize=address,pointer-compare,pointer-subtract,leak,shift,integer-divide-by-zero,unreachable,null,return,signed-integer-overflow just in case.

How such command line look like?

The documentation is also not clear for the ASAN_OPTIONS runtime variable, it is not clear if things need to be activated or not. For example, I have ASAN_OPTIONS="handle_ioctl=true:check_initialization_order=true:detect_container_overflow=1:detect_stack_use_after_return=false:detect_odr_violation=1:allow_addr2line=true:strict_init_order=true" but perhaps the on/true options are not really necessary.

alfC
  • 14,261
  • 4
  • 67
  • 118

1 Answers1

3

Sanitizers let you check for individual errors (alignment, signed-integer-overflow, etc.) and groups of errors:

  • address - buffer overflows
  • leak - memory leaks (implied by address)
  • undefined - mostly integer Undefined Behavior errors
  • integer - other suspicious integer behavior

(there are also thread and memory but let's not touch those as they are incompatible with Asan and UBsan and have to be run separately).

Contents of groups is documented in Clang documentation:

GCC generally tries to be compatible to Clang (for a noticeable exception of not supporting checking for integer errors).

In general I would suggest to use

-fsanitize=address,undefined,float-divide-by-zero,nullability \
-fno-sanitize-recover \
-fno-common \
-U_FORTIFY_SOURCE

(the -fno-sanitize-recover part is needed so that sanitizers abort your program whenever any check fails instead of continuing execution, the -fno-common improves buffer overflow detection for global arrays and -U_FORTIFY_SOURCE disables source fortification which prevents Asan from detecting some bugs). You could extend this by

  • adding integer to -fsanitize option (may report false positives for perfectly valid code in your program and libraries but this can worked around by using ignorelists)
  • adding -fsanitize-address-use-after-scope (may be too slow in your case)
  • adding pointer-compare,pointer-subtract to -fsanitize option (tend be too slow for practical use)

For ASAN_OPTIONS you could check the default values in

I recommend to use the following set of options which enables some complex checks that are disabled by default:

export ASAN_OPTIONS='check_initialization_order=true:strict_init_order=true:detect_stack_use_after_return=true:strict_string_checks=true'

Now to your questions.

For example, is -fsanitize=undefined,alignment redundant by having alignment?

Yes, it's redundant because alignment is included into undefined.

That is, I don't want to have -fsanitize=address,pointer-compare,pointer-subtract,leak,shift,integer-divide-by-zero,unreachable,null,return,signed-integer-overflow just in case.

According to documentation your command line could be reduced to

-fsanitize=address,undefined,integer,pointer-compare,pointer-subtract

For example, I have ASAN_OPTIONS="handle_ioctl=true:check_initialization_order=true:detect_container_overflow=1:detect_stack_use_after_return=false:detect_odr_violation=1:allow_addr2line=true:strict_init_order=true" but perhaps the on/true options are not really necessary.

According to docs your options could be reduced to

ASAN_OPTIONS='handle_ioctl=true:check_initialization_order=true:allow_addr2line=true:strict_init_order=true'
yugr
  • 19,769
  • 3
  • 51
  • 96
  • Thanks, "...could be reduced to ..." what about leak? What is the options by which I could enable the **maximum** number of (mutually compatible) checks. Of the ones you listed, which are the ones I can eliminate by having `leaks` added. From the first part of your answer I understand that it is simply `-fsanitize=address,leak,undefined,integer`, is it so? – alfC Oct 12 '22 at 21:00
  • `integer` seems to be incompatible with the GNU c++ library, since it detects errors in it (false positive hopefully?) `/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/random.tcc:416:33: runtime error: unsigned integer overflow: 397 - 624 cannot be represented in type 'unsigned long' SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/random.tcc:416:33 in ` – alfC Oct 12 '22 at 21:33
  • 1
    @alfC "what about leak?" - Lsan is enabled by default with Asan, so `address` implies `leak`. – yugr Oct 13 '22 at 12:06
  • 1
    "From the first part of your answer I understand that it is simply -fsanitize=address,leak,undefined,integer, is it so?" - not quite, some special checks are not included e.g. `pointer-compare` and `pointer-subtract` (they are very expensive) and also `float-divide-by-zero` and `nullability`. `bounds` is not included as well but all of it's checks are already covered by `address`. – yugr Oct 13 '22 at 12:07
  • 1
    @alfC "integer seems to be incompatible with the GNU c++ library" - yes, that's a known issue. You can work around this by disabling instrumentation of STL sources via [ignorelist](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html). – yugr Oct 13 '22 at 13:14
  • ok, thanks for the data. One more iteration, is this complete now `-fsanitize=address,undefined,integer,pointer-compare,pointer-subtract,float-divide-by-zero,nullability`? ("complete" in the sense that it has all the sanitizers that it can have at the same time). – alfC Oct 14 '22 at 06:25
  • Also, do I need to *activate* something with `ASAN_OPTIONS=`, or is it mostly to *deactivate* checks? – alfC Oct 14 '22 at 06:26
  • @alfC "is this complete now" - to my knowledge, yes. – yugr Oct 14 '22 at 08:11
  • 1
    @alfC "do I need to activate something with ASAN_OPTIONS" - the situation is the same as for `-fsanitize` flag: heavy checks are disabled by default so to enable them you require to set ASAN_OPTIONS. I typically use `ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true:detect_stack_use_after_return=true:detect_odr_violation=1`. – yugr Oct 14 '22 at 08:20
  • 1
    @alfC And by the way it makes sense to also supply `-fno-sanitize-recover=asan,undefined,integer,float-divide-by-zero,nullability`, otherwise detected errors in these checkers will not cause your app to abort (only warning will be printed). – yugr Oct 14 '22 at 08:20
  • 1
    `-fsanitize=integer` can really mess with you when it's going after code with perfectly defined behavior - and it's still reported as "undefined". Only use this option if you _know_ that neither you nor the libraries you use (including the standard C++ library) will use wraparounds on unsigned integers. I would _not_ recommend using this option when using gcc's C++ standard library for example. – Ted Lyngmo Oct 14 '22 at 15:59
  • 1
    @yugr, "And by the way it makes sense to also supply...", isn't `-fno-sanitize-recover=all` for that? – alfC Oct 14 '22 at 16:38
  • Random note: I have to use `ASAN_OPTIONS="new_delete_type_mismatch=0:etc" otherwise it forces to have a virtual destructor even when it is not needed. – alfC Oct 14 '22 at 16:43
  • @alfC _"otherwise it forces to have a virtual destructor even when it is not needed"_ - Is that on polymorphic classes used with shared pointers? – Ted Lyngmo Oct 14 '22 at 16:52
  • @alfC "isn't -fno-sanitize-recover=all for that?" - good catch! I've never used it myself, did it work for you? – yugr Oct 14 '22 at 17:56
  • @alfC "I have to use `ASAN_OPTIONS="new_delete_type_mismatch=0:etc"" - it's hard to comment without a reprocase, I think this should be a separate question. – yugr Oct 14 '22 at 18:01
  • `-fno-sanitize-recover=all`, yes it worked, it use to give the runtime analyzer warnings and continue. – alfC Oct 14 '22 at 19:52
  • @TedLyngmo "`-fsanitize=integer` can really mess with you when it's going after code with perfectly defined behavior" - thanks, that statement is true so I added a note in the answer. Still I believe this check is highly useful in practice even if user has to play a bit with [ignorelists](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html). – yugr Oct 17 '22 at 13:11