mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-05 19:31:57 -04:00
msm: adsprpc: use-after-free (UAF) in global maps
Currently, remote heap maps get added to the global list before the
fastrpc_internal_mmap function completes the mapping. Meanwhile, the
fastrpc_internal_munmap function accesses the map, starts unmapping, and
frees the map before the fastrpc_internal_mmap function completes,
resulting in a use-after-free (UAF) issue. Add the map to the list after
the fastrpc_internal_mmap function completes the mapping.
Change-Id: Ia524f142edba57a1f389dd0e5c83a1967c7f5a59
Acked-by: Abhishek Singh <abhishes@qti.qualcomm.com>
Signed-off-by: Santosh Sakore <quic_ssakore@quicinc.com>
(cherry picked from commit 6f9f631c90)
This commit is contained in:
parent
334dcc92ae
commit
e9218e2bb1
1 changed files with 44 additions and 48 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Uncomment this block to log an error on every VERIFY failure */
|
||||
|
|
@ -1108,64 +1108,43 @@ static void fastrpc_remote_buf_list_free(struct fastrpc_file *fl)
|
|||
} while (free);
|
||||
}
|
||||
|
||||
static void fastrpc_mmap_add_global(struct fastrpc_mmap *map)
|
||||
{
|
||||
struct fastrpc_apps *me = &gfa;
|
||||
unsigned long irq_flags = 0;
|
||||
|
||||
spin_lock_irqsave(&me->hlock, irq_flags);
|
||||
hlist_add_head(&map->hn, &me->maps);
|
||||
spin_unlock_irqrestore(&me->hlock, irq_flags);
|
||||
}
|
||||
|
||||
static void fastrpc_mmap_add(struct fastrpc_mmap *map)
|
||||
{
|
||||
if (map->flags == ADSP_MMAP_HEAP_ADDR ||
|
||||
map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
|
||||
struct fastrpc_apps *me = &gfa;
|
||||
struct fastrpc_file *fl = map->fl;
|
||||
|
||||
spin_lock(&me->hlock);
|
||||
hlist_add_head(&map->hn, &me->maps);
|
||||
spin_unlock(&me->hlock);
|
||||
} else {
|
||||
struct fastrpc_file *fl = map->fl;
|
||||
|
||||
hlist_add_head(&map->hn, &fl->maps);
|
||||
}
|
||||
hlist_add_head(&map->hn, &fl->maps);
|
||||
}
|
||||
|
||||
static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd,
|
||||
uintptr_t va, size_t len, int mflags, int refs,
|
||||
struct fastrpc_mmap **ppmap)
|
||||
{
|
||||
struct fastrpc_apps *me = &gfa;
|
||||
struct fastrpc_mmap *match = NULL, *map = NULL;
|
||||
struct hlist_node *n;
|
||||
|
||||
if ((va + len) < va)
|
||||
return -EFAULT;
|
||||
if (mflags == ADSP_MMAP_HEAP_ADDR ||
|
||||
mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
|
||||
spin_lock(&me->hlock);
|
||||
hlist_for_each_entry_safe(map, n, &me->maps, hn) {
|
||||
if (va >= map->va &&
|
||||
va + len <= map->va + map->len &&
|
||||
map->fd == fd) {
|
||||
if (refs) {
|
||||
if (map->refs + 1 == INT_MAX) {
|
||||
spin_unlock(&me->hlock);
|
||||
return -ETOOMANYREFS;
|
||||
}
|
||||
map->refs++;
|
||||
}
|
||||
match = map;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&me->hlock);
|
||||
} else {
|
||||
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
|
||||
if (va >= map->va &&
|
||||
va + len <= map->va + map->len &&
|
||||
map->fd == fd) {
|
||||
if (refs) {
|
||||
if (map->refs + 1 == INT_MAX)
|
||||
return -ETOOMANYREFS;
|
||||
map->refs++;
|
||||
}
|
||||
match = map;
|
||||
break;
|
||||
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
|
||||
if (va >= map->va &&
|
||||
va + len <= map->va + map->len &&
|
||||
map->fd == fd) {
|
||||
if (refs) {
|
||||
if (map->refs + 1 == INT_MAX)
|
||||
return -ETOOMANYREFS;
|
||||
map->refs++;
|
||||
}
|
||||
match = map;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
|
|
@ -1641,7 +1620,9 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
|
|||
}
|
||||
map->len = len;
|
||||
|
||||
fastrpc_mmap_add(map);
|
||||
if ((mflags != ADSP_MMAP_HEAP_ADDR) &&
|
||||
(mflags != ADSP_MMAP_REMOTE_HEAP_ADDR))
|
||||
fastrpc_mmap_add(map);
|
||||
*ppmap = map;
|
||||
|
||||
bail:
|
||||
|
|
@ -4039,6 +4020,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_file *fl,
|
|||
spin_lock(&me->hlock);
|
||||
mem->in_use = true;
|
||||
spin_unlock(&me->hlock);
|
||||
fastrpc_mmap_add_global(mem);
|
||||
}
|
||||
phys = mem->phys;
|
||||
size = mem->size;
|
||||
|
|
@ -4772,7 +4754,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
|
|||
me->enable_ramdump = false;
|
||||
bail:
|
||||
if (err && match)
|
||||
fastrpc_mmap_add(match);
|
||||
fastrpc_mmap_add_global(match);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -4901,7 +4883,11 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl,
|
|||
bail:
|
||||
if (err && map) {
|
||||
mutex_lock(&fl->map_mutex);
|
||||
fastrpc_mmap_add(map);
|
||||
if ((map->flags == ADSP_MMAP_HEAP_ADDR) ||
|
||||
(map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR))
|
||||
fastrpc_mmap_add_global(map);
|
||||
else
|
||||
fastrpc_mmap_add(map);
|
||||
mutex_unlock(&fl->map_mutex);
|
||||
}
|
||||
mutex_unlock(&fl->internal_map_mutex);
|
||||
|
|
@ -4987,6 +4973,9 @@ static int fastrpc_internal_mem_map(struct fastrpc_file *fl,
|
|||
if (err)
|
||||
goto bail;
|
||||
ud->m.vaddrout = map->raddr;
|
||||
if (ud->m.flags == ADSP_MMAP_HEAP_ADDR ||
|
||||
ud->m.flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
|
||||
fastrpc_mmap_add_global(map);
|
||||
bail:
|
||||
if (err) {
|
||||
pr_err("adsprpc: %s failed to map fd %d flags %d err %d\n",
|
||||
|
|
@ -5047,7 +5036,11 @@ bail:
|
|||
/* Add back to map list in case of error to unmap on DSP */
|
||||
if (map) {
|
||||
mutex_lock(&fl->map_mutex);
|
||||
fastrpc_mmap_add(map);
|
||||
if ((map->flags == ADSP_MMAP_HEAP_ADDR) ||
|
||||
(map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR))
|
||||
fastrpc_mmap_add_global(map);
|
||||
else
|
||||
fastrpc_mmap_add(map);
|
||||
mutex_unlock(&fl->map_mutex);
|
||||
}
|
||||
}
|
||||
|
|
@ -5115,6 +5108,9 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl,
|
|||
if (err)
|
||||
goto bail;
|
||||
map->raddr = raddr;
|
||||
if (ud->flags == ADSP_MMAP_HEAP_ADDR ||
|
||||
ud->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
|
||||
fastrpc_mmap_add_global(map);
|
||||
}
|
||||
ud->vaddrout = raddr;
|
||||
bail:
|
||||
|
|
|
|||
Loading…
Reference in a new issue