Skip to content

emrg: SECURITY_DESCRIPTOR_MIN_LENGTH is the 32-bit size, so the absolute-descriptor buffer is overrun on 64-bit #2509

Closed

Description

@argszero

emrg/sandbox/win32/abi.py declares SECURITY_DESCRIPTOR_MIN_LENGTH = 20, and emrg/sandbox/win32/registry.py uses it as the size of the buffer an absolute security descriptor is built in:

descriptor = ctypes.create_string_buffer(abi.SECURITY_DESCRIPTOR_MIN_LENGTH)
absolute = ctypes.cast(descriptor, ctypes.c_void_p)
api.advapi32.InitializeSecurityDescriptor(absolute, abi.SECURITY_DESCRIPTOR_REVISION)
api.advapi32.SetSecurityDescriptorDacl(absolute, True, ctypes.c_void_p(new_acl), False)

Twenty bytes is the 32-bit answer. The Win32 SDK defines SECURITY_DESCRIPTOR_MIN_LENGTH as sizeof(SECURITY_DESCRIPTOR), and on a 64-bit interpreter that struct is 40 bytes, measured with ctypes on this checkout:

Revision offset  0
Sbz1     offset  1
Control  offset  2
Owner    offset  8
Group    offset 16
Sacl     offset 24
Dacl     offset 32
sizeof(SECURITY_DESCRIPTOR) = 40

So InitializeSecurityDescriptor writes 40 bytes into a 20-byte allocation. create_string_buffer bounds nothing, so no exception is raised: the write goes 20 bytes past the buffer into the process heap, and the damage surfaces later, wherever the allocator hands that memory out next.

Observed symptom

Master's Windows CI leg is red with an access violation that names a test with no connection to the registry code. On run 39870597838 (fede281b), the test leg passed and test-windows failed; the crash report points at tests/test_llm.py::test_headers_carry_an_empty_key_unchanged — a test that takes no fixture — inside pytest's fixture setup (_fillfixtures → getfixturevalue → execute), i.e. the heap was already corrupt when that file started. The xdist worker's previous block was the whole tests/test_bash_v2_win32.py file (-n auto --dist loadfile gives one file per worker), and an earlier crash of the same family sits on the same file boundary.

The test that reaches the overrun is the one that applies a DACL to a real key: tests/test_bash_v2_win32.py::test_a_key_grant_is_applied_checkable_and_reversible_on_a_real_key → apply_dacl.

What the fix must satisfy

  • The buffer an absolute security descriptor is built in is sized by the struct, not by a number: SECURITY_DESCRIPTOR_MIN_LENGTH must be ctypes.sizeof of a declared SECURITY_DESCRIPTOR struct, so it answers 20 on a 32-bit interpreter and 40 on a 64-bit one without anyone choosing.
  • A guard holds that property on every platform. The tests that need a real Win32 call are Windows-only, but the struct's layout is computable anywhere, so the guard must run on the Linux and macOS legs too — a guard that only runs on Windows cannot catch the next hand-written size on the two legs that are green today.
  • The guard asserts the property that failed, both ways: the constant equals the struct's size, and the struct's last field fits inside it (Dacl offset + pointer size ≤ the constant). The second holds even where the first is trivially true.
  • No change to the grant/revoke behaviour: the two other create_string_buffer calls in registry.py are sized from MakeSelfRelativeSD's and RegGetKeySecurity's own measurements, and acl.py's descriptors are allocated by the API. Only the hand-sized one is the defect.

Confirmation

The pass criterion is the test-windows leg of the PR's own CI run going green, with tests/test_bash_v2_win32.py and the file that crashed after it in the same worker. Neither macOS nor Linux can exercise the Win32 call, so a local green says the guard runs, never that the overrun is gone.

Activity

  1. argszero commented on Oct 23, 2026

    @argszero
    OwnerAuthor

    Handled by #2510

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions