summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmine Najahi <anajahi@codeaurora.org>2018-09-17 16:05:25 -0400
committerGerrit - the friendly Code Review server <code-review@localhost>2018-09-24 13:40:47 -0700
commit883b0bfa10465f5afadc61fa8d379d56aa5f0597 (patch)
treea7323dac6cd029a784ba77359f34003a3b56c3f8
parentaa0ebdfe2d12829d8ee6dde5e841e1c67c9141c2 (diff)
fbdev/msm: sanitize debugfs inputs when reading mdp memory
Sanitize debugfs inputs to only allow access to mdp memory block specified in dtsi file. This change will allow only one single block to be read at the time and will avoid accessing memory outside of valid decode space which can trigger AHB error bus response. Change-Id: Icede9a8939a66faa59d674c18183fb0ebcf67908 Signed-off-by: Amine Najahi <anajahi@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_debug.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/mdss_debug.c b/drivers/video/fbdev/msm/mdss_debug.c
index 230b02061b39..e9989fbdd2ba 100644
--- a/drivers/video/fbdev/msm/mdss_debug.c
+++ b/drivers/video/fbdev/msm/mdss_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009-2018, 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
@@ -433,6 +433,39 @@ static int mdss_debug_base_release(struct inode *inode, struct file *file)
return 0;
}
+/**
+ * mdss_debug_base_is_valid_range - verify if requested memory range is valid
+ * @off: address offset in bytes
+ * @cnt: memory size in bytes
+ * Return: true if valid; false otherwise
+ */
+static bool mdss_debug_base_is_valid_range(u32 off, u32 cnt)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ struct mdss_debug_data *mdd = mdata->debug_inf.debug_data;
+ struct range_dump_node *node;
+ struct mdss_debug_base *base;
+
+ pr_debug("check offset=0x%x cnt=0x%x\n", off, cnt);
+
+ list_for_each_entry(base, &mdd->base_list, head) {
+ list_for_each_entry(node, &base->dump_list, head) {
+ pr_debug("%s: start=0x%x end=0x%x\n", node->range_name,
+ node->offset.start, node->offset.end);
+
+ if (node->offset.start <= off
+ && off <= node->offset.end
+ && off + cnt <= node->offset.end) {
+ pr_debug("valid range requested\n");
+ return true;
+ }
+ }
+ }
+
+ pr_err("invalid range requested\n");
+ return false;
+}
+
static ssize_t mdss_debug_base_offset_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
@@ -452,7 +485,8 @@ static ssize_t mdss_debug_base_offset_write(struct file *file,
buf[count] = 0; /* end of string */
- sscanf(buf, "%5x %x", &off, &cnt);
+ if (sscanf(buf, "%5x %x", &off, &cnt) != 2)
+ return -EFAULT;
if (off % sizeof(u32))
return -EINVAL;
@@ -463,6 +497,9 @@ static ssize_t mdss_debug_base_offset_write(struct file *file,
if (cnt > (dbg->max_offset - off))
cnt = dbg->max_offset - off;
+ if (!mdss_debug_base_is_valid_range(off, cnt))
+ return -EINVAL;
+
mutex_lock(&mdss_debug_lock);
dbg->off = off;
dbg->cnt = cnt;