Skip to content

Commit 1bdeb38

Browse files
committed
gh-149816: Fix UAF in Modules/_pickle.c
Get a strong reference atomically for list item instead of 2 operations.
1 parent 14af19e commit 1bdeb38

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

Modules/_pickle.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,14 +3188,16 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj)
31883188
assert(obj != NULL);
31893189
assert(self->proto > 0);
31903190
assert(PyList_CheckExact(obj));
3191-
assert(PyList_GET_SIZE(obj));
31923191

31933192
/* Write in batches of BATCHSIZE. */
31943193
total = 0;
31953194
do {
31963195
if (PyList_GET_SIZE(obj) - total == 1) {
3197-
item = PyList_GET_ITEM(obj, total);
3198-
Py_INCREF(item);
3196+
item = PyList_GetItemRef(obj, total);
3197+
if (item == NULL) {
3198+
_PyErr_FormatNote("when serializing %T item %zd", obj, total);
3199+
return -1;
3200+
}
31993201
int err = save(state, self, item, 0);
32003202
Py_DECREF(item);
32013203
if (err < 0) {
@@ -3210,8 +3212,11 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj)
32103212
if (_Pickler_Write(self, &mark_op, 1) < 0)
32113213
return -1;
32123214
while (total < PyList_GET_SIZE(obj)) {
3213-
item = PyList_GET_ITEM(obj, total);
3214-
Py_INCREF(item);
3215+
item = PyList_GetItemRef(obj, total);
3216+
if (item == NULL) {
3217+
_PyErr_FormatNote("when serializing %T item %zd", obj, total);
3218+
return -1;
3219+
}
32153220
int err = save(state, self, item, 0);
32163221
Py_DECREF(item);
32173222
if (err < 0) {

0 commit comments

Comments
 (0)