Skip to content

Commit 470b9e4

Browse files
committed
TSAN fixes
1 parent b0adc30 commit 470b9e4

File tree

3 files changed

+11
-7
lines changed

3 files changed

+11
-7
lines changed

Objects/object.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2682,8 +2682,8 @@ _Py_SetImmortalUntracked(PyObject *op)
26822682
}
26832683
#ifdef Py_GIL_DISABLED
26842684
op->ob_tid = _Py_UNOWNED_TID;
2685-
op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL;
2686-
op->ob_ref_shared = 0;
2685+
_Py_atomic_store_uint32_relaxed(&op->ob_ref_local, _Py_IMMORTAL_REFCNT_LOCAL);
2686+
_Py_atomic_store_ssize_relaxed(&op->ob_ref_shared, 0);
26872687
_Py_atomic_or_uint8(&op->ob_gc_bits, _PyGC_BITS_DEFERRED);
26882688
#elif SIZEOF_VOID_P > 4
26892689
op->ob_flags = _Py_IMMORTAL_FLAGS;

Objects/unicodeobject.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar)
13291329
else
13301330
data = unicode + 1;
13311331
_PyUnicode_LENGTH(unicode) = size;
1332-
_PyUnicode_HASH(unicode) = -1;
1332+
PyUnicode_SET_HASH((PyObject *)unicode, -1);
13331333
_PyUnicode_STATE(unicode).interned = 0;
13341334
_PyUnicode_STATE(unicode).kind = kind;
13351335
_PyUnicode_STATE(unicode).compact = 1;
@@ -13903,9 +13903,9 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode)
1390313903

1390413904
_PyUnicode_LENGTH(self) = length;
1390513905
#ifdef Py_DEBUG
13906-
_PyUnicode_HASH(self) = -1;
13906+
PyUnicode_SET_HASH((PyObject *)self, -1);
1390713907
#else
13908-
_PyUnicode_HASH(self) = _PyUnicode_HASH(unicode);
13908+
PyUnicode_SET_HASH((PyObject *)self, PyUnicode_HASH(unicode));
1390913909
#endif
1391013910
_PyUnicode_STATE(self).interned = 0;
1391113911
_PyUnicode_STATE(self).kind = kind;
@@ -13950,7 +13950,7 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode)
1395013950
memcpy(data, PyUnicode_DATA(unicode), kind * (length + 1));
1395113951
assert(_PyUnicode_CheckConsistency(self, 1));
1395213952
#ifdef Py_DEBUG
13953-
_PyUnicode_HASH(self) = _PyUnicode_HASH(unicode);
13953+
PyUnicode_SET_HASH((PyObject *)self, PyUnicode_HASH(unicode));
1395413954
#endif
1395513955
return self;
1395613956

Python/import.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5441,7 +5441,10 @@ _imp__set_lazy_attributes_impl(PyObject *module, PyObject *child_module,
54415441
PyThreadState *tstate = _PyThreadState_GET();
54425442
PyObject *child_dict = NULL;
54435443
PyObject *ret = NULL;
5444-
PyObject *lazy_modules = tstate->interp->imports.lazy_modules;
5444+
// Use atomic load and hold a reference to prevent use-after-free
5445+
// if another thread clears lazy_modules during interpreter shutdown.
5446+
PyObject *lazy_modules = FT_ATOMIC_LOAD_PTR_RELAXED(tstate->interp->imports.lazy_modules);
5447+
Py_XINCREF(lazy_modules);
54455448
if (lazy_modules != NULL) {
54465449
PyObject *lazy_submodules = PyDict_GetItemWithError(lazy_modules, name);
54475450
if (lazy_submodules == NULL) {
@@ -5483,6 +5486,7 @@ _imp__set_lazy_attributes_impl(PyObject *module, PyObject *child_module,
54835486
ret = Py_NewRef(Py_None);
54845487

54855488
error:
5489+
Py_XDECREF(lazy_modules);
54865490
Py_XDECREF(child_dict);
54875491
return ret;
54885492
}

0 commit comments

Comments
 (0)