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

Commit 3977a4ce authored by ansharma's avatar ansharma
Browse files

qcom: fg-util: Fix possible race condition in debugfs



There is a possible race condition when debugfs files are concurrently
accessed by multiple threads. Fix this.

CRs-Fixed: 1105395
Change-Id: Iea5a8d659da231a81630d8f2302714e69d35de61
Signed-off-by: default avataransharma <ansharma@codeaurora.org>
parent 314869eb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -369,6 +369,7 @@ struct fg_log_buffer {
/* transaction parameters */
struct fg_trans {
	struct fg_chip		*chip;
	struct mutex		fg_dfs_lock; /* Prevent thread concurrency */
	struct fg_log_buffer	*log;
	u32			cnt;
	u16			addr;
+19 −5
Original line number Diff line number Diff line
@@ -486,6 +486,7 @@ static int fg_sram_dfs_open(struct inode *inode, struct file *file)
	trans->addr = dbgfs_data.addr;
	trans->chip = dbgfs_data.chip;
	trans->offset = trans->addr;
	mutex_init(&trans->fg_dfs_lock);

	file->private_data = trans;
	return 0;
@@ -497,6 +498,7 @@ static int fg_sram_dfs_close(struct inode *inode, struct file *file)

	if (trans && trans->log && trans->data) {
		file->private_data = NULL;
		mutex_destroy(&trans->fg_dfs_lock);
		devm_kfree(trans->chip->dev, trans->log);
		devm_kfree(trans->chip->dev, trans->data);
		devm_kfree(trans->chip->dev, trans);
@@ -648,10 +650,13 @@ static ssize_t fg_sram_dfs_reg_read(struct file *file, char __user *buf,
	size_t ret;
	size_t len;

	mutex_lock(&trans->fg_dfs_lock);
	/* Is the the log buffer empty */
	if (log->rpos >= log->wpos) {
		if (get_log_data(trans) <= 0)
			return 0;
		if (get_log_data(trans) <= 0) {
			len = 0;
			goto unlock_mutex;
		}
	}

	len = min(count, log->wpos - log->rpos);
@@ -659,7 +664,8 @@ static ssize_t fg_sram_dfs_reg_read(struct file *file, char __user *buf,
	ret = copy_to_user(buf, &log->data[log->rpos], len);
	if (ret == len) {
		pr_err("error copy sram register values to user\n");
		return -EFAULT;
		len = -EFAULT;
		goto unlock_mutex;
	}

	/* 'ret' is the number of bytes not copied */
@@ -667,6 +673,9 @@ static ssize_t fg_sram_dfs_reg_read(struct file *file, char __user *buf,

	*ppos += len;
	log->rpos += len;

unlock_mutex:
	mutex_unlock(&trans->fg_dfs_lock);
	return len;
}

@@ -691,10 +700,13 @@ static ssize_t fg_sram_dfs_reg_write(struct file *file, const char __user *buf,
	struct fg_trans *trans = file->private_data;
	u32 address = trans->addr;

	mutex_lock(&trans->fg_dfs_lock);
	/* Make a copy of the user data */
	kbuf = kmalloc(count + 1, GFP_KERNEL);
	if (!kbuf)
		return -ENOMEM;
	if (!kbuf) {
		ret = -ENOMEM;
		goto unlock_mutex;
	}

	ret = copy_from_user(kbuf, buf, count);
	if (ret == count) {
@@ -744,6 +756,8 @@ static ssize_t fg_sram_dfs_reg_write(struct file *file, const char __user *buf,

free_buf:
	kfree(kbuf);
unlock_mutex:
	mutex_unlock(&trans->fg_dfs_lock);
	return ret;
}