This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Invalid memory write in bytearray
Type: Stage:
Components: Interpreter Core Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: JelleZijlstra, gvanrossum
Priority: normal Keywords:

Created on 2022-03-13 02:05 by JelleZijlstra, last changed 2022-04-11 14:59 by admin.

Messages (2)
msg415021 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-03-13 02:05
Inspired by Guido's comment in https://github.com/python/cpython/pull/31834/files#r825352900, I found that there are some places in bytearrayobject.c where we can write to free'd memory if we encounter an object with a sneaky __index__ method:

$ cat basneak.py 
ba = bytearray([0 for _ in range(10000)])

class sneaky:
    def __index__(self):
        ba.clear()
        return 1

ba[-1] = sneaky()
$ valgrind ./python basneak.py 
==87894== Memcheck, a memory error detector
==87894== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==87894== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==87894== Command: ./python basneak.py
==87894== 
==87894== Invalid write of size 1
==87894==    at 0x49B70F: bytearray_ass_subscript (bytearrayobject.c:632)
==87894==    by 0x488E03: PyObject_SetItem (abstract.c:211)
<snip>

In bytearray_setitem(), we first do bounds checking, and then call _getbytevalue() to get the numeric value of the argument.

I think there's a similar bug in bytearray_ass_subscript().
msg415022 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-03-13 02:14
3.9 segfaults.

(gdb) bt
#0  bytearray_ass_subscript (self=<optimized out>, index=0x7ffff7e118f0, values=0x7ffff6f918b0) at Objects/bytearrayobject.c:640
#1  0x0000000000536302 in _PyEval_EvalFrameDefault (tstate=<optimized out>, f=0x999a80, throwflag=<optimized out>) at Python/ceval.c:1990
#2  0x0000000000534775 in _PyEval_EvalFrame (throwflag=0, f=0x999a80, tstate=0x93de90) at ./Include/internal/pycore_ceval.h:40
History
Date User Action Args
2022-04-11 14:59:57adminsetgithub: 91153
2022-03-13 02:14:01JelleZijlstrasetmessages: + msg415022
versions: + Python 3.9
2022-03-13 02:12:32JelleZijlstrasetcomponents: + Interpreter Core
versions: + Python 3.10, Python 3.11
2022-03-13 02:05:03JelleZijlstracreate