已关闭
[Bug-Report|缺陷反馈]: 运行时 indices 边界检查错位导致错位写入与潜在越界写 #1947
wanglong9创建于  4月7日关闭于  4月22日
wanglong9
4月7日 创建

Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.

Describe the current behavior / 问题描述 (Mandatory / 必填)

OPSNN-IDX-001: scatter_nd 运行时 indices 边界检查错位导致错位写入与潜在越界写

结论摘要

  • 状态:已确认漏洞
  • confidence: high
  • verification_method: not-verified
  • sanitizer_build: not-applicable
  • 影响组件:
    • index/scatter_nd/op_kernel/arch35/scatter_nd.h
    • index/scatter_nd/op_kernel/arch35/scatter_nd_deterministic.h
  • 漏洞类型:运行时索引边界检查错误,导致错位写入,并在部分输入组合下形成 GM 越界写

影响范围与前置条件

  • 目标算子:scatter_nd
  • 触发条件:
    • 攻击者或上层调用者可控制运行时 indices 张量
    • kernel 进入 SimtCompute 或 deterministic 写回路径
  • 可达性说明:
    • host 侧会把输出真实 shape 传入 kernel
    • apt 模板会常规实例化非确定性和 deterministic 实现
    • 问题不是死代码或异常编译分支

调用路径

  1. host 侧准备 shape / stride 等 tiling 数据。
  2. index/scatter_nd/op_kernel/scatter_nd_apt.cpp 选择具体模板。
  3. 非确定性路径在 index/scatter_nd/op_kernel/arch35/scatter_nd.h:58-65 直接累加 idxAtomicAdd
  4. deterministic 路径在 index/scatter_nd/op_kernel/arch35/scatter_nd_deterministic.h:317-334 直接把 outOfstLocal(i) 转成写回偏移。

关键代码分析

1. 非确定性路径 SimtCompute

for (TYPE_T dim = 0; dim < rankSize; ++dim) {
  INDICES_T indiceVal = idxLocalAddr[currIndiceIdx + dim - indiceOffSet];
  outOfBound |= static_cast<TYPE_T>(indiceVal) > outputShapeAddr[dim];
  idx += indiceVal * strideListAddr[dim];
}
if (!outOfBound) {
  uint64_t dst = static_cast<uint64_t>(idx * sliceSize + scatterAxisIdx);
  Simt::AtomicAdd(outputGmAddr + dst, xLocalAddr[index]);
}

问题点:

  • 上界比较使用 >,因此 indiceVal == dim_size 被误判为合法。
  • 写回前缺少 idx >= 0 && idx < varInAxis 一类总范围校验。
  • 非法多维 index 会被直接扁平化成写回地址。

2. deterministic 路径

for (int64_t i = 0; i < indicesLen; ++i) {
  int64_t varRefOffset = outOfstLocal(i) * tilingData_.afterAxis;
  ...
  CopyOutUpdates(varRefOffset, updatesTailUbFactor);
}

问题点:

  • outOfstLocal(i) 直接参与 varRefOffset 计算。
  • 当前路径未见运行时边界过滤。
  • deterministic 不是安全 fallback,而是同模式 sibling。

根因

  1. 逐维上界比较语义错误,用 > 代替了 >=
  2. 缺少最终扁平化写回范围的二次防线。
  3. deterministic 与非确定性分支都没有统一的安全 helper。

可利用性与影响评估

  • 可控性:强,indices 为运行时输入。
  • 可达性:强,常规 host/apt 路径即可进入。
  • 影响:
    • 非法 index 被映射到错误行,造成错位写
    • 在部分组合下可进一步形成设备侧越界写
    • deterministic 分支同样受影响,回归风险高

最小 PoC 思路

  • 选择 rank > 1afterAxis > 0 的样例。
  • 构造 indiceVal == dim_size 的边界索引。
  • 观察:
    • 输出张量出现错误行更新
    • dst 脱离合法输出范围

修复建议

  1. 将逐维上界比较从 > 改为 >=
  2. 写回前统一加入 idx >= 0 && idx < varInAxis 或等价总行数检查。
  3. deterministic 路径在 varRefOffset 落盘前补同样的过滤。
  4. 按 family 统一修复,而不是只补一个模板。

验证状态

  • verification_method: not-verified
  • skip_reason:当前机器缺少 Ascend/CANN toolchain、相关二进制和 NPU 运行环境,无法构建并运行该 AICore kernel
  • attempted_strategies:
    • 检查 Ascend / CANN / toolkit 环境变量
    • 检查 npu_op_code_genop_buildaclnn 等工具
    • 检查常见安装路径 /usr/local/Ascend*/opt/Ascend*
  • attempt_count:3

任务与追踪信息

  • Candidate-ID:CAND-001
  • Family-ID:FAM-INDEX-BOUNDS-001
  • 相关扩展:artifacts/pattern_expansion_matrix.md

Environment / 环境信息 (Mandatory / 必填)

no

Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)

no

Describe the expected behavior / 预期结果 (Mandatory / 必填)

修复建议

  1. 将逐维上界比较从 > 改为 >=
  2. 写回前统一加入 idx >= 0 && idx < varInAxis 或等价总行数检查。
  3. deterministic 路径在 varRefOffset 落盘前补同样的过滤。
  4. 按 family 统一修复,而不是只补一个模板。

Special notes for this issue/备注 (Optional / 选填)

likedislike
zhang-wenbo-beatzhang-wenbo-beat成员
4月7日 将 zhang-wenbo-beat 设为负责人
zhang-wenbo-beatzhang-wenbo-beat成员
4月17日 关联了pull request:[ScatterNd] 补充对索引值范围的校验
zhang-wenbo-beatzhang-wenbo-beat成员
4月20日 关联了pull request:ScatterNd修复UB空间分配
CANN-robotCANN-robot成员
4月22日 关闭了 issue
CANN-robotCANN-robot成员
4月22日 添加了label:resolved