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

Commit 47f251b2 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: remove out of bound access for qos lut parsing"

parents 1a6933c3 cfb838fd
Loading
Loading
Loading
Loading
+67 −25
Original line number Diff line number Diff line
@@ -27,11 +27,11 @@

/**
 * Max hardware block in certain hardware. For ex: sspp pipes
 * can have QSEED, pcc, igc, pa, csc, etc. This count is max
 * 12 based on software design. It should be increased if any of the
 * can have QSEED, pcc, igc, pa, csc, qos entries, etc. This count is
 * 64 based on software design. It should be increased if any of the
 * hardware block has more subblocks.
 */
#define MAX_SDE_HW_BLK  12
#define MAX_SDE_HW_BLK  64

/* each entry will have register address and bit offset in that register */
#define MAX_BIT_OFFSET 2
@@ -444,8 +444,16 @@ static uint32_t _sde_copy_formats(
static int _parse_dt_u32_handler(struct device_node *np,
	char *prop_name, u32 *offsets, int len, bool mandatory)
{
	int rc = of_property_read_u32_array(np, prop_name, offsets, len);
	int rc = -EINVAL;

	if (len > MAX_SDE_HW_BLK) {
		SDE_ERROR(
			"prop: %s tries out of bound access for u32 array read len: %d\n",
				prop_name, len);
		return -E2BIG;
	}

	rc = of_property_read_u32_array(np, prop_name, offsets, len);
	if (rc && mandatory)
		SDE_ERROR("mandatory prop: %s u32 array read len:%d\n",
				prop_name, len);
@@ -467,6 +475,14 @@ static int _parse_dt_bit_offset(struct device_node *np,
	if (arr) {
		len /= sizeof(u32);
		len &= ~0x1;

		if (len > (MAX_SDE_HW_BLK * MAX_BIT_OFFSET)) {
			SDE_ERROR(
				"prop: %s len: %d will lead to out of bound access\n",
				prop_name, len / MAX_BIT_OFFSET);
			return -E2BIG;
		}

		for (i = 0, j = 0; i < len; j++) {
			PROP_BITVALUE_ACCESS(prop_value, prop_index, j, 0) =
				be32_to_cpu(arr[i]);
@@ -501,8 +517,8 @@ static int _validate_dt_entry(struct device_node *np,
				sde_prop[0].prop_name);
		if ((*off_count > MAX_BLOCKS) || (*off_count < 0)) {
			if (sde_prop[0].is_mandatory) {
				SDE_ERROR("invalid hw offset prop name:%s\"\
					  count: %d\n",
				SDE_ERROR(
					"invalid hw offset prop name:%s count: %d\n",
					sde_prop[0].prop_name, *off_count);
				rc = -EINVAL;
			}
@@ -545,8 +561,9 @@ static int _validate_dt_entry(struct device_node *np,
							sde_prop[i].type);
			break;
		}
		SDE_DEBUG("prop id:%d prop name:%s prop type:%d \"\
			prop_count:%d\n", i, sde_prop[i].prop_name,
		SDE_DEBUG(
			"prop id:%d prop name:%s prop type:%d prop_count:%d\n",
			i, sde_prop[i].prop_name,
			sde_prop[i].type, prop_count[i]);

		if (rc && sde_prop[i].is_mandatory &&
@@ -564,14 +581,16 @@ static int _validate_dt_entry(struct device_node *np,

		if (off_count && (prop_count[i] != *off_count) &&
				sde_prop[i].is_mandatory) {
			SDE_ERROR("prop:%s count:%d is different compared to \"\
				offset array:%d\n", sde_prop[i].prop_name,
			SDE_ERROR(
				"prop:%s count:%d is different compared to offset array:%d\n",
				sde_prop[i].prop_name,
				prop_count[i], *off_count);
			rc = -EINVAL;
			goto end;
		} else if (off_count && prop_count[i] != *off_count) {
			SDE_DEBUG("prop:%s count:%d is different compared to \"\
				offset array:%d\n", sde_prop[i].prop_name,
			SDE_DEBUG(
				"prop:%s count:%d is different compared to offset array:%d\n",
				sde_prop[i].prop_name,
				prop_count[i], *off_count);
			rc = 0;
			prop_count[i] = 0;
@@ -607,8 +626,9 @@ static int _read_dt_entry(struct device_node *np,
		case PROP_TYPE_U32:
			rc = of_property_read_u32(np, sde_prop[i].prop_name,
				&PROP_VALUE_ACCESS(prop_value, i, 0));
			SDE_DEBUG("prop id:%d prop name:%s prop type:%d \"\
				 value:0x%x\n", i, sde_prop[i].prop_name,
			SDE_DEBUG(
				"prop id:%d prop name:%s prop type:%d value:0x%x\n",
				i, sde_prop[i].prop_name,
				sde_prop[i].type,
				PROP_VALUE_ACCESS(prop_value, i, 0));
			if (rc)
@@ -618,8 +638,9 @@ static int _read_dt_entry(struct device_node *np,
			PROP_VALUE_ACCESS(prop_value, i, 0) =
				of_property_read_bool(np,
					sde_prop[i].prop_name);
			SDE_DEBUG("prop id:%d prop name:%s prop type:%d \"\
				value:0x%x\n", i, sde_prop[i].prop_name,
			SDE_DEBUG(
				"prop id:%d prop name:%s prop type:%d value:0x%x\n",
				i, sde_prop[i].prop_name,
				sde_prop[i].type,
				PROP_VALUE_ACCESS(prop_value, i, 0));
			break;
@@ -628,8 +649,9 @@ static int _read_dt_entry(struct device_node *np,
				&PROP_VALUE_ACCESS(prop_value, i, 0),
				prop_count[i], sde_prop[i].is_mandatory);
			if (rc && sde_prop[i].is_mandatory) {
				SDE_ERROR("%s prop validation success but \"\
					read failed\n", sde_prop[i].prop_name);
				SDE_ERROR(
					"%s prop validation success but read failed\n",
					sde_prop[i].prop_name);
				prop_exists[i] = false;
				goto end;
			} else {
@@ -651,19 +673,21 @@ static int _read_dt_entry(struct device_node *np,
				prop_value, i, prop_count[i],
				sde_prop[i].is_mandatory);
			if (rc && sde_prop[i].is_mandatory) {
				SDE_ERROR("%s prop validation success but \"\
					read failed\n", sde_prop[i].prop_name);
				SDE_ERROR(
					"%s prop validation success but read failed\n",
					sde_prop[i].prop_name);
				prop_exists[i] = false;
				goto end;
			} else {
				if (rc)
					prop_exists[i] = false;
				SDE_DEBUG("prop id:%d prop name:%s prop \"\
					type:%d", i, sde_prop[i].prop_name,
				SDE_DEBUG(
					"prop id:%d prop name:%s prop type:%d",
					i, sde_prop[i].prop_name,
					sde_prop[i].type);
				for (j = 0; j < prop_count[i]; j++)
					SDE_DEBUG(" count[%d]: bit:0x%x \"\
					off:0x%x \n", j,
					SDE_DEBUG(
					"count[%d]: bit:0x%x off:0x%x\n", j,
					PROP_BITVALUE_ACCESS(prop_value,
						i, j, 0),
					PROP_BITVALUE_ACCESS(prop_value,
@@ -979,6 +1003,16 @@ static int sde_sspp_parse_dt(struct device_node *np,
			goto end;
		}

		snprintf(sblk->src_blk.name, SDE_HW_BLK_NAME_LEN, "sspp_src_%u",
				sspp->id - SSPP_VIG0);

		if (sspp->clk_ctrl >= SDE_CLK_CTRL_MAX) {
			SDE_ERROR("%s: invalid clk ctrl: %d\n",
					sblk->src_blk.name, sspp->clk_ctrl);
			rc = -EINVAL;
			goto end;
		}

		sblk->maxhdeciexp = MAX_HORZ_DECIMATION;
		sblk->maxvdeciexp = MAX_VERT_DECIMATION;

@@ -1336,6 +1370,14 @@ static int sde_wb_parse_dt(struct device_node *np,
			PROP_VALUE_ACCESS(prop_value, WB_ID, i);
		wb->xin_id = PROP_VALUE_ACCESS(prop_value, WB_XIN_ID, i);
		wb->vbif_idx = VBIF_NRT;

		if (wb->clk_ctrl >= SDE_CLK_CTRL_MAX) {
			SDE_ERROR("%s: invalid clk ctrl: %d\n",
					wb->name, wb->clk_ctrl);
			rc = -EINVAL;
			goto end;
		}

		wb->len = PROP_VALUE_ACCESS(prop_value, WB_LEN, 0);
		wb->format_list = wb2_formats;
		if (!prop_exists[WB_LEN])
@@ -2052,7 +2094,7 @@ static int sde_perf_parse_dt(struct device_node *np,
		goto end;
	}

	prop_value = kzalloc(SDE_PROP_MAX *
	prop_value = kzalloc(PERF_PROP_MAX *
			sizeof(struct sde_prop_value), GFP_KERNEL);
	if (!prop_value) {
		rc = -ENOMEM;