已关闭
【缺陷报告】数据类型截断 - 文件rfft1_d_fast_dft.cpp - 函数aclfftRfft1D - 行号322 #59
zhangjunkai9创建于  9 天前关闭于  9 天前
zhangjunkai9
9 天前 创建

缺陷信息

缺陷类型dataTypeTruncation (数据类型截断)
函数aclfftRfft1D
文件ops-fft-master/ops-fft-master/src/rfft1_d/arch35/fast_dft/rfft1_d_fast_dft.cpp
行号322
置信度89%

缺陷描述

在 aclfftRfft1D 函数第322行,表达式 ((n/2)+1)*2*batches*sizeof(float) 中 ((n/2)+1)*2*batches 先以 uint32_t 运算(可能溢出),后 sizeof(float) 提升至 size_t,最终赋值给 uint32_t outputSize 截断。调用链中 n 被 aclfftExecR2C_1D 约束为 ≤4096 且函数内 n>4096 时提前返回,但 batches 无上界校验(最大 INT32_MAX≈21亿)。当 batches>262077 时 2049*2*batches*4 超过 UINT32_MAX,导致 aclrtMalloc 分配内存不足。

事实核查

核查1(缺陷模式): 第322行 const uint32_t outputSize = ((n / RFFT_SYMMETRY_DIVISOR) + 1) * COMPLEX_PART * batches * sizeof(float),n/batches 为 uint32_t,RFFT_SYMMETRY_DIVISOR 和 COMPLEX_PART 均为 uint32_t 常量,((n/2)+1)*2*batches 先以 uint32_t 运算可能溢出,后 sizeof(float) 提升至 size_t,最终赋值给 uint32_t 截断,模式成立。

核查2(防护有效性): 函数内第308行 if(n>DFT_BORDER_VALUE) return 仅约束 n<=4096,aclfftExecR2C_1D(rfft1_d_exec_api.cpp:46) 仅约束 n<=4096,均未约束 batches,无有效防护。

核查3(函数可达性): aclfftExecR2C_1D 在 rfft1_d_exec_api.cpp:47 调用 aclfftRfft1D,函数可达。

核查4(触发可达性): batch 为公共 API aclfftMakePlan1d 的用户可控参数(ACLFFT_API 导出),仅校验>0 无上界,当 batches>262077 时 2049*2*batches*4 超过 UINT32_MAX 触发截断;

仓内测试数据仅使用 batch=1/4/100,无内部调用方传入大 batch,触发条件在当前代码仓内无法证实满足。

属防御性编程缺失,外部可控输入直接到达 sink,触发条件广,对应 confidence 0.89

数据流证据

Source(问题源头)

ops-fft-master/ops-fft-master/lib/fft_plan_init_api.cpp:94 行 impl->lengths[0] = nx 与 :95 行 impl->batch = batch 作为 plan 入参存储(int32_t,仅校验 >0,无上界约束)

Sink(问题爆发点)

ops-fft-master/ops-fft-master/src/rfft1_d/arch35/fast_dft/rfft1_d_fast_dft.cpp:322 行 const uint32_t outputSize = ((n / 2) + 1) * 2 * batches * sizeof(float) 将 size_t 结果赋值给 uint32_t(截断 sink)

传播路径:

# 文件 行号 说明
1 ops-fft-master/ops-fft-master/lib/fft_plan_init_api.cpp 87 ACLFFT_CHECK_PARAM(nx > 0, ...) 仅校验 nx 为正,无上界
2 ops-fft-master/ops-fft-master/lib/fft_plan_init_api.cpp 88 ACLFFT_CHECK_PARAM(batch > 0, ...) 仅校验 batch 为正,无上界
3 ops-fft-master/ops-fft-master/lib/fft_plan_init_api.cpp 94 impl->lengths[0] = nx 将 int32_t nx 存入 plan
4 ops-fft-master/ops-fft-master/lib/fft_plan_init_api.cpp 95 impl->batch = batch 将 int32_t batch 存入 plan(最大 INT32_MAX≈21亿)
5 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/rfft1_d_exec_api.cpp 21 const uint32_t n = impl->lengths[0] 读取 plan 中的 n(无上界校验)
6 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/rfft1_d_exec_api.cpp 22 const uint32_t batch = impl->batch 读取 plan 中的 batch(无上界校验)
7 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/rfft1_d_exec_api.cpp 46 else if (n <= K_N_FFT_4096) 对 n 做上界约束(≤4096),但 batches 未被约束
8 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/rfft1_d_exec_api.cpp 47 err = aclfftRfft1D(..., n, ..., batch, ...) 将 n(≤4096)和 batch(无上界)作为实参传递
9 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/fast_dft/rfft1_d_fast_dft.cpp 308 if (n > DFT_BORDER_VALUE) return ACL_ERROR_INVALID_PARAM 函数内对 n 做上界校验(≤4096),但 batches 未被校验
10 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/fast_dft/rfft1_d_fast_dft.cpp 306 uint32_t n, ..., uint32_t batches 作为函数形参接收
11 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/fast_dft/rfft1_d_fast_dft.cpp 322 const uint32_t outputSize = ((n / 2) + 1) * 2 * batches * sizeof(float) 表达式 ((n/2)+1)*2*batches 先以 uint32_t 运算(可能溢出),后 sizeof(float) 提升至 size_t,最终赋值给 uint32_t 截断(sink)

调用链

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

# 文件 函数 函数起始行 调用点行
1 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/rfft1_d_exec_api.cpp aclfftExecR2C_1D 15 47
2 ops-fft-master/ops-fft-master/src/rfft1_d/arch35/fast_dft/rfft1_d_fast_dft.cpp aclfftRfft1D 306

修复建议

const size_t outputSize = (static_cast<size_t>(n / 2) + 1) * 2ULL * static_cast<size_t>(batches) * sizeof(float);
likedislike
east_yang成员
9 天前 评论:

感谢您的反馈,当前@east_yang跟踪处理中。

likedislike
Ssyy_3597
9 天前 关联了pull request:Fix: 修复8个issue(#41/#42/#50/#52/#53/#56/#59/#60) 构建脚本清理/空指针防护/尺寸截断/UAF
Yyangzhenyu成员
9 天前 issue状态由 进行中 改变为 已解决
Yyangzhenyu成员
9 天前 关闭了 issue
CANN-robotCANN-robot成员
9 天前 添加了label:resolved