已关闭
【缺陷报告】数组索引越界 - 文件compare.h - 函数CompareExtend - 行号660 #254
zhangjunkai9创建于  25 天前关闭于  7 天前
zhangjunkai9
25 天前 创建

缺陷信息

缺陷类型arrayIndexOutOfBounds (数组索引越界)
函数CompareExtend
文件autofuse/ascendc/api/compare.h
行号660
置信度85%

缺陷描述

在 CompareExtend 函数第660行,Compare 的第一源操作数使用了 src_tmp[cnt],但数据在第656行通过 DataCopy(src_tmp[0], src0[cnt], left_cnt) 被复制到了 src_tmp[0]。cnt 是源 tensor src0 的累计偏移量(在循环中每轮累加 max_block_cnt),而非临时缓冲区 src_tmp 的偏移量。当 cnt 超过 src_tmp 的有效大小时(src_tmp 是 tmp_buf 的子视图,大小受限于 UB 缓冲区),src_tmp[cnt] 构成数组越界访问。正确写法应为 src_tmp[0]。该函数通过调用链 UpdateMaxIndexAndValue→CompareExtend 可达。

事实核查

核查1(模式成立):第656行 DataCopy(src_tmp[0], src0[cnt], left_cnt) 和第658行 DataCopy(src_tmp[256/sizeof(T)], src1[cnt], left_cnt) 将数据复制到 src_tmp[0] 和 src_tmp[256/sizeof(T)],但第660行 Compare(compare_out[0], src_tmp[cnt], src_tmp[256/sizeof(T)], ...) 使用 src_tmp[cnt] 作为第一源操作数。
cnt 是源 tensor src0 的累计偏移(每轮累加 max_block_cnt),远超 src_tmp 有效边界,数组越界访问模式成立。
核查2(防护无效):第654行 if(left_cnt*sizeof(T)<256) 仅判断分支,无对 cnt 与 src_tmp 边界的校验,无有效防护。
核查3(函数可达):call_sites 确认 argmax_with_value.h:67 UpdateMaxIndexAndValue 调用 CompareExtend(mask, max_value_temp, max_value_saved, CMPMODE::GT, cal_cnt, common_tmp_buf),函数可达。
核查4(触发可满足):触发条件为 left_cnt*sizeof(T)<256(第654行),当总数据量非块对齐时常见满足,触发可满足。
四项均成立,确认缺陷。

数据流证据

Source(问题源头)

autofuse/ascendc/api/argmax_with_value.h:35 行 const uint32_t cal_cnt 作为 UpdateMaxIndexAndValue 入参传入(外部决定计算量大小)

Sink(问题爆发点)

autofuse/ascendc/api/compare.h:660 行 Compare(compare_out[0], src_tmp[cnt], src_tmp[256 / sizeof(T)], ...) 使用 src_tmp[cnt] 作为第一源操作数(cnt 为源 tensor 偏移而非临时缓冲区偏移,越界访问 sink)

传播路径:

# 文件 行号 说明
1 autofuse/ascendc/api/argmax_with_value.h 35 const uint32_t cal_cnt 作为 UpdateMaxIndexAndValue 函数入参接收(外部输入)
2 autofuse/ascendc/api/argmax_with_value.h 54 LocalTensor<uint8_t> common_tmp_buf = tmp_buf[index32_size + mask_size] 从 tmp_buf 分配子缓冲区 common_tmp_buf(大小受限)
3 autofuse/ascendc/api/argmax_with_value.h 67 CompareExtend(mask, max_value_temp, max_value_saved, CMPMODE::GT, cal_cnt, common_tmp_buf) 调用 CompareExtend 传递 cal_cnt 和 common_tmp_buf(调用点)
4 autofuse/ascendc/api/compare.h 628 CompareExtend 函数接收 cal_cnt 和 tmp_buf(即 common_tmp_buf)作为入参
5 autofuse/ascendc/api/compare.h 633 const int32_t loop_num = cal_cnt / max_block_cnt 根据 cal_cnt 计算循环次数
6 autofuse/ascendc/api/compare.h 639 LocalTensor src_tmp = tmp_buf[tmp_offset].ReinterpretCast() 创建临时缓冲区视图 src_tmp(大小受限于 common_tmp_buf 剩余空间)
7 autofuse/ascendc/api/compare.h 640 int32_t cnt = 0 初始化源 tensor 偏移计数器
8 autofuse/ascendc/api/compare.h 649 cnt += max_block_cnt 在循环中累加 cnt(每轮增加 max_block_cnt,可达数千至上万)
9 autofuse/ascendc/api/compare.h 656 DataCopy(src_tmp[0], src0[cnt], left_cnt) 将数据复制到 src_tmp[0](正确目标偏移为0)
10 autofuse/ascendc/api/compare.h 660 Compare(compare_out[0], src_tmp[cnt], src_tmp[256 / sizeof(T)], ...) 使用 src_tmp[cnt] 读取数据(应使用 src_tmp[0],cnt 远超 src_tmp 边界导致越界)

调用链

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

# 文件 函数 函数起始行 调用点行
1 autofuse/ascendc/api/argmax_with_value.h:AscendC: UpdateMaxIndexAndValue 31 67
2 autofuse/ascendc/api/compare.h CompareExtend 561

修复建议

Compare(compare_out[0], src_tmp[0], src_tmp[256 / sizeof(T)], mode, 256 / sizeof(T));
likedislike
wangmingming成员
25 天前 评论:

你好,感谢建议, 后续分析处理

likedislike
Wwangmingming成员
25 天前 将 gcw_V3YyYBt1 设为负责人
Jjcmrn0930
18 天前 关联了pull request:解决issue253 254 255
Jjcmrn0930
18 天前 关联了pull request:解决issue 253 254 255
Wwangmingming成员
7 天前 issue状态由 进行中 改变为 已完成
Wwangmingming成员
7 天前 关闭了 issue