Dashboard/Issues/OH-2026-DRIVERS-002
SubmittedCWE-20 — Improper Input Validation

SetModeImpl accepts any int32_t mode value — missing range validation for SensorMode enum

View Upstream Issuegitcode.com/openharmony/sensors_sensor_lite/issues/32
CWE:CWE-20 — Improper Input Validation
Date:2026-05-19
Affected Version:*
Component:sensor_service
Reporter:Toan
Affected Files
services/src/sensor_service_impl.cinterfaces/kits/native/include/sensor_agent_type.h

Summary

SetModeImpl in services/src/sensor_service_impl.c:279-289 validates sensorId but completely ignores the mode parameter. Any int32_t value — including negative numbers and values far exceeding the defined SensorMode enum range — is silently accepted and returns SENSOR_OK. Invalid modes propagate through the full call chain to the hardware driver unchecked.

Vulnerable Code

// services/src/sensor_service_impl.c lines 279–289
int32_t SetModeImpl(int32_t sensorId, const SensorUser *user, int32_t mode)
{
    HILOG_DEBUG(HILOG_MODULE_APP, "[SERVICE:%s]: %s begin",
        SENSOR_SERVICE, __func__);
    if ((sensorId >= SENSOR_TYPE_ID_MAX) || (sensorId < 0)) {
        HILOG_ERROR(HILOG_MODULE_APP, "[SERVICE:%s]: %s sensorId: %d is invalid",
            SENSOR_SERVICE, __func__, sensorId);
        return SENSOR_ERROR_INVALID_ID;
    }
    // ← NO validation of `mode`. Any int32_t passes silently.
    return SENSOR_OK;
}

The SensorMode enum defines exactly 5 valid modes (0–4), with SENSOR_MAX_MODE = 5 as a sentinel for range checking:

// interfaces/kits/native/include/sensor_agent_type.h
typedef enum SensorMode {
    SENSOR_DEFAULT_MODE  = 0,
    SENSOR_REALTIME_MODE = 1,
    SENSOR_ON_CHANGE     = 2,
    SENSOR_ONE_SHOT      = 3,
    SENSOR_FIFO_MODE     = 4,
    SENSOR_MAX_MODE,           // = 5, sentinel — not a real mode
} SensorMode;

Trigger Conditions

  1. Caller invokes SetMode with any out-of-range mode value on a valid subscribed sensor
  2. SetModeImpl validates sensorId but skips mode validation entirely
  3. Invalid mode propagates through the full call chain to the hardware driver:
SetMode(sensorTypeId, user, mode)                    ← agent API
  → SetModeByProxy(proxy, sensorId, user, mode)      ← checks proxy!=NULL, user!=NULL only
      → IPC invoke to service
          → SetModeImpl(sensorId, user, mode)         ← NO mode check
              → g_sensorDevice->SetMode(sensorId, mode)  ← garbage mode reaches driver
  1. All of the following incorrectly return SENSOR_OK(0):
InputExpected returnActual return
mode = -1SENSOR_ERROR_INVALID_PARAM (-3)SENSOR_OK (0)
mode = -100SENSOR_ERROR_INVALID_PARAM (-3)SENSOR_OK (0)
mode = 5 (SENSOR_MAX_MODE)SENSOR_ERROR_INVALID_PARAM (-3)SENSOR_OK (0)
mode = 100SENSOR_ERROR_INVALID_PARAM (-3)SENSOR_OK (0)
mode = INT32_MAXSENSOR_ERROR_INVALID_PARAM (-3)SENSOR_OK (0)

Impact

  • Invalid mode reaches hardware driver: No layer in the call chain rejects invalid modes — the service layer ignores it, the proxy layer ignores it, and the driver receives garbage
  • Silent acceptance: Callers receive SENSOR_OK for any mode value, giving no error signal for incorrect usage
  • Undefined hardware behavior: Driver behavior with out-of-range mode values is unpredictable

Suggested Fix

Add a 2-line range check using the existing SENSOR_MAX_MODE sentinel:

int32_t SetModeImpl(int32_t sensorId, const SensorUser *user, int32_t mode)
{
    if ((sensorId >= SENSOR_TYPE_ID_MAX) || (sensorId < 0)) {
        return SENSOR_ERROR_INVALID_ID;
    }
+   if (mode < 0 || mode >= (int32_t)SENSOR_MAX_MODE) {
+       return SENSOR_ERROR_INVALID_PARAM;
+   }
    return SENSOR_OK;
}

SENSOR_MAX_MODE is already defined in sensor_agent_type.h for exactly this purpose.