sys_parisc32.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:73k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * sys_parisc32.c: Conversion between 32bit and 64bit native syscalls.
  3.  *
  4.  * Copyright (C) 2000-2001 Hewlett Packard Company
  5.  * Copyright (C) 2000 John Marvin
  6.  * Copyright (C) 2001 Matthew Wilcox
  7.  *
  8.  * These routines maintain argument size conversion between 32bit and 64bit
  9.  * environment. Based heavily on sys_ia32.c and sys_sparc32.c.
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/kernel.h>
  13. #include <linux/sched.h>
  14. #include <linux/fs.h> 
  15. #include <linux/mm.h> 
  16. #include <linux/file.h> 
  17. #include <linux/signal.h>
  18. #include <linux/utime.h>
  19. #include <linux/resource.h>
  20. #include <linux/times.h>
  21. #include <linux/utsname.h>
  22. #include <linux/timex.h>
  23. #include <linux/smp.h>
  24. #include <linux/smp_lock.h>
  25. #include <linux/sem.h>
  26. #include <linux/msg.h>
  27. #include <linux/shm.h>
  28. #include <linux/slab.h>
  29. #include <linux/uio.h>
  30. #include <linux/nfs_fs.h>
  31. #include <linux/smb_fs.h>
  32. #include <linux/smb_mount.h>
  33. #include <linux/ncp_fs.h>
  34. #include <linux/quota.h>
  35. #include <linux/module.h>
  36. #include <linux/sunrpc/svc.h>
  37. #include <linux/nfsd/nfsd.h>
  38. #include <linux/nfsd/cache.h>
  39. #include <linux/nfsd/xdr.h>
  40. #include <linux/nfsd/syscall.h>
  41. #include <linux/poll.h>
  42. #include <linux/personality.h>
  43. #include <linux/stat.h>
  44. #include <linux/filter.h> /* for setsockopt() */
  45. #include <linux/icmpv6.h> /* for setsockopt() */
  46. #include <linux/netfilter_ipv4/ip_queue.h> /* for setsockopt() */
  47. #include <linux/netfilter_ipv4/ip_tables.h> /* for setsockopt() */
  48. #include <linux/netfilter_ipv6/ip6_tables.h> /* for setsockopt() */
  49. #include <linux/highmem.h>
  50. #include <linux/highuid.h>
  51. #include <linux/mman.h>
  52. #include <asm/types.h>
  53. #include <asm/uaccess.h>
  54. #include <asm/semaphore.h>
  55. #include "sys32.h"
  56. #define A(__x) ((unsigned long)(__x))
  57. #undef DEBUG
  58. #ifdef DEBUG
  59. #define DBG(x) printk x
  60. #else
  61. #define DBG(x)
  62. #endif
  63. /*
  64.  * count32() counts the number of arguments/envelopes. It is basically
  65.  *           a copy of count() from fs/exec.c, except that it works
  66.  *           with 32 bit argv and envp pointers.
  67.  */
  68. static int count32(u32 *argv, int max)
  69. {
  70. int i = 0;
  71. if (argv != NULL) {
  72. for (;;) {
  73. u32 p;
  74. int error;
  75. error = get_user(p,argv);
  76. if (error)
  77. return error;
  78. if (!p)
  79. break;
  80. argv++;
  81. if(++i > max)
  82. return -E2BIG;
  83. }
  84. }
  85. return i;
  86. }
  87. /*
  88.  * copy_strings32() is basically a copy of copy_strings() from fs/exec.c
  89.  *                  except that it works with 32 bit argv and envp pointers.
  90.  */
  91. static int copy_strings32(int argc, u32 *argv, struct linux_binprm *bprm)
  92. {
  93. while (argc-- > 0) {
  94. u32 str;
  95. int len;
  96. unsigned long pos;
  97. if (get_user(str, argv + argc) ||
  98.     !str ||
  99.     !(len = strnlen_user((char *)A(str), bprm->p)))
  100. return -EFAULT;
  101. if (bprm->p < len) 
  102. return -E2BIG; 
  103. bprm->p -= len;
  104. pos = bprm->p;
  105. while (len > 0) {
  106. char *kaddr;
  107. int i, new, err;
  108. struct page *page;
  109. int offset, bytes_to_copy;
  110. offset = pos % PAGE_SIZE;
  111. i = pos/PAGE_SIZE;
  112. page = bprm->page[i];
  113. new = 0;
  114. if (!page) {
  115. page = alloc_page(GFP_HIGHUSER);
  116. bprm->page[i] = page;
  117. if (!page)
  118. return -ENOMEM;
  119. new = 1;
  120. }
  121. kaddr = (char *)kmap(page);
  122. if (new && offset)
  123. memset(kaddr, 0, offset);
  124. bytes_to_copy = PAGE_SIZE - offset;
  125. if (bytes_to_copy > len) {
  126. bytes_to_copy = len;
  127. if (new)
  128. memset(kaddr+offset+len, 0, PAGE_SIZE-offset-len);
  129. }
  130. err = copy_from_user(kaddr + offset, (char *)A(str), bytes_to_copy);
  131. flush_dcache_page(page);
  132. flush_page_to_ram(page);
  133. kunmap(page);
  134. if (err)
  135. return -EFAULT; 
  136. pos += bytes_to_copy;
  137. str += bytes_to_copy;
  138. len -= bytes_to_copy;
  139. }
  140. }
  141. return 0;
  142. }
  143. /*
  144.  * do_execve32() is mostly a copy of do_execve(), with the exception
  145.  * that it processes 32 bit argv and envp pointers.
  146.  */
  147. static inline int 
  148. do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
  149. {
  150. struct linux_binprm bprm;
  151. struct file *file;
  152. int retval;
  153. int i;
  154. file = open_exec(filename);
  155. retval = PTR_ERR(file);
  156. if (IS_ERR(file))
  157. return retval;
  158. bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
  159. memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
  160. DBG(("do_execve32(%s, %p, %p, %p)n", filename, argv, envp, regs));
  161. bprm.file = file;
  162. bprm.filename = filename;
  163. bprm.sh_bang = 0;
  164. bprm.loader = 0;
  165. bprm.exec = 0;
  166. if ((bprm.argc = count32(argv, bprm.p / sizeof(u32))) < 0) {
  167. allow_write_access(file);
  168. fput(file);
  169. return bprm.argc;
  170. }
  171. if ((bprm.envc = count32(envp, bprm.p / sizeof(u32))) < 0) {
  172. allow_write_access(file);
  173. fput(file);
  174. return bprm.envc;
  175. }
  176. retval = prepare_binprm(&bprm);
  177. if (retval < 0)
  178. goto out;
  179. retval = copy_strings_kernel(1, &bprm.filename, &bprm);
  180. if (retval < 0)
  181. goto out;
  182. bprm.exec = bprm.p;
  183. retval = copy_strings32(bprm.envc, envp, &bprm);
  184. if (retval < 0)
  185. goto out;
  186. retval = copy_strings32(bprm.argc, argv, &bprm);
  187. if (retval < 0)
  188. goto out;
  189. retval = search_binary_handler(&bprm,regs);
  190. if (retval >= 0)
  191. /* execve success */
  192. return retval;
  193. out:
  194. /* Something went wrong, return the inode and free the argument pages*/
  195. allow_write_access(bprm.file);
  196. if (bprm.file)
  197. fput(bprm.file);
  198. for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
  199. struct page * page = bprm.page[i];
  200. if (page)
  201. __free_page(page);
  202. }
  203. return retval;
  204. }
  205. /*
  206.  * sys32_execve() executes a new program.
  207.  */
  208. asmlinkage int sys32_execve(struct pt_regs *regs)
  209. {
  210. int error;
  211. char *filename;
  212. DBG(("sys32_execve(%p) r26 = 0x%lxn", regs, regs->gr[26]));
  213. filename = getname((char *) regs->gr[26]);
  214. error = PTR_ERR(filename);
  215. if (IS_ERR(filename))
  216. goto out;
  217. error = do_execve32(filename, (u32 *) regs->gr[25],
  218. (u32 *) regs->gr[24], regs);
  219. if (error == 0)
  220. current->ptrace &= ~PT_DTRACE;
  221. putname(filename);
  222. out:
  223. return error;
  224. }
  225. asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
  226. int r22, int r21, int r20)
  227. {
  228.     printk(KERN_ERR "%s(%d): Unimplemented 32 on 64 syscall #%d!n", 
  229.      current->comm, current->pid, r20);
  230.     return -ENOSYS;
  231. }
  232. /* 32-bit user apps use struct statfs which uses 'long's */
  233. struct statfs32 {
  234. __s32 f_type;
  235. __s32 f_bsize;
  236. __s32 f_blocks;
  237. __s32 f_bfree;
  238. __s32 f_bavail;
  239. __s32 f_files;
  240. __s32 f_ffree;
  241. __kernel_fsid_t f_fsid;
  242. __s32 f_namelen;
  243. __s32 f_spare[6];
  244. };
  245. /* convert statfs struct to statfs32 struct and copy result to user */
  246. static unsigned long statfs32_to_user(struct statfs32 *ust32, struct statfs *st)
  247. {
  248.     struct statfs32 st32;
  249. #undef CP
  250. #define CP(a) st32.a = st->a
  251.     CP(f_type);
  252.     CP(f_bsize);
  253.     CP(f_blocks);
  254.     CP(f_bfree);
  255.     CP(f_bavail);
  256.     CP(f_files);
  257.     CP(f_ffree);
  258.     CP(f_fsid);
  259.     CP(f_namelen);
  260.     return copy_to_user(ust32, &st32, sizeof st32);
  261. }
  262. /* The following statfs calls are copies of code from linux/fs/open.c and
  263.  * should be checked against those from time to time */
  264. asmlinkage long sys32_statfs(const char * path, struct statfs32 * buf)
  265. {
  266. struct nameidata nd;
  267. int error;
  268. error = user_path_walk(path, &nd);
  269. if (!error) {
  270. struct statfs tmp;
  271. error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
  272. if (!error && statfs32_to_user(buf, &tmp))
  273. error = -EFAULT;
  274. path_release(&nd);
  275. }
  276. return error;
  277. }
  278. asmlinkage long sys32_fstatfs(unsigned int fd, struct statfs32 * buf)
  279. {
  280. struct file * file;
  281. struct statfs tmp;
  282. int error;
  283. error = -EBADF;
  284. file = fget(fd);
  285. if (!file)
  286. goto out;
  287. error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
  288. if (!error && statfs32_to_user(buf, &tmp))
  289. error = -EFAULT;
  290. fput(file);
  291. out:
  292. return error;
  293. }
  294. /* These may not work without my local types changes, but I wanted the
  295.  * code available in case it's useful to others. -PB
  296.  */
  297. /* from utime.h */
  298. struct utimbuf32 {
  299. __kernel_time_t32 actime;
  300. __kernel_time_t32 modtime;
  301. };
  302. asmlinkage long sys32_utime(char *filename, struct utimbuf32 *times)
  303. {
  304.     struct utimbuf32 times32;
  305.     struct utimbuf times64;
  306.     extern long sys_utime(char *filename, struct utimbuf *times);
  307.     char *fname;
  308.     long ret;
  309.     if (!times)
  310.      return sys_utime(filename, NULL);
  311.     /* get the 32-bit struct from user space */
  312.     if (copy_from_user(&times32, times, sizeof times32))
  313.      return -EFAULT;
  314.     /* convert it into the 64-bit one */
  315.     times64.actime = times32.actime;
  316.     times64.modtime = times32.modtime;
  317.     /* grab the file name */
  318.     fname = getname(filename);
  319.     KERNEL_SYSCALL(ret, sys_utime, fname, &times64);
  320.     /* free the file name */
  321.     putname(fname);
  322.     return ret;
  323. }
  324. struct tms32 {
  325. __kernel_clock_t32 tms_utime;
  326. __kernel_clock_t32 tms_stime;
  327. __kernel_clock_t32 tms_cutime;
  328. __kernel_clock_t32 tms_cstime;
  329. };
  330.                                 
  331. asmlinkage long sys32_times(struct tms32 *tbuf)
  332. {
  333. struct tms t;
  334. long ret;
  335. extern asmlinkage long sys_times(struct tms * tbuf);
  336. int err;
  337. KERNEL_SYSCALL(ret, sys_times, tbuf ? &t : NULL);
  338. if (tbuf) {
  339. err = put_user (t.tms_utime, &tbuf->tms_utime);
  340. err |= __put_user (t.tms_stime, &tbuf->tms_stime);
  341. err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
  342. err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
  343. if (err)
  344. ret = -EFAULT;
  345. }
  346. return ret;
  347. }
  348. struct flock32 {
  349. short l_type;
  350. short l_whence;
  351. __kernel_off_t32 l_start;
  352. __kernel_off_t32 l_len;
  353. __kernel_pid_t32 l_pid;
  354. };
  355. static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
  356. {
  357. int err;
  358. err = get_user(kfl->l_type, &ufl->l_type);
  359. err |= __get_user(kfl->l_whence, &ufl->l_whence);
  360. err |= __get_user(kfl->l_start, &ufl->l_start);
  361. err |= __get_user(kfl->l_len, &ufl->l_len);
  362. err |= __get_user(kfl->l_pid, &ufl->l_pid);
  363. return err;
  364. }
  365. static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
  366. {
  367. int err;
  368. err = __put_user(kfl->l_type, &ufl->l_type);
  369. err |= __put_user(kfl->l_whence, &ufl->l_whence);
  370. err |= __put_user(kfl->l_start, &ufl->l_start);
  371. err |= __put_user(kfl->l_len, &ufl->l_len);
  372. err |= __put_user(kfl->l_pid, &ufl->l_pid);
  373. return err;
  374. }
  375. extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
  376. asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
  377. {
  378. switch (cmd) {
  379. case F_GETLK:
  380. case F_SETLK:
  381. case F_SETLKW:
  382. {
  383. struct flock f;
  384. long ret;
  385. if(get_flock(&f, (struct flock32 *)arg))
  386. return -EFAULT;
  387. KERNEL_SYSCALL(ret, sys_fcntl, fd, cmd, (unsigned long)&f);
  388. if (ret) return ret;
  389. if (f.l_start >= 0x7fffffffUL ||
  390.     f.l_len >= 0x7fffffffUL ||
  391.     f.l_start + f.l_len >= 0x7fffffffUL)
  392. return -EOVERFLOW;
  393. if(put_flock(&f, (struct flock32 *)arg))
  394. return -EFAULT;
  395. return 0;
  396. }
  397. default:
  398. return sys_fcntl(fd, cmd, (unsigned long)arg);
  399. }
  400. }
  401. #ifdef CONFIG_SYSCTL
  402. struct __sysctl_args32 {
  403. u32 name;
  404. int nlen;
  405. u32 oldval;
  406. u32 oldlenp;
  407. u32 newval;
  408. u32 newlen;
  409. u32 __unused[4];
  410. };
  411. asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
  412. {
  413. struct __sysctl_args32 tmp;
  414. int error;
  415. unsigned int oldlen32;
  416. size_t oldlen, *oldlenp = NULL;
  417. unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
  418. extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
  419.        void *newval, size_t newlen);
  420. DBG(("sysctl32(%p)n", args));
  421. if (copy_from_user(&tmp, args, sizeof(tmp)))
  422. return -EFAULT;
  423. if (tmp.oldval && tmp.oldlenp) {
  424. /* Duh, this is ugly and might not work if sysctl_args
  425.    is in read-only memory, but do_sysctl does indirectly
  426.    a lot of uaccess in both directions and we'd have to
  427.    basically copy the whole sysctl.c here, and
  428.    glibc's __sysctl uses rw memory for the structure
  429.    anyway.  */
  430. /* a possibly better hack than this, which will avoid the
  431.  * problem if the struct is read only, is to push the
  432.  * 'oldlen' value out to the user's stack instead. -PB
  433.  */
  434. if (get_user(oldlen32, (u32 *)(u64)tmp.oldlenp))
  435. return -EFAULT;
  436. oldlen = oldlen32;
  437. if (put_user(oldlen, (size_t *)addr))
  438. return -EFAULT;
  439. oldlenp = (size_t *)addr;
  440. }
  441. lock_kernel();
  442. error = do_sysctl((int *)(u64)tmp.name, tmp.nlen, (void *)(u64)tmp.oldval,
  443.   oldlenp, (void *)(u64)tmp.newval, tmp.newlen);
  444. unlock_kernel();
  445. if (oldlenp) {
  446. if (!error) {
  447. if (get_user(oldlen, (size_t *)addr)) {
  448. error = -EFAULT;
  449. } else {
  450. oldlen32 = oldlen;
  451. if (put_user(oldlen32, (u32 *)(u64)tmp.oldlenp))
  452. error = -EFAULT;
  453. }
  454. }
  455. if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
  456. error = -EFAULT;
  457. }
  458. return error;
  459. }
  460. #else /* CONFIG_SYSCTL */
  461. asmlinkage long sys32_sysctl(struct __sysctl_args *args)
  462. {
  463. return -ENOSYS;
  464. }
  465. #endif /* CONFIG_SYSCTL */
  466. struct timespec32 {
  467. s32    tv_sec;
  468. s32    tv_nsec;
  469. };
  470.                 
  471. static int
  472. put_timespec32(struct timespec32 *u, struct timespec *t)
  473. {
  474. struct timespec32 t32;
  475. t32.tv_sec = t->tv_sec;
  476. t32.tv_nsec = t->tv_nsec;
  477. return copy_to_user(u, &t32, sizeof t32);
  478. }
  479. asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
  480. {
  481. struct timespec t;
  482. struct timespec32 t32;
  483. int ret;
  484. extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
  485. if (copy_from_user(&t32, rqtp, sizeof t32))
  486. return -EFAULT;
  487. t.tv_sec = t32.tv_sec;
  488. t.tv_nsec = t32.tv_nsec;
  489. DBG(("sys32_nanosleep({%d, %d})n", t32.tv_sec, t32.tv_nsec));
  490. KERNEL_SYSCALL(ret, sys_nanosleep, &t, rmtp ? &t : NULL);
  491. if (rmtp && ret == -EINTR) {
  492. if (put_timespec32(rmtp, &t))
  493. return -EFAULT;
  494. }
  495. return ret;
  496. }
  497. asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
  498. struct timespec32 *interval)
  499. {
  500. struct timespec t;
  501. int ret;
  502. extern asmlinkage long sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
  503. KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, &t);
  504. if (put_timespec32(interval, &t))
  505. return -EFAULT;
  506. return ret;
  507. }
  508. typedef __kernel_time_t32 time_t32;
  509. static int
  510. put_timeval32(struct timeval32 *u, struct timeval *t)
  511. {
  512. struct timeval32 t32;
  513. t32.tv_sec = t->tv_sec;
  514. t32.tv_usec = t->tv_usec;
  515. return copy_to_user(u, &t32, sizeof t32);
  516. }
  517. static int
  518. get_timeval32(struct timeval32 *u, struct timeval *t)
  519. {
  520. int err;
  521. struct timeval32 t32;
  522. if ((err = copy_from_user(&t32, u, sizeof t32)) == 0)
  523. {
  524.     t->tv_sec = t32.tv_sec;
  525.     t->tv_usec = t32.tv_usec;
  526. }
  527. return err;
  528. }
  529. asmlinkage long sys32_time(time_t32 *tloc)
  530. {
  531.     time_t now = CURRENT_TIME;
  532.     time_t32 now32 = now;
  533.     if (tloc)
  534.      if (put_user(now32, tloc))
  535. now32 = -EFAULT;
  536.     return now32;
  537. }
  538. asmlinkage int
  539. sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
  540. {
  541.     extern void do_gettimeofday(struct timeval *tv);
  542.     if (tv) {
  543.     struct timeval ktv;
  544.     do_gettimeofday(&ktv);
  545.     if (put_timeval32(tv, &ktv))
  546.     return -EFAULT;
  547.     }
  548.     if (tz) {
  549.     extern struct timezone sys_tz;
  550.     if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
  551.     return -EFAULT;
  552.     }
  553.     return 0;
  554. }
  555. asmlinkage int
  556. sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
  557. {
  558.     struct timeval ktv;
  559.     struct timezone ktz;
  560.     extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
  561.     if (tv) {
  562.     if (get_timeval32(tv, &ktv))
  563.     return -EFAULT;
  564.     }
  565.     if (tz) {
  566.     if (copy_from_user(&ktz, tz, sizeof(ktz)))
  567.     return -EFAULT;
  568.     }
  569.     return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
  570. }
  571. struct itimerval32 {
  572. struct timeval32 it_interval; /* timer interval */
  573. struct timeval32 it_value; /* current value */
  574. };
  575. asmlinkage long sys32_getitimer(int which, struct itimerval32 *ov32)
  576. {
  577. int error = -EFAULT;
  578. struct itimerval get_buffer;
  579. extern int do_getitimer(int which, struct itimerval *value);
  580. if (ov32) {
  581. error = do_getitimer(which, &get_buffer);
  582. if (!error) {
  583. struct itimerval32 gb32;
  584. gb32.it_interval.tv_sec = get_buffer.it_interval.tv_sec;
  585. gb32.it_interval.tv_usec = get_buffer.it_interval.tv_usec;
  586. gb32.it_value.tv_sec = get_buffer.it_value.tv_sec;
  587. gb32.it_value.tv_usec = get_buffer.it_value.tv_usec;
  588. if (copy_to_user(ov32, &gb32, sizeof(gb32)))
  589. error = -EFAULT; 
  590. }
  591. }
  592. return error;
  593. }
  594. asmlinkage long sys32_setitimer(int which, struct itimerval32 *v32,
  595.       struct itimerval32 *ov32)
  596. {
  597. struct itimerval set_buffer, get_buffer;
  598. struct itimerval32 sb32, gb32;
  599. extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ov32);
  600. int error;
  601. if (v32) {
  602. if(copy_from_user(&sb32, v32, sizeof(sb32)))
  603. return -EFAULT;
  604. set_buffer.it_interval.tv_sec = sb32.it_interval.tv_sec;
  605. set_buffer.it_interval.tv_usec = sb32.it_interval.tv_usec;
  606. set_buffer.it_value.tv_sec = sb32.it_value.tv_sec;
  607. set_buffer.it_value.tv_usec = sb32.it_value.tv_usec;
  608. } else
  609. memset((char *) &set_buffer, 0, sizeof(set_buffer));
  610. error = do_setitimer(which, &set_buffer, ov32 ? &get_buffer : 0);
  611. if (error || !ov32)
  612. return error;
  613. gb32.it_interval.tv_sec = get_buffer.it_interval.tv_sec;
  614. gb32.it_interval.tv_usec = get_buffer.it_interval.tv_usec;
  615. gb32.it_value.tv_sec = get_buffer.it_value.tv_sec;
  616. gb32.it_value.tv_usec = get_buffer.it_value.tv_usec;
  617. if (copy_to_user(ov32, &gb32, sizeof(gb32)))
  618. return -EFAULT; 
  619. return 0;
  620. }
  621. struct rusage32 {
  622.         struct timeval32 ru_utime;
  623.         struct timeval32 ru_stime;
  624.         int    ru_maxrss;
  625.         int    ru_ixrss;
  626.         int    ru_idrss;
  627.         int    ru_isrss;
  628.         int    ru_minflt;
  629.         int    ru_majflt;
  630.         int    ru_nswap;
  631.         int    ru_inblock;
  632.         int    ru_oublock;
  633.         int    ru_msgsnd; 
  634.         int    ru_msgrcv; 
  635.         int    ru_nsignals;
  636.         int    ru_nvcsw;
  637.         int    ru_nivcsw;
  638. };
  639. static int
  640. put_rusage32(struct rusage32 *ru32p, struct rusage *r)
  641. {
  642. struct rusage32 r32;
  643. #undef CP
  644. #define CP(t) r32.t = r->t;
  645. CP(ru_utime.tv_sec); CP(ru_utime.tv_usec);
  646. CP(ru_stime.tv_sec); CP(ru_stime.tv_usec);
  647. CP(ru_maxrss);
  648. CP(ru_ixrss);
  649. CP(ru_idrss);
  650. CP(ru_isrss);
  651. CP(ru_minflt);
  652. CP(ru_majflt);
  653. CP(ru_nswap);
  654. CP(ru_inblock);
  655. CP(ru_oublock);
  656. CP(ru_msgsnd);
  657. CP(ru_msgrcv);
  658. CP(ru_nsignals);
  659. CP(ru_nvcsw);
  660. CP(ru_nivcsw);
  661. return copy_to_user(ru32p, &r32, sizeof r32);
  662. }
  663. asmlinkage int
  664. sys32_getrusage(int who, struct rusage32 *ru)
  665. {
  666. struct rusage r;
  667. int ret;
  668. extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
  669. KERNEL_SYSCALL(ret, sys_getrusage, who, &r);
  670. if (put_rusage32(ru, &r)) return -EFAULT;
  671. return ret;
  672. }
  673. asmlinkage int
  674. sys32_wait4(__kernel_pid_t32 pid, unsigned int * stat_addr, int options,
  675.     struct rusage32 * ru)
  676. {
  677. if (!ru)
  678. return sys_wait4(pid, stat_addr, options, NULL);
  679. else {
  680. struct rusage r;
  681. int ret;
  682. unsigned int status;
  683. KERNEL_SYSCALL(ret, sys_wait4, pid, stat_addr ? &status : NULL, options, &r);
  684. if (put_rusage32(ru, &r)) return -EFAULT;
  685. if (stat_addr && put_user(status, stat_addr))
  686. return -EFAULT;
  687. return ret;
  688. }
  689. }
  690. struct stat32 {
  691. __kernel_dev_t32 st_dev; /* dev_t is 32 bits on parisc */
  692. __kernel_ino_t32 st_ino; /* 32 bits */
  693. __kernel_mode_t32 st_mode; /* 16 bits */
  694. __kernel_nlink_t32 st_nlink; /* 16 bits */
  695. unsigned short st_reserved1; /* old st_uid */
  696. unsigned short st_reserved2; /* old st_gid */
  697. __kernel_dev_t32 st_rdev;
  698. __kernel_off_t32 st_size;
  699. __kernel_time_t32 st_atime;
  700. unsigned int st_spare1;
  701. __kernel_time_t32 st_mtime;
  702. unsigned int st_spare2;
  703. __kernel_time_t32 st_ctime;
  704. unsigned int st_spare3;
  705. int st_blksize;
  706. int st_blocks;
  707. unsigned int __unused1; /* ACL stuff */
  708. __kernel_dev_t32 __unused2; /* network */
  709. __kernel_ino_t32 __unused3; /* network */
  710. unsigned int __unused4; /* cnodes */
  711. unsigned short __unused5; /* netsite */
  712. short st_fstype;
  713. __kernel_dev_t32 st_realdev;
  714. unsigned short st_basemode;
  715. unsigned short st_spareshort;
  716. __kernel_uid_t32 st_uid;
  717. __kernel_gid_t32 st_gid;
  718. unsigned int st_spare4[3];
  719. };
  720. /*
  721.  * Revalidate the inode. This is required for proper NFS attribute caching.
  722.  */
  723. static __inline__ int
  724. do_revalidate(struct dentry *dentry)
  725. {
  726. struct inode * inode = dentry->d_inode;
  727. if (inode->i_op && inode->i_op->revalidate)
  728. return inode->i_op->revalidate(dentry);
  729. return 0;
  730. }
  731. static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
  732. {
  733. struct stat32 tmp;
  734. unsigned int blocks, indirect;
  735. memset(&tmp, 0, sizeof(tmp));
  736. tmp.st_dev = kdev_t_to_nr(inode->i_dev);
  737. tmp.st_ino = inode->i_ino;
  738. tmp.st_mode = inode->i_mode;
  739. tmp.st_nlink = inode->i_nlink;
  740. SET_STAT_UID(tmp, inode->i_uid);
  741. SET_STAT_GID(tmp, inode->i_gid);
  742. tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
  743. #if BITS_PER_LONG == 32
  744. if (inode->i_size > 0x7fffffff)
  745. return -EOVERFLOW;
  746. #endif
  747. tmp.st_size = inode->i_size;
  748. tmp.st_atime = inode->i_atime;
  749. tmp.st_mtime = inode->i_mtime;
  750. tmp.st_ctime = inode->i_ctime;
  751. /*
  752.  * st_blocks and st_blksize are approximated with a simple algorithm if
  753.  * they aren't supported directly by the filesystem. The minix and msdos
  754.  * filesystems don't keep track of blocks, so they would either have to
  755.  * be counted explicitly (by delving into the file itself), or by using
  756.  * this simple algorithm to get a reasonable (although not 100% accurate)
  757.  * value.
  758.  */
  759. /*
  760.  * Use minix fs values for the number of direct and indirect blocks.  The
  761.  * count is now exact for the minix fs except that it counts zero blocks.
  762.  * Everything is in units of BLOCK_SIZE until the assignment to
  763.  * tmp.st_blksize.
  764.  */
  765. #define D_B   7
  766. #define I_B   (BLOCK_SIZE / sizeof(unsigned short))
  767. if (!inode->i_blksize) {
  768. blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
  769. if (blocks > D_B) {
  770. indirect = (blocks - D_B + I_B - 1) / I_B;
  771. blocks += indirect;
  772. if (indirect > 1) {
  773. indirect = (indirect - 1 + I_B - 1) / I_B;
  774. blocks += indirect;
  775. if (indirect > 1)
  776. blocks++;
  777. }
  778. }
  779. tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
  780. tmp.st_blksize = BLOCK_SIZE;
  781. } else {
  782. tmp.st_blocks = inode->i_blocks;
  783. tmp.st_blksize = inode->i_blksize;
  784. }
  785. return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
  786. }
  787. asmlinkage long sys32_newstat(char * filename, struct stat32 *statbuf)
  788. {
  789. struct nameidata nd;
  790. int error;
  791. error = user_path_walk(filename, &nd);
  792. if (!error) {
  793. error = do_revalidate(nd.dentry);
  794. if (!error)
  795. error = cp_new_stat32(nd.dentry->d_inode, statbuf);
  796. path_release(&nd);
  797. }
  798. return error;
  799. }
  800. asmlinkage long sys32_newlstat(char * filename, struct stat32 *statbuf)
  801. {
  802. struct nameidata nd;
  803. int error;
  804. error = user_path_walk_link(filename, &nd);
  805. if (!error) {
  806. error = do_revalidate(nd.dentry);
  807. if (!error)
  808. error = cp_new_stat32(nd.dentry->d_inode, statbuf);
  809. path_release(&nd);
  810. }
  811. return error;
  812. }
  813. asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
  814. {
  815. struct file * f;
  816. int err = -EBADF;
  817. f = fget(fd);
  818. if (f) {
  819. struct dentry * dentry = f->f_dentry;
  820. err = do_revalidate(dentry);
  821. if (!err)
  822. err = cp_new_stat32(dentry->d_inode, statbuf);
  823. fput(f);
  824. }
  825. return err;
  826. }
  827. struct linux32_dirent {
  828. u32 d_ino;
  829. __kernel_off_t32 d_off;
  830. u16 d_reclen;
  831. char d_name[1];
  832. };
  833. struct old_linux32_dirent {
  834. u32 d_ino;
  835. u32 d_offset;
  836. u16 d_namlen;
  837. char d_name[1];
  838. };
  839. struct getdents32_callback {
  840. struct linux32_dirent * current_dir;
  841. struct linux32_dirent * previous;
  842. int count;
  843. int error;
  844. };
  845. struct readdir32_callback {
  846. struct old_linux32_dirent * dirent;
  847. int count;
  848. };
  849. #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
  850. #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
  851. static int
  852. filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
  853.    unsigned int d_type)
  854. {
  855. struct linux32_dirent * dirent;
  856. struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
  857. int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
  858. buf->error = -EINVAL; /* only used if we fail.. */
  859. if (reclen > buf->count)
  860. return -EINVAL;
  861. dirent = buf->previous;
  862. if (dirent)
  863. put_user(offset, &dirent->d_off);
  864. dirent = buf->current_dir;
  865. buf->previous = dirent;
  866. put_user(ino, &dirent->d_ino);
  867. put_user(reclen, &dirent->d_reclen);
  868. copy_to_user(dirent->d_name, name, namlen);
  869. put_user(0, dirent->d_name + namlen);
  870. ((char *) dirent) += reclen;
  871. buf->current_dir = dirent;
  872. buf->count -= reclen;
  873. return 0;
  874. }
  875. asmlinkage long
  876. sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
  877. {
  878. struct file * file;
  879. struct linux32_dirent * lastdirent;
  880. struct getdents32_callback buf;
  881. int error;
  882. error = -EBADF;
  883. file = fget(fd);
  884. if (!file)
  885. goto out;
  886. buf.current_dir = (struct linux32_dirent *) dirent;
  887. buf.previous = NULL;
  888. buf.count = count;
  889. buf.error = 0;
  890. error = vfs_readdir(file, filldir32, &buf);
  891. if (error < 0)
  892. goto out_putf;
  893. error = buf.error;
  894. lastdirent = buf.previous;
  895. if (lastdirent) {
  896. put_user(file->f_pos, &lastdirent->d_off);
  897. error = count - buf.count;
  898. }
  899. out_putf:
  900. fput(file);
  901. out:
  902. return error;
  903. }
  904. static int
  905. fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
  906.       unsigned int d_type)
  907. {
  908. struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
  909. struct old_linux32_dirent * dirent;
  910. if (buf->count)
  911. return -EINVAL;
  912. buf->count++;
  913. dirent = buf->dirent;
  914. put_user(ino, &dirent->d_ino);
  915. put_user(offset, &dirent->d_offset);
  916. put_user(namlen, &dirent->d_namlen);
  917. copy_to_user(dirent->d_name, name, namlen);
  918. put_user(0, dirent->d_name + namlen);
  919. return 0;
  920. }
  921. asmlinkage long
  922. sys32_readdir (unsigned int fd, void * dirent, unsigned int count)
  923. {
  924. int error;
  925. struct file * file;
  926. struct readdir32_callback buf;
  927. error = -EBADF;
  928. file = fget(fd);
  929. if (!file)
  930. goto out;
  931. buf.count = 0;
  932. buf.dirent = dirent;
  933. error = vfs_readdir(file, fillonedir32, &buf);
  934. if (error >= 0)
  935. error = buf.count;
  936. fput(file);
  937. out:
  938. return error;
  939. }
  940. struct rlimit32 {
  941. __u32 rlim_cur;
  942. __u32 rlim_max;
  943. };
  944. #define RLIM32_INFINITY 0xffffffff
  945. asmlinkage long sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
  946. {
  947. struct rlimit32 rlim32;
  948. struct rlimit *rlimip;
  949. if (resource >= RLIM_NLIMITS)
  950. return -EINVAL;
  951. rlimip = current->rlim + resource;
  952. if (rlimip->rlim_cur >= RLIM32_INFINITY) {
  953. rlim32.rlim_cur = RLIM32_INFINITY;
  954. } else {
  955. rlim32.rlim_cur = rlimip->rlim_cur;
  956. }
  957. if (rlimip->rlim_max >= RLIM32_INFINITY) {
  958. rlim32.rlim_max = RLIM32_INFINITY;
  959. } else {
  960. rlim32.rlim_max = rlimip->rlim_max;
  961. }
  962. return copy_to_user(rlim, &rlim32, sizeof (struct rlimit32));
  963. }
  964. asmlinkage long sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
  965. {
  966. struct rlimit32 rlim32;
  967. struct rlimit new_rlim, *old_rlim;
  968. if (resource >= RLIM_NLIMITS)
  969. return -EINVAL;
  970. if (copy_from_user(&rlim32, rlim, sizeof(rlim)))
  971. return -EFAULT;
  972. if (rlim32.rlim_cur == RLIM32_INFINITY) {
  973. new_rlim.rlim_cur = RLIM_INFINITY;
  974. } else {
  975. new_rlim.rlim_cur = rlim32.rlim_cur;
  976. }
  977. if (rlim32.rlim_max == RLIM32_INFINITY) {
  978. new_rlim.rlim_max = RLIM_INFINITY;
  979. } else {
  980. new_rlim.rlim_max = rlim32.rlim_max;
  981. }
  982. old_rlim = current->rlim + resource;
  983. if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
  984.      (new_rlim.rlim_max > old_rlim->rlim_max)) &&
  985.     !capable(CAP_SYS_RESOURCE))
  986. return -EPERM;
  987. if (resource == RLIMIT_NOFILE) {
  988. if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
  989. return -EPERM;
  990. }
  991. if (resource == RLIMIT_STACK) {
  992. if (new_rlim.rlim_max > 1024 * 1024 * 1024) {
  993. new_rlim.rlim_max = 1024 * 1024 * 1024;
  994. }
  995. new_rlim.rlim_max = PAGE_ALIGN(new_rlim.rlim_max);
  996. }
  997. *old_rlim = new_rlim;
  998. return 0;
  999. }
  1000. static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
  1001. {
  1002. int i;
  1003. unsigned long page;
  1004. struct vm_area_struct *vma;
  1005. *kernel = 0;
  1006. if(!user)
  1007. return 0;
  1008. vma = find_vma(current->mm, (unsigned long)user);
  1009. if(!vma || (unsigned long)user < vma->vm_start)
  1010. return -EFAULT;
  1011. if(!(vma->vm_flags & VM_READ))
  1012. return -EFAULT;
  1013. i = vma->vm_end - (unsigned long) user;
  1014. if(PAGE_SIZE <= (unsigned long) i)
  1015. i = PAGE_SIZE - 1;
  1016. if(!(page = __get_free_page(GFP_KERNEL)))
  1017. return -ENOMEM;
  1018. if(copy_from_user((void *) page, user, i)) {
  1019. free_page(page);
  1020. return -EFAULT;
  1021. }
  1022. *kernel = page;
  1023. return 0;
  1024. }
  1025. #define SMBFS_NAME "smbfs"
  1026. #define NCPFS_NAME "ncpfs"
  1027. asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
  1028. {
  1029. unsigned long type_page = 0;
  1030. unsigned long data_page = 0;
  1031. unsigned long dev_page = 0;
  1032. unsigned long dir_page = 0;
  1033. int err, is_smb, is_ncp;
  1034. is_smb = is_ncp = 0;
  1035. err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
  1036. if (err)
  1037. goto out;
  1038. if (!type_page) {
  1039. err = -EINVAL;
  1040. goto out;
  1041. }
  1042. is_smb = !strcmp((char *)type_page, SMBFS_NAME);
  1043. is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
  1044. err = copy_mount_stuff_to_kernel((const void *)(unsigned long)data, &data_page);
  1045. if (err)
  1046. goto type_out;
  1047. err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
  1048. if (err)
  1049. goto data_out;
  1050. err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
  1051. if (err)
  1052. goto dev_out;
  1053. if (!is_smb && !is_ncp) {
  1054. lock_kernel();
  1055. err = do_mount((char*)dev_page, (char*)dir_page,
  1056. (char*)type_page, new_flags, (char*)data_page);
  1057. unlock_kernel();
  1058. } else {
  1059. if (is_ncp)
  1060. panic("NCP mounts not yet supported 32/64 parisc");
  1061. /* do_ncp_super_data_conv((void *)data_page); */
  1062. else {
  1063. panic("SMB mounts not yet supported 32/64 parisc");
  1064. /* do_smb_super_data_conv((void *)data_page); */
  1065. }
  1066. lock_kernel();
  1067. err = do_mount((char*)dev_page, (char*)dir_page,
  1068. (char*)type_page, new_flags, (char*)data_page);
  1069. unlock_kernel();
  1070. }
  1071. free_page(dir_page);
  1072. dev_out:
  1073. free_page(dev_page);
  1074. data_out:
  1075. free_page(data_page);
  1076. type_out:
  1077. free_page(type_page);
  1078. out:
  1079. return err;
  1080. }
  1081. #ifdef CONFIG_MODULES
  1082. struct module_info32 {
  1083. u32 addr;
  1084. u32 size;
  1085. u32 flags;
  1086. s32 usecount;
  1087. };
  1088. /* Query various bits about modules.  */
  1089. static inline long
  1090. get_mod_name(const char *user_name, char **buf)
  1091. {
  1092. unsigned long page;
  1093. long retval;
  1094. if ((unsigned long)user_name >= TASK_SIZE
  1095.     && !segment_eq(get_fs (), KERNEL_DS))
  1096. return -EFAULT;
  1097. page = __get_free_page(GFP_KERNEL);
  1098. if (!page)
  1099. return -ENOMEM;
  1100. retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
  1101. if (retval > 0) {
  1102. if (retval < PAGE_SIZE) {
  1103. *buf = (char *)page;
  1104. return retval;
  1105. }
  1106. retval = -ENAMETOOLONG;
  1107. } else if (!retval)
  1108. retval = -EINVAL;
  1109. free_page(page);
  1110. return retval;
  1111. }
  1112. static inline void
  1113. put_mod_name(char *buf)
  1114. {
  1115. free_page((unsigned long)buf);
  1116. }
  1117. static __inline__ struct module *find_module(const char *name)
  1118. {
  1119. struct module *mod;
  1120. for (mod = module_list; mod ; mod = mod->next) {
  1121. if (mod->flags & MOD_DELETED)
  1122. continue;
  1123. if (!strcmp(mod->name, name))
  1124. break;
  1125. }
  1126. return mod;
  1127. }
  1128. static int
  1129. qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
  1130. {
  1131. struct module *mod;
  1132. size_t nmod, space, len;
  1133. nmod = space = 0;
  1134. for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
  1135. len = strlen(mod->name)+1;
  1136. if (len > bufsize)
  1137. goto calc_space_needed;
  1138. if (copy_to_user(buf, mod->name, len))
  1139. return -EFAULT;
  1140. buf += len;
  1141. bufsize -= len;
  1142. space += len;
  1143. }
  1144. if (put_user(nmod, ret))
  1145. return -EFAULT;
  1146. else
  1147. return 0;
  1148. calc_space_needed:
  1149. space += len;
  1150. while ((mod = mod->next)->next != NULL)
  1151. space += strlen(mod->name)+1;
  1152. if (put_user(space, ret))
  1153. return -EFAULT;
  1154. else
  1155. return -ENOSPC;
  1156. }
  1157. static int
  1158. qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
  1159. {
  1160. size_t i, space, len;
  1161. if (mod->next == NULL)
  1162. return -EINVAL;
  1163. if (!MOD_CAN_QUERY(mod))
  1164. return put_user(0, ret);
  1165. space = 0;
  1166. for (i = 0; i < mod->ndeps; ++i) {
  1167. const char *dep_name = mod->deps[i].dep->name;
  1168. len = strlen(dep_name)+1;
  1169. if (len > bufsize)
  1170. goto calc_space_needed;
  1171. if (copy_to_user(buf, dep_name, len))
  1172. return -EFAULT;
  1173. buf += len;
  1174. bufsize -= len;
  1175. space += len;
  1176. }
  1177. return put_user(i, ret);
  1178. calc_space_needed:
  1179. space += len;
  1180. while (++i < mod->ndeps)
  1181. space += strlen(mod->deps[i].dep->name)+1;
  1182. if (put_user(space, ret))
  1183. return -EFAULT;
  1184. else
  1185. return -ENOSPC;
  1186. }
  1187. static int
  1188. qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
  1189. {
  1190. size_t nrefs, space, len;
  1191. struct module_ref *ref;
  1192. if (mod->next == NULL)
  1193. return -EINVAL;
  1194. if (!MOD_CAN_QUERY(mod))
  1195. if (put_user(0, ret))
  1196. return -EFAULT;
  1197. else
  1198. return 0;
  1199. space = 0;
  1200. for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
  1201. const char *ref_name = ref->ref->name;
  1202. len = strlen(ref_name)+1;
  1203. if (len > bufsize)
  1204. goto calc_space_needed;
  1205. if (copy_to_user(buf, ref_name, len))
  1206. return -EFAULT;
  1207. buf += len;
  1208. bufsize -= len;
  1209. space += len;
  1210. }
  1211. if (put_user(nrefs, ret))
  1212. return -EFAULT;
  1213. else
  1214. return 0;
  1215. calc_space_needed:
  1216. space += len;
  1217. while ((ref = ref->next_ref) != NULL)
  1218. space += strlen(ref->ref->name)+1;
  1219. if (put_user(space, ret))
  1220. return -EFAULT;
  1221. else
  1222. return -ENOSPC;
  1223. }
  1224. static inline int
  1225. qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
  1226. {
  1227. size_t i, space, len;
  1228. struct module_symbol *s;
  1229. char *strings;
  1230. unsigned *vals;
  1231. if (!MOD_CAN_QUERY(mod))
  1232. if (put_user(0, ret))
  1233. return -EFAULT;
  1234. else
  1235. return 0;
  1236. space = mod->nsyms * 2*sizeof(u32);
  1237. i = len = 0;
  1238. s = mod->syms;
  1239. if (space > bufsize)
  1240. goto calc_space_needed;
  1241. if (!access_ok(VERIFY_WRITE, buf, space))
  1242. return -EFAULT;
  1243. bufsize -= space;
  1244. vals = (unsigned *)buf;
  1245. strings = buf+space;
  1246. for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
  1247. len = strlen(s->name)+1;
  1248. if (len > bufsize)
  1249. goto calc_space_needed;
  1250. if (copy_to_user(strings, s->name, len)
  1251.     || __put_user(s->value, vals+0)
  1252.     || __put_user(space, vals+1))
  1253. return -EFAULT;
  1254. strings += len;
  1255. bufsize -= len;
  1256. space += len;
  1257. }
  1258. if (put_user(i, ret))
  1259. return -EFAULT;
  1260. else
  1261. return 0;
  1262. calc_space_needed:
  1263. for (; i < mod->nsyms; ++i, ++s)
  1264. space += strlen(s->name)+1;
  1265. if (put_user(space, ret))
  1266. return -EFAULT;
  1267. else
  1268. return -ENOSPC;
  1269. }
  1270. static inline int
  1271. qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
  1272. {
  1273. int error = 0;
  1274. if (mod->next == NULL)
  1275. return -EINVAL;
  1276. if (sizeof(struct module_info32) <= bufsize) {
  1277. struct module_info32 info;
  1278. info.addr = (unsigned long)mod;
  1279. info.size = mod->size;
  1280. info.flags = mod->flags;
  1281. info.usecount =
  1282. ((mod_member_present(mod, can_unload)
  1283.   && mod->can_unload)
  1284.  ? -1 : atomic_read(&mod->uc.usecount));
  1285. if (copy_to_user(buf, &info, sizeof(struct module_info32)))
  1286. return -EFAULT;
  1287. } else
  1288. error = -ENOSPC;
  1289. if (put_user(sizeof(struct module_info32), ret))
  1290. return -EFAULT;
  1291. return error;
  1292. }
  1293. asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, __kernel_size_t32 *ret)
  1294. {
  1295. struct module *mod;
  1296. int err;
  1297. lock_kernel();
  1298. if (name_user == 0) {
  1299. /* This finds "kernel_module" which is not exported. */
  1300. for(mod = module_list; mod->next != NULL; mod = mod->next)
  1301. ;
  1302. } else {
  1303. long namelen;
  1304. char *name;
  1305. if ((namelen = get_mod_name(name_user, &name)) < 0) {
  1306. err = namelen;
  1307. goto out;
  1308. }
  1309. err = -ENOENT;
  1310. if (namelen == 0) {
  1311. /* This finds "kernel_module" which is not exported. */
  1312. for(mod = module_list; mod->next != NULL; mod = mod->next)
  1313. ;
  1314. } else if ((mod = find_module(name)) == NULL) {
  1315. put_mod_name(name);
  1316. goto out;
  1317. }
  1318. put_mod_name(name);
  1319. }
  1320. switch (which)
  1321. {
  1322. case 0:
  1323. err = 0;
  1324. break;
  1325. case QM_MODULES:
  1326. err = qm_modules(buf, bufsize, ret);
  1327. break;
  1328. case QM_DEPS:
  1329. err = qm_deps(mod, buf, bufsize, ret);
  1330. break;
  1331. case QM_REFS:
  1332. err = qm_refs(mod, buf, bufsize, ret);
  1333. break;
  1334. case QM_SYMBOLS:
  1335. err = qm_symbols(mod, buf, bufsize, ret);
  1336. break;
  1337. case QM_INFO:
  1338. err = qm_info(mod, buf, bufsize, ret);
  1339. break;
  1340. default:
  1341. err = -EINVAL;
  1342. break;
  1343. }
  1344. out:
  1345. unlock_kernel();
  1346. return err;
  1347. }
  1348. struct kernel_sym32 {
  1349. u32 value;
  1350. char name[60];
  1351. };
  1352.  
  1353. extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
  1354. asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
  1355. {
  1356. int len, i;
  1357. struct kernel_sym *tbl;
  1358. mm_segment_t old_fs;
  1359. len = sys_get_kernel_syms(NULL);
  1360. if (!table) return len;
  1361. tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
  1362. if (!tbl) return -ENOMEM;
  1363. old_fs = get_fs();
  1364. set_fs (KERNEL_DS);
  1365. sys_get_kernel_syms(tbl);
  1366. set_fs (old_fs);
  1367. for (i = 0; i < len; i++, table++) {
  1368. if (put_user (tbl[i].value, &table->value) ||
  1369.     copy_to_user (table->name, tbl[i].name, 60))
  1370. break;
  1371. }
  1372. kfree (tbl);
  1373. return i;
  1374. }
  1375. #else /* CONFIG_MODULES */
  1376. asmlinkage int
  1377. sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
  1378.  size_t *ret)
  1379. {
  1380. /* Let the program know about the new interface.  Not that
  1381.    it'll do them much good.  */
  1382. if (which == 0)
  1383. return 0;
  1384. return -ENOSYS;
  1385. }
  1386. asmlinkage int
  1387. sys32_get_kernel_syms(struct kernel_sym *table)
  1388. {
  1389. return -ENOSYS;
  1390. }
  1391. #endif  /* CONFIG_MODULES */
  1392. /* readv/writev stolen from mips64 */
  1393. struct iovec32 { unsigned int iov_base; int iov_len; };
  1394. typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
  1395. static long
  1396. do_readv_writev32(int type, struct file *file, const struct iovec32 *vector,
  1397.   u32 count)
  1398. {
  1399. unsigned long tot_len;
  1400. struct iovec iovstack[UIO_FASTIOV];
  1401. struct iovec *iov=iovstack, *ivp;
  1402. struct inode *inode;
  1403. long retval, i;
  1404. IO_fn_t fn;
  1405. /* First get the "struct iovec" from user memory and
  1406.  * verify all the pointers
  1407.  */
  1408. if (!count)
  1409. return 0;
  1410. if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
  1411. return -EFAULT;
  1412. if (count > UIO_MAXIOV)
  1413. return -EINVAL;
  1414. if (count > UIO_FASTIOV) {
  1415. iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
  1416. if (!iov)
  1417. return -ENOMEM;
  1418. }
  1419. tot_len = 0;
  1420. i = count;
  1421. ivp = iov;
  1422. while (i > 0) {
  1423. u32 len;
  1424. u32 buf;
  1425. __get_user(len, &vector->iov_len);
  1426. __get_user(buf, &vector->iov_base);
  1427. tot_len += len;
  1428. ivp->iov_base = (void *)A(buf);
  1429. ivp->iov_len = (__kernel_size_t) len;
  1430. vector++;
  1431. ivp++;
  1432. i--;
  1433. }
  1434. inode = file->f_dentry->d_inode;
  1435. /* VERIFY_WRITE actually means a read, as we write to user space */
  1436. retval = locks_verify_area((type == VERIFY_WRITE
  1437.     ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
  1438.    inode, file, file->f_pos, tot_len);
  1439. if (retval) {
  1440. if (iov != iovstack)
  1441. kfree(iov);
  1442. return retval;
  1443. }
  1444. /* Then do the actual IO.  Note that sockets need to be handled
  1445.  * specially as they have atomicity guarantees and can handle
  1446.  * iovec's natively
  1447.  */
  1448. if (inode->i_sock) {
  1449. int err;
  1450. err = sock_readv_writev(type, inode, file, iov, count, tot_len);
  1451. if (iov != iovstack)
  1452. kfree(iov);
  1453. return err;
  1454. }
  1455. if (!file->f_op) {
  1456. if (iov != iovstack)
  1457. kfree(iov);
  1458. return -EINVAL;
  1459. }
  1460. /* VERIFY_WRITE actually means a read, as we write to user space */
  1461. fn = file->f_op->read;
  1462. if (type == VERIFY_READ)
  1463. fn = (IO_fn_t) file->f_op->write;
  1464. ivp = iov;
  1465. while (count > 0) {
  1466. void * base;
  1467. int len, nr;
  1468. base = ivp->iov_base;
  1469. len = ivp->iov_len;
  1470. ivp++;
  1471. count--;
  1472. nr = fn(file, base, len, &file->f_pos);
  1473. if (nr < 0) {
  1474. if (retval)
  1475. break;
  1476. retval = nr;
  1477. break;
  1478. }
  1479. retval += nr;
  1480. if (nr != len)
  1481. break;
  1482. }
  1483. if (iov != iovstack)
  1484. kfree(iov);
  1485. return retval;
  1486. }
  1487. asmlinkage long
  1488. sys32_readv(int fd, struct iovec32 *vector, u32 count)
  1489. {
  1490. struct file *file;
  1491. ssize_t ret;
  1492. ret = -EBADF;
  1493. file = fget(fd);
  1494. if (!file)
  1495. goto bad_file;
  1496. if (file->f_op && (file->f_mode & FMODE_READ) &&
  1497.     (file->f_op->readv || file->f_op->read))
  1498. ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
  1499. fput(file);
  1500. bad_file:
  1501. return ret;
  1502. }
  1503. asmlinkage long
  1504. sys32_writev(int fd, struct iovec32 *vector, u32 count)
  1505. {
  1506. struct file *file;
  1507. ssize_t ret;
  1508. ret = -EBADF;
  1509. file = fget(fd);
  1510. if(!file)
  1511. goto bad_file;
  1512. if (file->f_op && (file->f_mode & FMODE_WRITE) &&
  1513.     (file->f_op->writev || file->f_op->write))
  1514.         ret = do_readv_writev32(VERIFY_READ, file, vector, count);
  1515. fput(file);
  1516. bad_file:
  1517. return ret;
  1518. }
  1519. /********** Borrowed from sparc64 -- hardly reviewed, not tested *****/
  1520. #include <net/scm.h>
  1521. /* XXX This really belongs in some header file... -DaveM */
  1522. #define MAX_SOCK_ADDR 128 /* 108 for Unix domain - 
  1523.    16 for IP, 16 for IPX,
  1524.    24 for IPv6,
  1525.    about 80 for AX.25 */
  1526. extern struct socket *sockfd_lookup(int fd, int *err);
  1527. /* XXX This as well... */
  1528. extern __inline__ void sockfd_put(struct socket *sock)
  1529. {
  1530. fput(sock->file);
  1531. }
  1532. struct msghdr32 {
  1533.         u32               msg_name;
  1534.         int               msg_namelen;
  1535.         u32               msg_iov;
  1536.         __kernel_size_t32 msg_iovlen;
  1537.         u32               msg_control;
  1538.         __kernel_size_t32 msg_controllen;
  1539.         unsigned          msg_flags;
  1540. };
  1541. struct cmsghdr32 {
  1542.         __kernel_size_t32 cmsg_len;
  1543.         int               cmsg_level;
  1544.         int               cmsg_type;
  1545. };
  1546. /* Bleech... */
  1547. #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
  1548. #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
  1549. #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
  1550. #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
  1551. #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
  1552. #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
  1553. #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? 
  1554.     (struct cmsghdr32 *)(ctl) : 
  1555.     (struct cmsghdr32 *)NULL)
  1556. #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
  1557. __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
  1558.       struct cmsghdr32 *__cmsg, int __cmsg_len)
  1559. {
  1560. struct cmsghdr32 * __ptr;
  1561. __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
  1562.      CMSG32_ALIGN(__cmsg_len));
  1563. if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
  1564. return NULL;
  1565. return __ptr;
  1566. }
  1567. __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
  1568.     struct cmsghdr32 *__cmsg,
  1569.     int __cmsg_len)
  1570. {
  1571. return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
  1572.        __cmsg, __cmsg_len);
  1573. }
  1574. static inline int iov_from_user32_to_kern(struct iovec *kiov,
  1575.   struct iovec32 *uiov32,
  1576.   int niov)
  1577. {
  1578. int tot_len = 0;
  1579. while(niov > 0) {
  1580. u32 len, buf;
  1581. if(get_user(len, &uiov32->iov_len) ||
  1582.    get_user(buf, &uiov32->iov_base)) {
  1583. tot_len = -EFAULT;
  1584. break;
  1585. }
  1586. tot_len += len;
  1587. kiov->iov_base = (void *)A(buf);
  1588. kiov->iov_len = (__kernel_size_t) len;
  1589. uiov32++;
  1590. kiov++;
  1591. niov--;
  1592. }
  1593. return tot_len;
  1594. }
  1595. static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
  1596.      struct msghdr32 *umsg)
  1597. {
  1598. u32 tmp1, tmp2, tmp3;
  1599. int err;
  1600. err = get_user(tmp1, &umsg->msg_name);
  1601. err |= __get_user(tmp2, &umsg->msg_iov);
  1602. err |= __get_user(tmp3, &umsg->msg_control);
  1603. if (err)
  1604. return -EFAULT;
  1605. kmsg->msg_name = (void *)A(tmp1);
  1606. kmsg->msg_iov = (struct iovec *)A(tmp2);
  1607. kmsg->msg_control = (void *)A(tmp3);
  1608. err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
  1609. err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
  1610. err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
  1611. err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
  1612. return err;
  1613. }
  1614. /* I've named the args so it is easy to tell whose space the pointers are in. */
  1615. static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
  1616.   char *kern_address, int mode)
  1617. {
  1618. int tot_len;
  1619. if(kern_msg->msg_namelen) {
  1620. if(mode==VERIFY_READ) {
  1621. int err = move_addr_to_kernel(kern_msg->msg_name,
  1622.       kern_msg->msg_namelen,
  1623.       kern_address);
  1624. if(err < 0)
  1625. return err;
  1626. }
  1627. kern_msg->msg_name = kern_address;
  1628. } else
  1629. kern_msg->msg_name = NULL;
  1630. if(kern_msg->msg_iovlen > UIO_FASTIOV) {
  1631. kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
  1632.    GFP_KERNEL);
  1633. if(!kern_iov)
  1634. return -ENOMEM;
  1635. }
  1636. tot_len = iov_from_user32_to_kern(kern_iov,
  1637.   (struct iovec32 *)kern_msg->msg_iov,
  1638.   kern_msg->msg_iovlen);
  1639. if(tot_len >= 0)
  1640. kern_msg->msg_iov = kern_iov;
  1641. else if(kern_msg->msg_iovlen > UIO_FASTIOV)
  1642. kfree(kern_iov);
  1643. return tot_len;
  1644. }
  1645. /* There is a lot of hair here because the alignment rules (and
  1646.  * thus placement) of cmsg headers and length are different for
  1647.  * 32-bit apps.  -DaveM
  1648.  */
  1649. static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
  1650.        unsigned char *stackbuf, int stackbuf_size)
  1651. {
  1652. struct cmsghdr32 *ucmsg;
  1653. struct cmsghdr *kcmsg, *kcmsg_base;
  1654. __kernel_size_t32 ucmlen;
  1655. __kernel_size_t kcmlen, tmp;
  1656. kcmlen = 0;
  1657. kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
  1658. ucmsg = CMSG32_FIRSTHDR(kmsg);
  1659. while(ucmsg != NULL) {
  1660. if(get_user(ucmlen, &ucmsg->cmsg_len))
  1661. return -EFAULT;
  1662. /* Catch bogons. */
  1663. if(CMSG32_ALIGN(ucmlen) <
  1664.    CMSG32_ALIGN(sizeof(struct cmsghdr32)))
  1665. return -EINVAL;
  1666. if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
  1667.    + ucmlen) > kmsg->msg_controllen)
  1668. return -EINVAL;
  1669. tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
  1670.        CMSG_ALIGN(sizeof(struct cmsghdr)));
  1671. kcmlen += tmp;
  1672. ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
  1673. }
  1674. if(kcmlen == 0)
  1675. return -EINVAL;
  1676. /* The kcmlen holds the 64-bit version of the control length.
  1677.  * It may not be modified as we do not stick it into the kmsg
  1678.  * until we have successfully copied over all of the data
  1679.  * from the user.
  1680.  */
  1681. if(kcmlen > stackbuf_size)
  1682. kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
  1683. if(kcmsg == NULL)
  1684. return -ENOBUFS;
  1685. /* Now copy them over neatly. */
  1686. memset(kcmsg, 0, kcmlen);
  1687. ucmsg = CMSG32_FIRSTHDR(kmsg);
  1688. while(ucmsg != NULL) {
  1689. __get_user(ucmlen, &ucmsg->cmsg_len);
  1690. tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
  1691.        CMSG_ALIGN(sizeof(struct cmsghdr)));
  1692. kcmsg->cmsg_len = tmp;
  1693. __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
  1694. __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
  1695. /* Copy over the data. */
  1696. if(copy_from_user(CMSG_DATA(kcmsg),
  1697.   CMSG32_DATA(ucmsg),
  1698.   (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
  1699. goto out_free_efault;
  1700. /* Advance. */
  1701. kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
  1702. ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
  1703. }
  1704. /* Ok, looks like we made it.  Hook it up and return success. */
  1705. kmsg->msg_control = kcmsg_base;
  1706. kmsg->msg_controllen = kcmlen;
  1707. return 0;
  1708. out_free_efault:
  1709. if(kcmsg_base != (struct cmsghdr *)stackbuf)
  1710. kfree(kcmsg_base);
  1711. return -EFAULT;
  1712. }
  1713. static void put_cmsg32(struct msghdr *kmsg, int level, int type,
  1714.        int len, void *data)
  1715. {
  1716. struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
  1717. struct cmsghdr32 cmhdr;
  1718. int cmlen = CMSG32_LEN(len);
  1719. if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
  1720. kmsg->msg_flags |= MSG_CTRUNC;
  1721. return;
  1722. }
  1723. if(kmsg->msg_controllen < cmlen) {
  1724. kmsg->msg_flags |= MSG_CTRUNC;
  1725. cmlen = kmsg->msg_controllen;
  1726. }
  1727. cmhdr.cmsg_level = level;
  1728. cmhdr.cmsg_type = type;
  1729. cmhdr.cmsg_len = cmlen;
  1730. if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
  1731. return;
  1732. if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
  1733. return;
  1734. cmlen = CMSG32_SPACE(len);
  1735. kmsg->msg_control += cmlen;
  1736. kmsg->msg_controllen -= cmlen;
  1737. }
  1738. static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
  1739. {
  1740. struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
  1741. int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
  1742. int fdnum = scm->fp->count;
  1743. struct file **fp = scm->fp->fp;
  1744. int *cmfptr;
  1745. int err = 0, i;
  1746. if (fdnum < fdmax)
  1747. fdmax = fdnum;
  1748. for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
  1749. int new_fd;
  1750. err = get_unused_fd();
  1751. if (err < 0)
  1752. break;
  1753. new_fd = err;
  1754. err = put_user(new_fd, cmfptr);
  1755. if (err) {
  1756. put_unused_fd(new_fd);
  1757. break;
  1758. }
  1759. /* Bump the usage count and install the file. */
  1760. get_file(fp[i]);
  1761. fd_install(new_fd, fp[i]);
  1762. }
  1763. if (i > 0) {
  1764. int cmlen = CMSG32_LEN(i * sizeof(int));
  1765. if (!err)
  1766. err = put_user(SOL_SOCKET, &cm->cmsg_level);
  1767. if (!err)
  1768. err = put_user(SCM_RIGHTS, &cm->cmsg_type);
  1769. if (!err)
  1770. err = put_user(cmlen, &cm->cmsg_len);
  1771. if (!err) {
  1772. cmlen = CMSG32_SPACE(i * sizeof(int));
  1773. kmsg->msg_control += cmlen;
  1774. kmsg->msg_controllen -= cmlen;
  1775. }
  1776. }
  1777. if (i < fdnum)
  1778. kmsg->msg_flags |= MSG_CTRUNC;
  1779. /*
  1780.  * All of the files that fit in the message have had their
  1781.  * usage counts incremented, so we just free the list.
  1782.  */
  1783. __scm_destroy(scm);
  1784. }
  1785. /* In these cases we (currently) can just copy to data over verbatim
  1786.  * because all CMSGs created by the kernel have well defined types which
  1787.  * have the same layout in both the 32-bit and 64-bit API.  One must add
  1788.  * some special cased conversions here if we start sending control messages
  1789.  * with incompatible types.
  1790.  *
  1791.  * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
  1792.  * we do our work.  The remaining cases are:
  1793.  *
  1794.  * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
  1795.  * IP_TTL int 32-bit clean
  1796.  * IP_TOS __u8 32-bit clean
  1797.  * IP_RECVOPTS variable length 32-bit clean
  1798.  * IP_RETOPTS variable length 32-bit clean
  1799.  * (these last two are clean because the types are defined
  1800.  *  by the IPv4 protocol)
  1801.  * IP_RECVERR struct sock_extended_err +
  1802.  * struct sockaddr_in 32-bit clean
  1803.  * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
  1804.  * struct sockaddr_in6 32-bit clean
  1805.  * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
  1806.  * IPV6_HOPLIMIT int 32-bit clean
  1807.  * IPV6_FLOWINFO u32 32-bit clean
  1808.  * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
  1809.  * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
  1810.  * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
  1811.  * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
  1812.  */
  1813. static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
  1814. {
  1815. unsigned char *workbuf, *wp;
  1816. unsigned long bufsz, space_avail;
  1817. struct cmsghdr *ucmsg;
  1818. bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
  1819. space_avail = kmsg->msg_controllen + bufsz;
  1820. wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
  1821. if(workbuf == NULL)
  1822. goto fail;
  1823. /* To make this more sane we assume the kernel sends back properly
  1824.  * formatted control messages.  Because of how the kernel will truncate
  1825.  * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
  1826.  */
  1827. ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
  1828. while(((unsigned long)ucmsg) <=
  1829.       (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
  1830. struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
  1831. int clen64, clen32;
  1832. /* UCMSG is the 64-bit format CMSG entry in user-space.
  1833.  * KCMSG32 is within the kernel space temporary buffer
  1834.  * we use to convert into a 32-bit style CMSG.
  1835.  */
  1836. __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
  1837. __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
  1838. __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
  1839. clen64 = kcmsg32->cmsg_len;
  1840. copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
  1841.        clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
  1842. clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
  1843.   CMSG32_ALIGN(sizeof(struct cmsghdr32)));
  1844. kcmsg32->cmsg_len = clen32;
  1845. ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
  1846. wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
  1847. }
  1848. /* Copy back fixed up data, and adjust pointers. */
  1849. bufsz = (wp - workbuf);
  1850. copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
  1851. kmsg->msg_control = (struct cmsghdr *)
  1852. (((char *)orig_cmsg_uptr) + bufsz);
  1853. kmsg->msg_controllen = space_avail - bufsz;
  1854. kfree(workbuf);
  1855. return;
  1856. fail:
  1857. /* If we leave the 64-bit format CMSG chunks in there,
  1858.  * the application could get confused and crash.  So to
  1859.  * ensure greater recovery, we report no CMSGs.
  1860.  */
  1861. kmsg->msg_controllen += bufsz;
  1862. kmsg->msg_control = (void *) orig_cmsg_uptr;
  1863. }
  1864. asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
  1865. {
  1866. struct socket *sock;
  1867. char address[MAX_SOCK_ADDR];
  1868. struct iovec iov[UIO_FASTIOV];
  1869. unsigned char ctl[sizeof(struct cmsghdr) + 20];
  1870. unsigned char *ctl_buf = ctl;
  1871. struct msghdr kern_msg;
  1872. int err, total_len;
  1873. if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
  1874. return -EFAULT;
  1875. if(kern_msg.msg_iovlen > UIO_MAXIOV)
  1876. return -EINVAL;
  1877. err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
  1878. if (err < 0)
  1879. goto out;
  1880. total_len = err;
  1881. if(kern_msg.msg_controllen) {
  1882. err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
  1883. if(err)
  1884. goto out_freeiov;
  1885. ctl_buf = kern_msg.msg_control;
  1886. }
  1887. kern_msg.msg_flags = user_flags;
  1888. sock = sockfd_lookup(fd, &err);
  1889. if (sock != NULL) {
  1890. if (sock->file->f_flags & O_NONBLOCK)
  1891. kern_msg.msg_flags |= MSG_DONTWAIT;
  1892. err = sock_sendmsg(sock, &kern_msg, total_len);
  1893. sockfd_put(sock);
  1894. }
  1895. /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
  1896. if(ctl_buf != ctl)
  1897. kfree(ctl_buf);
  1898. out_freeiov:
  1899. if(kern_msg.msg_iov != iov)
  1900. kfree(kern_msg.msg_iov);
  1901. out:
  1902. return err;
  1903. }
  1904. asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
  1905. {
  1906. struct iovec iovstack[UIO_FASTIOV];
  1907. struct msghdr kern_msg;
  1908. char addr[MAX_SOCK_ADDR];
  1909. struct socket *sock;
  1910. struct iovec *iov = iovstack;
  1911. struct sockaddr *uaddr;
  1912. int *uaddr_len;
  1913. unsigned long cmsg_ptr;
  1914. int err, total_len, len = 0;
  1915. if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
  1916. return -EFAULT;
  1917. if(kern_msg.msg_iovlen > UIO_MAXIOV)
  1918. return -EINVAL;
  1919. uaddr = kern_msg.msg_name;
  1920. uaddr_len = &user_msg->msg_namelen;
  1921. err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
  1922. if (err < 0)
  1923. goto out;
  1924. total_len = err;
  1925. cmsg_ptr = (unsigned long) kern_msg.msg_control;
  1926. kern_msg.msg_flags = 0;
  1927. sock = sockfd_lookup(fd, &err);
  1928. if (sock != NULL) {
  1929. struct scm_cookie scm;
  1930. if (sock->file->f_flags & O_NONBLOCK)
  1931. user_flags |= MSG_DONTWAIT;
  1932. memset(&scm, 0, sizeof(scm));
  1933. err = sock->ops->recvmsg(sock, &kern_msg, total_len,
  1934.  user_flags, &scm);
  1935. if(err >= 0) {
  1936. len = err;
  1937. if(!kern_msg.msg_control) {
  1938. if(sock->passcred || scm.fp)
  1939. kern_msg.msg_flags |= MSG_CTRUNC;
  1940. if(scm.fp)
  1941. __scm_destroy(&scm);
  1942. } else {
  1943. /* If recvmsg processing itself placed some
  1944.  * control messages into user space, it's is
  1945.  * using 64-bit CMSG processing, so we need
  1946.  * to fix it up before we tack on more stuff.
  1947.  */
  1948. if((unsigned long) kern_msg.msg_control != cmsg_ptr)
  1949. cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
  1950. /* Wheee... */
  1951. if(sock->passcred)
  1952. put_cmsg32(&kern_msg,
  1953.    SOL_SOCKET, SCM_CREDENTIALS,
  1954.    sizeof(scm.creds), &scm.creds);
  1955. if(scm.fp != NULL)
  1956. scm_detach_fds32(&kern_msg, &scm);
  1957. }
  1958. }
  1959. sockfd_put(sock);
  1960. }
  1961. if(uaddr != NULL && err >= 0)
  1962. err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
  1963. if(cmsg_ptr != 0 && err >= 0) {
  1964. unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
  1965. __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
  1966. err |= __put_user(uclen, &user_msg->msg_controllen);
  1967. }
  1968. if(err >= 0)
  1969. err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
  1970. if(kern_msg.msg_iov != iov)
  1971. kfree(kern_msg.msg_iov);
  1972. out:
  1973. if(err < 0)
  1974. return err;
  1975. return len;
  1976. }
  1977. extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
  1978.      char *optval, int optlen);
  1979. static int do_set_attach_filter(int fd, int level, int optname,
  1980. char *optval, int optlen)
  1981. {
  1982. struct sock_fprog32 {
  1983. __u16 len;
  1984. __u32 filter;
  1985. } *fprog32 = (struct sock_fprog32 *)optval;
  1986. struct sock_fprog kfprog;
  1987. struct sock_filter *kfilter;
  1988. unsigned int fsize;
  1989. mm_segment_t old_fs;
  1990. __u32 uptr;
  1991. int ret;
  1992. if (get_user(kfprog.len, &fprog32->len) ||
  1993.     __get_user(uptr, &fprog32->filter))
  1994. return -EFAULT;
  1995. kfprog.filter = (struct sock_filter *)A(uptr);
  1996. fsize = kfprog.len * sizeof(struct sock_filter);
  1997. kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
  1998. if (kfilter == NULL)
  1999. return -ENOMEM;
  2000. if (copy_from_user(kfilter, kfprog.filter, fsize)) {
  2001. kfree(kfilter);
  2002. return -EFAULT;
  2003. }
  2004. kfprog.filter = kfilter;
  2005. old_fs = get_fs();
  2006. set_fs(KERNEL_DS);
  2007. ret = sys_setsockopt(fd, level, optname,
  2008.      (char *)&kfprog, sizeof(kfprog));
  2009. set_fs(old_fs);
  2010. kfree(kfilter);
  2011. return ret;
  2012. }
  2013. static int do_set_icmpv6_filter(int fd, int level, int optname,
  2014. char *optval, int optlen)
  2015. {
  2016. struct icmp6_filter kfilter;
  2017. mm_segment_t old_fs;
  2018. int ret, i;
  2019. if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
  2020. return -EFAULT;
  2021. for (i = 0; i < 8; i += 2) {
  2022. u32 tmp = kfilter.data[i];
  2023. kfilter.data[i] = kfilter.data[i + 1];
  2024. kfilter.data[i + 1] = tmp;
  2025. }
  2026. old_fs = get_fs();
  2027. set_fs(KERNEL_DS);
  2028. ret = sys_setsockopt(fd, level, optname,
  2029.      (char *) &kfilter, sizeof(kfilter));
  2030. set_fs(old_fs);
  2031. return ret;
  2032. }
  2033. static int do_ipv4_set_replace(int fd, int level, int optname,
  2034. char *optval, int optlen)
  2035. #if 1
  2036. /* Fields happen to be padded such that this works.
  2037. ** Don't need to change iptables.h:struct ipt_replace
  2038. */
  2039. {
  2040. struct ipt_replace *repl = (struct ipt_replace *) optval;
  2041. unsigned long ptr64;
  2042. unsigned int ptr32;
  2043. int ret;
  2044. if (copy_from_user(&ptr32, &repl->counters, sizeof(ptr32)))
  2045. return -EFAULT;
  2046. ptr64 = (unsigned long) ptr32;
  2047. if (copy_to_user(&repl->counters, &ptr64, sizeof(ptr64)))
  2048. return -EFAULT;
  2049. ret = sys_setsockopt(fd, level, optname, (char *) optval, optlen);
  2050. /* Restore 32-bit ptr */
  2051. if (copy_to_user(&repl->counters, &ptr32, sizeof(ptr32)))
  2052. return -EFAULT;
  2053. return ret;
  2054. }
  2055. #else
  2056. /* This version tries to "do it right". ie allocate kernel buffers for
  2057. ** everything and copy data in/out. Way too complicated.
  2058. ** NOT TESTED for correctness!
  2059. */
  2060. {
  2061. struct ipt_replace  *kern_repl;
  2062. struct ipt_counters *kern_counters;
  2063. unsigned int user_counters;
  2064. mm_segment_t old_fs;
  2065. int ret = 0;
  2066. kern_repl = (struct ipt_replace *) kmalloc(optlen+8, GFP_KERNEL);
  2067. if (!kern_repl)
  2068. return -ENOMEM;
  2069. if (copy_from_user(kern_repl, optval, optlen)) {
  2070. ret = -EFAULT;
  2071. goto err02;
  2072. }
  2073. /* 32-bit ptr is in the MSB's */
  2074. user_counters = (unsigned int) (((unsigned long) kern_repl->counters) >> 32);
  2075. /*
  2076. ** We are going to set_fs() to kernel space - and thus need
  2077. ** "relocate" the counters buffer to the kernel space.
  2078. */
  2079. kern_counters = (struct ipt_counters *) kmalloc(kern_repl->num_counters * sizeof(struct ipt_counters), GFP_KERNEL);
  2080. if (!user_counters) {
  2081. ret = -ENOMEM;
  2082. goto err02;
  2083. }
  2084. if (copy_from_user(kern_counters, (char *) user_counters, optlen)) {
  2085. ret = -EFAULT;
  2086. goto err01;
  2087. }
  2088. /* We can update the kernel ptr now that we have the data. */
  2089. kern_repl->counters = kern_counters;
  2090. old_fs = get_fs();
  2091. set_fs(KERNEL_DS);
  2092. ret = sys_setsockopt(fd, level, optname, (char *) optval, optlen);
  2093. set_fs(old_fs);
  2094. /* Copy counters back out to user space */
  2095. if (copy_to_user((char *) user_counters, kern_counters,
  2096. kern_repl->num_counters * sizeof(struct ipt_counters)))
  2097. {
  2098. ret = -EFAULT;
  2099. goto err01;
  2100. }
  2101. /* restore counters so userspace can consume it */
  2102. kern_repl->counters = NULL;
  2103. (unsigned int) kern_repl->counters = user_counters;
  2104. /* Copy repl back out to user space */
  2105. if (copy_to_user(optval, kern_repl, optlen))
  2106. {
  2107. ret = -EFAULT;
  2108. }
  2109. err01:
  2110. kfree(kern_counters);
  2111. err02:
  2112. kfree(kern_repl);
  2113. return ret;
  2114. }
  2115. #endif
  2116. asmlinkage int sys32_setsockopt(int fd, int level, int optname,
  2117. char *optval, int optlen)
  2118. {
  2119. if (optname == SO_ATTACH_FILTER)
  2120. return do_set_attach_filter(fd, level, optname, optval, optlen);
  2121. if (level == SOL_ICMPV6   && optname == ICMPV6_FILTER)
  2122. return do_set_icmpv6_filter(fd, level, optname, optval, optlen);
  2123. /*
  2124. ** Beware:    IPT_SO_SET_REPLACE == IP6T_SO_SET_REPLACE
  2125. */
  2126. if (level == IPPROTO_IP   && optname == IPT_SO_SET_REPLACE)
  2127. return do_ipv4_set_replace(fd, level, optname, optval, optlen);
  2128. if (level == IPPROTO_IPV6 && optname == IP6T_SO_SET_REPLACE)
  2129. #if 0
  2130. /* FIXME: I don't (yet) use IPV6. -ggg */
  2131. return do_ipv6_set_replace(fd, level, optname, optval, optlen);
  2132. #else
  2133. {
  2134. BUG();
  2135. return -ENXIO;
  2136. }
  2137. #endif
  2138. return sys_setsockopt(fd, level, optname, optval, optlen);
  2139. }
  2140. /*** copied from mips64 ***/
  2141. /*
  2142.  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
  2143.  * 64-bit unsigned longs.
  2144.  */
  2145. static inline int
  2146. get_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
  2147. {
  2148. n = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
  2149. if (ufdset) {
  2150. unsigned long odd;
  2151. if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
  2152. return -EFAULT;
  2153. odd = n & 1UL;
  2154. n &= ~1UL;
  2155. while (n) {
  2156. unsigned long h, l;
  2157. __get_user(l, ufdset);
  2158. __get_user(h, ufdset+1);
  2159. ufdset += 2;
  2160. *fdset++ = h << 32 | l;
  2161. n -= 2;
  2162. }
  2163. if (odd)
  2164. __get_user(*fdset, ufdset);
  2165. } else {
  2166. /* Tricky, must clear full unsigned long in the
  2167.  * kernel fdset at the end, this makes sure that
  2168.  * actually happens.
  2169.  */
  2170. memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
  2171. }
  2172. return 0;
  2173. }
  2174. static inline void
  2175. set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
  2176. {
  2177. unsigned long odd;
  2178. n = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
  2179. if (!ufdset)
  2180. return;
  2181. odd = n & 1UL;
  2182. n &= ~1UL;
  2183. while (n) {
  2184. unsigned long h, l;
  2185. l = *fdset++;
  2186. h = l >> 32;
  2187. __put_user(l, ufdset);
  2188. __put_user(h, ufdset+1);
  2189. ufdset += 2;
  2190. n -= 2;
  2191. }
  2192. if (odd)
  2193. __put_user(*fdset, ufdset);
  2194. }
  2195. /*** This is a virtual copy of sys_select from fs/select.c and probably
  2196.  *** should be compared to it from time to time
  2197.  ***/
  2198. static inline void *select_bits_alloc(int size)
  2199. {
  2200. return kmalloc(6 * size, GFP_KERNEL);
  2201. }
  2202. static inline void select_bits_free(void *bits, int size)
  2203. {
  2204. kfree(bits);
  2205. }
  2206. /*
  2207.  * We can actually return ERESTARTSYS instead of EINTR, but I'd
  2208.  * like to be certain this leads to no problems. So I return
  2209.  * EINTR just for safety.
  2210.  *
  2211.  * Update: ERESTARTSYS breaks at least the xview clock binary, so
  2212.  * I'm trying ERESTARTNOHAND which restart only when you want to.
  2213.  */
  2214. #define MAX_SELECT_SECONDS 
  2215. ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
  2216. #define DIVIDE_ROUND_UP(x,y) (((x)+(y)-1)/(y))
  2217. asmlinkage long
  2218. sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, struct timeval32 *tvp)
  2219. {
  2220. fd_set_bits fds;
  2221. char *bits;
  2222. long timeout;
  2223. int ret, size, err;
  2224. timeout = MAX_SCHEDULE_TIMEOUT;
  2225. if (tvp) {
  2226. struct timeval32 tv32;
  2227. time_t sec, usec;
  2228. if ((ret = copy_from_user(&tv32, tvp, sizeof tv32)))
  2229. goto out_nofds;
  2230. sec = tv32.tv_sec;
  2231. usec = tv32.tv_usec;
  2232. ret = -EINVAL;
  2233. if (sec < 0 || usec < 0)
  2234. goto out_nofds;
  2235. if ((unsigned long) sec < MAX_SELECT_SECONDS) {
  2236. timeout = DIVIDE_ROUND_UP(usec, 1000000/HZ);
  2237. timeout += sec * (unsigned long) HZ;
  2238. }
  2239. }
  2240. ret = -EINVAL;
  2241. if (n < 0)
  2242. goto out_nofds;
  2243. if (n > current->files->max_fdset)
  2244. n = current->files->max_fdset;
  2245. /*
  2246.  * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
  2247.  * since we used fdset we need to allocate memory in units of
  2248.  * long-words. 
  2249.  */
  2250. ret = -ENOMEM;
  2251. size = FDS_BYTES(n);
  2252. bits = select_bits_alloc(size);
  2253. if (!bits)
  2254. goto out_nofds;
  2255. fds.in      = (unsigned long *)  bits;
  2256. fds.out     = (unsigned long *) (bits +   size);
  2257. fds.ex      = (unsigned long *) (bits + 2*size);
  2258. fds.res_in  = (unsigned long *) (bits + 3*size);
  2259. fds.res_out = (unsigned long *) (bits + 4*size);
  2260. fds.res_ex  = (unsigned long *) (bits + 5*size);
  2261. if ((ret = get_fd_set32(n, inp, fds.in)) ||
  2262.     (ret = get_fd_set32(n, outp, fds.out)) ||
  2263.     (ret = get_fd_set32(n, exp, fds.ex)))
  2264. goto out;
  2265. zero_fd_set(n, fds.res_in);
  2266. zero_fd_set(n, fds.res_out);
  2267. zero_fd_set(n, fds.res_ex);
  2268. ret = do_select(n, &fds, &timeout);
  2269. if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
  2270. time_t sec = 0, usec = 0;
  2271. if (timeout) {
  2272. sec = timeout / HZ;
  2273. usec = timeout % HZ;
  2274. usec *= (1000000/HZ);
  2275. }
  2276. err = put_user(sec, &tvp->tv_sec);
  2277. err |= __put_user(usec, &tvp->tv_usec);
  2278. if (err)
  2279. ret = -EFAULT;
  2280. }
  2281. if (ret < 0)
  2282. goto out;
  2283. if (!ret) {
  2284. ret = -ERESTARTNOHAND;
  2285. if (signal_pending(current))
  2286. goto out;
  2287. ret = 0;
  2288. }
  2289. set_fd_set32(n, inp, fds.res_in);
  2290. set_fd_set32(n, outp, fds.res_out);
  2291. set_fd_set32(n, exp, fds.res_ex);
  2292. out:
  2293. select_bits_free(bits, size);
  2294. out_nofds:
  2295. return ret;
  2296. }
  2297. struct msgbuf32 {
  2298.     int mtype;
  2299.     char mtext[1];
  2300. };
  2301. asmlinkage long sys32_msgsnd(int msqid,
  2302. struct msgbuf32 *umsgp32,
  2303. size_t msgsz, int msgflg)
  2304. {
  2305. struct msgbuf *mb;
  2306. struct msgbuf32 mb32;
  2307. int err;
  2308. if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL)
  2309. return -ENOMEM;
  2310. err = get_user(mb32.mtype, &umsgp32->mtype);
  2311. mb->mtype = mb32.mtype;
  2312. err |= copy_from_user(mb->mtext, &umsgp32->mtext, msgsz);
  2313. if (err)
  2314. err = -EFAULT;
  2315. else
  2316. KERNEL_SYSCALL(err, sys_msgsnd, msqid, mb, msgsz, msgflg);
  2317. kfree(mb);
  2318. return err;
  2319. }
  2320. asmlinkage long sys32_msgrcv(int msqid,
  2321. struct msgbuf32 *umsgp32,
  2322. size_t msgsz, long msgtyp, int msgflg)
  2323. {
  2324. struct msgbuf *mb;
  2325. struct msgbuf32 mb32;
  2326. int err, len;
  2327. if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL)
  2328. return -ENOMEM;
  2329. KERNEL_SYSCALL(err, sys_msgrcv, msqid, mb, msgsz, msgtyp, msgflg);
  2330. if (err >= 0) {
  2331. len = err;
  2332. mb32.mtype = mb->mtype;
  2333. err = put_user(mb32.mtype, &umsgp32->mtype);
  2334. err |= copy_to_user(&umsgp32->mtext, mb->mtext, len);
  2335. if (err)
  2336. err = -EFAULT;
  2337. else
  2338. err = len;
  2339. }
  2340. kfree(mb);
  2341. return err;
  2342. }
  2343. /* LFS */
  2344. extern asmlinkage long sys_truncate(const char *, loff_t);
  2345. extern asmlinkage long sys_ftruncate(unsigned int, loff_t);
  2346. extern asmlinkage long sys_fcntl(unsigned int, unsigned int, unsigned long);
  2347. extern asmlinkage ssize_t sys_pread(unsigned int, char *, size_t, loff_t);
  2348. extern asmlinkage ssize_t sys_pwrite(unsigned int, char *, size_t, loff_t);
  2349. asmlinkage long sys32_truncate64(const char * path, unsigned int high, unsigned int low)
  2350. {
  2351. return sys_truncate(path, (loff_t)high << 32 | low);
  2352. }
  2353. asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned int high, unsigned int low)
  2354. {
  2355. return sys_ftruncate(fd, (loff_t)high << 32 | low);
  2356. }
  2357. asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
  2358. {
  2359. switch (cmd) {
  2360. case F_GETLK64:
  2361. cmd = F_GETLK;
  2362. break;
  2363. case F_SETLK64:
  2364. cmd = F_SETLK;
  2365. break;
  2366. case F_SETLKW64:
  2367. cmd = F_SETLKW;
  2368. break;
  2369. default:
  2370. break;
  2371. }
  2372. return sys_fcntl(fd, cmd, arg);
  2373. }
  2374. asmlinkage int sys32_pread(int fd, void *buf, size_t count, unsigned int high, unsigned int low)
  2375. {
  2376. return sys_pread(fd, buf, count, (loff_t)high << 32 | low);
  2377. }
  2378. asmlinkage int sys32_pwrite(int fd, void *buf, size_t count, unsigned int high, unsigned int low)
  2379. {
  2380.        return sys_pwrite(fd, buf, count, (loff_t)high << 32 | low);
  2381. }
  2382. /* EXPORT/UNEXPORT */
  2383. struct nfsctl_export32 {
  2384. char ex_client[NFSCLNT_IDMAX+1];
  2385. char ex_path[NFS_MAXPATHLEN+1];
  2386. __kernel_dev_t ex_dev;
  2387. __kernel_ino_t32 ex_ino;
  2388. int ex_flags;
  2389. __kernel_uid_t ex_anon_uid;
  2390. __kernel_gid_t ex_anon_gid;
  2391. };
  2392. /* GETFH */
  2393. struct nfsctl_fhparm32 {
  2394. struct sockaddr gf_addr;
  2395. __kernel_dev_t gf_dev;
  2396. __kernel_ino_t32 gf_ino;
  2397. int gf_version;
  2398. };
  2399. /* UGIDUPDATE */
  2400. struct nfsctl_uidmap32 {
  2401. __kernel_caddr_t32 ug_ident;
  2402. __kernel_uid_t ug_uidbase;
  2403. int ug_uidlen;
  2404. __kernel_caddr_t32 ug_udimap;
  2405. __kernel_gid_t ug_gidbase;
  2406. int ug_gidlen;
  2407. __kernel_caddr_t32 ug_gdimap;
  2408. };
  2409. struct nfsctl_arg32 {
  2410. int ca_version; /* safeguard */
  2411. /* wide kernel places this union on 8-byte boundary, narrow on 4 */
  2412. union {
  2413. struct nfsctl_svc u_svc;
  2414. struct nfsctl_client u_client;
  2415. struct nfsctl_export32 u_export;
  2416. struct nfsctl_uidmap32 u_umap;
  2417. struct nfsctl_fhparm32 u_getfh;
  2418. struct nfsctl_fdparm u_getfd;
  2419. struct nfsctl_fsparm u_getfs;
  2420. } u;
  2421. };
  2422. asmlinkage int sys32_nfsservctl(int cmd, void *argp, void *resp)
  2423. {
  2424. int ret, tmp;
  2425. struct nfsctl_arg32 n32;
  2426. struct nfsctl_arg n;
  2427. ret = copy_from_user(&n, argp, sizeof n.ca_version);
  2428. if (ret != 0)
  2429. return ret;
  2430. /* adjust argp to point at the union inside the user's n32 struct */
  2431. tmp = (unsigned long)&n32.u - (unsigned long)&n32;
  2432. argp = (void *)((unsigned long)argp + tmp);
  2433. switch(cmd) {
  2434. case NFSCTL_SVC:
  2435. ret = copy_from_user(&n.u, argp, sizeof n.u.u_svc);
  2436. break;
  2437. case NFSCTL_ADDCLIENT:
  2438. case NFSCTL_DELCLIENT:
  2439. ret = copy_from_user(&n.u, argp, sizeof n.u.u_client);
  2440. break;
  2441. case NFSCTL_GETFD:
  2442. ret = copy_from_user(&n.u, argp, sizeof n.u.u_getfd);
  2443. break;
  2444. case NFSCTL_GETFS:
  2445. ret = copy_from_user(&n.u, argp, sizeof n.u.u_getfs);
  2446. break;
  2447. case NFSCTL_GETFH: /* nfsctl_fhparm */
  2448. ret = copy_from_user(&n32.u, argp, sizeof n32.u.u_getfh);
  2449. #undef CP
  2450. #define CP(x) n.u.u_getfh.gf_##x = n32.u.u_getfh.gf_##x
  2451. CP(addr);
  2452. CP(dev);
  2453. CP(ino);
  2454. CP(version);
  2455. break;
  2456. case NFSCTL_UGIDUPDATE: /* nfsctl_uidmap */
  2457. ret = copy_from_user(&n32.u, argp, sizeof n32.u.u_umap);
  2458. #undef CP
  2459. #define CP(x) n.u.u_umap.ug_##x = n32.u.u_umap.ug_##x
  2460. n.u.u_umap.ug_ident = (char *)(u_long)n32.u.u_umap.ug_ident;
  2461. CP(uidbase);
  2462. CP(uidlen);
  2463. n.u.u_umap.ug_udimap = (__kernel_uid_t *)(u_long)n32.u.u_umap.ug_udimap;
  2464. CP(gidbase);
  2465. CP(gidlen);
  2466. n.u.u_umap.ug_gdimap = (__kernel_gid_t *)(u_long)n32.u.u_umap.ug_gdimap;
  2467. break;
  2468. case NFSCTL_UNEXPORT: /* nfsctl_export */
  2469. case NFSCTL_EXPORT: /* nfsctl_export */
  2470. ret = copy_from_user(&n32.u, argp, sizeof n32.u.u_export);
  2471. #undef CP
  2472. #define CP(x) n.u.u_export.ex_##x = n32.u.u_export.ex_##x
  2473. memcpy(n.u.u_export.ex_client, n32.u.u_export.ex_client, sizeof n32.u.u_export.ex_client);
  2474. memcpy(n.u.u_export.ex_path, n32.u.u_export.ex_path, sizeof n32.u.u_export.ex_path);
  2475. CP(dev);
  2476. CP(ino);
  2477. CP(flags);
  2478. CP(anon_uid);
  2479. CP(anon_gid);
  2480. break;
  2481. default:
  2482. BUG(); /* new cmd values to be translated... */
  2483. ret = -EINVAL;
  2484. break;
  2485. }
  2486. if (ret == 0) {
  2487. unsigned char rbuf[NFS_FHSIZE + sizeof (struct knfsd_fh)];
  2488. KERNEL_SYSCALL(ret, sys_nfsservctl, cmd, &n, &rbuf);
  2489. if (cmd == NFSCTL_GETFH || cmd == NFSCTL_GETFD) {
  2490. ret = copy_to_user(resp, rbuf, NFS_FHSIZE);
  2491. } else if (cmd == NFSCTL_GETFS) {
  2492. ret = copy_to_user(resp, rbuf, sizeof (struct knfsd_fh));
  2493. }
  2494. }
  2495. return ret;
  2496. }
  2497. #include <linux/quota.h>
  2498. struct dqblk32 {
  2499.     __u32 dqb_bhardlimit;
  2500.     __u32 dqb_bsoftlimit;
  2501.     __u32 dqb_curblocks;
  2502.     __u32 dqb_ihardlimit;
  2503.     __u32 dqb_isoftlimit;
  2504.     __u32 dqb_curinodes;
  2505.     __kernel_time_t32 dqb_btime;
  2506.     __kernel_time_t32 dqb_itime;
  2507. };
  2508.                                 
  2509. asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
  2510. {
  2511. extern int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
  2512. int cmds = cmd >> SUBCMDSHIFT;
  2513. int err;
  2514. struct dqblk d;
  2515. char *spec;
  2516. switch (cmds) {
  2517. case Q_GETQUOTA:
  2518. break;
  2519. case Q_SETQUOTA:
  2520. case Q_SETUSE:
  2521. case Q_SETQLIM:
  2522. if (copy_from_user (&d, (struct dqblk32 *)addr,
  2523.     sizeof (struct dqblk32)))
  2524. return -EFAULT;
  2525. d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
  2526. d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
  2527. break;
  2528. default:
  2529. return sys_quotactl(cmd, special,
  2530.     id, (caddr_t)addr);
  2531. }
  2532. spec = getname (special);
  2533. err = PTR_ERR(spec);
  2534. if (IS_ERR(spec)) return err;
  2535. KERNEL_SYSCALL(err, sys_quotactl, cmd, (const char *)spec, id, (caddr_t)&d);
  2536. putname (spec);
  2537. if (cmds == Q_GETQUOTA) {
  2538. __kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
  2539. ((struct dqblk32 *)&d)->dqb_itime = i;
  2540. ((struct dqblk32 *)&d)->dqb_btime = b;
  2541. if (copy_to_user ((struct dqblk32 *)addr, &d,
  2542.   sizeof (struct dqblk32)))
  2543. return -EFAULT;
  2544. }
  2545. return err;
  2546. }
  2547. struct timex32 {
  2548. unsigned int modes; /* mode selector */
  2549. int offset; /* time offset (usec) */
  2550. int freq; /* frequency offset (scaled ppm) */
  2551. int maxerror; /* maximum error (usec) */
  2552. int esterror; /* estimated error (usec) */
  2553. int status; /* clock command/status */
  2554. int constant; /* pll time constant */
  2555. int precision; /* clock precision (usec) (read only) */
  2556. int tolerance; /* clock frequency tolerance (ppm)
  2557.  * (read only)
  2558.  */
  2559. struct timeval32 time; /* (read only) */
  2560. int tick; /* (modified) usecs between clock ticks */
  2561. int ppsfreq;           /* pps frequency (scaled ppm) (ro) */
  2562. int jitter;            /* pps jitter (us) (ro) */
  2563. int shift;              /* interval duration (s) (shift) (ro) */
  2564. int stabil;            /* pps stability (scaled ppm) (ro) */
  2565. int jitcnt;            /* jitter limit exceeded (ro) */
  2566. int calcnt;            /* calibration intervals (ro) */
  2567. int errcnt;            /* calibration errors (ro) */
  2568. int stbcnt;            /* stability limit exceeded (ro) */
  2569. int  :32; int  :32; int  :32; int  :32;
  2570. int  :32; int  :32; int  :32; int  :32;
  2571. int  :32; int  :32; int  :32; int  :32;
  2572. };
  2573. asmlinkage long sys32_adjtimex(struct timex32 *txc_p32)
  2574. {
  2575. struct timex txc;
  2576. struct timex32 t32;
  2577. int ret;
  2578. extern int do_adjtimex(struct timex *txc);
  2579. if(copy_from_user(&t32, txc_p32, sizeof(struct timex32)))
  2580. return -EFAULT;
  2581. #undef CP
  2582. #define CP(x) txc.x = t32.x
  2583. CP(modes); CP(offset); CP(freq); CP(maxerror); CP(esterror);
  2584. CP(status); CP(constant); CP(precision); CP(tolerance);
  2585. CP(time.tv_sec); CP(time.tv_usec); CP(tick); CP(ppsfreq); CP(jitter);
  2586. CP(shift); CP(stabil); CP(jitcnt); CP(calcnt); CP(errcnt);
  2587. CP(stbcnt);
  2588. ret = do_adjtimex(&txc);
  2589. #define CP(x) t32.x = txc.x
  2590. CP(modes); CP(offset); CP(freq); CP(maxerror); CP(esterror);
  2591. CP(status); CP(constant); CP(precision); CP(tolerance);
  2592. CP(time.tv_sec); CP(time.tv_usec); CP(tick); CP(ppsfreq); CP(jitter);
  2593. CP(shift); CP(stabil); CP(jitcnt); CP(calcnt); CP(errcnt);
  2594. CP(stbcnt);
  2595. return copy_to_user(txc_p32, &t32, sizeof(struct timex32)) ? -EFAULT : ret;
  2596. }
  2597. struct sysinfo32 {
  2598. s32 uptime;
  2599. u32 loads[3];
  2600. u32 totalram;
  2601. u32 freeram;
  2602. u32 sharedram;
  2603. u32 bufferram;
  2604. u32 totalswap;
  2605. u32 freeswap;
  2606. unsigned short procs;
  2607. u32 totalhigh;
  2608. u32 freehigh;
  2609. u32 mem_unit;
  2610. char _f[12];
  2611. };
  2612. /* We used to call sys_sysinfo and translate the result.  But sys_sysinfo
  2613.  * undoes the good work done elsewhere, and rather than undoing the
  2614.  * damage, I decided to just duplicate the code from sys_sysinfo here.
  2615.  */
  2616. asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
  2617. {
  2618. struct sysinfo val;
  2619. int err;
  2620. /* We don't need a memset here because we copy the
  2621.  * struct to userspace once element at a time.
  2622.  */
  2623. cli();
  2624. val.uptime = jiffies / HZ;
  2625. val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
  2626. val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
  2627. val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
  2628. val.procs = nr_threads-1;
  2629. sti();
  2630. si_meminfo(&val);
  2631. si_swapinfo(&val);
  2632. err = put_user (val.uptime, &info->uptime);
  2633. err |= __put_user (val.loads[0], &info->loads[0]);
  2634. err |= __put_user (val.loads[1], &info->loads[1]);
  2635. err |= __put_user (val.loads[2], &info->loads[2]);
  2636. err |= __put_user (val.totalram, &info->totalram);
  2637. err |= __put_user (val.freeram, &info->freeram);
  2638. err |= __put_user (val.sharedram, &info->sharedram);
  2639. err |= __put_user (val.bufferram, &info->bufferram);
  2640. err |= __put_user (val.totalswap, &info->totalswap);
  2641. err |= __put_user (val.freeswap, &info->freeswap);
  2642. err |= __put_user (val.procs, &info->procs);
  2643. err |= __put_user (val.totalhigh, &info->totalhigh);
  2644. err |= __put_user (val.freehigh, &info->freehigh);
  2645. err |= __put_user (val.mem_unit, &info->mem_unit);
  2646. return err ? -EFAULT : 0;
  2647. }
  2648. /* lseek() needs a wrapper because 'offset' can be negative, but the top
  2649.  * half of the argument has been zeroed by syscall.S.
  2650.  */
  2651. extern asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin);
  2652. asmlinkage int sys32_lseek(unsigned int fd, int offset, unsigned int origin)
  2653. {
  2654. return sys_lseek(fd, offset, origin);
  2655. }
  2656. asmlinkage long sys32_semctl_broken(int semid, int semnum, int cmd, union semun arg)
  2657. {
  2658.         union semun u;
  2659. cmd &= ~IPC_64; /* should be removed together with the _broken suffix */
  2660.         if (cmd == SETVAL) {
  2661.                 /* Ugh.  arg is a union of int,ptr,ptr,ptr, so is 8 bytes.
  2662.                  * The int should be in the first 4, but our argument
  2663.                  * frobbing has left it in the last 4.
  2664.                  */
  2665.                 u.val = *((int *)&arg + 1);
  2666.                 return sys_semctl (semid, semnum, cmd, u);
  2667. }
  2668. return sys_semctl (semid, semnum, cmd, arg);
  2669. }