VYPR
High severityNVD Advisory· Published Aug 6, 2020· Updated Aug 4, 2024

CVE-2020-16845

CVE-2020-16845

Description

Go before 1.13.15 and 14.x before 1.14.7 can have an infinite read loop in ReadUvarint and ReadVarint in encoding/binary via invalid inputs.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Go's encoding/binary.ReadUvarint and ReadVarint functions before versions 1.13.15 and 1.14.7 can enter an infinite loop when processing specially crafted invalid inputs, leading to denial of service.

Vulnerability

Overview

The vulnerability resides in Go's encoding/binary package, specifically in the ReadUvarint and ReadVarint functions. When these functions decode unsigned or signed variable-length integers (uvarint/varint), they lack a check for excessive input length, causing them to read indefinitely from a byte stream containing specially crafted, non-terminating sequences. An attacker can provide a series of bytes with the high bit set (e.g., 0x81, 0x82...) that never sets the leading bit to zero, so the loop never exits [1]. The issue affects Go versions before 1.13.15 and before 1.14.7 [1].

Attack

Surface and Exploitation Prerequisites

No authentication is required; the vulnerability can be triggered by any input that is passed to ReadUvarint or ReadVarint. Common exposure points include parsing binary protocols, file formats, or network messages. For example, the ulikunitz/xz library for decompressing xz files was found to be vulnerable because its internal readUvarint function mirrored the standard library's flawed loop [2]. A remote attacker could send a malicious xz archive that, when processed, causes the reader to spin infinitely, consuming CPU resources and effectively halting the application [2].

Impact

Successful exploitation leads to a denial of service (DoS). The infinite loop will consume 100% CPU on the affected system, potentially causing the process to hang or become unresponsive. Memory exhaustion is not the primary vector; the attack relies on CPU starvation. Although no remote code execution is possible, the DoS condition can disrupt critical services that rely on Go's binary decoding functions.

Mitigation

Status

The Go project released fixes in versions 1.13.15 and 1.14.7 by introducing a maximum uvarint length constant (maxUvarintLen = 10) and checking against it inside the loop [3]. When the length exceeds 10 bytes, an overflow error is returned instead of continuing to read. Users should upgrade to the patched versions immediately. Downstream projects, such as ulikunitz/xz, have applied the fix in commit 69c6093c7b2397b923acf82cb378f55ab2652b9b [3]. Fedora packages were also updated [4]. There is no known workaround other than upgrading.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/ulikunitz/xzGo
< 0.5.80.5.8

Affected products

11

Patches

1
69c6093c7b23

xz: fix a security issue for readUvarint

https://github.com/ulikunitz/xzUlrich KunitzAug 19, 2020via ghsa
2 files changed · +17 1
  • bits.go+6 1 modified
    @@ -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)<<s, i, nil
    
  • bits_test.go+11 0 modified
    @@ -31,3 +31,14 @@ func TestUvarint(t *testing.T) {
     		}
     	}
     }
    +
    +func TestUvarIntCVE_2020_16845(t *testing.T) {
    +	var a = []byte{0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    +		0x88, 0x89, 0x8a, 0x8b}
    +
    +	r := bytes.NewReader(a)
    +	_, _, err := readUvarint(r)
    +	if err != errOverflowU64 {
    +		t.Fatalf("readUvarint overflow not detected")
    +	}
    +}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

26

News mentions

0

No linked articles in our index yet.