Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu/vcn4: Prevent OOB reads when parsing IB

Rewrite the IB parsing to use amdgpu_ib_get_value() which handles the
bounds checks.

Signed-off-by: Benjamin Cheng <benjamin.cheng@amd.com>
Acked-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

authored by

Benjamin Cheng and committed by
Alex Deucher
2444eb0e 0a78f2ba

+12 -11
+12 -11
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
··· 1928 1928 static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int start) 1929 1929 { 1930 1930 int i; 1931 + uint32_t len; 1931 1932 1932 - for (i = start; i < ib->length_dw && ib->ptr[i] >= 8; i += ib->ptr[i] / 4) { 1933 - if (ib->ptr[i + 1] == id) 1933 + for (i = start; (len = amdgpu_ib_get_value(ib, i)) >= 8; i += len / 4) { 1934 + if (amdgpu_ib_get_value(ib, i + 1) == id) 1934 1935 return i; 1935 1936 } 1936 1937 return -1; ··· 1942 1941 struct amdgpu_ib *ib) 1943 1942 { 1944 1943 struct amdgpu_ring *ring = amdgpu_job_ring(job); 1945 - struct amdgpu_vcn_decode_buffer *decode_buffer; 1946 - uint64_t addr; 1947 1944 uint32_t val; 1948 1945 int idx = 0, sidx; 1949 1946 ··· 1952 1953 while ((idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO, idx)) >= 0) { 1953 1954 val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */ 1954 1955 if (val == RADEON_VCN_ENGINE_TYPE_DECODE) { 1955 - decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6]; 1956 + uint32_t valid_buf_flag = amdgpu_ib_get_value(ib, idx + 6); 1957 + uint64_t msg_buffer_addr; 1956 1958 1957 - if (!(decode_buffer->valid_buf_flag & 0x1)) 1959 + if (!(valid_buf_flag & 0x1)) 1958 1960 return 0; 1959 1961 1960 - addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 | 1961 - decode_buffer->msg_buffer_address_lo; 1962 - return vcn_v4_0_dec_msg(p, job, addr); 1962 + msg_buffer_addr = ((u64)amdgpu_ib_get_value(ib, idx + 7)) << 32 | 1963 + amdgpu_ib_get_value(ib, idx + 8); 1964 + return vcn_v4_0_dec_msg(p, job, msg_buffer_addr); 1963 1965 } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) { 1964 1966 sidx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT, idx); 1965 - if (sidx >= 0 && ib->ptr[sidx + 2] == RENCODE_ENCODE_STANDARD_AV1) 1967 + if (sidx >= 0 && 1968 + amdgpu_ib_get_value(ib, sidx + 2) == RENCODE_ENCODE_STANDARD_AV1) 1966 1969 return vcn_v4_0_limit_sched(p, job); 1967 1970 } 1968 - idx += ib->ptr[idx] / 4; 1971 + idx += amdgpu_ib_get_value(ib, idx) / 4; 1969 1972 } 1970 1973 return 0; 1971 1974 }