fbdev: kyro: Validate overlay viewport coordinates

The overlay viewport end coordinates are computed from the viewport
origin and dimensions using 32-bit unsigned arithmetic. Large input
values can cause these calculations to wrap around before the resulting
coordinates are passed to SetOverlayViewPort().

SetOverlayViewPort() packs the viewport coordinates into 16-bit
register fields. The X coordinates are additionally adjusted by +2
and +1 before being written. Validate the coordinate calculations
for 32-bit wraparound and ensure that the adjusted coordinates fit
within their 16-bit register fields before calling
SetOverlayViewPort().

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
Danila Chernetsov
2026-07-24 00:42:45 +00:00
committed by Helge Deller
parent d1917ccb7b
commit 7b5c7bc55e

View File

@@ -369,6 +369,9 @@ static int kyro_dev_overlay_create(u32 ulWidth,
static int kyro_dev_overlay_viewport_set(u32 x, u32 y, u32 ulWidth, u32 ulHeight)
{
u32 right;
u32 bottom;
if (deviceInfo.ulOverlayOffset == 0)
/* probably haven't called CreateOverlay yet */
return -EINVAL;
@@ -378,11 +381,30 @@ static int kyro_dev_overlay_viewport_set(u32 x, u32 y, u32 ulWidth, u32 ulHeight
(x < 2 && ulWidth + 2 == 0))
return -EINVAL;
/*
* SetOverlayViewPort() adjusts X coordinates by +2 (left) and +1
* (right) before packing them into 16-bit register fields.
*/
if (x > U16_MAX - 2 || y > U16_MAX)
return -EINVAL;
right = x + ulWidth;
bottom = y + ulHeight;
if (right < x || bottom < y)
return -EINVAL;
right--;
bottom--;
if (right > U16_MAX - 1 || bottom > U16_MAX)
return -EINVAL;
/* Stop Ramdac Output */
DisableRamdacOutput(deviceInfo.pSTGReg);
SetOverlayViewPort(deviceInfo.pSTGReg,
x, y, x + ulWidth - 1, y + ulHeight - 1);
x, y, right, bottom);
EnableOverlayPlane(deviceInfo.pSTGReg);
/* Start Ramdac Output */