diff options
author | chasewu <chasewu@google.com> | 2022-01-12 17:10:40 +0800 |
---|---|---|
committer | chasewu <chasewu@google.com> | 2022-02-14 16:13:40 +0800 |
commit | 4edf770fd08f672a72131cf2fc60b36edd46e773 (patch) | |
tree | 1e0b5546046d3f5220e734c346c9518632bf241b | |
parent | a824f7e29cc6e1f9a1a12b1e6b4a08cbc916c5d4 (diff) | |
download | amplifiers-4edf770fd08f672a72131cf2fc60b36edd46e773.tar.gz |
misc: cs40l25: Replace strlcpy with strscpyandroid-t-preview-2_r0.4android-gs-raviole-5.10-t-preview-2
strscpy() is preferred to strlcpy() because strlcpy()
requires reading past "count" bytes of memory in the
source string in some cases, which can cause a buffer
overflow error.
Bug: 212365353
Test:
adb shell cmd vibrator_manager synced waveform -a -c
10 0 10 51 10 76 10 51
10 0 10 51 10 76 10 51
10 0 10 51 10 76 10 51
10 0 10 51 10 76 10 51
10 0 10 51 10 76 10 51
10 0 10 51 10 76 10 51
10 0 10 51 10 76 10 51
10 0 10 51 10 76 10 51
10 0 10 51 10 76 10 51
Change-Id: I3d4b26943563a862c1a15ff4cce96f2042089ba9
Signed-off-by: James Ogletree <james.ogletree@cirrus.com>
Signed-off-by: Paul Handrigan <paul.handrigan@cirrus.com>
Signed-off-by: chasewu <chasewu@google.com>
-rw-r--r-- | cs40l25/cs40l2x.c | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/cs40l25/cs40l2x.c b/cs40l25/cs40l2x.c index 977c09c..f5867be 100644 --- a/cs40l25/cs40l2x.c +++ b/cs40l25/cs40l2x.c @@ -275,6 +275,19 @@ void cs40l2x_set_state(struct cs40l2x_private *cs40l2x, bool state) } EXPORT_SYMBOL(cs40l2x_set_state); +ssize_t strscpy_pad(char *dest, const char *src, size_t count) +{ + ssize_t written; + + written = strscpy(dest, src, count); + if (written < 0 || written == count - 1) + return written; + + memset(dest + written + 1, 0, count - written - 1); + + return written; +} + static void cs40l2x_set_gpio_event(struct cs40l2x_private *cs40l2x, bool value) { if (cs40l2x->gpio_event != value) { @@ -1913,8 +1926,12 @@ static ssize_t cs40l2x_pwle_store(struct device *dev, bool a = false, v = false; int ret; + if (count > CS40L2X_PWLE_TOTAL_VALS - 1) { + dev_err(dev, "PWLE string too large\n"); + return -E2BIG; + } - pwle_str = kzalloc(count, GFP_KERNEL); + pwle_str = kzalloc(count + 1, GFP_KERNEL); if (!pwle_str) return -ENOMEM; @@ -1938,7 +1955,9 @@ static ssize_t cs40l2x_pwle_store(struct device *dev, section = pwle->sections; - strlcpy(pwle_str, buf, count); + ret = strscpy(pwle_str, buf, count + 1); + if (ret == -E2BIG) + goto err_exit; cur = pwle_str; @@ -1951,6 +1970,13 @@ static ssize_t cs40l2x_pwle_store(struct device *dev, } type = strsep(&token, ":"); + if (!type || !token) { + dev_err(cs40l2x->dev, + "Malformed PWLE. : not found\n"); + ret = -EINVAL; + goto err_exit; + } + token = strim(token); if (type[0] == 'S') { @@ -2131,7 +2157,11 @@ static ssize_t cs40l2x_pwle_store(struct device *dev, pwle->nsections = num_segs; - strlcpy(cs40l2x->pwle_str, buf, count); + ret = strscpy_pad(cs40l2x->pwle_str, buf, CS40L2X_PWLE_TOTAL_VALS); + if (ret == -E2BIG) { + goto err_exit; + } + cs40l2x->pwle_str_size = count; pwle->wlength *= pwle->repeat + 1; @@ -9321,15 +9351,15 @@ int cs40l2x_coeff_file_parse(struct cs40l2x_private *cs40l2x, if (!strncmp(cs40l2x->wt_file, CS40L2X_WT_FILE_NAME_MISSING, CS40L2X_WT_FILE_NAME_LEN_MAX)) - strlcpy(cs40l2x->wt_file, + strscpy(cs40l2x->wt_file, CS40L2X_WT_FILE_NAME_DEFAULT, CS40L2X_WT_FILE_NAME_LEN_MAX); if (*wt_date != '\0') - strlcpy(cs40l2x->wt_date, wt_date, + strscpy(cs40l2x->wt_date, wt_date, CS40L2X_WT_FILE_DATE_LEN_MAX); else - strlcpy(cs40l2x->wt_date, + strscpy(cs40l2x->wt_date, CS40L2X_WT_FILE_DATE_MISSING, CS40L2X_WT_FILE_DATE_LEN_MAX); @@ -9803,7 +9833,7 @@ static int cs40l2x_wavetable_swap(struct cs40l2x_private *cs40l2x, if (ret1) return ret1; - strlcpy(cs40l2x->wt_file, wt_file, CS40L2X_WT_FILE_NAME_LEN_MAX); + strscpy(cs40l2x->wt_file, wt_file, CS40L2X_WT_FILE_NAME_LEN_MAX); ret1 = regmap_write(regmap, cs40l2x_dsp_reg(cs40l2x, "NUMBEROFWAVES", @@ -11542,10 +11572,10 @@ static int cs40l2x_i2c_probe(struct i2c_client *i2c_client, cs40l2x->autosuspend_delay = CS40L2X_AUTOSUSPEND_DELAY_MS; - strlcpy(cs40l2x->wt_file, + strscpy(cs40l2x->wt_file, CS40L2X_WT_FILE_NAME_MISSING, CS40L2X_WT_FILE_NAME_LEN_MAX); - strlcpy(cs40l2x->wt_date, + strscpy(cs40l2x->wt_date, CS40L2X_WT_FILE_DATE_MISSING, CS40L2X_WT_FILE_DATE_LEN_MAX); |