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: Siva Kumar Akkireddi <sivaa@codeaurora.org>
(cherry picked from commit de875dd095d3ec0906c77518d28f793e6c69a9da)
This commit is contained in:
Siva Kumar Akkireddi 2017-05-11 15:29:47 +05:30 committed by Sean McCreary
parent 4fa71edbf5
commit b65c9eae8d
2 changed files with 13 additions and 17 deletions

View File

@ -97,6 +97,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;
@ -113,6 +114,7 @@ static struct sps_bam *phy2bam(u32 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;
@ -126,6 +128,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 */
@ -135,6 +138,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;
@ -144,6 +148,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;
}
@ -183,11 +188,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 */
@ -207,12 +214,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;
}
@ -260,6 +269,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;
@ -271,6 +281,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;
}
@ -468,6 +479,8 @@ static void sps_debugfs_init(void)
goto bam_addr_err;
}
mutex_init(&sps_debugfs_lock);
return;
bam_addr_err:

View File

@ -49,26 +49,17 @@ extern u8 debug_level_option;
extern u8 print_limit_option;
#define MAX_MSG_LEN 80
#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 (unlikely(print_limit_option > 2)) \
pr_err_ratelimited(msg, ##args); \
else \
pr_err(msg, ##args); \
if (unlikely(debugfs_record_enabled)) \
SPS_DEBUGFS(msg, ##args); \
} while (0)
#define SPS_INFO(msg, args...) do { \
if (unlikely(print_limit_option > 1)) \
pr_info_ratelimited(msg, ##args); \
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)) \
@ -79,8 +70,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)) \
@ -91,8 +80,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)) \
@ -103,8 +90,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)) \
@ -115,8 +100,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)