Messages in this thread Patch in this message | | | From | Andrzej Hajda <> | Subject | [PATCH] rtc: fix rtc_time64_to_tm calculation | Date | Thu, 07 Jan 2016 13:11:50 +0100 |
| |
Type of local variable days has been changed recently to unsigned, but it can take negative values. As a result it works incorrectly for some arguments. The patch fixes it.
The problem has been detected using proposed semantic patch scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci [1].
[1]: http://permalink.gmane.org/gmane.linux.kernel/2120705
Fixes: cab572b82c4b ('rtc: fix overflow and incorrect calculation in rtc_time64_to_tm') Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> --- drivers/rtc/rtc-lib.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index cf2b23c..6323d13 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c @@ -54,7 +54,7 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) { unsigned int month, year; int secs; - unsigned long days; + unsigned long days, leaps; /* * time must be positive @@ -66,13 +66,16 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) tm->tm_wday = (days + 4) % 7; year = 1970 + days / 365; - days -= (year - 1970) * 365 - + LEAPS_THRU_END_OF(year - 1) - - LEAPS_THRU_END_OF(1970 - 1); - if (days < 0) { + days -= (year - 1970) * 365; + leaps = LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(1970 - 1); + + while (days < leaps) { year -= 1; days += 365 + is_leap_year(year); } + + days -= leaps; + tm->tm_year = year - 1900; tm->tm_yday = days + 1; -- 1.9.1
| |