AFLplusplus: COMPCOV float bug?
It seems like there is a bug in the float splitting of compcov that was found in oss-fuzz in a bitcoin_core harness.
fuzzing harness:
#include <memusage.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <util/serfloat.h>
#include <version.h>
#include <cassert>
#include <cmath>
#include <limits>
FUZZ_TARGET(float)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
{
const double d{[&] {
double tmp;
CallOneOf(
fuzzed_data_provider,
// an actual number
[&] { tmp = fuzzed_data_provider.ConsumeFloatingPoint<double>(); },
// special numbers and NANs
[&] { tmp = fuzzed_data_provider.PickValueInArray({
std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::min(),
-std::numeric_limits<double>::min(),
std::numeric_limits<double>::max(),
-std::numeric_limits<double>::max(),
std::numeric_limits<double>::lowest(),
-std::numeric_limits<double>::lowest(),
std::numeric_limits<double>::quiet_NaN(),
-std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::signaling_NaN(),
-std::numeric_limits<double>::signaling_NaN(),
std::numeric_limits<double>::denorm_min(),
-std::numeric_limits<double>::denorm_min(),
}); },
// Anything from raw memory (also checks that DecodeDouble doesn't crash on any input)
[&] { tmp = DecodeDouble(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); });
return tmp;
}()};
(void)memusage::DynamicUsage(d);
uint64_t encoded = EncodeDouble(d);
if constexpr (std::numeric_limits<double>::is_iec559) {
if (!std::isnan(d)) {
uint64_t encoded_in_memory;
std::copy((const unsigned char*)&d, (const unsigned char*)(&d + 1), (unsigned char*)&encoded_in_memory);
assert(encoded_in_memory == encoded);
}
}
double d_deserialized = DecodeDouble(encoded);
assert(std::isnan(d) == std::isnan(d_deserialized));
assert(std::isnan(d) || d == d_deserialized);
}
}
testcase that results in an assert failure:
00000000: 0000 0000 0000 0000 0000 0000 0000 0000 [ ................ ]
00000010: 0000 0000 0000 0000 0000 0000 0000 0000 [ ................ ]
00000020: 0000 0000 0000 0000 0080 0000 0000 8000 [ ................ ]
00000030: 00ff ffff ff00 0000 0000 0000 0000 8041 [ ...............A ]
obtain testcase: wget 'https://oss-fuzz.com/download?testcase_id=6121564358180864'
to run:
./float testcase.bin
Running LLVMFuzzerInitialize ...
continue...
Reading 64 bytes from testcase.bin
float: test/fuzz/float.cpp:55: void float_fuzz_target(FuzzBufferType): Assertion `encoded_in_memory == encoded' failed.
Aborted
Download compiled harness and testcase: https://we.tl/t-KZiOA4NXOd
to build:
git clone --depth=1 https://github.com/google/oss-fuzz
cd oss-fuzz
echo N|python infra/helper.py build_image base-builder
echo N|python infra/helper.py build_image bitcoin_core
python infra/helper.py shell --sanitizer address --engine afl --architecture x86_64 bitcoin_core
# then in the shell:
vi /usr/local/bin/compile_afl
# change lines to
export AFL_ENABLE_CMPLOG=0
export AFL_LAF_CHANCE=100
# save and exit
# to update afl++:
pushd /src/aflplusplus/
git checkout dev
git pull
bash # <- important!
unset CFLAGS
unset CXXFLAGS
make install
exit # <- important
popd
compile # <- this builds the target
exit # exit docker shell
# compiled harness is in build/out/bitcoin-core outside of the docker container
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 18 (18 by maintainers)
Commits related to this issue
- saturated run test (#1174) * new run * add missing fuzzer variant — committed to mattweingarten/AFLplusplus by vanhauser-thc 3 years ago
ah typo.
python infra/helper.py build_image bitcoin-core
dash not underscore 😦