sigpending(): move compat to native
[linux-2.6-block.git] / kernel / compat.c
CommitLineData
1da177e4
LT
1/*
2 * linux/kernel/compat.c
3 *
4 * Kernel compatibililty routines for e.g. 32 bit syscall support
5 * on 64 bit kernels.
6 *
7 * Copyright (C) 2002-2003 Stephen Rothwell, IBM Corporation
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/linkage.h>
15#include <linux/compat.h>
16#include <linux/errno.h>
17#include <linux/time.h>
18#include <linux/signal.h>
19#include <linux/sched.h> /* for MAX_SCHEDULE_TIMEOUT */
1da177e4
LT
20#include <linux/syscalls.h>
21#include <linux/unistd.h>
22#include <linux/security.h>
3158e941 23#include <linux/timex.h>
6e5fdeed 24#include <linux/export.h>
1b2db9fb 25#include <linux/migrate.h>
1711ef38 26#include <linux/posix-timers.h>
f06febc9 27#include <linux/times.h>
e3d5a27d 28#include <linux/ptrace.h>
5a0e3ad6 29#include <linux/gfp.h>
1da177e4 30
7c0f6ba6 31#include <linux/uaccess.h>
1da177e4 32
65f5d80b
RC
33static int compat_get_timex(struct timex *txc, struct compat_timex __user *utp)
34{
35 memset(txc, 0, sizeof(struct timex));
36
37 if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) ||
38 __get_user(txc->modes, &utp->modes) ||
39 __get_user(txc->offset, &utp->offset) ||
40 __get_user(txc->freq, &utp->freq) ||
41 __get_user(txc->maxerror, &utp->maxerror) ||
42 __get_user(txc->esterror, &utp->esterror) ||
43 __get_user(txc->status, &utp->status) ||
44 __get_user(txc->constant, &utp->constant) ||
45 __get_user(txc->precision, &utp->precision) ||
46 __get_user(txc->tolerance, &utp->tolerance) ||
47 __get_user(txc->time.tv_sec, &utp->time.tv_sec) ||
48 __get_user(txc->time.tv_usec, &utp->time.tv_usec) ||
49 __get_user(txc->tick, &utp->tick) ||
50 __get_user(txc->ppsfreq, &utp->ppsfreq) ||
51 __get_user(txc->jitter, &utp->jitter) ||
52 __get_user(txc->shift, &utp->shift) ||
53 __get_user(txc->stabil, &utp->stabil) ||
54 __get_user(txc->jitcnt, &utp->jitcnt) ||
55 __get_user(txc->calcnt, &utp->calcnt) ||
56 __get_user(txc->errcnt, &utp->errcnt) ||
57 __get_user(txc->stbcnt, &utp->stbcnt))
58 return -EFAULT;
59
60 return 0;
61}
62
63static int compat_put_timex(struct compat_timex __user *utp, struct timex *txc)
64{
65 if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) ||
66 __put_user(txc->modes, &utp->modes) ||
67 __put_user(txc->offset, &utp->offset) ||
68 __put_user(txc->freq, &utp->freq) ||
69 __put_user(txc->maxerror, &utp->maxerror) ||
70 __put_user(txc->esterror, &utp->esterror) ||
71 __put_user(txc->status, &utp->status) ||
72 __put_user(txc->constant, &utp->constant) ||
73 __put_user(txc->precision, &utp->precision) ||
74 __put_user(txc->tolerance, &utp->tolerance) ||
75 __put_user(txc->time.tv_sec, &utp->time.tv_sec) ||
76 __put_user(txc->time.tv_usec, &utp->time.tv_usec) ||
77 __put_user(txc->tick, &utp->tick) ||
78 __put_user(txc->ppsfreq, &utp->ppsfreq) ||
79 __put_user(txc->jitter, &utp->jitter) ||
80 __put_user(txc->shift, &utp->shift) ||
81 __put_user(txc->stabil, &utp->stabil) ||
82 __put_user(txc->jitcnt, &utp->jitcnt) ||
83 __put_user(txc->calcnt, &utp->calcnt) ||
84 __put_user(txc->errcnt, &utp->errcnt) ||
85 __put_user(txc->stbcnt, &utp->stbcnt) ||
86 __put_user(txc->tai, &utp->tai))
87 return -EFAULT;
88 return 0;
89}
90
62a6fa97
HC
91COMPAT_SYSCALL_DEFINE2(gettimeofday, struct compat_timeval __user *, tv,
92 struct timezone __user *, tz)
b418da16
CH
93{
94 if (tv) {
95 struct timeval ktv;
96 do_gettimeofday(&ktv);
81993e81 97 if (compat_put_timeval(&ktv, tv))
b418da16
CH
98 return -EFAULT;
99 }
100 if (tz) {
101 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
102 return -EFAULT;
103 }
104
105 return 0;
106}
107
62a6fa97
HC
108COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv,
109 struct timezone __user *, tz)
b418da16 110{
2ac00f17 111 struct timespec64 new_ts;
81993e81 112 struct timeval user_tv;
81993e81 113 struct timezone new_tz;
b418da16
CH
114
115 if (tv) {
81993e81 116 if (compat_get_timeval(&user_tv, tv))
b418da16 117 return -EFAULT;
81993e81
PA
118 new_ts.tv_sec = user_tv.tv_sec;
119 new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
b418da16
CH
120 }
121 if (tz) {
81993e81 122 if (copy_from_user(&new_tz, tz, sizeof(*tz)))
b418da16
CH
123 return -EFAULT;
124 }
125
2ac00f17 126 return do_sys_settimeofday64(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
b418da16
CH
127}
128
81993e81 129static int __compat_get_timeval(struct timeval *tv, const struct compat_timeval __user *ctv)
6684ba20
PA
130{
131 return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
132 __get_user(tv->tv_sec, &ctv->tv_sec) ||
133 __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
134}
6684ba20 135
81993e81 136static int __compat_put_timeval(const struct timeval *tv, struct compat_timeval __user *ctv)
6684ba20
PA
137{
138 return (!access_ok(VERIFY_WRITE, ctv, sizeof(*ctv)) ||
139 __put_user(tv->tv_sec, &ctv->tv_sec) ||
140 __put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
141}
6684ba20 142
81993e81 143static int __compat_get_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
1da177e4
LT
144{
145 return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
146 __get_user(ts->tv_sec, &cts->tv_sec) ||
147 __get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
148}
149
81993e81 150static int __compat_put_timespec(const struct timespec *ts, struct compat_timespec __user *cts)
1da177e4
LT
151{
152 return (!access_ok(VERIFY_WRITE, cts, sizeof(*cts)) ||
153 __put_user(ts->tv_sec, &cts->tv_sec) ||
154 __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
155}
156
6684ba20
PA
157int compat_get_timeval(struct timeval *tv, const void __user *utv)
158{
159 if (COMPAT_USE_64BIT_TIME)
6516a466 160 return copy_from_user(tv, utv, sizeof(*tv)) ? -EFAULT : 0;
6684ba20 161 else
81993e81 162 return __compat_get_timeval(tv, utv);
6684ba20
PA
163}
164EXPORT_SYMBOL_GPL(compat_get_timeval);
165
166int compat_put_timeval(const struct timeval *tv, void __user *utv)
167{
168 if (COMPAT_USE_64BIT_TIME)
6516a466 169 return copy_to_user(utv, tv, sizeof(*tv)) ? -EFAULT : 0;
6684ba20 170 else
81993e81 171 return __compat_put_timeval(tv, utv);
6684ba20
PA
172}
173EXPORT_SYMBOL_GPL(compat_put_timeval);
174
175int compat_get_timespec(struct timespec *ts, const void __user *uts)
176{
177 if (COMPAT_USE_64BIT_TIME)
6516a466 178 return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0;
6684ba20 179 else
81993e81 180 return __compat_get_timespec(ts, uts);
6684ba20
PA
181}
182EXPORT_SYMBOL_GPL(compat_get_timespec);
183
184int compat_put_timespec(const struct timespec *ts, void __user *uts)
185{
186 if (COMPAT_USE_64BIT_TIME)
6516a466 187 return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0;
6684ba20 188 else
81993e81 189 return __compat_put_timespec(ts, uts);
6684ba20
PA
190}
191EXPORT_SYMBOL_GPL(compat_put_timespec);
192
81993e81
PA
193int compat_convert_timespec(struct timespec __user **kts,
194 const void __user *cts)
195{
196 struct timespec ts;
197 struct timespec __user *uts;
198
199 if (!cts || COMPAT_USE_64BIT_TIME) {
200 *kts = (struct timespec __user *)cts;
201 return 0;
202 }
203
204 uts = compat_alloc_user_space(sizeof(ts));
205 if (!uts)
206 return -EFAULT;
207 if (compat_get_timespec(&ts, cts))
208 return -EFAULT;
209 if (copy_to_user(uts, &ts, sizeof(ts)))
210 return -EFAULT;
211
212 *kts = uts;
213 return 0;
214}
215
41652937
ON
216static long compat_nanosleep_restart(struct restart_block *restart)
217{
218 struct compat_timespec __user *rmtp;
219 struct timespec rmt;
220 mm_segment_t oldfs;
221 long ret;
222
029a07e0 223 restart->nanosleep.rmtp = (struct timespec __user *) &rmt;
41652937
ON
224 oldfs = get_fs();
225 set_fs(KERNEL_DS);
226 ret = hrtimer_nanosleep_restart(restart);
227 set_fs(oldfs);
228
849151dd 229 if (ret == -ERESTART_RESTARTBLOCK) {
029a07e0 230 rmtp = restart->nanosleep.compat_rmtp;
41652937 231
81993e81 232 if (rmtp && compat_put_timespec(&rmt, rmtp))
41652937
ON
233 return -EFAULT;
234 }
235
236 return ret;
237}
238
62a6fa97
HC
239COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
240 struct compat_timespec __user *, rmtp)
1da177e4 241{
c70878b4 242 struct timespec tu, rmt;
ad196384 243 struct timespec64 tu64;
41652937 244 mm_segment_t oldfs;
c70878b4 245 long ret;
1da177e4 246
81993e81 247 if (compat_get_timespec(&tu, rqtp))
1da177e4
LT
248 return -EFAULT;
249
ad196384
DD
250 tu64 = timespec_to_timespec64(tu);
251 if (!timespec64_valid(&tu64))
1da177e4
LT
252 return -EINVAL;
253
41652937
ON
254 oldfs = get_fs();
255 set_fs(KERNEL_DS);
ad196384 256 ret = hrtimer_nanosleep(&tu64,
41652937
ON
257 rmtp ? (struct timespec __user *)&rmt : NULL,
258 HRTIMER_MODE_REL, CLOCK_MONOTONIC);
259 set_fs(oldfs);
260
849151dd
TG
261 /*
262 * hrtimer_nanosleep() can only return 0 or
263 * -ERESTART_RESTARTBLOCK here because:
264 *
265 * - we call it with HRTIMER_MODE_REL and therefor exclude the
266 * -ERESTARTNOHAND return path.
267 *
268 * - we supply the rmtp argument from the task stack (due to
269 * the necessary compat conversion. So the update cannot
270 * fail, which excludes the -EFAULT return path as well. If
271 * it fails nevertheless we have a bigger problem and wont
272 * reach this place anymore.
273 *
274 * - if the return value is 0, we do not have to update rmtp
275 * because there is no remaining time.
276 *
277 * We check for -ERESTART_RESTARTBLOCK nevertheless if the
278 * core implementation decides to return random nonsense.
279 */
280 if (ret == -ERESTART_RESTARTBLOCK) {
f56141e3 281 struct restart_block *restart = &current->restart_block;
41652937
ON
282
283 restart->fn = compat_nanosleep_restart;
029a07e0 284 restart->nanosleep.compat_rmtp = rmtp;
1da177e4 285
81993e81 286 if (rmtp && compat_put_timespec(&rmt, rmtp))
1da177e4
LT
287 return -EFAULT;
288 }
c70878b4 289 return ret;
1da177e4
LT
290}
291
292static inline long get_compat_itimerval(struct itimerval *o,
293 struct compat_itimerval __user *i)
294{
295 return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
296 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
297 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
298 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
299 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
300}
301
302static inline long put_compat_itimerval(struct compat_itimerval __user *o,
303 struct itimerval *i)
304{
305 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
306 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
307 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
308 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
309 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
310}
311
baa73d9e
NP
312asmlinkage long sys_ni_posix_timers(void);
313
37784074
AV
314COMPAT_SYSCALL_DEFINE2(getitimer, int, which,
315 struct compat_itimerval __user *, it)
1da177e4
LT
316{
317 struct itimerval kit;
318 int error;
319
baa73d9e
NP
320 if (!IS_ENABLED(CONFIG_POSIX_TIMERS))
321 return sys_ni_posix_timers();
322
1da177e4
LT
323 error = do_getitimer(which, &kit);
324 if (!error && put_compat_itimerval(it, &kit))
325 error = -EFAULT;
326 return error;
327}
328
37784074
AV
329COMPAT_SYSCALL_DEFINE3(setitimer, int, which,
330 struct compat_itimerval __user *, in,
331 struct compat_itimerval __user *, out)
1da177e4
LT
332{
333 struct itimerval kin, kout;
334 int error;
335
baa73d9e
NP
336 if (!IS_ENABLED(CONFIG_POSIX_TIMERS))
337 return sys_ni_posix_timers();
338
1da177e4
LT
339 if (in) {
340 if (get_compat_itimerval(&kin, in))
341 return -EFAULT;
342 } else
343 memset(&kin, 0, sizeof(kin));
344
345 error = do_setitimer(which, &kin, out ? &kout : NULL);
346 if (error || !out)
347 return error;
348 if (put_compat_itimerval(out, &kout))
349 return -EFAULT;
350 return 0;
351}
352
be84cb43
CM
353#ifdef __ARCH_WANT_SYS_SIGPROCMASK
354
b7dafa0e
JK
355/*
356 * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the
357 * blocked set of signals to the supplied signal set
358 */
359static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set)
1da177e4 360{
b7dafa0e
JK
361 memcpy(blocked->sig, &set, sizeof(set));
362}
1da177e4 363
5cf22100
AV
364COMPAT_SYSCALL_DEFINE3(sigprocmask, int, how,
365 compat_old_sigset_t __user *, nset,
366 compat_old_sigset_t __user *, oset)
b7dafa0e
JK
367{
368 old_sigset_t old_set, new_set;
369 sigset_t new_blocked;
370
371 old_set = current->blocked.sig[0];
372
373 if (nset) {
374 if (get_user(new_set, nset))
375 return -EFAULT;
376 new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));
377
378 new_blocked = current->blocked;
379
380 switch (how) {
381 case SIG_BLOCK:
382 sigaddsetmask(&new_blocked, new_set);
383 break;
384 case SIG_UNBLOCK:
385 sigdelsetmask(&new_blocked, new_set);
386 break;
387 case SIG_SETMASK:
388 compat_sig_setmask(&new_blocked, new_set);
389 break;
390 default:
391 return -EINVAL;
392 }
393
394 set_current_blocked(&new_blocked);
395 }
396
397 if (oset) {
398 if (put_user(old_set, oset))
399 return -EFAULT;
400 }
401
402 return 0;
1da177e4
LT
403}
404
be84cb43
CM
405#endif
406
1da177e4
LT
407int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
408{
409 if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
410 __put_user(r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
411 __put_user(r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
412 __put_user(r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
413 __put_user(r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
414 __put_user(r->ru_maxrss, &ru->ru_maxrss) ||
415 __put_user(r->ru_ixrss, &ru->ru_ixrss) ||
416 __put_user(r->ru_idrss, &ru->ru_idrss) ||
417 __put_user(r->ru_isrss, &ru->ru_isrss) ||
418 __put_user(r->ru_minflt, &ru->ru_minflt) ||
419 __put_user(r->ru_majflt, &ru->ru_majflt) ||
420 __put_user(r->ru_nswap, &ru->ru_nswap) ||
421 __put_user(r->ru_inblock, &ru->ru_inblock) ||
422 __put_user(r->ru_oublock, &ru->ru_oublock) ||
423 __put_user(r->ru_msgsnd, &ru->ru_msgsnd) ||
424 __put_user(r->ru_msgrcv, &ru->ru_msgrcv) ||
425 __put_user(r->ru_nsignals, &ru->ru_nsignals) ||
426 __put_user(r->ru_nvcsw, &ru->ru_nvcsw) ||
427 __put_user(r->ru_nivcsw, &ru->ru_nivcsw))
428 return -EFAULT;
429 return 0;
430}
431
8d9807b1
AV
432COMPAT_SYSCALL_DEFINE4(wait4,
433 compat_pid_t, pid,
434 compat_uint_t __user *, stat_addr,
435 int, options,
436 struct compat_rusage __user *, ru)
1da177e4
LT
437{
438 if (!ru) {
439 return sys_wait4(pid, stat_addr, options, NULL);
440 } else {
441 struct rusage r;
442 int ret;
443 unsigned int status;
444 mm_segment_t old_fs = get_fs();
445
446 set_fs (KERNEL_DS);
447 ret = sys_wait4(pid,
448 (stat_addr ?
449 (unsigned int __user *) &status : NULL),
450 options, (struct rusage __user *) &r);
451 set_fs (old_fs);
452
453 if (ret > 0) {
454 if (put_compat_rusage(&r, ru))
455 return -EFAULT;
456 if (stat_addr && put_user(status, stat_addr))
457 return -EFAULT;
458 }
459 return ret;
460 }
461}
462
8d9807b1
AV
463COMPAT_SYSCALL_DEFINE5(waitid,
464 int, which, compat_pid_t, pid,
465 struct compat_siginfo __user *, uinfo, int, options,
466 struct compat_rusage __user *, uru)
1da177e4
LT
467{
468 siginfo_t info;
469 struct rusage ru;
470 long ret;
471 mm_segment_t old_fs = get_fs();
472
473 memset(&info, 0, sizeof(info));
474
475 set_fs(KERNEL_DS);
476 ret = sys_waitid(which, pid, (siginfo_t __user *)&info, options,
477 uru ? (struct rusage __user *)&ru : NULL);
478 set_fs(old_fs);
479
480 if ((ret < 0) || (info.si_signo == 0))
481 return ret;
482
483 if (uru) {
a566c288
AV
484 /* sys_waitid() overwrites everything in ru */
485 if (COMPAT_USE_64BIT_TIME)
486 ret = copy_to_user(uru, &ru, sizeof(ru));
487 else
488 ret = put_compat_rusage(&ru, uru);
1da177e4 489 if (ret)
bffea77c 490 return -EFAULT;
1da177e4
LT
491 }
492
493 BUG_ON(info.si_code & __SI_MASK);
494 info.si_code |= __SI_CHLD;
495 return copy_siginfo_to_user32(uinfo, &info);
496}
497
498static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr,
a45185d2 499 unsigned len, struct cpumask *new_mask)
1da177e4
LT
500{
501 unsigned long *k;
502
a45185d2
RR
503 if (len < cpumask_size())
504 memset(new_mask, 0, cpumask_size());
505 else if (len > cpumask_size())
506 len = cpumask_size();
1da177e4 507
a45185d2 508 k = cpumask_bits(new_mask);
1da177e4
LT
509 return compat_get_bitmap(k, user_mask_ptr, len * 8);
510}
511
62a6fa97
HC
512COMPAT_SYSCALL_DEFINE3(sched_setaffinity, compat_pid_t, pid,
513 unsigned int, len,
514 compat_ulong_t __user *, user_mask_ptr)
1da177e4 515{
a45185d2 516 cpumask_var_t new_mask;
1da177e4
LT
517 int retval;
518
a45185d2
RR
519 if (!alloc_cpumask_var(&new_mask, GFP_KERNEL))
520 return -ENOMEM;
521
522 retval = compat_get_user_cpu_mask(user_mask_ptr, len, new_mask);
1da177e4 523 if (retval)
a45185d2 524 goto out;
1da177e4 525
a45185d2
RR
526 retval = sched_setaffinity(pid, new_mask);
527out:
528 free_cpumask_var(new_mask);
529 return retval;
1da177e4
LT
530}
531
62a6fa97
HC
532COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t, pid, unsigned int, len,
533 compat_ulong_t __user *, user_mask_ptr)
1da177e4
LT
534{
535 int ret;
a45185d2 536 cpumask_var_t mask;
1da177e4 537
fa9dc265
KM
538 if ((len * BITS_PER_BYTE) < nr_cpu_ids)
539 return -EINVAL;
540 if (len & (sizeof(compat_ulong_t)-1))
1da177e4
LT
541 return -EINVAL;
542
a45185d2
RR
543 if (!alloc_cpumask_var(&mask, GFP_KERNEL))
544 return -ENOMEM;
545
546 ret = sched_getaffinity(pid, mask);
fa9dc265
KM
547 if (ret == 0) {
548 size_t retlen = min_t(size_t, len, cpumask_size());
1da177e4 549
fa9dc265
KM
550 if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
551 ret = -EFAULT;
552 else
553 ret = retlen;
554 }
a45185d2 555 free_cpumask_var(mask);
fa9dc265 556
a45185d2 557 return ret;
1da177e4
LT
558}
559
83f5d126
DL
560int get_compat_itimerspec(struct itimerspec *dst,
561 const struct compat_itimerspec __user *src)
bd3a8492 562{
81993e81
PA
563 if (__compat_get_timespec(&dst->it_interval, &src->it_interval) ||
564 __compat_get_timespec(&dst->it_value, &src->it_value))
1da177e4
LT
565 return -EFAULT;
566 return 0;
bd3a8492 567}
1da177e4 568
83f5d126
DL
569int put_compat_itimerspec(struct compat_itimerspec __user *dst,
570 const struct itimerspec *src)
bd3a8492 571{
81993e81
PA
572 if (__compat_put_timespec(&src->it_interval, &dst->it_interval) ||
573 __compat_put_timespec(&src->it_value, &dst->it_value))
1da177e4
LT
574 return -EFAULT;
575 return 0;
bd3a8492 576}
1da177e4 577
62a6fa97
HC
578COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,
579 struct compat_sigevent __user *, timer_event_spec,
580 timer_t __user *, created_timer_id)
3a0f69d5
CH
581{
582 struct sigevent __user *event = NULL;
583
584 if (timer_event_spec) {
585 struct sigevent kevent;
586
587 event = compat_alloc_user_space(sizeof(*event));
588 if (get_compat_sigevent(&kevent, timer_event_spec) ||
589 copy_to_user(event, &kevent, sizeof(*event)))
590 return -EFAULT;
591 }
592
593 return sys_timer_create(which_clock, event, created_timer_id);
594}
595
62a6fa97
HC
596COMPAT_SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
597 struct compat_itimerspec __user *, new,
598 struct compat_itimerspec __user *, old)
bd3a8492 599{
1da177e4
LT
600 long err;
601 mm_segment_t oldfs;
602 struct itimerspec newts, oldts;
603
604 if (!new)
605 return -EINVAL;
606 if (get_compat_itimerspec(&newts, new))
bd3a8492 607 return -EFAULT;
1da177e4
LT
608 oldfs = get_fs();
609 set_fs(KERNEL_DS);
610 err = sys_timer_settime(timer_id, flags,
611 (struct itimerspec __user *) &newts,
612 (struct itimerspec __user *) &oldts);
bd3a8492 613 set_fs(oldfs);
1da177e4
LT
614 if (!err && old && put_compat_itimerspec(old, &oldts))
615 return -EFAULT;
616 return err;
bd3a8492 617}
1da177e4 618
62a6fa97
HC
619COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
620 struct compat_itimerspec __user *, setting)
bd3a8492 621{
1da177e4
LT
622 long err;
623 mm_segment_t oldfs;
bd3a8492 624 struct itimerspec ts;
1da177e4
LT
625
626 oldfs = get_fs();
627 set_fs(KERNEL_DS);
628 err = sys_timer_gettime(timer_id,
bd3a8492
DW
629 (struct itimerspec __user *) &ts);
630 set_fs(oldfs);
1da177e4
LT
631 if (!err && put_compat_itimerspec(setting, &ts))
632 return -EFAULT;
633 return err;
bd3a8492 634}
1da177e4 635
62a6fa97
HC
636COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
637 struct compat_timespec __user *, tp)
1da177e4
LT
638{
639 long err;
640 mm_segment_t oldfs;
bd3a8492 641 struct timespec ts;
1da177e4 642
81993e81 643 if (compat_get_timespec(&ts, tp))
bd3a8492 644 return -EFAULT;
1da177e4 645 oldfs = get_fs();
bd3a8492 646 set_fs(KERNEL_DS);
1da177e4
LT
647 err = sys_clock_settime(which_clock,
648 (struct timespec __user *) &ts);
649 set_fs(oldfs);
650 return err;
bd3a8492 651}
1da177e4 652
62a6fa97
HC
653COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
654 struct compat_timespec __user *, tp)
1da177e4
LT
655{
656 long err;
657 mm_segment_t oldfs;
bd3a8492 658 struct timespec ts;
1da177e4
LT
659
660 oldfs = get_fs();
661 set_fs(KERNEL_DS);
662 err = sys_clock_gettime(which_clock,
663 (struct timespec __user *) &ts);
664 set_fs(oldfs);
81993e81 665 if (!err && compat_put_timespec(&ts, tp))
bd3a8492 666 return -EFAULT;
1da177e4 667 return err;
bd3a8492 668}
1da177e4 669
62a6fa97
HC
670COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
671 struct compat_timex __user *, utp)
f1f1d5eb
RC
672{
673 struct timex txc;
674 mm_segment_t oldfs;
675 int err, ret;
676
677 err = compat_get_timex(&txc, utp);
678 if (err)
679 return err;
680
681 oldfs = get_fs();
682 set_fs(KERNEL_DS);
683 ret = sys_clock_adjtime(which_clock, (struct timex __user *) &txc);
684 set_fs(oldfs);
685
686 err = compat_put_timex(utp, &txc);
687 if (err)
688 return err;
689
690 return ret;
691}
692
62a6fa97
HC
693COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
694 struct compat_timespec __user *, tp)
1da177e4
LT
695{
696 long err;
697 mm_segment_t oldfs;
bd3a8492 698 struct timespec ts;
1da177e4
LT
699
700 oldfs = get_fs();
701 set_fs(KERNEL_DS);
702 err = sys_clock_getres(which_clock,
703 (struct timespec __user *) &ts);
704 set_fs(oldfs);
81993e81 705 if (!err && tp && compat_put_timespec(&ts, tp))
bd3a8492 706 return -EFAULT;
1da177e4 707 return err;
bd3a8492 708}
1da177e4 709
1711ef38
TA
710static long compat_clock_nanosleep_restart(struct restart_block *restart)
711{
712 long err;
713 mm_segment_t oldfs;
714 struct timespec tu;
dce44e03 715 struct compat_timespec __user *rmtp = restart->nanosleep.compat_rmtp;
1711ef38 716
029a07e0 717 restart->nanosleep.rmtp = (struct timespec __user *) &tu;
1711ef38
TA
718 oldfs = get_fs();
719 set_fs(KERNEL_DS);
720 err = clock_nanosleep_restart(restart);
721 set_fs(oldfs);
722
723 if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
81993e81 724 compat_put_timespec(&tu, rmtp))
1711ef38
TA
725 return -EFAULT;
726
727 if (err == -ERESTART_RESTARTBLOCK) {
728 restart->fn = compat_clock_nanosleep_restart;
029a07e0 729 restart->nanosleep.compat_rmtp = rmtp;
1711ef38
TA
730 }
731 return err;
732}
733
62a6fa97
HC
734COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
735 struct compat_timespec __user *, rqtp,
736 struct compat_timespec __user *, rmtp)
1da177e4
LT
737{
738 long err;
739 mm_segment_t oldfs;
bd3a8492 740 struct timespec in, out;
1711ef38 741 struct restart_block *restart;
1da177e4 742
81993e81 743 if (compat_get_timespec(&in, rqtp))
1da177e4
LT
744 return -EFAULT;
745
746 oldfs = get_fs();
747 set_fs(KERNEL_DS);
748 err = sys_clock_nanosleep(which_clock, flags,
749 (struct timespec __user *) &in,
750 (struct timespec __user *) &out);
751 set_fs(oldfs);
1711ef38 752
1da177e4 753 if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
81993e81 754 compat_put_timespec(&out, rmtp))
1da177e4 755 return -EFAULT;
1711ef38
TA
756
757 if (err == -ERESTART_RESTARTBLOCK) {
f56141e3 758 restart = &current->restart_block;
1711ef38 759 restart->fn = compat_clock_nanosleep_restart;
029a07e0 760 restart->nanosleep.compat_rmtp = rmtp;
1711ef38 761 }
bd3a8492
DW
762 return err;
763}
1da177e4
LT
764
765/*
766 * We currently only need the following fields from the sigevent
767 * structure: sigev_value, sigev_signo, sig_notify and (sometimes
768 * sigev_notify_thread_id). The others are handled in user mode.
769 * We also assume that copying sigev_value.sival_int is sufficient
770 * to keep all the bits of sigev_value.sival_ptr intact.
771 */
772int get_compat_sigevent(struct sigevent *event,
773 const struct compat_sigevent __user *u_event)
774{
51410d3c 775 memset(event, 0, sizeof(*event));
1da177e4
LT
776 return (!access_ok(VERIFY_READ, u_event, sizeof(*u_event)) ||
777 __get_user(event->sigev_value.sival_int,
778 &u_event->sigev_value.sival_int) ||
779 __get_user(event->sigev_signo, &u_event->sigev_signo) ||
780 __get_user(event->sigev_notify, &u_event->sigev_notify) ||
781 __get_user(event->sigev_notify_thread_id,
782 &u_event->sigev_notify_thread_id))
783 ? -EFAULT : 0;
784}
785
5fa3839a 786long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
1da177e4
LT
787 unsigned long bitmap_size)
788{
1da177e4
LT
789 unsigned long nr_compat_longs;
790
791 /* align bitmap up to nearest compat_long_t boundary */
792 bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
1e1fc133 793 nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
1da177e4
LT
794
795 if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
796 return -EFAULT;
797
1e1fc133
AV
798 user_access_begin();
799 while (nr_compat_longs > 1) {
800 compat_ulong_t l1, l2;
801 unsafe_get_user(l1, umask++, Efault);
802 unsafe_get_user(l2, umask++, Efault);
803 *mask++ = ((unsigned long)l2 << BITS_PER_COMPAT_LONG) | l1;
804 nr_compat_longs -= 2;
1da177e4 805 }
1e1fc133
AV
806 if (nr_compat_longs)
807 unsafe_get_user(*mask, umask++, Efault);
808 user_access_end();
1da177e4 809 return 0;
1e1fc133
AV
810
811Efault:
812 user_access_end();
813 return -EFAULT;
1da177e4
LT
814}
815
816long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
817 unsigned long bitmap_size)
818{
1da177e4
LT
819 unsigned long nr_compat_longs;
820
821 /* align bitmap up to nearest compat_long_t boundary */
822 bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
1e1fc133 823 nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
1da177e4
LT
824
825 if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
826 return -EFAULT;
827
1e1fc133
AV
828 user_access_begin();
829 while (nr_compat_longs > 1) {
830 unsigned long m = *mask++;
831 unsafe_put_user((compat_ulong_t)m, umask++, Efault);
832 unsafe_put_user(m >> BITS_PER_COMPAT_LONG, umask++, Efault);
833 nr_compat_longs -= 2;
1da177e4 834 }
1e1fc133
AV
835 if (nr_compat_longs)
836 unsafe_put_user((compat_ulong_t)*mask, umask++, Efault);
837 user_access_end();
1da177e4 838 return 0;
1e1fc133
AV
839Efault:
840 user_access_end();
841 return -EFAULT;
1da177e4
LT
842}
843
844void
322a56cb 845sigset_from_compat(sigset_t *set, const compat_sigset_t *compat)
1da177e4
LT
846{
847 switch (_NSIG_WORDS) {
1da177e4
LT
848 case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
849 case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 );
850 case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 );
851 case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
1da177e4
LT
852 }
853}
1dda606c 854EXPORT_SYMBOL_GPL(sigset_from_compat);
1da177e4 855
322a56cb
AV
856void
857sigset_to_compat(compat_sigset_t *compat, const sigset_t *set)
858{
859 switch (_NSIG_WORDS) {
860 case 4: compat->sig[7] = (set->sig[3] >> 32); compat->sig[6] = set->sig[3];
861 case 3: compat->sig[5] = (set->sig[2] >> 32); compat->sig[4] = set->sig[2];
862 case 2: compat->sig[3] = (set->sig[1] >> 32); compat->sig[2] = set->sig[1];
863 case 1: compat->sig[1] = (set->sig[0] >> 32); compat->sig[0] = set->sig[0];
864 }
865}
866
28d27f2d
AV
867COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
868 struct compat_siginfo __user *, uinfo,
869 struct compat_timespec __user *, uts, compat_size_t, sigsetsize)
1da177e4
LT
870{
871 compat_sigset_t s32;
872 sigset_t s;
1da177e4
LT
873 struct timespec t;
874 siginfo_t info;
943df148 875 long ret;
1da177e4
LT
876
877 if (sigsetsize != sizeof(sigset_t))
878 return -EINVAL;
879
880 if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
881 return -EFAULT;
882 sigset_from_compat(&s, &s32);
1da177e4
LT
883
884 if (uts) {
b2ddedcd 885 if (compat_get_timespec(&t, uts))
1da177e4 886 return -EFAULT;
1da177e4
LT
887 }
888
943df148 889 ret = do_sigtimedwait(&s, &info, uts ? &t : NULL);
1da177e4 890
943df148
ON
891 if (ret > 0 && uinfo) {
892 if (copy_siginfo_to_user32(uinfo, &info))
893 ret = -EFAULT;
1da177e4 894 }
943df148 895
1da177e4 896 return ret;
62ab4505
TG
897}
898
1da177e4
LT
899#ifdef __ARCH_WANT_COMPAT_SYS_TIME
900
901/* compat_time_t is a 32 bit "long" and needs to get converted. */
902
62a6fa97 903COMPAT_SYSCALL_DEFINE1(time, compat_time_t __user *, tloc)
1da177e4
LT
904{
905 compat_time_t i;
906 struct timeval tv;
907
908 do_gettimeofday(&tv);
909 i = tv.tv_sec;
910
911 if (tloc) {
912 if (put_user(i,tloc))
e3d5a27d 913 return -EFAULT;
1da177e4 914 }
e3d5a27d 915 force_successful_syscall_return();
1da177e4
LT
916 return i;
917}
918
62a6fa97 919COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr)
1da177e4
LT
920{
921 struct timespec tv;
922 int err;
923
924 if (get_user(tv.tv_sec, tptr))
925 return -EFAULT;
926
927 tv.tv_nsec = 0;
928
929 err = security_settime(&tv, NULL);
930 if (err)
931 return err;
932
933 do_settimeofday(&tv);
934 return 0;
935}
936
937#endif /* __ARCH_WANT_COMPAT_SYS_TIME */
150256d8 938
62a6fa97 939COMPAT_SYSCALL_DEFINE1(adjtimex, struct compat_timex __user *, utp)
3158e941
SR
940{
941 struct timex txc;
65f5d80b 942 int err, ret;
3158e941 943
65f5d80b
RC
944 err = compat_get_timex(&txc, utp);
945 if (err)
946 return err;
3158e941
SR
947
948 ret = do_adjtimex(&txc);
949
65f5d80b
RC
950 err = compat_put_timex(utp, &txc);
951 if (err)
952 return err;
3158e941
SR
953
954 return ret;
955}
1b2db9fb
CL
956
957#ifdef CONFIG_NUMA
2f2728f6
HC
958COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages,
959 compat_uptr_t __user *, pages32,
960 const int __user *, nodes,
961 int __user *, status,
962 int, flags)
1b2db9fb
CL
963{
964 const void __user * __user *pages;
965 int i;
966
967 pages = compat_alloc_user_space(nr_pages * sizeof(void *));
968 for (i = 0; i < nr_pages; i++) {
969 compat_uptr_t p;
970
9216dfad 971 if (get_user(p, pages32 + i) ||
1b2db9fb
CL
972 put_user(compat_ptr(p), pages + i))
973 return -EFAULT;
974 }
975 return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
976}
3fd59397 977
62a6fa97
HC
978COMPAT_SYSCALL_DEFINE4(migrate_pages, compat_pid_t, pid,
979 compat_ulong_t, maxnode,
980 const compat_ulong_t __user *, old_nodes,
981 const compat_ulong_t __user *, new_nodes)
3fd59397
SR
982{
983 unsigned long __user *old = NULL;
984 unsigned long __user *new = NULL;
985 nodemask_t tmp_mask;
986 unsigned long nr_bits;
987 unsigned long size;
988
989 nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES);
990 size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
991 if (old_nodes) {
992 if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits))
993 return -EFAULT;
994 old = compat_alloc_user_space(new_nodes ? size * 2 : size);
995 if (new_nodes)
996 new = old + size / sizeof(unsigned long);
997 if (copy_to_user(old, nodes_addr(tmp_mask), size))
998 return -EFAULT;
999 }
1000 if (new_nodes) {
1001 if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits))
1002 return -EFAULT;
1003 if (new == NULL)
1004 new = compat_alloc_user_space(size);
1005 if (copy_to_user(new, nodes_addr(tmp_mask), size))
1006 return -EFAULT;
1007 }
1008 return sys_migrate_pages(pid, nr_bits + 1, old, new);
1009}
1b2db9fb 1010#endif
d4d23add 1011
6883da8c
AV
1012COMPAT_SYSCALL_DEFINE2(sched_rr_get_interval,
1013 compat_pid_t, pid,
1014 struct compat_timespec __user *, interval)
0ad50c38
CM
1015{
1016 struct timespec t;
1017 int ret;
1018 mm_segment_t old_fs = get_fs();
1019
1020 set_fs(KERNEL_DS);
1021 ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
1022 set_fs(old_fs);
81993e81 1023 if (compat_put_timespec(&t, interval))
0ad50c38
CM
1024 return -EFAULT;
1025 return ret;
1026}
0ad50c38 1027
c41d68a5
PA
1028/*
1029 * Allocate user-space memory for the duration of a single system call,
1030 * in order to marshall parameters inside a compat thunk.
1031 */
1032void __user *compat_alloc_user_space(unsigned long len)
1033{
1034 void __user *ptr;
1035
1036 /* If len would occupy more than half of the entire compat space... */
1037 if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
1038 return NULL;
1039
1040 ptr = arch_compat_alloc_user_space(len);
1041
1042 if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
1043 return NULL;
1044
1045 return ptr;
1046}
1047EXPORT_SYMBOL_GPL(compat_alloc_user_space);