From c9754b807b68ca9861965ad6d37a9a6d2b6574d0 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 1d193d5866cc..f72e47b70426 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -2745,17 +2745,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; @@ -2806,7 +2808,7 @@ static ssize_t pattern_s_dbgfs_write(struct file *fp, rc = count; exit: - kfree(str); + kfree(kbuf); return rc; } @@ -2877,7 +2879,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; @@ -2886,13 +2888,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); @@ -2901,7 +2904,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; @@ -3001,7 +3004,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}; @@ -3009,10 +3012,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; @@ -3044,7 +3048,7 @@ static ssize_t brake_s_dbgfs_write(struct file *fp, rc = count; exit: - kfree(str); + kfree(kbuf); return rc; }