Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Deadlock when __len__ re-enters __length_hint__ via list iterator #6590

@jackfromeast

Description

@jackfromeast

What happened?

iterator.__length_hint__ holds its internal PyMutex while calling the sequence’s __len__. A user __len__ can call back into the same __length_hint__, which immediately blocks on the already-held mutex and deadlocks the interpreter instead of raising an error or progressing the iterator.

Proof of Concept:

it = None

class Evil:
    def __getitem__(self, index):
        if index == 0:
            return 0
        raise IndexError

    def __len__(self):
        it.__length_hint__()
        return 1

obj = Evil()
it = iter(obj)
it.__length_hint__()
Affected Versions
RustPython Version Status Exit Code
Python 3.13.0alpha (heads/main-dirty:21300f689, Dec 13 2025, 22:16:49) [RustPython 0.4.0 with rustc 1.90.0-nightly (11ad40bb8 2025-06-28)] Deadlock 124
Vulnerable Code
#[pymethod]
fn __length_hint__(&self, vm: &VirtualMachine) -> PyObjectRef {
    let internal = self.internal.lock(); // holds PyMutex across user callbacks
    if let IterStatus::Active(obj) = &internal.status {
        let seq = PySequence { obj, methods: self.seq_methods };
        seq.length(vm) // invokes user __len__. PoC calls iterator.__length_hint__ again while lock is held
            .map(|x| PyInt::from(x).into_pyobject(vm))
            .unwrap_or_else(|_| vm.ctx.not_implemented())
    } else {
        PyInt::from(0).into_pyobject(vm)
    }
}
// Inner __length_hint__ call tries to lock the same mutex again, blocking forever → deadlock.
Rust Output
Program hangs forever
CPython Output
Traceback (most recent call last):
  File "<string>", line 15, in <module>
  File "<string>", line 10, in __len__
  File "<string>", line 10, in __len__
  File "<string>", line 10, in __len__
  [Previous line repeated 496 more times]
RecursionError: maximum recursion depth exceeded

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions