fuzz: add fuzz target for P2PGossipSync gossip message handling#4532
fuzz: add fuzz target for P2PGossipSync gossip message handling#4532NishantBansal2003 wants to merge 1 commit intolightningdevkit:mainfrom
Conversation
|
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
cb9e2a8 to
d29150d
Compare
|
I've completed a thorough review of the entire diff, checking every file and hunk. I also verified the underlying implementations that the assertions depend on ( All three issues from the prior review have been addressed:
No new issues found. The fuzz target is correct:
No issues found. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4532 +/- ##
=======================================
Coverage 87.10% 87.11%
=======================================
Files 163 163
Lines 108740 108740
Branches 108740 108740
=======================================
+ Hits 94723 94730 +7
+ Misses 11531 11526 -5
+ Partials 2486 2484 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
TheBlueMatt
left a comment
There was a problem hiding this comment.
Cool, thanks! Have you run any comparisons on the coverage of this vs the router fuzzer? I'm wondering if it makes sense to add a new fuzzer here or focus more CPU on the router fuzzer given it tests very similar codepaths.
Coverage wise, the additional benefit is that P2PGossipSync also gets covered, so that's a plus. My main goal was to cover all announcement messages in the fuzz tests (which the One option is to extend the OR, we can keep a separate fuzz target ( WDYT? I'm fine with either approach since both will ultimately achieve full coverage of gossip message processing. |
|
🔔 1st Reminder Hey @joostjager! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @joostjager! This PR has been waiting for your review. |
TheBlueMatt
left a comment
There was a problem hiding this comment.
Hmm, yea, I suppose the goal is sufficiently different that it makes sense to just ship a separate fuzzer. What could go wrong, anyway? :)
fuzz/src/gossip_discovery.rs
Outdated
| excess_data, | ||
| }; | ||
|
|
||
| if mutate_field!() { |
There was a problem hiding this comment.
I'm not entirely sure its worth all the effort for creative message building - should we instead just read a length and then deserialize N bytes as each message and process it?
There was a problem hiding this comment.
I followed your suggestion and used a decode method to fill the inputs (mostly taken from router.rs). The reason for doing this is that the code is now somewhat reduced. But, the downside is that some fuzz input gets wasted due to being overwritten. I think it’s fine?
The reason I initially did manual field parsing is i want the fuzz tests to cover P2P gossip sync e2e, including sign verify and raw fuzz input won't penetrate sign verification, so we need to define some valid fields manually
There was a problem hiding this comment.
including sign verify and raw fuzz input won't penetrate sign verification
We deliberately use broken signatures and hash function in fuzzing so the fuzzer should be able to do this, even if its a bit of work (usually just all-0s and a single byte).
There was a problem hiding this comment.
Great, I saw the code in rust-secp256k1 and noticed that with the secp256k1_fuzz flag, there is a fuzzed implementation of secp256k1_ecdsa_verify (https://github.com/rust-bitcoin/rust-secp256k1/blob/master/secp256k1-sys/src/lib.rs#L1828-L1845). So, I think it's fine to remove the manual message building. Working on it now
fuzz/src/gossip_discovery.rs
Outdated
| let mut node_ann = decode_msg!(msgs::NodeAnnouncement); | ||
| let peer = get_peer!(); | ||
|
|
||
| maybe_set!(node_ann.contents.node_id, NodeId::from_pubkey(&peer.node_id)); |
There was a problem hiding this comment.
What's the point of maybe_set vs just letting the fuzzer pick the values it wants?
There was a problem hiding this comment.
Yes, I was running the fuzzer, so I hadn't committed the changes. But now committed
So, maybe_set has been removed in the latest commit, and the fuzzer now directly picks values.
8ea1d00 to
e678f90
Compare
Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>
e678f90 to
d0f1f39
Compare
|
🔔 3rd Reminder Hey @TheBlueMatt @joostjager! This PR has been waiting for your review. |
Added gossip state machine fuzz tests for gossip discovery state handling. In these fuzz tests, we read bytes from the fuzz input to determine actions such as connecting peers, feeding channel announcements, node announcements, channel updates, or query messages. Both valid and malformed messages are generated to exercise error paths.
The reason for adding these fuzz tests is that
P2PGossipSyncis the ultimate sink for gossip messages received from peers, so there must not be any crashes or unintended behavior in LDK when handling messages from potentially malicious peers.I only included the states that LDK currently handles. For example, I did not add
reply_channel_rangeorquery_scidsmessages since LDK does not process them at the moment. Similarly, sinceP2PGossipSyncdoes not handlegossip_timestamp_filter, it is not included in these fuzz tests. Additionally, there is limited benefit in fuzzinggossip_timestamp_filterin LDK, as it is typically processed only once per peer and involves minimal logical processing.