HID: playstation: sanity check DualSense calibration data.

[ Upstream commit ccf1e1626d ]

Make sure calibration values are defined to prevent potential kernel
crashes. This fixes a hypothetical issue for virtual or clone devices
inspired by a similar fix for DS4.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Roderick Colenbrander 2023-01-05 17:59:08 -08:00 committed by Greg Kroah-Hartman
parent 6d7686cc11
commit a54c5ad007
1 changed files with 32 additions and 0 deletions

View File

@ -626,6 +626,7 @@ static const struct attribute_group ps_device_attribute_group = {
static int dualsense_get_calibration_data(struct dualsense *ds)
{
struct hid_device *hdev = ds->base.hdev;
short gyro_pitch_bias, gyro_pitch_plus, gyro_pitch_minus;
short gyro_yaw_bias, gyro_yaw_plus, gyro_yaw_minus;
short gyro_roll_bias, gyro_roll_plus, gyro_roll_minus;
@ -636,6 +637,7 @@ static int dualsense_get_calibration_data(struct dualsense *ds)
int speed_2x;
int range_2g;
int ret = 0;
int i;
uint8_t *buf;
buf = kzalloc(DS_FEATURE_REPORT_CALIBRATION_SIZE, GFP_KERNEL);
@ -687,6 +689,21 @@ static int dualsense_get_calibration_data(struct dualsense *ds)
ds->gyro_calib_data[2].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S;
ds->gyro_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus;
/*
* Sanity check gyro calibration data. This is needed to prevent crashes
* during report handling of virtual, clone or broken devices not implementing
* calibration data properly.
*/
for (i = 0; i < ARRAY_SIZE(ds->gyro_calib_data); i++) {
if (ds->gyro_calib_data[i].sens_denom == 0) {
hid_warn(hdev, "Invalid gyro calibration data for axis (%d), disabling calibration.",
ds->gyro_calib_data[i].abs_code);
ds->gyro_calib_data[i].bias = 0;
ds->gyro_calib_data[i].sens_numer = DS_GYRO_RANGE;
ds->gyro_calib_data[i].sens_denom = S16_MAX;
}
}
/*
* Set accelerometer calibration and normalization parameters.
* Data values will be normalized to 1/DS_ACC_RES_PER_G g.
@ -709,6 +726,21 @@ static int dualsense_get_calibration_data(struct dualsense *ds)
ds->accel_calib_data[2].sens_numer = 2*DS_ACC_RES_PER_G;
ds->accel_calib_data[2].sens_denom = range_2g;
/*
* Sanity check accelerometer calibration data. This is needed to prevent crashes
* during report handling of virtual, clone or broken devices not implementing calibration
* data properly.
*/
for (i = 0; i < ARRAY_SIZE(ds->accel_calib_data); i++) {
if (ds->accel_calib_data[i].sens_denom == 0) {
hid_warn(hdev, "Invalid accelerometer calibration data for axis (%d), disabling calibration.",
ds->accel_calib_data[i].abs_code);
ds->accel_calib_data[i].bias = 0;
ds->accel_calib_data[i].sens_numer = DS_ACC_RANGE;
ds->accel_calib_data[i].sens_denom = S16_MAX;
}
}
err_free:
kfree(buf);
return ret;