v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / arch / sparc64 / kernel / sys_sparc32.c
1 /* $Id: sys_sparc32.c,v 1.177 2001/06/10 06:48:46 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
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/fs.h> 
15 #include <linux/mm.h> 
16 #include <linux/file.h> 
17 #include <linux/signal.h>
18 #include <linux/utime.h>
19 #include <linux/resource.h>
20 #include <linux/times.h>
21 #include <linux/utsname.h>
22 #include <linux/timex.h>
23 #include <linux/smp.h>
24 #include <linux/smp_lock.h>
25 #include <linux/sem.h>
26 #include <linux/msg.h>
27 #include <linux/shm.h>
28 #include <linux/slab.h>
29 #include <linux/uio.h>
30 #include <linux/nfs_fs.h>
31 #include <linux/smb_fs.h>
32 #include <linux/smb_mount.h>
33 #include <linux/ncp_fs.h>
34 #include <linux/quota.h>
35 #include <linux/module.h>
36 #include <linux/sunrpc/svc.h>
37 #include <linux/nfsd/nfsd.h>
38 #include <linux/nfsd/cache.h>
39 #include <linux/nfsd/xdr.h>
40 #include <linux/nfsd/syscall.h>
41 #include <linux/poll.h>
42 #include <linux/personality.h>
43 #include <linux/stat.h>
44 #include <linux/filter.h>
45 #include <linux/highmem.h>
46 #include <linux/highuid.h>
47 #include <linux/mman.h>
48 #include <linux/ipv6.h>
49 #include <linux/in.h>
50 #include <linux/icmpv6.h>
51 #include <linux/sysctl.h>
52
53 #include <asm/types.h>
54 #include <asm/ipc.h>
55 #include <asm/uaccess.h>
56 #include <asm/fpumacro.h>
57 #include <asm/semaphore.h>
58
59 #include <net/scm.h>
60
61 /* Use this to get at 32-bit user passed pointers. */
62 /* Things to consider: the low-level assembly stub does
63    srl x, 0, x for first four arguments, so if you have
64    pointer to something in the first four arguments, just
65    declare it as a pointer, not u32. On the other side, 
66    arguments from 5th onwards should be declared as u32
67    for pointers, and need AA() around each usage.
68    A() macro should be used for places where you e.g.
69    have some internal variable u32 and just want to get
70    rid of a compiler warning. AA() has to be used in
71    places where you want to convert a function argument
72    to 32bit pointer or when you e.g. access pt_regs
73    structure and want to consider 32bit registers only.
74    -jj
75  */
76 #define A(__x) ((unsigned long)(__x))
77 #define AA(__x)                         \
78 ({      unsigned long __ret;            \
79         __asm__ ("srl   %0, 0, %0"      \
80                  : "=r" (__ret)         \
81                  : "0" (__x));          \
82         __ret;                          \
83 })
84
85 extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
86 extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
87 extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
88 extern asmlinkage long sys_setregid(gid_t, gid_t);
89 extern asmlinkage long sys_setgid(gid_t);
90 extern asmlinkage long sys_setreuid(uid_t, uid_t);
91 extern asmlinkage long sys_setuid(uid_t);
92 extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
93 extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
94 extern asmlinkage long sys_setfsuid(uid_t);
95 extern asmlinkage long sys_setfsgid(gid_t);
96  
97 /* For this source file, we want overflow handling. */
98
99 #undef high2lowuid
100 #undef high2lowgid
101 #undef low2highuid
102 #undef low2highgid
103 #undef SET_UID16
104 #undef SET_GID16
105 #undef NEW_TO_OLD_UID
106 #undef NEW_TO_OLD_GID
107 #undef SET_OLDSTAT_UID
108 #undef SET_OLDSTAT_GID
109 #undef SET_STAT_UID
110 #undef SET_STAT_GID
111
112 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
113 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
114 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
115 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
116 #define SET_UID16(var, uid)     var = high2lowuid(uid)
117 #define SET_GID16(var, gid)     var = high2lowgid(gid)
118 #define NEW_TO_OLD_UID(uid)     high2lowuid(uid)
119 #define NEW_TO_OLD_GID(gid)     high2lowgid(gid)
120 #define SET_OLDSTAT_UID(stat, uid)      (stat).st_uid = high2lowuid(uid)
121 #define SET_OLDSTAT_GID(stat, gid)      (stat).st_gid = high2lowgid(gid)
122 #define SET_STAT_UID(stat, uid)         (stat).st_uid = high2lowuid(uid)
123 #define SET_STAT_GID(stat, gid)         (stat).st_gid = high2lowgid(gid)
124
125 asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
126 {
127         return sys_chown(filename, low2highuid(user), low2highgid(group));
128 }
129
130 asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
131 {
132         return sys_lchown(filename, low2highuid(user), low2highgid(group));
133 }
134
135 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
136 {
137         return sys_fchown(fd, low2highuid(user), low2highgid(group));
138 }
139
140 asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
141 {
142         return sys_setregid(low2highgid(rgid), low2highgid(egid));
143 }
144
145 asmlinkage long sys32_setgid16(u16 gid)
146 {
147         return sys_setgid((gid_t)gid);
148 }
149
150 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
151 {
152         return sys_setreuid(low2highuid(ruid), low2highuid(euid));
153 }
154
155 asmlinkage long sys32_setuid16(u16 uid)
156 {
157         return sys_setuid((uid_t)uid);
158 }
159
160 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
161 {
162         return sys_setresuid(low2highuid(ruid), low2highuid(euid),
163                 low2highuid(suid));
164 }
165
166 asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
167 {
168         int retval;
169
170         if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
171             !(retval = put_user(high2lowuid(current->euid), euid)))
172                 retval = put_user(high2lowuid(current->suid), suid);
173
174         return retval;
175 }
176
177 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
178 {
179         return sys_setresgid(low2highgid(rgid), low2highgid(egid),
180                 low2highgid(sgid));
181 }
182
183 asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
184 {
185         int retval;
186
187         if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
188             !(retval = put_user(high2lowgid(current->egid), egid)))
189                 retval = put_user(high2lowgid(current->sgid), sgid);
190
191         return retval;
192 }
193
194 asmlinkage long sys32_setfsuid16(u16 uid)
195 {
196         return sys_setfsuid((uid_t)uid);
197 }
198
199 asmlinkage long sys32_setfsgid16(u16 gid)
200 {
201         return sys_setfsgid((gid_t)gid);
202 }
203
204 asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
205 {
206         u16 groups[NGROUPS];
207         int i,j;
208
209         if (gidsetsize < 0)
210                 return -EINVAL;
211         i = current->ngroups;
212         if (gidsetsize) {
213                 if (i > gidsetsize)
214                         return -EINVAL;
215                 for(j=0;j<i;j++)
216                         groups[j] = current->groups[j];
217                 if (copy_to_user(grouplist, groups, sizeof(u16)*i))
218                         return -EFAULT;
219         }
220         return i;
221 }
222
223 asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
224 {
225         u16 groups[NGROUPS];
226         int i;
227
228         if (!capable(CAP_SETGID))
229                 return -EPERM;
230         if ((unsigned) gidsetsize > NGROUPS)
231                 return -EINVAL;
232         if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
233                 return -EFAULT;
234         for (i = 0 ; i < gidsetsize ; i++)
235                 current->groups[i] = (gid_t)groups[i];
236         current->ngroups = gidsetsize;
237         return 0;
238 }
239
240 asmlinkage long sys32_getuid16(void)
241 {
242         return high2lowuid(current->uid);
243 }
244
245 asmlinkage long sys32_geteuid16(void)
246 {
247         return high2lowuid(current->euid);
248 }
249
250 asmlinkage long sys32_getgid16(void)
251 {
252         return high2lowgid(current->gid);
253 }
254
255 asmlinkage long sys32_getegid16(void)
256 {
257         return high2lowgid(current->egid);
258 }
259
260 /* 32-bit timeval and related flotsam.  */
261
262 struct timeval32
263 {
264     int tv_sec, tv_usec;
265 };
266
267 struct itimerval32
268 {
269     struct timeval32 it_interval;
270     struct timeval32 it_value;
271 };
272
273 static inline long get_tv32(struct timeval *o, struct timeval32 *i)
274 {
275         return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
276                 (__get_user(o->tv_sec, &i->tv_sec) |
277                  __get_user(o->tv_usec, &i->tv_usec)));
278 }
279
280 static inline long put_tv32(struct timeval32 *o, struct timeval *i)
281 {
282         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
283                 (__put_user(i->tv_sec, &o->tv_sec) |
284                  __put_user(i->tv_usec, &o->tv_usec)));
285 }
286
287 static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
288 {
289         return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
290                 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
291                  __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
292                  __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
293                  __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
294 }
295
296 static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
297 {
298         return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
299                 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
300                  __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
301                  __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
302                  __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
303 }
304
305 extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
306
307 asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
308 {
309         return sys_ioperm((unsigned long)from, (unsigned long)num, on);
310 }
311
312 struct msgbuf32 { s32 mtype; char mtext[1]; };
313
314 struct ipc_perm32
315 {
316         key_t             key;
317         __kernel_uid_t32  uid;
318         __kernel_gid_t32  gid;
319         __kernel_uid_t32  cuid;
320         __kernel_gid_t32  cgid;
321         __kernel_mode_t32 mode;
322         unsigned short  seq;
323 };
324
325 struct semid_ds32 {
326         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
327         __kernel_time_t32 sem_otime;              /* last semop time */
328         __kernel_time_t32 sem_ctime;              /* last change time */
329         u32 sem_base;              /* ptr to first semaphore in array */
330         u32 sem_pending;          /* pending operations to be processed */
331         u32 sem_pending_last;    /* last pending operation */
332         u32 undo;                  /* undo requests on this array */
333         unsigned short  sem_nsems;              /* no. of semaphores in array */
334 };
335
336 struct semid64_ds32 {
337         struct ipc64_perm sem_perm;               /* this structure is the same on sparc32 and sparc64 */
338         unsigned int      __pad1;
339         __kernel_time_t32 sem_otime;
340         unsigned int      __pad2;
341         __kernel_time_t32 sem_ctime;
342         u32 sem_nsems;
343         u32 __unused1;
344         u32 __unused2;
345 };
346
347 struct msqid_ds32
348 {
349         struct ipc_perm32 msg_perm;
350         u32 msg_first;
351         u32 msg_last;
352         __kernel_time_t32 msg_stime;
353         __kernel_time_t32 msg_rtime;
354         __kernel_time_t32 msg_ctime;
355         u32 wwait;
356         u32 rwait;
357         unsigned short msg_cbytes;
358         unsigned short msg_qnum;  
359         unsigned short msg_qbytes;
360         __kernel_ipc_pid_t32 msg_lspid;
361         __kernel_ipc_pid_t32 msg_lrpid;
362 };
363
364 struct msqid64_ds32 {
365         struct ipc64_perm msg_perm;
366         unsigned int   __pad1;
367         __kernel_time_t32 msg_stime;
368         unsigned int   __pad2;
369         __kernel_time_t32 msg_rtime;
370         unsigned int   __pad3;
371         __kernel_time_t32 msg_ctime;
372         unsigned int  msg_cbytes;
373         unsigned int  msg_qnum;
374         unsigned int  msg_qbytes;
375         __kernel_pid_t32 msg_lspid;
376         __kernel_pid_t32 msg_lrpid;
377         unsigned int  __unused1;
378         unsigned int  __unused2;
379 };
380
381
382 struct shmid_ds32 {
383         struct ipc_perm32       shm_perm;
384         int                     shm_segsz;
385         __kernel_time_t32       shm_atime;
386         __kernel_time_t32       shm_dtime;
387         __kernel_time_t32       shm_ctime;
388         __kernel_ipc_pid_t32    shm_cpid; 
389         __kernel_ipc_pid_t32    shm_lpid; 
390         unsigned short          shm_nattch;
391 };
392
393 struct shmid64_ds32 {
394         struct ipc64_perm       shm_perm;
395         unsigned int            __pad1;
396         __kernel_time_t32       shm_atime;
397         unsigned int            __pad2;
398         __kernel_time_t32       shm_dtime;
399         unsigned int            __pad3;
400         __kernel_time_t32       shm_ctime;
401         __kernel_size_t32       shm_segsz;
402         __kernel_pid_t32        shm_cpid;
403         __kernel_pid_t32        shm_lpid;
404         unsigned int            shm_nattch;
405         unsigned int            __unused1;
406         unsigned int            __unused2;
407 };
408
409                                                         
410 /*
411  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
412  *
413  * This is really horribly ugly.
414  */
415 #define IPCOP_MASK(__x) (1UL << (__x))
416 static int do_sys32_semctl(int first, int second, int third, void *uptr)
417 {
418         union semun fourth;
419         u32 pad;
420         int err = -EINVAL;
421
422         if (!uptr)
423                 goto out;
424         err = -EFAULT;
425         if (get_user (pad, (u32 *)uptr))
426                 goto out;
427         if(third == SETVAL)
428                 fourth.val = (int)pad;
429         else
430                 fourth.__pad = (void *)A(pad);
431         if (IPCOP_MASK (third) &
432             (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
433              IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
434              IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
435                 err = sys_semctl (first, second, third, fourth);
436         } else if (third & IPC_64) {
437                 struct semid64_ds s;
438                 struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
439                 mm_segment_t old_fs;
440                 int need_back_translation;
441
442                 if (third == (IPC_SET|IPC_64)) {
443                         err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
444                         err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
445                         err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
446                         if (err)
447                                 goto out;
448                         fourth.__pad = &s;
449                 }
450                 need_back_translation =
451                         (IPCOP_MASK (third) &
452                          (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
453                 if (need_back_translation)
454                         fourth.__pad = &s;
455                 old_fs = get_fs ();
456                 set_fs (KERNEL_DS);
457                 err = sys_semctl (first, second, third, fourth);
458                 set_fs (old_fs);
459                 if (need_back_translation) {
460                         int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
461                         err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
462                         if (err2) err = -EFAULT;
463                 }
464         } else {
465                 struct semid_ds s;
466                 struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
467                 mm_segment_t old_fs;
468                 int need_back_translation;
469
470                 if (third == IPC_SET) {
471                         err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
472                         err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
473                         err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
474                         if (err)
475                                 goto out;
476                         fourth.__pad = &s;
477                 }
478                 need_back_translation =
479                         (IPCOP_MASK (third) &
480                          (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
481                 if (need_back_translation)
482                         fourth.__pad = &s;
483                 old_fs = get_fs ();
484                 set_fs (KERNEL_DS);
485                 err = sys_semctl (first, second, third, fourth);
486                 set_fs (old_fs);
487                 if (need_back_translation) {
488                         int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
489                         err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
490                         err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
491                         err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
492                         err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
493                         err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
494                         err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
495                         err2 |= __put_user (s.sem_otime, &usp->sem_otime);
496                         err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
497                         err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
498                         if (err2) err = -EFAULT;
499                 }
500         }
501 out:
502         return err;
503 }
504
505 static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
506 {
507         struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
508         struct msgbuf32 *up = (struct msgbuf32 *)uptr;
509         mm_segment_t old_fs;
510         int err;
511
512         if (!p)
513                 return -ENOMEM;
514         err = get_user (p->mtype, &up->mtype);
515         err |= __copy_from_user (p->mtext, &up->mtext, second);
516         if (err)
517                 goto out;
518         old_fs = get_fs ();
519         set_fs (KERNEL_DS);
520         err = sys_msgsnd (first, p, second, third);
521         set_fs (old_fs);
522 out:
523         kfree (p);
524         return err;
525 }
526
527 static int do_sys32_msgrcv (int first, int second, int msgtyp, int third,
528                             int version, void *uptr)
529 {
530         struct msgbuf32 *up;
531         struct msgbuf *p;
532         mm_segment_t old_fs;
533         int err;
534
535         if (!version) {
536                 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
537                 struct ipc_kludge ipck;
538
539                 err = -EINVAL;
540                 if (!uptr)
541                         goto out;
542                 err = -EFAULT;
543                 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
544                         goto out;
545                 uptr = (void *)A(ipck.msgp);
546                 msgtyp = ipck.msgtyp;
547         }
548         err = -ENOMEM;
549         p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
550         if (!p)
551                 goto out;
552         old_fs = get_fs ();
553         set_fs (KERNEL_DS);
554         err = sys_msgrcv (first, p, second + 4, msgtyp, third);
555         set_fs (old_fs);
556         if (err < 0)
557                 goto free_then_out;
558         up = (struct msgbuf32 *)uptr;
559         if (put_user (p->mtype, &up->mtype) ||
560             __copy_to_user (&up->mtext, p->mtext, err))
561                 err = -EFAULT;
562 free_then_out:
563         kfree (p);
564 out:
565         return err;
566 }
567
568 static int do_sys32_msgctl (int first, int second, void *uptr)
569 {
570         int err;
571
572         if (IPCOP_MASK (second) &
573             (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
574              IPCOP_MASK (IPC_RMID))) {
575                 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
576         } else if (second & IPC_64) {
577                 struct msqid64_ds m;
578                 struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
579                 mm_segment_t old_fs;
580
581                 if (second == (IPC_SET|IPC_64)) {
582                         err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
583                         err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
584                         err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
585                         err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
586                         if (err)
587                                 goto out;
588                 }
589                 old_fs = get_fs ();
590                 set_fs (KERNEL_DS);
591                 err = sys_msgctl (first, second, (struct msqid_ds *)&m);
592                 set_fs (old_fs);
593                 if (IPCOP_MASK (second) &
594                     (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
595                         int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
596                         err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
597                         err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
598                         err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
599                         err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
600                         err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
601                         if (err2)
602                                 err = -EFAULT;
603                 }
604         } else {
605                 struct msqid_ds m;
606                 struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
607                 mm_segment_t old_fs;
608
609                 if (second == IPC_SET) {
610                         err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
611                         err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
612                         err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
613                         err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
614                         if (err)
615                                 goto out;
616                 }
617                 old_fs = get_fs ();
618                 set_fs (KERNEL_DS);
619                 err = sys_msgctl (first, second, &m);
620                 set_fs (old_fs);
621                 if (IPCOP_MASK (second) &
622                     (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
623                         int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
624                         err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
625                         err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
626                         err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
627                         err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
628                         err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
629                         err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
630                         err2 |= __put_user (m.msg_stime, &up->msg_stime);
631                         err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
632                         err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
633                         err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
634                         err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
635                         err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
636                         err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
637                         err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
638                         if (err2)
639                                 err = -EFAULT;
640                 }
641         }
642
643 out:
644         return err;
645 }
646
647 static int do_sys32_shmat (int first, int second, int third, int version, void *uptr)
648 {
649         unsigned long raddr;
650         u32 *uaddr = (u32 *)A((u32)third);
651         int err = -EINVAL;
652
653         if (version == 1)
654                 goto out;
655         err = sys_shmat (first, uptr, second, &raddr);
656         if (err)
657                 goto out;
658         err = put_user (raddr, uaddr);
659 out:
660         return err;
661 }
662
663 static int do_sys32_shmctl (int first, int second, void *uptr)
664 {
665         int err;
666
667         if (IPCOP_MASK (second) &
668             (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
669              IPCOP_MASK (IPC_RMID))) {
670                 if (second == (IPC_INFO|IPC_64))
671                         second = IPC_INFO; /* So that we don't have to translate it */
672                 err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
673         } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
674                 struct shmid64_ds s;
675                 struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
676                 mm_segment_t old_fs;
677
678                 if (second == (IPC_SET|IPC_64)) {
679                         err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
680                         err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
681                         err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
682                         if (err)
683                                 goto out;
684                 }
685                 old_fs = get_fs ();
686                 set_fs (KERNEL_DS);
687                 err = sys_shmctl (first, second, (struct shmid_ds *)&s);
688                 set_fs (old_fs);
689                 if (err < 0)
690                         goto out;
691
692                 /* Mask it even in this case so it becomes a CSE. */
693                 if (IPCOP_MASK (second) &
694                     (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
695                         int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
696                         err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
697                         err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
698                         err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
699                         err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
700                         if (err2)
701                                 err = -EFAULT;
702                 }
703         } else {
704                 struct shmid_ds s;
705                 struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
706                 mm_segment_t old_fs;
707
708                 second &= ~IPC_64;
709                 if (second == IPC_SET) {
710                         err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
711                         err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
712                         err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
713                         if (err)
714                                 goto out;
715                 }
716                 old_fs = get_fs ();
717                 set_fs (KERNEL_DS);
718                 err = sys_shmctl (first, second, &s);
719                 set_fs (old_fs);
720                 if (err < 0)
721                         goto out;
722
723                 /* Mask it even in this case so it becomes a CSE. */
724                 if (second == SHM_INFO) {
725                         struct shm_info32 {
726                                 int used_ids;
727                                 u32 shm_tot, shm_rss, shm_swp;
728                                 u32 swap_attempts, swap_successes;
729                         } *uip = (struct shm_info32 *)uptr;
730                         struct shm_info *kp = (struct shm_info *)&s;
731                         int err2 = put_user (kp->used_ids, &uip->used_ids);
732                         err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
733                         err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
734                         err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
735                         err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts);
736                         err2 |= __put_user (kp->swap_successes, &uip->swap_successes);
737                         if (err2)
738                                 err = -EFAULT;
739                 } else if (IPCOP_MASK (second) &
740                            (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
741                         int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
742                         err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
743                         err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid);
744                         err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
745                         err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid);
746                         err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
747                         err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
748                         err2 |= __put_user (s.shm_atime, &up->shm_atime);
749                         err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
750                         err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
751                         err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
752                         err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
753                         err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
754                         err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
755                         if (err2)
756                                 err = -EFAULT;
757                 }
758         }
759 out:
760         return err;
761 }
762
763 asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
764 {
765         int version, err;
766
767         version = call >> 16; /* hack for backward compatibility */
768         call &= 0xffff;
769
770         if (call <= SEMCTL)
771                 switch (call) {
772                 case SEMOP:
773                         /* struct sembuf is the same on 32 and 64bit :)) */
774                         err = sys_semop (first, (struct sembuf *)AA(ptr), second);
775                         goto out;
776                 case SEMGET:
777                         err = sys_semget (first, second, third);
778                         goto out;
779                 case SEMCTL:
780                         err = do_sys32_semctl (first, second, third, (void *)AA(ptr));
781                         goto out;
782                 default:
783                         err = -EINVAL;
784                         goto out;
785                 };
786         if (call <= MSGCTL) 
787                 switch (call) {
788                 case MSGSND:
789                         err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr));
790                         goto out;
791                 case MSGRCV:
792                         err = do_sys32_msgrcv (first, second, fifth, third,
793                                                version, (void *)AA(ptr));
794                         goto out;
795                 case MSGGET:
796                         err = sys_msgget ((key_t) first, second);
797                         goto out;
798                 case MSGCTL:
799                         err = do_sys32_msgctl (first, second, (void *)AA(ptr));
800                         goto out;
801                 default:
802                         err = -EINVAL;
803                         goto out;
804                 }
805         if (call <= SHMCTL) 
806                 switch (call) {
807                 case SHMAT:
808                         err = do_sys32_shmat (first, second, third,
809                                               version, (void *)AA(ptr));
810                         goto out;
811                 case SHMDT: 
812                         err = sys_shmdt ((char *)AA(ptr));
813                         goto out;
814                 case SHMGET:
815                         err = sys_shmget (first, second, third);
816                         goto out;
817                 case SHMCTL:
818                         err = do_sys32_shmctl (first, second, (void *)AA(ptr));
819                         goto out;
820                 default:
821                         err = -EINVAL;
822                         goto out;
823                 }
824
825         err = -EINVAL;
826
827 out:
828         return err;
829 }
830
831 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
832 {
833         int err;
834         
835         err = get_user(kfl->l_type, &ufl->l_type);
836         err |= __get_user(kfl->l_whence, &ufl->l_whence);
837         err |= __get_user(kfl->l_start, &ufl->l_start);
838         err |= __get_user(kfl->l_len, &ufl->l_len);
839         err |= __get_user(kfl->l_pid, &ufl->l_pid);
840         return err;
841 }
842
843 static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
844 {
845         int err;
846         
847         err = __put_user(kfl->l_type, &ufl->l_type);
848         err |= __put_user(kfl->l_whence, &ufl->l_whence);
849         err |= __put_user(kfl->l_start, &ufl->l_start);
850         err |= __put_user(kfl->l_len, &ufl->l_len);
851         err |= __put_user(kfl->l_pid, &ufl->l_pid);
852         return err;
853 }
854
855 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
856
857 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
858 {
859         switch (cmd) {
860         case F_GETLK:
861         case F_SETLK:
862         case F_SETLKW:
863                 {
864                         struct flock f;
865                         mm_segment_t old_fs;
866                         long ret;
867                         
868                         if (get_flock(&f, (struct flock32 *)arg))
869                                 return -EFAULT;
870                         old_fs = get_fs(); set_fs (KERNEL_DS);
871                         ret = sys_fcntl(fd, cmd, (unsigned long)&f);
872                         set_fs (old_fs);
873                         if (ret) return ret;
874                         if (put_flock(&f, (struct flock32 *)arg))
875                                 return -EFAULT;
876                         return 0;
877                 }
878         default:
879                 return sys_fcntl(fd, cmd, (unsigned long)arg);
880         }
881 }
882
883 asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
884 {
885         if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
886                 return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg);
887         return sys32_fcntl(fd, cmd, arg);
888 }
889
890 struct dqblk32 {
891     __u32 dqb_bhardlimit;
892     __u32 dqb_bsoftlimit;
893     __u32 dqb_curblocks;
894     __u32 dqb_ihardlimit;
895     __u32 dqb_isoftlimit;
896     __u32 dqb_curinodes;
897     __kernel_time_t32 dqb_btime;
898     __kernel_time_t32 dqb_itime;
899 };
900                                 
901 extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
902
903 asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
904 {
905         int cmds = cmd >> SUBCMDSHIFT;
906         int err;
907         struct dqblk d;
908         mm_segment_t old_fs;
909         char *spec;
910         
911         switch (cmds) {
912         case Q_GETQUOTA:
913                 break;
914         case Q_SETQUOTA:
915         case Q_SETUSE:
916         case Q_SETQLIM:
917                 if (copy_from_user (&d, (struct dqblk32 *)addr,
918                                     sizeof (struct dqblk32)))
919                         return -EFAULT;
920                 d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
921                 d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
922                 break;
923         default:
924                 return sys_quotactl(cmd, special,
925                                     id, (caddr_t)addr);
926         }
927         spec = getname (special);
928         err = PTR_ERR(spec);
929         if (IS_ERR(spec)) return err;
930         old_fs = get_fs ();
931         set_fs (KERNEL_DS);
932         err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
933         set_fs (old_fs);
934         putname (spec);
935         if (cmds == Q_GETQUOTA) {
936                 __kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
937                 ((struct dqblk32 *)&d)->dqb_itime = i;
938                 ((struct dqblk32 *)&d)->dqb_btime = b;
939                 if (copy_to_user ((struct dqblk32 *)addr, &d,
940                                   sizeof (struct dqblk32)))
941                         return -EFAULT;
942         }
943         return err;
944 }
945
946 static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
947 {
948         int err;
949         
950         err = put_user (kbuf->f_type, &ubuf->f_type);
951         err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
952         err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
953         err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
954         err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
955         err |= __put_user (kbuf->f_files, &ubuf->f_files);
956         err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
957         err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
958         err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
959         err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
960         return err;
961 }
962
963 extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
964
965 asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
966 {
967         int ret;
968         struct statfs s;
969         mm_segment_t old_fs = get_fs();
970         char *pth;
971         
972         pth = getname (path);
973         ret = PTR_ERR(pth);
974         if (!IS_ERR(pth)) {
975                 set_fs (KERNEL_DS);
976                 ret = sys_statfs((const char *)pth, &s);
977                 set_fs (old_fs);
978                 putname (pth);
979                 if (put_statfs(buf, &s))
980                         return -EFAULT;
981         }
982         return ret;
983 }
984
985 extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
986
987 asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
988 {
989         int ret;
990         struct statfs s;
991         mm_segment_t old_fs = get_fs();
992         
993         set_fs (KERNEL_DS);
994         ret = sys_fstatfs(fd, &s);
995         set_fs (old_fs);
996         if (put_statfs(buf, &s))
997                 return -EFAULT;
998         return ret;
999 }
1000
1001 extern asmlinkage long sys_truncate(const char * path, unsigned long length);
1002 extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
1003
1004 asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
1005 {
1006         if ((int)high < 0)
1007                 return -EINVAL;
1008         else
1009                 return sys_truncate(path, (high << 32) | low);
1010 }
1011
1012 asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
1013 {
1014         if ((int)high < 0)
1015                 return -EINVAL;
1016         else
1017                 return sys_ftruncate(fd, (high << 32) | low);
1018 }
1019
1020 extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
1021
1022 struct utimbuf32 {
1023         __kernel_time_t32 actime, modtime;
1024 };
1025
1026 asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
1027 {
1028         struct utimbuf t;
1029         mm_segment_t old_fs;
1030         int ret;
1031         char *filenam;
1032         
1033         if (!times)
1034                 return sys_utime(filename, NULL);
1035         if (get_user (t.actime, &times->actime) ||
1036             __get_user (t.modtime, &times->modtime))
1037                 return -EFAULT;
1038         filenam = getname (filename);
1039         ret = PTR_ERR(filenam);
1040         if (!IS_ERR(filenam)) {
1041                 old_fs = get_fs();
1042                 set_fs (KERNEL_DS); 
1043                 ret = sys_utime(filenam, &t);
1044                 set_fs (old_fs);
1045                 putname (filenam);
1046         }
1047         return ret;
1048 }
1049
1050 struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
1051
1052 typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
1053 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
1054
1055 static long do_readv_writev32(int type, struct file *file,
1056                               const struct iovec32 *vector, u32 count)
1057 {
1058         unsigned long tot_len;
1059         struct iovec iovstack[UIO_FASTIOV];
1060         struct iovec *iov=iovstack, *ivp;
1061         struct inode *inode;
1062         long retval, i;
1063         io_fn_t fn;
1064         iov_fn_t fnv;
1065
1066         /* First get the "struct iovec" from user memory and
1067          * verify all the pointers
1068          */
1069         if (!count)
1070                 return 0;
1071         if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
1072                 return -EFAULT;
1073         if (count > UIO_MAXIOV)
1074                 return -EINVAL;
1075         if (count > UIO_FASTIOV) {
1076                 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1077                 if (!iov)
1078                         return -ENOMEM;
1079         }
1080
1081         tot_len = 0;
1082         i = count;
1083         ivp = iov;
1084         while(i > 0) {
1085                 u32 len;
1086                 u32 buf;
1087
1088                 __get_user(len, &vector->iov_len);
1089                 __get_user(buf, &vector->iov_base);
1090                 tot_len += len;
1091                 ivp->iov_base = (void *)A(buf);
1092                 ivp->iov_len = (__kernel_size_t) len;
1093                 vector++;
1094                 ivp++;
1095                 i--;
1096         }
1097
1098         inode = file->f_dentry->d_inode;
1099         /* VERIFY_WRITE actually means a read, as we write to user space */
1100         retval = locks_verify_area((type == VERIFY_WRITE
1101                                     ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
1102                                    inode, file, file->f_pos, tot_len);
1103         if (retval)
1104                 goto out;
1105
1106         /* VERIFY_WRITE actually means a read, as we write to user space */
1107         fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
1108         if (fnv) {
1109                 retval = fnv(file, iov, count, &file->f_pos);
1110                 goto out;
1111         }
1112
1113         fn = (type == VERIFY_WRITE ? file->f_op->read :
1114               (io_fn_t) file->f_op->write);
1115
1116         ivp = iov;
1117         while (count > 0) {
1118                 void * base;
1119                 int len, nr;
1120
1121                 base = ivp->iov_base;
1122                 len = ivp->iov_len;
1123                 ivp++;
1124                 count--;
1125                 nr = fn(file, base, len, &file->f_pos);
1126                 if (nr < 0) {
1127                         if (!retval)
1128                                 retval = nr;
1129                         break;
1130                 }
1131                 retval += nr;
1132                 if (nr != len)
1133                         break;
1134         }
1135 out:
1136         if (iov != iovstack)
1137                 kfree(iov);
1138
1139         return retval;
1140 }
1141
1142 asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
1143 {
1144         struct file *file;
1145         long ret = -EBADF;
1146
1147         file = fget(fd);
1148         if(!file)
1149                 goto bad_file;
1150
1151         if (file->f_op && (file->f_mode & FMODE_READ) &&
1152             (file->f_op->readv || file->f_op->read))
1153                 ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
1154         fput(file);
1155
1156 bad_file:
1157         return ret;
1158 }
1159
1160 asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
1161 {
1162         struct file *file;
1163         int ret = -EBADF;
1164
1165         file = fget(fd);
1166         if(!file)
1167                 goto bad_file;
1168         if (file->f_op && (file->f_mode & FMODE_WRITE) &&
1169             (file->f_op->writev || file->f_op->write))
1170                 ret = do_readv_writev32(VERIFY_READ, file, vector, count);
1171         fput(file);
1172
1173 bad_file:
1174         return ret;
1175 }
1176
1177 /* readdir & getdents */
1178
1179 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1180 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1181
1182 struct old_linux_dirent32 {
1183         u32             d_ino;
1184         u32             d_offset;
1185         unsigned short  d_namlen;
1186         char            d_name[1];
1187 };
1188
1189 struct readdir_callback32 {
1190         struct old_linux_dirent32 * dirent;
1191         int count;
1192 };
1193
1194 static int fillonedir(void * __buf, const char * name, int namlen,
1195                       loff_t offset, ino_t ino, unsigned int d_type)
1196 {
1197         struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
1198         struct old_linux_dirent32 * dirent;
1199
1200         if (buf->count)
1201                 return -EINVAL;
1202         buf->count++;
1203         dirent = buf->dirent;
1204         put_user(ino, &dirent->d_ino);
1205         put_user(offset, &dirent->d_offset);
1206         put_user(namlen, &dirent->d_namlen);
1207         copy_to_user(dirent->d_name, name, namlen);
1208         put_user(0, dirent->d_name + namlen);
1209         return 0;
1210 }
1211
1212 asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
1213 {
1214         int error = -EBADF;
1215         struct file * file;
1216         struct readdir_callback32 buf;
1217
1218         file = fget(fd);
1219         if (!file)
1220                 goto out;
1221
1222         buf.count = 0;
1223         buf.dirent = dirent;
1224
1225         error = vfs_readdir(file, fillonedir, &buf);
1226         if (error < 0)
1227                 goto out_putf;
1228         error = buf.count;
1229
1230 out_putf:
1231         fput(file);
1232 out:
1233         return error;
1234 }
1235
1236 struct linux_dirent32 {
1237         u32             d_ino;
1238         u32             d_off;
1239         unsigned short  d_reclen;
1240         char            d_name[1];
1241 };
1242
1243 struct getdents_callback32 {
1244         struct linux_dirent32 * current_dir;
1245         struct linux_dirent32 * previous;
1246         int count;
1247         int error;
1248 };
1249
1250 static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
1251                    unsigned int d_type)
1252 {
1253         struct linux_dirent32 * dirent;
1254         struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
1255         int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
1256
1257         buf->error = -EINVAL;   /* only used if we fail.. */
1258         if (reclen > buf->count)
1259                 return -EINVAL;
1260         dirent = buf->previous;
1261         if (dirent)
1262                 put_user(offset, &dirent->d_off);
1263         dirent = buf->current_dir;
1264         buf->previous = dirent;
1265         put_user(ino, &dirent->d_ino);
1266         put_user(reclen, &dirent->d_reclen);
1267         copy_to_user(dirent->d_name, name, namlen);
1268         put_user(0, dirent->d_name + namlen);
1269         ((char *) dirent) += reclen;
1270         buf->current_dir = dirent;
1271         buf->count -= reclen;
1272         return 0;
1273 }
1274
1275 asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
1276 {
1277         struct file * file;
1278         struct linux_dirent32 * lastdirent;
1279         struct getdents_callback32 buf;
1280         int error = -EBADF;
1281
1282         file = fget(fd);
1283         if (!file)
1284                 goto out;
1285
1286         buf.current_dir = dirent;
1287         buf.previous = NULL;
1288         buf.count = count;
1289         buf.error = 0;
1290
1291         error = vfs_readdir(file, filldir, &buf);
1292         if (error < 0)
1293                 goto out_putf;
1294         lastdirent = buf.previous;
1295         error = buf.error;
1296         if(lastdirent) {
1297                 put_user(file->f_pos, &lastdirent->d_off);
1298                 error = count - buf.count;
1299         }
1300 out_putf:
1301         fput(file);
1302 out:
1303         return error;
1304 }
1305
1306 /* end of readdir & getdents */
1307
1308 /*
1309  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
1310  * 64-bit unsigned longs.
1311  */
1312
1313 static inline int
1314 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1315 {
1316         if (ufdset) {
1317                 unsigned long odd;
1318
1319                 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1320                         return -EFAULT;
1321
1322                 odd = n & 1UL;
1323                 n &= ~1UL;
1324                 while (n) {
1325                         unsigned long h, l;
1326                         __get_user(l, ufdset);
1327                         __get_user(h, ufdset+1);
1328                         ufdset += 2;
1329                         *fdset++ = h << 32 | l;
1330                         n -= 2;
1331                 }
1332                 if (odd)
1333                         __get_user(*fdset, ufdset);
1334         } else {
1335                 /* Tricky, must clear full unsigned long in the
1336                  * kernel fdset at the end, this makes sure that
1337                  * actually happens.
1338                  */
1339                 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1340         }
1341         return 0;
1342 }
1343
1344 static inline void
1345 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1346 {
1347         unsigned long odd;
1348
1349         if (!ufdset)
1350                 return;
1351
1352         odd = n & 1UL;
1353         n &= ~1UL;
1354         while (n) {
1355                 unsigned long h, l;
1356                 l = *fdset++;
1357                 h = l >> 32;
1358                 __put_user(l, ufdset);
1359                 __put_user(h, ufdset+1);
1360                 ufdset += 2;
1361                 n -= 2;
1362         }
1363         if (odd)
1364                 __put_user(*fdset, ufdset);
1365 }
1366
1367 #define MAX_SELECT_SECONDS \
1368         ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1369
1370 asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
1371 {
1372         fd_set_bits fds;
1373         struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
1374         char *bits;
1375         unsigned long nn;
1376         long timeout;
1377         int ret, size;
1378
1379         timeout = MAX_SCHEDULE_TIMEOUT;
1380         if (tvp) {
1381                 time_t sec, usec;
1382
1383                 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1384                     || (ret = __get_user(sec, &tvp->tv_sec))
1385                     || (ret = __get_user(usec, &tvp->tv_usec)))
1386                         goto out_nofds;
1387
1388                 ret = -EINVAL;
1389                 if(sec < 0 || usec < 0)
1390                         goto out_nofds;
1391
1392                 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1393                         timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1394                         timeout += sec * (unsigned long) HZ;
1395                 }
1396         }
1397
1398         ret = -EINVAL;
1399         if (n < 0)
1400                 goto out_nofds;
1401         if (n > current->files->max_fdset)
1402                 n = current->files->max_fdset;
1403
1404         /*
1405          * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1406          * since we used fdset we need to allocate memory in units of
1407          * long-words. 
1408          */
1409         ret = -ENOMEM;
1410         size = FDS_BYTES(n);
1411         bits = kmalloc(6 * size, GFP_KERNEL);
1412         if (!bits)
1413                 goto out_nofds;
1414         fds.in      = (unsigned long *)  bits;
1415         fds.out     = (unsigned long *) (bits +   size);
1416         fds.ex      = (unsigned long *) (bits + 2*size);
1417         fds.res_in  = (unsigned long *) (bits + 3*size);
1418         fds.res_out = (unsigned long *) (bits + 4*size);
1419         fds.res_ex  = (unsigned long *) (bits + 5*size);
1420
1421         nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1422         if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1423             (ret = get_fd_set32(nn, fds.out, outp)) ||
1424             (ret = get_fd_set32(nn, fds.ex, exp)))
1425                 goto out;
1426         zero_fd_set(n, fds.res_in);
1427         zero_fd_set(n, fds.res_out);
1428         zero_fd_set(n, fds.res_ex);
1429
1430         ret = do_select(n, &fds, &timeout);
1431
1432         if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1433                 time_t sec = 0, usec = 0;
1434                 if (timeout) {
1435                         sec = timeout / HZ;
1436                         usec = timeout % HZ;
1437                         usec *= (1000000/HZ);
1438                 }
1439                 put_user(sec, &tvp->tv_sec);
1440                 put_user(usec, &tvp->tv_usec);
1441         }
1442
1443         if (ret < 0)
1444                 goto out;
1445         if (!ret) {
1446                 ret = -ERESTARTNOHAND;
1447                 if (signal_pending(current))
1448                         goto out;
1449                 ret = 0;
1450         }
1451
1452         set_fd_set32(nn, inp, fds.res_in);
1453         set_fd_set32(nn, outp, fds.res_out);
1454         set_fd_set32(nn, exp, fds.res_ex);
1455
1456 out:
1457         kfree(bits);
1458 out_nofds:
1459         return ret;
1460 }
1461
1462 static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
1463 {
1464         unsigned long ino, blksize, blocks;
1465         kdev_t dev, rdev;
1466         umode_t mode;
1467         nlink_t nlink;
1468         uid_t uid;
1469         gid_t gid;
1470         off_t size;
1471         time_t atime, mtime, ctime;
1472         int err;
1473
1474         /* Stream the loads of inode data into the load buffer,
1475          * then we push it all into the store buffer below.  This
1476          * should give optimal cache performance.
1477          */
1478         ino = inode->i_ino;
1479         dev = inode->i_dev;
1480         mode = inode->i_mode;
1481         nlink = inode->i_nlink;
1482         uid = inode->i_uid;
1483         gid = inode->i_gid;
1484         rdev = inode->i_rdev;
1485         size = inode->i_size;
1486         atime = inode->i_atime;
1487         mtime = inode->i_mtime;
1488         ctime = inode->i_ctime;
1489         blksize = inode->i_blksize;
1490         blocks = inode->i_blocks;
1491
1492         err  = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
1493         err |= put_user(ino, &statbuf->st_ino);
1494         err |= put_user(mode, &statbuf->st_mode);
1495         err |= put_user(nlink, &statbuf->st_nlink);
1496         err |= put_user(high2lowuid(uid), &statbuf->st_uid);
1497         err |= put_user(high2lowgid(gid), &statbuf->st_gid);
1498         err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
1499         err |= put_user(size, &statbuf->st_size);
1500         err |= put_user(atime, &statbuf->st_atime);
1501         err |= put_user(0, &statbuf->__unused1);
1502         err |= put_user(mtime, &statbuf->st_mtime);
1503         err |= put_user(0, &statbuf->__unused2);
1504         err |= put_user(ctime, &statbuf->st_ctime);
1505         err |= put_user(0, &statbuf->__unused3);
1506         if (blksize) {
1507                 err |= put_user(blksize, &statbuf->st_blksize);
1508                 err |= put_user(blocks, &statbuf->st_blocks);
1509         } else {
1510                 unsigned int tmp_blocks;
1511
1512 #define D_B   7
1513 #define I_B   (BLOCK_SIZE / sizeof(unsigned short))
1514                 tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
1515                 if (tmp_blocks > D_B) {
1516                         unsigned int indirect;
1517
1518                         indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
1519                         tmp_blocks += indirect;
1520                         if (indirect > 1) {
1521                                 indirect = (indirect - 1 + I_B - 1) / I_B;
1522                                 tmp_blocks += indirect;
1523                                 if (indirect > 1)
1524                                         tmp_blocks++;
1525                         }
1526                 }
1527                 err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
1528                 err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
1529 #undef D_B
1530 #undef I_B
1531         }
1532         err |= put_user(0, &statbuf->__unused4[0]);
1533         err |= put_user(0, &statbuf->__unused4[1]);
1534
1535         return err;
1536 }
1537
1538 /* Perhaps this belongs in fs.h or similar. -DaveM */
1539 static __inline__ int
1540 do_revalidate(struct dentry *dentry)
1541 {
1542         struct inode * inode = dentry->d_inode;
1543         if (inode->i_op && inode->i_op->revalidate)
1544                 return inode->i_op->revalidate(dentry);
1545         return 0;
1546 }
1547
1548 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1549 {
1550         struct nameidata nd;
1551         int error;
1552
1553         error = user_path_walk(filename, &nd);
1554         if (!error) {
1555                 error = do_revalidate(nd.dentry);
1556                 if (!error)
1557                         error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1558                 path_release(&nd);
1559         }
1560         return error;
1561 }
1562
1563 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1564 {
1565         struct nameidata nd;
1566         int error;
1567
1568         error = user_path_walk_link(filename, &nd);
1569         if (!error) {
1570                 error = do_revalidate(nd.dentry);
1571                 if (!error)
1572                         error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1573
1574                 path_release(&nd);
1575         }
1576         return error;
1577 }
1578
1579 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1580 {
1581         struct file *f;
1582         int err = -EBADF;
1583
1584         f = fget(fd);
1585         if (f) {
1586                 struct dentry * dentry = f->f_dentry;
1587
1588                 err = do_revalidate(dentry);
1589                 if (!err)
1590                         err = cp_new_stat32(dentry->d_inode, statbuf);
1591                 fput(f);
1592         }
1593         return err;
1594 }
1595
1596 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1597
1598 asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
1599 {
1600         return sys_sysfs(option, arg1, arg2);
1601 }
1602
1603 struct ncp_mount_data32 {
1604         int version;
1605         unsigned int ncp_fd;
1606         __kernel_uid_t32 mounted_uid;
1607         __kernel_pid_t32 wdog_pid;
1608         unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
1609         unsigned int time_out;
1610         unsigned int retry_count;
1611         unsigned int flags;
1612         __kernel_uid_t32 uid;
1613         __kernel_gid_t32 gid;
1614         __kernel_mode_t32 file_mode;
1615         __kernel_mode_t32 dir_mode;
1616 };
1617
1618 static void *do_ncp_super_data_conv(void *raw_data)
1619 {
1620         struct ncp_mount_data news, *n = &news; 
1621         struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
1622
1623         n->dir_mode = n32->dir_mode;
1624         n->file_mode = n32->file_mode;
1625         n->gid = low2highgid(n32->gid);
1626         n->uid = low2highuid(n32->uid);
1627         memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
1628         n->wdog_pid = n32->wdog_pid;
1629         n->mounted_uid = low2highuid(n32->mounted_uid);
1630         memcpy(raw_data, n, sizeof(struct ncp_mount_data)); 
1631         return raw_data;
1632 }
1633
1634 struct smb_mount_data32 {
1635         int version;
1636         __kernel_uid_t32 mounted_uid;
1637         __kernel_uid_t32 uid;
1638         __kernel_gid_t32 gid;
1639         __kernel_mode_t32 file_mode;
1640         __kernel_mode_t32 dir_mode;
1641 };
1642
1643 static void *do_smb_super_data_conv(void *raw_data)
1644 {
1645         struct smb_mount_data news, *s = &news;
1646         struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
1647
1648         s->version = s32->version;
1649         s->mounted_uid = low2highuid(s32->mounted_uid);
1650         s->uid = low2highuid(s32->uid);
1651         s->gid = low2highgid(s32->gid);
1652         s->file_mode = s32->file_mode;
1653         s->dir_mode = s32->dir_mode;
1654         memcpy(raw_data, s, sizeof(struct smb_mount_data)); 
1655         return raw_data;
1656 }
1657
1658 static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
1659 {
1660         int i;
1661         unsigned long page;
1662         struct vm_area_struct *vma;
1663
1664         *kernel = 0;
1665         if(!user)
1666                 return 0;
1667         vma = find_vma(current->mm, (unsigned long)user);
1668         if(!vma || (unsigned long)user < vma->vm_start)
1669                 return -EFAULT;
1670         if(!(vma->vm_flags & VM_READ))
1671                 return -EFAULT;
1672         i = vma->vm_end - (unsigned long) user;
1673         if(PAGE_SIZE <= (unsigned long) i)
1674                 i = PAGE_SIZE - 1;
1675         if(!(page = __get_free_page(GFP_KERNEL)))
1676                 return -ENOMEM;
1677         if(copy_from_user((void *) page, user, i)) {
1678                 free_page(page);
1679                 return -EFAULT;
1680         }
1681         *kernel = page;
1682         return 0;
1683 }
1684
1685 #define SMBFS_NAME      "smbfs"
1686 #define NCPFS_NAME      "ncpfs"
1687
1688 asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
1689 {
1690         unsigned long type_page = 0;
1691         unsigned long data_page = 0;
1692         unsigned long dev_page = 0;
1693         unsigned long dir_page = 0;
1694         int err, is_smb, is_ncp;
1695
1696         is_smb = is_ncp = 0;
1697
1698         err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
1699         if (err)
1700                 goto out;
1701
1702         if (!type_page) {
1703                 err = -EINVAL;
1704                 goto out;
1705         }
1706
1707         is_smb = !strcmp((char *)type_page, SMBFS_NAME);
1708         is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
1709
1710         err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
1711         if (err)
1712                 goto type_out;
1713
1714         err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
1715         if (err)
1716                 goto data_out;
1717
1718         err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
1719         if (err)
1720                 goto dev_out;
1721
1722         if (!is_smb && !is_ncp) {
1723                 lock_kernel();
1724                 err = do_mount((char*)dev_page, (char*)dir_page,
1725                                 (char*)type_page, new_flags, (char*)data_page);
1726                 unlock_kernel();
1727         } else {
1728                 if (is_ncp)
1729                         do_ncp_super_data_conv((void *)data_page);
1730                 else
1731                         do_smb_super_data_conv((void *)data_page);
1732
1733                 lock_kernel();
1734                 err = do_mount((char*)dev_page, (char*)dir_page,
1735                                 (char*)type_page, new_flags, (char*)data_page);
1736                 unlock_kernel();
1737         }
1738         free_page(dir_page);
1739
1740 dev_out:
1741         free_page(dev_page);
1742
1743 data_out:
1744         free_page(data_page);
1745
1746 type_out:
1747         free_page(type_page);
1748
1749 out:
1750         return err;
1751 }
1752
1753 struct rusage32 {
1754         struct timeval32 ru_utime;
1755         struct timeval32 ru_stime;
1756         s32    ru_maxrss;
1757         s32    ru_ixrss;
1758         s32    ru_idrss;
1759         s32    ru_isrss;
1760         s32    ru_minflt;
1761         s32    ru_majflt;
1762         s32    ru_nswap;
1763         s32    ru_inblock;
1764         s32    ru_oublock;
1765         s32    ru_msgsnd; 
1766         s32    ru_msgrcv; 
1767         s32    ru_nsignals;
1768         s32    ru_nvcsw;
1769         s32    ru_nivcsw;
1770 };
1771
1772 static int put_rusage (struct rusage32 *ru, struct rusage *r)
1773 {
1774         int err;
1775         
1776         err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1777         err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1778         err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1779         err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1780         err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1781         err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1782         err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1783         err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1784         err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1785         err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1786         err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1787         err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1788         err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1789         err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1790         err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1791         err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1792         err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1793         err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1794         return err;
1795 }
1796
1797 asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
1798 {
1799         if (!ru)
1800                 return sys_wait4(pid, stat_addr, options, NULL);
1801         else {
1802                 struct rusage r;
1803                 int ret;
1804                 unsigned int status;
1805                 mm_segment_t old_fs = get_fs();
1806                 
1807                 set_fs (KERNEL_DS);
1808                 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1809                 set_fs (old_fs);
1810                 if (put_rusage (ru, &r)) return -EFAULT;
1811                 if (stat_addr && put_user (status, stat_addr))
1812                         return -EFAULT;
1813                 return ret;
1814         }
1815 }
1816
1817 struct sysinfo32 {
1818         s32 uptime;
1819         u32 loads[3];
1820         u32 totalram;
1821         u32 freeram;
1822         u32 sharedram;
1823         u32 bufferram;
1824         u32 totalswap;
1825         u32 freeswap;
1826         unsigned short procs;
1827         char _f[22];
1828 };
1829
1830 extern asmlinkage int sys_sysinfo(struct sysinfo *info);
1831
1832 asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
1833 {
1834         struct sysinfo s;
1835         int ret, err;
1836         mm_segment_t old_fs = get_fs ();
1837         
1838         set_fs (KERNEL_DS);
1839         ret = sys_sysinfo(&s);
1840         set_fs (old_fs);
1841         err = put_user (s.uptime, &info->uptime);
1842         err |= __put_user (s.loads[0], &info->loads[0]);
1843         err |= __put_user (s.loads[1], &info->loads[1]);
1844         err |= __put_user (s.loads[2], &info->loads[2]);
1845         err |= __put_user (s.totalram, &info->totalram);
1846         err |= __put_user (s.freeram, &info->freeram);
1847         err |= __put_user (s.sharedram, &info->sharedram);
1848         err |= __put_user (s.bufferram, &info->bufferram);
1849         err |= __put_user (s.totalswap, &info->totalswap);
1850         err |= __put_user (s.freeswap, &info->freeswap);
1851         err |= __put_user (s.procs, &info->procs);
1852         if (err)
1853                 return -EFAULT;
1854         return ret;
1855 }
1856
1857 struct timespec32 {
1858         s32    tv_sec;
1859         s32    tv_nsec;
1860 };
1861                 
1862 extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
1863
1864 asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1865 {
1866         struct timespec t;
1867         int ret;
1868         mm_segment_t old_fs = get_fs ();
1869         
1870         set_fs (KERNEL_DS);
1871         ret = sys_sched_rr_get_interval(pid, &t);
1872         set_fs (old_fs);
1873         if (put_user (t.tv_sec, &interval->tv_sec) ||
1874             __put_user (t.tv_nsec, &interval->tv_nsec))
1875                 return -EFAULT;
1876         return ret;
1877 }
1878
1879 extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
1880
1881 asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
1882 {
1883         struct timespec t;
1884         int ret;
1885         mm_segment_t old_fs = get_fs ();
1886         
1887         if (get_user (t.tv_sec, &rqtp->tv_sec) ||
1888             __get_user (t.tv_nsec, &rqtp->tv_nsec))
1889                 return -EFAULT;
1890         set_fs (KERNEL_DS);
1891         ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1892         set_fs (old_fs);
1893         if (rmtp && ret == -EINTR) {
1894                 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1895                     __put_user (t.tv_nsec, &rmtp->tv_nsec))
1896                         return -EFAULT;
1897         }
1898         return ret;
1899 }
1900
1901 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
1902
1903 asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
1904 {
1905         old_sigset_t s;
1906         int ret;
1907         mm_segment_t old_fs = get_fs();
1908         
1909         if (set && get_user (s, set)) return -EFAULT;
1910         set_fs (KERNEL_DS);
1911         ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
1912         set_fs (old_fs);
1913         if (ret) return ret;
1914         if (oset && put_user (s, oset)) return -EFAULT;
1915         return 0;
1916 }
1917
1918 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
1919
1920 asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
1921 {
1922         sigset_t s;
1923         sigset_t32 s32;
1924         int ret;
1925         mm_segment_t old_fs = get_fs();
1926         
1927         if (set) {
1928                 if (copy_from_user (&s32, set, sizeof(sigset_t32)))
1929                         return -EFAULT;
1930                 switch (_NSIG_WORDS) {
1931                 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
1932                 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
1933                 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
1934                 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
1935                 }
1936         }
1937         set_fs (KERNEL_DS);
1938         ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
1939         set_fs (old_fs);
1940         if (ret) return ret;
1941         if (oset) {
1942                 switch (_NSIG_WORDS) {
1943                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1944                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1945                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1946                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1947                 }
1948                 if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
1949                         return -EFAULT;
1950         }
1951         return 0;
1952 }
1953
1954 extern asmlinkage int sys_sigpending(old_sigset_t *set);
1955
1956 asmlinkage int sys32_sigpending(old_sigset_t32 *set)
1957 {
1958         old_sigset_t s;
1959         int ret;
1960         mm_segment_t old_fs = get_fs();
1961                 
1962         set_fs (KERNEL_DS);
1963         ret = sys_sigpending(&s);
1964         set_fs (old_fs);
1965         if (put_user (s, set)) return -EFAULT;
1966         return ret;
1967 }
1968
1969 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
1970
1971 asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
1972 {
1973         sigset_t s;
1974         sigset_t32 s32;
1975         int ret;
1976         mm_segment_t old_fs = get_fs();
1977                 
1978         set_fs (KERNEL_DS);
1979         ret = sys_rt_sigpending(&s, sigsetsize);
1980         set_fs (old_fs);
1981         if (!ret) {
1982                 switch (_NSIG_WORDS) {
1983                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1984                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1985                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1986                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1987                 }
1988                 if (copy_to_user (set, &s32, sizeof(sigset_t32)))
1989                         return -EFAULT;
1990         }
1991         return ret;
1992 }
1993
1994 asmlinkage int
1995 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
1996                       struct timespec32 *uts, __kernel_size_t32 sigsetsize)
1997 {
1998         int ret, sig;
1999         sigset_t these;
2000         sigset_t32 these32;
2001         struct timespec ts;
2002         siginfo_t info;
2003         long timeout = 0;
2004
2005         /* XXX: Don't preclude handling different sized sigset_t's.  */
2006         if (sigsetsize != sizeof(sigset_t))
2007                 return -EINVAL;
2008
2009         if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
2010                 return -EFAULT;
2011
2012         switch (_NSIG_WORDS) {
2013         case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
2014         case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
2015         case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
2016         case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
2017         }
2018                 
2019         /*
2020          * Invert the set of allowed signals to get those we
2021          * want to block.
2022          */
2023         sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
2024         signotset(&these);
2025
2026         if (uts) {
2027                 if (get_user (ts.tv_sec, &uts->tv_sec) ||
2028                     get_user (ts.tv_nsec, &uts->tv_nsec))
2029                         return -EINVAL;
2030                 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
2031                     || ts.tv_sec < 0)
2032                         return -EINVAL;
2033         }
2034
2035         spin_lock_irq(&current->sigmask_lock);
2036         sig = dequeue_signal(&these, &info);
2037         if (!sig) {
2038                 /* None ready -- temporarily unblock those we're interested
2039                    in so that we'll be awakened when they arrive.  */
2040                 sigset_t oldblocked = current->blocked;
2041                 sigandsets(&current->blocked, &current->blocked, &these);
2042                 recalc_sigpending(current);
2043                 spin_unlock_irq(&current->sigmask_lock);
2044
2045                 timeout = MAX_SCHEDULE_TIMEOUT;
2046                 if (uts)
2047                         timeout = (timespec_to_jiffies(&ts)
2048                                    + (ts.tv_sec || ts.tv_nsec));
2049
2050                 current->state = TASK_INTERRUPTIBLE;
2051                 timeout = schedule_timeout(timeout);
2052
2053                 spin_lock_irq(&current->sigmask_lock);
2054                 sig = dequeue_signal(&these, &info);
2055                 current->blocked = oldblocked;
2056                 recalc_sigpending(current);
2057         }
2058         spin_unlock_irq(&current->sigmask_lock);
2059
2060         if (sig) {
2061                 ret = sig;
2062                 if (uinfo) {
2063                         if (copy_siginfo_to_user32(uinfo, &info))
2064                                 ret = -EFAULT;
2065                 }
2066         } else {
2067                 ret = -EAGAIN;
2068                 if (timeout)
2069                         ret = -EINTR;
2070         }
2071
2072         return ret;
2073 }
2074
2075 extern asmlinkage int
2076 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2077
2078 asmlinkage int
2079 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2080 {
2081         siginfo_t info;
2082         int ret;
2083         mm_segment_t old_fs = get_fs();
2084         
2085         if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2086             copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2087                 return -EFAULT;
2088         set_fs (KERNEL_DS);
2089         ret = sys_rt_sigqueueinfo(pid, sig, &info);
2090         set_fs (old_fs);
2091         return ret;
2092 }
2093
2094 struct tms32 {
2095         __kernel_clock_t32 tms_utime;
2096         __kernel_clock_t32 tms_stime;
2097         __kernel_clock_t32 tms_cutime;
2098         __kernel_clock_t32 tms_cstime;
2099 };
2100                                 
2101 extern asmlinkage long sys_times(struct tms * tbuf);
2102
2103 asmlinkage long sys32_times(struct tms32 *tbuf)
2104 {
2105         struct tms t;
2106         long ret;
2107         mm_segment_t old_fs = get_fs ();
2108         int err;
2109         
2110         set_fs (KERNEL_DS);
2111         ret = sys_times(tbuf ? &t : NULL);
2112         set_fs (old_fs);
2113         if (tbuf) {
2114                 err = put_user (t.tms_utime, &tbuf->tms_utime);
2115                 err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2116                 err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2117                 err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2118                 if (err)
2119                         ret = -EFAULT;
2120         }
2121         return ret;
2122 }
2123
2124 #define RLIM_INFINITY32 0x7fffffff
2125 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2126
2127 struct rlimit32 {
2128         u32     rlim_cur;
2129         u32     rlim_max;
2130 };
2131
2132 extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2133
2134 asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2135 {
2136         struct rlimit r;
2137         int ret;
2138         mm_segment_t old_fs = get_fs ();
2139         
2140         set_fs (KERNEL_DS);
2141         ret = sys_getrlimit(resource, &r);
2142         set_fs (old_fs);
2143         if (!ret) {
2144                 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2145                 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2146         }
2147         return ret;
2148 }
2149
2150 extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2151
2152 asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2153 {
2154         struct rlimit r;
2155         int ret;
2156         mm_segment_t old_fs = get_fs ();
2157
2158         if (resource >= RLIM_NLIMITS) return -EINVAL;   
2159         if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2160             __get_user (r.rlim_max, &rlim->rlim_max))
2161                 return -EFAULT;
2162         if (r.rlim_cur == RLIM_INFINITY32)
2163                 r.rlim_cur = RLIM_INFINITY;
2164         if (r.rlim_max == RLIM_INFINITY32)
2165                 r.rlim_max = RLIM_INFINITY;
2166         set_fs (KERNEL_DS);
2167         ret = sys_setrlimit(resource, &r);
2168         set_fs (old_fs);
2169         return ret;
2170 }
2171
2172 extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2173
2174 asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2175 {
2176         struct rusage r;
2177         int ret;
2178         mm_segment_t old_fs = get_fs();
2179                 
2180         set_fs (KERNEL_DS);
2181         ret = sys_getrusage(who, &r);
2182         set_fs (old_fs);
2183         if (put_rusage (ru, &r)) return -EFAULT;
2184         return ret;
2185 }
2186
2187 /* XXX This really belongs in some header file... -DaveM */
2188 #define MAX_SOCK_ADDR   128             /* 108 for Unix domain - 
2189                                            16 for IP, 16 for IPX,
2190                                            24 for IPv6,
2191                                            about 80 for AX.25 */
2192
2193 extern struct socket *sockfd_lookup(int fd, int *err);
2194
2195 /* XXX This as well... */
2196 extern __inline__ void sockfd_put(struct socket *sock)
2197 {
2198         fput(sock->file);
2199 }
2200
2201 struct msghdr32 {
2202         u32               msg_name;
2203         int               msg_namelen;
2204         u32               msg_iov;
2205         __kernel_size_t32 msg_iovlen;
2206         u32               msg_control;
2207         __kernel_size_t32 msg_controllen;
2208         unsigned          msg_flags;
2209 };
2210
2211 struct cmsghdr32 {
2212         __kernel_size_t32 cmsg_len;
2213         int               cmsg_level;
2214         int               cmsg_type;
2215 };
2216
2217 /* Bleech... */
2218 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2219 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2220
2221 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2222
2223 #define CMSG32_DATA(cmsg)       ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2224 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2225 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2226
2227 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2228                                     (struct cmsghdr32 *)(ctl) : \
2229                                     (struct cmsghdr32 *)NULL)
2230 #define CMSG32_FIRSTHDR(msg)    __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2231
2232 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2233                                               struct cmsghdr32 *__cmsg, int __cmsg_len)
2234 {
2235         struct cmsghdr32 * __ptr;
2236
2237         __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2238                                      CMSG32_ALIGN(__cmsg_len));
2239         if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2240                 return NULL;
2241
2242         return __ptr;
2243 }
2244
2245 __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2246                                             struct cmsghdr32 *__cmsg,
2247                                             int __cmsg_len)
2248 {
2249         return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2250                                __cmsg, __cmsg_len);
2251 }
2252
2253 static inline int iov_from_user32_to_kern(struct iovec *kiov,
2254                                           struct iovec32 *uiov32,
2255                                           int niov)
2256 {
2257         int tot_len = 0;
2258
2259         while(niov > 0) {
2260                 u32 len, buf;
2261
2262                 if(get_user(len, &uiov32->iov_len) ||
2263                    get_user(buf, &uiov32->iov_base)) {
2264                         tot_len = -EFAULT;
2265                         break;
2266                 }
2267                 tot_len += len;
2268                 kiov->iov_base = (void *)A(buf);
2269                 kiov->iov_len = (__kernel_size_t) len;
2270                 uiov32++;
2271                 kiov++;
2272                 niov--;
2273         }
2274         return tot_len;
2275 }
2276
2277 static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2278                                              struct msghdr32 *umsg)
2279 {
2280         u32 tmp1, tmp2, tmp3;
2281         int err;
2282
2283         err = get_user(tmp1, &umsg->msg_name);
2284         err |= __get_user(tmp2, &umsg->msg_iov);
2285         err |= __get_user(tmp3, &umsg->msg_control);
2286         if (err)
2287                 return -EFAULT;
2288
2289         kmsg->msg_name = (void *)A(tmp1);
2290         kmsg->msg_iov = (struct iovec *)A(tmp2);
2291         kmsg->msg_control = (void *)A(tmp3);
2292
2293         err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2294         err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2295         err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2296         err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2297         
2298         return err;
2299 }
2300
2301 /* I've named the args so it is easy to tell whose space the pointers are in. */
2302 static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2303                           char *kern_address, int mode)
2304 {
2305         int tot_len;
2306
2307         if(kern_msg->msg_namelen) {
2308                 if(mode==VERIFY_READ) {
2309                         int err = move_addr_to_kernel(kern_msg->msg_name,
2310                                                       kern_msg->msg_namelen,
2311                                                       kern_address);
2312                         if(err < 0)
2313                                 return err;
2314                 }
2315                 kern_msg->msg_name = kern_address;
2316         } else
2317                 kern_msg->msg_name = NULL;
2318
2319         if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2320                 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2321                                    GFP_KERNEL);
2322                 if(!kern_iov)
2323                         return -ENOMEM;
2324         }
2325
2326         tot_len = iov_from_user32_to_kern(kern_iov,
2327                                           (struct iovec32 *)kern_msg->msg_iov,
2328                                           kern_msg->msg_iovlen);
2329         if(tot_len >= 0)
2330                 kern_msg->msg_iov = kern_iov;
2331         else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2332                 kfree(kern_iov);
2333
2334         return tot_len;
2335 }
2336
2337 /* There is a lot of hair here because the alignment rules (and
2338  * thus placement) of cmsg headers and length are different for
2339  * 32-bit apps.  -DaveM
2340  */
2341 static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2342                                        unsigned char *stackbuf, int stackbuf_size)
2343 {
2344         struct cmsghdr32 *ucmsg;
2345         struct cmsghdr *kcmsg, *kcmsg_base;
2346         __kernel_size_t32 ucmlen;
2347         __kernel_size_t kcmlen, tmp;
2348
2349         kcmlen = 0;
2350         kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2351         ucmsg = CMSG32_FIRSTHDR(kmsg);
2352         while(ucmsg != NULL) {
2353                 if(get_user(ucmlen, &ucmsg->cmsg_len))
2354                         return -EFAULT;
2355
2356                 /* Catch bogons. */
2357                 if(CMSG32_ALIGN(ucmlen) <
2358                    CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2359                         return -EINVAL;
2360                 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2361                                    + ucmlen) > kmsg->msg_controllen)
2362                         return -EINVAL;
2363
2364                 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2365                        CMSG_ALIGN(sizeof(struct cmsghdr)));
2366                 kcmlen += tmp;
2367                 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2368         }
2369         if(kcmlen == 0)
2370                 return -EINVAL;
2371
2372         /* The kcmlen holds the 64-bit version of the control length.
2373          * It may not be modified as we do not stick it into the kmsg
2374          * until we have successfully copied over all of the data
2375          * from the user.
2376          */
2377         if(kcmlen > stackbuf_size)
2378                 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2379         if(kcmsg == NULL)
2380                 return -ENOBUFS;
2381
2382         /* Now copy them over neatly. */
2383         memset(kcmsg, 0, kcmlen);
2384         ucmsg = CMSG32_FIRSTHDR(kmsg);
2385         while(ucmsg != NULL) {
2386                 __get_user(ucmlen, &ucmsg->cmsg_len);
2387                 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2388                        CMSG_ALIGN(sizeof(struct cmsghdr)));
2389                 kcmsg->cmsg_len = tmp;
2390                 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2391                 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2392
2393                 /* Copy over the data. */
2394                 if(copy_from_user(CMSG_DATA(kcmsg),
2395                                   CMSG32_DATA(ucmsg),
2396                                   (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2397                         goto out_free_efault;
2398
2399                 /* Advance. */
2400                 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2401                 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2402         }
2403
2404         /* Ok, looks like we made it.  Hook it up and return success. */
2405         kmsg->msg_control = kcmsg_base;
2406         kmsg->msg_controllen = kcmlen;
2407         return 0;
2408
2409 out_free_efault:
2410         if(kcmsg_base != (struct cmsghdr *)stackbuf)
2411                 kfree(kcmsg_base);
2412         return -EFAULT;
2413 }
2414
2415 static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2416                        int len, void *data)
2417 {
2418         struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2419         struct cmsghdr32 cmhdr;
2420         int cmlen = CMSG32_LEN(len);
2421
2422         if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2423                 kmsg->msg_flags |= MSG_CTRUNC;
2424                 return;
2425         }
2426
2427         if(kmsg->msg_controllen < cmlen) {
2428                 kmsg->msg_flags |= MSG_CTRUNC;
2429                 cmlen = kmsg->msg_controllen;
2430         }
2431         cmhdr.cmsg_level = level;
2432         cmhdr.cmsg_type = type;
2433         cmhdr.cmsg_len = cmlen;
2434
2435         if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2436                 return;
2437         if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2438                 return;
2439         cmlen = CMSG32_SPACE(len);
2440         kmsg->msg_control += cmlen;
2441         kmsg->msg_controllen -= cmlen;
2442 }
2443
2444 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2445 {
2446         struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2447         int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2448         int fdnum = scm->fp->count;
2449         struct file **fp = scm->fp->fp;
2450         int *cmfptr;
2451         int err = 0, i;
2452
2453         if (fdnum < fdmax)
2454                 fdmax = fdnum;
2455
2456         for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2457                 int new_fd;
2458                 err = get_unused_fd();
2459                 if (err < 0)
2460                         break;
2461                 new_fd = err;
2462                 err = put_user(new_fd, cmfptr);
2463                 if (err) {
2464                         put_unused_fd(new_fd);
2465                         break;
2466                 }
2467                 /* Bump the usage count and install the file. */
2468                 get_file(fp[i]);
2469                 fd_install(new_fd, fp[i]);
2470         }
2471
2472         if (i > 0) {
2473                 int cmlen = CMSG32_LEN(i * sizeof(int));
2474                 if (!err)
2475                         err = put_user(SOL_SOCKET, &cm->cmsg_level);
2476                 if (!err)
2477                         err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2478                 if (!err)
2479                         err = put_user(cmlen, &cm->cmsg_len);
2480                 if (!err) {
2481                         cmlen = CMSG32_SPACE(i * sizeof(int));
2482                         kmsg->msg_control += cmlen;
2483                         kmsg->msg_controllen -= cmlen;
2484                 }
2485         }
2486         if (i < fdnum)
2487                 kmsg->msg_flags |= MSG_CTRUNC;
2488
2489         /*
2490          * All of the files that fit in the message have had their
2491          * usage counts incremented, so we just free the list.
2492          */
2493         __scm_destroy(scm);
2494 }
2495
2496 /* In these cases we (currently) can just copy to data over verbatim
2497  * because all CMSGs created by the kernel have well defined types which
2498  * have the same layout in both the 32-bit and 64-bit API.  One must add
2499  * some special cased conversions here if we start sending control messages
2500  * with incompatible types.
2501  *
2502  * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2503  * we do our work.  The remaining cases are:
2504  *
2505  * SOL_IP       IP_PKTINFO      struct in_pktinfo       32-bit clean
2506  *              IP_TTL          int                     32-bit clean
2507  *              IP_TOS          __u8                    32-bit clean
2508  *              IP_RECVOPTS     variable length         32-bit clean
2509  *              IP_RETOPTS      variable length         32-bit clean
2510  *              (these last two are clean because the types are defined
2511  *               by the IPv4 protocol)
2512  *              IP_RECVERR      struct sock_extended_err +
2513  *                              struct sockaddr_in      32-bit clean
2514  * SOL_IPV6     IPV6_RECVERR    struct sock_extended_err +
2515  *                              struct sockaddr_in6     32-bit clean
2516  *              IPV6_PKTINFO    struct in6_pktinfo      32-bit clean
2517  *              IPV6_HOPLIMIT   int                     32-bit clean
2518  *              IPV6_FLOWINFO   u32                     32-bit clean
2519  *              IPV6_HOPOPTS    ipv6 hop exthdr         32-bit clean
2520  *              IPV6_DSTOPTS    ipv6 dst exthdr(s)      32-bit clean
2521  *              IPV6_RTHDR      ipv6 routing exthdr     32-bit clean
2522  *              IPV6_AUTHHDR    ipv6 auth exthdr        32-bit clean
2523  */
2524 static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2525 {
2526         unsigned char *workbuf, *wp;
2527         unsigned long bufsz, space_avail;
2528         struct cmsghdr *ucmsg;
2529
2530         bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2531         space_avail = kmsg->msg_controllen + bufsz;
2532         wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2533         if(workbuf == NULL)
2534                 goto fail;
2535
2536         /* To make this more sane we assume the kernel sends back properly
2537          * formatted control messages.  Because of how the kernel will truncate
2538          * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2539          */
2540         ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2541         while(((unsigned long)ucmsg) <=
2542               (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
2543                 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2544                 int clen64, clen32;
2545
2546                 /* UCMSG is the 64-bit format CMSG entry in user-space.
2547                  * KCMSG32 is within the kernel space temporary buffer
2548                  * we use to convert into a 32-bit style CMSG.
2549                  */
2550                 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2551                 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2552                 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2553
2554                 clen64 = kcmsg32->cmsg_len;
2555                 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2556                                clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2557                 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2558                           CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2559                 kcmsg32->cmsg_len = clen32;
2560
2561                 ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2562                 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2563         }
2564
2565         /* Copy back fixed up data, and adjust pointers. */
2566         bufsz = (wp - workbuf);
2567         copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2568
2569         kmsg->msg_control = (struct cmsghdr *)
2570                 (((char *)orig_cmsg_uptr) + bufsz);
2571         kmsg->msg_controllen = space_avail - bufsz;
2572
2573         kfree(workbuf);
2574         return;
2575
2576 fail:
2577         /* If we leave the 64-bit format CMSG chunks in there,
2578          * the application could get confused and crash.  So to
2579          * ensure greater recovery, we report no CMSGs.
2580          */
2581         kmsg->msg_controllen += bufsz;
2582         kmsg->msg_control = (void *) orig_cmsg_uptr;
2583 }
2584
2585 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2586 {
2587         struct socket *sock;
2588         char address[MAX_SOCK_ADDR];
2589         struct iovec iov[UIO_FASTIOV];
2590         unsigned char ctl[sizeof(struct cmsghdr) + 20];
2591         unsigned char *ctl_buf = ctl;
2592         struct msghdr kern_msg;
2593         int err, total_len;
2594
2595         if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2596                 return -EFAULT;
2597         if(kern_msg.msg_iovlen > UIO_MAXIOV)
2598                 return -EINVAL;
2599         err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2600         if (err < 0)
2601                 goto out;
2602         total_len = err;
2603
2604         if(kern_msg.msg_controllen) {
2605                 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2606                 if(err)
2607                         goto out_freeiov;
2608                 ctl_buf = kern_msg.msg_control;
2609         }
2610         kern_msg.msg_flags = user_flags;
2611
2612         sock = sockfd_lookup(fd, &err);
2613         if (sock != NULL) {
2614                 if (sock->file->f_flags & O_NONBLOCK)
2615                         kern_msg.msg_flags |= MSG_DONTWAIT;
2616                 err = sock_sendmsg(sock, &kern_msg, total_len);
2617                 sockfd_put(sock);
2618         }
2619
2620         /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2621         if(ctl_buf != ctl)
2622                 kfree(ctl_buf);
2623 out_freeiov:
2624         if(kern_msg.msg_iov != iov)
2625                 kfree(kern_msg.msg_iov);
2626 out:
2627         return err;
2628 }
2629
2630 asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2631 {
2632         struct iovec iovstack[UIO_FASTIOV];
2633         struct msghdr kern_msg;
2634         char addr[MAX_SOCK_ADDR];
2635         struct socket *sock;
2636         struct iovec *iov = iovstack;
2637         struct sockaddr *uaddr;
2638         int *uaddr_len;
2639         unsigned long cmsg_ptr;
2640         int err, total_len, len = 0;
2641
2642         if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2643                 return -EFAULT;
2644         if(kern_msg.msg_iovlen > UIO_MAXIOV)
2645                 return -EINVAL;
2646
2647         uaddr = kern_msg.msg_name;
2648         uaddr_len = &user_msg->msg_namelen;
2649         err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2650         if (err < 0)
2651                 goto out;
2652         total_len = err;
2653
2654         cmsg_ptr = (unsigned long) kern_msg.msg_control;
2655         kern_msg.msg_flags = 0;
2656
2657         sock = sockfd_lookup(fd, &err);
2658         if (sock != NULL) {
2659                 struct scm_cookie scm;
2660
2661                 if (sock->file->f_flags & O_NONBLOCK)
2662                         user_flags |= MSG_DONTWAIT;
2663                 memset(&scm, 0, sizeof(scm));
2664                 err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2665                                          user_flags, &scm);
2666                 if(err >= 0) {
2667                         len = err;
2668                         if(!kern_msg.msg_control) {
2669                                 if(sock->passcred || scm.fp)
2670                                         kern_msg.msg_flags |= MSG_CTRUNC;
2671                                 if(scm.fp)
2672                                         __scm_destroy(&scm);
2673                         } else {
2674                                 /* If recvmsg processing itself placed some
2675                                  * control messages into user space, it's is
2676                                  * using 64-bit CMSG processing, so we need
2677                                  * to fix it up before we tack on more stuff.
2678                                  */
2679                                 if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2680                                         cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2681
2682                                 /* Wheee... */
2683                                 if(sock->passcred)
2684                                         put_cmsg32(&kern_msg,
2685                                                    SOL_SOCKET, SCM_CREDENTIALS,
2686                                                    sizeof(scm.creds), &scm.creds);
2687                                 if(scm.fp != NULL)
2688                                         scm_detach_fds32(&kern_msg, &scm);
2689                         }