From 8581d22c69bf2063becce9bbb65812d55f6cfdb8 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Gattupalli Date: Mon, 21 Feb 2022 11:27:03 -0800 Subject: [PATCH] msm: adsprpc: fix UAF process init_mem Process init memory allowed to initialize only once to fix possible improper acecss from remote processor. Change-Id: Ic1a13738146fcf0d170abd76b50bdc6a75871755 Acked-by: Krishnaiah Tadakamalla Signed-off-by: Vamsi Krishna Gattupalli --- drivers/char/adsprpc.c | 29 +++++++++++++++-------------- drivers/char/adsprpc_shared.h | 6 ++++++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 98aa44c423a3..68a58d0ecf00 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -697,7 +697,7 @@ struct fastrpc_file { uint32_t poll_timeout; bool is_unsigned_pd; /* Flag to indicate dynamic process creation status*/ - bool in_process_create; + enum fastrpc_process_create_state dsp_process_state; }; static struct fastrpc_apps gfa; @@ -3926,13 +3926,13 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, } inbuf; spin_lock(&fl->hlock); - if (fl->in_process_create) { + if (fl->dsp_process_state) { err = -EALREADY; ADSPRPC_ERR("Already in create dynamic process\n"); spin_unlock(&fl->hlock); return err; } - fl->in_process_create = true; + fl->dsp_process_state = PROCESS_CREATE_IS_INPROGRESS; spin_unlock(&fl->hlock); inbuf.pgid = fl->tgid; inbuf.namelen = strlen(current->comm) + 1; @@ -4090,9 +4090,11 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, fastrpc_mmap_free(file, 0); mutex_unlock(&fl->map_mutex); } + + spin_lock(&fl->hlock); + locked = 1; if (err) { - spin_lock(&fl->hlock); - locked = 1; + fl->dsp_process_state = PROCESS_CREATE_DEFAULT; if (!IS_ERR_OR_NULL(fl->init_mem)) { init_mem = fl->init_mem; fl->init_mem = NULL; @@ -4100,14 +4102,13 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, locked = 0; fastrpc_buf_free(init_mem, 0); } - if (locked) { - spin_unlock(&fl->hlock); - locked = 0; - } + } else { + fl->dsp_process_state = PROCESS_CREATE_SUCCESS; + } + if (locked) { + spin_unlock(&fl->hlock); + locked = 0; } - spin_lock(&fl->hlock); - fl->in_process_create = false; - spin_unlock(&fl->hlock); return err; } @@ -5552,7 +5553,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) spin_lock_irqsave(&fl->apps->hlock, irq_flags); hlist_del_init(&fl->hn); fl->is_ramdump_pend = false; - fl->in_process_create = false; + fl->dsp_process_state = PROCESS_CREATE_DEFAULT; spin_unlock_irqrestore(&fl->apps->hlock, irq_flags); if (!fl->sctx) { @@ -5982,7 +5983,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->qos_request = 0; fl->dsp_proc_init = 0; fl->is_ramdump_pend = false; - fl->in_process_create = false; + fl->dsp_process_state = PROCESS_CREATE_DEFAULT; fl->is_unsigned_pd = false; init_completion(&fl->work); fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE; diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index bc6e0ac80d2a..120ea446a784 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -537,6 +537,12 @@ enum fastrpc_response_flags { POLL_MODE = 5, }; +enum fastrpc_process_create_state { + PROCESS_CREATE_DEFAULT = 0, /* Process is not created */ + PROCESS_CREATE_IS_INPROGRESS = 1, /* Process creation is in progress */ + PROCESS_CREATE_SUCCESS = 2, /* Process creation is successful */ +}; + struct smq_invoke_rspv2 { uint64_t ctx; /* invoke caller context */ int retval; /* invoke return value */