Page 40 - 《软件学报》2026年第7期
P. 40
胡明哲 等: Python 软件包库中 C/C++外部语言调用的安全性分析 2725
32 字节内存, 错误地使用 C 标准库的 free 函数释放该内存将绕过 Python 内存管理器, 可能破坏其内部状态导致
未定义行为甚至内存损坏. 类似地, 外部函数实现 demo_rawmalloc_pymemfree 通过 PyMem_RawMalloc 分配原始
内存块, 但错误地使用 PyMem_Free 进行释放. 不同族内存接口的内部实现机制不同, 不匹配的使用会导致内存回
收异常, 引发崩溃或堆结构破坏.
代码 2. 构造析构不匹配测例.
//测例 1: PyMem_Malloc 错配 free (M2.1)
static PyObject* demo_pymem_malloc_free(PyObject *self, PyObject *args) {
char *buf = PyMem_Malloc(32);
if (!buf) return PyErr_NoMemory(), NULL;
free(buf); //错误: PyMem_Malloc 应对应 PyMem_Free
Py_RETURN_NONE;
}
//测例 2: PyMem_RawMalloc 错配 PyMem_Free (M2.1)
static PyObject* demo_rawmalloc_pymemfree(PyObject *self, PyObject *args) {
void *buf = PyMem_RawMalloc(64);
if (!buf) return PyErr_NoMemory(), NULL;
PyMem_Free(buf); //错误: PyMem_RawMalloc 应对应 PyMem_RawFree
Py_RETURN_NONE;
}
除了不同域之间内存操作 Python/C API 错配的问题外, 在表 2 中同一族内存接口内部, 重复释放、释放后使
用、内存泄漏、非法释放、偏移释放等 C 语言经典内存管理错误仍然存在, 我们将其统一记为非法内存分配与
释放 (M2.2). 漏洞测例如代码 3 所示. 代码 3 的测例 1 会破坏堆内存分配器的空闲链表结构或分配元数据, 进而引
发程序崩溃. 代码 3 的测例 2 堆中释放的内存可能已被回收到空闲池或分配给其他对象, 后续的写操作将产生未
定义行为, 可能带来数据破坏、非法访问和内存劫持的风险.
代码 3. 非法内存分配与释放测例.
//测例 1: 重复释放 (M2.2)
static PyObject* demo_double_free(PyObject *self, PyObject *args) {
char *buf = PyMem_Malloc(16);
if (!buf) return PyErr_NoMemory(), NULL;
PyMem_Free(buf);
PyMem_Free(buf); //错误
Py_RETURN_NONE;
}
//测例 2: 释放后使用 (M2.2)
static PyObject* demo_use_after_free(PyObject *self, PyObject *args) {
char *buf = PyMem_Malloc(16);
if (!buf) return PyErr_NoMemory(), NULL;
PyMem_Free(buf);
buf[0] = “X”; //错误: 释放后写入
Py_RETURN_NONE;
}

