diff options
| author | Nicholas Troast <ntroast@codeaurora.org> | 2017-01-16 11:08:07 -0800 |
|---|---|---|
| committer | Nicholas Troast <ntroast@codeaurora.org> | 2017-01-17 12:21:05 -0800 |
| commit | 6b20920b2d2bdbc13fe7b9f405c06d2cabf9763c (patch) | |
| tree | c186a06873578d2df25496998c50eba58e6f3c9e | |
| parent | f0ea5d918d4916715bd041175b92004224753e6d (diff) | |
qcom-charger: qpnp-fg: fix oob array access and uninitialized return
pos is incremented by bytes_read which could exceed the boundary of
kbuf. Fix this by checking the bounds of pos.
resched_ms is used when uninitialized. Initialize it.
Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
Change-Id: I3a01d59bb5ed53666307a5210a684c7d9fd654fc
| -rw-r--r-- | drivers/power/qcom-charger/qpnp-fg.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/power/qcom-charger/qpnp-fg.c b/drivers/power/qcom-charger/qpnp-fg.c index 0658f0d3b1eb..e4a8ade80d4f 100644 --- a/drivers/power/qcom-charger/qpnp-fg.c +++ b/drivers/power/qcom-charger/qpnp-fg.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2081,7 +2081,7 @@ static void update_sram_data_work(struct work_struct *work) struct fg_chip *chip = container_of(work, struct fg_chip, update_sram_data.work); - int resched_ms, ret; + int resched_ms = SRAM_PERIOD_NO_ID_UPDATE_MS, ret; bool tried_again = false; wait: @@ -5961,7 +5961,19 @@ static ssize_t fg_memif_dfs_reg_write(struct file *file, const char __user *buf, values = kbuf; /* Parse the data in the buffer. It should be a string of numbers */ - while (sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) { + while ((pos < count) && + sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) { + /* + * We shouldn't be receiving a string of characters that + * exceeds a size of 5 to keep this functionally correct. + * Also, we should make sure that pos never gets overflowed + * beyond the limit. + */ + if (bytes_read > 5 || bytes_read > INT_MAX - pos) { + cnt = 0; + ret = -EINVAL; + break; + } pos += bytes_read; values[cnt++] = data & 0xff; } |
