aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/time.h4
-rw-r--r--kernel/time/time.c14
2 files changed, 12 insertions, 6 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 @@
10extern struct timezone sys_tz; 10extern struct timezone sys_tz;
11 11
12int get_timespec64(struct timespec64 *ts, 12int get_timespec64(struct timespec64 *ts,
13 const struct timespec __user *uts); 13 const struct __kernel_timespec __user *uts);
14int put_timespec64(const struct timespec64 *ts, 14int put_timespec64(const struct timespec64 *ts,
15 struct timespec __user *uts); 15 struct __kernel_timespec __user *uts);
16int get_itimerspec64(struct itimerspec64 *it, 16int get_itimerspec64(struct itimerspec64 *it,
17 const struct itimerspec __user *uit); 17 const struct itimerspec __user *uit);
18int put_itimerspec64(const struct itimerspec64 *it, 18int put_itimerspec64(const struct itimerspec64 *it,
diff --git a/kernel/time/time.c b/kernel/time/time.c
index df61143a54f6..ccd751e95fcb 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -853,9 +853,9 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
853} 853}
854 854
855int get_timespec64(struct timespec64 *ts, 855int get_timespec64(struct timespec64 *ts,
856 const struct timespec __user *uts) 856 const struct __kernel_timespec __user *uts)
857{ 857{
858 struct timespec kts; 858 struct __kernel_timespec kts;
859 int ret; 859 int ret;
860 860
861 ret = copy_from_user(&kts, uts, sizeof(kts)); 861 ret = copy_from_user(&kts, uts, sizeof(kts));
@@ -863,6 +863,11 @@ int get_timespec64(struct timespec64 *ts,
863 return -EFAULT; 863 return -EFAULT;
864 864
865 ts->tv_sec = kts.tv_sec; 865 ts->tv_sec = kts.tv_sec;
866
867 /* Zero out the padding for 32 bit systems or in compat mode */
868 if (IS_ENABLED(CONFIG_64BIT_TIME) && (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()))
869 kts.tv_nsec &= 0xFFFFFFFFUL;
870
866 ts->tv_nsec = kts.tv_nsec; 871 ts->tv_nsec = kts.tv_nsec;
867 872
868 return 0; 873 return 0;
@@ -870,12 +875,13 @@ int get_timespec64(struct timespec64 *ts,
870EXPORT_SYMBOL_GPL(get_timespec64); 875EXPORT_SYMBOL_GPL(get_timespec64);
871 876
872int put_timespec64(const struct timespec64 *ts, 877int put_timespec64(const struct timespec64 *ts,
873 struct timespec __user *uts) 878 struct __kernel_timespec __user *uts)
874{ 879{
875 struct timespec kts = { 880 struct __kernel_timespec kts = {
876 .tv_sec = ts->tv_sec, 881 .tv_sec = ts->tv_sec,
877 .tv_nsec = ts->tv_nsec 882 .tv_nsec = ts->tv_nsec
878 }; 883 };
884
879 return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0; 885 return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0;
880} 886}
881EXPORT_SYMBOL_GPL(put_timespec64); 887EXPORT_SYMBOL_GPL(put_timespec64);