:: commit 1b5f95c2ac20a7b471068637fbaab819914934b3

Mintsuki <mintsuki@protonmail.com> — 2025-12-26 10:29

parents: 8a0f7684a7

drivers/vbe: Add iteration limit and EDID sanity checks

diff --git a/common/drivers/vbe.c b/common/drivers/vbe.c
index ffe66efc..97547f44 100644
--- a/common/drivers/vbe.c
+++ b/common/drivers/vbe.c
@@ -135,6 +135,10 @@ static bool set_vbe_mode(uint16_t mode) {
     return true;
 }
 
+// Maximum number of video modes to enumerate to prevent infinite loops
+// from corrupted VBE mode lists without a proper 0xffff terminator
+#define VBE_MAX_MODES 512
+
 struct fb_info *vbe_get_mode_list(size_t *count) {
     struct vbe_info_struct vbe_info;
     if (!get_vbe_info(&vbe_info)) {
@@ -145,7 +149,7 @@ struct fb_info *vbe_get_mode_list(size_t *count) {
                                                    vbe_info.vid_modes_off);
 
     size_t modes_count = 0;
-    for (size_t i = 0; vid_modes[i] != 0xffff; i++) {
+    for (size_t i = 0; i < VBE_MAX_MODES && vid_modes[i] != 0xffff; i++) {
         struct vbe_mode_info_struct vbe_mode_info;
         if (!get_vbe_mode_info(&vbe_mode_info, vid_modes[i])) {
             continue;
@@ -163,7 +167,7 @@ struct fb_info *vbe_get_mode_list(size_t *count) {
 
     struct fb_info *ret = ext_mem_alloc(modes_count * sizeof(struct fb_info));
 
-    for (size_t i = 0, j = 0; vid_modes[i] != 0xffff; i++) {
+    for (size_t i = 0, j = 0; i < VBE_MAX_MODES && vid_modes[i] != 0xffff; i++) {
         struct vbe_mode_info_struct vbe_mode_info;
         if (!get_vbe_mode_info(&vbe_mode_info, vid_modes[i])) {
             continue;
@@ -247,7 +251,9 @@ bool init_vbe(struct fb_info *ret,
                 edid_width  += ((int)edid_info->det_timing_desc1[4] & 0xf0) << 4;
             int edid_height  = (int)edid_info->det_timing_desc1[5];
                 edid_height += ((int)edid_info->det_timing_desc1[7] & 0xf0) << 4;
-            if (edid_width && edid_height) {
+            // Sanity check EDID values
+            if (edid_width > 0 && edid_width <= 16384 &&
+                edid_height > 0 && edid_height <= 16384) {
                 target_width  = edid_width;
                 target_height = edid_height;
                 target_bpp    = 32;
@@ -263,7 +269,7 @@ bool init_vbe(struct fb_info *ret,
     }
 
 retry:
-    for (size_t i = 0; vid_modes[i] != 0xffff; i++) {
+    for (size_t i = 0; i < VBE_MAX_MODES && vid_modes[i] != 0xffff; i++) {
         struct vbe_mode_info_struct vbe_mode_info;
         if (!get_vbe_mode_info(&vbe_mode_info, vid_modes[i])) {
             continue;
tab: 248 wrap: offon