From 1bc20170dc558eab70e7a7fa70c787ed396a4b4c Mon Sep 17 00:00:00 2001 From: Siva Kumar Akkireddi Date: Thu, 11 May 2017 15:29:47 +0530 Subject: [PATCH] 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 (cherry picked from commit de875dd095d3ec0906c77518d28f793e6c69a9da) --- drivers/platform/msm/sps/sps.c | 13 +++++++++++++ drivers/platform/msm/sps/spsi.h | 17 ----------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c index d44cfd92b2f5..ab7f1273098a 100644 --- a/drivers/platform/msm/sps/sps.c +++ b/drivers/platform/msm/sps/sps.c @@ -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: diff --git a/drivers/platform/msm/sps/spsi.h b/drivers/platform/msm/sps/spsi.h index 0f7318a2fff9..341094ea1cdc 100644 --- a/drivers/platform/msm/sps/spsi.h +++ b/drivers/platform/msm/sps/spsi.h @@ -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)