mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
gh-143195: fix UAF in {bytearray,memoryview}.hex(sep) via re-entrant sep.__len__ (#143209)
This commit is contained in:
parent
f5e11facf2
commit
9976c2b634
5 changed files with 44 additions and 2 deletions
|
|
@ -2092,6 +2092,19 @@ def make_case():
|
|||
with self.assertRaises(BufferError):
|
||||
ba.rsplit(evil)
|
||||
|
||||
def test_hex_use_after_free(self):
|
||||
# Prevent UAF in bytearray.hex(sep) with re-entrant sep.__len__.
|
||||
# Regression test for https://github.com/python/cpython/issues/143195.
|
||||
ba = bytearray(b'\xAA')
|
||||
|
||||
class S(bytes):
|
||||
def __len__(self):
|
||||
ba.clear()
|
||||
return 1
|
||||
|
||||
self.assertRaises(BufferError, ba.hex, S(b':'))
|
||||
|
||||
|
||||
class AssortedBytesTest(unittest.TestCase):
|
||||
#
|
||||
# Test various combinations of bytes and bytearray
|
||||
|
|
|
|||
|
|
@ -442,6 +442,20 @@ def test_issue22668(self):
|
|||
self.assertEqual(c.format, "H")
|
||||
self.assertEqual(d.format, "H")
|
||||
|
||||
def test_hex_use_after_free(self):
|
||||
# Prevent UAF in memoryview.hex(sep) with re-entrant sep.__len__.
|
||||
# Regression test for https://github.com/python/cpython/issues/143195.
|
||||
ba = bytearray(b'A' * 1024)
|
||||
mv = memoryview(ba)
|
||||
|
||||
class S(bytes):
|
||||
def __len__(self):
|
||||
mv.release()
|
||||
ba.clear()
|
||||
return 1
|
||||
|
||||
self.assertRaises(BufferError, mv.hex, S(b':'))
|
||||
|
||||
|
||||
# Variations on source objects for the buffer: bytes-like objects, then arrays
|
||||
# with itemsize > 1.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
Fix use-after-free crashes in :meth:`bytearray.hex` and :meth:`memoryview.hex`
|
||||
when the separator's :meth:`~object.__len__` mutates the original object.
|
||||
Patch by Bénédikt Tran.
|
||||
|
|
@ -2664,7 +2664,13 @@ bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep)
|
|||
{
|
||||
char* argbuf = PyByteArray_AS_STRING(self);
|
||||
Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
|
||||
return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep);
|
||||
// Prevent 'self' from being freed if computing len(sep) mutates 'self'
|
||||
// in _Py_strhex_with_sep().
|
||||
// See: https://github.com/python/cpython/issues/143195.
|
||||
self->ob_exports++;
|
||||
PyObject *res = _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep);
|
||||
self->ob_exports--;
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
|
|||
|
|
@ -2349,7 +2349,13 @@ memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep,
|
|||
CHECK_RELEASED(self);
|
||||
|
||||
if (MV_C_CONTIGUOUS(self->flags)) {
|
||||
return _Py_strhex_with_sep(src->buf, src->len, sep, bytes_per_sep);
|
||||
// Prevent 'self' from being freed if computing len(sep) mutates 'self'
|
||||
// in _Py_strhex_with_sep().
|
||||
// See: https://github.com/python/cpython/issues/143195.
|
||||
self->exports++;
|
||||
PyObject *ret = _Py_strhex_with_sep(src->buf, src->len, sep, bytes_per_sep);
|
||||
self->exports--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
PyBytesWriter *writer = PyBytesWriter_Create(src->len);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue