Skip to content

Conversation

practicalswift
Copy link
Contributor

Add UBSan suppressions needed for fuzz tests to not warn under -fsanitize=integer.

Avoid -fsanitize=integer warnings in fuzzing harnesses.

Suppressed warnings (excluding warnings from src/crypto/ and src/test/):

addrman.cpp:306:24: runtime error: implicit conversion from type 'long' of value 5190149478 (64-bit, signed) to type 'uint32_t' (aka 'unsigned int') changed the value to 895182182 (32-bit, unsigned)
addrman.h:446:43: runtime error: implicit conversion from type 'int' of value -22 (32-bit, signed) to type 'const uint8_t' (aka 'const unsigned char') changed the value to 234 (8-bit, unsigned)
arith_uint256.cpp:32:35: runtime error: left shift of 1712128 by 24 places cannot be represented in type 'uint32_t' (aka 'unsigned int')
arith_uint256.cpp:47:39: runtime error: left shift of 4294966784 by 31 places cannot be represented in type 'uint32_t' (aka 'unsigned int')
chain.cpp:151:12: runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed) to type 'unsigned long' changed the value to 18446744073709551615 (64-bit, unsigned)
coins.cpp:114:22: runtime error: unsigned integer overflow: 0 - 96 cannot be represented in type 'unsigned long'
compressor.cpp:162:33: runtime error: unsigned integer overflow: 15617702637291228364 * 10 cannot be represented in type 'unsigned long'
compressor.cpp:188:11: runtime error: unsigned integer overflow: 2265760372865400000 * 10 cannot be represented in type 'unsigned long'
hash.cpp:13:15: runtime error: left shift of 1692305888 by 15 places cannot be represented in type 'uint32_t' (aka 'unsigned int')
pubkey.h:152:23: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int'
streams.h:570:31: runtime error: left shift of 350879 by 52 places cannot be represented in type 'uint64_t' (aka 'unsigned long')
util/bip32.cpp:57:36: runtime error: left shift of 3241096244 by 1 places cannot be represented in type 'unsigned int'
util/strencodings.cpp:562:38: runtime error: implicit conversion from type 'unsigned char' of value 255 (8-bit, unsigned) to type 'char' changed the value to -1 (8-bit, signed)
util/strencodings.h:164:24: runtime error: implicit conversion from type 'int' of value -74 (32-bit, signed) to type 'unsigned long' changed the value to 18446744073709551542 (64-bit, unsigned)

The warnings above happen here:

pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);

const uint8_t lowest_compatible = compat - INCOMPATIBILITY_BASE;

pn[i + k] |= (a.pn[i] << shift);

pn[i - k - 1] |= (a.pn[i] << (32 - shift));

return sign * r.GetLow64();

cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();

return 1 + (n*9 + d - 1)*10 + e;

n *= 10;

return (x << r) | (x >> (32 - r));

while (len--)

m_buffer |= (data << (64 - nbits)) >> (64 - 8 + m_offset);

ret += strprintf("/%i", (i << 1) >> 1);

for (auto ch : str) r += ToLower((unsigned char)ch);

accumulator |= a[i] ^ b[i%b.size()];

@laanwj laanwj added the Tests label Jan 24, 2021
@practicalswift
Copy link
Contributor Author

practicalswift commented Jan 24, 2021

See #21001 for the src/coins.cpp case. It should probably be addressed rather than suppressed.

Edit: See #21001 (comment).

@DrahtBot
Copy link
Contributor

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@maflcko
Copy link
Member

maflcko commented Jan 25, 2021

Is this supposed to be complete? If yes, could enable the sanitizer in ci. If not, it would be good to motivate the changes and explain how to test them.

Locally it crashes soon after trying to test:

net.cpp:183:17: runtime error: implicit conversion from type 'int64_t' (aka 'long') of value 55751376386 (64-bit, signed) to type 'uint32_t' (aka 'unsigned int') changed the value to 4211768834 (32-bit, unsigned)

@practicalswift
Copy link
Contributor Author

@MarcoFalke It is currently complete only with regards to the fuzz tests.

More specifically it survives the following under -fsanitize=integer:

$ ./fuzz_survival_test.sh 2
Running fuzzer "addition_overflow" for 2 second(s): ✅
Running fuzzer "addrdb" for 2 second(s): ✅
Running fuzzer "address_deserialize" for 2 second(s): ✅
Running fuzzer "addr_info_deserialize" for 2 second(s): ✅
Running fuzzer "addrman" for 2 second(s): ✅
…

fuzz_survival_test.sh can be found here: https://gist.github.com/practicalswift/e3de0d96af31f42d3a2f5bcb6f631432

I haven't gotten around to covering also the unit tests and functional tests, but it makes sense to cover them as well. I'll look in to expanding the scope of this PR to cover them too :)

@maflcko
Copy link
Member

maflcko commented Jan 25, 2021

I was running the process_messages harness, compiled with clang version 11.0.0 sanitizers: fuzzer,integer. Which version are you using for testing?

Edit: The crasher for me:

XAAAAABcXP///7z/EAAAAAAAAAAAXAAKQABcAACAYYcACgD/APP6gjtdEwAhO784//X+///9QAAA
EAAAQSoBAAr6CRhAgb/BAQAAXCcsABAAAEEqCkAAAAAAXAAKQIBBhwAKAP/z4IDgBWX/////7ztp
x/709Qh6AAAAAAAAAED3/50AAP//

