1
0
mirror of https://github.com/openbsd/src.git synced 2026-06-18 07:13:36 +02:00

drm/amdgpu/vcn3: Prevent OOB reads when parsing dec msg

From Benjamin Cheng
638e48ee39d0f2af9336f917a6f5d6692dd64d93 in linux-6.18.y/6.18.32
b193019860d61e92da395eae2011f2f6716b182f in mainline linux
This commit is contained in:
jsg
2026-05-18 01:37:36 +00:00
parent 3071a36f6d
commit 24cbbbb2f6
+19 -4
View File
@@ -1908,7 +1908,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_bo_va_mapping *map;
uint32_t *msg, num_buffers;
uint32_t *msg, num_buffers, len_dw;
struct amdgpu_bo *bo;
uint64_t start, end;
unsigned int i;
@@ -1929,6 +1929,11 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
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;
amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
@@ -1945,8 +1950,8 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
msg = ptr + addr - start;
/* Check length */
if (msg[1] > end - addr) {
DRM_ERROR("VCN message header does not fit in BO!\n");
r = -EINVAL;
goto out;
}
@@ -1954,7 +1959,16 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
if (msg[3] != RDECODE_MSG_CREATE)
goto out;
len_dw = msg[1] / 4;
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) {
uint32_t offset, size, *create;
@@ -1964,14 +1978,15 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
offset = msg[1];
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;
goto out;
}
create = ptr + addr + offset - start;
/* H246, HEVC and VP9 can run on any instance */
/* H264, HEVC and VP9 can run on any instance */
if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
continue;