From 9db8cb5a6fa96ef0637e55f66dd970e51224d99c Mon Sep 17 00:00:00 2001 From: Ales Novak Date: Fri, 6 Jun 2014 14:35:39 -0700 Subject: drivers/rtc/interface.c: fix infinite loop in initializing the alarm commit ee1d90146815fdc8d653c558b327fff2acba041d upstream. In __rtc_read_alarm(), if the alarm time retrieved by rtc_read_alarm_internal() from the device contains invalid values (e.g. month=2,mday=31) and the year not set (=-1), the initialization will loop infinitely because the year-fixing loop expects the time being invalid due to leap year. Fix reduces the loop to the leap years and adds final validity check. Signed-off-by: Ales Novak Acked-by: Alessandro Zummo Reported-by: Jiri Bohac Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Jiri Slaby --- drivers/rtc/interface.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 72c5cdbe0791..ff20d90ea8e7 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -290,7 +290,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); do { alarm->time.tm_year++; - } while (rtc_valid_tm(&alarm->time) != 0); + } while (!is_leap_year(alarm->time.tm_year + 1900) + && rtc_valid_tm(&alarm->time) != 0); break; default: @@ -298,7 +299,16 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) } done: - return 0; + err = rtc_valid_tm(&alarm->time); + + if (err) { + dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n", + alarm->time.tm_year + 1900, alarm->time.tm_mon + 1, + alarm->time.tm_mday, alarm->time.tm_hour, alarm->time.tm_min, + alarm->time.tm_sec); + } + + return err; } int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) -- cgit v1.2.3