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