Skip to content

Out-of-bounds write in bytearray.extend() with a reentrant __buffer__ #153578

Description

@tonghuaroot

Bug report

Bug description:

The C implementation of bytearray.extend() acquires the argument's buffer
(running its __buffer__()) before clamping the append range, then clamps only
the high bound to the current size. A __buffer__ that shrinks the bytearray
leaves the low bound past the high bound, so extend runs a negative-size
memmove (an out-of-bounds write; SIGABRT on a debug build).

b = bytearray(b'x' * 100)
class Evil:
    def __buffer__(self, flags):
        b.clear()
        return memoryview(b'ABCDEFGH')
b.extend(Evil())   # out-of-bounds write

bytearray.__iadd__ re-reads the size after acquiring the buffer; extend()
does not.

CPython versions tested on:

3.13, 3.14, 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