Received: by 2002:ab2:7b86:0:b0:1f7:5705:b850 with SMTP id q6csp520381lqh; Sat, 4 May 2024 10:09:33 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVIfwGukVO/vYXsPxjAkzQaIA0MzIZWhXcRla04TJ9HGHmkJ9sRY8KuO2/yF6c/GuezhissEOJGH5/VSO+J9OWZlzBxudZi+cosJFe43Q== X-Google-Smtp-Source: AGHT+IGMoMgnD7a7AQfQrqE3whVRLYEuObmQV4gPWdF3hZPVoEu2aheI9e6lAbVg9nJKgQAmAuq9 X-Received: by 2002:a17:903:1247:b0:1e3:c9f6:c4b with SMTP id u7-20020a170903124700b001e3c9f60c4bmr7653297plh.10.1714842572910; Sat, 04 May 2024 10:09:32 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714842572; cv=pass; d=google.com; s=arc-20160816; b=xIzDyAPqWA84pyvmUj1BvQMcsOI1v0Hm4KZF1s/ozbczEKPiPN8buymHgDBWS4xLLQ Q1/pmGRxI8w8l4Cdr8pffKfGp1l1lo+st+a0dTOwENqZpHs7c8DBy52Wt4RHpRnScBe5 Yx5PkANsgrhNv4Rb4QMZeXdFUT8ymQ2nXwvdJwbRgPj7c3jjvmJRWuvhc8B9v9TlRhYp hfHkY5uEoUijwuNeMvmjVTInnafPZJUQGpRPdHmcRJa5Ewir+vlwmaenvjQ1g3zB0DZF Cr4dS5gZepyNRfPp3BpVGsa/kISgtlWWgoSLCH3Ph2PaPwFL0YnRdMGUf17/67g4tPr9 o5vA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from; bh=sMVrQFLWNhhhDVNl/Our3Fv4BzqrUCSd8mUT9biRndM=; fh=3M1PHg4byxu2MygWip944LqLZSq0Urk5Qa4iYXrexb8=; b=mfx/vzE5LFMfoVacHk+tcgekOmsll1HetCME+bFtZTX7X1kjbxdEBOOVJljwovPVkf amDkC49esUTofZRZCBaVQYjEO11MawaToj+qwy0gfoAkO22ege8ckuGG9DHflaf7Xfun t7pINW9A4DgsObcO/h4UspzgE+EecktaeL3zGKKjPF5iNQI5DUisO7DCZYoBm5IFvixG 06r1faf4uKkIyPMSCzrMuc9gu2TsbkoD2s191plj17dzeBDorGme3op56lD9tg3j1IB0 X/WgZuGS0TQtkIICIwJNFMiXSnPUNtFRv74IXqHqhaK2HuQPfAWpBJzZVSymbV7iyQEB saqQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=enpas.org); spf=pass (google.com: domain of linux-kernel+bounces-168764-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-168764-linux.lists.archive=gmail.com@vger.kernel.org" Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id m1-20020a170902db0100b001ea594ae4d0si5231365plx.222.2024.05.04.10.09.32 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 May 2024 10:09:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-168764-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=enpas.org); spf=pass (google.com: domain of linux-kernel+bounces-168764-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-168764-linux.lists.archive=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 26CEAB20EC6 for ; Sat, 4 May 2024 17:09:24 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 03B205CDF0; Sat, 4 May 2024 17:09:17 +0000 (UTC) Received: from mail.enpas.org (zhong.enpas.org [46.38.239.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 979846BB33; Sat, 4 May 2024 17:09:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.38.239.100 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714842556; cv=none; b=CXlg6aM4YDOgyloaY9eSWaRlHZ/6YsE0uK0rr8OFY6eHpmB+ZAg3JUzNoQTqpKuuW7IJqxofzIdwWWvztQABgofIva07t97Sy3eYG7ZQrMM5W72/W62+HhxEbY2ixD1pIISH13+895IIc16EnD14MOG6jJH1Pc+Zxh7bG2kuMTQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714842556; c=relaxed/simple; bh=yIjoJtSMB/U4omH3XyRyosupZ+BTbZUBwVD01ARDxjg=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=J3VMp7IZQY/qHiH7xovGBl/PkB6pPuWd084VS/9SYz7Kp3S4TTHomDCs2cROfa56esRTjUGvJ3BRS+EzYh15kAeO7mCzMiikV63iGmm0V6hkrwHNBBRT3K4iBSMO21mNko2vrMb5Hvb9oSp8MJeILLqHUy3OKQFJppmXEckPVps= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=enpas.org; spf=pass smtp.mailfrom=enpas.org; arc=none smtp.client-ip=46.38.239.100 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=enpas.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=enpas.org Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail.enpas.org (Postfix) with ESMTPSA id 50139FF9C3; Sat, 4 May 2024 16:59:19 +0000 (UTC) From: Max Staudt To: Roderick Colenbrander , Jiri Kosina , Benjamin Tissoires Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, max@enpas.org Subject: [PATCH v2] HID: playstation: DS4: Fix calibration workaround for clone devices Date: Sun, 5 May 2024 01:55:32 +0900 Message-Id: <20240504165531.21315-1-max@enpas.org> X-Mailer: git-send-email 2.39.2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The logic in dualshock4_get_calibration_data() used uninitialised data in case of a failed kzalloc() for the transfer buffer. The solution is to group all business logic and all sanity checks together, and jump only to the latter in case of an error. While we're at it, factor out the axes' labelling, since it must happen either way for input_report_abs() to succeed later on. Thanks to Dan Carpenter for the Smatch static checker warning. Fixes: a48a7cd85f55 ("HID: playstation: DS4: Don't fail on calibration data request") Signed-off-by: Max Staudt --- Changes in v1 -> v2: - Restored assignments to .abs_code in their original location - Added assignments to .abs_code in the error handling loops --- drivers/hid/hid-playstation.c | 52 +++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c index edc46fc02e9a..e7c309cfe3a0 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -1787,7 +1787,7 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_SIZE, GFP_KERNEL); if (!buf) { ret = -ENOMEM; - goto no_buffer_tail_check; + goto transfer_failed; } /* We should normally receive the feature report data we asked @@ -1807,6 +1807,7 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) hid_warn(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret); ret = -EILSEQ; + goto transfer_failed; } else { break; } @@ -1815,17 +1816,19 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, GFP_KERNEL); if (!buf) { ret = -ENOMEM; - goto no_buffer_tail_check; + goto transfer_failed; } ret = ps_get_report(hdev, DS4_FEATURE_REPORT_CALIBRATION_BT, buf, DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, true); - if (ret) + if (ret) { hid_warn(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret); + goto transfer_failed; + } } - /* Parse buffer. If the transfer failed, this safely copies zeroes. */ + /* Transfer succeeded - parse the calibration data received. */ gyro_pitch_bias = get_unaligned_le16(&buf[1]); gyro_yaw_bias = get_unaligned_le16(&buf[3]); gyro_roll_bias = get_unaligned_le16(&buf[5]); @@ -1854,6 +1857,9 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) acc_z_plus = get_unaligned_le16(&buf[31]); acc_z_minus = get_unaligned_le16(&buf[33]); + /* Done parsing the buffer, so let's free it. */ + kfree(buf); + /* * Set gyroscope calibration and normalization parameters. * Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s. @@ -1877,26 +1883,6 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) ds4->gyro_calib_data[2].sens_denom = abs(gyro_roll_plus - gyro_roll_bias) + abs(gyro_roll_minus - gyro_roll_bias); - /* Done parsing the buffer, so let's free it. */ - kfree(buf); - -no_buffer_tail_check: - - /* - * 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(ds4->gyro_calib_data); i++) { - if (ds4->gyro_calib_data[i].sens_denom == 0) { - hid_warn(hdev, "Invalid gyro calibration data for axis (%d), disabling calibration.", - ds4->gyro_calib_data[i].abs_code); - ds4->gyro_calib_data[i].bias = 0; - ds4->gyro_calib_data[i].sens_numer = DS4_GYRO_RANGE; - ds4->gyro_calib_data[i].sens_denom = S16_MAX; - } - } - /* * Set accelerometer calibration and normalization parameters. * Data values will be normalized to 1/DS4_ACC_RES_PER_G g. @@ -1919,6 +1905,23 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) ds4->accel_calib_data[2].sens_numer = 2*DS4_ACC_RES_PER_G; ds4->accel_calib_data[2].sens_denom = range_2g; +transfer_failed: + /* + * 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(ds4->gyro_calib_data); i++) { + if (ds4->gyro_calib_data[i].sens_denom == 0) { + ds4->gyro_calib_data[i].abs_code = ABS_RX + i; + hid_warn(hdev, "Invalid gyro calibration data for axis (%d), disabling calibration.", + ds4->gyro_calib_data[i].abs_code); + ds4->gyro_calib_data[i].bias = 0; + ds4->gyro_calib_data[i].sens_numer = DS4_GYRO_RANGE; + ds4->gyro_calib_data[i].sens_denom = S16_MAX; + } + } + /* * Sanity check accelerometer calibration data. This is needed to prevent crashes * during report handling of virtual, clone or broken devices not implementing calibration @@ -1926,6 +1929,7 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) */ for (i = 0; i < ARRAY_SIZE(ds4->accel_calib_data); i++) { if (ds4->accel_calib_data[i].sens_denom == 0) { + ds4->accel_calib_data[i].abs_code = ABS_X + i; hid_warn(hdev, "Invalid accelerometer calibration data for axis (%d), disabling calibration.", ds4->accel_calib_data[i].abs_code); ds4->accel_calib_data[i].bias = 0; -- 2.39.2