[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 08/43] rtc: fix overflow in mktimegm
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 08/43] rtc: fix overflow in mktimegm |
Date: |
Mon, 3 Dec 2012 16:08:32 -0600 |
From: Paolo Bonzini <address@hidden>
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>
Signed-off-by: Anthony Liguori <address@hidden>
(cherry picked from commit b6db4aca20e9af4f62c9c9e08b9b9672a6ed3390)
Signed-off-by: Michael Roth <address@hidden>
---
cutils.c | 2 +-
tests/rtc-test.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletion(-)
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.9.5
- [Qemu-stable] Patch Round-up for stable 1.2.2, freeze Wednesday, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 02/43] fix CONFIG_QEMU_HELPERDIR generation again, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 01/43] configure: Fix CONFIG_QEMU_HELPERDIR generation, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 03/43] ui/vnc: Only report/use TIGHT_PNG encoding if enabled., Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 04/43] vnc: fix "info vnc" with "-vnc ..., reverse=on", Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 05/43] uhci: Raise interrupt when requested even for non active tds, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 06/43] hw/qxl: qxl_dirty_surfaces: use uintptr_t, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 07/43] qxl: always update displaysurface on resize, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 08/43] rtc: fix overflow in mktimegm,
Michael Roth <=
- [Qemu-stable] [PATCH 09/43] hw: Fix return value check for bdrv_read, bdrv_write, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 10/43] target-i386: Allow tsc-frequency to be larger then 2.147G, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 11/43] e1000: drop check_rxov, always treat RX ring with RDH == RDT as empty, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 12/43] memory: fix rendering of a region obscured by another, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 13/43] s390x: fix -initrd in virtio machine, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 14/43] PPC: Bamboo: Fix memory size DT property, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 15/43] target-sparc64: disable VGA cirrus, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 16/43] xhci: fix usb name in caps, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 17/43] tools: initialize main loop before block layer, Michael Roth, 2012/12/03
- [Qemu-stable] [PATCH 19/43] nbd: fixes to read-only handling, Michael Roth, 2012/12/03