已关闭
【缺陷报告】内存操作函数的源缓冲区长度参数错误导致越界 - 文件model_parse.c - 函数ParseModelDescExtend - 行号560 #551
zhangjunkai9创建于  9月6日关闭于  9月20日
zhangjunkai9
9月6日 创建

缺陷信息

缺陷类型sourceBufferAccessWithIncorrectLengthValue (内存操作函数的源缓冲区长度参数错误导致越界)
函数ParseModelDescExtend
文件runtime/c/executor/model_parse.c
行号560
置信度90%
分析模型glm-5.3-flash

缺陷描述

ParseModelDescExtend 解析 om 文件的 PRE_MODEL_DESC_EXTEND 分区:第550行仅校验分区实际 size >= sizeof(ModelExtendHead) 与 magic,第560行直接将文件中声称的 extendDesc->len(uint64)作为 tlvListLen 传入 ParseTlvList,未校验 extendDesc->len <= size - sizeof(ModelExtendHead)。ParseTlvList(第527-547行)内部所有边界检查(CheckLenValid(tlvListLen, ...))均以该声称长度为基准,TlvHead 读取(第530行)与 tlv->data 的处理(ProcFifoInfo)在声称长度超出分区实际大小时越过 om 模型内存缓冲区造成堆越界读。已验证完整可达链:公开 ACL API aclmdlQueryExeOMDesc(api/acl_c/acl_model/model/model.c:203→208)→ GetPartitionSize → GetModelPartitionSize → GetModelAllPartitionSize → GetModelFifoSize(model_desc.c:104,传入经 modelLen 校验的分区 data/size)→ ParseModelDescExtend。用户提供构造的 om 文件即可触发。

事实核查

核查1模式成立:第550行仅校验分区实际 size >= sizeof(ModelExtendHead),第556行仅校验 magic,第560行将 om 文件中声称的 extendDesc->len(uint64)直接作为 tlvListLen 传入 ParseTlvList;

ParseTlvList(第527-547行)内所有边界检查 CheckLenValid(model_desc.h:18-20,纯算术比较 total/offset/nextLen)均以该声称长度为基准,第530行 TlvHead 读取与第537行 ProcFifoInfo 对 tlv->data 的处理在声称长度超过分区实际大小时越出分区缓冲区。

核查2无防护:无 extendDesc->len 与 size - sizeof(ModelExtendHead) 的比较。

核查3可达链已逐行验证:公开 ACL API aclmdlQueryExeOMDesc(api/acl_c/acl_model/model/model.c:203-208,用户提供 om 文件路径)→ GetPartitionSize(ge_executor.c:97-107,LoadDataFromFile 加载)→ GetModelPartitionSize(model_desc.c:172-178)→ GetModelAllPartitionSize(第130行分区表对 modelLen 校验、第158行 PRE_MODEL_DESC_EXTEND 分支)→ GetModelFifoSize(model_desc.c:94-104,GetPartInfoFromModel 校验分区界内后返回 partition.data/size)→ ParseModelDescExtend;

另有 ParseModelDescExtendInfo(model_parse.c:568)模型加载解析路径。

核查4触发可满足:分区 data+size 虽保证在模型缓冲区界内,但 extendDesc->len 完全由 om 文件内容控制,声明大于分区实际剩余大小时 TlvHead/tlv->data 读取越过模型缓冲区造成堆越界读,构造 om 文件即可触发,缺陷真实

数据流证据

Source(问题源头)

runtime/c/executor/model_parse.c:555 行 struct ModelExtendHead *extendDesc = (struct ModelExtendHead *)data,其 len 字段(uint64)直接取自用户提供的 om 文件分区内容

Sink(问题爆发点)

runtime/c/executor/model_parse.c:560 行 ParseTlvList(modelData, data + sizeof(struct ModelExtendHead), extendDesc->len, mdlDesc) 以声称长度为全部边界检查基准;model_parse.c:530 行 struct TlvHead *tlv = (struct TlvHead *)(tlvList + offset) 及后续 tlv->data 读取越过实际分区缓冲区

传播路径:

# 文件 行号 说明
1 api/acl_c/acl_model/model/model.c 203-208 公开 API aclmdlQueryExeOMDesc(fileName, ...) 调用 GetPartitionSize(用户提供 om 文件路径)
2 runtime/c/executor/ge_executor.c 97-107 GetPartitionSize 调用 GetModelPartitionSize
3 runtime/c/executor/model_desc.c 172-178 GetModelPartitionSize 经 ParsePartitionPreProcess 校验分区表后调用 GetModelAllPartitionSize
4 runtime/c/executor/model_desc.c 157-158 PRE_MODEL_DESC_EXTEND 分区调用 GetModelFifoSize
5 runtime/c/executor/model_desc.c 94-104 GetModelFifoSize 取得分区 data/size(partitionInfo->mem_size 已对 modelLen 校验,分区 data+size 在模型缓冲区界内)后调用 ParseModelDescExtend
6 runtime/c/executor/model_parse.c 550-554 仅校验 size >= sizeof(ModelExtendHead) 与 magic,不含 len 与 size 的关系
7 runtime/c/executor/model_parse.c 560 extendDesc->len(文件声称值)未与 size - sizeof(ModelExtendHead) 比较即作为 tlvListLen 传入(sink)
8 runtime/c/executor/model_parse.c 529-540 ParseTlvList 的 while/CheckLenValid 全部以 tlvListLen 为界,TlvHead 与 tlv->data 读取可越出实际分区(CheckLenValid 定义于 model_desc.h:18,仅比较 total 与 offset)

调用链

可达调用链1 起点:(entry functions) → 终点:ParseModelDescExtend 深度:5

# 文件 函数 函数起始行 调用点行
1 api/acl_c/acl_model/model/model.c aclmdlQueryExeOMDesc 203 208
2 runtime/c/executor/ge_executor.c GetPartitionSize 97 107
3 runtime/c/executor/model_desc.c GetModelPartitionSize 172 178
4 runtime/c/executor/model_desc.c GetModelAllPartitionSize 122 158
5 runtime/c/executor/model_desc.c GetModelFifoSize 94 104
6 runtime/c/executor/model_parse.c ParseModelDescExtend 549 —

修复建议

在第560行调用 ParseTlvList 前校验声称长度不超过分区实际剩余大小:

if (extendDesc->len > (uint64_t)(size - sizeof(struct ModelExtendHead))) {
  GELOGE(ACL_ERROR_GE_PARAM_INVALID, "extend len %lu exceeds part size %zu.", extendDesc->len, size);
  return ACL_ERROR_GE_LOAD_MODEL;
}
return ParseTlvList(modelData, data + sizeof(struct ModelExtendHead), extendDesc->len, mdlDesc);
likedislike
夏国正成员
9月7日 评论:

我们将尽快根据您的描述确认问题是否存在,请您关注issue状态

likedislike
夏夏国正成员
9月7日 将 zhangpengpeng8 设为负责人
Nningjingyuan
9月9日 关联了pull request:fix: 校验模型扩展分区长度(#551)
CANN-robotCANN-robot成员
9月20日 关闭了 issue
CANN-robotCANN-robot成员
9月20日 添加了label:resolved