DF-2015 / fix.diff
diff --git a/sys/dev/drm/radeon/vce_v1_0.c b/sys/dev/drm/radeon/vce_v1_0.c --- a/sys/dev/drm/radeon/vce_v1_0.c +++ b/sys/dev/drm/radeon/vce_v1_0.c @@ -158,9 +158,18 @@ int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data) { const struct vce_v1_0_fw_signature *sign = (const void*)rdev->vce_fw->data; - uint32_t chip_id; + uint32_t chip_id, fw_num, fw_len, fw_datasize; int i; + fw_datasize = rdev->vce_fw->datasize; + if (fw_datasize < sizeof(*sign)) + return -EINVAL; + fw_num = le32_to_cpu(sign->num); + fw_len = le32_to_cpu(sign->len); + if (fw_num > 64 || fw_len > fw_datasize || + sizeof(*sign) + fw_num * sizeof(sign->val[0]) > fw_datasize) + return -EINVAL; + switch (rdev->family) { case CHIP_TAHITI: chip_id = 0x01000014; @@ -195,7 +204,7 @@ data[4] = cpu_to_le32(le32_to_cpu(sign->len) + 64); memset(&data[5], 0, 44); - memcpy(&data[16], &sign[1], rdev->vce_fw->datasize - sizeof(*sign)); + memcpy(&data[16], &sign[1], min(fw_datasize - sizeof(*sign), (uint32_t)VCE_V1_0_DATA_SIZE)); data += (le32_to_cpu(sign->len) + 64) / 4; data[0] = sign->val[i].sigval[0]; |