From b0b19247aa31633650c32638fb55f597fa6e2468 Mon Sep 17 00:00:00 2001 From: Eric Lindvall Date: Tue, 8 Aug 2023 01:57:35 -0700 Subject: [PATCH] Fix descriptor panic (#53) * Provide fuzzer for descriptor * Don't panic when the length of a descriptor is 0 --- descriptor.go | 8 +++++ descriptor_test.go | 31 ++++++++++++++++++- testdata/fuzz/FuzzDescriptor/6ae8bb726335d15a | 2 ++ testdata/fuzz/FuzzDescriptor/c18ae01ae2349b75 | 2 ++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 testdata/fuzz/FuzzDescriptor/6ae8bb726335d15a create mode 100644 testdata/fuzz/FuzzDescriptor/c18ae01ae2349b75 diff --git a/descriptor.go b/descriptor.go index b391d22..8953a52 100644 --- a/descriptor.go +++ b/descriptor.go @@ -2002,6 +2002,10 @@ func calcDescriptorLength(d *Descriptor) uint8 { return calcDescriptorUserDefinedLength(d.UserDefined) } + if d.Length == 0 { + return 0 + } + switch d.Tag { case DescriptorTagAC3: return calcDescriptorAC3Length(d.AC3) @@ -2068,6 +2072,10 @@ func writeDescriptor(w *astikit.BitsWriter, d *Descriptor) (int, error) { written := int(length) + 2 + if d.Length == 0 { + return written, nil + } + if d.Tag >= 0x80 && d.Tag <= 0xfe { return written, writeDescriptorUserDefined(w, d.UserDefined) } diff --git a/descriptor_test.go b/descriptor_test.go index 088aac5..e46e207 100644 --- a/descriptor_test.go +++ b/descriptor_test.go @@ -2,9 +2,10 @@ package astits import ( "bytes" + "testing" + "github.com/asticode/go-astikit" "github.com/stretchr/testify/assert" - "testing" ) var descriptors = []*Descriptor{{ @@ -703,3 +704,31 @@ func BenchmarkParseDescriptor(b *testing.B) { }) } } + +func FuzzDescriptor(f *testing.F) { + bufExpected := bytes.Buffer{} + bufExpected.Write([]byte{0x00, 0x00}) // reserve two bytes for length + wExpected := astikit.NewBitsWriter(astikit.BitsWriterOptions{Writer: &bufExpected}) + + for _, tc := range descriptorTestTable { + tc.bytesFunc(wExpected) + } + + descLen := uint16(bufExpected.Len() - 2) + descBytes := bufExpected.Bytes() + descBytes[0] = byte(descLen>>8) | 0b11110000 // program_info_length is preceded by 4 reserved bits + descBytes[1] = byte(descLen & 0xff) + + f.Add(descBytes) + + f.Fuzz(func(t *testing.T, b []byte) { + ds, err := parseDescriptors(astikit.NewBytesIterator(b)) + + if err == nil { + bufActual := bytes.Buffer{} + wActual := astikit.NewBitsWriter(astikit.BitsWriterOptions{Writer: &bufActual}) + + writeDescriptorsWithLength(wActual, ds) + } + }) +} diff --git a/testdata/fuzz/FuzzDescriptor/6ae8bb726335d15a b/testdata/fuzz/FuzzDescriptor/6ae8bb726335d15a new file mode 100644 index 0000000..e6d1725 --- /dev/null +++ b/testdata/fuzz/FuzzDescriptor/6ae8bb726335d15a @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0\x060\x02000\x00") diff --git a/testdata/fuzz/FuzzDescriptor/c18ae01ae2349b75 b/testdata/fuzz/FuzzDescriptor/c18ae01ae2349b75 new file mode 100644 index 0000000..98ce148 --- /dev/null +++ b/testdata/fuzz/FuzzDescriptor/c18ae01ae2349b75 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0\x060\x0200X\x00")