summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSwathi K <quic_c_kataka@quicinc.com>2022-04-29 01:12:49 +0530
committerSwathi K <quic_c_kataka@quicinc.com>2022-04-29 01:15:12 +0530
commit2ed91a98d8b4ad9bafceeed171f33e5fb1376911 (patch)
treec5988dec5104a124e1f41c4790a581ed52bb06f4
parent2967159ad303bf665c64467ad1328ee24cfda123 (diff)
msm: adsprpc: Handle UAF in fastrpc debugfs read
Use lock to protect maps among multiple threads to avoid race condition. Change-Id: Ib0c83dd38ea8e5acb54a1478d10b02385c27ba31 Signed-off-by: Swathi K <quic_c_kataka@quicinc.com>
-rw-r--r--drivers/char/adsprpc.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index a21bde22c830..c94d93611d49 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -2745,6 +2745,7 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
char *fileinfo = NULL;
char single_line[UL_SIZE] = "----------------";
char title[UL_SIZE] = "=========================";
+ unsigned long irq_flags = 0;
fileinfo = kzalloc(DEBUGFS_SIZE, GFP_KERNEL);
if (!fileinfo)
@@ -2807,6 +2808,7 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%s%s%s%s%s\n", single_line, single_line,
single_line, single_line, single_line);
+ spin_lock_irqsave(&me->hlock, irq_flags);
hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%-20d|0x%-18llX|0x%-18X|0x%-20lX\n\n",
@@ -2814,18 +2816,21 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
(uint32_t)gmaps->size,
gmaps->va);
}
+ spin_unlock_irqrestore(&me->hlock, irq_flags);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%-20s|%-20s|%-20s|%-20s\n",
"len", "refs", "raddr", "flags");
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%s%s%s%s%s\n", single_line, single_line,
single_line, single_line, single_line);
+ spin_lock_irqsave(&me->hlock, irq_flags);
hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"0x%-18X|%-20d|%-20lu|%-20u\n",
(uint32_t)gmaps->len, gmaps->refs,
gmaps->raddr, gmaps->flags);
}
+ spin_unlock_irqrestore(&me->hlock, irq_flags);
} else {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"\n%s %13s %d\n", "cid", ":", fl->cid);
@@ -2867,6 +2872,7 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
"%s%s%s%s%s\n",
single_line, single_line, single_line,
single_line, single_line);
+ mutex_lock(&fl->map_mutex);
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"0x%-20lX|0x%-20llX|0x%-20zu\n\n",
@@ -2876,6 +2882,7 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
"%s %d\n\n",
"DEV_MINOR:", fl->dev_minor);
}
+ mutex_unlock(&fl->map_mutex);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%-20s|%-20s|%-20s|%-20s\n",
"len", "refs",
@@ -2884,23 +2891,27 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
"%s%s%s%s%s\n",
single_line, single_line, single_line,
single_line, single_line);
+ mutex_lock(&fl->map_mutex);
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%-20zu|%-20d|0x%-20lX|%-20d\n\n",
map->len, map->refs, map->raddr,
map->uncached);
}
+ mutex_unlock(&fl->map_mutex);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%-20s|%-20s\n", "secure", "attr");
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%s%s%s%s%s\n",
single_line, single_line, single_line,
single_line, single_line);
+ mutex_lock(&fl->map_mutex);
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%-20d|0x%-20lX\n\n",
map->secure, map->attr);
}
+ mutex_unlock(&fl->map_mutex);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"\n%s %s %s\n", title,
" LIST OF PENDING SMQCONTEXTS ", title);