Fix PyText_AS_UTF8/PyUnicode_AsUTF8 NULL dereference vulnerabilities#256
Open
dynapx wants to merge 1 commit into
Open
Fix PyText_AS_UTF8/PyUnicode_AsUTF8 NULL dereference vulnerabilities#256dynapx wants to merge 1 commit into
dynapx wants to merge 1 commit into
Conversation
Add NULL checks before passing UTF-8 strings to PyErr_Format, PyUnicode_FromFormat, parse_c_type, and detect_custom_layout. These APIs can return NULL when the input string contains invalid surrogate characters or when memory allocation fails. Passing NULL to a %%s format specifier causes strlen(NULL) -> Segmentation Fault. Affected functions: - fetch_global_var_addr (cglob.c) - _ffi_type (ffi_obj.c) - cdata_repr, _cdata_repr2, _add_field, b_complete_struct_or_union_lock_held, b_do_dlopen (_cffi_backend.c)
Contributor
|
Add some tests that prove your claims, without the bogus "memory allocation fails" since if memory allocation fails for these small messages the interpreter will soon crash anyway. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Hi maintainers,
During a robustness audit of Python C‑API contracts using a static analysis tool, we identified a systematic pattern of unchecked
PyText_AS_UTF8/PyUnicode_AsUTF8return values across multiple files in the_cffi_backendC extension.These functions can return
NULLwhen:UnicodeEncodeErrorMemoryErrorWhen the return value is
NULLand passed directly toPyErr_FormatorPyUnicode_FromFormatwith a%sformat specifier, it causesstrlen(NULL)→ Segmentation Fault, crashing the interpreter.This PR adds NULL checks before passing UTF-8 strings to any string-consuming API, ensuring errors are properly propagated rather than crashing.
1. Unchecked
PyText_AS_UTF8/PyUnicode_AsUTF8return → NULL dereferenceLocation: Multiple functions across
src/c/_cffi_backend.c,src/c/cglob.c,src/c/ffi_obj.cIssue:
PyText_AS_UTF8(macro forPyUnicode_AsUTF8) is called and its return value is passed directly toPyErr_Format,PyUnicode_FromFormat,parse_c_type, ordetect_custom_layoutwithout checking forNULL. If the string contains invalid surrogate characters (e.g.,\uD800) or memory allocation fails, the function returnsNULLand sets an exception. PassingNULLto a%sformat specifier causesstrlen(NULL)→ Segmentation Fault, killing the interpreter.Fix:
Check the return value of
PyText_AS_UTF8/PyUnicode_AsUTF8before using it. IfNULL, propagate the already-set exception by returningNULLor-1.Affected functions:
src/c/cglob.cfetch_global_var_addrsrc/c/ffi_obj.c_ffi_typesrc/c/_cffi_backend.ccdata_repr,_cdata_repr2,_add_field,b_complete_struct_or_union_lock_held(6 locations),b_do_dlopenExample fix (
cglob.c):Same fix applied to all PyErr_Format calls with unchecked %s parameters:
Impact & Rationale
Availability: A crash in
cffican take down the entire Python process with no recoverable error.cffiis a foundational library used by thousands of projects includingcryptography,bcrypt,gevent, andPyPy.Reachability: The vulnerability is reachable when:
ffi.cast(),ffi.typeof(), or struct field definitionsPyUnicode_AsUTF8to fail withMemoryErrorDebuggability: In the
%sformat specifier case, the original exception is lost and replaced by a crash, making debugging extremely difficult.Note: All changes are minimal and backward‑compatible – they only affect error paths, leaving the happy path unchanged.
Thank you for maintaining
cffi!