Skip to content

itertools.count use-after-free via re-entrant step.__radd__ #154670

Description

@tonghuaroot

Bug description

itertools.count has a use-after-free when the step object's __radd__ re-enters the iterator via next().

count_nextlong() borrows lz->long_cnt without Py_INCREF, then calls PyNumber_Add(result, lz->long_step). If long_step.__radd__ calls next() on the same count, the inner call returns the same pointer and the caller frees it. The outer call then returns a dangling pointer.

Crashes with PYTHONMALLOC=debug (SIGSEGV).

import itertools

class Step:
    def __radd__(self, other):
        next(c)
        return other + 1

c = itertools.count(1 << 100, Step())
next(c)  # SIGSEGV

CPython versions tested on

main

Operating systems tested on

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions