Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efbd001f authored by Archana Obannagari's avatar Archana Obannagari Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarArchana Obannagari <aobann@codeaurora.org>
parent f2b019ee
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -61,8 +61,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);

@@ -659,6 +659,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);
@@ -1120,8 +1121,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;
@@ -1131,7 +1132,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) {
@@ -1227,6 +1229,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);