From c0697769dfff30c9c5fc33cec4289bb205281372 Mon Sep 17 00:00:00 2001 From: Puthikorn Voravootivat Date: Tue, 26 Jan 2016 10:58:17 -0800 Subject: [PATCH] CHROMIUM: bq27x00: Fix OOB write in model name The BQ27500_MAX_NAME_LEN is now 7 and when we are unable to read the model name we strcpy "unknown" to the model name variable which will cause out of bound write because of \0 at the end of the string. To address this issue, this patch does 3 things. - Increase model name max length from 7 to 20 - Truncate model name when length >= 20 - Change strcpy to strlcpy BUG=chromium:581343 TEST=build / ryu boot Change-Id: Ibf2003be17aed991568d98dfe50bbe72ef5a8292 Signed-off-by: Puthikorn Voravootivat Reviewed-on: https://chromium-review.googlesource.com/324058 Reviewed-by: David Riley (cherry picked from commit f8e84e625e8f5c4250912b2ce413c8d350e1f483) Reviewed-on: https://chrome-internal-review.googlesource.com/246295 Reviewed-by: David Riley Commit-Queue: Andrew Bresticker Tested-by: Andrew Bresticker --- drivers/power/bq27x00_battery.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index d830d68f196e6..bce12eb2e6fcc 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -74,7 +74,7 @@ #define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */ #define BQ27500_FLAG_FC BIT(9) #define BQ27500_FLAG_OTC BIT(15) -#define BQ27500_MAX_NAME_LEN 7 +#define BQ27500_MAX_NAME_LEN 20 #define BQ27742_POWER_AVG 0x76 @@ -353,14 +353,20 @@ static int bq27x00_battery_model_name(struct bq27x00_device_info *di) return -EINVAL; len = bq27x00_read(di, BQ27500_REG_DEV_NAME_LEN, false); - if (len < 0 || len > BQ27500_MAX_NAME_LEN) { + if (len <= 0) { dev_err(di->dev, "error reading available length = %d\n", len); return -EINVAL; } + if (len >= BQ27500_MAX_NAME_LEN) { + dev_info(di->dev, "model name too long, length = %d\n", len); + len = BQ27500_MAX_NAME_LEN - 1; + } + for (i = 0; i < len; ++i) model_name[i] = bq27x00_read(di, BQ27500_REG_DEV_NAME + i, false); + model_name[i] = '\0'; return 0; } @@ -942,7 +948,7 @@ static int bq27x00_battery_probe(struct i2c_client *client, retval = bq27x00_battery_model_name(di); if (retval) - strcpy(model_name, "unknown"); + strlcpy(model_name, "unknown", BQ27500_MAX_NAME_LEN); return 0;