From patchwork Mon Oct 1 12:22:06 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 188281 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id F2E382C00F5 for ; Mon, 1 Oct 2012 22:22:48 +1000 (EST) Received: from localhost ([::1]:41105 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TIf1L-0005ES-35 for incoming@patchwork.ozlabs.org; Mon, 01 Oct 2012 08:22:47 -0400 Received: from eggs.gnu.org ([208.118.235.92]:44726) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TIf13-0004pM-KT for qemu-devel@nongnu.org; Mon, 01 Oct 2012 08:22:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TIf12-0005rf-DG for qemu-devel@nongnu.org; Mon, 01 Oct 2012 08:22:29 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:59474) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TIf12-0005r7-72 for qemu-devel@nongnu.org; Mon, 01 Oct 2012 08:22:28 -0400 Received: by mail-pb0-f45.google.com with SMTP id rp2so7731995pbb.4 for ; Mon, 01 Oct 2012 05:22:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=WuUm5nYJaLbjRUVBAlkZ6NAgqlt8+8aGg9TH67CQ/rE=; b=ceUB5ABjIIK6AwDDbvQefaEzRcINAjbe31Rr8/bn4GKooCbwgYJMc3yo7VnxETr3fI CIn43E0z51wmdlTir4MInTBdExLxpnaJDNV+MUUDdIDfLbgU9zanQJ2+868Zsx8jwuvj PjyynOq4RUzJsbqhzuEWoX4bxxNTXTwF07S7MLjOajhw3DewvgyQdBGYihalH0SB6JzQ 61gBVfzoLa+zpsrRjlNeGigm/MOB4891LMg9Po2VkGD4yOy5PFM6tXGZGgzOnYCsR8by NXxcdPkdgt7zJj19uAR1RhjECpM6B5NHuBFrcNyw7lnJLw5J85vczFABJnnjtUvd75dT O2Vw== Received: by 10.68.220.169 with SMTP id px9mr41378126pbc.14.1349094145018; Mon, 01 Oct 2012 05:22:25 -0700 (PDT) Received: from yakj.usersys.redhat.com (93-34-169-1.ip50.fastwebnet.it. [93.34.169.1]) by mx.google.com with ESMTPS id x8sm10317171paw.16.2012.10.01.05.22.22 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 01 Oct 2012 05:22:23 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 1 Oct 2012 14:22:06 +0200 Message-Id: <1349094128-32332-2-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.12 In-Reply-To: <1349094128-32332-1-git-send-email-pbonzini@redhat.com> References: <1349094128-32332-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: lookkas@gmail.com Subject: [Qemu-devel] [PATCH 1/3] rtc: fix overflow in mktimegm X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 Signed-off-by: Paolo Bonzini --- 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();