mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
drm/amdgpu/vcn4: Prevent OOB reads when parsing dec msg
Check bounds against the end of the BO whenever we access the msg. Signed-off-by: Benjamin Cheng <benjamin.cheng@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Reviewed-by: Ruijing Dong <ruijing.dong@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
b193019860
commit
0a78f2bac1
|
|
@ -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 ttm_operation_ctx ctx = { false, false };
|
||||||
struct amdgpu_device *adev = p->adev;
|
struct amdgpu_device *adev = p->adev;
|
||||||
struct amdgpu_bo_va_mapping *map;
|
struct amdgpu_bo_va_mapping *map;
|
||||||
uint32_t *msg, num_buffers;
|
uint32_t *msg, num_buffers, len_dw;
|
||||||
struct amdgpu_bo *bo;
|
struct amdgpu_bo *bo;
|
||||||
uint64_t start, end;
|
uint64_t start, end;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
@ -1847,6 +1847,11 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (end - addr < 16) {
|
||||||
|
DRM_ERROR("VCN messages must be at least 4 DWORDs!\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
||||||
amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
|
amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
|
||||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||||
|
|
@ -1863,8 +1868,8 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
|
||||||
|
|
||||||
msg = ptr + addr - start;
|
msg = ptr + addr - start;
|
||||||
|
|
||||||
/* Check length */
|
|
||||||
if (msg[1] > end - addr) {
|
if (msg[1] > end - addr) {
|
||||||
|
DRM_ERROR("VCN message header does not fit in BO!\n");
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
@ -1872,7 +1877,16 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
|
||||||
if (msg[3] != RDECODE_MSG_CREATE)
|
if (msg[3] != RDECODE_MSG_CREATE)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
len_dw = msg[1] / 4;
|
||||||
num_buffers = msg[2];
|
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) {
|
||||||
|
DRM_ERROR("VCN message has too many buffers!\n");
|
||||||
|
r = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
|
for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
|
||||||
uint32_t offset, size, *create;
|
uint32_t offset, size, *create;
|
||||||
|
|
||||||
|
|
@ -1882,7 +1896,8 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
|
||||||
offset = msg[1];
|
offset = msg[1];
|
||||||
size = msg[2];
|
size = msg[2];
|
||||||
|
|
||||||
if (offset + size > end) {
|
if (size < 4 || offset + size > end - addr) {
|
||||||
|
DRM_ERROR("VCN message buffer exceeds BO bounds!\n");
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user