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: Ranjith Goud Namala <rnamala@qti.qualcomm.com>
Signed-off-by: rnamala <quic_rnamala@quicinc.com>
This commit is contained in:
rnamala 2022-09-21 11:13:42 +05:30
parent 747163a77d
commit 1414389bb2
2 changed files with 16 additions and 10 deletions

View File

@ -656,7 +656,7 @@ struct fastrpc_file {
/* Flag to indicate ram dump collection status*/ /* Flag to indicate ram dump collection status*/
bool is_ramdump_pend; bool is_ramdump_pend;
/* Flag to indicate dynamic process creation status*/ /* Flag to indicate dynamic process creation status*/
bool in_process_create; enum fastrpc_process_create_state dsp_process_state;
}; };
static struct fastrpc_apps gfa; static struct fastrpc_apps gfa;
@ -3755,13 +3755,13 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
} inbuf; } inbuf;
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
if (fl->in_process_create) { if (fl->dsp_process_state) {
err = -EALREADY; err = -EALREADY;
ADSPRPC_ERR("Already in create dynamic process\n"); ADSPRPC_ERR("Already in create dynamic process\n");
spin_unlock(&fl->hlock); spin_unlock(&fl->hlock);
return err; return err;
} }
fl->in_process_create = true; fl->dsp_process_state = PROCESS_CREATE_IS_INPROGRESS;
spin_unlock(&fl->hlock); spin_unlock(&fl->hlock);
inbuf.pgid = fl->tgid; inbuf.pgid = fl->tgid;
inbuf.namelen = strlen(current->comm) + 1; inbuf.namelen = strlen(current->comm) + 1;
@ -3916,9 +3916,11 @@ bail:
fastrpc_mmap_free(file, 0); fastrpc_mmap_free(file, 0);
mutex_unlock(&fl->map_mutex); mutex_unlock(&fl->map_mutex);
} }
if (err) {
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
locked = 1; locked = 1;
if (err) {
fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
if (!IS_ERR_OR_NULL(fl->init_mem)) { if (!IS_ERR_OR_NULL(fl->init_mem)) {
init_mem = fl->init_mem; init_mem = fl->init_mem;
fl->init_mem = NULL; fl->init_mem = NULL;
@ -3926,14 +3928,13 @@ bail:
locked = 0; locked = 0;
fastrpc_buf_free(init_mem, 0); fastrpc_buf_free(init_mem, 0);
} }
} else {
fl->dsp_process_state = PROCESS_CREATE_SUCCESS;
}
if (locked) { if (locked) {
spin_unlock(&fl->hlock); spin_unlock(&fl->hlock);
locked = 0; locked = 0;
}
} }
spin_lock(&fl->hlock);
fl->in_process_create = false;
spin_unlock(&fl->hlock);
return err; return err;
} }
@ -5355,7 +5356,7 @@ skip_dump_wait:
spin_lock(&fl->apps->hlock); spin_lock(&fl->apps->hlock);
hlist_del_init(&fl->hn); hlist_del_init(&fl->hn);
fl->is_ramdump_pend = false; fl->is_ramdump_pend = false;
fl->in_process_create = false; fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
spin_unlock(&fl->apps->hlock); spin_unlock(&fl->apps->hlock);
kfree(fl->debug_buf); kfree(fl->debug_buf);
kfree(fl->gidlist.gids); kfree(fl->gidlist.gids);
@ -5773,7 +5774,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
fl->qos_request = 0; fl->qos_request = 0;
fl->dsp_proc_init = 0; fl->dsp_proc_init = 0;
fl->is_ramdump_pend = false; fl->is_ramdump_pend = false;
fl->in_process_create = false; fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
init_completion(&fl->work); init_completion(&fl->work);
fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE; fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE;
filp->private_data = fl; filp->private_data = fl;

View File

@ -513,6 +513,11 @@ enum fastrpc_response_flags {
COMPLETE_SIGNAL = 3 COMPLETE_SIGNAL = 3
}; };
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 { struct smq_invoke_rspv2 {
uint64_t ctx; /* invoke caller context */ uint64_t ctx; /* invoke caller context */
int retval; /* invoke return value */ int retval; /* invoke return value */