FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-156939: Detect buffer overflow in bytearray by vstinner · Pull Request #157382 · python/cpython · GitHub

Repository navigation

3 changes: 2 additions & 1 deletion Include/cpython/bytearrayobject.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ typedef struct {
PyObject_VAR_HEAD
/* How many bytes allocated in ob_bytes

In the current implementation this is equivalent to Py_SIZE(ob_bytes_object).
In the current implementation this is equivalent to
PyBytes_GET_SIZE(ob_bytes_object).
The value is always loaded and stored atomically for thread safety.
There are API compatibilty concerns with removing so keeping for now. */
Py_ssize_t ob_alloc;
Expand Down
40 changes: 40 additions & 0 deletions Lib/test/test_capi/test_bytearray.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import sys
import textwrap
import unittest
from test import support
from test.support import import_helper
from test.support.script_helper import assert_python_failure

_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
Expand Down Expand Up @@ -172,6 +175,43 @@ def test_resize(self):
# CRASHES resize(object(), 0)
# CRASHES resize(NULL, 0)

@unittest.skipUnless(support.built_with_c_assertions(),
'Python built without assertions')
def test_detect_overflow(self):
# Test detection of buffer overflow
size = 123
for operation in (
'repr(ba)',
'ba.resize(5)',
'del ba[5:]',
'ba[5]',
'ba % ()',
):
with self.subTest(operation=operation):
code = textwrap.dedent(f'''
from test.support import SuppressCrashReport
import os
import _testcapi

size = {size}
with SuppressCrashReport():
# Trigger a buffer overflow in a new bytearray
ba = _testcapi.bytearray_overflow(size)
try:
{operation}
except:
# Ignore all exceptions
pass
# If we reached this line, the operation didn't
# detect the overflow. Exit immediatetly without
# calling the bytearray destructor since it can detect
# the overflow.
os._exit(0)
''')
proc = assert_python_failure('-c', code)
self.assertIn(b'Buffer overflow detected in bytearray', proc.err)
self.assertIn(f'at position {size}'.encode(), proc.err)


if __name__ == "__main__":
unittest.main()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
When Python is built in debug mode, :class:`bytearray` now detects buffer
overflow. Patch by Victor Stinner.
16 changes: 16 additions & 0 deletions Modules/_testcapi/bytes.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,29 @@ test_byteswriter_ptr(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
}


static PyObject *
bytearray_overflow(PyObject *Py_UNUSED(module), PyObject *arg)
{
PyObject *bytearray = PyObject_CallOneArg((PyObject*)&PyByteArray_Type, arg);
if (bytearray == NULL) {
return NULL;
}

char *data = PyByteArray_AS_STRING(bytearray);
Py_ssize_t size = PyByteArray_GET_SIZE(bytearray);
data[size] = '#'; // Buffer overflow!
return bytearray;
}


static PyMethodDef test_methods[] = {
{"bytes_resize", bytes_resize, METH_VARARGS},
{"bytes_join", bytes_join, METH_VARARGS},
{"byteswriter_abc", byteswriter_abc, METH_NOARGS},
{"byteswriter_resize", byteswriter_resize, METH_NOARGS},
{"byteswriter_highlevel", byteswriter_highlevel, METH_NOARGS},
{"test_byteswriter_ptr", test_byteswriter_ptr, METH_NOARGS},
{"bytearray_overflow", bytearray_overflow, METH_O},
{NULL},
};

Expand Down
Loading
Loading

Back | FazBrowse Home | New Git URL