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: Abhinav Parihar <parihar@qti.qualcomm.com>
Signed-off-by: Vamsi Krishna Gattupalli <quic_vgattupa@quicinc.com>
This commit is contained in:
Vamsi Krishna Gattupalli 2022-11-24 15:23:28 +05:30
parent edd205328e
commit 2b4159d5f0
2 changed files with 32 additions and 15 deletions

View file

@ -483,7 +483,7 @@ struct fastrpc_file {
/* To indicate attempt has been made to allocate memory for debug_buf */
int debug_buf_alloced_attempted;
/* Flag to indicate dynamic process creation status*/
bool in_process_create;
enum fastrpc_process_create_state dsp_process_state;
struct completion shutdown;
};
@ -2538,7 +2538,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl, int locked);
static int fastrpc_init_process(struct fastrpc_file *fl,
struct fastrpc_ioctl_init_attrs *uproc)
{
int err = 0, rh_hyp_done = 0;
int err = 0, rh_hyp_done = 0, locked = 0;
struct fastrpc_apps *me = &gfa;
struct fastrpc_ioctl_invoke_crc ioctl;
struct fastrpc_ioctl_init *init = &uproc->init;
@ -2552,6 +2552,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
int unsigned_request = proc_attrs && init_flags;
int cid = fl->cid;
struct fastrpc_channel_ctx *chan = &me->channel[cid];
struct fastrpc_buf *init_mem;
if (chan->unsigned_support &&
fl->dev_minor == MINOR_NUM_DEV) {
@ -2617,13 +2618,13 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
} inbuf;
spin_lock(&fl->hlock);
if (fl->in_process_create) {
if (fl->dsp_process_state) {
err = -EALREADY;
pr_err("Already in create init 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;
@ -2832,20 +2833,27 @@ bail:
fastrpc_mmap_free(mem, 0);
mutex_unlock(&fl->map_mutex);
}
if (err) {
if (!IS_ERR_OR_NULL(fl->init_mem)) {
fastrpc_buf_free(fl->init_mem, 0);
fl->init_mem = NULL;
}
}
if (file) {
mutex_lock(&fl->map_mutex);
fastrpc_mmap_free(file, 0);
mutex_unlock(&fl->map_mutex);
}
if (init->flags == FASTRPC_INIT_CREATE) {
spin_lock(&fl->hlock);
fl->in_process_create = false;
spin_lock(&fl->hlock);
locked = 1;
if (err) {
fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
if (!IS_ERR_OR_NULL(fl->init_mem)) {
init_mem = fl->init_mem;
fl->init_mem = NULL;
locked = 0;
spin_unlock(&fl->hlock);
fastrpc_buf_free(init_mem, 0);
}
} else {
fl->dsp_process_state = PROCESS_CREATE_SUCCESS;
}
if (locked) {
locked = 0;
spin_unlock(&fl->hlock);
}
return err;
@ -3811,7 +3819,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
}
spin_lock(&fl->hlock);
fl->file_close = 1;
fl->in_process_create = false;
fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
spin_unlock(&fl->hlock);
if (!IS_ERR_OR_NULL(fl->init_mem))
fastrpc_buf_free(fl->init_mem, 0);
@ -4213,7 +4221,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
fl->cid = -1;
fl->dev_minor = dev_minor;
fl->init_mem = NULL;
fl->in_process_create = false;
fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
memset(&fl->perf, 0, sizeof(fl->perf));
fl->qos_request = 0;
fl->dsp_proc_init = 0;

View file

@ -319,6 +319,15 @@ struct smq_invoke_rsp {
int retval; /* invoke return value */
};
enum fastrpc_process_create_state {
/* Process is not created */
PROCESS_CREATE_DEFAULT = 0,
/* Process creation is in progress */
PROCESS_CREATE_IS_INPROGRESS = 1,
/* Process creation is successful */
PROCESS_CREATE_SUCCESS = 2,
};
enum fastrpc_response_flags {
NORMAL_RESPONSE = 0,
EARLY_RESPONSE = 1,