File: /usr/src/linux/arch/ia64/ia32/sys_ia32.c
1 /*
2 * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Based on
3 * sys_sparc32
4 *
5 * Copyright (C) 2000 VA Linux Co
6 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
7 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
8 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
10 * Copyright (C) 2000 Hewlett-Packard Co.
11 * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
12 *
13 * These routines maintain argument size conversion between 32bit and 64bit
14 * environment.
15 */
16
17 #include <linux/config.h>
18 #include <linux/kernel.h>
19 #include <linux/sysctl.h>
20 #include <linux/sched.h>
21 #include <linux/fs.h>
22 #include <linux/file.h>
23 #include <linux/signal.h>
24 #include <linux/utime.h>
25 #include <linux/resource.h>
26 #include <linux/times.h>
27 #include <linux/utsname.h>
28 #include <linux/timex.h>
29 #include <linux/smp.h>
30 #include <linux/smp_lock.h>
31 #include <linux/sem.h>
32 #include <linux/msg.h>
33 #include <linux/mm.h>
34 #include <linux/shm.h>
35 #include <linux/slab.h>
36 #include <linux/uio.h>
37 #include <linux/nfs_fs.h>
38 #include <linux/smb_fs.h>
39 #include <linux/smb_mount.h>
40 #include <linux/ncp_fs.h>
41 #include <linux/quota.h>
42 #include <linux/module.h>
43 #include <linux/sunrpc/svc.h>
44 #include <linux/nfsd/nfsd.h>
45 #include <linux/nfsd/cache.h>
46 #include <linux/nfsd/xdr.h>
47 #include <linux/nfsd/syscall.h>
48 #include <linux/poll.h>
49 #include <linux/personality.h>
50 #include <linux/stat.h>
51 #include <linux/ipc.h>
52
53 #include <asm/types.h>
54 #include <asm/uaccess.h>
55 #include <asm/semaphore.h>
56 #include <asm/ipc.h>
57
58 #include <net/scm.h>
59 #include <net/sock.h>
60 #include <asm/ia32.h>
61
62 #define A(__x) ((unsigned long)(__x))
63 #define AA(__x) ((unsigned long)(__x))
64 #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
65 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
66
67 extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *);
68 extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long);
69
70 static int
71 nargs (unsigned int arg, char **ap)
72 {
73 int n, err, addr;
74
75 if (!arg)
76 return 0;
77
78 n = 0;
79 do {
80 err = get_user(addr, (int *)A(arg));
81 if (err)
82 return err;
83 if (ap)
84 *ap++ = (char *) A(addr);
85 arg += sizeof(unsigned int);
86 n++;
87 } while (addr);
88 return n - 1;
89 }
90
91 asmlinkage long
92 sys32_execve (char *filename, unsigned int argv, unsigned int envp,
93 int dummy3, int dummy4, int dummy5, int dummy6, int dummy7,
94 int stack)
95 {
96 struct pt_regs *regs = (struct pt_regs *)&stack;
97 unsigned long old_map_base, old_task_size;
98 char **av, **ae;
99 int na, ne, len;
100 long r;
101
102 na = nargs(argv, NULL);
103 if (na < 0)
104 return na;
105 ne = nargs(envp, NULL);
106 if (ne < 0)
107 return ne;
108 len = (na + ne + 2) * sizeof(*av);
109 av = kmalloc(len, GFP_KERNEL);
110 if (!av)
111 return -ENOMEM;
112
113 ae = av + na + 1;
114 av[na] = NULL;
115 ae[ne] = NULL;
116
117 r = nargs(argv, av);
118 if (r < 0)
119 goto out;
120 r = nargs(envp, ae);
121 if (r < 0)
122 goto out;
123
124 old_map_base = current->thread.map_base;
125 old_task_size = current->thread.task_size;
126
127 /* we may be exec'ing a 64-bit process: reset map base & task-size: */
128 current->thread.map_base = DEFAULT_MAP_BASE;
129 current->thread.task_size = DEFAULT_TASK_SIZE;
130
131 set_fs(KERNEL_DS);
132 r = sys_execve(filename, av, ae, regs);
133 if (r < 0) {
134 /* oops, execve failed, switch back to old map base & task-size: */
135 current->thread.map_base = old_map_base;
136 current->thread.task_size = old_task_size;
137 set_fs(USER_DS); /* establish new task-size as the address-limit */
138 out:
139 kfree(av);
140 }
141 return r;
142 }
143
144 static inline int
145 putstat(struct stat32 *ubuf, struct stat *kbuf)
146 {
147 int err;
148
149 err = put_user (kbuf->st_dev, &ubuf->st_dev);
150 err |= __put_user (kbuf->st_ino, &ubuf->st_ino);
151 err |= __put_user (kbuf->st_mode, &ubuf->st_mode);
152 err |= __put_user (kbuf->st_nlink, &ubuf->st_nlink);
153 err |= __put_user (kbuf->st_uid, &ubuf->st_uid);
154 err |= __put_user (kbuf->st_gid, &ubuf->st_gid);
155 err |= __put_user (kbuf->st_rdev, &ubuf->st_rdev);
156 err |= __put_user (kbuf->st_size, &ubuf->st_size);
157 err |= __put_user (kbuf->st_atime, &ubuf->st_atime);
158 err |= __put_user (kbuf->st_mtime, &ubuf->st_mtime);
159 err |= __put_user (kbuf->st_ctime, &ubuf->st_ctime);
160 err |= __put_user (kbuf->st_blksize, &ubuf->st_blksize);
161 err |= __put_user (kbuf->st_blocks, &ubuf->st_blocks);
162 return err;
163 }
164
165 extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
166
167 asmlinkage long
168 sys32_newstat(char * filename, struct stat32 *statbuf)
169 {
170 int ret;
171 struct stat s;
172 mm_segment_t old_fs = get_fs();
173
174 set_fs(KERNEL_DS);
175 ret = sys_newstat(filename, &s);
176 set_fs (old_fs);
177 if (putstat (statbuf, &s))
178 return -EFAULT;
179 return ret;
180 }
181
182 extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
183
184 asmlinkage long
185 sys32_newlstat(char * filename, struct stat32 *statbuf)
186 {
187 int ret;
188 struct stat s;
189 mm_segment_t old_fs = get_fs();
190
191 set_fs (KERNEL_DS);
192 ret = sys_newlstat(filename, &s);
193 set_fs (old_fs);
194 if (putstat (statbuf, &s))
195 return -EFAULT;
196 return ret;
197 }
198
199 extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
200
201 asmlinkage long
202 sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
203 {
204 int ret;
205 struct stat s;
206 mm_segment_t old_fs = get_fs();
207
208 set_fs (KERNEL_DS);
209 ret = sys_newfstat(fd, &s);
210 set_fs (old_fs);
211 if (putstat (statbuf, &s))
212 return -EFAULT;
213 return ret;
214 }
215
216 #define OFFSET4K(a) ((a) & 0xfff)
217
218 unsigned long
219 do_mmap_fake(struct file *file, unsigned long addr, unsigned long len,
220 unsigned long prot, unsigned long flags, loff_t off)
221 {
222 struct inode *inode;
223 void *front, *back;
224 unsigned long baddr;
225 int r;
226 char c;
227
228 if (OFFSET4K(addr) || OFFSET4K(off))
229 return -EINVAL;
230 prot |= PROT_WRITE;
231 front = NULL;
232 back = NULL;
233 if ((baddr = (addr & PAGE_MASK)) != addr && get_user(c, (char *)baddr) == 0) {
234 front = kmalloc(addr - baddr, GFP_KERNEL);
235 if (!front)
236 return -ENOMEM;
237 __copy_user(front, (void *)baddr, addr - baddr);
238 }
239 if (addr && ((addr + len) & ~PAGE_MASK) && get_user(c, (char *)(addr + len)) == 0) {
240 back = kmalloc(PAGE_SIZE - ((addr + len) & ~PAGE_MASK), GFP_KERNEL);
241 if (!back) {
242 if (front)
243 kfree(front);
244 return -ENOMEM;
245 }
246 __copy_user(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
247 }
248 down_write(¤t->mm->mmap_sem);
249 r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0);
250 up_write(¤t->mm->mmap_sem);
251 if (r < 0)
252 return(r);
253 if (addr == 0)
254 addr = r;
255 if (back) {
256 __copy_user((char *)addr + len, back, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
257 kfree(back);
258 }
259 if (front) {
260 __copy_user((void *)baddr, front, addr - baddr);
261 kfree(front);
262 }
263 if (flags & MAP_ANONYMOUS) {
264 clear_user((char *)addr, len);
265 return(addr);
266 }
267 if (!file)
268 return -EINVAL;
269 inode = file->f_dentry->d_inode;
270 if (!inode->i_fop)
271 return -EINVAL;
272 if (!file->f_op->read)
273 return -EINVAL;
274 r = file->f_op->read(file, (char *)addr, len, &off);
275 return (r < 0) ? -EINVAL : addr;
276 }
277
278 long
279 ia32_do_mmap (struct file *file, unsigned int addr, unsigned int len, unsigned int prot,
280 unsigned int flags, unsigned int fd, unsigned int offset)
281 {
282 long error = -EFAULT;
283 unsigned int poff;
284
285 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
286 prot |= PROT_EXEC;
287
288 if ((flags & MAP_FIXED) && ((addr & ~PAGE_MASK) || (offset & ~PAGE_MASK)))
289 error = do_mmap_fake(file, addr, len, prot, flags, (loff_t)offset);
290 else {
291 poff = offset & PAGE_MASK;
292 len += offset - poff;
293
294 down_write(¤t->mm->mmap_sem);
295 error = do_mmap_pgoff(file, addr, len, prot, flags, poff >> PAGE_SHIFT);
296 up_write(¤t->mm->mmap_sem);
297
298 if (!IS_ERR((void *) error))
299 error += offset - poff;
300 }
301 return error;
302 }
303
304 /*
305 * Linux/i386 didn't use to be able to handle more than
306 * 4 system call parameters, so these system calls used a memory
307 * block for parameter passing..
308 */
309
310 struct mmap_arg_struct {
311 unsigned int addr;
312 unsigned int len;
313 unsigned int prot;
314 unsigned int flags;
315 unsigned int fd;
316 unsigned int offset;
317 };
318
319 asmlinkage long
320 sys32_mmap(struct mmap_arg_struct *arg)
321 {
322 struct mmap_arg_struct a;
323 struct file *file = NULL;
324 long retval;
325
326 if (copy_from_user(&a, arg, sizeof(a)))
327 return -EFAULT;
328
329 if (PAGE_ALIGN(a.len) == 0)
330 return a.addr;
331
332 if (!(a.flags & MAP_ANONYMOUS)) {
333 file = fget(a.fd);
334 if (!file)
335 return -EBADF;
336 }
337 #ifdef CONFIG_IA64_PAGE_SIZE_4KB
338 if ((a.offset & ~PAGE_MASK) != 0)
339 return -EINVAL;
340
341 down_write(¤t->mm->mmap_sem);
342 retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset >> PAGE_SHIFT);
343 up_write(¤t->mm->mmap_sem);
344 #else
345 retval = ia32_do_mmap(file, a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
346 #endif
347 if (file)
348 fput(file);
349 return retval;
350 }
351
352 asmlinkage long
353 sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
354 {
355
356 #ifdef CONFIG_IA64_PAGE_SIZE_4KB
357 return(sys_mprotect(start, len, prot));
358 #else // CONFIG_IA64_PAGE_SIZE_4KB
359 if (prot == 0)
360 return(0);
361 len += start & ~PAGE_MASK;
362 if ((start & ~PAGE_MASK) && (prot & PROT_WRITE))
363 prot |= PROT_EXEC;
364 return(sys_mprotect(start & PAGE_MASK, len & PAGE_MASK, prot));
365 #endif // CONFIG_IA64_PAGE_SIZE_4KB
366 }
367
368 asmlinkage long
369 sys32_pipe(int *fd)
370 {
371 int retval;
372 int fds[2];
373
374 retval = do_pipe(fds);
375 if (retval)
376 goto out;
377 if (copy_to_user(fd, fds, sizeof(fds)))
378 retval = -EFAULT;
379 out:
380 return retval;
381 }
382
383 asmlinkage long
384 sys32_signal (int sig, unsigned int handler)
385 {
386 struct k_sigaction new_sa, old_sa;
387 int ret;
388
389 new_sa.sa.sa_handler = (__sighandler_t) A(handler);
390 new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
391
392 ret = do_sigaction(sig, &new_sa, &old_sa);
393
394 return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
395 }
396
397 asmlinkage long
398 sys32_rt_sigaction(int sig, struct sigaction32 *act,
399 struct sigaction32 *oact, unsigned int sigsetsize)
400 {
401 struct k_sigaction new_ka, old_ka;
402 int ret;
403 sigset32_t set32;
404
405 /* XXX: Don't preclude handling different sized sigset_t's. */
406 if (sigsetsize != sizeof(sigset32_t))
407 return -EINVAL;
408
409 if (act) {
410 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
411 ret |= __copy_from_user(&set32, &act->sa_mask,
412 sizeof(sigset32_t));
413 switch (_NSIG_WORDS) {
414 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
415 | (((long)set32.sig[7]) << 32);
416 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
417 | (((long)set32.sig[5]) << 32);
418 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
419 | (((long)set32.sig[3]) << 32);
420 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
421 | (((long)set32.sig[1]) << 32);
422 }
423 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
424
425 if (ret)
426 return -EFAULT;
427 }
428
429 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
430
431 if (!ret && oact) {
432 switch (_NSIG_WORDS) {
433 case 4:
434 set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
435 set32.sig[6] = old_ka.sa.sa_mask.sig[3];
436 case 3:
437 set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
438 set32.sig[4] = old_ka.sa.sa_mask.sig[2];
439 case 2:
440 set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
441 set32.sig[2] = old_ka.sa.sa_mask.sig[1];
442 case 1:
443 set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
444 set32.sig[0] = old_ka.sa.sa_mask.sig[0];
445 }
446 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
447 ret |= __copy_to_user(&oact->sa_mask, &set32,
448 sizeof(sigset32_t));
449 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
450 }
451
452 return ret;
453 }
454
455
456 extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
457 size_t sigsetsize);
458
459 asmlinkage long
460 sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
461 unsigned int sigsetsize)
462 {
463 sigset_t s;
464 sigset32_t s32;
465 int ret;
466 mm_segment_t old_fs = get_fs();
467
468 if (set) {
469 if (copy_from_user (&s32, set, sizeof(sigset32_t)))
470 return -EFAULT;
471 switch (_NSIG_WORDS) {
472 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
473 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
474 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
475 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
476 }
477 }
478 set_fs (KERNEL_DS);
479 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL,
480 sigsetsize);
481 set_fs (old_fs);
482 if (ret) return ret;
483 if (oset) {
484 switch (_NSIG_WORDS) {
485 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
486 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
487 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
488 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
489 }
490 if (copy_to_user (oset, &s32, sizeof(sigset32_t)))
491 return -EFAULT;
492 }
493 return 0;
494 }
495
496 static inline int
497 put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
498 {
499 int err;
500
501 err = put_user (kbuf->f_type, &ubuf->f_type);
502 err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
503 err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
504 err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
505 err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
506 err |= __put_user (kbuf->f_files, &ubuf->f_files);
507 err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
508 err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
509 err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
510 err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
511 return err;
512 }
513
514 extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
515
516 asmlinkage long
517 sys32_statfs(const char * path, struct statfs32 *buf)
518 {
519 int ret;
520 struct statfs s;
521 mm_segment_t old_fs = get_fs();
522
523 set_fs (KERNEL_DS);
524 ret = sys_statfs((const char *)path, &s);
525 set_fs (old_fs);
526 if (put_statfs(buf, &s))
527 return -EFAULT;
528 return ret;
529 }
530
531 extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
532
533 asmlinkage long
534 sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
535 {
536 int ret;
537 struct statfs s;
538 mm_segment_t old_fs = get_fs();
539
540 set_fs (KERNEL_DS);
541 ret = sys_fstatfs(fd, &s);
542 set_fs (old_fs);
543 if (put_statfs(buf, &s))
544 return -EFAULT;
545 return ret;
546 }
547
548 struct timeval32
549 {
550 int tv_sec, tv_usec;
551 };
552
553 struct itimerval32
554 {
555 struct timeval32 it_interval;
556 struct timeval32 it_value;
557 };
558
559 static inline long
560 get_tv32(struct timeval *o, struct timeval32 *i)
561 {
562 return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
563 (__get_user(o->tv_sec, &i->tv_sec) |
564 __get_user(o->tv_usec, &i->tv_usec)));
565 }
566
567 static inline long
568 put_tv32(struct timeval32 *o, struct timeval *i)
569 {
570 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
571 (__put_user(i->tv_sec, &o->tv_sec) |
572 __put_user(i->tv_usec, &o->tv_usec)));
573 }
574
575 static inline long
576 get_it32(struct itimerval *o, struct itimerval32 *i)
577 {
578 return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
579 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
580 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
581 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
582 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
583 }
584
585 static inline long
586 put_it32(struct itimerval32 *o, struct itimerval *i)
587 {
588 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
589 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
590 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
591 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
592 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
593 }
594
595 extern int do_getitimer(int which, struct itimerval *value);
596
597 asmlinkage long
598 sys32_getitimer(int which, struct itimerval32 *it)
599 {
600 struct itimerval kit;
601 int error;
602
603 error = do_getitimer(which, &kit);
604 if (!error && put_it32(it, &kit))
605 error = -EFAULT;
606
607 return error;
608 }
609
610 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
611
612 asmlinkage long
613 sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
614 {
615 struct itimerval kin, kout;
616 int error;
617
618 if (in) {
619 if (get_it32(&kin, in))
620 return -EFAULT;
621 } else
622 memset(&kin, 0, sizeof(kin));
623
624 error = do_setitimer(which, &kin, out ? &kout : NULL);
625 if (error || !out)
626 return error;
627 if (put_it32(out, &kout))
628 return -EFAULT;
629
630 return 0;
631
632 }
633 asmlinkage unsigned long
634 sys32_alarm(unsigned int seconds)
635 {
636 struct itimerval it_new, it_old;
637 unsigned int oldalarm;
638
639 it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
640 it_new.it_value.tv_sec = seconds;
641 it_new.it_value.tv_usec = 0;
642 do_setitimer(ITIMER_REAL, &it_new, &it_old);
643 oldalarm = it_old.it_value.tv_sec;
644 /* ehhh.. We can't return 0 if we have an alarm pending.. */
645 /* And we'd better return too much than too little anyway */
646 if (it_old.it_value.tv_usec)
647 oldalarm++;
648 return oldalarm;
649 }
650
651 /* Translations due to time_t size differences. Which affects all
652 sorts of things, like timeval and itimerval. */
653
654 struct utimbuf_32 {
655 int atime;
656 int mtime;
657 };
658
659 extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
660 extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
661
662 asmlinkage long
663 ia32_utime(char * filename, struct utimbuf_32 *times32)
664 {
665 mm_segment_t old_fs = get_fs();
666 struct timeval tv[2], *tvp;
667 long ret;
668
669 if (times32) {
670 if (get_user(tv[0].tv_sec, ×32->atime))
671 return -EFAULT;
672 tv[0].tv_usec = 0;
673 if (get_user(tv[1].tv_sec, ×32->mtime))
674 return -EFAULT;
675 tv[1].tv_usec = 0;
676 set_fs (KERNEL_DS);
677 tvp = tv;
678 } else
679 tvp = NULL;
680 ret = sys_utimes(filename, tvp);
681 set_fs (old_fs);
682 return ret;
683 }
684
685 extern struct timezone sys_tz;
686 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
687
688 asmlinkage long
689 sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
690 {
691 if (tv) {
692 struct timeval ktv;
693 do_gettimeofday(&ktv);
694 if (put_tv32(tv, &ktv))
695 return -EFAULT;
696 }
697 if (tz) {
698 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
699 return -EFAULT;
700 }
701 return 0;
702 }
703
704 asmlinkage long
705 sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
706 {
707 struct timeval ktv;
708 struct timezone ktz;
709
710 if (tv) {
711 if (get_tv32(&ktv, tv))
712 return -EFAULT;
713 }
714 if (tz) {
715 if (copy_from_user(&ktz, tz, sizeof(ktz)))
716 return -EFAULT;
717 }
718
719 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
720 }
721
722 struct linux32_dirent {
723 u32 d_ino;
724 u32 d_off;
725 u16 d_reclen;
726 char d_name[1];
727 };
728
729 struct old_linux32_dirent {
730 u32 d_ino;
731 u32 d_offset;
732 u16 d_namlen;
733 char d_name[1];
734 };
735
736 struct getdents32_callback {
737 struct linux32_dirent * current_dir;
738 struct linux32_dirent * previous;
739 int count;
740 int error;
741 };
742
743 struct readdir32_callback {
744 struct old_linux32_dirent * dirent;
745 int count;
746 };
747
748 static int
749 filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
750 unsigned int d_type)
751 {
752 struct linux32_dirent * dirent;
753 struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
754 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
755
756 buf->error = -EINVAL; /* only used if we fail.. */
757 if (reclen > buf->count)
758 return -EINVAL;
759 buf->error = -EFAULT; /* only used if we fail.. */
760 dirent = buf->previous;
761 if (dirent)
762 if (put_user(offset, &dirent->d_off))
763 return -EFAULT;
764 dirent = buf->current_dir;
765 buf->previous = dirent;
766 if (put_user(ino, &dirent->d_ino)
767 || put_user(reclen, &dirent->d_reclen)
768 || copy_to_user(dirent->d_name, name, namlen)
769 || put_user(0, dirent->d_name + namlen))
770 return -EFAULT;
771 ((char *) dirent) += reclen;
772 buf->current_dir = dirent;
773 buf->count -= reclen;
774 return 0;
775 }
776
777 asmlinkage long
778 sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
779 {
780 struct file * file;
781 struct linux32_dirent * lastdirent;
782 struct getdents32_callback buf;
783 int error;
784
785 error = -EBADF;
786 file = fget(fd);
787 if (!file)
788 goto out;
789
790 buf.current_dir = (struct linux32_dirent *) dirent;
791 buf.previous = NULL;
792 buf.count = count;
793 buf.error = 0;
794
795 error = vfs_readdir(file, filldir32, &buf);
796 if (error < 0)
797 goto out_putf;
798 error = buf.error;
799 lastdirent = buf.previous;
800 if (lastdirent) {
801 error = -EINVAL;
802 if (put_user(file->f_pos, &lastdirent->d_off))
803 goto out_putf;
804 error = count - buf.count;
805 }
806
807 out_putf:
808 fput(file);
809 out:
810 return error;
811 }
812
813 static int
814 fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
815 unsigned int d_type)
816 {
817 struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
818 struct old_linux32_dirent * dirent;
819
820 if (buf->count)
821 return -EINVAL;
822 buf->count++;
823 dirent = buf->dirent;
824 if (put_user(ino, &dirent->d_ino)
825 || put_user(offset, &dirent->d_offset)
826 || put_user(namlen, &dirent->d_namlen)
827 || copy_to_user(dirent->d_name, name, namlen)
828 || put_user(0, dirent->d_name + namlen))
829 return -EFAULT;
830 return 0;
831 }
832
833 asmlinkage long
834 sys32_readdir (unsigned int fd, void * dirent, unsigned int count)
835 {
836 int error;
837 struct file * file;
838 struct readdir32_callback buf;
839
840 error = -EBADF;
841 file = fget(fd);
842 if (!file)
843 goto out;
844
845 buf.count = 0;
846 buf.dirent = dirent;
847
848 error = vfs_readdir(file, fillonedir32, &buf);
849 if (error >= 0)
850 error = buf.count;
851 fput(file);
852 out:
853 return error;
854 }
855
856 /*
857 * We can actually return ERESTARTSYS instead of EINTR, but I'd
858 * like to be certain this leads to no problems. So I return
859 * EINTR just for safety.
860 *
861 * Update: ERESTARTSYS breaks at least the xview clock binary, so
862 * I'm trying ERESTARTNOHAND which restart only when you want to.
863 */
864 #define MAX_SELECT_SECONDS \
865 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
866 #define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
867
868 asmlinkage long
869 sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32)
870 {
871 fd_set_bits fds;
872 char *bits;
873 long timeout;
874 int ret, size;
875
876 timeout = MAX_SCHEDULE_TIMEOUT;
877 if (tvp32) {
878 time_t sec, usec;
879
880 ret = -EFAULT;
881 if (get_user(sec, &tvp32->tv_sec)
882 || get_user(usec, &tvp32->tv_usec))
883 goto out_nofds;
884
885 ret = -EINVAL;
886 if (sec < 0 || usec < 0)
887 goto out_nofds;
888
889 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
890 timeout = ROUND_UP_TIME(usec, 1000000/HZ);
891 timeout += sec * (unsigned long) HZ;
892 }
893 }
894
895 ret = -EINVAL;
896 if (n < 0)
897 goto out_nofds;
898
899 if (n > current->files->max_fdset)
900 n = current->files->max_fdset;
901
902 /*
903 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
904 * since we used fdset we need to allocate memory in units of
905 * long-words.
906 */
907 ret = -ENOMEM;
908 size = FDS_BYTES(n);
909 bits = kmalloc(6 * size, GFP_KERNEL);
910 if (!bits)
911 goto out_nofds;
912 fds.in = (unsigned long *) bits;
913 fds.out = (unsigned long *) (bits + size);
914 fds.ex = (unsigned long *) (bits + 2*size);
915 fds.res_in = (unsigned long *) (bits + 3*size);
916 fds.res_out = (unsigned long *) (bits + 4*size);
917 fds.res_ex = (unsigned long *) (bits + 5*size);
918
919 if ((ret = get_fd_set(n, inp, fds.in)) ||
920 (ret = get_fd_set(n, outp, fds.out)) ||
921 (ret = get_fd_set(n, exp, fds.ex)))
922 goto out;
923 zero_fd_set(n, fds.res_in);
924 zero_fd_set(n, fds.res_out);
925 zero_fd_set(n, fds.res_ex);
926
927 ret = do_select(n, &fds, &timeout);
928
929 if (tvp32 && !(current->personality & STICKY_TIMEOUTS)) {
930 time_t sec = 0, usec = 0;
931 if (timeout) {
932 sec = timeout / HZ;
933 usec = timeout % HZ;
934 usec *= (1000000/HZ);
935 }
936 if (put_user(sec, (int *)&tvp32->tv_sec)
937 || put_user(usec, (int *)&tvp32->tv_usec))
938 {
939 ret = -EFAULT;
940 goto out;
941 }
942 }
943
944 if (ret < 0)
945 goto out;
946 if (!ret) {
947 ret = -ERESTARTNOHAND;
948 if (signal_pending(current))
949 goto out;
950 ret = 0;
951 }
952
953 set_fd_set(n, inp, fds.res_in);
954 set_fd_set(n, outp, fds.res_out);
955 set_fd_set(n, exp, fds.res_ex);
956
957 out:
958 kfree(bits);
959 out_nofds:
960 return ret;
961 }
962
963 struct sel_arg_struct {
964 unsigned int n;
965 unsigned int inp;
966 unsigned int outp;
967 unsigned int exp;
968 unsigned int tvp;
969 };
970
971 asmlinkage long
972 old_select(struct sel_arg_struct *arg)
973 {
974 struct sel_arg_struct a;
975
976 if (copy_from_user(&a, arg, sizeof(a)))
977 return -EFAULT;
978 return sys32_select(a.n, (fd_set *)A(a.inp), (fd_set *)A(a.outp), (fd_set *)A(a.exp),
979 (struct timeval32 *)A(a.tvp));
980 }
981
982 struct timespec32 {
983 int tv_sec;
984 int tv_nsec;
985 };
986
987 extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
988
989 asmlinkage long
990 sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
991 {
992 struct timespec t;
993 int ret;
994 mm_segment_t old_fs = get_fs ();
995
996 if (get_user (t.tv_sec, &rqtp->tv_sec) ||
997 __get_user (t.tv_nsec, &rqtp->tv_nsec))
998 return -EFAULT;
999 set_fs (KERNEL_DS);
1000 ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1001 set_fs (old_fs);
1002 if (rmtp && ret == -EINTR) {
1003 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1004 __put_user (t.tv_nsec, &rmtp->tv_nsec))
1005 return -EFAULT;
1006 }
1007 return ret;
1008 }
1009
1010 struct iovec32 { unsigned int iov_base; int iov_len; };
1011 asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
1012 asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
1013
1014 static struct iovec *
1015 get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
1016 {
1017 int i;
1018 u32 buf, len;
1019 struct iovec *ivp, *iov;
1020
1021 /* Get the "struct iovec" from user memory */
1022
1023 if (!count)
1024 return 0;
1025 if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
1026 return(struct iovec *)0;
1027 if (count > UIO_MAXIOV)
1028 return(struct iovec *)0;
1029 if (count > UIO_FASTIOV) {
1030 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1031 if (!iov)
1032 return((struct iovec *)0);
1033 } else
1034 iov = iov_buf;
1035
1036 ivp = iov;
1037 for (i = 0; i < count; i++) {
1038 if (__get_user(len, &iov32->iov_len) ||
1039 __get_user(buf, &iov32->iov_base)) {
1040 if (iov != iov_buf)
1041 kfree(iov);
1042 return((struct iovec *)0);
1043 }
1044 if (verify_area(type, (void *)A(buf), len)) {
1045 if (iov != iov_buf)
1046 kfree(iov);
1047 return((struct iovec *)0);
1048 }
1049 ivp->iov_base = (void *)A(buf);
1050 ivp->iov_len = (__kernel_size_t)len;
1051 iov32++;
1052 ivp++;
1053 }
1054 return(iov);
1055 }
1056
1057 asmlinkage long
1058 sys32_readv(int fd, struct iovec32 *vector, u32 count)
1059 {
1060 struct iovec iovstack[UIO_FASTIOV];
1061 struct iovec *iov;
1062 int ret;
1063 mm_segment_t old_fs = get_fs();
1064
1065 if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE)) == (struct iovec *)0)
1066 return -EFAULT;
1067 set_fs(KERNEL_DS);
1068 ret = sys_readv(fd, iov, count);
1069 set_fs(old_fs);
1070 if (iov != iovstack)
1071 kfree(iov);
1072 return ret;
1073 }
1074
1075 asmlinkage long
1076 sys32_writev(int fd, struct iovec32 *vector, u32 count)
1077 {
1078 struct iovec iovstack[UIO_FASTIOV];
1079 struct iovec *iov;
1080 int ret;
1081 mm_segment_t old_fs = get_fs();
1082
1083 if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ)) == (struct iovec *)0)
1084 return -EFAULT;
1085 set_fs(KERNEL_DS);
1086 ret = sys_writev(fd, iov, count);
1087 set_fs(old_fs);
1088 if (iov != iovstack)
1089 kfree(iov);
1090 return ret;
1091 }
1092
1093 #define RLIM_INFINITY32 0x7fffffff
1094 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
1095
1096 struct rlimit32 {
1097 int rlim_cur;
1098 int rlim_max;
1099 };
1100
1101 extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
1102
1103 asmlinkage long
1104 sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
1105 {
1106 struct rlimit r;
1107 int ret;
1108 mm_segment_t old_fs = get_fs ();
1109
1110 set_fs (KERNEL_DS);
1111 ret = sys_getrlimit(resource, &r);
1112 set_fs (old_fs);
1113 if (!ret) {
1114 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
1115 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
1116 }
1117 return ret;
1118 }
1119
1120 extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
1121
1122 asmlinkage long
1123 sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
1124 {
1125 struct rlimit r;
1126 int ret;
1127 mm_segment_t old_fs = get_fs ();
1128
1129 if (resource >= RLIM_NLIMITS) return -EINVAL;
1130 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
1131 __get_user (r.rlim_max, &rlim->rlim_max))
1132 return -EFAULT;
1133 if (r.rlim_cur == RLIM_INFINITY32)
1134 r.rlim_cur = RLIM_INFINITY;
1135 if (r.rlim_max == RLIM_INFINITY32)
1136 r.rlim_max = RLIM_INFINITY;
1137 set_fs (KERNEL_DS);
1138 ret = sys_setrlimit(resource, &r);
1139 set_fs (old_fs);
1140 return ret;
1141 }
1142
1143 /*
1144 * Declare the IA32 version of the msghdr
1145 */
1146
1147 struct msghdr32 {
1148 unsigned int msg_name; /* Socket name */
1149 int msg_namelen; /* Length of name */
1150 unsigned int msg_iov; /* Data blocks */
1151 unsigned int msg_iovlen; /* Number of blocks */
1152 unsigned int msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
1153 unsigned int msg_controllen; /* Length of cmsg list */
1154 unsigned msg_flags;
1155 };
1156
1157 static inline int
1158 shape_msg(struct msghdr *mp, struct msghdr32 *mp32)
1159 {
1160 int ret;
1161 unsigned int i;
1162
1163 if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32)))
1164 return(-EFAULT);
1165 ret = __get_user(i, &mp32->msg_name);
1166 mp->msg_name = (void *)A(i);
1167 ret |= __get_user(mp->msg_namelen, &mp32->msg_namelen);
1168 ret |= __get_user(i, &mp32->msg_iov);
1169 mp->msg_iov = (struct iovec *)A(i);
1170 ret |= __get_user(mp->msg_iovlen, &mp32->msg_iovlen);
1171 ret |= __get_user(i, &mp32->msg_control);
1172 mp->msg_control = (void *)A(i);
1173 ret |= __get_user(mp->msg_controllen, &mp32->msg_controllen);
1174 ret |= __get_user(mp->msg_flags, &mp32->msg_flags);
1175 return(ret ? -EFAULT : 0);
1176 }
1177
1178 /*
1179 * Verify & re-shape IA32 iovec. The caller must ensure that the
1180 * iovec is big enough to hold the re-shaped message iovec.
1181 *
1182 * Save time not doing verify_area. copy_*_user will make this work
1183 * in any case.
1184 *
1185 * Don't need to check the total size for overflow (cf net/core/iovec.c),
1186 * 32-bit sizes can't overflow a 64-bit count.
1187 */
1188
1189 static inline int
1190 verify_iovec32(struct msghdr *m, struct iovec *iov, char *address, int mode)
1191 {
1192 int size, err, ct;
1193 struct iovec32 *iov32;
1194
1195 if(m->msg_namelen)
1196 {
1197 if(mode==VERIFY_READ)
1198 {
1199 err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address);
1200 if(err<0)
1201 goto out;
1202 }
1203
1204 m->msg_name = address;
1205 } else
1206 m->msg_name = NULL;
1207
1208 err = -EFAULT;
1209 size = m->msg_iovlen * sizeof(struct iovec32);
1210 if (copy_from_user(iov, m->msg_iov, size))
1211 goto out;
1212 m->msg_iov=iov;
1213
1214 err = 0;
1215 iov32 = (struct iovec32 *)iov;
1216 for (ct = m->msg_iovlen; ct-- > 0; ) {
1217 iov[ct].iov_len = (__kernel_size_t)iov32[ct].iov_len;
1218 iov[ct].iov_base = (void *) A(iov32[ct].iov_base);
1219 err += iov[ct].iov_len;
1220 }
1221 out:
1222 return err;
1223 }
1224
1225 extern __inline__ void
1226 sockfd_put(struct socket *sock)
1227 {
1228 fput(sock->file);
1229 }
1230
1231 /* XXX This really belongs in some header file... -DaveM */
1232 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
1233 16 for IP, 16 for IPX,
1234 24 for IPv6,
1235 about 80 for AX.25 */
1236
1237 extern struct socket *sockfd_lookup(int fd, int *err);
1238
1239 /*
1240 * BSD sendmsg interface
1241 */
1242
1243 int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
1244 {
1245 struct socket *sock;
1246 char address[MAX_SOCK_ADDR];
1247 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
1248 unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */
1249 unsigned char *ctl_buf = ctl;
1250 struct msghdr msg_sys;
1251 int err, ctl_len, iov_size, total_len;
1252
1253 err = -EFAULT;
1254 if (shape_msg(&msg_sys, msg))
1255 goto out;
1256
1257 sock = sockfd_lookup(fd, &err);
1258 if (!sock)
1259 goto out;
1260
1261 /* do not move before msg_sys is valid */
1262 err = -EINVAL;
1263 if (msg_sys.msg_iovlen > UIO_MAXIOV)
1264 goto out_put;
1265
1266 /* Check whether to allocate the iovec area*/
1267 err = -ENOMEM;
1268 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32);
1269 if (msg_sys.msg_iovlen > UIO_FASTIOV) {
1270 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
1271 if (!iov)
1272 goto out_put;
1273 }
1274
1275 /* This will also move the address data into kernel space */
1276 err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
1277 if (err < 0)
1278 goto out_freeiov;
1279 total_len = err;
1280
1281 err = -ENOBUFS;
1282
1283 if (msg_sys.msg_controllen > INT_MAX)
1284 goto out_freeiov;
1285 ctl_len = msg_sys.msg_controllen;
1286 if (ctl_len)
1287 {
1288 if (ctl_len > sizeof(ctl))
1289 {
1290 err = -ENOBUFS;
1291 ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
1292 if (ctl_buf == NULL)
1293 goto out_freeiov;
1294 }
1295 err = -EFAULT;
1296 if (copy_from_user(ctl_buf, msg_sys.msg_control, ctl_len))
1297 goto out_freectl;
1298 msg_sys.msg_control = ctl_buf;
1299 }
1300 msg_sys.msg_flags = flags;
1301
1302 if (sock->file->f_flags & O_NONBLOCK)
1303 msg_sys.msg_flags |= MSG_DONTWAIT;
1304 err = sock_sendmsg(sock, &msg_sys, total_len);
1305
1306 out_freectl:
1307 if (ctl_buf != ctl)
1308 sock_kfree_s(sock->sk, ctl_buf, ctl_len);
1309 out_freeiov:
1310 if (iov != iovstack)
1311 sock_kfree_s(sock->sk, iov, iov_size);
1312 out_put:
1313 sockfd_put(sock);
1314 out:
1315 return err;
1316 }
1317
1318 /*
1319 * BSD recvmsg interface
1320 */
1321
1322 int
1323 sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
1324 {
1325 struct socket *sock;
1326 struct iovec iovstack[UIO_FASTIOV];
1327 struct iovec *iov=iovstack;
1328 struct msghdr msg_sys;
1329 unsigned long cmsg_ptr;
1330 int err, iov_size, total_len, len;
1331
1332 /* kernel mode address */
1333 char addr[MAX_SOCK_ADDR];
1334
1335 /* user mode address pointers */
1336 struct sockaddr *uaddr;
1337 int *uaddr_len;
1338
1339 err=-EFAULT;
1340 if (shape_msg(&msg_sys, msg))
1341 goto out;
1342
1343 sock = sockfd_lookup(fd, &err);
1344 if (!sock)
1345 goto out;
1346
1347 err = -EINVAL;
1348 if (msg_sys.msg_iovlen > UIO_MAXIOV)
1349 goto out_put;
1350
1351 /* Check whether to allocate the iovec area*/
1352 err = -ENOMEM;
1353 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
1354 if (msg_sys.msg_iovlen > UIO_FASTIOV) {
1355 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
1356 if (!iov)
1357 goto out_put;
1358 }
1359
1360 /*
1361 * Save the user-mode address (verify_iovec will change the
1362 * kernel msghdr to use the kernel address space)
1363 */
1364
1365 uaddr = msg_sys.msg_name;
1366 uaddr_len = &msg->msg_namelen;
1367 err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
1368 if (err < 0)
1369 goto out_freeiov;
1370 total_len=err;
1371
1372 cmsg_ptr = (unsigned long)msg_sys.msg_control;
1373 msg_sys.msg_flags = 0;
1374
1375 if (sock->file->f_flags & O_NONBLOCK)
1376 flags |= MSG_DONTWAIT;
1377 err = sock_recvmsg(sock, &msg_sys, total_len, flags);
1378 if (err < 0)
1379 goto out_freeiov;
1380 len = err;
1381
1382 if (uaddr != NULL) {
1383 err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
1384 if (err < 0)
1385 goto out_freeiov;
1386 }
1387 err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
1388 if (err)
1389 goto out_freeiov;
1390 err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
1391 &msg->msg_controllen);
1392 if (err)
1393 goto out_freeiov;
1394 err = len;
1395
1396 out_freeiov:
1397 if (iov != iovstack)
1398 sock_kfree_s(sock->sk, iov, iov_size);
1399 out_put:
1400 sockfd_put(sock);
1401 out:
1402 return err;
1403 }
1404
1405 /* Argument list sizes for sys_socketcall */
1406 #define AL(x) ((x) * sizeof(u32))
1407 static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
1408 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
1409 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
1410 #undef AL
1411
1412 extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
1413 extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,
1414 int addrlen);
1415 extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,
1416 int *upeer_addrlen);
1417 extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
1418 int *usockaddr_len);
1419 extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
1420 int *usockaddr_len);
1421 extern asmlinkage long sys_send(int fd, void *buff, size_t len, unsigned flags);
1422 extern asmlinkage long sys_sendto(int fd, u32 buff, __kernel_size_t32 len,
1423 unsigned flags, u32 addr, int addr_len);
1424 extern asmlinkage long sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
1425 extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
1426 unsigned flags, u32 addr, u32 addr_len);
1427 extern asmlinkage long sys_setsockopt(int fd, int level, int optname,
1428 char *optval, int optlen);
1429 extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
1430 u32 optval, u32 optlen);
1431
1432 extern asmlinkage long sys_socket(int family, int type, int protocol);
1433 extern asmlinkage long sys_socketpair(int family, int type, int protocol,
1434 int usockvec[2]);
1435 extern asmlinkage long sys_shutdown(int fd, int how);
1436 extern asmlinkage long sys_listen(int fd, int backlog);
1437
1438 asmlinkage long sys32_socketcall(int call, u32 *args)
1439 {
1440 int ret;
1441 u32 a[6];
1442 u32 a0,a1;
1443
1444 if (call<SYS_SOCKET||call>SYS_RECVMSG)
1445 return -EINVAL;
1446 if (copy_from_user(a, args, nas[call]))
1447 return -EFAULT;
1448 a0=a[0];
1449 a1=a[1];
1450
1451 switch(call)
1452 {
1453 case SYS_SOCKET:
1454 ret = sys_socket(a0, a1, a[2]);
1455 break;
1456 case SYS_BIND:
1457 ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
1458 break;
1459 case SYS_CONNECT:
1460 ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
1461 break;
1462 case SYS_LISTEN:
1463 ret = sys_listen(a0, a1);
1464 break;
1465 case SYS_ACCEPT:
1466 ret = sys_accept(a0, (struct sockaddr *)A(a1),
1467 (int *)A(a[2]));
1468 break;
1469 case SYS_GETSOCKNAME:
1470 ret = sys_getsockname(a0, (struct sockaddr *)A(a1),
1471 (int *)A(a[2]));
1472 break;
1473 case SYS_GETPEERNAME:
1474 ret = sys_getpeername(a0, (struct sockaddr *)A(a1),
1475 (int *)A(a[2]));
1476 break;
1477 case SYS_SOCKETPAIR:
1478 ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
1479 break;
1480 case SYS_SEND:
1481 ret = sys_send(a0, (void *)A(a1), a[2], a[3]);
1482 break;
1483 case SYS_SENDTO:
1484 ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);
1485 break;
1486 case SYS_RECV:
1487 ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);
1488 break;
1489 case SYS_RECVFROM:
1490 ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
1491 break;
1492 case SYS_SHUTDOWN:
1493 ret = sys_shutdown(a0,a1);
1494 break;
1495 case SYS_SETSOCKOPT:
1496 ret = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
1497 a[4]);
1498 break;
1499 case SYS_GETSOCKOPT:
1500 ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);
1501 break;
1502 case SYS_SENDMSG:
1503 ret = sys32_sendmsg(a0, (struct msghdr32 *)A(a1),
1504 a[2]);
1505 break;
1506 case SYS_RECVMSG:
1507 ret = sys32_recvmsg(a0, (struct msghdr32 *)A(a1),
1508 a[2]);
1509 break;
1510 default:
1511 ret = EINVAL;
1512 break;
1513 }
1514 return ret;
1515 }
1516
1517 /*
1518 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
1519 *
1520 * This is really horribly ugly.
1521 */
1522
1523 struct msgbuf32 { s32 mtype; char mtext[1]; };
1524
1525 struct ipc_perm32
1526 {
1527 key_t key;
1528 __kernel_uid_t32 uid;
1529 __kernel_gid_t32 gid;
1530 __kernel_uid_t32 cuid;
1531 __kernel_gid_t32 cgid;
1532 __kernel_mode_t32 mode;
1533 unsigned short seq;
1534 };
1535
1536 struct semid_ds32 {
1537 struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
1538 __kernel_time_t32 sem_otime; /* last semop time */
1539 __kernel_time_t32 sem_ctime; /* last change time */
1540 u32 sem_base; /* ptr to first semaphore in array */
1541 u32 sem_pending; /* pending operations to be processed */
1542 u32 sem_pending_last; /* last pending operation */
1543 u32 undo; /* undo requests on this array */
1544 unsigned short sem_nsems; /* no. of semaphores in array */
1545 };
1546
1547 struct msqid_ds32
1548 {
1549 struct ipc_perm32 msg_perm;
1550 u32 msg_first;
1551 u32 msg_last;
1552 __kernel_time_t32 msg_stime;
1553 __kernel_time_t32 msg_rtime;
1554 __kernel_time_t32 msg_ctime;
1555 u32 wwait;
1556 u32 rwait;
1557 unsigned short msg_cbytes;
1558 unsigned short msg_qnum;
1559 unsigned short msg_qbytes;
1560 __kernel_ipc_pid_t32 msg_lspid;
1561 __kernel_ipc_pid_t32 msg_lrpid;
1562 };
1563
1564 struct shmid_ds32 {
1565 struct ipc_perm32 shm_perm;
1566 int shm_segsz;
1567 __kernel_time_t32 shm_atime;
1568 __kernel_time_t32 shm_dtime;
1569 __kernel_time_t32 shm_ctime;
1570 __kernel_ipc_pid_t32 shm_cpid;
1571 __kernel_ipc_pid_t32 shm_lpid;
1572 unsigned short shm_nattch;
1573 };
1574
1575 #define IPCOP_MASK(__x) (1UL << (__x))
1576
1577 static int
1578 do_sys32_semctl(int first, int second, int third, void *uptr)
1579 {
1580 union semun fourth;
1581 u32 pad;
1582 int err = 0, err2;
1583 struct semid64_ds s;
1584 struct semid_ds32 *usp;
1585 mm_segment_t old_fs;
1586
1587 if (!uptr)
1588 return -EINVAL;
1589 if (get_user(pad, (u32 *)uptr))
1590 return -EFAULT;
1591 if(third == SETVAL)
1592 fourth.val = (int)pad;
1593 else
1594 fourth.__pad = (void *)A(pad);
1595 switch (third) {
1596
1597 case IPC_INFO:
1598 case IPC_RMID:
1599 case IPC_SET:
1600 case SEM_INFO:
1601 case GETVAL:
1602 case GETPID:
1603 case GETNCNT:
1604 case GETZCNT:
1605 case GETALL:
1606 case SETVAL:
1607 case SETALL:
1608 err = sys_semctl (first, second, third, fourth);
1609 break;
1610
1611 case IPC_STAT:
1612 case SEM_STAT:
1613 usp = (struct semid_ds32 *)A(pad);
1614 fourth.__pad = &s;
1615 old_fs = get_fs ();
1616 set_fs (KERNEL_DS);
1617 err = sys_semctl (first, second, third, fourth);
1618 set_fs (old_fs);
1619 err2 = put_user(s.sem_perm.key, &usp->sem_perm.key);
1620 err2 |= __put_user(s.sem_perm.uid, &usp->sem_perm.uid);
1621 err2 |= __put_user(s.sem_perm.gid, &usp->sem_perm.gid);
1622 err2 |= __put_user(s.sem_perm.cuid,
1623 &usp->sem_perm.cuid);
1624 err2 |= __put_user (s.sem_perm.cgid,
1625 &usp->sem_perm.cgid);
1626 err2 |= __put_user (s.sem_perm.mode,
1627 &usp->sem_perm.mode);
1628 err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
1629 err2 |= __put_user (s.sem_otime, &usp->sem_otime);
1630 err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
1631 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
1632 if (err2)
1633 err = -EFAULT;
1634 break;
1635
1636 }
1637
1638 return err;
1639 }
1640
1641 static int
1642 do_sys32_msgsnd (int first, int second, int third, void *uptr)
1643 {
1644 struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
1645 + 4, GFP_USER);
1646 struct msgbuf32 *up = (struct msgbuf32 *)uptr;
1647 mm_segment_t old_fs;
1648 int err;
1649
1650 if (!p)
1651 return -ENOMEM;
1652 err = get_user (p->mtype, &up->mtype);
1653 err |= __copy_from_user (p->mtext, &up->mtext, second);
1654 if (err)
1655 goto out;
1656 old_fs = get_fs ();
1657 set_fs (KERNEL_DS);
1658 err = sys_msgsnd (first, p, second, third);
1659 set_fs (old_fs);
1660 out:
1661 kfree (p);
1662 return err;
1663 }
1664
1665 static int
1666 do_sys32_msgrcv (int first, int second, int msgtyp, int third,
1667 int version, void *uptr)
1668 {
1669 struct msgbuf32 *up;
1670 struct msgbuf *p;
1671 mm_segment_t old_fs;
1672 int err;
1673
1674 if (!version) {
1675 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
1676 struct ipc_kludge ipck;
1677
1678 err = -EINVAL;
1679 if (!uptr)
1680 goto out;
1681 err = -EFAULT;
1682 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
1683 goto out;
1684 uptr = (void *)A(ipck.msgp);
1685 msgtyp = ipck.msgtyp;
1686 }
1687 err = -ENOMEM;
1688 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
1689 if (!p)
1690 goto out;
1691 old_fs = get_fs ();
1692 set_fs (KERNEL_DS);
1693 err = sys_msgrcv (first, p, second + 4, msgtyp, third);
1694 set_fs (old_fs);
1695 if (err < 0)
1696 goto free_then_out;
1697 up = (struct msgbuf32 *)uptr;
1698 if (put_user (p->mtype, &up->mtype) ||
1699 __copy_to_user (&up->mtext, p->mtext, err))
1700 err = -EFAULT;
1701 free_then_out:
1702 kfree (p);
1703 out:
1704 return err;
1705 }
1706
1707 static int
1708 do_sys32_msgctl (int first, int second, void *uptr)
1709 {
1710 int err = -EINVAL, err2;
1711 struct msqid_ds m;
1712 struct msqid64_ds m64;
1713 struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
1714 mm_segment_t old_fs;
1715
1716 switch (second) {
1717
1718 case IPC_INFO:
1719 case IPC_RMID:
1720 case MSG_INFO:
1721 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
1722 break;
1723
1724 case IPC_SET:
1725 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
1726 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
1727 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
1728 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
1729 if (err)
1730 break;
1731 old_fs = get_fs ();
1732 set_fs (KERNEL_DS);
1733 err = sys_msgctl (first, second, &m);
1734 set_fs (old_fs);
1735 break;
1736
1737 case IPC_STAT:
1738 case MSG_STAT:
1739 old_fs = get_fs ();
1740 set_fs (KERNEL_DS);
1741 err = sys_msgctl (first, second, (void *) &m64);
1742 set_fs (old_fs);
1743 err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
1744 err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
1745 err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid);
1746 err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid);
1747 err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid);
1748 err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode);
1749 err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq);
1750 err2 |= __put_user(m64.msg_stime, &up->msg_stime);
1751 err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);
1752 err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);
1753 err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);
1754 err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);
1755 err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);
1756 err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);
1757 err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);
1758 if (err2)
1759 err = -EFAULT;
1760 break;
1761
1762 }
1763
1764 return err;
1765 }
1766
1767 static int
1768 do_sys32_shmat (int first, int second, int third, int version, void *uptr)
1769 {
1770 unsigned long raddr;
1771 u32 *uaddr = (u32 *)A((u32)third);
1772 int err;
1773
1774 if (version == 1)
1775 return -EINVAL;
1776 err = sys_shmat (first, uptr, second, &raddr);
1777 if (err)
1778 return err;
1779 return put_user(raddr, uaddr);
1780 }
1781
1782 static int
1783 do_sys32_shmctl (int first, int second, void *uptr)
1784 {
1785 int err = -EFAULT, err2;
1786 struct shmid_ds s;
1787 struct shmid64_ds s64;
1788 struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
1789 mm_segment_t old_fs;
1790 struct shm_info32 {
1791 int used_ids;
1792 u32 shm_tot, shm_rss, shm_swp;
1793 u32 swap_attempts, swap_successes;
1794 } *uip = (struct shm_info32 *)uptr;
1795 struct shm_info si;
1796
1797 switch (second) {
1798
1799 case IPC_INFO:
1800 case IPC_RMID:
1801 case SHM_LOCK:
1802 case SHM_UNLOCK:
1803 err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
1804 break;
1805 case IPC_SET:
1806 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
1807 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
1808 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
1809 if (err)
1810 break;
1811 old_fs = get_fs ();
1812 set_fs (KERNEL_DS);
1813 err = sys_shmctl (first, second, &s);
1814 set_fs (old_fs);
1815 break;
1816
1817 case IPC_STAT:
1818 case SHM_STAT:
1819 old_fs = get_fs ();
1820 set_fs (KERNEL_DS);
1821 err = sys_shmctl (first, second, (void *) &s64);
1822 set_fs (old_fs);
1823 if (err < 0)
1824 break;
1825 err2 = put_user (s64.shm_perm.key, &up->shm_perm.key);
1826 err2 |= __put_user (s64.shm_perm.uid, &up->shm_perm.uid);
1827 err2 |= __put_user (s64.shm_perm.gid, &up->shm_perm.gid);
1828 err2 |= __put_user (s64.shm_perm.cuid,
1829 &up->shm_perm.cuid);
1830 err2 |= __put_user (s64.shm_perm.cgid,
1831 &up->shm_perm.cgid);
1832 err2 |= __put_user (s64.shm_perm.mode,
1833 &up->shm_perm.mode);
1834 err2 |= __put_user (s64.shm_perm.seq, &up->shm_perm.seq);
1835 err2 |= __put_user (s64.shm_atime, &up->shm_atime);
1836 err2 |= __put_user (s64.shm_dtime, &up->shm_dtime);
1837 err2 |= __put_user (s64.shm_ctime, &up->shm_ctime);
1838 err2 |= __put_user (s64.shm_segsz, &up->shm_segsz);
1839 err2 |= __put_user (s64.shm_nattch, &up->shm_nattch);
1840 err2 |= __put_user (s64.shm_cpid, &up->shm_cpid);
1841 err2 |= __put_user (s64.shm_lpid, &up->shm_lpid);
1842 if (err2)
1843 err = -EFAULT;
1844 break;
1845
1846 case SHM_INFO:
1847 old_fs = get_fs ();
1848 set_fs (KERNEL_DS);
1849 err = sys_shmctl (first, second, (void *)&si);
1850 set_fs (old_fs);
1851 if (err < 0)
1852 break;
1853 err2 = put_user (si.used_ids, &uip->used_ids);
1854 err2 |= __put_user (si.shm_tot, &uip->shm_tot);
1855 err2 |= __put_user (si.shm_rss, &uip->shm_rss);
1856 err2 |= __put_user (si.shm_swp, &uip->shm_swp);
1857 err2 |= __put_user (si.swap_attempts,
1858 &uip->swap_attempts);
1859 err2 |= __put_user (si.swap_successes,
1860 &uip->swap_successes);
1861 if (err2)
1862 err = -EFAULT;
1863 break;
1864
1865 }
1866 return err;
1867 }
1868
1869 asmlinkage long
1870 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
1871 {
1872 int version, err;
1873
1874 version = call >> 16; /* hack for backward compatibility */
1875 call &= 0xffff;
1876
1877 switch (call) {
1878
1879 case SEMOP:
1880 /* struct sembuf is the same on 32 and 64bit :)) */
1881 err = sys_semop (first, (struct sembuf *)AA(ptr),
1882 second);
1883 break;
1884 case SEMGET:
1885 err = sys_semget (first, second, third);
1886 break;
1887 case SEMCTL:
1888 err = do_sys32_semctl (first, second, third,
1889 (void *)AA(ptr));
1890 break;
1891
1892 case MSGSND:
1893 err = do_sys32_msgsnd (first, second, third,
1894 (void *)AA(ptr));
1895 break;
1896 case MSGRCV:
1897 err = do_sys32_msgrcv (first, second, fifth, third,
1898 version, (void *)AA(ptr));
1899 break;
1900 case MSGGET:
1901 err = sys_msgget ((key_t) first, second);
1902 break;
1903 case MSGCTL:
1904 err = do_sys32_msgctl (first, second, (void *)AA(ptr));
1905 break;
1906
1907 case SHMAT:
1908 err = do_sys32_shmat (first, second, third, version, (void *)AA(ptr));
1909 break;
1910 case SHMDT:
1911 err = sys_shmdt ((char *)AA(ptr));
1912 break;
1913 case SHMGET:
1914 err = sys_shmget (first, second, third);
1915 break;
1916 case SHMCTL:
1917 err = do_sys32_shmctl (first, second, (void *)AA(ptr));
1918 break;
1919 default:
1920 err = -EINVAL;
1921 break;
1922 }
1923
1924 return err;
1925 }
1926
1927 /*
1928 * sys_time() can be implemented in user-level using
1929 * sys_gettimeofday(). IA64 did this but i386 Linux did not
1930 * so we have to implement this system call here.
1931 */
1932 asmlinkage long sys32_time(int * tloc)
1933 {
1934 int i;
1935
1936 /* SMP: This is fairly trivial. We grab CURRENT_TIME and
1937 stuff it to user space. No side effects */
1938 i = CURRENT_TIME;
1939 if (tloc) {
1940 if (put_user(i,tloc))
1941 i = -EFAULT;
1942 }
1943 return i;
1944 }
1945
1946 struct rusage32 {
1947 struct timeval32 ru_utime;
1948 struct timeval32 ru_stime;
1949 int ru_maxrss;
1950 int ru_ixrss;
1951 int ru_idrss;
1952 int ru_isrss;
1953 int ru_minflt;
1954 int ru_majflt;
1955 int ru_nswap;
1956 int ru_inblock;
1957 int ru_oublock;
1958 int ru_msgsnd;
1959 int ru_msgrcv;
1960 int ru_nsignals;
1961 int ru_nvcsw;
1962 int ru_nivcsw;
1963 };
1964
1965 static int
1966 put_rusage (struct rusage32 *ru, struct rusage *r)
1967 {
1968 int err;
1969
1970 err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1971 err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1972 err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1973 err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1974 err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1975 err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1976 err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1977 err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1978 err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1979 err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1980 err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1981 err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1982 err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1983 err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1984 err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1985 err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1986 err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1987 err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1988 return err;
1989 }
1990
1991 asmlinkage long
1992 sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
1993 struct rusage32 *ru)
1994 {
1995 if (!ru)
1996 return sys_wait4(pid, stat_addr, options, NULL);
1997 else {
1998 struct rusage r;
1999 int ret;
2000 unsigned int status;
2001 mm_segment_t old_fs = get_fs();
2002
2003 set_fs (KERNEL_DS);
2004 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
2005 set_fs (old_fs);
2006 if (put_rusage (ru, &r)) return -EFAULT;
2007 if (stat_addr && put_user (status, stat_addr))
2008 return -EFAULT;
2009 return ret;
2010 }
2011 }
2012
2013 asmlinkage long
2014 sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
2015 {
2016 return sys32_wait4(pid, stat_addr, options, NULL);
2017 }
2018
2019
2020 extern asmlinkage long
2021 sys_getrusage(int who, struct rusage *ru);
2022
2023 asmlinkage long
2024 sys32_getrusage(int who, struct rusage32 *ru)
2025 {
2026 struct rusage r;
2027 int ret;
2028 mm_segment_t old_fs = get_fs();
2029
2030 set_fs (KERNEL_DS);
2031 ret = sys_getrusage(who, &r);
2032 set_fs (old_fs);
2033 if (put_rusage (ru, &r)) return -EFAULT;
2034 return ret;
2035 }
2036
2037 struct tms32 {
2038 __kernel_clock_t32 tms_utime;
2039 __kernel_clock_t32 tms_stime;
2040 __kernel_clock_t32 tms_cutime;
2041 __kernel_clock_t32 tms_cstime;
2042 };
2043
2044 extern asmlinkage long sys_times(struct tms * tbuf);
2045
2046 asmlinkage long
2047 sys32_times(struct tms32 *tbuf)
2048 {
2049 struct tms t;
2050 long ret;
2051 mm_segment_t old_fs = get_fs ();
2052 int err;
2053
2054 set_fs (KERNEL_DS);
2055 ret = sys_times(tbuf ? &t : NULL);
2056 set_fs (old_fs);
2057 if (tbuf) {
2058 err = put_user (IA32_TICK(t.tms_utime), &tbuf->tms_utime);
2059 err |= __put_user (IA32_TICK(t.tms_stime), &tbuf->tms_stime);
2060 err |= __put_user (IA32_TICK(t.tms_cutime), &tbuf->tms_cutime);
2061 err |= __put_user (IA32_TICK(t.tms_cstime), &tbuf->tms_cstime);
2062 if (err)
2063 ret = -EFAULT;
2064 }
2065 return IA32_TICK(ret);
2066 }
2067
2068 unsigned int
2069 ia32_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int *val)
2070 {
2071 size_t copied;
2072 unsigned int ret;
2073
2074 copied = access_process_vm(child, addr, val, sizeof(*val), 0);
2075 return(copied != sizeof(ret) ? -EIO : 0);
2076 }
2077
2078 unsigned int
2079 ia32_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int val)
2080 {
2081
2082 if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
2083 return -EIO;
2084 return 0;
2085 }
2086
2087 /*
2088 * The order in which registers are stored in the ptrace regs structure
2089 */
2090 #define PT_EBX 0
2091 #define PT_ECX 1
2092 #define PT_EDX 2
2093 #define PT_ESI 3
2094 #define PT_EDI 4
2095 #define PT_EBP 5
2096 #define PT_EAX 6
2097 #define PT_DS 7
2098 #define PT_ES 8
2099 #define PT_FS 9
2100 #define PT_GS 10
2101 #define PT_ORIG_EAX 11
2102 #define PT_EIP 12
2103 #define PT_CS 13
2104 #define PT_EFL 14
2105 #define PT_UESP 15
2106 #define PT_SS 16
2107
2108 unsigned int
2109 getreg(struct task_struct *child, int regno)
2110 {
2111 struct pt_regs *child_regs;
2112
2113 child_regs = ia64_task_regs(child);
2114 switch (regno / sizeof(int)) {
2115
2116 case PT_EBX:
2117 return(child_regs->r11);
2118 case PT_ECX:
2119 return(child_regs->r9);
2120 case PT_EDX:
2121 return(child_regs->r10);
2122 case PT_ESI:
2123 return(child_regs->r14);
2124 case PT_EDI:
2125 return(child_regs->r15);
2126 case PT_EBP:
2127 return(child_regs->r13);
2128 case PT_EAX:
2129 case PT_ORIG_EAX:
2130 return(child_regs->r8);
2131 case PT_EIP:
2132 return(child_regs->cr_iip);
2133 case PT_UESP:
2134 return(child_regs->r12);
2135 case PT_EFL:
2136 return(child->thread.eflag);
2137 case PT_DS:
2138 case PT_ES:
2139 case PT_FS:
2140 case PT_GS:
2141 case PT_SS:
2142 return((unsigned int)__USER_DS);
2143 case PT_CS:
2144 return((unsigned int)__USER_CS);
2145 default:
2146 printk(KERN_ERR "getregs:unknown register %d\n", regno);
2147 break;
2148
2149 }
2150 return(0);
2151 }
2152
2153 void
2154 putreg(struct task_struct *child, int regno, unsigned int value)
2155 {
2156 struct pt_regs *child_regs;
2157
2158 child_regs = ia64_task_regs(child);
2159 switch (regno / sizeof(int)) {
2160
2161 case PT_EBX:
2162 child_regs->r11 = value;
2163 break;
2164 case PT_ECX:
2165 child_regs->r9 = value;
2166 break;
2167 case PT_EDX:
2168 child_regs->r10 = value;
2169 break;
2170 case PT_ESI:
2171 child_regs->r14 = value;
2172 break;
2173 case PT_EDI:
2174 child_regs->r15 = value;
2175 break;
2176 case PT_EBP:
2177 child_regs->r13 = value;
2178 break;
2179 case PT_EAX:
2180 case PT_ORIG_EAX:
2181 child_regs->r8 = value;
2182 break;
2183 case PT_EIP:
2184 child_regs->cr_iip = value;
2185 break;
2186 case PT_UESP:
2187 child_regs->r12 = value;
2188 break;
2189 case PT_EFL:
2190 child->thread.eflag = value;
2191 break;
2192 case PT_DS:
2193 case PT_ES:
2194 case PT_FS:
2195 case PT_GS:
2196 case PT_SS:
2197 if (value != __USER_DS)
2198 printk(KERN_ERR "setregs:try to set invalid segment register %d = %x\n",
2199 regno, value);
2200 break;
2201 case PT_CS:
2202 if (value != __USER_CS)
2203 printk(KERN_ERR "setregs:try to set invalid segment register %d = %x\n",
2204 regno, value);
2205 break;
2206 default:
2207 printk(KERN_ERR "getregs:unknown register %d\n", regno);
2208 break;
2209
2210 }
2211 }
2212
2213 static inline void
2214 ia32f2ia64f(void *dst, void *src)
2215 {
2216
2217 __asm__ ("ldfe f6=[%1] ;;\n\t"
2218 "stf.spill [%0]=f6"
2219 :
2220 : "r"(dst), "r"(src));
2221 return;
2222 }
2223
2224 static inline void
2225 ia64f2ia32f(void *dst, void *src)
2226 {
2227
2228 __asm__ ("ldf.fill f6=[%1] ;;\n\t"
2229 "stfe [%0]=f6"
2230 :
2231 : "r"(dst), "r"(src));
2232 return;
2233 }
2234
2235 void
2236 put_fpreg(int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp, int tos)
2237 {
2238 struct _fpreg_ia32 *f;
2239 char buf[32];
2240
2241 f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
2242 if ((regno += tos) >= 8)
2243 regno -= 8;
2244 switch (regno) {
2245
2246 case 0:
2247 ia64f2ia32f(f, &ptp->f8);
2248 break;
2249 case 1:
2250 ia64f2ia32f(f, &ptp->f9);
2251 break;
2252 case 2:
2253 case 3:
2254 case 4:
2255 case 5:
2256 case 6:
2257 case 7:
2258 ia64f2ia32f(f, &swp->f10 + (regno - 2));
2259 break;
2260
2261 }
2262 __copy_to_user(reg, f, sizeof(*reg));
2263 }
2264
2265 void
2266 get_fpreg(int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp, int tos)
2267 {
2268
2269 if ((regno += tos) >= 8)
2270 regno -= 8;
2271 switch (regno) {
2272
2273 case 0:
2274 __copy_from_user(&ptp->f8, reg, sizeof(*reg));
2275 break;
2276 case 1:
2277 __copy_from_user(&ptp->f9, reg, sizeof(*reg));
2278 break;
2279 case 2:
2280 case 3:
2281 case 4:
2282 case 5:
2283 case 6:
2284 case 7:
2285 __copy_from_user(&swp->f10 + (regno - 2), reg, sizeof(*reg));
2286 break;
2287
2288 }
2289 return;
2290 }
2291
2292 int
2293 save_ia32_fpstate(struct task_struct *tsk, struct _fpstate_ia32 *save)
2294 {
2295 struct switch_stack *swp;
2296 struct pt_regs *ptp;
2297 int i, tos;
2298
2299 if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
2300 return(-EIO);
2301 __put_user(tsk->thread.fcr, &save->cw);
2302 __put_user(tsk->thread.fsr, &save->sw);
2303 __put_user(tsk->thread.fsr >> 32, &save->tag);
2304 __put_user(tsk->thread.fir, &save->ipoff);
2305 __put_user(__USER_CS, &save->cssel);
2306 __put_user(tsk->thread.fdr, &save->dataoff);
2307 __put_user(__USER_DS, &save->datasel);
2308 /*
2309 * Stack frames start with 16-bytes of temp space
2310 */
2311 swp = (struct switch_stack *)(tsk->thread.ksp + 16);
2312 ptp = ia64_task_regs(tsk);
2313 tos = (tsk->thread.fsr >> 11) & 3;
2314 for (i = 0; i < 8; i++)
2315 put_fpreg(i, &save->_st[i], ptp, swp, tos);
2316 return(0);
2317 }
2318
2319 int
2320 restore_ia32_fpstate(struct task_struct *tsk, struct _fpstate_ia32 *save)
2321 {
2322 struct switch_stack *swp;
2323 struct pt_regs *ptp;
2324 int i, tos, ret;
2325 int fsrlo, fsrhi;
2326
2327 if (!access_ok(VERIFY_READ, save, sizeof(*save)))
2328 return(-EIO);
2329 ret = __get_user(tsk->thread.fcr, (unsigned int *)&save->cw);
2330 ret |= __get_user(fsrlo, (unsigned int *)&save->sw);
2331 ret |= __get_user(fsrhi, (unsigned int *)&save->tag);
2332 tsk->thread.fsr = ((long)fsrhi << 32) | (long)fsrlo;
2333 ret |= __get_user(tsk->thread.fir, (unsigned int *)&save->ipoff);
2334 ret |= __get_user(tsk->thread.fdr, (unsigned int *)&save->dataoff);
2335 /*
2336 * Stack frames start with 16-bytes of temp space
2337 */
2338 swp = (struct switch_stack *)(tsk->thread.ksp + 16);
2339 ptp = ia64_task_regs(tsk);
2340 tos = (tsk->thread.fsr >> 11) & 3;
2341 for (i = 0; i < 8; i++)
2342 get_fpreg(i, &save->_st[i], ptp, swp, tos);
2343 return(ret ? -EFAULT : 0);
2344 }
2345
2346 asmlinkage long sys_ptrace(long, pid_t, unsigned long, unsigned long, long, long, long, long, long);
2347
2348 /*
2349 * Note that the IA32 version of `ptrace' calls the IA64 routine for
2350 * many of the requests. This will only work for requests that do
2351 * not need access to the calling processes `pt_regs' which is located
2352 * at the address of `stack'. Once we call the IA64 `sys_ptrace' then
2353 * the address of `stack' will not be the address of the `pt_regs'.
2354 */
2355 asmlinkage long
2356 sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
2357 long arg4, long arg5, long arg6, long arg7, long stack)
2358 {
2359 struct pt_regs *regs = (struct pt_regs *) &stack;
2360 struct task_struct *child;
2361 long i, ret;
2362 unsigned int value;
2363
2364 lock_kernel();
2365 if (request == PTRACE_TRACEME) {
2366 ret = sys_ptrace(request, pid, addr, data,
2367 arg4, arg5, arg6, arg7, stack);
2368 goto out;
2369 }
2370
2371 ret = -ESRCH;
2372 read_lock(&tasklist_lock);
2373 child = find_task_by_pid(pid);
2374 read_unlock(&tasklist_lock);
2375 if (!child)
2376 goto out;
2377 ret = -EPERM;
2378 if (pid == 1) /* no messing around with init! */
2379 goto out;
2380
2381 if (request == PTRACE_ATTACH) {
2382 ret = sys_ptrace(request, pid, addr, data,
2383 arg4, arg5, arg6, arg7, stack);
2384 goto out;
2385 }
2386 ret = -ESRCH;
2387 if (!(child->ptrace & PT_PTRACED))
2388 goto out;
2389 if (child->state != TASK_STOPPED) {
2390 if (request != PTRACE_KILL)
2391 goto out;
2392 }
2393 if (child->p_pptr != current)
2394 goto out;
2395
2396 switch (request) {
2397 case PTRACE_PEEKTEXT:
2398 case PTRACE_PEEKDATA: /* read word at location addr */
2399 ret = ia32_peek(regs, child, addr, &value);
2400 if (ret == 0)
2401 ret = put_user(value, (unsigned int *)A(data));
2402 else
2403 ret = -EIO;
2404 goto out;
2405
2406 case PTRACE_POKETEXT:
2407 case PTRACE_POKEDATA: /* write the word at location addr */
2408 ret = ia32_poke(regs, child, addr, (unsigned int)data);
2409 goto out;
2410
2411 case PTRACE_PEEKUSR: /* read word at addr in USER area */
2412 ret = 0;
2413 break;
2414
2415 case PTRACE_POKEUSR: /* write word at addr in USER area */
2416 ret = 0;
2417 break;
2418
2419 case IA32_PTRACE_GETREGS:
2420 if (!access_ok(VERIFY_WRITE, (int *) A(data), 17*sizeof(int))) {
2421 ret = -EIO;
2422 break;
2423 }
2424 for ( i = 0; i < 17*sizeof(int); i += sizeof(int) ) {
2425 __put_user(getreg(child, i), (unsigned int *) A(data));
2426 data += sizeof(int);
2427 }
2428 ret = 0;
2429 break;
2430
2431 case IA32_PTRACE_SETREGS:
2432 {
2433 unsigned int tmp;
2434 if (!access_ok(VERIFY_READ, (int *) A(data), 17*sizeof(int))) {
2435 ret = -EIO;
2436 break;
2437 }
2438 for ( i = 0; i < 17*sizeof(int); i += sizeof(int) ) {
2439 __get_user(tmp, (unsigned int *) A(data));
2440 putreg(child, i, tmp);
2441 data += sizeof(int);
2442 }
2443 ret = 0;
2444 break;
2445 }
2446
2447 case IA32_PTRACE_GETFPREGS:
2448 ret = save_ia32_fpstate(child, (struct _fpstate_ia32 *) A(data));
2449 break;
2450
2451 case IA32_PTRACE_SETFPREGS:
2452 ret = restore_ia32_fpstate(child, (struct _fpstate_ia32 *) A(data));
2453 break;
2454
2455 case PTRACE_SYSCALL: /* continue, stop after next syscall */
2456 case PTRACE_CONT: /* restart after signal. */
2457 case PTRACE_KILL:
2458 case PTRACE_SINGLESTEP: /* execute chile for one instruction */
2459 case PTRACE_DETACH: /* detach a process */
2460 unlock_kernel();
2461 ret = sys_ptrace(request, pid, addr, data,
2462 arg4, arg5, arg6, arg7, stack);
2463 return(ret);
2464
2465 default:
2466 ret = -EIO;
2467 break;
2468
2469 }
2470 out:
2471 unlock_kernel();
2472 return ret;
2473 }
2474
2475 static inline int
2476 get_flock32(struct flock *kfl, struct flock32 *ufl)
2477 {
2478 int err;
2479
2480 err = get_user(kfl->l_type, &ufl->l_type);
2481 err |= __get_user(kfl->l_whence, &ufl->l_whence);
2482 err |= __get_user(kfl->l_start, &ufl->l_start);
2483 err |= __get_user(kfl->l_len, &ufl->l_len);
2484 err |= __get_user(kfl->l_pid, &ufl->l_pid);
2485 return err;
2486 }
2487
2488 static inline int
2489 put_flock32(struct flock *kfl, struct flock32 *ufl)
2490 {
2491 int err;
2492
2493 err = __put_user(kfl->l_type, &ufl->l_type);
2494 err |= __put_user(kfl->l_whence, &ufl->l_whence);
2495 err |= __put_user(kfl->l_start, &ufl->l_start);
2496 err |= __put_user(kfl->l_len, &ufl->l_len);
2497 err |= __put_user(kfl->l_pid, &ufl->l_pid);
2498 return err;
2499 }
2500
2501 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd,
2502 unsigned long arg);
2503
2504 asmlinkage long
2505 sys32_fcntl(unsigned int fd, unsigned int cmd, int arg)
2506 {
2507 struct flock f;
2508 mm_segment_t old_fs;
2509 long ret;
2510
2511 switch (cmd) {
2512 case F_GETLK:
2513 case F_SETLK:
2514 case F_SETLKW:
2515 if(get_flock32(&f, (struct flock32 *)((long)arg)))
2516 return -EFAULT;
2517 old_fs = get_fs();
2518 set_fs(KERNEL_DS);
2519 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
2520 set_fs(old_fs);
2521 if(cmd == F_GETLK && put_flock32(&f, (struct flock32 *)((long)arg)))
2522 return -EFAULT;
2523 return ret;
2524 default:
2525 /*
2526 * `sys_fcntl' lies about arg, for the F_SETOWN
2527 * sub-function arg can have a negative value.
2528 */
2529 return sys_fcntl(fd, cmd, (unsigned long)((long)arg));
2530 }
2531 }
2532
2533 asmlinkage long
2534 sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2535 {
2536 struct k_sigaction new_ka, old_ka;
2537 int ret;
2538
2539 if (act) {
2540 old_sigset32_t mask;
2541
2542 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2543 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2544 ret |= __get_user(mask, &act->sa_mask);
2545 if (ret)
2546 return ret;
2547 siginitset(&new_ka.sa.sa_mask, mask);
2548 }
2549
2550 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2551
2552 if (!ret && oact) {
2553 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2554 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2555 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2556 }
2557
2558 return ret;
2559 }
2560
2561 asmlinkage long sys_ni_syscall(void);
2562
2563 asmlinkage long
2564 sys32_ni_syscall(int dummy0, int dummy1, int dummy2, int dummy3,
2565 int dummy4, int dummy5, int dummy6, int dummy7, int stack)
2566 {
2567 struct pt_regs *regs = (struct pt_regs *)&stack;
2568
2569 printk(KERN_WARNING "IA32 syscall #%d issued, maybe we should implement it\n",
2570 (int)regs->r1);
2571 return(sys_ni_syscall());
2572 }
2573
2574 /*
2575 * The IA64 maps 4 I/O ports for each 4K page
2576 */
2577 #define IOLEN ((65536 / 4) * 4096)
2578
2579 asmlinkage long
2580 sys_iopl (int level)
2581 {
2582 extern unsigned long ia64_iobase;
2583 int fd;
2584 struct file * file;
2585 unsigned int old;
2586 unsigned long addr;
2587 mm_segment_t old_fs = get_fs ();
2588
2589 if (level != 3)
2590 return(-EINVAL);
2591 /* Trying to gain more privileges? */
2592 asm volatile ("mov %0=ar.eflag ;;" : "=r"(old));
2593 if (level > ((old >> 12) & 3)) {
2594 if (!capable(CAP_SYS_RAWIO))
2595 return -EPERM;
2596 }
2597 set_fs(KERNEL_DS);
2598 fd = sys_open("/dev/mem", O_SYNC | O_RDWR, 0);
2599 set_fs(old_fs);
2600 if (fd < 0)
2601 return fd;
2602 file = fget(fd);
2603 if (file == NULL) {
2604 sys_close(fd);
2605 return(-EFAULT);
2606 }
2607
2608 down_write(¤t->mm->mmap_sem);
2609 addr = do_mmap_pgoff(file, IA32_IOBASE,
2610 IOLEN, PROT_READ|PROT_WRITE, MAP_SHARED,
2611 (ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT);
2612 up_write(¤t->mm->mmap_sem);
2613
2614 if (addr >= 0) {
2615 ia64_set_kr(IA64_KR_IO_BASE, addr);
2616 old = (old & ~0x3000) | (level << 12);
2617 __asm__ __volatile__("mov ar.eflag=%0 ;;" :: "r"(old));
2618 }
2619
2620 fput(file);
2621 sys_close(fd);
2622 return 0;
2623 }
2624
2625 asmlinkage long
2626 sys_ioperm (unsigned int from, unsigned int num, int on)
2627 {
2628
2629 /*
2630 * Since IA64 doesn't have permission bits we'd have to go to
2631 * a lot of trouble to simulate them in software. There's
2632 * no point, only trusted programs can make this call so we'll
2633 * just turn it into an iopl call and let the process have
2634 * access to all I/O ports.
2635 *
2636 * XXX proper ioperm() support should be emulated by
2637 * manipulating the page protections...
2638 */
2639 return sys_iopl(3);
2640 }
2641
2642 typedef struct {
2643 unsigned int ss_sp;
2644 unsigned int ss_flags;
2645 unsigned int ss_size;
2646 } ia32_stack_t;
2647
2648 asmlinkage long
2649 sys32_sigaltstack (const ia32_stack_t *uss32, ia32_stack_t *uoss32,
2650 long arg2, long arg3, long arg4,
2651 long arg5, long arg6, long arg7,
2652 long stack)
2653 {
2654 struct pt_regs *pt = (struct pt_regs *) &stack;
2655 stack_t uss, uoss;
2656 ia32_stack_t buf32;
2657 int ret;
2658 mm_segment_t old_fs = get_fs();
2659
2660 if (uss32)
2661 if (copy_from_user(&buf32, (void *)A(uss32), sizeof(ia32_stack_t)))
2662 return(-EFAULT);
2663 uss.ss_sp = (void *) (long) buf32.ss_sp;
2664 uss.ss_flags = buf32.ss_flags;
2665 uss.ss_size = buf32.ss_size;
2666 set_fs(KERNEL_DS);
2667 ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12);
2668 set_fs(old_fs);
2669 if (ret < 0)
2670 return(ret);
2671 if (uoss32) {
2672 buf32.ss_sp = (long) uoss.ss_sp;
2673 buf32.ss_flags = uoss.ss_flags;
2674 buf32.ss_size = uoss.ss_size;
2675 if (copy_to_user((void*)A(uoss32), &buf32, sizeof(ia32_stack_t)))
2676 return(-EFAULT);
2677 }
2678 return(ret);
2679 }
2680
2681 asmlinkage int
2682 sys_pause (void)
2683 {
2684 current->state = TASK_INTERRUPTIBLE;
2685 schedule();
2686 return -ERESTARTNOHAND;
2687 }
2688
2689 asmlinkage long sys_msync(unsigned long start, size_t len, int flags);
2690
2691 asmlinkage int
2692 sys32_msync(unsigned int start, unsigned int len, int flags)
2693 {
2694 unsigned int addr;
2695
2696 if (OFFSET4K(start))
2697 return -EINVAL;
2698 addr = start & PAGE_MASK;
2699 return(sys_msync(addr, len + (start - addr), flags));
2700 }
2701
2702 struct sysctl_ia32 {
2703 unsigned int name;
2704 int nlen;
2705 unsigned int oldval;
2706 unsigned int oldlenp;
2707 unsigned int newval;
2708 unsigned int newlen;
2709 unsigned int __unused[4];
2710 };
2711
2712 extern asmlinkage long sys_sysctl(struct __sysctl_args *args);
2713
2714 asmlinkage long
2715 sys32_sysctl(struct sysctl_ia32 *args32)
2716 {
2717 struct sysctl_ia32 a32;
2718 mm_segment_t old_fs = get_fs ();
2719 void *oldvalp, *newvalp;
2720 size_t oldlen;
2721 int *namep;
2722 long ret;
2723
2724 if (copy_from_user(&a32, args32, sizeof (a32)))
2725 return -EFAULT;
2726
2727 /*
2728 * We need to pre-validate these because we have to disable address checking
2729 * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
2730 * user specifying bad addresses here. Well, since we're dealing with 32 bit
2731 * addresses, we KNOW that access_ok() will always succeed, so this is an
2732 * expensive NOP, but so what...
2733 */
2734 namep = (int *) A(a32.name);
2735 oldvalp = (void *) A(a32.oldval);
2736 newvalp = (void *) A(a32.newval);
2737
2738 if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))
2739 || !access_ok(VERIFY_WRITE, namep, 0)
2740 || !access_ok(VERIFY_WRITE, oldvalp, 0)
2741 || !access_ok(VERIFY_WRITE, newvalp, 0))
2742 return -EFAULT;
2743
2744 set_fs(KERNEL_DS);
2745 lock_kernel();
2746 ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);
2747 unlock_kernel();
2748 set_fs(old_fs);
2749
2750 if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))
2751 return -EFAULT;
2752
2753 return ret;
2754 }
2755
2756 asmlinkage long
2757 sys32_newuname(struct new_utsname * name)
2758 {
2759 extern asmlinkage long sys_newuname(struct new_utsname * name);
2760 int ret = sys_newuname(name);
2761
2762 if (!ret)
2763 if (copy_to_user(name->machine, "i686\0\0\0", 8))
2764 ret = -EFAULT;
2765 return ret;
2766 }
2767
2768 extern asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
2769
2770 asmlinkage long
2771 sys32_getresuid (u16 *ruid, u16 *euid, u16 *suid)
2772 {
2773 uid_t a, b, c;
2774 int ret;
2775 mm_segment_t old_fs = get_fs();
2776
2777 set_fs(KERNEL_DS);
2778 ret = sys_getresuid(&a, &b, &c);
2779 set_fs(old_fs);
2780
2781 if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
2782 return -EFAULT;
2783 return ret;
2784 }
2785
2786 extern asmlinkage long sys_getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid);
2787
2788 asmlinkage long
2789 sys32_getresgid(u16 *rgid, u16 *egid, u16 *sgid)
2790 {
2791 gid_t a, b, c;
2792 int ret;
2793 mm_segment_t old_fs = get_fs();
2794
2795 set_fs(KERNEL_DS);
2796 ret = sys_getresgid(&a, &b, &c);
2797 set_fs(old_fs);
2798
2799 if (!ret) {
2800 ret = put_user(a, rgid);
2801 ret |= put_user(b, egid);
2802 ret |= put_user(c, sgid);
2803 }
2804 return ret;
2805 }
2806
2807 int
2808 sys32_lseek (unsigned int fd, int offset, unsigned int whence)
2809 {
2810 extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
2811
2812 /* Sign-extension of "offset" is important here... */
2813 return sys_lseek(fd, offset, whence);
2814 }
2815
2816 #ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */
2817
2818 /* In order to reduce some races, while at the same time doing additional
2819 * checking and hopefully speeding things up, we copy filenames to the
2820 * kernel data space before using them..
2821 *
2822 * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
2823 */
2824 static inline int
2825 do_getname32(const char *filename, char *page)
2826 {
2827 int retval;
2828
2829 /* 32bit pointer will be always far below TASK_SIZE :)) */
2830 retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
2831 if (retval > 0) {
2832 if (retval < PAGE_SIZE)
2833 return 0;
2834 return -ENAMETOOLONG;
2835 } else if (!retval)
2836 retval = -ENOENT;
2837 return retval;
2838 }
2839
2840 char *
2841 getname32(const char *filename)
2842 {
2843 char *tmp, *result;
2844
2845 result = ERR_PTR(-ENOMEM);
2846 tmp = (char *)__get_free_page(GFP_KERNEL);
2847 if (tmp) {
2848 int retval = do_getname32(filename, tmp);
2849
2850 result = tmp;
2851 if (retval < 0) {
2852 putname(tmp);
2853 result = ERR_PTR(retval);
2854 }
2855 }
2856 return result;
2857 }
2858
2859 /* 32-bit timeval and related flotsam. */
2860
2861 extern asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
2862
2863 asmlinkage long
2864 sys32_ioperm(u32 from, u32 num, int on)
2865 {
2866 return sys_ioperm((unsigned long)from, (unsigned long)num, on);
2867 }
2868
2869 struct dqblk32 {
2870 __u32 dqb_bhardlimit;
2871 __u32 dqb_bsoftlimit;
2872 __u32 dqb_curblocks;
2873 __u32 dqb_ihardlimit;
2874 __u32 dqb_isoftlimit;
2875 __u32 dqb_curinodes;
2876 __kernel_time_t32 dqb_btime;
2877 __kernel_time_t32 dqb_itime;
2878 };
2879
2880 extern asmlinkage long sys_quotactl(int cmd, const char *special, int id,
2881 caddr_t addr);
2882
2883 asmlinkage long
2884 sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
2885 {
2886 int cmds = cmd >> SUBCMDSHIFT;
2887 int err;
2888 struct dqblk d;
2889 mm_segment_t old_fs;
2890 char *spec;
2891
2892 switch (cmds) {
2893 case Q_GETQUOTA:
2894 break;
2895 case Q_SETQUOTA:
2896 case Q_SETUSE:
2897 case Q_SETQLIM:
2898 if (copy_from_user (&d, (struct dqblk32 *)addr,
2899 sizeof (struct dqblk32)))
2900 return -EFAULT;
2901 d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
2902 d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
2903 break;
2904 default:
2905 return sys_quotactl(cmd, special,
2906 id, (caddr_t)addr);
2907 }
2908 spec = getname32 (special);
2909 err = PTR_ERR(spec);
2910 if (IS_ERR(spec)) return err;
2911 old_fs = get_fs ();
2912 set_fs (KERNEL_DS);
2913 err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
2914 set_fs (old_fs);
2915 putname (spec);
2916 if (cmds == Q_GETQUOTA) {
2917 __kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
2918 ((struct dqblk32 *)&d)->dqb_itime = i;
2919 ((struct dqblk32 *)&d)->dqb_btime = b;
2920 if (copy_to_user ((struct dqblk32 *)addr, &d,
2921 sizeof (struct dqblk32)))
2922 return -EFAULT;
2923 }
2924 return err;
2925 }
2926
2927 extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
2928
2929 struct utimbuf32 {
2930 __kernel_time_t32 actime, modtime;
2931 };
2932
2933 asmlinkage long
2934 sys32_utime(char * filename, struct utimbuf32 *times)
2935 {
2936 struct utimbuf t;
2937 mm_segment_t old_fs;
2938 int ret;
2939 char *filenam;
2940
2941 if (!times)
2942 return sys_utime(filename, NULL);
2943 if (get_user (t.actime, ×->actime) ||
2944 __get_user (t.modtime, ×->modtime))
2945 return -EFAULT;
2946 filenam = getname32 (filename);
2947 ret = PTR_ERR(filenam);
2948 if (!IS_ERR(filenam)) {
2949 old_fs = get_fs();
2950 set_fs (KERNEL_DS);
2951 ret = sys_utime(filenam, &t);
2952 set_fs (old_fs);
2953 putname (filenam);
2954 }
2955 return ret;
2956 }
2957
2958 /*
2959 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
2960 * 64-bit unsigned longs.
2961 */
2962
2963 static inline int
2964 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
2965 {
2966 if (ufdset) {
2967 unsigned long odd;
2968
2969 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
2970 return -EFAULT;
2971
2972 odd = n & 1UL;
2973 n &= ~1UL;
2974 while (n) {
2975 unsigned long h, l;
2976 __get_user(l, ufdset);
2977 __get_user(h, ufdset+1);
2978 ufdset += 2;
2979 *fdset++ = h << 32 | l;
2980 n -= 2;
2981 }
2982 if (odd)
2983 __get_user(*fdset, ufdset);
2984 } else {
2985 /* Tricky, must clear full unsigned long in the
2986 * kernel fdset at the end, this makes sure that
2987 * actually happens.
2988 */
2989 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
2990 }
2991 return 0;
2992 }
2993
2994 static inline void
2995 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
2996 {
2997 unsigned long odd;
2998
2999 if (!ufdset)
3000 return;
3001
3002 odd = n & 1UL;
3003 n &= ~1UL;
3004 while (n) {
3005 unsigned long h, l;
3006 l = *fdset++;
3007 h = l >> 32;
3008 __put_user(l, ufdset);
3009 __put_user(h, ufdset+1);
3010 ufdset += 2;
3011 n -= 2;
3012 }
3013 if (odd)
3014 __put_user(*fdset, ufdset);
3015 }
3016
3017 extern asmlinkage long sys_sysfs(int option, unsigned long arg1,
3018 unsigned long arg2);
3019
3020 asmlinkage long
3021 sys32_sysfs(int option, u32 arg1, u32 arg2)
3022 {
3023 return sys_sysfs(option, arg1, arg2);
3024 }
3025
3026 struct ncp_mount_data32 {
3027 int version;
3028 unsigned int ncp_fd;
3029 __kernel_uid_t32 mounted_uid;
3030 __kernel_pid_t32 wdog_pid;
3031 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
3032 unsigned int time_out;
3033 unsigned int retry_count;
3034 unsigned int flags;
3035 __kernel_uid_t32 uid;
3036 __kernel_gid_t32 gid;
3037 __kernel_mode_t32 file_mode;
3038 __kernel_mode_t32 dir_mode;
3039 };
3040
3041 static void *
3042 do_ncp_super_data_conv(void *raw_data)
3043 {
3044 struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
3045 struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
3046
3047 n->dir_mode = n32->dir_mode;
3048 n->file_mode = n32->file_mode;
3049 n->gid = n32->gid;
3050 n->uid = n32->uid;
3051 memmove (n->mounted_vol, n32->mounted_vol,
3052 (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
3053 n->wdog_pid = n32->wdog_pid;
3054 n->mounted_uid = n32->mounted_uid;
3055 return raw_data;
3056 }
3057
3058 struct smb_mount_data32 {
3059 int version;
3060 __kernel_uid_t32 mounted_uid;
3061 __kernel_uid_t32 uid;
3062 __kernel_gid_t32 gid;
3063 __kernel_mode_t32 file_mode;
3064 __kernel_mode_t32 dir_mode;
3065 };
3066
3067 static void *
3068 do_smb_super_data_conv(void *raw_data)
3069 {
3070 struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
3071 struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
3072
3073 s->version = s32->version;
3074 s->mounted_uid = s32->mounted_uid;
3075 s->uid = s32->uid;
3076 s->gid = s32->gid;
3077 s->file_mode = s32->file_mode;
3078 s->dir_mode = s32->dir_mode;
3079 return raw_data;
3080 }
3081
3082 static int
3083 copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
3084 {
3085 int i;
3086 unsigned long page;
3087 struct vm_area_struct *vma;
3088
3089 *kernel = 0;
3090 if(!user)
3091 return 0;
3092 vma = find_vma(current->mm, (unsigned long)user);
3093 if(!vma || (unsigned long)user < vma->vm_start)
3094 return -EFAULT;
3095 if(!(vma->vm_flags & VM_READ))
3096 return -EFAULT;
3097 i = vma->vm_end - (unsigned long) user;
3098 if(PAGE_SIZE <= (unsigned long) i)
3099 i = PAGE_SIZE - 1;
3100 if(!(page = __get_free_page(GFP_KERNEL)))
3101 return -ENOMEM;
3102 if(copy_from_user((void *) page, user, i)) {
3103 free_page(page);
3104 return -EFAULT;
3105 }
3106 *kernel = page;
3107 return 0;
3108 }
3109
3110 extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
3111 unsigned long new_flags, void *data);
3112
3113 #define SMBFS_NAME "smbfs"
3114 #define NCPFS_NAME "ncpfs"
3115
3116 asmlinkage long
3117 sys32_mount(char *dev_name, char *dir_name, char *type,
3118 unsigned long new_flags, u32 data)
3119 {
3120 unsigned long type_page;
3121 int err, is_smb, is_ncp;
3122
3123 if(!capable(CAP_SYS_ADMIN))
3124 return -EPERM;
3125 is_smb = is_ncp = 0;
3126 err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
3127 if(err)
3128 return err;
3129 if(type_page) {
3130 is_smb = !strcmp((char *)type_page, SMBFS_NAME);
3131 is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
3132 }
3133 if(!is_smb && !is_ncp) {
3134 if(type_page)
3135 free_page(type_page);
3136 return sys_mount(dev_name, dir_name, type, new_flags,
3137 (void *)AA(data));
3138 } else {
3139 unsigned long dev_page, dir_page, data_page;
3140
3141 err = copy_mount_stuff_to_kernel((const void *)dev_name,
3142 &dev_page);
3143 if(err)
3144 goto out;
3145 err = copy_mount_stuff_to_kernel((const void *)dir_name,
3146 &dir_page);
3147 if(err)
3148 goto dev_out;
3149 err = copy_mount_stuff_to_kernel((const void *)AA(data),
3150 &data_page);
3151 if(err)
3152 goto dir_out;
3153 if(is_ncp)
3154 do_ncp_super_data_conv((void *)data_page);
3155 else if(is_smb)
3156 do_smb_super_data_conv((void *)data_page);
3157 else
3158 panic("The problem is here...");
3159 err = do_mount((char *)dev_page, (char *)dir_page,
3160 (char *)type_page, new_flags,
3161 (void *)data_page);
3162 if(data_page)
3163 free_page(data_page);
3164 dir_out:
3165 if(dir_page)
3166 free_page(dir_page);
3167 dev_out:
3168 if(dev_page)
3169 free_page(dev_page);
3170 out:
3171 if(type_page)
3172 free_page(type_page);
3173 return err;
3174 }
3175 }
3176
3177 struct sysinfo32 {
3178 s32 uptime;
3179 u32 loads[3];
3180 u32 totalram;
3181 u32 freeram;
3182 u32 sharedram;
3183 u32 bufferram;
3184 u32 totalswap;
3185 u32 freeswap;
3186 unsigned short procs;
3187 char _f[22];
3188 };
3189
3190 extern asmlinkage long sys_sysinfo(struct sysinfo *info);
3191
3192 asmlinkage long
3193 sys32_sysinfo(struct sysinfo32 *info)
3194 {
3195 struct sysinfo s;
3196 int ret, err;
3197 mm_segment_t old_fs = get_fs ();
3198
3199 set_fs (KERNEL_DS);
3200 ret = sys_sysinfo(&s);
3201 set_fs (old_fs);
3202 err = put_user (s.uptime, &info->uptime);
3203 err |= __put_user (s.loads[0], &info->loads[0]);
3204 err |= __put_user (s.loads[1], &info->loads[1]);
3205 err |= __put_user (s.loads[2], &info->loads[2]);
3206 err |= __put_user (s.totalram, &info->totalram);
3207 err |= __put_user (s.freeram, &info->freeram);
3208 err |= __put_user (s.sharedram, &info->sharedram);
3209 err |= __put_user (s.bufferram, &info->bufferram);
3210 err |= __put_user (s.totalswap, &info->totalswap);
3211 err |= __put_user (s.freeswap, &info->freeswap);
3212 err |= __put_user (s.procs, &info->procs);
3213 if (err)
3214 return -EFAULT;
3215 return ret;
3216 }
3217
3218 extern asmlinkage long sys_sched_rr_get_interval(pid_t pid,
3219 struct timespec *interval);
3220
3221 asmlinkage long
3222 sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
3223 {
3224 struct timespec t;
3225 int ret;
3226 mm_segment_t old_fs = get_fs ();
3227
3228 set_fs (KERNEL_DS);
3229 ret = sys_sched_rr_get_interval(pid, &t);
3230 set_fs (old_fs);
3231 if (put_user (t.tv_sec, &interval->tv_sec) ||
3232 __put_user (t.tv_nsec, &interval->tv_nsec))
3233 return -EFAULT;
3234 return ret;
3235 }
3236
3237 extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
3238 old_sigset_t *oset);
3239
3240 asmlinkage long
3241 sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
3242 {
3243 old_sigset_t s;
3244 int ret;
3245 mm_segment_t old_fs = get_fs();
3246
3247 if (set && get_user (s, set)) return -EFAULT;
3248 set_fs (KERNEL_DS);
3249 ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
3250 set_fs (old_fs);
3251 if (ret) return ret;
3252 if (oset && put_user (s, oset)) return -EFAULT;
3253 return 0;
3254 }
3255
3256 extern asmlinkage long sys_sigpending(old_sigset_t *set);
3257
3258 asmlinkage long
3259 sys32_sigpending(old_sigset_t32 *set)
3260 {
3261 old_sigset_t s;
3262 int ret;
3263 mm_segment_t old_fs = get_fs();
3264
3265 set_fs (KERNEL_DS);
3266 ret = sys_sigpending(&s);
3267 set_fs (old_fs);
3268 if (put_user (s, set)) return -EFAULT;
3269 return ret;
3270 }
3271
3272 extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
3273
3274 asmlinkage long
3275 sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
3276 {
3277 sigset_t s;
3278 sigset_t32 s32;
3279 int ret;
3280 mm_segment_t old_fs = get_fs();
3281
3282 set_fs (KERNEL_DS);
3283 ret = sys_rt_sigpending(&s, sigsetsize);
3284 set_fs (old_fs);
3285 if (!ret) {
3286 switch (_NSIG_WORDS) {
3287 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
3288 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
3289 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
3290 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
3291 }
3292 if (copy_to_user (set, &s32, sizeof(sigset_t32)))
3293 return -EFAULT;
3294 }
3295 return ret;
3296 }
3297
3298 siginfo_t32 *
3299 siginfo64to32(siginfo_t32 *d, siginfo_t *s)
3300 {
3301 memset(d, 0, sizeof(siginfo_t32));
3302 d->si_signo = s->si_signo;
3303 d->si_errno = s->si_errno;
3304 d->si_code = s->si_code;
3305 if (s->si_signo >= SIGRTMIN) {
3306 d->si_pid = s->si_pid;
3307 d->si_uid = s->si_uid;
3308 /* XXX: Ouch, how to find this out??? */
3309 d->si_int = s->si_int;
3310 } else switch (s->si_signo) {
3311 /* XXX: What about POSIX1.b timers */
3312 case SIGCHLD:
3313 d->si_pid = s->si_pid;
3314 d->si_status = s->si_status;
3315 d->si_utime = s->si_utime;
3316 d->si_stime = s->si_stime;
3317 break;
3318 case SIGSEGV:
3319 case SIGBUS:
3320 case SIGFPE:
3321 case SIGILL:
3322 d->si_addr = (long)(s->si_addr);
3323 /* XXX: Do we need to translate this from ia64 to ia32 traps? */
3324 d->si_trapno = s->si_trapno;
3325 break;
3326 case SIGPOLL:
3327 d->si_band = s->si_band;
3328 d->si_fd = s->si_fd;
3329 break;
3330 default:
3331 d->si_pid = s->si_pid;
3332 d->si_uid = s->si_uid;
3333 break;
3334 }
3335 return d;
3336 }
3337
3338 siginfo_t *
3339 siginfo32to64(siginfo_t *d, siginfo_t32 *s)
3340 {
3341 d->si_signo = s->si_signo;
3342 d->si_errno = s->si_errno;
3343 d->si_code = s->si_code;
3344 if (s->si_signo >= SIGRTMIN) {
3345 d->si_pid = s->si_pid;
3346 d->si_uid = s->si_uid;
3347 /* XXX: Ouch, how to find this out??? */
3348 d->si_int = s->si_int;
3349 } else switch (s->si_signo) {
3350 /* XXX: What about POSIX1.b timers */
3351 case SIGCHLD:
3352 d->si_pid = s->si_pid;
3353 d->si_status = s->si_status;
3354 d->si_utime = s->si_utime;
3355 d->si_stime = s->si_stime;
3356 break;
3357 case SIGSEGV:
3358 case SIGBUS:
3359 case SIGFPE:
3360 case SIGILL:
3361 d->si_addr = (void *)A(s->si_addr);
3362 /* XXX: Do we need to translate this from ia32 to ia64 traps? */
3363 d->si_trapno = s->si_trapno;
3364 break;
3365 case SIGPOLL:
3366 d->si_band = s->si_band;
3367 d->si_fd = s->si_fd;
3368 break;
3369 default:
3370 d->si_pid = s->si_pid;
3371 d->si_uid = s->si_uid;
3372 break;
3373 }
3374 return d;
3375 }
3376
3377 extern asmlinkage long
3378 sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
3379 const struct timespec *uts, size_t sigsetsize);
3380
3381 asmlinkage long
3382 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
3383 struct timespec32 *uts, __kernel_size_t32 sigsetsize)
3384 {
3385 sigset_t s;
3386 sigset_t32 s32;
3387 struct timespec t;
3388 int ret;
3389 mm_segment_t old_fs = get_fs();
3390 siginfo_t info;
3391 siginfo_t32 info32;
3392
3393 if (copy_from_user (&s32, uthese, sizeof(sigset_t32)))
3394 return -EFAULT;
3395 switch (_NSIG_WORDS) {
3396 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
3397 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
3398 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
3399 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
3400 }
3401 if (uts) {
3402 ret = get_user (t.tv_sec, &uts->tv_sec);
3403 ret |= __get_user (t.tv_nsec, &uts->tv_nsec);
3404 if (ret)
3405 return -EFAULT;
3406 }
3407 set_fs (KERNEL_DS);
3408 ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
3409 set_fs (old_fs);
3410 if (ret >= 0 && uinfo) {
3411 if (copy_to_user (uinfo, siginfo64to32(&info32, &info),
3412 sizeof(siginfo_t32)))
3413 return -EFAULT;
3414 }
3415 return ret;
3416 }
3417
3418 extern asmlinkage long
3419 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
3420
3421 asmlinkage long
3422 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
3423 {
3424 siginfo_t info;
3425 siginfo_t32 info32;
3426 int ret;
3427 mm_segment_t old_fs = get_fs();
3428
3429 if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32)))
3430 return -EFAULT;
3431 /* XXX: Is this correct? */
3432 siginfo32to64(&info, &info32);
3433 set_fs (KERNEL_DS);
3434 ret = sys_rt_sigqueueinfo(pid, sig, &info);
3435 set_fs (old_fs);
3436 return ret;
3437 }
3438
3439 extern asmlinkage long sys_setreuid(uid_t ruid, uid_t euid);
3440
3441 asmlinkage long sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
3442 {
3443 uid_t sruid, seuid;
3444
3445 sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
3446 seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
3447 return sys_setreuid(sruid, seuid);
3448 }
3449
3450 extern asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
3451
3452 asmlinkage long
3453 sys32_setresuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid,
3454 __kernel_uid_t32 suid)
3455 {
3456 uid_t sruid, seuid, ssuid;
3457
3458 sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
3459 seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
3460 ssuid = (suid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)suid);
3461 return sys_setresuid(sruid, seuid, ssuid);
3462 }
3463
3464 extern asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
3465
3466 asmlinkage long
3467 sys32_getresuid(__kernel_uid_t32 *ruid, __kernel_uid_t32 *euid,
3468 __kernel_uid_t32 *suid)
3469 {
3470 uid_t a, b, c;
3471 int ret;
3472 mm_segment_t old_fs = get_fs();
3473
3474 set_fs (KERNEL_DS);
3475 ret = sys_getresuid(&a, &b, &c);
3476 set_fs (old_fs);
3477 if (put_user (a, ruid) || put_user (b, euid) || put_user (c, suid))
3478 return -EFAULT;
3479 return ret;
3480 }
3481
3482 extern asmlinkage long sys_setregid(gid_t rgid, gid_t egid);
3483
3484 asmlinkage long
3485 sys32_setregid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid)
3486 {
3487 gid_t srgid, segid;
3488
3489 srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
3490 segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
3491 return sys_setregid(srgid, segid);
3492 }
3493
3494 extern asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
3495
3496 asmlinkage long
3497 sys32_setresgid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid,
3498 __kernel_gid_t32 sgid)
3499 {
3500 gid_t srgid, segid, ssgid;
3501
3502 srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
3503 segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
3504 ssgid = (sgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)sgid);
3505 return sys_setresgid(srgid, segid, ssgid);
3506 }
3507
3508 extern asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist);
3509
3510 asmlinkage long
3511 sys32_getgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
3512 {
3513 gid_t gl[NGROUPS];
3514 int ret, i;
3515 mm_segment_t old_fs = get_fs ();
3516
3517 set_fs (KERNEL_DS);
3518 ret = sys_getgroups(gidsetsize, gl);
3519 set_fs (old_fs);
3520 if (gidsetsize && ret > 0 && ret <= NGROUPS)
3521 for (i = 0; i < ret; i++, grouplist++)
3522 if (__put_user (gl[i], grouplist))
3523 return -EFAULT;
3524 return ret;
3525 }
3526
3527 extern asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist);
3528
3529 asmlinkage long
3530 sys32_setgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
3531 {
3532 gid_t gl[NGROUPS];
3533 int ret, i;
3534 mm_segment_t old_fs = get_fs ();
3535
3536 if ((unsigned) gidsetsize > NGROUPS)
3537 return -EINVAL;
3538 for (i = 0; i < gidsetsize; i++, grouplist++)
3539 if (__get_user (gl[i], grouplist))
3540 return -EFAULT;
3541 set_fs (KERNEL_DS);
3542 ret = sys_setgroups(gidsetsize, gl);
3543 set_fs (old_fs);
3544 return ret;
3545 }
3546
3547
3548 /* XXX These as well... */
3549 extern __inline__ struct socket *
3550 socki_lookup(struct inode *inode)
3551 {
3552 return &inode->u.socket_i;
3553 }
3554
3555 extern __inline__ struct socket *
3556 sockfd_lookup(int fd, int *err)
3557 {
3558 struct file *file;
3559 struct inode *inode;
3560
3561 if (!(file = fget(fd)))
3562 {
3563 *err = -EBADF;
3564 return NULL;
3565 }
3566
3567 inode = file->f_dentry->d_inode;
3568 if (!inode->i_sock || !socki_lookup(inode))
3569 {
3570 *err = -ENOTSOCK;
3571 fput(file);
3572 return NULL;
3573 }
3574
3575 return socki_lookup(inode);
3576 }
3577
3578 struct msghdr32 {
3579 u32 msg_name;
3580 int msg_namelen;
3581 u32 msg_iov;
3582 __kernel_size_t32 msg_iovlen;
3583 u32 msg_control;
3584 __kernel_size_t32 msg_controllen;
3585 unsigned msg_flags;
3586 };
3587
3588 struct cmsghdr32 {
3589 __kernel_size_t32 cmsg_len;
3590 int cmsg_level;
3591 int cmsg_type;
3592 };
3593
3594 /* Bleech... */
3595 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) \
3596 __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
3597 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) \
3598 cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
3599
3600 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
3601
3602 #define CMSG32_DATA(cmsg) \
3603 ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
3604 #define CMSG32_SPACE(len) \
3605 (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
3606 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
3607
3608 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
3609 (struct cmsghdr32 *)(ctl) : \
3610 (struct cmsghdr32 *)NULL)
3611 #define CMSG32_FIRSTHDR(msg) \
3612 __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
3613
3614 __inline__ struct cmsghdr32 *
3615 __cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
3616 struct cmsghdr32 *__cmsg, int __cmsg_len)
3617 {
3618 struct cmsghdr32 * __ptr;
3619
3620 __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
3621 CMSG32_ALIGN(__cmsg_len));
3622 if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
3623 return NULL;
3624
3625 return __ptr;
3626 }
3627
3628 __inline__ struct cmsghdr32 *
3629 cmsg32_nxthdr (struct msghdr *__msg, struct cmsghdr32 *__cmsg, int __cmsg_len)
3630 {
3631 return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
3632 __cmsg, __cmsg_len);
3633 }
3634
3635 static inline int
3636 iov_from_user32_to_kern(struct iovec *kiov, struct iovec32 *uiov32, int niov)
3637 {
3638 int tot_len = 0;
3639
3640 while(niov > 0) {
3641 u32 len, buf;
3642
3643 if(get_user(len, &uiov32->iov_len) ||
3644 get_user(buf, &uiov32->iov_base)) {
3645 tot_len = -EFAULT;
3646 break;
3647 }
3648 tot_len += len;
3649 kiov->iov_base = (void *)A(buf);
3650 kiov->iov_len = (__kernel_size_t) len;
3651 uiov32++;
3652 kiov++;
3653 niov--;
3654 }
3655 return tot_len;
3656 }
3657
3658 static inline int
3659 msghdr_from_user32_to_kern(struct msghdr *kmsg, struct msghdr32 *umsg)
3660 {
3661 u32 tmp1, tmp2, tmp3;
3662 int err;
3663
3664 err = get_user(tmp1, &umsg->msg_name);
3665 err |= __get_user(tmp2, &umsg->msg_iov);
3666 err |= __get_user(tmp3, &umsg->msg_control);
3667 if (err)
3668 return -EFAULT;
3669
3670 kmsg->msg_name = (void *)A(tmp1);
3671 kmsg->msg_iov = (struct iovec *)A(tmp2);
3672 kmsg->msg_control = (void *)A(tmp3);
3673
3674 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
3675 err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
3676 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
3677 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
3678
3679 return err;
3680 }
3681
3682 /* I've named the args so it is easy to tell whose space the pointers are in. */
3683 static int
3684 verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
3685 char *kern_address, int mode)
3686 {
3687 int tot_len;
3688
3689 if(kern_msg->msg_namelen) {
3690 if(mode==VERIFY_READ) {
3691 int err = move_addr_to_kernel(kern_msg->msg_name,
3692 kern_msg->msg_namelen,
3693 kern_address);
3694 if(err < 0)
3695 return err;
3696 }
3697 kern_msg->msg_name = kern_address;
3698 } else
3699 kern_msg->msg_name = NULL;
3700
3701 if(kern_msg->msg_iovlen > UIO_FASTIOV) {
3702 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
3703 GFP_KERNEL);
3704 if(!kern_iov)
3705 return -ENOMEM;
3706 }
3707
3708 tot_len = iov_from_user32_to_kern(kern_iov,
3709 (struct iovec32 *)kern_msg->msg_iov,
3710 kern_msg->msg_iovlen);
3711 if(tot_len >= 0)
3712 kern_msg->msg_iov = kern_iov;
3713 else if(kern_msg->msg_iovlen > UIO_FASTIOV)
3714 kfree(kern_iov);
3715
3716 return tot_len;
3717 }
3718
3719 /* There is a lot of hair here because the alignment rules (and
3720 * thus placement) of cmsg headers and length are different for
3721 * 32-bit apps. -DaveM
3722 */
3723 static int
3724 cmsghdr_from_user32_to_kern(struct msghdr *kmsg, unsigned char *stackbuf,
3725 int stackbuf_size)
3726 {
3727 struct cmsghdr32 *ucmsg;
3728 struct cmsghdr *kcmsg, *kcmsg_base;
3729 __kernel_size_t32 ucmlen;
3730 __kernel_size_t kcmlen, tmp;
3731
3732 kcmlen = 0;
3733 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
3734 ucmsg = CMSG32_FIRSTHDR(kmsg);
3735 while(ucmsg != NULL) {
3736 if(get_user(ucmlen, &ucmsg->cmsg_len))
3737 return -EFAULT;
3738
3739 /* Catch bogons. */
3740 if(CMSG32_ALIGN(ucmlen) <
3741 CMSG32_ALIGN(sizeof(struct cmsghdr32)))
3742 return -EINVAL;
3743 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
3744 + ucmlen) > kmsg->msg_controllen)
3745 return -EINVAL;
3746
3747 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
3748 CMSG_ALIGN(sizeof(struct cmsghdr)));
3749 kcmlen += tmp;
3750 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
3751 }
3752 if(kcmlen == 0)
3753 return -EINVAL;
3754
3755 /* The kcmlen holds the 64-bit version of the control length.
3756 * It may not be modified as we do not stick it into the kmsg
3757 * until we have successfully copied over all of the data
3758 * from the user.
3759 */
3760 if(kcmlen > stackbuf_size)
3761 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
3762 if(kcmsg == NULL)
3763 return -ENOBUFS;
3764
3765 /* Now copy them over neatly. */
3766 memset(kcmsg, 0, kcmlen);
3767 ucmsg = CMSG32_FIRSTHDR(kmsg);
3768 while(ucmsg != NULL) {
3769 __get_user(ucmlen, &ucmsg->cmsg_len);
3770 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
3771 CMSG_ALIGN(sizeof(struct cmsghdr)));
3772 kcmsg->cmsg_len = tmp;
3773 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
3774 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
3775
3776 /* Copy over the data. */
3777 if(copy_from_user(CMSG_DATA(kcmsg),
3778 CMSG32_DATA(ucmsg),
3779 (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
3780 goto out_free_efault;
3781
3782 /* Advance. */
3783 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
3784 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
3785 }
3786
3787 /* Ok, looks like we made it. Hook it up and return success. */
3788 kmsg->msg_control = kcmsg_base;
3789 kmsg->msg_controllen = kcmlen;
3790 return 0;
3791
3792 out_free_efault:
3793 if(kcmsg_base != (struct cmsghdr *)stackbuf)
3794 kfree(kcmsg_base);
3795 return -EFAULT;
3796 }
3797
3798 static void
3799 put_cmsg32(struct msghdr *kmsg, int level, int type, int len, void *data)
3800 {
3801 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
3802 struct cmsghdr32 cmhdr;
3803 int cmlen = CMSG32_LEN(len);
3804
3805 if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
3806 kmsg->msg_flags |= MSG_CTRUNC;
3807 return;
3808 }
3809
3810 if(kmsg->msg_controllen < cmlen) {
3811 kmsg->msg_flags |= MSG_CTRUNC;
3812 cmlen = kmsg->msg_controllen;
3813 }
3814 cmhdr.cmsg_level = level;
3815 cmhdr.cmsg_type = type;
3816 cmhdr.cmsg_len = cmlen;
3817
3818 if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
3819 return;
3820 if(copy_to_user(CMSG32_DATA(cm), data,
3821 cmlen - sizeof(struct cmsghdr32)))
3822 return;
3823 cmlen = CMSG32_SPACE(len);
3824 kmsg->msg_control += cmlen;
3825 kmsg->msg_controllen -= cmlen;
3826 }
3827
3828 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
3829 {
3830 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
3831 int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32))
3832 / sizeof(int);
3833 int fdnum = scm->fp->count;
3834 struct file **fp = scm->fp->fp;
3835 int *cmfptr;
3836 int err = 0, i;
3837
3838 if (fdnum < fdmax)
3839 fdmax = fdnum;
3840
3841 for (i = 0, cmfptr = (int *) CMSG32_DATA(cm);
3842 i < fdmax;
3843 i++, cmfptr++) {
3844 int new_fd;
3845 err = get_unused_fd();
3846 if (err < 0)
3847 break;
3848 new_fd = err;
3849 err = put_user(new_fd, cmfptr);
3850 if (err) {
3851 put_unused_fd(new_fd);
3852 break;
3853 }
3854 /* Bump the usage count and install the file. */
3855 fp[i]->f_count++;
3856 current->files->fd[new_fd] = fp[i];
3857 }
3858
3859 if (i > 0) {
3860 int cmlen = CMSG32_LEN(i * sizeof(int));
3861 if (!err)
3862 err = put_user(SOL_SOCKET, &cm->cmsg_level);
3863 if (!err)
3864 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
3865 if (!err)
3866 err = put_user(cmlen, &cm->cmsg_len);
3867 if (!err) {
3868 cmlen = CMSG32_SPACE(i * sizeof(int));
3869 kmsg->msg_control += cmlen;
3870 kmsg->msg_controllen -= cmlen;
3871 }
3872 }
3873 if (i < fdnum)
3874 kmsg->msg_flags |= MSG_CTRUNC;
3875
3876 /*
3877 * All of the files that fit in the message have had their
3878 * usage counts incremented, so we just free the list.
3879 */
3880 __scm_destroy(scm);
3881 }
3882
3883 /* In these cases we (currently) can just copy to data over verbatim
3884 * because all CMSGs created by the kernel have well defined types which
3885 * have the same layout in both the 32-bit and 64-bit API. One must add
3886 * some special cased conversions here if we start sending control messages
3887 * with incompatible types.
3888 *
3889 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
3890 * we do our work. The remaining cases are:
3891 *
3892 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
3893 * IP_TTL int 32-bit clean
3894 * IP_TOS __u8 32-bit clean
3895 * IP_RECVOPTS variable length 32-bit clean
3896 * IP_RETOPTS variable length 32-bit clean
3897 * (these last two are clean because the types are defined
3898 * by the IPv4 protocol)
3899 * IP_RECVERR struct sock_extended_err +
3900 * struct sockaddr_in 32-bit clean
3901 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
3902 * struct sockaddr_in6 32-bit clean
3903 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
3904 * IPV6_HOPLIMIT int 32-bit clean
3905 * IPV6_FLOWINFO u32 32-bit clean
3906 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
3907 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
3908 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
3909 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
3910 */
3911 static void
3912 cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
3913 {
3914 unsigned char *workbuf, *wp;
3915 unsigned long bufsz, space_avail;
3916 struct cmsghdr *ucmsg;
3917
3918 bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
3919 space_avail = kmsg->msg_controllen + bufsz;
3920 wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
3921 if(workbuf == NULL)
3922 goto fail;
3923
3924 /* To make this more sane we assume the kernel sends back properly
3925 * formatted control messages. Because of how the kernel will truncate
3926 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
3927 */
3928 ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
3929 while(((unsigned long)ucmsg) < ((unsigned long)kmsg->msg_control)) {
3930 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
3931 int clen64, clen32;
3932
3933 /* UCMSG is the 64-bit format CMSG entry in user-space.
3934 * KCMSG32 is within the kernel space temporary buffer
3935 * we use to convert into a 32-bit style CMSG.
3936 */
3937 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
3938 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
3939 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
3940
3941 clen64 = kcmsg32->cmsg_len;
3942 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
3943 clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
3944 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
3945 CMSG32_ALIGN(sizeof(struct cmsghdr32)));
3946 kcmsg32->cmsg_len = clen32;
3947
3948 ucmsg = (struct cmsghdr *) (((char *)ucmsg) +
3949 CMSG_ALIGN(clen64));
3950 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
3951 }
3952
3953 /* Copy back fixed up data, and adjust pointers. */
3954 bufsz = (wp - workbuf);
3955 copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
3956
3957 kmsg->msg_control = (struct cmsghdr *)
3958 (((char *)orig_cmsg_uptr) + bufsz);
3959 kmsg->msg_controllen = space_avail - bufsz;
3960
3961 kfree(workbuf);
3962 return;
3963
3964 fail:
3965 /* If we leave the 64-bit format CMSG chunks in there,
3966 * the application could get confused and crash. So to
3967 * ensure greater recovery, we report no CMSGs.
3968 */
3969 kmsg->msg_controllen += bufsz;
3970 kmsg->msg_control = (void *) orig_cmsg_uptr;
3971 }
3972
3973 asmlinkage long
3974 sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
3975 {
3976 struct socket *sock;
3977 char address[MAX_SOCK_ADDR];
3978 struct iovec iov[UIO_FASTIOV];
3979 unsigned char ctl[sizeof(struct cmsghdr) + 20];
3980 unsigned char *ctl_buf = ctl;
3981 struct msghdr kern_msg;
3982 int err, total_len;
3983
3984 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
3985 return -EFAULT;
3986 if(kern_msg.msg_iovlen > UIO_MAXIOV)
3987 return -EINVAL;
3988 err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
3989 if (err < 0)
3990 goto out;
3991 total_len = err;
3992
3993 if(kern_msg.msg_controllen) {
3994 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
3995 if(err)
3996 goto out_freeiov;
3997 ctl_buf = kern_msg.msg_control;
3998 }
3999 kern_msg.msg_flags = user_flags;
4000
4001 sock = sockfd_lookup(fd, &err);
4002 if (sock != NULL) {
4003 if (sock->file->f_flags & O_NONBLOCK)
4004 kern_msg.msg_flags |= MSG_DONTWAIT;
4005 err = sock_sendmsg(sock, &kern_msg, total_len);
4006 sockfd_put(sock);
4007 }
4008
4009 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
4010 if(ctl_buf != ctl)
4011 kfree(ctl_buf);
4012 out_freeiov:
4013 if(kern_msg.msg_iov != iov)
4014 kfree(kern_msg.msg_iov);
4015 out:
4016 return err;
4017 }
4018
4019 asmlinkage long
4020 sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
4021 {
4022 struct iovec iovstack[UIO_FASTIOV];
4023 struct msghdr kern_msg;
4024 char addr[MAX_SOCK_ADDR];
4025 struct socket *sock;
4026 struct iovec *iov = iovstack;
4027 struct sockaddr *uaddr;
4028 int *uaddr_len;
4029 unsigned long cmsg_ptr;
4030 int err, total_len, len = 0;
4031
4032 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
4033 return -EFAULT;
4034 if(kern_msg.msg_iovlen > UIO_MAXIOV)
4035 return -EINVAL;
4036
4037 uaddr = kern_msg.msg_name;
4038 uaddr_len = &user_msg->msg_namelen;
4039 err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
4040 if (err < 0)
4041 goto out;
4042 total_len = err;
4043
4044 cmsg_ptr = (unsigned long) kern_msg.msg_control;
4045 kern_msg.msg_flags = 0;
4046
4047 sock = sockfd_lookup(fd, &err);
4048 if (sock != NULL) {
4049 struct scm_cookie scm;
4050
4051 if (sock->file->f_flags & O_NONBLOCK)
4052 user_flags |= MSG_DONTWAIT;
4053 memset(&scm, 0, sizeof(scm));
4054 lock_kernel();
4055 err = sock->ops->recvmsg(sock, &kern_msg, total_len,
4056 user_flags, &scm);
4057 if(err >= 0) {
4058 len = err;
4059 if(!kern_msg.msg_control) {
4060 if(sock->passcred || scm.fp)
4061 kern_msg.msg_flags |= MSG_CTRUNC;
4062 if(scm.fp)
4063 __scm_destroy(&scm);
4064 } else {
4065 /* If recvmsg processing itself placed some
4066 * control messages into user space, it's is
4067 * using 64-bit CMSG processing, so we need
4068 * to fix it up before we tack on more stuff.
4069 */
4070 if((unsigned long) kern_msg.msg_control
4071 != cmsg_ptr)
4072 cmsg32_recvmsg_fixup(&kern_msg,
4073 cmsg_ptr);
4074
4075 /* Wheee... */
4076 if(sock->passcred)
4077 put_cmsg32(&kern_msg,
4078 SOL_SOCKET, SCM_CREDENTIALS,
4079 sizeof(scm.creds),
4080 &scm.creds);
4081 if(scm.fp != NULL)
4082 scm_detach_fds32(&kern_msg, &scm);
4083 }
4084 }
4085 unlock_kernel();
4086 sockfd_put(sock);
4087 }
4088
4089 if(uaddr != NULL && err >= 0)
4090 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr,
4091 uaddr_len);
4092 if(cmsg_ptr != 0 && err >= 0) {
4093 unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
4094 __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr
4095 - cmsg_ptr);
4096 err |= __put_user(uclen, &user_msg->msg_controllen);
4097 }
4098 if(err >= 0)
4099 err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
4100 if(kern_msg.msg_iov != iov)
4101 kfree(kern_msg.msg_iov);
4102 out:
4103 if(err < 0)
4104 return err;
4105 return len;
4106 }
4107
4108 extern void check_pending(int signum);
4109
4110 #ifdef CONFIG_MODULES
4111
4112 extern asmlinkage unsigned long sys_create_module(const char *name_user,
4113 size_t size);
4114
4115 asmlinkage unsigned long
4116 sys32_create_module(const char *name_user, __kernel_size_t32 size)
4117 {
4118 return sys_create_module(name_user, (size_t)size);
4119 }
4120
4121 extern asmlinkage long sys_init_module(const char *name_user,
4122 struct module *mod_user);
4123
4124 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
4125 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
4126 */
4127 asmlinkage long
4128 sys32_init_module(const char *name_user, struct module *mod_user)
4129 {
4130 return sys_init_module(name_user, mod_user);
4131 }
4132
4133 extern asmlinkage long sys_delete_module(const char *name_user);
4134
4135 asmlinkage long
4136 sys32_delete_module(const char *name_user)
4137 {
4138 return sys_delete_module(name_user);
4139 }
4140
4141 struct module_info32 {
4142 u32 addr;
4143 u32 size;
4144 u32 flags;
4145 s32 usecount;
4146 };
4147
4148 /* Query various bits about modules. */
4149
4150 static inline long
4151 get_mod_name(const char *user_name, char **buf)
4152 {
4153 unsigned long page;
4154 long retval;
4155
4156 if ((unsigned long)user_name >= TASK_SIZE
4157 && !segment_eq(get_fs (), KERNEL_DS))
4158 return -EFAULT;
4159
4160 page = __get_free_page(GFP_KERNEL);
4161 if (!page)
4162 return -ENOMEM;
4163
4164 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
4165 if (retval > 0) {
4166 if (retval < PAGE_SIZE) {
4167 *buf = (char *)page;
4168 return retval;
4169 }
4170 retval = -ENAMETOOLONG;
4171 } else if (!retval)
4172 retval = -EINVAL;
4173
4174 free_page(page);
4175 return retval;
4176 }
4177
4178 static inline void
4179 put_mod_name(char *buf)
4180 {
4181 free_page((unsigned long)buf);
4182 }
4183
4184 static __inline__ struct module *
4185 find_module(const char *name)
4186 {
4187 struct module *mod;
4188
4189 for (mod = module_list; mod ; mod = mod->next) {
4190 if (mod->flags & MOD_DELETED)
4191 continue;
4192 if (!strcmp(mod->name, name))
4193 break;
4194 }
4195
4196 return mod;
4197 }
4198
4199 static int
4200 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
4201 {
4202 struct module *mod;
4203 size_t nmod, space, len;
4204
4205 nmod = space = 0;
4206
4207 for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
4208 len = strlen(mod->name)+1;
4209 if (len > bufsize)
4210 goto calc_space_needed;
4211 if (copy_to_user(buf, mod->name, len))
4212 return -EFAULT;
4213 buf += len;
4214 bufsize -= len;
4215 space += len;
4216 }
4217
4218 if (put_user(nmod, ret))
4219 return -EFAULT;
4220 else
4221 return 0;
4222
4223 calc_space_needed:
4224 space += len;
4225 while ((mod = mod->next)->next != NULL)
4226 space += strlen(mod->name)+1;
4227
4228 if (put_user(space, ret))
4229 return -EFAULT;
4230 else
4231 return -ENOSPC;
4232 }
4233
4234 static int
4235 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
4236 {
4237 size_t i, space, len;
4238
4239 if (mod->next == NULL)
4240 return -EINVAL;
4241 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
4242 if (put_user(0, ret))
4243 return -EFAULT;
4244 else
4245 return 0;
4246
4247 space = 0;
4248 for (i = 0; i < mod->ndeps; ++i) {
4249 const char *dep_name = mod->deps[i].dep->name;
4250
4251 len = strlen(dep_name)+1;
4252 if (len > bufsize)
4253 goto calc_space_needed;
4254 if (copy_to_user(buf, dep_name, len))
4255 return -EFAULT;
4256 buf += len;
4257 bufsize -= len;
4258 space += len;
4259 }
4260
4261 if (put_user(i, ret))
4262 return -EFAULT;
4263 else
4264 return 0;
4265
4266 calc_space_needed:
4267 space += len;
4268 while (++i < mod->ndeps)
4269 space += strlen(mod->deps[i].dep->name)+1;
4270
4271 if (put_user(space, ret))
4272 return -EFAULT;
4273 else
4274 return -ENOSPC;
4275 }
4276
4277 static int
4278 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
4279 {
4280 size_t nrefs, space, len;
4281 struct module_ref *ref;
4282
4283 if (mod->next == NULL)
4284 return -EINVAL;
4285 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
4286 if (put_user(0, ret))
4287 return -EFAULT;
4288 else
4289 return 0;
4290
4291 space = 0;
4292 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
4293 const char *ref_name = ref->ref->name;
4294
4295 len = strlen(ref_name)+1;
4296 if (len > bufsize)
4297 goto calc_space_needed;
4298 if (copy_to_user(buf, ref_name, len))
4299 return -EFAULT;
4300 buf += len;
4301 bufsize -= len;
4302 space += len;
4303 }
4304
4305 if (put_user(nrefs, ret))
4306 return -EFAULT;
4307 else
4308 return 0;
4309
4310 calc_space_needed:
4311 space += len;
4312 while ((ref = ref->next_ref) != NULL)
4313 space += strlen(ref->ref->name)+1;
4314
4315 if (put_user(space, ret))
4316 return -EFAULT;
4317 else
4318 return -ENOSPC;
4319 }
4320
4321 static inline int
4322 qm_symbols(struct module *mod, char *buf, size_t bufsize,
4323 __kernel_size_t32 *ret)
4324 {
4325 size_t i, space, len;
4326 struct module_symbol *s;
4327 char *strings;
4328 unsigned *vals;
4329
4330 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
4331 if (put_user(0, ret))
4332 return -EFAULT;
4333 else
4334 return 0;
4335
4336 space = mod->nsyms * 2*sizeof(u32);
4337
4338 i = len = 0;
4339 s = mod->syms;
4340
4341 if (space > bufsize)
4342 goto calc_space_needed;
4343
4344 if (!access_ok(VERIFY_WRITE, buf, space))
4345 return -EFAULT;
4346
4347 bufsize -= space;
4348 vals = (unsigned *)buf;
4349 strings = buf+space;
4350
4351 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
4352 len = strlen(s->name)+1;
4353 if (len > bufsize)
4354 goto calc_space_needed;
4355
4356 if (copy_to_user(strings, s->name, len)
4357 || __put_user(s->value, vals+0)
4358 || __put_user(space, vals+1))
4359 return -EFAULT;
4360
4361 strings += len;
4362 bufsize -= len;
4363 space += len;
4364 }
4365
4366 if (put_user(i, ret))
4367 return -EFAULT;
4368 else
4369 return 0;
4370
4371 calc_space_needed:
4372 for (; i < mod->nsyms; ++i, ++s)
4373 space += strlen(s->name)+1;
4374
4375 if (put_user(space, ret))
4376 return -EFAULT;
4377 else
4378 return -ENOSPC;
4379 }
4380
4381 static inline int
4382 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
4383 {
4384 int error = 0;
4385
4386 if (mod->next == NULL)
4387 return -EINVAL;
4388
4389 if (sizeof(struct module_info32) <= bufsize) {
4390 struct module_info32 info;
4391 info.addr = (unsigned long)mod;
4392 info.size = mod->size;
4393 info.flags = mod->flags;
4394 info.usecount =
4395 ((mod_member_present(mod, can_unload)
4396 && mod->can_unload)
4397 ? -1 : atomic_read(&mod->uc.usecount));
4398
4399 if (copy_to_user(buf, &info, sizeof(struct module_info32)))
4400 return -EFAULT;
4401 } else
4402 error = -ENOSPC;
4403
4404 if (put_user(sizeof(struct module_info32), ret))
4405 return -EFAULT;
4406
4407 return error;
4408 }
4409
4410 asmlinkage long
4411 sys32_query_module(char *name_user, int which, char *buf,
4412 __kernel_size_t32 bufsize, u32 ret)
4413 {
4414 struct module *mod;
4415 int err;
4416
4417 lock_kernel();
4418 if (name_user == 0) {
4419 /* This finds "kernel_module" which is not exported. */
4420 for(mod = module_list; mod->next != NULL; mod = mod->next)
4421 ;
4422 } else {
4423 long namelen;
4424 char *name;
4425
4426 if ((namelen = get_mod_name(name_user, &name)) < 0) {
4427 err = namelen;
4428 goto out;
4429 }
4430 err = -ENOENT;
4431 if (namelen == 0) {
4432 /* This finds "kernel_module" which is not exported. */
4433 for(mod = module_list;
4434 mod->next != NULL;
4435 mod = mod->next) ;
4436 } else if ((mod = find_module(name)) == NULL) {
4437 put_mod_name(name);
4438 goto out;
4439 }
4440 put_mod_name(name);
4441 }
4442
4443 switch (which)
4444 {
4445 case 0:
4446 err = 0;
4447 break;
4448 case QM_MODULES:
4449 err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
4450 break;
4451 case QM_DEPS:
4452 err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
4453 break;
4454 case QM_REFS:
4455 err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
4456 break;
4457 case QM_SYMBOLS:
4458 err = qm_symbols(mod, buf, bufsize,
4459 (__kernel_size_t32 *)AA(ret));
4460 break;
4461 case QM_INFO:
4462 err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
4463 break;
4464 default:
4465 err = -EINVAL;
4466 break;
4467 }
4468 out:
4469 unlock_kernel();
4470 return err;
4471 }
4472
4473 struct kernel_sym32 {
4474 u32 value;
4475 char name[60];
4476 };
4477
4478 extern asmlinkage long sys_get_kernel_syms(struct kernel_sym *table);
4479
4480 asmlinkage long
4481 sys32_get_kernel_syms(struct kernel_sym32 *table)
4482 {
4483 int len, i;
4484 struct kernel_sym *tbl;
4485 mm_segment_t old_fs;
4486
4487 len = sys_get_kernel_syms(NULL);
4488 if (!table) return len;
4489 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
4490 if (!tbl) return -ENOMEM;
4491 old_fs = get_fs();
4492 set_fs (KERNEL_DS);
4493 sys_get_kernel_syms(tbl);
4494 set_fs (old_fs);
4495 for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
4496 if (put_user (tbl[i].value, &table->value) ||
4497 copy_to_user (table->name, tbl[i].name, 60))
4498 break;
4499 }
4500 kfree (tbl);
4501 return i;
4502 }
4503
4504 #else /* CONFIG_MODULES */
4505
4506 asmlinkage unsigned long
4507 sys32_create_module(const char *name_user, size_t size)
4508 {
4509 return -ENOSYS;
4510 }
4511
4512 asmlinkage long
4513 sys32_init_module(const char *name_user, struct module *mod_user)
4514 {
4515 return -ENOSYS;
4516 }
4517
4518 asmlinkage long
4519 sys32_delete_module(const char *name_user)
4520 {
4521 return -ENOSYS;
4522 }
4523
4524 asmlinkage long
4525 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
4526 size_t *ret)
4527 {
4528 /* Let the program know about the new interface. Not that
4529 it'll do them much good. */
4530 if (which == 0)
4531 return 0;
4532
4533 return -ENOSYS;
4534 }
4535
4536 asmlinkage long
4537 sys32_get_kernel_syms(struct kernel_sym *table)
4538 {
4539 return -ENOSYS;
4540 }
4541
4542 #endif /* CONFIG_MODULES */
4543
4544 /* Stuff for NFS server syscalls... */
4545 struct nfsctl_svc32 {
4546 u16 svc32_port;
4547 s32 svc32_nthreads;
4548 };
4549
4550 struct nfsctl_client32 {
4551 s8 cl32_ident[NFSCLNT_IDMAX+1];
4552 s32 cl32_naddr;
4553 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
4554 s32 cl32_fhkeytype;
4555 s32 cl32_fhkeylen;
4556 u8 cl32_fhkey[NFSCLNT_KEYMAX];
4557 };
4558
4559 struct nfsctl_export32 {
4560 s8 ex32_client[NFSCLNT_IDMAX+1];
4561 s8 ex32_path[NFS_MAXPATHLEN+1];
4562 __kernel_dev_t32 ex32_dev;
4563 __kernel_ino_t32 ex32_ino;
4564 s32 ex32_flags;
4565 __kernel_uid_t32 ex32_anon_uid;
4566 __kernel_gid_t32 ex32_anon_gid;
4567 };
4568
4569 struct nfsctl_uidmap32 {
4570 u32 ug32_ident; /* char * */
4571 __kernel_uid_t32 ug32_uidbase;
4572 s32 ug32_uidlen;
4573 u32 ug32_udimap; /* uid_t * */
4574 __kernel_uid_t32 ug32_gidbase;
4575 s32 ug32_gidlen;
4576 u32 ug32_gdimap; /* gid_t * */
4577 };
4578
4579 struct nfsctl_fhparm32 {
4580 struct sockaddr gf32_addr;
4581 __kernel_dev_t32 gf32_dev;
4582 __kernel_ino_t32 gf32_ino;
4583 s32 gf32_version;
4584 };
4585
4586 struct nfsctl_arg32 {
4587 s32 ca32_version; /* safeguard */
4588 union {
4589 struct nfsctl_svc32 u32_svc;
4590 struct nfsctl_client32 u32_client;
4591 struct nfsctl_export32 u32_export;
4592 struct nfsctl_uidmap32 u32_umap;
4593 struct nfsctl_fhparm32 u32_getfh;
4594 u32 u32_debug;
4595 } u;
4596 #define ca32_svc u.u32_svc
4597 #define ca32_client u.u32_client
4598 #define ca32_export u.u32_export
4599 #define ca32_umap u.u32_umap
4600 #define ca32_getfh u.u32_getfh
4601 #define ca32_authd u.u32_authd
4602 #define ca32_debug u.u32_debug
4603 };
4604
4605 union nfsctl_res32 {
4606 struct knfs_fh cr32_getfh;
4607 u32 cr32_debug;
4608 };
4609
4610 static int
4611 nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
4612 {
4613 int err;
4614
4615 err = __get_user(karg->ca_version, &arg32->ca32_version);
4616 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
4617 err |= __get_user(karg->ca_svc.svc_nthreads,
4618 &arg32->ca32_svc.svc32_nthreads);
4619 return err;
4620 }
4621
4622 static int
4623 nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
4624 {
4625 int err;
4626
4627 err = __get_user(karg->ca_version, &arg32->ca32_version);
4628 err |= copy_from_user(&karg->ca_client.cl_ident[0],
4629 &arg32->ca32_client.cl32_ident[0],
4630 NFSCLNT_IDMAX);
4631 err |= __get_user(karg->ca_client.cl_naddr,
4632 &arg32->ca32_client.cl32_naddr);
4633 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
4634 &arg32->ca32_client.cl32_addrlist[0],
4635 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
4636 err |= __get_user(karg->ca_client.cl_fhkeytype,
4637 &arg32->ca32_client.cl32_fhkeytype);
4638 err |= __get_user(karg->ca_client.cl_fhkeylen,
4639 &arg32->ca32_client.cl32_fhkeylen);
4640 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
4641 &arg32->ca32_client.cl32_fhkey[0],
4642 NFSCLNT_KEYMAX);
4643 return err;
4644 }
4645
4646 static int
4647 nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
4648 {
4649 int err;
4650
4651 err = __get_user(karg->ca_version, &arg32->ca32_version);
4652 err |= copy_from_user(&karg->ca_export.ex_client[0],
4653 &arg32->ca32_export.ex32_client[0],
4654 NFSCLNT_IDMAX);
4655 err |= copy_from_user(&karg->ca_export.ex_path[0],
4656 &arg32->ca32_export.ex32_path[0],
4657 NFS_MAXPATHLEN);
4658 err |= __get_user(karg->ca_export.ex_dev,
4659 &arg32->ca32_export.ex32_dev);
4660 err |= __get_user(karg->ca_export.ex_ino,
4661 &arg32->ca32_export.ex32_ino);
4662 err |= __get_user(karg->ca_export.ex_flags,
4663 &arg32->ca32_export.ex32_flags);
4664 err |= __get_user(karg->ca_export.ex_anon_uid,
4665 &arg32->ca32_export.ex32_anon_uid);
4666 err |= __get_user(karg->ca_export.ex_anon_gid,
4667 &arg32->ca32_export.ex32_anon_gid);
4668 return err;
4669 }
4670
4671 static int
4672 nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
4673 {
4674 u32 uaddr;
4675 int i;
4676 int err;
4677
4678 memset(karg, 0, sizeof(*karg));
4679 if(__get_user(karg->ca_version, &arg32->ca32_version))
4680 return -EFAULT;
4681 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
4682 if(!karg->ca_umap.ug_ident)
4683 return -ENOMEM;
4684 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
4685 if(strncpy_from_user(karg->ca_umap.ug_ident,
4686 (char *)A(uaddr), PAGE_SIZE) <= 0)
4687 return -EFAULT;
4688 err |= __get_user(karg->ca_umap.ug_uidbase,
4689 &arg32->ca32_umap.ug32_uidbase);
4690 err |= __get_user(karg->ca_umap.ug_uidlen,
4691 &arg32->ca32_umap.ug32_uidlen);
4692 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
4693 if (err)
4694 return -EFAULT;
4695 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) *
4696 karg->ca_umap.ug_uidlen),
4697 GFP_USER);
4698 if(!karg->ca_umap.ug_udimap)
4699 return -ENOMEM;
4700 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
4701 err |= __get_user(karg->ca_umap.ug_udimap[i],
4702 &(((__kernel_uid_t32 *)A(uaddr))[i]));
4703 err |= __get_user(karg->ca_umap.ug_gidbase,
4704 &arg32->ca32_umap.ug32_gidbase);
4705 err |= __get_user(karg->ca_umap.ug_uidlen,
4706 &arg32->ca32_umap.ug32_gidlen);
4707 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
4708 if (err)
4709 return -EFAULT;
4710 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) *
4711 karg->ca_umap.ug_uidlen),
4712 GFP_USER);
4713 if(!karg->ca_umap.ug_gdimap)
4714 return -ENOMEM;
4715 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
4716 err |= __get_user(karg->ca_umap.ug_gdimap[i],
4717 &(((__kernel_gid_t32 *)A(uaddr))[i]));
4718
4719 return err;
4720 }
4721
4722 static int
4723 nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
4724 {
4725 int err;
4726
4727 err = __get_user(karg->ca_version, &arg32->ca32_version);
4728 err |= copy_from_user(&karg->ca_getfh.gf_addr,
4729 &arg32->ca32_getfh.gf32_addr,
4730 (sizeof(struct sockaddr)));
4731 err |= __get_user(karg->ca_getfh.gf_dev,
4732 &arg32->ca32_getfh.gf32_dev);
4733 err |= __get_user(karg->ca_getfh.gf_ino,
4734 &arg32->ca32_getfh.gf32_ino);
4735 err |= __get_user(karg->ca_getfh.gf_version,
4736 &arg32->ca32_getfh.gf32_version);
4737 return err;
4738 }
4739
4740 static int
4741 nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
4742 {
4743 int err;
4744
4745 err = copy_to_user(&res32->cr32_getfh,
4746 &kres->cr_getfh,
4747 sizeof(res32->cr32_getfh));
4748 err |= __put_user(kres->cr_debug, &res32->cr32_debug);
4749 return err;
4750 }
4751
4752 extern asmlinkage long sys_nfsservctl(int cmd, void *arg, void *resp);
4753
4754 int asmlinkage
4755 sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
4756 {
4757 struct nfsctl_arg *karg = NULL;
4758 union nfsctl_res *kres = NULL;
4759 mm_segment_t oldfs;
4760 int err;
4761
4762 karg = kmalloc(sizeof(*karg), GFP_USER);
4763 if(!karg)
4764 return -ENOMEM;
4765 if(res32) {
4766 kres = kmalloc(sizeof(*kres), GFP_USER);
4767 if(!kres) {
4768 kfree(karg);
4769 return -ENOMEM;
4770 }
4771 }
4772 switch(cmd) {
4773 case NFSCTL_SVC:
4774 err = nfs_svc32_trans(karg, arg32);
4775 break;
4776 case NFSCTL_ADDCLIENT:
4777 err = nfs_clnt32_trans(karg, arg32);
4778 break;
4779 case NFSCTL_DELCLIENT:
4780 err = nfs_clnt32_trans(karg, arg32);
4781 break;
4782 case NFSCTL_EXPORT:
4783 err = nfs_exp32_trans(karg, arg32);
4784 break;
4785 /* This one is unimplemented, be we're ready for it. */
4786 case NFSCTL_UGIDUPDATE:
4787 err = nfs_uud32_trans(karg, arg32);
4788 break;
4789 case NFSCTL_GETFH:
4790 err = nfs_getfh32_trans(karg, arg32);
4791 break;
4792 default:
4793 err = -EINVAL;
4794 break;
4795 }
4796 if(err)
4797 goto done;
4798 oldfs = get_fs();
4799 set_fs(KERNEL_DS);
4800 err = sys_nfsservctl(cmd, karg, kres);
4801 set_fs(oldfs);
4802
4803 if(!err && cmd == NFSCTL_GETFH)
4804 err = nfs_getfh32_res_trans(kres, res32);
4805
4806 done:
4807 if(karg) {
4808 if(cmd == NFSCTL_UGIDUPDATE) {
4809 if(karg->ca_umap.ug_ident)
4810 kfree(karg->ca_umap.ug_ident);
4811 if(karg->ca_umap.ug_udimap)
4812 kfree(karg->ca_umap.ug_udimap);
4813 if(karg->ca_umap.ug_gdimap)
4814 kfree(karg->ca_umap.ug_gdimap);
4815 }
4816 kfree(karg);
4817 }
4818 if(kres)
4819 kfree(kres);
4820 return err;
4821 }
4822
4823 asmlinkage long sys_utimes(char *, struct timeval *);
4824
4825 asmlinkage long
4826 sys32_utimes(char *filename, struct timeval32 *tvs)
4827 {
4828 char *kfilename;
4829 struct timeval ktvs[2];
4830 mm_segment_t old_fs;
4831 int ret;
4832
4833 kfilename = getname32(filename);
4834 ret = PTR_ERR(kfilename);
4835 if (!IS_ERR(kfilename)) {
4836 if (tvs) {
4837 if (get_tv32(&ktvs[0], tvs) ||
4838 get_tv32(&ktvs[1], 1+tvs))
4839 return -EFAULT;
4840 }
4841
4842 old_fs = get_fs();
4843 set_fs(KERNEL_DS);
4844 ret = sys_utimes(kfilename, &ktvs[0]);
4845 set_fs(old_fs);
4846
4847 putname(kfilename);
4848 }
4849 return ret;
4850 }
4851
4852 /* These are here just in case some old ia32 binary calls it. */
4853 asmlinkage long
4854 sys32_pause(void)
4855 {
4856 current->state = TASK_INTERRUPTIBLE;
4857 schedule();
4858 return -ERESTARTNOHAND;
4859 }
4860
4861 /* PCI config space poking. */
4862 extern asmlinkage long sys_pciconfig_read(unsigned long bus,
4863 unsigned long dfn,
4864 unsigned long off,
4865 unsigned long len,
4866 unsigned char *buf);
4867
4868 extern asmlinkage long sys_pciconfig_write(unsigned long bus,
4869 unsigned long dfn,
4870 unsigned long off,
4871 unsigned long len,
4872 unsigned char *buf);
4873
4874 asmlinkage long
4875 sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
4876 {
4877 return sys_pciconfig_read((unsigned long) bus,
4878 (unsigned long) dfn,
4879 (unsigned long) off,
4880 (unsigned long) len,
4881 (unsigned char *)AA(ubuf));
4882 }
4883
4884 asmlinkage long
4885 sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
4886 {
4887 return sys_pciconfig_write((unsigned long) bus,
4888 (unsigned long) dfn,
4889 (unsigned long) off,
4890 (unsigned long) len,
4891 (unsigned char *)AA(ubuf));
4892 }
4893
4894 extern asmlinkage long sys_prctl(int option, unsigned long arg2,
4895 unsigned long arg3, unsigned long arg4,
4896 unsigned long arg5);
4897
4898 asmlinkage long
4899 sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
4900 {
4901 return sys_prctl(option,
4902 (unsigned long) arg2,
4903 (unsigned long) arg3,
4904 (unsigned long) arg4,
4905 (unsigned long) arg5);
4906 }
4907
4908
4909 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
4910 size_t count, loff_t pos);
4911
4912 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
4913 size_t count, loff_t pos);
4914
4915 typedef __kernel_ssize_t32 ssize_t32;
4916
4917 asmlinkage ssize_t32
4918 sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count,
4919 u32 poshi, u32 poslo)
4920 {
4921 return sys_pread(fd, ubuf, count,
4922 ((loff_t)AA(poshi) << 32) | AA(poslo));
4923 }
4924
4925 asmlinkage ssize_t32
4926 sys32_pwrite(unsigned int fd, char *ubuf, __kernel_size_t32 count,
4927 u32 poshi, u32 poslo)
4928 {
4929 return sys_pwrite(fd, ubuf, count,
4930 ((loff_t)AA(poshi) << 32) | AA(poslo));
4931 }
4932
4933
4934 extern asmlinkage long sys_personality(unsigned long);
4935
4936 asmlinkage long
4937 sys32_personality(unsigned long personality)
4938 {
4939 int ret;
4940 if (current->personality == PER_LINUX32 && personality == PER_LINUX)
4941 personality = PER_LINUX32;
4942 ret = sys_personality(personality);
4943 if (ret == PER_LINUX32)
4944 ret = PER_LINUX;
4945 return ret;
4946 }
4947
4948 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset,
4949 size_t count);
4950
4951 asmlinkage long
4952 sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4953 {
4954 mm_segment_t old_fs = get_fs();
4955 int ret;
4956 off_t of;
4957
4958 if (offset && get_user(of, offset))
4959 return -EFAULT;
4960
4961 set_fs(KERNEL_DS);
4962 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4963 set_fs(old_fs);
4964
4965 if (!ret && offset && put_user(of, offset))
4966 return -EFAULT;
4967
4968 return ret;
4969 }
4970
4971 /* Handle adjtimex compatability. */
4972
4973 struct timex32 {
4974 u32 modes;
4975 s32 offset, freq, maxerror, esterror;
4976 s32 status, constant, precision, tolerance;
4977 struct timeval32 time;
4978 s32 tick;
4979 s32 ppsfreq, jitter, shift, stabil;
4980 s32 jitcnt, calcnt, errcnt, stbcnt;
4981 s32 :32; s32 :32; s32 :32; s32 :32;
4982 s32 :32; s32 :32; s32 :32; s32 :32;
4983 s32 :32; s32 :32; s32 :32; s32 :32;
4984 };
4985
4986 extern int do_adjtimex(struct timex *);
4987
4988 asmlinkage long
4989 sys32_adjtimex(struct timex32 *utp)
4990 {
4991 struct timex txc;
4992 int ret;
4993
4994 memset(&txc, 0, sizeof(struct timex));
4995
4996 if(get_user(txc.modes, &utp->modes) ||
4997 __get_user(txc.offset, &utp->offset) ||
4998 __get_user(txc.freq, &utp->freq) ||
4999 __get_user(txc.maxerror, &utp->maxerror) ||
5000 __get_user(txc.esterror, &utp->esterror) ||
5001 __get_user(txc.status, &utp->status) ||
5002 __get_user(txc.constant, &utp->constant) ||
5003 __get_user(txc.precision, &utp->precision) ||
5004 __get_user(txc.tolerance, &utp->tolerance) ||
5005 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
5006 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
5007 __get_user(txc.tick, &utp->tick) ||
5008 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
5009 __get_user(txc.jitter, &utp->jitter) ||
5010 __get_user(txc.shift, &utp->shift) ||
5011 __get_user(txc.stabil, &utp->stabil) ||
5012 __get_user(txc.jitcnt, &utp->jitcnt) ||
5013 __get_user(txc.calcnt, &utp->calcnt) ||
5014 __get_user(txc.errcnt, &utp->errcnt) ||
5015 __get_user(txc.stbcnt, &utp->stbcnt))
5016 return -EFAULT;
5017
5018 ret = do_adjtimex(&txc);
5019
5020 if(put_user(txc.modes, &utp->modes) ||
5021 __put_user(txc.offset, &utp->offset) ||
5022 __put_user(txc.freq, &utp->freq) ||
5023 __put_user(txc.maxerror, &utp->maxerror) ||
5024 __put_user(txc.esterror, &utp->esterror) ||
5025 __put_user(txc.status, &utp->status) ||
5026 __put_user(txc.constant, &utp->constant) ||
5027 __put_user(txc.precision, &utp->precision) ||
5028 __put_user(txc.tolerance, &utp->tolerance) ||
5029 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
5030 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
5031 __put_user(txc.tick, &utp->tick) ||
5032 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
5033 __put_user(txc.jitter, &utp->jitter) ||
5034 __put_user(txc.shift, &utp->shift) ||
5035 __put_user(txc.stabil, &utp->stabil) ||
5036 __put_user(txc.jitcnt, &utp->jitcnt) ||
5037 __put_user(txc.calcnt, &utp->calcnt) ||
5038 __put_user(txc.errcnt, &utp->errcnt) ||
5039 __put_user(txc.stbcnt, &utp->stbcnt))
5040 ret = -EFAULT;
5041
5042 return ret;
5043 }
5044 #endif // NOTYET
5045