From f49f146a302adddb5f15327a5e14e08a14a4d246 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Fri, 7 May 2021 09:19:30 +0800 Subject: [PATCH] input: qcom-hv-haptics: ensure valid pointer when calling kfree In haptics pattern/fifo/brake debugfs file write operation functions, strsep() is used iteratively to split the user-passed string into tokens for setting parameters. However, strsep() modifies the pointer passed and hence the same pointer cannot be used in kfree(). Fix this by copying the pointer originally allocated by kzalloc() and use it in kfree() as well. Change-Id: I2baf8db4f7c39e7ab0a83411717e46a29a2e849b Signed-off-by: Fenglin Wu --- drivers/input/misc/qcom-hv-haptics.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index e363aff6c515..a0480403bc6f 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -2744,17 +2744,19 @@ static ssize_t pattern_s_dbgfs_write(struct file *fp, { struct haptics_effect *effect = fp->private_data; struct pattern_s patterns[SAMPLES_PER_PATTERN] = {{0, 0, 0},}; - char *str, *token; + char *str, *kbuf, *token; u32 val, tmp[3 * SAMPLES_PER_PATTERN] = {0}; int rc, i = 0, j = 0; if (count > CHAR_PER_PATTERN_S * SAMPLES_PER_PATTERN) return -EINVAL; - str = kzalloc(CHAR_PER_PATTERN_S * SAMPLES_PER_PATTERN + 1, GFP_KERNEL); - if (!str) + kbuf = kzalloc(CHAR_PER_PATTERN_S * SAMPLES_PER_PATTERN + 1, + GFP_KERNEL); + if (!kbuf) return -ENOMEM; + str = kbuf; rc = copy_from_user(str, buf, count); if (rc > 0) { rc = -EFAULT; @@ -2805,7 +2807,7 @@ static ssize_t pattern_s_dbgfs_write(struct file *fp, rc = count; exit: - kfree(str); + kfree(kbuf); return rc; } @@ -2876,7 +2878,7 @@ static ssize_t fifo_s_dbgfs_write(struct file *fp, { struct haptics_effect *effect = fp->private_data; struct fifo_cfg *fifo = effect->fifo; - char *kbuf, *token; + char *str, *kbuf, *token; int rc, i = 0; int val; u8 *samples; @@ -2885,13 +2887,14 @@ static ssize_t fifo_s_dbgfs_write(struct file *fp, if (!kbuf) return -ENOMEM; - rc = copy_from_user(kbuf, buf, count); + str = kbuf; + rc = copy_from_user(str, buf, count); if (rc > 0) { rc = -EFAULT; goto exit; } - kbuf[count] = '\0'; + str[count] = '\0'; *ppos += count; samples = kcalloc(fifo->num_s, sizeof(*samples), GFP_KERNEL); @@ -2900,7 +2903,7 @@ static ssize_t fifo_s_dbgfs_write(struct file *fp, goto exit; } - while ((token = strsep(&kbuf, " ")) != NULL) { + while ((token = strsep(&str, " ")) != NULL) { rc = kstrtoint(token, 0, &val); if (rc < 0) { rc = -EINVAL; @@ -3000,7 +3003,7 @@ static ssize_t brake_s_dbgfs_write(struct file *fp, { struct haptics_effect *effect = fp->private_data; struct brake_cfg *brake = effect->brake; - char *str, *token; + char *str, *kbuf, *token; int rc, i = 0; u32 val; u8 samples[BRAKE_SAMPLE_COUNT] = {0}; @@ -3008,10 +3011,11 @@ static ssize_t brake_s_dbgfs_write(struct file *fp, if (count > CHAR_PER_SAMPLE * BRAKE_SAMPLE_COUNT) return -EINVAL; - str = kzalloc(CHAR_PER_SAMPLE * BRAKE_SAMPLE_COUNT + 1, GFP_KERNEL); - if (!str) + kbuf = kzalloc(CHAR_PER_SAMPLE * BRAKE_SAMPLE_COUNT + 1, GFP_KERNEL); + if (!kbuf) return -ENOMEM; + str = kbuf; rc = copy_from_user(str, buf, count); if (rc > 0) { rc = -EFAULT; @@ -3043,7 +3047,7 @@ static ssize_t brake_s_dbgfs_write(struct file *fp, rc = count; exit: - kfree(str); + kfree(kbuf); return rc; }