1 /* 2 * Conversion between 32-bit and 64-bit native system calls. 3 * 4 * Copyright (C) 2000 Silicon Graphics, Inc. 5 * Written by Ulf Carlsson (ulfc@engr.sgi.com) 6 * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com) 7 */ 8 #include <linux/config.h> 9 #include <linux/compiler.h> 10 #include <linux/mm.h> 11 #include <linux/errno.h> 12 #include <linux/file.h> 13 #include <linux/smp_lock.h> 14 #include <linux/highuid.h> 15 #include <linux/dirent.h> 16 #include <linux/resource.h> 17 #include <linux/highmem.h> 18 #include <linux/time.h> 19 #include <linux/times.h> 20 #include <linux/poll.h> 21 #include <linux/slab.h> 22 #include <linux/skbuff.h> 23 #include <linux/filter.h> 24 #include <linux/shm.h> 25 #include <linux/sem.h> 26 #include <linux/msg.h> 27 #include <linux/icmpv6.h> 28 #include <linux/syscalls.h> 29 #include <linux/sysctl.h> 30 #include <linux/utime.h> 31 #include <linux/utsname.h> 32 #include <linux/personality.h> 33 #include <linux/timex.h> 34 #include <linux/dnotify.h> 35 #include <linux/module.h> 36 #include <linux/binfmts.h> 37 #include <linux/security.h> 38 #include <linux/compat.h> 39 #include <linux/vfs.h> 40 41 #include <net/sock.h> 42 #include <net/scm.h> 43 44 #include <asm/ipc.h> 45 #include <asm/sim.h> 46 #include <asm/uaccess.h> 47 #include <asm/mmu_context.h> 48 #include <asm/mman.h> 49 50 /* Use this to get at 32-bit user passed pointers. */ 51 /* A() macro should be used for places where you e.g. 52 have some internal variable u32 and just want to get 53 rid of a compiler warning. AA() has to be used in 54 places where you want to convert a function argument 55 to 32bit pointer or when you e.g. access pt_regs 56 structure and want to consider 32bit registers only. 57 */ 58 #define A(__x) ((unsigned long)(__x)) 59 #define AA(__x) ((unsigned long)((int)__x)) 60 61 #ifdef __MIPSEB__ 62 #define merge_64(r1,r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL)) 63 #endif 64 #ifdef __MIPSEL__ 65 #define merge_64(r1,r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL)) 66 #endif 67 68 /* 69 * Revalidate the inode. This is required for proper NFS attribute caching. 70 */ 71 72 int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf) 73 { 74 struct compat_stat tmp; 75 76 if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) 77 return -EOVERFLOW; 78 79 memset(&tmp, 0, sizeof(tmp)); 80 tmp.st_dev = new_encode_dev(stat->dev); 81 tmp.st_ino = stat->ino; 82 tmp.st_mode = stat->mode; 83 tmp.st_nlink = stat->nlink; 84 SET_UID(tmp.st_uid, stat->uid); 85 SET_GID(tmp.st_gid, stat->gid); 86 tmp.st_rdev = new_encode_dev(stat->rdev); 87 tmp.st_size = stat->size; 88 tmp.st_atime = stat->atime.tv_sec; 89 tmp.st_mtime = stat->mtime.tv_sec; 90 tmp.st_ctime = stat->ctime.tv_sec; 91 #ifdef STAT_HAVE_NSEC 92 tmp.st_atime_nsec = stat->atime.tv_nsec; 93 tmp.st_mtime_nsec = stat->mtime.tv_nsec; 94 tmp.st_ctime_nsec = stat->ctime.tv_nsec; 95 #endif 96 tmp.st_blocks = stat->blocks; 97 tmp.st_blksize = stat->blksize; 98 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 99 } 100 101 asmlinkage unsigned long 102 sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 103 unsigned long flags, unsigned long fd, unsigned long pgoff) 104 { 105 struct file * file = NULL; 106 unsigned long error; 107 108 error = -EINVAL; 109 if (!(flags & MAP_ANONYMOUS)) { 110 error = -EBADF; 111 file = fget(fd); 112 if (!file) 113 goto out; 114 } 115 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 116 117 down_write(¤t->mm->mmap_sem); 118 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); 119 up_write(¤t->mm->mmap_sem); 120 if (file) 121 fput(file); 122 123 out: 124 return error; 125 } 126 127 128 asmlinkage int sys_truncate64(const char *path, unsigned int high, 129 unsigned int low) 130 { 131 if ((int)high < 0) 132 return -EINVAL; 133 return sys_truncate(path, ((long) high << 32) | low); 134 } 135 136 asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high, 137 unsigned int low) 138 { 139 if ((int)high < 0) 140 return -EINVAL; 141 return sys_ftruncate(fd, ((long) high << 32) | low); 142 } 143 144 /* 145 * sys_execve() executes a new program. 146 */ 147 asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs) 148 { 149 int error; 150 char * filename; 151 152 filename = getname(compat_ptr(regs.regs[4])); 153 error = PTR_ERR(filename); 154 if (IS_ERR(filename)) 155 goto out; 156 error = compat_do_execve(filename, compat_ptr(regs.regs[5]), 157 compat_ptr(regs.regs[6]), ®s); 158 putname(filename); 159 160 out: 161 return error; 162 } 163 164 asmlinkage int 165 sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options) 166 { 167 return compat_sys_wait4(pid, stat_addr, options, NULL); 168 } 169 170 asmlinkage long 171 sysn32_waitid(int which, compat_pid_t pid, 172 siginfo_t __user *uinfo, int options, 173 struct compat_rusage __user *uru) 174 { 175 struct rusage ru; 176 long ret; 177 mm_segment_t old_fs = get_fs(); 178 179 if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo))) 180 return -EFAULT; 181 182 set_fs (KERNEL_DS); 183 ret = sys_waitid(which, pid, uinfo, options, 184 uru ? (struct rusage __user *) &ru : NULL); 185 set_fs (old_fs); 186 187 if (ret < 0 || uinfo->si_signo == 0) 188 return ret; 189 190 if (uru) 191 ret = put_compat_rusage(&ru, uru); 192 return ret; 193 } 194 195 struct sysinfo32 { 196 s32 uptime; 197 u32 loads[3]; 198 u32 totalram; 199 u32 freeram; 200 u32 sharedram; 201 u32 bufferram; 202 u32 totalswap; 203 u32 freeswap; 204 u16 procs; 205 u32 totalhigh; 206 u32 freehigh; 207 u32 mem_unit; 208 char _f[8]; 209 }; 210 211 asmlinkage int sys32_sysinfo(struct sysinfo32 *info) 212 { 213 struct sysinfo s; 214 int ret, err; 215 mm_segment_t old_fs = get_fs (); 216 217 set_fs (KERNEL_DS); 218 ret = sys_sysinfo(&s); 219 set_fs (old_fs); 220 err = put_user (s.uptime, &info->uptime); 221 err |= __put_user (s.loads[0], &info->loads[0]); 222 err |= __put_user (s.loads[1], &info->loads[1]); 223 err |= __put_user (s.loads[2], &info->loads[2]); 224 err |= __put_user (s.totalram, &info->totalram); 225 err |= __put_user (s.freeram, &info->freeram); 226 err |= __put_user (s.sharedram, &info->sharedram); 227 err |= __put_user (s.bufferram, &info->bufferram); 228 err |= __put_user (s.totalswap, &info->totalswap); 229 err |= __put_user (s.freeswap, &info->freeswap); 230 err |= __put_user (s.procs, &info->procs); 231 err |= __put_user (s.totalhigh, &info->totalhigh); 232 err |= __put_user (s.freehigh, &info->freehigh); 233 err |= __put_user (s.mem_unit, &info->mem_unit); 234 if (err) 235 return -EFAULT; 236 return ret; 237 } 238 239 #define RLIM_INFINITY32 0x7fffffff 240 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) 241 242 struct rlimit32 { 243 int rlim_cur; 244 int rlim_max; 245 }; 246 247 #ifdef __MIPSEB__ 248 asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy, 249 int length_hi, int length_lo) 250 #endif 251 #ifdef __MIPSEL__ 252 asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy, 253 int length_lo, int length_hi) 254 #endif 255 { 256 loff_t length; 257 258 length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo; 259 260 return sys_truncate(path, length); 261 } 262 263 #ifdef __MIPSEB__ 264 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, 265 int length_hi, int length_lo) 266 #endif 267 #ifdef __MIPSEL__ 268 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, 269 int length_lo, int length_hi) 270 #endif 271 { 272 loff_t length; 273 274 length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo; 275 276 return sys_ftruncate(fd, length); 277 } 278 279 static inline long 280 get_tv32(struct timeval *o, struct compat_timeval *i) 281 { 282 return (!access_ok(VERIFY_READ, i, sizeof(*i)) || 283 (__get_user(o->tv_sec, &i->tv_sec) | 284 __get_user(o->tv_usec, &i->tv_usec))); 285 } 286 287 static inline long 288 put_tv32(struct compat_timeval *o, struct timeval *i) 289 { 290 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 291 (__put_user(i->tv_sec, &o->tv_sec) | 292 __put_user(i->tv_usec, &o->tv_usec))); 293 } 294 295 extern struct timezone sys_tz; 296 297 asmlinkage int 298 sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) 299 { 300 if (tv) { 301 struct timeval ktv; 302 do_gettimeofday(&ktv); 303 if (put_tv32(tv, &ktv)) 304 return -EFAULT; 305 } 306 if (tz) { 307 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 308 return -EFAULT; 309 } 310 return 0; 311 } 312 313 static inline long get_ts32(struct timespec *o, struct compat_timeval *i) 314 { 315 long usec; 316 317 if (!access_ok(VERIFY_READ, i, sizeof(*i))) 318 return -EFAULT; 319 if (__get_user(o->tv_sec, &i->tv_sec)) 320 return -EFAULT; 321 if (__get_user(usec, &i->tv_usec)) 322 return -EFAULT; 323 o->tv_nsec = usec * 1000; 324 return 0; 325 } 326 327 asmlinkage int 328 sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) 329 { 330 struct timespec kts; 331 struct timezone ktz; 332 333 if (tv) { 334 if (get_ts32(&kts, tv)) 335 return -EFAULT; 336 } 337 if (tz) { 338 if (copy_from_user(&ktz, tz, sizeof(ktz))) 339 return -EFAULT; 340 } 341 342 return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 343 } 344 345 asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, 346 unsigned int offset_low, loff_t * result, 347 unsigned int origin) 348 { 349 return sys_llseek(fd, offset_high, offset_low, result, origin); 350 } 351 352 /* From the Single Unix Spec: pread & pwrite act like lseek to pos + op + 353 lseek back to original location. They fail just like lseek does on 354 non-seekable files. */ 355 356 asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf, 357 size_t count, u32 unused, u64 a4, u64 a5) 358 { 359 ssize_t ret; 360 struct file * file; 361 ssize_t (*read)(struct file *, char *, size_t, loff_t *); 362 loff_t pos; 363 364 ret = -EBADF; 365 file = fget(fd); 366 if (!file) 367 goto bad_file; 368 if (!(file->f_mode & FMODE_READ)) 369 goto out; 370 pos = merge_64(a4, a5); 371 ret = rw_verify_area(READ, file, &pos, count); 372 if (ret < 0) 373 goto out; 374 ret = -EINVAL; 375 if (!file->f_op || !(read = file->f_op->read)) 376 goto out; 377 if (pos < 0) 378 goto out; 379 ret = -ESPIPE; 380 if (!(file->f_mode & FMODE_PREAD)) 381 goto out; 382 ret = read(file, buf, count, &pos); 383 if (ret > 0) 384 dnotify_parent(file->f_dentry, DN_ACCESS); 385 out: 386 fput(file); 387 bad_file: 388 return ret; 389 } 390 391 asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf, 392 size_t count, u32 unused, u64 a4, u64 a5) 393 { 394 ssize_t ret; 395 struct file * file; 396 ssize_t (*write)(struct file *, const char *, size_t, loff_t *); 397 loff_t pos; 398 399 ret = -EBADF; 400 file = fget(fd); 401 if (!file) 402 goto bad_file; 403 if (!(file->f_mode & FMODE_WRITE)) 404 goto out; 405 pos = merge_64(a4, a5); 406 ret = rw_verify_area(WRITE, file, &pos, count); 407 if (ret < 0) 408 goto out; 409 ret = -EINVAL; 410 if (!file->f_op || !(write = file->f_op->write)) 411 goto out; 412 if (pos < 0) 413 goto out; 414 415 ret = -ESPIPE; 416 if (!(file->f_mode & FMODE_PWRITE)) 417 goto out; 418 419 ret = write(file, buf, count, &pos); 420 if (ret > 0) 421 dnotify_parent(file->f_dentry, DN_MODIFY); 422 out: 423 fput(file); 424 bad_file: 425 return ret; 426 } 427 428 asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, 429 struct compat_timespec *interval) 430 { 431 struct timespec t; 432 int ret; 433 mm_segment_t old_fs = get_fs (); 434 435 set_fs (KERNEL_DS); 436 ret = sys_sched_rr_get_interval(pid, &t); 437 set_fs (old_fs); 438 if (put_user (t.tv_sec, &interval->tv_sec) || 439 __put_user (t.tv_nsec, &interval->tv_nsec)) 440 return -EFAULT; 441 return ret; 442 } 443 444 struct msgbuf32 { s32 mtype; char mtext[1]; }; 445 446 struct ipc_perm32 447 { 448 key_t key; 449 __compat_uid_t uid; 450 __compat_gid_t gid; 451 __compat_uid_t cuid; 452 __compat_gid_t cgid; 453 compat_mode_t mode; 454 unsigned short seq; 455 }; 456 457 struct ipc64_perm32 { 458 key_t key; 459 __compat_uid_t uid; 460 __compat_gid_t gid; 461 __compat_uid_t cuid; 462 __compat_gid_t cgid; 463 compat_mode_t mode; 464 unsigned short seq; 465 unsigned short __pad1; 466 unsigned int __unused1; 467 unsigned int __unused2; 468 }; 469 470 struct semid_ds32 { 471 struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */ 472 compat_time_t sem_otime; /* last semop time */ 473 compat_time_t sem_ctime; /* last change time */ 474 u32 sem_base; /* ptr to first semaphore in array */ 475 u32 sem_pending; /* pending operations to be processed */ 476 u32 sem_pending_last; /* last pending operation */ 477 u32 undo; /* undo requests on this array */ 478 unsigned short sem_nsems; /* no. of semaphores in array */ 479 }; 480 481 struct semid64_ds32 { 482 struct ipc64_perm32 sem_perm; 483 compat_time_t sem_otime; 484 compat_time_t sem_ctime; 485 unsigned int sem_nsems; 486 unsigned int __unused1; 487 unsigned int __unused2; 488 }; 489 490 struct msqid_ds32 491 { 492 struct ipc_perm32 msg_perm; 493 u32 msg_first; 494 u32 msg_last; 495 compat_time_t msg_stime; 496 compat_time_t msg_rtime; 497 compat_time_t msg_ctime; 498 u32 wwait; 499 u32 rwait; 500 unsigned short msg_cbytes; 501 unsigned short msg_qnum; 502 unsigned short msg_qbytes; 503 compat_ipc_pid_t msg_lspid; 504 compat_ipc_pid_t msg_lrpid; 505 }; 506 507 struct msqid64_ds32 { 508 struct ipc64_perm32 msg_perm; 509 compat_time_t msg_stime; 510 unsigned int __unused1; 511 compat_time_t msg_rtime; 512 unsigned int __unused2; 513 compat_time_t msg_ctime; 514 unsigned int __unused3; 515 unsigned int msg_cbytes; 516 unsigned int msg_qnum; 517 unsigned int msg_qbytes; 518 compat_pid_t msg_lspid; 519 compat_pid_t msg_lrpid; 520 unsigned int __unused4; 521 unsigned int __unused5; 522 }; 523 524 struct shmid_ds32 { 525 struct ipc_perm32 shm_perm; 526 int shm_segsz; 527 compat_time_t shm_atime; 528 compat_time_t shm_dtime; 529 compat_time_t shm_ctime; 530 compat_ipc_pid_t shm_cpid; 531 compat_ipc_pid_t shm_lpid; 532 unsigned short shm_nattch; 533 }; 534 535 struct shmid64_ds32 { 536 struct ipc64_perm32 shm_perm; 537 compat_size_t shm_segsz; 538 compat_time_t shm_atime; 539 compat_time_t shm_dtime; 540 compat_time_t shm_ctime; 541 compat_pid_t shm_cpid; 542 compat_pid_t shm_lpid; 543 unsigned int shm_nattch; 544 unsigned int __unused1; 545 unsigned int __unused2; 546 }; 547 548 struct ipc_kludge32 { 549 u32 msgp; 550 s32 msgtyp; 551 }; 552 553 static int 554 do_sys32_semctl(int first, int second, int third, void *uptr) 555 { 556 union semun fourth; 557 u32 pad; 558 int err, err2; 559 struct semid64_ds s; 560 mm_segment_t old_fs; 561 562 if (!uptr) 563 return -EINVAL; 564 err = -EFAULT; 565 if (get_user (pad, (u32 *)uptr)) 566 return err; 567 if ((third & ~IPC_64) == SETVAL) 568 fourth.val = (int)pad; 569 else 570 fourth.__pad = (void *)A(pad); 571 switch (third & ~IPC_64) { 572 case IPC_INFO: 573 case IPC_RMID: 574 case IPC_SET: 575 case SEM_INFO: 576 case GETVAL: 577 case GETPID: 578 case GETNCNT: 579 case GETZCNT: 580 case GETALL: 581 case SETVAL: 582 case SETALL: 583 err = sys_semctl (first, second, third, fourth); 584 break; 585 586 case IPC_STAT: 587 case SEM_STAT: 588 fourth.__pad = &s; 589 old_fs = get_fs(); 590 set_fs(KERNEL_DS); 591 err = sys_semctl(first, second, third | IPC_64, fourth); 592 set_fs(old_fs); 593 594 if (third & IPC_64) { 595 struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad); 596 597 if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) { 598 err = -EFAULT; 599 break; 600 } 601 err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key); 602 err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid); 603 err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid); 604 err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid); 605 err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid); 606 err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode); 607 err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq); 608 err2 |= __put_user(s.sem_otime, &usp64->sem_otime); 609 err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime); 610 err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems); 611 } else { 612 struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad); 613 614 if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) { 615 err = -EFAULT; 616 break; 617 } 618 err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key); 619 err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid); 620 err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid); 621 err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid); 622 err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid); 623 err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode); 624 err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq); 625 err2 |= __put_user(s.sem_otime, &usp32->sem_otime); 626 err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime); 627 err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems); 628 } 629 if (err2) 630 err = -EFAULT; 631 break; 632 633 default: 634 err = - EINVAL; 635 break; 636 } 637 638 return err; 639 } 640 641 static int 642 do_sys32_msgsnd (int first, int second, int third, void *uptr) 643 { 644 struct msgbuf32 *up = (struct msgbuf32 *)uptr; 645 struct msgbuf *p; 646 mm_segment_t old_fs; 647 int err; 648 649 if (second < 0) 650 return -EINVAL; 651 p = kmalloc (second + sizeof (struct msgbuf) 652 + 4, GFP_USER); 653 if (!p) 654 return -ENOMEM; 655 err = get_user (p->mtype, &up->mtype); 656 if (err) 657 goto out; 658 err |= __copy_from_user (p->mtext, &up->mtext, second); 659 if (err) 660 goto out; 661 old_fs = get_fs (); 662 set_fs (KERNEL_DS); 663 err = sys_msgsnd (first, p, second, third); 664 set_fs (old_fs); 665 out: 666 kfree (p); 667 668 return err; 669 } 670 671 static int 672 do_sys32_msgrcv (int first, int second, int msgtyp, int third, 673 int version, void *uptr) 674 { 675 struct msgbuf32 *up; 676 struct msgbuf *p; 677 mm_segment_t old_fs; 678 int err; 679 680 if (!version) { 681 struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr; 682 struct ipc_kludge32 ipck; 683 684 err = -EINVAL; 685 if (!uptr) 686 goto out; 687 err = -EFAULT; 688 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32))) 689 goto out; 690 uptr = (void *)AA(ipck.msgp); 691 msgtyp = ipck.msgtyp; 692 } 693 694 if (second < 0) 695 return -EINVAL; 696 err = -ENOMEM; 697 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); 698 if (!p) 699 goto out; 700 old_fs = get_fs (); 701 set_fs (KERNEL_DS); 702 err = sys_msgrcv (first, p, second + 4, msgtyp, third); 703 set_fs (old_fs); 704 if (err < 0) 705 goto free_then_out; 706 up = (struct msgbuf32 *)uptr; 707 if (put_user (p->mtype, &up->mtype) || 708 __copy_to_user (&up->mtext, p->mtext, err)) 709 err = -EFAULT; 710 free_then_out: 711 kfree (p); 712 out: 713 return err; 714 } 715 716 static int 717 do_sys32_msgctl (int first, int second, void *uptr) 718 { 719 int err = -EINVAL, err2; 720 struct msqid64_ds m; 721 struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr; 722 struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr; 723 mm_segment_t old_fs; 724 725 switch (second & ~IPC_64) { 726 case IPC_INFO: 727 case IPC_RMID: 728 case MSG_INFO: 729 err = sys_msgctl (first, second, (struct msqid_ds *)uptr); 730 break; 731 732 case IPC_SET: 733 if (second & IPC_64) { 734 if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) { 735 err = -EFAULT; 736 break; 737 } 738 err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid); 739 err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid); 740 err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode); 741 err |= __get_user(m.msg_qbytes, &up64->msg_qbytes); 742 } else { 743 if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) { 744 err = -EFAULT; 745 break; 746 } 747 err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid); 748 err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid); 749 err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode); 750 err |= __get_user(m.msg_qbytes, &up32->msg_qbytes); 751 } 752 if (err) 753 break; 754 old_fs = get_fs(); 755 set_fs(KERNEL_DS); 756 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m); 757 set_fs(old_fs); 758 break; 759 760 case IPC_STAT: 761 case MSG_STAT: 762 old_fs = get_fs(); 763 set_fs(KERNEL_DS); 764 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m); 765 set_fs(old_fs); 766 if (second & IPC_64) { 767 if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { 768 err = -EFAULT; 769 break; 770 } 771 err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key); 772 err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid); 773 err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid); 774 err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid); 775 err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid); 776 err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode); 777 err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq); 778 err2 |= __put_user(m.msg_stime, &up64->msg_stime); 779 err2 |= __put_user(m.msg_rtime, &up64->msg_rtime); 780 err2 |= __put_user(m.msg_ctime, &up64->msg_ctime); 781 err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes); 782 err2 |= __put_user(m.msg_qnum, &up64->msg_qnum); 783 err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes); 784 err2 |= __put_user(m.msg_lspid, &up64->msg_lspid); 785 err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid); 786 if (err2) 787 err = -EFAULT; 788 } else { 789 if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { 790 err = -EFAULT; 791 break; 792 } 793 err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key); 794 err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid); 795 err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid); 796 err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid); 797 err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid); 798 err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode); 799 err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq); 800 err2 |= __put_user(m.msg_stime, &up32->msg_stime); 801 err2 |= __put_user(m.msg_rtime, &up32->msg_rtime); 802 err2 |= __put_user(m.msg_ctime, &up32->msg_ctime); 803 err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes); 804 err2 |= __put_user(m.msg_qnum, &up32->msg_qnum); 805 err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes); 806 err2 |= __put_user(m.msg_lspid, &up32->msg_lspid); 807 err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid); 808 if (err2) 809 err = -EFAULT; 810 } 811 break; 812 } 813 814 return err; 815 } 816 817 static int 818 do_sys32_shmat (int first, int second, int third, int version, void *uptr) 819 { 820 unsigned long raddr; 821 u32 *uaddr = (u32 *)A((u32)third); 822 int err = -EINVAL; 823 824 if (version == 1) 825 return err; 826 err = do_shmat (first, uptr, second, &raddr); 827 if (err) 828 return err; 829 err = put_user (raddr, uaddr); 830 return err; 831 } 832 833 struct shm_info32 { 834 int used_ids; 835 u32 shm_tot, shm_rss, shm_swp; 836 u32 swap_attempts, swap_successes; 837 }; 838 839 static int 840 do_sys32_shmctl (int first, int second, void *uptr) 841 { 842 struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr; 843 struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr; 844 struct shm_info32 *uip = (struct shm_info32 *)uptr; 845 int err = -EFAULT, err2; 846 struct shmid64_ds s64; 847 mm_segment_t old_fs; 848 struct shm_info si; 849 struct shmid_ds s; 850 851 switch (second & ~IPC_64) { 852 case IPC_INFO: 853 second = IPC_INFO; /* So that we don't have to translate it */ 854 case IPC_RMID: 855 case SHM_LOCK: 856 case SHM_UNLOCK: 857 err = sys_shmctl(first, second, (struct shmid_ds *)uptr); 858 break; 859 case IPC_SET: 860 if (second & IPC_64) { 861 err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); 862 err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); 863 err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); 864 } else { 865 err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); 866 err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); 867 err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); 868 } 869 if (err) 870 break; 871 old_fs = get_fs(); 872 set_fs(KERNEL_DS); 873 err = sys_shmctl(first, second & ~IPC_64, &s); 874 set_fs(old_fs); 875 break; 876 877 case IPC_STAT: 878 case SHM_STAT: 879 old_fs = get_fs(); 880 set_fs(KERNEL_DS); 881 err = sys_shmctl(first, second | IPC_64, (void *) &s64); 882 set_fs(old_fs); 883 if (err < 0) 884 break; 885 if (second & IPC_64) { 886 if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { 887 err = -EFAULT; 888 break; 889 } 890 err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key); 891 err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid); 892 err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid); 893 err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid); 894 err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid); 895 err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode); 896 err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq); 897 err2 |= __put_user(s64.shm_atime, &up64->shm_atime); 898 err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime); 899 err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime); 900 err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz); 901 err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch); 902 err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid); 903 err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid); 904 } else { 905 if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { 906 err = -EFAULT; 907 break; 908 } 909 err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key); 910 err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid); 911 err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid); 912 err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid); 913 err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid); 914 err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode); 915 err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq); 916 err2 |= __put_user(s64.shm_atime, &up32->shm_atime); 917 err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime); 918 err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime); 919 err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz); 920 err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch); 921 err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid); 922 err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid); 923 } 924 if (err2) 925 err = -EFAULT; 926 break; 927 928 case SHM_INFO: 929 old_fs = get_fs(); 930 set_fs(KERNEL_DS); 931 err = sys_shmctl(first, second, (void *)&si); 932 set_fs(old_fs); 933 if (err < 0) 934 break; 935 err2 = put_user(si.used_ids, &uip->used_ids); 936 err2 |= __put_user(si.shm_tot, &uip->shm_tot); 937 err2 |= __put_user(si.shm_rss, &uip->shm_rss); 938 err2 |= __put_user(si.shm_swp, &uip->shm_swp); 939 err2 |= __put_user(si.swap_attempts, &uip->swap_attempts); 940 err2 |= __put_user (si.swap_successes, &uip->swap_successes); 941 if (err2) 942 err = -EFAULT; 943 break; 944 945 default: 946 err = -EINVAL; 947 break; 948 } 949 950 return err; 951 } 952 953 static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems, 954 const struct compat_timespec *timeout32) 955 { 956 struct compat_timespec t32; 957 struct timespec *t64 = compat_alloc_user_space(sizeof(*t64)); 958 959 if (copy_from_user(&t32, timeout32, sizeof(t32))) 960 return -EFAULT; 961 962 if (put_user(t32.tv_sec, &t64->tv_sec) || 963 put_user(t32.tv_nsec, &t64->tv_nsec)) 964 return -EFAULT; 965 966 return sys_semtimedop(semid, tsems, nsems, t64); 967 } 968 969 asmlinkage long 970 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) 971 { 972 int version, err; 973 974 version = call >> 16; /* hack for backward compatibility */ 975 call &= 0xffff; 976 977 switch (call) { 978 case SEMOP: 979 /* struct sembuf is the same on 32 and 64bit :)) */ 980 err = sys_semtimedop (first, (struct sembuf *)AA(ptr), second, 981 NULL); 982 break; 983 case SEMTIMEDOP: 984 err = sys32_semtimedop (first, (struct sembuf *)AA(ptr), second, 985 (const struct compat_timespec __user *)AA(fifth)); 986 break; 987 case SEMGET: 988 err = sys_semget (first, second, third); 989 break; 990 case SEMCTL: 991 err = do_sys32_semctl (first, second, third, 992 (void *)AA(ptr)); 993 break; 994 995 case MSGSND: 996 err = do_sys32_msgsnd (first, second, third, 997 (void *)AA(ptr)); 998 break; 999 case MSGRCV: 1000 err = do_sys32_msgrcv (first, second, fifth, third, 1001 version, (void *)AA(ptr)); 1002 break; 1003 case MSGGET: 1004 err = sys_msgget ((key_t) first, second); 1005 break; 1006 case MSGCTL: 1007 err = do_sys32_msgctl (first, second, (void *)AA(ptr)); 1008 break; 1009 1010 case SHMAT: 1011 err = do_sys32_shmat (first, second, third, 1012 version, (void *)AA(ptr)); 1013 break; 1014 case SHMDT: 1015 err = sys_shmdt ((char *)A(ptr)); 1016 break; 1017 case SHMGET: 1018 err = sys_shmget (first, (unsigned)second, third); 1019 break; 1020 case SHMCTL: 1021 err = do_sys32_shmctl (first, second, (void *)AA(ptr)); 1022 break; 1023 default: 1024 err = -EINVAL; 1025 break; 1026 } 1027 1028 return err; 1029 } 1030 1031 asmlinkage long sys32_shmat(int shmid, char __user *shmaddr, 1032 int shmflg, int32_t *addr) 1033 { 1034 unsigned long raddr; 1035 int err; 1036 1037 err = do_shmat(shmid, shmaddr, shmflg, &raddr); 1038 if (err) 1039 return err; 1040 1041 return put_user(raddr, addr); 1042 } 1043 1044 struct sysctl_args32 1045 { 1046 compat_caddr_t name; 1047 int nlen; 1048 compat_caddr_t oldval; 1049 compat_caddr_t oldlenp; 1050 compat_caddr_t newval; 1051 compat_size_t newlen; 1052 unsigned int __unused[4]; 1053 }; 1054 1055 #ifdef CONFIG_SYSCTL 1056 1057 asmlinkage long sys32_sysctl(struct sysctl_args32 *args) 1058 { 1059 struct sysctl_args32 tmp; 1060 int error; 1061 size_t oldlen, *oldlenp = NULL; 1062 unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; 1063 1064 if (copy_from_user(&tmp, args, sizeof(tmp))) 1065 return -EFAULT; 1066 1067 if (tmp.oldval && tmp.oldlenp) { 1068 /* Duh, this is ugly and might not work if sysctl_args 1069 is in read-only memory, but do_sysctl does indirectly 1070 a lot of uaccess in both directions and we'd have to 1071 basically copy the whole sysctl.c here, and 1072 glibc's __sysctl uses rw memory for the structure 1073 anyway. */ 1074 if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) || 1075 put_user(oldlen, (size_t *)addr)) 1076 return -EFAULT; 1077 oldlenp = (size_t *)addr; 1078 } 1079 1080 lock_kernel(); 1081 error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval), 1082 oldlenp, (void *)A(tmp.newval), tmp.newlen); 1083 unlock_kernel(); 1084 if (oldlenp) { 1085 if (!error) { 1086 if (get_user(oldlen, (size_t *)addr) || 1087 put_user(oldlen, (u32 *)A(tmp.oldlenp))) 1088 error = -EFAULT; 1089 } 1090 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); 1091 } 1092 return error; 1093 } 1094 1095 #endif /* CONFIG_SYSCTL */ 1096 1097 asmlinkage long sys32_newuname(struct new_utsname * name) 1098 { 1099 int ret = 0; 1100 1101 down_read(&uts_sem); 1102 if (copy_to_user(name,&system_utsname,sizeof *name)) 1103 ret = -EFAULT; 1104 up_read(&uts_sem); 1105 1106 if (current->personality == PER_LINUX32 && !ret) 1107 if (copy_to_user(name->machine, "mips\0\0\0", 8)) 1108 ret = -EFAULT; 1109 1110 return ret; 1111 } 1112 1113 asmlinkage int sys32_personality(unsigned long personality) 1114 { 1115 int ret; 1116 if (current->personality == PER_LINUX32 && personality == PER_LINUX) 1117 personality = PER_LINUX32; 1118 ret = sys_personality(personality); 1119 if (ret == PER_LINUX32) 1120 ret = PER_LINUX; 1121 return ret; 1122 } 1123 1124 /* ustat compatibility */ 1125 struct ustat32 { 1126 compat_daddr_t f_tfree; 1127 compat_ino_t f_tinode; 1128 char f_fname[6]; 1129 char f_fpack[6]; 1130 }; 1131 1132 extern asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf); 1133 1134 asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32) 1135 { 1136 int err; 1137 struct ustat tmp; 1138 struct ustat32 tmp32; 1139 mm_segment_t old_fs = get_fs(); 1140 1141 set_fs(KERNEL_DS); 1142 err = sys_ustat(dev, &tmp); 1143 set_fs (old_fs); 1144 1145 if (err) 1146 goto out; 1147 1148 memset(&tmp32,0,sizeof(struct ustat32)); 1149 tmp32.f_tfree = tmp.f_tfree; 1150 tmp32.f_tinode = tmp.f_tinode; 1151 1152 err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0; 1153 1154 out: 1155 return err; 1156 } 1157 1158 /* Handle adjtimex compatibility. */ 1159 1160 struct timex32 { 1161 u32 modes; 1162 s32 offset, freq, maxerror, esterror; 1163 s32 status, constant, precision, tolerance; 1164 struct compat_timeval time; 1165 s32 tick; 1166 s32 ppsfreq, jitter, shift, stabil; 1167 s32 jitcnt, calcnt, errcnt, stbcnt; 1168 s32 :32; s32 :32; s32 :32; s32 :32; 1169 s32 :32; s32 :32; s32 :32; s32 :32; 1170 s32 :32; s32 :32; s32 :32; s32 :32; 1171 }; 1172 1173 extern int do_adjtimex(struct timex *); 1174 1175 asmlinkage int sys32_adjtimex(struct timex32 *utp) 1176 { 1177 struct timex txc; 1178 int ret; 1179 1180 memset(&txc, 0, sizeof(struct timex)); 1181 1182 if (get_user(txc.modes, &utp->modes) || 1183 __get_user(txc.offset, &utp->offset) || 1184 __get_user(txc.freq, &utp->freq) || 1185 __get_user(txc.maxerror, &utp->maxerror) || 1186 __get_user(txc.esterror, &utp->esterror) || 1187 __get_user(txc.status, &utp->status) || 1188 __get_user(txc.constant, &utp->constant) || 1189 __get_user(txc.precision, &utp->precision) || 1190 __get_user(txc.tolerance, &utp->tolerance) || 1191 __get_user(txc.time.tv_sec, &utp->time.tv_sec) || 1192 __get_user(txc.time.tv_usec, &utp->time.tv_usec) || 1193 __get_user(txc.tick, &utp->tick) || 1194 __get_user(txc.ppsfreq, &utp->ppsfreq) || 1195 __get_user(txc.jitter, &utp->jitter) || 1196 __get_user(txc.shift, &utp->shift) || 1197 __get_user(txc.stabil, &utp->stabil) || 1198 __get_user(txc.jitcnt, &utp->jitcnt) || 1199 __get_user(txc.calcnt, &utp->calcnt) || 1200 __get_user(txc.errcnt, &utp->errcnt) || 1201 __get_user(txc.stbcnt, &utp->stbcnt)) 1202 return -EFAULT; 1203 1204 ret = do_adjtimex(&txc); 1205 1206 if (put_user(txc.modes, &utp->modes) || 1207 __put_user(txc.offset, &utp->offset) || 1208 __put_user(txc.freq, &utp->freq) || 1209 __put_user(txc.maxerror, &utp->maxerror) || 1210 __put_user(txc.esterror, &utp->esterror) || 1211 __put_user(txc.status, &utp->status) || 1212 __put_user(txc.constant, &utp->constant) || 1213 __put_user(txc.precision, &utp->precision) || 1214 __put_user(txc.tolerance, &utp->tolerance) || 1215 __put_user(txc.time.tv_sec, &utp->time.tv_sec) || 1216 __put_user(txc.time.tv_usec, &utp->time.tv_usec) || 1217 __put_user(txc.tick, &utp->tick) || 1218 __put_user(txc.ppsfreq, &utp->ppsfreq) || 1219 __put_user(txc.jitter, &utp->jitter) || 1220 __put_user(txc.shift, &utp->shift) || 1221 __put_user(txc.stabil, &utp->stabil) || 1222 __put_user(txc.jitcnt, &utp->jitcnt) || 1223 __put_user(txc.calcnt, &utp->calcnt) || 1224 __put_user(txc.errcnt, &utp->errcnt) || 1225 __put_user(txc.stbcnt, &utp->stbcnt)) 1226 ret = -EFAULT; 1227 1228 return ret; 1229 } 1230 1231 asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, 1232 s32 count) 1233 { 1234 mm_segment_t old_fs = get_fs(); 1235 int ret; 1236 off_t of; 1237 1238 if (offset && get_user(of, offset)) 1239 return -EFAULT; 1240 1241 set_fs(KERNEL_DS); 1242 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); 1243 set_fs(old_fs); 1244 1245 if (offset && put_user(of, offset)) 1246 return -EFAULT; 1247 1248 return ret; 1249 } 1250 1251 asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3, 1252 size_t count) 1253 { 1254 return sys_readahead(fd, merge_64(a2, a3), count); 1255 } 1256 1257 /* Argument list sizes for sys_socketcall */ 1258 #define AL(x) ((x) * sizeof(unsigned int)) 1259 static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), 1260 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), 1261 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)}; 1262 #undef AL 1263 1264 /* 1265 * System call vectors. 1266 * 1267 * Argument checking cleaned up. Saved 20% in size. 1268 * This function doesn't need to set the kernel lock because 1269 * it is set by the callees. 1270 */ 1271 1272 asmlinkage long sys32_socketcall(int call, unsigned int *args32) 1273 { 1274 unsigned int a[6]; 1275 unsigned int a0,a1; 1276 int err; 1277 1278 extern asmlinkage long sys_socket(int family, int type, int protocol); 1279 extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); 1280 extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen); 1281 extern asmlinkage long sys_listen(int fd, int backlog); 1282 extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen); 1283 extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); 1284 extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); 1285 extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec); 1286 extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags); 1287 extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags, 1288 struct sockaddr __user *addr, int addr_len); 1289 extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags); 1290 extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags, 1291 struct sockaddr __user *addr, int __user *addr_len); 1292 extern asmlinkage long sys_shutdown(int fd, int how); 1293 extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen); 1294 extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int *optlen); 1295 extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); 1296 extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags); 1297 1298 1299 if(call<1||call>SYS_RECVMSG) 1300 return -EINVAL; 1301 1302 /* copy_from_user should be SMP safe. */ 1303 if (copy_from_user(a, args32, socketcall_nargs[call])) 1304 return -EFAULT; 1305 1306 a0=a[0]; 1307 a1=a[1]; 1308 1309 switch(call) 1310 { 1311 case SYS_SOCKET: 1312 err = sys_socket(a0,a1,a[2]); 1313 break; 1314 case SYS_BIND: 1315 err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]); 1316 break; 1317 case SYS_CONNECT: 1318 err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]); 1319 break; 1320 case SYS_LISTEN: 1321 err = sys_listen(a0,a1); 1322 break; 1323 case SYS_ACCEPT: 1324 err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1325 break; 1326 case SYS_GETSOCKNAME: 1327 err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1328 break; 1329 case SYS_GETPEERNAME: 1330 err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1331 break; 1332 case SYS_SOCKETPAIR: 1333 err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3])); 1334 break; 1335 case SYS_SEND: 1336 err = sys_send(a0, (void __user *)A(a1), a[2], a[3]); 1337 break; 1338 case SYS_SENDTO: 1339 err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3], 1340 (struct sockaddr __user *)A(a[4]), a[5]); 1341 break; 1342 case SYS_RECV: 1343 err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]); 1344 break; 1345 case SYS_RECVFROM: 1346 err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3], 1347 (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5])); 1348 break; 1349 case SYS_SHUTDOWN: 1350 err = sys_shutdown(a0,a1); 1351 break; 1352 case SYS_SETSOCKOPT: 1353 err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]); 1354 break; 1355 case SYS_GETSOCKOPT: 1356 err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4])); 1357 break; 1358 case SYS_SENDMSG: 1359 err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]); 1360 break; 1361 case SYS_RECVMSG: 1362 err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]); 1363 break; 1364 default: 1365 err = -EINVAL; 1366 break; 1367 } 1368 return err; 1369 } 1370 1371 struct sigevent32 { 1372 u32 sigev_value; 1373 u32 sigev_signo; 1374 u32 sigev_notify; 1375 u32 payload[(64 / 4) - 3]; 1376 }; 1377 1378 extern asmlinkage long 1379 sys_timer_create(clockid_t which_clock, 1380 struct sigevent __user *timer_event_spec, 1381 timer_t __user * created_timer_id); 1382 1383 long 1384 sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id) 1385 { 1386 struct sigevent __user *p = NULL; 1387 if (se32) { 1388 struct sigevent se; 1389 p = compat_alloc_user_space(sizeof(struct sigevent)); 1390 memset(&se, 0, sizeof(struct sigevent)); 1391 if (get_user(se.sigev_value.sival_int, &se32->sigev_value) || 1392 __get_user(se.sigev_signo, &se32->sigev_signo) || 1393 __get_user(se.sigev_notify, &se32->sigev_notify) || 1394 __copy_from_user(&se._sigev_un._pad, &se32->payload, 1395 sizeof(se32->payload)) || 1396 copy_to_user(p, &se, sizeof(se))) 1397 return -EFAULT; 1398 } 1399 return sys_timer_create(clock, p, timer_id); 1400 } 1401 1402 save_static_function(sys32_clone); 1403 __attribute_used__ noinline static int 1404 _sys32_clone(nabi_no_regargs struct pt_regs regs) 1405 { 1406 unsigned long clone_flags; 1407 unsigned long newsp; 1408 int __user *parent_tidptr, *child_tidptr; 1409 1410 clone_flags = regs.regs[4]; 1411 newsp = regs.regs[5]; 1412 if (!newsp) 1413 newsp = regs.regs[29]; 1414 parent_tidptr = (int *) regs.regs[6]; 1415 1416 /* Use __dummy4 instead of getting it off the stack, so that 1417 syscall() works. */ 1418 child_tidptr = (int __user *) __dummy4; 1419 return do_fork(clone_flags, newsp, ®s, 0, 1420 parent_tidptr, child_tidptr); 1421 } 1422 1423 extern asmlinkage void sys_set_thread_area(u32 addr); 1424 asmlinkage void sys32_set_thread_area(u32 addr) 1425 { 1426 sys_set_thread_area(AA(addr)); 1427 } 1428