From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753680AbdK0TdT (ORCPT ); Mon, 27 Nov 2017 14:33:19 -0500 Received: from mail-qt0-f194.google.com ([209.85.216.194]:34689 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753647AbdK0TcE (ORCPT ); Mon, 27 Nov 2017 14:32:04 -0500 X-Google-Smtp-Source: AGs4zMYy3t4wDoNF/gTPbb0ve1x9sUfLyuhEYGNt1y2xkzkXY5GQ+zlpLf5N5z0GIXGu8EfbB5+ghg== From: Deepa Dinamani To: tglx@linutronix.de, john.stultz@linaro.org Cc: linux-kernel@vger.kernel.org, arnd@arndb.de, y2038@lists.linaro.org Subject: [PATCH v2 08/10] fix get_timespec64() for y2038 safe compat interfaces Date: Mon, 27 Nov 2017 11:30:35 -0800 Message-Id: <20171127193037.8711-9-deepa.kernel@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171127193037.8711-1-deepa.kernel@gmail.com> References: <20171127193037.8711-1-deepa.kernel@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org get/put_timespec64() interfaces will eventually be used for conversions between the new y2038 safe struct __kernel_timespec and struct timespec64. The new y2038 safe syscalls have a common entry for native and compat interfaces. On compat interfaces, the high order bits of nanoseconds should be zeroed out. This is because the application code or the libc do not garuntee zeroing of these. If used without zeroing, kernel might be at risk of using timespec values incorrectly. Signed-off-by: Deepa Dinamani --- include/linux/time.h | 4 ++-- kernel/time/time.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/linux/time.h b/include/linux/time.h index 4b62a2c0a661..aed74463592d 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -10,9 +10,9 @@ extern struct timezone sys_tz; int get_timespec64(struct timespec64 *ts, - const struct timespec __user *uts); + const struct __kernel_timespec __user *uts); int put_timespec64(const struct timespec64 *ts, - struct timespec __user *uts); + struct __kernel_timespec __user *uts); int get_itimerspec64(struct itimerspec64 *it, const struct itimerspec __user *uit); int put_itimerspec64(const struct itimerspec64 *it, diff --git a/kernel/time/time.c b/kernel/time/time.c index bd4e6c7dd689..9de69f3e4f44 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -841,7 +841,7 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs, } int get_timespec64(struct timespec64 *ts, - const struct timespec __user *uts) + const struct __kernel_timespec __user *uts) { struct timespec kts; int ret; @@ -851,6 +851,11 @@ int get_timespec64(struct timespec64 *ts, return -EFAULT; ts->tv_sec = kts.tv_sec; + + /* Zero out the padding for 32 bit systems or in compat mode */ + if (IS_ENABLED(CONFIG_64BIT_TIME) || !IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()) + kts.tv_nsec &= 0xFFFFFFFFUL; + ts->tv_nsec = kts.tv_nsec; return 0; @@ -858,12 +863,13 @@ int get_timespec64(struct timespec64 *ts, EXPORT_SYMBOL_GPL(get_timespec64); int put_timespec64(const struct timespec64 *ts, - struct timespec __user *uts) + struct __kernel_timespec __user *uts) { struct timespec kts = { .tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec }; + return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0; } EXPORT_SYMBOL_GPL(put_timespec64); -- 2.14.1