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