Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac2db530 authored by Edgar Flores's avatar Edgar Flores Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarEdgar Flores <edgarf@codeaurora.org>
parent 1c0ece44
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -3166,7 +3166,7 @@ static int fastrpc_init_attach_process(struct fastrpc_file *fl,
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 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
		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;