1 /* 2 * arch/s390x/kernel/linux32.c 3 * 4 * S390 version 5 * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 7 * Gerhard Tonn (ton@de.ibm.com) 8 * Thomas Spatzier (tspat@de.ibm.com) 9 * 10 * Conversion between 31bit and 64bit native syscalls. 11 * 12 * Heavily inspired by the 32-bit Sparc compat code which is 13 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 14 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 15 * 16 */ 17 18 19 #include <linux/config.h> 20 #include <linux/kernel.h> 21 #include <linux/sched.h> 22 #include <linux/fs.h> 23 #include <linux/mm.h> 24 #include <linux/file.h> 25 #include <linux/signal.h> 26 #include <linux/resource.h> 27 #include <linux/times.h> 28 #include <linux/utsname.h> 29 #include <linux/timex.h> 30 #include <linux/smp.h> 31 #include <linux/smp_lock.h> 32 #include <linux/sem.h> 33 #include <linux/msg.h> 34 #include <linux/shm.h> 35 #include <linux/slab.h> 36 #include <linux/uio.h> 37 #include <linux/nfs_fs.h> 38 #include <linux/quota.h> 39 #include <linux/module.h> 40 #include <linux/sunrpc/svc.h> 41 #include <linux/nfsd/nfsd.h> 42 #include <linux/nfsd/cache.h> 43 #include <linux/nfsd/xdr.h> 44 #include <linux/nfsd/syscall.h> 45 #include <linux/poll.h> 46 #include <linux/personality.h> 47 #include <linux/stat.h> 48 #include <linux/filter.h> 49 #include <linux/highmem.h> 50 #include <linux/highuid.h> 51 #include <linux/mman.h> 52 #include <linux/ipv6.h> 53 #include <linux/in.h> 54 #include <linux/icmpv6.h> 55 #include <linux/syscalls.h> 56 #include <linux/sysctl.h> 57 #include <linux/binfmts.h> 58 #include <linux/compat.h> 59 #include <linux/vfs.h> 60 #include <linux/ptrace.h> 61 62 #include <asm/types.h> 63 #include <asm/ipc.h> 64 #include <asm/uaccess.h> 65 #include <asm/semaphore.h> 66 67 #include <net/scm.h> 68 #include <net/sock.h> 69 70 #include "compat_linux.h" 71 72 73 /* For this source file, we want overflow handling. */ 74 75 #undef high2lowuid 76 #undef high2lowgid 77 #undef low2highuid 78 #undef low2highgid 79 #undef SET_UID16 80 #undef SET_GID16 81 #undef NEW_TO_OLD_UID 82 #undef NEW_TO_OLD_GID 83 #undef SET_OLDSTAT_UID 84 #undef SET_OLDSTAT_GID 85 #undef SET_STAT_UID 86 #undef SET_STAT_GID 87 88 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) 89 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) 90 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid) 91 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid) 92 #define SET_UID16(var, uid) var = high2lowuid(uid) 93 #define SET_GID16(var, gid) var = high2lowgid(gid) 94 #define NEW_TO_OLD_UID(uid) high2lowuid(uid) 95 #define NEW_TO_OLD_GID(gid) high2lowgid(gid) 96 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) 97 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) 98 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) 99 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) 100 101 asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group) 102 { 103 return sys_chown(filename, low2highuid(user), low2highgid(group)); 104 } 105 106 asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group) 107 { 108 return sys_lchown(filename, low2highuid(user), low2highgid(group)); 109 } 110 111 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group) 112 { 113 return sys_fchown(fd, low2highuid(user), low2highgid(group)); 114 } 115 116 asmlinkage long sys32_setregid16(u16 rgid, u16 egid) 117 { 118 return sys_setregid(low2highgid(rgid), low2highgid(egid)); 119 } 120 121 asmlinkage long sys32_setgid16(u16 gid) 122 { 123 return sys_setgid((gid_t)gid); 124 } 125 126 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid) 127 { 128 return sys_setreuid(low2highuid(ruid), low2highuid(euid)); 129 } 130 131 asmlinkage long sys32_setuid16(u16 uid) 132 { 133 return sys_setuid((uid_t)uid); 134 } 135 136 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid) 137 { 138 return sys_setresuid(low2highuid(ruid), low2highuid(euid), 139 low2highuid(suid)); 140 } 141 142 asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid) 143 { 144 int retval; 145 146 if (!(retval = put_user(high2lowuid(current->uid), ruid)) && 147 !(retval = put_user(high2lowuid(current->euid), euid))) 148 retval = put_user(high2lowuid(current->suid), suid); 149 150 return retval; 151 } 152 153 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid) 154 { 155 return sys_setresgid(low2highgid(rgid), low2highgid(egid), 156 low2highgid(sgid)); 157 } 158 159 asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid) 160 { 161 int retval; 162 163 if (!(retval = put_user(high2lowgid(current->gid), rgid)) && 164 !(retval = put_user(high2lowgid(current->egid), egid))) 165 retval = put_user(high2lowgid(current->sgid), sgid); 166 167 return retval; 168 } 169 170 asmlinkage long sys32_setfsuid16(u16 uid) 171 { 172 return sys_setfsuid((uid_t)uid); 173 } 174 175 asmlinkage long sys32_setfsgid16(u16 gid) 176 { 177 return sys_setfsgid((gid_t)gid); 178 } 179 180 static int groups16_to_user(u16 *grouplist, struct group_info *group_info) 181 { 182 int i; 183 u16 group; 184 185 for (i = 0; i < group_info->ngroups; i++) { 186 group = (u16)GROUP_AT(group_info, i); 187 if (put_user(group, grouplist+i)) 188 return -EFAULT; 189 } 190 191 return 0; 192 } 193 194 static int groups16_from_user(struct group_info *group_info, u16 *grouplist) 195 { 196 int i; 197 u16 group; 198 199 for (i = 0; i < group_info->ngroups; i++) { 200 if (get_user(group, grouplist+i)) 201 return -EFAULT; 202 GROUP_AT(group_info, i) = (gid_t)group; 203 } 204 205 return 0; 206 } 207 208 asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist) 209 { 210 int i; 211 212 if (gidsetsize < 0) 213 return -EINVAL; 214 215 get_group_info(current->group_info); 216 i = current->group_info->ngroups; 217 if (gidsetsize) { 218 if (i > gidsetsize) { 219 i = -EINVAL; 220 goto out; 221 } 222 if (groups16_to_user(grouplist, current->group_info)) { 223 i = -EFAULT; 224 goto out; 225 } 226 } 227 out: 228 put_group_info(current->group_info); 229 return i; 230 } 231 232 asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist) 233 { 234 struct group_info *group_info; 235 int retval; 236 237 if (!capable(CAP_SETGID)) 238 return -EPERM; 239 if ((unsigned)gidsetsize > NGROUPS_MAX) 240 return -EINVAL; 241 242 group_info = groups_alloc(gidsetsize); 243 if (!group_info) 244 return -ENOMEM; 245 retval = groups16_from_user(group_info, grouplist); 246 if (retval) { 247 put_group_info(group_info); 248 return retval; 249 } 250 251 retval = set_current_groups(group_info); 252 put_group_info(group_info); 253 254 return retval; 255 } 256 257 asmlinkage long sys32_getuid16(void) 258 { 259 return high2lowuid(current->uid); 260 } 261 262 asmlinkage long sys32_geteuid16(void) 263 { 264 return high2lowuid(current->euid); 265 } 266 267 asmlinkage long sys32_getgid16(void) 268 { 269 return high2lowgid(current->gid); 270 } 271 272 asmlinkage long sys32_getegid16(void) 273 { 274 return high2lowgid(current->egid); 275 } 276 277 /* 32-bit timeval and related flotsam. */ 278 279 static inline long get_tv32(struct timeval *o, struct compat_timeval *i) 280 { 281 return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) || 282 (__get_user(o->tv_sec, &i->tv_sec) || 283 __get_user(o->tv_usec, &i->tv_usec))); 284 } 285 286 static inline long put_tv32(struct compat_timeval *o, struct timeval *i) 287 { 288 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 289 (__put_user(i->tv_sec, &o->tv_sec) || 290 __put_user(i->tv_usec, &o->tv_usec))); 291 } 292 293 /* 294 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation. 295 * 296 * This is really horribly ugly. 297 */ 298 asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) 299 { 300 if (call >> 16) /* hack for backward compatibility */ 301 return -EINVAL; 302 303 call &= 0xffff; 304 305 switch (call) { 306 case SEMTIMEDOP: 307 return compat_sys_semtimedop(first, compat_ptr(ptr), 308 second, compat_ptr(third)); 309 case SEMOP: 310 /* struct sembuf is the same on 32 and 64bit :)) */ 311 return sys_semtimedop(first, compat_ptr(ptr), 312 second, NULL); 313 case SEMGET: 314 return sys_semget(first, second, third); 315 case SEMCTL: 316 return compat_sys_semctl(first, second, third, 317 compat_ptr(ptr)); 318 case MSGSND: 319 return compat_sys_msgsnd(first, second, third, 320 compat_ptr(ptr)); 321 case MSGRCV: 322 return compat_sys_msgrcv(first, second, 0, third, 323 0, compat_ptr(ptr)); 324 case MSGGET: 325 return sys_msgget((key_t) first, second); 326 case MSGCTL: 327 return compat_sys_msgctl(first, second, compat_ptr(ptr)); 328 case SHMAT: 329 return compat_sys_shmat(first, second, third, 330 0, compat_ptr(ptr)); 331 case SHMDT: 332 return sys_shmdt(compat_ptr(ptr)); 333 case SHMGET: 334 return sys_shmget(first, (unsigned)second, third); 335 case SHMCTL: 336 return compat_sys_shmctl(first, second, compat_ptr(ptr)); 337 } 338 339 return -ENOSYS; 340 } 341 342 asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low) 343 { 344 if ((int)high < 0) 345 return -EINVAL; 346 else 347 return sys_truncate(path, (high << 32) | low); 348 } 349 350 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low) 351 { 352 if ((int)high < 0) 353 return -EINVAL; 354 else 355 return sys_ftruncate(fd, (high << 32) | low); 356 } 357 358 int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf) 359 { 360 int err; 361 362 if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) 363 return -EOVERFLOW; 364 365 err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); 366 err |= put_user(stat->ino, &statbuf->st_ino); 367 err |= put_user(stat->mode, &statbuf->st_mode); 368 err |= put_user(stat->nlink, &statbuf->st_nlink); 369 err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid); 370 err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid); 371 err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev); 372 err |= put_user(stat->size, &statbuf->st_size); 373 err |= put_user(stat->atime.tv_sec, &statbuf->st_atime); 374 err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); 375 err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime); 376 err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); 377 err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime); 378 err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); 379 err |= put_user(stat->blksize, &statbuf->st_blksize); 380 err |= put_user(stat->blocks, &statbuf->st_blocks); 381 /* fixme 382 err |= put_user(0, &statbuf->__unused4[0]); 383 err |= put_user(0, &statbuf->__unused4[1]); 384 */ 385 return err; 386 } 387 388 struct sysinfo32 { 389 s32 uptime; 390 u32 loads[3]; 391 u32 totalram; 392 u32 freeram; 393 u32 sharedram; 394 u32 bufferram; 395 u32 totalswap; 396 u32 freeswap; 397 unsigned short procs; 398 unsigned short pads; 399 u32 totalhigh; 400 u32 freehigh; 401 unsigned int mem_unit; 402 char _f[8]; 403 }; 404 405 asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info) 406 { 407 struct sysinfo s; 408 int ret, err; 409 mm_segment_t old_fs = get_fs (); 410 411 set_fs (KERNEL_DS); 412 ret = sys_sysinfo(&s); 413 set_fs (old_fs); 414 err = put_user (s.uptime, &info->uptime); 415 err |= __put_user (s.loads[0], &info->loads[0]); 416 err |= __put_user (s.loads[1], &info->loads[1]); 417 err |= __put_user (s.loads[2], &info->loads[2]); 418 err |= __put_user (s.totalram, &info->totalram); 419 err |= __put_user (s.freeram, &info->freeram); 420 err |= __put_user (s.sharedram, &info->sharedram); 421 err |= __put_user (s.bufferram, &info->bufferram); 422 err |= __put_user (s.totalswap, &info->totalswap); 423 err |= __put_user (s.freeswap, &info->freeswap); 424 err |= __put_user (s.procs, &info->procs); 425 err |= __put_user (s.totalhigh, &info->totalhigh); 426 err |= __put_user (s.freehigh, &info->freehigh); 427 err |= __put_user (s.mem_unit, &info->mem_unit); 428 if (err) 429 return -EFAULT; 430 return ret; 431 } 432 433 asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid, 434 struct compat_timespec __user *interval) 435 { 436 struct timespec t; 437 int ret; 438 mm_segment_t old_fs = get_fs (); 439 440 set_fs (KERNEL_DS); 441 ret = sys_sched_rr_get_interval(pid, &t); 442 set_fs (old_fs); 443 if (put_compat_timespec(&t, interval)) 444 return -EFAULT; 445 return ret; 446 } 447 448 asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, 449 compat_sigset_t __user *oset, size_t sigsetsize) 450 { 451 sigset_t s; 452 compat_sigset_t s32; 453 int ret; 454 mm_segment_t old_fs = get_fs(); 455 456 if (set) { 457 if (copy_from_user (&s32, set, sizeof(compat_sigset_t))) 458 return -EFAULT; 459 switch (_NSIG_WORDS) { 460 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); 461 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); 462 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); 463 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); 464 } 465 } 466 set_fs (KERNEL_DS); 467 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize); 468 set_fs (old_fs); 469 if (ret) return ret; 470 if (oset) { 471 switch (_NSIG_WORDS) { 472 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; 473 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; 474 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; 475 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; 476 } 477 if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) 478 return -EFAULT; 479 } 480 return 0; 481 } 482 483 asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set, 484 size_t sigsetsize) 485 { 486 sigset_t s; 487 compat_sigset_t s32; 488 int ret; 489 mm_segment_t old_fs = get_fs(); 490 491 set_fs (KERNEL_DS); 492 ret = sys_rt_sigpending(&s, sigsetsize); 493 set_fs (old_fs); 494 if (!ret) { 495 switch (_NSIG_WORDS) { 496 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; 497 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; 498 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; 499 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; 500 } 501 if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) 502 return -EFAULT; 503 } 504 return ret; 505 } 506 507 asmlinkage long 508 sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) 509 { 510 siginfo_t info; 511 int ret; 512 mm_segment_t old_fs = get_fs(); 513 514 if (copy_siginfo_from_user32(&info, uinfo)) 515 return -EFAULT; 516 set_fs (KERNEL_DS); 517 ret = sys_rt_sigqueueinfo(pid, sig, &info); 518 set_fs (old_fs); 519 return ret; 520 } 521 522 /* 523 * sys32_execve() executes a new program after the asm stub has set 524 * things up for us. This should basically do what I want it to. 525 */ 526 asmlinkage long 527 sys32_execve(struct pt_regs regs) 528 { 529 int error; 530 char * filename; 531 532 filename = getname(compat_ptr(regs.orig_gpr2)); 533 error = PTR_ERR(filename); 534 if (IS_ERR(filename)) 535 goto out; 536 error = compat_do_execve(filename, compat_ptr(regs.gprs[3]), 537 compat_ptr(regs.gprs[4]), ®s); 538 if (error == 0) 539 { 540 task_lock(current); 541 current->ptrace &= ~PT_DTRACE; 542 task_unlock(current); 543 current->thread.fp_regs.fpc=0; 544 __asm__ __volatile__ 545 ("sr 0,0\n\t" 546 "sfpc 0,0\n\t" 547 : : :"0"); 548 } 549 putname(filename); 550 out: 551 return error; 552 } 553 554 555 #ifdef CONFIG_MODULES 556 557 asmlinkage long 558 sys32_init_module(void __user *umod, unsigned long len, 559 const char __user *uargs) 560 { 561 return sys_init_module(umod, len, uargs); 562 } 563 564 asmlinkage long 565 sys32_delete_module(const char __user *name_user, unsigned int flags) 566 { 567 return sys_delete_module(name_user, flags); 568 } 569 570 #else /* CONFIG_MODULES */ 571 572 asmlinkage long 573 sys32_init_module(void __user *umod, unsigned long len, 574 const char __user *uargs) 575 { 576 return -ENOSYS; 577 } 578 579 asmlinkage long 580 sys32_delete_module(const char __user *name_user, unsigned int flags) 581 { 582 return -ENOSYS; 583 } 584 585 #endif /* CONFIG_MODULES */ 586 587 /* Translations due to time_t size differences. Which affects all 588 sorts of things, like timeval and itimerval. */ 589 590 extern struct timezone sys_tz; 591 592 asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) 593 { 594 if (tv) { 595 struct timeval ktv; 596 do_gettimeofday(&ktv); 597 if (put_tv32(tv, &ktv)) 598 return -EFAULT; 599 } 600 if (tz) { 601 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 602 return -EFAULT; 603 } 604 return 0; 605 } 606 607 static inline long get_ts32(struct timespec *o, struct compat_timeval *i) 608 { 609 long usec; 610 611 if (!access_ok(VERIFY_READ, i, sizeof(*i))) 612 return -EFAULT; 613 if (__get_user(o->tv_sec, &i->tv_sec)) 614 return -EFAULT; 615 if (__get_user(usec, &i->tv_usec)) 616 return -EFAULT; 617 o->tv_nsec = usec * 1000; 618 return 0; 619 } 620 621 asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) 622 { 623 struct timespec kts; 624 struct timezone ktz; 625 626 if (tv) { 627 if (get_ts32(&kts, tv)) 628 return -EFAULT; 629 } 630 if (tz) { 631 if (copy_from_user(&ktz, tz, sizeof(ktz))) 632 return -EFAULT; 633 } 634 635 return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 636 } 637 638 /* These are here just in case some old sparc32 binary calls it. */ 639 asmlinkage long sys32_pause(void) 640 { 641 current->state = TASK_INTERRUPTIBLE; 642 schedule(); 643 return -ERESTARTNOHAND; 644 } 645 646 asmlinkage long sys32_pread64(unsigned int fd, char *ubuf, 647 size_t count, u32 poshi, u32 poslo) 648 { 649 if ((compat_ssize_t) count < 0) 650 return -EINVAL; 651 return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); 652 } 653 654 asmlinkage long sys32_pwrite64(unsigned int fd, const char *ubuf, 655 size_t count, u32 poshi, u32 poslo) 656 { 657 if ((compat_ssize_t) count < 0) 658 return -EINVAL; 659 return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); 660 } 661 662 asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count) 663 { 664 return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); 665 } 666 667 asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size_t count) 668 { 669 mm_segment_t old_fs = get_fs(); 670 int ret; 671 off_t of; 672 673 if (offset && get_user(of, offset)) 674 return -EFAULT; 675 676 set_fs(KERNEL_DS); 677 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); 678 set_fs(old_fs); 679 680 if (!ret && offset && put_user(of, offset)) 681 return -EFAULT; 682 683 return ret; 684 } 685 686 asmlinkage long sys32_sendfile64(int out_fd, int in_fd, 687 compat_loff_t *offset, s32 count) 688 { 689 mm_segment_t old_fs = get_fs(); 690 int ret; 691 loff_t lof; 692 693 if (offset && get_user(lof, offset)) 694 return -EFAULT; 695 696 set_fs(KERNEL_DS); 697 ret = sys_sendfile64(out_fd, in_fd, offset ? &lof : NULL, count); 698 set_fs(old_fs); 699 700 if (offset && put_user(lof, offset)) 701 return -EFAULT; 702 703 return ret; 704 } 705 706 /* Handle adjtimex compatibility. */ 707 708 struct timex32 { 709 u32 modes; 710 s32 offset, freq, maxerror, esterror; 711 s32 status, constant, precision, tolerance; 712 struct compat_timeval time; 713 s32 tick; 714 s32 ppsfreq, jitter, shift, stabil; 715 s32 jitcnt, calcnt, errcnt, stbcnt; 716 s32 :32; s32 :32; s32 :32; s32 :32; 717 s32 :32; s32 :32; s32 :32; s32 :32; 718 s32 :32; s32 :32; s32 :32; s32 :32; 719 }; 720 721 extern int do_adjtimex(struct timex *); 722 723 asmlinkage long sys32_adjtimex(struct timex32 *utp) 724 { 725 struct timex txc; 726 int ret; 727 728 memset(&txc, 0, sizeof(struct timex)); 729 730 if(get_user(txc.modes, &utp->modes) || 731 __get_user(txc.offset, &utp->offset) || 732 __get_user(txc.freq, &utp->freq) || 733 __get_user(txc.maxerror, &utp->maxerror) || 734 __get_user(txc.esterror, &utp->esterror) || 735 __get_user(txc.status, &utp->status) || 736 __get_user(txc.constant, &utp->constant) || 737 __get_user(txc.precision, &utp->precision) || 738 __get_user(txc.tolerance, &utp->tolerance) || 739 __get_user(txc.time.tv_sec, &utp->time.tv_sec) || 740 __get_user(txc.time.tv_usec, &utp->time.tv_usec) || 741 __get_user(txc.tick, &utp->tick) || 742 __get_user(txc.ppsfreq, &utp->ppsfreq) || 743 __get_user(txc.jitter, &utp->jitter) || 744 __get_user(txc.shift, &utp->shift) || 745 __get_user(txc.stabil, &utp->stabil) || 746 __get_user(txc.jitcnt, &utp->jitcnt) || 747 __get_user(txc.calcnt, &utp->calcnt) || 748 __get_user(txc.errcnt, &utp->errcnt) || 749 __get_user(txc.stbcnt, &utp->stbcnt)) 750 return -EFAULT; 751 752 ret = do_adjtimex(&txc); 753 754 if(put_user(txc.modes, &utp->modes) || 755 __put_user(txc.offset, &utp->offset) || 756 __put_user(txc.freq, &utp->freq) || 757 __put_user(txc.maxerror, &utp->maxerror) || 758 __put_user(txc.esterror, &utp->esterror) || 759 __put_user(txc.status, &utp->status) || 760 __put_user(txc.constant, &utp->constant) || 761 __put_user(txc.precision, &utp->precision) || 762 __put_user(txc.tolerance, &utp->tolerance) || 763 __put_user(txc.time.tv_sec, &utp->time.tv_sec) || 764 __put_user(txc.time.tv_usec, &utp->time.tv_usec) || 765 __put_user(txc.tick, &utp->tick) || 766 __put_user(txc.ppsfreq, &utp->ppsfreq) || 767 __put_user(txc.jitter, &utp->jitter) || 768 __put_user(txc.shift, &utp->shift) || 769 __put_user(txc.stabil, &utp->stabil) || 770 __put_user(txc.jitcnt, &utp->jitcnt) || 771 __put_user(txc.calcnt, &utp->calcnt) || 772 __put_user(txc.errcnt, &utp->errcnt) || 773 __put_user(txc.stbcnt, &utp->stbcnt)) 774 ret = -EFAULT; 775 776 return ret; 777 } 778 779 #ifdef CONFIG_SYSCTL 780 struct __sysctl_args32 { 781 u32 name; 782 int nlen; 783 u32 oldval; 784 u32 oldlenp; 785 u32 newval; 786 u32 newlen; 787 u32 __unused[4]; 788 }; 789 790 asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) 791 { 792 struct __sysctl_args32 tmp; 793 int error; 794 size_t oldlen, *oldlenp = NULL; 795 unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; 796 797 if (copy_from_user(&tmp, args, sizeof(tmp))) 798 return -EFAULT; 799 800 if (tmp.oldval && tmp.oldlenp) { 801 /* Duh, this is ugly and might not work if sysctl_args 802 is in read-only memory, but do_sysctl does indirectly 803 a lot of uaccess in both directions and we'd have to 804 basically copy the whole sysctl.c here, and 805 glibc's __sysctl uses rw memory for the structure 806 anyway. */ 807 if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) || 808 put_user(oldlen, (size_t *)addr)) 809 return -EFAULT; 810 oldlenp = (size_t *)addr; 811 } 812 813 lock_kernel(); 814 error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval), 815 oldlenp, (void *)A(tmp.newval), tmp.newlen); 816 unlock_kernel(); 817 if (oldlenp) { 818 if (!error) { 819 if (get_user(oldlen, (size_t *)addr) || 820 put_user(oldlen, (u32 *)A(tmp.oldlenp))) 821 error = -EFAULT; 822 } 823 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); 824 } 825 return error; 826 } 827 #endif 828 829 struct stat64_emu31 { 830 unsigned long long st_dev; 831 unsigned int __pad1; 832 #define STAT64_HAS_BROKEN_ST_INO 1 833 u32 __st_ino; 834 unsigned int st_mode; 835 unsigned int st_nlink; 836 u32 st_uid; 837 u32 st_gid; 838 unsigned long long st_rdev; 839 unsigned int __pad3; 840 long st_size; 841 u32 st_blksize; 842 unsigned char __pad4[4]; 843 u32 __pad5; /* future possible st_blocks high bits */ 844 u32 st_blocks; /* Number 512-byte blocks allocated. */ 845 u32 st_atime; 846 u32 __pad6; 847 u32 st_mtime; 848 u32 __pad7; 849 u32 st_ctime; 850 u32 __pad8; /* will be high 32 bits of ctime someday */ 851 unsigned long st_ino; 852 }; 853 854 static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat) 855 { 856 struct stat64_emu31 tmp; 857 858 memset(&tmp, 0, sizeof(tmp)); 859 860 tmp.st_dev = huge_encode_dev(stat->dev); 861 tmp.st_ino = stat->ino; 862 tmp.__st_ino = (u32)stat->ino; 863 tmp.st_mode = stat->mode; 864 tmp.st_nlink = (unsigned int)stat->nlink; 865 tmp.st_uid = stat->uid; 866 tmp.st_gid = stat->gid; 867 tmp.st_rdev = huge_encode_dev(stat->rdev); 868 tmp.st_size = stat->size; 869 tmp.st_blksize = (u32)stat->blksize; 870 tmp.st_blocks = (u32)stat->blocks; 871 tmp.st_atime = (u32)stat->atime.tv_sec; 872 tmp.st_mtime = (u32)stat->mtime.tv_sec; 873 tmp.st_ctime = (u32)stat->ctime.tv_sec; 874 875 return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 876 } 877 878 asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf) 879 { 880 struct kstat stat; 881 int ret = vfs_stat(filename, &stat); 882 if (!ret) 883 ret = cp_stat64(statbuf, &stat); 884 return ret; 885 } 886 887 asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf) 888 { 889 struct kstat stat; 890 int ret = vfs_lstat(filename, &stat); 891 if (!ret) 892 ret = cp_stat64(statbuf, &stat); 893 return ret; 894 } 895 896 asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf) 897 { 898 struct kstat stat; 899 int ret = vfs_fstat(fd, &stat); 900 if (!ret) 901 ret = cp_stat64(statbuf, &stat); 902 return ret; 903 } 904 905 /* 906 * Linux/i386 didn't use to be able to handle more than 907 * 4 system call parameters, so these system calls used a memory 908 * block for parameter passing.. 909 */ 910 911 struct mmap_arg_struct_emu31 { 912 u32 addr; 913 u32 len; 914 u32 prot; 915 u32 flags; 916 u32 fd; 917 u32 offset; 918 }; 919 920 /* common code for old and new mmaps */ 921 static inline long do_mmap2( 922 unsigned long addr, unsigned long len, 923 unsigned long prot, unsigned long flags, 924 unsigned long fd, unsigned long pgoff) 925 { 926 struct file * file = NULL; 927 unsigned long error = -EBADF; 928 929 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 930 if (!(flags & MAP_ANONYMOUS)) { 931 file = fget(fd); 932 if (!file) 933 goto out; 934 } 935 936 down_write(¤t->mm->mmap_sem); 937 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); 938 if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) { 939 /* Result is out of bounds. */ 940 do_munmap(current->mm, addr, len); 941 error = -ENOMEM; 942 } 943 up_write(¤t->mm->mmap_sem); 944 945 if (file) 946 fput(file); 947 out: 948 return error; 949 } 950 951 952 asmlinkage unsigned long 953 old32_mmap(struct mmap_arg_struct_emu31 *arg) 954 { 955 struct mmap_arg_struct_emu31 a; 956 int error = -EFAULT; 957 958 if (copy_from_user(&a, arg, sizeof(a))) 959 goto out; 960 961 error = -EINVAL; 962 if (a.offset & ~PAGE_MASK) 963 goto out; 964 965 error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); 966 out: 967 return error; 968 } 969 970 asmlinkage long 971 sys32_mmap2(struct mmap_arg_struct_emu31 *arg) 972 { 973 struct mmap_arg_struct_emu31 a; 974 int error = -EFAULT; 975 976 if (copy_from_user(&a, arg, sizeof(a))) 977 goto out; 978 error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); 979 out: 980 return error; 981 } 982 983 asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count) 984 { 985 if ((compat_ssize_t) count < 0) 986 return -EINVAL; 987 988 return sys_read(fd, buf, count); 989 } 990 991 asmlinkage long sys32_write(unsigned int fd, char * buf, size_t count) 992 { 993 if ((compat_ssize_t) count < 0) 994 return -EINVAL; 995 996 return sys_write(fd, buf, count); 997 } 998 999 asmlinkage long sys32_clone(struct pt_regs regs) 1000 { 1001 unsigned long clone_flags; 1002 unsigned long newsp; 1003 int *parent_tidptr, *child_tidptr; 1004 1005 clone_flags = regs.gprs[3] & 0xffffffffUL; 1006 newsp = regs.orig_gpr2 & 0x7fffffffUL; 1007 parent_tidptr = (int *) (regs.gprs[4] & 0x7fffffffUL); 1008 child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL); 1009 if (!newsp) 1010 newsp = regs.gprs[15]; 1011 return do_fork(clone_flags, newsp, ®s, 0, 1012 parent_tidptr, child_tidptr); 1013 } 1014 1015 /* 1016 * Wrapper function for sys_timer_create. 1017 */ 1018 extern asmlinkage long 1019 sys_timer_create(clockid_t, struct sigevent *, timer_t *); 1020 1021 asmlinkage long 1022 sys32_timer_create(clockid_t which_clock, struct compat_sigevent *se32, 1023 timer_t *timer_id) 1024 { 1025 struct sigevent se; 1026 timer_t ktimer_id; 1027 mm_segment_t old_fs; 1028 long ret; 1029 1030 if (se32 == NULL) 1031 return sys_timer_create(which_clock, NULL, timer_id); 1032 1033 if (get_compat_sigevent(&se, se32)) 1034 return -EFAULT; 1035 1036 old_fs = get_fs(); 1037 set_fs(KERNEL_DS); 1038 ret = sys_timer_create(which_clock, &se, &ktimer_id); 1039 set_fs(old_fs); 1040 1041 if (!ret) 1042 ret = put_user (ktimer_id, timer_id); 1043 1044 return ret; 1045 } 1046