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