Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fuzz: Add fuzzing harness for TorController #19288

Merged
merged 2 commits into from
Mar 3, 2021

Conversation

practicalswift
Copy link
Contributor

Add fuzzing harness for TorController.

See doc/fuzzing.md for information on how to fuzz Bitcoin Core. Don't forget to contribute any coverage increasing inputs you find to the Bitcoin Core fuzzing corpus repo.

Happy fuzzing :)

@DrahtBot
Copy link
Contributor

DrahtBot commented Jun 16, 2020

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.

@laanwj
Copy link
Member

laanwj commented Jul 15, 2020

Concept ACK
I don't really like moving all kinds of internal details to the public header, but testability and encapsuation are always a bit at odds.

Copy link
Contributor

@Crypt-iQ Crypt-iQ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

48 hour coverage with libfuzzer here: https://crypt-iq.github.io/torcontrol_cov/src/torcontrol.cpp.gcov.html

Currently two functions are coverage lacking from the above output:

  • authchallenge_cb
  • protocolinfo_cb

authchallenge_cb coverage is a bit tricky to get coverage for because it has to pass the HMAC check. protocolinfo_cb just needs better seeds and it should be able to hit every part but this one:

bitcoin/src/torcontrol.cpp

Lines 643 to 652 in 9d4b3d8

std::string torpassword = gArgs.GetArg("-torpassword", "");
if (!torpassword.empty()) {
if (methods.count("HASHEDPASSWORD")) {
LogPrint(BCLog::TOR, "tor: Using HASHEDPASSWORD authentication\n");
boost::replace_all(torpassword, "\"", "\\\"");
_conn.Command("AUTHENTICATE \"" + torpassword + "\"", std::bind(&TorController::auth_cb, this, std::placeholders::_1, std::placeholders::_2));
} else {
LogPrintf("tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n");
}
} else if (methods.count("NULL")) {

src/test/fuzz/torcontrol.cpp Show resolved Hide resolved
@jonatack
Copy link
Member

Concept ACK

@Crypt-iQ
Copy link
Contributor

Runs without complaint on Ubuntu 18:
./configure --enable-fuzz --with-sanitizers=address,undefined,fuzzer CC=clang-10 CXX=clang++-10

Will build on macOS and report back.

@Crypt-iQ
Copy link
Contributor

Builds on macOS:
./configure --enable-fuzz --with-sanitizers=fuzzer,address,undefined no actionable complaints
./configure --enable-fuzz --with-sanitizers=fuzzer,integer,undefined no actionable complaints

Ran with Ubuntu 18 again:
./configure --enable-fuzz --with-sanitizers=fuzzer,integer:

/usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/basic_string.tcc:1271:25: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::size_type' (aka 'unsigned long')
#0 0x55db7101bde3 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::rfind(char, unsigned long) const /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/basic_string.tcc:1271:25
#1 0x55db7101bde3 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_of(char, unsigned long) const /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/basic_string.h:2636:22
#2 0x55db7101bde3 in SplitHostPort(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) /root/bitcoin/src/util/strencodings.cpp:111:23
#3 0x55db70fc30f6 in Lookup(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<CService, std::allocator<CService> >&, int, bool, unsigned int) /root/bitcoin/src/netbase.cpp:213:5
#4 0x55db70fc36ca in Lookup(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, CService&, int, bool) /root/bitcoin/src/netbase.cpp:237:17
#5 0x55db70fc389b in LookupNumeric(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int) /root/bitcoin/src/netbase.cpp:262:9
#6 0x55db70ec5bfa in TorController::auth_cb(TorControlConnection&, TorControlReply const&) /root/bitcoin/src/torcontrol.cpp:411:31
#7 0x55db70ebb54b in test_one_input(std::vector<unsigned char, std::allocator<unsigned char> > const&) /root/bitcoin/src/test/fuzz/torcontrol.cpp:66:28
#8 0x55db71583916 in LLVMFuzzerTestOneInput /root/bitcoin/src/test/fuzz/fuzz.cpp:45:5
#9 0x55db70e4b641 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/root/bitcoin/src/test/fuzz/torcontrol+0x649641)
#10 0x55db70e4ad85 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/root/bitcoin/src/test/fuzz/torcontrol+0x648d85)
#11 0x55db70e4d6a7 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/root/bitcoin/src/test/fuzz/torcontrol+0x64b6a7)
#12 0x55db70e4da09 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/root/bitcoin/src/test/fuzz/torcontrol+0x64ba09)
#13 0x55db70e3c6de in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/root/bitcoin/src/test/fuzz/torcontrol+0x63a6de)
#14 0x55db70e65522 in main (/root/bitcoin/src/test/fuzz/torcontrol+0x663522)
#15 0x7f13c3c4fb96 in __libc_start_main /build/glibc-2ORdQG/glibc-2.27/csu/../csu/libc-start.c:310
#16 0x55db70e11459 in _start (/root/bitcoin/src/test/fuzz/torcontrol+0x60f459)
SUMMARY: UndefinedBehaviorSanitizer: unsigned-integer-overflow /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/basic_string.tcc:1271:25

@Crypt-iQ
Copy link
Contributor

ACK 9b82584

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haven't reviewed, but it would probably be good to use the new style here

src/test/fuzz/torcontrol.cpp Outdated Show resolved Hide resolved
src/test/fuzz/torcontrol.cpp Outdated Show resolved Hide resolved
@practicalswift
Copy link
Contributor Author

Updated to use the excellent CallOneOf!

Should be ready for final review :)

