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

Commit 488567d2 authored by Xiaogang Cui's avatar Xiaogang Cui Committed by Gerrit - the friendly Code Review server
Browse files

soc: qcom: dcc: add check if sram data oversteps



If the size of captured data oversteps over SRAM boundary then
it causes corruption of configuration data. Add boundary check
while programming configuration linked list in SRAM, to avoid
this problem.

Change-Id: Idd33f53560585fdbfee4d3822fd93d6f3a365e17
Signed-off-by: default avatarXiaogang Cui <xiaogang@codeaurora.org>
parent 72ee5cb1
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata)
	uint32_t prev_addr, addr;
	uint32_t prev_off = 0, off;
	uint32_t link;
	uint32_t pos;
	uint32_t pos, total_len = 0;
	struct dcc_config_entry *entry;

	if (list_empty(&drvdata->config_head)) {
@@ -272,6 +272,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata)
		addr = (entry->base >> 4) & BM(0, 27);
		addr |= BIT(31);
		off = entry->offset/4;
		total_len += entry->len * 4;

		if (!prev_addr || prev_addr != addr || prev_off > off) {
			/* Check if we need to write link of prev entry */
@@ -289,7 +290,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata)
			prev_off = 0;
		}

		if ((off - prev_off) > 0xFF || entry->len > 0x7F) {
		if ((off - prev_off) > 0xFF || entry->len > MAX_DCC_LEN) {
			dev_err(drvdata->dev,
				"DCC: Progamming error! Base: 0x%x, offset 0x%x.\n",
				entry->base, entry->offset);
@@ -339,8 +340,25 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata)
	dcc_sram_writel(drvdata, 0, sram_offset);
	sram_offset += 4;

	drvdata->ram_cfg = (sram_offset  / 4);
	/* check if the data will overstep */
	if (drvdata->data_sink == DCC_DATA_SINK_SRAM
	    && drvdata->func_type == DCC_FUNC_TYPE_CAPTURE) {
		if (sram_offset + total_len > drvdata->ram_size) {
			sram_offset += total_len;
			goto overstep;
		}
	} else {
		if (sram_offset > drvdata->ram_size)
			goto overstep;
	}

	drvdata->ram_cfg = (sram_offset  / 4);
	return 0;
overstep:
	ret = -EINVAL;
	memset_io(drvdata->ram_base, 0, drvdata->ram_size);
	dev_err(drvdata->dev, "DCC SRAM oversteps, 0x%x (0x%x)\n",
		sram_offset, drvdata->ram_size);
err:
	return ret;
}