diff options
author | Swathi K <quic_c_kataka@quicinc.com> | 2022-04-29 01:12:49 +0530 |
---|---|---|
committer | Swathi K <quic_c_kataka@quicinc.com> | 2022-04-29 01:15:12 +0530 |
commit | 2ed91a98d8b4ad9bafceeed171f33e5fb1376911 (patch) | |
tree | c5988dec5104a124e1f41c4790a581ed52bb06f4 | |
parent | 2967159ad303bf665c64467ad1328ee24cfda123 (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.c | 11 |
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); |