Skip to content

Conversation

@rgfegegeegege
Copy link

The perf JIT trampoline code writes to a shared FILE* from multiple threads
(perf_map_jit_write_entry can be called concurrently when generating JIT code),
but it does so without holding the map_lock.

During interpreter shutdown, perf_map_jit_fini() closes the file while holding
the lock, but sets perf_map to NULL only after releasing the lock.

This opens a small race window where a concurrent write could:

  • read a stale perf_map pointer after fclose(), or
  • call fwrite() on a closed (or NULL) FILE*, leading to undefined behavior
    (likely a crash or corrupted jitdump file).

Although the JIT perf support is experimental and the race is rare,
it is a real thread-safety bug.

This change fixes it by:

  • Acquiring the map_lock around all writes in perf_map_jit_write_entry().
  • Adding a double-check after acquiring the lock (in case fini() ran while
    waiting for the lock).
  • Moving the perf_map = NULL assignment inside the locked section in fini()
    for consistency.

No functional changes in the single-threaded case, and no regression in
jitdump file format or perf compatibility.

Fixes a potential use-after-close (CWE-910).

@bedevere-app
Copy link

bedevere-app bot commented Jan 17, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@python-cla-bot
Copy link

The following commit authors need to sign the Contributor License Agreement:

CLA not 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.

1 participant