Message ID | 1452168710-16317-1-git-send-email-a.hajda@samsung.com |
---|---|
State | Rejected |
Headers | show |
On 07/01/2016 at 13:11:50 +0100, Andrzej Hajda wrote : > 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. > Yeah, I was not planning to send that patch finally because it had more issues than expected. What you did seems good, I'll have a closer look when I'm back from vacations. My current internet access is too limited to be able to pull/push anything with git. > 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 >
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;
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(-)