diff options
| author | Danila Chernetsov <listdansp@mail.ru> | 2026-07-24 00:42:45 +0000 |
|---|---|---|
| committer | Helge Deller <deller@gmx.de> | 2026-07-25 17:25:12 +0200 |
| commit | 5d71f800fc85c1aa6c8b0140bb5d62af39b1effe (patch) | |
| tree | e06d76913cd5902c7b11fdd5b8d0399738b3bf2c | |
| parent | 0738ecee1ab15aa75d2ea433e636d8cbf25623de (diff) | |
| download | linux-next-5d71f800fc85c1aa6c8b0140bb5d62af39b1effe.tar.gz linux-next-5d71f800fc85c1aa6c8b0140bb5d62af39b1effe.zip | |
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: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
Signed-off-by: Helge Deller <deller@gmx.de>
| -rw-r--r-- | drivers/video/fbdev/kyro/fbdev.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c index d756b3603fa6..c23738988822 100644 --- a/drivers/video/fbdev/kyro/fbdev.c +++ b/drivers/video/fbdev/kyro/fbdev.c @@ -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 */ |
