Bug report
gh-128714 added @critical_section to the __annotations__ setter and deleter, but the getter (function___annotations___get_impl) and its helper func_get_annotation_dict were not protected.
// NO @critical_section on the getter
static PyObject *
function___annotations___get_impl(PyFunctionObject *self)
{
...
d = func_get_annotation_dict(self); // reads + Py_XSETREF without lock
}
// line ~976 — setter has @critical_section, getter does not
func_get_annotation_dict (line 539) does an unprotected read of op->func_annotations and a Py_XSETREF into it at line 557. A concurrent setter holds a critical section; the getter does not. This is a read-write race.
Found while auditing CPython with cpython-review-toolkit (maintained by @devdanzin and myself).
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
Bug report
gh-128714 added
@critical_sectionto the__annotations__setter and deleter, but the getter (function___annotations___get_impl) and its helperfunc_get_annotation_dictwere not protected.func_get_annotation_dict(line 539) does an unprotected read ofop->func_annotationsand aPy_XSETREFinto it at line 557. A concurrent setter holds a critical section; the getter does not. This is a read-write race.Found while auditing CPython with cpython-review-toolkit (maintained by @devdanzin and myself).
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs