https://github.com/python/cpython/commit/cb8b96ed25070ea7107ecda8ea7a38a56db73fa8 commit: cb8b96ed25070ea7107ecda8ea7a38a56db73fa8 branch: 3.14 author: Miss Islington (bot) <[email protected]> committer: picnixz <[email protected]> date: 2025-12-27T13:37:32Z summary:
[3.14] gh-142664: fix UAF in `memoryview.__hash__` via re-entrant data's `__hash__` (GH-143217) (#143221) gh-142664: fix UAF in `memoryview.__hash__` via re-entrant data's `__hash__` (GH-143217) (cherry picked from commit 00e24b80e092e7d36dc189fd260b2a4e730a6e7f) Co-authored-by: Bénédikt Tran <[email protected]> files: A Misc/NEWS.d/next/Core_and_Builtins/2025-12-27-13-18-12.gh-issue-142664.peeEDV.rst M Lib/test/test_memoryview.py M Objects/memoryobject.c diff --git a/Lib/test/test_memoryview.py b/Lib/test/test_memoryview.py index 1bd58eb6408833..a88413e4bb1d9e 100644 --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -387,6 +387,20 @@ def test_hash_writable(self): m = self._view(b) self.assertRaises(ValueError, hash, m) + def test_hash_use_after_free(self): + # Prevent crash in memoryview(v).__hash__ with re-entrant v.__hash__. + # Regression test for https://github.com/python/cpython/issues/142664. + class E(array.array): + def __hash__(self): + mv.release() + self.clear() + return 123 + + v = E('B', b'A' * 4096) + mv = memoryview(v).toreadonly() # must be read-only for hash() + self.assertRaises(BufferError, hash, mv) + self.assertRaises(BufferError, mv.__hash__) + def test_weakref(self): # Check memoryviews are weakrefable for tp in self._types: diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-27-13-18-12.gh-issue-142664.peeEDV.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-27-13-18-12.gh-issue-142664.peeEDV.rst new file mode 100644 index 00000000000000..39c218395cc4d3 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-27-13-18-12.gh-issue-142664.peeEDV.rst @@ -0,0 +1,3 @@ +Fix a use-after-free crash in :meth:`memoryview.__hash__ <object.__hash__>` +when the ``__hash__`` method of the referenced object mutates that object or +the view. Patch by Bénédikt Tran. diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index cf673fb379edcd..cf570d091102f3 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -3222,9 +3222,16 @@ memory_hash(PyObject *_self) "memoryview: hashing is restricted to formats 'B', 'b' or 'c'"); return -1; } - if (view->obj != NULL && PyObject_Hash(view->obj) == -1) { - /* Keep the original error message */ - return -1; + if (view->obj != NULL) { + // Prevent 'self' from being freed when computing the item's hash. + // See https://github.com/python/cpython/issues/142664. + self->exports++; + int rc = PyObject_Hash(view->obj); + self->exports--; + if (rc == -1) { + /* Keep the original error message */ + return -1; + } } if (!MV_C_CONTIGUOUS(self->flags)) { _______________________________________________ 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]
