msm: adsprpc: double free when creating dynamic process

Adding synchronization access to allocated memory of userPD
to avoid double-freeing the buffer when multiple calls are
made to create dynamic userPD process.

Change-Id: I07b2c290cc400007ce00d96b36c5b40b17ea43c9
Signed-off-by: Edgar Flores <edgarf@codeaurora.org>
This commit is contained in:
Edgar Flores 2020-06-18 09:44:04 -07:00 • committed by Gerrit - the friendly Code Review server
commit ac2db530fb

View file

@ -3166,7 +3166,7 @@ bail:
static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
struct fastrpc_ioctl_init_attrs *uproc)
{
int err = 0, memlen = 0, mflags = 0;
int err = 0, memlen = 0, mflags = 0, locked = 0;
struct fastrpc_ioctl_invoke_async ioctl;
struct fastrpc_ioctl_init *init = &uproc->init;
struct smq_phy_page pages[1];
@ -3176,6 +3176,8 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
remote_arg_t ra[6];
int fds[6];
unsigned int gid = 0, one_mb = 1024*1024;
struct fastrpc_buf *init_mem;
struct {
int pgid;
unsigned int namelen;
@ -3248,8 +3250,19 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
goto bail;
}
/* Free any previous donated memory */
if (fl->init_mem)
fastrpc_buf_free(fl->init_mem, 0);
spin_lock(&fl->hlock);
locked = 1;
if (fl->init_mem) {
init_mem = fl->init_mem;
fl->init_mem = NULL;
spin_unlock(&fl->hlock);
locked = 0;
fastrpc_buf_free(init_mem, 0);
}
if (locked) {
spin_unlock(&fl->hlock);
locked = 0;
}
/* Allocate DMA buffer in kernel for donating to remote process */
memlen = ALIGN(max(3*one_mb, init->filelen * 4), one_mb);
@ -3324,9 +3337,18 @@ bail:
mutex_unlock(&fl->map_mutex);
}
if (err) {
spin_lock(&fl->hlock);
locked = 1;
if (!IS_ERR_OR_NULL(fl->init_mem)) {
fastrpc_buf_free(fl->init_mem, 0);
init_mem = fl->init_mem;
fl->init_mem = NULL;
spin_unlock(&fl->hlock);
locked = 0;
fastrpc_buf_free(init_mem, 0);
}
if (locked) {
spin_unlock(&fl->hlock);
locked = 0;
}
}
return err;