Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp3967238img; Mon, 25 Mar 2019 23:44:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqwi+CCC8o9VZQKe/kgG6NlwT2TiN4zvnE9mupiUz63dHj7ijlJn5QHli4ecnHsptogD58Ce X-Received: by 2002:aa7:8c84:: with SMTP id p4mr14702120pfd.164.1553582658587; Mon, 25 Mar 2019 23:44:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553582658; cv=none; d=google.com; s=arc-20160816; b=BHSqZyLMfSal5zIzSbV7GgtSUj6t6j/dNW/cQBB4yNaYnuNumoD/OrgbZeJukLk1Pc S6dlYWZ4gdr2YX6NUBMco24z+68J7Wx5xMC9SPzZSidq+hgSlyJAE8YsdkCdwevCpjM7 OEZSOoYIhz4ze4T3KjunNPiXmp8c1GYWxT2Q0h7YJuNRmVKp6A4zE+cABBbnt5VjcKR6 1a/oMpY4vdePshdTvPob6XwiBNsXItxVZHZBNSvKZw1Nmv1ci21rxRQ9zorm1fWzfiW5 VIOtJN6Ww9a0n3/c2lZpawzR2whiwlD57eTe9Q8F8sknQ1s4rtpwxwR/79yjLzw2opZn AACA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=vWyTylY+X5LmCftJky8Hqx0Xu6pTHR3EcE4Ic/K3aVg=; b=Jw+/AEzzkleVm1oR5O/cY1K9LpUrZ1IW8iuMSZprhIE7u+NlOlzFP5ozbBUeplCUR1 Y+IyckIU9i3KGoR7uWwhh+2AJ0fLqPHahGf5UHIzrBfW29j0vLQn+uXvhdtocHTUA1bu bPpuFNTPfGyiXckhSqLNouWK6GxBraJVqCQ5mhi5aF7hE2Q5U/pLSDrVSoUBJvOsGxcE MLgOKnzF5sYbNHCfwPSa8o0zSS8f1dP15zWjcvHizVHYkzI8C/SnkWnCjokUYn2CWlb/ uN1jGreF3Kow43nsIFF+Y9jSuUWwBLhPzj2Z9TRl/xvvk/xTJZfacs5F6BGmsKpZZcUv pl+Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=MBLyoltl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z72si5764407pgd.401.2019.03.25.23.44.03; Mon, 25 Mar 2019 23:44:18 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=MBLyoltl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732371AbfCZGh0 (ORCPT + 99 others); Tue, 26 Mar 2019 02:37:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:50754 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731399AbfCZGhY (ORCPT ); Tue, 26 Mar 2019 02:37:24 -0400 Received: from localhost (unknown [104.132.152.111]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A2AF82075E; Tue, 26 Mar 2019 06:37:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1553582243; bh=gFQWJ8MiRxLeuyhFa58VBC9DZ8Mx65qGonWrWzzjtZs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MBLyoltlhHg/r+gmbsJTiljcAyfTHeECzyXpKyWmRT5G8vOiST1Iav+81jfol+zD+ AJ6GTZmaErRQ+eW5WHIgk5ar0pDsTnF4S/0OAjpg7Gh4SsIvQKHpN8YiLpD4xNTIgf QEke+OUQt1EXQ7zF3vgf/wk7b3XTymcQ5m/THUDI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jakub Drnec , Michael Ellerman Subject: [PATCH 4.19 14/45] powerpc/vdso64: Fix CLOCK_MONOTONIC inconsistencies across Y2038 Date: Tue, 26 Mar 2019 15:29:57 +0900 Message-Id: <20190326042703.417534104@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190326042702.565683325@linuxfoundation.org> References: <20190326042702.565683325@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Michael Ellerman commit b5b4453e7912f056da1ca7572574cada32ecb60c upstream. Jakub Drnec reported: Setting the realtime clock can sometimes make the monotonic clock go back by over a hundred years. Decreasing the realtime clock across the y2k38 threshold is one reliable way to reproduce. Allegedly this can also happen just by running ntpd, I have not managed to reproduce that other than booting with rtc at >2038 and then running ntp. When this happens, anything with timers (e.g. openjdk) breaks rather badly. And included a test case (slightly edited for brevity): #define _POSIX_C_SOURCE 199309L #include #include #include #include long get_time(void) { struct timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); return tp.tv_sec + tp.tv_nsec / 1000000000; } int main(void) { long last = get_time(); while(1) { long now = get_time(); if (now < last) { printf("clock went backwards by %ld seconds!\n", last - now); } last = now; sleep(1); } return 0; } Which when run concurrently with: # date -s 2040-1-1 # date -s 2037-1-1 Will detect the clock going backward. The root cause is that wtom_clock_sec in struct vdso_data is only a 32-bit signed value, even though we set its value to be equal to tk->wall_to_monotonic.tv_sec which is 64-bits. Because the monotonic clock starts at zero when the system boots the wall_to_montonic.tv_sec offset is negative for current and future dates. Currently on a freshly booted system the offset will be in the vicinity of negative 1.5 billion seconds. However if the wall clock is set past the Y2038 boundary, the offset from wall to monotonic becomes less than negative 2^31, and no longer fits in 32-bits. When that value is assigned to wtom_clock_sec it is truncated and becomes positive, causing the VDSO assembly code to calculate CLOCK_MONOTONIC incorrectly. That causes CLOCK_MONOTONIC to jump ahead by ~4 billion seconds which it is not meant to do. Worse, if the time is then set back before the Y2038 boundary CLOCK_MONOTONIC will jump backward. We can fix it simply by storing the full 64-bit offset in the vdso_data, and using that in the VDSO assembly code. We also shuffle some of the fields in vdso_data to avoid creating a hole. The original commit that added the CLOCK_MONOTONIC support to the VDSO did actually use a 64-bit value for wtom_clock_sec, see commit a7f290dad32e ("[PATCH] powerpc: Merge vdso's and add vdso support to 32 bits kernel") (Nov 2005). However just 3 days later it was converted to 32-bits in commit 0c37ec2aa88b ("[PATCH] powerpc: vdso fixes (take #2)"), and the bug has existed since then AFAICS. Fixes: 0c37ec2aa88b ("[PATCH] powerpc: vdso fixes (take #2)") Cc: stable@vger.kernel.org # v2.6.15+ Link: http://lkml.kernel.org/r/HaC.ZfES.62bwlnvAvMP.1STMMj@seznam.cz Reported-by: Jakub Drnec Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/include/asm/vdso_datapage.h | 8 ++++---- arch/powerpc/kernel/vdso64/gettimeofday.S | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -82,10 +82,10 @@ struct vdso_data { __u32 icache_block_size; /* L1 i-cache block size */ __u32 dcache_log_block_size; /* L1 d-cache log block size */ __u32 icache_log_block_size; /* L1 i-cache log block size */ - __s32 wtom_clock_sec; /* Wall to monotonic clock */ - __s32 wtom_clock_nsec; - struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ - __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ + __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ + __s32 wtom_clock_nsec; /* Wall to monotonic clock nsec */ + __s64 wtom_clock_sec; /* Wall to monotonic clock sec */ + struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ }; --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -92,7 +92,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) * At this point, r4,r5 contain our sec/nsec values. */ - lwa r6,WTOM_CLOCK_SEC(r3) + ld r6,WTOM_CLOCK_SEC(r3) lwa r9,WTOM_CLOCK_NSEC(r3) /* We now have our result in r6,r9. We create a fake dependency @@ -125,7 +125,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) bne cr6,75f /* CLOCK_MONOTONIC_COARSE */ - lwa r6,WTOM_CLOCK_SEC(r3) + ld r6,WTOM_CLOCK_SEC(r3) lwa r9,WTOM_CLOCK_NSEC(r3) /* check if counter has updated */