From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: lookkas@gmail.com
Subject: [Qemu-devel] [PATCH 1/3] rtc: fix overflow in mktimegm
Date: Mon, 1 Oct 2012 14:22:06 +0200 [thread overview]
Message-ID: <1349094128-32332-2-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1349094128-32332-1-git-send-email-pbonzini@redhat.com>
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 <lookkas@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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
next prev parent reply other threads:[~2012-10-01 12:22 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-01 12:22 [Qemu-devel] [PATCH 0/3] Fix autotest-exposed RTC bug 1058225 Paolo Bonzini
2012-10-01 12:22 ` Paolo Bonzini [this message]
2012-10-05 21:19 ` [Qemu-devel] [PATCH 1/3] rtc: fix overflow in mktimegm Anthony Liguori
2012-10-01 12:22 ` [Qemu-devel] [PATCH 2/3] rtc: map CMOS index 0x37 to 0x32 on read and writes Paolo Bonzini
2012-10-01 12:22 ` [Qemu-devel] [PATCH 3/3] rtc: implement century byte Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1349094128-32332-2-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=lookkas@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).