Skip to content

Commit 89ddffb

Browse files
authored
bpo-29438: fixed use-after-free in key sharing dict (#39)
1 parent f66c81f commit 89ddffb

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

Misc/NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ What's New in Python 3.6.1 release candidate 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- bpo-29438: Fixed use-after-free problem in key sharing dict.
14+
1315
- Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0].
1416

1517
- Issue #29337: Fixed possible BytesWarning when compare the code objects.

Objects/dictobject.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -4376,15 +4376,19 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
43764376
}
43774377
if (value == NULL) {
43784378
res = PyDict_DelItem(dict, key);
4379-
if (cached != ((PyDictObject *)dict)->ma_keys) {
4379+
// Since key sharing dict doesn't allow deletion, PyDict_DelItem()
4380+
// always converts dict to combined form.
4381+
if ((cached = CACHED_KEYS(tp)) != NULL) {
43804382
CACHED_KEYS(tp) = NULL;
43814383
DK_DECREF(cached);
43824384
}
43834385
}
43844386
else {
4385-
int was_shared = cached == ((PyDictObject *)dict)->ma_keys;
4387+
int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
43864388
res = PyDict_SetItem(dict, key, value);
4387-
if (was_shared && cached != ((PyDictObject *)dict)->ma_keys) {
4389+
if (was_shared &&
4390+
(cached = CACHED_KEYS(tp)) != NULL &&
4391+
cached != ((PyDictObject *)dict)->ma_keys) {
43884392
/* PyDict_SetItem() may call dictresize and convert split table
43894393
* into combined table. In such case, convert it to split
43904394
* table again and update type's shared key only when this is

0 commit comments

Comments
 (0)