整数溢出:第145行 uint32_t inputSize = n * batches * sizeof(float) * 2 中,n 和 batches 均为 uint32_t 入参,乘法运算在 uint32_t 算术下执行。n*batches 的中间结果在 uint32_t 范围内可能不溢出,但最终乘积 n*batches*sizeof(float)*2 赋值给 uint32_t inputSize 时发生截断溢出。例如 n=16384, batches=32768(FindConfig entry 3: batch∈[1024,65537), 16384∈fftBRadices → configCore=kFftB → 第84行调用 aclfftFft1DB)时,n*batches=2^29(不溢出),但 n*batches*8=2^32 截断为 0,导致 aclrtMalloc 分配 0 字节、kernel 写入 4GB 数据造成堆溢出。aclfftMakePlan1d(fft_plan_init_api.cpp:79-80)仅校验 nx>0 和 batch>0,无上界检查,溢出值可达。
经独立复核源代码确认缺陷真实存在。(1) fft1_d_b.cpp:145 行确为 uint32_t inputSize = n * batches * sizeof(float) * 2;,函数签名(:132-133)中 n/batches 均为 uint32_t。(2) 求值顺序:n*batches(uint32_t*uint32_t=uint32_t,n=16384*batch=32768=2^29 不溢出)→ *sizeof(float)(提升为 size_t)→ *2(size_t)→ 赋给 uint32_t inputSize 截断:2^29*4*2=2^32 截断为0。inputSize=0 用于 :187 aclrtMalloc(分配0字节)和 :201 aclrtMemcpy,但 kernel fft_b(:218)写入 n*batches*8=4GB 数据导致堆溢出。(3) 调用链可达且触发值在配置范围内:aclfftMakePlan1d(fft_plan_init_api.cpp:73)仅校验 nx>0/batch>0(:79-80)无上界;aclfftExecC2C(fft_exec_api.cpp:42-43)→aclfftExecC2C_1D(fft1_d_exec_api.cpp:53)→FindConfig(32768,16384) 命中 entry 3(batch∈[1024,65537),16384∈fftBRadices)返回 kFftB →:84 调用 aclfftFft1DB,参数 n=16384、batches=32768 均经校验且在 int32_t 范围内。InitRadixB(:23,case 16384)不抛异常。缺陷确认。
uint32_t inputSize = n * batches * sizeof(float) * 2;
n*batches
*sizeof(float)
*2
Source(污点源) src/fft1_d/arch32/fft1_d_exec_api.cpp:60 行 const uint32_t n = impl->lengths[0] 及 :61 行 const uint32_t batch = impl->batch,n 和 batch 来自用户通过 aclfftPlan1d 创建的 plan 句柄(aclfftMakePlan1d 仅校验 >0,无上界约束)
Source(污点源)
src/fft1_d/arch32/fft1_d_exec_api.cpp:60 行 const uint32_t n = impl->lengths[0] 及 :61 行 const uint32_t batch = impl->batch,n 和 batch 来自用户通过 aclfftPlan1d 创建的 plan 句柄(aclfftMakePlan1d 仅校验 >0,无上界约束)
Sink(污点汇聚点) src/fft1_d/arch32/fft_b/fft1_d_b.cpp:187 行 CHECK_ACL(aclrtMalloc(&dev_input, inputSize, ACL_MEM_MALLOC_HUGE_FIRST)) 以溢出后的 inputSize 分配过小缓冲区;第218行 kernel fft_b 写入 n*batches*8 字节到该缓冲区导致堆溢出
Sink(污点汇聚点)
src/fft1_d/arch32/fft_b/fft1_d_b.cpp:187 行 CHECK_ACL(aclrtMalloc(&dev_input, inputSize, ACL_MEM_MALLOC_HUGE_FIRST)) 以溢出后的 inputSize 分配过小缓冲区;第218行 kernel fft_b 写入 n*batches*8 字节到该缓冲区导致堆溢出
传播路径:
可达调用链1 起点:(entry functions) → 终点:aclfftFft1DB 深度:1
(entry functions)
aclfftFft1DB
可达调用链2 起点:(entry functions) → 终点:aclfftFft1DB 深度:1
uint64_t inputSize64 = static_cast<uint64_t>(n) * batches * sizeof(float) * 2; if (inputSize64 > UINT32_MAX) { std::cerr << "FFT input size overflow: n=" << n << " batches=" << batches << std::endl; return ACL_ERROR_INVALID_PARAM; } uint32_t inputSize = static_cast<uint32_t>(inputSize64);
已收到问题,我们将尽快修复。
缺陷信息
缺陷描述
整数溢出:第145行 uint32_t inputSize = n * batches * sizeof(float) * 2 中,n 和 batches 均为 uint32_t 入参,乘法运算在 uint32_t 算术下执行。n*batches 的中间结果在 uint32_t 范围内可能不溢出,但最终乘积 n*batches*sizeof(float)*2 赋值给 uint32_t inputSize 时发生截断溢出。例如 n=16384, batches=32768(FindConfig entry 3: batch∈[1024,65537), 16384∈fftBRadices → configCore=kFftB → 第84行调用 aclfftFft1DB)时,n*batches=2^29(不溢出),但 n*batches*8=2^32 截断为 0,导致 aclrtMalloc 分配 0 字节、kernel 写入 4GB 数据造成堆溢出。aclfftMakePlan1d(fft_plan_init_api.cpp:79-80)仅校验 nx>0 和 batch>0,无上界检查,溢出值可达。
详细解释
经独立复核源代码确认缺陷真实存在。(1) fft1_d_b.cpp:145 行确为
uint32_t inputSize = n * batches * sizeof(float) * 2;,函数签名(:132-133)中 n/batches 均为 uint32_t。(2) 求值顺序:n*batches(uint32_t*uint32_t=uint32_t,n=16384*batch=32768=2^29 不溢出)→*sizeof(float)(提升为 size_t)→*2(size_t)→ 赋给 uint32_t inputSize 截断:2^29*4*2=2^32 截断为0。inputSize=0 用于 :187 aclrtMalloc(分配0字节)和 :201 aclrtMemcpy,但 kernel fft_b(:218)写入 n*batches*8=4GB 数据导致堆溢出。(3) 调用链可达且触发值在配置范围内:aclfftMakePlan1d(fft_plan_init_api.cpp:73)仅校验 nx>0/batch>0(:79-80)无上界;aclfftExecC2C(fft_exec_api.cpp:42-43)→aclfftExecC2C_1D(fft1_d_exec_api.cpp:53)→FindConfig(32768,16384) 命中 entry 3(batch∈[1024,65537),16384∈fftBRadices)返回 kFftB →:84 调用 aclfftFft1DB,参数 n=16384、batches=32768 均经校验且在 int32_t 范围内。InitRadixB(:23,case 16384)不抛异常。缺陷确认。数据流证据
传播路径:
调用链
可达调用链1 起点:
(entry functions)→ 终点:aclfftFft1DB深度:1可达调用链2 起点:
(entry functions)→ 终点:aclfftFft1DB深度:1修复建议
uint64_t inputSize64 = static_cast<uint64_t>(n) * batches * sizeof(float) * 2; if (inputSize64 > UINT32_MAX) { std::cerr << "FFT input size overflow: n=" << n << " batches=" << batches << std::endl; return ACL_ERROR_INVALID_PARAM; } uint32_t inputSize = static_cast<uint32_t>(inputSize64);