Skip to content

[macOS x86_64, python >= 3.14] Process hangs when importing ctypes from embedded interpreter in a x86_64 macOS executable with enabled hardened runtime #160627

Open

Description

@rokm

The addition of early ffi_closure_alloc() call to execution/initialization of the _ctypes extension in python 3.14.0 (04d4aac / #131633) has exacerbated the problem that embedders (such as PyInstaller) encounter on macOS with x86_64 executables that have been codesigned with enabled hardened runtime (which is a requirement for app notarization in Apple Store).

Namely, when such executable (running either natively on an intel Mac, or under Rosetta on an arm64 Mac) ends up calling ffi_closure_alloc(), the process hangs, and the system log shows continuous stream of error messages like this one:

2026-10-20 09:48:59.486398-0700 0x6afb Error 0x0 0 0 kernel: (AppleMobileFileIntegrity) Library Validation failed: Rejecting '/private/var/folders/7c/49675rcx2nb0lwjms_6wmdpr0000gs/T/ffiiyZPuH' (Team ID: none, platform: no) for process 'dangerzone(3322)' (Team ID: 94ZZGGGJ3W, platform: no), reason: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.

At PyInstaller, we've previously observed this issue with python packages that use cffi (e.g., PyOpenSSL in pyinstaller/pyinstaller#8099); and presumably it would also happen with code that uses ctypes and ends up in a codepath that ends up calling ffi_closure_alloc, for example in PyCFuncPtr_new.

The issue does not affect arm64 executables, and the work-around for x86_64 is to enable com.apple.security.cs.allow-unsigned-executable-memory entitlement when signing the executable / app bundle.

We have now received a report of it happening simply by switching from python 3.13 to 3.14 (pyinstaller/pyinstaller#9554). I've traced the problem to import of ctypes (and subsequently the afore-mentioned early ffi_closure_alloc() call in _ctypes), which happens during bootstrap phase of a PyInstaller-frozen python application; so it is guaranteed to happen with python >= 3.14 and with hardened runtime enabled, regardless of how ctypes is actually used, and requires the entitlement as a work-around.

The true cause of the problem is a bug in libffi; in x86_64 codepath it tries to mmap an empty temporary file with PROT_EXEC, which fails due to hardened runtime and file not being signed, and leads to an endless retry loop - see libffi/libffi#1032.

So strictly speaking, this is not a bug in CPython. However, in the grander scheme of things, with Apple dropping support for Intel Macs, even if libffi fixes the problem on their side, the remaining Intel Macs are unlikely to see the fix; the official python builds from python.org seem to be using system-provided copy of libffi (/usr/lib/libffi.dylib, which would have to be updated by Apple), and both Homebrew and Anaconda have also dropped support for x86_64 on macOS.

As #131633 seems to have been trying to address an issue in free-threaded python builds (#128485), I was wondering if it would be possible to put the early ffi_closure_alloc call under ifdefs so that it is omitted for regular (non-free-threaded) python builds on x86_64 macOS? This would mitigate the issue for embedders who still want to support Intel Macs and use latest versions of python. If it is not possible (or worth the hassle), then hopefully this issue report can nudge them in the right direction with the entitlement-based work-around.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions