Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
compat.c
Go to the documentation of this file.
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/export.h>
25 #include <linux/migrate.h>
26 #include <linux/posix-timers.h>
27 #include <linux/times.h>
28 #include <linux/ptrace.h>
29 #include <linux/gfp.h>
30 
31 #include <asm/uaccess.h>
32 
33 /*
34  * Get/set struct timeval with struct timespec on the native side
35  */
36 static int compat_get_timeval_convert(struct timespec *o,
37  struct compat_timeval __user *i)
38 {
39  long usec;
40 
41  if (get_user(o->tv_sec, &i->tv_sec) ||
42  get_user(usec, &i->tv_usec))
43  return -EFAULT;
44  o->tv_nsec = usec * 1000;
45  return 0;
46 }
47 
48 static int compat_put_timeval_convert(struct compat_timeval __user *o,
49  struct timeval *i)
50 {
51  return (put_user(i->tv_sec, &o->tv_sec) ||
52  put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0;
53 }
54 
55 static int compat_get_timex(struct timex *txc, struct compat_timex __user *utp)
56 {
57  memset(txc, 0, sizeof(struct timex));
58 
59  if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) ||
60  __get_user(txc->modes, &utp->modes) ||
61  __get_user(txc->offset, &utp->offset) ||
62  __get_user(txc->freq, &utp->freq) ||
63  __get_user(txc->maxerror, &utp->maxerror) ||
64  __get_user(txc->esterror, &utp->esterror) ||
65  __get_user(txc->status, &utp->status) ||
66  __get_user(txc->constant, &utp->constant) ||
67  __get_user(txc->precision, &utp->precision) ||
68  __get_user(txc->tolerance, &utp->tolerance) ||
69  __get_user(txc->time.tv_sec, &utp->time.tv_sec) ||
70  __get_user(txc->time.tv_usec, &utp->time.tv_usec) ||
71  __get_user(txc->tick, &utp->tick) ||
72  __get_user(txc->ppsfreq, &utp->ppsfreq) ||
73  __get_user(txc->jitter, &utp->jitter) ||
74  __get_user(txc->shift, &utp->shift) ||
75  __get_user(txc->stabil, &utp->stabil) ||
76  __get_user(txc->jitcnt, &utp->jitcnt) ||
77  __get_user(txc->calcnt, &utp->calcnt) ||
78  __get_user(txc->errcnt, &utp->errcnt) ||
79  __get_user(txc->stbcnt, &utp->stbcnt))
80  return -EFAULT;
81 
82  return 0;
83 }
84 
85 static int compat_put_timex(struct compat_timex __user *utp, struct timex *txc)
86 {
87  if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) ||
88  __put_user(txc->modes, &utp->modes) ||
89  __put_user(txc->offset, &utp->offset) ||
90  __put_user(txc->freq, &utp->freq) ||
91  __put_user(txc->maxerror, &utp->maxerror) ||
92  __put_user(txc->esterror, &utp->esterror) ||
93  __put_user(txc->status, &utp->status) ||
94  __put_user(txc->constant, &utp->constant) ||
95  __put_user(txc->precision, &utp->precision) ||
96  __put_user(txc->tolerance, &utp->tolerance) ||
97  __put_user(txc->time.tv_sec, &utp->time.tv_sec) ||
98  __put_user(txc->time.tv_usec, &utp->time.tv_usec) ||
99  __put_user(txc->tick, &utp->tick) ||
100  __put_user(txc->ppsfreq, &utp->ppsfreq) ||
101  __put_user(txc->jitter, &utp->jitter) ||
102  __put_user(txc->shift, &utp->shift) ||
103  __put_user(txc->stabil, &utp->stabil) ||
104  __put_user(txc->jitcnt, &utp->jitcnt) ||
105  __put_user(txc->calcnt, &utp->calcnt) ||
106  __put_user(txc->errcnt, &utp->errcnt) ||
107  __put_user(txc->stbcnt, &utp->stbcnt) ||
108  __put_user(txc->tai, &utp->tai))
109  return -EFAULT;
110  return 0;
111 }
112 
114  struct timezone __user *tz)
115 {
116  if (tv) {
117  struct timeval ktv;
118  do_gettimeofday(&ktv);
119  if (compat_put_timeval_convert(tv, &ktv))
120  return -EFAULT;
121  }
122  if (tz) {
123  if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
124  return -EFAULT;
125  }
126 
127  return 0;
128 }
129 
131  struct timezone __user *tz)
132 {
133  struct timespec kts;
134  struct timezone ktz;
135 
136  if (tv) {
137  if (compat_get_timeval_convert(&kts, tv))
138  return -EFAULT;
139  }
140  if (tz) {
141  if (copy_from_user(&ktz, tz, sizeof(ktz)))
142  return -EFAULT;
143  }
144 
145  return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
146 }
147 
148 int get_compat_timeval(struct timeval *tv, const struct compat_timeval __user *ctv)
149 {
150  return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
151  __get_user(tv->tv_sec, &ctv->tv_sec) ||
152  __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
153 }
155 
156 int put_compat_timeval(const struct timeval *tv, struct compat_timeval __user *ctv)
157 {
158  return (!access_ok(VERIFY_WRITE, ctv, sizeof(*ctv)) ||
159  __put_user(tv->tv_sec, &ctv->tv_sec) ||
160  __put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
161 }
163 
164 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
165 {
166  return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
167  __get_user(ts->tv_sec, &cts->tv_sec) ||
168  __get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
169 }
171 
172 int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user *cts)
173 {
174  return (!access_ok(VERIFY_WRITE, cts, sizeof(*cts)) ||
175  __put_user(ts->tv_sec, &cts->tv_sec) ||
176  __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
177 }
179 
180 int compat_get_timeval(struct timeval *tv, const void __user *utv)
181 {
182  if (COMPAT_USE_64BIT_TIME)
183  return copy_from_user(tv, utv, sizeof *tv) ? -EFAULT : 0;
184  else
185  return get_compat_timeval(tv, utv);
186 }
188 
189 int compat_put_timeval(const struct timeval *tv, void __user *utv)
190 {
191  if (COMPAT_USE_64BIT_TIME)
192  return copy_to_user(utv, tv, sizeof *tv) ? -EFAULT : 0;
193  else
194  return put_compat_timeval(tv, utv);
195 }
197 
198 int compat_get_timespec(struct timespec *ts, const void __user *uts)
199 {
200  if (COMPAT_USE_64BIT_TIME)
201  return copy_from_user(ts, uts, sizeof *ts) ? -EFAULT : 0;
202  else
203  return get_compat_timespec(ts, uts);
204 }
206 
207 int compat_put_timespec(const struct timespec *ts, void __user *uts)
208 {
209  if (COMPAT_USE_64BIT_TIME)
210  return copy_to_user(uts, ts, sizeof *ts) ? -EFAULT : 0;
211  else
212  return put_compat_timespec(ts, uts);
213 }
215 
216 static 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 
223  restart->nanosleep.rmtp = (struct timespec __user *) &rmt;
224  oldfs = get_fs();
225  set_fs(KERNEL_DS);
226  ret = hrtimer_nanosleep_restart(restart);
227  set_fs(oldfs);
228 
229  if (ret) {
230  rmtp = restart->nanosleep.compat_rmtp;
231 
232  if (rmtp && put_compat_timespec(&rmt, rmtp))
233  return -EFAULT;
234  }
235 
236  return ret;
237 }
238 
240  struct compat_timespec __user *rmtp)
241 {
242  struct timespec tu, rmt;
243  mm_segment_t oldfs;
244  long ret;
245 
246  if (get_compat_timespec(&tu, rqtp))
247  return -EFAULT;
248 
249  if (!timespec_valid(&tu))
250  return -EINVAL;
251 
252  oldfs = get_fs();
253  set_fs(KERNEL_DS);
254  ret = hrtimer_nanosleep(&tu,
255  rmtp ? (struct timespec __user *)&rmt : NULL,
257  set_fs(oldfs);
258 
259  if (ret) {
260  struct restart_block *restart
261  = &current_thread_info()->restart_block;
262 
263  restart->fn = compat_nanosleep_restart;
264  restart->nanosleep.compat_rmtp = rmtp;
265 
266  if (rmtp && put_compat_timespec(&rmt, rmtp))
267  return -EFAULT;
268  }
269 
270  return ret;
271 }
272 
273 static inline long get_compat_itimerval(struct itimerval *o,
274  struct compat_itimerval __user *i)
275 {
276  return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
277  (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
278  __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
279  __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
280  __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
281 }
282 
283 static inline long put_compat_itimerval(struct compat_itimerval __user *o,
284  struct itimerval *i)
285 {
286  return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
287  (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
288  __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
289  __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
290  __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
291 }
292 
294  struct compat_itimerval __user *it)
295 {
296  struct itimerval kit;
297  int error;
298 
299  error = do_getitimer(which, &kit);
300  if (!error && put_compat_itimerval(it, &kit))
301  error = -EFAULT;
302  return error;
303 }
304 
306  struct compat_itimerval __user *in,
307  struct compat_itimerval __user *out)
308 {
309  struct itimerval kin, kout;
310  int error;
311 
312  if (in) {
313  if (get_compat_itimerval(&kin, in))
314  return -EFAULT;
315  } else
316  memset(&kin, 0, sizeof(kin));
317 
318  error = do_setitimer(which, &kin, out ? &kout : NULL);
319  if (error || !out)
320  return error;
321  if (put_compat_itimerval(out, &kout))
322  return -EFAULT;
323  return 0;
324 }
325 
326 static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
327 {
328  return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
329 }
330 
331 asmlinkage long compat_sys_times(struct compat_tms __user *tbuf)
332 {
333  if (tbuf) {
334  struct tms tms;
335  struct compat_tms tmp;
336 
337  do_sys_times(&tms);
338  /* Convert our struct tms to the compat version. */
339  tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
340  tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
341  tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
342  tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
343  if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
344  return -EFAULT;
345  }
347  return compat_jiffies_to_clock_t(jiffies);
348 }
349 
350 #ifdef __ARCH_WANT_SYS_SIGPENDING
351 
352 /*
353  * Assumption: old_sigset_t and compat_old_sigset_t are both
354  * types that can be passed to put_user()/get_user().
355  */
356 
357 asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set)
358 {
359  old_sigset_t s;
360  long ret;
361  mm_segment_t old_fs = get_fs();
362 
363  set_fs(KERNEL_DS);
364  ret = sys_sigpending((old_sigset_t __user *) &s);
365  set_fs(old_fs);
366  if (ret == 0)
367  ret = put_user(s, set);
368  return ret;
369 }
370 
371 #endif
372 
373 #ifdef __ARCH_WANT_SYS_SIGPROCMASK
374 
375 /*
376  * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the
377  * blocked set of signals to the supplied signal set
378  */
379 static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set)
380 {
381  memcpy(blocked->sig, &set, sizeof(set));
382 }
383 
384 asmlinkage long compat_sys_sigprocmask(int how,
385  compat_old_sigset_t __user *nset,
386  compat_old_sigset_t __user *oset)
387 {
388  old_sigset_t old_set, new_set;
389  sigset_t new_blocked;
390 
391  old_set = current->blocked.sig[0];
392 
393  if (nset) {
394  if (get_user(new_set, nset))
395  return -EFAULT;
396  new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));
397 
398  new_blocked = current->blocked;
399 
400  switch (how) {
401  case SIG_BLOCK:
402  sigaddsetmask(&new_blocked, new_set);
403  break;
404  case SIG_UNBLOCK:
405  sigdelsetmask(&new_blocked, new_set);
406  break;
407  case SIG_SETMASK:
408  compat_sig_setmask(&new_blocked, new_set);
409  break;
410  default:
411  return -EINVAL;
412  }
413 
414  set_current_blocked(&new_blocked);
415  }
416 
417  if (oset) {
418  if (put_user(old_set, oset))
419  return -EFAULT;
420  }
421 
422  return 0;
423 }
424 
425 #endif
426 
428  struct compat_rlimit __user *rlim)
429 {
430  struct rlimit r;
431 
432  if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
433  __get_user(r.rlim_cur, &rlim->rlim_cur) ||
434  __get_user(r.rlim_max, &rlim->rlim_max))
435  return -EFAULT;
436 
441  return do_prlimit(current, resource, &r, NULL);
442 }
443 
444 #ifdef COMPAT_RLIM_OLD_INFINITY
445 
446 asmlinkage long compat_sys_old_getrlimit(unsigned int resource,
447  struct compat_rlimit __user *rlim)
448 {
449  struct rlimit r;
450  int ret;
451  mm_segment_t old_fs = get_fs();
452 
453  set_fs(KERNEL_DS);
454  ret = sys_old_getrlimit(resource, &r);
455  set_fs(old_fs);
456 
457  if (!ret) {
458  if (r.rlim_cur > COMPAT_RLIM_OLD_INFINITY)
459  r.rlim_cur = COMPAT_RLIM_INFINITY;
460  if (r.rlim_max > COMPAT_RLIM_OLD_INFINITY)
461  r.rlim_max = COMPAT_RLIM_INFINITY;
462 
463  if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
464  __put_user(r.rlim_cur, &rlim->rlim_cur) ||
465  __put_user(r.rlim_max, &rlim->rlim_max))
466  return -EFAULT;
467  }
468  return ret;
469 }
470 
471 #endif
472 
473 asmlinkage long compat_sys_getrlimit(unsigned int resource,
474  struct compat_rlimit __user *rlim)
475 {
476  struct rlimit r;
477  int ret;
478 
479  ret = do_prlimit(current, resource, NULL, &r);
480  if (!ret) {
485 
486  if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
487  __put_user(r.rlim_cur, &rlim->rlim_cur) ||
488  __put_user(r.rlim_max, &rlim->rlim_max))
489  return -EFAULT;
490  }
491  return ret;
492 }
493 
494 int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
495 {
496  if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
497  __put_user(r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
498  __put_user(r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
499  __put_user(r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
500  __put_user(r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
501  __put_user(r->ru_maxrss, &ru->ru_maxrss) ||
502  __put_user(r->ru_ixrss, &ru->ru_ixrss) ||
503  __put_user(r->ru_idrss, &ru->ru_idrss) ||
504  __put_user(r->ru_isrss, &ru->ru_isrss) ||
505  __put_user(r->ru_minflt, &ru->ru_minflt) ||
506  __put_user(r->ru_majflt, &ru->ru_majflt) ||
507  __put_user(r->ru_nswap, &ru->ru_nswap) ||
508  __put_user(r->ru_inblock, &ru->ru_inblock) ||
509  __put_user(r->ru_oublock, &ru->ru_oublock) ||
510  __put_user(r->ru_msgsnd, &ru->ru_msgsnd) ||
511  __put_user(r->ru_msgrcv, &ru->ru_msgrcv) ||
512  __put_user(r->ru_nsignals, &ru->ru_nsignals) ||
513  __put_user(r->ru_nvcsw, &ru->ru_nvcsw) ||
514  __put_user(r->ru_nivcsw, &ru->ru_nivcsw))
515  return -EFAULT;
516  return 0;
517 }
518 
519 asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru)
520 {
521  struct rusage r;
522  int ret;
523  mm_segment_t old_fs = get_fs();
524 
525  set_fs(KERNEL_DS);
526  ret = sys_getrusage(who, (struct rusage __user *) &r);
527  set_fs(old_fs);
528 
529  if (ret)
530  return ret;
531 
532  if (put_compat_rusage(&r, ru))
533  return -EFAULT;
534 
535  return 0;
536 }
537 
538 asmlinkage long
540  struct compat_rusage __user *ru)
541 {
542  if (!ru) {
543  return sys_wait4(pid, stat_addr, options, NULL);
544  } else {
545  struct rusage r;
546  int ret;
547  unsigned int status;
548  mm_segment_t old_fs = get_fs();
549 
550  set_fs (KERNEL_DS);
551  ret = sys_wait4(pid,
552  (stat_addr ?
553  (unsigned int __user *) &status : NULL),
554  options, (struct rusage __user *) &r);
555  set_fs (old_fs);
556 
557  if (ret > 0) {
558  if (put_compat_rusage(&r, ru))
559  return -EFAULT;
560  if (stat_addr && put_user(status, stat_addr))
561  return -EFAULT;
562  }
563  return ret;
564  }
565 }
566 
568  struct compat_siginfo __user *uinfo, int options,
569  struct compat_rusage __user *uru)
570 {
571  siginfo_t info;
572  struct rusage ru;
573  long ret;
574  mm_segment_t old_fs = get_fs();
575 
576  memset(&info, 0, sizeof(info));
577 
578  set_fs(KERNEL_DS);
579  ret = sys_waitid(which, pid, (siginfo_t __user *)&info, options,
580  uru ? (struct rusage __user *)&ru : NULL);
581  set_fs(old_fs);
582 
583  if ((ret < 0) || (info.si_signo == 0))
584  return ret;
585 
586  if (uru) {
587  ret = put_compat_rusage(&ru, uru);
588  if (ret)
589  return ret;
590  }
591 
592  BUG_ON(info.si_code & __SI_MASK);
593  info.si_code |= __SI_CHLD;
594  return copy_siginfo_to_user32(uinfo, &info);
595 }
596 
597 static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr,
598  unsigned len, struct cpumask *new_mask)
599 {
600  unsigned long *k;
601 
602  if (len < cpumask_size())
603  memset(new_mask, 0, cpumask_size());
604  else if (len > cpumask_size())
605  len = cpumask_size();
606 
607  k = cpumask_bits(new_mask);
608  return compat_get_bitmap(k, user_mask_ptr, len * 8);
609 }
610 
612  unsigned int len,
613  compat_ulong_t __user *user_mask_ptr)
614 {
615  cpumask_var_t new_mask;
616  int retval;
617 
618  if (!alloc_cpumask_var(&new_mask, GFP_KERNEL))
619  return -ENOMEM;
620 
621  retval = compat_get_user_cpu_mask(user_mask_ptr, len, new_mask);
622  if (retval)
623  goto out;
624 
625  retval = sched_setaffinity(pid, new_mask);
626 out:
627  free_cpumask_var(new_mask);
628  return retval;
629 }
630 
632  compat_ulong_t __user *user_mask_ptr)
633 {
634  int ret;
636 
637  if ((len * BITS_PER_BYTE) < nr_cpu_ids)
638  return -EINVAL;
639  if (len & (sizeof(compat_ulong_t)-1))
640  return -EINVAL;
641 
642  if (!alloc_cpumask_var(&mask, GFP_KERNEL))
643  return -ENOMEM;
644 
645  ret = sched_getaffinity(pid, mask);
646  if (ret == 0) {
647  size_t retlen = min_t(size_t, len, cpumask_size());
648 
649  if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
650  ret = -EFAULT;
651  else
652  ret = retlen;
653  }
654  free_cpumask_var(mask);
655 
656  return ret;
657 }
658 
660  const struct compat_itimerspec __user *src)
661 {
662  if (get_compat_timespec(&dst->it_interval, &src->it_interval) ||
663  get_compat_timespec(&dst->it_value, &src->it_value))
664  return -EFAULT;
665  return 0;
666 }
667 
668 int put_compat_itimerspec(struct compat_itimerspec __user *dst,
669  const struct itimerspec *src)
670 {
671  if (put_compat_timespec(&src->it_interval, &dst->it_interval) ||
672  put_compat_timespec(&src->it_value, &dst->it_value))
673  return -EFAULT;
674  return 0;
675 }
676 
678  struct compat_sigevent __user *timer_event_spec,
679  timer_t __user *created_timer_id)
680 {
681  struct sigevent __user *event = NULL;
682 
683  if (timer_event_spec) {
684  struct sigevent kevent;
685 
686  event = compat_alloc_user_space(sizeof(*event));
687  if (get_compat_sigevent(&kevent, timer_event_spec) ||
688  copy_to_user(event, &kevent, sizeof(*event)))
689  return -EFAULT;
690  }
691 
692  return sys_timer_create(which_clock, event, created_timer_id);
693 }
694 
696  struct compat_itimerspec __user *new,
697  struct compat_itimerspec __user *old)
698 {
699  long err;
700  mm_segment_t oldfs;
701  struct itimerspec newts, oldts;
702 
703  if (!new)
704  return -EINVAL;
705  if (get_compat_itimerspec(&newts, new))
706  return -EFAULT;
707  oldfs = get_fs();
708  set_fs(KERNEL_DS);
709  err = sys_timer_settime(timer_id, flags,
710  (struct itimerspec __user *) &newts,
711  (struct itimerspec __user *) &oldts);
712  set_fs(oldfs);
713  if (!err && old && put_compat_itimerspec(old, &oldts))
714  return -EFAULT;
715  return err;
716 }
717 
719  struct compat_itimerspec __user *setting)
720 {
721  long err;
722  mm_segment_t oldfs;
723  struct itimerspec ts;
724 
725  oldfs = get_fs();
726  set_fs(KERNEL_DS);
727  err = sys_timer_gettime(timer_id,
728  (struct itimerspec __user *) &ts);
729  set_fs(oldfs);
730  if (!err && put_compat_itimerspec(setting, &ts))
731  return -EFAULT;
732  return err;
733 }
734 
736  struct compat_timespec __user *tp)
737 {
738  long err;
739  mm_segment_t oldfs;
740  struct timespec ts;
741 
742  if (get_compat_timespec(&ts, tp))
743  return -EFAULT;
744  oldfs = get_fs();
745  set_fs(KERNEL_DS);
746  err = sys_clock_settime(which_clock,
747  (struct timespec __user *) &ts);
748  set_fs(oldfs);
749  return err;
750 }
751 
753  struct compat_timespec __user *tp)
754 {
755  long err;
756  mm_segment_t oldfs;
757  struct timespec ts;
758 
759  oldfs = get_fs();
760  set_fs(KERNEL_DS);
761  err = sys_clock_gettime(which_clock,
762  (struct timespec __user *) &ts);
763  set_fs(oldfs);
764  if (!err && put_compat_timespec(&ts, tp))
765  return -EFAULT;
766  return err;
767 }
768 
770  struct compat_timex __user *utp)
771 {
772  struct timex txc;
773  mm_segment_t oldfs;
774  int err, ret;
775 
776  err = compat_get_timex(&txc, utp);
777  if (err)
778  return err;
779 
780  oldfs = get_fs();
781  set_fs(KERNEL_DS);
782  ret = sys_clock_adjtime(which_clock, (struct timex __user *) &txc);
783  set_fs(oldfs);
784 
785  err = compat_put_timex(utp, &txc);
786  if (err)
787  return err;
788 
789  return ret;
790 }
791 
793  struct compat_timespec __user *tp)
794 {
795  long err;
796  mm_segment_t oldfs;
797  struct timespec ts;
798 
799  oldfs = get_fs();
800  set_fs(KERNEL_DS);
801  err = sys_clock_getres(which_clock,
802  (struct timespec __user *) &ts);
803  set_fs(oldfs);
804  if (!err && tp && put_compat_timespec(&ts, tp))
805  return -EFAULT;
806  return err;
807 }
808 
809 static long compat_clock_nanosleep_restart(struct restart_block *restart)
810 {
811  long err;
812  mm_segment_t oldfs;
813  struct timespec tu;
814  struct compat_timespec *rmtp = restart->nanosleep.compat_rmtp;
815 
816  restart->nanosleep.rmtp = (struct timespec __user *) &tu;
817  oldfs = get_fs();
818  set_fs(KERNEL_DS);
819  err = clock_nanosleep_restart(restart);
820  set_fs(oldfs);
821 
822  if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
823  put_compat_timespec(&tu, rmtp))
824  return -EFAULT;
825 
826  if (err == -ERESTART_RESTARTBLOCK) {
827  restart->fn = compat_clock_nanosleep_restart;
828  restart->nanosleep.compat_rmtp = rmtp;
829  }
830  return err;
831 }
832 
834  struct compat_timespec __user *rqtp,
835  struct compat_timespec __user *rmtp)
836 {
837  long err;
838  mm_segment_t oldfs;
839  struct timespec in, out;
840  struct restart_block *restart;
841 
842  if (get_compat_timespec(&in, rqtp))
843  return -EFAULT;
844 
845  oldfs = get_fs();
846  set_fs(KERNEL_DS);
847  err = sys_clock_nanosleep(which_clock, flags,
848  (struct timespec __user *) &in,
849  (struct timespec __user *) &out);
850  set_fs(oldfs);
851 
852  if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
853  put_compat_timespec(&out, rmtp))
854  return -EFAULT;
855 
856  if (err == -ERESTART_RESTARTBLOCK) {
857  restart = &current_thread_info()->restart_block;
858  restart->fn = compat_clock_nanosleep_restart;
859  restart->nanosleep.compat_rmtp = rmtp;
860  }
861  return err;
862 }
863 
864 /*
865  * We currently only need the following fields from the sigevent
866  * structure: sigev_value, sigev_signo, sig_notify and (sometimes
867  * sigev_notify_thread_id). The others are handled in user mode.
868  * We also assume that copying sigev_value.sival_int is sufficient
869  * to keep all the bits of sigev_value.sival_ptr intact.
870  */
872  const struct compat_sigevent __user *u_event)
873 {
874  memset(event, 0, sizeof(*event));
875  return (!access_ok(VERIFY_READ, u_event, sizeof(*u_event)) ||
877  &u_event->sigev_value.sival_int) ||
878  __get_user(event->sigev_signo, &u_event->sigev_signo) ||
879  __get_user(event->sigev_notify, &u_event->sigev_notify) ||
880  __get_user(event->sigev_notify_thread_id,
881  &u_event->sigev_notify_thread_id))
882  ? -EFAULT : 0;
883 }
884 
885 long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
886  unsigned long bitmap_size)
887 {
888  int i, j;
889  unsigned long m;
890  compat_ulong_t um;
891  unsigned long nr_compat_longs;
892 
893  /* align bitmap up to nearest compat_long_t boundary */
894  bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
895 
896  if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
897  return -EFAULT;
898 
899  nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
900 
901  for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
902  m = 0;
903 
904  for (j = 0; j < sizeof(m)/sizeof(um); j++) {
905  /*
906  * We dont want to read past the end of the userspace
907  * bitmap. We must however ensure the end of the
908  * kernel bitmap is zeroed.
909  */
910  if (nr_compat_longs-- > 0) {
911  if (__get_user(um, umask))
912  return -EFAULT;
913  } else {
914  um = 0;
915  }
916 
917  umask++;
918  m |= (long)um << (j * BITS_PER_COMPAT_LONG);
919  }
920  *mask++ = m;
921  }
922 
923  return 0;
924 }
925 
926 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
927  unsigned long bitmap_size)
928 {
929  int i, j;
930  unsigned long m;
931  compat_ulong_t um;
932  unsigned long nr_compat_longs;
933 
934  /* align bitmap up to nearest compat_long_t boundary */
935  bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
936 
937  if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
938  return -EFAULT;
939 
940  nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
941 
942  for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
943  m = *mask++;
944 
945  for (j = 0; j < sizeof(m)/sizeof(um); j++) {
946  um = m;
947 
948  /*
949  * We dont want to write past the end of the userspace
950  * bitmap.
951  */
952  if (nr_compat_longs-- > 0) {
953  if (__put_user(um, umask))
954  return -EFAULT;
955  }
956 
957  umask++;
958  m >>= 4*sizeof(um);
959  m >>= 4*sizeof(um);
960  }
961  }
962 
963  return 0;
964 }
965 
966 void
967 sigset_from_compat (sigset_t *set, compat_sigset_t *compat)
968 {
969  switch (_NSIG_WORDS) {
970  case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
971  case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 );
972  case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 );
973  case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
974  }
975 }
977 
978 asmlinkage long
979 compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
980  struct compat_siginfo __user *uinfo,
981  struct compat_timespec __user *uts, compat_size_t sigsetsize)
982 {
983  compat_sigset_t s32;
984  sigset_t s;
985  struct timespec t;
986  siginfo_t info;
987  long ret;
988 
989  if (sigsetsize != sizeof(sigset_t))
990  return -EINVAL;
991 
992  if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
993  return -EFAULT;
994  sigset_from_compat(&s, &s32);
995 
996  if (uts) {
997  if (get_compat_timespec(&t, uts))
998  return -EFAULT;
999  }
1000 
1001  ret = do_sigtimedwait(&s, &info, uts ? &t : NULL);
1002 
1003  if (ret > 0 && uinfo) {
1004  if (copy_siginfo_to_user32(uinfo, &info))
1005  ret = -EFAULT;
1006  }
1007 
1008  return ret;
1009 
1010 }
1011 
1012 asmlinkage long
1014  struct compat_siginfo __user *uinfo)
1015 {
1016  siginfo_t info;
1017 
1018  if (copy_siginfo_from_user32(&info, uinfo))
1019  return -EFAULT;
1020  return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
1021 }
1022 
1023 #ifdef __ARCH_WANT_COMPAT_SYS_TIME
1024 
1025 /* compat_time_t is a 32 bit "long" and needs to get converted. */
1026 
1027 asmlinkage long compat_sys_time(compat_time_t __user * tloc)
1028 {
1029  compat_time_t i;
1030  struct timeval tv;
1031 
1032  do_gettimeofday(&tv);
1033  i = tv.tv_sec;
1034 
1035  if (tloc) {
1036  if (put_user(i,tloc))
1037  return -EFAULT;
1038  }
1040  return i;
1041 }
1042 
1043 asmlinkage long compat_sys_stime(compat_time_t __user *tptr)
1044 {
1045  struct timespec tv;
1046  int err;
1047 
1048  if (get_user(tv.tv_sec, tptr))
1049  return -EFAULT;
1050 
1051  tv.tv_nsec = 0;
1052 
1053  err = security_settime(&tv, NULL);
1054  if (err)
1055  return err;
1056 
1057  do_settimeofday(&tv);
1058  return 0;
1059 }
1060 
1061 #endif /* __ARCH_WANT_COMPAT_SYS_TIME */
1062 
1063 #ifdef __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
1064 asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat_size_t sigsetsize)
1065 {
1066  sigset_t newset;
1067  compat_sigset_t newset32;
1068 
1069  /* XXX: Don't preclude handling different sized sigset_t's. */
1070  if (sigsetsize != sizeof(sigset_t))
1071  return -EINVAL;
1072 
1073  if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
1074  return -EFAULT;
1075  sigset_from_compat(&newset, &newset32);
1076  return sigsuspend(&newset);
1077 }
1078 #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
1079 
1080 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp)
1081 {
1082  struct timex txc;
1083  int err, ret;
1084 
1085  err = compat_get_timex(&txc, utp);
1086  if (err)
1087  return err;
1088 
1089  ret = do_adjtimex(&txc);
1090 
1091  err = compat_put_timex(utp, &txc);
1092  if (err)
1093  return err;
1094 
1095  return ret;
1096 }
1097 
1098 #ifdef CONFIG_NUMA
1099 asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_pages,
1100  compat_uptr_t __user *pages32,
1101  const int __user *nodes,
1102  int __user *status,
1103  int flags)
1104 {
1105  const void __user * __user *pages;
1106  int i;
1107 
1108  pages = compat_alloc_user_space(nr_pages * sizeof(void *));
1109  for (i = 0; i < nr_pages; i++) {
1110  compat_uptr_t p;
1111 
1112  if (get_user(p, pages32 + i) ||
1113  put_user(compat_ptr(p), pages + i))
1114  return -EFAULT;
1115  }
1116  return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
1117 }
1118 
1119 asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
1120  compat_ulong_t maxnode,
1121  const compat_ulong_t __user *old_nodes,
1122  const compat_ulong_t __user *new_nodes)
1123 {
1124  unsigned long __user *old = NULL;
1125  unsigned long __user *new = NULL;
1126  nodemask_t tmp_mask;
1127  unsigned long nr_bits;
1128  unsigned long size;
1129 
1130  nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES);
1131  size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
1132  if (old_nodes) {
1133  if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits))
1134  return -EFAULT;
1135  old = compat_alloc_user_space(new_nodes ? size * 2 : size);
1136  if (new_nodes)
1137  new = old + size / sizeof(unsigned long);
1138  if (copy_to_user(old, nodes_addr(tmp_mask), size))
1139  return -EFAULT;
1140  }
1141  if (new_nodes) {
1142  if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits))
1143  return -EFAULT;
1144  if (new == NULL)
1145  new = compat_alloc_user_space(size);
1146  if (copy_to_user(new, nodes_addr(tmp_mask), size))
1147  return -EFAULT;
1148  }
1149  return sys_migrate_pages(pid, nr_bits + 1, old, new);
1150 }
1151 #endif
1152 
1167  char _f[20-2*sizeof(u32)-sizeof(int)];
1168 };
1169 
1170 asmlinkage long
1172 {
1173  struct sysinfo s;
1174 
1175  do_sysinfo(&s);
1176 
1177  /* Check to see if any memory value is too large for 32-bit and scale
1178  * down if needed
1179  */
1180  if ((s.totalram >> 32) || (s.totalswap >> 32)) {
1181  int bitcount = 0;
1182 
1183  while (s.mem_unit < PAGE_SIZE) {
1184  s.mem_unit <<= 1;
1185  bitcount++;
1186  }
1187 
1188  s.totalram >>= bitcount;
1189  s.freeram >>= bitcount;
1190  s.sharedram >>= bitcount;
1191  s.bufferram >>= bitcount;
1192  s.totalswap >>= bitcount;
1193  s.freeswap >>= bitcount;
1194  s.totalhigh >>= bitcount;
1195  s.freehigh >>= bitcount;
1196  }
1197 
1198  if (!access_ok(VERIFY_WRITE, info, sizeof(struct compat_sysinfo)) ||
1199  __put_user (s.uptime, &info->uptime) ||
1200  __put_user (s.loads[0], &info->loads[0]) ||
1201  __put_user (s.loads[1], &info->loads[1]) ||
1202  __put_user (s.loads[2], &info->loads[2]) ||
1203  __put_user (s.totalram, &info->totalram) ||
1204  __put_user (s.freeram, &info->freeram) ||
1205  __put_user (s.sharedram, &info->sharedram) ||
1206  __put_user (s.bufferram, &info->bufferram) ||
1207  __put_user (s.totalswap, &info->totalswap) ||
1208  __put_user (s.freeswap, &info->freeswap) ||
1209  __put_user (s.procs, &info->procs) ||
1210  __put_user (s.totalhigh, &info->totalhigh) ||
1211  __put_user (s.freehigh, &info->freehigh) ||
1212  __put_user (s.mem_unit, &info->mem_unit))
1213  return -EFAULT;
1214 
1215  return 0;
1216 }
1217 
1218 /*
1219  * Allocate user-space memory for the duration of a single system call,
1220  * in order to marshall parameters inside a compat thunk.
1221  */
1222 void __user *compat_alloc_user_space(unsigned long len)
1223 {
1224  void __user *ptr;
1225 
1226  /* If len would occupy more than half of the entire compat space... */
1227  if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
1228  return NULL;
1229 
1230  ptr = arch_compat_alloc_user_space(len);
1231 
1232  if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
1233  return NULL;
1234 
1235  return ptr;
1236 }