From 637dd819351e80bcac9b2ebff65ad3de499c3b8e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 4 Jan 2024 16:57:45 -0800 Subject: [PATCH] drivers: pva: check cb_size against memory size verify that circular buffer size is within the allocated buffer when checking address range for bot source and destination. Bug 4432254 Change-Id: I265f2c4b9f46cf24db8bd86cf5abf3f9b2e67994 Signed-off-by: omar Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3046464 GVS: Gerrit_Virtual_Submit --- drivers/video/tegra/host/pva/pva_dma.c | 32 +++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/video/tegra/host/pva/pva_dma.c b/drivers/video/tegra/host/pva/pva_dma.c index bfec9cd2..10b51052 100644 --- a/drivers/video/tegra/host/pva/pva_dma.c +++ b/drivers/video/tegra/host/pva/pva_dma.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -// SPDX-FileCopyrightText: Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. #include #include @@ -195,16 +195,20 @@ static int32_t check_address_range(struct nvpva_dma_descriptor const *desc, /* 2nd destination dim */ s[1] = (int64_t)desc->dstLinePitch * last_ty; if (desc->dstCbEnable == 1U) { + int64_t excursion = (s[1] + last_tx + 1) * bppSize; + /* ((DLP_ADV * (Ty-1)) + Tx) * BPP <= DB_SIZE */ - if (((s[1] + last_tx + 1) * bppSize) <= - (int64_t)desc->dstCbSize) - return 0; + if (((uint64_t)desc->dstCbSize > max_size) + || (dst2 && ((uint64_t)desc->dstCbSize > max_size2)) + || (excursion > (int64_t)desc->dstCbSize) + || (desc->dstFormat == 1)) { + pr_err("invalid dst cb"); + return -EINVAL; + } - pr_err("invalid dst cb advance"); - return -EINVAL; + return 0; } - err = pitch_linear_eq_offset(desc, &offset, desc->surfBLOffset, block_height_log2, desc->bytePerPixel, true, false); if (err) @@ -225,12 +229,18 @@ static int32_t check_address_range(struct nvpva_dma_descriptor const *desc, /* 2nd source dim */ s[1] = (int64_t)desc->srcLinePitch * last_ty; if (desc->srcCbEnable == 1U) { + int64_t excursion = (s[1] + last_tx + 1) * bppSize; + /* ((SLP_ADV * (Ty-1)) + Tx) * BPP <= SB_SIZE */ - if (((s[1] + last_tx + 1) * bppSize) <= - (int64_t)desc->srcCbSize) - return 0; - pr_err("invalid src cb"); + if (((uint64_t)desc->srcCbSize > max_size) + || (dst2 && ((uint64_t)desc->srcCbSize > max_size2)) + || (excursion > (int64_t)desc->srcCbSize) + || (desc->srcFormat == 1)) { + pr_err("invalid src cb"); return -EINVAL; + } + + return 0; } err = pitch_linear_eq_offset(desc, &offset, desc->surfBLOffset,