Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 256f3c15 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

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
parent 5ba9720d
Loading
Loading
Loading
Loading
+34 −49
Original line number Diff line number Diff line
@@ -1987,43 +1987,39 @@ static jobject nativeGetLights(JNIEnv* env, jclass clazz, jlong ptr, jint device
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
    jobject jLights = env->NewObject(gArrayListClassInfo.clazz, gArrayListClassInfo.constructor);

    std::vector<int> lightIds = im->getInputManager()->getReader()->getLightIds(deviceId);
    std::vector<InputDeviceLightInfo> 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<jobject> lightObj(env,
                                         env->NewObject(gLightClassInfo.clazz,
                                                        gLightClassInfo.constructor,
                                                        static_cast<jint>(lightInfo->id),
                                                        env->NewStringUTF(lightInfo->name.c_str()),
                                                        static_cast<jint>(lightInfo->ordinal),
                                                        static_cast<jint>(lightInfo.id),
                                                        env->NewStringUTF(lightInfo.name.c_str()),
                                                        static_cast<jint>(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<NativeInputManager*>(ptr);
    std::vector<InputDeviceInfo> 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; });

    if (it == devices.end()) {
        // Return an array of size 0
        return env->NewObjectArray(0, gInputSensorInfo.clazz, nullptr);
    }

    std::vector<InputDeviceSensorType> 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()),
    std::vector<InputDeviceSensorInfo> sensors =
            im->getInputManager()->getReader()->getSensors(deviceId);

    jobjectArray arr = env->NewObjectArray(sensors.size(), gInputSensorInfo.clazz, nullptr);
    for (int i = 0; i < sensors.size(); i++) {
        const InputDeviceSensorInfo& sensorInfo = sensors[i];

        jobject info = createInputSensorInfo(env, env->NewStringUTF(sensorInfo.name.c_str()),
                                             env->NewStringUTF(sensorInfo.vendor.c_str()),
                                             static_cast<jint>(sensorInfo.version), 0 /* handle */,
                                             static_cast<jint>(sensorInfo.type),
                                             static_cast<jfloat>(sensorInfo.maxRange),
                                             static_cast<jfloat>(sensorInfo.resolution),
                                             static_cast<jfloat>(sensorInfo.power),
                                             static_cast<jfloat>(sensorInfo.minDelay),
                                             static_cast<jint>(sensorInfo.fifoReservedEventCount),
                                             static_cast<jint>(sensorInfo.fifoMaxEventCount),
                                             env->NewStringUTF(sensorInfo.stringType.c_str()),
                                             env->NewStringUTF("") /* requiredPermission */,
                                      (jint)sensorInfo->maxDelay, (jint)sensorInfo->flags,
                                      (jint)sensorInfo->id);
                                             static_cast<jint>(sensorInfo.maxDelay),
                                             static_cast<jint>(sensorInfo.flags),
                                             static_cast<jint>(sensorInfo.id));
        env->SetObjectArrayElement(arr, i, info);
        env->DeleteLocalRef(info);
    }