Closed
Description
Bug report
Bug description:
If a custom iterator is passed into bytearray.join
, and then it frees the bytearray inside of its __iter__
, then memory can be read after it is freed:
# stringlib_join_ReadAfterFree.py
def ReadAfterFree(size, do):
b = bytearray(size)
class T:
def __iter__(self):
b.clear()
self.v = do()
yield b''
yield b''
c = b.join(t:=T())
return memoryview(c).cast('P'), t.v
if __name__ == '__main__':
leak, obj = ReadAfterFree(bytearray.__basicsize__, lambda: bytearray(8))
print('bytearray:', obj)
print('leaked memory of buffer:', leak.tolist())
➜ ~/Desktop/Coding/cpython_source git:(main) ./python.exe ../python/stringlib_join_ReadAfterFree.py
bytearray: bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
leaked memory of buffer: [1, 4305259912, 8, 9, 4307812848, 4307812848, 0]
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
- gh-112625: Protect bytearray from being freed by misbehaving iterator inside bytearray.join #112626
- [3.12] gh-112625: Protect bytearray from being freed by misbehaving iterator inside bytearray.join (GH-112626) #112693
- [3.11] gh-112625: Protect bytearray from being freed by misbehaving iterator inside bytearray.join (GH-112626) #112694