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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Derived from sys_sparc32.c.
  3.  *
  4.  * Copyright (C) 2000 VA Linux Co
  5.  * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
  6.  * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
  7.  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  8.  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  9.  * Copyright (C) 2000-2002 Hewlett-Packard Co
  10.  * David Mosberger-Tang <davidm@hpl.hp.com>
  11.  *
  12.  * These routines maintain argument size conversion between 32bit and 64bit
  13.  * environment.
  14.  */
  15. #include <linux/config.h>
  16. #include <linux/kernel.h>
  17. #include <linux/sysctl.h>
  18. #include <linux/sched.h>
  19. #include <linux/fs.h>
  20. #include <linux/file.h>
  21. #include <linux/signal.h>
  22. #include <linux/utime.h>
  23. #include <linux/resource.h>
  24. #include <linux/times.h>
  25. #include <linux/utsname.h>
  26. #include <linux/timex.h>
  27. #include <linux/smp.h>
  28. #include <linux/smp_lock.h>
  29. #include <linux/sem.h>
  30. #include <linux/msg.h>
  31. #include <linux/mm.h>
  32. #include <linux/shm.h>
  33. #include <linux/slab.h>
  34. #include <linux/uio.h>
  35. #include <linux/nfs_fs.h>
  36. #include <linux/smb_fs.h>
  37. #include <linux/smb_mount.h>
  38. #include <linux/ncp_fs.h>
  39. #include <linux/quota.h>
  40. #include <linux/module.h>
  41. #include <linux/sunrpc/svc.h>
  42. #include <linux/nfsd/nfsd.h>
  43. #include <linux/nfsd/cache.h>
  44. #include <linux/nfsd/xdr.h>
  45. #include <linux/nfsd/syscall.h>
  46. #include <linux/poll.h>
  47. #include <linux/personality.h>
  48. #include <linux/stat.h>
  49. #include <linux/ipc.h>
  50. #include <asm/types.h>
  51. #include <asm/uaccess.h>
  52. #include <asm/semaphore.h>
  53. #include <net/scm.h>
  54. #include <net/sock.h>
  55. #include <asm/ia32.h>
  56. #define DEBUG 0
  57. #if DEBUG
  58. # define DBG(fmt...) printk(KERN_DEBUG fmt)
  59. #else
  60. # define DBG(fmt...)
  61. #endif
  62. #define A(__x) ((unsigned long)(__x))
  63. #define AA(__x) ((unsigned long)(__x))
  64. #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
  65. #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
  66. #define OFFSET4K(a) ((a) & 0xfff)
  67. #define PAGE_START(addr) ((addr) & PAGE_MASK)
  68. #define PAGE_OFF(addr) ((addr) & ~PAGE_MASK)
  69. extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *);
  70. extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long);
  71. extern asmlinkage long sys_munmap (unsigned long, size_t);
  72. extern unsigned long arch_get_unmapped_area (struct file *, unsigned long, unsigned long,
  73.      unsigned long, unsigned long);
  74. /* forward declaration: */
  75. asmlinkage long sys32_mprotect (unsigned int, unsigned int, int);
  76. asmlinkage unsigned long sys_brk(unsigned long);
  77. /*
  78.  * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
  79.  * while doing so.
  80.  */
  81. /* XXX make per-mm: */
  82. static DECLARE_MUTEX(ia32_mmap_sem);
  83. static int
  84. nargs (unsigned int arg, char **ap)
  85. {
  86. unsigned int addr;
  87. int n, err;
  88. if (!arg)
  89. return 0;
  90. n = 0;
  91. do {
  92. err = get_user(addr, (unsigned int *)A(arg));
  93. if (err)
  94. return err;
  95. if (ap)
  96. *ap++ = (char *) A(addr);
  97. arg += sizeof(unsigned int);
  98. n++;
  99. } while (addr);
  100. return n - 1;
  101. }
  102. asmlinkage long
  103. sys32_execve (char *filename, unsigned int argv, unsigned int envp,
  104.       int dummy3, int dummy4, int dummy5, int dummy6, int dummy7,
  105.       int stack)
  106. {
  107. struct pt_regs *regs = (struct pt_regs *)&stack;
  108. unsigned long old_map_base, old_task_size, tssd;
  109. char **av, **ae;
  110. int na, ne, len;
  111. long r;
  112. na = nargs(argv, NULL);
  113. if (na < 0)
  114. return na;
  115. ne = nargs(envp, NULL);
  116. if (ne < 0)
  117. return ne;
  118. len = (na + ne + 2) * sizeof(*av);
  119. av = kmalloc(len, GFP_KERNEL);
  120. if (!av)
  121. return -ENOMEM;
  122. ae = av + na + 1;
  123. av[na] = NULL;
  124. ae[ne] = NULL;
  125. r = nargs(argv, av);
  126. if (r < 0)
  127. goto out;
  128. r = nargs(envp, ae);
  129. if (r < 0)
  130. goto out;
  131. old_map_base  = current->thread.map_base;
  132. old_task_size = current->thread.task_size;
  133. tssd = ia64_get_kr(IA64_KR_TSSD);
  134. /* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */
  135. current->thread.map_base  = DEFAULT_MAP_BASE;
  136. current->thread.task_size = DEFAULT_TASK_SIZE;
  137. ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
  138. ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
  139. set_fs(KERNEL_DS);
  140. r = sys_execve(filename, av, ae, regs);
  141. if (r < 0) {
  142. /* oops, execve failed, switch back to old values... */
  143. ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
  144. ia64_set_kr(IA64_KR_TSSD, tssd);
  145. current->thread.map_base  = old_map_base;
  146. current->thread.task_size = old_task_size;
  147. set_fs(USER_DS); /* establish new task-size as the address-limit */
  148.   out:
  149. kfree(av);
  150. }
  151. return r;
  152. }
  153. static inline int
  154. putstat (struct stat32 *ubuf, struct stat *kbuf)
  155. {
  156. int err;
  157. if (clear_user(ubuf, sizeof(*ubuf)))
  158. return 1;
  159. err  = __put_user(kbuf->st_dev, &ubuf->st_dev);
  160. err |= __put_user(kbuf->st_ino, &ubuf->st_ino);
  161. err |= __put_user(kbuf->st_mode, &ubuf->st_mode);
  162. err |= __put_user(kbuf->st_nlink, &ubuf->st_nlink);
  163. err |= __put_user(kbuf->st_uid, &ubuf->st_uid);
  164. err |= __put_user(kbuf->st_gid, &ubuf->st_gid);
  165. err |= __put_user(kbuf->st_rdev, &ubuf->st_rdev);
  166. err |= __put_user(kbuf->st_size, &ubuf->st_size);
  167. err |= __put_user(kbuf->st_atime, &ubuf->st_atime);
  168. err |= __put_user(kbuf->st_mtime, &ubuf->st_mtime);
  169. err |= __put_user(kbuf->st_ctime, &ubuf->st_ctime);
  170. err |= __put_user(kbuf->st_blksize, &ubuf->st_blksize);
  171. err |= __put_user(kbuf->st_blocks, &ubuf->st_blocks);
  172. return err;
  173. }
  174. extern asmlinkage long sys_newstat (char * filename, struct stat * statbuf);
  175. asmlinkage long
  176. sys32_newstat (char *filename, struct stat32 *statbuf)
  177. {
  178. int ret;
  179. struct stat s;
  180. mm_segment_t old_fs = get_fs();
  181. set_fs(KERNEL_DS);
  182. ret = sys_newstat(filename, &s);
  183. set_fs(old_fs);
  184. if (putstat(statbuf, &s))
  185. return -EFAULT;
  186. return ret;
  187. }
  188. extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
  189. asmlinkage long
  190. sys32_newlstat (char *filename, struct stat32 *statbuf)
  191. {
  192. mm_segment_t old_fs = get_fs();
  193. struct stat s;
  194. int ret;
  195. set_fs(KERNEL_DS);
  196. ret = sys_newlstat(filename, &s);
  197. set_fs(old_fs);
  198. if (putstat(statbuf, &s))
  199. return -EFAULT;
  200. return ret;
  201. }
  202. extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
  203. asmlinkage long
  204. sys32_newfstat (unsigned int fd, struct stat32 *statbuf)
  205. {
  206. mm_segment_t old_fs = get_fs();
  207. struct stat s;
  208. int ret;
  209. set_fs(KERNEL_DS);
  210. ret = sys_newfstat(fd, &s);
  211. set_fs(old_fs);
  212. if (putstat(statbuf, &s))
  213. return -EFAULT;
  214. return ret;
  215. }
  216. #if PAGE_SHIFT > IA32_PAGE_SHIFT
  217. static int
  218. get_page_prot (unsigned long addr)
  219. {
  220. struct vm_area_struct *vma = find_vma(current->mm, addr);
  221. int prot = 0;
  222. if (!vma || vma->vm_start > addr)
  223. return 0;
  224. if (vma->vm_flags & VM_READ)
  225. prot |= PROT_READ;
  226. if (vma->vm_flags & VM_WRITE)
  227. prot |= PROT_WRITE;
  228. if (vma->vm_flags & VM_EXEC)
  229. prot |= PROT_EXEC;
  230. return prot;
  231. }
  232. /*
  233.  * Map a subpage by creating an anonymous page that contains the union of the old page and
  234.  * the subpage.
  235.  */
  236. static unsigned long
  237. mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
  238.       loff_t off)
  239. {
  240. void *page = (void *) get_zeroed_page(GFP_KERNEL);
  241. struct inode *inode;
  242. unsigned long ret;
  243. int old_prot = get_page_prot(start);
  244. DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)n",
  245.     file, start, end, prot, flags, off);
  246. if (!page)
  247. return -ENOMEM;
  248. if (old_prot)
  249. copy_from_user(page, (void *) PAGE_START(start), PAGE_SIZE);
  250. down_write(&current->mm->mmap_sem);
  251. {
  252. ret = do_mmap(0, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE,
  253.       flags | MAP_FIXED | MAP_ANONYMOUS, 0);
  254. }
  255. up_write(&current->mm->mmap_sem);
  256. if (IS_ERR((void *) ret))
  257. goto out;
  258. if (old_prot) {
  259. /* copy back the old page contents.  */
  260. if (PAGE_OFF(start))
  261. copy_to_user((void *) PAGE_START(start), page, PAGE_OFF(start));
  262. if (PAGE_OFF(end))
  263. copy_to_user((void *) end, page + PAGE_OFF(end),
  264.      PAGE_SIZE - PAGE_OFF(end));
  265. }
  266. if (!(flags & MAP_ANONYMOUS)) {
  267. /* read the file contents */
  268. inode = file->f_dentry->d_inode;
  269. if (!inode->i_fop || !file->f_op->read
  270.     || ((*file->f_op->read)(file, (char *) start, end - start, &off) < 0))
  271. {
  272. ret = -EINVAL;
  273. goto out;
  274. }
  275. }
  276. if (!(prot & PROT_WRITE))
  277. ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
  278.   out:
  279. free_page((unsigned long) page);
  280. return ret;
  281. }
  282. static unsigned long
  283. emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags,
  284.       loff_t off)
  285. {
  286. unsigned long tmp, end, pend, pstart, ret, is_congruent, fudge = 0;
  287. struct inode *inode;
  288. loff_t poff;
  289. end = start + len;
  290. pstart = PAGE_START(start);
  291. pend = PAGE_ALIGN(end);
  292. if (flags & MAP_FIXED) {
  293. if (start > pstart) {
  294. if (flags & MAP_SHARED)
  295. printk(KERN_INFO
  296.        "%s(%d): emulate_mmap() can't share head (addr=0x%lx)n",
  297.        current->comm, current->pid, start);
  298. ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
  299.    off);
  300. if (IS_ERR((void *) ret))
  301. return ret;
  302. pstart += PAGE_SIZE;
  303. if (pstart >= pend)
  304. return start; /* done */
  305. }
  306. if (end < pend) {
  307. if (flags & MAP_SHARED)
  308. printk(KERN_INFO
  309.        "%s(%d): emulate_mmap() can't share tail (end=0x%lx)n",
  310.        current->comm, current->pid, end);
  311. ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
  312.    (off + len) - PAGE_OFF(end));
  313. if (IS_ERR((void *) ret))
  314. return ret;
  315. pend -= PAGE_SIZE;
  316. if (pstart >= pend)
  317. return start; /* done */
  318. }
  319. } else {
  320. /*
  321.  * If a start address was specified, use it if the entire rounded out area
  322.  * is available.
  323.  */
  324. if (start && !pstart)
  325. fudge = 1; /* handle case of mapping to range (0,PAGE_SIZE) */
  326. tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags);
  327. if (tmp != pstart) {
  328. pstart = tmp;
  329. start = pstart + PAGE_OFF(off); /* make start congruent with off */
  330. end = start + len;
  331. pend = PAGE_ALIGN(end);
  332. }
  333. }
  334. poff = off + (pstart - start); /* note: (pstart - start) may be negative */
  335. is_congruent = (flags & MAP_ANONYMOUS) || (PAGE_OFF(poff) == 0);
  336. if ((flags & MAP_SHARED) && !is_congruent)
  337. printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
  338.        "(addr=0x%lx,off=0x%llx)n", current->comm, current->pid, start, off);
  339. DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llxn", pstart, pend,
  340.     is_congruent ? "congruent" : "not congruent", poff);
  341. down_write(&current->mm->mmap_sem);
  342. {
  343. if (!(flags & MAP_ANONYMOUS) && is_congruent)
  344. ret = do_mmap(file, pstart, pend - pstart, prot, flags | MAP_FIXED, poff);
  345. else
  346. ret = do_mmap(0, pstart, pend - pstart,
  347.       prot | ((flags & MAP_ANONYMOUS) ? 0 : PROT_WRITE),
  348.       flags | MAP_FIXED | MAP_ANONYMOUS, 0);
  349. }
  350. up_write(&current->mm->mmap_sem);
  351. if (IS_ERR((void *) ret))
  352. return ret;
  353. if (!is_congruent) {
  354. /* read the file contents */
  355. inode = file->f_dentry->d_inode;
  356. if (!inode->i_fop || !file->f_op->read
  357.     || ((*file->f_op->read)(file, (char *) pstart, pend - pstart, &poff) < 0))
  358. {
  359. sys_munmap(pstart, pend - pstart);
  360. return -EINVAL;
  361. }
  362. if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0)
  363. return -EINVAL;
  364. }
  365. return start;
  366. }
  367. #endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
  368. static inline unsigned int
  369. get_prot32 (unsigned int prot)
  370. {
  371. if (prot & PROT_WRITE)
  372. /* on x86, PROT_WRITE implies PROT_READ which implies PROT_EEC */
  373. prot |= PROT_READ | PROT_WRITE | PROT_EXEC;
  374. else if (prot & (PROT_READ | PROT_EXEC))
  375. /* on x86, there is no distinction between PROT_READ and PROT_EXEC */
  376. prot |= (PROT_READ | PROT_EXEC);
  377. return prot;
  378. }
  379. unsigned long
  380. ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot, int flags,
  381.       loff_t offset)
  382. {
  383. DBG("ia32_do_mmap(file=%p,addr=0x%lx,len=0x%lx,prot=%x,flags=%x,offset=0x%llx)n",
  384.     file, addr, len, prot, flags, offset);
  385. if (file && (!file->f_op || !file->f_op->mmap))
  386. return -ENODEV;
  387. len = IA32_PAGE_ALIGN(len);
  388. if (len == 0)
  389. return addr;
  390. if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
  391. return -EINVAL;
  392. if (OFFSET4K(offset))
  393. return -EINVAL;
  394. prot = get_prot32(prot);
  395. #if PAGE_SHIFT > IA32_PAGE_SHIFT
  396. down(&ia32_mmap_sem);
  397. {
  398. addr = emulate_mmap(file, addr, len, prot, flags, offset);
  399. }
  400. up(&ia32_mmap_sem);
  401. #else
  402. down_write(&current->mm->mmap_sem);
  403. {
  404. addr = do_mmap(file, addr, len, prot, flags, offset);
  405. }
  406. up_write(&current->mm->mmap_sem);
  407. #endif
  408. DBG("ia32_do_mmap: returning 0x%lxn", addr);
  409. return addr;
  410. }
  411. /*
  412.  * Linux/i386 didn't use to be able to handle more than 4 system call parameters, so these
  413.  * system calls used a memory block for parameter passing..
  414.  */
  415. struct mmap_arg_struct {
  416. unsigned int addr;
  417. unsigned int len;
  418. unsigned int prot;
  419. unsigned int flags;
  420. unsigned int fd;
  421. unsigned int offset;
  422. };
  423. asmlinkage long
  424. sys32_mmap (struct mmap_arg_struct *arg)
  425. {
  426. struct mmap_arg_struct a;
  427. struct file *file = NULL;
  428. unsigned long addr;
  429. int flags;
  430. if (copy_from_user(&a, arg, sizeof(a)))
  431. return -EFAULT;
  432. if (OFFSET4K(a.offset))
  433. return -EINVAL;
  434. flags = a.flags;
  435. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  436. if (!(flags & MAP_ANONYMOUS)) {
  437. file = fget(a.fd);
  438. if (!file)
  439. return -EBADF;
  440. }
  441. addr = ia32_do_mmap(file, a.addr, a.len, a.prot, flags, a.offset);
  442. if (file)
  443. fput(file);
  444. return addr;
  445. }
  446. asmlinkage long
  447. sys32_mmap2 (unsigned int addr, unsigned int len, unsigned int prot, unsigned int flags,
  448.      unsigned int fd, unsigned int pgoff)
  449. {
  450. struct file *file = NULL;
  451. unsigned long retval;
  452. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  453. if (!(flags & MAP_ANONYMOUS)) {
  454. file = fget(fd);
  455. if (!file)
  456. return -EBADF;
  457. }
  458. retval = ia32_do_mmap(file, addr, len, prot, flags,
  459.       (unsigned long) pgoff << IA32_PAGE_SHIFT);
  460. if (file)
  461. fput(file);
  462. return retval;
  463. }
  464. asmlinkage long
  465. sys32_munmap (unsigned int start, unsigned int len)
  466. {
  467. unsigned int end = start + len;
  468. long ret;
  469. #if PAGE_SHIFT <= IA32_PAGE_SHIFT
  470. ret = sys_munmap(start, end - start);
  471. #else
  472. if (start > end)
  473. return -EINVAL;
  474. start = PAGE_ALIGN(start);
  475. end = PAGE_START(end);
  476. if (start >= end)
  477. return 0;
  478. down(&ia32_mmap_sem);
  479. {
  480. ret = sys_munmap(start, end - start);
  481. }
  482. up(&ia32_mmap_sem);
  483. #endif
  484. return ret;
  485. }
  486. #if PAGE_SHIFT > IA32_PAGE_SHIFT
  487. /*
  488.  * When mprotect()ing a partial page, we set the permission to the union of the old
  489.  * settings and the new settings.  In other words, it's only possible to make access to a
  490.  * partial page less restrictive.
  491.  */
  492. static long
  493. mprotect_subpage (unsigned long address, int new_prot)
  494. {
  495. int old_prot;
  496. if (new_prot == PROT_NONE)
  497. return 0; /* optimize case where nothing changes... */
  498. old_prot = get_page_prot(address);
  499. return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
  500. }
  501. #endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
  502. asmlinkage long
  503. sys32_mprotect (unsigned int start, unsigned int len, int prot)
  504. {
  505. unsigned long end = start + len;
  506. #if PAGE_SHIFT > IA32_PAGE_SHIFT
  507. long retval = 0;
  508. #endif
  509. prot = get_prot32(prot);
  510. #if PAGE_SHIFT <= IA32_PAGE_SHIFT
  511. return sys_mprotect(start, end - start, prot);
  512. #else
  513. if (OFFSET4K(start))
  514. return -EINVAL;
  515. end = IA32_PAGE_ALIGN(end);
  516. if (end < start)
  517. return -EINVAL;
  518. down(&ia32_mmap_sem);
  519. {
  520. if (PAGE_OFF(start)) {
  521. /* start address is 4KB aligned but not page aligned. */
  522. retval = mprotect_subpage(PAGE_START(start), prot);
  523. if (retval < 0)
  524. goto out;
  525. start = PAGE_ALIGN(start);
  526. if (start >= end)
  527. goto out; /* retval is already zero... */
  528. }
  529. if (PAGE_OFF(end)) {
  530. /* end address is 4KB aligned but not page aligned. */
  531. retval = mprotect_subpage(PAGE_START(end), prot);
  532. if (retval < 0)
  533. return retval;
  534. end = PAGE_START(end);
  535. }
  536. retval = sys_mprotect(start, end - start, prot);
  537. }
  538.   out:
  539. up(&ia32_mmap_sem);
  540. return retval;
  541. #endif
  542. }
  543. asmlinkage long
  544. sys32_pipe (int *fd)
  545. {
  546. int retval;
  547. int fds[2];
  548. retval = do_pipe(fds);
  549. if (retval)
  550. goto out;
  551. if (copy_to_user(fd, fds, sizeof(fds)))
  552. retval = -EFAULT;
  553.   out:
  554. return retval;
  555. }
  556. static inline int
  557. put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
  558. {
  559. int err;
  560. if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
  561. return -EFAULT;
  562. err = __put_user(kbuf->f_type, &ubuf->f_type);
  563. err |= __put_user(kbuf->f_bsize, &ubuf->f_bsize);
  564. err |= __put_user(kbuf->f_blocks, &ubuf->f_blocks);
  565. err |= __put_user(kbuf->f_bfree, &ubuf->f_bfree);
  566. err |= __put_user(kbuf->f_bavail, &ubuf->f_bavail);
  567. err |= __put_user(kbuf->f_files, &ubuf->f_files);
  568. err |= __put_user(kbuf->f_ffree, &ubuf->f_ffree);
  569. err |= __put_user(kbuf->f_namelen, &ubuf->f_namelen);
  570. err |= __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
  571. err |= __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
  572. return err;
  573. }
  574. extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
  575. asmlinkage long
  576. sys32_statfs (const char *path, struct statfs32 *buf)
  577. {
  578. int ret;
  579. struct statfs s;
  580. mm_segment_t old_fs = get_fs();
  581. set_fs(KERNEL_DS);
  582. ret = sys_statfs(path, &s);
  583. set_fs(old_fs);
  584. if (put_statfs(buf, &s))
  585. return -EFAULT;
  586. return ret;
  587. }
  588. extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
  589. asmlinkage long
  590. sys32_fstatfs (unsigned int fd, struct statfs32 *buf)
  591. {
  592. int ret;
  593. struct statfs s;
  594. mm_segment_t old_fs = get_fs();
  595. set_fs(KERNEL_DS);
  596. ret = sys_fstatfs(fd, &s);
  597. set_fs(old_fs);
  598. if (put_statfs(buf, &s))
  599. return -EFAULT;
  600. return ret;
  601. }
  602. struct timeval32
  603. {
  604.     int tv_sec, tv_usec;
  605. };
  606. struct itimerval32
  607. {
  608.     struct timeval32 it_interval;
  609.     struct timeval32 it_value;
  610. };
  611. static inline long
  612. get_tv32 (struct timeval *o, struct timeval32 *i)
  613. {
  614. return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
  615. (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
  616. }
  617. static inline long
  618. put_tv32 (struct timeval32 *o, struct timeval *i)
  619. {
  620. return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
  621. (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
  622. }
  623. static inline long
  624. get_it32 (struct itimerval *o, struct itimerval32 *i)
  625. {
  626. return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
  627. (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
  628.  __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
  629.  __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
  630.  __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
  631. }
  632. static inline long
  633. put_it32 (struct itimerval32 *o, struct itimerval *i)
  634. {
  635. return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
  636. (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
  637.  __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
  638.  __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
  639.  __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
  640. }
  641. extern int do_getitimer (int which, struct itimerval *value);
  642. asmlinkage long
  643. sys32_getitimer (int which, struct itimerval32 *it)
  644. {
  645. struct itimerval kit;
  646. int error;
  647. error = do_getitimer(which, &kit);
  648. if (!error && put_it32(it, &kit))
  649. error = -EFAULT;
  650. return error;
  651. }
  652. extern int do_setitimer (int which, struct itimerval *, struct itimerval *);
  653. asmlinkage long
  654. sys32_setitimer (int which, struct itimerval32 *in, struct itimerval32 *out)
  655. {
  656. struct itimerval kin, kout;
  657. int error;
  658. if (in) {
  659. if (get_it32(&kin, in))
  660. return -EFAULT;
  661. } else
  662. memset(&kin, 0, sizeof(kin));
  663. error = do_setitimer(which, &kin, out ? &kout : NULL);
  664. if (error || !out)
  665. return error;
  666. if (put_it32(out, &kout))
  667. return -EFAULT;
  668. return 0;
  669. }
  670. asmlinkage unsigned long
  671. sys32_alarm (unsigned int seconds)
  672. {
  673. struct itimerval it_new, it_old;
  674. unsigned int oldalarm;
  675. it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
  676. it_new.it_value.tv_sec = seconds;
  677. it_new.it_value.tv_usec = 0;
  678. do_setitimer(ITIMER_REAL, &it_new, &it_old);
  679. oldalarm = it_old.it_value.tv_sec;
  680. /* ehhh.. We can't return 0 if we have an alarm pending.. */
  681. /* And we'd better return too much than too little anyway */
  682. if (it_old.it_value.tv_usec)
  683. oldalarm++;
  684. return oldalarm;
  685. }
  686. /* Translations due to time_t size differences.  Which affects all
  687.    sorts of things, like timeval and itimerval.  */
  688. struct utimbuf_32 {
  689. int atime;
  690. int mtime;
  691. };
  692. extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
  693. extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
  694. asmlinkage long
  695. sys32_utime (char *filename, struct utimbuf_32 *times32)
  696. {
  697. mm_segment_t old_fs = get_fs();
  698. struct timeval tv[2], *tvp;
  699. long ret;
  700. if (times32) {
  701. if (get_user(tv[0].tv_sec, &times32->atime))
  702. return -EFAULT;
  703. tv[0].tv_usec = 0;
  704. if (get_user(tv[1].tv_sec, &times32->mtime))
  705. return -EFAULT;
  706. tv[1].tv_usec = 0;
  707. set_fs(KERNEL_DS);
  708. tvp = tv;
  709. } else
  710. tvp = NULL;
  711. ret = sys_utimes(filename, tvp);
  712. set_fs(old_fs);
  713. return ret;
  714. }
  715. extern struct timezone sys_tz;
  716. extern int do_sys_settimeofday (struct timeval *tv, struct timezone *tz);
  717. asmlinkage long
  718. sys32_gettimeofday (struct timeval32 *tv, struct timezone *tz)
  719. {
  720. if (tv) {
  721. struct timeval ktv;
  722. do_gettimeofday(&ktv);
  723. if (put_tv32(tv, &ktv))
  724. return -EFAULT;
  725. }
  726. if (tz) {
  727. if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
  728. return -EFAULT;
  729. }
  730. return 0;
  731. }
  732. asmlinkage long
  733. sys32_settimeofday (struct timeval32 *tv, struct timezone *tz)
  734. {
  735. struct timeval ktv;
  736. struct timezone ktz;
  737. if (tv) {
  738. if (get_tv32(&ktv, tv))
  739. return -EFAULT;
  740. }
  741. if (tz) {
  742. if (copy_from_user(&ktz, tz, sizeof(ktz)))
  743. return -EFAULT;
  744. }
  745. return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
  746. }
  747. struct getdents32_callback {
  748. struct linux32_dirent * current_dir;
  749. struct linux32_dirent * previous;
  750. int count;
  751. int error;
  752. };
  753. struct readdir32_callback {
  754. struct old_linux32_dirent * dirent;
  755. int count;
  756. };
  757. static int
  758. filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
  759.    unsigned int d_type)
  760. {
  761. struct linux32_dirent * dirent;
  762. struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
  763. int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
  764. buf->error = -EINVAL; /* only used if we fail.. */
  765. if (reclen > buf->count)
  766. return -EINVAL;
  767. buf->error = -EFAULT; /* only used if we fail.. */
  768. dirent = buf->previous;
  769. if (dirent)
  770. if (put_user(offset, &dirent->d_off))
  771. return -EFAULT;
  772. dirent = buf->current_dir;
  773. buf->previous = dirent;
  774. if (put_user(ino, &dirent->d_ino)
  775.     || put_user(reclen, &dirent->d_reclen)
  776.     || copy_to_user(dirent->d_name, name, namlen)
  777.     || put_user(0, dirent->d_name + namlen))
  778. return -EFAULT;
  779. ((char *) dirent) += reclen;
  780. buf->current_dir = dirent;
  781. buf->count -= reclen;
  782. return 0;
  783. }
  784. asmlinkage long
  785. sys32_getdents (unsigned int fd, struct linux32_dirent *dirent, unsigned int count)
  786. {
  787. struct file * file;
  788. struct linux32_dirent * lastdirent;
  789. struct getdents32_callback buf;
  790. int error;
  791. error = -EBADF;
  792. file = fget(fd);
  793. if (!file)
  794. goto out;
  795. buf.current_dir = dirent;
  796. buf.previous = NULL;
  797. buf.count = count;
  798. buf.error = 0;
  799. error = vfs_readdir(file, filldir32, &buf);
  800. if (error < 0)
  801. goto out_putf;
  802. error = buf.error;
  803. lastdirent = buf.previous;
  804. if (lastdirent) {
  805. error = -EINVAL;
  806. if (put_user(file->f_pos, &lastdirent->d_off))
  807. goto out_putf;
  808. error = count - buf.count;
  809. }
  810. out_putf:
  811. fput(file);
  812. out:
  813. return error;
  814. }
  815. static int
  816. fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
  817.       unsigned int d_type)
  818. {
  819. struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
  820. struct old_linux32_dirent * dirent;
  821. if (buf->count)
  822. return -EINVAL;
  823. buf->count++;
  824. dirent = buf->dirent;
  825. if (put_user(ino, &dirent->d_ino)
  826.     || put_user(offset, &dirent->d_offset)
  827.     || put_user(namlen, &dirent->d_namlen)
  828.     || copy_to_user(dirent->d_name, name, namlen)
  829.     || put_user(0, dirent->d_name + namlen))
  830. return -EFAULT;
  831. return 0;
  832. }
  833. asmlinkage long
  834. sys32_readdir (unsigned int fd, void *dirent, unsigned int count)
  835. {
  836. int error;
  837. struct file * file;
  838. struct readdir32_callback buf;
  839. error = -EBADF;
  840. file = fget(fd);
  841. if (!file)
  842. goto out;
  843. buf.count = 0;
  844. buf.dirent = dirent;
  845. error = vfs_readdir(file, fillonedir32, &buf);
  846. if (error >= 0)
  847. error = buf.count;
  848. fput(file);
  849. out:
  850. return error;
  851. }
  852. /*
  853.  * We can actually return ERESTARTSYS instead of EINTR, but I'd
  854.  * like to be certain this leads to no problems. So I return
  855.  * EINTR just for safety.
  856.  *
  857.  * Update: ERESTARTSYS breaks at least the xview clock binary, so
  858.  * I'm trying ERESTARTNOHAND which restart only when you want to.
  859.  */
  860. #define MAX_SELECT_SECONDS 
  861. ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
  862. #define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
  863. asmlinkage long
  864. sys32_select (int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32)
  865. {
  866. fd_set_bits fds;
  867. char *bits;
  868. long timeout;
  869. int ret, size;
  870. timeout = MAX_SCHEDULE_TIMEOUT;
  871. if (tvp32) {
  872. time_t sec, usec;
  873. ret = -EFAULT;
  874. if (get_user(sec, &tvp32->tv_sec) || get_user(usec, &tvp32->tv_usec))
  875. goto out_nofds;
  876. ret = -EINVAL;
  877. if (sec < 0 || usec < 0)
  878. goto out_nofds;
  879. if ((unsigned long) sec < MAX_SELECT_SECONDS) {
  880. timeout = ROUND_UP_TIME(usec, 1000000/HZ);
  881. timeout += sec * (unsigned long) HZ;
  882. }
  883. }
  884. ret = -EINVAL;
  885. if (n < 0)
  886. goto out_nofds;
  887. if (n > current->files->max_fdset)
  888. n = current->files->max_fdset;
  889. /*
  890.  * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
  891.  * since we used fdset we need to allocate memory in units of
  892.  * long-words.
  893.  */
  894. ret = -ENOMEM;
  895. size = FDS_BYTES(n);
  896. bits = kmalloc(6 * size, GFP_KERNEL);
  897. if (!bits)
  898. goto out_nofds;
  899. fds.in      = (unsigned long *)  bits;
  900. fds.out     = (unsigned long *) (bits +   size);
  901. fds.ex      = (unsigned long *) (bits + 2*size);
  902. fds.res_in  = (unsigned long *) (bits + 3*size);
  903. fds.res_out = (unsigned long *) (bits + 4*size);
  904. fds.res_ex  = (unsigned long *) (bits + 5*size);
  905. if ((ret = get_fd_set(n, inp, fds.in)) ||
  906.     (ret = get_fd_set(n, outp, fds.out)) ||
  907.     (ret = get_fd_set(n, exp, fds.ex)))
  908. goto out;
  909. zero_fd_set(n, fds.res_in);
  910. zero_fd_set(n, fds.res_out);
  911. zero_fd_set(n, fds.res_ex);
  912. ret = do_select(n, &fds, &timeout);
  913. if (tvp32 && !(current->personality & STICKY_TIMEOUTS)) {
  914. time_t sec = 0, usec = 0;
  915. if (timeout) {
  916. sec = timeout / HZ;
  917. usec = timeout % HZ;
  918. usec *= (1000000/HZ);
  919. }
  920. if (put_user(sec, &tvp32->tv_sec) || put_user(usec, &tvp32->tv_usec)) {
  921. ret = -EFAULT;
  922. goto out;
  923. }
  924. }
  925. if (ret < 0)
  926. goto out;
  927. if (!ret) {
  928. ret = -ERESTARTNOHAND;
  929. if (signal_pending(current))
  930. goto out;
  931. ret = 0;
  932. }
  933. set_fd_set(n, inp, fds.res_in);
  934. set_fd_set(n, outp, fds.res_out);
  935. set_fd_set(n, exp, fds.res_ex);
  936. out:
  937. kfree(bits);
  938. out_nofds:
  939. return ret;
  940. }
  941. struct sel_arg_struct {
  942. unsigned int n;
  943. unsigned int inp;
  944. unsigned int outp;
  945. unsigned int exp;
  946. unsigned int tvp;
  947. };
  948. asmlinkage long
  949. sys32_old_select (struct sel_arg_struct *arg)
  950. {
  951. struct sel_arg_struct a;
  952. if (copy_from_user(&a, arg, sizeof(a)))
  953. return -EFAULT;
  954. return sys32_select(a.n, (fd_set *) A(a.inp), (fd_set *) A(a.outp), (fd_set *) A(a.exp),
  955.     (struct timeval32 *) A(a.tvp));
  956. }
  957. extern asmlinkage long sys_nanosleep (struct timespec *rqtp, struct timespec *rmtp);
  958. asmlinkage long
  959. sys32_nanosleep (struct timespec32 *rqtp, struct timespec32 *rmtp)
  960. {
  961. struct timespec t;
  962. int ret;
  963. mm_segment_t old_fs = get_fs();
  964. if (get_user (t.tv_sec, &rqtp->tv_sec) || get_user (t.tv_nsec, &rqtp->tv_nsec))
  965. return -EFAULT;
  966. set_fs(KERNEL_DS);
  967. ret = sys_nanosleep(&t, rmtp ? &t : NULL);
  968. set_fs(old_fs);
  969. if (rmtp && ret == -EINTR) {
  970. if (put_user(t.tv_sec, &rmtp->tv_sec) || put_user(t.tv_nsec, &rmtp->tv_nsec))
  971. return -EFAULT;
  972. }
  973. return ret;
  974. }
  975. struct iovec32 { unsigned int iov_base; int iov_len; };
  976. asmlinkage ssize_t sys_readv (unsigned long,const struct iovec *,unsigned long);
  977. asmlinkage ssize_t sys_writev (unsigned long,const struct iovec *,unsigned long);
  978. static struct iovec *
  979. get_iovec32 (struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
  980. {
  981. int i;
  982. u32 buf, len;
  983. struct iovec *ivp, *iov;
  984. /* Get the "struct iovec" from user memory */
  985. if (!count)
  986. return 0;
  987. if (verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
  988. return NULL;
  989. if (count > UIO_MAXIOV)
  990. return NULL;
  991. if (count > UIO_FASTIOV) {
  992. iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
  993. if (!iov)
  994. return NULL;
  995. } else
  996. iov = iov_buf;
  997. ivp = iov;
  998. for (i = 0; i < count; i++) {
  999. if (__get_user(len, &iov32->iov_len) || __get_user(buf, &iov32->iov_base)) {
  1000. if (iov != iov_buf)
  1001. kfree(iov);
  1002. return NULL;
  1003. }
  1004. if (verify_area(type, (void *)A(buf), len)) {
  1005. if (iov != iov_buf)
  1006. kfree(iov);
  1007. return((struct iovec *)0);
  1008. }
  1009. ivp->iov_base = (void *)A(buf);
  1010. ivp->iov_len = (__kernel_size_t) len;
  1011. iov32++;
  1012. ivp++;
  1013. }
  1014. return iov;
  1015. }
  1016. asmlinkage long
  1017. sys32_readv (int fd, struct iovec32 *vector, u32 count)
  1018. {
  1019. struct iovec iovstack[UIO_FASTIOV];
  1020. struct iovec *iov;
  1021. long ret;
  1022. mm_segment_t old_fs = get_fs();
  1023. iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE);
  1024. if (!iov)
  1025. return -EFAULT;
  1026. set_fs(KERNEL_DS);
  1027. ret = sys_readv(fd, iov, count);
  1028. set_fs(old_fs);
  1029. if (iov != iovstack)
  1030. kfree(iov);
  1031. return ret;
  1032. }
  1033. asmlinkage long
  1034. sys32_writev (int fd, struct iovec32 *vector, u32 count)
  1035. {
  1036. struct iovec iovstack[UIO_FASTIOV];
  1037. struct iovec *iov;
  1038. long ret;
  1039. mm_segment_t old_fs = get_fs();
  1040. iov = get_iovec32(vector, iovstack, count, VERIFY_READ);
  1041. if (!iov)
  1042. return -EFAULT;
  1043. set_fs(KERNEL_DS);
  1044. ret = sys_writev(fd, iov, count);
  1045. set_fs(old_fs);
  1046. if (iov != iovstack)
  1047. kfree(iov);
  1048. return ret;
  1049. }
  1050. #define RLIM_INFINITY32 0x7fffffff
  1051. #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
  1052. struct rlimit32 {
  1053. int rlim_cur;
  1054. int rlim_max;
  1055. };
  1056. extern asmlinkage long sys_getrlimit (unsigned int resource, struct rlimit *rlim);
  1057. asmlinkage long
  1058. sys32_old_getrlimit (unsigned int resource, struct rlimit32 *rlim)
  1059. {
  1060. mm_segment_t old_fs = get_fs();
  1061. struct rlimit r;
  1062. int ret;
  1063. set_fs(KERNEL_DS);
  1064. ret = sys_getrlimit(resource, &r);
  1065. set_fs(old_fs);
  1066. if (!ret) {
  1067. ret = put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
  1068. ret |= put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max);
  1069. }
  1070. return ret;
  1071. }
  1072. asmlinkage long
  1073. sys32_getrlimit (unsigned int resource, struct rlimit32 *rlim)
  1074. {
  1075. mm_segment_t old_fs = get_fs();
  1076. struct rlimit r;
  1077. int ret;
  1078. set_fs(KERNEL_DS);
  1079. ret = sys_getrlimit(resource, &r);
  1080. set_fs(old_fs);
  1081. if (!ret) {
  1082. if (r.rlim_cur >= 0xffffffff)
  1083. r.rlim_cur = 0xffffffff;
  1084. if (r.rlim_max >= 0xffffffff)
  1085. r.rlim_max = 0xffffffff;
  1086. ret = put_user(r.rlim_cur, &rlim->rlim_cur);
  1087. ret |= put_user(r.rlim_max, &rlim->rlim_max);
  1088. }
  1089. return ret;
  1090. }
  1091. extern asmlinkage long sys_setrlimit (unsigned int resource, struct rlimit *rlim);
  1092. asmlinkage long
  1093. sys32_setrlimit (unsigned int resource, struct rlimit32 *rlim)
  1094. {
  1095. struct rlimit r;
  1096. int ret;
  1097. mm_segment_t old_fs = get_fs();
  1098. if (resource >= RLIM_NLIMITS)
  1099. return -EINVAL;
  1100. if (get_user(r.rlim_cur, &rlim->rlim_cur) || get_user(r.rlim_max, &rlim->rlim_max))
  1101. return -EFAULT;
  1102. if (r.rlim_cur == RLIM_INFINITY32)
  1103. r.rlim_cur = RLIM_INFINITY;
  1104. if (r.rlim_max == RLIM_INFINITY32)
  1105. r.rlim_max = RLIM_INFINITY;
  1106. set_fs(KERNEL_DS);
  1107. ret = sys_setrlimit(resource, &r);
  1108. set_fs(old_fs);
  1109. return ret;
  1110. }
  1111. /*
  1112.  *  Declare the IA32 version of the msghdr
  1113.  */
  1114. struct msghdr32 {
  1115. unsigned int    msg_name; /* Socket name */
  1116. int msg_namelen; /* Length of name */
  1117. unsigned int    msg_iov; /* Data blocks */
  1118. unsigned int msg_iovlen; /* Number of blocks */
  1119. unsigned int    msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
  1120. unsigned int msg_controllen; /* Length of cmsg list */
  1121. unsigned msg_flags;
  1122. };
  1123. struct cmsghdr32 {
  1124. __kernel_size_t32 cmsg_len;
  1125. int               cmsg_level;
  1126. int               cmsg_type;
  1127. };
  1128. /* Bleech... */
  1129. #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
  1130. #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
  1131. #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
  1132. #define CMSG32_DATA(cmsg) 
  1133. ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
  1134. #define CMSG32_SPACE(len) 
  1135. (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
  1136. #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
  1137. #define __CMSG32_FIRSTHDR(ctl,len) 
  1138. ((len) >= sizeof(struct cmsghdr32) ? (struct cmsghdr32 *)(ctl) : (struct cmsghdr32 *)NULL)
  1139. #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
  1140. static inline struct cmsghdr32 *
  1141. __cmsg32_nxthdr (void *ctl, __kernel_size_t size, struct cmsghdr32 *cmsg, int cmsg_len)
  1142. {
  1143. struct cmsghdr32 * ptr;
  1144. ptr = (struct cmsghdr32 *)(((unsigned char *) cmsg) + CMSG32_ALIGN(cmsg_len));
  1145. if ((unsigned long)((char*)(ptr+1) - (char *) ctl) > size)
  1146. return NULL;
  1147. return ptr;
  1148. }
  1149. static inline struct cmsghdr32 *
  1150. cmsg32_nxthdr (struct msghdr *msg, struct cmsghdr32 *cmsg, int cmsg_len)
  1151. {
  1152. return __cmsg32_nxthdr(msg->msg_control, msg->msg_controllen, cmsg, cmsg_len);
  1153. }
  1154. static inline int
  1155. get_msghdr32 (struct msghdr *mp, struct msghdr32 *mp32)
  1156. {
  1157. int ret;
  1158. unsigned int i;
  1159. if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32)))
  1160. return -EFAULT;
  1161. ret = __get_user(i, &mp32->msg_name);
  1162. mp->msg_name = (void *)A(i);
  1163. ret |= __get_user(mp->msg_namelen, &mp32->msg_namelen);
  1164. ret |= __get_user(i, &mp32->msg_iov);
  1165. mp->msg_iov = (struct iovec *)A(i);
  1166. ret |= __get_user(mp->msg_iovlen, &mp32->msg_iovlen);
  1167. ret |= __get_user(i, &mp32->msg_control);
  1168. mp->msg_control = (void *)A(i);
  1169. ret |= __get_user(mp->msg_controllen, &mp32->msg_controllen);
  1170. ret |= __get_user(mp->msg_flags, &mp32->msg_flags);
  1171. return ret ? -EFAULT : 0;
  1172. }
  1173. /*
  1174.  * There is a lot of hair here because the alignment rules (and thus placement) of cmsg
  1175.  * headers and length are different for 32-bit apps.  -DaveM
  1176.  */
  1177. static int
  1178. get_cmsghdr32 (struct msghdr *kmsg, unsigned char *stackbuf, struct sock *sk, size_t *bufsize)
  1179. {
  1180. struct cmsghdr *kcmsg, *kcmsg_base;
  1181. __kernel_size_t kcmlen, tmp;
  1182. __kernel_size_t32 ucmlen;
  1183. struct cmsghdr32 *ucmsg;
  1184. long err;
  1185. kcmlen = 0;
  1186. kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
  1187. ucmsg = CMSG32_FIRSTHDR(kmsg);
  1188. while (ucmsg != NULL) {
  1189. if (get_user(ucmlen, &ucmsg->cmsg_len))
  1190. return -EFAULT;
  1191. /* Catch bogons. */
  1192. if (CMSG32_ALIGN(ucmlen) < CMSG32_ALIGN(sizeof(struct cmsghdr32)))
  1193. return -EINVAL;
  1194. if ((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control) + ucmlen)
  1195.     > kmsg->msg_controllen)
  1196. return -EINVAL;
  1197. tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
  1198.        CMSG_ALIGN(sizeof(struct cmsghdr)));
  1199. kcmlen += tmp;
  1200. ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
  1201. }
  1202. if (kcmlen == 0)
  1203. return -EINVAL;
  1204. /*
  1205.  * The kcmlen holds the 64-bit version of the control length.  It may not be
  1206.  * modified as we do not stick it into the kmsg until we have successfully copied
  1207.  * over all of the data from the user.
  1208.  */
  1209. if (kcmlen > *bufsize) {
  1210. *bufsize = kcmlen;
  1211. kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL);
  1212. }
  1213. if (kcmsg == NULL)
  1214. return -ENOBUFS;
  1215. /* Now copy them over neatly. */
  1216. memset(kcmsg, 0, kcmlen);
  1217. ucmsg = CMSG32_FIRSTHDR(kmsg);
  1218. while (ucmsg != NULL) {
  1219. err = get_user(ucmlen, &ucmsg->cmsg_len);
  1220. tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
  1221.        CMSG_ALIGN(sizeof(struct cmsghdr)));
  1222. kcmsg->cmsg_len = tmp;
  1223. err |= get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
  1224. err |= get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
  1225. /* Copy over the data. */
  1226. err |= copy_from_user(CMSG_DATA(kcmsg), CMSG32_DATA(ucmsg),
  1227.       (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))));
  1228. if (err)
  1229. goto out_free_efault;
  1230. /* Advance. */
  1231. kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
  1232. ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
  1233. }
  1234. /* Ok, looks like we made it.  Hook it up and return success. */
  1235. kmsg->msg_control = kcmsg_base;
  1236. kmsg->msg_controllen = kcmlen;
  1237. return 0;
  1238. out_free_efault:
  1239. if (kcmsg_base != (struct cmsghdr *)stackbuf)
  1240. sock_kfree_s(sk, kcmsg_base, kcmlen);
  1241. return -EFAULT;
  1242. }
  1243. /*
  1244.  * Verify & re-shape IA32 iovec. The caller must ensure that the
  1245.  *      iovec is big enough to hold the re-shaped message iovec.
  1246.  *
  1247.  * Save time not doing verify_area. copy_*_user will make this work
  1248.  * in any case.
  1249.  *
  1250.  * Don't need to check the total size for overflow (cf net/core/iovec.c),
  1251.  * 32-bit sizes can't overflow a 64-bit count.
  1252.  */
  1253. static inline int
  1254. verify_iovec32 (struct msghdr *m, struct iovec *iov, char *address, int mode)
  1255. {
  1256. int size, err, ct;
  1257. struct iovec32 *iov32;
  1258. if (m->msg_namelen) {
  1259. if (mode == VERIFY_READ) {
  1260. err = move_addr_to_kernel(m->msg_name, m->msg_namelen, address);
  1261. if (err < 0)
  1262. goto out;
  1263. }
  1264. m->msg_name = address;
  1265. } else
  1266. m->msg_name = NULL;
  1267. err = -EFAULT;
  1268. size = m->msg_iovlen * sizeof(struct iovec32);
  1269. if (copy_from_user(iov, m->msg_iov, size))
  1270. goto out;
  1271. m->msg_iov = iov;
  1272. err = 0;
  1273. iov32 = (struct iovec32 *)iov;
  1274. for (ct = m->msg_iovlen; ct-- > 0; ) {
  1275. iov[ct].iov_len = (__kernel_size_t)iov32[ct].iov_len;
  1276. iov[ct].iov_base = (void *) A(iov32[ct].iov_base);
  1277. err += iov[ct].iov_len;
  1278. }
  1279. out:
  1280. return err;
  1281. }
  1282. static void
  1283. put_cmsg32(struct msghdr *kmsg, int level, int type, int len, void *data)
  1284. {
  1285. struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
  1286. struct cmsghdr32 cmhdr;
  1287. int cmlen = CMSG32_LEN(len);
  1288. if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
  1289. kmsg->msg_flags |= MSG_CTRUNC;
  1290. return;
  1291. }
  1292. if(kmsg->msg_controllen < cmlen) {
  1293. kmsg->msg_flags |= MSG_CTRUNC;
  1294. cmlen = kmsg->msg_controllen;
  1295. }
  1296. cmhdr.cmsg_level = level;
  1297. cmhdr.cmsg_type = type;
  1298. cmhdr.cmsg_len = cmlen;
  1299. if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
  1300. return;
  1301. if(copy_to_user(CMSG32_DATA(cm), data,
  1302. cmlen - sizeof(struct cmsghdr32)))
  1303. return;
  1304. cmlen = CMSG32_SPACE(len);
  1305. kmsg->msg_control += cmlen;
  1306. kmsg->msg_controllen -= cmlen;
  1307. }
  1308. static void
  1309. scm_detach_fds32 (struct msghdr *kmsg, struct scm_cookie *scm)
  1310. {
  1311. struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
  1312. int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32))
  1313. / sizeof(int);
  1314. int fdnum = scm->fp->count;
  1315. struct file **fp = scm->fp->fp;
  1316. int *cmfptr;
  1317. int err = 0, i;
  1318. if (fdnum < fdmax)
  1319. fdmax = fdnum;
  1320. for (i = 0, cmfptr = (int *) CMSG32_DATA(cm);
  1321.      i < fdmax;
  1322.      i++, cmfptr++) {
  1323. int new_fd;
  1324. err = get_unused_fd();
  1325. if (err < 0)
  1326. break;
  1327. new_fd = err;
  1328. err = put_user(new_fd, cmfptr);
  1329. if (err) {
  1330. put_unused_fd(new_fd);
  1331. break;
  1332. }
  1333. /* Bump the usage count and install the file. */
  1334. get_file(fp[i]);
  1335. current->files->fd[new_fd] = fp[i];
  1336. }
  1337. if (i > 0) {
  1338. int cmlen = CMSG32_LEN(i * sizeof(int));
  1339. if (!err)
  1340. err = put_user(SOL_SOCKET, &cm->cmsg_level);
  1341. if (!err)
  1342. err = put_user(SCM_RIGHTS, &cm->cmsg_type);
  1343. if (!err)
  1344. err = put_user(cmlen, &cm->cmsg_len);
  1345. if (!err) {
  1346. cmlen = CMSG32_SPACE(i * sizeof(int));
  1347. kmsg->msg_control += cmlen;
  1348. kmsg->msg_controllen -= cmlen;
  1349. }
  1350. }
  1351. if (i < fdnum)
  1352. kmsg->msg_flags |= MSG_CTRUNC;
  1353. /*
  1354.  * All of the files that fit in the message have had their
  1355.  * usage counts incremented, so we just free the list.
  1356.  */
  1357. __scm_destroy(scm);
  1358. }
  1359. /*
  1360.  * In these cases we (currently) can just copy to data over verbatim because all CMSGs
  1361.  * created by the kernel have well defined types which have the same layout in both the
  1362.  * 32-bit and 64-bit API.  One must add some special cased conversions here if we start
  1363.  * sending control messages with incompatible types.
  1364.  *
  1365.  * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
  1366.  * we do our work.  The remaining cases are:
  1367.  *
  1368.  * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
  1369.  * IP_TTL int 32-bit clean
  1370.  * IP_TOS __u8 32-bit clean
  1371.  * IP_RECVOPTS variable length 32-bit clean
  1372.  * IP_RETOPTS variable length 32-bit clean
  1373.  * (these last two are clean because the types are defined
  1374.  *  by the IPv4 protocol)
  1375.  * IP_RECVERR struct sock_extended_err +
  1376.  * struct sockaddr_in 32-bit clean
  1377.  * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
  1378.  * struct sockaddr_in6 32-bit clean
  1379.  * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
  1380.  * IPV6_HOPLIMIT int 32-bit clean
  1381.  * IPV6_FLOWINFO u32 32-bit clean
  1382.  * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
  1383.  * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
  1384.  * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
  1385.  * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
  1386.  */
  1387. static void
  1388. cmsg32_recvmsg_fixup (struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
  1389. {
  1390. unsigned char *workbuf, *wp;
  1391. unsigned long bufsz, space_avail;
  1392. struct cmsghdr *ucmsg;
  1393. long err;
  1394. bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
  1395. space_avail = kmsg->msg_controllen + bufsz;
  1396. wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
  1397. if (workbuf == NULL)
  1398. goto fail;
  1399. /* To make this more sane we assume the kernel sends back properly
  1400.  * formatted control messages.  Because of how the kernel will truncate
  1401.  * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
  1402.  */
  1403. ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
  1404. while (((unsigned long)ucmsg) < ((unsigned long)kmsg->msg_control)) {
  1405. struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
  1406. int clen64, clen32;
  1407. /*
  1408.  * UCMSG is the 64-bit format CMSG entry in user-space.  KCMSG32 is within
  1409.  * the kernel space temporary buffer we use to convert into a 32-bit style
  1410.  * CMSG.
  1411.  */
  1412. err = get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
  1413. err |= get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
  1414. err |= get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
  1415. if (err)
  1416. goto fail2;
  1417. clen64 = kcmsg32->cmsg_len;
  1418. copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
  1419.        clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
  1420. clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
  1421.   CMSG32_ALIGN(sizeof(struct cmsghdr32)));
  1422. kcmsg32->cmsg_len = clen32;
  1423. ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
  1424. wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
  1425. }
  1426. /* Copy back fixed up data, and adjust pointers. */
  1427. bufsz = (wp - workbuf);
  1428. if (copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz))
  1429. goto fail2;
  1430. kmsg->msg_control = (struct cmsghdr *) (((char *)orig_cmsg_uptr) + bufsz);
  1431. kmsg->msg_controllen = space_avail - bufsz;
  1432. kfree(workbuf);
  1433. return;
  1434.   fail2:
  1435. kfree(workbuf);
  1436.   fail:
  1437. /*
  1438.  * If we leave the 64-bit format CMSG chunks in there, the application could get
  1439.  * confused and crash.  So to ensure greater recovery, we report no CMSGs.
  1440.  */
  1441. kmsg->msg_controllen += bufsz;
  1442. kmsg->msg_control = (void *) orig_cmsg_uptr;
  1443. }
  1444. static inline void
  1445. sockfd_put (struct socket *sock)
  1446. {
  1447. fput(sock->file);
  1448. }
  1449. /* XXX This really belongs in some header file... -DaveM */
  1450. #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
  1451.    16 for IP, 16 for IPX,
  1452.    24 for IPv6,
  1453.    about 80 for AX.25 */
  1454. extern struct socket *sockfd_lookup (int fd, int *err);
  1455. /*
  1456.  * BSD sendmsg interface
  1457.  */
  1458. int
  1459. sys32_sendmsg (int fd, struct msghdr32 *msg, unsigned flags)
  1460. {
  1461. struct socket *sock;
  1462. char address[MAX_SOCK_ADDR];
  1463. struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
  1464. unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */
  1465. unsigned char *ctl_buf = ctl;
  1466. struct msghdr msg_sys;
  1467. int err, iov_size, total_len;
  1468. size_t ctl_len;
  1469. err = -EFAULT;
  1470. if (get_msghdr32(&msg_sys, msg))
  1471. goto out;
  1472. sock = sockfd_lookup(fd, &err);
  1473. if (!sock)
  1474. goto out;
  1475. /* do not move before msg_sys is valid */
  1476. err = -EINVAL;
  1477. if (msg_sys.msg_iovlen > UIO_MAXIOV)
  1478. goto out_put;
  1479. /* Check whether to allocate the iovec area*/
  1480. err = -ENOMEM;
  1481. iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32);
  1482. if (msg_sys.msg_iovlen > UIO_FASTIOV) {
  1483. iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
  1484. if (!iov)
  1485. goto out_put;
  1486. }
  1487. /* This will also move the address data into kernel space */
  1488. err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
  1489. if (err < 0)
  1490. goto out_freeiov;
  1491. total_len = err;
  1492. err = -ENOBUFS;
  1493. if (msg_sys.msg_controllen > INT_MAX)
  1494. goto out_freeiov;
  1495. if (msg_sys.msg_controllen) {
  1496. ctl_len = sizeof(ctl);
  1497. err = get_cmsghdr32(&msg_sys, ctl_buf, sock->sk, &ctl_len);
  1498. if (err)
  1499. goto out_freeiov;
  1500. ctl_buf = msg_sys.msg_control;
  1501. }
  1502. msg_sys.msg_flags = flags;
  1503. if (sock->file->f_flags & O_NONBLOCK)
  1504. msg_sys.msg_flags |= MSG_DONTWAIT;
  1505. err = sock_sendmsg(sock, &msg_sys, total_len);
  1506. if (ctl_buf != ctl)
  1507. sock_kfree_s(sock->sk, ctl_buf, ctl_len);
  1508. out_freeiov:
  1509. if (iov != iovstack)
  1510. sock_kfree_s(sock->sk, iov, iov_size);
  1511. out_put:
  1512. sockfd_put(sock);
  1513. out:
  1514. return err;
  1515. }
  1516. /*
  1517.  * BSD recvmsg interface
  1518.  */
  1519. int
  1520. sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
  1521. {
  1522. struct socket *sock;
  1523. struct iovec iovstack[UIO_FASTIOV];
  1524. struct iovec *iov=iovstack;
  1525. struct msghdr msg_sys;
  1526. unsigned long cmsg_ptr;
  1527. int err, iov_size, total_len, len;
  1528. struct scm_cookie scm;
  1529. /* kernel mode address */
  1530. char addr[MAX_SOCK_ADDR];
  1531. /* user mode address pointers */
  1532. struct sockaddr *uaddr;
  1533. int *uaddr_len;
  1534. err = -EFAULT;
  1535. if (get_msghdr32(&msg_sys, msg))
  1536. goto out;
  1537. sock = sockfd_lookup(fd, &err);
  1538. if (!sock)
  1539. goto out;
  1540. err = -EINVAL;
  1541. if (msg_sys.msg_iovlen > UIO_MAXIOV)
  1542. goto out_put;
  1543. /* Check whether to allocate the iovec area*/
  1544. err = -ENOMEM;
  1545. iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
  1546. if (msg_sys.msg_iovlen > UIO_FASTIOV) {
  1547. iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
  1548. if (!iov)
  1549. goto out_put;
  1550. }
  1551. /*
  1552.  * Save the user-mode address (verify_iovec will change the
  1553.  * kernel msghdr to use the kernel address space)
  1554.  */
  1555. uaddr = msg_sys.msg_name;
  1556. uaddr_len = &msg->msg_namelen;
  1557. err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
  1558. if (err < 0)
  1559. goto out_freeiov;
  1560. total_len=err;
  1561. cmsg_ptr = (unsigned long)msg_sys.msg_control;
  1562. msg_sys.msg_flags = 0;
  1563. if (sock->file->f_flags & O_NONBLOCK)
  1564. flags |= MSG_DONTWAIT;
  1565. memset(&scm, 0, sizeof(scm));
  1566. lock_kernel();
  1567. {
  1568. err = sock->ops->recvmsg(sock, &msg_sys, total_len, flags, &scm);
  1569. if (err < 0)
  1570. goto out_unlock_freeiov;
  1571. len = err;
  1572. if (!msg_sys.msg_control) {
  1573. if (sock->passcred || scm.fp)
  1574. msg_sys.msg_flags |= MSG_CTRUNC;
  1575. if (scm.fp)
  1576. __scm_destroy(&scm);
  1577. } else {
  1578. /*
  1579.  * If recvmsg processing itself placed some control messages into
  1580.  * user space, it's is using 64-bit CMSG processing, so we need to
  1581.  * fix it up before we tack on more stuff.
  1582.  */
  1583. if ((unsigned long) msg_sys.msg_control != cmsg_ptr)
  1584. cmsg32_recvmsg_fixup(&msg_sys, cmsg_ptr);
  1585. /* Wheee... */
  1586. if (sock->passcred)
  1587. put_cmsg32(&msg_sys, SOL_SOCKET, SCM_CREDENTIALS,
  1588.    sizeof(scm.creds), &scm.creds);
  1589. if (scm.fp != NULL)
  1590. scm_detach_fds32(&msg_sys, &scm);
  1591. }
  1592. }
  1593. unlock_kernel();
  1594. if (uaddr != NULL) {
  1595. err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
  1596. if (err < 0)
  1597. goto out_freeiov;
  1598. }
  1599. err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
  1600. if (err)
  1601. goto out_freeiov;
  1602. err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
  1603.  &msg->msg_controllen);
  1604. if (err)
  1605. goto out_freeiov;
  1606. err = len;
  1607.   out_freeiov:
  1608. if (iov != iovstack)
  1609. sock_kfree_s(sock->sk, iov, iov_size);
  1610.   out_put:
  1611. sockfd_put(sock);
  1612.   out:
  1613. return err;
  1614.   out_unlock_freeiov:
  1615. goto out_freeiov;
  1616. }
  1617. /* Argument list sizes for sys_socketcall */
  1618. #define AL(x) ((x) * sizeof(u32))
  1619. static const unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
  1620.     AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
  1621.     AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
  1622. #undef AL
  1623. extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
  1624. extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,
  1625.   int addrlen);
  1626. extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,
  1627.  int *upeer_addrlen);
  1628. extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
  1629.       int *usockaddr_len);
  1630. extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
  1631.       int *usockaddr_len);
  1632. extern asmlinkage long sys_send(int fd, void *buff, size_t len, unsigned flags);
  1633. extern asmlinkage long sys_sendto(int fd, u32 buff, __kernel_size_t32 len,
  1634.    unsigned flags, u32 addr, int addr_len);
  1635. extern asmlinkage long sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
  1636. extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
  1637.      unsigned flags, u32 addr, u32 addr_len);
  1638. extern asmlinkage long sys_setsockopt(int fd, int level, int optname,
  1639.      char *optval, int optlen);
  1640. extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
  1641.        u32 optval, u32 optlen);
  1642. extern asmlinkage long sys_socket(int family, int type, int protocol);
  1643. extern asmlinkage long sys_socketpair(int family, int type, int protocol,
  1644.      int usockvec[2]);
  1645. extern asmlinkage long sys_shutdown(int fd, int how);
  1646. extern asmlinkage long sys_listen(int fd, int backlog);
  1647. asmlinkage long
  1648. sys32_socketcall (int call, u32 *args)
  1649. {
  1650. int ret;
  1651. u32 a[6];
  1652. u32 a0,a1;
  1653. if (call<SYS_SOCKET||call>SYS_RECVMSG)
  1654. return -EINVAL;
  1655. if (copy_from_user(a, args, nas[call]))
  1656. return -EFAULT;
  1657. a0=a[0];
  1658. a1=a[1];
  1659. switch(call)
  1660. {
  1661. case SYS_SOCKET:
  1662. ret = sys_socket(a0, a1, a[2]);
  1663. break;
  1664. case SYS_BIND:
  1665. ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
  1666. break;
  1667. case SYS_CONNECT:
  1668. ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
  1669. break;
  1670. case SYS_LISTEN:
  1671. ret = sys_listen(a0, a1);
  1672. break;
  1673. case SYS_ACCEPT:
  1674. ret = sys_accept(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
  1675. break;
  1676. case SYS_GETSOCKNAME:
  1677. ret = sys_getsockname(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
  1678. break;
  1679. case SYS_GETPEERNAME:
  1680. ret = sys_getpeername(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
  1681. break;
  1682. case SYS_SOCKETPAIR:
  1683. ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
  1684. break;
  1685. case SYS_SEND:
  1686. ret = sys_send(a0, (void *)A(a1), a[2], a[3]);
  1687. break;
  1688. case SYS_SENDTO:
  1689. ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);
  1690. break;
  1691. case SYS_RECV:
  1692. ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);
  1693. break;
  1694. case SYS_RECVFROM:
  1695. ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
  1696. break;
  1697. case SYS_SHUTDOWN:
  1698. ret = sys_shutdown(a0,a1);
  1699. break;
  1700. case SYS_SETSOCKOPT:
  1701. ret = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
  1702.       a[4]);
  1703. break;
  1704. case SYS_GETSOCKOPT:
  1705. ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);
  1706. break;
  1707. case SYS_SENDMSG:
  1708. ret = sys32_sendmsg(a0, (struct msghdr32 *) A(a1), a[2]);
  1709. break;
  1710. case SYS_RECVMSG:
  1711. ret = sys32_recvmsg(a0, (struct msghdr32 *) A(a1), a[2]);
  1712. break;
  1713. default:
  1714. ret = EINVAL;
  1715. break;
  1716. }
  1717. return ret;
  1718. }
  1719. /*
  1720.  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
  1721.  *
  1722.  * This is really horribly ugly.
  1723.  */
  1724. struct msgbuf32 { s32 mtype; char mtext[1]; };
  1725. struct ipc_perm32 {
  1726. key_t key;
  1727. __kernel_uid_t32 uid;
  1728. __kernel_gid_t32 gid;
  1729. __kernel_uid_t32 cuid;
  1730. __kernel_gid_t32 cgid;
  1731. __kernel_mode_t32 mode;
  1732. unsigned short seq;
  1733. };
  1734. struct ipc64_perm32 {
  1735. key_t key;
  1736. __kernel_uid32_t32 uid;
  1737. __kernel_gid32_t32 gid;
  1738. __kernel_uid32_t32 cuid;
  1739. __kernel_gid32_t32 cgid;
  1740. __kernel_mode_t32 mode;
  1741. unsigned short __pad1;
  1742. unsigned short seq;
  1743. unsigned short __pad2;
  1744. unsigned int unused1;
  1745. unsigned int unused2;
  1746. };
  1747. struct semid_ds32 {
  1748. struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
  1749. __kernel_time_t32 sem_otime;              /* last semop time */
  1750. __kernel_time_t32 sem_ctime;              /* last change time */
  1751. u32 sem_base;              /* ptr to first semaphore in array */
  1752. u32 sem_pending;          /* pending operations to be processed */
  1753. u32 sem_pending_last;    /* last pending operation */
  1754. u32 undo;                  /* undo requests on this array */
  1755. unsigned short  sem_nsems;              /* no. of semaphores in array */
  1756. };
  1757. struct semid64_ds32 {
  1758. struct ipc64_perm32 sem_perm;
  1759. __kernel_time_t32 sem_otime;
  1760. unsigned int __unused1;
  1761. __kernel_time_t32 sem_ctime;
  1762. unsigned int __unused2;
  1763. unsigned int sem_nsems;
  1764. unsigned int __unused3;
  1765. unsigned int __unused4;
  1766. };
  1767. struct msqid_ds32 {
  1768. struct ipc_perm32 msg_perm;
  1769. u32 msg_first;
  1770. u32 msg_last;
  1771. __kernel_time_t32 msg_stime;
  1772. __kernel_time_t32 msg_rtime;
  1773. __kernel_time_t32 msg_ctime;
  1774. u32 wwait;
  1775. u32 rwait;
  1776. unsigned short msg_cbytes;
  1777. unsigned short msg_qnum;
  1778. unsigned short msg_qbytes;
  1779. __kernel_ipc_pid_t32 msg_lspid;
  1780. __kernel_ipc_pid_t32 msg_lrpid;
  1781. };
  1782. struct msqid64_ds32 {
  1783. struct ipc64_perm32 msg_perm;
  1784. __kernel_time_t32 msg_stime;
  1785. unsigned int __unused1;
  1786. __kernel_time_t32 msg_rtime;
  1787. unsigned int __unused2;
  1788. __kernel_time_t32 msg_ctime;
  1789. unsigned int __unused3;
  1790. unsigned int msg_cbytes;
  1791. unsigned int msg_qnum;
  1792. unsigned int msg_qbytes;
  1793. __kernel_pid_t32 msg_lspid;
  1794. __kernel_pid_t32 msg_lrpid;
  1795. unsigned int __unused4;
  1796. unsigned int __unused5;
  1797. };
  1798. struct shmid_ds32 {
  1799. struct ipc_perm32 shm_perm;
  1800. int shm_segsz;
  1801. __kernel_time_t32 shm_atime;
  1802. __kernel_time_t32 shm_dtime;
  1803. __kernel_time_t32 shm_ctime;
  1804. __kernel_ipc_pid_t32 shm_cpid;
  1805. __kernel_ipc_pid_t32 shm_lpid;
  1806. unsigned short shm_nattch;
  1807. };
  1808. struct shmid64_ds32 {
  1809. struct ipc64_perm shm_perm;
  1810. __kernel_size_t32 shm_segsz;
  1811. __kernel_time_t32 shm_atime;
  1812. unsigned int __unused1;
  1813. __kernel_time_t32 shm_dtime;
  1814. unsigned int __unused2;
  1815. __kernel_time_t32 shm_ctime;
  1816. unsigned int __unused3;
  1817. __kernel_pid_t32 shm_cpid;
  1818. __kernel_pid_t32 shm_lpid;
  1819. unsigned int shm_nattch;
  1820. unsigned int __unused4;
  1821. unsigned int __unused5;
  1822. };
  1823. struct shminfo64_32 {
  1824. unsigned int shmmax;
  1825. unsigned int shmmin;
  1826. unsigned int shmmni;
  1827. unsigned int shmseg;
  1828. unsigned int shmall;
  1829. unsigned int __unused1;
  1830. unsigned int __unused2;
  1831. unsigned int __unused3;
  1832. unsigned int __unused4;
  1833. };
  1834. struct shm_info32 {
  1835. int used_ids;
  1836. u32 shm_tot, shm_rss, shm_swp;
  1837. u32 swap_attempts, swap_successes;
  1838. };
  1839. struct ipc_kludge {
  1840. struct msgbuf *msgp;
  1841. long msgtyp;
  1842. };
  1843. #define SEMOP  1
  1844. #define SEMGET  2
  1845. #define SEMCTL  3
  1846. #define MSGSND 11
  1847. #define MSGRCV 12
  1848. #define MSGGET 13
  1849. #define MSGCTL 14
  1850. #define SHMAT 21
  1851. #define SHMDT 22
  1852. #define SHMGET 23
  1853. #define SHMCTL 24
  1854. #define IPCOP_MASK(__x) (1UL << (__x))
  1855. static int
  1856. ipc_parse_version32 (int *cmd)
  1857. {
  1858. if (*cmd & IPC_64) {
  1859. *cmd ^= IPC_64;
  1860. return IPC_64;
  1861. } else {
  1862. return IPC_OLD;
  1863. }
  1864. }
  1865. static int
  1866. semctl32 (int first, int second, int third, void *uptr)
  1867. {
  1868. union semun fourth;
  1869. u32 pad;
  1870. int err = 0, err2;
  1871. struct semid64_ds s;
  1872. mm_segment_t old_fs;
  1873. int version = ipc_parse_version32(&third);
  1874. if (!uptr)
  1875. return -EINVAL;
  1876. if (get_user(pad, (u32 *)uptr))
  1877. return -EFAULT;
  1878. if (third == SETVAL)
  1879. fourth.val = (int)pad;
  1880. else
  1881. fourth.__pad = (void *)A(pad);
  1882. switch (third) {
  1883.       case IPC_INFO:
  1884.       case IPC_RMID:
  1885.       case IPC_SET:
  1886.       case SEM_INFO:
  1887.       case GETVAL:
  1888.       case GETPID:
  1889.       case GETNCNT:
  1890.       case GETZCNT:
  1891.       case GETALL:
  1892.       case SETVAL:
  1893.       case SETALL:
  1894. err = sys_semctl(first, second, third, fourth);
  1895. break;
  1896.       case IPC_STAT:
  1897.       case SEM_STAT:
  1898. fourth.__pad = &s;
  1899. old_fs = get_fs();
  1900. set_fs(KERNEL_DS);
  1901. err = sys_semctl(first, second, third, fourth);
  1902. set_fs(old_fs);
  1903. if (version == IPC_64) {
  1904. struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad);
  1905. if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
  1906. err = -EFAULT;
  1907. break;
  1908. }
  1909. err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
  1910. err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
  1911. err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
  1912. err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
  1913. err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
  1914. err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
  1915. err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
  1916. err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
  1917. err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
  1918. err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
  1919. } else {
  1920. struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad);
  1921. if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
  1922. err = -EFAULT;
  1923. break;
  1924. }
  1925. err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
  1926. err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
  1927. err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
  1928. err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
  1929. err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
  1930. err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
  1931. err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
  1932. err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
  1933. err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
  1934. err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
  1935. }
  1936. if (err2)
  1937.     err = -EFAULT;
  1938. break;
  1939. }
  1940. return err;
  1941. }
  1942. static int
  1943. do_sys32_msgsnd (int first, int second, int third, void *uptr)
  1944. {
  1945. struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
  1946. struct msgbuf32 *up = (struct msgbuf32 *)uptr;
  1947. mm_segment_t old_fs;
  1948. int err;
  1949. if (!p)
  1950. return -ENOMEM;
  1951. err = get_user(p->mtype, &up->mtype);
  1952. err |= copy_from_user(p->mtext, &up->mtext, second);
  1953. if (err)
  1954. goto out;
  1955. old_fs = get_fs();
  1956. set_fs(KERNEL_DS);
  1957. err = sys_msgsnd(first, p, second, third);
  1958. set_fs(old_fs);
  1959.   out:
  1960. kfree(p);
  1961. return err;
  1962. }
  1963. static int
  1964. do_sys32_msgrcv (int first, int second, int msgtyp, int third, int version, void *uptr)
  1965. {
  1966. struct msgbuf32 *up;
  1967. struct msgbuf *p;
  1968. mm_segment_t old_fs;
  1969. int err;
  1970. if (!version) {
  1971. struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
  1972. struct ipc_kludge ipck;
  1973. err = -EINVAL;
  1974. if (!uptr)
  1975. goto out;
  1976. err = -EFAULT;
  1977. if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge)))
  1978. goto out;
  1979. uptr = (void *)A(ipck.msgp);
  1980. msgtyp = ipck.msgtyp;
  1981. }
  1982. err = -ENOMEM;
  1983. p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
  1984. if (!p)
  1985. goto out;
  1986. old_fs = get_fs();
  1987. set_fs(KERNEL_DS);
  1988. err = sys_msgrcv(first, p, second + 4, msgtyp, third);
  1989. set_fs(old_fs);
  1990. if (err < 0)
  1991. goto free_then_out;
  1992. up = (struct msgbuf32 *)uptr;
  1993. if (put_user(p->mtype, &up->mtype) || copy_to_user(&up->mtext, p->mtext, err))
  1994. err = -EFAULT;
  1995. free_then_out:
  1996. kfree(p);
  1997. out:
  1998. return err;
  1999. }
  2000. static int
  2001. msgctl32 (int first, int second, void *uptr)
  2002. {
  2003. int err = -EINVAL, err2;
  2004. struct msqid_ds m;
  2005. struct msqid64_ds m64;
  2006. struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
  2007. struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
  2008. mm_segment_t old_fs;
  2009. int version = ipc_parse_version32(&second);
  2010. switch (second) {
  2011.       case IPC_INFO:
  2012.       case IPC_RMID:
  2013.       case MSG_INFO:
  2014. err = sys_msgctl(first, second, (struct msqid_ds *)uptr);
  2015. break;
  2016.       case IPC_SET:
  2017. if (version == IPC_64) {
  2018. err = get_user(m.msg_perm.uid, &up64->msg_perm.uid);
  2019. err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid);
  2020. err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode);
  2021. err |= get_user(m.msg_qbytes, &up64->msg_qbytes);
  2022. } else {
  2023. err = get_user(m.msg_perm.uid, &up32->msg_perm.uid);
  2024. err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid);
  2025. err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode);
  2026. err |= get_user(m.msg_qbytes, &up32->msg_qbytes);
  2027. }
  2028. if (err)
  2029. break;
  2030. old_fs = get_fs();
  2031. set_fs(KERNEL_DS);
  2032. err = sys_msgctl(first, second, &m);
  2033. set_fs(old_fs);
  2034. break;
  2035.       case IPC_STAT:
  2036.       case MSG_STAT:
  2037. old_fs = get_fs();
  2038. set_fs(KERNEL_DS);
  2039. err = sys_msgctl(first, second, (void *) &m64);
  2040. set_fs(old_fs);
  2041. if (version == IPC_64) {
  2042. if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
  2043. err = -EFAULT;
  2044. break;
  2045. }
  2046. err2 = __put_user(m64.msg_perm.key, &up64->msg_perm.key);
  2047. err2 |= __put_user(m64.msg_perm.uid, &up64->msg_perm.uid);
  2048. err2 |= __put_user(m64.msg_perm.gid, &up64->msg_perm.gid);
  2049. err2 |= __put_user(m64.msg_perm.cuid, &up64->msg_perm.cuid);
  2050. err2 |= __put_user(m64.msg_perm.cgid, &up64->msg_perm.cgid);
  2051. err2 |= __put_user(m64.msg_perm.mode, &up64->msg_perm.mode);
  2052. err2 |= __put_user(m64.msg_perm.seq, &up64->msg_perm.seq);
  2053. err2 |= __put_user(m64.msg_stime, &up64->msg_stime);
  2054. err2 |= __put_user(m64.msg_rtime, &up64->msg_rtime);
  2055. err2 |= __put_user(m64.msg_ctime, &up64->msg_ctime);
  2056. err2 |= __put_user(m64.msg_cbytes, &up64->msg_cbytes);
  2057. err2 |= __put_user(m64.msg_qnum, &up64->msg_qnum);
  2058. err2 |= __put_user(m64.msg_qbytes, &up64->msg_qbytes);
  2059. err2 |= __put_user(m64.msg_lspid, &up64->msg_lspid);
  2060. err2 |= __put_user(m64.msg_lrpid, &up64->msg_lrpid);
  2061. if (err2)
  2062. err = -EFAULT;
  2063. } else {
  2064. if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
  2065. err = -EFAULT;
  2066. break;
  2067. }
  2068. err2 = __put_user(m64.msg_perm.key, &up32->msg_perm.key);
  2069. err2 |= __put_user(m64.msg_perm.uid, &up32->msg_perm.uid);
  2070. err2 |= __put_user(m64.msg_perm.gid, &up32->msg_perm.gid);
  2071. err2 |= __put_user(m64.msg_perm.cuid, &up32->msg_perm.cuid);
  2072. err2 |= __put_user(m64.msg_perm.cgid, &up32->msg_perm.cgid);
  2073. err2 |= __put_user(m64.msg_perm.mode, &up32->msg_perm.mode);
  2074. err2 |= __put_user(m64.msg_perm.seq, &up32->msg_perm.seq);
  2075. err2 |= __put_user(m64.msg_stime, &up32->msg_stime);
  2076. err2 |= __put_user(m64.msg_rtime, &up32->msg_rtime);
  2077. err2 |= __put_user(m64.msg_ctime, &up32->msg_ctime);
  2078. err2 |= __put_user(m64.msg_cbytes, &up32->msg_cbytes);
  2079. err2 |= __put_user(m64.msg_qnum, &up32->msg_qnum);
  2080. err2 |= __put_user(m64.msg_qbytes, &up32->msg_qbytes);
  2081. err2 |= __put_user(m64.msg_lspid, &up32->msg_lspid);
  2082. err2 |= __put_user(m64.msg_lrpid, &up32->msg_lrpid);
  2083. if (err2)
  2084. err = -EFAULT;
  2085. }
  2086. break;
  2087. }
  2088. return err;
  2089. }
  2090. static int
  2091. shmat32 (int first, int second, int third, int version, void *uptr)
  2092. {
  2093. unsigned long raddr;
  2094. u32 *uaddr = (u32 *)A((u32)third);
  2095. int err;
  2096. if (version == 1)
  2097. return -EINVAL; /* iBCS2 emulator entry point: unsupported */
  2098. err = sys_shmat(first, uptr, second, &raddr);
  2099. if (err)
  2100. return err;
  2101. return put_user(raddr, uaddr);
  2102. }
  2103. static int
  2104. shmctl32 (int first, int second, void *uptr)
  2105. {
  2106. int err = -EFAULT, err2;
  2107. struct shmid_ds s;
  2108. struct shmid64_ds s64;
  2109. struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
  2110. struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
  2111. mm_segment_t old_fs;
  2112. struct shm_info32 *uip = (struct shm_info32 *)uptr;
  2113. struct shm_info si;
  2114. int version = ipc_parse_version32(&second);
  2115. struct shminfo64 smi;
  2116. struct shminfo *usi32 = (struct shminfo *) uptr;
  2117. struct shminfo64_32 *usi64 = (struct shminfo64_32 *) uptr;
  2118. switch (second) {
  2119.       case IPC_INFO:
  2120. old_fs = get_fs();
  2121. set_fs(KERNEL_DS);
  2122. err = sys_shmctl(first, second, (struct shmid_ds *)&smi);
  2123. set_fs(old_fs);
  2124. if (version == IPC_64) {
  2125. if (!access_ok(VERIFY_WRITE, usi64, sizeof(*usi64))) {
  2126. err = -EFAULT;
  2127. break;
  2128. }
  2129. err2 = __put_user(smi.shmmax, &usi64->shmmax);
  2130. err2 |= __put_user(smi.shmmin, &usi64->shmmin);
  2131. err2 |= __put_user(smi.shmmni, &usi64->shmmni);
  2132. err2 |= __put_user(smi.shmseg, &usi64->shmseg);
  2133. err2 |= __put_user(smi.shmall, &usi64->shmall);
  2134. } else {
  2135. if (!access_ok(VERIFY_WRITE, usi32, sizeof(*usi32))) {
  2136. err = -EFAULT;
  2137. break;
  2138. }
  2139. err2 = __put_user(smi.shmmax, &usi32->shmmax);
  2140. err2 |= __put_user(smi.shmmin, &usi32->shmmin);
  2141. err2 |= __put_user(smi.shmmni, &usi32->shmmni);
  2142. err2 |= __put_user(smi.shmseg, &usi32->shmseg);
  2143. err2 |= __put_user(smi.shmall, &usi32->shmall);
  2144. }
  2145. if (err2)
  2146. err = -EFAULT;
  2147. break;
  2148.       case IPC_RMID:
  2149.       case SHM_LOCK:
  2150.       case SHM_UNLOCK:
  2151. err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
  2152. break;
  2153.       case IPC_SET:
  2154. if (version == IPC_64) {
  2155. err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
  2156. err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
  2157. err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
  2158. } else {
  2159. err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
  2160. err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
  2161. err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
  2162. }
  2163. if (err)
  2164. break;
  2165. old_fs = get_fs();
  2166. set_fs(KERNEL_DS);
  2167. err = sys_shmctl(first, second, &s);
  2168. set_fs(old_fs);
  2169. break;
  2170.       case IPC_STAT:
  2171.       case SHM_STAT:
  2172. old_fs = get_fs();
  2173. set_fs(KERNEL_DS);
  2174. err = sys_shmctl(first, second, (void *) &s64);
  2175. set_fs(old_fs);
  2176. if (err < 0)
  2177. break;
  2178. if (version == IPC_64) {
  2179. if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
  2180. err = -EFAULT;
  2181. break;
  2182. }
  2183. err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
  2184. err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
  2185. err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
  2186. err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
  2187. err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
  2188. err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
  2189. err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
  2190. err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
  2191. err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
  2192. err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
  2193. err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
  2194. err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
  2195. err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
  2196. err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
  2197. } else {
  2198. if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
  2199. err = -EFAULT;
  2200. break;
  2201. }
  2202. err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
  2203. err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
  2204. err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
  2205. err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
  2206. err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
  2207. err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
  2208. err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
  2209. err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
  2210. err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
  2211. err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
  2212. err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
  2213. err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
  2214. err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
  2215. err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
  2216. }
  2217. if (err2)
  2218. err = -EFAULT;
  2219. break;
  2220.       case SHM_INFO:
  2221. old_fs = get_fs();
  2222. set_fs(KERNEL_DS);
  2223. err = sys_shmctl(first, second, (void *)&si);
  2224. set_fs(old_fs);
  2225. if (err < 0)
  2226. break;
  2227. if (!access_ok(VERIFY_WRITE, uip, sizeof(*uip))) {
  2228. err = -EFAULT;
  2229. break;
  2230. }
  2231. err2 = __put_user(si.used_ids, &uip->used_ids);
  2232. err2 |= __put_user(si.shm_tot, &uip->shm_tot);
  2233. err2 |= __put_user(si.shm_rss, &uip->shm_rss);
  2234. err2 |= __put_user(si.shm_swp, &uip->shm_swp);
  2235. err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
  2236. err2 |= __put_user(si.swap_successes, &uip->swap_successes);
  2237. if (err2)
  2238. err = -EFAULT;
  2239. break;
  2240. }
  2241. return err;
  2242. }
  2243. asmlinkage long
  2244. sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
  2245. {
  2246. int version;
  2247. version = call >> 16; /* hack for backward compatibility */
  2248. call &= 0xffff;
  2249. switch (call) {
  2250.       case SEMOP:
  2251. /* struct sembuf is the same on 32 and 64bit :)) */
  2252. return sys_semop(first, (struct sembuf *)AA(ptr), second);
  2253.       case SEMGET:
  2254. return sys_semget(first, second, third);
  2255.       case SEMCTL:
  2256. return semctl32(first, second, third, (void *)AA(ptr));
  2257.       case MSGSND:
  2258. return do_sys32_msgsnd(first, second, third, (void *)AA(ptr));
  2259.       case MSGRCV:
  2260. return do_sys32_msgrcv(first, second, fifth, third, version, (void *)AA(ptr));
  2261.       case MSGGET:
  2262. return sys_msgget((key_t) first, second);
  2263.       case MSGCTL:
  2264. return msgctl32(first, second, (void *)AA(ptr));
  2265.       case SHMAT:
  2266. return shmat32(first, second, third, version, (void *)AA(ptr));
  2267. break;
  2268.       case SHMDT:
  2269. return sys_shmdt((char *)AA(ptr));
  2270.       case SHMGET:
  2271. return sys_shmget(first, second, third);
  2272.       case SHMCTL:
  2273. return shmctl32(first, second, (void *)AA(ptr));
  2274.       default:
  2275. return -EINVAL;
  2276. }
  2277. return -EINVAL;
  2278. }
  2279. /*
  2280.  * sys_time() can be implemented in user-level using
  2281.  * sys_gettimeofday().  IA64 did this but i386 Linux did not
  2282.  * so we have to implement this system call here.
  2283.  */
  2284. asmlinkage long
  2285. sys32_time (int *tloc)
  2286. {
  2287. int i;
  2288. /* SMP: This is fairly trivial. We grab CURRENT_TIME and
  2289.    stuff it to user space. No side effects */
  2290. i = CURRENT_TIME;
  2291. if (tloc) {
  2292. if (put_user(i, tloc))
  2293. i = -EFAULT;
  2294. }
  2295. return i;
  2296. }
  2297. struct rusage32 {
  2298. struct timeval32 ru_utime;
  2299. struct timeval32 ru_stime;
  2300. int    ru_maxrss;
  2301. int    ru_ixrss;
  2302. int    ru_idrss;
  2303. int    ru_isrss;
  2304. int    ru_minflt;
  2305. int    ru_majflt;
  2306. int    ru_nswap;
  2307. int    ru_inblock;
  2308. int    ru_oublock;
  2309. int    ru_msgsnd;
  2310. int    ru_msgrcv;
  2311. int    ru_nsignals;
  2312. int    ru_nvcsw;
  2313. int    ru_nivcsw;
  2314. };
  2315. static int
  2316. put_rusage (struct rusage32 *ru, struct rusage *r)
  2317. {
  2318. int err;
  2319. if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)))
  2320. return -EFAULT;
  2321. err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
  2322. err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
  2323. err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
  2324. err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
  2325. err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
  2326. err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
  2327. err |= __put_user (r->ru_idrss, &ru->ru_idrss);
  2328. err |= __put_user (r->ru_isrss, &ru->ru_isrss);
  2329. err |= __put_user (r->ru_minflt, &ru->ru_minflt);
  2330. err |= __put_user (r->ru_majflt, &ru->ru_majflt);
  2331. err |= __put_user (r->ru_nswap, &ru->ru_nswap);
  2332. err |= __put_user (r->ru_inblock, &ru->ru_inblock);
  2333. err |= __put_user (r->ru_oublock, &ru->ru_oublock);
  2334. err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
  2335. err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
  2336. err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
  2337. err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
  2338. err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
  2339. return err;
  2340. }
  2341. asmlinkage long
  2342. sys32_wait4 (int pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
  2343. {
  2344. if (!ru)
  2345. return sys_wait4(pid, stat_addr, options, NULL);
  2346. else {
  2347. struct rusage r;
  2348. int ret;
  2349. unsigned int status;
  2350. mm_segment_t old_fs = get_fs();
  2351. set_fs(KERNEL_DS);
  2352. ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
  2353. set_fs(old_fs);
  2354. if (put_rusage(ru, &r))
  2355. return -EFAULT;
  2356. if (stat_addr && put_user(status, stat_addr))
  2357. return -EFAULT;
  2358. return ret;
  2359. }
  2360. }
  2361. asmlinkage long
  2362. sys32_waitpid (int pid, unsigned int *stat_addr, int options)
  2363. {
  2364. return sys32_wait4(pid, stat_addr, options, NULL);
  2365. }
  2366. extern asmlinkage long sys_getrusage (int who, struct rusage *ru);
  2367. asmlinkage long
  2368. sys32_getrusage (int who, struct rusage32 *ru)
  2369. {
  2370. struct rusage r;
  2371. int ret;
  2372. mm_segment_t old_fs = get_fs();
  2373. set_fs(KERNEL_DS);
  2374. ret = sys_getrusage(who, &r);
  2375. set_fs(old_fs);
  2376. if (put_rusage (ru, &r))
  2377. return -EFAULT;
  2378. return ret;
  2379. }
  2380. struct tms32 {
  2381. __kernel_clock_t32 tms_utime;
  2382. __kernel_clock_t32 tms_stime;
  2383. __kernel_clock_t32 tms_cutime;
  2384. __kernel_clock_t32 tms_cstime;
  2385. };
  2386. extern asmlinkage long sys_times (struct tms * tbuf);
  2387. asmlinkage long
  2388. sys32_times (struct tms32 *tbuf)
  2389. {
  2390. mm_segment_t old_fs = get_fs();
  2391. struct tms t;
  2392. long ret;
  2393. int err;
  2394. set_fs(KERNEL_DS);
  2395. ret = sys_times(tbuf ? &t : NULL);
  2396. set_fs(old_fs);
  2397. if (tbuf) {
  2398. err = put_user (IA32_TICK(t.tms_utime), &tbuf->tms_utime);
  2399. err |= put_user (IA32_TICK(t.tms_stime), &tbuf->tms_stime);
  2400. err |= put_user (IA32_TICK(t.tms_cutime), &tbuf->tms_cutime);
  2401. err |= put_user (IA32_TICK(t.tms_cstime), &tbuf->tms_cstime);
  2402. if (err)
  2403. ret = -EFAULT;
  2404. }
  2405. return IA32_TICK(ret);
  2406. }
  2407. static unsigned int
  2408. ia32_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int *val)
  2409. {
  2410. size_t copied;
  2411. unsigned int ret;
  2412. copied = access_process_vm(child, addr, val, sizeof(*val), 0);
  2413. return (copied != sizeof(ret)) ? -EIO : 0;
  2414. }
  2415. static unsigned int
  2416. ia32_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int val)
  2417. {
  2418. if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
  2419. return -EIO;
  2420. return 0;
  2421. }
  2422. /*
  2423.  *  The order in which registers are stored in the ptrace regs structure
  2424.  */
  2425. #define PT_EBX 0
  2426. #define PT_ECX 1
  2427. #define PT_EDX 2
  2428. #define PT_ESI 3
  2429. #define PT_EDI 4
  2430. #define PT_EBP 5
  2431. #define PT_EAX 6
  2432. #define PT_DS 7
  2433. #define PT_ES 8
  2434. #define PT_FS 9
  2435. #define PT_GS 10
  2436. #define PT_ORIG_EAX 11
  2437. #define PT_EIP 12
  2438. #define PT_CS 13
  2439. #define PT_EFL 14
  2440. #define PT_UESP 15
  2441. #define PT_SS 16
  2442. static unsigned int
  2443. getreg (struct task_struct *child, int regno)
  2444. {
  2445. struct pt_regs *child_regs;
  2446. child_regs = ia64_task_regs(child);
  2447. switch (regno / sizeof(int)) {
  2448.       case PT_EBX: return child_regs->r11;
  2449.       case PT_ECX: return child_regs->r9;
  2450.       case PT_EDX: return child_regs->r10;
  2451.       case PT_ESI: return child_regs->r14;
  2452.       case PT_EDI: return child_regs->r15;
  2453.       case PT_EBP: return child_regs->r13;
  2454.       case PT_EAX: return child_regs->r8;
  2455.       case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */
  2456.       case PT_EIP: return child_regs->cr_iip;
  2457.       case PT_UESP: return child_regs->r12;
  2458.       case PT_EFL: return child->thread.eflag;
  2459.       case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
  2460. return __USER_DS;
  2461.       case PT_CS: return __USER_CS;
  2462.       default:
  2463. printk(KERN_ERR "ia32.getreg(): unknown register %dn", regno);
  2464. break;
  2465. }
  2466. return 0;
  2467. }
  2468. static void
  2469. putreg (struct task_struct *child, int regno, unsigned int value)
  2470. {
  2471. struct pt_regs *child_regs;
  2472. child_regs = ia64_task_regs(child);
  2473. switch (regno / sizeof(int)) {
  2474.       case PT_EBX: child_regs->r11 = value; break;
  2475.       case PT_ECX: child_regs->r9 = value; break;
  2476.       case PT_EDX: child_regs->r10 = value; break;
  2477.       case PT_ESI: child_regs->r14 = value; break;
  2478.       case PT_EDI: child_regs->r15 = value; break;
  2479.       case PT_EBP: child_regs->r13 = value; break;
  2480.       case PT_EAX: child_regs->r8 = value; break;
  2481.       case PT_ORIG_EAX: child_regs->r1 = value; break;
  2482.       case PT_EIP: child_regs->cr_iip = value; break;
  2483.       case PT_UESP: child_regs->r12 = value; break;
  2484.       case PT_EFL: child->thread.eflag = value; break;
  2485.       case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
  2486. if (value != __USER_DS)
  2487. printk(KERN_ERR
  2488.        "ia32.putreg: attempt to set invalid segment register %d = %xn",
  2489.        regno, value);
  2490. break;
  2491.       case PT_CS:
  2492. if (value != __USER_CS)
  2493. printk(KERN_ERR
  2494.        "ia32.putreg: attempt to to set invalid segment register %d = %xn",
  2495.        regno, value);
  2496. break;
  2497.       default:
  2498. printk(KERN_ERR "ia32.putreg: unknown register %dn", regno);
  2499. break;
  2500. }
  2501. }
  2502. static inline void
  2503. ia32f2ia64f (void *dst, void *src)
  2504. {
  2505. asm volatile ("ldfe f6=[%1];; stf.spill [%0]=f6" :: "r"(dst), "r"(src) : "memory");
  2506. return;
  2507. }
  2508. static inline void
  2509. ia64f2ia32f (void *dst, void *src)
  2510. {
  2511. asm volatile ("ldf.fill f6=[%1];; stfe [%0]=f6" :: "r"(dst),  "r"(src) : "memory");
  2512. return;
  2513. }
  2514. static void
  2515. put_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp,
  2516.    int tos)
  2517. {
  2518. struct _fpreg_ia32 *f;
  2519. char buf[32];
  2520. f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
  2521. if ((regno += tos) >= 8)
  2522. regno -= 8;
  2523. switch (regno) {
  2524.       case 0:
  2525. ia64f2ia32f(f, &ptp->f8);
  2526. break;
  2527.       case 1:
  2528. ia64f2ia32f(f, &ptp->f9);
  2529. break;
  2530.       case 2:
  2531.       case 3:
  2532.       case 4:
  2533.       case 5:
  2534.       case 6:
  2535.       case 7:
  2536. ia64f2ia32f(f, &swp->f10 + (regno - 2));
  2537. break;
  2538. }
  2539. copy_to_user(reg, f, sizeof(*reg));
  2540. }
  2541. static void
  2542. get_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp,
  2543.    int tos)
  2544. {
  2545. if ((regno += tos) >= 8)
  2546. regno -= 8;
  2547. switch (regno) {
  2548.       case 0:
  2549. copy_from_user(&ptp->f8, reg, sizeof(*reg));
  2550. break;
  2551.       case 1:
  2552. copy_from_user(&ptp->f9, reg, sizeof(*reg));
  2553. break;
  2554.       case 2:
  2555.       case 3:
  2556.       case 4:
  2557.       case 5:
  2558.       case 6:
  2559.       case 7:
  2560. copy_from_user(&swp->f10 + (regno - 2), reg, sizeof(*reg));
  2561. break;
  2562. }
  2563. return;
  2564. }
  2565. static int
  2566. save_ia32_fpstate (struct task_struct *tsk, struct _fpstate_ia32 *save)
  2567. {
  2568. struct switch_stack *swp;
  2569. struct pt_regs *ptp;
  2570. int i, tos;
  2571. if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
  2572. return -EIO;
  2573. __put_user(tsk->thread.fcr, &save->cw);
  2574. __put_user(tsk->thread.fsr, &save->sw);
  2575. __put_user(tsk->thread.fsr >> 32, &save->tag);
  2576. __put_user(tsk->thread.fir, &save->ipoff);
  2577. __put_user(__USER_CS, &save->cssel);
  2578. __put_user(tsk->thread.fdr, &save->dataoff);
  2579. __put_user(__USER_DS, &save->datasel);
  2580. /*
  2581.  *  Stack frames start with 16-bytes of temp space
  2582.  */
  2583. swp = (struct switch_stack *)(tsk->thread.ksp + 16);
  2584. ptp = ia64_task_regs(tsk);
  2585. tos = (tsk->thread.fsr >> 11) & 3;
  2586. for (i = 0; i < 8; i++)
  2587. put_fpreg(i, &save->_st[i], ptp, swp, tos);
  2588. return 0;
  2589. }
  2590. static int
  2591. restore_ia32_fpstate (struct task_struct *tsk, struct _fpstate_ia32 *save)
  2592. {
  2593. struct switch_stack *swp;
  2594. struct pt_regs *ptp;
  2595. int i, tos, ret;
  2596. int fsrlo, fsrhi;
  2597. if (!access_ok(VERIFY_READ, save, sizeof(*save)))
  2598. return(-EIO);
  2599. ret = __get_user(tsk->thread.fcr, (unsigned int *)&save->cw);
  2600. ret |= __get_user(fsrlo, (unsigned int *)&save->sw);
  2601. ret |= __get_user(fsrhi, (unsigned int *)&save->tag);
  2602. tsk->thread.fsr = ((long)fsrhi << 32) | (long)fsrlo;
  2603. ret |= __get_user(tsk->thread.fir, (unsigned int *)&save->ipoff);
  2604. ret |= __get_user(tsk->thread.fdr, (unsigned int *)&save->dataoff);
  2605. /*
  2606.  *  Stack frames start with 16-bytes of temp space
  2607.  */
  2608. swp = (struct switch_stack *)(tsk->thread.ksp + 16);
  2609. ptp = ia64_task_regs(tsk);
  2610. tos = (tsk->thread.fsr >> 11) & 3;
  2611. for (i = 0; i < 8; i++)
  2612. get_fpreg(i, &save->_st[i], ptp, swp, tos);
  2613. return ret ? -EFAULT : 0;
  2614. }
  2615. extern asmlinkage long sys_ptrace (long, pid_t, unsigned long, unsigned long, long, long, long,
  2616.    long, long);
  2617. /*
  2618.  *  Note that the IA32 version of `ptrace' calls the IA64 routine for
  2619.  *    many of the requests.  This will only work for requests that do
  2620.  *    not need access to the calling processes `pt_regs' which is located
  2621.  *    at the address of `stack'.  Once we call the IA64 `sys_ptrace' then
  2622.  *    the address of `stack' will not be the address of the `pt_regs'.
  2623.  */
  2624. asmlinkage long
  2625. sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
  2626.       long arg4, long arg5, long arg6, long arg7, long stack)
  2627. {
  2628. struct pt_regs *regs = (struct pt_regs *) &stack;
  2629. struct task_struct *child;
  2630. unsigned int value, tmp;
  2631. long i, ret;
  2632. lock_kernel();
  2633. if (request == PTRACE_TRACEME) {
  2634. ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
  2635. goto out;
  2636. }
  2637. ret = -ESRCH;
  2638. read_lock(&tasklist_lock);
  2639. child = find_task_by_pid(pid);
  2640. read_unlock(&tasklist_lock);
  2641. if (!child)
  2642. goto out;
  2643. ret = -EPERM;
  2644. if (pid == 1) /* no messing around with init! */
  2645. goto out;
  2646. if (request == PTRACE_ATTACH) {
  2647. ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
  2648. goto out;
  2649. }
  2650. ret = -ESRCH;
  2651. if (!(child->ptrace & PT_PTRACED))
  2652. goto out;
  2653. if (child->state != TASK_STOPPED) {
  2654. if (request != PTRACE_KILL)
  2655. goto out;
  2656. }
  2657. if (child->p_pptr != current)
  2658. goto out;
  2659. switch (request) {
  2660.       case PTRACE_PEEKTEXT:
  2661.       case PTRACE_PEEKDATA: /* read word at location addr */
  2662. ret = ia32_peek(regs, child, addr, &value);
  2663. if (ret == 0)
  2664. ret = put_user(value, (unsigned int *) A(data));
  2665. else
  2666. ret = -EIO;
  2667. goto out;
  2668.       case PTRACE_POKETEXT:
  2669.       case PTRACE_POKEDATA: /* write the word at location addr */
  2670. ret = ia32_poke(regs, child, addr, data);
  2671. goto out;
  2672.       case PTRACE_PEEKUSR: /* read word at addr in USER area */
  2673. ret = -EIO;
  2674. if ((addr & 3) || addr > 17*sizeof(int))
  2675. break;
  2676. tmp = getreg(child, addr);
  2677. if (!put_user(tmp, (unsigned int *) A(data)))
  2678. ret = 0;
  2679. break;
  2680.       case PTRACE_POKEUSR: /* write word at addr in USER area */
  2681. ret = -EIO;
  2682. if ((addr & 3) || addr > 17*sizeof(int))
  2683. break;
  2684. putreg(child, addr, data);
  2685. ret = 0;
  2686. break;
  2687.       case IA32_PTRACE_GETREGS:
  2688. if (!access_ok(VERIFY_WRITE, (int *) A(data), 17*sizeof(int))) {
  2689. ret = -EIO;
  2690. break;
  2691. }
  2692. for (i = 0; i < 17*sizeof(int); i += sizeof(int) ) {
  2693. put_user(getreg(child, i), (unsigned int *) A(data));
  2694. data += sizeof(int);
  2695. }
  2696. ret = 0;
  2697. break;
  2698.       case IA32_PTRACE_SETREGS:
  2699. if (!access_ok(VERIFY_READ, (int *) A(data), 17*sizeof(int))) {
  2700. ret = -EIO;
  2701. break;
  2702. }
  2703. for (i = 0; i < 17*sizeof(int); i += sizeof(int) ) {
  2704. get_user(tmp, (unsigned int *) A(data));
  2705. putreg(child, i, tmp);
  2706. data += sizeof(int);
  2707. }
  2708. ret = 0;
  2709. break;
  2710.       case IA32_PTRACE_GETFPREGS:
  2711. ret = save_ia32_fpstate(child, (struct _fpstate_ia32 *) A(data));
  2712. break;
  2713.       case IA32_PTRACE_SETFPREGS:
  2714. ret = restore_ia32_fpstate(child, (struct _fpstate_ia32 *) A(data));
  2715. break;
  2716.       case PTRACE_SYSCALL: /* continue, stop after next syscall */
  2717.       case PTRACE_CONT: /* restart after signal. */
  2718.       case PTRACE_KILL:
  2719.       case PTRACE_SINGLESTEP: /* execute chile for one instruction */
  2720.       case PTRACE_DETACH: /* detach a process */
  2721. ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
  2722. break;
  2723.       default:
  2724. ret = -EIO;
  2725. break;
  2726. }
  2727.   out:
  2728. unlock_kernel();
  2729. return ret;
  2730. }
  2731. static inline int
  2732. get_flock32(struct flock *kfl, struct flock32 *ufl)
  2733. {
  2734. int err;
  2735. if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)))
  2736. return -EFAULT;
  2737. err = __get_user(kfl->l_type, &ufl->l_type);
  2738. err |= __get_user(kfl->l_whence, &ufl->l_whence);
  2739. err |= __get_user(kfl->l_start, &ufl->l_start);
  2740. err |= __get_user(kfl->l_len, &ufl->l_len);
  2741. err |= __get_user(kfl->l_pid, &ufl->l_pid);
  2742. return err;
  2743. }
  2744. static inline int
  2745. put_flock32(struct flock *kfl, struct flock32 *ufl)
  2746. {
  2747. int err;
  2748. if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)))
  2749. return -EFAULT;
  2750. err = __put_user(kfl->l_type, &ufl->l_type);
  2751. err |= __put_user(kfl->l_whence, &ufl->l_whence);
  2752. err |= __put_user(kfl->l_start, &ufl->l_start);
  2753. err |= __put_user(kfl->l_len, &ufl->l_len);
  2754. err |= __put_user(kfl->l_pid, &ufl->l_pid);
  2755. return err;
  2756. }
  2757. extern asmlinkage long sys_fcntl (unsigned int fd, unsigned int cmd, unsigned long arg);
  2758. asmlinkage long
  2759. sys32_fcntl (unsigned int fd, unsigned int cmd, unsigned int arg)
  2760. {
  2761. mm_segment_t old_fs;
  2762. struct flock f;
  2763. long ret;
  2764. switch (cmd) {
  2765.       case F_GETLK:
  2766.       case F_SETLK:
  2767.       case F_SETLKW:
  2768. if (get_flock32(&f, (struct flock32 *) A(arg)))
  2769. return -EFAULT;
  2770. old_fs = get_fs();
  2771. set_fs(KERNEL_DS);
  2772. ret = sys_fcntl(fd, cmd, (unsigned long) &f);
  2773. set_fs(old_fs);
  2774. if (cmd == F_GETLK && put_flock32(&f, (struct flock32 *) A(arg)))
  2775. return -EFAULT;
  2776. return ret;
  2777.       default:
  2778. /*
  2779.  *  `sys_fcntl' lies about arg, for the F_SETOWN
  2780.  *  sub-function arg can have a negative value.
  2781.  */
  2782. return sys_fcntl(fd, cmd, arg);
  2783. }
  2784. }
  2785. asmlinkage long sys_ni_syscall(void);
  2786. asmlinkage long
  2787. sys32_ni_syscall (int dummy0, int dummy1, int dummy2, int dummy3, int dummy4, int dummy5,
  2788.   int dummy6, int dummy7, int stack)
  2789. {
  2790. struct pt_regs *regs = (struct pt_regs *)&stack;
  2791. printk(KERN_WARNING "IA32 syscall #%d issued, maybe we should implement itn",
  2792.        (int)regs->r1);
  2793. return(sys_ni_syscall());
  2794. }
  2795. /*
  2796.  *  The IA64 maps 4 I/O ports for each 4K page
  2797.  */
  2798. #define IOLEN ((65536 / 4) * 4096)
  2799. asmlinkage long
  2800. sys32_iopl (int level)
  2801. {
  2802. extern unsigned long ia64_iobase;
  2803. int fd;
  2804. struct file * file;
  2805. unsigned int old;
  2806. unsigned long addr;
  2807. mm_segment_t old_fs = get_fs ();
  2808. if (level != 3)
  2809. return(-EINVAL);
  2810. /* Trying to gain more privileges? */
  2811. asm volatile ("mov %0=ar.eflag ;;" : "=r"(old));
  2812. if (level > ((old >> 12) & 3)) {
  2813. if (!capable(CAP_SYS_RAWIO))
  2814. return -EPERM;
  2815. }
  2816. set_fs(KERNEL_DS);
  2817. fd = sys_open("/dev/mem", O_SYNC | O_RDWR, 0);
  2818. set_fs(old_fs);
  2819. if (fd < 0)
  2820. return fd;
  2821. file = fget(fd);
  2822. if (file == NULL) {
  2823. sys_close(fd);
  2824. return(-EFAULT);
  2825. }
  2826. down_write(&current->mm->mmap_sem);
  2827. addr = do_mmap_pgoff(file, IA32_IOBASE,
  2828.      IOLEN, PROT_READ|PROT_WRITE, MAP_SHARED,
  2829.      (ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT);
  2830. up_write(&current->mm->mmap_sem);
  2831. if (addr >= 0) {
  2832. old = (old & ~0x3000) | (level << 12);
  2833. asm volatile ("mov ar.eflag=%0;;" :: "r"(old));
  2834. }
  2835. fput(file);
  2836. sys_close(fd);
  2837. return 0;
  2838. }
  2839. asmlinkage long
  2840. sys32_ioperm (unsigned int from, unsigned int num, int on)
  2841. {
  2842. /*
  2843.  *  Since IA64 doesn't have permission bits we'd have to go to
  2844.  *    a lot of trouble to simulate them in software.  There's
  2845.  *    no point, only trusted programs can make this call so we'll
  2846.  *    just turn it into an iopl call and let the process have
  2847.  *    access to all I/O ports.
  2848.  *
  2849.  * XXX proper ioperm() support should be emulated by
  2850.  * manipulating the page protections...
  2851.  */
  2852. return sys32_iopl(3);
  2853. }
  2854. typedef struct {
  2855. unsigned int ss_sp;
  2856. unsigned int ss_flags;
  2857. unsigned int ss_size;
  2858. } ia32_stack_t;
  2859. asmlinkage long
  2860. sys32_sigaltstack (ia32_stack_t *uss32, ia32_stack_t *uoss32,
  2861.    long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long stack)
  2862. {
  2863. struct pt_regs *pt = (struct pt_regs *) &stack;
  2864. stack_t uss, uoss;
  2865. ia32_stack_t buf32;
  2866. int ret;
  2867. mm_segment_t old_fs = get_fs();
  2868. if (uss32)
  2869. if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
  2870. return -EFAULT;
  2871. uss.ss_sp = (void *) (long) buf32.ss_sp;
  2872. uss.ss_flags = buf32.ss_flags;
  2873. uss.ss_size = buf32.ss_size;
  2874. set_fs(KERNEL_DS);
  2875. ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12);
  2876. set_fs(old_fs);
  2877. if (ret < 0)
  2878. return(ret);
  2879. if (uoss32) {
  2880. buf32.ss_sp = (long) uoss.ss_sp;
  2881. buf32.ss_flags = uoss.ss_flags;
  2882. buf32.ss_size = uoss.ss_size;
  2883. if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
  2884. return -EFAULT;
  2885. }
  2886. return ret;
  2887. }
  2888. asmlinkage int
  2889. sys32_pause (void)
  2890. {
  2891. current->state = TASK_INTERRUPTIBLE;
  2892. schedule();
  2893. return -ERESTARTNOHAND;
  2894. }
  2895. asmlinkage long sys_msync (unsigned long start, size_t len, int flags);
  2896. asmlinkage int
  2897. sys32_msync (unsigned int start, unsigned int len, int flags)
  2898. {
  2899. unsigned int addr;
  2900. if (OFFSET4K(start))
  2901. return -EINVAL;
  2902. addr = PAGE_START(start);
  2903. return sys_msync(addr, len + (start - addr), flags);
  2904. }
  2905. struct sysctl32 {
  2906. unsigned int name;
  2907. int nlen;
  2908. unsigned int oldval;
  2909. unsigned int oldlenp;
  2910. unsigned int newval;
  2911. unsigned int newlen;
  2912. unsigned int __unused[4];
  2913. };
  2914. extern asmlinkage long sys_sysctl(struct __sysctl_args *args);
  2915. asmlinkage long
  2916. sys32_sysctl (struct sysctl32 *args)
  2917. {
  2918. struct sysctl32 a32;
  2919. mm_segment_t old_fs = get_fs ();
  2920. void *oldvalp, *newvalp;
  2921. size_t oldlen;
  2922. int *namep;
  2923. long ret;
  2924. if (copy_from_user(&a32, args, sizeof(a32)))
  2925. return -EFAULT;
  2926. /*
  2927.  * We need to pre-validate these because we have to disable address checking
  2928.  * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
  2929.  * user specifying bad addresses here.  Well, since we're dealing with 32 bit
  2930.  * addresses, we KNOW that access_ok() will always succeed, so this is an
  2931.  * expensive NOP, but so what...
  2932.  */
  2933. namep = (int *) A(a32.name);
  2934. oldvalp = (void *) A(a32.oldval);
  2935. newvalp = (void *) A(a32.newval);
  2936. if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))
  2937.     || !access_ok(VERIFY_WRITE, namep, 0)
  2938.     || !access_ok(VERIFY_WRITE, oldvalp, 0)
  2939.     || !access_ok(VERIFY_WRITE, newvalp, 0))
  2940. return -EFAULT;
  2941. set_fs(KERNEL_DS);
  2942. lock_kernel();
  2943. ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);
  2944. unlock_kernel();
  2945. set_fs(old_fs);
  2946. if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))
  2947. return -EFAULT;
  2948. return ret;
  2949. }
  2950. asmlinkage long
  2951. sys32_newuname (struct new_utsname *name)
  2952. {
  2953. extern asmlinkage long sys_newuname(struct new_utsname * name);
  2954. int ret = sys_newuname(name);
  2955. if (!ret)
  2956. if (copy_to_user(name->machine, "i686", 8))
  2957. ret = -EFAULT;
  2958. return ret;
  2959. }
  2960. extern asmlinkage long sys_getresuid (uid_t *ruid, uid_t *euid, uid_t *suid);
  2961. asmlinkage long
  2962. sys32_getresuid16 (u16 *ruid, u16 *euid, u16 *suid)
  2963. {
  2964. uid_t a, b, c;
  2965. int ret;
  2966. mm_segment_t old_fs = get_fs();
  2967. set_fs(KERNEL_DS);
  2968. ret = sys_getresuid(&a, &b, &c);
  2969. set_fs(old_fs);
  2970. if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
  2971. return -EFAULT;
  2972. return ret;
  2973. }
  2974. extern asmlinkage long sys_getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid);
  2975. asmlinkage long
  2976. sys32_getresgid16 (u16 *rgid, u16 *egid, u16 *sgid)
  2977. {
  2978. gid_t a, b, c;
  2979. int ret;
  2980. mm_segment_t old_fs = get_fs();
  2981. set_fs(KERNEL_DS);
  2982. ret = sys_getresgid(&a, &b, &c);
  2983. set_fs(old_fs);
  2984. if (ret)
  2985. return ret;
  2986. return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid);
  2987. }
  2988. asmlinkage long
  2989. sys32_lseek (unsigned int fd, int offset, unsigned int whence)
  2990. {
  2991. extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
  2992. /* Sign-extension of "offset" is important here... */
  2993. return sys_lseek(fd, offset, whence);
  2994. }
  2995. extern asmlinkage long sys_getgroups (int gidsetsize, gid_t *grouplist);
  2996. asmlinkage long
  2997. sys32_getgroups16 (int gidsetsize, short *grouplist)
  2998. {
  2999. mm_segment_t old_fs = get_fs();
  3000. gid_t gl[NGROUPS];
  3001. int ret, i;
  3002. set_fs(KERNEL_DS);
  3003. ret = sys_getgroups(gidsetsize, gl);
  3004. set_fs(old_fs);
  3005. if (gidsetsize && ret > 0 && ret <= NGROUPS)
  3006. for (i = 0; i < ret; i++, grouplist++)
  3007. if (put_user(gl[i], grouplist))
  3008. return -EFAULT;
  3009. return ret;
  3010. }
  3011. extern asmlinkage long sys_setgroups (int gidsetsize, gid_t *grouplist);
  3012. asmlinkage long
  3013. sys32_setgroups16 (int gidsetsize, short *grouplist)
  3014. {
  3015. mm_segment_t old_fs = get_fs();
  3016. gid_t gl[NGROUPS];
  3017. int ret, i;
  3018. if ((unsigned) gidsetsize > NGROUPS)
  3019. return -EINVAL;
  3020. for (i = 0; i < gidsetsize; i++, grouplist++)
  3021. if (get_user(gl[i], grouplist))
  3022. return -EFAULT;
  3023. set_fs(KERNEL_DS);
  3024. ret = sys_setgroups(gidsetsize, gl);
  3025. set_fs(old_fs);
  3026. return ret;
  3027. }
  3028. /*
  3029.  * Unfortunately, the x86 compiler aligns variables of type "long long" to a 4 byte boundary
  3030.  * only, which means that the x86 version of "struct flock64" doesn't match the ia64 version
  3031.  * of struct flock.
  3032.  */
  3033. static inline long
  3034. ia32_put_flock (struct flock *l, unsigned long addr)
  3035. {
  3036. return (put_user(l->l_type, (short *) addr)
  3037. | put_user(l->l_whence, (short *) (addr + 2))
  3038. | put_user(l->l_start, (long *) (addr + 4))
  3039. | put_user(l->l_len, (long *) (addr + 12))
  3040. | put_user(l->l_pid, (int *) (addr + 20)));
  3041. }
  3042. static inline long
  3043. ia32_get_flock (struct flock *l, unsigned long addr)
  3044. {
  3045. unsigned int start_lo, start_hi, len_lo, len_hi;
  3046. int err = (get_user(l->l_type, (short *) addr)
  3047.    | get_user(l->l_whence, (short *) (addr + 2))
  3048.    | get_user(start_lo, (int *) (addr + 4))
  3049.    | get_user(start_hi, (int *) (addr + 8))
  3050.    | get_user(len_lo, (int *) (addr + 12))
  3051.    | get_user(len_hi, (int *) (addr + 16))
  3052.    | get_user(l->l_pid, (int *) (addr + 20)));
  3053. l->l_start = ((unsigned long) start_hi << 32) | start_lo;
  3054. l->l_len = ((unsigned long) len_hi << 32) | len_lo;
  3055. return err;
  3056. }
  3057. asmlinkage long
  3058. sys32_fcntl64 (unsigned int fd, unsigned int cmd, unsigned int arg)
  3059. {
  3060. mm_segment_t old_fs;
  3061. struct flock f;
  3062. long ret;
  3063. switch (cmd) {
  3064.       case F_GETLK64:
  3065.       case F_SETLK64:
  3066.       case F_SETLKW64:
  3067. if (ia32_get_flock(&f, arg))
  3068. return -EFAULT;
  3069. old_fs = get_fs();
  3070. set_fs(KERNEL_DS);
  3071. ret = sys_fcntl(fd, cmd, (unsigned long) &f);
  3072. set_fs(old_fs);
  3073. if (cmd == F_GETLK && ia32_put_flock(&f, arg))
  3074. return -EFAULT;
  3075. break;
  3076.       default:
  3077. ret = sys32_fcntl(fd, cmd, arg);
  3078. break;
  3079. }
  3080. return ret;
  3081. }
  3082. asmlinkage long
  3083. sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
  3084. {
  3085. extern asmlinkage long sys_truncate (const char *path, unsigned long length);
  3086. return sys_truncate((const char *) A(path), ((unsigned long) len_hi << 32) | len_lo);
  3087. }
  3088. asmlinkage long
  3089. sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
  3090. {
  3091. extern asmlinkage long sys_ftruncate (int fd, unsigned long length);
  3092. return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo);
  3093. }
  3094. static int
  3095. putstat64 (struct stat64 *ubuf, struct stat *kbuf)
  3096. {
  3097. int err;
  3098. if (clear_user(ubuf, sizeof(*ubuf)))
  3099. return 1;
  3100. err  = __put_user(kbuf->st_dev, &ubuf->st_dev);
  3101. err |= __put_user(kbuf->st_ino, &ubuf->__st_ino);
  3102. err |= __put_user(kbuf->st_ino, &ubuf->st_ino_lo);
  3103. err |= __put_user(kbuf->st_ino >> 32, &ubuf->st_ino_hi);
  3104. err |= __put_user(kbuf->st_mode, &ubuf->st_mode);
  3105. err |= __put_user(kbuf->st_nlink, &ubuf->st_nlink);
  3106. err |= __put_user(kbuf->st_uid, &ubuf->st_uid);
  3107. err |= __put_user(kbuf->st_gid, &ubuf->st_gid);
  3108. err |= __put_user(kbuf->st_rdev, &ubuf->st_rdev);
  3109. err |= __put_user(kbuf->st_size, &ubuf->st_size_lo);
  3110. err |= __put_user((kbuf->st_size >> 32), &ubuf->st_size_hi);
  3111. err |= __put_user(kbuf->st_atime, &ubuf->st_atime);
  3112. err |= __put_user(kbuf->st_mtime, &ubuf->st_mtime);
  3113. err |= __put_user(kbuf->st_ctime, &ubuf->st_ctime);
  3114. err |= __put_user(kbuf->st_blksize, &ubuf->st_blksize);
  3115. err |= __put_user(kbuf->st_blocks, &ubuf->st_blocks);
  3116. return err;
  3117. }
  3118. asmlinkage long
  3119. sys32_stat64 (char *filename, struct stat64 *statbuf)
  3120. {
  3121. mm_segment_t old_fs = get_fs();
  3122. struct stat s;
  3123. long ret;
  3124. set_fs(KERNEL_DS);
  3125. ret = sys_newstat(filename, &s);
  3126. set_fs(old_fs);
  3127. if (putstat64(statbuf, &s))
  3128. return -EFAULT;
  3129. return ret;
  3130. }
  3131. asmlinkage long
  3132. sys32_lstat64 (char *filename, struct stat64 *statbuf)
  3133. {
  3134. mm_segment_t old_fs = get_fs();
  3135. struct stat s;
  3136. long ret;
  3137. set_fs(KERNEL_DS);
  3138. ret = sys_newlstat(filename, &s);
  3139. set_fs(old_fs);
  3140. if (putstat64(statbuf, &s))
  3141. return -EFAULT;
  3142. return ret;
  3143. }
  3144. asmlinkage long
  3145. sys32_fstat64 (unsigned int fd, struct stat64 *statbuf)
  3146. {
  3147. mm_segment_t old_fs = get_fs();
  3148. struct stat s;
  3149. long ret;
  3150. set_fs(KERNEL_DS);
  3151. ret = sys_newfstat(fd, &s);
  3152. set_fs(old_fs);
  3153. if (putstat64(statbuf, &s))
  3154. return -EFAULT;
  3155. return ret;
  3156. }
  3157. asmlinkage long
  3158. sys32_sigpending (unsigned int *set)
  3159. {
  3160. return do_sigpending(set, sizeof(*set));
  3161. }
  3162. struct sysinfo32 {
  3163. s32 uptime;
  3164. u32 loads[3];
  3165. u32 totalram;
  3166. u32 freeram;
  3167. u32 sharedram;
  3168. u32 bufferram;
  3169. u32 totalswap;
  3170. u32 freeswap;
  3171. unsigned short procs;
  3172. char _f[22];
  3173. };
  3174. asmlinkage long
  3175. sys32_sysinfo (struct sysinfo32 *info)
  3176. {
  3177. extern asmlinkage long sys_sysinfo (struct sysinfo *);
  3178. mm_segment_t old_fs = get_fs();
  3179. struct sysinfo s;
  3180. long ret, err;
  3181. set_fs(KERNEL_DS);
  3182. ret = sys_sysinfo(&s);
  3183. set_fs(old_fs);
  3184. if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
  3185. return -EFAULT;
  3186. err  = __put_user(s.uptime, &info->uptime);
  3187. err |= __put_user(s.loads[0], &info->loads[0]);
  3188. err |= __put_user(s.loads[1], &info->loads[1]);
  3189. err |= __put_user(s.loads[2], &info->loads[2]);
  3190. err |= __put_user(s.totalram, &info->totalram);
  3191. err |= __put_user(s.freeram, &info->freeram);
  3192. err |= __put_user(s.sharedram, &info->sharedram);
  3193. err |= __put_user(s.bufferram, &info->bufferram);
  3194. err |= __put_user(s.totalswap, &info->totalswap);
  3195. err |= __put_user(s.freeswap, &info->freeswap);
  3196. err |= __put_user(s.procs, &info->procs);
  3197. if (err)
  3198. return -EFAULT;
  3199. return ret;
  3200. }
  3201. /* In order to reduce some races, while at the same time doing additional
  3202.  * checking and hopefully speeding things up, we copy filenames to the
  3203.  * kernel data space before using them..
  3204.  *
  3205.  * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
  3206.  */
  3207. static inline int
  3208. do_getname32 (const char *filename, char *page)
  3209. {
  3210. int retval;
  3211. /* 32bit pointer will be always far below TASK_SIZE :)) */
  3212. retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
  3213. if (retval > 0) {
  3214. if (retval < PAGE_SIZE)
  3215. return 0;
  3216. return -ENAMETOOLONG;
  3217. } else if (!retval)
  3218. retval = -ENOENT;
  3219. return retval;
  3220. }
  3221. static char *
  3222. getname32 (const char *filename)
  3223. {
  3224. char *tmp, *result;
  3225. result = ERR_PTR(-ENOMEM);
  3226. tmp = (char *)__get_free_page(GFP_KERNEL);
  3227. if (tmp)  {
  3228. int retval = do_getname32(filename, tmp);
  3229. result = tmp;
  3230. if (retval < 0) {
  3231. putname(tmp);
  3232. result = ERR_PTR(retval);
  3233. }
  3234. }
  3235. return result;
  3236. }
  3237. struct dqblk32 {
  3238. __u32 dqb_bhardlimit;
  3239. __u32 dqb_bsoftlimit;
  3240. __u32 dqb_curblocks;
  3241. __u32 dqb_ihardlimit;
  3242. __u32 dqb_isoftlimit;
  3243. __u32 dqb_curinodes;
  3244. __kernel_time_t32 dqb_btime;
  3245. __kernel_time_t32 dqb_itime;
  3246. };
  3247. asmlinkage long
  3248. sys32_quotactl (int cmd, unsigned int special, int id, struct dqblk32 *addr)
  3249. {
  3250. extern asmlinkage long sys_quotactl (int, const char *, int, caddr_t);
  3251. int cmds = cmd >> SUBCMDSHIFT;
  3252. mm_segment_t old_fs;
  3253. struct dqblk d;
  3254. char *spec;
  3255. long err;
  3256. switch (cmds) {
  3257.       case Q_GETQUOTA:
  3258. break;
  3259.       case Q_SETQUOTA:
  3260.       case Q_SETUSE:
  3261.       case Q_SETQLIM:
  3262. if (copy_from_user (&d, addr, sizeof(struct dqblk32)))
  3263. return -EFAULT;
  3264. d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
  3265. d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
  3266. break;
  3267.       default:
  3268. return sys_quotactl(cmd, (void *) A(special), id, (caddr_t) addr);
  3269. }
  3270. spec = getname32((void *) A(special));
  3271. err = PTR_ERR(spec);
  3272. if (IS_ERR(spec))
  3273. return err;
  3274. old_fs = get_fs ();
  3275. set_fs(KERNEL_DS);
  3276. err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
  3277. set_fs(old_fs);
  3278. putname(spec);
  3279. if (cmds == Q_GETQUOTA) {
  3280. __kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
  3281. ((struct dqblk32 *)&d)->dqb_itime = i;
  3282. ((struct dqblk32 *)&d)->dqb_btime = b;
  3283. if (copy_to_user(addr, &d, sizeof(struct dqblk32)))
  3284. return -EFAULT;
  3285. }
  3286. return err;
  3287. }
  3288. asmlinkage long
  3289. sys32_sched_rr_get_interval (pid_t pid, struct timespec32 *interval)
  3290. {
  3291. extern asmlinkage long sys_sched_rr_get_interval (pid_t, struct timespec *);
  3292. mm_segment_t old_fs = get_fs();
  3293. struct timespec t;
  3294. long ret;
  3295. set_fs(KERNEL_DS);
  3296. ret = sys_sched_rr_get_interval(pid, &t);
  3297. set_fs(old_fs);
  3298. if (put_user (t.tv_sec, &interval->tv_sec) || put_user (t.tv_nsec, &interval->tv_nsec))
  3299. return -EFAULT;
  3300. return ret;
  3301. }
  3302. asmlinkage long
  3303. sys32_pread (unsigned int fd, void *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
  3304. {
  3305. extern asmlinkage long sys_pread (unsigned int, char *, size_t, loff_t);
  3306. return sys_pread(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
  3307. }
  3308. asmlinkage long
  3309. sys32_pwrite (unsigned int fd, void *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
  3310. {
  3311. extern asmlinkage long sys_pwrite (unsigned int, const char *, size_t, loff_t);
  3312. return sys_pwrite(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
  3313. }
  3314. asmlinkage long
  3315. sys32_sendfile (int out_fd, int in_fd, int *offset, unsigned int count)
  3316. {
  3317. extern asmlinkage long sys_sendfile (int, int, off_t *, size_t);
  3318. mm_segment_t old_fs = get_fs();
  3319. long ret;
  3320. off_t of;
  3321. if (offset && get_user(of, offset))
  3322. return -EFAULT;
  3323. set_fs(KERNEL_DS);
  3324. ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
  3325. set_fs(old_fs);
  3326. if (!ret && offset && put_user(of, offset))
  3327. return -EFAULT;
  3328. return ret;
  3329. }
  3330. asmlinkage long
  3331. sys32_personality (unsigned int personality)
  3332. {
  3333. extern asmlinkage long sys_personality (unsigned long);
  3334. long ret;
  3335. if (current->personality == PER_LINUX32 && personality == PER_LINUX)
  3336. personality = PER_LINUX32;
  3337. ret = sys_personality(personality);
  3338. if (ret == PER_LINUX32)
  3339. ret = PER_LINUX;
  3340. return ret;
  3341. }
  3342. asmlinkage unsigned long
  3343. sys32_brk (unsigned int brk)
  3344. {
  3345. unsigned long ret, obrk;
  3346. struct mm_struct *mm = current->mm;
  3347. obrk = mm->brk;
  3348. ret = sys_brk(brk);
  3349. if (ret < obrk)
  3350. clear_user((void *) ret, PAGE_ALIGN(ret) - ret);
  3351. return ret;
  3352. }
  3353. #ifdef NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
  3354. struct ncp_mount_data32 {
  3355. int version;
  3356. unsigned int ncp_fd;
  3357. __kernel_uid_t32 mounted_uid;
  3358. int wdog_pid;
  3359. unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
  3360. unsigned int time_out;
  3361. unsigned int retry_count;
  3362. unsigned int flags;
  3363. __kernel_uid_t32 uid;
  3364. __kernel_gid_t32 gid;
  3365. __kernel_mode_t32 file_mode;
  3366. __kernel_mode_t32 dir_mode;
  3367. };
  3368. static void *
  3369. do_ncp_super_data_conv(void *raw_data)
  3370. {
  3371. struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
  3372. struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
  3373. n->dir_mode = n32->dir_mode;
  3374. n->file_mode = n32->file_mode;
  3375. n->gid = n32->gid;
  3376. n->uid = n32->uid;
  3377. memmove (n->mounted_vol, n32->mounted_vol,
  3378.  (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
  3379. n->wdog_pid = n32->wdog_pid;
  3380. n->mounted_uid = n32->mounted_uid;
  3381. return raw_data;
  3382. }
  3383. struct smb_mount_data32 {
  3384. int version;
  3385. __kernel_uid_t32 mounted_uid;
  3386. __kernel_uid_t32 uid;
  3387. __kernel_gid_t32 gid;
  3388. __kernel_mode_t32 file_mode;
  3389. __kernel_mode_t32 dir_mode;
  3390. };
  3391. static void *
  3392. do_smb_super_data_conv(void *raw_data)
  3393. {
  3394. struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
  3395. struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
  3396. s->version = s32->version;
  3397. s->mounted_uid = s32->mounted_uid;
  3398. s->uid = s32->uid;
  3399. s->gid = s32->gid;
  3400. s->file_mode = s32->file_mode;
  3401. s->dir_mode = s32->dir_mode;
  3402. return raw_data;
  3403. }
  3404. static int
  3405. copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
  3406. {
  3407. int i;
  3408. unsigned long page;
  3409. struct vm_area_struct *vma;
  3410. *kernel = 0;
  3411. if(!user)
  3412. return 0;
  3413. vma = find_vma(current->mm, (unsigned long)user);
  3414. if(!vma || (unsigned long)user < vma->vm_start)
  3415. return -EFAULT;
  3416. if(!(vma->vm_flags & VM_READ))
  3417. return -EFAULT;
  3418. i = vma->vm_end - (unsigned long) user;
  3419. if(PAGE_SIZE <= (unsigned long) i)
  3420. i = PAGE_SIZE - 1;
  3421. if(!(page = __get_free_page(GFP_KERNEL)))
  3422. return -ENOMEM;
  3423. if(copy_from_user((void *) page, user, i)) {
  3424. free_page(page);
  3425. return -EFAULT;
  3426. }
  3427. *kernel = page;
  3428. return 0;
  3429. }
  3430. extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
  3431. unsigned long new_flags, void *data);
  3432. #define SMBFS_NAME "smbfs"
  3433. #define NCPFS_NAME "ncpfs"
  3434. asmlinkage long
  3435. sys32_mount(char *dev_name, char *dir_name, char *type,
  3436.     unsigned long new_flags, u32 data)
  3437. {
  3438. unsigned long type_page;
  3439. int err, is_smb, is_ncp;
  3440. if(!capable(CAP_SYS_ADMIN))
  3441. return -EPERM;
  3442. is_smb = is_ncp = 0;
  3443. err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
  3444. if(err)
  3445. return err;
  3446. if(type_page) {
  3447. is_smb = !strcmp((char *)type_page, SMBFS_NAME);
  3448. is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
  3449. }
  3450. if(!is_smb && !is_ncp) {
  3451. if(type_page)
  3452. free_page(type_page);
  3453. return sys_mount(dev_name, dir_name, type, new_flags,
  3454.  (void *)AA(data));
  3455. } else {
  3456. unsigned long dev_page, dir_page, data_page;
  3457. err = copy_mount_stuff_to_kernel((const void *)dev_name,
  3458.  &dev_page);
  3459. if(err)
  3460. goto out;
  3461. err = copy_mount_stuff_to_kernel((const void *)dir_name,
  3462.  &dir_page);
  3463. if(err)
  3464. goto dev_out;
  3465. err = copy_mount_stuff_to_kernel((const void *)AA(data),
  3466.  &data_page);
  3467. if(err)
  3468. goto dir_out;
  3469. if(is_ncp)
  3470. do_ncp_super_data_conv((void *)data_page);
  3471. else if(is_smb)
  3472. do_smb_super_data_conv((void *)data_page);
  3473. else
  3474. panic("The problem is here...");
  3475. err = do_mount((char *)dev_page, (char *)dir_page,
  3476. (char *)type_page, new_flags,
  3477. (void *)data_page);
  3478. if(data_page)
  3479. free_page(data_page);
  3480. dir_out:
  3481. if(dir_page)
  3482. free_page(dir_page);
  3483. dev_out:
  3484. if(dev_page)
  3485. free_page(dev_page);
  3486. out:
  3487. if(type_page)
  3488. free_page(type_page);
  3489. return err;
  3490. }
  3491. }
  3492. extern asmlinkage long sys_setreuid(uid_t ruid, uid_t euid);
  3493. asmlinkage long sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
  3494. {
  3495. uid_t sruid, seuid;
  3496. sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
  3497. seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
  3498. return sys_setreuid(sruid, seuid);
  3499. }
  3500. extern asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
  3501. asmlinkage long
  3502. sys32_setresuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid,
  3503. __kernel_uid_t32 suid)
  3504. {
  3505. uid_t sruid, seuid, ssuid;
  3506. sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
  3507. seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
  3508. ssuid = (suid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)suid);
  3509. return sys_setresuid(sruid, seuid, ssuid);
  3510. }
  3511. extern asmlinkage long sys_setregid(gid_t rgid, gid_t egid);
  3512. asmlinkage long
  3513. sys32_setregid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid)
  3514. {
  3515. gid_t srgid, segid;
  3516. srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
  3517. segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
  3518. return sys_setregid(srgid, segid);
  3519. }
  3520. extern asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
  3521. asmlinkage long
  3522. sys32_setresgid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid,
  3523. __kernel_gid_t32 sgid)
  3524. {
  3525. gid_t srgid, segid, ssgid;
  3526. srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
  3527. segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
  3528. ssgid = (sgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)sgid);
  3529. return sys_setresgid(srgid, segid, ssgid);
  3530. }
  3531. /* Stuff for NFS server syscalls... */
  3532. struct nfsctl_svc32 {
  3533. u16 svc32_port;
  3534. s32 svc32_nthreads;
  3535. };
  3536. struct nfsctl_client32 {
  3537. s8 cl32_ident[NFSCLNT_IDMAX+1];
  3538. s32 cl32_naddr;
  3539. struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
  3540. s32 cl32_fhkeytype;
  3541. s32 cl32_fhkeylen;
  3542. u8 cl32_fhkey[NFSCLNT_KEYMAX];
  3543. };
  3544. struct nfsctl_export32 {
  3545. s8 ex32_client[NFSCLNT_IDMAX+1];
  3546. s8 ex32_path[NFS_MAXPATHLEN+1];
  3547. __kernel_dev_t32 ex32_dev;
  3548. __kernel_ino_t32 ex32_ino;
  3549. s32 ex32_flags;
  3550. __kernel_uid_t32 ex32_anon_uid;
  3551. __kernel_gid_t32 ex32_anon_gid;
  3552. };
  3553. struct nfsctl_uidmap32 {
  3554. u32 ug32_ident;   /* char * */
  3555. __kernel_uid_t32 ug32_uidbase;
  3556. s32 ug32_uidlen;
  3557. u32 ug32_udimap;  /* uid_t * */
  3558. __kernel_uid_t32 ug32_gidbase;
  3559. s32 ug32_gidlen;
  3560. u32 ug32_gdimap;  /* gid_t * */
  3561. };
  3562. struct nfsctl_fhparm32 {
  3563. struct sockaddr gf32_addr;
  3564. __kernel_dev_t32 gf32_dev;
  3565. __kernel_ino_t32 gf32_ino;
  3566. s32 gf32_version;
  3567. };
  3568. struct nfsctl_arg32 {
  3569. s32 ca32_version; /* safeguard */
  3570. union {
  3571. struct nfsctl_svc32 u32_svc;
  3572. struct nfsctl_client32 u32_client;
  3573. struct nfsctl_export32 u32_export;
  3574. struct nfsctl_uidmap32 u32_umap;
  3575. struct nfsctl_fhparm32 u32_getfh;
  3576. u32 u32_debug;
  3577. } u;
  3578. #define ca32_svc u.u32_svc
  3579. #define ca32_client u.u32_client
  3580. #define ca32_export u.u32_export
  3581. #define ca32_umap u.u32_umap
  3582. #define ca32_getfh u.u32_getfh
  3583. #define ca32_authd u.u32_authd
  3584. #define ca32_debug u.u32_debug
  3585. };
  3586. union nfsctl_res32 {
  3587. struct knfs_fh cr32_getfh;
  3588. u32 cr32_debug;
  3589. };
  3590. static int
  3591. nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3592. {
  3593. int err;
  3594. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3595. err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
  3596. err |= __get_user(karg->ca_svc.svc_nthreads,
  3597.   &arg32->ca32_svc.svc32_nthreads);
  3598. return err;
  3599. }
  3600. static int
  3601. nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3602. {
  3603. int err;
  3604. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3605. err |= copy_from_user(&karg->ca_client.cl_ident[0],
  3606.   &arg32->ca32_client.cl32_ident[0],
  3607.   NFSCLNT_IDMAX);
  3608. err |= __get_user(karg->ca_client.cl_naddr,
  3609.   &arg32->ca32_client.cl32_naddr);
  3610. err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
  3611.   &arg32->ca32_client.cl32_addrlist[0],
  3612.   (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
  3613. err |= __get_user(karg->ca_client.cl_fhkeytype,
  3614.       &arg32->ca32_client.cl32_fhkeytype);
  3615. err |= __get_user(karg->ca_client.cl_fhkeylen,
  3616.       &arg32->ca32_client.cl32_fhkeylen);
  3617. err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
  3618.   &arg32->ca32_client.cl32_fhkey[0],
  3619.   NFSCLNT_KEYMAX);
  3620. return err;
  3621. }
  3622. static int
  3623. nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3624. {
  3625. int err;
  3626. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3627. err |= copy_from_user(&karg->ca_export.ex_client[0],
  3628.   &arg32->ca32_export.ex32_client[0],
  3629.   NFSCLNT_IDMAX);
  3630. err |= copy_from_user(&karg->ca_export.ex_path[0],
  3631.   &arg32->ca32_export.ex32_path[0],
  3632.   NFS_MAXPATHLEN);
  3633. err |= __get_user(karg->ca_export.ex_dev,
  3634.       &arg32->ca32_export.ex32_dev);
  3635. err |= __get_user(karg->ca_export.ex_ino,
  3636.       &arg32->ca32_export.ex32_ino);
  3637. err |= __get_user(karg->ca_export.ex_flags,
  3638.       &arg32->ca32_export.ex32_flags);
  3639. err |= __get_user(karg->ca_export.ex_anon_uid,
  3640.       &arg32->ca32_export.ex32_anon_uid);
  3641. err |= __get_user(karg->ca_export.ex_anon_gid,
  3642.       &arg32->ca32_export.ex32_anon_gid);
  3643. return err;
  3644. }
  3645. static int
  3646. nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3647. {
  3648. u32 uaddr;
  3649. int i;
  3650. int err;
  3651. memset(karg, 0, sizeof(*karg));
  3652. if(__get_user(karg->ca_version, &arg32->ca32_version))
  3653. return -EFAULT;
  3654. karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
  3655. if(!karg->ca_umap.ug_ident)
  3656. return -ENOMEM;
  3657. err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
  3658. if(strncpy_from_user(karg->ca_umap.ug_ident,
  3659.      (char *)A(uaddr), PAGE_SIZE) <= 0)
  3660. return -EFAULT;
  3661. err |= __get_user(karg->ca_umap.ug_uidbase,
  3662.       &arg32->ca32_umap.ug32_uidbase);
  3663. err |= __get_user(karg->ca_umap.ug_uidlen,
  3664.       &arg32->ca32_umap.ug32_uidlen);
  3665. err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
  3666. if (err)
  3667. return -EFAULT;
  3668. karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) *
  3669.    karg->ca_umap.ug_uidlen),
  3670.   GFP_USER);
  3671. if(!karg->ca_umap.ug_udimap)
  3672. return -ENOMEM;
  3673. for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
  3674. err |= __get_user(karg->ca_umap.ug_udimap[i],
  3675.       &(((__kernel_uid_t32 *)A(uaddr))[i]));
  3676. err |= __get_user(karg->ca_umap.ug_gidbase,
  3677.       &arg32->ca32_umap.ug32_gidbase);
  3678. err |= __get_user(karg->ca_umap.ug_uidlen,
  3679.       &arg32->ca32_umap.ug32_gidlen);
  3680. err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
  3681. if (err)
  3682. return -EFAULT;
  3683. karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) *
  3684.    karg->ca_umap.ug_uidlen),
  3685.   GFP_USER);
  3686. if(!karg->ca_umap.ug_gdimap)
  3687. return -ENOMEM;
  3688. for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
  3689. err |= __get_user(karg->ca_umap.ug_gdimap[i],
  3690.       &(((__kernel_gid_t32 *)A(uaddr))[i]));
  3691. return err;
  3692. }
  3693. static int
  3694. nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3695. {
  3696. int err;
  3697. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3698. err |= copy_from_user(&karg->ca_getfh.gf_addr,
  3699.   &arg32->ca32_getfh.gf32_addr,
  3700.   (sizeof(struct sockaddr)));
  3701. err |= __get_user(karg->ca_getfh.gf_dev,
  3702.       &arg32->ca32_getfh.gf32_dev);
  3703. err |= __get_user(karg->ca_getfh.gf_ino,
  3704.       &arg32->ca32_getfh.gf32_ino);
  3705. err |= __get_user(karg->ca_getfh.gf_version,
  3706.       &arg32->ca32_getfh.gf32_version);
  3707. return err;
  3708. }
  3709. static int
  3710. nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
  3711. {
  3712. int err;
  3713. err = copy_to_user(&res32->cr32_getfh,
  3714. &kres->cr_getfh,
  3715. sizeof(res32->cr32_getfh));
  3716. err |= __put_user(kres->cr_debug, &res32->cr32_debug);
  3717. return err;
  3718. }
  3719. extern asmlinkage long sys_nfsservctl(int cmd, void *arg, void *resp);
  3720. int asmlinkage
  3721. sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
  3722. {
  3723. struct nfsctl_arg *karg = NULL;
  3724. union nfsctl_res *kres = NULL;
  3725. mm_segment_t oldfs;
  3726. int err;
  3727. karg = kmalloc(sizeof(*karg), GFP_USER);
  3728. if(!karg)
  3729. return -ENOMEM;
  3730. if(res32) {
  3731. kres = kmalloc(sizeof(*kres), GFP_USER);
  3732. if(!kres) {
  3733. kfree(karg);
  3734. return -ENOMEM;
  3735. }
  3736. }
  3737. switch(cmd) {
  3738. case NFSCTL_SVC:
  3739. err = nfs_svc32_trans(karg, arg32);
  3740. break;
  3741. case NFSCTL_ADDCLIENT:
  3742. err = nfs_clnt32_trans(karg, arg32);
  3743. break;
  3744. case NFSCTL_DELCLIENT:
  3745. err = nfs_clnt32_trans(karg, arg32);
  3746. break;
  3747. case NFSCTL_EXPORT:
  3748. err = nfs_exp32_trans(karg, arg32);
  3749. break;
  3750. /* This one is unimplemented, be we're ready for it. */
  3751. case NFSCTL_UGIDUPDATE:
  3752. err = nfs_uud32_trans(karg, arg32);
  3753. break;
  3754. case NFSCTL_GETFH:
  3755. err = nfs_getfh32_trans(karg, arg32);
  3756. break;
  3757. default:
  3758. err = -EINVAL;
  3759. break;
  3760. }
  3761. if(err)
  3762. goto done;
  3763. oldfs = get_fs();
  3764. set_fs(KERNEL_DS);
  3765. err = sys_nfsservctl(cmd, karg, kres);
  3766. set_fs(oldfs);
  3767. if(!err && cmd == NFSCTL_GETFH)
  3768. err = nfs_getfh32_res_trans(kres, res32);
  3769. done:
  3770. if(karg) {
  3771. if(cmd == NFSCTL_UGIDUPDATE) {
  3772. if(karg->ca_umap.ug_ident)
  3773. kfree(karg->ca_umap.ug_ident);
  3774. if(karg->ca_umap.ug_udimap)
  3775. kfree(karg->ca_umap.ug_udimap);
  3776. if(karg->ca_umap.ug_gdimap)
  3777. kfree(karg->ca_umap.ug_gdimap);
  3778. }
  3779. kfree(karg);
  3780. }
  3781. if(kres)
  3782. kfree(kres);
  3783. return err;
  3784. }
  3785. /* Handle adjtimex compatability. */
  3786. struct timex32 {
  3787. u32 modes;
  3788. s32 offset, freq, maxerror, esterror;
  3789. s32 status, constant, precision, tolerance;
  3790. struct timeval32 time;
  3791. s32 tick;
  3792. s32 ppsfreq, jitter, shift, stabil;
  3793. s32 jitcnt, calcnt, errcnt, stbcnt;
  3794. s32  :32; s32  :32; s32  :32; s32  :32;
  3795. s32  :32; s32  :32; s32  :32; s32  :32;
  3796. s32  :32; s32  :32; s32  :32; s32  :32;
  3797. };
  3798. extern int do_adjtimex(struct timex *);
  3799. asmlinkage long
  3800. sys32_adjtimex(struct timex32 *utp)
  3801. {
  3802. struct timex txc;
  3803. int ret;
  3804. memset(&txc, 0, sizeof(struct timex));
  3805. if(get_user(txc.modes, &utp->modes) ||
  3806.    __get_user(txc.offset, &utp->offset) ||
  3807.    __get_user(txc.freq, &utp->freq) ||
  3808.    __get_user(txc.maxerror, &utp->maxerror) ||
  3809.    __get_user(txc.esterror, &utp->esterror) ||
  3810.    __get_user(txc.status, &utp->status) ||
  3811.    __get_user(txc.constant, &utp->constant) ||
  3812.    __get_user(txc.precision, &utp->precision) ||
  3813.    __get_user(txc.tolerance, &utp->tolerance) ||
  3814.    __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
  3815.    __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
  3816.    __get_user(txc.tick, &utp->tick) ||
  3817.    __get_user(txc.ppsfreq, &utp->ppsfreq) ||
  3818.    __get_user(txc.jitter, &utp->jitter) ||
  3819.    __get_user(txc.shift, &utp->shift) ||
  3820.    __get_user(txc.stabil, &utp->stabil) ||
  3821.    __get_user(txc.jitcnt, &utp->jitcnt) ||
  3822.    __get_user(txc.calcnt, &utp->calcnt) ||
  3823.    __get_user(txc.errcnt, &utp->errcnt) ||
  3824.    __get_user(txc.stbcnt, &utp->stbcnt))
  3825. return -EFAULT;
  3826. ret = do_adjtimex(&txc);
  3827. if(put_user(txc.modes, &utp->modes) ||
  3828.    __put_user(txc.offset, &utp->offset) ||
  3829.    __put_user(txc.freq, &utp->freq) ||
  3830.    __put_user(txc.maxerror, &utp->maxerror) ||
  3831.    __put_user(txc.esterror, &utp->esterror) ||
  3832.    __put_user(txc.status, &utp->status) ||
  3833.    __put_user(txc.constant, &utp->constant) ||
  3834.    __put_user(txc.precision, &utp->precision) ||
  3835.    __put_user(txc.tolerance, &utp->tolerance) ||
  3836.    __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
  3837.    __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
  3838.    __put_user(txc.tick, &utp->tick) ||
  3839.    __put_user(txc.ppsfreq, &utp->ppsfreq) ||
  3840.    __put_user(txc.jitter, &utp->jitter) ||
  3841.    __put_user(txc.shift, &utp->shift) ||
  3842.    __put_user(txc.stabil, &utp->stabil) ||
  3843.    __put_user(txc.jitcnt, &utp->jitcnt) ||
  3844.    __put_user(txc.calcnt, &utp->calcnt) ||
  3845.    __put_user(txc.errcnt, &utp->errcnt) ||
  3846.    __put_user(txc.stbcnt, &utp->stbcnt))
  3847. ret = -EFAULT;
  3848. return ret;
  3849. }
  3850. #endif /* NOTYET */