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

tlv: fuzz test encoding/decoding #7889

Merged
merged 6 commits into from Oct 10, 2023
Merged

Conversation

morehouse
Copy link
Collaborator

Based on #4641.

Copy link
Collaborator

@yyforyongyu yyforyongyu left a comment

Choose a reason for hiding this comment

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

Sorry for the late review. Left some questions, and this PR needs a rebase.

// bytes unparsed from data, causing the encoded data to be shorter than the
// original.
func bigSizeHarness(t *testing.T, data []byte, val1, val2 interface{}) {
if len(data) > 9 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm starting to wonder how often this is hit and whether it deteriorates the efficacy of our test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It should increase efficacy, actually. Shorter inputs are faster for the fuzzer to generate, mutate, and execute. So by short-circuiting for inputs longer than necessary, we encourage the fuzzing engine to spend more time on smaller inputs.

Other fuzzing engines (e.g., libFuzzer, AFL) have a flag for max input size, which prevents the fuzzer from generating inputs larger than that. Go's fuzzing engine doesn't have such a flag, unfortunately.


var buf [8]byte
if err := DBigSize(r, val1, &buf, 9); err != nil {
return
Copy link
Collaborator

Choose a reason for hiding this comment

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

why can we return here instead of assertion?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not every byte sequence is a valid BigSize, so we shouldn't fail the test when we encounter an invalid sequence.

tlv/fuzz_test.go Outdated

func FuzzTUint64(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte, decodeLen uint8) {
if decodeLen > 8 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

what do you say if we just iterate from 0 to 7 here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 93cd750.

b64 [64]byte
pk *btcec.PublicKey
b []byte
bs32 uint32
Copy link
Collaborator

Choose a reason for hiding this comment

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

curious about what bs and tu stand for?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

BigSize and Truncated Uint.


var encodeRecords []Record
for typ, val := range parsedTypes {
if typ < Type(len(decodedRecords)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

would be helpful if we add some docs explaining why this check.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 5bb4df4.

We use a new harness to compare decoded values instead of encoded
values, since there may be some unparsed bytes in the original data.
These fuzz tests are identical to non-truncated integers, except that we
allow the fuzzer to choose decode lengths shorter than the length of
normal integers.
Copy link
Collaborator Author

@morehouse morehouse left a comment

Choose a reason for hiding this comment

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

Rebased and updated.

// bytes unparsed from data, causing the encoded data to be shorter than the
// original.
func bigSizeHarness(t *testing.T, data []byte, val1, val2 interface{}) {
if len(data) > 9 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It should increase efficacy, actually. Shorter inputs are faster for the fuzzer to generate, mutate, and execute. So by short-circuiting for inputs longer than necessary, we encourage the fuzzing engine to spend more time on smaller inputs.

Other fuzzing engines (e.g., libFuzzer, AFL) have a flag for max input size, which prevents the fuzzer from generating inputs larger than that. Go's fuzzing engine doesn't have such a flag, unfortunately.


var buf [8]byte
if err := DBigSize(r, val1, &buf, 9); err != nil {
return
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not every byte sequence is a valid BigSize, so we shouldn't fail the test when we encounter an invalid sequence.

tlv/fuzz_test.go Outdated

func FuzzTUint64(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte, decodeLen uint8) {
if decodeLen > 8 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 93cd750.

b64 [64]byte
pk *btcec.PublicKey
b []byte
bs32 uint32
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

BigSize and Truncated Uint.


var encodeRecords []Record
for typ, val := range parsedTypes {
if typ < Type(len(decodedRecords)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 5bb4df4.

@saubyk saubyk added this to the v0.18.0 milestone Oct 5, 2023
@lightninglabs-deploy
Copy link

@yyforyongyu: review reminder

Copy link
Collaborator

@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.

looks good, will test locally

Copy link
Collaborator

@yyforyongyu yyforyongyu left a comment

Choose a reason for hiding this comment

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

LGTM🙏

@guggero guggero merged commit 2d98dcf into lightningnetwork:master Oct 10, 2023
23 of 25 checks passed
@morehouse morehouse deleted the fuzz_tlv branch October 10, 2023 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

6 participants