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

Commit 240f3bd8 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran
Browse files

msm: mdss: fix possible out-of-bounds and overflow issue in mdp debugfs



There are few cases where the count argument passed by the user
space is not validated, which can potentially lead to out of bounds
or overflow issues. In some cases, kernel might copy more data than
what is requested. Add necessary checks to avoid such cases.

Change-Id: Ifa42fbd475665a0ca581c907ce5432584ea0e7ed
[veeras@codeaurora.org: Resolve conflicts in mdss_debug.c]
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent 2198278e
Loading
Loading
Loading
Loading
+29 −18
Original line number Diff line number Diff line
@@ -111,11 +111,11 @@ static ssize_t panel_debug_base_offset_read(struct file *file,
	if (*ppos)
		return 0;	/* the end */

	len = snprintf(buf, sizeof(buf), "0x%02zx %zd\n", dbg->off, dbg->cnt);
	if (len < 0)
	len = snprintf(buf, sizeof(buf), "0x%02zx %zx\n", dbg->off, dbg->cnt);
	if (len < 0 || len >= sizeof(buf))
		return 0;

	if (copy_to_user(buff, buf, len))
	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
		return -EFAULT;

	*ppos += len;	/* increase offset */
@@ -244,7 +244,11 @@ static ssize_t panel_debug_base_reg_read(struct file *file,
	if (mdata->debug_inf.debug_enable_clock)
		mdata->debug_inf.debug_enable_clock(0);

	if (copy_to_user(user_buf, panel_reg_buf, len))
	if (len < 0 || len >= sizeof(panel_reg_buf))
		return 0;

	if ((count < sizeof(panel_reg_buf))
			|| (copy_to_user(user_buf, panel_reg_buf, len)))
		goto read_reg_fail;

	kfree(rx_buf);
@@ -403,7 +407,7 @@ static ssize_t mdss_debug_base_offset_read(struct file *file,
{
	struct mdss_debug_base *dbg = file->private_data;
	int len = 0;
	char buf[24];
	char buf[24] = {'\0'};

	if (!dbg)
		return -ENODEV;
@@ -412,10 +416,10 @@ static ssize_t mdss_debug_base_offset_read(struct file *file,
		return 0;	/* the end */

	len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt);
	if (len < 0)
	if (len < 0 || len >= sizeof(buf))
		return 0;

	if (copy_to_user(buff, buf, len))
	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
		return -EFAULT;

	*ppos += len;	/* increase offset */
@@ -759,7 +763,7 @@ static ssize_t mdss_debug_factor_read(struct file *file,
{
	struct mult_factor *factor = file->private_data;
	int len = 0;
	char buf[32];
	char buf[32] = {'\0'};

	if (!factor)
		return -ENODEV;
@@ -769,10 +773,10 @@ static ssize_t mdss_debug_factor_read(struct file *file,

	len = snprintf(buf, sizeof(buf), "%d/%d\n",
			factor->numer, factor->denom);
	if (len < 0)
	if (len < 0 || len >= sizeof(buf))
		return 0;

	if (copy_to_user(buff, buf, len))
	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
		return -EFAULT;

	*ppos += len;	/* increase offset */
@@ -803,6 +807,8 @@ static ssize_t mdss_debug_perf_mode_write(struct file *file,
	if (copy_from_user(buf, user_buf, count))
		return -EFAULT;

	buf[count] = 0;	/* end of string */

	if (sscanf(buf, "%d", &perf_mode) != 1)
		return -EFAULT;

@@ -823,7 +829,7 @@ static ssize_t mdss_debug_perf_mode_read(struct file *file,
{
	struct mdss_perf_tune *perf_tune = file->private_data;
	int len = 0;
	char buf[40];
	char buf[40] = {'\0'};

	if (!perf_tune)
		return -ENODEV;
@@ -833,10 +839,10 @@ static ssize_t mdss_debug_perf_mode_read(struct file *file,

	len = snprintf(buf, sizeof(buf), "min_mdp_clk %lu min_bus_vote %llu\n",
	perf_tune->min_mdp_clk, perf_tune->min_bus_vote);
	if (len < 0)
	if (len < 0 || len >= sizeof(buf))
		return 0;

	if (copy_to_user(buff, buf, len))
	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
		return -EFAULT;

	*ppos += len;   /* increase offset */
@@ -856,7 +862,7 @@ static ssize_t mdss_debug_perf_panic_read(struct file *file,
{
	struct mdss_data_type *mdata = file->private_data;
	int len = 0;
	char buf[40];
	char buf[40] = {'\0'};

	if (!mdata)
		return -ENODEV;
@@ -866,10 +872,10 @@ static ssize_t mdss_debug_perf_panic_read(struct file *file,

	len = snprintf(buf, sizeof(buf), "%d\n",
		!mdata->has_panic_ctrl);
	if (len < 0)
	if (len < 0 || len >= sizeof(buf))
		return 0;

	if (copy_to_user(buff, buf, len))
	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
		return -EFAULT;

	*ppos += len;   /* increase offset */
@@ -932,9 +938,14 @@ static ssize_t mdss_debug_perf_panic_write(struct file *file,
	if (!mdata)
		return -EFAULT;

	if (count >= sizeof(buf))
		return -EFAULT;

	if (copy_from_user(buf, user_buf, count))
		return -EFAULT;

	buf[count] = 0;	/* end of string */

	if (sscanf(buf, "%d", &disable_panic) != 1)
		return -EFAULT;

@@ -1004,10 +1015,10 @@ static ssize_t mdss_debug_perf_bw_limit_read(struct file *file,
		temp_settings++;
	}

	if (len < 0)
	if (len < 0 || len >= sizeof(buf))
		return 0;

	if (copy_to_user(buff, buf, len))
	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
		return -EFAULT;

	*ppos += len;	/* increase offset */