Skip to content

itertoolsmodule: free-threading use after free bug in counting slow mode #153981

Description

@johng

Bug report

Bug description:

https://github.com/python/cpython/blob/main/Modules/itertoolsmodule.c#L3663

During next we swap out the pointer for lz->long_cnt inside count_nextlong. This can cause a use after free bug as shown with a new test. Running this is TSAN mode exposes this reliably.

ThreadSanitizer can not provide additional info.
SUMMARY: ThreadSanitizer: SEGV object.c:766 in PyObject_Repr
==83915==ABORTING
[1] 83915 abort PYTHON_GIL=0 ./python.exe -m unittest -v

class TestCountConcurrent(unittest.TestCase):
    @staticmethod
    def _spin_next(it, n=2000):
        for _ in range(n):
            next(it)

    @staticmethod
    def _spin_repr(it, n=2000):
        for _ in range(n):
            repr(it)

    @threading_helper.reap_threads
    def test_repr_racing_next_fast_mode(self):
        for _ in range(10):
            it = count()
            workers = [self._spin_next] * 2 + [self._spin_repr] * 4
            threading_helper.run_concurrently(workers, args=(it,))

    @threading_helper.reap_threads
    def test_repr_racing_next_slow_mode(self):
        for _ in range(10):
            # Large count to trigger "slow mode"
            it = count(10**18, 2)
            workers = [self._spin_next] * 2 + [self._spin_repr] * 4
            threading_helper.run_concurrently(workers, args=(it,))

To fix I believe we need to hold a critical section reference in repr to fetching a reference to long_cnt

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions