Make all tests pass UBSan (-fsanitize=undefined
) without using any UBSan suppressions.
From a fuzzing perspective it would be really nice to be able to run UBSan without having to deal with suppression files :)
Note that the commit c8c393b149f975f13e3ac7e4be17196d7c482b69 needs to be cherry-picked in from PR #17156 to get rid of the two alignment related suppressions :)
Before this PR:
0$ ./configure --with-sanitizers=undefined
1$ make
2$ UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" src/test/test_bitcoin
3…
4validation.cpp:2563:164: runtime error: division by zero
5validation.cpp:2568:138: runtime error: division by zero
6validation.cpp:2573:161: runtime error: division by zero
7validation.cpp:2582:164: runtime error: division by zero
8validation.cpp:2583:144: runtime error: division by zero
9policy/fees.cpp:347:44: runtime error: division by zero
10policy/fees.cpp:344:44: runtime error: division by zero
11wallet/wallet.cpp:2049:67: runtime error: division by zero
12wallet/wallet.cpp:3280:51: runtime error: division by zero
13wallet/wallet.cpp:3283:51: runtime error: division by zero
14…
15$ echo $?
161
17$ UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" test/functional/test_runner.py
18…
19AssertionError: Unexpected stderr validation.cpp:2563:164: runtime error: division by zero
20SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior validation.cpp:2563:164 in
21validation.cpp:2568:138: runtime error: division by zero
22SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior validation.cpp:2568:138 in
23validation.cpp:2573:161: runtime error: division by zero
24SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior validation.cpp:2573:161 in
25validation.cpp:2582:164: runtime error: division by zero
26SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior validation.cpp:2582:164 in
27validation.cpp:2583:144: runtime error: division by zero
28SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior validation.cpp:2583:144 in !=
29…
30$ echo $?
311
After this PR (with cherry-pick as described above):
0$ ./configure --with-sanitizers=undefined
1$ make
2$ UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" src/test/test_bitcoin
3$ echo $?
40
5$ UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" test/functional/test_runner.py
6$ echo $?
70
Note: This PR is not a bug fix (there is no bug to fix!). We assume the floating-point types to fulfil the requirements of IEC 559 (IEEE 754) standard: floating-point division by zero is thus well-defined.
The IEC 559 (IEEE 754) assumption is made explicitly in assumptions.h
and also checked at compile-time:
However, UBSan is not aware of that assumption we’re making.