https://github.com/python/cpython/commit/fd9db61a25019b982d2588270526c3c7e6438687 commit: fd9db61a25019b982d2588270526c3c7e6438687 branch: 3.14 author: Miss Islington (bot) <[email protected]> committer: picnixz <[email protected]> date: 2025-12-27T15:23:08Z summary:
[3.14] gh-142557: fix UAF in `bytearray.__mod__` when object is mutated while formatting `%`-style arguments (GH-143213) (#143227) gh-142557: fix UAF in `bytearray.__mod__` when object is mutated while formatting `%`-style arguments (GH-143213) (cherry picked from commit 61ee04834b096be00678c6819b4957f3f4413a5e) Co-authored-by: Bénédikt Tran <[email protected]> files: A Misc/NEWS.d/next/Core_and_Builtins/2025-12-27-12-25-06.gh-issue-142557.KWOc8b.rst M Lib/test/test_bytes.py M Objects/bytearrayobject.c diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 54604376863d35..ce26700aa6dcbf 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -1382,6 +1382,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) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-27-12-25-06.gh-issue-142557.KWOc8b.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-27-12-25-06.gh-issue-142557.KWOc8b.rst new file mode 100644 index 00000000000000..b7f7a585906c34 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-27-12-25-06.gh-issue-142557.KWOc8b.rst @@ -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. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 3778a37daac818..ba4ad85201ecab 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2790,7 +2790,15 @@ bytearray_mod_lock_held(PyObject *v, PyObject *w) _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(v); 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 PyObject * _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
