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