Skip to content

Commit 870c873

Browse files
lolzballsgregkh
authored andcommitted
drm/amdgpu/vcn3: Prevent OOB reads when parsing dec msg
commit b193019 upstream. 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 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 7688143 commit 870c873

1 file changed

Lines changed: 19 additions & 4 deletions

File tree

drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,7 +1843,7 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
18431843
{
18441844
struct ttm_operation_ctx ctx = { false, false };
18451845
struct amdgpu_bo_va_mapping *map;
1846-
uint32_t *msg, num_buffers;
1846+
uint32_t *msg, num_buffers, len_dw;
18471847
struct amdgpu_bo *bo;
18481848
uint64_t start, end;
18491849
unsigned int i;
@@ -1864,6 +1864,11 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
18641864
return -EINVAL;
18651865
}
18661866

1867+
if (end - addr < 16) {
1868+
DRM_ERROR("VCN messages must be at least 4 DWORDs!\n");
1869+
return -EINVAL;
1870+
}
1871+
18671872
bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
18681873
amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
18691874
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
@@ -1880,16 +1885,25 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
18801885

18811886
msg = ptr + addr - start;
18821887

1883-
/* Check length */
18841888
if (msg[1] > end - addr) {
1889+
DRM_ERROR("VCN message header does not fit in BO!\n");
18851890
r = -EINVAL;
18861891
goto out;
18871892
}
18881893

18891894
if (msg[3] != RDECODE_MSG_CREATE)
18901895
goto out;
18911896

1897+
len_dw = msg[1] / 4;
18921898
num_buffers = msg[2];
1899+
1900+
/* Verify that all indices fit within the claimed length. Each index is 4 DWORDs */
1901+
if (num_buffers > len_dw || 6 + num_buffers * 4 > len_dw) {
1902+
DRM_ERROR("VCN message has too many buffers!\n");
1903+
r = -EINVAL;
1904+
goto out;
1905+
}
1906+
18931907
for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
18941908
uint32_t offset, size, *create;
18951909

@@ -1899,14 +1913,15 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
18991913
offset = msg[1];
19001914
size = msg[2];
19011915

1902-
if (offset + size > end) {
1916+
if (size < 4 || offset + size > end - addr) {
1917+
DRM_ERROR("VCN message buffer exceeds BO bounds!\n");
19031918
r = -EINVAL;
19041919
goto out;
19051920
}
19061921

19071922
create = ptr + addr + offset - start;
19081923

1909-
/* H246, HEVC and VP9 can run on any instance */
1924+
/* H264, HEVC and VP9 can run on any instance */
19101925
if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
19111926
continue;
19121927

0 commit comments

Comments
 (0)