From cd7e6dcd5cfb67734724c6bdda985b6659c2a5c7 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Fri, 10 Dec 2021 15:10:26 +1100 Subject: [PATCH] bencode: Avoid allocating interface string up front This should fix crashes during fuzzing. It's not a complete fix, we really want to limit the amount a given Decode can allocate. Maybe Go isn't the right language for this. --- bencode/decode.go | 16 +++++++++++++--- ...9ce4998a08e90a5c437df90e68caeea0650ee3c7e7b42 | 2 ++ ...0f4f59e17e92d2936cda9f4b260994a830ec27cfb88c3 | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 bencode/testdata/fuzz/FuzzInterfaceRoundTrip/c73f26cbd996104c4e39ce4998a08e90a5c437df90e68caeea0650ee3c7e7b42 create mode 100644 bencode/testdata/fuzz/FuzzInterfaceRoundTrip/eef53fca91deb00d4e30f4f59e17e92d2936cda9f4b260994a830ec27cfb88c3 diff --git a/bencode/decode.go b/bencode/decode.go index 4552da1c..53ce6efd 100644 --- a/bencode/decode.go +++ b/bencode/decode.go @@ -642,14 +642,24 @@ func (d *Decoder) parseIntInterface() (ret interface{}) { return } +func (d *Decoder) readBytes(length int) []byte { + b, err := io.ReadAll(io.LimitReader(d.r, int64(length))) + if err != nil { + panic(err) + } + if len(b) != length { + panic(fmt.Errorf("read %v bytes expected %v", len(b), length)) + } + return b +} + func (d *Decoder) parseStringInterface() string { length, err := d.parseStringLength() if err != nil { panic(err) } - b := make([]byte, length) - n, err := io.ReadFull(d.r, b) - d.Offset += int64(n) + b := d.readBytes(int(length)) + d.Offset += int64(len(b)) if err != nil { panic(&SyntaxError{Offset: d.Offset, What: err}) } diff --git a/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/c73f26cbd996104c4e39ce4998a08e90a5c437df90e68caeea0650ee3c7e7b42 b/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/c73f26cbd996104c4e39ce4998a08e90a5c437df90e68caeea0650ee3c7e7b42 new file mode 100644 index 00000000..7dcf27ee --- /dev/null +++ b/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/c73f26cbd996104c4e39ce4998a08e90a5c437df90e68caeea0650ee3c7e7b42 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("1:") diff --git a/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/eef53fca91deb00d4e30f4f59e17e92d2936cda9f4b260994a830ec27cfb88c3 b/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/eef53fca91deb00d4e30f4f59e17e92d2936cda9f4b260994a830ec27cfb88c3 new file mode 100644 index 00000000..384fff77 --- /dev/null +++ b/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/eef53fca91deb00d4e30f4f59e17e92d2936cda9f4b260994a830ec27cfb88c3 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("d10000000000") -- 2.48.1