Fix SIGSEGV on malformed Text field

C++ helper c_reraise_kj_exception() (capnp/helpers/capabilityHelper.cpp)
unconditionally dereferences the PyObject* returned by wrap_kj_exception_for_reraise()
(capnp/lib/capnp.pyx). For a specific class of malformed input -- a Cap'n Proto Text
field whose NUL terminator is corrupt -- the wrapper returns NULL, and the subsequent
"obj->ob_type" access dereferences NULL (offset 0x8) inside the C extension, producing
a deterministic, UNCATCHABLE SIGSEGV. libcapnp itself detects the corruption correctly
and would raise a catchable KjException for the sibling code path; only this reraise
helper crashes.

The malformed bytes reach the crash through the documented public API
Type.from_bytes(...) + lazy field access -- exactly how pycapnp consumers deserialize
untrusted Cap'n Proto messages received over the network / RPC / from files. A single
flipped byte in an attacker-controlled message takes down the consuming process; the
crash cannot be caught with try/except, so no graceful degradation is possible.
This commit is contained in:
Jacob Alexander
2026-07-01 23:06:40 -07:00
parent 6f70b8d737
commit 277483b963
3 changed files with 23 additions and 1 deletions

View File

@@ -288,8 +288,8 @@ cdef api object wrap_kj_exception(capnp.Exception & exception) with gil:
cdef api object wrap_kj_exception_for_reraise(capnp.Exception & exception) with gil:
PyErr_Clear()
wrapper = _KjExceptionWrapper()._init(exception)
ret = KjException(wrapper=wrapper)
return ret