• John Stultz's avatar
    timekeeping: Cap array access in timekeeping_debug · a4f8f666
    John Stultz authored
    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' RTC (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
    which is a completely meaningless value.
    
    Then in timekeeping_resume -> tk_debug_account_sleep_time, if the bit31 of the
    sleep time happened to be set to 1, fls() returns 32 and we add 1 to
    sleep_time_bin[32], which causes an out of bounds array access and therefor
    memory being 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.
    
    [jstultz: Problem diagnosed and original patch by Chen Yu, I've solved the
     issue slightly differently, but borrowed his excelent explanation of the
     issue here.]
    
    Fixes: 5c83545f "power: Add option to log time spent in suspend"
    Reported-by: default avatarJanek Kozicki <cosurgi@gmail.com>
    Reported-by: default avatarChen Yu <yu.c.chen@intel.com>
    Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
    Cc: linux-pm@vger.kernel.org
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Xunlei Pang <xpang@redhat.com>
    Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
    Cc: stable <stable@vger.kernel.org>
    Cc: Zhang Rui <rui.zhang@intel.com>
    Link: http://lkml.kernel.org/r/1471993702-29148-3-git-send-email-john.stultz@linaro.orgSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    a4f8f666
timekeeping_debug.c 2 KB