Skip to content

Double DECREF from deque.extend() if block allocation fails in deque_append_lock_held #152951

Closed

Description

@stestagg

Crash report

What happened?

The following double-frees integers being added to the deque:

from collections import deque
import _testcapi

for n in range(100):
    try:
        _testcapi.set_nomemory(n, n+1)
        deque().extend(range(1000, 1500))
    except Exception as e:
        pass
    finally:
        _testcapi.remove_mem_hooks()    
./Include/refcount.h:520: _Py_NegativeRefcount: Assertion failed: object has negative ref count
<object at 0x105f21580 is freed>

Problem

deque_extend_impl

deque_extend_impl(dequeobject *deque, PyObject *iterable)

Calls deque_append_lock_held for each item:
if (deque_append_lock_held(deque, item, maxlen) == -1) {
Py_DECREF(item);
Py_DECREF(it);
return NULL;
}

And if the call fails, frees the references.

BUT, the only time deque_append_lock_held returns -1 is if a new block allocation fails:

block *b = newblock(deque);
if (b == NULL) {
Py_DECREF(item);
return -1;
}

And in this case, item has been decref'd already.

As far as I can tell, deque_append_lock_held reliably steals the reference from callers, so deque_extend_impl should not attempt to decref item after calling deque_append_lock_held in any situation.

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Output from running 'python -VV' on the command line:

Python 3.16.0a0 (heads/main-dirty:c4739533f33, Jul 3 2026, 12:23:57) [Clang 21.0.0 (clang-2100.3.20.102)]

Linked PRs

Activity

  1. added
    type-crashA hard crash of the interpreter, possibly with a core dump
    on Jul 3, 2026
  2. changed the title [-]Double free from deque.extend() if block allocation fails in `deque_append_lock_held`[/-] [+]Double DECREF from deque.extend() if block allocation fails in `deque_append_lock_held`[/+] on Jul 3, 2026
  3. added 4 commits that reference this issue on Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions