File: /usr/src/linux/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, ×->actime) ||
1048 __get_user (t.modtime, ×->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(¤t->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(¤t->blocked, ¤t->blocked, &these);
2057 recalc_sigpending(current);
2058 spin_unlock_irq(¤t->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(¤t->sigmask_lock);
2069 sig = dequeue_signal(&these, &info);
2070 current->blocked = oldblocked;
2071 recalc_sigpending(current);
2072 }
2073 spin_unlock_irq(¤t->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;
2724 }
2725
2726 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2727 char *optval, int optlen);
2728
2729 static int do_set_attach_filter(int fd, int level, int optname,
2730 char *optval, int optlen)
2731 {
2732 struct sock_fprog32 {
2733 __u16 len;
2734 __u32 filter;
2735 } *fprog32 = (struct sock_fprog32 *)optval;
2736 struct sock_fprog kfprog;
2737 struct sock_filter *kfilter;
2738 unsigned int fsize;
2739 mm_segment_t old_fs;
2740 __u32 uptr;
2741 int ret;
2742
2743 if (get_user(kfprog.len, &fprog32->len) ||
2744 __get_user(uptr, &fprog32->filter))
2745 return -EFAULT;
2746
2747 kfprog.filter = (struct sock_filter *)A(uptr);
2748 fsize = kfprog.len * sizeof(struct sock_filter);
2749
2750 kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2751 if (kfilter == NULL)
2752 return -ENOMEM;
2753
2754 if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2755 kfree(kfilter);
2756 return -EFAULT;
2757 }
2758
2759 kfprog.filter = kfilter;
2760
2761 old_fs = get_fs();
2762 set_fs(KERNEL_DS);
2763 ret = sys_setsockopt(fd, level, optname,
2764 (char *)&kfprog, sizeof(kfprog));
2765 set_fs(old_fs);
2766
2767 kfree(kfilter);
2768
2769 return ret;
2770 }
2771
2772 static int do_set_icmpv6_filter(int fd, int level, int optname,
2773 char *optval, int optlen)
2774 {
2775 struct icmp6_filter kfilter;
2776 mm_segment_t old_fs;
2777 int ret, i;
2778
2779 if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
2780 return -EFAULT;
2781
2782
2783 for (i = 0; i < 8; i += 2) {
2784 u32 tmp = kfilter.data[i];
2785
2786 kfilter.data[i] = kfilter.data[i + 1];
2787 kfilter.data[i + 1] = tmp;
2788 }
2789
2790 old_fs = get_fs();
2791 set_fs(KERNEL_DS);
2792 ret = sys_setsockopt(fd, level, optname,
2793 (char *) &kfilter, sizeof(kfilter));
2794 set_fs(old_fs);
2795
2796 return ret;
2797 }
2798
2799 asmlinkage int sys32_setsockopt(int fd, int level, int optname,
2800 char *optval, int optlen)
2801 {
2802 if (optname == SO_ATTACH_FILTER)
2803 return do_set_attach_filter(fd, level, optname,
2804 optval, optlen);
2805 if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
2806 return do_set_icmpv6_filter(fd, level, optname,
2807 optval, optlen);
2808
2809 return sys_setsockopt(fd, level, optname, optval, optlen);
2810 }
2811
2812 extern void check_pending(int signum);
2813
2814 /*
2815 * count32() counts the number of arguments/envelopes
2816 */
2817 static int count32(u32 * argv)
2818 {
2819 int i = 0;
2820
2821 if (argv != NULL) {
2822 for (;;) {
2823 u32 p; int error;
2824
2825 error = get_user(p,argv);
2826 if (error) return error;
2827 if (!p) break;
2828 argv++; i++;
2829 }
2830 }
2831 return i;
2832 }
2833
2834 /*
2835 * 'copy_string32()' copies argument/envelope strings from user
2836 * memory to free pages in kernel mem. These are in a format ready
2837 * to be put directly into the top of new user memory.
2838 */
2839 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
2840 {
2841 while (argc-- > 0) {
2842 u32 str;
2843 int len;
2844 unsigned long pos;
2845
2846 if (get_user(str, argv + argc) ||
2847 !str ||
2848 !(len = strnlen_user((char *)A(str), bprm->p)))
2849 return -EFAULT;
2850
2851 if (bprm->p < len)
2852 return -E2BIG;
2853
2854 bprm->p -= len;
2855
2856 pos = bprm->p;
2857 while (len) {
2858 char *kaddr;
2859 struct page *page;
2860 int offset, bytes_to_copy, new, err;
2861
2862 offset = pos % PAGE_SIZE;
2863 page = bprm->page[pos / PAGE_SIZE];
2864 new = 0;
2865 if (!page) {
2866 page = alloc_page(GFP_USER);
2867 bprm->page[pos / PAGE_SIZE] = page;
2868 if (!page)
2869 return -ENOMEM;
2870 new = 1;
2871 }
2872 kaddr = (char *)kmap(page);
2873
2874 if (new && offset)
2875 memset(kaddr, 0, offset);
2876 bytes_to_copy = PAGE_SIZE - offset;
2877 if (bytes_to_copy > len) {
2878 bytes_to_copy = len;
2879 if (new)
2880 memset(kaddr+offset+len, 0,
2881 PAGE_SIZE-offset-len);
2882 }
2883
2884 err = copy_from_user(kaddr + offset, (char *)A(str),
2885 bytes_to_copy);
2886 flush_page_to_ram(page);
2887 kunmap((unsigned long)kaddr);
2888
2889 if (err)
2890 return -EFAULT;
2891
2892 pos += bytes_to_copy;
2893 str += bytes_to_copy;
2894 len -= bytes_to_copy;
2895 }
2896 }
2897 return 0;
2898 }
2899
2900 /*
2901 * sys32_execve() executes a new program.
2902 */
2903 static inline int
2904 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
2905 {
2906 struct linux_binprm bprm;
2907 struct file * file;
2908 int retval;
2909 int i;
2910
2911 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
2912 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
2913
2914 file = open_exec(filename);
2915
2916 retval = PTR_ERR(file);
2917 if (IS_ERR(file))
2918 return retval;
2919
2920 bprm.file = file;
2921 bprm.filename = filename;
2922 bprm.sh_bang = 0;
2923 bprm.loader = 0;
2924 bprm.exec = 0;
2925 if ((bprm.argc = count32(argv)) < 0) {
2926 allow_write_access(file);
2927 fput(file);
2928 return bprm.argc;
2929 }
2930 if ((bprm.envc = count32(envp)) < 0) {
2931 allow_write_access(file);
2932 fput(file);
2933 return bprm.envc;
2934 }
2935
2936 retval = prepare_binprm(&bprm);
2937 if (retval < 0)
2938 goto out;
2939
2940 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
2941 if (retval < 0)
2942 goto out;
2943
2944 bprm.exec = bprm.p;
2945 retval = copy_strings32(bprm.envc, envp, &bprm);
2946 if (retval < 0)
2947 goto out;
2948
2949 retval = copy_strings32(bprm.argc, argv, &bprm);
2950 if (retval < 0)
2951 goto out;
2952
2953 retval = search_binary_handler(&bprm, regs);
2954 if (retval >= 0)
2955 /* execve success */
2956 return retval;
2957
2958 out:
2959 /* Something went wrong, return the inode and free the argument pages*/
2960 allow_write_access(bprm.file);
2961 if (bprm.file)
2962 fput(bprm.file);
2963
2964 for (i=0 ; i<MAX_ARG_PAGES ; i++)
2965 if (bprm.page[i])
2966 __free_page(bprm.page[i]);
2967
2968 return retval;
2969 }
2970
2971 /*
2972 * sys32_execve() executes a new program after the asm stub has set
2973 * things up for us. This should basically do what I want it to.
2974 */
2975 asmlinkage int
2976 sys32_execve(struct pt_regs regs)
2977 {
2978 int error;
2979 char * filename;
2980
2981 filename = getname((char *)A(regs.orig_gpr2));
2982 error = PTR_ERR(filename);
2983 if (IS_ERR(filename))
2984 goto out;
2985 error = do_execve32(filename, (u32 *)A(regs.gprs[3]), (u32 *)A(regs.gprs[4]), ®s);
2986 if (error == 0)
2987 {
2988 current->ptrace &= ~PT_DTRACE;
2989 current->thread.fp_regs.fpc=0;
2990 __asm__ __volatile__
2991 ("sr 0,0\n\t"
2992 "sfpc 0,0\n\t"
2993 : : :"0");
2994 }
2995 putname(filename);
2996 out:
2997 return error;
2998 }
2999
3000
3001 #ifdef CONFIG_MODULES
3002
3003 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3004
3005 asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3006 {
3007 return sys_create_module(name_user, (size_t)size);
3008 }
3009
3010 extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3011
3012 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3013 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3014 */
3015 asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3016 {
3017 return sys_init_module(name_user, mod_user);
3018 }
3019
3020 extern asmlinkage int sys_delete_module(const char *name_user);
3021
3022 asmlinkage int sys32_delete_module(const char *name_user)
3023 {
3024 return sys_delete_module(name_user);
3025 }
3026
3027 struct module_info32 {
3028 u32 addr;
3029 u32 size;
3030 u32 flags;
3031 s32 usecount;
3032 };
3033
3034 /* Query various bits about modules. */
3035
3036 static inline long
3037 get_mod_name(const char *user_name, char **buf)
3038 {
3039 unsigned long page;
3040 long retval;
3041
3042 if ((unsigned long)user_name >= TASK_SIZE
3043 && !segment_eq(get_fs (), KERNEL_DS))
3044 return -EFAULT;
3045
3046 page = __get_free_page(GFP_KERNEL);
3047 if (!page)
3048 return -ENOMEM;
3049
3050 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3051 if (retval > 0) {
3052 if (retval < PAGE_SIZE) {
3053 *buf = (char *)page;
3054 return retval;
3055 }
3056 retval = -ENAMETOOLONG;
3057 } else if (!retval)
3058 retval = -EINVAL;
3059
3060 free_page(page);
3061 return retval;
3062 }
3063
3064 static inline void
3065 put_mod_name(char *buf)
3066 {
3067 free_page((unsigned long)buf);
3068 }
3069
3070 static __inline__ struct module *find_module(const char *name)
3071 {
3072 struct module *mod;
3073
3074 for (mod = module_list; mod ; mod = mod->next) {
3075 if (mod->flags & MOD_DELETED)
3076 continue;
3077 if (!strcmp(mod->name, name))
3078 break;
3079 }
3080
3081 return mod;
3082 }
3083
3084 static int
3085 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3086 {
3087 struct module *mod;
3088 size_t nmod, space, len;
3089
3090 nmod = space = 0;
3091
3092 for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3093 len = strlen(mod->name)+1;
3094 if (len > bufsize)
3095 goto calc_space_needed;
3096 if (copy_to_user(buf, mod->name, len))
3097 return -EFAULT;
3098 buf += len;
3099 bufsize -= len;
3100 space += len;
3101 }
3102
3103 if (put_user(nmod, ret))
3104 return -EFAULT;
3105 else
3106 return 0;
3107
3108 calc_space_needed:
3109 space += len;
3110 while ((mod = mod->next)->next != NULL)
3111 space += strlen(mod->name)+1;
3112
3113 if (put_user(space, ret))
3114 return -EFAULT;
3115 else
3116 return -ENOSPC;
3117 }
3118
3119 static int
3120 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3121 {
3122 size_t i, space, len;
3123
3124 if (mod->next == NULL)
3125 return -EINVAL;
3126 if (!MOD_CAN_QUERY(mod))
3127 return put_user(0, ret);
3128
3129 space = 0;
3130 for (i = 0; i < mod->ndeps; ++i) {
3131 const char *dep_name = mod->deps[i].dep->name;
3132
3133 len = strlen(dep_name)+1;
3134 if (len > bufsize)
3135 goto calc_space_needed;
3136 if (copy_to_user(buf, dep_name, len))
3137 return -EFAULT;
3138 buf += len;
3139 bufsize -= len;
3140 space += len;
3141 }
3142
3143 return put_user(i, ret);
3144
3145 calc_space_needed:
3146 space += len;
3147 while (++i < mod->ndeps)
3148 space += strlen(mod->deps[i].dep->name)+1;
3149
3150 if (put_user(space, ret))
3151 return -EFAULT;
3152 else
3153 return -ENOSPC;
3154 }
3155
3156 static int
3157 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3158 {
3159 size_t nrefs, space, len;
3160 struct module_ref *ref;
3161
3162 if (mod->next == NULL)
3163 return -EINVAL;
3164 if (!MOD_CAN_QUERY(mod))
3165 if (put_user(0, ret))
3166 return -EFAULT;
3167 else
3168 return 0;
3169
3170 space = 0;
3171 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3172 const char *ref_name = ref->ref->name;
3173
3174 len = strlen(ref_name)+1;
3175 if (len > bufsize)
3176 goto calc_space_needed;
3177 if (copy_to_user(buf, ref_name, len))
3178 return -EFAULT;
3179 buf += len;
3180 bufsize -= len;
3181 space += len;
3182 }
3183
3184 if (put_user(nrefs, ret))
3185 return -EFAULT;
3186 else
3187 return 0;
3188
3189 calc_space_needed:
3190 space += len;
3191 while ((ref = ref->next_ref) != NULL)
3192 space += strlen(ref->ref->name)+1;
3193
3194 if (put_user(space, ret))
3195 return -EFAULT;
3196 else
3197 return -ENOSPC;
3198 }
3199
3200 static inline int
3201 qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3202 {
3203 size_t i, space, len;
3204 struct module_symbol *s;
3205 char *strings;
3206 unsigned *vals;
3207
3208 if (!MOD_CAN_QUERY(mod))
3209 if (put_user(0, ret))
3210 return -EFAULT;
3211 else
3212 return 0;
3213
3214 space = mod->nsyms * 2*sizeof(u32);
3215
3216 i = len = 0;
3217 s = mod->syms;
3218
3219 if (space > bufsize)
3220 goto calc_space_needed;
3221
3222 if (!access_ok(VERIFY_WRITE, buf, space))
3223 return -EFAULT;
3224
3225 bufsize -= space;
3226 vals = (unsigned *)buf;
3227 strings = buf+space;
3228
3229 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3230 len = strlen(s->name)+1;
3231 if (len > bufsize)
3232 goto calc_space_needed;
3233
3234 if (copy_to_user(strings, s->name, len)
3235 || __put_user(s->value, vals+0)
3236 || __put_user(space, vals+1))
3237 return -EFAULT;
3238
3239 strings += len;
3240 bufsize -= len;
3241 space += len;
3242 }
3243
3244 if (put_user(i, ret))
3245 return -EFAULT;
3246 else
3247 return 0;
3248
3249 calc_space_needed:
3250 for (; i < mod->nsyms; ++i, ++s)
3251 space += strlen(s->name)+1;
3252
3253 if (put_user(space, ret))
3254 return -EFAULT;
3255 else
3256 return -ENOSPC;
3257 }
3258
3259 static inline int
3260 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3261 {
3262 int error = 0;
3263
3264 if (mod->next == NULL)
3265 return -EINVAL;
3266
3267 if (sizeof(struct module_info32) <= bufsize) {
3268 struct module_info32 info;
3269 info.addr = (unsigned long)mod;
3270 info.size = mod->size;
3271 info.flags = mod->flags;
3272 info.usecount =
3273 ((mod_member_present(mod, can_unload)
3274 && mod->can_unload)
3275 ? -1 : atomic_read(&mod->uc.usecount));
3276
3277 if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3278 return -EFAULT;
3279 } else
3280 error = -ENOSPC;
3281
3282 if (put_user(sizeof(struct module_info32), ret))
3283 return -EFAULT;
3284
3285 return error;
3286 }
3287
3288 asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3289 {
3290 struct module *mod;
3291 int err;
3292
3293 lock_kernel();
3294 if (name_user == 0) {
3295 /* This finds "kernel_module" which is not exported. */
3296 for(mod = module_list; mod->next != NULL; mod = mod->next)
3297 ;
3298 } else {
3299 long namelen;
3300 char *name;
3301
3302 if ((namelen = get_mod_name(name_user, &name)) < 0) {
3303 err = namelen;
3304 goto out;
3305 }
3306 err = -ENOENT;
3307 if (namelen == 0) {
3308 /* This finds "kernel_module" which is not exported. */
3309 for(mod = module_list; mod->next != NULL; mod = mod->next)
3310 ;
3311 } else if ((mod = find_module(name)) == NULL) {
3312 put_mod_name(name);
3313 goto out;
3314 }
3315 put_mod_name(name);
3316 }
3317
3318 switch (which)
3319 {
3320 case 0:
3321 err = 0;
3322 break;
3323 case QM_MODULES:
3324 err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3325 break;
3326 case QM_DEPS:
3327 err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3328 break;
3329 case QM_REFS:
3330 err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3331 break;
3332 case QM_SYMBOLS:
3333 err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3334 break;
3335 case QM_INFO:
3336 err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3337 break;
3338 default:
3339 err = -EINVAL;
3340 break;
3341 }
3342 out:
3343 unlock_kernel();
3344 return err;
3345 }
3346
3347 struct kernel_sym32 {
3348 u32 value;
3349 char name[60];
3350 };
3351
3352 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3353
3354 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3355 {
3356 int len, i;
3357 struct kernel_sym *tbl;
3358 mm_segment_t old_fs;
3359
3360 len = sys_get_kernel_syms(NULL);
3361 if (!table) return len;
3362 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3363 if (!tbl) return -ENOMEM;
3364 old_fs = get_fs();
3365 set_fs (KERNEL_DS);
3366 sys_get_kernel_syms(tbl);
3367 set_fs (old_fs);
3368 for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
3369 if (put_user (tbl[i].value, &table->value) ||
3370 copy_to_user (table->name, tbl[i].name, 60))
3371 break;
3372 }
3373 kfree (tbl);
3374 return i;
3375 }
3376
3377 #else /* CONFIG_MODULES */
3378
3379 asmlinkage unsigned long
3380 sys32_create_module(const char *name_user, size_t size)
3381 {
3382 return -ENOSYS;
3383 }
3384
3385 asmlinkage int
3386 sys32_init_module(const char *name_user, struct module *mod_user)
3387 {
3388 return -ENOSYS;
3389 }
3390
3391 asmlinkage int
3392 sys32_delete_module(const char *name_user)
3393 {
3394 return -ENOSYS;
3395 }
3396
3397 asmlinkage int
3398 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3399 size_t *ret)
3400 {
3401 /* Let the program know about the new interface. Not that
3402 it'll do them much good. */
3403 if (which == 0)
3404 return 0;
3405
3406 return -ENOSYS;
3407 }
3408
3409 asmlinkage int
3410 sys32_get_kernel_syms(struct kernel_sym *table)
3411 {
3412 return -ENOSYS;
3413 }
3414
3415 #endif /* CONFIG_MODULES */
3416
3417 /* Stuff for NFS server syscalls... */
3418 struct nfsctl_svc32 {
3419 u16 svc32_port;
3420 s32 svc32_nthreads;
3421 };
3422
3423 struct nfsctl_client32 {
3424 s8 cl32_ident[NFSCLNT_IDMAX+1];
3425 s32 cl32_naddr;
3426 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
3427 s32 cl32_fhkeytype;
3428 s32 cl32_fhkeylen;
3429 u8 cl32_fhkey[NFSCLNT_KEYMAX];
3430 };
3431
3432 struct nfsctl_export32 {
3433 s8 ex32_client[NFSCLNT_IDMAX+1];
3434 s8 ex32_path[NFS_MAXPATHLEN+1];
3435 __kernel_dev_t32 ex32_dev;
3436 __kernel_ino_t32 ex32_ino;
3437 s32 ex32_flags;
3438 __kernel_uid_t32 ex32_anon_uid;
3439 __kernel_gid_t32 ex32_anon_gid;
3440 };
3441
3442 struct nfsctl_uidmap32 {
3443 u32 ug32_ident; /* char * */
3444 __kernel_uid_t32 ug32_uidbase;
3445 s32 ug32_uidlen;
3446 u32 ug32_udimap; /* uid_t * */
3447 __kernel_uid_t32 ug32_gidbase;
3448 s32 ug32_gidlen;
3449 u32 ug32_gdimap; /* gid_t * */
3450 };
3451
3452 struct nfsctl_fhparm32 {
3453 struct sockaddr gf32_addr;
3454 __kernel_dev_t32 gf32_dev;
3455 __kernel_ino_t32 gf32_ino;
3456 s32 gf32_version;
3457 };
3458
3459 struct nfsctl_fdparm32 {
3460 struct sockaddr gd32_addr;
3461 s8 gd32_path[NFS_MAXPATHLEN+1];
3462 s32 gd32_version;
3463 };
3464
3465 struct nfsctl_fsparm32 {
3466 struct sockaddr gd32_addr;
3467 s8 gd32_path[NFS_MAXPATHLEN+1];
3468 s32 gd32_maxlen;
3469 };
3470
3471 struct nfsctl_arg32 {
3472 s32 ca32_version; /* safeguard */
3473 union {
3474 struct nfsctl_svc32 u32_svc;
3475 struct nfsctl_client32 u32_client;
3476 struct nfsctl_export32 u32_export;
3477 struct nfsctl_uidmap32 u32_umap;
3478 struct nfsctl_fhparm32 u32_getfh;
3479 struct nfsctl_fdparm32 u32_getfd;
3480 struct nfsctl_fsparm32 u32_getfs;
3481 } u;
3482 #define ca32_svc u.u32_svc
3483 #define ca32_client u.u32_client
3484 #define ca32_export u.u32_export
3485 #define ca32_umap u.u32_umap
3486 #define ca32_getfh u.u32_getfh
3487 #define ca32_getfd u.u32_getfd
3488 #define ca32_getfs u.u32_getfs
3489 #define ca32_authd u.u32_authd
3490 };
3491
3492 union nfsctl_res32 {
3493 __u8 cr32_getfh[NFS_FHSIZE];
3494 struct knfsd_fh cr32_getfs;
3495 };
3496
3497 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3498 {
3499 int err;
3500
3501 err = __get_user(karg->ca_version, &arg32->ca32_version);
3502 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3503 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3504 return err;
3505 }
3506
3507 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3508 {
3509 int err;
3510
3511 err = __get_user(karg->ca_version, &arg32->ca32_version);
3512 err |= copy_from_user(&karg->ca_client.cl_ident[0],
3513 &arg32->ca32_client.cl32_ident[0],
3514 NFSCLNT_IDMAX);
3515 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3516 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3517 &arg32->ca32_client.cl32_addrlist[0],
3518 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3519 err |= __get_user(karg->ca_client.cl_fhkeytype,
3520 &arg32->ca32_client.cl32_fhkeytype);
3521 err |= __get_user(karg->ca_client.cl_fhkeylen,
3522 &arg32->ca32_client.cl32_fhkeylen);
3523 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3524 &arg32->ca32_client.cl32_fhkey[0],
3525 NFSCLNT_KEYMAX);
3526 return err;
3527 }
3528
3529 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3530 {
3531 int err;
3532
3533 err = __get_user(karg->ca_version, &arg32->ca32_version);
3534 err |= copy_from_user(&karg->ca_export.ex_client[0],
3535 &arg32->ca32_export.ex32_client[0],
3536 NFSCLNT_IDMAX);
3537 err |= copy_from_user(&karg->ca_export.ex_path[0],
3538 &arg32->ca32_export.ex32_path[0],
3539 NFS_MAXPATHLEN);
3540 err |= __get_user(karg->ca_export.ex_dev,
3541 &arg32->ca32_export.ex32_dev);
3542 err |= __get_user(karg->ca_export.ex_ino,
3543 &arg32->ca32_export.ex32_ino);
3544 err |= __get_user(karg->ca_export.ex_flags,
3545 &arg32->ca32_export.ex32_flags);
3546 err |= __get_user(karg->ca_export.ex_anon_uid,
3547 &arg32->ca32_export.ex32_anon_uid);
3548 err |= __get_user(karg->ca_export.ex_anon_gid,
3549 &arg32->ca32_export.ex32_anon_gid);
3550 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3551 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3552 return err;
3553 }
3554
3555 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3556 {
3557 u32 uaddr;
3558 int i;
3559 int err;
3560
3561 memset(karg, 0, sizeof(*karg));
3562 if(__get_user(karg->ca_version, &arg32->ca32_version))
3563 return -EFAULT;
3564 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3565 if(!karg->ca_umap.ug_ident)
3566 return -ENOMEM;
3567 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3568 if(strncpy_from_user(karg->ca_umap.ug_ident,
3569 (char *)A(uaddr), PAGE_SIZE) <= 0)
3570 return -EFAULT;
3571 err |= __get_user(karg->ca_umap.ug_uidbase,
3572 &arg32->ca32_umap.ug32_uidbase);
3573 err |= __get_user(karg->ca_umap.ug_uidlen,
3574 &arg32->ca32_umap.ug32_uidlen);
3575 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3576 if (err)
3577 return -EFAULT;
3578 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3579 GFP_USER);
3580 if(!karg->ca_umap.ug_udimap)
3581 return -ENOMEM;
3582 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3583 err |= __get_user(karg->ca_umap.ug_udimap[i],
3584 &(((__kernel_uid_t32 *)A(uaddr))[i]));
3585 err |= __get_user(karg->ca_umap.ug_gidbase,
3586 &arg32->ca32_umap.ug32_gidbase);
3587 err |= __get_user(karg->ca_umap.ug_uidlen,
3588 &arg32->ca32_umap.ug32_gidlen);
3589 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3590 if (err)
3591 return -EFAULT;
3592 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3593 GFP_USER);
3594 if(!karg->ca_umap.ug_gdimap)
3595 return -ENOMEM;
3596 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3597 err |= __get_user(karg->ca_umap.ug_gdimap[i],
3598 &(((__kernel_gid_t32 *)A(uaddr))[i]));
3599
3600 return err;
3601 }
3602
3603 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3604 {
3605 int err;
3606
3607 err = __get_user(karg->ca_version, &arg32->ca32_version);
3608 err |= copy_from_user(&karg->ca_getfh.gf_addr,
3609 &arg32->ca32_getfh.gf32_addr,
3610 (sizeof(struct sockaddr)));
3611 err |= __get_user(karg->ca_getfh.gf_dev,
3612 &arg32->ca32_getfh.gf32_dev);
3613 err |= __get_user(karg->ca_getfh.gf_ino,
3614 &arg32->ca32_getfh.gf32_ino);
3615 err |= __get_user(karg->ca_getfh.gf_version,
3616 &arg32->ca32_getfh.gf32_version);
3617 return err;
3618 }
3619
3620 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3621 {
3622 int err;
3623
3624 err = __get_user(karg->ca_version, &arg32->ca32_version);
3625 err |= copy_from_user(&karg->ca_getfd.gd_addr,
3626 &arg32->ca32_getfd.gd32_addr,
3627 (sizeof(struct sockaddr)));
3628 err |= copy_from_user(&karg->ca_getfd.gd_path,
3629 &arg32->ca32_getfd.gd32_path,
3630 (NFS_MAXPATHLEN+1));
3631 err |= __get_user(karg->ca_getfd.gd_version,
3632 &arg32->ca32_getfd.gd32_version);
3633 return err;
3634 }
3635
3636 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3637 {
3638 int err;
3639
3640 err = __get_user(karg->ca_version, &arg32->ca32_version);
3641 err |= copy_from_user(&karg->ca_getfs.gd_addr,
3642 &arg32->ca32_getfs.gd32_addr,
3643 (sizeof(struct sockaddr)));
3644 err |= copy_from_user(&karg->ca_getfs.gd_path,
3645 &arg32->ca32_getfs.gd32_path,
3646 (NFS_MAXPATHLEN+1));
3647 err |= __get_user(karg->ca_getfs.gd_maxlen,
3648 &arg32->ca32_getfs.gd32_maxlen);
3649 return err;
3650 }
3651
3652 /* This really doesn't need translations, we are only passing
3653 * back a union which contains opaque nfs file handle data.
3654 */
3655 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3656 {
3657 return copy_to_user(res32, kres, sizeof(*res32));
3658 }
3659
3660 /*
3661 asmlinkage long sys_ni_syscall(void);
3662 */
3663
3664 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3665 {
3666 struct nfsctl_arg *karg = NULL;
3667 union nfsctl_res *kres = NULL;
3668 mm_segment_t oldfs;
3669 int err;
3670
3671 karg = kmalloc(sizeof(*karg), GFP_USER);
3672 if(!karg)
3673 return -ENOMEM;
3674 if(res32) {
3675 kres = kmalloc(sizeof(*kres), GFP_USER);
3676 if(!kres) {
3677 kfree(karg);
3678 return -ENOMEM;
3679 }
3680 }
3681 switch(cmd) {
3682 case NFSCTL_SVC:
3683 err = nfs_svc32_trans(karg, arg32);
3684 break;
3685 case NFSCTL_ADDCLIENT:
3686 err = nfs_clnt32_trans(karg, arg32);
3687 break;
3688 case NFSCTL_DELCLIENT:
3689 err = nfs_clnt32_trans(karg, arg32);
3690 break;
3691 case NFSCTL_EXPORT:
3692 case NFSCTL_UNEXPORT:
3693 err = nfs_exp32_trans(karg, arg32);
3694 break;
3695 /* This one is unimplemented, be we're ready for it. */
3696 case NFSCTL_UGIDUPDATE:
3697 err = nfs_uud32_trans(karg, arg32);
3698 break;
3699 case NFSCTL_GETFH:
3700 err = nfs_getfh32_trans(karg, arg32);
3701 break;
3702 case NFSCTL_GETFD:
3703 err = nfs_getfd32_trans(karg, arg32);
3704 break;
3705 case NFSCTL_GETFS:
3706 err = nfs_getfs32_trans(karg, arg32);
3707 break;
3708 default:
3709 err = -EINVAL;
3710 break;
3711 }
3712 if(err)
3713 goto done;
3714 oldfs = get_fs();
3715 set_fs(KERNEL_DS);
3716 err = sys_nfsservctl(cmd, karg, kres);
3717 set_fs(oldfs);
3718
3719 if (err)
3720 goto done;
3721
3722 if((cmd == NFSCTL_GETFH) ||
3723 (cmd == NFSCTL_GETFD) ||
3724 (cmd == NFSCTL_GETFS))
3725 err = nfs_getfh32_res_trans(kres, res32);
3726
3727 done:
3728 if(karg) {
3729 if(cmd == NFSCTL_UGIDUPDATE) {
3730 if(karg->ca_umap.ug_ident)
3731 kfree(karg->ca_umap.ug_ident);
3732 if(karg->ca_umap.ug_udimap)
3733 kfree(karg->ca_umap.ug_udimap);
3734 if(karg->ca_umap.ug_gdimap)
3735 kfree(karg->ca_umap.ug_gdimap);
3736 }
3737 kfree(karg);
3738 }
3739 if(kres)
3740 kfree(kres);
3741 return err;
3742 }
3743
3744 /* Translations due to time_t size differences. Which affects all
3745 sorts of things, like timeval and itimerval. */
3746
3747 extern struct timezone sys_tz;
3748 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3749
3750 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3751 {
3752 if (tv) {
3753 struct timeval ktv;
3754 do_gettimeofday(&ktv);
3755 if (put_tv32(tv, &ktv))
3756 return -EFAULT;
3757 }
3758 if (tz) {
3759 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3760 return -EFAULT;
3761 }
3762 return 0;
3763 }
3764
3765 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3766 {
3767 struct timeval ktv;
3768 struct timezone ktz;
3769
3770 if (tv) {
3771 if (get_tv32(&ktv, tv))
3772 return -EFAULT;
3773 }
3774 if (tz) {
3775 if (copy_from_user(&ktz, tz, sizeof(ktz)))
3776 return -EFAULT;
3777 }
3778
3779 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3780 }
3781
3782 extern int do_getitimer(int which, struct itimerval *value);
3783
3784 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3785 {
3786 struct itimerval kit;
3787 int error;
3788
3789 error = do_getitimer(which, &kit);
3790 if (!error && put_it32(it, &kit))
3791 error = -EFAULT;
3792
3793 return error;
3794 }
3795
3796 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3797
3798 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3799 {
3800 struct itimerval kin, kout;
3801 int error;
3802
3803 if (in) {
3804 if (get_it32(&kin, in))
3805 return -EFAULT;
3806 } else
3807 memset(&kin, 0, sizeof(kin));
3808
3809 error = do_setitimer(which, &kin, out ? &kout : NULL);
3810 if (error || !out)
3811 return error;
3812 if (put_it32(out, &kout))
3813 return -EFAULT;
3814
3815 return 0;
3816
3817 }
3818
3819 asmlinkage int sys_utimes(char *, struct timeval *);
3820
3821 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3822 {
3823 char *kfilename;
3824 struct timeval ktvs[2];
3825 mm_segment_t old_fs;
3826 int ret;
3827
3828 kfilename = getname(filename);
3829 ret = PTR_ERR(kfilename);
3830 if (!IS_ERR(kfilename)) {
3831 if (tvs) {
3832 if (get_tv32(&ktvs[0], tvs) ||
3833 get_tv32(&ktvs[1], 1+tvs))
3834 return -EFAULT;
3835 }
3836
3837 old_fs = get_fs();
3838 set_fs(KERNEL_DS);
3839 ret = sys_utimes(kfilename, &ktvs[0]);
3840 set_fs(old_fs);
3841
3842 putname(kfilename);
3843 }
3844 return ret;
3845 }
3846
3847 /* These are here just in case some old sparc32 binary calls it. */
3848 asmlinkage int sys32_pause(void)
3849 {
3850 current->state = TASK_INTERRUPTIBLE;
3851 schedule();
3852 return -ERESTARTNOHAND;
3853 }
3854
3855 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
3856 unsigned long arg4, unsigned long arg5);
3857
3858 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
3859 {
3860 return sys_prctl(option,
3861 (unsigned long) arg2,
3862 (unsigned long) arg3,
3863 (unsigned long) arg4,
3864 (unsigned long) arg5);
3865 }
3866
3867
3868 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
3869 size_t count, loff_t pos);
3870
3871 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
3872 size_t count, loff_t pos);
3873
3874 typedef __kernel_ssize_t32 ssize_t32;
3875
3876 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
3877 __kernel_size_t32 count, u32 poshi, u32 poslo)
3878 {
3879 return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
3880 }
3881
3882 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
3883 __kernel_size_t32 count, u32 poshi, u32 poslo)
3884 {
3885 return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
3886 }
3887
3888
3889 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
3890
3891 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
3892 {
3893 mm_segment_t old_fs = get_fs();
3894 int ret;
3895 off_t of;
3896
3897 if (offset && get_user(of, offset))
3898 return -EFAULT;
3899
3900 set_fs(KERNEL_DS);
3901 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
3902 set_fs(old_fs);
3903
3904 if (!ret && offset && put_user(of, offset))
3905 return -EFAULT;
3906
3907 return ret;
3908 }
3909
3910 /* Handle adjtimex compatability. */
3911
3912 struct timex32 {
3913 u32 modes;
3914 s32 offset, freq, maxerror, esterror;
3915 s32 status, constant, precision, tolerance;
3916 struct timeval32 time;
3917 s32 tick;
3918 s32 ppsfreq, jitter, shift, stabil;
3919 s32 jitcnt, calcnt, errcnt, stbcnt;
3920 s32 :32; s32 :32; s32 :32; s32 :32;
3921 s32 :32; s32 :32; s32 :32; s32 :32;
3922 s32 :32; s32 :32; s32 :32; s32 :32;
3923 };
3924
3925 extern int do_adjtimex(struct timex *);
3926
3927 asmlinkage int sys32_adjtimex(struct timex32 *utp)
3928 {
3929 struct timex txc;
3930 int ret;
3931
3932 memset(&txc, 0, sizeof(struct timex));
3933
3934 if(get_user(txc.modes, &utp->modes) ||
3935 __get_user(txc.offset, &utp->offset) ||
3936 __get_user(txc.freq, &utp->freq) ||
3937 __get_user(txc.maxerror, &utp->maxerror) ||
3938 __get_user(txc.esterror, &utp->esterror) ||
3939 __get_user(txc.status, &utp->status) ||
3940 __get_user(txc.constant, &utp->constant) ||
3941 __get_user(txc.precision, &utp->precision) ||
3942 __get_user(txc.tolerance, &utp->tolerance) ||
3943 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
3944 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
3945 __get_user(txc.tick, &utp->tick) ||
3946 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
3947 __get_user(txc.jitter, &utp->jitter) ||
3948 __get_user(txc.shift, &utp->shift) ||
3949 __get_user(txc.stabil, &utp->stabil) ||
3950 __get_user(txc.jitcnt, &utp->jitcnt) ||
3951 __get_user(txc.calcnt, &utp->calcnt) ||
3952 __get_user(txc.errcnt, &utp->errcnt) ||
3953 __get_user(txc.stbcnt, &utp->stbcnt))
3954 return -EFAULT;
3955
3956 ret = do_adjtimex(&txc);
3957
3958 if(put_user(txc.modes, &utp->modes) ||
3959 __put_user(txc.offset, &utp->offset) ||
3960 __put_user(txc.freq, &utp->freq) ||
3961 __put_user(txc.maxerror, &utp->maxerror) ||
3962 __put_user(txc.esterror, &utp->esterror) ||
3963 __put_user(txc.status, &utp->status) ||
3964 __put_user(txc.constant, &utp->constant) ||
3965 __put_user(txc.precision, &utp->precision) ||
3966 __put_user(txc.tolerance, &utp->tolerance) ||
3967 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
3968 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
3969 __put_user(txc.tick, &utp->tick) ||
3970 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
3971 __put_user(txc.jitter, &utp->jitter) ||
3972 __put_user(txc.shift, &utp->shift) ||
3973 __put_user(txc.stabil, &utp->stabil) ||
3974 __put_user(txc.jitcnt, &utp->jitcnt) ||
3975 __put_user(txc.calcnt, &utp->calcnt) ||
3976 __put_user(txc.errcnt, &utp->errcnt) ||
3977 __put_user(txc.stbcnt, &utp->stbcnt))
3978 ret = -EFAULT;
3979
3980 return ret;
3981 }
3982
3983 extern asmlinkage long sys_setpriority(int which, int who, int niceval);
3984
3985 asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval)
3986 {
3987 return sys_setpriority((int) which,
3988 (int) who,
3989 (int) niceval);
3990 }
3991
3992 struct __sysctl_args32 {
3993 u32 name;
3994 int nlen;
3995 u32 oldval;
3996 u32 oldlenp;
3997 u32 newval;
3998 u32 newlen;
3999 u32 __unused[4];
4000 };
4001
4002 extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
4003 {
4004 struct __sysctl_args32 tmp;
4005 int error;
4006 size_t oldlen, *oldlenp = NULL;
4007 unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
4008
4009 if (copy_from_user(&tmp, args, sizeof(tmp)))
4010 return -EFAULT;
4011
4012 if (tmp.oldval && tmp.oldlenp) {
4013 /* Duh, this is ugly and might not work if sysctl_args
4014 is in read-only memory, but do_sysctl does indirectly
4015 a lot of uaccess in both directions and we'd have to
4016 basically copy the whole sysctl.c here, and
4017 glibc's __sysctl uses rw memory for the structure
4018 anyway. */
4019 if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
4020 put_user(oldlen, (size_t *)addr))
4021 return -EFAULT;
4022 oldlenp = (size_t *)addr;
4023 }
4024
4025 lock_kernel();
4026 error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
4027 oldlenp, (void *)A(tmp.newval), tmp.newlen);
4028 unlock_kernel();
4029 if (oldlenp) {
4030 if (!error) {
4031 if (get_user(oldlen, (size_t *)addr) ||
4032 put_user(oldlen, (u32 *)A(tmp.oldlenp)))
4033 error = -EFAULT;
4034 }
4035 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
4036 }
4037 return error;
4038 }
4039
4040 struct stat64_emu31 {
4041 unsigned short st_dev;
4042 unsigned char __pad0[6];
4043
4044 long long st_ino;
4045 unsigned int st_mode;
4046 unsigned int st_nlink;
4047
4048 __u32 st_uid;
4049 __u32 st_gid;
4050
4051 unsigned short st_rdev;
4052 unsigned char __pad3[10];
4053
4054 long long st_size;
4055 __u32 st_blksize;
4056
4057 __u32 st_blocks; /* Number 512-byte blocks allocated. */
4058 __u32 __pad4; /* future possible st_blocks high bits */
4059
4060 __u32 st_atime;
4061 __u32 __pad5;
4062
4063 __u32 st_mtime;
4064 __u32 __pad6;
4065
4066 __u32 st_ctime;
4067 __u32 __pad7; /* will be high 32 bits of ctime someday */
4068
4069 __u32 __unused1;
4070 __u32 __unused2;
4071 };
4072
4073 static inline int
4074 putstat64 (struct stat64_emu31 *ubuf, struct stat *kbuf)
4075 {
4076 int err;
4077
4078 err = put_user (kbuf->st_dev, &ubuf->st_dev);
4079 err |= __put_user (kbuf->st_ino, &ubuf->st_ino);
4080 err |= __put_user (kbuf->st_mode, &ubuf->st_mode);
4081 err |= __put_user (kbuf->st_nlink, &ubuf->st_nlink);
4082 err |= __put_user (kbuf->st_uid, &ubuf->st_uid);
4083 err |= __put_user (kbuf->st_gid, &ubuf->st_gid);
4084 err |= __put_user (kbuf->st_rdev, &ubuf->st_rdev);
4085 err |= __put_user (kbuf->st_size, &ubuf->st_size);
4086 err |= __put_user (kbuf->st_blksize, &ubuf->st_blksize);
4087 err |= __put_user (kbuf->st_blocks, &ubuf->st_blocks);
4088 err |= __put_user (kbuf->st_atime, &ubuf->st_atime);
4089 err |= __put_user (kbuf->st_mtime, &ubuf->st_mtime);
4090 err |= __put_user (kbuf->st_ctime, &ubuf->st_ctime);
4091 return err;
4092 }
4093
4094 extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
4095
4096 asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf, long flags)
4097 {
4098 int ret;
4099 struct stat s;
4100 char * tmp;
4101 int err;
4102 mm_segment_t old_fs = get_fs();
4103
4104 tmp = getname(filename);
4105 err = PTR_ERR(tmp);
4106 if (IS_ERR(tmp))
4107 return err;
4108
4109 set_fs (KERNEL_DS);
4110 ret = sys_newstat(tmp, &s);
4111 set_fs (old_fs);
4112 putname(tmp);
4113 if (putstat64 (statbuf, &s))
4114 return -EFAULT;
4115 return ret;
4116 }
4117
4118 extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
4119
4120 asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf, long flags)
4121 {
4122 int ret;
4123 struct stat s;
4124 char * tmp;
4125 int err;
4126 mm_segment_t old_fs = get_fs();
4127
4128 tmp = getname(filename);
4129 err = PTR_ERR(tmp);
4130 if (IS_ERR(tmp))
4131 return err;
4132
4133 set_fs (KERNEL_DS);
4134 ret = sys_newstat(tmp, &s);
4135 set_fs (old_fs);
4136 putname(tmp);
4137 if (putstat64 (statbuf, &s))
4138 return -EFAULT;
4139 return ret;
4140 }
4141
4142 extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
4143
4144 asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf, long flags)
4145 {
4146 int ret;
4147 struct stat s;
4148 mm_segment_t old_fs = get_fs();
4149
4150 set_fs (KERNEL_DS);
4151 ret = sys_newfstat(fd, &s);
4152 set_fs (old_fs);
4153 if (putstat64 (statbuf, &s))
4154 return -EFAULT;
4155 return ret;
4156 }
4157
4158 /*
4159 * Linux/i386 didn't use to be able to handle more than
4160 * 4 system call parameters, so these system calls used a memory
4161 * block for parameter passing..
4162 */
4163
4164 struct mmap_arg_struct_emu31 {
4165 u32 addr;
4166 u32 len;
4167 u32 prot;
4168 u32 flags;
4169 u32 fd;
4170 u32 offset;
4171 };
4172
4173 /* common code for old and new mmaps */
4174 static inline long do_mmap2(
4175 unsigned long addr, unsigned long len,
4176 unsigned long prot, unsigned long flags,
4177 unsigned long fd, unsigned long pgoff)
4178 {
4179 struct file * file = NULL;
4180 unsigned long error = -EBADF;
4181
4182 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
4183 if (!(flags & MAP_ANONYMOUS)) {
4184 file = fget(fd);
4185 if (!file)
4186 goto out;
4187 }
4188
4189 down_write(¤t->mm->mmap_sem);
4190 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
4191 if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) {
4192 /* Result is out of bounds. */
4193 do_munmap(current->mm, addr, len);
4194 error = -ENOMEM;
4195 }
4196 up_write(¤t->mm->mmap_sem);
4197
4198 if (file)
4199 fput(file);
4200 out:
4201 return error;
4202 }
4203
4204
4205 asmlinkage unsigned long
4206 old32_mmap(struct mmap_arg_struct_emu31 *arg)
4207 {
4208 struct mmap_arg_struct_emu31 a;
4209 int error = -EFAULT;
4210
4211 if (copy_from_user(&a, arg, sizeof(a)))
4212 goto out;
4213
4214 error = -EINVAL;
4215 if (a.offset & ~PAGE_MASK)
4216 goto out;
4217
4218 error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
4219 out:
4220 return error;
4221 }
4222
4223 asmlinkage long
4224 sys32_mmap2(struct mmap_arg_struct_emu31 *arg)
4225 {
4226 struct mmap_arg_struct_emu31 a;
4227 int error = -EFAULT;
4228
4229 if (copy_from_user(&a, arg, sizeof(a)))
4230 goto out;
4231 error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
4232 out:
4233 return error;
4234 }
4235
4236 extern asmlinkage long sys_socket(int family, int type, int protocol);
4237 extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
4238 extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
4239 extern asmlinkage long sys_listen(int fd, int backlog);
4240 extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen);
4241 extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len);
4242 extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len);
4243 extern asmlinkage long sys_socketpair(int family, int type, int protocol, int usockvec[2]);
4244 extern asmlinkage long sys_send(int fd, void * buff, size_t len, unsigned flags);
4245 extern asmlinkage long sys_sendto(int fd, void * buff, size_t len, unsigned flags,
4246 struct sockaddr *addr, int addr_len);
4247 extern asmlinkage long sys_recv(int fd, void * ubuf, size_t size, unsigned flags);
4248 extern asmlinkage long sys_recvfrom(int fd, void * ubuf, size_t size, unsigned flags,
4249 struct sockaddr *addr, int *addr_len);
4250 extern asmlinkage long sys_shutdown(int fd, int how);
4251 extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char *optval, int * optlen);
4252
4253 /* Argument list sizes for sys_socketcall */
4254 #define AL(x) ((x) * sizeof(u32))
4255 static unsigned char nas[18] = {AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
4256 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
4257 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
4258 #undef AL
4259
4260 asmlinkage long sys32_socketcall(int call, u32 *args)
4261 {
4262 int ret;
4263 u32 a[6];
4264
4265 if (call < SYS_SOCKET || call > SYS_RECVMSG)
4266 return -EINVAL;
4267 if (copy_from_user(a, args, nas[call]))
4268 return -EFAULT;
4269 switch(call) {
4270 case SYS_SOCKET:
4271 ret = sys_socket(a[0], a[1], a[2]);
4272 break;
4273 case SYS_BIND:
4274 ret = sys_bind(a[0], (struct sockaddr *) A(a[1]), a[2]);
4275 break;
4276 case SYS_CONNECT:
4277 ret = sys_connect(a[0], (struct sockaddr *) A(a[1]), a[2]);
4278 break;
4279 case SYS_LISTEN:
4280 ret = sys_listen(a[0], a[1]);
4281 break;
4282 case SYS_ACCEPT:
4283 ret = sys_accept(a[0], (struct sockaddr *) A(a[1]),
4284 (int *) A(a[2]));
4285 break;
4286 case SYS_GETSOCKNAME:
4287 ret = sys_getsockname(a[0], (struct sockaddr *) A(a[1]),
4288 (int *) A(a[2]));
4289 break;
4290 case SYS_GETPEERNAME:
4291 ret = sys_getpeername(a[0], (struct sockaddr *) A(a[1]),
4292 (int *) A(a[2]));
4293 break;
4294 case SYS_SOCKETPAIR:
4295 ret = sys_socketpair(a[0], a[1], a[2], (int *) A(a[3]));
4296 break;
4297 case SYS_SEND:
4298 ret = sys_send(a[0], (void *) A(a[1]), a[2], a[3]);
4299 break;
4300 case SYS_SENDTO:
4301 ret = sys_sendto(a[0], (void*) A(a[1]), a[2], a[3], (struct sockaddr *) A(a[4]), a[5]);
4302 break;
4303 case SYS_RECV:
4304 ret = sys_recv(a[0], (void *) A(a[1]), a[2], a[3]);
4305 break;
4306 case SYS_RECVFROM:
4307 ret = sys_recvfrom(a[0], (void *) A(a[1]), a[2], a[3], (struct sockaddr *) A(a[4]), (int *) A(a[5]) );
4308 break;
4309 case SYS_SHUTDOWN:
4310 ret = sys_shutdown(a[0], a[1]);
4311 break;
4312 case SYS_SETSOCKOPT:
4313 ret = sys32_setsockopt(a[0], a[1], a[2], (char *) A(a[3]),
4314 a[4]);
4315 break;
4316 case SYS_GETSOCKOPT:
4317 ret = sys_getsockopt(a[0], a[1], a[2], (char *) A(a[3]), (int *) A(a[4]) );
4318 break;
4319 case SYS_SENDMSG:
4320 ret = sys32_sendmsg(a[0], (struct msghdr32 *) A(a[1]),
4321 a[2]);
4322 break;
4323 case SYS_RECVMSG:
4324 ret = sys32_recvmsg(a[0], (struct msghdr32 *) A(a[1]),
4325 a[2]);
4326 break;
4327 default:
4328 ret = EINVAL;
4329 break;
4330 }
4331 return ret;
4332 }
4333
4334