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

嵌入式Linux

开发平台:

Unix_Linux

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