cpython (3.4): Issue #24456: Fixed possible buffer over-read in adpcm2lin() and lin2adpcm()
https://hg.python.org/cpython/rev/fd17e168b59f changeset: 96703:fd17e168b59f branch: 3.4 parent: 96698:f0053d05ed6d user: Serhiy Storchaka <storchaka@gmail.com> date: Sun Jun 28 17:52:09 2015 +0300 summary: Issue #24456: Fixed possible buffer over-read in adpcm2lin() and lin2adpcm() functions of the audioop module. files: Lib/test/test_audioop.py | 10 +++++++ Misc/NEWS | 3 ++ Modules/audioop.c | 39 ++++++++++++++++++--------- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_audioop.py b/Lib/test/test_audioop.py --- a/Lib/test/test_audioop.py +++ b/Lib/test/test_audioop.py @@ -273,6 +273,16 @@ # state must be a tuple or None, not an integer self.assertRaises(TypeError, audioop.adpcm2lin, b'\0', 1, 555) self.assertRaises(TypeError, audioop.lin2adpcm, b'\0', 1, 555) + # Issues #24456, #24457: index out of range + self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, -1)) + self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, 89)) + self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, -1)) + self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, 89)) + # value out of range + self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (-0x8001, 0)) + self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0x8000, 0)) + self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (-0x8001, 0)) + self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0x8000, 0)) def test_lin2alaw(self): self.assertEqual(audioop.lin2alaw(datas[1], 1), diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -60,6 +60,9 @@ Library ------- +- Issue #24456: Fixed possible buffer over-read in adpcm2lin() and lin2adpcm() + functions of the audioop module. + - Issue #24336: The contextmanager decorator now works with functions with keyword arguments called "func" and "self". Patch by Martin Panter. diff --git a/Modules/audioop.c b/Modules/audioop.c --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1615,22 +1615,29 @@ if (!audioop_check_parameters(fragment->len, width)) return NULL; - str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2)); - if (str == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(str); - /* Decode state, should have (value, step) */ if ( state == Py_None ) { /* First time, it seems. Set defaults */ valpred = 0; index = 0; - } else if (!PyTuple_Check(state)) { + } + else if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); - goto exit; - } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) { - goto exit; + return NULL; } + else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) { + return NULL; + } + else if (valpred >= 0x8000 || valpred < -0x8000 || + (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) { + PyErr_SetString(PyExc_ValueError, "bad state"); + return NULL; + } + + str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2)); + if (str == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(str); step = stepsizeTable[index]; bufferstep = 1; @@ -1706,8 +1713,6 @@ bufferstep = !bufferstep; } rv = Py_BuildValue("(O(ii))", str, valpred, index); - - exit: Py_DECREF(str); return rv; } @@ -1742,11 +1747,19 @@ /* First time, it seems. Set defaults */ valpred = 0; index = 0; - } else if (!PyTuple_Check(state)) { + } + else if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); return NULL; - } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) + } + else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) { return NULL; + } + else if (valpred >= 0x8000 || valpred < -0x8000 || + (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) { + PyErr_SetString(PyExc_ValueError, "bad state"); + return NULL; + } if (fragment->len > (PY_SSIZE_T_MAX/2)/width) { PyErr_SetString(PyExc_MemoryError, -- Repository URL: https://hg.python.org/cpython
participants (1)
-
serhiy.storchaka