已关闭
【缺陷报告】整数溢出 - 文件fft1_d_b.cpp - 函数aclfftFft1DB - 行号145 #24
zhangjunkai9创建于  15 天前关闭于  12 天前
zhangjunkai9
15 天前 创建

缺陷信息

缺陷类型integerOverflow (整数溢出)
函数aclfftFft1DB
文件src/fft1_d/arch32/fft_b/fft1_d_b.cpp
行号145

缺陷描述

整数溢出:第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)不抛异常。缺陷确认。

数据流证据

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 字节到该缓冲区导致堆溢出

传播路径:

# 文件 行号 说明
1 src/fft1_d/arch32/fft1_d_exec_api.cpp 60 const uint32_t n = impl->lengths[0] 用户可控的 FFT 长度(int32_t → uint32_t)
2 src/fft1_d/arch32/fft1_d_exec_api.cpp 61 const uint32_t batch = impl->batch 用户可控的批次数(int32_t → uint32_t)
3 src/fft1_d/arch32/fft1_d_exec_api.cpp 84 err = aclfftFft1DB(reinterpret_cast<float*>(idata), reinterpret_cast<float*>(odata), n, batch, isForward, impl->stream) configCore==kFftB 路径将 n 和 batch 传入 aclfftFft1DB
4 src/fft1_d/arch32/fft_b/fft1_d_b.cpp 132 extern "C" aclError aclfftFft1DB(float *x, float *y, uint32_t n, uint32_t batches, int isForward, void *stream) 形参 n 和 batches 接收为 uint32_t
5 src/fft1_d/arch32/fft_b/fft1_d_b.cpp 145 uint32_t inputSize = n * batches * sizeof(float) * 2 运算 n*batches 在 uint32_t 下执行(16384*32768=2^29 不溢出),乘以 sizeof(float)*2 后得 2^32 赋值给 uint32_t 截断为 0
6 src/fft1_d/arch32/fft_b/fft1_d_b.cpp 187 CHECK_ACL(aclrtMalloc(&dev_input, inputSize, ...)) 以截断后 inputSize=0 分配设备内存(sink)

调用链

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

# 文件 函数 函数起始行 调用点行
1 src/fft1_d/arch32/fft1_d_exec_api.cpp aclfftExecC2C_1D 53 84
2 src/fft1_d/arch32/fft_b/fft1_d_b.cpp aclfftFft1DB 132

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

# 文件 函数 函数起始行 调用点行
1 src/fft1_d/arch32/fft1_d_exec_api.cpp aclfftExecC2C_1D 53 94
2 src/fft1_d/arch32/fft_b/fft1_d_b.cpp aclfftFft1DB 132

修复建议

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);
likedislike
east_yang成员
15 天前 评论:

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

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