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/dnotify.h> 34 #include <linux/module.h> 35 #include <linux/binfmts.h> 36 #include <linux/security.h> 37 #include <linux/compat.h> 38 #include <linux/vfs.h> 39 40 #include <net/sock.h> 41 #include <net/scm.h> 42 43 #include <asm/ipc.h> 44 #include <asm/sim.h> 45 #include <asm/uaccess.h> 46 #include <asm/mmu_context.h> 47 #include <asm/mman.h> 48 49 /* Use this to get at 32-bit user passed pointers. */ 50 /* A() macro should be used for places where you e.g. 51 have some internal variable u32 and just want to get 52 rid of a compiler warning. AA() has to be used in 53 places where you want to convert a function argument 54 to 32bit pointer or when you e.g. access pt_regs 55 structure and want to consider 32bit registers only. 56 */ 57 #define A(__x) ((unsigned long)(__x)) 58 #define AA(__x) ((unsigned long)((int)__x)) 59 60 #ifdef __MIPSEB__ 61 #define merge_64(r1,r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL)) 62 #endif 63 #ifdef __MIPSEL__ 64 #define merge_64(r1,r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL)) 65 #endif 66 67 /* 68 * Revalidate the inode. This is required for proper NFS attribute caching. 69 */ 70 71 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) 72 { 73 struct compat_stat tmp; 74 75 if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) 76 return -EOVERFLOW; 77 78 memset(&tmp, 0, sizeof(tmp)); 79 tmp.st_dev = new_encode_dev(stat->dev); 80 tmp.st_ino = stat->ino; 81 tmp.st_mode = stat->mode; 82 tmp.st_nlink = stat->nlink; 83 SET_UID(tmp.st_uid, stat->uid); 84 SET_GID(tmp.st_gid, stat->gid); 85 tmp.st_rdev = new_encode_dev(stat->rdev); 86 tmp.st_size = stat->size; 87 tmp.st_atime = stat->atime.tv_sec; 88 tmp.st_mtime = stat->mtime.tv_sec; 89 tmp.st_ctime = stat->ctime.tv_sec; 90 #ifdef STAT_HAVE_NSEC 91 tmp.st_atime_nsec = stat->atime.tv_nsec; 92 tmp.st_mtime_nsec = stat->mtime.tv_nsec; 93 tmp.st_ctime_nsec = stat->ctime.tv_nsec; 94 #endif 95 tmp.st_blocks = stat->blocks; 96 tmp.st_blksize = stat->blksize; 97 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 98 } 99 100 asmlinkage unsigned long 101 sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 102 unsigned long flags, unsigned long fd, unsigned long pgoff) 103 { 104 struct file * file = NULL; 105 unsigned long error; 106 107 error = -EINVAL; 108 if (pgoff & (~PAGE_MASK >> 12)) 109 goto out; 110 pgoff >>= PAGE_SHIFT-12; 111 112 if (!(flags & MAP_ANONYMOUS)) { 113 error = -EBADF; 114 file = fget(fd); 115 if (!file) 116 goto out; 117 } 118 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 119 120 down_write(¤t->mm->mmap_sem); 121 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); 122 up_write(¤t->mm->mmap_sem); 123 if (file) 124 fput(file); 125 126 out: 127 return error; 128 } 129 130 131 asmlinkage int sys_truncate64(const char __user *path, unsigned int high, 132 unsigned int low) 133 { 134 if ((int)high < 0) 135 return -EINVAL; 136 return sys_truncate(path, ((long) high << 32) | low); 137 } 138 139 asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high, 140 unsigned int low) 141 { 142 if ((int)high < 0) 143 return -EINVAL; 144 return sys_ftruncate(fd, ((long) high << 32) | low); 145 } 146 147 /* 148 * sys_execve() executes a new program. 149 */ 150 asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs) 151 { 152 int error; 153 char * filename; 154 155 filename = getname(compat_ptr(regs.regs[4])); 156 error = PTR_ERR(filename); 157 if (IS_ERR(filename)) 158 goto out; 159 error = compat_do_execve(filename, compat_ptr(regs.regs[5]), 160 compat_ptr(regs.regs[6]), ®s); 161 putname(filename); 162 163 out: 164 return error; 165 } 166 167 asmlinkage long 168 sysn32_waitid(int which, compat_pid_t pid, 169 siginfo_t __user *uinfo, int options, 170 struct compat_rusage __user *uru) 171 { 172 struct rusage ru; 173 long ret; 174 mm_segment_t old_fs = get_fs(); 175 int si_signo; 176 177 if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo))) 178 return -EFAULT; 179 180 set_fs (KERNEL_DS); 181 ret = sys_waitid(which, pid, uinfo, options, 182 uru ? (struct rusage __user *) &ru : NULL); 183 set_fs (old_fs); 184 185 if (__get_user(si_signo, &uinfo->si_signo)) 186 return -EFAULT; 187 if (ret < 0 || 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 __user *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((struct sysinfo __user *)&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 __user * path, unsigned long __dummy, 249 int length_hi, int length_lo) 250 #endif 251 #ifdef __MIPSEL__ 252 asmlinkage long sys32_truncate64(const char __user * 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 __user *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 __user *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 __user *tv, struct timezone __user *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 __user *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 __user *tv, struct timezone __user *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 __user * 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 __user * 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 __user *, 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 __user * 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 __user *, 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 __user *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, (struct timespec __user *)&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 __user *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 __user *)uptr)) 566 return err; 567 if ((third & ~IPC_64) == SETVAL) 568 fourth.val = (int)pad; 569 else 570 fourth.__pad = (void __user *)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 = (struct semid64_ds __user *)&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 __user *usp64 = (struct semid64_ds32 __user *) 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 __user *usp32 = (struct semid_ds32 __user *) 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 __user *uptr) 643 { 644 struct msgbuf32 __user *up = (struct msgbuf32 __user *)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, (struct msgbuf __user *)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 __user *uptr) 674 { 675 struct msgbuf32 __user *up; 676 struct msgbuf *p; 677 mm_segment_t old_fs; 678 int err; 679 680 if (!version) { 681 struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)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 __user *)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, (struct msgbuf __user *)p, second + 4, msgtyp, third); 703 set_fs (old_fs); 704 if (err < 0) 705 goto free_then_out; 706 up = (struct msgbuf32 __user *)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 __user *uptr) 718 { 719 int err = -EINVAL, err2; 720 struct msqid64_ds m; 721 struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr; 722 struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)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 __user *)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 __user *)&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 __user *)&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 __user *uptr) 819 { 820 unsigned long raddr; 821 u32 __user *uaddr = (u32 __user *)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 __user *uptr) 841 { 842 struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr; 843 struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr; 844 struct shm_info32 __user *uip = (struct shm_info32 __user *)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 __user *)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, (struct shmid_ds __user *)&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 __user *) &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 __user *)&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 __user *tsems, int nsems, 954 const struct compat_timespec __user *timeout32) 955 { 956 struct compat_timespec t32; 957 struct timespec __user *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 __user *)AA(ptr), second, 981 NULL); 982 break; 983 case SEMTIMEDOP: 984 err = sys32_semtimedop (first, (struct sembuf __user *)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 __user *)AA(ptr)); 993 break; 994 995 case MSGSND: 996 err = do_sys32_msgsnd (first, second, third, 997 (void __user *)AA(ptr)); 998 break; 999 case MSGRCV: 1000 err = do_sys32_msgrcv (first, second, fifth, third, 1001 version, (void __user *)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 __user *)AA(ptr)); 1008 break; 1009 1010 case SHMAT: 1011 err = do_sys32_shmat (first, second, third, 1012 version, (void __user *)AA(ptr)); 1013 break; 1014 case SHMDT: 1015 err = sys_shmdt ((char __user *)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 __user *)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 __user *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 __user *args) 1058 { 1059 struct sysctl_args32 tmp; 1060 int error; 1061 size_t oldlen; 1062 size_t __user *oldlenp = NULL; 1063 unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; 1064 1065 if (copy_from_user(&tmp, args, sizeof(tmp))) 1066 return -EFAULT; 1067 1068 if (tmp.oldval && tmp.oldlenp) { 1069 /* Duh, this is ugly and might not work if sysctl_args 1070 is in read-only memory, but do_sysctl does indirectly 1071 a lot of uaccess in both directions and we'd have to 1072 basically copy the whole sysctl.c here, and 1073 glibc's __sysctl uses rw memory for the structure 1074 anyway. */ 1075 if (get_user(oldlen, (u32 __user *)A(tmp.oldlenp)) || 1076 put_user(oldlen, (size_t __user *)addr)) 1077 return -EFAULT; 1078 oldlenp = (size_t __user *)addr; 1079 } 1080 1081 lock_kernel(); 1082 error = do_sysctl((int __user *)A(tmp.name), tmp.nlen, (void __user *)A(tmp.oldval), 1083 oldlenp, (void __user *)A(tmp.newval), tmp.newlen); 1084 unlock_kernel(); 1085 if (oldlenp) { 1086 if (!error) { 1087 if (get_user(oldlen, (size_t __user *)addr) || 1088 put_user(oldlen, (u32 __user *)A(tmp.oldlenp))) 1089 error = -EFAULT; 1090 } 1091 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); 1092 } 1093 return error; 1094 } 1095 1096 #endif /* CONFIG_SYSCTL */ 1097 1098 asmlinkage long sys32_newuname(struct new_utsname __user * name) 1099 { 1100 int ret = 0; 1101 1102 down_read(&uts_sem); 1103 if (copy_to_user(name,&system_utsname,sizeof *name)) 1104 ret = -EFAULT; 1105 up_read(&uts_sem); 1106 1107 if (current->personality == PER_LINUX32 && !ret) 1108 if (copy_to_user(name->machine, "mips\0\0\0", 8)) 1109 ret = -EFAULT; 1110 1111 return ret; 1112 } 1113 1114 asmlinkage int sys32_personality(unsigned long personality) 1115 { 1116 int ret; 1117 if (current->personality == PER_LINUX32 && personality == PER_LINUX) 1118 personality = PER_LINUX32; 1119 ret = sys_personality(personality); 1120 if (ret == PER_LINUX32) 1121 ret = PER_LINUX; 1122 return ret; 1123 } 1124 1125 /* ustat compatibility */ 1126 struct ustat32 { 1127 compat_daddr_t f_tfree; 1128 compat_ino_t f_tinode; 1129 char f_fname[6]; 1130 char f_fpack[6]; 1131 }; 1132 1133 extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf); 1134 1135 asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32) 1136 { 1137 int err; 1138 struct ustat tmp; 1139 struct ustat32 tmp32; 1140 mm_segment_t old_fs = get_fs(); 1141 1142 set_fs(KERNEL_DS); 1143 err = sys_ustat(dev, (struct ustat __user *)&tmp); 1144 set_fs (old_fs); 1145 1146 if (err) 1147 goto out; 1148 1149 memset(&tmp32,0,sizeof(struct ustat32)); 1150 tmp32.f_tfree = tmp.f_tfree; 1151 tmp32.f_tinode = tmp.f_tinode; 1152 1153 err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0; 1154 1155 out: 1156 return err; 1157 } 1158 1159 asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, 1160 s32 count) 1161 { 1162 mm_segment_t old_fs = get_fs(); 1163 int ret; 1164 off_t of; 1165 1166 if (offset && get_user(of, offset)) 1167 return -EFAULT; 1168 1169 set_fs(KERNEL_DS); 1170 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count); 1171 set_fs(old_fs); 1172 1173 if (offset && put_user(of, offset)) 1174 return -EFAULT; 1175 1176 return ret; 1177 } 1178 1179 asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3, 1180 size_t count) 1181 { 1182 return sys_readahead(fd, merge_64(a2, a3), count); 1183 } 1184 1185 /* Argument list sizes for sys_socketcall */ 1186 #define AL(x) ((x) * sizeof(unsigned int)) 1187 static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), 1188 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), 1189 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)}; 1190 #undef AL 1191 1192 /* 1193 * System call vectors. 1194 * 1195 * Argument checking cleaned up. Saved 20% in size. 1196 * This function doesn't need to set the kernel lock because 1197 * it is set by the callees. 1198 */ 1199 1200 asmlinkage long sys32_socketcall(int call, unsigned int __user *args32) 1201 { 1202 unsigned int a[6]; 1203 unsigned int a0,a1; 1204 int err; 1205 1206 extern asmlinkage long sys_socket(int family, int type, int protocol); 1207 extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); 1208 extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen); 1209 extern asmlinkage long sys_listen(int fd, int backlog); 1210 extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen); 1211 extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); 1212 extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); 1213 extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec); 1214 extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags); 1215 extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags, 1216 struct sockaddr __user *addr, int addr_len); 1217 extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags); 1218 extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags, 1219 struct sockaddr __user *addr, int __user *addr_len); 1220 extern asmlinkage long sys_shutdown(int fd, int how); 1221 extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen); 1222 extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen); 1223 extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); 1224 extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags); 1225 1226 1227 if(call<1||call>SYS_RECVMSG) 1228 return -EINVAL; 1229 1230 /* copy_from_user should be SMP safe. */ 1231 if (copy_from_user(a, args32, socketcall_nargs[call])) 1232 return -EFAULT; 1233 1234 a0=a[0]; 1235 a1=a[1]; 1236 1237 switch(call) 1238 { 1239 case SYS_SOCKET: 1240 err = sys_socket(a0,a1,a[2]); 1241 break; 1242 case SYS_BIND: 1243 err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]); 1244 break; 1245 case SYS_CONNECT: 1246 err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]); 1247 break; 1248 case SYS_LISTEN: 1249 err = sys_listen(a0,a1); 1250 break; 1251 case SYS_ACCEPT: 1252 err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1253 break; 1254 case SYS_GETSOCKNAME: 1255 err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1256 break; 1257 case SYS_GETPEERNAME: 1258 err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1259 break; 1260 case SYS_SOCKETPAIR: 1261 err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3])); 1262 break; 1263 case SYS_SEND: 1264 err = sys_send(a0, (void __user *)A(a1), a[2], a[3]); 1265 break; 1266 case SYS_SENDTO: 1267 err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3], 1268 (struct sockaddr __user *)A(a[4]), a[5]); 1269 break; 1270 case SYS_RECV: 1271 err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]); 1272 break; 1273 case SYS_RECVFROM: 1274 err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3], 1275 (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5])); 1276 break; 1277 case SYS_SHUTDOWN: 1278 err = sys_shutdown(a0,a1); 1279 break; 1280 case SYS_SETSOCKOPT: 1281 err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]); 1282 break; 1283 case SYS_GETSOCKOPT: 1284 err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4])); 1285 break; 1286 case SYS_SENDMSG: 1287 err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]); 1288 break; 1289 case SYS_RECVMSG: 1290 err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]); 1291 break; 1292 default: 1293 err = -EINVAL; 1294 break; 1295 } 1296 return err; 1297 } 1298 1299 struct sigevent32 { 1300 u32 sigev_value; 1301 u32 sigev_signo; 1302 u32 sigev_notify; 1303 u32 payload[(64 / 4) - 3]; 1304 }; 1305 1306 extern asmlinkage long 1307 sys_timer_create(clockid_t which_clock, 1308 struct sigevent __user *timer_event_spec, 1309 timer_t __user * created_timer_id); 1310 1311 long 1312 sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id) 1313 { 1314 struct sigevent __user *p = NULL; 1315 if (se32) { 1316 struct sigevent se; 1317 p = compat_alloc_user_space(sizeof(struct sigevent)); 1318 memset(&se, 0, sizeof(struct sigevent)); 1319 if (get_user(se.sigev_value.sival_int, &se32->sigev_value) || 1320 __get_user(se.sigev_signo, &se32->sigev_signo) || 1321 __get_user(se.sigev_notify, &se32->sigev_notify) || 1322 __copy_from_user(&se._sigev_un._pad, &se32->payload, 1323 sizeof(se32->payload)) || 1324 copy_to_user(p, &se, sizeof(se))) 1325 return -EFAULT; 1326 } 1327 return sys_timer_create(clock, p, timer_id); 1328 } 1329 1330 save_static_function(sys32_clone); 1331 __attribute_used__ noinline static int 1332 _sys32_clone(nabi_no_regargs struct pt_regs regs) 1333 { 1334 unsigned long clone_flags; 1335 unsigned long newsp; 1336 int __user *parent_tidptr, *child_tidptr; 1337 1338 clone_flags = regs.regs[4]; 1339 newsp = regs.regs[5]; 1340 if (!newsp) 1341 newsp = regs.regs[29]; 1342 parent_tidptr = (int __user *) regs.regs[6]; 1343 1344 /* Use __dummy4 instead of getting it off the stack, so that 1345 syscall() works. */ 1346 child_tidptr = (int __user *) __dummy4; 1347 return do_fork(clone_flags, newsp, ®s, 0, 1348 parent_tidptr, child_tidptr); 1349 } 1350 1351 extern asmlinkage void sys_set_thread_area(u32 addr); 1352 asmlinkage void sys32_set_thread_area(u32 addr) 1353 { 1354 sys_set_thread_area(AA(addr)); 1355 } 1356