Skip to content

Conversation

brunoerg
Copy link
Contributor

@brunoerg brunoerg commented Oct 1, 2024

Fixes #30957

We currently have some instructions on the documentation about how to fuzz the Bitcoin Core P2P layer using Honggfuzz NetDriver. It includes a patch to be applied to bypass network magic and checksum validation, that is outdated. However, we can change the code to bypass them using FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION. It also makes the p2p_transport_serialization fuzz target simpler since we do not need to assist the network magic and checksum creation anymore.

@DrahtBot
Copy link
Contributor

DrahtBot commented Oct 1, 2024

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

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK dergoegge, marcofleon

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

No conflicts as of last run.

@DrahtBot DrahtBot added the P2P label Oct 1, 2024
@brunoerg
Copy link
Contributor Author

brunoerg commented Oct 1, 2024

cc: @dergoegge

@dergoegge
Copy link
Member

Concept ACK

@brunoerg brunoerg force-pushed the 2024-09-fuzz-netdriver branch 2 times, most recently from fe8fa56 to aa8208b Compare October 1, 2024 20:12
@brunoerg brunoerg marked this pull request as draft October 1, 2024 20:35
@brunoerg
Copy link
Contributor Author

brunoerg commented Oct 1, 2024

Just moved it to draft to get some conceptual feedbacks first. I added a commit to bypass some asserts in ConnmanTestMsg that would fail since we're bypassing network magic and checksum validation. Also, I think we will have to change p2p_transport_bidirectional target since there are some sanity checks that would fail with the bypasses, especially the assertions about ReceivedBytes/GetReceivedMessage. Any thoughts?

@maflcko
Copy link
Member

maflcko commented Oct 2, 2024

I added a commit to bypass some asserts in ConnmanTestMsg that would fail since we're bypassing network magic and checksum validation. Also, I think we will have to change p2p_transport_bidirectional target since there are some sanity checks that would fail with the bypasses, especially the assertions about ReceivedBytes/GetReceivedMessage. Any thoughts?

Can you explain why the asserts and sanity checks would be failing? They are unrelated to the checksum, so if they are failing, it seems like this patch is incomplete and some part is still checking the magic or checksum, no?

@dergoegge
Copy link
Member

They are unrelated to the checksum, so if they are failing, it seems like this patch is incomplete and some part is still checking the magic or checksum, no?

I'm guessing that we need to make sure that (if we are fuzzing) V1Transport::SetMessageToSend creates valid checksums/magic-bytes according to the new fuzzing mode check.

@brunoerg
Copy link
Contributor Author

brunoerg commented Oct 2, 2024

Can you explain why the asserts and sanity checks would be failing? They are unrelated to the checksum, so if they are failing, it seems like this patch is incomplete and some part is still checking the magic or checksum, no?

