mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 10:31:33 -04:00
HID: tmff: Use 64-bit arithmetic for force feedback scaling
The logical minimum and maximum values come from the HID report descriptor and cover the full signed 32-bit range. Subtracting them in an int can overflow before the force feedback value is scaled. The subsequent multiplication can overflow as well, producing an incorrect value despite the final range checks. Use 64-bit intermediates for both scaling helpers, as done by commit48d1677779("HID: pidff: Fix integer overflow in pidff_rescale") for the same arithmetic in the PID driver. This keeps the arithmetic defined for the complete descriptor range before the result is clamped. Fixes:dc76c91214("Input: use new FF interface in the HID force feedback drivers") Fixes:b27c9590ca("HID: add support for Thrustmaster FGT Force Feedback wheel") Signed-off-by: Linmao Li <lilinmao@kylinos.cn> Signed-off-by: Jiri Kosina <jkosina@suse.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <linux/hid.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
@@ -47,9 +48,9 @@ struct tmff_device {
|
||||
/* Changes values from 0 to 0xffff into values from minimum to maximum */
|
||||
static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum)
|
||||
{
|
||||
int ret;
|
||||
s64 ret;
|
||||
|
||||
ret = (in * (maximum - minimum) / 0xffff) + minimum;
|
||||
ret = div_s64((s64)in * ((s64)maximum - minimum), 0xffff) + minimum;
|
||||
if (ret < minimum)
|
||||
return minimum;
|
||||
if (ret > maximum)
|
||||
@@ -60,9 +61,9 @@ static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum)
|
||||
/* Changes values from -0x80 to 0x7f into values from minimum to maximum */
|
||||
static inline int tmff_scale_s8(int in, int minimum, int maximum)
|
||||
{
|
||||
int ret;
|
||||
s64 ret;
|
||||
|
||||
ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum;
|
||||
ret = div_s64((s64)(in + 0x80) * ((s64)maximum - minimum), 0xff) + minimum;
|
||||
if (ret < minimum)
|
||||
return minimum;
|
||||
if (ret > maximum)
|
||||
|
||||
Reference in New Issue
Block a user