compat.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  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. #include <linux/linkage.h>
  14. #include <linux/compat.h>
  15. #include <linux/errno.h>
  16. #include <linux/time.h>
  17. #include <linux/signal.h>
  18. #include <linux/sched.h> /* for MAX_SCHEDULE_TIMEOUT */
  19. #include <linux/syscalls.h>
  20. #include <linux/unistd.h>
  21. #include <linux/security.h>
  22. #include <linux/timex.h>
  23. #include <linux/export.h>
  24. #include <linux/migrate.h>
  25. #include <linux/posix-timers.h>
  26. #include <linux/times.h>
  27. #include <linux/ptrace.h>
  28. #include <linux/gfp.h>
  29. #include <linux/uaccess.h>
  30. int compat_get_timex(struct timex *txc, const struct compat_timex __user *utp)
  31. {
  32. struct compat_timex tx32;
  33. if (copy_from_user(&tx32, utp, sizeof(struct compat_timex)))
  34. return -EFAULT;
  35. txc->modes = tx32.modes;
  36. txc->offset = tx32.offset;
  37. txc->freq = tx32.freq;
  38. txc->maxerror = tx32.maxerror;
  39. txc->esterror = tx32.esterror;
  40. txc->status = tx32.status;
  41. txc->constant = tx32.constant;
  42. txc->precision = tx32.precision;
  43. txc->tolerance = tx32.tolerance;
  44. txc->time.tv_sec = tx32.time.tv_sec;
  45. txc->time.tv_usec = tx32.time.tv_usec;
  46. txc->tick = tx32.tick;
  47. txc->ppsfreq = tx32.ppsfreq;
  48. txc->jitter = tx32.jitter;
  49. txc->shift = tx32.shift;
  50. txc->stabil = tx32.stabil;
  51. txc->jitcnt = tx32.jitcnt;
  52. txc->calcnt = tx32.calcnt;
  53. txc->errcnt = tx32.errcnt;
  54. txc->stbcnt = tx32.stbcnt;
  55. return 0;
  56. }
  57. int compat_put_timex(struct compat_timex __user *utp, const struct timex *txc)
  58. {
  59. struct compat_timex tx32;
  60. memset(&tx32, 0, sizeof(struct compat_timex));
  61. tx32.modes = txc->modes;
  62. tx32.offset = txc->offset;
  63. tx32.freq = txc->freq;
  64. tx32.maxerror = txc->maxerror;
  65. tx32.esterror = txc->esterror;
  66. tx32.status = txc->status;
  67. tx32.constant = txc->constant;
  68. tx32.precision = txc->precision;
  69. tx32.tolerance = txc->tolerance;
  70. tx32.time.tv_sec = txc->time.tv_sec;
  71. tx32.time.tv_usec = txc->time.tv_usec;
  72. tx32.tick = txc->tick;
  73. tx32.ppsfreq = txc->ppsfreq;
  74. tx32.jitter = txc->jitter;
  75. tx32.shift = txc->shift;
  76. tx32.stabil = txc->stabil;
  77. tx32.jitcnt = txc->jitcnt;
  78. tx32.calcnt = txc->calcnt;
  79. tx32.errcnt = txc->errcnt;
  80. tx32.stbcnt = txc->stbcnt;
  81. tx32.tai = txc->tai;
  82. if (copy_to_user(utp, &tx32, sizeof(struct compat_timex)))
  83. return -EFAULT;
  84. return 0;
  85. }
  86. COMPAT_SYSCALL_DEFINE2(gettimeofday, struct compat_timeval __user *, tv,
  87. struct timezone __user *, tz)
  88. {
  89. if (tv) {
  90. struct timeval ktv;
  91. do_gettimeofday(&ktv);
  92. if (compat_put_timeval(&ktv, tv))
  93. return -EFAULT;
  94. }
  95. if (tz) {
  96. if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
  97. return -EFAULT;
  98. }
  99. return 0;
  100. }
  101. COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv,
  102. struct timezone __user *, tz)
  103. {
  104. struct timespec64 new_ts;
  105. struct timeval user_tv;
  106. struct timezone new_tz;
  107. if (tv) {
  108. if (compat_get_timeval(&user_tv, tv))
  109. return -EFAULT;
  110. new_ts.tv_sec = user_tv.tv_sec;
  111. new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
  112. }
  113. if (tz) {
  114. if (copy_from_user(&new_tz, tz, sizeof(*tz)))
  115. return -EFAULT;
  116. }
  117. return do_sys_settimeofday64(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
  118. }
  119. static int __compat_get_timeval(struct timeval *tv, const struct compat_timeval __user *ctv)
  120. {
  121. return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
  122. __get_user(tv->tv_sec, &ctv->tv_sec) ||
  123. __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
  124. }
  125. static int __compat_put_timeval(const struct timeval *tv, struct compat_timeval __user *ctv)
  126. {
  127. return (!access_ok(VERIFY_WRITE, ctv, sizeof(*ctv)) ||
  128. __put_user(tv->tv_sec, &ctv->tv_sec) ||
  129. __put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
  130. }
  131. static int __compat_get_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
  132. {
  133. return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
  134. __get_user(ts->tv_sec, &cts->tv_sec) ||
  135. __get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
  136. }
  137. static int __compat_put_timespec(const struct timespec *ts, struct compat_timespec __user *cts)
  138. {
  139. return (!access_ok(VERIFY_WRITE, cts, sizeof(*cts)) ||
  140. __put_user(ts->tv_sec, &cts->tv_sec) ||
  141. __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
  142. }
  143. int compat_get_timeval(struct timeval *tv, const void __user *utv)
  144. {
  145. if (COMPAT_USE_64BIT_TIME)
  146. return copy_from_user(tv, utv, sizeof(*tv)) ? -EFAULT : 0;
  147. else
  148. return __compat_get_timeval(tv, utv);
  149. }
  150. EXPORT_SYMBOL_GPL(compat_get_timeval);
  151. int compat_put_timeval(const struct timeval *tv, void __user *utv)
  152. {
  153. if (COMPAT_USE_64BIT_TIME)
  154. return copy_to_user(utv, tv, sizeof(*tv)) ? -EFAULT : 0;
  155. else
  156. return __compat_put_timeval(tv, utv);
  157. }
  158. EXPORT_SYMBOL_GPL(compat_put_timeval);
  159. int compat_get_timespec(struct timespec *ts, const void __user *uts)
  160. {
  161. if (COMPAT_USE_64BIT_TIME)
  162. return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0;
  163. else
  164. return __compat_get_timespec(ts, uts);
  165. }
  166. EXPORT_SYMBOL_GPL(compat_get_timespec);
  167. int compat_put_timespec(const struct timespec *ts, void __user *uts)
  168. {
  169. if (COMPAT_USE_64BIT_TIME)
  170. return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0;
  171. else
  172. return __compat_put_timespec(ts, uts);
  173. }
  174. EXPORT_SYMBOL_GPL(compat_put_timespec);
  175. int compat_convert_timespec(struct timespec __user **kts,
  176. const void __user *cts)
  177. {
  178. struct timespec ts;
  179. struct timespec __user *uts;
  180. if (!cts || COMPAT_USE_64BIT_TIME) {
  181. *kts = (struct timespec __user *)cts;
  182. return 0;
  183. }
  184. uts = compat_alloc_user_space(sizeof(ts));
  185. if (!uts)
  186. return -EFAULT;
  187. if (compat_get_timespec(&ts, cts))
  188. return -EFAULT;
  189. if (copy_to_user(uts, &ts, sizeof(ts)))
  190. return -EFAULT;
  191. *kts = uts;
  192. return 0;
  193. }
  194. int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i)
  195. {
  196. struct compat_itimerval v32;
  197. if (copy_from_user(&v32, i, sizeof(struct compat_itimerval)))
  198. return -EFAULT;
  199. o->it_interval.tv_sec = v32.it_interval.tv_sec;
  200. o->it_interval.tv_usec = v32.it_interval.tv_usec;
  201. o->it_value.tv_sec = v32.it_value.tv_sec;
  202. o->it_value.tv_usec = v32.it_value.tv_usec;
  203. return 0;
  204. }
  205. int put_compat_itimerval(struct compat_itimerval __user *o, const struct itimerval *i)
  206. {
  207. struct compat_itimerval v32;
  208. v32.it_interval.tv_sec = i->it_interval.tv_sec;
  209. v32.it_interval.tv_usec = i->it_interval.tv_usec;
  210. v32.it_value.tv_sec = i->it_value.tv_sec;
  211. v32.it_value.tv_usec = i->it_value.tv_usec;
  212. return copy_to_user(o, &v32, sizeof(struct compat_itimerval)) ? -EFAULT : 0;
  213. }
  214. static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
  215. {
  216. return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
  217. }
  218. COMPAT_SYSCALL_DEFINE1(times, struct compat_tms __user *, tbuf)
  219. {
  220. if (tbuf) {
  221. struct tms tms;
  222. struct compat_tms tmp;
  223. do_sys_times(&tms);
  224. /* Convert our struct tms to the compat version. */
  225. tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
  226. tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
  227. tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
  228. tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
  229. if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
  230. return -EFAULT;
  231. }
  232. force_successful_syscall_return();
  233. return compat_jiffies_to_clock_t(jiffies);
  234. }
  235. #ifdef __ARCH_WANT_SYS_SIGPENDING
  236. /*
  237. * Assumption: old_sigset_t and compat_old_sigset_t are both
  238. * types that can be passed to put_user()/get_user().
  239. */
  240. COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set)
  241. {
  242. old_sigset_t s;
  243. long ret;
  244. mm_segment_t old_fs = get_fs();
  245. set_fs(KERNEL_DS);
  246. ret = sys_sigpending((old_sigset_t __user *) &s);
  247. set_fs(old_fs);
  248. if (ret == 0)
  249. ret = put_user(s, set);
  250. return ret;
  251. }
  252. #endif
  253. #ifdef __ARCH_WANT_SYS_SIGPROCMASK
  254. /*
  255. * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the
  256. * blocked set of signals to the supplied signal set
  257. */
  258. static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set)
  259. {
  260. memcpy(blocked->sig, &set, sizeof(set));
  261. }
  262. COMPAT_SYSCALL_DEFINE3(sigprocmask, int, how,
  263. compat_old_sigset_t __user *, nset,
  264. compat_old_sigset_t __user *, oset)
  265. {
  266. old_sigset_t old_set, new_set;
  267. sigset_t new_blocked;
  268. old_set = current->blocked.sig[0];
  269. if (nset) {
  270. if (get_user(new_set, nset))
  271. return -EFAULT;
  272. new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));
  273. new_blocked = current->blocked;
  274. switch (how) {
  275. case SIG_BLOCK:
  276. sigaddsetmask(&new_blocked, new_set);
  277. break;
  278. case SIG_UNBLOCK:
  279. sigdelsetmask(&new_blocked, new_set);
  280. break;
  281. case SIG_SETMASK:
  282. compat_sig_setmask(&new_blocked, new_set);
  283. break;
  284. default:
  285. return -EINVAL;
  286. }
  287. set_current_blocked(&new_blocked);
  288. }
  289. if (oset) {
  290. if (put_user(old_set, oset))
  291. return -EFAULT;
  292. }
  293. return 0;
  294. }
  295. #endif
  296. COMPAT_SYSCALL_DEFINE2(setrlimit, unsigned int, resource,
  297. struct compat_rlimit __user *, rlim)
  298. {
  299. struct rlimit r;
  300. if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
  301. __get_user(r.rlim_cur, &rlim->rlim_cur) ||
  302. __get_user(r.rlim_max, &rlim->rlim_max))
  303. return -EFAULT;
  304. if (r.rlim_cur == COMPAT_RLIM_INFINITY)
  305. r.rlim_cur = RLIM_INFINITY;
  306. if (r.rlim_max == COMPAT_RLIM_INFINITY)
  307. r.rlim_max = RLIM_INFINITY;
  308. return do_prlimit(current, resource, &r, NULL);
  309. }
  310. #ifdef COMPAT_RLIM_OLD_INFINITY
  311. COMPAT_SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
  312. struct compat_rlimit __user *, rlim)
  313. {
  314. struct rlimit r;
  315. int ret;
  316. mm_segment_t old_fs = get_fs();
  317. set_fs(KERNEL_DS);
  318. ret = sys_old_getrlimit(resource, (struct rlimit __user *)&r);
  319. set_fs(old_fs);
  320. if (!ret) {
  321. if (r.rlim_cur > COMPAT_RLIM_OLD_INFINITY)
  322. r.rlim_cur = COMPAT_RLIM_INFINITY;
  323. if (r.rlim_max > COMPAT_RLIM_OLD_INFINITY)
  324. r.rlim_max = COMPAT_RLIM_INFINITY;
  325. if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
  326. __put_user(r.rlim_cur, &rlim->rlim_cur) ||
  327. __put_user(r.rlim_max, &rlim->rlim_max))
  328. return -EFAULT;
  329. }
  330. return ret;
  331. }
  332. #endif
  333. COMPAT_SYSCALL_DEFINE2(getrlimit, unsigned int, resource,
  334. struct compat_rlimit __user *, rlim)
  335. {
  336. struct rlimit r;
  337. int ret;
  338. ret = do_prlimit(current, resource, NULL, &r);
  339. if (!ret) {
  340. if (r.rlim_cur > COMPAT_RLIM_INFINITY)
  341. r.rlim_cur = COMPAT_RLIM_INFINITY;
  342. if (r.rlim_max > COMPAT_RLIM_INFINITY)
  343. r.rlim_max = COMPAT_RLIM_INFINITY;
  344. if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
  345. __put_user(r.rlim_cur, &rlim->rlim_cur) ||
  346. __put_user(r.rlim_max, &rlim->rlim_max))
  347. return -EFAULT;
  348. }
  349. return ret;
  350. }
  351. int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
  352. {
  353. if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
  354. __put_user(r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
  355. __put_user(r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
  356. __put_user(r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
  357. __put_user(r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
  358. __put_user(r->ru_maxrss, &ru->ru_maxrss) ||
  359. __put_user(r->ru_ixrss, &ru->ru_ixrss) ||
  360. __put_user(r->ru_idrss, &ru->ru_idrss) ||
  361. __put_user(r->ru_isrss, &ru->ru_isrss) ||
  362. __put_user(r->ru_minflt, &ru->ru_minflt) ||
  363. __put_user(r->ru_majflt, &ru->ru_majflt) ||
  364. __put_user(r->ru_nswap, &ru->ru_nswap) ||
  365. __put_user(r->ru_inblock, &ru->ru_inblock) ||
  366. __put_user(r->ru_oublock, &ru->ru_oublock) ||
  367. __put_user(r->ru_msgsnd, &ru->ru_msgsnd) ||
  368. __put_user(r->ru_msgrcv, &ru->ru_msgrcv) ||
  369. __put_user(r->ru_nsignals, &ru->ru_nsignals) ||
  370. __put_user(r->ru_nvcsw, &ru->ru_nvcsw) ||
  371. __put_user(r->ru_nivcsw, &ru->ru_nivcsw))
  372. return -EFAULT;
  373. return 0;
  374. }
  375. COMPAT_SYSCALL_DEFINE4(wait4,
  376. compat_pid_t, pid,
  377. compat_uint_t __user *, stat_addr,
  378. int, options,
  379. struct compat_rusage __user *, ru)
  380. {
  381. if (!ru) {
  382. return sys_wait4(pid, stat_addr, options, NULL);
  383. } else {
  384. struct rusage r;
  385. int ret;
  386. unsigned int status;
  387. mm_segment_t old_fs = get_fs();
  388. set_fs (KERNEL_DS);
  389. ret = sys_wait4(pid,
  390. (stat_addr ?
  391. (unsigned int __user *) &status : NULL),
  392. options, (struct rusage __user *) &r);
  393. set_fs (old_fs);
  394. if (ret > 0) {
  395. if (put_compat_rusage(&r, ru))
  396. return -EFAULT;
  397. if (stat_addr && put_user(status, stat_addr))
  398. return -EFAULT;
  399. }
  400. return ret;
  401. }
  402. }
  403. COMPAT_SYSCALL_DEFINE5(waitid,
  404. int, which, compat_pid_t, pid,
  405. struct compat_siginfo __user *, uinfo, int, options,
  406. struct compat_rusage __user *, uru)
  407. {
  408. siginfo_t info;
  409. struct rusage ru;
  410. long ret;
  411. mm_segment_t old_fs = get_fs();
  412. memset(&info, 0, sizeof(info));
  413. set_fs(KERNEL_DS);
  414. ret = sys_waitid(which, pid, (siginfo_t __user *)&info, options,
  415. uru ? (struct rusage __user *)&ru : NULL);
  416. set_fs(old_fs);
  417. if ((ret < 0) || (info.si_signo == 0))
  418. return ret;
  419. if (uru) {
  420. /* sys_waitid() overwrites everything in ru */
  421. if (COMPAT_USE_64BIT_TIME)
  422. ret = copy_to_user(uru, &ru, sizeof(ru));
  423. else
  424. ret = put_compat_rusage(&ru, uru);
  425. if (ret)
  426. return -EFAULT;
  427. }
  428. BUG_ON(info.si_code & __SI_MASK);
  429. info.si_code |= __SI_CHLD;
  430. return copy_siginfo_to_user32(uinfo, &info);
  431. }
  432. static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr,
  433. unsigned len, struct cpumask *new_mask)
  434. {
  435. unsigned long *k;
  436. if (len < cpumask_size())
  437. memset(new_mask, 0, cpumask_size());
  438. else if (len > cpumask_size())
  439. len = cpumask_size();
  440. k = cpumask_bits(new_mask);
  441. return compat_get_bitmap(k, user_mask_ptr, len * 8);
  442. }
  443. COMPAT_SYSCALL_DEFINE3(sched_setaffinity, compat_pid_t, pid,
  444. unsigned int, len,
  445. compat_ulong_t __user *, user_mask_ptr)
  446. {
  447. cpumask_var_t new_mask;
  448. int retval;
  449. if (!alloc_cpumask_var(&new_mask, GFP_KERNEL))
  450. return -ENOMEM;
  451. retval = compat_get_user_cpu_mask(user_mask_ptr, len, new_mask);
  452. if (retval)
  453. goto out;
  454. retval = sched_setaffinity(pid, new_mask);
  455. out:
  456. free_cpumask_var(new_mask);
  457. return retval;
  458. }
  459. COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t, pid, unsigned int, len,
  460. compat_ulong_t __user *, user_mask_ptr)
  461. {
  462. int ret;
  463. cpumask_var_t mask;
  464. if ((len * BITS_PER_BYTE) < nr_cpu_ids)
  465. return -EINVAL;
  466. if (len & (sizeof(compat_ulong_t)-1))
  467. return -EINVAL;
  468. if (!alloc_cpumask_var(&mask, GFP_KERNEL))
  469. return -ENOMEM;
  470. ret = sched_getaffinity(pid, mask);
  471. if (ret == 0) {
  472. size_t retlen = min_t(size_t, len, cpumask_size());
  473. if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
  474. ret = -EFAULT;
  475. else
  476. ret = retlen;
  477. }
  478. free_cpumask_var(mask);
  479. return ret;
  480. }
  481. int get_compat_itimerspec(struct itimerspec *dst,
  482. const struct compat_itimerspec __user *src)
  483. {
  484. if (__compat_get_timespec(&dst->it_interval, &src->it_interval) ||
  485. __compat_get_timespec(&dst->it_value, &src->it_value))
  486. return -EFAULT;
  487. return 0;
  488. }
  489. int put_compat_itimerspec(struct compat_itimerspec __user *dst,
  490. const struct itimerspec *src)
  491. {
  492. if (__compat_put_timespec(&src->it_interval, &dst->it_interval) ||
  493. __compat_put_timespec(&src->it_value, &dst->it_value))
  494. return -EFAULT;
  495. return 0;
  496. }
  497. COMPAT_SYSCALL_DEFINE3(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. if (timer_event_spec) {
  503. struct sigevent kevent;
  504. event = compat_alloc_user_space(sizeof(*event));
  505. if (get_compat_sigevent(&kevent, timer_event_spec) ||
  506. copy_to_user(event, &kevent, sizeof(*event)))
  507. return -EFAULT;
  508. }
  509. return sys_timer_create(which_clock, event, created_timer_id);
  510. }
  511. /*
  512. * We currently only need the following fields from the sigevent
  513. * structure: sigev_value, sigev_signo, sig_notify and (sometimes
  514. * sigev_notify_thread_id). The others are handled in user mode.
  515. * We also assume that copying sigev_value.sival_int is sufficient
  516. * to keep all the bits of sigev_value.sival_ptr intact.
  517. */
  518. int get_compat_sigevent(struct sigevent *event,
  519. const struct compat_sigevent __user *u_event)
  520. {
  521. memset(event, 0, sizeof(*event));
  522. return (!access_ok(VERIFY_READ, u_event, sizeof(*u_event)) ||
  523. __get_user(event->sigev_value.sival_int,
  524. &u_event->sigev_value.sival_int) ||
  525. __get_user(event->sigev_signo, &u_event->sigev_signo) ||
  526. __get_user(event->sigev_notify, &u_event->sigev_notify) ||
  527. __get_user(event->sigev_notify_thread_id,
  528. &u_event->sigev_notify_thread_id))
  529. ? -EFAULT : 0;
  530. }
  531. long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
  532. unsigned long bitmap_size)
  533. {
  534. int i, j;
  535. unsigned long m;
  536. compat_ulong_t um;
  537. unsigned long nr_compat_longs;
  538. /* align bitmap up to nearest compat_long_t boundary */
  539. bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
  540. if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
  541. return -EFAULT;
  542. nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
  543. for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
  544. m = 0;
  545. for (j = 0; j < sizeof(m)/sizeof(um); j++) {
  546. /*
  547. * We dont want to read past the end of the userspace
  548. * bitmap. We must however ensure the end of the
  549. * kernel bitmap is zeroed.
  550. */
  551. if (nr_compat_longs) {
  552. nr_compat_longs--;
  553. if (__get_user(um, umask))
  554. return -EFAULT;
  555. } else {
  556. um = 0;
  557. }
  558. umask++;
  559. m |= (long)um << (j * BITS_PER_COMPAT_LONG);
  560. }
  561. *mask++ = m;
  562. }
  563. return 0;
  564. }
  565. long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
  566. unsigned long bitmap_size)
  567. {
  568. int i, j;
  569. unsigned long m;
  570. compat_ulong_t um;
  571. unsigned long nr_compat_longs;
  572. /* align bitmap up to nearest compat_long_t boundary */
  573. bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
  574. if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
  575. return -EFAULT;
  576. nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
  577. for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
  578. m = *mask++;
  579. for (j = 0; j < sizeof(m)/sizeof(um); j++) {
  580. um = m;
  581. /*
  582. * We dont want to write past the end of the userspace
  583. * bitmap.
  584. */
  585. if (nr_compat_longs) {
  586. nr_compat_longs--;
  587. if (__put_user(um, umask))
  588. return -EFAULT;
  589. }
  590. umask++;
  591. m >>= 4*sizeof(um);
  592. m >>= 4*sizeof(um);
  593. }
  594. }
  595. return 0;
  596. }
  597. void
  598. sigset_from_compat(sigset_t *set, const compat_sigset_t *compat)
  599. {
  600. switch (_NSIG_WORDS) {
  601. case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
  602. case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 );
  603. case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 );
  604. case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
  605. }
  606. }
  607. EXPORT_SYMBOL_GPL(sigset_from_compat);
  608. void
  609. sigset_to_compat(compat_sigset_t *compat, const sigset_t *set)
  610. {
  611. switch (_NSIG_WORDS) {
  612. case 4: compat->sig[7] = (set->sig[3] >> 32); compat->sig[6] = set->sig[3];
  613. case 3: compat->sig[5] = (set->sig[2] >> 32); compat->sig[4] = set->sig[2];
  614. case 2: compat->sig[3] = (set->sig[1] >> 32); compat->sig[2] = set->sig[1];
  615. case 1: compat->sig[1] = (set->sig[0] >> 32); compat->sig[0] = set->sig[0];
  616. }
  617. }
  618. COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
  619. struct compat_siginfo __user *, uinfo,
  620. struct compat_timespec __user *, uts, compat_size_t, sigsetsize)
  621. {
  622. compat_sigset_t s32;
  623. sigset_t s;
  624. struct timespec t;
  625. siginfo_t info;
  626. long ret;
  627. if (sigsetsize != sizeof(sigset_t))
  628. return -EINVAL;
  629. if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
  630. return -EFAULT;
  631. sigset_from_compat(&s, &s32);
  632. if (uts) {
  633. if (compat_get_timespec(&t, uts))
  634. return -EFAULT;
  635. }
  636. ret = do_sigtimedwait(&s, &info, uts ? &t : NULL);
  637. if (ret > 0 && uinfo) {
  638. if (copy_siginfo_to_user32(uinfo, &info))
  639. ret = -EFAULT;
  640. }
  641. return ret;
  642. }
  643. #ifdef __ARCH_WANT_COMPAT_SYS_TIME
  644. /* compat_time_t is a 32 bit "long" and needs to get converted. */
  645. COMPAT_SYSCALL_DEFINE1(time, compat_time_t __user *, tloc)
  646. {
  647. compat_time_t i;
  648. struct timeval tv;
  649. do_gettimeofday(&tv);
  650. i = tv.tv_sec;
  651. if (tloc) {
  652. if (put_user(i,tloc))
  653. return -EFAULT;
  654. }
  655. force_successful_syscall_return();
  656. return i;
  657. }
  658. COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr)
  659. {
  660. struct timespec tv;
  661. int err;
  662. if (get_user(tv.tv_sec, tptr))
  663. return -EFAULT;
  664. tv.tv_nsec = 0;
  665. err = security_settime(&tv, NULL);
  666. if (err)
  667. return err;
  668. do_settimeofday(&tv);
  669. return 0;
  670. }
  671. #endif /* __ARCH_WANT_COMPAT_SYS_TIME */
  672. #ifdef CONFIG_NUMA
  673. COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages,
  674. compat_uptr_t __user *, pages32,
  675. const int __user *, nodes,
  676. int __user *, status,
  677. int, flags)
  678. {
  679. const void __user * __user *pages;
  680. int i;
  681. pages = compat_alloc_user_space(nr_pages * sizeof(void *));
  682. for (i = 0; i < nr_pages; i++) {
  683. compat_uptr_t p;
  684. if (get_user(p, pages32 + i) ||
  685. put_user(compat_ptr(p), pages + i))
  686. return -EFAULT;
  687. }
  688. return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
  689. }
  690. COMPAT_SYSCALL_DEFINE4(migrate_pages, compat_pid_t, pid,
  691. compat_ulong_t, maxnode,
  692. const compat_ulong_t __user *, old_nodes,
  693. const compat_ulong_t __user *, new_nodes)
  694. {
  695. unsigned long __user *old = NULL;
  696. unsigned long __user *new = NULL;
  697. nodemask_t tmp_mask;
  698. unsigned long nr_bits;
  699. unsigned long size;
  700. nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES);
  701. size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
  702. if (old_nodes) {
  703. if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits))
  704. return -EFAULT;
  705. old = compat_alloc_user_space(new_nodes ? size * 2 : size);
  706. if (new_nodes)
  707. new = old + size / sizeof(unsigned long);
  708. if (copy_to_user(old, nodes_addr(tmp_mask), size))
  709. return -EFAULT;
  710. }
  711. if (new_nodes) {
  712. if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits))
  713. return -EFAULT;
  714. if (new == NULL)
  715. new = compat_alloc_user_space(size);
  716. if (copy_to_user(new, nodes_addr(tmp_mask), size))
  717. return -EFAULT;
  718. }
  719. return sys_migrate_pages(pid, nr_bits + 1, old, new);
  720. }
  721. #endif
  722. COMPAT_SYSCALL_DEFINE2(sched_rr_get_interval,
  723. compat_pid_t, pid,
  724. struct compat_timespec __user *, interval)
  725. {
  726. struct timespec t;
  727. int ret;
  728. mm_segment_t old_fs = get_fs();
  729. set_fs(KERNEL_DS);
  730. ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
  731. set_fs(old_fs);
  732. if (compat_put_timespec(&t, interval))
  733. return -EFAULT;
  734. return ret;
  735. }
  736. /*
  737. * Allocate user-space memory for the duration of a single system call,
  738. * in order to marshall parameters inside a compat thunk.
  739. */
  740. void __user *compat_alloc_user_space(unsigned long len)
  741. {
  742. void __user *ptr;
  743. /* If len would occupy more than half of the entire compat space... */
  744. if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
  745. return NULL;
  746. ptr = arch_compat_alloc_user_space(len);
  747. if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
  748. return NULL;
  749. return ptr;
  750. }
  751. EXPORT_SYMBOL_GPL(compat_alloc_user_space);