[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 1/3] rtc: fix overflow in mktimegm
From: |
Anthony Liguori |
Subject: |
Re: [Qemu-devel] [PATCH 1/3] rtc: fix overflow in mktimegm |
Date: |
Fri, 05 Oct 2012 16:19:57 -0500 |
User-agent: |
Notmuch/0.13.2+93~ged93d79 (http://notmuchmail.org) Emacs/23.3.1 (x86_64-pc-linux-gnu) |
Paolo Bonzini <address@hidden> writes:
> When setting a date in 1980, Linux is actually disregarding the century
> byte and setting the year to 2080. This causes a year-2038 overflow
> in mktimegm. Fix this by doing the days-to-seconds computation in
> 64-bit math.
>
> Reported-by: Lucas Meneghel Rodrigues <address@hidden>
> Signed-off-by: Paolo Bonzini <address@hidden>
Applied. Thanks.
Regards,
Anthony Liguori
> ---
> cutils.c | 2 +-
> tests/rtc-test.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
> 2 file modificati, 46 inserzioni(+). 1 rimozione(-)
>
> diff --git a/cutils.c b/cutils.c
> index 8ef648f..8edd8fa 100644
> --- a/cutils.c
> +++ b/cutils.c
> @@ -115,7 +115,7 @@ time_t mktimegm(struct tm *tm)
> m += 12;
> y--;
> }
> - t = 86400 * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
> + t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
> y / 400 - 719469);
> t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
> return t;
> diff --git a/tests/rtc-test.c b/tests/rtc-test.c
> index f23ac3a..2b9aa63 100644
> --- a/tests/rtc-test.c
> +++ b/tests/rtc-test.c
> @@ -179,6 +179,50 @@ static void check_time(int wiggle)
>
> static int wiggle = 2;
>
> +static void set_year(void)
> +{
> + /* Set BCD mode */
> + cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_DM);
> + cmos_write(RTC_REG_A, 0x76);
> + cmos_write(RTC_YEAR, 0x11);
> + cmos_write(RTC_MONTH, 0x02);
> + cmos_write(RTC_DAY_OF_MONTH, 0x02);
> + cmos_write(RTC_HOURS, 0x02);
> + cmos_write(RTC_MINUTES, 0x04);
> + cmos_write(RTC_SECONDS, 0x58);
> + cmos_write(RTC_REG_A, 0x26);
> +
> + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
> + g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
> + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
> +
> + /* Set a date in 2080 to ensure there is no year-2038 overflow. */
> + cmos_write(RTC_REG_A, 0x76);
> + cmos_write(RTC_YEAR, 0x80);
> + cmos_write(RTC_REG_A, 0x26);
> +
> + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
> + g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
> + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x80);
> +
> + cmos_write(RTC_REG_A, 0x76);
> + cmos_write(RTC_YEAR, 0x11);
> + cmos_write(RTC_REG_A, 0x26);
> +
> + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
> + g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
> + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
> + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
> +}
> +
> static void bcd_check_time(void)
> {
> /* Set BCD mode */
> @@ -269,6 +313,7 @@ int main(int argc, char **argv)
> qtest_add_func("/rtc/bcd/check-time", bcd_check_time);
> qtest_add_func("/rtc/dec/check-time", dec_check_time);
> qtest_add_func("/rtc/alarm-time", alarm_time);
> + qtest_add_func("/rtc/set-year", set_year);
> qtest_add_func("/rtc/fuzz-registers", fuzz_registers);
> ret = g_test_run();
>
> --
> 1.7.12