已关闭
【缺陷报告】整数溢出 - 文件fft1_d_stride.cpp - 函数aclfftFft1DStride - 行号134 #23
zhangjunkai9创建于  21 天前关闭于  18 天前
zhangjunkai9
21 天前 创建

缺陷信息

缺陷类型integerOverflow (整数溢出)
函数aclfftFft1DStride
文件src/fft1_d/arch32/fft_stride/fft1_d_stride.cpp
行号134

缺陷描述

整数溢出:第134行 uint32_t inputSize = n * stride * sizeof(float) * 2 中,n 和 stride 均为 uint32_t 入参。stride 路径在 impl->stride[0] > 1 时触发(fft1_d_exec_api.cpp:73)。stride 由 aclfftMakePlan1d 设置(dimType==ACLFFT_VERTICAL 时 impl->stride[0]=batch)。例如 n=262144, stride=16384(用户调用 aclfftPlan1d(&plan, 262144, ACLFFT_C2C, 16384, ACLFFT_VERTICAL) → stride=16384, batch=1;n=262144 在 switch 第86行有效)时,n*stride=262144*16384=2^32 在 uint32_t 算术中直接溢出为 0,导致 aclrtMalloc 分配 0 字节。即使 n*stride 不溢出(如 n=131072, stride=4096 → n*stride=2^29),最终 n*stride*8=2^32 赋值给 uint32_t 仍截断为 0。aclfftMakePlan1d 无 stride 上界检查。

详细解释

经独立复核源代码确认缺陷真实存在。fft1_d_stride.cpp:134 行 uint32_t inputSize = n * stride * sizeof(float) * 2 中,n 和 stride 均为 uint32_t 入参(函数签名第45行)。当 n=262144、stride=16384 时,n*stride=4,294,967,296=2^32,在 uint32_t 算术中溢出为 0,导致 inputSize=0。即使 n*stride 不溢出(如 n=131072、stride=4096 → n*stride=2^29),最终 n*stride*8=2^32 赋值给 uint32_t 仍截断为 0。第148行 aclrtMalloc 以 inputSize=0 分配设备内存,随后 kernel 写入 n*stride*8 字节造成堆溢出。调用链可达性已验证:stride 由 aclfftMakePlan1d(fft_plan_init_api.cpp:93-95)在 dimType==ACLFFT_VERTICAL 时设置 impl->stride[0]=batch,且仅校验 nx>0、batch>0 无上界检查;aclfftExecC2C_1D(fft1_d_exec_api.cpp:73)当 impl->stride[0]>1 时第74行调用 aclfftFft1DStride。n=262144 在 fft1_d_stride.cpp:86 的 switch case 中有效(radixVec={64,64,64}),故缺陷可达。

数据流证据

Source(污点源)

src/fft1_d/arch32/fft1_d_exec_api.cpp:60 行 const uint32_t n = impl->lengths[0] 及 :73 行 if (impl->stride[0] > 1) stride 来自用户 plan 句柄(aclfftMakePlan1d:95 impl->stride[0] = batch 当 dimType==ACLFFT_VERTICAL)

Sink(污点汇聚点)

src/fft1_d/arch32/fft_stride/fft1_d_stride.cpp:148 行 CHECK_ACL(aclrtMalloc(&dev_input, inputSize, ACL_MEM_MALLOC_HUGE_FIRST)) 以溢出后的 inputSize 分配过小缓冲区

传播路径:

# 文件 行号 说明
1 src/fft1_d/arch32/fft1_d_exec_api.cpp 60 const uint32_t n = impl->lengths[0] 用户可控 FFT 长度
2 src/fft1_d/arch32/fft1_d_exec_api.cpp 73 if (impl->stride[0] > 1) stride 由 aclfftMakePlan1d 设置(dimType==ACLFFT_VERTICAL 时 stride=batch)
3 src/fft1_d/arch32/fft1_d_exec_api.cpp 74 err = aclfftFft1DStride(reinterpret_cast<float*>(idata), reinterpret_cast<float*>(odata), n, impl->stride[0], batch, isForward, impl->stream) 将 n 和 stride 传入 aclfftFft1DStride
4 src/fft1_d/arch32/fft_stride/fft1_d_stride.cpp 45 aclError aclfftFft1DStride(float *x, float *y, uint32_t n, uint32_t stride, uint32_t batches, int isForward, void *stream) 形参接收为 uint32_t
5 src/fft1_d/arch32/fft_stride/fft1_d_stride.cpp 134 uint32_t inputSize = n * stride * sizeof(float) * 2 n*stride=262144*16384=2^32 在 uint32_t 算术中溢出为 0
6 src/fft1_d/arch32/fft_stride/fft1_d_stride.cpp 148 CHECK_ACL(aclrtMalloc(&dev_input, inputSize, ...)) 以溢出后 inputSize=0 分配设备内存(sink)

调用链

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

# 文件 函数 函数起始行 调用点行
1 src/fft1_d/arch32/fft1_d_exec_api.cpp aclfftExecC2C_1D 53 74
2 src/fft1_d/arch32/fft_stride/fft1_d_stride.cpp aclfftFft1DStride 45

修复建议

uint64_t inputSize64 = static_cast<uint64_t>(n) * stride * sizeof(float) * 2;
if (inputSize64 > UINT32_MAX) {
    std::cerr << "FFT input size overflow: n=" << n << " stride=" << stride << std::endl;
    return ACL_ERROR_INVALID_PARAM;
}
uint32_t inputSize = static_cast<uint32_t>(inputSize64);
likedislike
east_yang成员
20 天前 评论:

已收到问题,我们将尽快修复。

likedislike
CANN-robotCANN-robot成员
18 天前 关闭了 issue
CANN-robotCANN-robot成员
18 天前 添加了label:resolved