Skip to content

Commit 2f49a0d

Browse files
committed
found two panics with go-fuzz from Dmitry Vyukov
go-fuzz-build github.com/cryptix/wav go-fuzz -bin=./wav-fuzz -corpus=./corpus -workdir=~/wdir
1 parent 61bc089 commit 2f49a0d

File tree

10 files changed

+91
-4
lines changed

10 files changed

+91
-4
lines changed

corpus/16_50samples.wav

144 Bytes
Binary file not shown.

corpus/16bit.wav

46 Bytes
Binary file not shown.

corpus/24_50samples.wav

194 Bytes
Binary file not shown.

corpus/24bit.wav

47 Bytes
Binary file not shown.

corpus/headers_zerosamples.wav

262 Bytes
Binary file not shown.

corpus/u8bit.wav

45 Bytes
Binary file not shown.

errors.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ var (
1010
ErrNotRiff = errors.New("Not a RIFF file")
1111
ErrNotWave = errors.New("Not a WAVE file")
1212

13+
ErrBrokenChunkFmt = errors.New("could not decode chunkFmt")
14+
ErrNoBitsPerSample = errors.New("could not decode chunkFmt")
15+
1316
ErrFormatNotSupported = errors.New("Format not supported - Only uncompressed PCM currently")
1417
)
1518

fuzz.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// +build gofuzz
2+
3+
package wav
4+
5+
import (
6+
"bytes"
7+
"io"
8+
)
9+
10+
func Fuzz(data []byte) int {
11+
rd, err := NewReader(bytes.NewReader(data), int64(len(data)))
12+
if err != nil {
13+
if rd != nil {
14+
panic("rd != nil on error")
15+
}
16+
return 0
17+
}
18+
for {
19+
_, err = rd.ReadSample()
20+
if err != nil {
21+
if err == io.EOF {
22+
break
23+
}
24+
return 0
25+
}
26+
}
27+
return 1
28+
}

reader.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,16 @@ readLoop:
130130
}
131131
}
132132

133-
// Is audio supported ?
134-
if wav.chunkFmt.AudioFormat != 1 {
135-
return ErrFormatNotSupported
133+
if wav.chunkFmt == nil {
134+
return ErrBrokenChunkFmt
136135
}
137136

138137
wav.bytesPerSample = uint32(wav.chunkFmt.BitsPerSample / 8)
138+
139+
if wav.bytesPerSample == 0 {
140+
return ErrNoBitsPerSample
141+
}
142+
139143
wav.numSamples = wav.dataBlocSize / wav.bytesPerSample
140144
wav.duration = time.Duration(float64(wav.numSamples)/float64(wav.chunkFmt.SampleRate)) * time.Second
141145

@@ -144,7 +148,7 @@ readLoop:
144148

145149
// parseChunkFmt
146150
func (wav *Reader) parseChunkFmt() (err error) {
147-
wav.chunkFmt = &riffChunkFmt{}
151+
wav.chunkFmt = new(riffChunkFmt)
148152

149153
if err = binary.Read(wav.input, binary.LittleEndian, wav.chunkFmt); err != nil {
150154
return err
@@ -162,6 +166,11 @@ func (wav *Reader) parseChunkFmt() (err error) {
162166
}
163167
}
164168

169+
// Is audio supported ?
170+
if wav.chunkFmt.AudioFormat != 1 {
171+
return ErrFormatNotSupported
172+
}
173+
165174
return nil
166175
}
167176

reader_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package wav
33
import (
44
"bytes"
55
"io"
6+
"strings"
67
"testing"
78

89
"github.com/stretchr/testify/assert"
@@ -194,3 +195,49 @@ func TestReadSample(t *testing.T) {
194195
assert.Nil(t, err)
195196
assert.Equal(t, 257, sample)
196197
}
198+
199+
// panic: runtime error: invalid memory address or nil pointer dereference
200+
// [signal 0xb code=0x1 addr=0x4 pc=0x4399fb]
201+
//
202+
// goroutine 1 [running]:
203+
// github.com/cryptix/wav.(*Reader).parseHeaders(0xc208033720, 0x0, 0x0)
204+
// /tmp/go-fuzz-build857960013/src/github.com/cryptix/wav/reader.go:191 +0xe3b
205+
// github.com/cryptix/wav.NewReader(0x7f23a9550bd8, 0xc208037c80, 0x2d, 0xc208033720, 0x0, 0x0)
206+
// /tmp/go-fuzz-build857960013/src/github.com/cryptix/wav/reader.go:64 +0x177
207+
// github.com/cryptix/wav.Fuzz(0x7f23a92cf000, 0x2d, 0x100000, 0x2)
208+
// /tmp/go-fuzz-build857960013/src/github.com/cryptix/wav/fuzz.go:12 +0x167
209+
// github.com/dvyukov/go-fuzz/go-fuzz-dep.Main(0x570c60, 0x5d4200, 0x5f6, 0x5f6)
210+
// /home/cryptix/go/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/main.go:64 +0x309
211+
// main.main()
212+
// /tmp/go-fuzz-build857960013/src/go-fuzz-main/main.go:10 +0x4e
213+
// exit status 2
214+
func TestReadFuzzed_panic1(t *testing.T) {
215+
t.Parallel()
216+
wavFile := strings.NewReader("RIFF%\x00\x00\x00WAVE0000\x10\x00\x00\x000000000000000000data00000")
217+
_, err := NewReader(wavFile, int64(wavFile.Len()))
218+
assert.NotNil(t, err)
219+
assert.Equal(t, ErrBrokenChunkFmt, err)
220+
}
221+
222+
// panic: runtime error: integer divide by zero
223+
// [signal 0x8 code=0x1 addr=0x439ae9 pc=0x439ae9]
224+
//
225+
// goroutine 1 [running]:
226+
// github.com/cryptix/wav.(*Reader).parseHeaders(0xc208032cd0, 0x0, 0x0)
227+
// /tmp/go-fuzz-build857960013/src/github.com/cryptix/wav/reader.go:200 +0xf29
228+
// github.com/cryptix/wav.NewReader(0x7fbca32b6bd8, 0xc208037ef0, 0x2d, 0xc208032cd0, 0x0, 0x0)
229+
// /tmp/go-fuzz-build857960013/src/github.com/cryptix/wav/reader.go:64 +0x177
230+
// github.com/cryptix/wav.Fuzz(0x7fbca3035000, 0x2d, 0x100000, 0x2)
231+
// /tmp/go-fuzz-build857960013/src/github.com/cryptix/wav/fuzz.go:12 +0x167
232+
// github.com/dvyukov/go-fuzz/go-fuzz-dep.Main(0x570c60, 0x5d4200, 0x5f6, 0x5f6)
233+
// /home/cryptix/go/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/main.go:64 +0x309
234+
// main.main()
235+
// /tmp/go-fuzz-build857960013/src/go-fuzz-main/main.go:10 +0x4e
236+
// exit status 2
237+
func TestReadFuzzed_panic2(t *testing.T) {
238+
t.Parallel()
239+
wavFile := strings.NewReader("RIFF%\x00\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00000000000000\a\x00data00000")
240+
_, err := NewReader(wavFile, int64(wavFile.Len()))
241+
assert.NotNil(t, err)
242+
assert.Equal(t, ErrBrokenChunkFmt, err)
243+
}

0 commit comments

Comments
 (0)