Skip to content

ctypes: out-of-bounds read/write in bool() and argument passing after resize() #160708

Open

Description

@DmitryTD

Crash report

After ctypes.resize(), the buffer of a simple ctypes object is larger than the type itself. Two places in _ctypes.c use the buffer size (b_size) instead of the type size and go out of bounds.

Found with a fuzzer. Tested on main (c436e8d).

1. Reading out of bounds in bool()

import ctypes
x = ctypes.c_bool()
ctypes.resize(x, 190)
bool(x)
==94599==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7f54a2fc1b71 at pc 0x563480cae666 bp 0x7ffc5c95adf0 sp 0x7ffc5c95a598
READ of size 190 at 0x7f54a2fc1b71 thread T0
    #0 in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long) /usr/src/RPM/BUILD/llvm-project-18/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:814:7
    #1 in memcmp /usr/src/RPM/BUILD/llvm-project-18/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:845:10
    #2 in PyObject_IsTrue Objects/object.c:2163:15
    #3 in bool_vectorcall Objects/boolobject.c:60:14
    #4 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:143:11
    ...

0x7f54a2fc1b71 is located 0 bytes after global variable '.str.245' defined in '/host/triage/cpython/Modules/_ctypes/_ctypes.c:5525' (0x7f54a2fc1b60) of size 17
SUMMARY: AddressSanitizer: global-buffer-overflow Objects/object.c:2163:15 in PyObject_IsTrue

Simple_bool_impl compares the object with a 16-byte string literal (_ctypes.c:5525) using b_size as the length.

Without ASAN, a debug build aborts with:

Fatal Python error: _Py_CheckFunctionResult: a function returned NULL without setting an exception
Python runtime state: initialized
SystemError: <class 'bool'> returned NULL without setting an exception

2. Writing out of bounds when calling a function

import ctypes
x = ctypes.c_bool()
ctypes.resize(x, 128)
abs_ = ctypes.CDLL(None).abs
abs_.argtypes = (ctypes.c_bool,)
abs_(x)
==94604==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x508000021000 at pc 0x55a5906863d4 bp 0x7fff29dbc9b0 sp 0x7fff29dbc170
WRITE of size 128 at 0x508000021000 thread T0
    #0 in __asan_memcpy /usr/src/RPM/BUILD/llvm-project-18/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3
    #1 in PyCSimpleType_paramfunc Modules/_ctypes/_ctypes.c:2320:5
    #2 in ConvParam Modules/_ctypes/callproc.c:728:16
    #3 in _ctypes_callproc Modules/_ctypes/callproc.c:1308:19
    #4 in PyCFuncPtr_call Modules/_ctypes/_ctypes.c:4698:14
    ...

0x508000021000 is located 0 bytes after 96-byte region [0x508000020fa0,0x508000021000)
allocated by thread T0 here:
    #0 in malloc /usr/src/RPM/BUILD/llvm-project-18/compiler-rt/lib/asan/asan_malloc_linux.cpp:68:3
    #1 in _PyObject_MallocWithType Include/internal/pycore_object_alloc.h:46:17
    #2 in gc_alloc Python/gc.c:2034:17
    #3 in _PyObject_GC_New Python/gc.c:2054:20
    #4 in PyCArgObject_new Modules/_ctypes/callproc.c:520:9

SUMMARY: AddressSanitizer: heap-buffer-overflow Modules/_ctypes/_ctypes.c:2320:5 in PyCSimpleType_paramfunc

PyCSimpleType_paramfunc copies b_size bytes into the value union of PyCArgObject. The union is 32 bytes on x86-64 (its largest member is long double G[2]), so the copy goes past the end of the object.

Without ASAN, a debug build aborts with:

Fatal Python error: _PyMem_DebugRawFree: bad trailing pad byte
Python runtime state: initialized

I think both places should use info->size, as gh-159767 did in _ctypes_Simple_value_get_impl. I'm going to open a PR.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.16.0a1+dev (heads/main:c436e8d8359, Oct 26 2026, 12:26:29) [Clang 18.1.8 ]

Linked PRs

Activity

  1. added
    type-crashA hard crash of the interpreter, possibly with a core dump
    on Oct 26, 2026
  2. added a commit that references this issue on Nov 4, 2026
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

    extension-modulesC modules in the Modules dirtopic-ctypestype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions