Skip to content

Use Py_SETREF() macro to fix race conditions (potential race conditions) in C extensions #99537

Closed
@vstinner

Description

@vstinner

A lot of C code in Python uses this pattern:

Py_XDECREF(var);
var = value;

If var was holding the last strong reference to a Python object, the object finalizer is called which can call arbitrary Python code which can access the var variable which is now a dangling pointer, and so Python does just crash in this case.

The correct pattern is:

old_var = var;
var = value;
Py_XDECREF(old_var);

And Py_SETREF() can be used to make this code shorter and easier to read and maintain:

Py_XSETREF(var, value);

While the pattern is unsafe, maybe it's not possible to crash Python. But I prefer to replace this pattern with Py_SETREF() or Py_XSETREF() so I don't have to think about: oh, is it possible to crash Python?

Again, Py_SETREF() also makes the code shorter, easier to read and maintain.

While we are here, I also propose to replace:

Py_XDECREF(var);
var = NULL;

with:

Py_CLEAR(var);

which is shorter than:

Py_XSETREF(var, NULL);

See also issue #99300 "Replace Py_INCREF()/Py_XINCREF() usage with Py_NewRef()/Py_XNewRef()" and issue #99481 "Add Py_HOLD_REF() macro to hold a strong reference to a Python object while executing code".

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions