summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorArchana Sriram <apsrir@codeaurora.org>2017-09-18 17:33:31 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-09-26 23:12:04 -0700
commit8662023651ff4db5bad5857133117ef183000684 (patch)
tree8fa83f0c74a0e1b7b94f811685881176027a3af0 /drivers/gpu
parentb56464c7cb37be7ddd498ccff8cc11124cea39e6 (diff)
msm: kgsl: Fix calculation of size in _load_regfile
During firmware load, there could be data over reads due to calculation of lm_size and lm_sequence from block and block_size. Added bounds checking to prevent this and improved the size calculation. CRs-Fixed: 2107981 Change-Id: Ib4283951b0d6c8fb699af1f85e657981ad4c0318 Signed-off-by: Archana Sriram <apsrir@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 3fb13c7a0814..4683a263d75e 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -1306,8 +1306,8 @@ static void _load_regfile(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
const struct firmware *fw;
- uint32_t block_size = 0, block_total = 0, fw_size;
- uint32_t *block;
+ uint64_t block_size = 0, block_total = 0;
+ uint32_t fw_size, *block;
int ret = -EINVAL;
if (!adreno_dev->gpucore->regfw_name)
@@ -1329,7 +1329,8 @@ static void _load_regfile(struct adreno_device *adreno_dev)
/* All offset numbers calculated from file description */
while (block_total < fw_size) {
block_size = block[0];
- if (block_size >= fw_size || block_size < 2)
+ if (((block_total + block_size) >= fw_size)
+ || block_size < 5)
goto err;
if (block[1] != GPMU_SEQUENCE_ID)
goto err;
@@ -1344,6 +1345,9 @@ static void _load_regfile(struct adreno_device *adreno_dev)
goto err;
adreno_dev->lm_fw = fw;
+
+ if (block[2] > (block_size - 2))
+ goto err;
adreno_dev->lm_sequence = block + block[2] + 3;
adreno_dev->lm_size = block_size - block[2] - 2;
}
@@ -1356,7 +1360,7 @@ static void _load_regfile(struct adreno_device *adreno_dev)
err:
release_firmware(fw);
KGSL_PWR_ERR(device,
- "Register file failed to load sz=%d bsz=%d header=%d\n",
+ "Register file failed to load sz=%d bsz=%llu header=%d\n",
fw_size, block_size, ret);
return;
}