Skip to content

Commit 2294f3a

Browse files
authored
bpo-29438: fixed use-after-free in key sharing dict (#17)
1 parent e7ffb99 commit 2294f3a

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.7.0 alpha 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
@@ -4352,15 +4352,19 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
43524352
}
43534353
if (value == NULL) {
43544354
res = PyDict_DelItem(dict, key);
4355-
if (cached != ((PyDictObject *)dict)->ma_keys) {
4355+
// Since key sharing dict doesn't allow deletion, PyDict_DelItem()
4356+
// always converts dict to combined form.
4357+
if ((cached = CACHED_KEYS(tp)) != NULL) {
43564358
CACHED_KEYS(tp) = NULL;
43574359
DK_DECREF(cached);
43584360
}
43594361
}
43604362
else {
4361-
int was_shared = cached == ((PyDictObject *)dict)->ma_keys;
4363+
int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
43624364
res = PyDict_SetItem(dict, key, value);
4363-
if (was_shared && cached != ((PyDictObject *)dict)->ma_keys) {
4365+
if (was_shared &&
4366+
(cached = CACHED_KEYS(tp)) != NULL &&
4367+
cached != ((PyDictObject *)dict)->ma_keys) {
43644368
/* PyDict_SetItem() may call dictresize and convert split table
43654369
* into combined table. In such case, convert it to split
43664370
* table again and update type's shared key only when this is

0 commit comments

Comments
 (0)