Skip to content

Commit 19fda67

Browse files
authored
[3.13] gh-142557: fix UAF in bytearray.__mod__ when object is mutated while formatting %-style arguments (GH-143213) (#143229)
(cherry picked from commit 61ee048)
1 parent b3a0d15 commit 19fda67

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

Lib/test/test_bytes.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,18 @@ def test_bytearray_api(self):
13491349
except OSError:
13501350
pass
13511351

1352+
def test_mod_concurrent_mutation(self):
1353+
# Prevent crash in __mod__ when formatting mutates the bytearray.
1354+
# Regression test for https://github.com/python/cpython/issues/142557.
1355+
fmt = bytearray(b"%a end")
1356+
1357+
class S:
1358+
def __repr__(self):
1359+
fmt.clear()
1360+
return "E"
1361+
1362+
self.assertRaises(BufferError, fmt.__mod__, S())
1363+
13521364
def test_reverse(self):
13531365
b = bytearray(b'hello')
13541366
self.assertEqual(b.reverse(), None)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a use-after-free crash in :ref:`bytearray.__mod__ <bytes-formatting>` when
2+
the :class:`!bytearray` is mutated while formatting the ``%``-style arguments.
3+
Patch by Bénédikt Tran.

Objects/bytearrayobject.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2401,7 +2401,15 @@ bytearray_mod(PyObject *v, PyObject *w)
24012401
{
24022402
if (!PyByteArray_Check(v))
24032403
Py_RETURN_NOTIMPLEMENTED;
2404-
return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
2404+
2405+
PyByteArrayObject *self = _PyByteArray_CAST(v);
2406+
/* Increase exports to prevent bytearray storage from changing during op. */
2407+
self->ob_exports++;
2408+
PyObject *res = _PyBytes_FormatEx(
2409+
PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1
2410+
);
2411+
self->ob_exports--;
2412+
return res;
24052413
}
24062414

24072415
static PyNumberMethods bytearray_as_number = {

0 commit comments

Comments
 (0)