[3.13] gh-142557: fix UAF in bytearray.__mod__ when object is mutated while formatting %-style arguments (GH-143213) (#143229)

(cherry picked from commit 61ee04834b)
This commit is contained in:
Bénédikt Tran 2025-12-27 17:20:49 +00:00 committed by GitHub
parent b3a0d15e3b
commit 19fda670d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 1 deletions

View file

@ -1349,6 +1349,18 @@ def test_bytearray_api(self):
except OSError:
pass
def test_mod_concurrent_mutation(self):
# Prevent crash in __mod__ when formatting mutates the bytearray.
# Regression test for https://github.com/python/cpython/issues/142557.
fmt = bytearray(b"%a end")
class S:
def __repr__(self):
fmt.clear()
return "E"
self.assertRaises(BufferError, fmt.__mod__, S())
def test_reverse(self):
b = bytearray(b'hello')
self.assertEqual(b.reverse(), None)

View file

@ -0,0 +1,3 @@
Fix a use-after-free crash in :ref:`bytearray.__mod__ <bytes-formatting>` when
the :class:`!bytearray` is mutated while formatting the ``%``-style arguments.
Patch by Bénédikt Tran.

View file

@ -2401,7 +2401,15 @@ bytearray_mod(PyObject *v, PyObject *w)
{
if (!PyByteArray_Check(v))
Py_RETURN_NOTIMPLEMENTED;
return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
PyByteArrayObject *self = _PyByteArray_CAST(v);
/* Increase exports to prevent bytearray storage from changing during op. */
self->ob_exports++;
PyObject *res = _PyBytes_FormatEx(
PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1
);
self->ob_exports--;
return res;
}
static PyNumberMethods bytearray_as_number = {