Closed
【缺陷报告】数组索引越界 - 文件pad_simt_huge.h - 函数SimtComputeHugeDimSeven - 行号289 #3487
zhangjunkai9Add on  Oct 12Closed at  20 days ago
zhangjunkai9
Oct 12 Create

缺陷信息

缺陷类型arrayIndexOutOfBounds (数组索引越界)
函数SimtComputeHugeDimSeven
文件ops-math-master/conversion/pad_v3/op_kernel/arch35/pad_simt_huge.h
行号289
置信度90%
分析模型maas-glm-5.1-zhipu

缺陷描述

在 SimtComputeHugeDimSeven 函数的边界检查中,dimSevenInIndex5(维度5的输入索引)的边界校验错误地使用了 tD->inShape[6](维度6的大小)而非 tD->inShape[5](维度5的大小)。当 inShape[5] > inShape[6] 时,dimSevenInIndex5 可能落在 [inShape[6], inShape[5]) 区间内通过错误的边界检查,但后续使用 dimSevenInIndex5 计算的 inputOffset 会导致 inputGM 越界读取。对比同文件的 SimtComputeHugeDimEight(第345-346行),dimEightInIndex5 正确使用了 tD->inShape[5],证实此处为复制粘贴错误。

事实核查

核查1(模式成立): 第288-289行边界检查 dimSevenInIndex5 < tD->inShape[6],应为 inShape[5],dimSevenInIndex5 是维度5的输入索引(第281行 dimSevenIndex5 - tD->leftPad[5]),对比 SimtComputeHugeDimEight 第346行正确使用 inShape[5],证实此处为复制粘贴错误,当 inShape[5]>inShape[6] 时 dimSevenInIndex5 落在 [inShape[6],inShape[5]) 区间通过错误检查,后续第300行用 dimSevenInIndex5 计算 inputOffset 访问 inputGM 导致越界读,模式属实。

核查2(防护无效): 该边界检查本身就是错误的(用了 inShape[6]),不存在其他对 dimSevenInIndex5 的有效校验。

核查3(函数可达): entry_callchain 确认 SimtComputeHugeDimSeven 为入口,pad_simt_huge.h 第427行 asc_vf_call 在 mDimNum==7 时调用,PadSimtHuge::Process 经 LaunchKernelPadMirrorSimtHuge(pad_mirror.h 第50行)由 pad_v3 入口(pad_v3_apt.cpp 第88行 REFLECT_SIMT_BIG_SIZE_BRANCH)分发,可达。

核查4(触发可满足): inShape 由用户输入 shape 决定(host 第1106行 tilingData_->inShape[i]=inShapeVal.GetDim(i)),用户可构造 inShape[5]>inShape[6] 的 7 维输入,使 dimSevenInIndex5 落入 [inShape[6],inShape[5]) 区间通过错误检查后越界读 inputGM,触发条件可满足。

缺陷类型为 arrayIndexOutOfBounds 正确。

数据流证据

Source(问题源头)

ops-math-master/conversion/pad_v3/op_kernel/arch35/pad_simt_huge.h:281 行 int64_t dimSevenInIndex5 = dimSevenIndex5 - tD->leftPad[5] 计算维度5的输入索引

Sink(问题爆发点)

ops-math-master/conversion/pad_v3/op_kernel/arch35/pad_simt_huge.h:293-301 行 outputGM[idx] = inputGM[dimSevenInIndex0 * ... * tD->inShape[6] + ... + dimSevenInIndex5 * tD->inShape[6] + dimSevenInIndex6] 当 dimSevenInIndex5 >= inShape[5] 时 inputOffset 超出 inputGM 有效范围

传播路径:

