-
Notifications
You must be signed in to change notification settings - Fork 947
fuzz-tests: Add a test for the gossipd-connectd interface #8423
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
base: master
Are you sure you want to change the base?
Conversation
The test results in the following LeakSanitizer error when run on its corpus:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
High level review: I like the target. Needs some rework so we consider exit
to be a crash.
Haven't studied create_gossip_msg
yet.
tests/fuzz/fuzz-gossipd-connectd.c
Outdated
struct node_id id = node_id(privkey_from_index(tal_count(peer_ids))); | ||
tal_arr_expand(&peer_ids, id); | ||
|
||
msg = towire_gossipd_new_peer(tmpctx, &id, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting gossip_queries_feature = false
will limit some of the code paths that can be executed, especially all the seeker
stuff. If there's a good reason to do this, please add a comment here that explains why.
tests/fuzz/fuzz-gossipd-connectd.c
Outdated
switch (fromwire_u8(&data, &size) % 5) | ||
{ | ||
case 0: | ||
gossip_msg = create_gossip_msg(tmpctx, &data, &size, WIRE_CHANNEL_ANNOUNCEMENT); | ||
break; | ||
case 1: | ||
gossip_msg = create_gossip_msg(tmpctx, &data, &size, WIRE_CHANNEL_UPDATE); | ||
break; | ||
case 2: | ||
gossip_msg = create_gossip_msg(tmpctx, &data, &size, WIRE_NODE_ANNOUNCEMENT); | ||
break; | ||
case 3: | ||
gossip_msg = create_gossip_msg(tmpctx, &data, &size, WIRE_REPLY_CHANNEL_RANGE); | ||
break; | ||
case 4: | ||
gossip_msg = create_gossip_msg(tmpctx, &data, &size, WIRE_REPLY_SHORT_CHANNEL_IDS_END); | ||
break; | ||
default: | ||
break; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: perhaps this switch could go inside create_gossip_msg
, so there's one less parameter to pass.
|
||
cleanup: | ||
if (daemon) | ||
tal_free(daemon->connectd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the explicit tal_free
necessary? Naively it looks like clean_tmpctx
should take care of this already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to circumvent the dangling allocation error fixed in #8424 .
if (setjmp(exit_jmp) != 0) | ||
goto cleanup; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For gossipd, we actually shouldn't consider exit
to be normal. If gossipd exits, the entire CLN node shuts down, which would be a DoS vulnerability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This path can only be triggered by status_failed()
and towire_warningfmt()
.
I can get rid of the mock for towire_warningfmt()
by including common/wire_error.o
for linking. As for status_failed()
, I don't think triggering it would mean a vulnerability, it's used pretty liberally throughout gossipd/gossipd.c
to report a bad message from the peer. Maybe exit()
's behavior manifests differently in a live node than it does in our fuzzer (where it aborts the entire process).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any reason for us to quit the fuzz target for towire_warning_fmt
.
status_failed
means "print error and exit", and should never happen in the wild. If it does, it's a DoS vulnerability.
I looked closer at this. The accused line of code does a naked We might need to manually delete all elements from the gossmap at the end of each iteration. |
This makes the target a bit messier but does seem to manage to evade the issue at hand. |
Changelon-None: `connectd_req()` in `gossipd/gossipd.c` is responsible for handling gossip messages from peers handed to it by `connectd`. Add a stateful test simulating its behaviour.
Add a minimal input set as a seed corpus for the newly introduced test. This leads to discovery of interesting code paths faster.
448e689
to
4721eb2
Compare
connectd_req()
ingossipd/gossipd.c
is responsible for handling gossip messages from peers handed to it byconnectd
. Add a stateful test simulating its behaviour.Checklist
Before submitting the PR, ensure the following tasks are completed. If an item is not applicable to your PR, please mark it as checked:
CC: @morehouse