起步
相关的 issue 与 修复 ,从描述来看,这是一个 sprintf
函数引发的缓冲区溢出漏洞。
补丁获取链接:https://python-security.readthedocs.io/vuln/ctypes-buffer-overflow-pycarg_repr.html
复现
使用 3.8.7
进行复现:
这个漏洞在 3.8.8
便已修复:
分析
通过生成的 coredump
文件,查看异常堆栈:
注意到 Python-3.8.7/Modules/_ctypes/callproc.c
:
PyCArg_repr(PyCArgObject *self)
{
char buffer[256];
switch(self->tag) {
...
case 'd':
sprintf(buffer, "<cparam '%c' (%f)>", // 这行引发异常
self->tag, self->value.d); // value.d 的值是 1e300
break;
变量 buffer
的长度为 256 ,因此长度不够使得 sprintf
的缓冲区溢出,造成内存的破坏。
写个简单的 C 代码复现这个问题:
#include <stdio.h>
int main(int argc, char **argv) {
char buffer[256];
char tag = 'd';
double value = 1e300;
sprintf(buffer, "<cparam '%c' (%f)>", tag, value);
return 0;
}
我在中间加了一行 printf("%f\n", value);
再次执行:
这个长度已经超过 buffer
定义的长度了。double
类型,表示的小数位数能很大,所以至少可以覆盖 300 个字节;如果是 float
类型,就要小的多了。
在新版本之中该问题已经得到修复,已经将 sprintf
换成 PyUnicode_FromFormat
。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。