ApiInfo::set 是 Python C 扩展的属性 setter 函数,在第218行调用 PyUnicode_AsUTF8(value) 将 Python 对象转为 C 字符串,但未对返回值做空指针校验。CPython API 文档明确 PyUnicode_AsUTF8 在 value 非 Unicode 对象时返回 nullptr。当 Python 代码传入非字符串值(如整数、None 或 del 操作导致 value=NULL)时,第227行 string(val) 用 nullptr 构造 std::string 触发未定义行为。该函数作为 PyGetSetDef setter 注册,可被 Python 运行时直接调用。
核查1模式成立:第218行 PyUnicode_AsUTF8(value) 返回值 val 未做空指针校验,第227行 string(val) 在 val 为 nullptr 时触发未定义行为;亦无 PyUnicode_Check 或 value==nullptr 防护(核查2防护无效)。 核查3函数可达:函数在第275行注册为 PyGetSetDef setter({"compute_type", ApiInfo::get, ApiInfo::set, ...}),第1548行 tp_getset 赋值确认类型初始化完成,Python 运行时可直接调用;entry_callchain 与 call_sites 均为 std::set 容器命名的误匹配,但函数经 Python 类型注册确实可达。 核查4触发可达性:仓内无 Python 代码设置 compute_type 为非字符串值,但该 setter 是公开 Python C 扩展 API,Python 端任意非 Unicode 值(整数、None、del 操作致 value=NULL)均可直接到达 sink,属防御性编程缺失,触发条件广、外部可控输入直接到达 sink,对应 confidence 0.89
Source(问题源头) autofuse/compiler/py_module/pyascir.cpp:216 行 PyObject *value 作为 Python setter 入参(外部 Python 输入,类型由运行时决定,可能为非 Unicode 对象或 NULL)
Source(问题源头)
autofuse/compiler/py_module/pyascir.cpp:216 行 PyObject *value 作为 Python setter 入参(外部 Python 输入,类型由运行时决定,可能为非 Unicode 对象或 NULL)
Sink(问题爆发点) autofuse/compiler/py_module/pyascir.cpp:227 行 name_to_type.find(string(val)) 用可能为 nullptr 的 val 构造 std::string(空指针解引用 sink)
Sink(问题爆发点)
autofuse/compiler/py_module/pyascir.cpp:227 行 name_to_type.find(string(val)) 用可能为 nullptr 的 val 构造 std::string(空指针解引用 sink)
传播路径:
可达调用链1 起点:(entry functions) → 终点:pyascir::ApiInfo::set 深度:1
(entry functions)
pyascir::ApiInfo::set
可达调用链2 起点:(entry functions) → 终点:pyascir::ApiInfo::set 深度:1
可达调用链3 起点:(entry functions) → 终点:pyascir::ApiInfo::set 深度:1
可达调用链4 起点:(entry functions) → 终点:pyascir::ApiInfo::set 深度:1
可达调用链5 起点:(entry functions) → 终点:pyascir::ApiInfo::set 深度:1
int ApiInfo::set(PyObject *self, PyObject *value, void *closure) { (void)closure; if (value == nullptr || !PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, "compute_type must be a string"); return -1; } const char *val = PyUnicode_AsUTF8(value); if (val == nullptr) { PyErr_SetString(PyExc_TypeError, "compute_type must be a valid UTF-8 string"); return -1; } static const map<string, af::ComputeType> name_to_type = {
你好,感谢建议, 后续分析处理
缺陷信息
缺陷描述
ApiInfo::set 是 Python C 扩展的属性 setter 函数,在第218行调用 PyUnicode_AsUTF8(value) 将 Python 对象转为 C 字符串,但未对返回值做空指针校验。CPython API 文档明确 PyUnicode_AsUTF8 在 value 非 Unicode 对象时返回 nullptr。当 Python 代码传入非字符串值(如整数、None 或 del 操作导致 value=NULL)时,第227行 string(val) 用 nullptr 构造 std::string 触发未定义行为。该函数作为 PyGetSetDef setter 注册,可被 Python 运行时直接调用。
事实核查
数据流证据
传播路径:
调用链
可达调用链1 起点:
(entry functions)→ 终点:pyascir::ApiInfo::set深度:1可达调用链2 起点:
(entry functions)→ 终点:pyascir::ApiInfo::set深度:1可达调用链3 起点:
(entry functions)→ 终点:pyascir::ApiInfo::set深度:1可达调用链4 起点:
(entry functions)→ 终点:pyascir::ApiInfo::set深度:1可达调用链5 起点:
(entry functions)→ 终点:pyascir::ApiInfo::set深度:1修复建议
int ApiInfo::set(PyObject *self, PyObject *value, void *closure) { (void)closure; if (value == nullptr || !PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, "compute_type must be a string"); return -1; } const char *val = PyUnicode_AsUTF8(value); if (val == nullptr) { PyErr_SetString(PyExc_TypeError, "compute_type must be a valid UTF-8 string"); return -1; } static const map<string, af::ComputeType> name_to_type = {