aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 18:34:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 18:34:35 -0400
commitea3b25e1320df4e575c323b6ab22a5fc79976fbe (patch)
treeee824920b52a6458e383bc2b057cc5508e60fafe /kernel/time
parent89fbf5384ddf666a595eb6562dc63fcbfeb8f6a5 (diff)
parent725816e8aabb1c183baa2bc9572ab9a0d26b9ea1 (diff)
Merge branch 'timers-compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull timer-related user access updates from Al Viro: "Continuation of timers-related stuff (there had been more, but my parts of that series are already merged via timers/core). This is more of y2038 work by Deepa Dinamani, partially disrupted by the unification of native and compat timers-related syscalls" * 'timers-compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: posix_clocks: Use get_itimerspec64() and put_itimerspec64() timerfd: Use get_itimerspec64() and put_itimerspec64() nanosleep: Use get_timespec64() and put_timespec64() posix-timers: Use get_timespec64() and put_timespec64() posix-stubs: Conditionally include COMPAT_SYS_NI defines time: introduce {get,put}_itimerspec64 time: add get_timespec64 and put_timespec64
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/alarmtimer.c4
-rw-r--r--kernel/time/hrtimer.c30
-rw-r--r--kernel/time/posix-cpu-timers.c8
-rw-r--r--kernel/time/posix-stubs.c96
-rw-r--r--kernel/time/posix-timers.c127
-rw-r--r--kernel/time/time.c58
6 files changed, 176 insertions, 147 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index c991cf212c6d..0b8ff7d257ea 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -712,14 +712,14 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,
712 alarmtimer_freezerset(absexp, type); 712 alarmtimer_freezerset(absexp, type);
713 restart = &current->restart_block; 713 restart = &current->restart_block;
714 if (restart->nanosleep.type != TT_NONE) { 714 if (restart->nanosleep.type != TT_NONE) {
715 struct timespec rmt; 715 struct timespec64 rmt;
716 ktime_t rem; 716 ktime_t rem;
717 717
718 rem = ktime_sub(absexp, alarm_bases[type].gettime()); 718 rem = ktime_sub(absexp, alarm_bases[type].gettime());
719 719
720 if (rem <= 0) 720 if (rem <= 0)
721 return 0; 721 return 0;
722 rmt = ktime_to_timespec(rem); 722 rmt = ktime_to_timespec64(rem);
723 723
724 return nanosleep_copyout(restart, &rmt); 724 return nanosleep_copyout(restart, &rmt);
725 } 725 }
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 81da124f1115..88f75f92ef36 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1440,17 +1440,17 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
1440} 1440}
1441EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); 1441EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
1442 1442
1443int nanosleep_copyout(struct restart_block *restart, struct timespec *ts) 1443int nanosleep_copyout(struct restart_block *restart, struct timespec64 *ts)
1444{ 1444{
1445 switch(restart->nanosleep.type) { 1445 switch(restart->nanosleep.type) {
1446#ifdef CONFIG_COMPAT 1446#ifdef CONFIG_COMPAT
1447 case TT_COMPAT: 1447 case TT_COMPAT:
1448 if (compat_put_timespec(ts, restart->nanosleep.compat_rmtp)) 1448 if (compat_put_timespec64(ts, restart->nanosleep.compat_rmtp))
1449 return -EFAULT; 1449 return -EFAULT;
1450 break; 1450 break;
1451#endif 1451#endif
1452 case TT_NATIVE: 1452 case TT_NATIVE:
1453 if (copy_to_user(restart->nanosleep.rmtp, ts, sizeof(struct timespec))) 1453 if (put_timespec64(ts, restart->nanosleep.rmtp))
1454 return -EFAULT; 1454 return -EFAULT;
1455 break; 1455 break;
1456 default: 1456 default:
@@ -1485,11 +1485,11 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
1485 restart = &current->restart_block; 1485 restart = &current->restart_block;
1486 if (restart->nanosleep.type != TT_NONE) { 1486 if (restart->nanosleep.type != TT_NONE) {
1487 ktime_t rem = hrtimer_expires_remaining(&t->timer); 1487 ktime_t rem = hrtimer_expires_remaining(&t->timer);
1488 struct timespec rmt; 1488 struct timespec64 rmt;
1489 1489
1490 if (rem <= 0) 1490 if (rem <= 0)
1491 return 0; 1491 return 0;
1492 rmt = ktime_to_timespec(rem); 1492 rmt = ktime_to_timespec64(rem);
1493 1493
1494 return nanosleep_copyout(restart, &rmt); 1494 return nanosleep_copyout(restart, &rmt);
1495 } 1495 }
@@ -1546,19 +1546,17 @@ out:
1546SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, 1546SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
1547 struct timespec __user *, rmtp) 1547 struct timespec __user *, rmtp)
1548{ 1548{
1549 struct timespec64 tu64; 1549 struct timespec64 tu;
1550 struct timespec tu;
1551 1550
1552 if (copy_from_user(&tu, rqtp, sizeof(tu))) 1551 if (get_timespec64(&tu, rqtp))
1553 return -EFAULT; 1552 return -EFAULT;
1554 1553
1555 tu64 = timespec_to_timespec64(tu); 1554 if (!timespec64_valid(&tu))
1556 if (!timespec64_valid(&tu64))
1557 return -EINVAL; 1555 return -EINVAL;
1558 1556
1559 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 1557 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
1560 current->restart_block.nanosleep.rmtp = rmtp; 1558 current->restart_block.nanosleep.rmtp = rmtp;
1561 return hrtimer_nanosleep(&tu64, HRTIMER_MODE_REL, CLOCK_MONOTONIC); 1559 return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
1562} 1560}
1563 1561
1564#ifdef CONFIG_COMPAT 1562#ifdef CONFIG_COMPAT
@@ -1566,19 +1564,17 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
1566COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, 1564COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
1567 struct compat_timespec __user *, rmtp) 1565 struct compat_timespec __user *, rmtp)
1568{ 1566{
1569 struct timespec64 tu64; 1567 struct timespec64 tu;
1570 struct timespec tu;
1571 1568
1572 if (compat_get_timespec(&tu, rqtp)) 1569 if (compat_get_timespec64(&tu, rqtp))
1573 return -EFAULT; 1570 return -EFAULT;
1574 1571
1575 tu64 = timespec_to_timespec64(tu); 1572 if (!timespec64_valid(&tu))
1576 if (!timespec64_valid(&tu64))
1577 return -EINVAL; 1573 return -EINVAL;
1578 1574
1579 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 1575 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
1580 current->restart_block.nanosleep.compat_rmtp = rmtp; 1576 current->restart_block.nanosleep.compat_rmtp = rmtp;
1581 return hrtimer_nanosleep(&tu64, HRTIMER_MODE_REL, CLOCK_MONOTONIC); 1577 return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
1582} 1578}
1583#endif 1579#endif
1584 1580
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 60cb24ac9ebc..a3bd5dbe0dc4 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -1318,12 +1318,8 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
1318 */ 1318 */
1319 restart = &current->restart_block; 1319 restart = &current->restart_block;
1320 restart->nanosleep.expires = expires; 1320 restart->nanosleep.expires = expires;
1321 if (restart->nanosleep.type != TT_NONE) { 1321 if (restart->nanosleep.type != TT_NONE)
1322 struct timespec ts; 1322 error = nanosleep_copyout(restart, &it.it_value);
1323
1324 ts = timespec64_to_timespec(it.it_value);
1325 error = nanosleep_copyout(restart, &ts);
1326 }
1327 } 1323 }
1328 1324
1329 return error; 1325 return error;
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c
index 38f3b20efa29..06f34feb635e 100644
--- a/kernel/time/posix-stubs.c
+++ b/kernel/time/posix-stubs.c
@@ -41,12 +41,6 @@ SYS_NI(setitimer);
41#ifdef __ARCH_WANT_SYS_ALARM 41#ifdef __ARCH_WANT_SYS_ALARM
42SYS_NI(alarm); 42SYS_NI(alarm);
43#endif 43#endif
44COMPAT_SYS_NI(timer_create);
45COMPAT_SYS_NI(clock_adjtime);
46COMPAT_SYS_NI(timer_settime);
47COMPAT_SYS_NI(timer_gettime);
48COMPAT_SYS_NI(getitimer);
49COMPAT_SYS_NI(setitimer);
50 44
51/* 45/*
52 * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC 46 * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
@@ -57,40 +51,52 @@ COMPAT_SYS_NI(setitimer);
57SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 51SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
58 const struct timespec __user *, tp) 52 const struct timespec __user *, tp)
59{ 53{
60 struct timespec64 new_tp64; 54 struct timespec64 new_tp;
61 struct timespec new_tp;
62 55
63 if (which_clock != CLOCK_REALTIME) 56 if (which_clock != CLOCK_REALTIME)
64 return -EINVAL; 57 return -EINVAL;
65 if (copy_from_user(&new_tp, tp, sizeof (*tp))) 58 if (get_timespec64(&new_tp, tp))
66 return -EFAULT; 59 return -EFAULT;
67 60
68 new_tp64 = timespec_to_timespec64(new_tp); 61 return do_sys_settimeofday64(&new_tp, NULL);
69 return do_sys_settimeofday64(&new_tp64, NULL);
70} 62}
71 63
72SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 64int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
73 struct timespec __user *,tp)
74{ 65{
75 struct timespec64 kernel_tp64;
76 struct timespec kernel_tp;
77
78 switch (which_clock) { 66 switch (which_clock) {
79 case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break; 67 case CLOCK_REALTIME:
80 case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break; 68 ktime_get_real_ts64(tp);
81 case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break; 69 break;
82 default: return -EINVAL; 70 case CLOCK_MONOTONIC:
71 ktime_get_ts64(tp);
72 break;
73 case CLOCK_BOOTTIME:
74 get_monotonic_boottime64(tp);
75 break;
76 default:
77 return -EINVAL;
83 } 78 }
84 79
85 kernel_tp = timespec64_to_timespec(kernel_tp64); 80 return 0;
86 if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) 81}
82SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
83 struct timespec __user *, tp)
84{
85 int ret;
86 struct timespec64 kernel_tp;
87
88 ret = do_clock_gettime(which_clock, &kernel_tp);
89 if (ret)
90 return ret;
91
92 if (put_timespec64(&kernel_tp, tp))
87 return -EFAULT; 93 return -EFAULT;
88 return 0; 94 return 0;
89} 95}
90 96
91SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) 97SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
92{ 98{
93 struct timespec rtn_tp = { 99 struct timespec64 rtn_tp = {
94 .tv_sec = 0, 100 .tv_sec = 0,
95 .tv_nsec = hrtimer_resolution, 101 .tv_nsec = hrtimer_resolution,
96 }; 102 };
@@ -99,7 +105,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __us
99 case CLOCK_REALTIME: 105 case CLOCK_REALTIME:
100 case CLOCK_MONOTONIC: 106 case CLOCK_MONOTONIC:
101 case CLOCK_BOOTTIME: 107 case CLOCK_BOOTTIME:
102 if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp))) 108 if (put_timespec64(&rtn_tp, tp))
103 return -EFAULT; 109 return -EFAULT;
104 return 0; 110 return 0;
105 default: 111 default:
@@ -138,44 +144,45 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
138} 144}
139 145
140#ifdef CONFIG_COMPAT 146#ifdef CONFIG_COMPAT
147COMPAT_SYS_NI(timer_create);
148COMPAT_SYS_NI(clock_adjtime);
149COMPAT_SYS_NI(timer_settime);
150COMPAT_SYS_NI(timer_gettime);
151COMPAT_SYS_NI(getitimer);
152COMPAT_SYS_NI(setitimer);
153
141COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 154COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
142 struct compat_timespec __user *, tp) 155 struct compat_timespec __user *, tp)
143{ 156{
144 struct timespec64 new_tp64; 157 struct timespec64 new_tp;
145 struct timespec new_tp;
146 158
147 if (which_clock != CLOCK_REALTIME) 159 if (which_clock != CLOCK_REALTIME)
148 return -EINVAL; 160 return -EINVAL;
149 if (compat_get_timespec(&new_tp, tp)) 161 if (compat_get_timespec64(&new_tp, tp))
150 return -EFAULT; 162 return -EFAULT;
151 163
152 new_tp64 = timespec_to_timespec64(new_tp); 164 return do_sys_settimeofday64(&new_tp, NULL);
153 return do_sys_settimeofday64(&new_tp64, NULL);
154} 165}
155 166
156COMPAT_SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 167COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
157 struct compat_timespec __user *,tp) 168 struct compat_timespec __user *, tp)
158{ 169{
159 struct timespec64 kernel_tp64; 170 int ret;
160 struct timespec kernel_tp; 171 struct timespec64 kernel_tp;
161 172
162 switch (which_clock) { 173 ret = do_clock_gettime(which_clock, &kernel_tp);
163 case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break; 174 if (ret)
164 case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break; 175 return ret;
165 case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break;
166 default: return -EINVAL;
167 }
168 176
169 kernel_tp = timespec64_to_timespec(kernel_tp64); 177 if (compat_put_timespec64(&kernel_tp, tp))
170 if (compat_put_timespec(&kernel_tp, tp))
171 return -EFAULT; 178 return -EFAULT;
172 return 0; 179 return 0;
173} 180}
174 181
175COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, 182COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
176 struct compat_timespec __user *, tp) 183 struct compat_timespec __user *, tp)
177{ 184{
178 struct timespec rtn_tp = { 185 struct timespec64 rtn_tp = {
179 .tv_sec = 0, 186 .tv_sec = 0,
180 .tv_nsec = hrtimer_resolution, 187 .tv_nsec = hrtimer_resolution,
181 }; 188 };
@@ -184,13 +191,14 @@ COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
184 case CLOCK_REALTIME: 191 case CLOCK_REALTIME:
185 case CLOCK_MONOTONIC: 192 case CLOCK_MONOTONIC:
186 case CLOCK_BOOTTIME: 193 case CLOCK_BOOTTIME:
187 if (compat_put_timespec(&rtn_tp, tp)) 194 if (compat_put_timespec64(&rtn_tp, tp))
188 return -EFAULT; 195 return -EFAULT;
189 return 0; 196 return 0;
190 default: 197 default:
191 return -EINVAL; 198 return -EINVAL;
192 } 199 }
193} 200}
201
194COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, 202COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
195 struct compat_timespec __user *, rqtp, 203 struct compat_timespec __user *, rqtp,
196 struct compat_timespec __user *, rmtp) 204 struct compat_timespec __user *, rmtp)
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 82d67be7d9d1..13d6881f908b 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -739,13 +739,11 @@ static int do_timer_gettime(timer_t timer_id, struct itimerspec64 *setting)
739SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, 739SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
740 struct itimerspec __user *, setting) 740 struct itimerspec __user *, setting)
741{ 741{
742 struct itimerspec64 cur_setting64; 742 struct itimerspec64 cur_setting;
743 743
744 int ret = do_timer_gettime(timer_id, &cur_setting64); 744 int ret = do_timer_gettime(timer_id, &cur_setting);
745 if (!ret) { 745 if (!ret) {
746 struct itimerspec cur_setting; 746 if (put_itimerspec64(&cur_setting, setting))
747 cur_setting = itimerspec64_to_itimerspec(&cur_setting64);
748 if (copy_to_user(setting, &cur_setting, sizeof (cur_setting)))
749 ret = -EFAULT; 747 ret = -EFAULT;
750 } 748 }
751 return ret; 749 return ret;
@@ -755,13 +753,11 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
755COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, 753COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
756 struct compat_itimerspec __user *, setting) 754 struct compat_itimerspec __user *, setting)
757{ 755{
758 struct itimerspec64 cur_setting64; 756 struct itimerspec64 cur_setting;
759 757
760 int ret = do_timer_gettime(timer_id, &cur_setting64); 758 int ret = do_timer_gettime(timer_id, &cur_setting);
761 if (!ret) { 759 if (!ret) {
762 struct itimerspec cur_setting; 760 if (put_compat_itimerspec64(&cur_setting, setting))
763 cur_setting = itimerspec64_to_itimerspec(&cur_setting64);
764 if (put_compat_itimerspec(setting, &cur_setting))
765 ret = -EFAULT; 761 ret = -EFAULT;
766 } 762 }
767 return ret; 763 return ret;
@@ -907,23 +903,19 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
907 const struct itimerspec __user *, new_setting, 903 const struct itimerspec __user *, new_setting,
908 struct itimerspec __user *, old_setting) 904 struct itimerspec __user *, old_setting)
909{ 905{
910 struct itimerspec64 new_spec64, old_spec64; 906 struct itimerspec64 new_spec, old_spec;
911 struct itimerspec64 *rtn = old_setting ? &old_spec64 : NULL; 907 struct itimerspec64 *rtn = old_setting ? &old_spec : NULL;
912 struct itimerspec new_spec;
913 int error = 0; 908 int error = 0;
914 909
915 if (!new_setting) 910 if (!new_setting)
916 return -EINVAL; 911 return -EINVAL;
917 912
918 if (copy_from_user(&new_spec, new_setting, sizeof (new_spec))) 913 if (get_itimerspec64(&new_spec, new_setting))
919 return -EFAULT; 914 return -EFAULT;
920 new_spec64 = itimerspec_to_itimerspec64(&new_spec);
921 915
922 error = do_timer_settime(timer_id, flags, &new_spec64, rtn); 916 error = do_timer_settime(timer_id, flags, &new_spec, rtn);
923 if (!error && old_setting) { 917 if (!error && old_setting) {
924 struct itimerspec old_spec; 918 if (put_itimerspec64(&old_spec, old_setting))
925 old_spec = itimerspec64_to_itimerspec(&old_spec64);
926 if (copy_to_user(old_setting, &old_spec, sizeof (old_spec)))
927 error = -EFAULT; 919 error = -EFAULT;
928 } 920 }
929 return error; 921 return error;
@@ -934,22 +926,18 @@ COMPAT_SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
934 struct compat_itimerspec __user *, new, 926 struct compat_itimerspec __user *, new,
935 struct compat_itimerspec __user *, old) 927 struct compat_itimerspec __user *, old)
936{ 928{
937 struct itimerspec64 new_spec64, old_spec64; 929 struct itimerspec64 new_spec, old_spec;
938 struct itimerspec64 *rtn = old ? &old_spec64 : NULL; 930 struct itimerspec64 *rtn = old ? &old_spec : NULL;
939 struct itimerspec new_spec;
940 int error = 0; 931 int error = 0;
941 932
942 if (!new) 933 if (!new)
943 return -EINVAL; 934 return -EINVAL;
944 if (get_compat_itimerspec(&new_spec, new)) 935 if (get_compat_itimerspec64(&new_spec, new))
945 return -EFAULT; 936 return -EFAULT;
946 937
947 new_spec64 = itimerspec_to_itimerspec64(&new_spec); 938 error = do_timer_settime(timer_id, flags, &new_spec, rtn);
948 error = do_timer_settime(timer_id, flags, &new_spec64, rtn);
949 if (!error && old) { 939 if (!error && old) {
950 struct itimerspec old_spec; 940 if (put_compat_itimerspec64(&old_spec, old))
951 old_spec = itimerspec64_to_itimerspec(&old_spec64);
952 if (put_compat_itimerspec(old, &old_spec))
953 error = -EFAULT; 941 error = -EFAULT;
954 } 942 }
955 return error; 943 return error;
@@ -1049,34 +1037,30 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
1049 const struct timespec __user *, tp) 1037 const struct timespec __user *, tp)
1050{ 1038{
1051 const struct k_clock *kc = clockid_to_kclock(which_clock); 1039 const struct k_clock *kc = clockid_to_kclock(which_clock);
1052 struct timespec64 new_tp64; 1040 struct timespec64 new_tp;
1053 struct timespec new_tp;
1054 1041
1055 if (!kc || !kc->clock_set) 1042 if (!kc || !kc->clock_set)
1056 return -EINVAL; 1043 return -EINVAL;
1057 1044
1058 if (copy_from_user(&new_tp, tp, sizeof (*tp))) 1045 if (get_timespec64(&new_tp, tp))
1059 return -EFAULT; 1046 return -EFAULT;
1060 new_tp64 = timespec_to_timespec64(new_tp);
1061 1047
1062 return kc->clock_set(which_clock, &new_tp64); 1048 return kc->clock_set(which_clock, &new_tp);
1063} 1049}
1064 1050
1065SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 1051SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
1066 struct timespec __user *,tp) 1052 struct timespec __user *,tp)
1067{ 1053{
1068 const struct k_clock *kc = clockid_to_kclock(which_clock); 1054 const struct k_clock *kc = clockid_to_kclock(which_clock);
1069 struct timespec64 kernel_tp64; 1055 struct timespec64 kernel_tp;
1070 struct timespec kernel_tp;
1071 int error; 1056 int error;
1072 1057
1073 if (!kc) 1058 if (!kc)
1074 return -EINVAL; 1059 return -EINVAL;
1075 1060
1076 error = kc->clock_get(which_clock, &kernel_tp64); 1061 error = kc->clock_get(which_clock, &kernel_tp);
1077 kernel_tp = timespec64_to_timespec(kernel_tp64);
1078 1062
1079 if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) 1063 if (!error && put_timespec64(&kernel_tp, tp))
1080 error = -EFAULT; 1064 error = -EFAULT;
1081 1065
1082 return error; 1066 return error;
@@ -1109,17 +1093,15 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
1109 struct timespec __user *, tp) 1093 struct timespec __user *, tp)
1110{ 1094{
1111 const struct k_clock *kc = clockid_to_kclock(which_clock); 1095 const struct k_clock *kc = clockid_to_kclock(which_clock);
1112 struct timespec64 rtn_tp64; 1096 struct timespec64 rtn_tp;
1113 struct timespec rtn_tp;
1114 int error; 1097 int error;
1115 1098
1116 if (!kc) 1099 if (!kc)
1117 return -EINVAL; 1100 return -EINVAL;
1118 1101
1119 error = kc->clock_getres(which_clock, &rtn_tp64); 1102 error = kc->clock_getres(which_clock, &rtn_tp);
1120 rtn_tp = timespec64_to_timespec(rtn_tp64);
1121 1103
1122 if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) 1104 if (!error && tp && put_timespec64(&rtn_tp, tp))
1123 error = -EFAULT; 1105 error = -EFAULT;
1124 1106
1125 return error; 1107 return error;
@@ -1131,38 +1113,33 @@ COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
1131 struct compat_timespec __user *, tp) 1113 struct compat_timespec __user *, tp)
1132{ 1114{
1133 const struct k_clock *kc = clockid_to_kclock(which_clock); 1115 const struct k_clock *kc = clockid_to_kclock(which_clock);
1134 struct timespec64 new_tp64; 1116 struct timespec64 ts;
1135 struct timespec new_tp;
1136 1117
1137 if (!kc || !kc->clock_set) 1118 if (!kc || !kc->clock_set)
1138 return -EINVAL; 1119 return -EINVAL;
1139 1120
1140 if (compat_get_timespec(&new_tp, tp)) 1121 if (compat_get_timespec64(&ts, tp))
1141 return -EFAULT; 1122 return -EFAULT;
1142 1123
1143 new_tp64 = timespec_to_timespec64(new_tp); 1124 return kc->clock_set(which_clock, &ts);
1144
1145 return kc->clock_set(which_clock, &new_tp64);
1146} 1125}
1147 1126
1148COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, 1127COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
1149 struct compat_timespec __user *, tp) 1128 struct compat_timespec __user *, tp)
1150{ 1129{
1151 const struct k_clock *kc = clockid_to_kclock(which_clock); 1130 const struct k_clock *kc = clockid_to_kclock(which_clock);
1152 struct timespec64 kernel_tp64; 1131 struct timespec64 ts;
1153 struct timespec kernel_tp; 1132 int err;
1154 int error;
1155 1133
1156 if (!kc) 1134 if (!kc)
1157 return -EINVAL; 1135 return -EINVAL;
1158 1136
1159 error = kc->clock_get(which_clock, &kernel_tp64); 1137 err = kc->clock_get(which_clock, &ts);
1160 kernel_tp = timespec64_to_timespec(kernel_tp64);
1161 1138
1162 if (!error && compat_put_timespec(&kernel_tp, tp)) 1139 if (!err && compat_put_timespec64(&ts, tp))
1163 error = -EFAULT; 1140 err = -EFAULT;
1164 1141
1165 return error; 1142 return err;
1166} 1143}
1167 1144
1168COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock, 1145COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
@@ -1193,21 +1170,19 @@ COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
1193 struct compat_timespec __user *, tp) 1170 struct compat_timespec __user *, tp)
1194{ 1171{
1195 const struct k_clock *kc = clockid_to_kclock(which_clock); 1172 const struct k_clock *kc = clockid_to_kclock(which_clock);
1196 struct timespec64 rtn_tp64; 1173 struct timespec64 ts;
1197 struct timespec rtn_tp; 1174 int err;
1198 int error;
1199 1175
1200 if (!kc) 1176 if (!kc)
1201 return -EINVAL; 1177 return -EINVAL;
1202 1178
1203 error = kc->clock_getres(which_clock, &rtn_tp64); 1179 err = kc->clock_getres(which_clock, &ts);
1204 rtn_tp = timespec64_to_timespec(rtn_tp64); 1180 if (!err && tp && compat_put_timespec64(&ts, tp))
1205 1181 return -EFAULT;
1206 if (!error && tp && compat_put_timespec(&rtn_tp, tp))
1207 error = -EFAULT;
1208 1182
1209 return error; 1183 return err;
1210} 1184}
1185
1211#endif 1186#endif
1212 1187
1213/* 1188/*
@@ -1226,26 +1201,24 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
1226 struct timespec __user *, rmtp) 1201 struct timespec __user *, rmtp)
1227{ 1202{
1228 const struct k_clock *kc = clockid_to_kclock(which_clock); 1203 const struct k_clock *kc = clockid_to_kclock(which_clock);
1229 struct timespec64 t64; 1204 struct timespec64 t;
1230 struct timespec t;
1231 1205
1232 if (!kc) 1206 if (!kc)
1233 return -EINVAL; 1207 return -EINVAL;
1234 if (!kc->nsleep) 1208 if (!kc->nsleep)
1235 return -ENANOSLEEP_NOTSUP; 1209 return -ENANOSLEEP_NOTSUP;
1236 1210
1237 if (copy_from_user(&t, rqtp, sizeof (struct timespec))) 1211 if (get_timespec64(&t, rqtp))
1238 return -EFAULT; 1212 return -EFAULT;
1239 1213
1240 t64 = timespec_to_timespec64(t); 1214 if (!timespec64_valid(&t))
1241 if (!timespec64_valid(&t64))
1242 return -EINVAL; 1215 return -EINVAL;
1243 if (flags & TIMER_ABSTIME) 1216 if (flags & TIMER_ABSTIME)
1244 rmtp = NULL; 1217 rmtp = NULL;
1245 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 1218 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
1246 current->restart_block.nanosleep.rmtp = rmtp; 1219 current->restart_block.nanosleep.rmtp = rmtp;
1247 1220
1248 return kc->nsleep(which_clock, flags, &t64); 1221 return kc->nsleep(which_clock, flags, &t);
1249} 1222}
1250 1223
1251#ifdef CONFIG_COMPAT 1224#ifdef CONFIG_COMPAT
@@ -1254,26 +1227,24 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
1254 struct compat_timespec __user *, rmtp) 1227 struct compat_timespec __user *, rmtp)
1255{ 1228{
1256 const struct k_clock *kc = clockid_to_kclock(which_clock); 1229 const struct k_clock *kc = clockid_to_kclock(which_clock);
1257 struct timespec64 t64; 1230 struct timespec64 t;
1258 struct timespec t;
1259 1231
1260 if (!kc) 1232 if (!kc)
1261 return -EINVAL; 1233 return -EINVAL;
1262 if (!kc->nsleep) 1234 if (!kc->nsleep)
1263 return -ENANOSLEEP_NOTSUP; 1235 return -ENANOSLEEP_NOTSUP;
1264 1236
1265 if (compat_get_timespec(&t, rqtp)) 1237 if (compat_get_timespec64(&t, rqtp))
1266 return -EFAULT; 1238 return -EFAULT;
1267 1239
1268 t64 = timespec_to_timespec64(t); 1240 if (!timespec64_valid(&t))
1269 if (!timespec64_valid(&t64))
1270 return -EINVAL; 1241 return -EINVAL;
1271 if (flags & TIMER_ABSTIME) 1242 if (flags & TIMER_ABSTIME)
1272 rmtp = NULL; 1243 rmtp = NULL;
1273 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 1244 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
1274 current->restart_block.nanosleep.compat_rmtp = rmtp; 1245 current->restart_block.nanosleep.compat_rmtp = rmtp;
1275 1246
1276 return kc->nsleep(which_clock, flags, &t64); 1247 return kc->nsleep(which_clock, flags, &t);
1277} 1248}
1278#endif 1249#endif
1279 1250
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 7c89e437c4d7..44a8c1402133 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -890,3 +890,61 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
890 890
891 return res; 891 return res;
892} 892}
893
894int get_timespec64(struct timespec64 *ts,
895 const struct timespec __user *uts)
896{
897 struct timespec kts;
898 int ret;
899
900 ret = copy_from_user(&kts, uts, sizeof(kts));
901 if (ret)
902 return -EFAULT;
903
904 ts->tv_sec = kts.tv_sec;
905 ts->tv_nsec = kts.tv_nsec;
906
907 return 0;
908}
909EXPORT_SYMBOL_GPL(get_timespec64);
910
911int put_timespec64(const struct timespec64 *ts,
912 struct timespec __user *uts)
913{
914 struct timespec kts = {
915 .tv_sec = ts->tv_sec,
916 .tv_nsec = ts->tv_nsec
917 };
918 return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0;
919}
920EXPORT_SYMBOL_GPL(put_timespec64);
921
922int get_itimerspec64(struct itimerspec64 *it,
923 const struct itimerspec __user *uit)
924{
925 int ret;
926
927 ret = get_timespec64(&it->it_interval, &uit->it_interval);
928 if (ret)
929 return ret;
930
931 ret = get_timespec64(&it->it_value, &uit->it_value);
932
933 return ret;
934}
935EXPORT_SYMBOL_GPL(get_itimerspec64);
936
937int put_itimerspec64(const struct itimerspec64 *it,
938 struct itimerspec __user *uit)
939{
940 int ret;
941
942 ret = put_timespec64(&it->it_interval, &uit->it_interval);
943 if (ret)
944 return ret;
945
946 ret = put_timespec64(&it->it_value, &uit->it_value);
947
948 return ret;
949}
950EXPORT_SYMBOL_GPL(put_itimerspec64);