DragonFlyBSD Kernel Audit
DF-1299 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/amd/display/dc/bios/bios_parser.c b/sys/dev/drm/amd/display/dc/bios/bios_parser.c
--- a/sys/dev/drm/amd/display/dc/bios/bios_parser.c
+++ b/sys/dev/drm/amd/display/dc/bios/bios_parser.c
@@ -1991,6 +1991,19 @@
 	if (!tbl)
 		return NULL;
 
+	/* DF-1299: GET_IMAGE only validated sizeof(ATOM_OBJECT_TABLE) (4-byte
+	 * header + the single flex[1] element). The loop below walks
+	 * ucNumberOfObjects entries (VBIOS-controlled u8, up to 255); re-validate
+	 * the FULL extent the loop will touch, otherwise a crafted VBIOS with a
+	 * large ucNumberOfObjects and a near-tail table offset walks off the
+	 * kmalloc'd bios buffer -> kernel heap OOB read. Same pattern affects
+	 * get_device_tag:354 / get_ss_info_v3_1:675 / get_gpio_pin_info:1812. */
+	if (tbl->ucNumberOfObjects == 0 ||
+	    !bios_get_image(&bp->base, offset,
+			sizeof(ATOM_OBJECT_TABLE) +
+			(uint32_t)(tbl->ucNumberOfObjects - 1) * sizeof(ATOM_OBJECT)))
+		return NULL;
+
 	for (i = 0; i < tbl->ucNumberOfObjects; i++)
 		if (dal_graphics_object_id_is_equal(id,
 				object_id_from_bios_object_id(