已关闭
【缺陷报告】容器访问越界 - 文件sort_merge_sort.h - 函数Process - 行号344 #2781
zhangjunkai9创建于  8月20日关闭于  8月26日
zhangjunkai9
8月20日 创建

缺陷信息

缺陷类型containerOutOfBounds (容器访问越界)
函数Process
文件math/sort/op_kernel/arch35/sort_merge_sort.h
行号344
置信度90%

缺陷描述

sort_merge_sort.h 第344行使用 if (blockIdx_ > GetBlockNum()) return; 作为边界保护,但同目录下 sort_radix_sort_one_core.h 第151行使用 if (blockIdx_ >= realCoreNum_) ,sort_axis_one_copy.h 第106行使用 if (blockIdx_ >= blockDim_) 等均使用 >= 比较。当 blockIdx_ 恰好等于 GetBlockNum() 时,该保护不会触发 return,该核会继续执行后续的 ProcessSingleBlockSort 循环,其中第303行 tileOffset = blockIdx_ * numTileData_ * oneCoreRowNum_ 和第337行 answerTileOffset = blockIdx_ * outputLastDimValue_ * oneCoreRowNum_ 会使用该无效 blockIdx_ 计算偏移,导致全局内存越界访问。

事实核查

经复核确认:第344行使用if(blockIdx_>GetBlockNum())作为边界保护,当blockIdx_==GetBlockNum()时不会return,该核继续执行。

对比同目录sort_radix_sort_one_core.h:151使用>=、sort_axis_one_copy.h:106使用>=、sort_small_axis_two_stage.h:125使用>=、sort_small_axis_insertion.h:126使用>=、non_last_small_axis_base.h:53使用>=、radix_more_core_base.h:1166使用>=,所有其他sort kernel均用>=比较。

blockIdx_由GetBlockIdx()获取(第92行),合法范围[0, GetBlockNum()-1],等于GetBlockNum()时为无效索引,后续第303行和第337行用blockIdx_计算GM偏移将导致越界访问。

这是一个明确的off-by-one缺陷。

数据流证据

Source(问题源头)

math/sort/op_kernel/arch35/sort_merge_sort.h:92 行 blockIdx_ = GetBlockIdx() 获取当前核索引(可能等于 GetBlockNum())

Sink(问题爆发点)

math/sort/op_kernel/arch35/sort_merge_sort.h:344 行 if (blockIdx_ > GetBlockNum()) return 边界检查使用 > 而非 >=,当 blockIdx_==GetBlockNum() 时不返回,后续访问 GM 越界

传播路径:

# 文件 行号 说明
1 math/sort/op_kernel/arch35/sort_merge_sort.h 92 blockIdx_ = GetBlockIdx() 获取核索引(可能等于总核数)
2 math/sort/op_kernel/arch35/sort_merge_sort.h 344 if (blockIdx_ > GetBlockNum()) return 使用 > 比较,blockIdx_==GetBlockNum() 时不返回(保护失败)
3 math/sort/op_kernel/arch35/sort_merge_sort.h 303 uint64_t tileOffset = blockIdx_ * numTileData_ * oneCoreRowNum_ 使用无效 blockIdx_ 计算偏移
4 math/sort/op_kernel/arch35/sort_merge_sort.h 337 uint64_t answerTileOffset = blockIdx_ * outputLastDimValue_ * oneCoreRowNum_ 使用无效 blockIdx_ 计算输出偏移(GM越界sink)

修复建议

if (blockIdx_ >= GetBlockNum()) {
    return;
}
likedislike
陈思
陈思成员
8月21日 评论:

分析结论

当前材料不足以认定存在可达越界。Ascend C GetBlockIdx() 的合法范围是 [0, GetBlockNum()),因此正常运行时 blockIdx_ == GetBlockNum() 不会发生;Issue 将该等值情况作为可达输入的前提不成立。官方接口说明:https://www.hiascend.com/document/detail/zh/canncommercial/900/API/ascendcopapi/atlasascendc_api_07_0185.html

当前 if (blockIdx_ > GetBlockNum()) 对合法 block index 实际上是不可触发的冗余保护,改成 >= 可以提升代码表达和防御性,但不能据此证明现有代码在正常调度下会越界。若有自定义启动参数能让该等值情况出现,请补充最小复现和 blockDim 配置。

likedislike
陈思陈思成员
8月25日 将 ConanHuang 设为负责人
Wwuxiyuan
8月25日 关联了pull request:修复Sort访问越界问题
CANN-robotCANN-robot成员
8月26日 关闭了 issue
CANN-robotCANN-robot成员
8月26日 添加了label:resolved