Skip to content

func_get_annotation_dict missing critical section after gh-128714 #159091

Description

@BHUVANSH855

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

Activity

  1. hetaozdh commented on Oct 9, 2026

    @hetaozdh
    Contributor

    I don't think the getter part of this issue is a real bug. The getter already has the @critical_section tag, and Argument Clinic generates the locking code correctly.

    However, I tested and found that PyFunction_GetAnnotations() appears to access the same field without holding the critical section. I'll open a PR to fix that path instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions