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

Commit ce14a087 authored by Siva Kumar Akkireddi's avatar Siva Kumar Akkireddi Committed by Gerrit - the friendly Code Review server
Browse files

msm: sps: Fix race condition in SPS debugfs APIs



SPS debugfs APIs can be called concurrently which can result
in dangling pointer access. This change synchronizes access
to the SPS debugfs buffer.

Change-Id: I409b3f0618f760cb67eba47b43c81d166cdae4aa
Signed-off-by: default avatarSiva Kumar Akkireddi <sivaa@codeaurora.org>
parent cbf162ed
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -101,6 +101,7 @@ static char *debugfs_buf;
static u32 debugfs_buf_size;
static u32 debugfs_buf_used;
static int wraparound;
static struct mutex sps_debugfs_lock;

struct dentry *dent;
struct dentry *dfile_info;
@@ -118,6 +119,7 @@ static struct sps_bam *phy2bam(phys_addr_t phys_addr);
/* record debug info for debugfs */
void sps_debugfs_record(const char *msg)
{
	mutex_lock(&sps_debugfs_lock);
	if (debugfs_record_enabled) {
		if (debugfs_buf_used + MAX_MSG_LEN >= debugfs_buf_size) {
			debugfs_buf_used = 0;
@@ -131,6 +133,7 @@ void sps_debugfs_record(const char *msg)
					debugfs_buf_size - debugfs_buf_used,
					"\n**** end line of sps log ****\n\n");
	}
	mutex_unlock(&sps_debugfs_lock);
}

/* read the recorded debug info to userspace */
@@ -140,6 +143,7 @@ static ssize_t sps_read_info(struct file *file, char __user *ubuf,
	int ret = 0;
	int size;

	mutex_lock(&sps_debugfs_lock);
	if (debugfs_record_enabled) {
		if (wraparound)
			size = debugfs_buf_size - MAX_MSG_LEN;
@@ -149,6 +153,7 @@ static ssize_t sps_read_info(struct file *file, char __user *ubuf,
		ret = simple_read_from_buffer(ubuf, count, ppos,
				debugfs_buf, size);
	}
	mutex_unlock(&sps_debugfs_lock);

	return ret;
}
@@ -194,11 +199,13 @@ static ssize_t sps_set_info(struct file *file, const char __user *buf,

	new_buf_size = buf_size_kb * SZ_1K;

	mutex_lock(&sps_debugfs_lock);
	if (debugfs_record_enabled) {
		if (debugfs_buf_size == new_buf_size) {
			/* need do nothing */
			pr_info("sps:debugfs: input buffer size "
				"is the same as before.\n");
			mutex_unlock(&sps_debugfs_lock);
			return count;
		} else {
			/* release the current buffer */
@@ -218,12 +225,14 @@ static ssize_t sps_set_info(struct file *file, const char __user *buf,
	if (!debugfs_buf) {
		debugfs_buf_size = 0;
		pr_err("sps:fail to allocate memory for debug_fs.\n");
		mutex_unlock(&sps_debugfs_lock);
		return -ENOMEM;
	}

	debugfs_buf_used = 0;
	wraparound = false;
	debugfs_record_enabled = true;
	mutex_unlock(&sps_debugfs_lock);

	return count;
}
@@ -272,6 +281,7 @@ static ssize_t sps_set_logging_option(struct file *file, const char __user *buf,
		return count;
	}

	mutex_lock(&sps_debugfs_lock);
	if (((option == 0) || (option == 2)) &&
		((logging_option == 1) || (logging_option == 3))) {
		debugfs_record_enabled = false;
@@ -283,6 +293,7 @@ static ssize_t sps_set_logging_option(struct file *file, const char __user *buf,
	}

	logging_option = option;
	mutex_unlock(&sps_debugfs_lock);

	return count;
}
@@ -610,6 +621,8 @@ static void sps_debugfs_init(void)
		goto bam_addr_err;
	}

	mutex_init(&sps_debugfs_lock);

	return;

bam_addr_err:
+0 −17
Original line number Diff line number Diff line
@@ -61,11 +61,6 @@ extern u8 logging_option;
extern u8 debug_level_option;
extern u8 print_limit_option;

#define SPS_DEBUGFS(msg, args...) do {					\
		char buf[MAX_MSG_LEN];		\
		snprintf(buf, MAX_MSG_LEN, msg"\n", ##args);	\
		sps_debugfs_record(buf);	\
	} while (0)
#define SPS_ERR(msg, args...) do {					\
		if (logging_option != 1) {	\
			if (unlikely(print_limit_option > 2))	\
@@ -73,8 +68,6 @@ extern u8 print_limit_option;
			else	\
				pr_err(msg, ##args);	\
		}	\
		if (unlikely(debugfs_record_enabled))	\
			SPS_DEBUGFS(msg, ##args);	\
	} while (0)
#define SPS_INFO(msg, args...) do {					\
		if (logging_option != 1) {	\
@@ -83,8 +76,6 @@ extern u8 print_limit_option;
			else	\
				pr_info(msg, ##args);	\
		}	\
		if (unlikely(debugfs_record_enabled))	\
			SPS_DEBUGFS(msg, ##args);	\
	} while (0)
#define SPS_DBG(msg, args...) do {					\
		if ((unlikely(logging_option > 1))	\
@@ -95,8 +86,6 @@ extern u8 print_limit_option;
				pr_info(msg, ##args);	\
		} else	\
			pr_debug(msg, ##args);	\
		if (unlikely(debugfs_record_enabled))	\
			SPS_DEBUGFS(msg, ##args);	\
	} while (0)
#define SPS_DBG1(msg, args...) do {					\
		if ((unlikely(logging_option > 1))	\
@@ -107,8 +96,6 @@ extern u8 print_limit_option;
				pr_info(msg, ##args);	\
		} else	\
			pr_debug(msg, ##args);	\
		if (unlikely(debugfs_record_enabled))	\
			SPS_DEBUGFS(msg, ##args);	\
	} while (0)
#define SPS_DBG2(msg, args...) do {					\
		if ((unlikely(logging_option > 1))	\
@@ -119,8 +106,6 @@ extern u8 print_limit_option;
				pr_info(msg, ##args);	\
		} else	\
			pr_debug(msg, ##args);	\
		if (unlikely(debugfs_record_enabled))	\
			SPS_DEBUGFS(msg, ##args);	\
	} while (0)
#define SPS_DBG3(msg, args...) do {					\
		if ((unlikely(logging_option > 1))	\
@@ -131,8 +116,6 @@ extern u8 print_limit_option;
				pr_info(msg, ##args);	\
		} else	\
			pr_debug(msg, ##args);	\
		if (unlikely(debugfs_record_enabled))	\
			SPS_DEBUGFS(msg, ##args);	\
	} while (0)
#else
#define	SPS_DBG3(x...)		pr_debug(x)