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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user