From 69c6093c7b2397b923acf82cb378f55ab2652b9b Mon Sep 17 00:00:00 2001 From: Ulrich Kunitz Date: Wed, 19 Aug 2020 18:04:10 +0200 Subject: [PATCH] xz: fix a security issue for readUvarint readUvarint could be provided a sequence of bytes where the application would never stop. That is the same issue that has been recently reported for the Go Standard Library as CVE-2020-16845. The fix simply adds a check for the number of bytes read and reports an overflow after more than 10 bytes are read, which is $\ceil{\frac{64}{7}}$. The commit also includes a test to ensure that the error is returned. I thank Github user 0xdecaf for reporting the issue. --- bits.go | 7 ++++++- bits_test.go | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/bits.go b/bits.go index 364213d..dc8f328 100644 --- a/bits.go +++ b/bits.go @@ -54,6 +54,8 @@ var errOverflowU64 = errors.New("xz: uvarint overflows 64-bit unsigned integer") // readUvarint reads a uvarint from the given byte reader. func readUvarint(r io.ByteReader) (x uint64, n int, err error) { + const maxUvarintLen = 10 + var s uint i := 0 for { @@ -62,8 +64,11 @@ func readUvarint(r io.ByteReader) (x uint64, n int, err error) { return x, i, err } i++ + if i > maxUvarintLen { + return x, i, errOverflowU64 + } if b < 0x80 { - if i > 10 || i == 10 && b > 1 { + if i == maxUvarintLen && b > 1 { return x, i, errOverflowU64 } return x | uint64(b)<