VYPR
Medium severity5.3NVD Advisory· Published May 27, 2024· Updated Apr 15, 2026

CVE-2022-4969

CVE-2022-4969

Description

Buffer overflow in rockhopper's binary parser allows local attackers to read arbitrary memory or cause denial of service via crafted input.

AI Insight

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

Buffer overflow in rockhopper's binary parser allows local attackers to read arbitrary memory or cause denial of service via crafted input.

Vulnerability

Overview

CVE-2022-4969 describes a buffer overflow vulnerability in the rockhopper library (versions up to 0.1.2). The flaw is located in the count_rows function within rockhopper/src/ragged_array.c, which is part of the binary parser used by RaggedArray.loads(). When parsing binary data with a row length type (ldtype) of np.uint64, a maliciously crafted row length value close to 2^64 can cause the internal buffer pointer to overflow, leading to out-of-bounds memory access [1][2][3].

Exploitation

Conditions

Exploitation requires local access to the system. An attacker must supply a specially crafted binary file to the RaggedArray.loads() function. No authentication or special privileges are needed beyond the ability to execute code that calls this function. The attack surface is limited to local users or processes that can feed untrusted data into the library [2][4].

Impact

Successful exploitation can result in reading arbitrary memory within the address space of the process using rockhopper, potentially leaking sensitive information. Alternatively, if the overflow causes the pointer to map to an unmapped memory region, a segmentation fault occurs, leading to a denial of service. The vulnerability is rated as critical in the original advisory, with a CVSS v3 base score of 5.3 (Medium) [2].

Mitigation

The issue is fixed in rockhopper version 0.2.0. The patch (commit 1a15fad5e06ae693eb9b8908363d2c8ef455104e) adds a guard that detects the pointer overflow and raises a ValueError instead of allowing the unsafe memory access. Users are strongly recommended to upgrade to the latest version [3][4].

AI Insight generated on May 20, 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
rockhopperPyPI
< 0.2.00.2.0

Affected products

1

Patches

2
1a15fad5e06a

Fix a potential security exploit in RaggedArray.loads(buffer, ldtype=np.uint64).

https://github.com/bwoodsend/rockhopperBrénainn WoodsendMay 22, 2022via ghsa
3 files changed · +47 2
  • rockhopper/src/ragged_array.c+2 1 modified
    @@ -59,8 +59,9 @@ int count_rows(void * raw, int raw_length, int length_power, int big_endian,
     
       int rows = 0;
     
    +  void * start = raw;
       void * end = raw + raw_length;
    -  while (raw <= end - (1 << length_power)) {
    +  while (raw <= end - (1 << length_power) && raw >= start) {
         uint64_t length = read(raw);
         raw += (1 << length_power);
         raw += length * itemsize;
    
  • setup.py+1 1 modified
    @@ -34,7 +34,7 @@
         extras_require={
             "test": [
                 'pytest>=3', 'pytest-order', 'coverage', 'pytest-cov',
    -            'coverage-conditional-plugin'
    +            'coverage-conditional-plugin', 'hypothesis'
             ]
         },
         license="MIT license",
    
  • tests/test_io.py+44 0 modified
    @@ -7,6 +7,7 @@
     import numpy as np
     import pytest
     from cslug import ptr
    +from hypothesis import given, strategies, settings, Verbosity, example
     
     from rockhopper import RaggedArray
     from rockhopper._ragged_array import _2_power, _big_endian
    @@ -61,6 +62,49 @@ def test_dump_load(dtype, byteorder):
         assert consumed == len(bin)
     
     
    +int_types = [
    +    np.uint8, np.uint16, np.uint32, np.uint64,
    +    np.int8, np.int16, np.int32, np.int64,
    +]
    +blob = bytes(range(256)) + bytes(range(256))[::-1]
    +
    +
    +@pytest.mark.parametrize("dtype", int_types)
    +@pytest.mark.parametrize("ldtype", int_types)
    +def test_loads_pointer_overflow_guard(dtype, ldtype):
    +    """Test that the check for pointer overflowing caused by reading a huge row
    +    length works."""
    +    for i in range(-30, len(blob)):
    +        try:
    +            RaggedArray.loads(blob[i: i+30], dtype=dtype, ldtype=ldtype)
    +        except ValueError:
    +            pass
    +
    +
    +@pytest.mark.parametrize("dtype", int_types)
    +@pytest.mark.parametrize("ldtype", int_types)
    +def test_fuzz_loads(dtype, ldtype):
    +    """Scan for possible segfaults.
    +
    +    All invalid inputs must lead to a ValueError rather than a seg-fault or
    +    RaggedArray.loads() could be tricked into reading arbitrary memory addresses
    +    by a maliciously constructed invalid data file.
    +
    +    """
    +    @given(strategies.binary())
    +    @example(b'\xc0\\\\\xb0\x93\x91\xff\xffpEfe\x167\xee')
    +    def fuzz(x):
    +        print(x)
    +        try:
    +            self, _ = RaggedArray.loads(x, dtype=dtype, ldtype=ldtype)
    +        except ValueError:
    +            pass
    +        else:
    +            assert self.dumps(ldtype=ldtype).tobytes() == x
    +
    +    fuzz()
    +
    +
     def test_dump_byteorder():
         self = RaggedArray.from_nested([[0x0109, 0x0208, 0x0307]], dtype=np.uint16)
     
    

Vulnerability mechanics

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

References

6

News mentions

0

No linked articles in our index yet.