- There is a latent bug that the PF may size a giant CPER record
  length and corrupt the VF's kernel memory.

- We must check if the pointer goes more than the buffer boundary

Signed-off-by: Bokun Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 6974b1c5b56c..f77709586115 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -1797,6 +1797,7 @@ amdgpu_virt_write_cpers_to_ring(struct amdgpu_device 
*adev,
 {
        struct amd_sriov_ras_cper_dump *cper_dump = NULL;
        struct cper_hdr *entry = NULL;
+       uint32_t record_length = 0;
        struct amdgpu_ring *ring = &adev->cper.ring_buf;
        uint32_t checksum, used_size, i;
        int ret = 0;
@@ -1831,6 +1832,13 @@ amdgpu_virt_write_cpers_to_ring(struct amdgpu_device 
*adev,
        entry = (struct cper_hdr *)&cper_dump->buf[0];
 
        for (i = 0; i < cper_dump->count; i++) {
+               record_length = entry->record_length;
+               if (((char *)entry + record_length) > ((char *)cper_dump + 
used_size)) {
+                       dev_warn(adev->dev, "PF sends corrupted CEPR entry\n");
+                       ret = -EINVAL;
+                       goto out;
+               }
+
                amdgpu_cper_ring_write(ring, entry, entry->record_length);
                entry = (struct cper_hdr *)((char *)entry +
                                            entry->record_length);
-- 
2.51.0

Reply via email to