Skip to content

Commit ccf1e16

Browse files
Roderick ColenbranderJiri Kosina
authored andcommitted
HID: playstation: sanity check DualSense calibration data.
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 <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 74cb485 commit ccf1e16

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

drivers/hid/hid-playstation.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,7 @@ ATTRIBUTE_GROUPS(ps_device);
944944

945945
static int dualsense_get_calibration_data(struct dualsense *ds)
946946
{
947+
struct hid_device *hdev = ds->base.hdev;
947948
short gyro_pitch_bias, gyro_pitch_plus, gyro_pitch_minus;
948949
short gyro_yaw_bias, gyro_yaw_plus, gyro_yaw_minus;
949950
short gyro_roll_bias, gyro_roll_plus, gyro_roll_minus;
@@ -954,6 +955,7 @@ static int dualsense_get_calibration_data(struct dualsense *ds)
954955
int speed_2x;
955956
int range_2g;
956957
int ret = 0;
958+
int i;
957959
uint8_t *buf;
958960

959961
buf = kzalloc(DS_FEATURE_REPORT_CALIBRATION_SIZE, GFP_KERNEL);
@@ -1005,6 +1007,21 @@ static int dualsense_get_calibration_data(struct dualsense *ds)
10051007
ds->gyro_calib_data[2].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S;
10061008
ds->gyro_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus;
10071009

1010+
/*
1011+
* Sanity check gyro calibration data. This is needed to prevent crashes
1012+
* during report handling of virtual, clone or broken devices not implementing
1013+
* calibration data properly.
1014+
*/
1015+
for (i = 0; i < ARRAY_SIZE(ds->gyro_calib_data); i++) {
1016+
if (ds->gyro_calib_data[i].sens_denom == 0) {
1017+
hid_warn(hdev, "Invalid gyro calibration data for axis (%d), disabling calibration.",
1018+
ds->gyro_calib_data[i].abs_code);
1019+
ds->gyro_calib_data[i].bias = 0;
1020+
ds->gyro_calib_data[i].sens_numer = DS_GYRO_RANGE;
1021+
ds->gyro_calib_data[i].sens_denom = S16_MAX;
1022+
}
1023+
}
1024+
10081025
/*
10091026
* Set accelerometer calibration and normalization parameters.
10101027
* Data values will be normalized to 1/DS_ACC_RES_PER_G g.
@@ -1027,6 +1044,21 @@ static int dualsense_get_calibration_data(struct dualsense *ds)
10271044
ds->accel_calib_data[2].sens_numer = 2*DS_ACC_RES_PER_G;
10281045
ds->accel_calib_data[2].sens_denom = range_2g;
10291046

1047+
/*
1048+
* Sanity check accelerometer calibration data. This is needed to prevent crashes
1049+
* during report handling of virtual, clone or broken devices not implementing calibration
1050+
* data properly.
1051+
*/
1052+
for (i = 0; i < ARRAY_SIZE(ds->accel_calib_data); i++) {
1053+
if (ds->accel_calib_data[i].sens_denom == 0) {
1054+
hid_warn(hdev, "Invalid accelerometer calibration data for axis (%d), disabling calibration.",
1055+
ds->accel_calib_data[i].abs_code);
1056+
ds->accel_calib_data[i].bias = 0;
1057+
ds->accel_calib_data[i].sens_numer = DS_ACC_RANGE;
1058+
ds->accel_calib_data[i].sens_denom = S16_MAX;
1059+
}
1060+
}
1061+
10301062
err_free:
10311063
kfree(buf);
10321064
return ret;

0 commit comments

Comments
 (0)