diff options
author | Chase Wu <chasewu@google.com> | 2023-01-12 15:31:04 +0800 |
---|---|---|
committer | Necip Fazil Yildiran <necip@google.com> | 2023-01-13 18:29:08 +0000 |
commit | f9ff2a09afff03b927a561e66a5ece9596dbc5cf (patch) | |
tree | 6422035bd8ff3307a3d42818adb9e2623ce88505 | |
parent | 5e4a2359658d6439c765fcdaf45f55d89f582942 (diff) | |
download | drivers-f9ff2a09afff03b927a561e66a5ece9596dbc5cf.tar.gz |
misc: cs40l25: Use strscpy to write the buffer
Use strscpy to write to the buffer in cs40l2x_cp_trigger_queue_show
to avoid writing incorrect addresses using snprintf.
Also, checking to see if the input trigger queue string is too large.
Bug: 224000736
Test: push a poc file and check the log
Change-Id: Id46d8a0dbe8eea188362e4f2ca54ccbd720d2bc8
Signed-off-by: Paul Handrigan <Paul.Handrigan@cirrus.com>
Signed-off-by: Chase Wu <chasewu@google.com>
(cherry picked from commit 31ef461089e795b4347499e792a6a5c88425aeae)
Signed-off-by: Necip Fazil Yildiran <necip@google.com>
-rw-r--r-- | haptics/cs40l2x/cs40l2x.c | 36 | ||||
-rw-r--r-- | haptics/cs40l2x/linux/mfd/cs40l2x.h | 1 |
2 files changed, 30 insertions, 7 deletions
diff --git a/haptics/cs40l2x/cs40l2x.c b/haptics/cs40l2x/cs40l2x.c index e4bdb52..1703558 100644 --- a/haptics/cs40l2x/cs40l2x.c +++ b/haptics/cs40l2x/cs40l2x.c @@ -994,41 +994,56 @@ static ssize_t cs40l2x_cp_trigger_queue_show(struct device *dev, { struct cs40l2x_private *cs40l2x = cs40l2x_get_private(dev); struct wt_type10_comp_section *section = cs40l2x->pbq_comp.sections; + char *pbq_str; int i, len = 0; + if (!cs40l2x->pbq_str_size) { + dev_err(dev, "PBQ string is not set\n"); + return -EPERM; + } + + pbq_str = kzalloc(cs40l2x->pbq_str_size + 1, GFP_KERNEL); + if (!pbq_str) + return -ENOMEM; + mutex_lock(&cs40l2x->lock); for (i = 0; i < cs40l2x->pbq_comp.nsections; i++, section++) { if (section->repeat == WT_REPEAT_LOOP_MARKER) - len += snprintf(buf + len, PAGE_SIZE - len, "!!, "); + len += snprintf(pbq_str + len, PAGE_SIZE - len, "!!, "); if (section->amplitude) - len += snprintf(buf + len, PAGE_SIZE - len, "%d.%d, ", + len += snprintf(pbq_str + len, PAGE_SIZE - len, "%d.%d, ", section->index, section->amplitude); if (section->delay) - len += snprintf(buf + len, PAGE_SIZE - len, "%d, ", + len += snprintf(pbq_str + len, PAGE_SIZE - len, "%d, ", section->delay); if (section->repeat && section->repeat != WT_REPEAT_LOOP_MARKER) - len += snprintf(buf + len, PAGE_SIZE - len, "%d!!, ", + len += snprintf(pbq_str + len, PAGE_SIZE - len, "%d!!, ", section->repeat); } switch (cs40l2x->pbq_comp.repeat) { case WT_REPEAT_LOOP_MARKER: - len += snprintf(buf + len, PAGE_SIZE - len, "~\n"); + len += snprintf(pbq_str + len, PAGE_SIZE - len, "~\n"); break; case 0: len -= 2; // Remove ", " from end of string - len += snprintf(buf + len, PAGE_SIZE - len, "\n"); + len += snprintf(pbq_str + len, PAGE_SIZE - len, "\n"); break; default: - len += snprintf(buf + len, PAGE_SIZE - len, "%d!\n", + len += snprintf(pbq_str + len, PAGE_SIZE - len, "%d!\n", cs40l2x->pbq_comp.repeat); } + len = strscpy(buf, pbq_str, PAGE_SIZE); + if (len == -E2BIG) + dev_err(dev, "String too large for buffer\n"); + mutex_unlock(&cs40l2x->lock); + kfree(pbq_str); return len; } @@ -1085,10 +1100,17 @@ static ssize_t cs40l2x_cp_trigger_queue_store(struct device *dev, bool inner_loop = false; int ret; + if (count >= PAGE_SIZE) { + dev_err(dev, "Trigger queue string too large\n"); + return -E2BIG; + } + pbq_str = kstrndup(buf, count, GFP_KERNEL); if (!pbq_str) return -ENOMEM; + cs40l2x->pbq_str_size = count; + disable_irq(i2c_client->irq); mutex_lock(&cs40l2x->lock); diff --git a/haptics/cs40l2x/linux/mfd/cs40l2x.h b/haptics/cs40l2x/linux/mfd/cs40l2x.h index e7b0330..6cb0b09 100644 --- a/haptics/cs40l2x/linux/mfd/cs40l2x.h +++ b/haptics/cs40l2x/linux/mfd/cs40l2x.h @@ -1098,6 +1098,7 @@ struct cs40l2x_private { struct wt_type10_comp pbq_comp; unsigned int pbq_index; unsigned int pbq_state; + size_t pbq_str_size; int pbq_inner_mark; int pbq_inner_loop; int pbq_outer_loop; |