| From 4d098000ac193f359e6b8ca4801dbdbd6a27b41f Mon Sep 17 00:00:00 2001 |
| From: Nikita Zhandarovich <n.zhandarovich@fintech.ru> |
| Date: Thu, 16 Jan 2025 05:48:01 -0800 |
| Subject: drm/repaper: fix integer overflows in repeat functions |
| |
| From: Nikita Zhandarovich <n.zhandarovich@fintech.ru> |
| |
| commit 4d098000ac193f359e6b8ca4801dbdbd6a27b41f upstream. |
| |
| There are conditions, albeit somewhat unlikely, under which right hand |
| expressions, calculating the end of time period in functions like |
| repaper_frame_fixed_repeat(), may overflow. |
| |
| For instance, if 'factor10x' in repaper_get_temperature() is high |
| enough (170), as is 'epd->stage_time' in repaper_probe(), then the |
| resulting value of 'end' will not fit in unsigned int expression. |
| |
| Mitigate this by casting 'epd->factored_stage_time' to wider type before |
| any multiplication is done. |
| |
| Found by Linux Verification Center (linuxtesting.org) with static |
| analysis tool SVACE. |
| |
| Fixes: 3589211e9b03 ("drm/tinydrm: Add RePaper e-ink driver") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru> |
| Signed-off-by: Alex Lanzano <lanzano.alex@gmail.com> |
| Link: https://patchwork.freedesktop.org/patch/msgid/20250116134801.22067-1-n.zhandarovich@fintech.ru |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/gpu/drm/tiny/repaper.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/gpu/drm/tiny/repaper.c |
| +++ b/drivers/gpu/drm/tiny/repaper.c |
| @@ -454,7 +454,7 @@ static void repaper_frame_fixed_repeat(s |
| enum repaper_stage stage) |
| { |
| u64 start = local_clock(); |
| - u64 end = start + (epd->factored_stage_time * 1000 * 1000); |
| + u64 end = start + ((u64)epd->factored_stage_time * 1000 * 1000); |
| |
| do { |
| repaper_frame_fixed(epd, fixed_value, stage); |
| @@ -465,7 +465,7 @@ static void repaper_frame_data_repeat(st |
| const u8 *mask, enum repaper_stage stage) |
| { |
| u64 start = local_clock(); |
| - u64 end = start + (epd->factored_stage_time * 1000 * 1000); |
| + u64 end = start + ((u64)epd->factored_stage_time * 1000 * 1000); |
| |
| do { |
| repaper_frame_data(epd, image, mask, stage); |