]> xenbits.xensource.com Git - osstest/seabios.git/commitdiff
vbe: Add VBE 2.0+ OemData field to struct vbe_info
authorDaniel Verkamp <daniel@drv.nu>
Thu, 7 Mar 2024 09:08:27 +0000 (01:08 -0800)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 10 Mar 2024 17:00:27 +0000 (13:00 -0400)
Per the VBE 2.0 specification, the VBE controller information is 512
bytes long when the "VBE2" signature is provided, instead of the
original 256 bytes.

src/bootsplash.c uses the original pre-VBE-2.0 256-byte structure while
also filling in the "VBE2" signature, so a video BIOS that makes use of
the VBE2 OemData area could write past the end of the allocated region.

The original bootsplash code did not have this bug; it was introduced
when the bootsplash VBE structures were merged with the VGA ROM struct
definitions.

Fixes: 69e941c159ed ("Merge bootsplash and VGA ROM vbe structure definitions")
Signed-off-by: Daniel Verkamp <daniel@drv.nu>
src/std/vbe.h
vgasrc/vbe.c

index 94b4ad86fff97545cf73710c9ccc10b4a44fc7e0..fe96f5ecf9a8ab64b211a8eb7219867b87f13ddb 100644 (file)
@@ -18,6 +18,8 @@ struct vbe_info {
     struct segoff_s oem_product_string;
     struct segoff_s oem_revision_string;
     u8 reserved[222];
+    /* VBE 2.0 */
+    u8 oem_data[256];
 } PACKED;
 
 struct vbe_mode_info {
index 66afb011ada034d53b518f8de068567f6c96ffd9..91abc9abc6328811b1fa08874246b06357f869c7 100644 (file)
@@ -32,16 +32,18 @@ vbe_104f00(struct bregs *regs)
 {
     u16 seg = regs->es;
     struct vbe_info *info = (void*)(regs->di+0);
+    size_t info_size = offsetof(struct vbe_info, oem_data);
 
     if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) {
         dprintf(4, "Get VBE Controller: VBE2 Signature found\n");
+        info_size = sizeof(*info);
     } else if (GET_FARVAR(seg, info->signature) == VESA_SIGNATURE) {
         dprintf(4, "Get VBE Controller: VESA Signature found\n");
     } else {
         dprintf(4, "Get VBE Controller: Invalid Signature\n");
     }
 
-    memset_far(seg, info, 0, sizeof(*info));
+    memset_far(seg, info, 0, info_size);
 
     SET_FARVAR(seg, info->signature, VESA_SIGNATURE);