aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2019-01-02 07:28:47 -0500
committerArnd Bergmann <arnd@arndb.de>2019-02-06 18:13:27 -0500
commit4d5f007eedb74d71a7bde2bff69b6a31ad8ab427 (patch)
tree9704984d9137621c8bdbba2e1c86018e5d3c755f
parent805089c2f77047d81f47ddc227435d606ceb180e (diff)
time: make adjtime compat handling available for 32 bit
We want to reuse the compat_timex handling on 32-bit architectures the same way we are using the compat handling for timespec when moving to 64-bit time_t. Move all definitions related to compat_timex out of the compat code into the normal timekeeping code, along with a rename to old_timex32, corresponding to the timespec/timeval structures, and make it controlled by CONFIG_COMPAT_32BIT_TIME, which 32-bit architectures will then select. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--include/linux/compat.h35
-rw-r--r--include/linux/time32.h32
-rw-r--r--kernel/compat.c64
-rw-r--r--kernel/time/posix-timers.c14
-rw-r--r--kernel/time/time.c70
5 files changed, 102 insertions, 113 deletions
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 056be0d03722..657ca6abd855 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -132,37 +132,6 @@ struct compat_tms {
132 compat_clock_t tms_cstime; 132 compat_clock_t tms_cstime;
133}; 133};
134 134
135struct compat_timex {
136 compat_uint_t modes;
137 compat_long_t offset;
138 compat_long_t freq;
139 compat_long_t maxerror;
140 compat_long_t esterror;
141 compat_int_t status;
142 compat_long_t constant;
143 compat_long_t precision;
144 compat_long_t tolerance;
145 struct old_timeval32 time;
146 compat_long_t tick;
147 compat_long_t ppsfreq;
148 compat_long_t jitter;
149 compat_int_t shift;
150 compat_long_t stabil;
151 compat_long_t jitcnt;
152 compat_long_t calcnt;
153 compat_long_t errcnt;
154 compat_long_t stbcnt;
155 compat_int_t tai;
156
157 compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
158 compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
159 compat_int_t:32; compat_int_t:32; compat_int_t:32;
160};
161
162struct timex;
163int compat_get_timex(struct timex *, const struct compat_timex __user *);
164int compat_put_timex(struct compat_timex __user *, const struct timex *);
165
166#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) 135#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW)
167 136
168typedef struct { 137typedef struct {
@@ -808,7 +777,7 @@ asmlinkage long compat_sys_gettimeofday(struct old_timeval32 __user *tv,
808 struct timezone __user *tz); 777 struct timezone __user *tz);
809asmlinkage long compat_sys_settimeofday(struct old_timeval32 __user *tv, 778asmlinkage long compat_sys_settimeofday(struct old_timeval32 __user *tv,
810 struct timezone __user *tz); 779 struct timezone __user *tz);
811asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); 780asmlinkage long compat_sys_adjtimex(struct old_timex32 __user *utp);
812 781
813/* kernel/timer.c */ 782/* kernel/timer.c */
814asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); 783asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
@@ -911,7 +880,7 @@ asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
911 struct file_handle __user *handle, 880 struct file_handle __user *handle,
912 int flags); 881 int flags);
913asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock, 882asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock,
914 struct compat_timex __user *tp); 883 struct old_timex32 __user *tp);
915asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, 884asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
916 unsigned vlen, unsigned int flags); 885 unsigned vlen, unsigned int flags);
917asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid, 886asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid,
diff --git a/include/linux/time32.h b/include/linux/time32.h
index 118b9977080c..820a22e2b98b 100644
--- a/include/linux/time32.h
+++ b/include/linux/time32.h
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/time64.h> 12#include <linux/time64.h>
13#include <linux/timex.h>
13 14
14#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) 15#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
15 16
@@ -35,13 +36,42 @@ struct old_utimbuf32 {
35 old_time32_t modtime; 36 old_time32_t modtime;
36}; 37};
37 38
39struct old_timex32 {
40 u32 modes;
41 s32 offset;
42 s32 freq;
43 s32 maxerror;
44 s32 esterror;
45 s32 status;
46 s32 constant;
47 s32 precision;
48 s32 tolerance;
49 struct old_timeval32 time;
50 s32 tick;
51 s32 ppsfreq;
52 s32 jitter;
53 s32 shift;
54 s32 stabil;
55 s32 jitcnt;
56 s32 calcnt;
57 s32 errcnt;
58 s32 stbcnt;
59 s32 tai;
60
61 s32:32; s32:32; s32:32; s32:32;
62 s32:32; s32:32; s32:32; s32:32;
63 s32:32; s32:32; s32:32;
64};
65
38extern int get_old_timespec32(struct timespec64 *, const void __user *); 66extern int get_old_timespec32(struct timespec64 *, const void __user *);
39extern int put_old_timespec32(const struct timespec64 *, void __user *); 67extern int put_old_timespec32(const struct timespec64 *, void __user *);
40extern int get_old_itimerspec32(struct itimerspec64 *its, 68extern int get_old_itimerspec32(struct itimerspec64 *its,
41 const struct old_itimerspec32 __user *uits); 69 const struct old_itimerspec32 __user *uits);
42extern int put_old_itimerspec32(const struct itimerspec64 *its, 70extern int put_old_itimerspec32(const struct itimerspec64 *its,
43 struct old_itimerspec32 __user *uits); 71 struct old_itimerspec32 __user *uits);
44 72struct timex;
73int get_old_timex32(struct timex *, const struct old_timex32 __user *);
74int put_old_timex32(struct old_timex32 __user *, const struct timex *);
45 75
46#if __BITS_PER_LONG == 64 76#if __BITS_PER_LONG == 64
47 77
diff --git a/kernel/compat.c b/kernel/compat.c
index f01affa17e22..d8a36c6ad7c9 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -20,7 +20,6 @@
20#include <linux/syscalls.h> 20#include <linux/syscalls.h>
21#include <linux/unistd.h> 21#include <linux/unistd.h>
22#include <linux/security.h> 22#include <linux/security.h>
23#include <linux/timex.h>
24#include <linux/export.h> 23#include <linux/export.h>
25#include <linux/migrate.h> 24#include <linux/migrate.h>
26#include <linux/posix-timers.h> 25#include <linux/posix-timers.h>
@@ -30,69 +29,6 @@
30 29
31#include <linux/uaccess.h> 30#include <linux/uaccess.h>
32 31
33int compat_get_timex(struct timex *txc, const struct compat_timex __user *utp)
34{
35 struct compat_timex tx32;
36
37 memset(txc, 0, sizeof(struct timex));
38 if (copy_from_user(&tx32, utp, sizeof(struct compat_timex)))
39 return -EFAULT;
40
41 txc->modes = tx32.modes;
42 txc->offset = tx32.offset;
43 txc->freq = tx32.freq;
44 txc->maxerror = tx32.maxerror;
45 txc->esterror = tx32.esterror;
46 txc->status = tx32.status;
47 txc->constant = tx32.constant;
48 txc->precision = tx32.precision;
49 txc->tolerance = tx32.tolerance;
50 txc->time.tv_sec = tx32.time.tv_sec;
51 txc->time.tv_usec = tx32.time.tv_usec;
52 txc->tick = tx32.tick;
53 txc->ppsfreq = tx32.ppsfreq;
54 txc->jitter = tx32.jitter;
55 txc->shift = tx32.shift;
56 txc->stabil = tx32.stabil;
57 txc->jitcnt = tx32.jitcnt;
58 txc->calcnt = tx32.calcnt;
59 txc->errcnt = tx32.errcnt;
60 txc->stbcnt = tx32.stbcnt;
61
62 return 0;
63}
64
65int compat_put_timex(struct compat_timex __user *utp, const struct timex *txc)
66{
67 struct compat_timex tx32;
68
69 memset(&tx32, 0, sizeof(struct compat_timex));
70 tx32.modes = txc->modes;
71 tx32.offset = txc->offset;
72 tx32.freq = txc->freq;
73 tx32.maxerror = txc->maxerror;
74 tx32.esterror = txc->esterror;
75 tx32.status = txc->status;
76 tx32.constant = txc->constant;
77 tx32.precision = txc->precision;
78 tx32.tolerance = txc->tolerance;
79 tx32.time.tv_sec = txc->time.tv_sec;
80 tx32.time.tv_usec = txc->time.tv_usec;
81 tx32.tick = txc->tick;
82 tx32.ppsfreq = txc->ppsfreq;
83 tx32.jitter = txc->jitter;
84 tx32.shift = txc->shift;
85 tx32.stabil = txc->stabil;
86 tx32.jitcnt = txc->jitcnt;
87 tx32.calcnt = txc->calcnt;
88 tx32.errcnt = txc->errcnt;
89 tx32.stbcnt = txc->stbcnt;
90 tx32.tai = txc->tai;
91 if (copy_to_user(utp, &tx32, sizeof(struct compat_timex)))
92 return -EFAULT;
93 return 0;
94}
95
96static int __compat_get_timeval(struct timeval *tv, const struct old_timeval32 __user *ctv) 32static int __compat_get_timeval(struct timeval *tv, const struct old_timeval32 __user *ctv)
97{ 33{
98 return (!access_ok(ctv, sizeof(*ctv)) || 34 return (!access_ok(ctv, sizeof(*ctv)) ||
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 0e84bb72a3da..8955f32f2a36 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -1123,12 +1123,8 @@ COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
1123 return err; 1123 return err;
1124} 1124}
1125 1125
1126#endif
1127
1128#ifdef CONFIG_COMPAT
1129
1130COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock, 1126COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
1131 struct compat_timex __user *, utp) 1127 struct old_timex32 __user *, utp)
1132{ 1128{
1133 const struct k_clock *kc = clockid_to_kclock(which_clock); 1129 const struct k_clock *kc = clockid_to_kclock(which_clock);
1134 struct timex ktx; 1130 struct timex ktx;
@@ -1139,22 +1135,18 @@ COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
1139 if (!kc->clock_adj) 1135 if (!kc->clock_adj)
1140 return -EOPNOTSUPP; 1136 return -EOPNOTSUPP;
1141 1137
1142 err = compat_get_timex(&ktx, utp); 1138 err = get_old_timex32(&ktx, utp);
1143 if (err) 1139 if (err)
1144 return err; 1140 return err;
1145 1141
1146 err = kc->clock_adj(which_clock, &ktx); 1142 err = kc->clock_adj(which_clock, &ktx);
1147 1143
1148 if (err >= 0) 1144 if (err >= 0)
1149 err = compat_put_timex(utp, &ktx); 1145 err = put_old_timex32(utp, &ktx);
1150 1146
1151 return err; 1147 return err;
1152} 1148}
1153 1149
1154#endif
1155
1156#ifdef CONFIG_COMPAT_32BIT_TIME
1157
1158COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock, 1150COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
1159 struct old_timespec32 __user *, tp) 1151 struct old_timespec32 __user *, tp)
1160{ 1152{
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 2edb5088a70b..2d013bc2b271 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -278,20 +278,82 @@ SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p)
278 return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret; 278 return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
279} 279}
280 280
281#ifdef CONFIG_COMPAT 281#ifdef CONFIG_COMPAT_32BIT_TIME
282int get_old_timex32(struct timex *txc, const struct old_timex32 __user *utp)
283{
284 struct old_timex32 tx32;
285
286 memset(txc, 0, sizeof(struct timex));
287 if (copy_from_user(&tx32, utp, sizeof(struct old_timex32)))
288 return -EFAULT;
289
290 txc->modes = tx32.modes;
291 txc->offset = tx32.offset;
292 txc->freq = tx32.freq;
293 txc->maxerror = tx32.maxerror;
294 txc->esterror = tx32.esterror;
295 txc->status = tx32.status;
296 txc->constant = tx32.constant;
297 txc->precision = tx32.precision;
298 txc->tolerance = tx32.tolerance;
299 txc->time.tv_sec = tx32.time.tv_sec;
300 txc->time.tv_usec = tx32.time.tv_usec;
301 txc->tick = tx32.tick;
302 txc->ppsfreq = tx32.ppsfreq;
303 txc->jitter = tx32.jitter;
304 txc->shift = tx32.shift;
305 txc->stabil = tx32.stabil;
306 txc->jitcnt = tx32.jitcnt;
307 txc->calcnt = tx32.calcnt;
308 txc->errcnt = tx32.errcnt;
309 txc->stbcnt = tx32.stbcnt;
310
311 return 0;
312}
313
314int put_old_timex32(struct old_timex32 __user *utp, const struct timex *txc)
315{
316 struct old_timex32 tx32;
317
318 memset(&tx32, 0, sizeof(struct old_timex32));
319 tx32.modes = txc->modes;
320 tx32.offset = txc->offset;
321 tx32.freq = txc->freq;
322 tx32.maxerror = txc->maxerror;
323 tx32.esterror = txc->esterror;
324 tx32.status = txc->status;
325 tx32.constant = txc->constant;
326 tx32.precision = txc->precision;
327 tx32.tolerance = txc->tolerance;
328 tx32.time.tv_sec = txc->time.tv_sec;
329 tx32.time.tv_usec = txc->time.tv_usec;
330 tx32.tick = txc->tick;
331 tx32.ppsfreq = txc->ppsfreq;
332 tx32.jitter = txc->jitter;
333 tx32.shift = txc->shift;
334 tx32.stabil = txc->stabil;
335 tx32.jitcnt = txc->jitcnt;
336 tx32.calcnt = txc->calcnt;
337 tx32.errcnt = txc->errcnt;
338 tx32.stbcnt = txc->stbcnt;
339 tx32.tai = txc->tai;
340 if (copy_to_user(utp, &tx32, sizeof(struct old_timex32)))
341 return -EFAULT;
342 return 0;
343}
282 344
283COMPAT_SYSCALL_DEFINE1(adjtimex, struct compat_timex __user *, utp) 345COMPAT_SYSCALL_DEFINE1(adjtimex, struct old_timex32 __user *, utp)
284{ 346{
285 struct timex txc; 347 struct timex txc;
286 int err, ret; 348 int err, ret;
287 349
288 err = compat_get_timex(&txc, utp); 350 err = get_old_timex32(&txc, utp);
289 if (err) 351 if (err)
290 return err; 352 return err;
291 353
292 ret = do_adjtimex(&txc); 354 ret = do_adjtimex(&txc);
293 355
294 err = compat_put_timex(utp, &txc); 356 err = put_old_timex32(utp, &txc);
295 if (err) 357 if (err)
296 return err; 358 return err;
297 359