# 文件 行号 说明
1 ops-math-master/conversion/pad_v3/op_kernel/arch35/pad_simt_huge.h 269 uint64_t dimSevenIndex5 = yIdx - Simt::UintDiv(yIdx, m5, s5) * tD->outShape[5] 从输出索引分解出维度5的输出位置
2 ops-math-master/conversion/pad_v3/op_kernel/arch35/pad_simt_huge.h 281 int64_t dimSevenInIndex5 = dimSevenIndex5 - tD->leftPad[5] 减去左padding得到输入索引
3 ops-math-master/conversion/pad_v3/op_kernel/arch35/pad_simt_huge.h 288-289 dimSevenInIndex5 >= 0 && dimSevenInIndex5 < tD->inShape[6] 错误地用 inShape[6] 代替 inShape[5] 做边界检查
4 ops-math-master/conversion/pad_v3/op_kernel/arch35/pad_simt_huge.h 300 dimSevenInIndex5 * tD->inShape[6] + dimSevenInIndex6 使用未正确校验的 dimSevenInIndex5 计算 inputOffset 访问 inputGM

调用链

可达调用链1 起点:(entry functions) → 终点:PadV3::SimtComputeHugeDimSeven 深度:0

# 文件 函数 函数起始行 调用点行
1 ops-math-master/conversion/pad_v3/op_kernel/arch35/pad_simt_huge.h:PadV3: SimtComputeHugeDimSeven 256 —

修复建议

// 修复: 将 inShape[6] 改为 inShape[5]
// 第288-289行:
// 修改前:
//   dimSevenInIndex5 >= 0 && dimSevenInIndex5 < tD->inShape[6] &&
// 修改后:
//   dimSevenInIndex5 >= 0 && dimSevenInIndex5 < tD->inShape[5] &&

if (dimSevenInIndex6 >= 0 && dimSevenInIndex6 < tD->inShape[6] && dimSevenInIndex5 >= 0 &&
    dimSevenInIndex5 < tD->inShape[5] && dimSevenInIndex4 >= 0 && dimSevenInIndex4 < tD->inShape[4] &&
    dimSevenInIndex3 >= 0 && dimSevenInIndex3 < tD->inShape[3] && dimSevenInIndex2 >= 0 &&
    dimSevenInIndex2 < tD->inShape[2] && dimSevenInIndex1 >= 0 && dimSevenInIndex1 < tD->inShape[1] &&
    dimSevenInIndex0 >= 0 && dimSevenInIndex0 < tD->inShape[0]) {
likedislike
陈思
陈思Collaborators
Oct 13 Comments:

您好,感谢反馈!

问题分析

核对 ops-math 提交 f6c1c6f4aeccca50c9e60873e1a0fb4c40f7621d 的 pad_simt_huge.h,七维分支确实用 inShape[6] 检查第 5 维的输入索引,而该索引对应的合法上界应是 inShape[5]。

影响需要按两个方向区分:当 inShape[5] > inShape[6] 时,检查过严,会把部分合法输入位置当作 padding 并写入填充值;当 inShape[5] < inShape[6] 且输出位置产生了落在两者之间的第 5 维输入索引时,检查会错误放行,可能读取错误位置,在线性偏移超出整个输入范围时才构成越界读取。因此,报告中“大于时通过较小上界检查”的触发方向需要更正。

实际入口是 constant padding 的 LaunchKernelPadSimtHuge,并非 reflect 分支。host tiling 还会合并维度并选择计算模板;验证该七维 huge 分支时,需要确认合并后的维度仍为 7、选中 constant SIMT 分支,且输入或输出元素数超过 INT32_MAX,不能仅由原始输入是七维就判断已命中。

处理方向

可以将该上界改为 inShape[5],同时保留其余维度的独立检查。针对第 5、6 维大小分别小于、大于和相等的情况,核对有效区域拷贝与 padding 填充值,并检查末端索引的输入偏移边界,可以覆盖此次索引错配的主要影响。

目前已确认边界条件写错,具体输入到该模板的分发和设备表现仍需结合上述条件验证。

likedislike
Xxujiachen8Collaborators
27 days ago Assign yangjinwen as responsible person
YyangjinwenCollaborators
24 days ago Assign onanfield as responsible person
YyangjinwenCollaborators
24 days ago Removed responsible person yangjinwen
OonanfieldCollaborators
22 days ago Associated pull request
CANN-robotCANN-robotCollaborators
20 days ago Close issue
CANN-robotCANN-robotCollaborators
20 days ago Added label: resolved