Skip to content

Use-after-free in bytearray.take_bytes() with a reentrant __index__ #153570

Description

@tonghuaroot

Bug report

Bug description:

The C implementation of bytearray.take_bytes() reads the size before calling
the argument's __index__(), then uses that stale size for the bounds check and
the buffer reads, so an __index__ that resizes the bytearray reads freed
memory (a use-after-free; segfaults on a debug build).

b = bytearray(b'A' * (16 * 1024 * 1024))
class Evil:
    def __index__(self):
        b.clear()
        return 8 * 1024 * 1024
b.take_bytes(Evil())   # use-after-free

bytearray.__setitem__ re-reads the size after __index__ (GH-91153).

CPython versions tested on:

3.15, 3.16

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-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