diff options
| author | Archana Obannagari <aobann@codeaurora.org> | 2017-09-18 12:49:24 +0530 |
|---|---|---|
| committer | Archana Obannagari <aobann@codeaurora.org> | 2017-09-22 19:01:12 +0530 |
| commit | 4533fa32529c38ee15b5072c324e28aca8c35afb (patch) | |
| tree | f90b2ce4f1b1a6838ff803b554b8171c8233d1d8 /drivers/gpu/msm | |
| parent | 393bfcf23206ec8302876474526b6e595cbaacce (diff) | |
msm: kgsl: Fix size check issue in _read_fw2_block_header()
During firmware data read, it may leads to cross the max
range. Add a check to validate data size with in the max
range.
Change-Id: I12b3c1761214a7d2af2c45ad73bf61954c8398b6
Signed-off-by: Archana Obannagari <aobann@codeaurora.org>
Diffstat (limited to 'drivers/gpu/msm')
| -rw-r--r-- | drivers/gpu/msm/adreno_a5xx.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 3fb13c7a0814..c5d6affeee4d 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -65,8 +65,8 @@ static const struct adreno_vbif_platform a5xx_vbif_platforms[] = { }; static void a5xx_irq_storm_worker(struct work_struct *work); -static int _read_fw2_block_header(uint32_t *header, uint32_t id, - uint32_t major, uint32_t minor); +static int _read_fw2_block_header(uint32_t *header, uint32_t remain, + uint32_t id, uint32_t major, uint32_t minor); static void a5xx_gpmu_reset(struct work_struct *work); static int a5xx_gpmu_init(struct adreno_device *adreno_dev); @@ -709,6 +709,7 @@ static int _load_gpmu_firmware(struct adreno_device *adreno_dev) if (data[1] != GPMU_FIRMWARE_ID) goto err; ret = _read_fw2_block_header(&data[2], + data[0] - 2, GPMU_FIRMWARE_ID, adreno_dev->gpucore->gpmu_major, adreno_dev->gpucore->gpmu_minor); @@ -1231,8 +1232,8 @@ void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on) kgsl_regwrite(device, A5XX_RBBM_ISDB_CNT, on ? 0x00000182 : 0x00000180); } -static int _read_fw2_block_header(uint32_t *header, uint32_t id, - uint32_t major, uint32_t minor) +static int _read_fw2_block_header(uint32_t *header, uint32_t remain, + uint32_t id, uint32_t major, uint32_t minor) { uint32_t header_size; int i = 1; @@ -1242,7 +1243,8 @@ static int _read_fw2_block_header(uint32_t *header, uint32_t id, header_size = header[0]; /* Headers have limited size and always occur as pairs of words */ - if (header_size > MAX_HEADER_SIZE || header_size % 2) + if (header_size > MAX_HEADER_SIZE || header_size >= remain || + header_size % 2 || header_size == 0) return -EINVAL; /* Sequences must have an identifying id first thing in their header */ if (id == GPMU_SEQUENCE_ID) { @@ -1337,6 +1339,7 @@ static void _load_regfile(struct adreno_device *adreno_dev) /* For now ignore blocks other than the LM sequence */ if (block[4] == LM_SEQUENCE_ID) { ret = _read_fw2_block_header(&block[2], + block_size - 2, GPMU_SEQUENCE_ID, adreno_dev->gpucore->lm_major, adreno_dev->gpucore->lm_minor); |
