Check bounds against the end of the BO whenever we access the msg.
Signed-off-by: Benjamin Cheng <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
index 02d5c5af65f2..500a337e8987 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
@@ -1909,7 +1909,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_device *adev = p->adev;
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;
@@ -1946,6 +1946,12 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p,
struct amdgpu_job *job,
msg = ptr + addr - start;
+ /* Make sure there's at least 4 DWORDs accessible */
+ if (end - addr < 16) {
+ r = -EINVAL;
+ goto out;
+ }
+
/* Check length */
if (msg[1] > end - addr) {
r = -EINVAL;
@@ -1955,7 +1961,15 @@ 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) {
+ r = -EINVAL;
+ goto out;
+ }
+
for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
uint32_t offset, size, *create;
@@ -1965,14 +1979,14 @@ 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) {
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;
--
2.53.0