summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Troast <ntroast@codeaurora.org>2017-01-16 11:08:07 -0800
committerNicholas Troast <ntroast@codeaurora.org>2017-01-17 12:21:05 -0800
commit6b20920b2d2bdbc13fe7b9f405c06d2cabf9763c (patch)
treec186a06873578d2df25496998c50eba58e6f3c9e
parentf0ea5d918d4916715bd041175b92004224753e6d (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.c18
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;
}