From: Christian Heimes <christian@cheimes.de>
Date: Mon, 1 Jul 2013 21:42:28 +0000 (+0200)
Subject: Issue #18328: Reorder ops in PyThreadState_Delete*() functions. Now the
X-Git-Tag: v3.4.0a1~344^2
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b9dbc7d6e1ad5700ed0084f63215db97a2c9bcbb;p=python

Issue #18328: Reorder ops in PyThreadState_Delete*() functions. Now the
tstate is first removed from TLS and then deallocated.
CID 1019639 (#1 of 1): Use after free (USE_AFTER_FREE)
 use_after_free: Using freed pointer tstate.
---

diff --git a/Misc/NEWS b/Misc/NEWS
index cdc0225544..dd6d8d13c7 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 3.3.3 release candidate 1?
 Core and Builtins
 -----------------
 
+- Issue #18328: Reorder ops in PyThreadState_Delete*() functions. Now the
+  tstate is first removed from TLS and then deallocated.
+
 - Issue #18184: PyUnicode_FromFormat() and PyUnicode_FromFormatV() now raise
   OverflowError when an argument of %c format is out of range.
 
diff --git a/Python/pystate.c b/Python/pystate.c
index cfd61d0098..772aa53168 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -388,11 +388,11 @@ PyThreadState_Delete(PyThreadState *tstate)
 {
     if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current))
         Py_FatalError("PyThreadState_Delete: tstate is still current");
-    tstate_delete_common(tstate);
 #ifdef WITH_THREAD
     if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
         PyThread_delete_key_value(autoTLSkey);
 #endif /* WITH_THREAD */
+    tstate_delete_common(tstate);
 }
 
 
@@ -406,9 +406,9 @@ PyThreadState_DeleteCurrent()
         Py_FatalError(
             "PyThreadState_DeleteCurrent: no current tstate");
     _Py_atomic_store_relaxed(&_PyThreadState_Current, NULL);
-    tstate_delete_common(tstate);
     if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
         PyThread_delete_key_value(autoTLSkey);
+    tstate_delete_common(tstate);
     PyEval_ReleaseLock();
 }
 #endif /* WITH_THREAD */