]> granicus.if.org Git - python/commitdiff
bpo-29438: fixed use-after-free in key sharing dict (#39)
authorINADA Naoki <methane@users.noreply.github.com>
Mon, 13 Feb 2017 00:19:05 +0000 (09:19 +0900)
committerGitHub <noreply@github.com>
Mon, 13 Feb 2017 00:19:05 +0000 (09:19 +0900)
Misc/NEWS
Objects/dictobject.c

index d79ff2450defaa78f151aee5446833e16e3367fa..ceea2226561fd6c76c0c4f2121d854db6faa4a79 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ What's New in Python 3.6.1 release candidate 1?
 Core and Builtins
 -----------------
 
+- bpo-29438: Fixed use-after-free problem in key sharing dict.
+
 - Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0].
 
 - Issue #29337: Fixed possible BytesWarning when compare the code objects.
index a7b403bcecc5da2f76df4dc6bbfb9be6ce04dae0..b63b78a337225acc043db8a660033212006fe024 100644 (file)
@@ -4376,15 +4376,19 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
         }
         if (value == NULL) {
             res = PyDict_DelItem(dict, key);
-            if (cached != ((PyDictObject *)dict)->ma_keys) {
+            // Since key sharing dict doesn't allow deletion, PyDict_DelItem()
+            // always converts dict to combined form.
+            if ((cached = CACHED_KEYS(tp)) != NULL) {
                 CACHED_KEYS(tp) = NULL;
                 DK_DECREF(cached);
             }
         }
         else {
-            int was_shared = cached == ((PyDictObject *)dict)->ma_keys;
+            int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
             res = PyDict_SetItem(dict, key, value);
-            if (was_shared && cached != ((PyDictObject *)dict)->ma_keys) {
+            if (was_shared &&
+                    (cached = CACHED_KEYS(tp)) != NULL &&
+                    cached != ((PyDictObject *)dict)->ma_keys) {
                 /* PyDict_SetItem() may call dictresize and convert split table
                  * into combined table.  In such case, convert it to split
                  * table again and update type's shared key only when this is