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;
}
缺陷信息
缺陷描述
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 的存在证明开发者预期了重复销毁场景。
事实核查
数据流证据
传播路径:
修复建议
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; }