fuzz.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // +build gofuzz
  2. package stun
  3. import (
  4. "encoding/binary"
  5. "fmt"
  6. )
  7. var (
  8. m = New()
  9. )
  10. // FuzzMessage is go-fuzz endpoint for message.
  11. func FuzzMessage(data []byte) int {
  12. m.Reset()
  13. // fuzzer dont know about cookies
  14. binary.BigEndian.PutUint32(data[4:8], magicCookie)
  15. // trying to read data as message
  16. if _, err := m.Write(data); err != nil {
  17. return 0
  18. }
  19. m2 := New()
  20. if _, err := m2.Write(m.Raw); err != nil {
  21. panic(err) // nolint
  22. }
  23. if m2.TransactionID != m.TransactionID {
  24. panic("transaction ID mismatch") // nolint
  25. }
  26. if m2.Type != m.Type {
  27. panic("type missmatch") // nolint
  28. }
  29. if len(m2.Attributes) != len(m.Attributes) {
  30. panic("attributes length missmatch") // nolint
  31. }
  32. return 1
  33. }
  34. // FuzzType is go-fuzz endpoint for message type.
  35. func FuzzType(data []byte) int {
  36. t := MessageType{}
  37. vt, _ := binary.Uvarint(data)
  38. v := uint16(vt) & 0x1fff // first 3 bits are empty
  39. t.ReadValue(v)
  40. v2 := t.Value()
  41. if v != v2 {
  42. panic("v != v2") // nolint
  43. }
  44. t2 := MessageType{}
  45. t2.ReadValue(v2)
  46. if t2 != t {
  47. panic("t2 != t") // nolint
  48. }
  49. return 0
  50. }
  51. type attr interface {
  52. Getter
  53. Setter
  54. }
  55. type attrs []struct {
  56. g attr
  57. t AttrType
  58. }
  59. func (a attrs) pick(v byte) struct {
  60. g attr
  61. t AttrType
  62. } {
  63. idx := int(v) % len(a)
  64. return a[idx]
  65. }
  66. func FuzzSetters(data []byte) int {
  67. var (
  68. m1 = &Message{
  69. Raw: make([]byte, 0, 2048),
  70. }
  71. m2 = &Message{
  72. Raw: make([]byte, 0, 2048),
  73. }
  74. m3 = &Message{
  75. Raw: make([]byte, 0, 2048),
  76. }
  77. )
  78. attributes := attrs{
  79. {new(Realm), AttrRealm},
  80. {new(XORMappedAddress), AttrXORMappedAddress},
  81. {new(Nonce), AttrNonce},
  82. {new(Software), AttrSoftware},
  83. {new(AlternateServer), AttrAlternateServer},
  84. {new(ErrorCodeAttribute), AttrErrorCode},
  85. {new(UnknownAttributes), AttrUnknownAttributes},
  86. {new(Username), AttrUsername},
  87. {new(MappedAddress), AttrMappedAddress},
  88. {new(Realm), AttrRealm},
  89. }
  90. var firstByte = byte(0)
  91. if len(data) > 0 {
  92. firstByte = data[0]
  93. }
  94. a := attributes.pick(firstByte)
  95. value := data
  96. if len(data) > 1 {
  97. value = value[1:]
  98. }
  99. m1.WriteHeader()
  100. m1.Add(a.t, value)
  101. err := a.g.GetFrom(m1)
  102. if err == ErrAttributeNotFound {
  103. fmt.Println("unexpected 404") // nolint
  104. panic(err) // nolint
  105. }
  106. if err != nil {
  107. return 1
  108. }
  109. m2.WriteHeader()
  110. if err = a.g.AddTo(m2); err != nil {
  111. // We allow decoding some text attributes
  112. // when their length is too big, but
  113. // not encoding.
  114. if !IsAttrSizeOverflow(err) {
  115. panic(err) // nolint
  116. }
  117. return 1
  118. }
  119. m3.WriteHeader()
  120. v, err := m2.Get(a.t)
  121. if err != nil {
  122. panic(err) // nolint
  123. }
  124. m3.Add(a.t, v)
  125. if !m2.Equal(m3) {
  126. fmt.Println(m2, "not equal", m3) // nolint
  127. panic("not equal") // nolint
  128. }
  129. return 1
  130. }