From patchwork Wed Aug 1 23:21:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 10450 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 217EE23F61 for ; Wed, 1 Aug 2012 23:22:30 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id BD5AFA1902C for ; Wed, 1 Aug 2012 23:22:29 +0000 (UTC) Received: by yenq6 with SMTP id q6so7841685yen.11 for ; Wed, 01 Aug 2012 16:22:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:x-content-scanned:x-cbid :x-gm-message-state; bh=x6XBX+dCfHVndAi2JHZD0rWca4GJykPXKViK8YAXsIw=; b=hV7L2I4/Rge33ZKAU4SPTlyn6ZWYMexGNhWI/s/3En31xoK/bB40YrJ8UG8xZmpNmc sFZRKozisDqbkpimSw5OGnruDl1/YBNBsyQjjYS4zYLopKli8aeV35sMdGtpoZwWa4l5 6189hNg4ZkUmY5tzEl7zSlbzquw4+JZbf9RxiqeoUM13OqxQpnSF5f/CveuHwZgJWQ91 GLMT7/YOg5Z2CXyvagTeUdw2KwX4qVu270Sq4mbuCExmYEhjxamyZhSC/0vjBhEaGyqU XXsLwSJUqKaIc5vC2An22NGdEJU0FgP2GQO4U7v8tzZtDI5e1P0JeT6zWXoklUeyD5We Fg7g== Received: by 10.43.69.12 with SMTP id ya12mr766125icb.50.1343863348779; Wed, 01 Aug 2012 16:22:28 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.87.40 with SMTP id u8csp224905igz; Wed, 1 Aug 2012 16:22:28 -0700 (PDT) Received: by 10.182.14.36 with SMTP id m4mr31833274obc.71.1343863347851; Wed, 01 Aug 2012 16:22:27 -0700 (PDT) Received: from e1.ny.us.ibm.com (e1.ny.us.ibm.com. [32.97.182.141]) by mx.google.com with ESMTPS id rp7si4056876obc.80.2012.08.01.16.22.27 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 01 Aug 2012 16:22:27 -0700 (PDT) Received-SPF: neutral (google.com: 32.97.182.141 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=32.97.182.141; Authentication-Results: mx.google.com; spf=neutral (google.com: 32.97.182.141 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) smtp.mail=john.stultz@linaro.org Received: from /spool/local by e1.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2012 19:22:20 -0400 Received: from d01dlp02.pok.ibm.com (9.56.250.167) by e1.ny.us.ibm.com (192.168.1.101) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 1 Aug 2012 19:21:28 -0400 Received: from d01relay04.pok.ibm.com (d01relay04.pok.ibm.com [9.56.227.236]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id 145026E8045; Wed, 1 Aug 2012 19:21:26 -0400 (EDT) Received: from d01av03.pok.ibm.com (d01av03.pok.ibm.com [9.56.224.217]) by d01relay04.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q71NLO8J143150; Wed, 1 Aug 2012 19:21:24 -0400 Received: from d01av03.pok.ibm.com (loopback [127.0.0.1]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q71NLMpP026329; Wed, 1 Aug 2012 20:21:24 -0300 Received: from kernel-pok.stglabs.ibm.com (kernel.stglabs.ibm.com [9.114.214.19]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q71NLMbQ026287; Wed, 1 Aug 2012 20:21:22 -0300 From: John Stultz To: linux-kernel Cc: John Stultz , Ingo Molnar , Peter Zijlstra , Prarit Bhargava , Thomas Gleixner , Zhouping Liu , CAI Qian , stable@vger.kernel.org Subject: [PATCH] time: Limit time values that would overflow ktime_t Date: Wed, 1 Aug 2012 19:21:16 -0400 Message-Id: <1343863276-30340-1-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12080123-6078-0000-0000-00000DC752FC X-Gm-Message-State: ALoCoQkKe4OvK9QpL+c6CLbo5WM6tQLWolAH6tObzDtGTU89kfmwomkVGSe0FAcfDlnr16eoeg+N Thomas, Ingo, This is against tip/timers/urgent. Let me know if you'd like to see any further changes -john Unexpected behavior could occur if the time is set to a value large enough to overflow a 64bit ktime_t (which is something larger then the year 2264). So check timekeeping inputs to make sure we don't set the time to a value that overflows ktime_t. Note: This does not protect from setting the time close to overflowing ktime_t and then letting natural accumulation cause the overflow. Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Zhouping Liu Cc: CAI Qian Cc: stable@vger.kernel.org Reported-by: CAI Qian Signed-off-by: John Stultz --- kernel/time/timekeeping.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 2988bc8..6a31968 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -88,6 +88,8 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); /* flag for if timekeeping is suspended */ int __read_mostly timekeeping_suspended; +#define TWENTY_YEARS (20LL*365*24*60*60) + static inline void tk_normalize_xtime(struct timekeeper *tk) { while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) { @@ -430,6 +432,9 @@ int do_settimeofday(const struct timespec *tv) if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; + if ((unsigned long long)tv->tv_sec >= KTIME_SEC_MAX) + return -EINVAL; + write_seqlock_irqsave(&tk->lock, flags); timekeeping_forward_now(tk); @@ -463,6 +468,8 @@ int timekeeping_inject_offset(struct timespec *ts) { struct timekeeper *tk = &timekeeper; unsigned long flags; + long long tmp; + int ret = 0; if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) return -EINVAL; @@ -471,10 +478,17 @@ int timekeeping_inject_offset(struct timespec *ts) timekeeping_forward_now(tk); + /* Make sure the increased value won't cause ktime_t trouble */ + tmp = tk->xtime_sec + ts->tv_sec; + if (tmp >= KTIME_SEC_MAX) { + ret = -EINVAL; + goto error; + } tk_xtime_add(tk, ts); tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); +error: /* even if we error out, we forwarded the time, so call update */ timekeeping_update(tk, true); write_sequnlock_irqrestore(&tk->lock, flags); @@ -482,7 +496,7 @@ int timekeeping_inject_offset(struct timespec *ts) /* signal hrtimers about time change */ clock_was_set(); - return 0; + return ret; } EXPORT_SYMBOL(timekeeping_inject_offset); @@ -651,6 +665,16 @@ void __init timekeeping_init(void) read_persistent_clock(&now); read_boot_clock(&boot); + /* + * Check to make sure the persistent clock + * didn't return something crazy. + */ + if (now.tv_sec > (KTIME_SEC_MAX - TWENTY_YEARS)) { + pr_warn("WARNING: Persistent clock returned > year 2242!\n" + " Check your CMOS/BIOS settings.\n"); + now.tv_sec = KTIME_SEC_MAX - TWENTY_YEARS; + } + seqlock_init(&tk->lock); ntp_init();