已关闭
【缺陷报告】访问已释放内存 - 文件fft_plan_destroy_api.cpp - 函数aclfftDestroy - 行号32 #60
zhangjunkai9创建于  9 天前关闭于  9 天前
zhangjunkai9
9 天前 创建

缺陷信息

缺陷类型useAfterFree (访问已释放内存)
函数aclfftDestroy
文件ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp
行号32
置信度89%

缺陷描述

aclfftDestroy 在第42行 delete impl 释放了 aclfftHandle_t 对象内存,但 is_destroyed 标志存储在该对象内部。当同一句柄被第二次传入 aclfftDestroy 时,第25行 impl=plan 获得悬垂指针,第29行 ACLFFT_CHECK_NULL(impl) 仅检查空指针无法拦截悬垂指针,第32行 impl->is_destroyed 直接访问已释放内存,构成 use-after-free。is_destroyed 检查本意是防止重复销毁,但由于对象在首次调用时即被 delete,该标志随对象一同销毁,导致第二次调用时读取已释放内存来检查标志,保护机制本身即为 UAF。该函数为公共 API 入口,is_destroyed 的存在证明开发者预期了重复销毁场景。

事实核查

核查1模式成立:第42行 delete impl 释放对象内存,第二次调用时第25行 impl=plan 获得悬垂指针,第29行 ACLFFT_CHECK_NULL(impl) 仅检查 NULL 无法拦截非空悬垂指针,第32行 impl->is_destroyed 访问已释放内存,构成 use-after-free。

核查2防护无效:is_destroyed 标志本意防重复销毁,但首次调用即 delete impl(第42行),标志随对象一同销毁,第二次调用时读取已释放内存来检查标志——防护机制本身即为 UAF。

核查3函数可达:aclfftDestroy 为公共 API,fft_plan_api.cpp 第61/90/119行有内部调用。

核查4触发无法证实满足:内部调用方(fft_plan_api.cpp)在 aclfftDestroy 后均执行 *plan=nullptr(第62/91/120行),防止了重复销毁;

但 is_destroyed 标志的存在证明开发者预期了外部调用方重复销毁场景,仓内无法证实外部调用方是否会重复调用且不置空。

属防御性编程缺失·触发条件广·外部可控输入(plan 句柄)直接到达 sink(impl->is_destroyed 解引用)→ confidence 0.89

数据流证据

Source(问题源头)

ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp:24 行 aclfftHandle plan 作为函数入参传入(外部调用方持有的句柄,首次销毁后变为悬垂指针)

Sink(问题爆发点)

ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp:32 行 if (impl->is_destroyed) 通过悬垂指针 impl 访问已释放对象的成员 is_destroyed(use-after-free sink)

传播路径:

# 文件 行号 说明
1 ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp 24 aclfftHandle plan 作为函数入参接收(外部句柄,首次调用后 plan 仍持有已释放内存地址)
2 ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp 25 aclfftHandle_t* impl = plan 将句柄赋值给 impl(第二次调用时 impl 为悬垂指针)
3 ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp 29 ACLFFT_CHECK_NULL(impl) 仅检查 NULL,无法拦截非空的悬垂指针(保护无效)
4 ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp 39 impl->is_destroyed = true 首次调用时设置标志(此写入在 delete 前完成)
5 ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp 42 delete impl 首次调用时释放对象内存(is_destroyed 标志随对象一同销毁)
6 ops-fft-master/ops-fft-master/lib/fft_plan_destroy_api.cpp 32 第二次调用时 impl->is_destroyed 访问已释放内存(UAF sink 触发)

修复建议

aclfftResult aclfftDestroy(aclfftHandle plan) {
    aclfftHandle_t* impl = plan;
    ACLFFT_CHECK_NULL(impl);
    if (impl->is_destroyed) {
        return ACLFFT_INVALID_PLAN;
    }
    if (impl->has_operator_state && impl->operator_state != nullptr) {}
    impl->is_destroyed = true;
    // Fix: do not delete impl here. The is_destroyed flag is stored inside
    // the object; deleting it makes subsequent is_destroyed checks read freed
    // memory (UAF). Keep the object as a tombstone so double-destroy is
    // safely detected via the is_destroyed flag.
    return ACLFFT_SUCCESS;
}
likedislike
east_yang成员
9 天前 评论:

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

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