1
2
3
4
5
6
7
8#include <linux/config.h>
9#include <linux/mm.h>
10#include <linux/errno.h>
11#include <linux/file.h>
12#include <linux/smp_lock.h>
13#include <linux/highuid.h>
14#include <linux/dirent.h>
15#include <linux/resource.h>
16#include <linux/highmem.h>
17#include <linux/time.h>
18#include <linux/poll.h>
19#include <linux/slab.h>
20#include <linux/skbuff.h>
21#include <linux/filter.h>
22#include <linux/shm.h>
23#include <linux/sem.h>
24#include <linux/msg.h>
25#include <linux/icmpv6.h>
26#include <linux/sysctl.h>
27#include <linux/utime.h>
28#include <linux/utsname.h>
29#include <linux/personality.h>
30#include <linux/timex.h>
31#include <linux/dnotify.h>
32#include <linux/linkage.h>
33#include <linux/module.h>
34#include <net/sock.h>
35#include <net/scm.h>
36
37#include <asm/uaccess.h>
38#include <asm/mman.h>
39#include <asm/ipc.h>
40
41extern asmlinkage long sys_socket(int family, int type, int protocol);
42extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
43extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,
44 int addrlen);
45extern asmlinkage long sys_listen(int fd, int backlog);
46extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,
47 int *upeer_addrlen);
48extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
49 int *usockaddr_len);
50extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
51 int *usockaddr_len);
52extern asmlinkage long sys_socketpair(int family, int type, int protocol,
53 int *usockvec);
54extern asmlinkage long sys_send(int fd, void * buff, size_t len,
55 unsigned flags);
56extern asmlinkage long sys_sendto(int fd, void * buff, size_t len,
57 unsigned flags, struct sockaddr *addr, int addr_len);
58extern asmlinkage long sys_recv(int fd, void * ubuf, size_t size,
59 unsigned flags);
60extern asmlinkage long sys_recvfrom(int fd, void * ubuf, size_t size,
61 unsigned flags, struct sockaddr *addr, int *addr_len);
62extern asmlinkage long sys_shutdown(int fd, int how);
63extern asmlinkage long sys_setsockopt(int fd, int level, int optname,
64 char *optval, int optlen);
65extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
66 char *optval, int *optlen);
67extern asmlinkage long sys_sendmsg(int fd, struct msghdr *msg, unsigned flags);
68extern asmlinkage long sys_recvmsg(int fd, struct msghdr *msg,
69 unsigned int flags);
70
71
72
73
74
75
76
77
78
79
80#define A(__x) ((unsigned long)(__x))
81#define AA(__x) ((unsigned long)((int)__x))
82
83#ifdef __MIPSEB__
84#define merge_64(r1,r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
85#endif
86#ifdef __MIPSEL__
87#define merge_64(r1,r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
88#endif
89
90
91
92
93static __inline__ int
94do_revalidate(struct dentry *dentry)
95{
96 struct inode * inode = dentry->d_inode;
97
98 if (inode->i_op && inode->i_op->revalidate)
99 return inode->i_op->revalidate(dentry);
100
101 return 0;
102}
103
104static int cp_new_stat32(struct inode * inode, struct stat32 * statbuf)
105{
106 struct stat32 tmp;
107 unsigned int blocks, indirect;
108
109 memset(&tmp, 0, sizeof(tmp));
110 tmp.st_dev = kdev_t_to_nr(inode->i_dev);
111 tmp.st_ino = inode->i_ino;
112 tmp.st_mode = inode->i_mode;
113 tmp.st_nlink = inode->i_nlink;
114 SET_STAT_UID(tmp, inode->i_uid);
115 SET_STAT_GID(tmp, inode->i_gid);
116 tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
117 tmp.st_size = inode->i_size;
118 tmp.st_atime = inode->i_atime;
119 tmp.st_mtime = inode->i_mtime;
120 tmp.st_ctime = inode->i_ctime;
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137#define D_B 7
138#define I_B (BLOCK_SIZE / sizeof(unsigned short))
139
140 if (!inode->i_blksize) {
141 blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
142 if (blocks > D_B) {
143 indirect = (blocks - D_B + I_B - 1) / I_B;
144 blocks += indirect;
145 if (indirect > 1) {
146 indirect = (indirect - 1 + I_B - 1) / I_B;
147 blocks += indirect;
148 if (indirect > 1)
149 blocks++;
150 }
151 }
152 tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
153 tmp.st_blksize = BLOCK_SIZE;
154 } else {
155 tmp.st_blocks = inode->i_blocks;
156 tmp.st_blksize = inode->i_blksize;
157 }
158
159 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
160}
161
162asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
163{
164 struct nameidata nd;
165 int error;
166
167 error = user_path_walk(filename, &nd);
168 if (!error) {
169 error = do_revalidate(nd.dentry);
170 if (!error)
171 error = cp_new_stat32(nd.dentry->d_inode, statbuf);
172
173 path_release(&nd);
174 }
175
176 return error;
177}
178
179asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
180{
181 struct nameidata nd;
182 int error;
183
184 error = user_path_walk_link(filename, &nd);
185 if (!error) {
186 error = do_revalidate(nd.dentry);
187 if (!error)
188 error = cp_new_stat32(nd.dentry->d_inode, statbuf);
189
190 path_release(&nd);
191 }
192
193 return error;
194}
195
196asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 * statbuf)
197{
198 struct file * f;
199 int err = -EBADF;
200
201 f = fget(fd);
202 if (f) {
203 struct dentry * dentry = f->f_dentry;
204
205 err = do_revalidate(dentry);
206 if (!err)
207 err = cp_new_stat32(dentry->d_inode, statbuf);
208 fput(f);
209 }
210
211 return err;
212}
213
214asmlinkage unsigned long
215sys32_mmap2(unsigned long addr, size_t len, unsigned long prot,
216 unsigned long flags, unsigned long fd, unsigned long pgoff)
217{
218 struct file * file = NULL;
219 unsigned long error;
220
221 error = -EINVAL;
222 if (!(flags & MAP_ANONYMOUS)) {
223 error = -EBADF;
224 file = fget(fd);
225 if (!file)
226 goto out;
227 }
228 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
229
230 down_write(¤t->mm->mmap_sem);
231 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
232 up_write(¤t->mm->mmap_sem);
233 if (file)
234 fput(file);
235
236out:
237 return error;
238}
239
240
241asmlinkage long sys_truncate(const char * path, unsigned long length);
242
243asmlinkage int sys_truncate64(const char *path, unsigned int high,
244 unsigned int low)
245{
246 if ((int)high < 0)
247 return -EINVAL;
248 return sys_truncate(path, ((long) high << 32) | low);
249}
250
251asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
252
253asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high,
254 unsigned int low)
255{
256 if ((int)high < 0)
257 return -EINVAL;
258 return sys_ftruncate(fd, ((long) high << 32) | low);
259}
260
261extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
262
263struct utimbuf32 {
264 __kernel_time_t32 actime, modtime;
265};
266
267asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
268{
269 struct utimbuf t;
270 mm_segment_t old_fs;
271 int ret;
272 char *filenam;
273
274 if (!times)
275 return sys_utime(filename, NULL);
276 if (get_user (t.actime, ×->actime) ||
277 __get_user (t.modtime, ×->modtime))
278 return -EFAULT;
279 filenam = getname (filename);
280 ret = PTR_ERR(filenam);
281 if (!IS_ERR(filenam)) {
282 old_fs = get_fs();
283 set_fs (KERNEL_DS);
284 ret = sys_utime(filenam, &t);
285 set_fs (old_fs);
286 putname (filenam);
287 }
288 return ret;
289}
290
291#if 0
292
293
294
295static int count32(u32 * argv, int max)
296{
297 int i = 0;
298
299 if (argv != NULL) {
300 for (;;) {
301 u32 p; int error;
302
303 error = get_user(p,argv);
304 if (error)
305 return error;
306 if (!p)
307 break;
308 argv++;
309 if (++i > max)
310 return -E2BIG;
311 }
312 }
313 return i;
314}
315
316
317
318
319
320
321
322int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
323{
324 while (argc-- > 0) {
325 u32 str;
326 int len;
327 unsigned long pos;
328
329 if (get_user(str, argv+argc) || !str ||
330 !(len = strnlen_user((char *)A(str), bprm->p)))
331 return -EFAULT;
332 if (bprm->p < len)
333 return -E2BIG;
334
335 bprm->p -= len;
336
337
338 pos = bprm->p;
339 while (len > 0) {
340 char *kaddr;
341 int i, new, err;
342 struct page *page;
343 int offset, bytes_to_copy;
344
345 offset = pos % PAGE_SIZE;
346 i = pos/PAGE_SIZE;
347 page = bprm->page[i];
348 new = 0;
349 if (!page) {
350 page = alloc_page(GFP_HIGHUSER);
351 bprm->page[i] = page;
352 if (!page)
353 return -ENOMEM;
354 new = 1;
355 }
356 kaddr = kmap(page);
357
358 if (new && offset)
359 memset(kaddr, 0, offset);
360 bytes_to_copy = PAGE_SIZE - offset;
361 if (bytes_to_copy > len) {
362 bytes_to_copy = len;
363 if (new)
364 memset(kaddr+offset+len, 0,
365 PAGE_SIZE-offset-len);
366 }
367 err = copy_from_user(kaddr + offset, (char *)A(str),
368 bytes_to_copy);
369 kunmap(page);
370
371 if (err)
372 return -EFAULT;
373
374 pos += bytes_to_copy;
375 str += bytes_to_copy;
376 len -= bytes_to_copy;
377 }
378 }
379 return 0;
380}
381
382
383
384
385
386int do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
387{
388 struct linux_binprm bprm;
389 struct dentry * dentry;
390 int retval;
391 int i;
392
393 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
394 memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
395
396 dentry = open_namei(filename, 0, 0);
397 retval = PTR_ERR(dentry);
398 if (IS_ERR(dentry))
399 return retval;
400
401 bprm.dentry = dentry;
402 bprm.filename = filename;
403 bprm.sh_bang = 0;
404 bprm.loader = 0;
405 bprm.exec = 0;
406 if ((bprm.argc = count32(argv, bprm.p / sizeof(u32))) < 0) {
407 dput(dentry);
408 return bprm.argc;
409 }
410
411 if ((bprm.envc = count32(envp, bprm.p / sizeof(u32))) < 0) {
412 dput(dentry);
413 return bprm.envc;
414 }
415
416 retval = prepare_binprm(&bprm);
417 if (retval < 0)
418 goto out;
419
420 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
421 if (retval < 0)
422 goto out;
423
424 bprm.exec = bprm.p;
425 retval = copy_strings32(bprm.envc, envp, &bprm);
426 if (retval < 0)
427 goto out;
428
429 retval = copy_strings32(bprm.argc, argv, &bprm);
430 if (retval < 0)
431 goto out;
432
433 retval = search_binary_handler(&bprm,regs);
434 if (retval >= 0)
435
436 return retval;
437
438out:
439
440 if (bprm.dentry)
441 dput(bprm.dentry);
442
443
444
445 for (i = 0 ; i < MAX_ARG_PAGES ; i++)
446 if (bprm.page[i])
447 __free_page(bprm.page[i]);
448
449 return retval;
450}
451
452
453
454
455asmlinkage int sys32_execve(abi64_no_regargs, struct pt_regs regs)
456{
457 int error;
458 char * filename;
459
460 filename = getname((char *) (long)regs.regs[4]);
461 printk("Executing: %s\n", filename);
462 error = PTR_ERR(filename);
463 if (IS_ERR(filename))
464 goto out;
465 error = do_execve32(filename, (u32 *) (long)regs.regs[5],
466 (u32 *) (long)regs.regs[6], ®s);
467 putname(filename);
468
469out:
470 return error;
471}
472#else
473static int nargs(unsigned int arg, char **ap)
474{
475 unsigned int addr;
476 int n, err;
477
478 if (!arg)
479 return 0;
480
481 n = 0;
482 do {
483 err = get_user(addr, (unsigned int *)A(arg));
484 if (err)
485 return err;
486 if (ap)
487 *ap++ = (char *) A(addr);
488 arg += sizeof(unsigned int);
489 n++;
490 } while (addr);
491 return n - 1;
492}
493
494asmlinkage int
495sys32_execve(abi64_no_regargs, struct pt_regs regs)
496{
497 extern asmlinkage int sys_execve(abi64_no_regargs, struct pt_regs regs);
498 extern asmlinkage long sys_munmap(unsigned long addr, size_t len);
499 unsigned int argv = (unsigned int)regs.regs[5];
500 unsigned int envp = (unsigned int)regs.regs[6];
501 char **av, **ae;
502 int na, ne, r, len;
503 char * filename;
504
505 na = nargs(argv, NULL);
506 if (na < 0)
507 return na;
508 ne = nargs(envp, NULL);
509 if (ne < 0)
510 return ne;
511 len = (na + ne + 2) * sizeof(*av);
512
513
514
515
516
517
518
519
520
521 down_write(¤t->mm->mmap_sem);
522 av = (char **) do_mmap_pgoff(0, 0, len, PROT_READ | PROT_WRITE,
523 MAP_PRIVATE | MAP_ANONYMOUS, 0);
524 up_write(¤t->mm->mmap_sem);
525
526 if (IS_ERR(av))
527 return (long) av;
528 ae = av + na + 1;
529 r = __put_user(0, (av + na));
530 r |= __put_user(0, (ae + ne));
531 if (r)
532 goto out;
533 r = nargs(argv, av);
534 if (r < 0)
535 goto out;
536 r = nargs(envp, ae);
537 if (r < 0)
538 goto out;
539 filename = getname((char *) (long)regs.regs[4]);
540 r = PTR_ERR(filename);
541 if (IS_ERR(filename))
542 goto out;
543
544 r = do_execve(filename, av, ae, ®s);
545 putname(filename);
546 if (r)
547out:
548 sys_munmap((unsigned long)av, len);
549 return r ;
550}
551#endif
552
553struct dirent32 {
554 unsigned int d_ino;
555 unsigned int d_off;
556 unsigned short d_reclen;
557 char d_name[NAME_MAX + 1];
558};
559
560static void
561xlate_dirent(void *dirent64, void *dirent32, long n)
562{
563 long off;
564 struct dirent *dirp;
565 struct dirent32 *dirp32;
566
567 off = 0;
568 while (off < n) {
569 dirp = (struct dirent *)(dirent64 + off);
570 dirp32 = (struct dirent32 *)(dirent32 + off);
571 off += dirp->d_reclen;
572 dirp32->d_ino = dirp->d_ino;
573 dirp32->d_off = (unsigned int)dirp->d_off;
574 dirp32->d_reclen = dirp->d_reclen;
575 strncpy(dirp32->d_name, dirp->d_name, dirp->d_reclen - ((3 * 4) + 2));
576 }
577 return;
578}
579
580asmlinkage long sys_getdents(unsigned int fd, void * dirent, unsigned int count);
581
582asmlinkage long
583sys32_getdents(unsigned int fd, void * dirent32, unsigned int count)
584{
585 long n;
586 void *dirent64;
587
588 dirent64 = (void *)((unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1));
589 if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)
590 return(n);
591 xlate_dirent(dirent64, dirent32, n);
592 return(n);
593}
594
595asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count);
596
597asmlinkage int
598sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
599{
600 int n;
601 struct dirent dirent64;
602
603 if ((n = old_readdir(fd, &dirent64, count)) < 0)
604 return(n);
605 xlate_dirent(&dirent64, dirent32, dirent64.d_reclen);
606 return(n);
607}
608
609struct timeval32
610{
611 int tv_sec, tv_usec;
612};
613
614struct itimerval32
615{
616 struct timeval32 it_interval;
617 struct timeval32 it_value;
618};
619
620struct rusage32 {
621 struct timeval32 ru_utime;
622 struct timeval32 ru_stime;
623 int ru_maxrss;
624 int ru_ixrss;
625 int ru_idrss;
626 int ru_isrss;
627 int ru_minflt;
628 int ru_majflt;
629 int ru_nswap;
630 int ru_inblock;
631 int ru_oublock;
632 int ru_msgsnd;
633 int ru_msgrcv;
634 int ru_nsignals;
635 int ru_nvcsw;
636 int ru_nivcsw;
637};
638
639static int
640put_rusage (struct rusage32 *ru, struct rusage *r)
641{
642 int err;
643
644 if (verify_area(VERIFY_WRITE, ru, sizeof *ru))
645 return -EFAULT;
646
647 err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
648 err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
649 err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
650 err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
651 err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
652 err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
653 err |= __put_user (r->ru_idrss, &ru->ru_idrss);
654 err |= __put_user (r->ru_isrss, &ru->ru_isrss);
655 err |= __put_user (r->ru_minflt, &ru->ru_minflt);
656 err |= __put_user (r->ru_majflt, &ru->ru_majflt);
657 err |= __put_user (r->ru_nswap, &ru->ru_nswap);
658 err |= __put_user (r->ru_inblock, &ru->ru_inblock);
659 err |= __put_user (r->ru_oublock, &ru->ru_oublock);
660 err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
661 err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
662 err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
663 err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
664 err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
665
666 return err;
667}
668
669asmlinkage int
670sys32_wait4(__kernel_pid_t32 pid, unsigned int * stat_addr, int options,
671 struct rusage32 * ru)
672{
673 if (!ru)
674 return sys_wait4(pid, stat_addr, options, NULL);
675 else {
676 struct rusage r;
677 int ret;
678 unsigned int status;
679 mm_segment_t old_fs = get_fs();
680
681 set_fs(KERNEL_DS);
682 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
683 set_fs(old_fs);
684 if (put_rusage (ru, &r)) return -EFAULT;
685 if (stat_addr && put_user (status, stat_addr))
686 return -EFAULT;
687 return ret;
688 }
689}
690
691asmlinkage int
692sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
693{
694 return sys32_wait4(pid, stat_addr, options, NULL);
695}
696
697struct sysinfo32 {
698 s32 uptime;
699 u32 loads[3];
700 u32 totalram;
701 u32 freeram;
702 u32 sharedram;
703 u32 bufferram;
704 u32 totalswap;
705 u32 freeswap;
706 u16 procs;
707 u32 totalhigh;
708 u32 freehigh;
709 u32 mem_unit;
710 char _f[8];
711};
712
713extern asmlinkage int sys_sysinfo(struct sysinfo *info);
714
715asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
716{
717 struct sysinfo s;
718 int ret, err;
719 mm_segment_t old_fs = get_fs ();
720
721 set_fs (KERNEL_DS);
722 ret = sys_sysinfo(&s);
723 set_fs (old_fs);
724 err = put_user (s.uptime, &info->uptime);
725 err |= __put_user (s.loads[0], &info->loads[0]);
726 err |= __put_user (s.loads[1], &info->loads[1]);
727 err |= __put_user (s.loads[2], &info->loads[2]);
728 err |= __put_user (s.totalram, &info->totalram);
729 err |= __put_user (s.freeram, &info->freeram);
730 err |= __put_user (s.sharedram, &info->sharedram);
731 err |= __put_user (s.bufferram, &info->bufferram);
732 err |= __put_user (s.totalswap, &info->totalswap);
733 err |= __put_user (s.freeswap, &info->freeswap);
734 err |= __put_user (s.procs, &info->procs);
735 err |= __put_user (s.totalhigh, &info->totalhigh);
736 err |= __put_user (s.freehigh, &info->freehigh);
737 err |= __put_user (s.mem_unit, &info->mem_unit);
738 if (err)
739 return -EFAULT;
740 return ret;
741}
742
743#define RLIM_INFINITY32 0x7fffffff
744#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
745
746struct rlimit32 {
747 int rlim_cur;
748 int rlim_max;
749};
750
751extern asmlinkage int sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);
752
753asmlinkage int
754sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
755{
756 struct rlimit r;
757 int ret;
758 mm_segment_t old_fs = get_fs ();
759
760 set_fs (KERNEL_DS);
761 ret = sys_old_getrlimit(resource, &r);
762 set_fs (old_fs);
763 if (!ret) {
764 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
765 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
766 }
767 return ret;
768}
769
770extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
771
772asmlinkage int
773sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
774{
775 struct rlimit r;
776 int ret;
777 mm_segment_t old_fs = get_fs ();
778
779 if (resource >= RLIM_NLIMITS) return -EINVAL;
780 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
781 __get_user (r.rlim_max, &rlim->rlim_max))
782 return -EFAULT;
783 if (r.rlim_cur == RLIM_INFINITY32)
784 r.rlim_cur = RLIM_INFINITY;
785 if (r.rlim_max == RLIM_INFINITY32)
786 r.rlim_max = RLIM_INFINITY;
787 set_fs (KERNEL_DS);
788 ret = sys_setrlimit(resource, &r);
789 set_fs (old_fs);
790 return ret;
791}
792
793struct statfs32 {
794 int f_type;
795 int f_bsize;
796 int f_frsize;
797 int f_blocks;
798 int f_bfree;
799 int f_files;
800 int f_ffree;
801 int f_bavail;
802 __kernel_fsid_t32 f_fsid;
803 int f_namelen;
804 int f_spare[6];
805};
806
807static inline int
808put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
809{
810 int err;
811
812 err = put_user (kbuf->f_type, &ubuf->f_type);
813 err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
814 err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
815 err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
816 err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
817 err |= __put_user (kbuf->f_files, &ubuf->f_files);
818 err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
819 err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
820 err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
821 err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
822 return err;
823}
824
825extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
826
827asmlinkage int
828sys32_statfs(const char * path, struct statfs32 *buf)
829{
830 int ret;
831 struct statfs s;
832 mm_segment_t old_fs = get_fs();
833 char *pth;
834
835 pth = getname (path);
836 ret = PTR_ERR(pth);
837 if (!IS_ERR(pth)) {
838 set_fs (KERNEL_DS);
839 ret = sys_statfs((const char *)path, &s);
840 set_fs (old_fs);
841 if (!ret && put_statfs(buf, &s))
842 return -EFAULT;
843 }
844 return ret;
845}
846
847extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
848
849asmlinkage int
850sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
851{
852 int ret;
853 struct statfs s;
854 mm_segment_t old_fs = get_fs();
855
856 set_fs (KERNEL_DS);
857 ret = sys_fstatfs(fd, &s);
858 set_fs (old_fs);
859 if (put_statfs(buf, &s))
860 return -EFAULT;
861 return ret;
862}
863
864#ifdef __MIPSEB__
865asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,
866 int length_hi, int length_lo)
867#endif
868#ifdef __MIPSEL__
869asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,
870 int length_lo, int length_hi)
871#endif
872{
873 loff_t length;
874
875 length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
876
877 return sys_truncate(path, length);
878}
879
880#ifdef __MIPSEB__
881asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
882 int length_hi, int length_lo)
883#endif
884#ifdef __MIPSEL__
885asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
886 int length_lo, int length_hi)
887#endif
888{
889 loff_t length;
890
891 length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
892
893 return sys_ftruncate(fd, length);
894}
895
896extern asmlinkage int
897sys_getrusage(int who, struct rusage *ru);
898
899asmlinkage int
900sys32_getrusage(int who, struct rusage32 *ru)
901{
902 struct rusage r;
903 int ret;
904 mm_segment_t old_fs = get_fs();
905
906 set_fs (KERNEL_DS);
907 ret = sys_getrusage(who, &r);
908 set_fs (old_fs);
909 if (put_rusage (ru, &r))
910 return -EFAULT;
911
912 return ret;
913}
914
915static inline long
916get_tv32(struct timeval *o, struct timeval32 *i)
917{
918 return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
919 (__get_user(o->tv_sec, &i->tv_sec) |
920 __get_user(o->tv_usec, &i->tv_usec)));
921}
922
923static inline long
924get_it32(struct itimerval *o, struct itimerval32 *i)
925{
926 return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
927 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
928 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
929 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
930 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
931}
932
933static inline long
934put_tv32(struct timeval32 *o, struct timeval *i)
935{
936 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
937 (__put_user(i->tv_sec, &o->tv_sec) |
938 __put_user(i->tv_usec, &o->tv_usec)));
939}
940
941static inline long
942put_it32(struct itimerval32 *o, struct itimerval *i)
943{
944 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
945 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
946 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
947 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
948 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
949}
950
951extern int do_getitimer(int which, struct itimerval *value);
952
953asmlinkage int
954sys32_getitimer(int which, struct itimerval32 *it)
955{
956 struct itimerval kit;
957 int error;
958
959 error = do_getitimer(which, &kit);
960 if (!error && put_it32(it, &kit))
961 error = -EFAULT;
962
963 return error;
964}
965
966extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
967
968
969asmlinkage int
970sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
971{
972 struct itimerval kin, kout;
973 int error;
974
975 if (in) {
976 if (get_it32(&kin, in))
977 return -EFAULT;
978 } else
979 memset(&kin, 0, sizeof(kin));
980
981 error = do_setitimer(which, &kin, out ? &kout : NULL);
982 if (error || !out)
983 return error;
984 if (put_it32(out, &kout))
985 return -EFAULT;
986
987 return 0;
988}
989
990
991
992
993
994extern struct timezone sys_tz;
995extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
996
997asmlinkage int
998sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
999{
1000 if (tv) {
1001 struct timeval ktv;
1002 do_gettimeofday(&ktv);
1003 if (put_tv32(tv, &ktv))
1004 return -EFAULT;
1005 }
1006 if (tz) {
1007 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
1008 return -EFAULT;
1009 }
1010 return 0;
1011}
1012
1013asmlinkage int
1014sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
1015{
1016 struct timeval ktv;
1017 struct timezone ktz;
1018
1019 if (tv) {
1020 if (get_tv32(&ktv, tv))
1021 return -EFAULT;
1022 }
1023 if (tz) {
1024 if (copy_from_user(&ktz, tz, sizeof(ktz)))
1025 return -EFAULT;
1026 }
1027
1028 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
1029}
1030
1031extern asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
1032 unsigned long offset_low, loff_t * result,
1033 unsigned int origin);
1034
1035asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
1036 unsigned int offset_low, loff_t * result,
1037 unsigned int origin)
1038{
1039 return sys_llseek(fd, offset_high, offset_low, result, origin);
1040}
1041
1042struct iovec32 { unsigned int iov_base; int iov_len; };
1043
1044typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
1045
1046static long
1047do_readv_writev32(int type, struct file *file, const struct iovec32 *vector,
1048 u32 count)
1049{
1050 unsigned long tot_len;
1051 struct iovec iovstack[UIO_FASTIOV];
1052 struct iovec *iov=iovstack, *ivp;
1053 struct inode *inode;
1054 long retval, i;
1055 IO_fn_t fn;
1056
1057
1058
1059
1060 if (!count)
1061 return 0;
1062 if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
1063 return -EFAULT;
1064 if (count > UIO_MAXIOV)
1065 return -EINVAL;
1066 if (count > UIO_FASTIOV) {
1067 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1068 if (!iov)
1069 return -ENOMEM;
1070 }
1071
1072 tot_len = 0;
1073 i = count;
1074 ivp = iov;
1075 while (i > 0) {
1076 u32 len;
1077 u32 buf;
1078
1079 __get_user(len, &vector->iov_len);
1080 __get_user(buf, &vector->iov_base);
1081 tot_len += len;
1082 ivp->iov_base = (void *)A(buf);
1083 ivp->iov_len = (__kernel_size_t) len;
1084 vector++;
1085 ivp++;
1086 i--;
1087 }
1088
1089 inode = file->f_dentry->d_inode;
1090
1091 retval = locks_verify_area((type == VERIFY_WRITE
1092 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
1093 inode, file, file->f_pos, tot_len);
1094 if (retval) {
1095 if (iov != iovstack)
1096 kfree(iov);
1097 return retval;
1098 }
1099
1100
1101
1102
1103
1104 if (inode->i_sock) {
1105 int err;
1106 err = sock_readv_writev(type, inode, file, iov, count, tot_len);
1107 if (iov != iovstack)
1108 kfree(iov);
1109 return err;
1110 }
1111
1112 if (!file->f_op) {
1113 if (iov != iovstack)
1114 kfree(iov);
1115 return -EINVAL;
1116 }
1117
1118 fn = file->f_op->read;
1119 if (type == VERIFY_READ)
1120 fn = (IO_fn_t) file->f_op->write;
1121 ivp = iov;
1122 while (count > 0) {
1123 void * base;
1124 int len, nr;
1125
1126 base = ivp->iov_base;
1127 len = ivp->iov_len;
1128 ivp++;
1129 count--;
1130 nr = fn(file, base, len, &file->f_pos);
1131 if (nr < 0) {
1132 if (retval)
1133 break;
1134 retval = nr;
1135 break;
1136 }
1137 retval += nr;
1138 if (nr != len)
1139 break;
1140 }
1141 if (iov != iovstack)
1142 kfree(iov);
1143
1144 return retval;
1145}
1146
1147asmlinkage long
1148sys32_readv(int fd, struct iovec32 *vector, u32 count)
1149{
1150 struct file *file;
1151 ssize_t ret;
1152
1153 ret = -EBADF;
1154 file = fget(fd);
1155 if (!file)
1156 goto bad_file;
1157 if (file->f_op && (file->f_mode & FMODE_READ) &&
1158 (file->f_op->readv || file->f_op->read))
1159 ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
1160
1161 fput(file);
1162
1163bad_file:
1164 return ret;
1165}
1166
1167asmlinkage long
1168sys32_writev(int fd, struct iovec32 *vector, u32 count)
1169{
1170 struct file *file;
1171 ssize_t ret;
1172
1173 ret = -EBADF;
1174 file = fget(fd);
1175 if(!file)
1176 goto bad_file;
1177 if (file->f_op && (file->f_mode & FMODE_WRITE) &&
1178 (file->f_op->writev || file->f_op->write))
1179 ret = do_readv_writev32(VERIFY_READ, file, vector, count);
1180 fput(file);
1181
1182bad_file:
1183 return ret;
1184}
1185
1186
1187
1188
1189
1190asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
1191 size_t count, u32 unused, u64 a4, u64 a5)
1192{
1193 ssize_t ret;
1194 struct file * file;
1195 ssize_t (*read)(struct file *, char *, size_t, loff_t *);
1196 loff_t pos;
1197
1198 ret = -EBADF;
1199 file = fget(fd);
1200 if (!file)
1201 goto bad_file;
1202 if (!(file->f_mode & FMODE_READ))
1203 goto out;
1204 pos = merge_64(a4, a5);
1205 ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
1206 file, pos, count);
1207 if (ret)
1208 goto out;
1209 ret = -EINVAL;
1210 if (!file->f_op || !(read = file->f_op->read))
1211 goto out;
1212 if (pos < 0)
1213 goto out;
1214 ret = read(file, buf, count, &pos);
1215 if (ret > 0)
1216 dnotify_parent(file->f_dentry, DN_ACCESS);
1217out:
1218 fput(file);
1219bad_file:
1220 return ret;
1221}
1222
1223asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
1224 size_t count, u32 unused, u64 a4, u64 a5)
1225{
1226 ssize_t ret;
1227 struct file * file;
1228 ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
1229 loff_t pos;
1230
1231 ret = -EBADF;
1232 file = fget(fd);
1233 if (!file)
1234 goto bad_file;
1235 if (!(file->f_mode & FMODE_WRITE))
1236 goto out;
1237 pos = merge_64(a4, a5);
1238 ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode,
1239 file, pos, count);
1240 if (ret)
1241 goto out;
1242 ret = -EINVAL;
1243 if (!file->f_op || !(write = file->f_op->write))
1244 goto out;
1245 if (pos < 0)
1246 goto out;
1247
1248 ret = write(file, buf, count, &pos);
1249 if (ret > 0)
1250 dnotify_parent(file->f_dentry, DN_MODIFY);
1251out:
1252 fput(file);
1253bad_file:
1254 return ret;
1255}
1256
1257
1258
1259
1260
1261static inline int
1262get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1263{
1264 if (ufdset) {
1265 unsigned long odd;
1266
1267 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1268 return -EFAULT;
1269
1270 odd = n & 1UL;
1271 n &= ~1UL;
1272 while (n) {
1273 unsigned long h, l;
1274 __get_user(l, ufdset);
1275 __get_user(h, ufdset+1);
1276 ufdset += 2;
1277 *fdset++ = h << 32 | l;
1278 n -= 2;
1279 }
1280 if (odd)
1281 __get_user(*fdset, ufdset);
1282 } else {
1283
1284
1285
1286
1287 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1288 }
1289 return 0;
1290}
1291
1292static inline void
1293set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1294{
1295 unsigned long odd;
1296
1297 if (!ufdset)
1298 return;
1299
1300 odd = n & 1UL;
1301 n &= ~1UL;
1302 while (n) {
1303 unsigned long h, l;
1304 l = *fdset++;
1305 h = l >> 32;
1306 __put_user(l, ufdset);
1307 __put_user(h, ufdset+1);
1308 ufdset += 2;
1309 n -= 2;
1310 }
1311 if (odd)
1312 __put_user(*fdset, ufdset);
1313}
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323#define MAX_SELECT_SECONDS \
1324 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1325
1326asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, struct timeval32 *tvp)
1327{
1328 fd_set_bits fds;
1329 char *bits;
1330 unsigned long nn;
1331 long timeout;
1332 int ret, size;
1333
1334 timeout = MAX_SCHEDULE_TIMEOUT;
1335 if (tvp) {
1336 time_t sec, usec;
1337
1338 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1339 || (ret = __get_user(sec, &tvp->tv_sec))
1340 || (ret = __get_user(usec, &tvp->tv_usec)))
1341 goto out_nofds;
1342
1343 ret = -EINVAL;
1344 if(sec < 0 || usec < 0)
1345 goto out_nofds;
1346
1347 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1348 timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1349 timeout += sec * (unsigned long) HZ;
1350 }
1351 }
1352
1353 ret = -EINVAL;
1354 if (n < 0)
1355 goto out_nofds;
1356 if (n > current->files->max_fdset)
1357 n = current->files->max_fdset;
1358
1359
1360
1361
1362
1363
1364 ret = -ENOMEM;
1365 size = FDS_BYTES(n);
1366 bits = kmalloc(6 * size, GFP_KERNEL);
1367 if (!bits)
1368 goto out_nofds;
1369 fds.in = (unsigned long *) bits;
1370 fds.out = (unsigned long *) (bits + size);
1371 fds.ex = (unsigned long *) (bits + 2*size);
1372 fds.res_in = (unsigned long *) (bits + 3*size);
1373 fds.res_out = (unsigned long *) (bits + 4*size);
1374 fds.res_ex = (unsigned long *) (bits + 5*size);
1375
1376 nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1377 if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1378 (ret = get_fd_set32(nn, fds.out, outp)) ||
1379 (ret = get_fd_set32(nn, fds.ex, exp)))
1380 goto out;
1381 zero_fd_set(n, fds.res_in);
1382 zero_fd_set(n, fds.res_out);
1383 zero_fd_set(n, fds.res_ex);
1384
1385 ret = do_select(n, &fds, &timeout);
1386
1387 if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1388 time_t sec = 0, usec = 0;
1389 if (timeout) {
1390 sec = timeout / HZ;
1391 usec = timeout % HZ;
1392 usec *= (1000000/HZ);
1393 }
1394 put_user(sec, &tvp->tv_sec);
1395 put_user(usec, &tvp->tv_usec);
1396 }
1397
1398 if (ret < 0)
1399 goto out;
1400 if (!ret) {
1401 ret = -ERESTARTNOHAND;
1402 if (signal_pending(current))
1403 goto out;
1404 ret = 0;
1405 }
1406
1407 set_fd_set32(nn, inp, fds.res_in);
1408 set_fd_set32(nn, outp, fds.res_out);
1409 set_fd_set32(nn, exp, fds.res_ex);
1410
1411out:
1412 kfree(bits);
1413out_nofds:
1414 return ret;
1415}
1416
1417
1418
1419struct timespec32 {
1420 int tv_sec;
1421 int tv_nsec;
1422};
1423
1424extern asmlinkage int sys_sched_rr_get_interval(pid_t pid,
1425 struct timespec *interval);
1426
1427asmlinkage int
1428sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1429{
1430 struct timespec t;
1431 int ret;
1432 mm_segment_t old_fs = get_fs ();
1433
1434 set_fs (KERNEL_DS);
1435 ret = sys_sched_rr_get_interval(pid, &t);
1436 set_fs (old_fs);
1437 if (put_user (t.tv_sec, &interval->tv_sec) ||
1438 __put_user (t.tv_nsec, &interval->tv_nsec))
1439 return -EFAULT;
1440 return ret;
1441}
1442
1443
1444extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
1445 struct timespec *rmtp);
1446
1447asmlinkage int
1448sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
1449{
1450 struct timespec t;
1451 int ret;
1452 mm_segment_t old_fs = get_fs ();
1453
1454 if (get_user (t.tv_sec, &rqtp->tv_sec) ||
1455 __get_user (t.tv_nsec, &rqtp->tv_nsec))
1456 return -EFAULT;
1457
1458 set_fs (KERNEL_DS);
1459 ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1460 set_fs (old_fs);
1461 if (rmtp && ret == -EINTR) {
1462 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1463 __put_user (t.tv_nsec, &rmtp->tv_nsec))
1464 return -EFAULT;
1465 }
1466 return ret;
1467}
1468
1469struct tms32 {
1470 int tms_utime;
1471 int tms_stime;
1472 int tms_cutime;
1473 int tms_cstime;
1474};
1475
1476extern asmlinkage long sys_times(struct tms * tbuf);
1477asmlinkage long sys32_times(struct tms32 *tbuf)
1478{
1479 struct tms t;
1480 long ret;
1481 mm_segment_t old_fs = get_fs();
1482 int err;
1483
1484 set_fs(KERNEL_DS);
1485 ret = sys_times(tbuf ? &t : NULL);
1486 set_fs(old_fs);
1487 if (tbuf) {
1488 err = put_user (t.tms_utime, &tbuf->tms_utime);
1489 err |= __put_user (t.tms_stime, &tbuf->tms_stime);
1490 err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
1491 err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
1492 if (err)
1493 ret = -EFAULT;
1494 }
1495 return ret;
1496}
1497
1498static int do_set_attach_filter(int fd, int level, int optname,
1499 char *optval, int optlen)
1500{
1501 struct sock_fprog32 {
1502 __u16 len;
1503 __u32 filter;
1504 } *fprog32 = (struct sock_fprog32 *)optval;
1505 struct sock_fprog kfprog;
1506 struct sock_filter *kfilter;
1507 unsigned int fsize;
1508 mm_segment_t old_fs;
1509 __u32 uptr;
1510 int ret;
1511
1512 if (get_user(kfprog.len, &fprog32->len) ||
1513 __get_user(uptr, &fprog32->filter))
1514 return -EFAULT;
1515
1516 kfprog.filter = (struct sock_filter *)A(uptr);
1517 fsize = kfprog.len * sizeof(struct sock_filter);
1518
1519 kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
1520 if (kfilter == NULL)
1521 return -ENOMEM;
1522
1523 if (copy_from_user(kfilter, kfprog.filter, fsize)) {
1524 kfree(kfilter);
1525 return -EFAULT;
1526 }
1527
1528 kfprog.filter = kfilter;
1529
1530 old_fs = get_fs();
1531 set_fs(KERNEL_DS);
1532 ret = sys_setsockopt(fd, level, optname,
1533 (char *)&kfprog, sizeof(kfprog));
1534 set_fs(old_fs);
1535
1536 kfree(kfilter);
1537
1538 return ret;
1539}
1540
1541static int do_set_icmpv6_filter(int fd, int level, int optname,
1542 char *optval, int optlen)
1543{
1544 struct icmp6_filter kfilter;
1545 mm_segment_t old_fs;
1546 int ret, i;
1547
1548 if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
1549 return -EFAULT;
1550
1551
1552 for (i = 0; i < 8; i += 2) {
1553 u32 tmp = kfilter.data[i];
1554
1555 kfilter.data[i] = kfilter.data[i + 1];
1556 kfilter.data[i + 1] = tmp;
1557 }
1558
1559 old_fs = get_fs();
1560 set_fs(KERNEL_DS);
1561 ret = sys_setsockopt(fd, level, optname,
1562 (char *) &kfilter, sizeof(kfilter));
1563 set_fs(old_fs);
1564
1565 return ret;
1566}
1567
1568asmlinkage int sys32_setsockopt(int fd, int level, int optname,
1569 char *optval, int optlen)
1570{
1571 if (level == SOL_SOCKET && optname == SO_ATTACH_FILTER)
1572 return do_set_attach_filter(fd, level, optname,
1573 optval, optlen);
1574 if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
1575 return do_set_icmpv6_filter(fd, level, optname,
1576 optval, optlen);
1577
1578 return sys_setsockopt(fd, level, optname, optval, optlen);
1579}
1580
1581static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
1582{
1583 int err;
1584
1585 if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)))
1586 return -EFAULT;
1587
1588 err = __get_user(kfl->l_type, &ufl->l_type);
1589 err |= __get_user(kfl->l_whence, &ufl->l_whence);
1590 err |= __get_user(kfl->l_start, &ufl->l_start);
1591 err |= __get_user(kfl->l_len, &ufl->l_len);
1592 err |= __get_user(kfl->l_pid, &ufl->l_pid);
1593
1594 return err;
1595}
1596
1597static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
1598{
1599 int err;
1600
1601 if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)))
1602 return -EFAULT;
1603
1604 err = __put_user(kfl->l_type, &ufl->l_type);
1605 err |= __put_user(kfl->l_whence, &ufl->l_whence);
1606 err |= __put_user(kfl->l_start, &ufl->l_start);
1607 err |= __put_user(kfl->l_len, &ufl->l_len);
1608 err |= __put_user(0, &ufl->l_sysid);
1609 err |= __put_user(kfl->l_pid, &ufl->l_pid);
1610
1611 return err;
1612}
1613
1614extern asmlinkage long
1615sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
1616
1617asmlinkage long
1618sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
1619{
1620 switch (cmd) {
1621 case F_GETLK:
1622 case F_SETLK:
1623 case F_SETLKW:
1624 {
1625 struct flock f;
1626 mm_segment_t old_fs;
1627 long ret;
1628
1629 if (get_flock(&f, (struct flock32 *)arg))
1630 return -EFAULT;
1631 old_fs = get_fs(); set_fs (KERNEL_DS);
1632 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
1633 set_fs (old_fs);
1634 if (put_flock(&f, (struct flock32 *)arg))
1635 return -EFAULT;
1636 return ret;
1637 }
1638 default:
1639 return sys_fcntl(fd, cmd, (unsigned long)arg);
1640 }
1641}
1642
1643asmlinkage long
1644sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
1645{
1646 switch (cmd) {
1647 case F_GETLK64:
1648 return sys_fcntl(fd, F_GETLK, arg);
1649 case F_SETLK64:
1650 return sys_fcntl(fd, F_SETLK, arg);
1651 case F_SETLKW64:
1652 return sys_fcntl(fd, F_SETLKW, arg);
1653 }
1654
1655 return sys32_fcntl(fd, cmd, arg);
1656}
1657
1658struct msgbuf32 { s32 mtype; char mtext[1]; };
1659
1660struct ipc_perm32
1661{
1662 key_t key;
1663 __kernel_uid_t32 uid;
1664 __kernel_gid_t32 gid;
1665 __kernel_uid_t32 cuid;
1666 __kernel_gid_t32 cgid;
1667 __kernel_mode_t32 mode;
1668 unsigned short seq;
1669};
1670
1671struct ipc64_perm32 {
1672 key_t key;
1673 __kernel_uid_t32 uid;
1674 __kernel_gid_t32 gid;
1675 __kernel_uid_t32 cuid;
1676 __kernel_gid_t32 cgid;
1677 __kernel_mode_t32 mode;
1678 unsigned short seq;
1679 unsigned short __pad1;
1680 unsigned int __unused1;
1681 unsigned int __unused2;
1682};
1683
1684struct semid_ds32 {
1685 struct ipc_perm32 sem_perm;
1686 __kernel_time_t32 sem_otime;
1687 __kernel_time_t32 sem_ctime;
1688 u32 sem_base;
1689 u32 sem_pending;
1690 u32 sem_pending_last;
1691 u32 undo;
1692 unsigned short sem_nsems;
1693};
1694
1695struct semid64_ds32 {
1696 struct ipc64_perm32 sem_perm;
1697 __kernel_time_t32 sem_otime;
1698 __kernel_time_t32 sem_ctime;
1699 unsigned int sem_nsems;
1700 unsigned int __unused1;
1701 unsigned int __unused2;
1702};
1703
1704struct msqid_ds32
1705{
1706 struct ipc_perm32 msg_perm;
1707 u32 msg_first;
1708 u32 msg_last;
1709 __kernel_time_t32 msg_stime;
1710 __kernel_time_t32 msg_rtime;
1711 __kernel_time_t32 msg_ctime;
1712 u32 wwait;
1713 u32 rwait;
1714 unsigned short msg_cbytes;
1715 unsigned short msg_qnum;
1716 unsigned short msg_qbytes;
1717 __kernel_ipc_pid_t32 msg_lspid;
1718 __kernel_ipc_pid_t32 msg_lrpid;
1719};
1720
1721struct msqid64_ds32 {
1722 struct ipc64_perm32 msg_perm;
1723 __kernel_time_t32 msg_stime;
1724 unsigned int __unused1;
1725 __kernel_time_t32 msg_rtime;
1726 unsigned int __unused2;
1727 __kernel_time_t32 msg_ctime;
1728 unsigned int __unused3;
1729 unsigned int msg_cbytes;
1730 unsigned int msg_qnum;
1731 unsigned int msg_qbytes;
1732 __kernel_pid_t32 msg_lspid;
1733 __kernel_pid_t32 msg_lrpid;
1734 unsigned int __unused4;
1735 unsigned int __unused5;
1736};
1737
1738struct shmid_ds32 {
1739 struct ipc_perm32 shm_perm;
1740 int shm_segsz;
1741 __kernel_time_t32 shm_atime;
1742 __kernel_time_t32 shm_dtime;
1743 __kernel_time_t32 shm_ctime;
1744 __kernel_ipc_pid_t32 shm_cpid;
1745 __kernel_ipc_pid_t32 shm_lpid;
1746 unsigned short shm_nattch;
1747};
1748
1749struct shmid64_ds32 {
1750 struct ipc64_perm32 shm_perm;
1751 __kernel_size_t32 shm_segsz;
1752 __kernel_time_t32 shm_atime;
1753 __kernel_time_t32 shm_dtime;
1754 __kernel_time_t32 shm_ctime;
1755 __kernel_pid_t32 shm_cpid;
1756 __kernel_pid_t32 shm_lpid;
1757 unsigned int shm_nattch;
1758 unsigned int __unused1;
1759 unsigned int __unused2;
1760};
1761
1762struct ipc_kludge32 {
1763 u32 msgp;
1764 s32 msgtyp;
1765};
1766
1767static int
1768do_sys32_semctl(int first, int second, int third, void *uptr)
1769{
1770 union semun fourth;
1771 u32 pad;
1772 int err, err2;
1773 struct semid64_ds s;
1774 mm_segment_t old_fs;
1775
1776 if (!uptr)
1777 return -EINVAL;
1778 err = -EFAULT;
1779 if (get_user (pad, (u32 *)uptr))
1780 return err;
1781 if ((third & ~IPC_64) == SETVAL)
1782 fourth.val = (int)pad;
1783 else
1784 fourth.__pad = (void *)A(pad);
1785 switch (third & ~IPC_64) {
1786 case IPC_INFO:
1787 case IPC_RMID:
1788 case IPC_SET:
1789 case SEM_INFO:
1790 case GETVAL:
1791 case GETPID:
1792 case GETNCNT:
1793 case GETZCNT:
1794 case GETALL:
1795 case SETVAL:
1796 case SETALL:
1797 err = sys_semctl (first, second, third, fourth);
1798 break;
1799
1800 case IPC_STAT:
1801 case SEM_STAT:
1802 fourth.__pad = &s;
1803 old_fs = get_fs();
1804 set_fs(KERNEL_DS);
1805 err = sys_semctl(first, second, third | IPC_64, fourth);
1806 set_fs(old_fs);
1807
1808 if (third & IPC_64) {
1809 struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad);
1810
1811 if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
1812 err = -EFAULT;
1813 break;
1814 }
1815 err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
1816 err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
1817 err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
1818 err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
1819 err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
1820 err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
1821 err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
1822 err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
1823 err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
1824 err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
1825 } else {
1826 struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad);
1827
1828 if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
1829 err = -EFAULT;
1830 break;
1831 }
1832 err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
1833 err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
1834 err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
1835 err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
1836 err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
1837 err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
1838 err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
1839 err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
1840 err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
1841 err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
1842 }
1843 if (err2)
1844 err = -EFAULT;
1845 break;
1846
1847 default:
1848 err = - EINVAL;
1849 break;
1850 }
1851
1852 return err;
1853}
1854
1855static int
1856do_sys32_msgsnd (int first, int second, int third, void *uptr)
1857{
1858 struct msgbuf32 *up = (struct msgbuf32 *)uptr;
1859 struct msgbuf *p;
1860 mm_segment_t old_fs;
1861 int err;
1862
1863 if (second < 0)
1864 return -EINVAL;
1865 p = kmalloc (second + sizeof (struct msgbuf)
1866 + 4, GFP_USER);
1867 if (!p)
1868 return -ENOMEM;
1869 err = get_user (p->mtype, &up->mtype);
1870 if (err)
1871 goto out;
1872 err |= __copy_from_user (p->mtext, &up->mtext, second);
1873 if (err)
1874 goto out;
1875 old_fs = get_fs ();
1876 set_fs (KERNEL_DS);
1877 err = sys_msgsnd (first, p, second, third);
1878 set_fs (old_fs);
1879out:
1880 kfree (p);
1881
1882 return err;
1883}
1884
1885static int
1886do_sys32_msgrcv (int first, int second, int msgtyp, int third,
1887 int version, void *uptr)
1888{
1889 struct msgbuf32 *up;
1890 struct msgbuf *p;
1891 mm_segment_t old_fs;
1892 int err;
1893
1894 if (!version) {
1895 struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr;
1896 struct ipc_kludge32 ipck;
1897
1898 err = -EINVAL;
1899 if (!uptr)
1900 goto out;
1901 err = -EFAULT;
1902 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
1903 goto out;
1904 uptr = (void *)AA(ipck.msgp);
1905 msgtyp = ipck.msgtyp;
1906 }
1907
1908 if (second < 0)
1909 return -EINVAL;
1910 err = -ENOMEM;
1911 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
1912 if (!p)
1913 goto out;
1914 old_fs = get_fs ();
1915 set_fs (KERNEL_DS);
1916 err = sys_msgrcv (first, p, second + 4, msgtyp, third);
1917 set_fs (old_fs);
1918 if (err < 0)
1919 goto free_then_out;
1920 up = (struct msgbuf32 *)uptr;
1921 if (put_user (p->mtype, &up->mtype) ||
1922 __copy_to_user (&up->mtext, p->mtext, err))
1923 err = -EFAULT;
1924free_then_out:
1925 kfree (p);
1926out:
1927 return err;
1928}
1929
1930static int
1931do_sys32_msgctl (int first, int second, void *uptr)
1932{
1933 int err = -EINVAL, err2;
1934 struct msqid64_ds m;
1935 struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
1936 struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
1937 mm_segment_t old_fs;
1938
1939 switch (second & ~IPC_64) {
1940 case IPC_INFO:
1941 case IPC_RMID:
1942 case MSG_INFO:
1943 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
1944 break;
1945
1946 case IPC_SET:
1947 if (second & IPC_64) {
1948 if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
1949 err = -EFAULT;
1950 break;
1951 }
1952 err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
1953 err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
1954 err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
1955 err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
1956 } else {
1957 if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
1958 err = -EFAULT;
1959 break;
1960 }
1961 err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
1962 err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
1963 err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
1964 err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
1965 }
1966 if (err)
1967 break;
1968 old_fs = get_fs();
1969 set_fs(KERNEL_DS);
1970 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m);
1971 set_fs(old_fs);
1972 break;
1973
1974 case IPC_STAT:
1975 case MSG_STAT:
1976 old_fs = get_fs();
1977 set_fs(KERNEL_DS);
1978 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m);
1979 set_fs(old_fs);
1980 if (second & IPC_64) {
1981 if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
1982 err = -EFAULT;
1983 break;
1984 }
1985 err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
1986 err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
1987 err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
1988 err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
1989 err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
1990 err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
1991 err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
1992 err2 |= __put_user(m.msg_stime, &up64->msg_stime);
1993 err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
1994 err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
1995 err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
1996 err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
1997 err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
1998 err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
1999 err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
2000 if (err2)
2001 err = -EFAULT;
2002 } else {
2003 if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
2004 err = -EFAULT;
2005 break;
2006 }
2007 err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
2008 err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
2009 err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
2010 err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
2011 err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
2012 err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
2013 err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
2014 err2 |= __put_user(m.msg_stime, &up32->msg_stime);
2015 err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
2016 err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
2017 err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
2018 err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
2019 err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
2020 err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
2021 err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
2022 if (err2)
2023 err = -EFAULT;
2024 }
2025 break;
2026 }
2027
2028 return err;
2029}
2030
2031static int
2032do_sys32_shmat (int first, int second, int third, int version, void *uptr)
2033{
2034 unsigned long raddr;
2035 u32 *uaddr = (u32 *)A((u32)third);
2036 int err = -EINVAL;
2037
2038 if (version == 1)
2039 return err;
2040 err = sys_shmat (first, uptr, second, &raddr);
2041 if (err)
2042 return err;
2043 err = put_user (raddr, uaddr);
2044 return err;
2045}
2046
2047struct shm_info32 {
2048 int used_ids;
2049 u32 shm_tot, shm_rss, shm_swp;
2050 u32 swap_attempts, swap_successes;
2051};
2052
2053static int
2054do_sys32_shmctl (int first, int second, void *uptr)
2055{
2056 struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
2057 struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
2058 struct shm_info32 *uip = (struct shm_info32 *)uptr;
2059 int err = -EFAULT, err2;
2060 struct shmid64_ds s64;
2061 mm_segment_t old_fs;
2062 struct shm_info si;
2063 struct shmid_ds s;
2064
2065 switch (second & ~IPC_64) {
2066 case IPC_INFO:
2067 second = IPC_INFO;
2068 case IPC_RMID:
2069 case SHM_LOCK:
2070 case SHM_UNLOCK:
2071 err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
2072 break;
2073 case IPC_SET:
2074 if (second & IPC_64) {
2075 err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
2076 err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
2077 err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
2078 } else {
2079 err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
2080 err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
2081 err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
2082 }
2083 if (err)
2084 break;
2085 old_fs = get_fs();
2086 set_fs(KERNEL_DS);
2087 err = sys_shmctl(first, second & ~IPC_64, &s);
2088 set_fs(old_fs);
2089 break;
2090
2091 case IPC_STAT:
2092 case SHM_STAT:
2093 old_fs = get_fs();
2094 set_fs(KERNEL_DS);
2095 err = sys_shmctl(first, second | IPC_64, (void *) &s64);
2096 set_fs(old_fs);
2097 if (err < 0)
2098 break;
2099 if (second & IPC_64) {
2100 if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
2101 err = -EFAULT;
2102 break;
2103 }
2104 err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
2105 err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
2106 err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
2107 err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
2108 err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
2109 err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
2110 err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
2111 err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
2112 err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
2113 err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
2114 err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
2115 err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
2116 err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
2117 err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
2118 } else {
2119 if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
2120 err = -EFAULT;
2121 break;
2122 }
2123 err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
2124 err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
2125 err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
2126 err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
2127 err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
2128 err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
2129 err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
2130 err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
2131 err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
2132 err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
2133 err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
2134 err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
2135 err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
2136 err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
2137 }
2138 if (err2)
2139 err = -EFAULT;
2140 break;
2141
2142 case SHM_INFO:
2143 old_fs = get_fs();
2144 set_fs(KERNEL_DS);
2145 err = sys_shmctl(first, second, (void *)&si);
2146 set_fs(old_fs);
2147 if (err < 0)
2148 break;
2149 err2 = put_user(si.used_ids, &uip->used_ids);
2150 err2 |= __put_user(si.shm_tot, &uip->shm_tot);
2151 err2 |= __put_user(si.shm_rss, &uip->shm_rss);
2152 err2 |= __put_user(si.shm_swp, &uip->shm_swp);
2153 err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
2154 err2 |= __put_user (si.swap_successes, &uip->swap_successes);
2155 if (err2)
2156 err = -EFAULT;
2157 break;
2158
2159 default:
2160 err = -EINVAL;
2161 break;
2162 }
2163
2164 return err;
2165}
2166
2167static inline void *alloc_user_space(long len)
2168{
2169 unsigned long sp = (unsigned long) current + THREAD_SIZE - 32;
2170
2171 return (void *) (sp - len);
2172}
2173
2174static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems,
2175 const struct timespec32 *timeout32)
2176{
2177 struct timespec32 t32;
2178 struct timespec *t64 = alloc_user_space(sizeof(*t64));
2179
2180 if (copy_from_user(&t32, timeout32, sizeof(t32)))
2181 return -EFAULT;
2182
2183 if (put_user(t32.tv_sec, &t64->tv_sec) ||
2184 put_user(t32.tv_nsec, &t64->tv_nsec))
2185 return -EFAULT;
2186
2187 return sys_semtimedop(semid, tsems, nsems, t64);
2188}
2189
2190asmlinkage long
2191sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
2192{
2193 int version, err;
2194
2195 version = call >> 16;
2196 call &= 0xffff;
2197
2198 switch (call) {
2199
2200 case SEMOP:
2201
2202 err = sys_semtimedop (first, (struct sembuf *)AA(ptr),
2203 second, NULL);
2204 break;
2205 case SEMTIMEDOP:
2206 err = sys32_semtimedop(first, (struct sembuf *)AA(ptr), second,
2207 (const struct timespec32 *) AA(fifth));
2208 break;
2209 case SEMGET:
2210 err = sys_semget (first, second, third);
2211 break;
2212 case SEMCTL:
2213 err = do_sys32_semctl (first, second, third,
2214 (void *)AA(ptr));
2215 break;
2216
2217 case MSGSND:
2218 err = do_sys32_msgsnd (first, second, third,
2219 (void *)AA(ptr));
2220 break;
2221 case MSGRCV:
2222 err = do_sys32_msgrcv (first, second, fifth, third,
2223 version, (void *)AA(ptr));
2224 break;
2225 case MSGGET:
2226 err = sys_msgget ((key_t) first, second);
2227 break;
2228 case MSGCTL:
2229 err = do_sys32_msgctl (first, second, (void *)AA(ptr));
2230 break;
2231
2232 case SHMAT:
2233 err = do_sys32_shmat (first, second, third,
2234 version, (void *)AA(ptr));
2235 break;
2236 case SHMDT:
2237 err = sys_shmdt ((char *)A(ptr));
2238 break;
2239 case SHMGET:
2240 err = sys_shmget (first, second, third);
2241 break;
2242 case SHMCTL:
2243 err = do_sys32_shmctl (first, second, (void *)AA(ptr));
2244 break;
2245 default:
2246 err = -EINVAL;
2247 break;
2248 }
2249
2250 return err;
2251}
2252
2253struct sysctl_args32
2254{
2255 __kernel_caddr_t32 name;
2256 int nlen;
2257 __kernel_caddr_t32 oldval;
2258 __kernel_caddr_t32 oldlenp;
2259 __kernel_caddr_t32 newval;
2260 __kernel_size_t32 newlen;
2261 unsigned int __unused[4];
2262};
2263
2264#ifdef CONFIG_SYSCTL
2265
2266asmlinkage long sys32_sysctl(struct sysctl_args32 *args)
2267{
2268 struct sysctl_args32 tmp;
2269 int error;
2270 size_t oldlen, *oldlenp = NULL;
2271 unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
2272
2273 if (copy_from_user(&tmp, args, sizeof(tmp)))
2274 return -EFAULT;
2275
2276 if (tmp.oldval && tmp.oldlenp) {
2277
2278
2279
2280
2281
2282
2283 if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
2284 put_user(oldlen, (size_t *)addr))
2285 return -EFAULT;
2286 oldlenp = (size_t *)addr;
2287 }
2288
2289 lock_kernel();
2290 error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
2291 oldlenp, (void *)A(tmp.newval), tmp.newlen);
2292 unlock_kernel();
2293 if (oldlenp) {
2294 if (!error) {
2295 if (get_user(oldlen, (size_t *)addr) ||
2296 put_user(oldlen, (u32 *)A(tmp.oldlenp)))
2297 error = -EFAULT;
2298 }
2299 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
2300 }
2301 return error;
2302}
2303
2304#else
2305
2306asmlinkage long sys32_sysctl(struct sysctl_args32 *args)
2307{
2308 return -ENOSYS;
2309}
2310
2311#endif
2312
2313asmlinkage long sys32_newuname(struct new_utsname * name)
2314{
2315 int ret = 0;
2316
2317 down_read(&uts_sem);
2318 if (copy_to_user(name,&system_utsname,sizeof *name))
2319 ret = -EFAULT;
2320 up_read(&uts_sem);
2321
2322 if (current->personality == PER_LINUX32 && !ret)
2323 if (copy_to_user(name->machine, "mips\0\0\0", 8))
2324 ret = -EFAULT;
2325
2326 return ret;
2327}
2328
2329extern asmlinkage long sys_personality(unsigned long);
2330
2331asmlinkage int sys32_personality(unsigned long personality)
2332{
2333 int ret;
2334 if (current->personality == PER_LINUX32 && personality == PER_LINUX)
2335 personality = PER_LINUX32;
2336 ret = sys_personality(personality);
2337 if (ret == PER_LINUX32)
2338 ret = PER_LINUX;
2339 return ret;
2340}
2341
2342
2343struct ustat32 {
2344 __kernel_daddr_t32 f_tfree;
2345 __kernel_ino_t32 f_tinode;
2346 char f_fname[6];
2347 char f_fpack[6];
2348};
2349
2350extern asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf);
2351
2352asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32)
2353{
2354 int err;
2355 struct ustat tmp;
2356 struct ustat32 tmp32;
2357 mm_segment_t old_fs = get_fs();
2358
2359 set_fs(KERNEL_DS);
2360 err = sys_ustat(dev, &tmp);
2361 set_fs (old_fs);
2362
2363 if (err)
2364 goto out;
2365
2366 memset(&tmp32,0,sizeof(struct ustat32));
2367 tmp32.f_tfree = tmp.f_tfree;
2368 tmp32.f_tinode = tmp.f_tinode;
2369
2370 err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0;
2371
2372out:
2373 return err;
2374}
2375
2376
2377
2378struct timex32 {
2379 u32 modes;
2380 s32 offset, freq, maxerror, esterror;
2381 s32 status, constant, precision, tolerance;
2382 struct timeval32 time;
2383 s32 tick;
2384 s32 ppsfreq, jitter, shift, stabil;
2385 s32 jitcnt, calcnt, errcnt, stbcnt;
2386 s32 :32; s32 :32; s32 :32; s32 :32;
2387 s32 :32; s32 :32; s32 :32; s32 :32;
2388 s32 :32; s32 :32; s32 :32; s32 :32;
2389};
2390
2391extern int do_adjtimex(struct timex *);
2392
2393asmlinkage int sys32_adjtimex(struct timex32 *utp)
2394{
2395 struct timex txc;
2396 int ret;
2397
2398 memset(&txc, 0, sizeof(struct timex));
2399
2400 if(get_user(txc.modes, &utp->modes) ||
2401 __get_user(txc.offset, &utp->offset) ||
2402 __get_user(txc.freq, &utp->freq) ||
2403 __get_user(txc.maxerror, &utp->maxerror) ||
2404 __get_user(txc.esterror, &utp->esterror) ||
2405 __get_user(txc.status, &utp->status) ||
2406 __get_user(txc.constant, &utp->constant) ||
2407 __get_user(txc.precision, &utp->precision) ||
2408 __get_user(txc.tolerance, &utp->tolerance) ||
2409 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
2410 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
2411 __get_user(txc.tick, &utp->tick) ||
2412 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
2413 __get_user(txc.jitter, &utp->jitter) ||
2414 __get_user(txc.shift, &utp->shift) ||
2415 __get_user(txc.stabil, &utp->stabil) ||
2416 __get_user(txc.jitcnt, &utp->jitcnt) ||
2417 __get_user(txc.calcnt, &utp->calcnt) ||
2418 __get_user(txc.errcnt, &utp->errcnt) ||
2419 __get_user(txc.stbcnt, &utp->stbcnt))
2420 return -EFAULT;
2421
2422 ret = do_adjtimex(&txc);
2423
2424 if(put_user(txc.modes, &utp->modes) ||
2425 __put_user(txc.offset, &utp->offset) ||
2426 __put_user(txc.freq, &utp->freq) ||
2427 __put_user(txc.maxerror, &utp->maxerror) ||
2428 __put_user(txc.esterror, &utp->esterror) ||
2429 __put_user(txc.status, &utp->status) ||
2430 __put_user(txc.constant, &utp->constant) ||
2431 __put_user(txc.precision, &utp->precision) ||
2432 __put_user(txc.tolerance, &utp->tolerance) ||
2433 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
2434 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
2435 __put_user(txc.tick, &utp->tick) ||
2436 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
2437 __put_user(txc.jitter, &utp->jitter) ||
2438 __put_user(txc.shift, &utp->shift) ||
2439 __put_user(txc.stabil, &utp->stabil) ||
2440 __put_user(txc.jitcnt, &utp->jitcnt) ||
2441 __put_user(txc.calcnt, &utp->calcnt) ||
2442 __put_user(txc.errcnt, &utp->errcnt) ||
2443 __put_user(txc.stbcnt, &utp->stbcnt))
2444 ret = -EFAULT;
2445
2446 return ret;
2447}
2448
2449
2450
2451
2452
2453struct msghdr32 {
2454 unsigned int msg_name;
2455 int msg_namelen;
2456 unsigned int msg_iov;
2457 unsigned int msg_iovlen;
2458 unsigned int msg_control;
2459 unsigned int msg_controllen;
2460 unsigned msg_flags;
2461};
2462
2463struct cmsghdr32 {
2464 __kernel_size_t32 cmsg_len;
2465 int cmsg_level;
2466 int cmsg_type;
2467};
2468
2469
2470#define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2471#define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2472
2473#define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2474
2475#define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2476#define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2477#define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2478
2479#define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2480 (struct cmsghdr32 *)(ctl) : \
2481 (struct cmsghdr32 *)NULL)
2482#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2483
2484__inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2485 struct cmsghdr32 *__cmsg, int __cmsg_len)
2486{
2487 struct cmsghdr32 * __ptr;
2488
2489 __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2490 CMSG32_ALIGN(__cmsg_len));
2491 if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2492 return NULL;
2493
2494 return __ptr;
2495}
2496
2497__inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2498 struct cmsghdr32 *__cmsg,
2499 int __cmsg_len)
2500{
2501 return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2502 __cmsg, __cmsg_len);
2503}
2504
2505static inline int iov_from_user32_to_kern(struct iovec *kiov,
2506 struct iovec32 *uiov32,
2507 int niov)
2508{
2509 int tot_len = 0;
2510
2511 while(niov > 0) {
2512 u32 len, buf;
2513
2514 if(get_user(len, &uiov32->iov_len) ||
2515 get_user(buf, &uiov32->iov_base)) {
2516 tot_len = -EFAULT;
2517 break;
2518 }
2519 tot_len += len;
2520 kiov->iov_base = (void *)AA(buf);
2521 kiov->iov_len = (__kernel_size_t) len;
2522 uiov32++;
2523 kiov++;
2524 niov--;
2525 }
2526 return tot_len;
2527}
2528
2529static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2530 struct msghdr32 *umsg)
2531{
2532 u32 tmp1, tmp2, tmp3;
2533 int err;
2534
2535 err = get_user(tmp1, &umsg->msg_name);
2536 err |= __get_user(tmp2, &umsg->msg_iov);
2537 err |= __get_user(tmp3, &umsg->msg_control);
2538 if (err)
2539 return -EFAULT;
2540
2541 kmsg->msg_name = (void *)AA(tmp1);
2542 kmsg->msg_iov = (struct iovec *)AA(tmp2);
2543 kmsg->msg_control = (void *)AA(tmp3);
2544
2545 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2546 err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2547 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2548 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2549
2550 return err;
2551}
2552
2553
2554static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2555 char *kern_address, int mode)
2556{
2557 int tot_len;
2558
2559 if(kern_msg->msg_namelen) {
2560 if(mode==VERIFY_READ) {
2561 int err = move_addr_to_kernel(kern_msg->msg_name,
2562 kern_msg->msg_namelen,
2563 kern_address);
2564 if(err < 0)
2565 return err;
2566 }
2567 kern_msg->msg_name = kern_address;
2568 } else
2569 kern_msg->msg_name = NULL;
2570
2571 if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2572 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2573 GFP_KERNEL);
2574 if(!kern_iov)
2575 return -ENOMEM;
2576 }
2577
2578 tot_len = iov_from_user32_to_kern(kern_iov,
2579 (struct iovec32 *)kern_msg->msg_iov,
2580 kern_msg->msg_iovlen);
2581 if(tot_len >= 0)
2582 kern_msg->msg_iov = kern_iov;
2583 else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2584 kfree(kern_iov);
2585
2586 return tot_len;
2587}
2588
2589static __inline__ void
2590sockfd_put(struct socket *sock)
2591{
2592 fput(sock->file);
2593}
2594
2595
2596#define MAX_SOCK_ADDR 128
2597
2598
2599
2600
2601extern struct socket *sockfd_lookup(int fd, int *err);
2602
2603
2604
2605
2606
2607static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2608 unsigned char *stackbuf, int stackbuf_size)
2609{
2610 struct cmsghdr32 *ucmsg;
2611 struct cmsghdr *kcmsg, *kcmsg_base;
2612 __kernel_size_t32 ucmlen;
2613 __kernel_size_t kcmlen, tmp;
2614
2615 kcmlen = 0;
2616 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2617 ucmsg = CMSG32_FIRSTHDR(kmsg);
2618 while(ucmsg != NULL) {
2619 if(get_user(ucmlen, &ucmsg->cmsg_len))
2620 return -EFAULT;
2621
2622
2623 if(CMSG32_ALIGN(ucmlen) <
2624 CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2625 return -ENOBUFS;
2626 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2627 + ucmlen) > kmsg->msg_controllen)
2628 return -EINVAL;
2629
2630 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2631 CMSG_ALIGN(sizeof(struct cmsghdr)));
2632 kcmlen += tmp;
2633 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2634 }
2635 if(kcmlen == 0)
2636 return -EINVAL;
2637
2638
2639
2640
2641
2642
2643 if(kcmlen > stackbuf_size)
2644 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2645 if(kcmsg == NULL)
2646 return -ENOBUFS;
2647
2648
2649 memset(kcmsg, 0, kcmlen);
2650 ucmsg = CMSG32_FIRSTHDR(kmsg);
2651 while(ucmsg != NULL) {
2652 __get_user(ucmlen, &ucmsg->cmsg_len);
2653 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2654 CMSG_ALIGN(sizeof(struct cmsghdr)));
2655 kcmsg->cmsg_len = tmp;
2656 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2657 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2658
2659
2660 if(copy_from_user(CMSG_DATA(kcmsg),
2661 CMSG32_DATA(ucmsg),
2662 (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2663 goto out_free_efault;
2664
2665
2666 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2667 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2668 }
2669
2670
2671 kmsg->msg_control = kcmsg_base;
2672 kmsg->msg_controllen = kcmlen;
2673 return 0;
2674
2675out_free_efault:
2676 if(kcmsg_base != (struct cmsghdr *)stackbuf)
2677 kfree(kcmsg_base);
2678 return -EFAULT;
2679}
2680
2681static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2682 int len, void *data)
2683{
2684 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2685 struct cmsghdr32 cmhdr;
2686 int cmlen = CMSG32_LEN(len);
2687
2688 if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2689 kmsg->msg_flags |= MSG_CTRUNC;
2690 return;
2691 }
2692
2693 if(kmsg->msg_controllen < cmlen) {
2694 kmsg->msg_flags |= MSG_CTRUNC;
2695 cmlen = kmsg->msg_controllen;
2696 }
2697 cmhdr.cmsg_level = level;
2698 cmhdr.cmsg_type = type;
2699 cmhdr.cmsg_len = cmlen;
2700
2701 if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2702 return;
2703 if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2704 return;
2705 cmlen = CMSG32_SPACE(len);
2706 kmsg->msg_control += cmlen;
2707 kmsg->msg_controllen -= cmlen;
2708}
2709
2710static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2711{
2712 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2713 int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2714 int fdnum = scm->fp->count;
2715 struct file **fp = scm->fp->fp;
2716 int *cmfptr;
2717 int err = 0, i;
2718
2719 if (fdnum < fdmax)
2720 fdmax = fdnum;
2721
2722 for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2723 int new_fd;
2724 err = get_unused_fd();
2725 if (err < 0)
2726 break;
2727 new_fd = err;
2728 err = put_user(new_fd, cmfptr);
2729 if (err) {
2730 put_unused_fd(new_fd);
2731 break;
2732 }
2733
2734 get_file(fp[i]);
2735 fd_install(new_fd, fp[i]);
2736 }
2737
2738 if (i > 0) {
2739 int cmlen = CMSG32_LEN(i * sizeof(int));
2740 if (!err)
2741 err = put_user(SOL_SOCKET, &cm->cmsg_level);
2742 if (!err)
2743 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2744 if (!err)
2745 err = put_user(cmlen, &cm->cmsg_len);
2746 if (!err) {
2747 cmlen = CMSG32_SPACE(i * sizeof(int));
2748 kmsg->msg_control += cmlen;
2749 kmsg->msg_controllen -= cmlen;
2750 }
2751 }
2752 if (i < fdnum)
2753 kmsg->msg_flags |= MSG_CTRUNC;
2754
2755
2756
2757
2758
2759 __scm_destroy(scm);
2760}
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2791{
2792 unsigned char *workbuf, *wp;
2793 unsigned long bufsz, space_avail;
2794 struct cmsghdr *ucmsg;
2795
2796 bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2797 space_avail = kmsg->msg_controllen + bufsz;
2798 wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2799 if(workbuf == NULL)
2800 goto fail;
2801
2802
2803
2804
2805
2806 ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2807 while(((unsigned long)ucmsg) <=
2808 (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
2809 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2810 int clen64, clen32;
2811
2812
2813
2814
2815
2816 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2817 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2818 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2819
2820 clen64 = kcmsg32->cmsg_len;
2821 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2822 clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2823 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2824 CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2825 kcmsg32->cmsg_len = clen32;
2826
2827 ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2828 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2829 }
2830
2831
2832 bufsz = (wp - workbuf);
2833 copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2834
2835 kmsg->msg_control = (struct cmsghdr *)
2836 (((char *)orig_cmsg_uptr) + bufsz);
2837 kmsg->msg_controllen = space_avail - bufsz;
2838
2839 kfree(workbuf);
2840 return;
2841
2842fail:
2843
2844
2845
2846
2847 kmsg->msg_controllen += bufsz;
2848 kmsg->msg_control = (void *) orig_cmsg_uptr;
2849}
2850
2851asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2852{
2853 struct socket *sock;
2854 char address[MAX_SOCK_ADDR];
2855 struct iovec iov[UIO_FASTIOV];
2856 unsigned char ctl[sizeof(struct cmsghdr) + 20];
2857 unsigned char *ctl_buf = ctl;
2858 struct msghdr kern_msg;
2859 int err, total_len;
2860
2861 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2862 return -EFAULT;
2863 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2864 return -EINVAL;
2865 err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2866 if (err < 0)
2867 goto out;
2868 total_len = err;
2869
2870 if(kern_msg.msg_controllen) {
2871 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2872 if(err)
2873 goto out_freeiov;
2874 ctl_buf = kern_msg.msg_control;
2875 }
2876 kern_msg.msg_flags = user_flags;
2877
2878 sock = sockfd_lookup(fd, &err);
2879 if (sock != NULL) {
2880 if (sock->file->f_flags & O_NONBLOCK)
2881 kern_msg.msg_flags |= MSG_DONTWAIT;
2882 err = sock_sendmsg(sock, &kern_msg, total_len);
2883 sockfd_put(sock);
2884 }
2885
2886
2887 if(ctl_buf != ctl)
2888 kfree(ctl_buf);
2889out_freeiov:
2890 if(kern_msg.msg_iov != iov)
2891 kfree(kern_msg.msg_iov);
2892out:
2893 return err;
2894}
2895
2896asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2897{
2898 struct iovec iovstack[UIO_FASTIOV];
2899 struct msghdr kern_msg;
2900 char addr[MAX_SOCK_ADDR];
2901 struct socket *sock;
2902 struct iovec *iov = iovstack;
2903 struct sockaddr *uaddr;
2904 int *uaddr_len;
2905 unsigned long cmsg_ptr;
2906 int err, total_len, len = 0;
2907
2908 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2909 return -EFAULT;
2910 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2911 return -EINVAL;
2912
2913 uaddr = kern_msg.msg_name;
2914 uaddr_len = &user_msg->msg_namelen;
2915 err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2916 if (err < 0)
2917 goto out;
2918 total_len = err;
2919
2920 cmsg_ptr = (unsigned long) kern_msg.msg_control;
2921 kern_msg.msg_flags = 0;
2922
2923 sock = sockfd_lookup(fd, &err);
2924 if (sock != NULL) {
2925 struct scm_cookie scm;
2926
2927 if (sock->file->f_flags & O_NONBLOCK)
2928 user_flags |= MSG_DONTWAIT;
2929 memset(&scm, 0, sizeof(scm));
2930 err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2931 user_flags, &scm);
2932 if(err >= 0) {
2933 len = err;
2934 if(!kern_msg.msg_control) {
2935 if(sock->passcred || scm.fp)
2936 kern_msg.msg_flags |= MSG_CTRUNC;
2937 if(scm.fp)
2938 __scm_destroy(&scm);
2939 } else {
2940
2941
2942
2943
2944
2945 if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2946 cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2947
2948
2949 if(sock->passcred)
2950 put_cmsg32(&kern_msg,
2951 SOL_SOCKET, SCM_CREDENTIALS,
2952 sizeof(scm.creds), &scm.creds);
2953 if(scm.fp != NULL)
2954 scm_detach_fds32(&kern_msg, &scm);
2955 }
2956 }
2957 sockfd_put(sock);
2958 }
2959
2960 if(uaddr != NULL && kern_msg.msg_namelen && err >= 0)
2961 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2962 if(cmsg_ptr != 0 && err >= 0) {
2963 unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2964 __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2965 err |= __put_user(uclen, &user_msg->msg_controllen);
2966 }
2967 if(err >= 0)
2968 err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2969 if(kern_msg.msg_iov != iov)
2970 kfree(kern_msg.msg_iov);
2971out:
2972 if(err < 0)
2973 return err;
2974 return len;
2975}
2976
2977extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
2978
2979asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
2980{
2981 mm_segment_t old_fs = get_fs();
2982 int ret;
2983 off_t of;
2984
2985 if (offset && get_user(of, offset))
2986 return -EFAULT;
2987
2988 set_fs(KERNEL_DS);
2989 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
2990 set_fs(old_fs);
2991
2992 if (offset && put_user(of, offset))
2993 return -EFAULT;
2994
2995 return ret;
2996}
2997
2998asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
2999
3000asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,
3001 size_t count)
3002{
3003 return sys_readahead(fd, merge_64(a2, a3), count);
3004}
3005
3006
3007#define AL(x) ((x) * sizeof(unsigned int))
3008static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
3009 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
3010 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
3011#undef AL
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021asmlinkage long sys32_socketcall(int call, unsigned int *args32)
3022{
3023 unsigned int a[6];
3024 unsigned int a0,a1;
3025 int err;
3026
3027 if(call<1||call>SYS_RECVMSG)
3028 return -EINVAL;
3029
3030
3031 if (copy_from_user(a, args32, socketcall_nargs[call]))
3032 return -EFAULT;
3033
3034 a0=a[0];
3035 a1=a[1];
3036
3037 switch (call) {
3038 case SYS_SOCKET:
3039 err = sys_socket(a0,a1,a[2]);
3040 break;
3041 case SYS_BIND:
3042 err = sys_bind(a0,(struct sockaddr *)A(a1), a[2]);
3043 break;
3044 case SYS_CONNECT:
3045 err = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
3046 break;
3047 case SYS_LISTEN:
3048 err = sys_listen(a0,a1);
3049 break;
3050 case SYS_ACCEPT:
3051 err = sys_accept(a0,(struct sockaddr *)A(a1), (int *)A(a[2]));
3052 break;
3053 case SYS_GETSOCKNAME:
3054 err = sys_getsockname(a0,(struct sockaddr *)A(a1), (int *)A(a[2]));
3055 break;
3056 case SYS_GETPEERNAME:
3057 err = sys_getpeername(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
3058 break;
3059 case SYS_SOCKETPAIR:
3060 err = sys_socketpair(a0,a1, a[2], (int *)A(a[3]));
3061 break;
3062 case SYS_SEND:
3063 err = sys_send(a0, (void *)A(a1), a[2], a[3]);
3064 break;
3065 case SYS_SENDTO:
3066 err = sys_sendto(a0,(void *)A(a1), a[2], a[3],
3067 (struct sockaddr *)A(a[4]), a[5]);
3068 break;
3069 case SYS_RECV:
3070 err = sys_recv(a0, (void *)A(a1), a[2], a[3]);
3071 break;
3072 case SYS_RECVFROM:
3073 err = sys_recvfrom(a0, (void *)A(a1), a[2], a[3],
3074 (struct sockaddr *)A(a[4]), (int *)A(a[5]));
3075 break;
3076 case SYS_SHUTDOWN:
3077 err = sys_shutdown(a0,a1);
3078 break;
3079 case SYS_SETSOCKOPT:
3080 err = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]), a[4]);
3081 break;
3082 case SYS_GETSOCKOPT:
3083 err = sys_getsockopt(a0, a1, a[2], (char *)A(a[3]), (int *)A(a[4]));
3084 break;
3085 case SYS_SENDMSG:
3086 err = sys_sendmsg(a0, (struct msghdr *) A(a1), a[2]);
3087 break;
3088 case SYS_RECVMSG:
3089 err = sys_recvmsg(a0, (struct msghdr *) A(a1), a[2]);
3090 break;
3091 default:
3092 err = -EINVAL;
3093 break;
3094 }
3095 return err;
3096}
3097
3098#ifdef CONFIG_MODULES
3099
3100
3101
3102struct kernel_sym32 {
3103 u32 value;
3104 char name[60];
3105};
3106
3107extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3108
3109asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3110{
3111 int len, i;
3112 struct kernel_sym *tbl;
3113 mm_segment_t old_fs;
3114
3115 len = sys_get_kernel_syms(NULL);
3116 if (!table) return len;
3117 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3118 if (!tbl) return -ENOMEM;
3119 old_fs = get_fs();
3120 set_fs (KERNEL_DS);
3121 sys_get_kernel_syms(tbl);
3122 set_fs (old_fs);
3123 for (i = 0; i < len; i++, table++) {
3124 if (put_user (tbl[i].value, &table->value) ||
3125 copy_to_user (table->name, tbl[i].name, 60))
3126 break;
3127 }
3128 kfree (tbl);
3129 return i;
3130}
3131
3132#else
3133
3134asmlinkage unsigned long
3135sys32_create_module(const char *name_user, size_t size)
3136{
3137 return -ENOSYS;
3138}
3139
3140asmlinkage int
3141sys32_init_module(const char *name_user, struct module *mod_user)
3142{
3143 return -ENOSYS;
3144}
3145
3146asmlinkage int
3147sys32_delete_module(const char *name_user)
3148{
3149 return -ENOSYS;
3150}
3151
3152asmlinkage int
3153sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3154 size_t *ret)
3155{
3156
3157
3158 if (which == 0)
3159 return 0;
3160
3161 return -ENOSYS;
3162}
3163
3164asmlinkage long
3165sys32_get_kernel_syms(struct kernel_sym *table)
3166{
3167 return -ENOSYS;
3168}
3169
3170#endif
3171