msm: mdss: 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: Nirmal Abraham <nabrah@codeaurora.org>
Signed-off-by: Raghavendra Ambadas <rambad@codeaurora.org>
This commit is contained in:
Amine Najahi 2018-10-10 17:43:40 +05:30 committed by syphyr
parent ffa060e7d6
commit 0812b3144e

View file

@ -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
@ -391,6 +391,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)
{
@ -413,7 +446,8 @@ static ssize_t mdss_debug_base_offset_write(struct file *file,
if (off % sizeof(u32))
return -EINVAL;
sscanf(buf, "%5x %x", &off, &cnt);
if (sscanf(buf, "%5x %x", &off, &cnt) != 2)
return -EFAULT;
if (off > dbg->max_offset)
return -EINVAL;
@ -421,6 +455,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;