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 return sys_pread64(fd, buf, count, merge_64(a4, a5)); 360 } 361 362 asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf, 363 size_t count, u32 unused, u64 a4, u64 a5) 364 { 365 return sys_pwrite64(fd, buf, count, merge_64(a4, a5)); 366 } 367 368 asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, 369 struct compat_timespec __user *interval) 370 { 371 struct timespec t; 372 int ret; 373 mm_segment_t old_fs = get_fs (); 374 375 set_fs (KERNEL_DS); 376 ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t); 377 set_fs (old_fs); 378 if (put_user (t.tv_sec, &interval->tv_sec) || 379 __put_user (t.tv_nsec, &interval->tv_nsec)) 380 return -EFAULT; 381 return ret; 382 } 383 384 struct msgbuf32 { s32 mtype; char mtext[1]; }; 385 386 struct ipc_perm32 387 { 388 key_t key; 389 __compat_uid_t uid; 390 __compat_gid_t gid; 391 __compat_uid_t cuid; 392 __compat_gid_t cgid; 393 compat_mode_t mode; 394 unsigned short seq; 395 }; 396 397 struct ipc64_perm32 { 398 key_t key; 399 __compat_uid_t uid; 400 __compat_gid_t gid; 401 __compat_uid_t cuid; 402 __compat_gid_t cgid; 403 compat_mode_t mode; 404 unsigned short seq; 405 unsigned short __pad1; 406 unsigned int __unused1; 407 unsigned int __unused2; 408 }; 409 410 struct semid_ds32 { 411 struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */ 412 compat_time_t sem_otime; /* last semop time */ 413 compat_time_t sem_ctime; /* last change time */ 414 u32 sem_base; /* ptr to first semaphore in array */ 415 u32 sem_pending; /* pending operations to be processed */ 416 u32 sem_pending_last; /* last pending operation */ 417 u32 undo; /* undo requests on this array */ 418 unsigned short sem_nsems; /* no. of semaphores in array */ 419 }; 420 421 struct semid64_ds32 { 422 struct ipc64_perm32 sem_perm; 423 compat_time_t sem_otime; 424 compat_time_t sem_ctime; 425 unsigned int sem_nsems; 426 unsigned int __unused1; 427 unsigned int __unused2; 428 }; 429 430 struct msqid_ds32 431 { 432 struct ipc_perm32 msg_perm; 433 u32 msg_first; 434 u32 msg_last; 435 compat_time_t msg_stime; 436 compat_time_t msg_rtime; 437 compat_time_t msg_ctime; 438 u32 wwait; 439 u32 rwait; 440 unsigned short msg_cbytes; 441 unsigned short msg_qnum; 442 unsigned short msg_qbytes; 443 compat_ipc_pid_t msg_lspid; 444 compat_ipc_pid_t msg_lrpid; 445 }; 446 447 struct msqid64_ds32 { 448 struct ipc64_perm32 msg_perm; 449 compat_time_t msg_stime; 450 unsigned int __unused1; 451 compat_time_t msg_rtime; 452 unsigned int __unused2; 453 compat_time_t msg_ctime; 454 unsigned int __unused3; 455 unsigned int msg_cbytes; 456 unsigned int msg_qnum; 457 unsigned int msg_qbytes; 458 compat_pid_t msg_lspid; 459 compat_pid_t msg_lrpid; 460 unsigned int __unused4; 461 unsigned int __unused5; 462 }; 463 464 struct shmid_ds32 { 465 struct ipc_perm32 shm_perm; 466 int shm_segsz; 467 compat_time_t shm_atime; 468 compat_time_t shm_dtime; 469 compat_time_t shm_ctime; 470 compat_ipc_pid_t shm_cpid; 471 compat_ipc_pid_t shm_lpid; 472 unsigned short shm_nattch; 473 }; 474 475 struct shmid64_ds32 { 476 struct ipc64_perm32 shm_perm; 477 compat_size_t shm_segsz; 478 compat_time_t shm_atime; 479 compat_time_t shm_dtime; 480 compat_time_t shm_ctime; 481 compat_pid_t shm_cpid; 482 compat_pid_t shm_lpid; 483 unsigned int shm_nattch; 484 unsigned int __unused1; 485 unsigned int __unused2; 486 }; 487 488 struct ipc_kludge32 { 489 u32 msgp; 490 s32 msgtyp; 491 }; 492 493 static int 494 do_sys32_semctl(int first, int second, int third, void __user *uptr) 495 { 496 union semun fourth; 497 u32 pad; 498 int err, err2; 499 struct semid64_ds s; 500 mm_segment_t old_fs; 501 502 if (!uptr) 503 return -EINVAL; 504 err = -EFAULT; 505 if (get_user (pad, (u32 __user *)uptr)) 506 return err; 507 if ((third & ~IPC_64) == SETVAL) 508 fourth.val = (int)pad; 509 else 510 fourth.__pad = (void __user *)A(pad); 511 switch (third & ~IPC_64) { 512 case IPC_INFO: 513 case IPC_RMID: 514 case IPC_SET: 515 case SEM_INFO: 516 case GETVAL: 517 case GETPID: 518 case GETNCNT: 519 case GETZCNT: 520 case GETALL: 521 case SETVAL: 522 case SETALL: 523 err = sys_semctl (first, second, third, fourth); 524 break; 525 526 case IPC_STAT: 527 case SEM_STAT: 528 fourth.__pad = (struct semid64_ds __user *)&s; 529 old_fs = get_fs(); 530 set_fs(KERNEL_DS); 531 err = sys_semctl(first, second, third | IPC_64, fourth); 532 set_fs(old_fs); 533 534 if (third & IPC_64) { 535 struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) A(pad); 536 537 if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) { 538 err = -EFAULT; 539 break; 540 } 541 err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key); 542 err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid); 543 err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid); 544 err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid); 545 err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid); 546 err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode); 547 err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq); 548 err2 |= __put_user(s.sem_otime, &usp64->sem_otime); 549 err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime); 550 err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems); 551 } else { 552 struct semid_ds32 __user *usp32 = (struct semid_ds32 __user *) A(pad); 553 554 if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) { 555 err = -EFAULT; 556 break; 557 } 558 err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key); 559 err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid); 560 err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid); 561 err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid); 562 err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid); 563 err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode); 564 err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq); 565 err2 |= __put_user(s.sem_otime, &usp32->sem_otime); 566 err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime); 567 err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems); 568 } 569 if (err2) 570 err = -EFAULT; 571 break; 572 573 default: 574 err = - EINVAL; 575 break; 576 } 577 578 return err; 579 } 580 581 static int 582 do_sys32_msgsnd (int first, int second, int third, void __user *uptr) 583 { 584 struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr; 585 struct msgbuf *p; 586 mm_segment_t old_fs; 587 int err; 588 589 if (second < 0) 590 return -EINVAL; 591 p = kmalloc (second + sizeof (struct msgbuf) 592 + 4, GFP_USER); 593 if (!p) 594 return -ENOMEM; 595 err = get_user (p->mtype, &up->mtype); 596 if (err) 597 goto out; 598 err |= __copy_from_user (p->mtext, &up->mtext, second); 599 if (err) 600 goto out; 601 old_fs = get_fs (); 602 set_fs (KERNEL_DS); 603 err = sys_msgsnd (first, (struct msgbuf __user *)p, second, third); 604 set_fs (old_fs); 605 out: 606 kfree (p); 607 608 return err; 609 } 610 611 static int 612 do_sys32_msgrcv (int first, int second, int msgtyp, int third, 613 int version, void __user *uptr) 614 { 615 struct msgbuf32 __user *up; 616 struct msgbuf *p; 617 mm_segment_t old_fs; 618 int err; 619 620 if (!version) { 621 struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr; 622 struct ipc_kludge32 ipck; 623 624 err = -EINVAL; 625 if (!uptr) 626 goto out; 627 err = -EFAULT; 628 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32))) 629 goto out; 630 uptr = (void __user *)AA(ipck.msgp); 631 msgtyp = ipck.msgtyp; 632 } 633 634 if (second < 0) 635 return -EINVAL; 636 err = -ENOMEM; 637 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); 638 if (!p) 639 goto out; 640 old_fs = get_fs (); 641 set_fs (KERNEL_DS); 642 err = sys_msgrcv (first, (struct msgbuf __user *)p, second + 4, msgtyp, third); 643 set_fs (old_fs); 644 if (err < 0) 645 goto free_then_out; 646 up = (struct msgbuf32 __user *)uptr; 647 if (put_user (p->mtype, &up->mtype) || 648 __copy_to_user (&up->mtext, p->mtext, err)) 649 err = -EFAULT; 650 free_then_out: 651 kfree (p); 652 out: 653 return err; 654 } 655 656 static int 657 do_sys32_msgctl (int first, int second, void __user *uptr) 658 { 659 int err = -EINVAL, err2; 660 struct msqid64_ds m; 661 struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr; 662 struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr; 663 mm_segment_t old_fs; 664 665 switch (second & ~IPC_64) { 666 case IPC_INFO: 667 case IPC_RMID: 668 case MSG_INFO: 669 err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr); 670 break; 671 672 case IPC_SET: 673 if (second & IPC_64) { 674 if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) { 675 err = -EFAULT; 676 break; 677 } 678 err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid); 679 err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid); 680 err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode); 681 err |= __get_user(m.msg_qbytes, &up64->msg_qbytes); 682 } else { 683 if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) { 684 err = -EFAULT; 685 break; 686 } 687 err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid); 688 err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid); 689 err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode); 690 err |= __get_user(m.msg_qbytes, &up32->msg_qbytes); 691 } 692 if (err) 693 break; 694 old_fs = get_fs(); 695 set_fs(KERNEL_DS); 696 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m); 697 set_fs(old_fs); 698 break; 699 700 case IPC_STAT: 701 case MSG_STAT: 702 old_fs = get_fs(); 703 set_fs(KERNEL_DS); 704 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m); 705 set_fs(old_fs); 706 if (second & IPC_64) { 707 if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { 708 err = -EFAULT; 709 break; 710 } 711 err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key); 712 err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid); 713 err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid); 714 err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid); 715 err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid); 716 err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode); 717 err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq); 718 err2 |= __put_user(m.msg_stime, &up64->msg_stime); 719 err2 |= __put_user(m.msg_rtime, &up64->msg_rtime); 720 err2 |= __put_user(m.msg_ctime, &up64->msg_ctime); 721 err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes); 722 err2 |= __put_user(m.msg_qnum, &up64->msg_qnum); 723 err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes); 724 err2 |= __put_user(m.msg_lspid, &up64->msg_lspid); 725 err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid); 726 if (err2) 727 err = -EFAULT; 728 } else { 729 if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { 730 err = -EFAULT; 731 break; 732 } 733 err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key); 734 err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid); 735 err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid); 736 err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid); 737 err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid); 738 err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode); 739 err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq); 740 err2 |= __put_user(m.msg_stime, &up32->msg_stime); 741 err2 |= __put_user(m.msg_rtime, &up32->msg_rtime); 742 err2 |= __put_user(m.msg_ctime, &up32->msg_ctime); 743 err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes); 744 err2 |= __put_user(m.msg_qnum, &up32->msg_qnum); 745 err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes); 746 err2 |= __put_user(m.msg_lspid, &up32->msg_lspid); 747 err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid); 748 if (err2) 749 err = -EFAULT; 750 } 751 break; 752 } 753 754 return err; 755 } 756 757 static int 758 do_sys32_shmat (int first, int second, int third, int version, void __user *uptr) 759 { 760 unsigned long raddr; 761 u32 __user *uaddr = (u32 __user *)A((u32)third); 762 int err = -EINVAL; 763 764 if (version == 1) 765 return err; 766 err = do_shmat (first, uptr, second, &raddr); 767 if (err) 768 return err; 769 err = put_user (raddr, uaddr); 770 return err; 771 } 772 773 struct shm_info32 { 774 int used_ids; 775 u32 shm_tot, shm_rss, shm_swp; 776 u32 swap_attempts, swap_successes; 777 }; 778 779 static int 780 do_sys32_shmctl (int first, int second, void __user *uptr) 781 { 782 struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr; 783 struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr; 784 struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr; 785 int err = -EFAULT, err2; 786 struct shmid64_ds s64; 787 mm_segment_t old_fs; 788 struct shm_info si; 789 struct shmid_ds s; 790 791 switch (second & ~IPC_64) { 792 case IPC_INFO: 793 second = IPC_INFO; /* So that we don't have to translate it */ 794 case IPC_RMID: 795 case SHM_LOCK: 796 case SHM_UNLOCK: 797 err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr); 798 break; 799 case IPC_SET: 800 if (second & IPC_64) { 801 err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); 802 err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); 803 err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); 804 } else { 805 err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); 806 err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); 807 err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); 808 } 809 if (err) 810 break; 811 old_fs = get_fs(); 812 set_fs(KERNEL_DS); 813 err = sys_shmctl(first, second & ~IPC_64, (struct shmid_ds __user *)&s); 814 set_fs(old_fs); 815 break; 816 817 case IPC_STAT: 818 case SHM_STAT: 819 old_fs = get_fs(); 820 set_fs(KERNEL_DS); 821 err = sys_shmctl(first, second | IPC_64, (void __user *) &s64); 822 set_fs(old_fs); 823 if (err < 0) 824 break; 825 if (second & IPC_64) { 826 if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { 827 err = -EFAULT; 828 break; 829 } 830 err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key); 831 err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid); 832 err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid); 833 err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid); 834 err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid); 835 err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode); 836 err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq); 837 err2 |= __put_user(s64.shm_atime, &up64->shm_atime); 838 err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime); 839 err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime); 840 err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz); 841 err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch); 842 err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid); 843 err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid); 844 } else { 845 if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { 846 err = -EFAULT; 847 break; 848 } 849 err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key); 850 err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid); 851 err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid); 852 err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid); 853 err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid); 854 err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode); 855 err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq); 856 err2 |= __put_user(s64.shm_atime, &up32->shm_atime); 857 err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime); 858 err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime); 859 err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz); 860 err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch); 861 err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid); 862 err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid); 863 } 864 if (err2) 865 err = -EFAULT; 866 break; 867 868 case SHM_INFO: 869 old_fs = get_fs(); 870 set_fs(KERNEL_DS); 871 err = sys_shmctl(first, second, (void __user *)&si); 872 set_fs(old_fs); 873 if (err < 0) 874 break; 875 err2 = put_user(si.used_ids, &uip->used_ids); 876 err2 |= __put_user(si.shm_tot, &uip->shm_tot); 877 err2 |= __put_user(si.shm_rss, &uip->shm_rss); 878 err2 |= __put_user(si.shm_swp, &uip->shm_swp); 879 err2 |= __put_user(si.swap_attempts, &uip->swap_attempts); 880 err2 |= __put_user (si.swap_successes, &uip->swap_successes); 881 if (err2) 882 err = -EFAULT; 883 break; 884 885 default: 886 err = -EINVAL; 887 break; 888 } 889 890 return err; 891 } 892 893 static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems, 894 const struct compat_timespec __user *timeout32) 895 { 896 struct compat_timespec t32; 897 struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64)); 898 899 if (copy_from_user(&t32, timeout32, sizeof(t32))) 900 return -EFAULT; 901 902 if (put_user(t32.tv_sec, &t64->tv_sec) || 903 put_user(t32.tv_nsec, &t64->tv_nsec)) 904 return -EFAULT; 905 906 return sys_semtimedop(semid, tsems, nsems, t64); 907 } 908 909 asmlinkage long 910 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) 911 { 912 int version, err; 913 914 version = call >> 16; /* hack for backward compatibility */ 915 call &= 0xffff; 916 917 switch (call) { 918 case SEMOP: 919 /* struct sembuf is the same on 32 and 64bit :)) */ 920 err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second, 921 NULL); 922 break; 923 case SEMTIMEDOP: 924 err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second, 925 (const struct compat_timespec __user *)AA(fifth)); 926 break; 927 case SEMGET: 928 err = sys_semget (first, second, third); 929 break; 930 case SEMCTL: 931 err = do_sys32_semctl (first, second, third, 932 (void __user *)AA(ptr)); 933 break; 934 935 case MSGSND: 936 err = do_sys32_msgsnd (first, second, third, 937 (void __user *)AA(ptr)); 938 break; 939 case MSGRCV: 940 err = do_sys32_msgrcv (first, second, fifth, third, 941 version, (void __user *)AA(ptr)); 942 break; 943 case MSGGET: 944 err = sys_msgget ((key_t) first, second); 945 break; 946 case MSGCTL: 947 err = do_sys32_msgctl (first, second, (void __user *)AA(ptr)); 948 break; 949 950 case SHMAT: 951 err = do_sys32_shmat (first, second, third, 952 version, (void __user *)AA(ptr)); 953 break; 954 case SHMDT: 955 err = sys_shmdt ((char __user *)A(ptr)); 956 break; 957 case SHMGET: 958 err = sys_shmget (first, (unsigned)second, third); 959 break; 960 case SHMCTL: 961 err = do_sys32_shmctl (first, second, (void __user *)AA(ptr)); 962 break; 963 default: 964 err = -EINVAL; 965 break; 966 } 967 968 return err; 969 } 970 971 asmlinkage long sys32_shmat(int shmid, char __user *shmaddr, 972 int shmflg, int32_t __user *addr) 973 { 974 unsigned long raddr; 975 int err; 976 977 err = do_shmat(shmid, shmaddr, shmflg, &raddr); 978 if (err) 979 return err; 980 981 return put_user(raddr, addr); 982 } 983 984 struct sysctl_args32 985 { 986 compat_caddr_t name; 987 int nlen; 988 compat_caddr_t oldval; 989 compat_caddr_t oldlenp; 990 compat_caddr_t newval; 991 compat_size_t newlen; 992 unsigned int __unused[4]; 993 }; 994 995 #ifdef CONFIG_SYSCTL 996 997 asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args) 998 { 999 struct sysctl_args32 tmp; 1000 int error; 1001 size_t oldlen; 1002 size_t __user *oldlenp = NULL; 1003 unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; 1004 1005 if (copy_from_user(&tmp, args, sizeof(tmp))) 1006 return -EFAULT; 1007 1008 if (tmp.oldval && tmp.oldlenp) { 1009 /* Duh, this is ugly and might not work if sysctl_args 1010 is in read-only memory, but do_sysctl does indirectly 1011 a lot of uaccess in both directions and we'd have to 1012 basically copy the whole sysctl.c here, and 1013 glibc's __sysctl uses rw memory for the structure 1014 anyway. */ 1015 if (get_user(oldlen, (u32 __user *)A(tmp.oldlenp)) || 1016 put_user(oldlen, (size_t __user *)addr)) 1017 return -EFAULT; 1018 oldlenp = (size_t __user *)addr; 1019 } 1020 1021 lock_kernel(); 1022 error = do_sysctl((int __user *)A(tmp.name), tmp.nlen, (void __user *)A(tmp.oldval), 1023 oldlenp, (void __user *)A(tmp.newval), tmp.newlen); 1024 unlock_kernel(); 1025 if (oldlenp) { 1026 if (!error) { 1027 if (get_user(oldlen, (size_t __user *)addr) || 1028 put_user(oldlen, (u32 __user *)A(tmp.oldlenp))) 1029 error = -EFAULT; 1030 } 1031 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); 1032 } 1033 return error; 1034 } 1035 1036 #endif /* CONFIG_SYSCTL */ 1037 1038 asmlinkage long sys32_newuname(struct new_utsname __user * name) 1039 { 1040 int ret = 0; 1041 1042 down_read(&uts_sem); 1043 if (copy_to_user(name,&system_utsname,sizeof *name)) 1044 ret = -EFAULT; 1045 up_read(&uts_sem); 1046 1047 if (current->personality == PER_LINUX32 && !ret) 1048 if (copy_to_user(name->machine, "mips\0\0\0", 8)) 1049 ret = -EFAULT; 1050 1051 return ret; 1052 } 1053 1054 asmlinkage int sys32_personality(unsigned long personality) 1055 { 1056 int ret; 1057 if (current->personality == PER_LINUX32 && personality == PER_LINUX) 1058 personality = PER_LINUX32; 1059 ret = sys_personality(personality); 1060 if (ret == PER_LINUX32) 1061 ret = PER_LINUX; 1062 return ret; 1063 } 1064 1065 /* ustat compatibility */ 1066 struct ustat32 { 1067 compat_daddr_t f_tfree; 1068 compat_ino_t f_tinode; 1069 char f_fname[6]; 1070 char f_fpack[6]; 1071 }; 1072 1073 extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf); 1074 1075 asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32) 1076 { 1077 int err; 1078 struct ustat tmp; 1079 struct ustat32 tmp32; 1080 mm_segment_t old_fs = get_fs(); 1081 1082 set_fs(KERNEL_DS); 1083 err = sys_ustat(dev, (struct ustat __user *)&tmp); 1084 set_fs (old_fs); 1085 1086 if (err) 1087 goto out; 1088 1089 memset(&tmp32,0,sizeof(struct ustat32)); 1090 tmp32.f_tfree = tmp.f_tfree; 1091 tmp32.f_tinode = tmp.f_tinode; 1092 1093 err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0; 1094 1095 out: 1096 return err; 1097 } 1098 1099 asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, 1100 s32 count) 1101 { 1102 mm_segment_t old_fs = get_fs(); 1103 int ret; 1104 off_t of; 1105 1106 if (offset && get_user(of, offset)) 1107 return -EFAULT; 1108 1109 set_fs(KERNEL_DS); 1110 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count); 1111 set_fs(old_fs); 1112 1113 if (offset && put_user(of, offset)) 1114 return -EFAULT; 1115 1116 return ret; 1117 } 1118 1119 asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3, 1120 size_t count) 1121 { 1122 return sys_readahead(fd, merge_64(a2, a3), count); 1123 } 1124 1125 asmlinkage long sys32_sync_file_range(int fd, int __pad, 1126 unsigned long a2, unsigned long a3, 1127 unsigned long a4, unsigned long a5, 1128 int flags) 1129 { 1130 return sys_sync_file_range(fd, 1131 merge_64(a2, a3), merge_64(a4, a5), 1132 flags); 1133 } 1134 1135 /* Argument list sizes for sys_socketcall */ 1136 #define AL(x) ((x) * sizeof(unsigned int)) 1137 static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), 1138 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), 1139 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)}; 1140 #undef AL 1141 1142 /* 1143 * System call vectors. 1144 * 1145 * Argument checking cleaned up. Saved 20% in size. 1146 * This function doesn't need to set the kernel lock because 1147 * it is set by the callees. 1148 */ 1149 1150 asmlinkage long sys32_socketcall(int call, unsigned int __user *args32) 1151 { 1152 unsigned int a[6]; 1153 unsigned int a0,a1; 1154 int err; 1155 1156 extern asmlinkage long sys_socket(int family, int type, int protocol); 1157 extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); 1158 extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen); 1159 extern asmlinkage long sys_listen(int fd, int backlog); 1160 extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen); 1161 extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); 1162 extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); 1163 extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec); 1164 extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags); 1165 extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags, 1166 struct sockaddr __user *addr, int addr_len); 1167 extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags); 1168 extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags, 1169 struct sockaddr __user *addr, int __user *addr_len); 1170 extern asmlinkage long sys_shutdown(int fd, int how); 1171 extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen); 1172 extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen); 1173 extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); 1174 extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags); 1175 1176 1177 if(call<1||call>SYS_RECVMSG) 1178 return -EINVAL; 1179 1180 /* copy_from_user should be SMP safe. */ 1181 if (copy_from_user(a, args32, socketcall_nargs[call])) 1182 return -EFAULT; 1183 1184 a0=a[0]; 1185 a1=a[1]; 1186 1187 switch(call) 1188 { 1189 case SYS_SOCKET: 1190 err = sys_socket(a0,a1,a[2]); 1191 break; 1192 case SYS_BIND: 1193 err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]); 1194 break; 1195 case SYS_CONNECT: 1196 err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]); 1197 break; 1198 case SYS_LISTEN: 1199 err = sys_listen(a0,a1); 1200 break; 1201 case SYS_ACCEPT: 1202 err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1203 break; 1204 case SYS_GETSOCKNAME: 1205 err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1206 break; 1207 case SYS_GETPEERNAME: 1208 err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2])); 1209 break; 1210 case SYS_SOCKETPAIR: 1211 err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3])); 1212 break; 1213 case SYS_SEND: 1214 err = sys_send(a0, (void __user *)A(a1), a[2], a[3]); 1215 break; 1216 case SYS_SENDTO: 1217 err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3], 1218 (struct sockaddr __user *)A(a[4]), a[5]); 1219 break; 1220 case SYS_RECV: 1221 err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]); 1222 break; 1223 case SYS_RECVFROM: 1224 err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3], 1225 (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5])); 1226 break; 1227 case SYS_SHUTDOWN: 1228 err = sys_shutdown(a0,a1); 1229 break; 1230 case SYS_SETSOCKOPT: 1231 err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]); 1232 break; 1233 case SYS_GETSOCKOPT: 1234 err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4])); 1235 break; 1236 case SYS_SENDMSG: 1237 err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]); 1238 break; 1239 case SYS_RECVMSG: 1240 err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]); 1241 break; 1242 default: 1243 err = -EINVAL; 1244 break; 1245 } 1246 return err; 1247 } 1248 1249 struct sigevent32 { 1250 u32 sigev_value; 1251 u32 sigev_signo; 1252 u32 sigev_notify; 1253 u32 payload[(64 / 4) - 3]; 1254 }; 1255 1256 extern asmlinkage long 1257 sys_timer_create(clockid_t which_clock, 1258 struct sigevent __user *timer_event_spec, 1259 timer_t __user * created_timer_id); 1260 1261 long 1262 sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id) 1263 { 1264 struct sigevent __user *p = NULL; 1265 if (se32) { 1266 struct sigevent se; 1267 p = compat_alloc_user_space(sizeof(struct sigevent)); 1268 memset(&se, 0, sizeof(struct sigevent)); 1269 if (get_user(se.sigev_value.sival_int, &se32->sigev_value) || 1270 __get_user(se.sigev_signo, &se32->sigev_signo) || 1271 __get_user(se.sigev_notify, &se32->sigev_notify) || 1272 __copy_from_user(&se._sigev_un._pad, &se32->payload, 1273 sizeof(se32->payload)) || 1274 copy_to_user(p, &se, sizeof(se))) 1275 return -EFAULT; 1276 } 1277 return sys_timer_create(clock, p, timer_id); 1278 } 1279 1280 save_static_function(sys32_clone); 1281 __attribute_used__ noinline static int 1282 _sys32_clone(nabi_no_regargs struct pt_regs regs) 1283 { 1284 unsigned long clone_flags; 1285 unsigned long newsp; 1286 int __user *parent_tidptr, *child_tidptr; 1287 1288 clone_flags = regs.regs[4]; 1289 newsp = regs.regs[5]; 1290 if (!newsp) 1291 newsp = regs.regs[29]; 1292 parent_tidptr = (int __user *) regs.regs[6]; 1293 1294 /* Use __dummy4 instead of getting it off the stack, so that 1295 syscall() works. */ 1296 child_tidptr = (int __user *) __dummy4; 1297 return do_fork(clone_flags, newsp, ®s, 0, 1298 parent_tidptr, child_tidptr); 1299 } 1300 1301 extern asmlinkage void sys_set_thread_area(u32 addr); 1302 asmlinkage void sys32_set_thread_area(u32 addr) 1303 { 1304 sys_set_thread_area(AA(addr)); 1305 } 1306