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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/s390x/kernel/linux32.c
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  7.  *               Gerhard Tonn (ton@de.ibm.com)   
  8.  *
  9.  *  Conversion between 31bit and 64bit native syscalls.
  10.  *
  11.  * Heavily inspired by the 32-bit Sparc compat code which is 
  12.  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  13.  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  14.  *
  15.  */
  16. #include <linux/config.h>
  17. #include <linux/kernel.h>
  18. #include <linux/sched.h>
  19. #include <linux/fs.h> 
  20. #include <linux/mm.h> 
  21. #include <linux/file.h> 
  22. #include <linux/signal.h>
  23. #include <linux/utime.h>
  24. #include <linux/resource.h>
  25. #include <linux/times.h>
  26. #include <linux/utsname.h>
  27. #include <linux/timex.h>
  28. #include <linux/smp.h>
  29. #include <linux/smp_lock.h>
  30. #include <linux/sem.h>
  31. #include <linux/msg.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/filter.h>
  50. #include <linux/highmem.h>
  51. #include <linux/highuid.h>
  52. #include <linux/mman.h>
  53. #include <linux/ipv6.h>
  54. #include <linux/in.h>
  55. #include <linux/icmpv6.h>
  56. #include <linux/sysctl.h>
  57. #include <asm/types.h>
  58. #include <asm/ipc.h>
  59. #include <asm/uaccess.h>
  60. #include <asm/semaphore.h>
  61. #include <net/scm.h>
  62. #include "linux32.h"
  63. extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
  64. extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
  65. extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
  66. extern asmlinkage long sys_setregid(gid_t, gid_t);
  67. extern asmlinkage long sys_setgid(gid_t);
  68. extern asmlinkage long sys_setreuid(uid_t, uid_t);
  69. extern asmlinkage long sys_setuid(uid_t);
  70. extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
  71. extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
  72. extern asmlinkage long sys_setfsuid(uid_t);
  73. extern asmlinkage long sys_setfsgid(gid_t);
  74.  
  75. /* For this source file, we want overflow handling. */
  76. #undef high2lowuid
  77. #undef high2lowgid
  78. #undef low2highuid
  79. #undef low2highgid
  80. #undef SET_UID16
  81. #undef SET_GID16
  82. #undef NEW_TO_OLD_UID
  83. #undef NEW_TO_OLD_GID
  84. #undef SET_OLDSTAT_UID
  85. #undef SET_OLDSTAT_GID
  86. #undef SET_STAT_UID
  87. #undef SET_STAT_GID
  88. #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
  89. #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
  90. #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
  91. #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
  92. #define SET_UID16(var, uid) var = high2lowuid(uid)
  93. #define SET_GID16(var, gid) var = high2lowgid(gid)
  94. #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
  95. #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
  96. #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
  97. #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
  98. #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
  99. #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
  100. asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
  101. {
  102. return sys_chown(filename, low2highuid(user), low2highgid(group));
  103. }
  104. asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
  105. {
  106. return sys_lchown(filename, low2highuid(user), low2highgid(group));
  107. }
  108. asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
  109. {
  110. return sys_fchown(fd, low2highuid(user), low2highgid(group));
  111. }
  112. asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
  113. {
  114. return sys_setregid(low2highgid(rgid), low2highgid(egid));
  115. }
  116. asmlinkage long sys32_setgid16(u16 gid)
  117. {
  118. return sys_setgid((gid_t)gid);
  119. }
  120. asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
  121. {
  122. return sys_setreuid(low2highuid(ruid), low2highuid(euid));
  123. }
  124. asmlinkage long sys32_setuid16(u16 uid)
  125. {
  126. return sys_setuid((uid_t)uid);
  127. }
  128. asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
  129. {
  130. return sys_setresuid(low2highuid(ruid), low2highuid(euid),
  131. low2highuid(suid));
  132. }
  133. asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
  134. {
  135. int retval;
  136. if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
  137.     !(retval = put_user(high2lowuid(current->euid), euid)))
  138. retval = put_user(high2lowuid(current->suid), suid);
  139. return retval;
  140. }
  141. asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
  142. {
  143. return sys_setresgid(low2highgid(rgid), low2highgid(egid),
  144. low2highgid(sgid));
  145. }
  146. asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
  147. {
  148. int retval;
  149. if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
  150.     !(retval = put_user(high2lowgid(current->egid), egid)))
  151. retval = put_user(high2lowgid(current->sgid), sgid);
  152. return retval;
  153. }
  154. asmlinkage long sys32_setfsuid16(u16 uid)
  155. {
  156. return sys_setfsuid((uid_t)uid);
  157. }
  158. asmlinkage long sys32_setfsgid16(u16 gid)
  159. {
  160. return sys_setfsgid((gid_t)gid);
  161. }
  162. asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
  163. {
  164. u16 groups[NGROUPS];
  165. int i,j;
  166. if (gidsetsize < 0)
  167. return -EINVAL;
  168. i = current->ngroups;
  169. if (gidsetsize) {
  170. if (i > gidsetsize)
  171. return -EINVAL;
  172. for(j=0;j<i;j++)
  173. groups[j] = current->groups[j];
  174. if (copy_to_user(grouplist, groups, sizeof(u16)*i))
  175. return -EFAULT;
  176. }
  177. return i;
  178. }
  179. asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
  180. {
  181. u16 groups[NGROUPS];
  182. int i;
  183. if (!capable(CAP_SETGID))
  184. return -EPERM;
  185. if ((unsigned) gidsetsize > NGROUPS)
  186. return -EINVAL;
  187. if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
  188. return -EFAULT;
  189. for (i = 0 ; i < gidsetsize ; i++)
  190. current->groups[i] = (gid_t)groups[i];
  191. current->ngroups = gidsetsize;
  192. return 0;
  193. }
  194. asmlinkage long sys32_getuid16(void)
  195. {
  196. return high2lowuid(current->uid);
  197. }
  198. asmlinkage long sys32_geteuid16(void)
  199. {
  200. return high2lowuid(current->euid);
  201. }
  202. asmlinkage long sys32_getgid16(void)
  203. {
  204. return high2lowgid(current->gid);
  205. }
  206. asmlinkage long sys32_getegid16(void)
  207. {
  208. return high2lowgid(current->egid);
  209. }
  210. /* 32-bit timeval and related flotsam.  */
  211. struct timeval32
  212. {
  213.     int tv_sec, tv_usec;
  214. };
  215. struct itimerval32
  216. {
  217.     struct timeval32 it_interval;
  218.     struct timeval32 it_value;
  219. };
  220. static inline long get_tv32(struct timeval *o, struct timeval32 *i)
  221. {
  222. return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
  223. (__get_user(o->tv_sec, &i->tv_sec) |
  224.  __get_user(o->tv_usec, &i->tv_usec)));
  225. }
  226. static inline long put_tv32(struct timeval32 *o, struct timeval *i)
  227. {
  228. return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
  229. (__put_user(i->tv_sec, &o->tv_sec) |
  230.  __put_user(i->tv_usec, &o->tv_usec)));
  231. }
  232. static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
  233. {
  234. return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
  235. (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
  236.  __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
  237.  __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
  238.  __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
  239. }
  240. static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
  241. {
  242. return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
  243. (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
  244.  __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
  245.  __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
  246.  __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
  247. }
  248. struct msgbuf32 { s32 mtype; char mtext[1]; };
  249. struct ipc_perm32
  250. {
  251. key_t       key;
  252.         __kernel_uid_t32  uid;
  253.         __kernel_gid_t32  gid;
  254.         __kernel_uid_t32  cuid;
  255.         __kernel_gid_t32  cgid;
  256.         __kernel_mode_t32 mode;
  257.         unsigned short  seq;
  258. };
  259. struct semid_ds32 {
  260.         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
  261.         __kernel_time_t32 sem_otime;              /* last semop time */
  262.         __kernel_time_t32 sem_ctime;              /* last change time */
  263.         u32 sem_base;              /* ptr to first semaphore in array */
  264.         u32 sem_pending;          /* pending operations to be processed */
  265.         u32 sem_pending_last;    /* last pending operation */
  266.         u32 undo;                  /* undo requests on this array */
  267.         unsigned short  sem_nsems;              /* no. of semaphores in array */
  268. };
  269. struct semid64_ds32 {
  270. struct ipc64_perm sem_perm;   /* this structure is the same on sparc32 and sparc64 */
  271. unsigned int   __pad1;
  272. __kernel_time_t32 sem_otime;
  273. unsigned int   __pad2;
  274. __kernel_time_t32 sem_ctime;
  275. u32 sem_nsems;
  276. u32 __unused1;
  277. u32 __unused2;
  278. };
  279. struct msqid_ds32
  280. {
  281.         struct ipc_perm32 msg_perm;
  282.         u32 msg_first;
  283.         u32 msg_last;
  284.         __kernel_time_t32 msg_stime;
  285.         __kernel_time_t32 msg_rtime;
  286.         __kernel_time_t32 msg_ctime;
  287.         u32 wwait;
  288.         u32 rwait;
  289.         unsigned short msg_cbytes;
  290.         unsigned short msg_qnum;  
  291.         unsigned short msg_qbytes;
  292.         __kernel_ipc_pid_t32 msg_lspid;
  293.         __kernel_ipc_pid_t32 msg_lrpid;
  294. };
  295. struct msqid64_ds32 {
  296. struct ipc64_perm msg_perm;
  297. unsigned int   __pad1;
  298. __kernel_time_t32 msg_stime;
  299. unsigned int   __pad2;
  300. __kernel_time_t32 msg_rtime;
  301. unsigned int   __pad3;
  302. __kernel_time_t32 msg_ctime;
  303. unsigned int  msg_cbytes;
  304. unsigned int  msg_qnum;
  305. unsigned int  msg_qbytes;
  306. __kernel_pid_t32 msg_lspid;
  307. __kernel_pid_t32 msg_lrpid;
  308. unsigned int  __unused1;
  309. unsigned int  __unused2;
  310. };
  311. struct shmid_ds32 {
  312. struct ipc_perm32       shm_perm;
  313. int                     shm_segsz;
  314. __kernel_time_t32       shm_atime;
  315. __kernel_time_t32       shm_dtime;
  316. __kernel_time_t32       shm_ctime;
  317. __kernel_ipc_pid_t32    shm_cpid; 
  318. __kernel_ipc_pid_t32    shm_lpid; 
  319. unsigned short          shm_nattch;
  320. };
  321. struct shmid64_ds32 {
  322. struct ipc64_perm shm_perm;
  323. unsigned int __pad1;
  324. __kernel_time_t32 shm_atime;
  325. unsigned int __pad2;
  326. __kernel_time_t32 shm_dtime;
  327. unsigned int __pad3;
  328. __kernel_time_t32 shm_ctime;
  329. __kernel_size_t32 shm_segsz;
  330. __kernel_pid_t32 shm_cpid;
  331. __kernel_pid_t32 shm_lpid;
  332. unsigned int shm_nattch;
  333. unsigned int __unused1;
  334. unsigned int __unused2;
  335. };
  336.                                                         
  337. /*
  338.  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
  339.  *
  340.  * This is really horribly ugly.
  341.  */
  342. #define IPCOP_MASK(__x) (1UL << (__x))
  343. static int do_sys32_semctl(int first, int second, int third, void *uptr)
  344. {
  345. union semun fourth;
  346. u32 pad;
  347. int err = -EINVAL;
  348. if (!uptr)
  349. goto out;
  350. err = -EFAULT;
  351. if (get_user (pad, (u32 *)uptr))
  352. goto out;
  353. if(third == SETVAL)
  354. fourth.val = (int)pad;
  355. else
  356. fourth.__pad = (void *)A(pad);
  357. if (IPCOP_MASK (third) &
  358.     (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
  359.      IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
  360.      IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
  361. err = sys_semctl (first, second, third, fourth);
  362. } else if (third & IPC_64) {
  363. struct semid64_ds s;
  364. struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
  365. mm_segment_t old_fs;
  366. int need_back_translation;
  367. if (third == (IPC_SET|IPC_64)) {
  368. err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
  369. err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
  370. err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
  371. if (err)
  372. goto out;
  373. fourth.__pad = &s;
  374. }
  375. need_back_translation =
  376. (IPCOP_MASK (third) &
  377.  (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
  378. if (need_back_translation)
  379. fourth.__pad = &s;
  380. old_fs = get_fs ();
  381. set_fs (KERNEL_DS);
  382. err = sys_semctl (first, second, third, fourth);
  383. set_fs (old_fs);
  384. if (need_back_translation) {
  385. int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
  386. err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
  387. err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
  388. err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
  389. err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
  390. err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
  391. err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
  392. err2 |= __put_user (s.sem_otime, &usp->sem_otime);
  393. err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
  394. err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
  395. if (err2) err = -EFAULT;
  396. }
  397. } else {
  398. struct semid_ds s;
  399. struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
  400. mm_segment_t old_fs;
  401. int need_back_translation;
  402. if (third == IPC_SET) {
  403. err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
  404. err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
  405. err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
  406. if (err)
  407. goto out;
  408. fourth.__pad = &s;
  409. }
  410. need_back_translation =
  411. (IPCOP_MASK (third) &
  412.  (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
  413. if (need_back_translation)
  414. fourth.__pad = &s;
  415. old_fs = get_fs ();
  416. set_fs (KERNEL_DS);
  417. err = sys_semctl (first, second, third, fourth);
  418. set_fs (old_fs);
  419. if (need_back_translation) {
  420. int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
  421. err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
  422. err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
  423. err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
  424. err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
  425. err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
  426. err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
  427. err2 |= __put_user (s.sem_otime, &usp->sem_otime);
  428. err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
  429. err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
  430. if (err2) err = -EFAULT;
  431. }
  432. }
  433. out:
  434. return err;
  435. }
  436. static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
  437. {
  438. struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
  439. struct msgbuf32 *up = (struct msgbuf32 *)uptr;
  440. mm_segment_t old_fs;
  441. int err;
  442. if (!p)
  443. return -ENOMEM;
  444. err = get_user (p->mtype, &up->mtype);
  445. err |= __copy_from_user (p->mtext, &up->mtext, second);
  446. if (err)
  447. goto out;
  448. old_fs = get_fs ();
  449. set_fs (KERNEL_DS);
  450. err = sys_msgsnd (first, p, second, third);
  451. set_fs (old_fs);
  452. out:
  453. kfree (p);
  454. return err;
  455. }
  456. static int do_sys32_msgrcv (int first, int second, int msgtyp, int third,
  457.     int version, void *uptr)
  458. {
  459. struct msgbuf32 *up;
  460. struct msgbuf *p;
  461. mm_segment_t old_fs;
  462. int err;
  463. if (!version) {
  464. struct ipc_kludge_32 *uipck = (struct ipc_kludge_32 *)uptr;
  465. struct ipc_kludge_32 ipck;
  466. err = -EINVAL;
  467. if (!uptr)
  468. goto out;
  469. err = -EFAULT;
  470. if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge_32)))
  471. goto out;
  472. uptr = (void *)A(ipck.msgp);
  473. msgtyp = ipck.msgtyp;
  474. }
  475. err = -ENOMEM;
  476. p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
  477. if (!p)
  478. goto out;
  479. old_fs = get_fs ();
  480. set_fs (KERNEL_DS);
  481. err = sys_msgrcv (first, p, second + 4, msgtyp, third);
  482. set_fs (old_fs);
  483. if (err < 0)
  484. goto free_then_out;
  485. up = (struct msgbuf32 *)uptr;
  486. if (put_user (p->mtype, &up->mtype) ||
  487.     __copy_to_user (&up->mtext, p->mtext, err))
  488. err = -EFAULT;
  489. free_then_out:
  490. kfree (p);
  491. out:
  492. return err;
  493. }
  494. static int do_sys32_msgctl (int first, int second, void *uptr)
  495. {
  496. int err;
  497. if (IPCOP_MASK (second) &
  498.     (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
  499.      IPCOP_MASK (IPC_RMID))) {
  500. err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
  501. } else if (second & IPC_64) {
  502. struct msqid64_ds m;
  503. struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
  504. mm_segment_t old_fs;
  505. if (second == (IPC_SET|IPC_64)) {
  506. err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
  507. err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
  508. err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
  509. err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
  510. if (err)
  511. goto out;
  512. }
  513. old_fs = get_fs ();
  514. set_fs (KERNEL_DS);
  515. err = sys_msgctl (first, second, (struct msqid_ds *)&m);
  516. set_fs (old_fs);
  517. if (IPCOP_MASK (second) &
  518.     (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
  519. int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
  520. err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
  521. err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
  522. err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
  523. err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
  524. err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
  525. err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
  526. err2 |= __put_user (m.msg_stime, &up->msg_stime);
  527. err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
  528. err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
  529. err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
  530. err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
  531. err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
  532. err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
  533. err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
  534. if (err2)
  535. err = -EFAULT;
  536. }
  537. } else {
  538. struct msqid_ds m;
  539. struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
  540. mm_segment_t old_fs;
  541. if (second == IPC_SET) {
  542. err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
  543. err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
  544. err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
  545. err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
  546. if (err)
  547. goto out;
  548. }
  549. old_fs = get_fs ();
  550. set_fs (KERNEL_DS);
  551. err = sys_msgctl (first, second, &m);
  552. set_fs (old_fs);
  553. if (IPCOP_MASK (second) &
  554.     (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
  555. int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
  556. err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
  557. err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
  558. err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
  559. err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
  560. err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
  561. err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
  562. err2 |= __put_user (m.msg_stime, &up->msg_stime);
  563. err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
  564. err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
  565. err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
  566. err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
  567. err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
  568. err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
  569. err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
  570. if (err2)
  571. err = -EFAULT;
  572. }
  573. }
  574. out:
  575. return err;
  576. }
  577. static int do_sys32_shmat (int first, int second, int third, int version, void *uptr)
  578. {
  579. unsigned long raddr;
  580. u32 *uaddr = (u32 *)A((u32)third);
  581. int err = -EINVAL;
  582. if (version == 1)
  583. goto out;
  584. err = sys_shmat (first, uptr, second, &raddr);
  585. if (err)
  586. goto out;
  587. err = put_user (raddr, uaddr);
  588. out:
  589. return err;
  590. }
  591. static int do_sys32_shmctl (int first, int second, void *uptr)
  592. {
  593. int err;
  594. if (IPCOP_MASK (second) &
  595.     (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
  596.      IPCOP_MASK (IPC_RMID))) {
  597. if (second == (IPC_INFO|IPC_64))
  598. second = IPC_INFO; /* So that we don't have to translate it */
  599. err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
  600. } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
  601. struct shmid64_ds s;
  602. struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
  603. mm_segment_t old_fs;
  604. if (second == (IPC_SET|IPC_64)) {
  605. err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
  606. err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
  607. err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
  608. if (err)
  609. goto out;
  610. }
  611. old_fs = get_fs ();
  612. set_fs (KERNEL_DS);
  613. err = sys_shmctl (first, second, (struct shmid_ds *)&s);
  614. set_fs (old_fs);
  615. if (err < 0)
  616. goto out;
  617. /* Mask it even in this case so it becomes a CSE. */
  618. if (IPCOP_MASK (second) &
  619.     (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
  620. int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
  621. err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
  622. err2 |= __put_user (high2lowgid(s.shm_perm.gid), &up->shm_perm.gid);
  623. err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
  624. err2 |= __put_user (high2lowgid(s.shm_perm.cgid), &up->shm_perm.cgid);
  625. err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
  626. err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
  627. err2 |= __put_user (s.shm_atime, &up->shm_atime);
  628. err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
  629. err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
  630. err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
  631. err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
  632. err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
  633. err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
  634. if (err2)
  635. err = -EFAULT;
  636. }
  637. } else {
  638. struct shmid_ds s;
  639. struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
  640. mm_segment_t old_fs;
  641. second &= ~IPC_64;
  642. if (second == IPC_SET) {
  643. err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
  644. err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
  645. err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
  646. if (err)
  647. goto out;
  648. }
  649. old_fs = get_fs ();
  650. set_fs (KERNEL_DS);
  651. err = sys_shmctl (first, second, &s);
  652. set_fs (old_fs);
  653. if (err < 0)
  654. goto out;
  655. /* Mask it even in this case so it becomes a CSE. */
  656. if (second == SHM_INFO) {
  657. struct shm_info32 {
  658. int used_ids;
  659. u32 shm_tot, shm_rss, shm_swp;
  660. u32 swap_attempts, swap_successes;
  661. } *uip = (struct shm_info32 *)uptr;
  662. struct shm_info *kp = (struct shm_info *)&s;
  663. int err2 = put_user (kp->used_ids, &uip->used_ids);
  664. err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
  665. err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
  666. err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
  667. err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts);
  668. err2 |= __put_user (kp->swap_successes, &uip->swap_successes);
  669. if (err2)
  670. err = -EFAULT;
  671. } else if (IPCOP_MASK (second) &
  672.    (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
  673. int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
  674. err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
  675. err2 |= __put_user (high2lowgid(s.shm_perm.gid), &up->shm_perm.gid);
  676. err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
  677. err2 |= __put_user (high2lowgid(s.shm_perm.cgid), &up->shm_perm.cgid);
  678. err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
  679. err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
  680. err2 |= __put_user (s.shm_atime, &up->shm_atime);
  681. err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
  682. err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
  683. err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
  684. err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
  685. err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
  686. err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
  687. if (err2)
  688. err = -EFAULT;
  689. }
  690. }
  691. out:
  692. return err;
  693. }
  694. asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
  695. {
  696. int version, err;
  697. version = call >> 16; /* hack for backward compatibility */
  698. call &= 0xffff;
  699. if(version)
  700. return -EINVAL;
  701. if (call <= SEMCTL)
  702. switch (call) {
  703. case SEMOP:
  704. /* struct sembuf is the same on 32 and 64bit :)) */
  705. err = sys_semop (first, (struct sembuf *)AA(ptr), second);
  706. goto out;
  707. case SEMGET:
  708. err = sys_semget (first, second, third);
  709. goto out;
  710. case SEMCTL:
  711. err = do_sys32_semctl (first, second, third, (void *)AA(ptr));
  712. goto out;
  713. default:
  714. err = -EINVAL;
  715. goto out;
  716. };
  717. if (call <= MSGCTL) 
  718. switch (call) {
  719. case MSGSND:
  720. err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr));
  721. goto out;
  722. case MSGRCV:
  723. err = do_sys32_msgrcv (first, second, 0, third,
  724.        version, (void *)AA(ptr));
  725. goto out;
  726. case MSGGET:
  727. err = sys_msgget ((key_t) first, second);
  728. goto out;
  729. case MSGCTL:
  730. err = do_sys32_msgctl (first, second, (void *)AA(ptr));
  731. goto out;
  732. default:
  733. err = -EINVAL;
  734. goto out;
  735. }
  736. if (call <= SHMCTL) 
  737. switch (call) {
  738. case SHMAT:
  739. err = do_sys32_shmat (first, second, third,
  740.       version, (void *)AA(ptr));
  741. goto out;
  742. case SHMDT: 
  743. err = sys_shmdt ((char *)AA(ptr));
  744. goto out;
  745. case SHMGET:
  746. err = sys_shmget (first, second, third);
  747. goto out;
  748. case SHMCTL:
  749. err = do_sys32_shmctl (first, second, (void *)AA(ptr));
  750. goto out;
  751. default:
  752. err = -EINVAL;
  753. goto out;
  754. }
  755. err = -EINVAL;
  756. out:
  757. return err;
  758. }
  759. static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
  760. {
  761. int err;
  762. err = get_user(kfl->l_type, &ufl->l_type);
  763. err |= __get_user(kfl->l_whence, &ufl->l_whence);
  764. err |= __get_user(kfl->l_start, &ufl->l_start);
  765. err |= __get_user(kfl->l_len, &ufl->l_len);
  766. err |= __get_user(kfl->l_pid, &ufl->l_pid);
  767. return err;
  768. }
  769. static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
  770. {
  771. int err;
  772. err = __put_user(kfl->l_type, &ufl->l_type);
  773. err |= __put_user(kfl->l_whence, &ufl->l_whence);
  774. err |= __put_user(kfl->l_start, &ufl->l_start);
  775. err |= __put_user(kfl->l_len, &ufl->l_len);
  776. err |= __put_user(kfl->l_pid, &ufl->l_pid);
  777. return err;
  778. }
  779. extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
  780. asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
  781. {
  782. switch (cmd) {
  783. case F_GETLK:
  784. case F_SETLK:
  785. case F_SETLKW:
  786. {
  787. struct flock f;
  788. mm_segment_t old_fs;
  789. long ret;
  790. if(get_flock(&f, (struct flock32 *)arg))
  791. return -EFAULT;
  792. old_fs = get_fs(); set_fs (KERNEL_DS);
  793. ret = sys_fcntl(fd, cmd, (unsigned long)&f);
  794. set_fs (old_fs);
  795. if (ret) return ret;
  796. if (f.l_start >= 0x7fffffffUL ||
  797.     f.l_len >= 0x7fffffffUL ||
  798.     f.l_start + f.l_len >= 0x7fffffffUL)
  799. return -EOVERFLOW;
  800. if(put_flock(&f, (struct flock32 *)arg))
  801. return -EFAULT;
  802. return 0;
  803. }
  804. default:
  805. return sys_fcntl(fd, cmd, (unsigned long)arg);
  806. }
  807. }
  808. asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
  809. {
  810. if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
  811. return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg);
  812. return sys32_fcntl(fd, cmd, arg);
  813. }
  814. struct dqblk32 {
  815.     __u32 dqb_bhardlimit;
  816.     __u32 dqb_bsoftlimit;
  817.     __u32 dqb_curblocks;
  818.     __u32 dqb_ihardlimit;
  819.     __u32 dqb_isoftlimit;
  820.     __u32 dqb_curinodes;
  821.     __kernel_time_t32 dqb_btime;
  822.     __kernel_time_t32 dqb_itime;
  823. };
  824.                                 
  825. extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
  826. asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
  827. {
  828. int cmds = cmd >> SUBCMDSHIFT;
  829. int err;
  830. struct dqblk d;
  831. mm_segment_t old_fs;
  832. char *spec;
  833. switch (cmds) {
  834. case Q_GETQUOTA:
  835. break;
  836. case Q_SETQUOTA:
  837. case Q_SETUSE:
  838. case Q_SETQLIM:
  839. if (copy_from_user (&d, (struct dqblk32 *)addr,
  840.     sizeof (struct dqblk32)))
  841. return -EFAULT;
  842. d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
  843. d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
  844. break;
  845. default:
  846. return sys_quotactl(cmd, special,
  847.     id, (caddr_t)addr);
  848. }
  849. spec = getname (special);
  850. err = PTR_ERR(spec);
  851. if (IS_ERR(spec)) return err;
  852. old_fs = get_fs ();
  853. set_fs (KERNEL_DS);
  854. err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
  855. set_fs (old_fs);
  856. putname (spec);
  857. if (err)
  858. return err;
  859. if (cmds == Q_GETQUOTA) {
  860. __kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
  861. ((struct dqblk32 *)&d)->dqb_itime = i;
  862. ((struct dqblk32 *)&d)->dqb_btime = b;
  863. if (copy_to_user ((struct dqblk32 *)addr, &d,
  864.   sizeof (struct dqblk32)))
  865. return -EFAULT;
  866. }
  867. return 0;
  868. }
  869. static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
  870. {
  871. int err;
  872. err = put_user (kbuf->f_type, &ubuf->f_type);
  873. err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
  874. err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
  875. err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
  876. err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
  877. err |= __put_user (kbuf->f_files, &ubuf->f_files);
  878. err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
  879. err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
  880. err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
  881. err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
  882. return err;
  883. }
  884. extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
  885. asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
  886. {
  887. int ret;
  888. struct statfs s;
  889. mm_segment_t old_fs = get_fs();
  890. char *pth;
  891. pth = getname (path);
  892. ret = PTR_ERR(pth);
  893. if (!IS_ERR(pth)) {
  894. set_fs (KERNEL_DS);
  895. ret = sys_statfs((const char *)pth, &s);
  896. set_fs (old_fs);
  897. putname (pth);
  898. if (put_statfs(buf, &s))
  899. return -EFAULT;
  900. }
  901. return ret;
  902. }
  903. extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
  904. asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
  905. {
  906. int ret;
  907. struct statfs s;
  908. mm_segment_t old_fs = get_fs();
  909. set_fs (KERNEL_DS);
  910. ret = sys_fstatfs(fd, &s);
  911. set_fs (old_fs);
  912. if (put_statfs(buf, &s))
  913. return -EFAULT;
  914. return ret;
  915. }
  916. extern asmlinkage long sys_truncate(const char * path, unsigned long length);
  917. extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
  918. asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
  919. {
  920. if ((int)high < 0)
  921. return -EINVAL;
  922. else
  923. return sys_truncate(path, (high << 32) | low);
  924. }
  925. asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
  926. {
  927. if ((int)high < 0)
  928. return -EINVAL;
  929. else
  930. return sys_ftruncate(fd, (high << 32) | low);
  931. }
  932. extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
  933. struct utimbuf32 {
  934. __kernel_time_t32 actime, modtime;
  935. };
  936. asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
  937. {
  938. struct utimbuf t;
  939. mm_segment_t old_fs;
  940. int ret;
  941. char *filenam;
  942. if (!times)
  943. return sys_utime(filename, NULL);
  944. if (get_user (t.actime, &times->actime) ||
  945.     __get_user (t.modtime, &times->modtime))
  946. return -EFAULT;
  947. filenam = getname (filename);
  948. ret = PTR_ERR(filenam);
  949. if (!IS_ERR(filenam)) {
  950. old_fs = get_fs();
  951. set_fs (KERNEL_DS); 
  952. ret = sys_utime(filenam, &t);
  953. set_fs (old_fs);
  954. putname (filenam);
  955. }
  956. return ret;
  957. }
  958. struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
  959. typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
  960. typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
  961. static long do_readv_writev32(int type, struct file *file,
  962.       const struct iovec32 *vector, u32 count)
  963. {
  964. unsigned long tot_len;
  965. struct iovec iovstack[UIO_FASTIOV];
  966. struct iovec *iov=iovstack, *ivp;
  967. struct inode *inode;
  968. long retval, i;
  969. io_fn_t fn;
  970. iov_fn_t fnv;
  971. /* First get the "struct iovec" from user memory and
  972.  * verify all the pointers
  973.  */
  974. if (!count)
  975. return 0;
  976. if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
  977. return -EFAULT;
  978. if (count > UIO_MAXIOV)
  979. return -EINVAL;
  980. if (count > UIO_FASTIOV) {
  981. iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
  982. if (!iov)
  983. return -ENOMEM;
  984. }
  985. tot_len = 0;
  986. i = count;
  987. ivp = iov;
  988. while(i > 0) {
  989. u32 len;
  990. u32 buf;
  991. __get_user(len, &vector->iov_len);
  992. __get_user(buf, &vector->iov_base);
  993. tot_len += len;
  994. ivp->iov_base = (void *)A(buf);
  995. ivp->iov_len = (__kernel_size_t) len;
  996. vector++;
  997. ivp++;
  998. i--;
  999. }
  1000. inode = file->f_dentry->d_inode;
  1001. /* VERIFY_WRITE actually means a read, as we write to user space */
  1002. retval = locks_verify_area((type == VERIFY_WRITE
  1003.     ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
  1004.    inode, file, file->f_pos, tot_len);
  1005. if (retval)
  1006. goto out;
  1007. /* VERIFY_WRITE actually means a read, as we write to user space */
  1008. fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
  1009. if (fnv) {
  1010. retval = fnv(file, iov, count, &file->f_pos);
  1011. goto out;
  1012. }
  1013. fn = (type == VERIFY_WRITE ? file->f_op->read :
  1014.       (io_fn_t) file->f_op->write);
  1015. ivp = iov;
  1016. while (count > 0) {
  1017. void * base;
  1018. int len, nr;
  1019. base = ivp->iov_base;
  1020. len = ivp->iov_len;
  1021. ivp++;
  1022. count--;
  1023. nr = fn(file, base, len, &file->f_pos);
  1024. if (nr < 0) {
  1025. if (!retval)
  1026. retval = nr;
  1027. break;
  1028. }
  1029. retval += nr;
  1030. if (nr != len)
  1031. break;
  1032. }
  1033. out:
  1034. if (iov != iovstack)
  1035. kfree(iov);
  1036. return retval;
  1037. }
  1038. asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
  1039. {
  1040. struct file *file;
  1041. long ret = -EBADF;
  1042. file = fget(fd);
  1043. if(!file)
  1044. goto bad_file;
  1045. if (file->f_op && (file->f_mode & FMODE_READ) &&
  1046.     (file->f_op->readv || file->f_op->read))
  1047. ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
  1048. fput(file);
  1049. bad_file:
  1050. return ret;
  1051. }
  1052. asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
  1053. {
  1054. struct file *file;
  1055. int ret = -EBADF;
  1056. file = fget(fd);
  1057. if(!file)
  1058. goto bad_file;
  1059. if (file->f_op && (file->f_mode & FMODE_WRITE) &&
  1060.     (file->f_op->writev || file->f_op->write))
  1061. ret = do_readv_writev32(VERIFY_READ, file, vector, count);
  1062. fput(file);
  1063. bad_file:
  1064. return ret;
  1065. }
  1066. /* readdir & getdents */
  1067. #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
  1068. #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
  1069. struct old_linux_dirent32 {
  1070. u32 d_ino;
  1071. u32 d_offset;
  1072. unsigned short d_namlen;
  1073. char d_name[1];
  1074. };
  1075. struct readdir_callback32 {
  1076. struct old_linux_dirent32 * dirent;
  1077. int count;
  1078. };
  1079. static int fillonedir(void * __buf, const char * name, int namlen,
  1080.       loff_t offset, ino_t ino, unsigned int d_type)
  1081. {
  1082. struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
  1083. struct old_linux_dirent32 * dirent;
  1084. if (buf->count)
  1085. return -EINVAL;
  1086. buf->count++;
  1087. dirent = buf->dirent;
  1088. put_user(ino, &dirent->d_ino);
  1089. put_user(offset, &dirent->d_offset);
  1090. put_user(namlen, &dirent->d_namlen);
  1091. copy_to_user(dirent->d_name, name, namlen);
  1092. put_user(0, dirent->d_name + namlen);
  1093. return 0;
  1094. }
  1095. asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
  1096. {
  1097. int error = -EBADF;
  1098. struct file * file;
  1099. struct readdir_callback32 buf;
  1100. file = fget(fd);
  1101. if (!file)
  1102. goto out;
  1103. buf.count = 0;
  1104. buf.dirent = dirent;
  1105. error = vfs_readdir(file, fillonedir, &buf);
  1106. if (error < 0)
  1107. goto out_putf;
  1108. error = buf.count;
  1109. out_putf:
  1110. fput(file);
  1111. out:
  1112. return error;
  1113. }
  1114. struct linux_dirent32 {
  1115. u32 d_ino;
  1116. u32 d_off;
  1117. unsigned short d_reclen;
  1118. char d_name[1];
  1119. };
  1120. struct getdents_callback32 {
  1121. struct linux_dirent32 * current_dir;
  1122. struct linux_dirent32 * previous;
  1123. int count;
  1124. int error;
  1125. };
  1126. static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
  1127.    unsigned int d_type)
  1128. {
  1129. struct linux_dirent32 * dirent;
  1130. struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
  1131. int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
  1132. buf->error = -EINVAL; /* only used if we fail.. */
  1133. if (reclen > buf->count)
  1134. return -EINVAL;
  1135. dirent = buf->previous;
  1136. if (dirent)
  1137. put_user(offset, &dirent->d_off);
  1138. dirent = buf->current_dir;
  1139. buf->previous = dirent;
  1140. put_user(ino, &dirent->d_ino);
  1141. put_user(reclen, &dirent->d_reclen);
  1142. copy_to_user(dirent->d_name, name, namlen);
  1143. put_user(0, dirent->d_name + namlen);
  1144. ((char *) dirent) += reclen;
  1145. buf->current_dir = dirent;
  1146. buf->count -= reclen;
  1147. return 0;
  1148. }
  1149. asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
  1150. {
  1151. struct file * file;
  1152. struct linux_dirent32 * lastdirent;
  1153. struct getdents_callback32 buf;
  1154. int error = -EBADF;
  1155. file = fget(fd);
  1156. if (!file)
  1157. goto out;
  1158. buf.current_dir = dirent;
  1159. buf.previous = NULL;
  1160. buf.count = count;
  1161. buf.error = 0;
  1162. error = vfs_readdir(file, filldir, &buf);
  1163. if (error < 0)
  1164. goto out_putf;
  1165. lastdirent = buf.previous;
  1166. error = buf.error;
  1167. if(lastdirent) {
  1168. put_user(file->f_pos, &lastdirent->d_off);
  1169. error = count - buf.count;
  1170. }
  1171. out_putf:
  1172. fput(file);
  1173. out:
  1174. return error;
  1175. }
  1176. /* end of readdir & getdents */
  1177. /*
  1178.  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
  1179.  * 64-bit unsigned longs.
  1180.  */
  1181. static inline int
  1182. get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
  1183. {
  1184. if (ufdset) {
  1185. unsigned long odd;
  1186. if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
  1187. return -EFAULT;
  1188. odd = n & 1UL;
  1189. n &= ~1UL;
  1190. while (n) {
  1191. unsigned long h, l;
  1192. __get_user(l, ufdset);
  1193. __get_user(h, ufdset+1);
  1194. ufdset += 2;
  1195. *fdset++ = h << 32 | l;
  1196. n -= 2;
  1197. }
  1198. if (odd)
  1199. __get_user(*fdset, ufdset);
  1200. } else {
  1201. /* Tricky, must clear full unsigned long in the
  1202.  * kernel fdset at the end, this makes sure that
  1203.  * actually happens.
  1204.  */
  1205. memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
  1206. }
  1207. return 0;
  1208. }
  1209. static inline void
  1210. set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
  1211. {
  1212. unsigned long odd;
  1213. if (!ufdset)
  1214. return;
  1215. odd = n & 1UL;
  1216. n &= ~1UL;
  1217. while (n) {
  1218. unsigned long h, l;
  1219. l = *fdset++;
  1220. h = l >> 32;
  1221. __put_user(l, ufdset);
  1222. __put_user(h, ufdset+1);
  1223. ufdset += 2;
  1224. n -= 2;
  1225. }
  1226. if (odd)
  1227. __put_user(*fdset, ufdset);
  1228. }
  1229. #define MAX_SELECT_SECONDS 
  1230. ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
  1231. asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
  1232. {
  1233. fd_set_bits fds;
  1234. struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
  1235. char *bits;
  1236. unsigned long nn;
  1237. long timeout;
  1238. int ret, size;
  1239. timeout = MAX_SCHEDULE_TIMEOUT;
  1240. if (tvp) {
  1241. time_t sec, usec;
  1242. if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
  1243.     || (ret = __get_user(sec, &tvp->tv_sec))
  1244.     || (ret = __get_user(usec, &tvp->tv_usec)))
  1245. goto out_nofds;
  1246. ret = -EINVAL;
  1247. if(sec < 0 || usec < 0)
  1248. goto out_nofds;
  1249. if ((unsigned long) sec < MAX_SELECT_SECONDS) {
  1250. timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
  1251. timeout += sec * (unsigned long) HZ;
  1252. }
  1253. }
  1254. ret = -EINVAL;
  1255. if (n < 0)
  1256. goto out_nofds;
  1257. if (n > current->files->max_fdset)
  1258. n = current->files->max_fdset;
  1259. /*
  1260.  * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
  1261.  * since we used fdset we need to allocate memory in units of
  1262.  * long-words. 
  1263.  */
  1264. ret = -ENOMEM;
  1265. size = FDS_BYTES(n);
  1266. bits = kmalloc(6 * size, GFP_KERNEL);
  1267. if (!bits)
  1268. goto out_nofds;
  1269. fds.in      = (unsigned long *)  bits;
  1270. fds.out     = (unsigned long *) (bits +   size);
  1271. fds.ex      = (unsigned long *) (bits + 2*size);
  1272. fds.res_in  = (unsigned long *) (bits + 3*size);
  1273. fds.res_out = (unsigned long *) (bits + 4*size);
  1274. fds.res_ex  = (unsigned long *) (bits + 5*size);
  1275. nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
  1276. if ((ret = get_fd_set32(nn, fds.in, inp)) ||
  1277.     (ret = get_fd_set32(nn, fds.out, outp)) ||
  1278.     (ret = get_fd_set32(nn, fds.ex, exp)))
  1279. goto out;
  1280. zero_fd_set(n, fds.res_in);
  1281. zero_fd_set(n, fds.res_out);
  1282. zero_fd_set(n, fds.res_ex);
  1283. ret = do_select(n, &fds, &timeout);
  1284. if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
  1285. time_t sec = 0, usec = 0;
  1286. if (timeout) {
  1287. sec = timeout / HZ;
  1288. usec = timeout % HZ;
  1289. usec *= (1000000/HZ);
  1290. }
  1291. put_user(sec, &tvp->tv_sec);
  1292. put_user(usec, &tvp->tv_usec);
  1293. }
  1294. if (ret < 0)
  1295. goto out;
  1296. if (!ret) {
  1297. ret = -ERESTARTNOHAND;
  1298. if (signal_pending(current))
  1299. goto out;
  1300. ret = 0;
  1301. }
  1302. set_fd_set32(nn, inp, fds.res_in);
  1303. set_fd_set32(nn, outp, fds.res_out);
  1304. set_fd_set32(nn, exp, fds.res_ex);
  1305. out:
  1306. kfree(bits);
  1307. out_nofds:
  1308. return ret;
  1309. }
  1310. static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
  1311. {
  1312. unsigned long ino, blksize, blocks;
  1313. kdev_t dev, rdev;
  1314. umode_t mode;
  1315. nlink_t nlink;
  1316. uid_t uid;
  1317. gid_t gid;
  1318. off_t size;
  1319. time_t atime, mtime, ctime;
  1320. int err;
  1321. /* Stream the loads of inode data into the load buffer,
  1322.  * then we push it all into the store buffer below.  This
  1323.  * should give optimal cache performance.
  1324.  */
  1325. ino = inode->i_ino;
  1326. dev = inode->i_dev;
  1327. mode = inode->i_mode;
  1328. nlink = inode->i_nlink;
  1329. uid = inode->i_uid;
  1330. gid = inode->i_gid;
  1331. rdev = inode->i_rdev;
  1332. size = inode->i_size;
  1333. atime = inode->i_atime;
  1334. mtime = inode->i_mtime;
  1335. ctime = inode->i_ctime;
  1336. blksize = inode->i_blksize;
  1337. blocks = inode->i_blocks;
  1338. err  = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
  1339. err |= put_user(ino, &statbuf->st_ino);
  1340. err |= put_user(mode, &statbuf->st_mode);
  1341. err |= put_user(nlink, &statbuf->st_nlink);
  1342. err |= put_user(high2lowuid(uid), &statbuf->st_uid);
  1343. err |= put_user(high2lowgid(gid), &statbuf->st_gid);
  1344. err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
  1345. err |= put_user(size, &statbuf->st_size);
  1346. err |= put_user(atime, &statbuf->st_atime);
  1347. err |= put_user(0, &statbuf->__unused1);
  1348. err |= put_user(mtime, &statbuf->st_mtime);
  1349. err |= put_user(0, &statbuf->__unused2);
  1350. err |= put_user(ctime, &statbuf->st_ctime);
  1351. err |= put_user(0, &statbuf->__unused3);
  1352. if (blksize) {
  1353. err |= put_user(blksize, &statbuf->st_blksize);
  1354. err |= put_user(blocks, &statbuf->st_blocks);
  1355. } else {
  1356. unsigned int tmp_blocks;
  1357. #define D_B   7
  1358. #define I_B   (BLOCK_SIZE / sizeof(unsigned short))
  1359. tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
  1360. if (tmp_blocks > D_B) {
  1361. unsigned int indirect;
  1362. indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
  1363. tmp_blocks += indirect;
  1364. if (indirect > 1) {
  1365. indirect = (indirect - 1 + I_B - 1) / I_B;
  1366. tmp_blocks += indirect;
  1367. if (indirect > 1)
  1368. tmp_blocks++;
  1369. }
  1370. }
  1371. err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
  1372. err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
  1373. #undef D_B
  1374. #undef I_B
  1375. }
  1376. /* fixme
  1377. err |= put_user(0, &statbuf->__unused4[0]);
  1378. err |= put_user(0, &statbuf->__unused4[1]);
  1379. */
  1380. return err;
  1381. }
  1382. /* Perhaps this belongs in fs.h or similar. -DaveM */
  1383. static __inline__ int
  1384. do_revalidate(struct dentry *dentry)
  1385. {
  1386. struct inode * inode = dentry->d_inode;
  1387. if (inode->i_op && inode->i_op->revalidate)
  1388. return inode->i_op->revalidate(dentry);
  1389. return 0;
  1390. }
  1391. asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
  1392. {
  1393. struct nameidata nd;
  1394. int error;
  1395. error = user_path_walk(filename, &nd);
  1396. if (!error) {
  1397. error = do_revalidate(nd.dentry);
  1398. if (!error)
  1399. error = cp_new_stat32(nd.dentry->d_inode, statbuf);
  1400. path_release(&nd);
  1401. }
  1402. return error;
  1403. }
  1404. asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
  1405. {
  1406. struct nameidata nd;
  1407. int error;
  1408. error = user_path_walk_link(filename, &nd);
  1409. if (!error) {
  1410. error = do_revalidate(nd.dentry);
  1411. if (!error)
  1412. error = cp_new_stat32(nd.dentry->d_inode, statbuf);
  1413. path_release(&nd);
  1414. }
  1415. return error;
  1416. }
  1417. asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
  1418. {
  1419. struct file *f;
  1420. int err = -EBADF;
  1421. f = fget(fd);
  1422. if (f) {
  1423. struct dentry * dentry = f->f_dentry;
  1424. err = do_revalidate(dentry);
  1425. if (!err)
  1426. err = cp_new_stat32(dentry->d_inode, statbuf);
  1427. fput(f);
  1428. }
  1429. return err;
  1430. }
  1431. extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
  1432. asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
  1433. {
  1434. return sys_sysfs(option, arg1, arg2);
  1435. }
  1436. struct ncp_mount_data32 {
  1437.         int version;
  1438.         unsigned int ncp_fd;
  1439.         __kernel_uid_t32 mounted_uid;
  1440.         __kernel_pid_t32 wdog_pid;
  1441.         unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
  1442.         unsigned int time_out;
  1443.         unsigned int retry_count;
  1444.         unsigned int flags;
  1445.         __kernel_uid_t32 uid;
  1446.         __kernel_gid_t32 gid;
  1447.         __kernel_mode_t32 file_mode;
  1448.         __kernel_mode_t32 dir_mode;
  1449. };
  1450. static void *do_ncp_super_data_conv(void *raw_data)
  1451. {
  1452. struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
  1453. struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
  1454. n->dir_mode = n32->dir_mode;
  1455. n->file_mode = n32->file_mode;
  1456. n->gid = low2highgid(n32->gid);
  1457. n->uid = low2highuid(n32->uid);
  1458. memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
  1459. n->wdog_pid = n32->wdog_pid;
  1460. n->mounted_uid = low2highuid(n32->mounted_uid);
  1461. return raw_data;
  1462. }
  1463. struct smb_mount_data32 {
  1464.         int version;
  1465.         __kernel_uid_t32 mounted_uid;
  1466.         __kernel_uid_t32 uid;
  1467.         __kernel_gid_t32 gid;
  1468.         __kernel_mode_t32 file_mode;
  1469.         __kernel_mode_t32 dir_mode;
  1470. };
  1471. static void *do_smb_super_data_conv(void *raw_data)
  1472. {
  1473. struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
  1474. struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
  1475. s->version = s32->version;
  1476. s->mounted_uid = low2highuid(s32->mounted_uid);
  1477. s->uid = low2highuid(s32->uid);
  1478. s->gid = low2highgid(s32->gid);
  1479. s->file_mode = s32->file_mode;
  1480. s->dir_mode = s32->dir_mode;
  1481. return raw_data;
  1482. }
  1483. static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
  1484. {
  1485. int i;
  1486. unsigned long page;
  1487. struct vm_area_struct *vma;
  1488. *kernel = 0;
  1489. if(!user)
  1490. return 0;
  1491. vma = find_vma(current->mm, (unsigned long)user);
  1492. if(!vma || (unsigned long)user < vma->vm_start)
  1493. return -EFAULT;
  1494. if(!(vma->vm_flags & VM_READ))
  1495. return -EFAULT;
  1496. i = vma->vm_end - (unsigned long) user;
  1497. if(PAGE_SIZE <= (unsigned long) i)
  1498. i = PAGE_SIZE - 1;
  1499. if(!(page = __get_free_page(GFP_KERNEL)))
  1500. return -ENOMEM;
  1501. if(copy_from_user((void *) page, user, i)) {
  1502. free_page(page);
  1503. return -EFAULT;
  1504. }
  1505. *kernel = page;
  1506. return 0;
  1507. }
  1508. #define SMBFS_NAME "smbfs"
  1509. #define NCPFS_NAME "ncpfs"
  1510. asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
  1511. {
  1512. unsigned long type_page = 0;
  1513. unsigned long data_page = 0;
  1514. unsigned long dev_page = 0;
  1515. unsigned long dir_page = 0;
  1516. int err, is_smb, is_ncp;
  1517. is_smb = is_ncp = 0;
  1518. err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
  1519. if (err)
  1520. goto out;
  1521. if (!type_page) {
  1522. err = -EINVAL;
  1523. goto out;
  1524. }
  1525. is_smb = !strcmp((char *)type_page, SMBFS_NAME);
  1526. is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
  1527. err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
  1528. if (err)
  1529. goto type_out;
  1530. err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
  1531. if (err)
  1532. goto data_out;
  1533. err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
  1534. if (err)
  1535. goto dev_out;
  1536. if (!is_smb && !is_ncp) {
  1537. lock_kernel();
  1538. err = do_mount((char*)dev_page, (char*)dir_page,
  1539. (char*)type_page, new_flags, (char*)data_page);
  1540. unlock_kernel();
  1541. } else {
  1542. if (is_ncp)
  1543. do_ncp_super_data_conv((void *)data_page);
  1544. else
  1545. do_smb_super_data_conv((void *)data_page);
  1546. lock_kernel();
  1547. err = do_mount((char*)dev_page, (char*)dir_page,
  1548. (char*)type_page, new_flags, (char*)data_page);
  1549. unlock_kernel();
  1550. }
  1551. free_page(dir_page);
  1552. dev_out:
  1553. free_page(dev_page);
  1554. data_out:
  1555. free_page(data_page);
  1556. type_out:
  1557. free_page(type_page);
  1558. out:
  1559. return err;
  1560. }
  1561. struct rusage32 {
  1562.         struct timeval32 ru_utime;
  1563.         struct timeval32 ru_stime;
  1564.         s32    ru_maxrss;
  1565.         s32    ru_ixrss;
  1566.         s32    ru_idrss;
  1567.         s32    ru_isrss;
  1568.         s32    ru_minflt;
  1569.         s32    ru_majflt;
  1570.         s32    ru_nswap;
  1571.         s32    ru_inblock;
  1572.         s32    ru_oublock;
  1573.         s32    ru_msgsnd; 
  1574.         s32    ru_msgrcv; 
  1575.         s32    ru_nsignals;
  1576.         s32    ru_nvcsw;
  1577.         s32    ru_nivcsw;
  1578. };
  1579. static int put_rusage (struct rusage32 *ru, struct rusage *r)
  1580. {
  1581. int err;
  1582. err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
  1583. err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
  1584. err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
  1585. err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
  1586. err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
  1587. err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
  1588. err |= __put_user (r->ru_idrss, &ru->ru_idrss);
  1589. err |= __put_user (r->ru_isrss, &ru->ru_isrss);
  1590. err |= __put_user (r->ru_minflt, &ru->ru_minflt);
  1591. err |= __put_user (r->ru_majflt, &ru->ru_majflt);
  1592. err |= __put_user (r->ru_nswap, &ru->ru_nswap);
  1593. err |= __put_user (r->ru_inblock, &ru->ru_inblock);
  1594. err |= __put_user (r->ru_oublock, &ru->ru_oublock);
  1595. err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
  1596. err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
  1597. err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
  1598. err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
  1599. err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
  1600. return err;
  1601. }
  1602. asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
  1603. {
  1604. if (!ru)
  1605. return sys_wait4(pid, stat_addr, options, NULL);
  1606. else {
  1607. struct rusage r;
  1608. int ret;
  1609. unsigned int status;
  1610. mm_segment_t old_fs = get_fs();
  1611. set_fs (KERNEL_DS);
  1612. ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
  1613. set_fs (old_fs);
  1614. if (put_rusage (ru, &r)) return -EFAULT;
  1615. if (stat_addr && put_user (status, stat_addr))
  1616. return -EFAULT;
  1617. return ret;
  1618. }
  1619. }
  1620. struct sysinfo32 {
  1621.         s32 uptime;
  1622.         u32 loads[3];
  1623.         u32 totalram;
  1624.         u32 freeram;
  1625.         u32 sharedram;
  1626.         u32 bufferram;
  1627.         u32 totalswap;
  1628.         u32 freeswap;
  1629.         unsigned short procs;
  1630.         char _f[22];
  1631. };
  1632. extern asmlinkage int sys_sysinfo(struct sysinfo *info);
  1633. asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
  1634. {
  1635. struct sysinfo s;
  1636. int ret, err;
  1637. mm_segment_t old_fs = get_fs ();
  1638. set_fs (KERNEL_DS);
  1639. ret = sys_sysinfo(&s);
  1640. set_fs (old_fs);
  1641. err = put_user (s.uptime, &info->uptime);
  1642. err |= __put_user (s.loads[0], &info->loads[0]);
  1643. err |= __put_user (s.loads[1], &info->loads[1]);
  1644. err |= __put_user (s.loads[2], &info->loads[2]);
  1645. err |= __put_user (s.totalram, &info->totalram);
  1646. err |= __put_user (s.freeram, &info->freeram);
  1647. err |= __put_user (s.sharedram, &info->sharedram);
  1648. err |= __put_user (s.bufferram, &info->bufferram);
  1649. err |= __put_user (s.totalswap, &info->totalswap);
  1650. err |= __put_user (s.freeswap, &info->freeswap);
  1651. err |= __put_user (s.procs, &info->procs);
  1652. if (err)
  1653. return -EFAULT;
  1654. return ret;
  1655. }
  1656. struct timespec32 {
  1657. s32    tv_sec;
  1658. s32    tv_nsec;
  1659. };
  1660.                 
  1661. extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
  1662. asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
  1663. {
  1664. struct timespec t;
  1665. int ret;
  1666. mm_segment_t old_fs = get_fs ();
  1667. set_fs (KERNEL_DS);
  1668. ret = sys_sched_rr_get_interval(pid, &t);
  1669. set_fs (old_fs);
  1670. if (put_user (t.tv_sec, &interval->tv_sec) ||
  1671.     __put_user (t.tv_nsec, &interval->tv_nsec))
  1672. return -EFAULT;
  1673. return ret;
  1674. }
  1675. extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
  1676. asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
  1677. {
  1678. struct timespec t;
  1679. int ret;
  1680. mm_segment_t old_fs = get_fs ();
  1681. if (get_user (t.tv_sec, &rqtp->tv_sec) ||
  1682.     __get_user (t.tv_nsec, &rqtp->tv_nsec))
  1683. return -EFAULT;
  1684. set_fs (KERNEL_DS);
  1685. ret = sys_nanosleep(&t, rmtp ? &t : NULL);
  1686. set_fs (old_fs);
  1687. if (rmtp && ret == -EINTR) {
  1688. if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
  1689.          __put_user (t.tv_nsec, &rmtp->tv_nsec))
  1690. return -EFAULT;
  1691. }
  1692. return ret;
  1693. }
  1694. extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
  1695. asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
  1696. {
  1697. old_sigset_t s;
  1698. int ret;
  1699. mm_segment_t old_fs = get_fs();
  1700. if (set && get_user (s, set)) return -EFAULT;
  1701. set_fs (KERNEL_DS);
  1702. ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
  1703. set_fs (old_fs);
  1704. if (ret) return ret;
  1705. if (oset && put_user (s, oset)) return -EFAULT;
  1706. return 0;
  1707. }
  1708. extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
  1709. asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
  1710. {
  1711. sigset_t s;
  1712. sigset_t32 s32;
  1713. int ret;
  1714. mm_segment_t old_fs = get_fs();
  1715. if (set) {
  1716. if (copy_from_user (&s32, set, sizeof(sigset_t32)))
  1717. return -EFAULT;
  1718. switch (_NSIG_WORDS) {
  1719. case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
  1720. case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
  1721. case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
  1722. case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
  1723. }
  1724. }
  1725. set_fs (KERNEL_DS);
  1726. ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
  1727. set_fs (old_fs);
  1728. if (ret) return ret;
  1729. if (oset) {
  1730. switch (_NSIG_WORDS) {
  1731. case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
  1732. case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
  1733. case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
  1734. case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
  1735. }
  1736. if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
  1737. return -EFAULT;
  1738. }
  1739. return 0;
  1740. }
  1741. extern asmlinkage int sys_sigpending(old_sigset_t *set);
  1742. asmlinkage int sys32_sigpending(old_sigset_t32 *set)
  1743. {
  1744. old_sigset_t s;
  1745. int ret;
  1746. mm_segment_t old_fs = get_fs();
  1747. set_fs (KERNEL_DS);
  1748. ret = sys_sigpending(&s);
  1749. set_fs (old_fs);
  1750. if (put_user (s, set)) return -EFAULT;
  1751. return ret;
  1752. }
  1753. extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
  1754. asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
  1755. {
  1756. sigset_t s;
  1757. sigset_t32 s32;
  1758. int ret;
  1759. mm_segment_t old_fs = get_fs();
  1760. set_fs (KERNEL_DS);
  1761. ret = sys_rt_sigpending(&s, sigsetsize);
  1762. set_fs (old_fs);
  1763. if (!ret) {
  1764. switch (_NSIG_WORDS) {
  1765. case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
  1766. case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
  1767. case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
  1768. case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
  1769. }
  1770. if (copy_to_user (set, &s32, sizeof(sigset_t32)))
  1771. return -EFAULT;
  1772. }
  1773. return ret;
  1774. }
  1775. extern int
  1776. copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from);
  1777. asmlinkage int
  1778. sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
  1779.       struct timespec32 *uts, __kernel_size_t32 sigsetsize)
  1780. {
  1781. int ret, sig;
  1782. sigset_t these;
  1783. sigset_t32 these32;
  1784. struct timespec ts;
  1785. siginfo_t info;
  1786. long timeout = 0;
  1787. /* XXX: Don't preclude handling different sized sigset_t's.  */
  1788. if (sigsetsize != sizeof(sigset_t))
  1789. return -EINVAL;
  1790. if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
  1791. return -EFAULT;
  1792. switch (_NSIG_WORDS) {
  1793. case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
  1794. case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
  1795. case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
  1796. case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
  1797. }
  1798. /*
  1799.  * Invert the set of allowed signals to get those we
  1800.  * want to block.
  1801.  */
  1802. sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
  1803. signotset(&these);
  1804. if (uts) {
  1805. if (get_user (ts.tv_sec, &uts->tv_sec) ||
  1806.     get_user (ts.tv_nsec, &uts->tv_nsec))
  1807. return -EINVAL;
  1808. if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
  1809.     || ts.tv_sec < 0)
  1810. return -EINVAL;
  1811. }
  1812. spin_lock_irq(&current->sigmask_lock);
  1813. sig = dequeue_signal(&these, &info);
  1814. if (!sig) {
  1815. /* None ready -- temporarily unblock those we're interested
  1816.    in so that we'll be awakened when they arrive.  */
  1817. sigset_t oldblocked = current->blocked;
  1818. sigandsets(&current->blocked, &current->blocked, &these);
  1819. recalc_sigpending(current);
  1820. spin_unlock_irq(&current->sigmask_lock);
  1821. timeout = MAX_SCHEDULE_TIMEOUT;
  1822. if (uts)
  1823. timeout = (timespec_to_jiffies(&ts)
  1824.    + (ts.tv_sec || ts.tv_nsec));
  1825. current->state = TASK_INTERRUPTIBLE;
  1826. timeout = schedule_timeout(timeout);
  1827. spin_lock_irq(&current->sigmask_lock);
  1828. sig = dequeue_signal(&these, &info);
  1829. current->blocked = oldblocked;
  1830. recalc_sigpending(current);
  1831. }
  1832. spin_unlock_irq(&current->sigmask_lock);
  1833. if (sig) {
  1834. ret = sig;
  1835. if (uinfo) {
  1836. if (copy_siginfo_to_user32(uinfo, &info))
  1837. ret = -EFAULT;
  1838. }
  1839. } else {
  1840. ret = -EAGAIN;
  1841. if (timeout)
  1842. ret = -EINTR;
  1843. }
  1844. return ret;
  1845. }
  1846. extern asmlinkage int
  1847. sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
  1848. asmlinkage int
  1849. sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
  1850. {
  1851. siginfo_t info;
  1852. int ret;
  1853. mm_segment_t old_fs = get_fs();
  1854. if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
  1855.     copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
  1856. return -EFAULT;
  1857. set_fs (KERNEL_DS);
  1858. ret = sys_rt_sigqueueinfo(pid, sig, &info);
  1859. set_fs (old_fs);
  1860. return ret;
  1861. }
  1862. struct tms32 {
  1863. __kernel_clock_t32 tms_utime;
  1864. __kernel_clock_t32 tms_stime;
  1865. __kernel_clock_t32 tms_cutime;
  1866. __kernel_clock_t32 tms_cstime;
  1867. };
  1868.                                 
  1869. extern asmlinkage long sys_times(struct tms * tbuf);
  1870. asmlinkage long sys32_times(struct tms32 *tbuf)
  1871. {
  1872. struct tms t;
  1873. long ret;
  1874. mm_segment_t old_fs = get_fs ();
  1875. int err;
  1876. set_fs (KERNEL_DS);
  1877. ret = sys_times(tbuf ? &t : NULL);
  1878. set_fs (old_fs);
  1879. if (tbuf) {
  1880. err = put_user (t.tms_utime, &tbuf->tms_utime);
  1881. err |= __put_user (t.tms_stime, &tbuf->tms_stime);
  1882. err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
  1883. err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
  1884. if (err)
  1885. ret = -EFAULT;
  1886. }
  1887. return ret;
  1888. }
  1889. #define RLIM_INFINITY32 0x7fffffff
  1890. #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
  1891. struct rlimit32 {
  1892. u32 rlim_cur;
  1893. u32 rlim_max;
  1894. };
  1895. extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);
  1896. asmlinkage int sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim)
  1897. {
  1898. struct rlimit r;
  1899. int ret;
  1900. mm_segment_t old_fs = get_fs ();
  1901. set_fs (KERNEL_DS);
  1902. ret = sys_old_getrlimit(resource, &r);
  1903. set_fs (old_fs);
  1904. if (!ret) {
  1905. ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
  1906. ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
  1907. }
  1908. return ret;
  1909. }
  1910. extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
  1911. asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
  1912. {
  1913. struct rlimit r;
  1914. int ret;
  1915. mm_segment_t old_fs = get_fs ();
  1916. if (resource >= RLIM_NLIMITS) return -EINVAL;
  1917. if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
  1918.     __get_user (r.rlim_max, &rlim->rlim_max))
  1919. return -EFAULT;
  1920. if (r.rlim_cur == RLIM_INFINITY32)
  1921. r.rlim_cur = RLIM_INFINITY;
  1922. if (r.rlim_max == RLIM_INFINITY32)
  1923. r.rlim_max = RLIM_INFINITY;
  1924. set_fs (KERNEL_DS);
  1925. ret = sys_setrlimit(resource, &r);
  1926. set_fs (old_fs);
  1927. return ret;
  1928. }
  1929. extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
  1930. asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
  1931. {
  1932. struct rusage r;
  1933. int ret;
  1934. mm_segment_t old_fs = get_fs();
  1935. set_fs (KERNEL_DS);
  1936. ret = sys_getrusage(who, &r);
  1937. set_fs (old_fs);
  1938. if (put_rusage (ru, &r)) return -EFAULT;
  1939. return ret;
  1940. }
  1941. /* XXX This really belongs in some header file... -DaveM */
  1942. #define MAX_SOCK_ADDR 128 /* 108 for Unix domain - 
  1943.    16 for IP, 16 for IPX,
  1944.    24 for IPv6,
  1945.    about 80 for AX.25 */
  1946. extern struct socket *sockfd_lookup(int fd, int *err);
  1947. /* XXX This as well... */
  1948. extern __inline__ void sockfd_put(struct socket *sock)
  1949. {
  1950. fput(sock->file);
  1951. }
  1952. struct msghdr32 {
  1953.         u32               msg_name;
  1954.         int               msg_namelen;
  1955.         u32               msg_iov;
  1956.         __kernel_size_t32 msg_iovlen;
  1957.         u32               msg_control;
  1958.         __kernel_size_t32 msg_controllen;
  1959.         unsigned          msg_flags;
  1960. };
  1961. struct cmsghdr32 {
  1962.         __kernel_size_t32 cmsg_len;
  1963.         int               cmsg_level;
  1964.         int               cmsg_type;
  1965. };
  1966. /* Bleech... */
  1967. #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
  1968. #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
  1969. #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
  1970. #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
  1971. #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
  1972. #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
  1973. #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? 
  1974.     (struct cmsghdr32 *)(ctl) : 
  1975.     (struct cmsghdr32 *)NULL)
  1976. #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
  1977. __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
  1978.       struct cmsghdr32 *__cmsg, int __cmsg_len)
  1979. {
  1980. struct cmsghdr32 * __ptr;
  1981. __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
  1982.      CMSG32_ALIGN(__cmsg_len));
  1983. if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
  1984. return NULL;
  1985. return __ptr;
  1986. }
  1987. __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
  1988.     struct cmsghdr32 *__cmsg,
  1989.     int __cmsg_len)
  1990. {
  1991. return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
  1992.        __cmsg, __cmsg_len);
  1993. }
  1994. static inline int iov_from_user32_to_kern(struct iovec *kiov,
  1995.   struct iovec32 *uiov32,
  1996.   int niov)
  1997. {
  1998. int tot_len = 0;
  1999. while(niov > 0) {
  2000. u32 len, buf;
  2001. if(get_user(len, &uiov32->iov_len) ||
  2002.    get_user(buf, &uiov32->iov_base)) {
  2003. tot_len = -EFAULT;
  2004. break;
  2005. }
  2006. tot_len += len;
  2007. kiov->iov_base = (void *)A(buf);
  2008. kiov->iov_len = (__kernel_size_t) len;
  2009. uiov32++;
  2010. kiov++;
  2011. niov--;
  2012. }
  2013. return tot_len;
  2014. }
  2015. static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
  2016.      struct msghdr32 *umsg)
  2017. {
  2018. u32 tmp1, tmp2, tmp3;
  2019. int err;
  2020. err = get_user(tmp1, &umsg->msg_name);
  2021. err |= __get_user(tmp2, &umsg->msg_iov);
  2022. err |= __get_user(tmp3, &umsg->msg_control);
  2023. if (err)
  2024. return -EFAULT;
  2025. kmsg->msg_name = (void *)A(tmp1);
  2026. kmsg->msg_iov = (struct iovec *)A(tmp2);
  2027. kmsg->msg_control = (void *)A(tmp3);
  2028. err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
  2029. err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
  2030. err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
  2031. err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
  2032. return err;
  2033. }
  2034. /* I've named the args so it is easy to tell whose space the pointers are in. */
  2035. static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
  2036.   char *kern_address, int mode)
  2037. {
  2038. int tot_len;
  2039. if(kern_msg->msg_namelen) {
  2040. if(mode==VERIFY_READ) {
  2041. int err = move_addr_to_kernel(kern_msg->msg_name,
  2042.       kern_msg->msg_namelen,
  2043.       kern_address);
  2044. if(err < 0)
  2045. return err;
  2046. }
  2047. kern_msg->msg_name = kern_address;
  2048. } else
  2049. kern_msg->msg_name = NULL;
  2050. if(kern_msg->msg_iovlen > UIO_FASTIOV) {
  2051. kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
  2052.    GFP_KERNEL);
  2053. if(!kern_iov)
  2054. return -ENOMEM;
  2055. }
  2056. tot_len = iov_from_user32_to_kern(kern_iov,
  2057.   (struct iovec32 *)kern_msg->msg_iov,
  2058.   kern_msg->msg_iovlen);
  2059. if(tot_len >= 0)
  2060. kern_msg->msg_iov = kern_iov;
  2061. else if(kern_msg->msg_iovlen > UIO_FASTIOV)
  2062. kfree(kern_iov);
  2063. return tot_len;
  2064. }
  2065. /* There is a lot of hair here because the alignment rules (and
  2066.  * thus placement) of cmsg headers and length are different for
  2067.  * 32-bit apps.  -DaveM
  2068.  */
  2069. static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
  2070.        unsigned char *stackbuf, int stackbuf_size)
  2071. {
  2072. struct cmsghdr32 *ucmsg;
  2073. struct cmsghdr *kcmsg, *kcmsg_base;
  2074. __kernel_size_t32 ucmlen;
  2075. __kernel_size_t kcmlen, tmp;
  2076. kcmlen = 0;
  2077. kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
  2078. ucmsg = CMSG32_FIRSTHDR(kmsg);
  2079. while(ucmsg != NULL) {
  2080. if(get_user(ucmlen, &ucmsg->cmsg_len))
  2081. return -EFAULT;
  2082. /* Catch bogons. */
  2083. if(CMSG32_ALIGN(ucmlen) <
  2084.    CMSG32_ALIGN(sizeof(struct cmsghdr32)))
  2085. return -EINVAL;
  2086. if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
  2087.    + ucmlen) > kmsg->msg_controllen)
  2088. return -EINVAL;
  2089. tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
  2090.        CMSG_ALIGN(sizeof(struct cmsghdr)));
  2091. kcmlen += tmp;
  2092. ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
  2093. }
  2094. if(kcmlen == 0)
  2095. return -EINVAL;
  2096. /* The kcmlen holds the 64-bit version of the control length.
  2097.  * It may not be modified as we do not stick it into the kmsg
  2098.  * until we have successfully copied over all of the data
  2099.  * from the user.
  2100.  */
  2101. if(kcmlen > stackbuf_size)
  2102. kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
  2103. if(kcmsg == NULL)
  2104. return -ENOBUFS;
  2105. /* Now copy them over neatly. */
  2106. memset(kcmsg, 0, kcmlen);
  2107. ucmsg = CMSG32_FIRSTHDR(kmsg);
  2108. while(ucmsg != NULL) {
  2109. __get_user(ucmlen, &ucmsg->cmsg_len);
  2110. tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
  2111.        CMSG_ALIGN(sizeof(struct cmsghdr)));
  2112. kcmsg->cmsg_len = tmp;
  2113. __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
  2114. __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
  2115. /* Copy over the data. */
  2116. if(copy_from_user(CMSG_DATA(kcmsg),
  2117.   CMSG32_DATA(ucmsg),
  2118.   (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
  2119. goto out_free_efault;
  2120. /* Advance. */
  2121. kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
  2122. ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
  2123. }
  2124. /* Ok, looks like we made it.  Hook it up and return success. */
  2125. kmsg->msg_control = kcmsg_base;
  2126. kmsg->msg_controllen = kcmlen;
  2127. return 0;
  2128. out_free_efault:
  2129. if(kcmsg_base != (struct cmsghdr *)stackbuf)
  2130. kfree(kcmsg_base);
  2131. return -EFAULT;
  2132. }
  2133. static void put_cmsg32(struct msghdr *kmsg, int level, int type,
  2134.        int len, void *data)
  2135. {
  2136. struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
  2137. struct cmsghdr32 cmhdr;
  2138. int cmlen = CMSG32_LEN(len);
  2139. if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
  2140. kmsg->msg_flags |= MSG_CTRUNC;
  2141. return;
  2142. }
  2143. if(kmsg->msg_controllen < cmlen) {
  2144. kmsg->msg_flags |= MSG_CTRUNC;
  2145. cmlen = kmsg->msg_controllen;
  2146. }
  2147. cmhdr.cmsg_level = level;
  2148. cmhdr.cmsg_type = type;
  2149. cmhdr.cmsg_len = cmlen;
  2150. if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
  2151. return;
  2152. if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
  2153. return;
  2154. cmlen = CMSG32_SPACE(len);
  2155. kmsg->msg_control += cmlen;
  2156. kmsg->msg_controllen -= cmlen;
  2157. }
  2158. static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
  2159. {
  2160. struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
  2161. int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
  2162. int fdnum = scm->fp->count;
  2163. struct file **fp = scm->fp->fp;
  2164. int *cmfptr;
  2165. int err = 0, i;
  2166. if (fdnum < fdmax)
  2167. fdmax = fdnum;
  2168. for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
  2169. int new_fd;
  2170. err = get_unused_fd();
  2171. if (err < 0)
  2172. break;
  2173. new_fd = err;
  2174. err = put_user(new_fd, cmfptr);
  2175. if (err) {
  2176. put_unused_fd(new_fd);
  2177. break;
  2178. }
  2179. /* Bump the usage count and install the file. */
  2180. get_file(fp[i]);
  2181. fd_install(new_fd, fp[i]);
  2182. }
  2183. if (i > 0) {
  2184. int cmlen = CMSG32_LEN(i * sizeof(int));
  2185. if (!err)
  2186. err = put_user(SOL_SOCKET, &cm->cmsg_level);
  2187. if (!err)
  2188. err = put_user(SCM_RIGHTS, &cm->cmsg_type);
  2189. if (!err)
  2190. err = put_user(cmlen, &cm->cmsg_len);
  2191. if (!err) {
  2192. cmlen = CMSG32_SPACE(i * sizeof(int));
  2193. kmsg->msg_control += cmlen;
  2194. kmsg->msg_controllen -= cmlen;
  2195. }
  2196. }
  2197. if (i < fdnum)
  2198. kmsg->msg_flags |= MSG_CTRUNC;
  2199. /*
  2200.  * All of the files that fit in the message have had their
  2201.  * usage counts incremented, so we just free the list.
  2202.  */
  2203. __scm_destroy(scm);
  2204. }
  2205. /* In these cases we (currently) can just copy to data over verbatim
  2206.  * because all CMSGs created by the kernel have well defined types which
  2207.  * have the same layout in both the 32-bit and 64-bit API.  One must add
  2208.  * some special cased conversions here if we start sending control messages
  2209.  * with incompatible types.
  2210.  *
  2211.  * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
  2212.  * we do our work.  The remaining cases are:
  2213.  *
  2214.  * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
  2215.  * IP_TTL int 32-bit clean
  2216.  * IP_TOS __u8 32-bit clean
  2217.  * IP_RECVOPTS variable length 32-bit clean
  2218.  * IP_RETOPTS variable length 32-bit clean
  2219.  * (these last two are clean because the types are defined
  2220.  *  by the IPv4 protocol)
  2221.  * IP_RECVERR struct sock_extended_err +
  2222.  * struct sockaddr_in 32-bit clean
  2223.  * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
  2224.  * struct sockaddr_in6 32-bit clean
  2225.  * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
  2226.  * IPV6_HOPLIMIT int 32-bit clean
  2227.  * IPV6_FLOWINFO u32 32-bit clean
  2228.  * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
  2229.  * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
  2230.  * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
  2231.  * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
  2232.  */
  2233. static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
  2234. {
  2235. unsigned char *workbuf, *wp;
  2236. unsigned long bufsz, space_avail;
  2237. struct cmsghdr *ucmsg;
  2238. bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
  2239. space_avail = kmsg->msg_controllen + bufsz;
  2240. wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
  2241. if(workbuf == NULL)
  2242. goto fail;
  2243. /* To make this more sane we assume the kernel sends back properly
  2244.  * formatted control messages.  Because of how the kernel will truncate
  2245.  * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
  2246.  */
  2247. ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
  2248. while(((unsigned long)ucmsg) <=
  2249.       (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
  2250. struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
  2251. int clen64, clen32;
  2252. /* UCMSG is the 64-bit format CMSG entry in user-space.
  2253.  * KCMSG32 is within the kernel space temporary buffer
  2254.  * we use to convert into a 32-bit style CMSG.
  2255.  */
  2256. __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
  2257. __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
  2258. __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
  2259. clen64 = kcmsg32->cmsg_len;
  2260. copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
  2261.        clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
  2262. clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
  2263.   CMSG32_ALIGN(sizeof(struct cmsghdr32)));
  2264. kcmsg32->cmsg_len = clen32;
  2265. ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
  2266. wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
  2267. }
  2268. /* Copy back fixed up data, and adjust pointers. */
  2269. bufsz = (wp - workbuf);
  2270. copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
  2271. kmsg->msg_control = (struct cmsghdr *)
  2272. (((char *)orig_cmsg_uptr) + bufsz);
  2273. kmsg->msg_controllen = space_avail - bufsz;
  2274. kfree(workbuf);
  2275. return;
  2276. fail:
  2277. /* If we leave the 64-bit format CMSG chunks in there,
  2278.  * the application could get confused and crash.  So to
  2279.  * ensure greater recovery, we report no CMSGs.
  2280.  */
  2281. kmsg->msg_controllen += bufsz;
  2282. kmsg->msg_control = (void *) orig_cmsg_uptr;
  2283. }
  2284. asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
  2285. {
  2286. struct socket *sock;
  2287. char address[MAX_SOCK_ADDR];
  2288. struct iovec iov[UIO_FASTIOV];
  2289. unsigned char ctl[sizeof(struct cmsghdr) + 20];
  2290. unsigned char *ctl_buf = ctl;
  2291. struct msghdr kern_msg;
  2292. int err, total_len;
  2293. if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
  2294. return -EFAULT;
  2295. if(kern_msg.msg_iovlen > UIO_MAXIOV)
  2296. return -EINVAL;
  2297. err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
  2298. if (err < 0)
  2299. goto out;
  2300. total_len = err;
  2301. if(kern_msg.msg_controllen) {
  2302. err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
  2303. if(err)
  2304. goto out_freeiov;
  2305. ctl_buf = kern_msg.msg_control;
  2306. }
  2307. kern_msg.msg_flags = user_flags;
  2308. sock = sockfd_lookup(fd, &err);
  2309. if (sock != NULL) {
  2310. if (sock->file->f_flags & O_NONBLOCK)
  2311. kern_msg.msg_flags |= MSG_DONTWAIT;
  2312. err = sock_sendmsg(sock, &kern_msg, total_len);
  2313. sockfd_put(sock);
  2314. }
  2315. /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
  2316. if(ctl_buf != ctl)
  2317. kfree(ctl_buf);
  2318. out_freeiov:
  2319. if(kern_msg.msg_iov != iov)
  2320. kfree(kern_msg.msg_iov);
  2321. out:
  2322. return err;
  2323. }
  2324. asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
  2325. {
  2326. struct iovec iovstack[UIO_FASTIOV];
  2327. struct msghdr kern_msg;
  2328. char addr[MAX_SOCK_ADDR];
  2329. struct socket *sock;
  2330. struct iovec *iov = iovstack;
  2331. struct sockaddr *uaddr;
  2332. int *uaddr_len;
  2333. unsigned long cmsg_ptr;
  2334. int err, total_len, len = 0;
  2335. if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
  2336. return -EFAULT;
  2337. if(kern_msg.msg_iovlen > UIO_MAXIOV)
  2338. return -EINVAL;
  2339. uaddr = kern_msg.msg_name;
  2340. uaddr_len = &user_msg->msg_namelen;
  2341. err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
  2342. if (err < 0)
  2343. goto out;
  2344. total_len = err;
  2345. cmsg_ptr = (unsigned long) kern_msg.msg_control;
  2346. kern_msg.msg_flags = 0;
  2347. sock = sockfd_lookup(fd, &err);
  2348. if (sock != NULL) {
  2349. struct scm_cookie scm;
  2350. if (sock->file->f_flags & O_NONBLOCK)
  2351. user_flags |= MSG_DONTWAIT;
  2352. memset(&scm, 0, sizeof(scm));
  2353. err = sock->ops->recvmsg(sock, &kern_msg, total_len,
  2354.  user_flags, &scm);
  2355. if(err >= 0) {
  2356. len = err;
  2357. if(!kern_msg.msg_control) {
  2358. if(sock->passcred || scm.fp)
  2359. kern_msg.msg_flags |= MSG_CTRUNC;
  2360. if(scm.fp)
  2361. __scm_destroy(&scm);
  2362. } else {
  2363. /* If recvmsg processing itself placed some
  2364.  * control messages into user space, it's is
  2365.  * using 64-bit CMSG processing, so we need
  2366.  * to fix it up before we tack on more stuff.
  2367.  */
  2368. if((unsigned long) kern_msg.msg_control != cmsg_ptr)
  2369. cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
  2370. /* Wheee... */
  2371. if(sock->passcred)
  2372. put_cmsg32(&kern_msg,
  2373.    SOL_SOCKET, SCM_CREDENTIALS,
  2374.    sizeof(scm.creds), &scm.creds);
  2375. if(scm.fp != NULL)
  2376. scm_detach_fds32(&kern_msg, &scm);
  2377. }
  2378. }
  2379. sockfd_put(sock);
  2380. }
  2381. if(uaddr != NULL && err >= 0)
  2382. err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
  2383. if(cmsg_ptr != 0 && err >= 0) {
  2384. unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
  2385. __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
  2386. err |= __put_user(uclen, &user_msg->msg_controllen);
  2387. }
  2388. if(err >= 0)
  2389. err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
  2390. if(kern_msg.msg_iov != iov)
  2391. kfree(kern_msg.msg_iov);
  2392. out:
  2393. if(err < 0)
  2394. return err;
  2395. return len;
  2396. }
  2397. extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
  2398.      char *optval, int optlen);
  2399. static int do_set_attach_filter(int fd, int level, int optname,
  2400. char *optval, int optlen)
  2401. {
  2402. struct sock_fprog32 {
  2403. __u16 len;
  2404. __u32 filter;
  2405. } *fprog32 = (struct sock_fprog32 *)optval;
  2406. struct sock_fprog kfprog;
  2407. struct sock_filter *kfilter;
  2408. unsigned int fsize;
  2409. mm_segment_t old_fs;
  2410. __u32 uptr;
  2411. int ret;
  2412. if (get_user(kfprog.len, &fprog32->len) ||
  2413.     __get_user(uptr, &fprog32->filter))
  2414. return -EFAULT;
  2415. kfprog.filter = (struct sock_filter *)A(uptr);
  2416. fsize = kfprog.len * sizeof(struct sock_filter);
  2417. kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
  2418. if (kfilter == NULL)
  2419. return -ENOMEM;
  2420. if (copy_from_user(kfilter, kfprog.filter, fsize)) {
  2421. kfree(kfilter);
  2422. return -EFAULT;
  2423. }
  2424. kfprog.filter = kfilter;
  2425. old_fs = get_fs();
  2426. set_fs(KERNEL_DS);
  2427. ret = sys_setsockopt(fd, level, optname,
  2428.      (char *)&kfprog, sizeof(kfprog));
  2429. set_fs(old_fs);
  2430. kfree(kfilter);
  2431. return ret;
  2432. }
  2433. static int do_set_icmpv6_filter(int fd, int level, int optname,
  2434. char *optval, int optlen)
  2435. {
  2436. struct icmp6_filter kfilter;
  2437. mm_segment_t old_fs;
  2438. int ret, i;
  2439. if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
  2440. return -EFAULT;
  2441. for (i = 0; i < 8; i += 2) {
  2442. u32 tmp = kfilter.data[i];
  2443. kfilter.data[i] = kfilter.data[i + 1];
  2444. kfilter.data[i + 1] = tmp;
  2445. }
  2446. old_fs = get_fs();
  2447. set_fs(KERNEL_DS);
  2448. ret = sys_setsockopt(fd, level, optname,
  2449.      (char *) &kfilter, sizeof(kfilter));
  2450. set_fs(old_fs);
  2451. return ret;
  2452. }
  2453. asmlinkage int sys32_setsockopt(int fd, int level, int optname,
  2454. char *optval, int optlen)
  2455. {
  2456. if (optname == SO_ATTACH_FILTER)
  2457. return do_set_attach_filter(fd, level, optname,
  2458.     optval, optlen);
  2459. if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
  2460. return do_set_icmpv6_filter(fd, level, optname,
  2461.     optval, optlen);
  2462. return sys_setsockopt(fd, level, optname, optval, optlen);
  2463. }
  2464. extern void check_pending(int signum);
  2465. /*
  2466.  * count32() counts the number of arguments/envelopes
  2467.  */
  2468. static int count32(u32 * argv)
  2469. {
  2470. int i = 0;
  2471. if (argv != NULL) {
  2472. for (;;) {
  2473. u32 p; int error;
  2474. error = get_user(p,argv);
  2475. if (error) return error;
  2476. if (!p) break;
  2477. argv++; i++;
  2478. }
  2479. }
  2480. return i;
  2481. }
  2482. /*
  2483.  * 'copy_string32()' copies argument/envelope strings from user
  2484.  * memory to free pages in kernel mem. These are in a format ready
  2485.  * to be put directly into the top of new user memory.
  2486.  */
  2487. static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
  2488. {
  2489. while (argc-- > 0) {
  2490. u32 str;
  2491. int len;
  2492. unsigned long pos;
  2493. if (get_user(str, argv + argc) ||
  2494.     !str ||
  2495.     !(len = strnlen_user((char *)A(str), bprm->p)))
  2496. return -EFAULT;
  2497. if (bprm->p < len)
  2498. return -E2BIG;
  2499. bprm->p -= len;
  2500. pos = bprm->p;
  2501. while (len) {
  2502. char *kaddr;
  2503. struct page *page;
  2504. int offset, bytes_to_copy, new, err;
  2505. offset = pos % PAGE_SIZE;
  2506. page = bprm->page[pos / PAGE_SIZE];
  2507. new = 0;
  2508. if (!page) {
  2509. page = alloc_page(GFP_USER);
  2510. bprm->page[pos / PAGE_SIZE] = page;
  2511. if (!page)
  2512. return -ENOMEM;
  2513. new = 1;
  2514. }
  2515. kaddr = (char *)kmap(page);
  2516. if (new && offset)
  2517. memset(kaddr, 0, offset);
  2518. bytes_to_copy = PAGE_SIZE - offset;
  2519. if (bytes_to_copy > len) {
  2520. bytes_to_copy = len;
  2521. if (new)
  2522. memset(kaddr+offset+len, 0,
  2523.        PAGE_SIZE-offset-len);
  2524. }
  2525. err = copy_from_user(kaddr + offset, (char *)A(str),
  2526.      bytes_to_copy);
  2527. flush_page_to_ram(page);
  2528. kunmap(page);
  2529. if (err)
  2530. return -EFAULT;
  2531. pos += bytes_to_copy;
  2532. str += bytes_to_copy;
  2533. len -= bytes_to_copy;
  2534. }
  2535. }
  2536. return 0;
  2537. }
  2538. /*
  2539.  * sys32_execve() executes a new program.
  2540.  */
  2541. static inline int 
  2542. do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
  2543. {
  2544. struct linux_binprm bprm;
  2545. struct file * file;
  2546. int retval;
  2547. int i;
  2548. bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
  2549. memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
  2550. file = open_exec(filename);
  2551. retval = PTR_ERR(file);
  2552. if (IS_ERR(file))
  2553. return retval;
  2554. bprm.file = file;
  2555. bprm.filename = filename;
  2556. bprm.sh_bang = 0;
  2557. bprm.loader = 0;
  2558. bprm.exec = 0;
  2559. if ((bprm.argc = count32(argv)) < 0) {
  2560. allow_write_access(file);
  2561. fput(file);
  2562. return bprm.argc;
  2563. }
  2564. if ((bprm.envc = count32(envp)) < 0) {
  2565. allow_write_access(file);
  2566. fput(file);
  2567. return bprm.envc;
  2568. }
  2569. retval = prepare_binprm(&bprm);
  2570. if (retval < 0)
  2571. goto out;
  2572. retval = copy_strings_kernel(1, &bprm.filename, &bprm);
  2573. if (retval < 0)
  2574. goto out;
  2575. bprm.exec = bprm.p;
  2576. retval = copy_strings32(bprm.envc, envp, &bprm);
  2577. if (retval < 0)
  2578. goto out;
  2579. retval = copy_strings32(bprm.argc, argv, &bprm);
  2580. if (retval < 0)
  2581. goto out;
  2582. retval = search_binary_handler(&bprm, regs);
  2583. if (retval >= 0)
  2584. /* execve success */
  2585. return retval;
  2586. out:
  2587. /* Something went wrong, return the inode and free the argument pages*/
  2588. allow_write_access(bprm.file);
  2589. if (bprm.file)
  2590. fput(bprm.file);
  2591. for (i=0 ; i<MAX_ARG_PAGES ; i++)
  2592. if (bprm.page[i])
  2593. __free_page(bprm.page[i]);
  2594. return retval;
  2595. }
  2596. /*
  2597.  * sys32_execve() executes a new program after the asm stub has set
  2598.  * things up for us.  This should basically do what I want it to.
  2599.  */
  2600. asmlinkage int
  2601. sys32_execve(struct pt_regs regs)
  2602. {
  2603.         int error;
  2604.         char * filename;
  2605.         filename = getname((char *)A(regs.orig_gpr2));
  2606.         error = PTR_ERR(filename);
  2607.         if (IS_ERR(filename))
  2608.                 goto out;
  2609.         error = do_execve32(filename, (u32 *)A(regs.gprs[3]), (u32 *)A(regs.gprs[4]), &regs);
  2610. if (error == 0)
  2611. {
  2612. current->ptrace &= ~PT_DTRACE;
  2613. current->thread.fp_regs.fpc=0;
  2614. __asm__ __volatile__
  2615.         ("sr  0,0nt"
  2616.          "sfpc 0,0nt"
  2617.  : : :"0");
  2618. }
  2619.         putname(filename);
  2620. out:
  2621.         return error;
  2622. }
  2623. #ifdef CONFIG_MODULES
  2624. extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
  2625. asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
  2626. {
  2627. return sys_create_module(name_user, (size_t)size);
  2628. }
  2629. extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
  2630. /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
  2631.  * module structure, even if from 32bit modutils... Why to pollute kernel... :))
  2632.  */
  2633. asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
  2634. {
  2635. return sys_init_module(name_user, mod_user);
  2636. }
  2637. extern asmlinkage int sys_delete_module(const char *name_user);
  2638. asmlinkage int sys32_delete_module(const char *name_user)
  2639. {
  2640. return sys_delete_module(name_user);
  2641. }
  2642. struct module_info32 {
  2643. u32 addr;
  2644. u32 size;
  2645. u32 flags;
  2646. s32 usecount;
  2647. };
  2648. /* Query various bits about modules.  */
  2649. static inline long
  2650. get_mod_name(const char *user_name, char **buf)
  2651. {
  2652. unsigned long page;
  2653. long retval;
  2654. if ((unsigned long)user_name >= TASK_SIZE
  2655.     && !segment_eq(get_fs (), KERNEL_DS))
  2656. return -EFAULT;
  2657. page = __get_free_page(GFP_KERNEL);
  2658. if (!page)
  2659. return -ENOMEM;
  2660. retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
  2661. if (retval > 0) {
  2662. if (retval < PAGE_SIZE) {
  2663. *buf = (char *)page;
  2664. return retval;
  2665. }
  2666. retval = -ENAMETOOLONG;
  2667. } else if (!retval)
  2668. retval = -EINVAL;
  2669. free_page(page);
  2670. return retval;
  2671. }
  2672. static inline void
  2673. put_mod_name(char *buf)
  2674. {
  2675. free_page((unsigned long)buf);
  2676. }
  2677. static __inline__ struct module *find_module(const char *name)
  2678. {
  2679. struct module *mod;
  2680. for (mod = module_list; mod ; mod = mod->next) {
  2681. if (mod->flags & MOD_DELETED)
  2682. continue;
  2683. if (!strcmp(mod->name, name))
  2684. break;
  2685. }
  2686. return mod;
  2687. }
  2688. static int
  2689. qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
  2690. {
  2691. struct module *mod;
  2692. size_t nmod, space, len;
  2693. nmod = space = 0;
  2694. for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
  2695. len = strlen(mod->name)+1;
  2696. if (len > bufsize)
  2697. goto calc_space_needed;
  2698. if (copy_to_user(buf, mod->name, len))
  2699. return -EFAULT;
  2700. buf += len;
  2701. bufsize -= len;
  2702. space += len;
  2703. }
  2704. if (put_user(nmod, ret))
  2705. return -EFAULT;
  2706. else
  2707. return 0;
  2708. calc_space_needed:
  2709. space += len;
  2710. while ((mod = mod->next)->next != NULL)
  2711. space += strlen(mod->name)+1;
  2712. if (put_user(space, ret))
  2713. return -EFAULT;
  2714. else
  2715. return -ENOSPC;
  2716. }
  2717. static int
  2718. qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
  2719. {
  2720. size_t i, space, len;
  2721. if (mod->next == NULL)
  2722. return -EINVAL;
  2723. if (!MOD_CAN_QUERY(mod))
  2724. return put_user(0, ret);
  2725. space = 0;
  2726. for (i = 0; i < mod->ndeps; ++i) {
  2727. const char *dep_name = mod->deps[i].dep->name;
  2728. len = strlen(dep_name)+1;
  2729. if (len > bufsize)
  2730. goto calc_space_needed;
  2731. if (copy_to_user(buf, dep_name, len))
  2732. return -EFAULT;
  2733. buf += len;
  2734. bufsize -= len;
  2735. space += len;
  2736. }
  2737. return put_user(i, ret);
  2738. calc_space_needed:
  2739. space += len;
  2740. while (++i < mod->ndeps)
  2741. space += strlen(mod->deps[i].dep->name)+1;
  2742. if (put_user(space, ret))
  2743. return -EFAULT;
  2744. else
  2745. return -ENOSPC;
  2746. }
  2747. static int
  2748. qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
  2749. {
  2750. size_t nrefs, space, len;
  2751. struct module_ref *ref;
  2752. if (mod->next == NULL)
  2753. return -EINVAL;
  2754. if (!MOD_CAN_QUERY(mod))
  2755. if (put_user(0, ret))
  2756. return -EFAULT;
  2757. else
  2758. return 0;
  2759. space = 0;
  2760. for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
  2761. const char *ref_name = ref->ref->name;
  2762. len = strlen(ref_name)+1;
  2763. if (len > bufsize)
  2764. goto calc_space_needed;
  2765. if (copy_to_user(buf, ref_name, len))
  2766. return -EFAULT;
  2767. buf += len;
  2768. bufsize -= len;
  2769. space += len;
  2770. }
  2771. if (put_user(nrefs, ret))
  2772. return -EFAULT;
  2773. else
  2774. return 0;
  2775. calc_space_needed:
  2776. space += len;
  2777. while ((ref = ref->next_ref) != NULL)
  2778. space += strlen(ref->ref->name)+1;
  2779. if (put_user(space, ret))
  2780. return -EFAULT;
  2781. else
  2782. return -ENOSPC;
  2783. }
  2784. static inline int
  2785. qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
  2786. {
  2787. size_t i, space, len;
  2788. struct module_symbol *s;
  2789. char *strings;
  2790. unsigned *vals;
  2791. if (!MOD_CAN_QUERY(mod))
  2792. if (put_user(0, ret))
  2793. return -EFAULT;
  2794. else
  2795. return 0;
  2796. space = mod->nsyms * 2*sizeof(u32);
  2797. i = len = 0;
  2798. s = mod->syms;
  2799. if (space > bufsize)
  2800. goto calc_space_needed;
  2801. if (!access_ok(VERIFY_WRITE, buf, space))
  2802. return -EFAULT;
  2803. bufsize -= space;
  2804. vals = (unsigned *)buf;
  2805. strings = buf+space;
  2806. for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
  2807. len = strlen(s->name)+1;
  2808. if (len > bufsize)
  2809. goto calc_space_needed;
  2810. if (copy_to_user(strings, s->name, len)
  2811.     || __put_user(s->value, vals+0)
  2812.     || __put_user(space, vals+1))
  2813. return -EFAULT;
  2814. strings += len;
  2815. bufsize -= len;
  2816. space += len;
  2817. }
  2818. if (put_user(i, ret))
  2819. return -EFAULT;
  2820. else
  2821. return 0;
  2822. calc_space_needed:
  2823. for (; i < mod->nsyms; ++i, ++s)
  2824. space += strlen(s->name)+1;
  2825. if (put_user(space, ret))
  2826. return -EFAULT;
  2827. else
  2828. return -ENOSPC;
  2829. }
  2830. static inline int
  2831. qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
  2832. {
  2833. int error = 0;
  2834. if (mod->next == NULL)
  2835. return -EINVAL;
  2836. if (sizeof(struct module_info32) <= bufsize) {
  2837. struct module_info32 info;
  2838. info.addr = (unsigned long)mod;
  2839. info.size = mod->size;
  2840. info.flags = mod->flags;
  2841. info.usecount =
  2842. ((mod_member_present(mod, can_unload)
  2843.   && mod->can_unload)
  2844.  ? -1 : atomic_read(&mod->uc.usecount));
  2845. if (copy_to_user(buf, &info, sizeof(struct module_info32)))
  2846. return -EFAULT;
  2847. } else
  2848. error = -ENOSPC;
  2849. if (put_user(sizeof(struct module_info32), ret))
  2850. return -EFAULT;
  2851. return error;
  2852. }
  2853. asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
  2854. {
  2855. struct module *mod;
  2856. int err;
  2857. lock_kernel();
  2858. if (name_user == 0) {
  2859. /* This finds "kernel_module" which is not exported. */
  2860. for(mod = module_list; mod->next != NULL; mod = mod->next)
  2861. ;
  2862. } else {
  2863. long namelen;
  2864. char *name;
  2865. if ((namelen = get_mod_name(name_user, &name)) < 0) {
  2866. err = namelen;
  2867. goto out;
  2868. }
  2869. err = -ENOENT;
  2870. if (namelen == 0) {
  2871. /* This finds "kernel_module" which is not exported. */
  2872. for(mod = module_list; mod->next != NULL; mod = mod->next)
  2873. ;
  2874. } else if ((mod = find_module(name)) == NULL) {
  2875. put_mod_name(name);
  2876. goto out;
  2877. }
  2878. put_mod_name(name);
  2879. }
  2880. switch (which)
  2881. {
  2882. case 0:
  2883. err = 0;
  2884. break;
  2885. case QM_MODULES:
  2886. err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
  2887. break;
  2888. case QM_DEPS:
  2889. err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
  2890. break;
  2891. case QM_REFS:
  2892. err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
  2893. break;
  2894. case QM_SYMBOLS:
  2895. err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
  2896. break;
  2897. case QM_INFO:
  2898. err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
  2899. break;
  2900. default:
  2901. err = -EINVAL;
  2902. break;
  2903. }
  2904. out:
  2905. unlock_kernel();
  2906. return err;
  2907. }
  2908. struct kernel_sym32 {
  2909. u32 value;
  2910. char name[60];
  2911. };
  2912.  
  2913. extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
  2914. asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
  2915. {
  2916. int len, i;
  2917. struct kernel_sym *tbl;
  2918. mm_segment_t old_fs;
  2919. len = sys_get_kernel_syms(NULL);
  2920. if (!table) return len;
  2921. tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
  2922. if (!tbl) return -ENOMEM;
  2923. old_fs = get_fs();
  2924. set_fs (KERNEL_DS);
  2925. sys_get_kernel_syms(tbl);
  2926. set_fs (old_fs);
  2927. for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
  2928. if (put_user (tbl[i].value, &table->value) ||
  2929.     copy_to_user (table->name, tbl[i].name, 60))
  2930. break;
  2931. }
  2932. kfree (tbl);
  2933. return i;
  2934. }
  2935. #else /* CONFIG_MODULES */
  2936. asmlinkage unsigned long
  2937. sys32_create_module(const char *name_user, size_t size)
  2938. {
  2939. return -ENOSYS;
  2940. }
  2941. asmlinkage int
  2942. sys32_init_module(const char *name_user, struct module *mod_user)
  2943. {
  2944. return -ENOSYS;
  2945. }
  2946. asmlinkage int
  2947. sys32_delete_module(const char *name_user)
  2948. {
  2949. return -ENOSYS;
  2950. }
  2951. asmlinkage int
  2952. sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
  2953.  size_t *ret)
  2954. {
  2955. /* Let the program know about the new interface.  Not that
  2956.    it'll do them much good.  */
  2957. if (which == 0)
  2958. return 0;
  2959. return -ENOSYS;
  2960. }
  2961. asmlinkage int
  2962. sys32_get_kernel_syms(struct kernel_sym *table)
  2963. {
  2964. return -ENOSYS;
  2965. }
  2966. #endif  /* CONFIG_MODULES */
  2967. /* Stuff for NFS server syscalls... */
  2968. struct nfsctl_svc32 {
  2969. u16 svc32_port;
  2970. s32 svc32_nthreads;
  2971. };
  2972. struct nfsctl_client32 {
  2973. s8 cl32_ident[NFSCLNT_IDMAX+1];
  2974. s32 cl32_naddr;
  2975. struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
  2976. s32 cl32_fhkeytype;
  2977. s32 cl32_fhkeylen;
  2978. u8 cl32_fhkey[NFSCLNT_KEYMAX];
  2979. };
  2980. struct nfsctl_export32 {
  2981. s8 ex32_client[NFSCLNT_IDMAX+1];
  2982. s8 ex32_path[NFS_MAXPATHLEN+1];
  2983. __kernel_dev_t32 ex32_dev;
  2984. __kernel_ino_t32 ex32_ino;
  2985. s32 ex32_flags;
  2986. __kernel_uid_t32 ex32_anon_uid;
  2987. __kernel_gid_t32 ex32_anon_gid;
  2988. };
  2989. struct nfsctl_uidmap32 {
  2990. u32 ug32_ident;   /* char * */
  2991. __kernel_uid_t32 ug32_uidbase;
  2992. s32 ug32_uidlen;
  2993. u32 ug32_udimap;  /* uid_t * */
  2994. __kernel_uid_t32 ug32_gidbase;
  2995. s32 ug32_gidlen;
  2996. u32 ug32_gdimap;  /* gid_t * */
  2997. };
  2998. struct nfsctl_fhparm32 {
  2999. struct sockaddr gf32_addr;
  3000. __kernel_dev_t32 gf32_dev;
  3001. __kernel_ino_t32 gf32_ino;
  3002. s32 gf32_version;
  3003. };
  3004. struct nfsctl_fdparm32 {
  3005. struct sockaddr gd32_addr;
  3006. s8 gd32_path[NFS_MAXPATHLEN+1];
  3007. s32 gd32_version;
  3008. };
  3009. struct nfsctl_fsparm32 {
  3010. struct sockaddr gd32_addr;
  3011. s8 gd32_path[NFS_MAXPATHLEN+1];
  3012. s32 gd32_maxlen;
  3013. };
  3014. struct nfsctl_arg32 {
  3015. s32 ca32_version; /* safeguard */
  3016. union {
  3017. struct nfsctl_svc32 u32_svc;
  3018. struct nfsctl_client32 u32_client;
  3019. struct nfsctl_export32 u32_export;
  3020. struct nfsctl_uidmap32 u32_umap;
  3021. struct nfsctl_fhparm32 u32_getfh;
  3022. struct nfsctl_fdparm32 u32_getfd;
  3023. struct nfsctl_fsparm32 u32_getfs;
  3024. } u;
  3025. #define ca32_svc u.u32_svc
  3026. #define ca32_client u.u32_client
  3027. #define ca32_export u.u32_export
  3028. #define ca32_umap u.u32_umap
  3029. #define ca32_getfh u.u32_getfh
  3030. #define ca32_getfd u.u32_getfd
  3031. #define ca32_getfs u.u32_getfs
  3032. #define ca32_authd u.u32_authd
  3033. };
  3034. union nfsctl_res32 {
  3035. __u8 cr32_getfh[NFS_FHSIZE];
  3036. struct knfsd_fh cr32_getfs;
  3037. };
  3038. static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3039. {
  3040. int err;
  3041. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3042. err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
  3043. err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
  3044. return err;
  3045. }
  3046. static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3047. {
  3048. int err;
  3049. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3050. err |= copy_from_user(&karg->ca_client.cl_ident[0],
  3051.   &arg32->ca32_client.cl32_ident[0],
  3052.   NFSCLNT_IDMAX);
  3053. err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
  3054. err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
  3055.   &arg32->ca32_client.cl32_addrlist[0],
  3056.   (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
  3057. err |= __get_user(karg->ca_client.cl_fhkeytype,
  3058.       &arg32->ca32_client.cl32_fhkeytype);
  3059. err |= __get_user(karg->ca_client.cl_fhkeylen,
  3060.       &arg32->ca32_client.cl32_fhkeylen);
  3061. err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
  3062.   &arg32->ca32_client.cl32_fhkey[0],
  3063.   NFSCLNT_KEYMAX);
  3064. return err;
  3065. }
  3066. static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3067. {
  3068. int err;
  3069. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3070. err |= copy_from_user(&karg->ca_export.ex_client[0],
  3071.   &arg32->ca32_export.ex32_client[0],
  3072.   NFSCLNT_IDMAX);
  3073. err |= copy_from_user(&karg->ca_export.ex_path[0],
  3074.   &arg32->ca32_export.ex32_path[0],
  3075.   NFS_MAXPATHLEN);
  3076. err |= __get_user(karg->ca_export.ex_dev,
  3077.       &arg32->ca32_export.ex32_dev);
  3078. err |= __get_user(karg->ca_export.ex_ino,
  3079.       &arg32->ca32_export.ex32_ino);
  3080. err |= __get_user(karg->ca_export.ex_flags,
  3081.       &arg32->ca32_export.ex32_flags);
  3082. err |= __get_user(karg->ca_export.ex_anon_uid,
  3083.       &arg32->ca32_export.ex32_anon_uid);
  3084. err |= __get_user(karg->ca_export.ex_anon_gid,
  3085.       &arg32->ca32_export.ex32_anon_gid);
  3086. karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
  3087. karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
  3088. return err;
  3089. }
  3090. static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3091. {
  3092. u32 uaddr;
  3093. int i;
  3094. int err;
  3095. memset(karg, 0, sizeof(*karg));
  3096. if(__get_user(karg->ca_version, &arg32->ca32_version))
  3097. return -EFAULT;
  3098. karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
  3099. if(!karg->ca_umap.ug_ident)
  3100. return -ENOMEM;
  3101. err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
  3102. if(strncpy_from_user(karg->ca_umap.ug_ident,
  3103.      (char *)A(uaddr), PAGE_SIZE) <= 0)
  3104. return -EFAULT;
  3105. err |= __get_user(karg->ca_umap.ug_uidbase,
  3106.       &arg32->ca32_umap.ug32_uidbase);
  3107. err |= __get_user(karg->ca_umap.ug_uidlen,
  3108.       &arg32->ca32_umap.ug32_uidlen);
  3109. err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
  3110. if (err)
  3111. return -EFAULT;
  3112. karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
  3113.   GFP_USER);
  3114. if(!karg->ca_umap.ug_udimap)
  3115. return -ENOMEM;
  3116. for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
  3117. err |= __get_user(karg->ca_umap.ug_udimap[i],
  3118.       &(((__kernel_uid_t32 *)A(uaddr))[i]));
  3119. err |= __get_user(karg->ca_umap.ug_gidbase,
  3120.       &arg32->ca32_umap.ug32_gidbase);
  3121. err |= __get_user(karg->ca_umap.ug_uidlen,
  3122.       &arg32->ca32_umap.ug32_gidlen);
  3123. err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
  3124. if (err)
  3125. return -EFAULT;
  3126. karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
  3127.   GFP_USER);
  3128. if(!karg->ca_umap.ug_gdimap)
  3129. return -ENOMEM;
  3130. for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
  3131. err |= __get_user(karg->ca_umap.ug_gdimap[i],
  3132.       &(((__kernel_gid_t32 *)A(uaddr))[i]));
  3133. return err;
  3134. }
  3135. static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3136. {
  3137. int err;
  3138. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3139. err |= copy_from_user(&karg->ca_getfh.gf_addr,
  3140.   &arg32->ca32_getfh.gf32_addr,
  3141.   (sizeof(struct sockaddr)));
  3142. err |= __get_user(karg->ca_getfh.gf_dev,
  3143.       &arg32->ca32_getfh.gf32_dev);
  3144. err |= __get_user(karg->ca_getfh.gf_ino,
  3145.       &arg32->ca32_getfh.gf32_ino);
  3146. err |= __get_user(karg->ca_getfh.gf_version,
  3147.       &arg32->ca32_getfh.gf32_version);
  3148. return err;
  3149. }
  3150. static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3151. {
  3152. int err;
  3153. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3154. err |= copy_from_user(&karg->ca_getfd.gd_addr,
  3155.   &arg32->ca32_getfd.gd32_addr,
  3156.   (sizeof(struct sockaddr)));
  3157. err |= copy_from_user(&karg->ca_getfd.gd_path,
  3158.   &arg32->ca32_getfd.gd32_path,
  3159.   (NFS_MAXPATHLEN+1));
  3160. err |= __get_user(karg->ca_getfd.gd_version,
  3161.       &arg32->ca32_getfd.gd32_version);
  3162. return err;
  3163. }
  3164. static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  3165. {
  3166. int err;
  3167. err = __get_user(karg->ca_version, &arg32->ca32_version);
  3168. err |= copy_from_user(&karg->ca_getfs.gd_addr,
  3169.   &arg32->ca32_getfs.gd32_addr,
  3170.   (sizeof(struct sockaddr)));
  3171. err |= copy_from_user(&karg->ca_getfs.gd_path,
  3172.   &arg32->ca32_getfs.gd32_path,
  3173.   (NFS_MAXPATHLEN+1));
  3174. err |= __get_user(karg->ca_getfs.gd_maxlen,
  3175.       &arg32->ca32_getfs.gd32_maxlen);
  3176. return err;
  3177. }
  3178. /* This really doesn't need translations, we are only passing
  3179.  * back a union which contains opaque nfs file handle data.
  3180.  */
  3181. static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
  3182. {
  3183. return copy_to_user(res32, kres, sizeof(*res32));
  3184. }
  3185. /*
  3186. asmlinkage long sys_ni_syscall(void); 
  3187. */
  3188. int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
  3189. {
  3190. struct nfsctl_arg *karg = NULL;
  3191. union nfsctl_res *kres = NULL;
  3192. mm_segment_t oldfs;
  3193. int err;
  3194. karg = kmalloc(sizeof(*karg), GFP_USER);
  3195. if(!karg)
  3196. return -ENOMEM;
  3197. if(res32) {
  3198. kres = kmalloc(sizeof(*kres), GFP_USER);
  3199. if(!kres) {
  3200. kfree(karg);
  3201. return -ENOMEM;
  3202. }
  3203. }
  3204. switch(cmd) {
  3205. case NFSCTL_SVC:
  3206. err = nfs_svc32_trans(karg, arg32);
  3207. break;
  3208. case NFSCTL_ADDCLIENT:
  3209. err = nfs_clnt32_trans(karg, arg32);
  3210. break;
  3211. case NFSCTL_DELCLIENT:
  3212. err = nfs_clnt32_trans(karg, arg32);
  3213. break;
  3214. case NFSCTL_EXPORT:
  3215. case NFSCTL_UNEXPORT:
  3216. err = nfs_exp32_trans(karg, arg32);
  3217. break;
  3218. /* This one is unimplemented, be we're ready for it. */
  3219. case NFSCTL_UGIDUPDATE:
  3220. err = nfs_uud32_trans(karg, arg32);
  3221. break;
  3222. case NFSCTL_GETFH:
  3223. err = nfs_getfh32_trans(karg, arg32);
  3224. break;
  3225. case NFSCTL_GETFD:
  3226. err = nfs_getfd32_trans(karg, arg32);
  3227. break;
  3228. case NFSCTL_GETFS:
  3229. err = nfs_getfs32_trans(karg, arg32);
  3230. break;
  3231. default:
  3232. err = -EINVAL;
  3233. break;
  3234. }
  3235. if(err)
  3236. goto done;
  3237. oldfs = get_fs();
  3238. set_fs(KERNEL_DS);
  3239. err = sys_nfsservctl(cmd, karg, kres);
  3240. set_fs(oldfs);
  3241. if (err)
  3242. goto done;
  3243. if((cmd == NFSCTL_GETFH) ||
  3244.    (cmd == NFSCTL_GETFD) ||
  3245.    (cmd == NFSCTL_GETFS))
  3246. err = nfs_getfh32_res_trans(kres, res32);
  3247. done:
  3248. if(karg) {
  3249. if(cmd == NFSCTL_UGIDUPDATE) {
  3250. if(karg->ca_umap.ug_ident)
  3251. kfree(karg->ca_umap.ug_ident);
  3252. if(karg->ca_umap.ug_udimap)
  3253. kfree(karg->ca_umap.ug_udimap);
  3254. if(karg->ca_umap.ug_gdimap)
  3255. kfree(karg->ca_umap.ug_gdimap);
  3256. }
  3257. kfree(karg);
  3258. }
  3259. if(kres)
  3260. kfree(kres);
  3261. return err;
  3262. }
  3263. /* Translations due to time_t size differences.  Which affects all
  3264.    sorts of things, like timeval and itimerval.  */
  3265. extern struct timezone sys_tz;
  3266. extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
  3267. asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
  3268. {
  3269. if (tv) {
  3270. struct timeval ktv;
  3271. do_gettimeofday(&ktv);
  3272. if (put_tv32(tv, &ktv))
  3273. return -EFAULT;
  3274. }
  3275. if (tz) {
  3276. if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
  3277. return -EFAULT;
  3278. }
  3279. return 0;
  3280. }
  3281. asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
  3282. {
  3283. struct timeval ktv;
  3284. struct timezone ktz;
  3285.   if (tv) {
  3286. if (get_tv32(&ktv, tv))
  3287. return -EFAULT;
  3288. }
  3289. if (tz) {
  3290. if (copy_from_user(&ktz, tz, sizeof(ktz)))
  3291. return -EFAULT;
  3292. }
  3293. return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
  3294. }
  3295. extern int do_getitimer(int which, struct itimerval *value);
  3296. asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
  3297. {
  3298. struct itimerval kit;
  3299. int error;
  3300. error = do_getitimer(which, &kit);
  3301. if (!error && put_it32(it, &kit))
  3302. error = -EFAULT;
  3303. return error;
  3304. }
  3305. extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
  3306. asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
  3307. {
  3308. struct itimerval kin, kout;
  3309. int error;
  3310. if (in) {
  3311. if (get_it32(&kin, in))
  3312. return -EFAULT;
  3313. } else
  3314. memset(&kin, 0, sizeof(kin));
  3315. error = do_setitimer(which, &kin, out ? &kout : NULL);
  3316. if (error || !out)
  3317. return error;
  3318. if (put_it32(out, &kout))
  3319. return -EFAULT;
  3320. return 0;
  3321. }
  3322. asmlinkage int sys_utimes(char *, struct timeval *);
  3323. asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
  3324. {
  3325. char *kfilename;
  3326. struct timeval ktvs[2];
  3327. mm_segment_t old_fs;
  3328. int ret;
  3329. kfilename = getname(filename);
  3330. ret = PTR_ERR(kfilename);
  3331. if (!IS_ERR(kfilename)) {
  3332. if (tvs) {
  3333. if (get_tv32(&ktvs[0], tvs) ||
  3334.     get_tv32(&ktvs[1], 1+tvs))
  3335. return -EFAULT;
  3336. }
  3337. old_fs = get_fs();
  3338. set_fs(KERNEL_DS);
  3339. ret = sys_utimes(kfilename, &ktvs[0]);
  3340. set_fs(old_fs);
  3341. putname(kfilename);
  3342. }
  3343. return ret;
  3344. }
  3345. /* These are here just in case some old sparc32 binary calls it. */
  3346. asmlinkage int sys32_pause(void)
  3347. {
  3348. current->state = TASK_INTERRUPTIBLE;
  3349. schedule();
  3350. return -ERESTARTNOHAND;
  3351. }
  3352. extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
  3353. unsigned long arg4, unsigned long arg5);
  3354. asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
  3355. {
  3356. return sys_prctl(option,
  3357.  (unsigned long) arg2,
  3358.  (unsigned long) arg3,
  3359.  (unsigned long) arg4,
  3360.  (unsigned long) arg5);
  3361. }
  3362. extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
  3363.     size_t count, loff_t pos);
  3364. extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
  3365.      size_t count, loff_t pos);
  3366. typedef __kernel_ssize_t32 ssize_t32;
  3367. asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
  3368.  __kernel_size_t32 count, u32 poshi, u32 poslo)
  3369. {
  3370. return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
  3371. }
  3372. asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
  3373.   __kernel_size_t32 count, u32 poshi, u32 poslo)
  3374. {
  3375. return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
  3376. }
  3377. extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
  3378. asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
  3379. {
  3380. mm_segment_t old_fs = get_fs();
  3381. int ret;
  3382. off_t of;
  3383. if (offset && get_user(of, offset))
  3384. return -EFAULT;
  3385. set_fs(KERNEL_DS);
  3386. ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
  3387. set_fs(old_fs);
  3388. if (!ret && offset && put_user(of, offset))
  3389. return -EFAULT;
  3390. return ret;
  3391. }
  3392. /* Handle adjtimex compatability. */
  3393. struct timex32 {
  3394. u32 modes;
  3395. s32 offset, freq, maxerror, esterror;
  3396. s32 status, constant, precision, tolerance;
  3397. struct timeval32 time;
  3398. s32 tick;
  3399. s32 ppsfreq, jitter, shift, stabil;
  3400. s32 jitcnt, calcnt, errcnt, stbcnt;
  3401. s32  :32; s32  :32; s32  :32; s32  :32;
  3402. s32  :32; s32  :32; s32  :32; s32  :32;
  3403. s32  :32; s32  :32; s32  :32; s32  :32;
  3404. };
  3405. extern int do_adjtimex(struct timex *);
  3406. asmlinkage int sys32_adjtimex(struct timex32 *utp)
  3407. {
  3408. struct timex txc;
  3409. int ret;
  3410. memset(&txc, 0, sizeof(struct timex));
  3411. if(get_user(txc.modes, &utp->modes) ||
  3412.    __get_user(txc.offset, &utp->offset) ||
  3413.    __get_user(txc.freq, &utp->freq) ||
  3414.    __get_user(txc.maxerror, &utp->maxerror) ||
  3415.    __get_user(txc.esterror, &utp->esterror) ||
  3416.    __get_user(txc.status, &utp->status) ||
  3417.    __get_user(txc.constant, &utp->constant) ||
  3418.    __get_user(txc.precision, &utp->precision) ||
  3419.    __get_user(txc.tolerance, &utp->tolerance) ||
  3420.    __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
  3421.    __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
  3422.    __get_user(txc.tick, &utp->tick) ||
  3423.    __get_user(txc.ppsfreq, &utp->ppsfreq) ||
  3424.    __get_user(txc.jitter, &utp->jitter) ||
  3425.    __get_user(txc.shift, &utp->shift) ||
  3426.    __get_user(txc.stabil, &utp->stabil) ||
  3427.    __get_user(txc.jitcnt, &utp->jitcnt) ||
  3428.    __get_user(txc.calcnt, &utp->calcnt) ||
  3429.    __get_user(txc.errcnt, &utp->errcnt) ||
  3430.    __get_user(txc.stbcnt, &utp->stbcnt))
  3431. return -EFAULT;
  3432. ret = do_adjtimex(&txc);
  3433. if(put_user(txc.modes, &utp->modes) ||
  3434.    __put_user(txc.offset, &utp->offset) ||
  3435.    __put_user(txc.freq, &utp->freq) ||
  3436.    __put_user(txc.maxerror, &utp->maxerror) ||
  3437.    __put_user(txc.esterror, &utp->esterror) ||
  3438.    __put_user(txc.status, &utp->status) ||
  3439.    __put_user(txc.constant, &utp->constant) ||
  3440.    __put_user(txc.precision, &utp->precision) ||
  3441.    __put_user(txc.tolerance, &utp->tolerance) ||
  3442.    __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
  3443.    __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
  3444.    __put_user(txc.tick, &utp->tick) ||
  3445.    __put_user(txc.ppsfreq, &utp->ppsfreq) ||
  3446.    __put_user(txc.jitter, &utp->jitter) ||
  3447.    __put_user(txc.shift, &utp->shift) ||
  3448.    __put_user(txc.stabil, &utp->stabil) ||
  3449.    __put_user(txc.jitcnt, &utp->jitcnt) ||
  3450.    __put_user(txc.calcnt, &utp->calcnt) ||
  3451.    __put_user(txc.errcnt, &utp->errcnt) ||
  3452.    __put_user(txc.stbcnt, &utp->stbcnt))
  3453. ret = -EFAULT;
  3454. return ret;
  3455. }
  3456. extern asmlinkage long sys_setpriority(int which, int who, int niceval);
  3457. asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval)
  3458. {
  3459. return sys_setpriority((int) which,
  3460.        (int) who,
  3461.        (int) niceval);
  3462. }
  3463. struct __sysctl_args32 {
  3464. u32 name;
  3465. int nlen;
  3466. u32 oldval;
  3467. u32 oldlenp;
  3468. u32 newval;
  3469. u32 newlen;
  3470. u32 __unused[4];
  3471. };
  3472. extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
  3473. {
  3474. struct __sysctl_args32 tmp;
  3475. int error;
  3476. size_t oldlen, *oldlenp = NULL;
  3477. unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
  3478. if (copy_from_user(&tmp, args, sizeof(tmp)))
  3479. return -EFAULT;
  3480. if (tmp.oldval && tmp.oldlenp) {
  3481. /* Duh, this is ugly and might not work if sysctl_args
  3482.    is in read-only memory, but do_sysctl does indirectly
  3483.    a lot of uaccess in both directions and we'd have to
  3484.    basically copy the whole sysctl.c here, and
  3485.    glibc's __sysctl uses rw memory for the structure
  3486.    anyway.  */
  3487. if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
  3488.     put_user(oldlen, (size_t *)addr))
  3489. return -EFAULT;
  3490. oldlenp = (size_t *)addr;
  3491. }
  3492. lock_kernel();
  3493. error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
  3494.   oldlenp, (void *)A(tmp.newval), tmp.newlen);
  3495. unlock_kernel();
  3496. if (oldlenp) {
  3497. if (!error) {
  3498. if (get_user(oldlen, (size_t *)addr) ||
  3499.     put_user(oldlen, (u32 *)A(tmp.oldlenp)))
  3500. error = -EFAULT;
  3501. }
  3502. copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
  3503. }
  3504. return error;
  3505. }
  3506. struct stat64_emu31 {
  3507. unsigned char   __pad0[6];
  3508. unsigned short  st_dev;
  3509. unsigned int    __pad1;
  3510. #define STAT64_HAS_BROKEN_ST_INO        1
  3511. u32             __st_ino;
  3512. unsigned int    st_mode;
  3513. unsigned int    st_nlink;
  3514. u32             st_uid;
  3515. u32             st_gid;
  3516. unsigned char   __pad2[6];
  3517. unsigned short  st_rdev;
  3518. unsigned int    __pad3;
  3519. long            st_size;
  3520. u32             st_blksize;
  3521. unsigned char   __pad4[4];
  3522. u32             __pad5;     /* future possible st_blocks high bits */
  3523. u32             st_blocks;  /* Number 512-byte blocks allocated. */
  3524. u32             st_atime;
  3525. u32             __pad6;
  3526. u32             st_mtime;
  3527. u32             __pad7;
  3528. u32             st_ctime;
  3529. u32             __pad8;     /* will be high 32 bits of ctime someday */
  3530. unsigned long   st_ino;
  3531. };
  3532. static inline int
  3533. putstat64 (struct stat64_emu31 *ubuf, struct stat *kbuf)
  3534. {
  3535.     struct stat64_emu31 tmp;
  3536.    
  3537.     memset(&tmp, 0, sizeof(tmp));
  3538.     tmp.st_dev = (unsigned short)kbuf->st_dev;
  3539.     tmp.st_ino = kbuf->st_ino;
  3540.     tmp.__st_ino = (u32)kbuf->st_ino;
  3541.     tmp.st_mode = kbuf->st_mode;
  3542.     tmp.st_nlink = (unsigned int)kbuf->st_nlink;
  3543.     tmp.st_uid = kbuf->st_uid;
  3544.     tmp.st_gid = kbuf->st_gid;
  3545.     tmp.st_rdev = (unsigned short)kbuf->st_rdev;
  3546.     tmp.st_size = kbuf->st_size;
  3547.     tmp.st_blksize = (u32)kbuf->st_blksize;
  3548.     tmp.st_blocks = (u32)kbuf->st_blocks;
  3549.     tmp.st_atime = (u32)kbuf->st_atime;
  3550.     tmp.st_mtime = (u32)kbuf->st_mtime;
  3551.     tmp.st_ctime = (u32)kbuf->st_ctime;
  3552.     return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
  3553. }
  3554. extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
  3555. asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf, long flags)
  3556. {
  3557.     int ret;
  3558.     struct stat s;
  3559.     char * tmp;
  3560.     int err;
  3561.     mm_segment_t old_fs = get_fs();
  3562.     
  3563.     tmp = getname(filename);
  3564.     err = PTR_ERR(tmp);
  3565.     if (IS_ERR(tmp))   
  3566.     return err;
  3567.     set_fs (KERNEL_DS);
  3568.     ret = sys_newstat(tmp, &s);
  3569.     set_fs (old_fs);
  3570.     putname(tmp);
  3571.     if (putstat64 (statbuf, &s)) 
  3572.     return -EFAULT;
  3573.     return ret;
  3574. }
  3575. extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
  3576. asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf, long flags)
  3577. {
  3578.     int ret;
  3579.     struct stat s;
  3580.     char * tmp;
  3581.     int err;
  3582.     mm_segment_t old_fs = get_fs();
  3583.     
  3584.     tmp = getname(filename);
  3585.     err = PTR_ERR(tmp);
  3586.     if (IS_ERR(tmp))   
  3587.     return err;
  3588.     set_fs (KERNEL_DS);
  3589.     ret = sys_newlstat(tmp, &s);
  3590.     set_fs (old_fs);
  3591.     putname(tmp);
  3592.     if (putstat64 (statbuf, &s)) 
  3593.     return -EFAULT;
  3594.     return ret;
  3595. }
  3596. extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
  3597. asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf, long flags)
  3598. {
  3599.     int ret;
  3600.     struct stat s;
  3601.     mm_segment_t old_fs = get_fs();
  3602.     
  3603.     set_fs (KERNEL_DS);
  3604.     ret = sys_newfstat(fd, &s);
  3605.     set_fs (old_fs);
  3606.     if (putstat64 (statbuf, &s))
  3607.     return -EFAULT;
  3608.     return ret;
  3609. }
  3610. /*
  3611.  * Linux/i386 didn't use to be able to handle more than
  3612.  * 4 system call parameters, so these system calls used a memory
  3613.  * block for parameter passing..
  3614.  */
  3615. struct mmap_arg_struct_emu31 {
  3616. u32 addr;
  3617. u32 len;
  3618. u32 prot;
  3619. u32 flags;
  3620. u32 fd;
  3621. u32 offset;
  3622. };
  3623. /* common code for old and new mmaps */
  3624. static inline long do_mmap2(
  3625. unsigned long addr, unsigned long len,
  3626. unsigned long prot, unsigned long flags,
  3627. unsigned long fd, unsigned long pgoff)
  3628. {
  3629. struct file * file = NULL;
  3630. unsigned long error = -EBADF;
  3631. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  3632. if (!(flags & MAP_ANONYMOUS)) {
  3633. file = fget(fd);
  3634. if (!file)
  3635. goto out;
  3636. }
  3637. down_write(&current->mm->mmap_sem);
  3638. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  3639. if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) {
  3640. /* Result is out of bounds.  */
  3641. do_munmap(current->mm, addr, len);
  3642. error = -ENOMEM;
  3643. }
  3644. up_write(&current->mm->mmap_sem);
  3645. if (file)
  3646. fput(file);
  3647. out:    
  3648. return error;
  3649. }
  3650. asmlinkage unsigned long
  3651. old32_mmap(struct mmap_arg_struct_emu31 *arg)
  3652. {
  3653. struct mmap_arg_struct_emu31 a;
  3654. int error = -EFAULT;
  3655. if (copy_from_user(&a, arg, sizeof(a)))
  3656. goto out;
  3657. error = -EINVAL;
  3658. if (a.offset & ~PAGE_MASK)
  3659. goto out;
  3660. error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); 
  3661. out:
  3662. return error;
  3663. }
  3664. asmlinkage long 
  3665. sys32_mmap2(struct mmap_arg_struct_emu31 *arg)
  3666. {
  3667. struct mmap_arg_struct_emu31 a;
  3668. int error = -EFAULT;
  3669. if (copy_from_user(&a, arg, sizeof(a)))
  3670. goto out;
  3671. error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
  3672. out:
  3673. return error;
  3674. }
  3675. extern asmlinkage long sys_socket(int family, int type, int protocol);
  3676. extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
  3677. extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
  3678. extern asmlinkage long sys_listen(int fd, int backlog);
  3679. extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen);
  3680. extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len);
  3681. extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len);
  3682. extern asmlinkage long sys_socketpair(int family, int type, int protocol, int usockvec[2]);
  3683. extern asmlinkage long sys_send(int fd, void * buff, size_t len, unsigned flags);
  3684. extern asmlinkage long sys_sendto(int fd, void * buff, size_t len, unsigned flags,
  3685.                            struct sockaddr *addr, int addr_len);
  3686. extern asmlinkage long sys_recv(int fd, void * ubuf, size_t size, unsigned flags);
  3687. extern asmlinkage long sys_recvfrom(int fd, void * ubuf, size_t size, unsigned flags,
  3688.                              struct sockaddr *addr, int *addr_len);
  3689. extern asmlinkage long sys_shutdown(int fd, int how);
  3690. extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char *optval, int * optlen);
  3691. /* Argument list sizes for sys_socketcall */
  3692. #define AL(x) ((x) * sizeof(u32))
  3693. static unsigned char nas[18] = {AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
  3694.                                 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
  3695.                                 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
  3696. #undef AL
  3697. asmlinkage long sys32_socketcall(int call, u32 *args)
  3698. {
  3699. int ret;
  3700. u32 a[6];
  3701.  
  3702. if (call < SYS_SOCKET || call > SYS_RECVMSG)
  3703. return -EINVAL;
  3704. if (copy_from_user(a, args, nas[call]))
  3705. return -EFAULT;
  3706. switch(call) {
  3707. case SYS_SOCKET:
  3708. ret = sys_socket(a[0], a[1], a[2]);
  3709. break;
  3710. case SYS_BIND:
  3711. ret = sys_bind(a[0], (struct sockaddr *) A(a[1]), a[2]);
  3712. break;
  3713. case SYS_CONNECT:
  3714. ret = sys_connect(a[0], (struct sockaddr *) A(a[1]), a[2]);
  3715. break;
  3716. case SYS_LISTEN:
  3717. ret = sys_listen(a[0], a[1]);
  3718. break;
  3719. case SYS_ACCEPT:
  3720. ret = sys_accept(a[0], (struct sockaddr *) A(a[1]),
  3721.  (int *) A(a[2]));
  3722. break;
  3723. case SYS_GETSOCKNAME:
  3724. ret = sys_getsockname(a[0], (struct sockaddr *) A(a[1]),
  3725.       (int *) A(a[2]));
  3726. break;
  3727. case SYS_GETPEERNAME:
  3728. ret = sys_getpeername(a[0], (struct sockaddr *) A(a[1]),
  3729.       (int *) A(a[2]));
  3730. break;
  3731. case SYS_SOCKETPAIR:
  3732. ret = sys_socketpair(a[0], a[1], a[2], (int *) A(a[3]));
  3733. break;
  3734. case SYS_SEND:
  3735. ret = sys_send(a[0], (void *) A(a[1]), a[2], a[3]);
  3736. break;
  3737. case SYS_SENDTO:
  3738. ret = sys_sendto(a[0], (void*) A(a[1]), a[2], a[3], (struct sockaddr *) A(a[4]), a[5]);
  3739. break;
  3740. case SYS_RECV:
  3741. ret = sys_recv(a[0], (void *) A(a[1]), a[2], a[3]);
  3742. break;
  3743. case SYS_RECVFROM:
  3744. ret = sys_recvfrom(a[0], (void *) A(a[1]), a[2], a[3], (struct sockaddr *) A(a[4]), (int *) A(a[5]) );
  3745. break;
  3746. case SYS_SHUTDOWN:
  3747. ret = sys_shutdown(a[0], a[1]);
  3748. break;
  3749. case SYS_SETSOCKOPT:
  3750. ret = sys32_setsockopt(a[0], a[1], a[2], (char *) A(a[3]),
  3751.      a[4]);
  3752. break;
  3753. case SYS_GETSOCKOPT:
  3754. ret = sys_getsockopt(a[0], a[1], a[2], (char *) A(a[3]), (int *) A(a[4]) );
  3755. break;
  3756. case SYS_SENDMSG:
  3757. ret = sys32_sendmsg(a[0], (struct msghdr32 *) A(a[1]),
  3758.     a[2]);
  3759. break;
  3760. case SYS_RECVMSG:
  3761. ret = sys32_recvmsg(a[0], (struct msghdr32 *) A(a[1]),
  3762.     a[2]);
  3763. break;
  3764. default:
  3765. ret = EINVAL;
  3766. break;
  3767. }
  3768. return ret;
  3769. }