sys_ia32.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:111k
源码类别:

嵌入式Linux

开发平台:

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