| From 3314800e0aa99888ab8d95a146bc1d4d9a069494 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 6 Feb 2019 09:50:53 +0000 |
| Subject: rtc: 88pm860x: fix unintended sign extension |
| |
| From: Colin Ian King <colin.king@canonical.com> |
| |
| [ Upstream commit dc9e47160626cdb58d5c39a4f43dcfdb27a5c004 ] |
| |
| Shifting a u8 by 24 will cause the value to be promoted to an integer. If |
| the top bit of the u8 is set then the following conversion to an unsigned |
| long will sign extend the value causing the upper 32 bits to be set in |
| the result. |
| |
| Fix this by casting the u8 value to an unsigned long before the shift. |
| |
| Detected by CoverityScan, CID#144925-144928 ("Unintended sign extension") |
| |
| Fixes: 008b30408c40 ("mfd: Add rtc support to 88pm860x") |
| Signed-off-by: Colin Ian King <colin.king@canonical.com> |
| Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/rtc/rtc-88pm860x.c | 21 ++++++++++++++------- |
| 1 file changed, 14 insertions(+), 7 deletions(-) |
| |
| diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c |
| index 166faae3a59cd..7d3e5168fcefc 100644 |
| --- a/drivers/rtc/rtc-88pm860x.c |
| +++ b/drivers/rtc/rtc-88pm860x.c |
| @@ -115,11 +115,13 @@ static int pm860x_rtc_read_time(struct device *dev, struct rtc_time *tm) |
| pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); |
| dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], |
| buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); |
| - base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; |
| + base = ((unsigned long)buf[1] << 24) | (buf[3] << 16) | |
| + (buf[5] << 8) | buf[7]; |
| |
| /* load 32-bit read-only counter */ |
| pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); |
| - data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
| + data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) | |
| + (buf[1] << 8) | buf[0]; |
| ticks = base + data; |
| dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", |
| base, data, ticks); |
| @@ -145,7 +147,8 @@ static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm) |
| |
| /* load 32-bit read-only counter */ |
| pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); |
| - data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
| + data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) | |
| + (buf[1] << 8) | buf[0]; |
| base = ticks - data; |
| dev_dbg(info->dev, "set base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", |
| base, data, ticks); |
| @@ -170,10 +173,12 @@ static int pm860x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); |
| dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], |
| buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); |
| - base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; |
| + base = ((unsigned long)buf[1] << 24) | (buf[3] << 16) | |
| + (buf[5] << 8) | buf[7]; |
| |
| pm860x_bulk_read(info->i2c, PM8607_RTC_EXPIRE1, 4, buf); |
| - data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
| + data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) | |
| + (buf[1] << 8) | buf[0]; |
| ticks = base + data; |
| dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", |
| base, data, ticks); |
| @@ -198,11 +203,13 @@ static int pm860x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); |
| dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], |
| buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); |
| - base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; |
| + base = ((unsigned long)buf[1] << 24) | (buf[3] << 16) | |
| + (buf[5] << 8) | buf[7]; |
| |
| /* load 32-bit read-only counter */ |
| pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); |
| - data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
| + data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) | |
| + (buf[1] << 8) | buf[0]; |
| ticks = base + data; |
| dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", |
| base, data, ticks); |
| -- |
| 2.20.1 |
| |