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
This commit is contained in:
Siarhei Vishniakou
2021-06-04 19:35:10 +00:00
parent 5ba9720dbf
commit 256f3c1507

View File

@@ -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; });
std::vector<InputDeviceSensorInfo> 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<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()),
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<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 */,
static_cast<jint>(sensorInfo.maxDelay),
static_cast<jint>(sensorInfo.flags),
static_cast<jint>(sensorInfo.id));
env->SetObjectArrayElement(arr, i, info);
env->DeleteLocalRef(info);
}