SubmittedCWE-190 — Integer Overflow or Wraparound
SoftBusChannel::ExecuteCommand 中 static_cast<int32_t> 截断 size_t 导致堆溢出风险
View Upstream Issuegitcode.com/openharmony/security_access_token/issues/3173CWE:CWE-190 — Integer Overflow or Wraparound
Repository:security_access_token
Date:2026-04-29
Reporter:Zirui
漏洞编号:
CWE-190 (Integer Overflow), CWE-680 (Integer Overflow to Buffer Overflow)
漏洞归属组件
漏洞归属版本
CVSS V3.0分值
漏洞简述
问题描述
// soft_bus_channel.cpp:177-192
std::string SoftBusChannel::ExecuteCommand(const std::string &commandName, const std::string &jsonPayload)
{
// ...
int len = static_cast<int32_t>(RPC_TRANSFER_HEAD_BYTES_LENGTH + jsonPayload.length());
// ^^^^^^^^^^^^^^^^^ line 186: size_t (64位) 截断为 int32_t (32位有符号)
unsigned char* buf = new (std::nothrow) unsigned char[len + 1];
// ^^^^^^^ line 187: 若 len 为负数,len+1 作为 size_t 变为极大值
if (buf == nullptr) {
LOGE(ATM_DOMAIN, ATM_TAG, "No enough memory: %{public}d", len);
return "";
}
(void)memset_s(buf, len + 1, 0, len + 1); // line 192: 同样使用截断后的 len
// ...
}
jsonPayload.length() 返回 size_t(64 位平台上为 64 位无符号整数)。RPC_TRANSFER_HEAD_BYTES_LENGTH + jsonPayload.length() 的结果通过 static_cast<int32_t> 截断为 32 位有符号整数。
若 jsonPayload 长度超过 INT32_MAX - RPC_TRANSFER_HEAD_BYTES_LENGTH(约 2GB),len 将变为负数。len + 1 作为 size_t 传入 new[] 时,负数被解释为极大的无符号值,导致:
- 分配失败(返回 nullptr,被 null 检查捕获)— 较好情况
- 或分配极小缓冲区(取决于编译器对
int + 1的处理)— 后续memset_s和PrepareBytes越界写入
触发条件
TokenSyncManager 处理跨设备 Token 同步时,若远端设备发送超大 JSON payload(通过 SoftBusSocketListener::OnBytesReceived 接收),可触发此整数截断。
攻击路径:
- 攻击者控制分布式网络中的一台设备
- 通过 SoftBus 向目标设备发送超大 JSON payload
- 目标设备的
ExecuteCommand处理该 payload 时触发截断
影响性分析说明
影响
- 堆溢出:截断后的
len用于分配和后续内存操作,可能导致写入超出分配缓冲区 - 影响范围:所有参与分布式 Token 同步的 OpenHarmony 设备
原理分析
受影响版本
规避方案或消减措施
建议修复
// 修复方案:使用 size_t 并添加上限检查
std::string SoftBusChannel::ExecuteCommand(const std::string &commandName, const std::string &jsonPayload)
{
// ...
size_t total = RPC_TRANSFER_HEAD_BYTES_LENGTH + jsonPayload.length();
+ if (total > MAX_COMMAND_LENGTH) { // 添加合理上限,如 10MB
+ LOGE(ATM_DOMAIN, ATM_TAG, "payload too large: %{public}zu", total);
+ return "";
+ }
- int len = static_cast<int32_t>(RPC_TRANSFER_HEAD_BYTES_LENGTH + jsonPayload.length());
- unsigned char* buf = new (std::nothrow) unsigned char[len + 1];
+ unsigned char* buf = new (std::nothrow) unsigned char[total + 1];
// ...
}