f82653cb06
This allows gofuzz to store the mutating input as coverage if it reaches any new coverage, even if it didn't make it to the end of the test.
76 lines
2.3 KiB
Go
76 lines
2.3 KiB
Go
// +build gofuzz
|
|
|
|
package wtwirefuzz
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"fmt"
|
|
"reflect"
|
|
|
|
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
|
)
|
|
|
|
// 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 wtwire.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 wtwire.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 := wtwire.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 1
|
|
}
|
|
|
|
// We will serialize the message into a new bytes buffer.
|
|
var b bytes.Buffer
|
|
if _, err := wtwire.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 := wtwire.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(fmt.Errorf("deserialized message and original message " +
|
|
"are not deeply equal."))
|
|
}
|
|
|
|
// Add this input to the corpus.
|
|
return 1
|
|
}
|