diff --git a/sys/dev/drm/amd/amdgpu/psp_v11_0.c b/sys/dev/drm/amd/amdgpu/psp_v11_0.c --- a/sys/dev/drm/amd/amdgpu/psp_v11_0.c +++ b/sys/dev/drm/amd/amdgpu/psp_v11_0.c @@ -120,6 +120,17 @@ goto out; hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data; + + /* Reject obviously bogus firmware headers; amdgpu_ucode_validate only + * checks total size, not the inner offsets we use below. */ + if (le32_to_cpu(hdr->sos_size_bytes) > + le32_to_cpu(hdr->header.ucode_size_bytes) || + le32_to_cpu(hdr->header.ucode_array_offset_bytes) + + le32_to_cpu(hdr->sos_offset_bytes) + + le32_to_cpu(hdr->sos_size_bytes) > adev->psp.sos_fw->datasize) { + err = -EINVAL; + goto out; + } adev->psp.sos_fw_version = le32_to_cpu(hdr->header.ucode_version); adev->psp.sos_feature_version = le32_to_cpu(hdr->ucode_feature_version); adev->psp.sos_bin_size = le32_to_cpu(hdr->sos_size_bytes);