SubmittedCWE-476 — NULL Pointer Dereference
SecCompClient::GetInstance 在 OOM 时解引用空指针
View Upstream Issuegitcode.com/openharmony/security_security_component_manager/issues/395CWE:CWE-476 — NULL Pointer Dereference
Repository:security_security_component_manager
Date:2026-05-07
Reporter:Zirui
漏洞概述
SecCompClient::GetInstance() 使用 new (std::nothrow) 分配实例,当内存不足时返回 nullptr 并赋值给 instance。后续 return *instance 解引用 nullptr 导致崩溃。由于使用了 std::nothrow,开发者明确预期分配可能失败,但未处理失败情况。
漏洞详情
问题代码
文件: frameworks/inner_api/security_component/src/sec_comp_client.cpp:43-54
SecCompClient& SecCompClient::GetInstance()
{
static SecCompClient* instance = nullptr;
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(g_instanceMutex);
if (instance == nullptr) {
SecCompClient* tmp = new (std::nothrow)SecCompClient();
instance = std::move(tmp); // ← tmp 可能为 nullptr
}
}
return *instance; // ← OOM 时解引用 nullptr → 崩溃
}
分析
- 使用
new (std::nothrow)明确表示开发者预期分配可能失败 - 但分配失败后
instance被赋值为 nullptr return *instance解引用 nullptr → 未定义行为(通常 SIGSEGV)- 由于
instance是 static 变量,首次 OOM 后所有后续调用也会崩溃
触发条件
- 系统内存压力大,
new (std::nothrow)返回 nullptr - 任何调用
SecCompClient::GetInstance()的代码路径触发崩溃 - 嵌入式/IoT 设备上更容易触发
影响
- 调用进程崩溃(SIGSEGV)
- 所有使用安全组件客户端 SDK 的应用受影响
- OOM 条件下级联崩溃
修复建议
方案 A:移除 std::nothrow,让 OOM 抛出 std::bad_alloc(由上层处理):
SecCompClient& SecCompClient::GetInstance()
{
static SecCompClient* instance = nullptr;
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(g_instanceMutex);
if (instance == nullptr) {
- SecCompClient* tmp = new (std::nothrow)SecCompClient();
+ SecCompClient* tmp = new SecCompClient();
instance = std::move(tmp);
}
}
return *instance;
}
方案 B:保留 std::nothrow 但处理失败:
SecCompClient& SecCompClient::GetInstance()
{
static SecCompClient* instance = nullptr;
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(g_instanceMutex);
if (instance == nullptr) {
SecCompClient* tmp = new (std::nothrow)SecCompClient();
+ if (tmp == nullptr) {
+ SC_LOG_ERROR(LABEL, "Failed to allocate SecCompClient");
+ // 选择:abort() 或返回 static dummy(取决于架构决策)
+ }
instance = std::move(tmp);
}
}
return *instance;
}
涉及文件
frameworks/inner_api/security_component/src/sec_comp_client.cpp(line 49-53) — OOM 未处理