:: commit d54de36b0ba578ebfdd38be1fdf1a18eb8ef506d

Mintsuki <mintsuki@protonmail.com> — 2026-02-16 09:45

parents: 72c893401a

drivers/vbe: Skip modes with invalid pitch values

diff --git a/common/drivers/vbe.c b/common/drivers/vbe.c
index 97547f44..dc3bc39a 100644
--- a/common/drivers/vbe.c
+++ b/common/drivers/vbe.c
@@ -162,6 +162,15 @@ struct fb_info *vbe_get_mode_list(size_t *count) {
         if (!(vbe_mode_info.mode_attributes & (1 << 7)))
             continue;
 
+        uint16_t pitch = (vbe_info.version_maj < 3)
+                       ? vbe_mode_info.bytes_per_scanline
+                       : vbe_mode_info.lin_bytes_per_scanline;
+        uint16_t bytes_per_pixel = vbe_mode_info.bpp / 8;
+        if (bytes_per_pixel == 0
+         || pitch % bytes_per_pixel != 0
+         || pitch < (uint32_t)vbe_mode_info.res_x * bytes_per_pixel)
+            continue;
+
         modes_count++;
     }
 
@@ -180,6 +189,15 @@ struct fb_info *vbe_get_mode_list(size_t *count) {
         if (!(vbe_mode_info.mode_attributes & (1 << 7)))
             continue;
 
+        uint16_t pitch = (vbe_info.version_maj < 3)
+                       ? vbe_mode_info.bytes_per_scanline
+                       : vbe_mode_info.lin_bytes_per_scanline;
+        uint16_t bytes_per_pixel = vbe_mode_info.bpp / 8;
+        if (bytes_per_pixel == 0
+         || pitch % bytes_per_pixel != 0
+         || pitch < (uint32_t)vbe_mode_info.res_x * bytes_per_pixel)
+            continue;
+
         ret[j].memory_model = vbe_mode_info.memory_model;
 
         ret[j].framebuffer_width = vbe_mode_info.res_x;
@@ -317,6 +335,16 @@ retry:
                 ret->blue_mask_shift    = vbe_mode_info.lin_blue_mask_shift;
             }
 
+            uint16_t bytes_per_pixel = ret->framebuffer_bpp / 8;
+            if (bytes_per_pixel == 0
+             || ret->framebuffer_pitch % bytes_per_pixel != 0
+             || ret->framebuffer_pitch < (uint32_t)ret->framebuffer_width * bytes_per_pixel) {
+                printv("vbe: Mode %x has invalid pitch %u (width=%u, bpp=%u), skipping.\n",
+                       vid_modes[i], (uint32_t)ret->framebuffer_pitch,
+                       (uint32_t)ret->framebuffer_width, (uint32_t)ret->framebuffer_bpp);
+                continue;
+            }
+
             fb_clear(ret);
 
             return true;
tab: 248 wrap: offon