mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-20 21:34:24 -05:00
183 lines
4.9 KiB
Diff
183 lines
4.9 KiB
Diff
From aa23820b001ab1cfb86b79014e9fc44cd2be9ece Mon Sep 17 00:00:00 2001
|
|
From: Ingrid Gallardo <ingridg@codeaurora.org>
|
|
Date: Wed, 1 Mar 2017 12:24:06 -0800
|
|
Subject: msm: mdss: fix race condition in mdp debugfs
|
|
|
|
Fix race condition in mdp debugfs properties
|
|
during the read and write of the panel and
|
|
mdp registers. This race condition can cause
|
|
accessing memory out bounderies.
|
|
|
|
Change-Id: I97a90a154237343d4aaf237c11f525bcc2c3a8e3
|
|
Signed-off-by: Ingrid Gallardo <ingridg@codeaurora.org>
|
|
Signed-off-by: Nirmal Abraham <nabrah@codeaurora.org>
|
|
---
|
|
drivers/video/msm/mdss/mdss_debug.c | 48 ++++++++++++++++++++++++++++++-------
|
|
1 file changed, 40 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c
|
|
index a95fa43..cedd40cd 100644
|
|
--- a/drivers/video/msm/mdss/mdss_debug.c
|
|
+++ b/drivers/video/msm/mdss/mdss_debug.c
|
|
@@ -1,4 +1,4 @@
|
|
-/* Copyright (c) 2009-2016, The Linux Foundation. All rights reserved.
|
|
+/* Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
@@ -39,6 +39,8 @@
|
|
#define PANEL_CMD_MIN_TX_COUNT 2
|
|
#define PANEL_DATA_NODE_LEN 80
|
|
|
|
+static DEFINE_MUTEX(mdss_debug_lock);
|
|
+
|
|
static char panel_reg[2] = {DEFAULT_READ_PANEL_POWER_MODE_REG, 0x00};
|
|
|
|
static int panel_debug_base_open(struct inode *inode, struct file *file)
|
|
@@ -88,8 +90,10 @@ static ssize_t panel_debug_base_offset_write(struct file *file,
|
|
if (cnt > (dbg->max_offset - off))
|
|
cnt = dbg->max_offset - off;
|
|
|
|
+ mutex_lock(&mdss_debug_lock);
|
|
dbg->off = off;
|
|
dbg->cnt = cnt;
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
|
|
pr_debug("offset=%x cnt=%d\n", off, cnt);
|
|
|
|
@@ -109,15 +113,21 @@ static ssize_t panel_debug_base_offset_read(struct file *file,
|
|
if (*ppos)
|
|
return 0; /* the end */
|
|
|
|
+ mutex_lock(&mdss_debug_lock);
|
|
len = snprintf(buf, sizeof(buf), "0x%02zx %zx\n", dbg->off, dbg->cnt);
|
|
- if (len < 0 || len >= sizeof(buf))
|
|
+ if (len < 0 || len >= sizeof(buf)) {
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return 0;
|
|
+ }
|
|
|
|
- if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
|
|
+ if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) {
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return -EFAULT;
|
|
+ }
|
|
|
|
*ppos += len; /* increase offset */
|
|
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return len;
|
|
}
|
|
|
|
@@ -206,11 +216,16 @@ static ssize_t panel_debug_base_reg_read(struct file *file,
|
|
if (!dbg)
|
|
return -ENODEV;
|
|
|
|
- if (!dbg->cnt)
|
|
+ mutex_lock(&mdss_debug_lock);
|
|
+ if (!dbg->cnt) {
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return 0;
|
|
+ }
|
|
|
|
- if (*ppos)
|
|
+ if (*ppos) {
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return 0; /* the end */
|
|
+ }
|
|
|
|
/* '0x' + 2 digit + blank = 5 bytes for each number */
|
|
reg_buf_len = (dbg->cnt * PANEL_REG_FORMAT_LEN)
|
|
@@ -251,11 +266,13 @@ static ssize_t panel_debug_base_reg_read(struct file *file,
|
|
kfree(panel_reg_buf);
|
|
|
|
*ppos += len; /* increase offset */
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return len;
|
|
|
|
read_reg_fail:
|
|
kfree(rx_buf);
|
|
kfree(panel_reg_buf);
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return rc;
|
|
}
|
|
|
|
@@ -386,8 +403,10 @@ static ssize_t mdss_debug_base_offset_write(struct file *file,
|
|
if (cnt > (dbg->max_offset - off))
|
|
cnt = dbg->max_offset - off;
|
|
|
|
+ mutex_lock(&mdss_debug_lock);
|
|
dbg->off = off;
|
|
dbg->cnt = cnt;
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
|
|
pr_debug("offset=%x cnt=%x\n", off, cnt);
|
|
|
|
@@ -407,15 +426,21 @@ static ssize_t mdss_debug_base_offset_read(struct file *file,
|
|
if (*ppos)
|
|
return 0; /* the end */
|
|
|
|
+ mutex_lock(&mdss_debug_lock);
|
|
len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt);
|
|
- if (len < 0 || len >= sizeof(buf))
|
|
+ if (len < 0 || len >= sizeof(buf)) {
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return 0;
|
|
+ }
|
|
|
|
- if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
|
|
+ if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) {
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return -EFAULT;
|
|
+ }
|
|
|
|
*ppos += len; /* increase offset */
|
|
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return len;
|
|
}
|
|
|
|
@@ -472,6 +497,8 @@ static ssize_t mdss_debug_base_reg_read(struct file *file,
|
|
return -ENODEV;
|
|
}
|
|
|
|
+ mutex_lock(&mdss_debug_lock);
|
|
+
|
|
if (!dbg->buf) {
|
|
char dump_buf[64];
|
|
char *ptr;
|
|
@@ -483,6 +510,7 @@ static ssize_t mdss_debug_base_reg_read(struct file *file,
|
|
|
|
if (!dbg->buf) {
|
|
pr_err("not enough memory to hold reg dump\n");
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
@@ -513,17 +541,21 @@ static ssize_t mdss_debug_base_reg_read(struct file *file,
|
|
dbg->buf_len = tot;
|
|
}
|
|
|
|
- if (*ppos >= dbg->buf_len)
|
|
+ if (*ppos >= dbg->buf_len) {
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return 0; /* done reading */
|
|
+ }
|
|
|
|
len = min(count, dbg->buf_len - (size_t) *ppos);
|
|
if (copy_to_user(user_buf, dbg->buf + *ppos, len)) {
|
|
pr_err("failed to copy to user\n");
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return -EFAULT;
|
|
}
|
|
|
|
*ppos += len; /* increase offset */
|
|
|
|
+ mutex_unlock(&mdss_debug_lock);
|
|
return len;
|
|
}
|
|
|
|
--
|
|
cgit v1.1
|
|
|