@practicalswift practicalswift force-pushed the fsanitize-integer branch 2 times, most recently from 73f9dce to 03e34b5 Compare January 25, 2021 20:40
@practicalswift
Copy link
Contributor Author

@MarcoFalke Oh, I was starting from an empty seed corpus.

I've now added all -fsanitize=integer suppressions needed for the following commands to pass:

  1. Unit tests
  2. Functional tests
  3. Fuzz tests starting with an empty corpus and running for a minute or so
  4. Fuzz tests running over the qa-assets corpus

To reproduce:

# Unit tests
$ UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1:report_error_type=1:suppressions=$(pwd)/test/sanitizer_suppressions/ubsan" \
      src/test/test_bitcoin

# Functional tests
$ UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1:report_error_type=1:suppressions=$(pwd)/test/sanitizer_suppressions/ubsan" \
      test/functional/test_runner.py --timeout-factor=0 --failfast --combinedlogslen=100

# Fuzz tests starting with an empty corpus
$ ./fuzz_survival_test.sh # From https://gist.github.com/practicalswift/e3de0d96af31f42d3a2f5bcb6f631432

# Fuzz tests running over the qa-assets corpus
# Run ./fuzz_survival_test.sh after adjusting it to use the qa-seeds corpus.
$ ./fuzz_survival_test_qa.sh

@maflcko
Copy link
Member

maflcko commented Jan 26, 2021

review ACK f0f8b1a 🤚

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

review ACK f0f8b1a076c362c6e26570a2129809f4d6a0abad 🤚
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUgaOwv/Yl+4miTBnNJtB6jjBfibJcMOStYIEzi0t/LWFwEPNOViBnz4+FBYszgy
a2Zusppxw/Mt7hKB1cHmJgs9WAgS3kTXyH/c1vg043d7/qQrOBxSXu7EL/xO3sx8
NCDmXoIyMT0+wWdLFg/TGP/TeGnmmoK+UJ/i/seEl5quVaBPTauP3sdZv6tGqRaP
zY1Qq8btdAGohbp8o6Sxwp7gjfQBjoy8ggH4TheiGSpvuyvbomDcEmNu/j0E3b4d
t8g1Ef3Vcve88BN8SvRB5UN+DtpNjbsKjMjxTh8k1GOGEKgv3QdKABkNjQjsKABx
I3FbSZz0wElfIBHDZL6W7jopwhMFPf24v1dWKJyCNI1IwNE0T23EOndZxFpKqFKW
ZG5EhSY19vAkykW6NUo9KRUfHzuPvKPRBC64cvtX2AShHvltPynesIJkM2d+LTyn
2sW6Je34/oOKnWoyA2JrxlyMgJXzIqZkSFbfQAqztY8BU87sMcILEdxlV7leLdch
CZsN3rMe
=5LC+
-----END PGP SIGNATURE-----

Timestamp of file with hash 6949a3e88bd4ef7a52797e84db8a5eea62639166a78d8c2eed13eccb4dcfd32d -

@maflcko
Copy link
Member

maflcko commented Jan 26, 2021

review ACK 0d98997 🎅

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

review ACK 0d9899789e5d8f834eeb1bc67017a79bbc77530a 🎅
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUhBggwAhZaV0ehCdKDwIh/BP4PCpM/dybM7tXzkTO+Q31MgI3deJ31J0BXs+zSi
fBv16UbSLLXMAO7BmSOjt7WO4Q8f+B138ERrR+1W6DlmR8HJ/6hZTaiQAlikQIG5
ixgzzH1PX6FdMsAbTGbIrWOv4hflIoIs2MkKjXnKRKighD62viF8KFrzZSUOwls8
EYCxo/mcLE9uPWsccnUWM6ElpBwLwXdloEIDz9+k1X26VHVQk5Hb44dLOjFSIJld
vSZhRVgt8o9ZDaWV2F2Qi64A7pQAkvZ/fXjommAbeBZtzrh95r+WRECzXWjVnjrA
KtwcI9rYfbzePawFtxN4RHQab5VDxqUU1Og7ZG7c0ro6sqL8sM3eianvZaRnCJb1
EkR9k/yicw//S9XKXyNX/xVjBe/ead9IQdzUCLYbLqfbhj95nZxSzF47iAtJsnV0
m26U/s8d6zBtSsGFqk1q3Qa/58U4EFqrs05OTItaFsJ65lO3nFEDp0nroetojw+M
dWk7V6vD
=8Lkf
-----END PGP SIGNATURE-----

Timestamp of file with hash a8d5520f601c503b2ecc40e4169f8355ed84571b1827d52455af1e4256107a2b -

@maflcko
Copy link
Member

maflcko commented Jan 26, 2021

Force pushed to remove unrelated commit. Hope you don't mind @practicalswift

@maflcko
Copy link
Member

maflcko commented Jan 26, 2021

Only change was in the linter, which passed. So we don't need to wait for the other ci checks before merge.

@maflcko maflcko merged commit 32d44d2 into bitcoin:master Jan 26, 2021
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jan 26, 2021
…ts to n… …ot warn under -fsanitize=integer
@practicalswift practicalswift deleted the fsanitize-integer branch April 10, 2021 19:45
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants