整数溢出:第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}),故缺陷可达。
uint32_t inputSize = n * stride * sizeof(float) * 2
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)
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 分配过小缓冲区
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 起点:(entry functions) → 终点:aclfftFft1DStride 深度:1
(entry functions)
aclfftFft1DStride
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);
已收到问题,我们将尽快修复。
缺陷信息
缺陷描述
整数溢出:第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}),故缺陷可达。数据流证据
传播路径:
调用链
可达调用链1 起点:
(entry functions)→ 终点:aclfftFft1DStride深度:1修复建议
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);