Skip to content

gh-149816: Fix race in subtype_getweakref in free-threading build#150247

Open
Abhi210 wants to merge 1 commit into
python:mainfrom
Abhi210:gh-149816-61
Open

gh-149816: Fix race in subtype_getweakref in free-threading build#150247
Abhi210 wants to merge 1 commit into
python:mainfrom
Abhi210:gh-149816-61

Conversation

@Abhi210
Copy link
Copy Markdown
Contributor

@Abhi210 Abhi210 commented May 22, 2026

This PR resolves finding 61 from the weakref race tracking issue: "Racy weakref head load before incref in Objects/typeobject.c".

Description

In free-threaded builds, subtype_getweakref() had a race condition where the weakref list head (*weaklistptr) was loaded and immediately passed to Py_NewRef(). If another thread concurrently triggered weakref_dealloc(), the weakref could be freed before the incref, leading to a use-after-free (UAF).

This PR fixes the issue by:

  1. Wrapping the pointer load and incref sequence inside the existing LOCK_WEAKREFS(obj) / UNLOCK_WEAKREFS(obj) critical section.
  2. Replacing Py_NewRef() with _Py_TryIncref() to safely handle weakrefs whose refcount has reached zero during the race window.
  3. Returning Py_NewRef(Py_None) when the list is empty or the weakref is no longer live, preserving the existing API behavior.

Testing

Added regression tests in Lib/test/test_free_threading/test_weakref.py that:

  • Exercise obj.__weakref__ concurrently from reader and mutator threads synchronized with threading.Barrier.
  • Verify correct return values (None versus weakref.ref).
  • Check refcount stability across repeated accesses to detect leaks or incorrect incref/decref behavior.

@python-cla-bot
Copy link
Copy Markdown

python-cla-bot Bot commented May 22, 2026

All commit authors signed the Contributor License Agreement.

CLA signed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

22 free-threading race conditions

1 participant