⬢ DragonFlyBSD Kernel Audit
DF-4155 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c
@@ -1415,9 +1415,13 @@ static ATOM_VOLTAGE_OBJECT_V3 *amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOL
 									u8 voltage_type, u8 voltage_mode)
 {
 	u32 size = le16_to_cpu(v3->sHeader.usStructureSize);
 	u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
 	u8 *start = (u8*)v3;
+	u32 obj_size;
 
 	while (offset < size) {
 		ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
 		if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) &&
 		    (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode))
 			return vo;
-		offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize);
+		/* DF-4155: a zero-size object would loop forever */
+		obj_size = le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize);
+		if (obj_size < sizeof(ATOM_VOLTAGE_OBJECT_V3))
+			break;
+		offset += obj_size;
 	}
 	return NULL;
 }