Python是一种开放源代码的脚本编程语言。 Python的zlib扩展模块中用于flush解压流的方式获取一个输入参数来确定应flush多少数据。这个参数是一个有符型整数,没有经过过滤检查,因此如果传送了负值的话就会导致错误的内存分配,然后有符型整数会被转换为无符整数,触发缓冲区溢出。 Python-2.5.2/Modules/zlibmodule.c: 761 PyDoc_STRVAR(decomp_flush__doc__, 762 \"flush( [length] ) -- Return a string containing any remaining\n\" 763 \"decompressed data. length, if given, is the initial size of the\n\" 764 \"output buffer.\n\" 765 \"\n\" 766 \"The decompressor object can no longer be used after this call.\"); 767 768 static PyObject * 769 PyZlib_unflush(compobject *self, PyObject *args) 770 { 771 int err, length = DEFAULTALLOC; 772 PyObject * retval = NULL; 773 unsigned long start_total_out; 774 775 if (!PyArg_ParseTuple(args, \"|i:flush\", &length)) 776 return NULL; 777 if (!(retval = PyString_FromStringAndSize(NULL, length))) 778 return NULL; 779 780 781 ENTER_ZLIB 782 783 start_total_out = self->zst.total_out; 784 self->zst.avail_out = length; 785 self->zst.next_out = (Byte *)PyString_AS_STRING(retval); 786 787...
Python是一种开放源代码的脚本编程语言。 Python的zlib扩展模块中用于flush解压流的方式获取一个输入参数来确定应flush多少数据。这个参数是一个有符型整数,没有经过过滤检查,因此如果传送了负值的话就会导致错误的内存分配,然后有符型整数会被转换为无符整数,触发缓冲区溢出。 Python-2.5.2/Modules/zlibmodule.c: 761 PyDoc_STRVAR(decomp_flush__doc__, 762 \"flush( [length] ) -- Return a string containing any remaining\n\" 763 \"decompressed data. length, if given, is the initial size of the\n\" 764 \"output buffer.\n\" 765 \"\n\" 766 \"The decompressor object can no longer be used after this call.\"); 767 768 static PyObject * 769 PyZlib_unflush(compobject *self, PyObject *args) 770 { 771 int err, length = DEFAULTALLOC; 772 PyObject * retval = NULL; 773 unsigned long start_total_out; 774 775 if (!PyArg_ParseTuple(args, \"|i:flush\", &length)) 776 return NULL; 777 if (!(retval = PyString_FromStringAndSize(NULL, length))) 778 return NULL; 779 780 781 ENTER_ZLIB 782 783 start_total_out = self->zst.total_out; 784 self->zst.avail_out = length; 785 self->zst.next_out = (Byte *)PyString_AS_STRING(retval); 786 787 Py_BEGIN_ALLOW_THREADS 788 err = inflate(&(self->zst), Z_FINISH); 789 Py_END_ALLOW_THREADS PyArg_ParseTuple()函数为Python和C之间的转换方式,如果提供了的话就会初始化长度变量,然后在777行这个变量作为第二个参数传送给了PyString_FromStringAndSize()。该参数也是有符的,API调用本身没有验证非调试编译中的参数。之后这个值的大小为PyStringObject与该值大小的和,并传送给了Python分配程序。如果成功分配的话,在784行的赋值就会导致符号转换,zst结构的avail_out成员为无符变量。之后在785行将777行所分配内存的指针被分配给了zst结构的next_out成员,这会在zlib inflate()函数解压数据时在788行触发缓冲区溢出。