diff --git a/fuzz/lnwire/accept_channel.go b/fuzz/lnwire/accept_channel.go new file mode 100644 index 00000000..1f702825 --- /dev/null +++ b/fuzz/lnwire/accept_channel.go @@ -0,0 +1,135 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "bytes" + + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_accept_channel is used by go-fuzz. +func Fuzz_accept_channel(data []byte) int { + // Prefix with MsgAcceptChannel. + data = prefixWithMsgType(data, lnwire.MsgAcceptChannel) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.AcceptChannel{} + + // We have to do this here instead of in fuzz.Harness so that + // reflect.DeepEqual isn't called. Because of the UpfrontShutdownScript + // encoding, the first message and second message aren't deeply equal since + // the first has a nil slice and the other has an empty slice. + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Make sure byte array length (excluding 2 bytes for message type) is + // less than max payload size for the wire message. We check this because + // otherwise `go-fuzz` will keep creating inputs that crash on ReadMessage + // due to a large message size. + payloadLen := uint32(len(data)) - 2 + if payloadLen > emptyMsg.MaxPayloadLength(0) { + // Ignore this input - max payload constraint violated. + return -1 + } + + msg, err := lnwire.ReadMessage(r, 0) + if err != nil { + // go-fuzz generated []byte that cannot be represented as a + // wire message but we will return 0 so go-fuzz can modify the + // input. + return 0 + } + + // We will serialize the message into a new bytes buffer. + var b bytes.Buffer + if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil { + // Could not serialize message into bytes buffer, panic + panic(err) + } + + // Deserialize the message from the serialized bytes buffer, and then + // assert that the original message is equal to the newly deserialized + // message. + newMsg, err := lnwire.ReadMessage(&b, 0) + if err != nil { + // Could not deserialize message from bytes buffer, panic + panic(err) + } + + // Now compare every field instead of using reflect.DeepEqual. + // For UpfrontShutdownScript, we only compare bytes. This probably takes + // up more branches than necessary, but that's fine for now. + var shouldPanic bool + first := msg.(*lnwire.AcceptChannel) + second := newMsg.(*lnwire.AcceptChannel) + + if !bytes.Equal(first.PendingChannelID[:], second.PendingChannelID[:]) { + shouldPanic = true + } + + if first.DustLimit != second.DustLimit { + shouldPanic = true + } + + if first.MaxValueInFlight != second.MaxValueInFlight { + shouldPanic = true + } + + if first.ChannelReserve != second.ChannelReserve { + shouldPanic = true + } + + if first.HtlcMinimum != second.HtlcMinimum { + shouldPanic = true + } + + if first.MinAcceptDepth != second.MinAcceptDepth { + shouldPanic = true + } + + if first.CsvDelay != second.CsvDelay { + shouldPanic = true + } + + if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs { + shouldPanic = true + } + + if !first.FundingKey.IsEqual(second.FundingKey) { + shouldPanic = true + } + + if !first.RevocationPoint.IsEqual(second.RevocationPoint) { + shouldPanic = true + } + + if !first.PaymentPoint.IsEqual(second.PaymentPoint) { + shouldPanic = true + } + + if !first.DelayedPaymentPoint.IsEqual(second.DelayedPaymentPoint) { + shouldPanic = true + } + + if !first.HtlcPoint.IsEqual(second.HtlcPoint) { + shouldPanic = true + } + + if !first.FirstCommitmentPoint.IsEqual(second.FirstCommitmentPoint) { + shouldPanic = true + } + + if !bytes.Equal(first.UpfrontShutdownScript, second.UpfrontShutdownScript) { + shouldPanic = true + } + + if shouldPanic { + panic("original message and deserialized message are not equal") + } + + // Add this input to the corpus. + return 1 +} diff --git a/fuzz/lnwire/announce_signatures.go b/fuzz/lnwire/announce_signatures.go new file mode 100644 index 00000000..048cf5ab --- /dev/null +++ b/fuzz/lnwire/announce_signatures.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_announce_signatures is used by go-fuzz. +func Fuzz_announce_signatures(data []byte) int { + // Prefix with MsgAnnounceSignatures. + data = prefixWithMsgType(data, lnwire.MsgAnnounceSignatures) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.AnnounceSignatures{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/channel_announcement.go b/fuzz/lnwire/channel_announcement.go new file mode 100644 index 00000000..771df5d1 --- /dev/null +++ b/fuzz/lnwire/channel_announcement.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_channel_announcement is used by go-fuzz. +func Fuzz_channel_announcement(data []byte) int { + // Prefix with MsgChannelAnnouncement. + data = prefixWithMsgType(data, lnwire.MsgChannelAnnouncement) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.ChannelAnnouncement{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/channel_reestablish.go b/fuzz/lnwire/channel_reestablish.go new file mode 100644 index 00000000..08cca9a5 --- /dev/null +++ b/fuzz/lnwire/channel_reestablish.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_channel_reestablish is used by go-fuzz. +func Fuzz_channel_reestablish(data []byte) int { + // Prefix with MsgChannelReestablish. + data = prefixWithMsgType(data, lnwire.MsgChannelReestablish) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.ChannelReestablish{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/channel_update.go b/fuzz/lnwire/channel_update.go new file mode 100644 index 00000000..993181f7 --- /dev/null +++ b/fuzz/lnwire/channel_update.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_channel_update is used by go-fuzz. +func Fuzz_channel_update(data []byte) int { + // Prefix with MsgChannelUpdate. + data = prefixWithMsgType(data, lnwire.MsgChannelUpdate) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.ChannelUpdate{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/closing_signed.go b/fuzz/lnwire/closing_signed.go new file mode 100644 index 00000000..b6898a7c --- /dev/null +++ b/fuzz/lnwire/closing_signed.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_closing_signed is used by go-fuzz. +func Fuzz_closing_signed(data []byte) int { + // Prefix with MsgClosingSigned. + data = prefixWithMsgType(data, lnwire.MsgClosingSigned) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.ClosingSigned{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/commit_sig.go b/fuzz/lnwire/commit_sig.go new file mode 100644 index 00000000..6f9c76ec --- /dev/null +++ b/fuzz/lnwire/commit_sig.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_commit_sig is used by go-fuzz. +func Fuzz_commit_sig(data []byte) int { + // Prefix with MsgCommitSig. + data = prefixWithMsgType(data, lnwire.MsgCommitSig) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.CommitSig{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/error.go b/fuzz/lnwire/error.go new file mode 100644 index 00000000..8b5dd671 --- /dev/null +++ b/fuzz/lnwire/error.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_error is used by go-fuzz. +func Fuzz_error(data []byte) int { + // Prefix with MsgError. + data = prefixWithMsgType(data, lnwire.MsgError) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.Error{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/funding_created.go b/fuzz/lnwire/funding_created.go new file mode 100644 index 00000000..ffdb3390 --- /dev/null +++ b/fuzz/lnwire/funding_created.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_funding_created is used by go-fuzz. +func Fuzz_funding_created(data []byte) int { + // Prefix with MsgFundingCreated. + data = prefixWithMsgType(data, lnwire.MsgFundingCreated) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.FundingCreated{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/funding_locked.go b/fuzz/lnwire/funding_locked.go new file mode 100644 index 00000000..aa5d2c26 --- /dev/null +++ b/fuzz/lnwire/funding_locked.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_funding_locked is used by go-fuzz. +func Fuzz_funding_locked(data []byte) int { + // Prefix with MsgFundingLocked. + data = prefixWithMsgType(data, lnwire.MsgFundingLocked) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.FundingLocked{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/funding_signed.go b/fuzz/lnwire/funding_signed.go new file mode 100644 index 00000000..47f2bfd0 --- /dev/null +++ b/fuzz/lnwire/funding_signed.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_funding_signed is used by go-fuzz. +func Fuzz_funding_signed(data []byte) int { + // Prefix with MsgFundingSigned. + prefixWithMsgType(data, lnwire.MsgFundingSigned) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.FundingSigned{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/fuzz_utils.go b/fuzz/lnwire/fuzz_utils.go new file mode 100644 index 00000000..767f602a --- /dev/null +++ b/fuzz/lnwire/fuzz_utils.go @@ -0,0 +1,72 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "bytes" + "encoding/binary" + "reflect" + + "github.com/lightningnetwork/lnd/lnwire" +) + +// prefixWithMsgType takes []byte and adds a wire protocol prefix +// to make the []byte into an actual message to be used in fuzzing. +func prefixWithMsgType(data []byte, prefix lnwire.MessageType) []byte { + var prefixBytes [2]byte + binary.BigEndian.PutUint16(prefixBytes[:], uint16(prefix)) + data = append(prefixBytes[:], data...) + return data +} + +// harness performs the actual fuzz testing of the appropriate wire message. +// This function will check that the passed-in message passes wire length checks, +// is a valid message once deserialized, and passes a sequence of serialization +// and deserialization checks. Returns an int that determines whether the input +// is unique or not. +func harness(data []byte, emptyMsg lnwire.Message) int { + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Make sure byte array length (excluding 2 bytes for message type) is + // less than max payload size for the wire message. We check this because + // otherwise `go-fuzz` will keep creating inputs that crash on ReadMessage + // due to a large message size. + payloadLen := uint32(len(data)) - 2 + if payloadLen > emptyMsg.MaxPayloadLength(0) { + // Ignore this input - max payload constraint violated. + return -1 + } + + msg, err := lnwire.ReadMessage(r, 0) + if err != nil { + // go-fuzz generated []byte that cannot be represented as a + // wire message but we will return 0 so go-fuzz can modify the + // input. + return 0 + } + + // We will serialize the message into a new bytes buffer. + var b bytes.Buffer + if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil { + // Could not serialize message into bytes buffer, panic + panic(err) + } + + // Deserialize the message from the serialized bytes buffer, and then + // assert that the original message is equal to the newly deserialized + // message. + newMsg, err := lnwire.ReadMessage(&b, 0) + if err != nil { + // Could not deserialize message from bytes buffer, panic + panic(err) + } + + if !reflect.DeepEqual(msg, newMsg) { + // Deserialized message and original message are not deeply equal. + panic("original message and deserialized message are not deeply equal") + } + + // Add this input to the corpus. + return 1 +} diff --git a/fuzz/lnwire/gossip_timestamp_range.go b/fuzz/lnwire/gossip_timestamp_range.go new file mode 100644 index 00000000..9e5e4f11 --- /dev/null +++ b/fuzz/lnwire/gossip_timestamp_range.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_gossip_timestamp_range is used by go-fuzz. +func Fuzz_gossip_timestamp_range(data []byte) int { + // Prefix with MsgGossipTimestampRange. + data = prefixWithMsgType(data, lnwire.MsgGossipTimestampRange) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.GossipTimestampRange{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/init.go b/fuzz/lnwire/init.go new file mode 100644 index 00000000..b2be1aba --- /dev/null +++ b/fuzz/lnwire/init.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_init is used by go-fuzz. +func Fuzz_init(data []byte) int { + // Prefix with MsgInit. + data = prefixWithMsgType(data, lnwire.MsgInit) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.Init{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/node_announcement.go b/fuzz/lnwire/node_announcement.go new file mode 100644 index 00000000..76eabe35 --- /dev/null +++ b/fuzz/lnwire/node_announcement.go @@ -0,0 +1,112 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "bytes" + "reflect" + + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_node_announcement is used by go-fuzz. +func Fuzz_node_announcement(data []byte) int { + // Prefix with MsgNodeAnnouncement. + data = prefixWithMsgType(data, lnwire.MsgNodeAnnouncement) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.NodeAnnouncement{} + + // We have to do this here instead of in fuzz.Harness so that + // reflect.DeepEqual isn't called. Address (de)serialization messes up + // the fuzzing assertions. + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Make sure byte array length (excluding 2 bytes for message type) is + // less than max payload size for the wire message. We check this because + // otherwise `go-fuzz` will keep creating inputs that crash on ReadMessage + // due to a large message size. + payloadLen := uint32(len(data)) - 2 + if payloadLen > emptyMsg.MaxPayloadLength(0) { + // Ignore this input - max payload constraint violated. + return -1 + } + + msg, err := lnwire.ReadMessage(r, 0) + if err != nil { + // go-fuzz generated []byte that cannot be represented as a + // wire message but we will return 0 so go-fuzz can modify the + // input. + return 0 + } + + // We will serialize the message into a new bytes buffer. + var b bytes.Buffer + if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil { + // Could not serialize message into bytes buffer, panic + panic(err) + } + + // Deserialize the message from the serialized bytes buffer, and then + // assert that the original message is equal to the newly deserialized + // message. + newMsg, err := lnwire.ReadMessage(&b, 0) + if err != nil { + // Could not deserialize message from bytes buffer, panic + panic(err) + } + + // Now compare every field instead of using reflect.DeepEqual for the + // Addresses field. + var shouldPanic bool + first := msg.(*lnwire.NodeAnnouncement) + second := newMsg.(*lnwire.NodeAnnouncement) + if !bytes.Equal(first.Signature[:], second.Signature[:]) { + shouldPanic = true + } + + if !reflect.DeepEqual(first.Features, second.Features) { + shouldPanic = true + } + + if first.Timestamp != second.Timestamp { + shouldPanic = true + } + + if !bytes.Equal(first.NodeID[:], second.NodeID[:]) { + shouldPanic = true + } + + if !reflect.DeepEqual(first.RGBColor, second.RGBColor) { + shouldPanic = true + } + + if !bytes.Equal(first.Alias[:], second.Alias[:]) { + shouldPanic = true + } + + if len(first.Addresses) != len(second.Addresses) { + shouldPanic = true + } + + for i := range first.Addresses { + if first.Addresses[i].String() != second.Addresses[i].String() { + shouldPanic = true + break + } + } + + if !reflect.DeepEqual(first.ExtraOpaqueData, second.ExtraOpaqueData) { + shouldPanic = true + } + + if shouldPanic { + panic("original message and deserialized message are not equal") + } + + // Add this input to the corpus. + return 1 +} diff --git a/fuzz/lnwire/open_channel.go b/fuzz/lnwire/open_channel.go new file mode 100644 index 00000000..ddd268cc --- /dev/null +++ b/fuzz/lnwire/open_channel.go @@ -0,0 +1,151 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "bytes" + + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_open_channel is used by go-fuzz. +func Fuzz_open_channel(data []byte) int { + // Prefix with MsgOpenChannel. + data = prefixWithMsgType(data, lnwire.MsgOpenChannel) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.OpenChannel{} + + // We have to do this here instead of in fuzz.Harness so that + // reflect.DeepEqual isn't called. Because of the UpfrontShutdownScript + // encoding, the first message and second message aren't deeply equal since + // the first has a nil slice and the other has an empty slice. + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Make sure byte array length (excluding 2 bytes for message type) is + // less than max payload size for the wire message. We check this because + // otherwise `go-fuzz` will keep creating inputs that crash on ReadMessage + // due to a large message size. + payloadLen := uint32(len(data)) - 2 + if payloadLen > emptyMsg.MaxPayloadLength(0) { + // Ignore this input - max payload constraint violated. + return -1 + } + + msg, err := lnwire.ReadMessage(r, 0) + if err != nil { + // go-fuzz generated []byte that cannot be represented as a + // wire message but we will return 0 so go-fuzz can modify the + // input. + return 0 + } + + // We will serialize the message into a new bytes buffer. + var b bytes.Buffer + if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil { + // Could not serialize message into bytes buffer, panic + panic(err) + } + + // Deserialize the message from the serialized bytes buffer, and then + // assert that the original message is equal to the newly deserialized + // message. + newMsg, err := lnwire.ReadMessage(&b, 0) + if err != nil { + // Could not deserialize message from bytes buffer, panic + panic(err) + } + + // Now compare every field instead of using reflect.DeepEqual. + // For UpfrontShutdownScript, we only compare bytes. This probably takes + // up more branches than necessary, but that's fine for now. + var shouldPanic bool + first := msg.(*lnwire.OpenChannel) + second := newMsg.(*lnwire.OpenChannel) + + if !first.ChainHash.IsEqual(&second.ChainHash) { + shouldPanic = true + } + + if !bytes.Equal(first.PendingChannelID[:], second.PendingChannelID[:]) { + shouldPanic = true + } + + if first.FundingAmount != second.FundingAmount { + shouldPanic = true + } + + if first.PushAmount != second.PushAmount { + shouldPanic = true + } + + if first.DustLimit != second.DustLimit { + shouldPanic = true + } + + if first.MaxValueInFlight != second.MaxValueInFlight { + shouldPanic = true + } + + if first.ChannelReserve != second.ChannelReserve { + shouldPanic = true + } + + if first.HtlcMinimum != second.HtlcMinimum { + shouldPanic = true + } + + if first.FeePerKiloWeight != second.FeePerKiloWeight { + shouldPanic = true + } + + if first.CsvDelay != second.CsvDelay { + shouldPanic = true + } + + if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs { + shouldPanic = true + } + + if !first.FundingKey.IsEqual(second.FundingKey) { + shouldPanic = true + } + + if !first.RevocationPoint.IsEqual(second.RevocationPoint) { + shouldPanic = true + } + + if !first.PaymentPoint.IsEqual(second.PaymentPoint) { + shouldPanic = true + } + + if !first.DelayedPaymentPoint.IsEqual(second.DelayedPaymentPoint) { + shouldPanic = true + } + + if !first.HtlcPoint.IsEqual(second.HtlcPoint) { + shouldPanic = true + } + + if !first.FirstCommitmentPoint.IsEqual(second.FirstCommitmentPoint) { + shouldPanic = true + } + + if first.ChannelFlags != second.ChannelFlags { + shouldPanic = true + } + + if !bytes.Equal(first.UpfrontShutdownScript, second.UpfrontShutdownScript) { + shouldPanic = true + } + + if shouldPanic { + panic("original message and deserialized message are not equal") + } + + // Add this input to the corpus. + return 1 +} diff --git a/fuzz/lnwire/ping.go b/fuzz/lnwire/ping.go new file mode 100644 index 00000000..87e893e0 --- /dev/null +++ b/fuzz/lnwire/ping.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_ping is used by go-fuzz. +func Fuzz_ping(data []byte) int { + // Prefix with MsgPing. + data = prefixWithMsgType(data, lnwire.MsgPing) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.Ping{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/pong.go b/fuzz/lnwire/pong.go new file mode 100644 index 00000000..b51e3152 --- /dev/null +++ b/fuzz/lnwire/pong.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_pong is used by go-fuzz. +func Fuzz_pong(data []byte) int { + // Prefix with MsgPong. + data = prefixWithMsgType(data, lnwire.MsgPong) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.Pong{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/query_channel_range.go b/fuzz/lnwire/query_channel_range.go new file mode 100644 index 00000000..38f5f4d7 --- /dev/null +++ b/fuzz/lnwire/query_channel_range.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_query_channel_range is used by go-fuzz. +func Fuzz_query_channel_range(data []byte) int { + // Prefix with MsgQueryChannelRange. + data = prefixWithMsgType(data, lnwire.MsgQueryChannelRange) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.QueryChannelRange{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/query_short_chan_ids.go b/fuzz/lnwire/query_short_chan_ids.go new file mode 100644 index 00000000..b0adb879 --- /dev/null +++ b/fuzz/lnwire/query_short_chan_ids.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_query_short_chan_ids is used by go-fuzz. +func Fuzz_query_short_chan_ids(data []byte) int { + // Prefix with MsgQueryShortChanIDs. + data = prefixWithMsgType(data, lnwire.MsgQueryShortChanIDs) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.QueryShortChanIDs{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/query_short_chan_ids_zlib.go b/fuzz/lnwire/query_short_chan_ids_zlib.go new file mode 100644 index 00000000..7b2061d7 --- /dev/null +++ b/fuzz/lnwire/query_short_chan_ids_zlib.go @@ -0,0 +1,51 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "bytes" + "compress/zlib" + "encoding/binary" + + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_query_short_chan_ids_zlib is used by go-fuzz. +func Fuzz_query_short_chan_ids_zlib(data []byte) int { + + var buf bytes.Buffer + zlibWriter := zlib.NewWriter(&buf) + _, err := zlibWriter.Write(data) + if err != nil { + // Zlib bug? + panic(err) + } + + if err := zlibWriter.Close(); err != nil { + // Zlib bug? + panic(err) + } + + compressedPayload := buf.Bytes() + + chainhash := []byte("00000000000000000000000000000000") + numBytesInBody := len(compressedPayload) + 1 + zlibByte := []byte("\x01") + + bodyBytes := make([]byte, 2) + binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody)) + + payload := append(chainhash, bodyBytes...) + payload = append(payload, zlibByte...) + payload = append(payload, compressedPayload...) + + // Prefix with MsgQueryShortChanIDs. + payload = prefixWithMsgType(payload, lnwire.MsgQueryShortChanIDs) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.QueryShortChanIDs{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(payload, &emptyMsg) +} diff --git a/fuzz/lnwire/reply_channel_range.go b/fuzz/lnwire/reply_channel_range.go new file mode 100644 index 00000000..3bfdbf36 --- /dev/null +++ b/fuzz/lnwire/reply_channel_range.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_reply_channel_range is used by go-fuzz. +func Fuzz_reply_channel_range(data []byte) int { + // Prefix with MsgReplyChannelRange. + data = prefixWithMsgType(data, lnwire.MsgReplyChannelRange) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.ReplyChannelRange{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/reply_channel_range_zlib.go b/fuzz/lnwire/reply_channel_range_zlib.go new file mode 100644 index 00000000..944d1fa1 --- /dev/null +++ b/fuzz/lnwire/reply_channel_range_zlib.go @@ -0,0 +1,59 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "bytes" + "compress/zlib" + "encoding/binary" + + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_reply_channel_range_zlib is used by go-fuzz. +func Fuzz_reply_channel_range_zlib(data []byte) int { + + var buf bytes.Buffer + zlibWriter := zlib.NewWriter(&buf) + _, err := zlibWriter.Write(data) + if err != nil { + // Zlib bug? + panic(err) + } + + if err := zlibWriter.Close(); err != nil { + // Zlib bug? + panic(err) + } + + compressedPayload := buf.Bytes() + + // Initialize some []byte vars which will prefix our payload + chainhash := []byte("00000000000000000000000000000000") + firstBlockHeight := []byte("\x00\x00\x00\x00") + numBlocks := []byte("\x00\x00\x00\x00") + completeByte := []byte("\x00") + + numBytesInBody := len(compressedPayload) + 1 + zlibByte := []byte("\x01") + + bodyBytes := make([]byte, 2) + binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody)) + + payload := append(chainhash, firstBlockHeight...) + payload = append(payload, numBlocks...) + payload = append(payload, completeByte...) + payload = append(payload, bodyBytes...) + payload = append(payload, zlibByte...) + payload = append(payload, compressedPayload...) + + // Prefix with MsgReplyChannelRange. + payload = prefixWithMsgType(payload, lnwire.MsgReplyChannelRange) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.ReplyChannelRange{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(payload, &emptyMsg) +} diff --git a/fuzz/lnwire/reply_short_chan_ids_end.go b/fuzz/lnwire/reply_short_chan_ids_end.go new file mode 100644 index 00000000..c09282d9 --- /dev/null +++ b/fuzz/lnwire/reply_short_chan_ids_end.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_reply_short_chan_ids_end is used by go-fuzz. +func Fuzz_reply_short_chan_ids_end(data []byte) int { + // Prefix with MsgReplyShortChanIDsEnd. + data = prefixWithMsgType(data, lnwire.MsgReplyShortChanIDsEnd) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.ReplyShortChanIDsEnd{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/revoke_and_ack.go b/fuzz/lnwire/revoke_and_ack.go new file mode 100644 index 00000000..23951c35 --- /dev/null +++ b/fuzz/lnwire/revoke_and_ack.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_revoke_and_ack is used by go-fuzz. +func Fuzz_revoke_and_ack(data []byte) int { + // Prefix with MsgRevokeAndAck. + data = prefixWithMsgType(data, lnwire.MsgRevokeAndAck) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.RevokeAndAck{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/shutdown.go b/fuzz/lnwire/shutdown.go new file mode 100644 index 00000000..1ffd8660 --- /dev/null +++ b/fuzz/lnwire/shutdown.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_shutdown is used by go-fuzz. +func Fuzz_shutdown(data []byte) int { + // Prefix with MsgShutdown. + data = prefixWithMsgType(data, lnwire.MsgShutdown) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.Shutdown{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/update_add_htlc.go b/fuzz/lnwire/update_add_htlc.go new file mode 100644 index 00000000..570de741 --- /dev/null +++ b/fuzz/lnwire/update_add_htlc.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_update_add_htlc is used by go-fuzz. +func Fuzz_update_add_htlc(data []byte) int { + // Prefix with MsgUpdateAddHTLC. + data = prefixWithMsgType(data, lnwire.MsgUpdateAddHTLC) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.UpdateAddHTLC{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/update_fail_htlc.go b/fuzz/lnwire/update_fail_htlc.go new file mode 100644 index 00000000..4ef9ab88 --- /dev/null +++ b/fuzz/lnwire/update_fail_htlc.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_update_fail_htlc is used by go-fuzz. +func Fuzz_update_fail_htlc(data []byte) int { + // Prefix with MsgUpdateFailHTLC. + data = prefixWithMsgType(data, lnwire.MsgUpdateFailHTLC) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.UpdateFailHTLC{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/update_fail_malformed_htlc.go b/fuzz/lnwire/update_fail_malformed_htlc.go new file mode 100644 index 00000000..0a0d45a6 --- /dev/null +++ b/fuzz/lnwire/update_fail_malformed_htlc.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_update_fail_malformed_htlc is used by go-fuzz. +func Fuzz_update_fail_malformed_htlc(data []byte) int { + // Prefix with MsgUpdateFailMalformedHTLC. + data = prefixWithMsgType(data, lnwire.MsgUpdateFailMalformedHTLC) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.UpdateFailMalformedHTLC{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/update_fee.go b/fuzz/lnwire/update_fee.go new file mode 100644 index 00000000..bb82c5c1 --- /dev/null +++ b/fuzz/lnwire/update_fee.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_update_fee is used by go-fuzz. +func Fuzz_update_fee(data []byte) int { + // Prefix with MsgUpdateFee. + data = prefixWithMsgType(data, lnwire.MsgUpdateFee) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.UpdateFee{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +} diff --git a/fuzz/lnwire/update_fulfill_htlc.go b/fuzz/lnwire/update_fulfill_htlc.go new file mode 100644 index 00000000..de28dfbe --- /dev/null +++ b/fuzz/lnwire/update_fulfill_htlc.go @@ -0,0 +1,20 @@ +// +build gofuzz + +package lnwirefuzz + +import ( + "github.com/lightningnetwork/lnd/lnwire" +) + +// Fuzz_update_fulfill_htlc is used by go-fuzz. +func Fuzz_update_fulfill_htlc(data []byte) int { + // Prefix with MsgUpdateFulfillHTLC. + data = prefixWithMsgType(data, lnwire.MsgUpdateFulfillHTLC) + + // Create an empty message so that the FuzzHarness func can check + // if the max payload constraint is violated. + emptyMsg := lnwire.UpdateFulfillHTLC{} + + // Pass the message into our general fuzz harness for wire messages! + return harness(data, &emptyMsg) +}