This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author arigo
Recipients arigo
Date 2015-11-18.06:03:03
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1447826584.36.0.973987165664.issue25653@psf.upfronthosting.co.za>
In-reply-to
Content
Ctypes uses libffi's `ffi_closure_alloc()`, which has a bug that make existing applications obscurely crash in one situation: if we are running on SELinux, making use of callbacks, and forking.  This is because `ffi_closure_alloc()` will detect that it is running on SELinux and use an alternative way to allocate memory for the callbacks.

It does that because selinux won't let a process mmap() any anonymous read-write-execute memory (at least in some settings; but libffi always uses the workaround if selinux is detected).  The workaround is to create a temporary file and mmap() it twice (at randomly different addresses), once as a read-write mapping and once as a read-execute mapping.  However, the internal structure of libffi requires that this mapping be MAP_SHARED (we can't easily first build the memory content, then write it to the temporary file and mmap() that fixed content in executable memory).

The problem with this is that if the process forks, this memory is shared.  If one of the two processes then frees the callback, the memory becomes garbage in the other process.

The problem was reported a few times at various places already, but not in this bug tracker.  See:

https://sourceware.org/ml/libffi-discuss/2009/msg00320.html

https://bugzilla.redhat.com/show_bug.cgi?id=531233

https://bugzilla.redhat.com/show_bug.cgi?id=707944

I am adding this issue to Python's bug tracker because, while in theory a libffi issue, it seems that Python is one of the very few libffi users that actually frees callbacks in this way.  I don't have a solution for either libffi or ctypes, though.  My own recommendation would be to stop using ``ffi_closure_alloc()`` and let the application either work (on selinux without deny_execmem) or cleanly trigger an error (on selinux with deny_execmem).

For reference, the issue was reported to CFFI's bug tracker about python-cryptography 1.0: it uses cffi's version of callbacks, whose implementation is close to ctypes', except not using ``ffi_closure_alloc()`` and so hitting the original selinux error instead of a crash.  The file https://bitbucket.org/cffi/cffi/raw/default/c/malloc_closure.h inside CFFI comes from an older version of ctypes which (by chance in this case) does not call ``ffi_closure_alloc()``.
History
Date User Action Args
2015-11-18 06:03:04arigosetrecipients: + arigo
2015-11-18 06:03:04arigosetmessageid: <1447826584.36.0.973987165664.issue25653@psf.upfronthosting.co.za>
2015-11-18 06:03:04arigolinkissue25653 messages
2015-11-18 06:03:03arigocreate