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/vcn3: 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

authored by

Benjamin Cheng and committed by
Alex Deucher
b1930198 de2a02cc

+19 -4
+19 -4
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
··· 1909 1909 struct ttm_operation_ctx ctx = { false, false }; 1910 1910 struct amdgpu_device *adev = p->adev; 1911 1911 struct amdgpu_bo_va_mapping *map; 1912 - uint32_t *msg, num_buffers; 1912 + uint32_t *msg, num_buffers, len_dw; 1913 1913 struct amdgpu_bo *bo; 1914 1914 uint64_t start, end; 1915 1915 unsigned int i; ··· 1930 1930 return -EINVAL; 1931 1931 } 1932 1932 1933 + if (end - addr < 16) { 1934 + DRM_ERROR("VCN messages must be at least 4 DWORDs!\n"); 1935 + return -EINVAL; 1936 + } 1937 + 1933 1938 bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; 1934 1939 amdgpu_bo_placement_from_domain(bo, bo->allowed_domains); 1935 1940 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); ··· 1951 1946 1952 1947 msg = ptr + addr - start; 1953 1948 1954 - /* Check length */ 1955 1949 if (msg[1] > end - addr) { 1950 + DRM_ERROR("VCN message header does not fit in BO!\n"); 1956 1951 r = -EINVAL; 1957 1952 goto out; 1958 1953 } ··· 1960 1955 if (msg[3] != RDECODE_MSG_CREATE) 1961 1956 goto out; 1962 1957 1958 + len_dw = msg[1] / 4; 1963 1959 num_buffers = msg[2]; 1960 + 1961 + /* Verify that all indices fit within the claimed length. Each index is 4 DWORDs */ 1962 + if (num_buffers > len_dw || 6 + num_buffers * 4 > len_dw) { 1963 + DRM_ERROR("VCN message has too many buffers!\n"); 1964 + r = -EINVAL; 1965 + goto out; 1966 + } 1967 + 1964 1968 for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) { 1965 1969 uint32_t offset, size, *create; 1966 1970 ··· 1979 1965 offset = msg[1]; 1980 1966 size = msg[2]; 1981 1967 1982 - if (offset + size > end) { 1968 + if (size < 4 || offset + size > end - addr) { 1969 + DRM_ERROR("VCN message buffer exceeds BO bounds!\n"); 1983 1970 r = -EINVAL; 1984 1971 goto out; 1985 1972 } 1986 1973 1987 1974 create = ptr + addr + offset - start; 1988 1975 1989 - /* H246, HEVC and VP9 can run on any instance */ 1976 + /* H264, HEVC and VP9 can run on any instance */ 1990 1977 if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11) 1991 1978 continue; 1992 1979