github.com/decred/dcrlnd@v0.7.6/fuzz/wtwire/fuzz_utils.go (about) 1 //go:build gofuzz 2 // +build gofuzz 3 4 package wtwirefuzz 5 6 import ( 7 "bytes" 8 "encoding/binary" 9 "fmt" 10 "reflect" 11 12 "github.com/decred/dcrlnd/watchtower/wtwire" 13 ) 14 15 // prefixWithMsgType takes []byte and adds a wire protocol prefix 16 // to make the []byte into an actual message to be used in fuzzing. 17 func prefixWithMsgType(data []byte, prefix wtwire.MessageType) []byte { 18 var prefixBytes [2]byte 19 binary.BigEndian.PutUint16(prefixBytes[:], uint16(prefix)) 20 data = append(prefixBytes[:], data...) 21 return data 22 } 23 24 // harness performs the actual fuzz testing of the appropriate wire message. 25 // This function will check that the passed-in message passes wire length checks, 26 // is a valid message once deserialized, and passes a sequence of serialization 27 // and deserialization checks. Returns an int that determines whether the input 28 // is unique or not. 29 func harness(data []byte, emptyMsg wtwire.Message) int { 30 // Create a reader with the byte array. 31 r := bytes.NewReader(data) 32 33 // Make sure byte array length (excluding 2 bytes for message type) is 34 // less than max payload size for the wire message. We check this because 35 // otherwise `go-fuzz` will keep creating inputs that crash on ReadMessage 36 // due to a large message size. 37 payloadLen := uint32(len(data)) - 2 38 if payloadLen > emptyMsg.MaxPayloadLength(0) { 39 // Ignore this input - max payload constraint violated. 40 return 1 41 } 42 43 msg, err := wtwire.ReadMessage(r, 0) 44 if err != nil { 45 // go-fuzz generated []byte that cannot be represented as a 46 // wire message but we will return 0 so go-fuzz can modify the 47 // input. 48 return 1 49 } 50 51 // We will serialize the message into a new bytes buffer. 52 var b bytes.Buffer 53 if _, err := wtwire.WriteMessage(&b, msg, 0); err != nil { 54 // Could not serialize message into bytes buffer, panic. 55 panic(err) 56 } 57 58 // Deserialize the message from the serialized bytes buffer, and then 59 // assert that the original message is equal to the newly deserialized 60 // message. 61 newMsg, err := wtwire.ReadMessage(&b, 0) 62 if err != nil { 63 // Could not deserialize message from bytes buffer, panic. 64 panic(err) 65 } 66 67 if !reflect.DeepEqual(msg, newMsg) { 68 // Deserialized message and original message are not 69 // deeply equal. 70 panic(fmt.Errorf("deserialized message and original message " + 71 "are not deeply equal.")) 72 } 73 74 // Add this input to the corpus. 75 return 1 76 }