f2a2975042871ee8607803bd5eca47acdbda005f
[linux-2.6.git] / kernel / compat.c
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 */
20 #include <linux/syscalls.h>
21 #include <linux/unistd.h>
22 #include <linux/security.h>
23 #include <linux/timex.h>
24 #include <linux/migrate.h>
25 #include <linux/posix-timers.h>
26
27 #include <asm/uaccess.h>
28
29 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
30 {
31         return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
32                         __get_user(ts->tv_sec, &cts->tv_sec) ||
33                         __get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
34 }
35
36 int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user *cts)
37 {
38         return (!access_ok(VERIFY_WRITE, cts, sizeof(*cts)) ||
39                         __put_user(ts->tv_sec, &cts->tv_sec) ||
40                         __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
41 }
42
43 static long compat_nanosleep_restart(struct restart_block *restart)
44 {
45         struct compat_timespec __user *rmtp;
46         struct timespec rmt;
47         mm_segment_t oldfs;
48         long ret;
49
50         rmtp = (struct compat_timespec __user *)(restart->arg1);
51         restart->arg1 = (unsigned long)&rmt;
52         oldfs = get_fs();
53         set_fs(KERNEL_DS);
54         ret = hrtimer_nanosleep_restart(restart);
55         set_fs(oldfs);
56
57         if (ret) {
58                 restart->fn = compat_nanosleep_restart;
59                 restart->arg1 = (unsigned long)rmtp;
60
61                 if (rmtp && put_compat_timespec(&rmt, rmtp))
62                         return -EFAULT;
63         }
64
65         return ret;
66 }
67
68 asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
69                                      struct compat_timespec __user *rmtp)
70 {
71         struct timespec tu, rmt;
72         mm_segment_t oldfs;
73         long ret;
74
75         if (get_compat_timespec(&tu, rqtp))
76                 return -EFAULT;
77
78         if (!timespec_valid(&tu))
79                 return -EINVAL;
80
81         oldfs = get_fs();
82         set_fs(KERNEL_DS);
83         ret = hrtimer_nanosleep(&tu,
84                                 rmtp ? (struct timespec __user *)&rmt : NULL,
85                                 HRTIMER_MODE_REL, CLOCK_MONOTONIC);
86         set_fs(oldfs);
87
88         if (ret) {
89                 struct restart_block *restart
90                         = &current_thread_info()->restart_block;
91
92                 restart->fn = compat_nanosleep_restart;
93                 restart->arg1 = (unsigned long)rmtp;
94
95                 if (rmtp && put_compat_timespec(&rmt, rmtp))
96                         return -EFAULT;
97         }
98
99         return ret;
100 }
101
102 static inline long get_compat_itimerval(struct itimerval *o,
103                 struct compat_itimerval __user *i)
104 {
105         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
106                 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
107                  __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
108                  __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
109                  __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
110 }
111
112 static inline long put_compat_itimerval(struct compat_itimerval __user *o,
113                 struct itimerval *i)
114 {
115         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
116                 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
117                  __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
118                  __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
119                  __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
120 }
121
122 asmlinkage long compat_sys_getitimer(int which,
123                 struct compat_itimerval __user *it)
124 {
125         struct itimerval kit;
126         int error;
127
128         error = do_getitimer(which, &kit);
129         if (!error && put_compat_itimerval(it, &kit))
130                 error = -EFAULT;
131         return error;
132 }
133
134 asmlinkage long compat_sys_setitimer(int which,
135                 struct compat_itimerval __user *in,
136                 struct compat_itimerval __user *out)
137 {
138         struct itimerval kin, kout;
139         int error;
140
141         if (in) {
142                 if (get_compat_itimerval(&kin, in))
143                         return -EFAULT;
144         } else
145                 memset(&kin, 0, sizeof(kin));
146
147         error = do_setitimer(which, &kin, out ? &kout : NULL);
148         if (error || !out)
149                 return error;
150         if (put_compat_itimerval(out, &kout))
151                 return -EFAULT;
152         return 0;
153 }
154
155 asmlinkage long compat_sys_times(struct compat_tms __user *tbuf)
156 {
157         /*
158          *      In the SMP world we might just be unlucky and have one of
159          *      the times increment as we use it. Since the value is an
160          *      atomically safe type this is just fine. Conceptually its
161          *      as if the syscall took an instant longer to occur.
162          */
163         if (tbuf) {
164                 struct compat_tms tmp;
165                 struct task_struct *tsk = current;
166                 struct task_struct *t;
167                 cputime_t utime, stime, cutime, cstime;
168
169                 read_lock(&tasklist_lock);
170                 utime = tsk->signal->utime;
171                 stime = tsk->signal->stime;
172                 t = tsk;
173                 do {
174                         utime = cputime_add(utime, t->utime);
175                         stime = cputime_add(stime, t->stime);
176                         t = next_thread(t);
177                 } while (t != tsk);
178
179                 /*
180                  * While we have tasklist_lock read-locked, no dying thread
181                  * can be updating current->signal->[us]time.  Instead,
182                  * we got their counts included in the live thread loop.
183                  * However, another thread can come in right now and
184                  * do a wait call that updates current->signal->c[us]time.
185                  * To make sure we always see that pair updated atomically,
186                  * we take the siglock around fetching them.
187                  */
188                 spin_lock_irq(&tsk->sighand->siglock);
189                 cutime = tsk->signal->cutime;
190                 cstime = tsk->signal->cstime;
191                 spin_unlock_irq(&tsk->sighand->siglock);
192                 read_unlock(&tasklist_lock);
193
194                 tmp.tms_utime = compat_jiffies_to_clock_t(cputime_to_jiffies(utime));
195                 tmp.tms_stime = compat_jiffies_to_clock_t(cputime_to_jiffies(stime));
196                 tmp.tms_cutime = compat_jiffies_to_clock_t(cputime_to_jiffies(cutime));
197                 tmp.tms_cstime = compat_jiffies_to_clock_t(cputime_to_jiffies(cstime));
198                 if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
199                         return -EFAULT;
200         }
201         return compat_jiffies_to_clock_t(jiffies);
202 }
203
204 /*
205  * Assumption: old_sigset_t and compat_old_sigset_t are both
206  * types that can be passed to put_user()/get_user().
207  */
208
209 asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set)
210 {
211         old_sigset_t s;
212         long ret;
213         mm_segment_t old_fs = get_fs();
214
215         set_fs(KERNEL_DS);
216         ret = sys_sigpending((old_sigset_t __user *) &s);
217         set_fs(old_fs);
218         if (ret == 0)
219                 ret = put_user(s, set);
220         return ret;
221 }
222
223 asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
224                 compat_old_sigset_t __user *oset)
225 {
226         old_sigset_t s;
227         long ret;
228         mm_segment_t old_fs;
229
230         if (set && get_user(s, set))
231                 return -EFAULT;
232         old_fs = get_fs();
233         set_fs(KERNEL_DS);
234         ret = sys_sigprocmask(how,
235                               set ? (old_sigset_t __user *) &s : NULL,
236                               oset ? (old_sigset_t __user *) &s : NULL);
237         set_fs(old_fs);
238         if (ret == 0)
239                 if (oset)
240                         ret = put_user(s, oset);
241         return ret;
242 }
243
244 asmlinkage long compat_sys_setrlimit(unsigned int resource,
245                 struct compat_rlimit __user *rlim)
246 {
247         struct rlimit r;
248         int ret;
249         mm_segment_t old_fs = get_fs ();
250
251         if (resource >= RLIM_NLIMITS)
252                 return -EINVAL;
253
254         if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
255             __get_user(r.rlim_cur, &rlim->rlim_cur) ||
256             __get_user(r.rlim_max, &rlim->rlim_max))
257                 return -EFAULT;
258
259         if (r.rlim_cur == COMPAT_RLIM_INFINITY)
260                 r.rlim_cur = RLIM_INFINITY;
261         if (r.rlim_max == COMPAT_RLIM_INFINITY)
262                 r.rlim_max = RLIM_INFINITY;
263         set_fs(KERNEL_DS);
264         ret = sys_setrlimit(resource, (struct rlimit __user *) &r);
265         set_fs(old_fs);
266         return ret;
267 }
268
269 #ifdef COMPAT_RLIM_OLD_INFINITY
270
271 asmlinkage long compat_sys_old_getrlimit(unsigned int resource,
272                 struct compat_rlimit __user *rlim)
273 {
274         struct rlimit r;
275         int ret;
276         mm_segment_t old_fs = get_fs();
277
278         set_fs(KERNEL_DS);
279         ret = sys_old_getrlimit(resource, &r);
280         set_fs(old_fs);
281
282         if (!ret) {
283                 if (r.rlim_cur > COMPAT_RLIM_OLD_INFINITY)
284                         r.rlim_cur = COMPAT_RLIM_INFINITY;
285                 if (r.rlim_max > COMPAT_RLIM_OLD_INFINITY)
286                         r.rlim_max = COMPAT_RLIM_INFINITY;
287
288                 if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
289                     __put_user(r.rlim_cur, &rlim->rlim_cur) ||
290                     __put_user(r.rlim_max, &rlim->rlim_max))
291                         return -EFAULT;
292         }
293         return ret;
294 }
295
296 #endif
297
298 asmlinkage long compat_sys_getrlimit (unsigned int resource,
299                 struct compat_rlimit __user *rlim)
300 {
301         struct rlimit r;
302         int ret;
303         mm_segment_t old_fs = get_fs();
304
305         set_fs(KERNEL_DS);
306         ret = sys_getrlimit(resource, (struct rlimit __user *) &r);
307         set_fs(old_fs);
308         if (!ret) {
309                 if (r.rlim_cur > COMPAT_RLIM_INFINITY)
310                         r.rlim_cur = COMPAT_RLIM_INFINITY;
311                 if (r.rlim_max > COMPAT_RLIM_INFINITY)
312                         r.rlim_max = COMPAT_RLIM_INFINITY;
313
314                 if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
315                     __put_user(r.rlim_cur, &rlim->rlim_cur) ||
316                     __put_user(r.rlim_max, &rlim->rlim_max))
317                         return -EFAULT;
318         }
319         return ret;
320 }
321
322 int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
323 {
324         if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
325             __put_user(r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
326             __put_user(r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
327             __put_user(r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
328             __put_user(r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
329             __put_user(r->ru_maxrss, &ru->ru_maxrss) ||
330             __put_user(r->ru_ixrss, &ru->ru_ixrss) ||
331             __put_user(r->ru_idrss, &ru->ru_idrss) ||
332             __put_user(r->ru_isrss, &ru->ru_isrss) ||
333             __put_user(r->ru_minflt, &ru->ru_minflt) ||
334             __put_user(r->ru_majflt, &ru->ru_majflt) ||
335             __put_user(r->ru_nswap, &ru->ru_nswap) ||
336             __put_user(r->ru_inblock, &ru->ru_inblock) ||
337             __put_user(r->ru_oublock, &ru->ru_oublock) ||
338             __put_user(r->ru_msgsnd, &ru->ru_msgsnd) ||
339             __put_user(r->ru_msgrcv, &ru->ru_msgrcv) ||
340             __put_user(r->ru_nsignals, &ru->ru_nsignals) ||
341             __put_user(r->ru_nvcsw, &ru->ru_nvcsw) ||
342             __put_user(r->ru_nivcsw, &ru->ru_nivcsw))
343                 return -EFAULT;
344         return 0;
345 }
346
347 asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru)
348 {
349         struct rusage r;
350         int ret;
351         mm_segment_t old_fs = get_fs();
352
353         set_fs(KERNEL_DS);
354         ret = sys_getrusage(who, (struct rusage __user *) &r);
355         set_fs(old_fs);
356
357         if (ret)
358                 return ret;
359
360         if (put_compat_rusage(&r, ru))
361                 return -EFAULT;
362
363         return 0;
364 }
365
366 asmlinkage long
367 compat_sys_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options,
368         struct compat_rusage __user *ru)
369 {
370         if (!ru) {
371                 return sys_wait4(pid, stat_addr, options, NULL);
372         } else {
373                 struct rusage r;
374                 int ret;
375                 unsigned int status;
376                 mm_segment_t old_fs = get_fs();
377
378                 set_fs (KERNEL_DS);
379                 ret = sys_wait4(pid,
380                                 (stat_addr ?
381                                  (unsigned int __user *) &status : NULL),
382                                 options, (struct rusage __user *) &r);
383                 set_fs (old_fs);
384
385                 if (ret > 0) {
386                         if (put_compat_rusage(&r, ru))
387                                 return -EFAULT;
388                         if (stat_addr && put_user(status, stat_addr))
389                                 return -EFAULT;
390                 }
391                 return ret;
392         }
393 }
394
395 asmlinkage long compat_sys_waitid(int which, compat_pid_t pid,
396                 struct compat_siginfo __user *uinfo, int options,
397                 struct compat_rusage __user *uru)
398 {
399         siginfo_t info;
400         struct rusage ru;
401         long ret;
402         mm_segment_t old_fs = get_fs();
403
404         memset(&info, 0, sizeof(info));
405
406         set_fs(KERNEL_DS);
407         ret = sys_waitid(which, pid, (siginfo_t __user *)&info, options,
408                          uru ? (struct rusage __user *)&ru : NULL);
409         set_fs(old_fs);
410
411         if ((ret < 0) || (info.si_signo == 0))
412                 return ret;
413
414         if (uru) {
415                 ret = put_compat_rusage(&ru, uru);
416                 if (ret)
417                         return ret;
418         }
419
420         BUG_ON(info.si_code & __SI_MASK);
421         info.si_code |= __SI_CHLD;
422         return copy_siginfo_to_user32(uinfo, &info);
423 }
424
425 static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr,
426                                     unsigned len, cpumask_t *new_mask)
427 {
428         unsigned long *k;
429
430         if (len < sizeof(cpumask_t))
431                 memset(new_mask, 0, sizeof(cpumask_t));
432         else if (len > sizeof(cpumask_t))
433                 len = sizeof(cpumask_t);
434
435         k = cpus_addr(*new_mask);
436         return compat_get_bitmap(k, user_mask_ptr, len * 8);
437 }
438
439 asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
440                                              unsigned int len,
441                                              compat_ulong_t __user *user_mask_ptr)
442 {
443         cpumask_t new_mask;
444         int retval;
445
446         retval = compat_get_user_cpu_mask(user_mask_ptr, len, &new_mask);
447         if (retval)
448                 return retval;
449
450         return sched_setaffinity(pid, new_mask);
451 }
452
453 asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
454                                              compat_ulong_t __user *user_mask_ptr)
455 {
456         int ret;
457         cpumask_t mask;
458         unsigned long *k;
459         unsigned int min_length = sizeof(cpumask_t);
460
461         if (NR_CPUS <= BITS_PER_COMPAT_LONG)
462                 min_length = sizeof(compat_ulong_t);
463
464         if (len < min_length)
465                 return -EINVAL;
466
467         ret = sched_getaffinity(pid, &mask);
468         if (ret < 0)
469                 return ret;
470
471         k = cpus_addr(mask);
472         ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8);
473         if (ret)
474                 return ret;
475
476         return min_length;
477 }
478
479 int get_compat_itimerspec(struct itimerspec *dst,
480                           const struct compat_itimerspec __user *src)
481 {
482         if (get_compat_timespec(&dst->it_interval, &src->it_interval) ||
483             get_compat_timespec(&dst->it_value, &src->it_value))
484                 return -EFAULT;
485         return 0;
486 }
487
488 int put_compat_itimerspec(struct compat_itimerspec __user *dst,
489                           const struct itimerspec *src)
490 {
491         if (put_compat_timespec(&src->it_interval, &dst->it_interval) ||
492             put_compat_timespec(&src->it_value, &dst->it_value))
493                 return -EFAULT;
494         return 0;
495 }
496
497 long compat_sys_timer_create(clockid_t which_clock,
498                         struct compat_sigevent __user *timer_event_spec,
499                         timer_t __user *created_timer_id)
500 {
501         struct sigevent __user *event = NULL;
502
503         if (timer_event_spec) {
504                 struct sigevent kevent;
505
506                 event = compat_alloc_user_space(sizeof(*event));
507                 if (get_compat_sigevent(&kevent, timer_event_spec) ||
508                     copy_to_user(event, &kevent, sizeof(*event)))
509                         return -EFAULT;
510         }
511
512         return sys_timer_create(which_clock, event, created_timer_id);
513 }
514
515 long compat_sys_timer_settime(timer_t timer_id, int flags,
516                           struct compat_itimerspec __user *new,
517                           struct compat_itimerspec __user *old)
518 {
519         long err;
520         mm_segment_t oldfs;
521         struct itimerspec newts, oldts;
522
523         if (!new)
524                 return -EINVAL;
525         if (get_compat_itimerspec(&newts, new))
526                 return -EFAULT;
527         oldfs = get_fs();
528         set_fs(KERNEL_DS);
529         err = sys_timer_settime(timer_id, flags,
530                                 (struct itimerspec __user *) &newts,
531                                 (struct itimerspec __user *) &oldts);
532         set_fs(oldfs);
533         if (!err && old && put_compat_itimerspec(old, &oldts))
534                 return -EFAULT;
535         return err;
536 }
537
538 long compat_sys_timer_gettime(timer_t timer_id,
539                 struct compat_itimerspec __user *setting)
540 {
541         long err;
542         mm_segment_t oldfs;
543         struct itimerspec ts;
544
545         oldfs = get_fs();
546         set_fs(KERNEL_DS);
547         err = sys_timer_gettime(timer_id,
548                                 (struct itimerspec __user *) &ts);
549         set_fs(oldfs);
550         if (!err && put_compat_itimerspec(setting, &ts))
551                 return -EFAULT;
552         return err;
553 }
554
555 long compat_sys_clock_settime(clockid_t which_clock,
556                 struct compat_timespec __user *tp)
557 {
558         long err;
559         mm_segment_t oldfs;
560         struct timespec ts;
561
562         if (get_compat_timespec(&ts, tp))
563                 return -EFAULT;
564         oldfs = get_fs();
565         set_fs(KERNEL_DS);
566         err = sys_clock_settime(which_clock,
567                                 (struct timespec __user *) &ts);
568         set_fs(oldfs);
569         return err;
570 }
571
572 long compat_sys_clock_gettime(clockid_t which_clock,
573                 struct compat_timespec __user *tp)
574 {
575         long err;
576         mm_segment_t oldfs;
577         struct timespec ts;
578
579         oldfs = get_fs();
580         set_fs(KERNEL_DS);
581         err = sys_clock_gettime(which_clock,
582                                 (struct timespec __user *) &ts);
583         set_fs(oldfs);
584         if (!err && put_compat_timespec(&ts, tp))
585                 return -EFAULT;
586         return err;
587 }
588
589 long compat_sys_clock_getres(clockid_t which_clock,
590                 struct compat_timespec __user *tp)
591 {
592         long err;
593         mm_segment_t oldfs;
594         struct timespec ts;
595
596         oldfs = get_fs();
597         set_fs(KERNEL_DS);
598         err = sys_clock_getres(which_clock,
599                                (struct timespec __user *) &ts);
600         set_fs(oldfs);
601         if (!err && tp && put_compat_timespec(&ts, tp))
602                 return -EFAULT;
603         return err;
604 }
605
606 static long compat_clock_nanosleep_restart(struct restart_block *restart)
607 {
608         long err;
609         mm_segment_t oldfs;
610         struct timespec tu;
611         struct compat_timespec *rmtp = (struct compat_timespec *)(restart->arg1);
612
613         restart->arg1 = (unsigned long) &tu;
614         oldfs = get_fs();
615         set_fs(KERNEL_DS);
616         err = clock_nanosleep_restart(restart);
617         set_fs(oldfs);
618
619         if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
620             put_compat_timespec(&tu, rmtp))
621                 return -EFAULT;
622
623         if (err == -ERESTART_RESTARTBLOCK) {
624                 restart->fn = compat_clock_nanosleep_restart;
625                 restart->arg1 = (unsigned long) rmtp;
626         }
627         return err;
628 }
629
630 long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
631                             struct compat_timespec __user *rqtp,
632                             struct compat_timespec __user *rmtp)
633 {
634         long err;
635         mm_segment_t oldfs;
636         struct timespec in, out;
637         struct restart_block *restart;
638
639         if (get_compat_timespec(&in, rqtp))
640                 return -EFAULT;
641
642         oldfs = get_fs();
643         set_fs(KERNEL_DS);
644         err = sys_clock_nanosleep(which_clock, flags,
645                                   (struct timespec __user *) &in,
646                                   (struct timespec __user *) &out);
647         set_fs(oldfs);
648
649         if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
650             put_compat_timespec(&out, rmtp))
651                 return -EFAULT;
652
653         if (err == -ERESTART_RESTARTBLOCK) {
654                 restart = &current_thread_info()->restart_block;
655                 restart->fn = compat_clock_nanosleep_restart;
656                 restart->arg1 = (unsigned long) rmtp;
657         }
658         return err;
659 }
660
661 /*
662  * We currently only need the following fields from the sigevent
663  * structure: sigev_value, sigev_signo, sig_notify and (sometimes
664  * sigev_notify_thread_id).  The others are handled in user mode.
665  * We also assume that copying sigev_value.sival_int is sufficient
666  * to keep all the bits of sigev_value.sival_ptr intact.
667  */
668 int get_compat_sigevent(struct sigevent *event,
669                 const struct compat_sigevent __user *u_event)
670 {
671         memset(event, 0, sizeof(*event));
672         return (!access_ok(VERIFY_READ, u_event, sizeof(*u_event)) ||
673                 __get_user(event->sigev_value.sival_int,
674                         &u_event->sigev_value.sival_int) ||
675                 __get_user(event->sigev_signo, &u_event->sigev_signo) ||
676                 __get_user(event->sigev_notify, &u_event->sigev_notify) ||
677                 __get_user(event->sigev_notify_thread_id,
678                         &u_event->sigev_notify_thread_id))
679                 ? -EFAULT : 0;
680 }
681
682 long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
683                        unsigned long bitmap_size)
684 {
685         int i, j;
686         unsigned long m;
687         compat_ulong_t um;
688         unsigned long nr_compat_longs;
689
690         /* align bitmap up to nearest compat_long_t boundary */
691         bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
692
693         if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
694                 return -EFAULT;
695
696         nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
697
698         for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
699                 m = 0;
700
701                 for (j = 0; j < sizeof(m)/sizeof(um); j++) {
702                         /*
703                          * We dont want to read past the end of the userspace
704                          * bitmap. We must however ensure the end of the
705                          * kernel bitmap is zeroed.
706                          */
707                         if (nr_compat_longs-- > 0) {
708                                 if (__get_user(um, umask))
709                                         return -EFAULT;
710                         } else {
711                                 um = 0;
712                         }
713
714                         umask++;
715                         m |= (long)um << (j * BITS_PER_COMPAT_LONG);
716                 }
717                 *mask++ = m;
718         }
719
720         return 0;
721 }
722
723 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
724                        unsigned long bitmap_size)
725 {
726         int i, j;
727         unsigned long m;
728         compat_ulong_t um;
729         unsigned long nr_compat_longs;
730
731         /* align bitmap up to nearest compat_long_t boundary */
732         bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
733
734         if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
735                 return -EFAULT;
736
737         nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
738
739         for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
740                 m = *mask++;
741
742                 for (j = 0; j < sizeof(m)/sizeof(um); j++) {
743                         um = m;
744
745                         /*
746                          * We dont want to write past the end of the userspace
747                          * bitmap.
748                          */
749                         if (nr_compat_longs-- > 0) {
750                                 if (__put_user(um, umask))
751                                         return -EFAULT;
752                         }
753
754                         umask++;
755                         m >>= 4*sizeof(um);
756                         m >>= 4*sizeof(um);
757                 }
758         }
759
760         return 0;
761 }
762
763 void
764 sigset_from_compat (sigset_t *set, compat_sigset_t *compat)
765 {
766         switch (_NSIG_WORDS) {
767         case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
768         case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 );
769         case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 );
770         case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
771         }
772 }
773
774 asmlinkage long
775 compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
776                 struct compat_siginfo __user *uinfo,
777                 struct compat_timespec __user *uts, compat_size_t sigsetsize)
778 {
779         compat_sigset_t s32;
780         sigset_t s;
781         int sig;
782         struct timespec t;
783         siginfo_t info;
784         long ret, timeout = 0;
785
786         if (sigsetsize != sizeof(sigset_t))
787                 return -EINVAL;
788
789         if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
790                 return -EFAULT;
791         sigset_from_compat(&s, &s32);
792         sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP));
793         signotset(&s);
794
795         if (uts) {
796                 if (get_compat_timespec (&t, uts))
797                         return -EFAULT;
798                 if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0
799                                 || t.tv_sec < 0)
800                         return -EINVAL;
801         }
802
803         spin_lock_irq(&current->sighand->siglock);
804         sig = dequeue_signal(current, &s, &info);
805         if (!sig) {
806                 timeout = MAX_SCHEDULE_TIMEOUT;
807                 if (uts)
808                         timeout = timespec_to_jiffies(&t)
809                                 +(t.tv_sec || t.tv_nsec);
810                 if (timeout) {
811                         current->real_blocked = current->blocked;
812                         sigandsets(&current->blocked, &current->blocked, &s);
813
814                         recalc_sigpending();
815                         spin_unlock_irq(&current->sighand->siglock);
816
817                         timeout = schedule_timeout_interruptible(timeout);
818
819                         spin_lock_irq(&current->sighand->siglock);
820                         sig = dequeue_signal(current, &s, &info);
821                         current->blocked = current->real_blocked;
822                         siginitset(&current->real_blocked, 0);
823                         recalc_sigpending();
824                 }
825         }
826         spin_unlock_irq(&current->sighand->siglock);
827
828         if (sig) {
829                 ret = sig;
830                 if (uinfo) {
831                         if (copy_siginfo_to_user32(uinfo, &info))
832                                 ret = -EFAULT;
833                 }
834         }else {
835                 ret = timeout?-EINTR:-EAGAIN;
836         }
837         return ret;
838
839 }
840
841 #ifdef __ARCH_WANT_COMPAT_SYS_TIME
842
843 /* compat_time_t is a 32 bit "long" and needs to get converted. */
844
845 asmlinkage long compat_sys_time(compat_time_t __user * tloc)
846 {
847         compat_time_t i;
848         struct timeval tv;
849
850         do_gettimeofday(&tv);
851         i = tv.tv_sec;
852
853         if (tloc) {
854                 if (put_user(i,tloc))
855                         i = -EFAULT;
856         }
857         return i;
858 }
859
860 asmlinkage long compat_sys_stime(compat_time_t __user *tptr)
861 {
862         struct timespec tv;
863         int err;
864
865         if (get_user(tv.tv_sec, tptr))
866                 return -EFAULT;
867
868         tv.tv_nsec = 0;
869
870         err = security_settime(&tv, NULL);
871         if (err)
872                 return err;
873
874         do_settimeofday(&tv);
875         return 0;
876 }
877
878 #endif /* __ARCH_WANT_COMPAT_SYS_TIME */
879
880 #ifdef __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
881 asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat_size_t sigsetsize)
882 {
883         sigset_t newset;
884         compat_sigset_t newset32;
885
886         /* XXX: Don't preclude handling different sized sigset_t's.  */
887         if (sigsetsize != sizeof(sigset_t))
888                 return -EINVAL;
889
890         if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
891                 return -EFAULT;
892         sigset_from_compat(&newset, &newset32);
893         sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
894
895         spin_lock_irq(&current->sighand->siglock);
896         current->saved_sigmask = current->blocked;
897         current->blocked = newset;
898         recalc_sigpending();
899         spin_unlock_irq(&current->sighand->siglock);
900
901         current->state = TASK_INTERRUPTIBLE;
902         schedule();
903         set_thread_flag(TIF_RESTORE_SIGMASK);
904         return -ERESTARTNOHAND;
905 }
906 #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
907
908 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp)
909 {
910         struct timex txc;
911         int ret;
912
913         memset(&txc, 0, sizeof(struct timex));
914
915         if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) ||
916                         __get_user(txc.modes, &utp->modes) ||
917                         __get_user(txc.offset, &utp->offset) ||
918                         __get_user(txc.freq, &utp->freq) ||
919                         __get_user(txc.maxerror, &utp->maxerror) ||
920                         __get_user(txc.esterror, &utp->esterror) ||
921                         __get_user(txc.status, &utp->status) ||
922                         __get_user(txc.constant, &utp->constant) ||
923                         __get_user(txc.precision, &utp->precision) ||
924                         __get_user(txc.tolerance, &utp->tolerance) ||
925                         __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
926                         __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
927                         __get_user(txc.tick, &utp->tick) ||
928                         __get_user(txc.ppsfreq, &utp->ppsfreq) ||
929                         __get_user(txc.jitter, &utp->jitter) ||
930                         __get_user(txc.shift, &utp->shift) ||
931                         __get_user(txc.stabil, &utp->stabil) ||
932                         __get_user(txc.jitcnt, &utp->jitcnt) ||
933                         __get_user(txc.calcnt, &utp->calcnt) ||
934                         __get_user(txc.errcnt, &utp->errcnt) ||
935                         __get_user(txc.stbcnt, &utp->stbcnt))
936                 return -EFAULT;
937
938         ret = do_adjtimex(&txc);
939
940         if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) ||
941                         __put_user(txc.modes, &utp->modes) ||
942                         __put_user(txc.offset, &utp->offset) ||
943                         __put_user(txc.freq, &utp->freq) ||
944                         __put_user(txc.maxerror, &utp->maxerror) ||
945                         __put_user(txc.esterror, &utp->esterror) ||
946                         __put_user(txc.status, &utp->status) ||
947                         __put_user(txc.constant, &utp->constant) ||
948                         __put_user(txc.precision, &utp->precision) ||
949                         __put_user(txc.tolerance, &utp->tolerance) ||
950                         __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
951                         __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
952                         __put_user(txc.tick, &utp->tick) ||
953                         __put_user(txc.ppsfreq, &utp->ppsfreq) ||
954                         __put_user(txc.jitter, &utp->jitter) ||
955                         __put_user(txc.shift, &utp->shift) ||
956                         __put_user(txc.stabil, &utp->stabil) ||
957                         __put_user(txc.jitcnt, &utp->jitcnt) ||
958                         __put_user(txc.calcnt, &utp->calcnt) ||
959                         __put_user(txc.errcnt, &utp->errcnt) ||
960                         __put_user(txc.stbcnt, &utp->stbcnt))
961                 ret = -EFAULT;
962
963         return ret;
964 }
965
966 #ifdef CONFIG_NUMA
967 asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_pages,
968                 compat_uptr_t __user *pages32,
969                 const int __user *nodes,
970                 int __user *status,
971                 int flags)
972 {
973         const void __user * __user *pages;
974         int i;
975
976         pages = compat_alloc_user_space(nr_pages * sizeof(void *));
977         for (i = 0; i < nr_pages; i++) {
978                 compat_uptr_t p;
979
980                 if (get_user(p, pages32 + i) ||
981                         put_user(compat_ptr(p), pages + i))
982                         return -EFAULT;
983         }
984         return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
985 }
986
987 asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
988                         compat_ulong_t maxnode,
989                         const compat_ulong_t __user *old_nodes,
990                         const compat_ulong_t __user *new_nodes)
991 {
992         unsigned long __user *old = NULL;
993         unsigned long __user *new = NULL;
994         nodemask_t tmp_mask;
995         unsigned long nr_bits;
996         unsigned long size;
997
998         nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES);
999         size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
1000         if (old_nodes) {
1001                 if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits))
1002                         return -EFAULT;
1003                 old = compat_alloc_user_space(new_nodes ? size * 2 : size);
1004                 if (new_nodes)
1005                         new = old + size / sizeof(unsigned long);
1006                 if (copy_to_user(old, nodes_addr(tmp_mask), size))
1007                         return -EFAULT;
1008         }
1009         if (new_nodes) {
1010                 if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits))
1011                         return -EFAULT;
1012                 if (new == NULL)
1013                         new = compat_alloc_user_space(size);
1014                 if (copy_to_user(new, nodes_addr(tmp_mask), size))
1015                         return -EFAULT;
1016         }
1017         return sys_migrate_pages(pid, nr_bits + 1, old, new);
1018 }
1019 #endif
1020
1021 struct compat_sysinfo {
1022         s32 uptime;
1023         u32 loads[3];
1024         u32 totalram;
1025         u32 freeram;
1026         u32 sharedram;
1027         u32 bufferram;
1028         u32 totalswap;
1029         u32 freeswap;
1030         u16 procs;
1031         u16 pad;
1032         u32 totalhigh;
1033         u32 freehigh;
1034         u32 mem_unit;
1035         char _f[20-2*sizeof(u32)-sizeof(int)];
1036 };
1037
1038 asmlinkage long
1039 compat_sys_sysinfo(struct compat_sysinfo __user *info)
1040 {
1041         struct sysinfo s;
1042
1043         do_sysinfo(&s);
1044
1045         /* Check to see if any memory value is too large for 32-bit and scale
1046          *  down if needed
1047          */
1048         if ((s.totalram >> 32) || (s.totalswap >> 32)) {
1049                 int bitcount = 0;
1050
1051                 while (s.mem_unit < PAGE_SIZE) {
1052                         s.mem_unit <<= 1;
1053                         bitcount++;
1054                 }
1055
1056                 s.totalram >>= bitcount;
1057                 s.freeram >>= bitcount;
1058                 s.sharedram >>= bitcount;
1059                 s.bufferram >>= bitcount;
1060                 s.totalswap >>= bitcount;
1061                 s.freeswap >>= bitcount;
1062                 s.totalhigh >>= bitcount;
1063                 s.freehigh >>= bitcount;
1064         }
1065
1066         if (!access_ok(VERIFY_WRITE, info, sizeof(struct compat_sysinfo)) ||
1067             __put_user (s.uptime, &info->uptime) ||
1068             __put_user (s.loads[0], &info->loads[0]) ||
1069             __put_user (s.loads[1], &info->loads[1]) ||
1070             __put_user (s.loads[2], &info->loads[2]) ||
1071             __put_user (s.totalram, &info->totalram) ||
1072             __put_user (s.freeram, &info->freeram) ||
1073             __put_user (s.sharedram, &info->sharedram) ||
1074             __put_user (s.bufferram, &info->bufferram) ||
1075             __put_user (s.totalswap, &info->totalswap) ||
1076             __put_user (s.freeswap, &info->freeswap) ||
1077             __put_user (s.procs, &info->procs) ||
1078             __put_user (s.totalhigh, &info->totalhigh) ||
1079             __put_user (s.freehigh, &info->freehigh) ||
1080             __put_user (s.mem_unit, &info->mem_unit))
1081                 return -EFAULT;
1082
1083         return 0;
1084 }
1085