Some previously valid magic or checksum could be now be considered invalid. But I removed the commit that bypasses the asserts and changed the verification to:

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    if ((hdr.pchMessageStart[0] & 1) != 0 && hdr.pchMessageStart != m_magic_bytes) {
#else

instead of just:

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    if ((hdr.pchMessageStart[0] & 1) != 0) {
#else

I think this way we still facilitate it without invalidating valid magic/checksum.

@brunoerg brunoerg marked this pull request as ready for review October 2, 2024 11:10
@maflcko maflcko removed the CI failed label Oct 2, 2024
@brunoerg brunoerg force-pushed the 2024-09-fuzz-netdriver branch 2 times, most recently from 63fc7e5 to d5c8c62 Compare October 3, 2024 10:46
@brunoerg
Copy link
Contributor Author

brunoerg commented Oct 3, 2024

Force-pushed addressing #31012 (comment) and #31012 (comment). Thanks, @dergoegge.

@marcofleon
Copy link
Contributor

Approach ACK. The use of FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION in net.cpp looks good to me. Generated a coverage report to verify that both branches of both checks are hit.

I haven't yet worked through the honggfuzz instructions to confirm that they work. I'll circle back to this to give it a try.

@dergoegge
Copy link
Member

Copy and pasting the command from the docs doesn't work:

$ git apply << "EOF" ...
error: corrupt patch at line 15

@brunoerg brunoerg force-pushed the 2024-09-fuzz-netdriver branch from d5c8c62 to 37a6a75 Compare October 7, 2024 12:50
@brunoerg
Copy link
Contributor Author

brunoerg commented Oct 7, 2024

Copy and pasting the command from the docs doesn't work:

Just fixed it. Can you check it?

@dergoegge
Copy link
Member

-v2transport=0 should be added to the bitcoind args used for netdriver fuzzing. Otherwise, it doesn't seem like honggfuzz ever fuzzes anything besides the v2 handshake.

Also playing around with this and reading the netdriver post (i couldn't find any other docs on it) I'm not sure if this will ever even get past the version handshake? So I'm wondering how useful this tool really is for us.

@brunoerg brunoerg force-pushed the 2024-09-fuzz-netdriver branch from 37a6a75 to f53543f Compare October 7, 2024 17:35
@brunoerg
Copy link
Contributor Author

brunoerg commented Oct 7, 2024

-v2transport=0 should be added to the bitcoind args used for netdriver fuzzing. Otherwise, it doesn't seem like honggfuzz ever fuzzes anything besides the v2 handshake.

Well noticed, just added it.

@DrahtBot
Copy link
Contributor

DrahtBot commented Oct 7, 2024

🚧 At least one of the CI tasks failed.
Debug: https://github.com/bitcoin/bitcoin/runs/31190077287

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

@brunoerg brunoerg force-pushed the 2024-09-fuzz-netdriver branch from f53543f to d439666 Compare October 7, 2024 19:01
@DrahtBot DrahtBot removed the CI failed label Oct 7, 2024
@brunoerg
Copy link
Contributor Author

brunoerg commented Oct 7, 2024

Also playing around with this and reading the netdriver post (i couldn't find any other docs on it) I'm not sure if this will ever even get past the version handshake? So I'm wondering how useful this tool really is for us.

Yes, I don't think it will pass the version handshake. I can't see what kind of bugs it would find that other fuzzers would not get.

Copy link
Member

@dergoegge dergoegge left a comment

Choose a reason for hiding this comment

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

ACK d439666

I think we could consider removing the honggfuzz netdriver instructions in a follow up but the changes look good to me anyway. I tested this by running honggfuzz in netdriver mode.

@DrahtBot DrahtBot requested a review from marcofleon October 8, 2024 13:05
Copy link
Contributor

@marcofleon marcofleon left a comment

Choose a reason for hiding this comment

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

Tested ACK d439666

@theuni
Copy link
Member

theuni commented Oct 9, 2024

If we're going to be peppering the code with these, could we add a safety harness to make sure it's never being used accidentally for a live node?

Maybe somewhere in init.cpp or bitcoind.cpp:

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
exit(1);
#endif

Edit: I realize that bitcoind should be disabled in that case. This would be belt-and-suspenders to make sure that always holds.

@brunoerg
Copy link
Contributor Author

brunoerg commented Oct 9, 2024

If we're going to be peppering the code with these, could we add a safety harness to make sure it's never being used accidentally for a live node?

Seems good. Note that we're already use FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION to bypass CheckProofOfWork.

@fanquake
Copy link
Member

could we add a safety harness to make sure it's never being used accidentally for a live node?
Maybe somewhere in init.cpp or bitcoind.cpp:
Edit: I realize that bitcoind should be disabled in that case. This would be belt-and-suspenders to make sure that always holds.

Just want to note that putting something in either of these files wouldn't be enough to prevent someone producing a kernel lib with the fuzzing code.

@maflcko
Copy link
Member

maflcko commented Oct 10, 2024

I think we could consider removing the honggfuzz netdriver instructions in a follow

Not sure about touching real code with the motivation to make instructions happy that may be removed anyway.

If the changes are meaningful for the fuzz target, then it may be fine.

It also makes the p2p_transport_serialization fuzz target simpler since we do not need to assist the network magic and checksum creation anymore.

Can you provide more details here? IIUC a hash will still be calculated, just not compared, so this may only drop one hash call, with a possible maximum speed-up of 2x. However, it would be good to actually measure the difference. Otherwise, I am not sure if this is worth it.

@brunoerg
Copy link
Contributor Author

Can you provide more details here? IIUC a hash will still be calculated, just not compared, so this may only drop one hash call, with a possible maximum speed-up of 2x. However, it would be good to actually measure the difference. Otherwise, I am not sure if this is worth it.

This is not about performance. It makes the p2p_transport_serialization fuzz target simpler because we can remove the code that assists the checksum and magic bytes creation. So, we can achieve the same with less LoC.

@maflcko
Copy link
Member

maflcko commented Oct 10, 2024

Ok, then I am nack-ish on this. Generally, test code should follow real code, not the other way round, unless there is a reason. Saving 15 lines of test-only code seems a weak reason to me, but I don't mind if others like this.

@brunoerg
Copy link
Contributor Author

Since everyone agrees on removing Honggfuzz netdriver, I think we can change the approach to simply just remove it from the documentation.

@brunoerg
Copy link
Contributor Author

Closing this in favor of #31092

@brunoerg brunoerg closed this Oct 15, 2024
fanquake added a commit that referenced this pull request Oct 15, 2024
d823ba6 doc: fuzz: remove Honggfuzz NetDriver instructions (brunoerg)

Pull request description:

  Remove Honggfuzz NetDriver instructions from the documentation since it has not been useful for us. See #30957 and #31012.

ACKs for top commit:
  maflcko:
    lgtm ACK d823ba6
  marcofleon:
    ACK d823ba6

Tree-SHA512: f63fde1076d523dc5e511ef868ca3c1ea2e38fe7df56ae275f33209581f96452d86effedb54d9b0ee8b7a1d492b610799807a727d8bd81e2286d31db4aa68731
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: "Fuzzing the Bitcoin Core P2P layer using Honggfuzz NetDriver" is outdated

7 participants