fix: Narrow conditions for load_value to give invalid address - #6157
fix: Narrow conditions for load_value to give invalid address#6157amjames wants to merge 2 commits into
load_value to give invalid address#6157Conversation
…ting python object fixes: pybind#6153 Objects initialized with `cls.__new__(cls)` (`cls` is a pybind11 bound type). Will not have the C++ object allocated. When hitting `load_value` storage is allocated but not initialized, calling a virtual method will load a garbage vptr and segfault. This is similar to pybind#2152, but the guard in metaclass `__call__` is not triggered when using `__new__`. Protect against giving a pointer to garbage in all cases except the `__init__` + `__setstate__` path. Authored with claude
…y allocation for old-style constructors If an old-style placement-new `__init__`/`__setstate__` failed after `self` was loaded, the lazily allocated storage stayed behind with a null-holder instance, so the uninitialized-value guard never fired again and later use read uninitialized memory. `instance_construction_scope` now tracks the constructor's `value_and_holder` and frees storage that was lazily allocated during a construction that did not complete. Also arm the scope only when the overload chain contains an old-style constructor. New-style constructors receive `self` directly and never need lazy allocation, so reentrant loads of the half-built instance now raise `ValueError` instead of handing out uninitialized storage. Assisted-by: ClaudeCode:claude-fable-5 Claude-Session: https://claude.ai/code/session_01TQXCSykMn5EL7sc6VgTUTC
|
I pushed two fixes from Fable. Both started with failing tests, then fixed. 🤖 AI text below 🤖 Review complete: 12 candidates checked, 2 survived (both confirmed), 10 refuted. 1. Incomplete fix — failed old-style 2. Guard armed too broadly ( Notable refutations: cross-module ABI safe (layout unchanged, bit zero-filled by |
Description
fixes: #6153
Objects initialized with
cls.__new__(cls)(clsis a pybind11 bound type). Will not have the C++ object allocated. When hittingload_valuestorage is allocated but not initialized, calling a virtual method will load a garbage vptr and segfault. This is similar to #2152, but the guard in metaclass__call__is only triggered when a subclass__init__skips calling the parent init, the path blocked here can be hit with only a pybind exported type using__new__.Impact
Review Notes
tp_getattroslot onpybind11_objectwere rejected because they leave other edge-cases unprotected, and they add more overhead than what has been implemented here.vptr == nullptrbranch. There is no additional work done when the object is fully initialized.Authored with the assistance of claude
AI Generated Summary Below:
📚 Documentation preview 📚: https://pybind11--6157.org.readthedocs.build/