@practicalswift practicalswift force-pushed the fuzzers-torcontroller branch 2 times, most recently from 99e4f1e to 9b984fb Compare January 24, 2021 22:20
@practicalswift
Copy link
Contributor Author

Compared to other fuzzing PRs this PR is relatively cumbersome to keep up to date over time due to the code move from torcontrol.cpp to torcontrol.h which must be kept in sync. Final review welcome :)

Current status:

Concept ACK

ACKs

  • @Crypt-iQ: counting four now stale ACK:s - thanks for being patient! :)

@practicalswift
Copy link
Contributor Author

The first commit which is move-only is best viewed dimmed 🦓 style:

$ git show --color-moved=dimmed_zebra bb643af8a1bc207935e9ae2c0fe61378ee935bde

@practicalswift
Copy link
Contributor Author

This PR has one stale ACK and three Concept ACKs, and I believe all feedback has been addressed.

Ready for merge after re-review?

@laanwj
Copy link
Member

laanwj commented Mar 1, 2021

Sorry, forgot about this a bit. I'll have a look.

Looks like this has a silent merge conflict on current master:

…/bitcoin/src/test/fuzz/torcontrol.cpp:38:39: error: use of undeclared identifier 'MakeFuzzingContext'
    static const auto testing_setup = MakeFuzzingContext<>();
                                      ^
1 error generated.

@practicalswift practicalswift force-pushed the fuzzers-torcontroller branch from 9b984fb to 936cad9 Compare March 1, 2021 11:16
@practicalswift
Copy link
Contributor Author

@laanwj

Looks like this has a silent merge conflict on current master:

…/bitcoin/src/test/fuzz/torcontrol.cpp:38:39: error: use of undeclared identifier 'MakeFuzzingContext'
    static const auto testing_setup = MakeFuzzingContext<>();
                                      ^
1 error generated.

Oh, thanks for noticing!

Now addressed :)

@laanwj
Copy link
Member

laanwj commented Mar 3, 2021

I want to say this one more time before merging: I dislike moving internal implementation details to the header for testing purposes. It kind of violates encapsulation and makes the headers larger and less usefully self-documenting.

That said, I do not see any other solution in the immediate context here. A longer-term direction would be to have test-specific headers that expose internal functionality for unit testing[, benching, fuzzing] but are never included in production code.

ACK 10d4477

@laanwj laanwj merged commit dd8f474 into bitcoin:master Mar 3, 2021
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Mar 3, 2021
@practicalswift practicalswift deleted the fuzzers-torcontroller branch April 10, 2021 19:44
@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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants