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 <alno...@suse.cz>
---
 drivers/rtc/interface.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 544be72..a2df283 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -292,7 +292,9 @@ 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 (alarm->time.tm_mon == 1
+                       && is_leap_year(alarm->time.tm_year + 1900)
+                       && rtc_valid_tm(&alarm->time) != 0);
                break;
 
        default:
@@ -300,7 +302,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)
-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to