From patchwork Tue Aug 23 23:08:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 74532 Delivered-To: patches@linaro.org Received: by 10.140.29.52 with SMTP id a49csp18574qga; Tue, 23 Aug 2016 16:08:32 -0700 (PDT) X-Received: by 10.66.219.105 with SMTP id pn9mr57365710pac.25.1471993710459; Tue, 23 Aug 2016 16:08:30 -0700 (PDT) Return-Path: Received: from mail-pf0-x233.google.com (mail-pf0-x233.google.com. [2607:f8b0:400e:c00::233]) by mx.google.com with ESMTPS id 9si6016615pfr.240.2016.08.23.16.08.30 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 23 Aug 2016 16:08:30 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c00::233 as permitted sender) client-ip=2607:f8b0:400e:c00::233; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c00::233 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by mail-pf0-x233.google.com with SMTP id x72so48015068pfd.2 for ; Tue, 23 Aug 2016 16:08:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QVnH2KT1YQ4G0XyqTiMkdEXXSzAcPj2GJ+gVA/GoiTA=; b=FcH1p7pL4IUjteCtd7y02nn/ZB3bqaT4tchFdvxlYqYRkoOIRc+wRClI+L/x2+vE8d uHw5gRKnnGIGKtgoo5gJNkzTCiCgpTAwREpU0Z+z7yzbpgzK+Z9uwD1TOAH07uxvgOwQ swU6n6Jik5FDnEn0lJ1ueJaGmp4lO1XjieuzA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QVnH2KT1YQ4G0XyqTiMkdEXXSzAcPj2GJ+gVA/GoiTA=; b=KxYCIW1ltKTZ7BTM71NqdNNETt0P5GGM4iCBq1fwazPBWaCU1fsI1RbHl17+AAdJ8g X529rczrIttRI1H8qTNeFM3pI1frtVc716MHuDXWYQ8fgCPPe1RH+iNWGDsoNUStxcTG M7LZVKbwywL0qYVYpRTLX2h/Ozco6VA3UeoYWhkLvxMSYF98mW0JPTjSSsmcJ1GRlYli t2LBQdBVHL7HgxqH7U6yer5u7uWruTatgcOFqKua9Cj81vTHUoLLyUmiMTK07kokvPOX 6RD/oMzNgSsy3/VzplQY48w+QjLyR35IdvuMoTNryWL9WVbk4f+jRZAP/eK+O0WIBXWJ hFZQ== X-Gm-Message-State: AEkoouvntUE5IVqmZpoUlot1sc4emauQ94+QfI0OuR/wdV1yP0+NZC6DHrNIHQEYHTu7V7Oou8s= X-Received: by 10.98.74.91 with SMTP id x88mr57917460pfa.79.1471993710111; Tue, 23 Aug 2016 16:08:30 -0700 (PDT) Return-Path: Received: from localhost.localdomain (c-73-67-244-238.hsd1.or.comcast.net. [73.67.244.238]) by smtp.gmail.com with ESMTPSA id i137sm8200194pfe.64.2016.08.23.16.08.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 23 Aug 2016 16:08:29 -0700 (PDT) From: John Stultz To: lkml Cc: John Stultz , Thomas Gleixner , Peter Zijlstra , Ingo Molnar , "Rafael J. Wysocki" , Janek Kozicki , Chen Yu , Xunlei Pang , Zhang Rui , linux-pm@vger.kernel.org, stable Subject: [PATCH 2/2] timekeeping: Cap array access in timekeeping_debug to protect against invalid sleep times Date: Tue, 23 Aug 2016 16:08:22 -0700 Message-Id: <1471993702-29148-3-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1471993702-29148-1-git-send-email-john.stultz@linaro.org> References: <1471993702-29148-1-git-send-email-john.stultz@linaro.org> It was reported that hibernation could fail on the 2nd attempt, where the system hangs at hibernate() -> syscore_resume() -> i8237A_resume() -> claim_dma_lock(), because the lock has already been taken. However there is actually no other process would like to grab this lock on that problematic platform. Further investigation showed that the problem is triggered by setting /sys/power/pm_trace to 1 before the 1st hibernation. Since once pm_trace is enabled, the rtc becomes unmeaningful after suspend, and meanwhile some BIOSes would like to adjust the 'invalid' tsc(e.g, smaller than 1970) to the release date of that motherboard during POST stage, thus after resumed, it may seem that the system had a significant long sleep time might due to meaningless tsc or RTC delta. Then in timekeeping_resume -> tk_debug_account_sleep_time, if the bit31 of the sleep time happened to be set to 1, the fls returns 32 and then we add 1 to sleep_time_bin[32], which caused a memory overwritten. As depicted by System.map: 0xffffffff81c9d080 b sleep_time_bin 0xffffffff81c9d100 B dma_spin_lock the dma_spin_lock.val is set to 1, which caused this problem. This patch adds a sanity check in tk_debug_account_sleep_time() to ensure we don't index past the sleep_time_bin array. Cc: Thomas Gleixner Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Rafael J. Wysocki Cc: Janek Kozicki Cc: Chen Yu Cc: Xunlei Pang Cc: Zhang Rui Cc: linux-pm@vger.kernel.org Cc: stable Reported-by: Janek Kozicki Reported-by: Chen Yu [jstultz: Problem diagnosed and original patch by Chen Yu, I've solved the issue slightly differently, but borrowed his excelent explanation of of the issue here.] Signed-off-by: John Stultz --- kernel/time/timekeeping_debug.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) -- 1.9.1 diff --git a/kernel/time/timekeeping_debug.c b/kernel/time/timekeeping_debug.c index f6bd652..107310a6 100644 --- a/kernel/time/timekeeping_debug.c +++ b/kernel/time/timekeeping_debug.c @@ -23,7 +23,9 @@ #include "timekeeping_internal.h" -static unsigned int sleep_time_bin[32] = {0}; +#define NUM_BINS 32 + +static unsigned int sleep_time_bin[NUM_BINS] = {0}; static int tk_debug_show_sleep_time(struct seq_file *s, void *data) { @@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init); void tk_debug_account_sleep_time(struct timespec64 *t) { - sleep_time_bin[fls(t->tv_sec)]++; + /* Cap bin index so we don't overflow the array */ + int bin = min(fls(t->tv_sec), NUM_BINS-1); + + sleep_time_bin[bin]++; }