Skip to content

set_state does not validate the state buffer length, causing out-of-bounds reads #193

Open

Description

@vlad-perevezentsev

set_state validates only the type of state[1] (PyBytes_Check), not its length against the size vslLoadStreamM reads, so a truncated buffer is read past the end of the bytes object:

name, buf = mkl_random.MKLRandomState(1234).get_state()   # 2524 bytes for MT19937
r = mkl_random.MKLRandomState(1)
r.set_state((name, buf[:40]))   # accepted silently
r.random_sample(2)              # array([0., 0.]) or garbage, then a segfault

Being an out-of-bounds read, the symptom depends on the heap layout: some variants of the snippet above exit cleanly, others return zeros or garbage and segfault at interpreter teardown rather than at the call itself. Truncating each BRNG's state to half its length gives:

MT19937 (2524 bytes) -> segfault
WH      (52 bytes)   -> accepted, wrong state
ARS5    (76 bytes)   -> accepted, samples happen to match the correct state

Pre-existing; reproduces on master.

Suggested fix: pass the buffer length into irk_set_state_mkl and compare it against the expected size for expected_brng before calling vslLoadStreamM — e.g. create a temporary stream with that BRNG and take vslGetStreamSize, next to the existing BRNG probe — returning a new error code that set_state turns into a ValueError. Worth checking that the size depends only on the BRNG for the families with stream ids (MT2203, WH).

Found during review of gh-192.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions