if supplied msg[2] in the header is too large around
0x40000000, 4 times of this unsigned 32 bit value will
overflow and the test could pass.

v2: using kernel helpers to check the overflow.
    this needs 2 checks: multiplication and addition

Signed-off-by: David (Ming Qiang) Wu <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 6 ++++--
 drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c 
b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
index 81bba3ec2a93..7a301cfe91ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
@@ -1910,7 +1910,7 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, 
struct amdgpu_job *job,
        struct ttm_operation_ctx ctx = { false, false };
        struct amdgpu_device *adev = p->adev;
        struct amdgpu_bo_va_mapping *map;
-       uint32_t *msg, num_buffers, len_dw;
+       uint32_t *msg, num_buffers, len_dw, mul, total;
        struct amdgpu_bo *bo;
        uint64_t start, end;
        unsigned int i;
@@ -1965,7 +1965,9 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, 
struct amdgpu_job *job,
        num_buffers = msg[2];
 
        /* Verify that all indices fit within the claimed length. Each index is 
4 DWORDs */
-       if (num_buffers > len_dw || 6 + num_buffers * 4 > len_dw) {
+       if (check_mul_overflow(num_buffers, 4u, &mul) ||
+           check_add_overflow(6u, mul, &total) ||
+           total > len_dw) {
                DRM_ERROR("VCN message has too many buffers!\n");
                r = -EINVAL;
                goto out;
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c 
b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
index 0cce78b205a8..413854fcf84a 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
@@ -1826,7 +1826,7 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, 
struct amdgpu_job *job,
        struct ttm_operation_ctx ctx = { false, false };
        struct amdgpu_device *adev = p->adev;
        struct amdgpu_bo_va_mapping *map;
-       uint32_t *msg, num_buffers, len_dw;
+       uint32_t *msg, num_buffers, len_dw, mul, total;
        struct amdgpu_bo *bo;
        uint64_t start, end;
        unsigned int i;
@@ -1881,7 +1881,9 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, 
struct amdgpu_job *job,
        num_buffers = msg[2];
 
        /* Verify that all indices fit within the claimed length. Each index is 
4 DWORDs */
-       if (num_buffers > len_dw || 6 + num_buffers * 4 > len_dw) {
+       if (check_mul_overflow(num_buffers, 4u, &mul) ||
+           check_add_overflow(6u, mul, &total) ||
+           total > len_dw) {
                DRM_ERROR("VCN message has too many buffers!\n");
                r = -EINVAL;
                goto out;
-- 
2.43.0

Reply via email to