From 256f3c150724e4b3ee3575d1b3beeb65425e7834 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Fri, 4 Jun 2021 19:35:10 +0000 Subject: [PATCH] Prevent usage of freed memory by using getLights and getSensors Instead of separately querying light ids and light infos, just provide a list of light infos. They already contain the light ids. This way, we also avoid leaving uninitialized array elements when the lookup fails. In the InputReader code, a lock is obtained when the light information is being read, but that memory could change right after the call completes. Bug: 190126442 Test: atest inputflinger_tests libinput_tests Change-Id: I16ef37dce96d7077a8634d565b573fc26f1ebb5d --- ...droid_server_input_InputManagerService.cpp | 79 ++++++++----------- 1 file changed, 32 insertions(+), 47 deletions(-) diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index b7546441ae262..e13ef99e17dd0 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -1987,43 +1987,39 @@ static jobject nativeGetLights(JNIEnv* env, jclass clazz, jlong ptr, jint device NativeInputManager* im = reinterpret_cast(ptr); jobject jLights = env->NewObject(gArrayListClassInfo.clazz, gArrayListClassInfo.constructor); - std::vector lightIds = im->getInputManager()->getReader()->getLightIds(deviceId); + std::vector lights = + im->getInputManager()->getReader()->getLights(deviceId); - for (size_t i = 0; i < lightIds.size(); i++) { - const InputDeviceLightInfo* lightInfo = - im->getInputManager()->getReader()->getLightInfo(deviceId, lightIds[i]); - if (lightInfo == nullptr) { - ALOGW("Failed to get input device %d light info for id %d", deviceId, lightIds[i]); - continue; - } + for (size_t i = 0; i < lights.size(); i++) { + const InputDeviceLightInfo& lightInfo = lights[i]; jint jTypeId = env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeInput); jint jCapability = 0; - if (lightInfo->type == InputDeviceLightType::MONO) { + if (lightInfo.type == InputDeviceLightType::MONO) { jCapability = env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightCapabilityBrightness); - } else if (lightInfo->type == InputDeviceLightType::RGB || - lightInfo->type == InputDeviceLightType::MULTI_COLOR) { + } else if (lightInfo.type == InputDeviceLightType::RGB || + lightInfo.type == InputDeviceLightType::MULTI_COLOR) { jCapability = env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightCapabilityBrightness) | env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightCapabilityRgb); - } else if (lightInfo->type == InputDeviceLightType::PLAYER_ID) { + } else if (lightInfo.type == InputDeviceLightType::PLAYER_ID) { jTypeId = env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypePlayerId); } else { - ALOGW("Unknown light type %d", lightInfo->type); + ALOGW("Unknown light type %d", lightInfo.type); continue; } ScopedLocalRef lightObj(env, env->NewObject(gLightClassInfo.clazz, gLightClassInfo.constructor, - static_cast(lightInfo->id), - env->NewStringUTF(lightInfo->name.c_str()), - static_cast(lightInfo->ordinal), + static_cast(lightInfo.id), + env->NewStringUTF(lightInfo.name.c_str()), + static_cast(lightInfo.ordinal), jTypeId, jCapability)); // Add light object to list env->CallBooleanMethod(jLights, gArrayListClassInfo.add, lightObj.get()); @@ -2218,39 +2214,28 @@ static jobject createInputSensorInfo(JNIEnv* env, jstring name, jstring vendor, static jobjectArray nativeGetSensorList(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) { NativeInputManager* im = reinterpret_cast(ptr); - std::vector devices = im->getInputManager()->getReader()->getInputDevices(); - // Find the input device by deviceId - auto it = std::find_if(devices.begin(), devices.end(), - [deviceId](InputDeviceInfo& info) { return info.getId() == deviceId; }); + std::vector sensors = + im->getInputManager()->getReader()->getSensors(deviceId); - if (it == devices.end()) { - // Return an array of size 0 - return env->NewObjectArray(0, gInputSensorInfo.clazz, nullptr); - } + jobjectArray arr = env->NewObjectArray(sensors.size(), gInputSensorInfo.clazz, nullptr); + for (int i = 0; i < sensors.size(); i++) { + const InputDeviceSensorInfo& sensorInfo = sensors[i]; - std::vector types = it->getSensorTypes(); - jobjectArray arr = env->NewObjectArray(types.size(), gInputSensorInfo.clazz, nullptr); - for (int i = 0; i < types.size(); i++) { - const InputDeviceSensorInfo* sensorInfo = it->getSensorInfo(types[i]); - if (sensorInfo == nullptr) { - ALOGW("Failed to get input device %d sensor info for type %s", deviceId, - NamedEnum::string(types[i]).c_str()); - continue; - } - - jobject info = - createInputSensorInfo(env, env->NewStringUTF(sensorInfo->name.c_str()), - env->NewStringUTF(sensorInfo->vendor.c_str()), - (jint)sensorInfo->version, 0 /* handle */, - (jint)sensorInfo->type, (jfloat)sensorInfo->maxRange, - (jfloat)sensorInfo->resolution, (jfloat)sensorInfo->power, - (jfloat)sensorInfo->minDelay, - (jint)sensorInfo->fifoReservedEventCount, - (jint)sensorInfo->fifoMaxEventCount, - env->NewStringUTF(sensorInfo->stringType.c_str()), - env->NewStringUTF("") /* requiredPermission */, - (jint)sensorInfo->maxDelay, (jint)sensorInfo->flags, - (jint)sensorInfo->id); + jobject info = createInputSensorInfo(env, env->NewStringUTF(sensorInfo.name.c_str()), + env->NewStringUTF(sensorInfo.vendor.c_str()), + static_cast(sensorInfo.version), 0 /* handle */, + static_cast(sensorInfo.type), + static_cast(sensorInfo.maxRange), + static_cast(sensorInfo.resolution), + static_cast(sensorInfo.power), + static_cast(sensorInfo.minDelay), + static_cast(sensorInfo.fifoReservedEventCount), + static_cast(sensorInfo.fifoMaxEventCount), + env->NewStringUTF(sensorInfo.stringType.c_str()), + env->NewStringUTF("") /* requiredPermission */, + static_cast(sensorInfo.maxDelay), + static_cast(sensorInfo.flags), + static_cast(sensorInfo.id)); env->SetObjectArrayElement(arr, i, info); env->DeleteLocalRef(info); }