1/* 2 * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Based on 3 * sys_sparc32 4 * 5 * Copyright (C) 2000 VA Linux Co 6 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com> 7 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com> 8 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 9 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 10 * Copyright (C) 2000 Hewlett-Packard Co. 11 * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com> 12 * Copyright (C) 2000,2001 Andi Kleen, SuSE Labs (x86-64 port) 13 * 14 * These routines maintain argument size conversion between 32bit and 64bit 15 * environment. In 2.5 most of this should be moved to a generic directory. 16 * 17 * This file assumes that there is a hole at the end of user address space. 18 * $Id: sys_ia32.c,v 1.1.1.1 2008/10/15 03:26:20 james26_jang Exp $ 19 */ 20 21#include <linux/config.h> 22#include <linux/kernel.h> 23#include <linux/sched.h> 24#include <linux/fs.h> 25#include <linux/file.h> 26#include <linux/signal.h> 27#include <linux/utime.h> 28#include <linux/resource.h> 29#include <linux/times.h> 30#include <linux/utsname.h> 31#include <linux/timex.h> 32#include <linux/smp.h> 33#include <linux/smp_lock.h> 34#include <linux/sem.h> 35#include <linux/msg.h> 36#include <linux/mm.h> 37#include <linux/shm.h> 38#include <linux/slab.h> 39#include <linux/uio.h> 40#include <linux/nfs_fs.h> 41#include <linux/smb_fs.h> 42#include <linux/smb_mount.h> 43#include <linux/ncp_fs.h> 44#include <linux/quota.h> 45#include <linux/module.h> 46#include <linux/sunrpc/svc.h> 47#include <linux/nfsd/nfsd.h> 48#include <linux/nfsd/cache.h> 49#include <linux/nfsd/xdr.h> 50#include <linux/nfsd/syscall.h> 51#include <linux/poll.h> 52#include <linux/personality.h> 53#include <linux/stat.h> 54#include <linux/ipc.h> 55#include <linux/rwsem.h> 56#include <linux/binfmts.h> 57#include <linux/init.h> 58#include <asm/mman.h> 59#include <asm/types.h> 60#include <asm/uaccess.h> 61#include <asm/semaphore.h> 62#include <asm/ipc.h> 63#include <asm/atomic.h> 64 65#include <net/scm.h> 66#include <net/sock.h> 67#include <asm/ia32.h> 68 69#define A(__x) ((unsigned long)(__x)) 70#define AA(__x) ((unsigned long)(__x)) 71#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) 72#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) 73 74#undef high2lowuid 75#undef high2lowgid 76#undef low2highuid 77#undef low2highgid 78 79#define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) 80#define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) 81#define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid) 82#define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid) 83extern int overflowuid,overflowgid; 84 85 86static int 87putstat(struct stat32 *ubuf, struct stat *kbuf) 88{ 89 if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat32)) || 90 __put_user (kbuf->st_dev, &ubuf->st_dev) || 91 __put_user (kbuf->st_ino, &ubuf->st_ino) || 92 __put_user (kbuf->st_mode, &ubuf->st_mode) || 93 __put_user (kbuf->st_nlink, &ubuf->st_nlink) || 94 __put_user (kbuf->st_uid, &ubuf->st_uid) || 95 __put_user (kbuf->st_gid, &ubuf->st_gid) || 96 __put_user (kbuf->st_rdev, &ubuf->st_rdev) || 97 __put_user (kbuf->st_size, &ubuf->st_size) || 98 __put_user (kbuf->st_atime, &ubuf->st_atime) || 99 __put_user (kbuf->st_mtime, &ubuf->st_mtime) || 100 __put_user (kbuf->st_ctime, &ubuf->st_ctime) || 101 __put_user (kbuf->st_blksize, &ubuf->st_blksize) || 102 __put_user (kbuf->st_blocks, &ubuf->st_blocks)) 103 return -EFAULT; 104 return 0; 105} 106 107extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf); 108 109asmlinkage long 110sys32_newstat(char * filename, struct stat32 *statbuf) 111{ 112 int ret; 113 struct stat s; 114 mm_segment_t old_fs = get_fs(); 115 116 set_fs (KERNEL_DS); 117 ret = sys_newstat(filename, &s); 118 set_fs (old_fs); 119 if (putstat (statbuf, &s)) 120 return -EFAULT; 121 return ret; 122} 123 124extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf); 125 126asmlinkage long 127sys32_newlstat(char * filename, struct stat32 *statbuf) 128{ 129 int ret; 130 struct stat s; 131 mm_segment_t old_fs = get_fs(); 132 133 set_fs (KERNEL_DS); 134 ret = sys_newlstat(filename, &s); 135 set_fs (old_fs); 136 if (putstat (statbuf, &s)) 137 return -EFAULT; 138 return ret; 139} 140 141extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf); 142 143asmlinkage long 144sys32_newfstat(unsigned int fd, struct stat32 *statbuf) 145{ 146 int ret; 147 struct stat s; 148 mm_segment_t old_fs = get_fs(); 149 150 set_fs (KERNEL_DS); 151 ret = sys_newfstat(fd, &s); 152 set_fs (old_fs); 153 if (putstat (statbuf, &s)) 154 return -EFAULT; 155 return ret; 156} 157 158/* Another set for IA32/LFS -- x86_64 struct stat is different due to 159 support for 64bit inode numbers. */ 160 161static int 162putstat64(struct stat64 *ubuf, struct stat *kbuf) 163{ 164 if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat64)) || 165 __put_user (kbuf->st_dev, &ubuf->st_dev) || 166 __put_user (kbuf->st_ino, &ubuf->__st_ino) || 167 __put_user (kbuf->st_ino, &ubuf->st_ino) || 168 __put_user (kbuf->st_mode, &ubuf->st_mode) || 169 __put_user (kbuf->st_nlink, &ubuf->st_nlink) || 170 __put_user (kbuf->st_uid, &ubuf->st_uid) || 171 __put_user (kbuf->st_gid, &ubuf->st_gid) || 172 __put_user (kbuf->st_rdev, &ubuf->st_rdev) || 173 __put_user (kbuf->st_size, &ubuf->st_size) || 174 __put_user (kbuf->st_atime, &ubuf->st_atime) || 175 __put_user (kbuf->st_mtime, &ubuf->st_mtime) || 176 __put_user (kbuf->st_ctime, &ubuf->st_ctime) || 177 __put_user (kbuf->st_blksize, &ubuf->st_blksize) || 178 __put_user (kbuf->st_blocks, &ubuf->st_blocks)) 179 return -EFAULT; 180 return 0; 181} 182 183asmlinkage long 184sys32_stat64(char * filename, struct stat64 *statbuf) 185{ 186 int ret; 187 struct stat s; 188 mm_segment_t old_fs = get_fs(); 189 190 set_fs (KERNEL_DS); 191 ret = sys_newstat(filename, &s); 192 set_fs (old_fs); 193 if (putstat64 (statbuf, &s)) 194 return -EFAULT; 195 return ret; 196} 197 198asmlinkage long 199sys32_lstat64(char * filename, struct stat64 *statbuf) 200{ 201 int ret; 202 struct stat s; 203 mm_segment_t old_fs = get_fs(); 204 205 set_fs (KERNEL_DS); 206 ret = sys_newlstat(filename, &s); 207 set_fs (old_fs); 208 if (putstat64 (statbuf, &s)) 209 return -EFAULT; 210 return ret; 211} 212 213asmlinkage long 214sys32_fstat64(unsigned int fd, struct stat64 *statbuf) 215{ 216 int ret; 217 struct stat s; 218 mm_segment_t old_fs = get_fs(); 219 220 set_fs (KERNEL_DS); 221 ret = sys_newfstat(fd, &s); 222 set_fs (old_fs); 223 if (putstat64 (statbuf, &s)) 224 return -EFAULT; 225 return ret; 226} 227 228 229 230/* 231 * Linux/i386 didn't use to be able to handle more than 232 * 4 system call parameters, so these system calls used a memory 233 * block for parameter passing.. 234 */ 235 236struct mmap_arg_struct { 237 unsigned int addr; 238 unsigned int len; 239 unsigned int prot; 240 unsigned int flags; 241 unsigned int fd; 242 unsigned int offset; 243}; 244 245asmlinkage __u32 246sys32_mmap(struct mmap_arg_struct *arg) 247{ 248 struct mmap_arg_struct a; 249 struct file *file = NULL; 250 unsigned long retval; 251 struct mm_struct *mm ; 252 253 if (copy_from_user(&a, arg, sizeof(a))) 254 return -EFAULT; 255 256 if (a.offset & ~PAGE_MASK) 257 return -EINVAL; 258 259 if (!(a.flags & MAP_ANONYMOUS)) { 260 file = fget(a.fd); 261 if (!file) 262 return -EBADF; 263 } 264 if (a.prot & PROT_READ) 265 a.prot |= PROT_EXEC; 266 267 a.flags |= MAP_32BIT; 268 269 mm = current->mm; 270 down_write(&mm->mmap_sem); 271 retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT); 272 if (file) 273 fput(file); 274 275 /* Should not happen */ 276 if (retval >= 0xFFFFFFFF && (long)retval > 0) { 277 do_munmap(mm, retval, a.len); 278 retval = -ENOMEM; 279 } 280 up_write(&mm->mmap_sem); 281 282 return retval; 283} 284 285extern asmlinkage long sys_mprotect(unsigned long start,size_t len,unsigned long prot); 286 287asmlinkage int sys32_mprotect(unsigned long start, size_t len, unsigned long prot) 288{ 289 if (prot & PROT_READ) 290 prot |= PROT_EXEC; 291 return sys_mprotect(start,len,prot); 292} 293 294asmlinkage long 295sys32_pipe(int *fd) 296{ 297 int retval; 298 int fds[2]; 299 300 retval = do_pipe(fds); 301 if (retval) 302 goto out; 303 if (copy_to_user(fd, fds, sizeof(fds))) 304 retval = -EFAULT; 305 out: 306 return retval; 307} 308 309asmlinkage long 310sys32_rt_sigaction(int sig, struct sigaction32 *act, 311 struct sigaction32 *oact, unsigned int sigsetsize) 312{ 313 struct k_sigaction new_ka, old_ka; 314 int ret; 315 sigset32_t set32; 316 317 if (sigsetsize != sizeof(sigset32_t)) 318 return -EINVAL; 319 320 if (act) { 321 if (verify_area(VERIFY_READ, act, sizeof(*act)) || 322 __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || 323 __get_user(new_ka.sa.sa_flags, &act->sa_flags) || 324 __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer)|| 325 __copy_from_user(&set32, &act->sa_mask, sizeof(sigset32_t))) 326 return -EFAULT; 327 328 switch (_NSIG_WORDS) { 329 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] 330 | (((long)set32.sig[7]) << 32); 331 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] 332 | (((long)set32.sig[5]) << 32); 333 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] 334 | (((long)set32.sig[3]) << 32); 335 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] 336 | (((long)set32.sig[1]) << 32); 337 } 338 } 339 340 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 341 342 if (!ret && oact) { 343 switch (_NSIG_WORDS) { 344 case 4: 345 set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); 346 set32.sig[6] = old_ka.sa.sa_mask.sig[3]; 347 case 3: 348 set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); 349 set32.sig[4] = old_ka.sa.sa_mask.sig[2]; 350 case 2: 351 set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); 352 set32.sig[2] = old_ka.sa.sa_mask.sig[1]; 353 case 1: 354 set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); 355 set32.sig[0] = old_ka.sa.sa_mask.sig[0]; 356 } 357 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || 358 __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || 359 __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || 360 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || 361 __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset32_t))) 362 return -EFAULT; 363 } 364 365 return ret; 366} 367 368asmlinkage long 369sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact) 370{ 371 struct k_sigaction new_ka, old_ka; 372 int ret; 373 374 if (act) { 375 old_sigset32_t mask; 376 377 if (verify_area(VERIFY_READ, act, sizeof(*act)) || 378 __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || 379 __get_user(new_ka.sa.sa_flags, &act->sa_flags) || 380 __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer) || 381 __get_user(mask, &act->sa_mask)) 382 return -EFAULT; 383 siginitset(&new_ka.sa.sa_mask, mask); 384 } 385 386 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 387 388 if (!ret && oact) { 389 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || 390 __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || 391 __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || 392 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || 393 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) 394 return -EFAULT; 395 } 396 397 return ret; 398} 399 400extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, 401 size_t sigsetsize); 402 403asmlinkage long 404sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset, 405 unsigned int sigsetsize) 406{ 407 sigset_t s; 408 sigset32_t s32; 409 int ret; 410 mm_segment_t old_fs = get_fs(); 411 412 if (set) { 413 if (copy_from_user (&s32, set, sizeof(sigset32_t))) 414 return -EFAULT; 415 switch (_NSIG_WORDS) { 416 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); 417 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); 418 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); 419 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); 420 } 421 } 422 set_fs (KERNEL_DS); 423 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, 424 sigsetsize); 425 set_fs (old_fs); 426 if (ret) return ret; 427 if (oset) { 428 switch (_NSIG_WORDS) { 429 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; 430 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; 431 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; 432 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; 433 } 434 if (copy_to_user (oset, &s32, sizeof(sigset32_t))) 435 return -EFAULT; 436 } 437 return 0; 438} 439 440static int 441put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) 442{ 443 if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct statfs32)) || 444 __put_user (kbuf->f_type, &ubuf->f_type) || 445 __put_user (kbuf->f_bsize, &ubuf->f_bsize) || 446 __put_user (kbuf->f_blocks, &ubuf->f_blocks) || 447 __put_user (kbuf->f_bfree, &ubuf->f_bfree) || 448 __put_user (kbuf->f_bavail, &ubuf->f_bavail) || 449 __put_user (kbuf->f_files, &ubuf->f_files) || 450 __put_user (kbuf->f_ffree, &ubuf->f_ffree) || 451 __put_user (kbuf->f_namelen, &ubuf->f_namelen) || 452 __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 453 __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1])) 454 return -EFAULT; 455 return 0; 456} 457 458extern asmlinkage long sys_statfs(const char * path, struct statfs * buf); 459 460asmlinkage long 461sys32_statfs(const char * path, struct statfs32 *buf) 462{ 463 int ret; 464 struct statfs s; 465 mm_segment_t old_fs = get_fs(); 466 467 set_fs (KERNEL_DS); 468 ret = sys_statfs((const char *)path, &s); 469 set_fs (old_fs); 470 if (put_statfs(buf, &s)) 471 return -EFAULT; 472 return ret; 473} 474 475extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf); 476 477asmlinkage long 478sys32_fstatfs(unsigned int fd, struct statfs32 *buf) 479{ 480 int ret; 481 struct statfs s; 482 mm_segment_t old_fs = get_fs(); 483 484 set_fs (KERNEL_DS); 485 ret = sys_fstatfs(fd, &s); 486 set_fs (old_fs); 487 if (put_statfs(buf, &s)) 488 return -EFAULT; 489 return ret; 490} 491 492struct timeval32 493{ 494 int tv_sec, tv_usec; 495}; 496 497struct itimerval32 498{ 499 struct timeval32 it_interval; 500 struct timeval32 it_value; 501}; 502 503static inline long 504get_tv32(struct timeval *o, struct timeval32 *i) 505{ 506 int err = -EFAULT; 507 if (access_ok(VERIFY_READ, i, sizeof(*i))) { 508 err = __get_user(o->tv_sec, &i->tv_sec); 509 err |= __get_user(o->tv_usec, &i->tv_usec); 510 } 511 return err; 512} 513 514static inline long 515put_tv32(struct timeval32 *o, struct timeval *i) 516{ 517 int err = -EFAULT; 518 if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { 519 err = __put_user(i->tv_sec, &o->tv_sec); 520 err |= __put_user(i->tv_usec, &o->tv_usec); 521 } 522 return err; 523} 524 525static inline long 526get_it32(struct itimerval *o, struct itimerval32 *i) 527{ 528 int err = -EFAULT; 529 if (access_ok(VERIFY_READ, i, sizeof(*i))) { 530 err = __get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec); 531 err |= __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec); 532 err |= __get_user(o->it_value.tv_sec, &i->it_value.tv_sec); 533 err |= __get_user(o->it_value.tv_usec, &i->it_value.tv_usec); 534 } 535 return err; 536} 537 538static inline long 539put_it32(struct itimerval32 *o, struct itimerval *i) 540{ 541 int err = -EFAULT; 542 if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { 543 err = __put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec); 544 err |= __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec); 545 err |= __put_user(i->it_value.tv_sec, &o->it_value.tv_sec); 546 err |= __put_user(i->it_value.tv_usec, &o->it_value.tv_usec); 547 } 548 return err; 549} 550 551extern int do_getitimer(int which, struct itimerval *value); 552 553asmlinkage long 554sys32_getitimer(int which, struct itimerval32 *it) 555{ 556 struct itimerval kit; 557 int error; 558 559 error = do_getitimer(which, &kit); 560 if (!error && put_it32(it, &kit)) 561 error = -EFAULT; 562 563 return error; 564} 565 566extern int do_setitimer(int which, struct itimerval *, struct itimerval *); 567 568asmlinkage long 569sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out) 570{ 571 struct itimerval kin, kout; 572 int error; 573 574 if (in) { 575 if (get_it32(&kin, in)) 576 return -EFAULT; 577 } else 578 memset(&kin, 0, sizeof(kin)); 579 580 error = do_setitimer(which, &kin, out ? &kout : NULL); 581 if (error || !out) 582 return error; 583 if (put_it32(out, &kout)) 584 return -EFAULT; 585 586 return 0; 587 588} 589asmlinkage unsigned long 590sys32_alarm(unsigned int seconds) 591{ 592 struct itimerval it_new, it_old; 593 unsigned int oldalarm; 594 595 it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0; 596 it_new.it_value.tv_sec = seconds; 597 it_new.it_value.tv_usec = 0; 598 do_setitimer(ITIMER_REAL, &it_new, &it_old); 599 oldalarm = it_old.it_value.tv_sec; 600 /* ehhh.. We can't return 0 if we have an alarm pending.. */ 601 /* And we'd better return too much than too little anyway */ 602 if (it_old.it_value.tv_usec) 603 oldalarm++; 604 return oldalarm; 605} 606 607/* Translations due to time_t size differences. Which affects all 608 sorts of things, like timeval and itimerval. */ 609 610struct utimbuf_32 { 611 int atime; 612 int mtime; 613}; 614 615extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes); 616extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz); 617 618extern struct timezone sys_tz; 619extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); 620 621asmlinkage long 622sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz) 623{ 624 if (tv) { 625 struct timeval ktv; 626 do_gettimeofday(&ktv); 627 if (put_tv32(tv, &ktv)) 628 return -EFAULT; 629 } 630 if (tz) { 631 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 632 return -EFAULT; 633 } 634 return 0; 635} 636 637asmlinkage long 638sys32_settimeofday(struct timeval32 *tv, struct timezone *tz) 639{ 640 struct timeval ktv; 641 struct timezone ktz; 642 643 if (tv) { 644 if (get_tv32(&ktv, tv)) 645 return -EFAULT; 646 } 647 if (tz) { 648 if (copy_from_user(&ktz, tz, sizeof(ktz))) 649 return -EFAULT; 650 } 651 652 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL); 653} 654 655struct linux32_dirent { 656 u32 d_ino; 657 u32 d_off; 658 u16 d_reclen; 659 char d_name[1]; 660}; 661 662struct old_linux32_dirent { 663 u32 d_ino; 664 u32 d_offset; 665 u16 d_namlen; 666 char d_name[1]; 667}; 668 669struct getdents32_callback { 670 struct linux32_dirent * current_dir; 671 struct linux32_dirent * previous; 672 int count; 673 int error; 674}; 675 676struct readdir32_callback { 677 struct old_linux32_dirent * dirent; 678 int count; 679}; 680 681static int 682filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, 683 unsigned int d_type) 684{ 685 struct linux32_dirent * dirent; 686 struct getdents32_callback * buf = (struct getdents32_callback *) __buf; 687 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); 688 689 buf->error = -EINVAL; /* only used if we fail.. */ 690 if (reclen > buf->count) 691 return -EINVAL; 692 dirent = buf->previous; 693 if (dirent) 694 put_user(offset, &dirent->d_off); 695 dirent = buf->current_dir; 696 buf->previous = dirent; 697 put_user(ino, &dirent->d_ino); 698 put_user(reclen, &dirent->d_reclen); 699 copy_to_user(dirent->d_name, name, namlen); 700 put_user(0, dirent->d_name + namlen); 701 ((char *) dirent) += reclen; 702 buf->current_dir = dirent; 703 buf->count -= reclen; 704 return 0; 705} 706 707asmlinkage long 708sys32_getdents (unsigned int fd, void * dirent, unsigned int count) 709{ 710 struct file * file; 711 struct linux32_dirent * lastdirent; 712 struct getdents32_callback buf; 713 int error; 714 715 error = -EBADF; 716 file = fget(fd); 717 if (!file) 718 goto out; 719 720 buf.current_dir = (struct linux32_dirent *) dirent; 721 buf.previous = NULL; 722 buf.count = count; 723 buf.error = 0; 724 725 error = vfs_readdir(file, filldir32, &buf); 726 if (error < 0) 727 goto out_putf; 728 error = buf.error; 729 lastdirent = buf.previous; 730 if (lastdirent) { 731 put_user(file->f_pos, &lastdirent->d_off); 732 error = count - buf.count; 733 } 734 735out_putf: 736 fput(file); 737out: 738 return error; 739} 740 741static int 742fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned d_type) 743{ 744 struct readdir32_callback * buf = (struct readdir32_callback *) __buf; 745 struct old_linux32_dirent * dirent; 746 747 if (buf->count) 748 return -EINVAL; 749 buf->count++; 750 dirent = buf->dirent; 751 put_user(ino, &dirent->d_ino); 752 put_user(offset, &dirent->d_offset); 753 put_user(namlen, &dirent->d_namlen); 754 copy_to_user(dirent->d_name, name, namlen); 755 put_user(0, dirent->d_name + namlen); 756 return 0; 757} 758 759asmlinkage long 760sys32_oldreaddir (unsigned int fd, void * dirent, unsigned int count) 761{ 762 int error; 763 struct file * file; 764 struct readdir32_callback buf; 765 766 error = -EBADF; 767 file = fget(fd); 768 if (!file) 769 goto out; 770 771 buf.count = 0; 772 buf.dirent = dirent; 773 774 error = vfs_readdir(file, fillonedir32, &buf); 775 if (error >= 0) 776 error = buf.count; 777 fput(file); 778out: 779 return error; 780} 781 782/* 783 * We can actually return ERESTARTSYS instead of EINTR, but I'd 784 * like to be certain this leads to no problems. So I return 785 * EINTR just for safety. 786 * 787 * Update: ERESTARTSYS breaks at least the xview clock binary, so 788 * I'm trying ERESTARTNOHAND which restart only when you want to. 789 */ 790#define MAX_SELECT_SECONDS \ 791 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) 792#define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y)) 793 794asmlinkage long 795sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32) 796{ 797 fd_set_bits fds; 798 char *bits; 799 long timeout; 800 int ret, size; 801 802 timeout = MAX_SCHEDULE_TIMEOUT; 803 if (tvp32) { 804 time_t sec, usec; 805 806 get_user(sec, &tvp32->tv_sec); 807 get_user(usec, &tvp32->tv_usec); 808 809 ret = -EINVAL; 810 if (sec < 0 || usec < 0) 811 goto out_nofds; 812 813 if ((unsigned long) sec < MAX_SELECT_SECONDS) { 814 timeout = ROUND_UP_TIME(usec, 1000000/HZ); 815 timeout += sec * (unsigned long) HZ; 816 } 817 } 818 819 ret = -EINVAL; 820 if (n < 0) 821 goto out_nofds; 822 823 if (n > current->files->max_fdset) 824 n = current->files->max_fdset; 825 826 /* 827 * We need 6 bitmaps (in/out/ex for both incoming and outgoing), 828 * since we used fdset we need to allocate memory in units of 829 * long-words. 830 */ 831 ret = -ENOMEM; 832 size = FDS_BYTES(n); 833 bits = kmalloc(6 * size, GFP_KERNEL); 834 if (!bits) 835 goto out_nofds; 836 fds.in = (unsigned long *) bits; 837 fds.out = (unsigned long *) (bits + size); 838 fds.ex = (unsigned long *) (bits + 2*size); 839 fds.res_in = (unsigned long *) (bits + 3*size); 840 fds.res_out = (unsigned long *) (bits + 4*size); 841 fds.res_ex = (unsigned long *) (bits + 5*size); 842 843 if ((ret = get_fd_set(n, inp, fds.in)) || 844 (ret = get_fd_set(n, outp, fds.out)) || 845 (ret = get_fd_set(n, exp, fds.ex))) 846 goto out; 847 zero_fd_set(n, fds.res_in); 848 zero_fd_set(n, fds.res_out); 849 zero_fd_set(n, fds.res_ex); 850 851 ret = do_select(n, &fds, &timeout); 852 853 if (tvp32 && !(current->personality & STICKY_TIMEOUTS)) { 854 time_t sec = 0, usec = 0; 855 if (timeout) { 856 sec = timeout / HZ; 857 usec = timeout % HZ; 858 usec *= (1000000/HZ); 859 } 860 put_user(sec, (int *)&tvp32->tv_sec); 861 put_user(usec, (int *)&tvp32->tv_usec); 862 } 863 864 if (ret < 0) 865 goto out; 866 if (!ret) { 867 ret = -ERESTARTNOHAND; 868 if (signal_pending(current)) 869 goto out; 870 ret = 0; 871 } 872 873 set_fd_set(n, inp, fds.res_in); 874 set_fd_set(n, outp, fds.res_out); 875 set_fd_set(n, exp, fds.res_ex); 876 877out: 878 kfree(bits); 879out_nofds: 880 return ret; 881} 882 883struct sel_arg_struct { 884 unsigned int n; 885 unsigned int inp; 886 unsigned int outp; 887 unsigned int exp; 888 unsigned int tvp; 889}; 890 891asmlinkage long 892sys32_old_select(struct sel_arg_struct *arg) 893{ 894 struct sel_arg_struct a; 895 896 if (copy_from_user(&a, arg, sizeof(a))) 897 return -EFAULT; 898 return sys32_select(a.n, (fd_set *)A(a.inp), (fd_set *)A(a.outp), (fd_set *)A(a.exp), 899 (struct timeval32 *)A(a.tvp)); 900} 901 902struct timespec32 { 903 int tv_sec; 904 int tv_nsec; 905}; 906 907extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp); 908 909asmlinkage long 910sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp) 911{ 912 struct timespec t; 913 int ret; 914 mm_segment_t old_fs = get_fs (); 915 916 if (verify_area(VERIFY_READ, rqtp, sizeof(struct timespec32)) || 917 __get_user (t.tv_sec, &rqtp->tv_sec) || 918 __get_user (t.tv_nsec, &rqtp->tv_nsec)) 919 return -EFAULT; 920 set_fs (KERNEL_DS); 921 ret = sys_nanosleep(&t, rmtp ? &t : NULL); 922 set_fs (old_fs); 923 if (rmtp && ret == -EINTR) { 924 if (verify_area(VERIFY_WRITE, rmtp, sizeof(struct timespec32)) || 925 __put_user (t.tv_sec, &rmtp->tv_sec) || 926 __put_user (t.tv_nsec, &rmtp->tv_nsec)) 927 return -EFAULT; 928 } 929 return ret; 930} 931 932asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long); 933asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long); 934 935struct iovec * 936get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type) 937{ 938 int i; 939 u32 buf, len; 940 struct iovec *ivp, *iov; 941 942 /* Get the "struct iovec" from user memory */ 943 944 if (!count) 945 return 0; 946 if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count)) 947 return(struct iovec *)0; 948 if (count > UIO_MAXIOV) 949 return(struct iovec *)0; 950 if (count > UIO_FASTIOV) { 951 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL); 952 if (!iov) 953 return((struct iovec *)0); 954 } else 955 iov = iov_buf; 956 957 ivp = iov; 958 for (i = 0; i < count; i++) { 959 if (__get_user(len, &iov32->iov_len) || 960 __get_user(buf, &iov32->iov_base)) { 961 if (iov != iov_buf) 962 kfree(iov); 963 return((struct iovec *)0); 964 } 965 if (verify_area(type, (void *)A(buf), len)) { 966 if (iov != iov_buf) 967 kfree(iov); 968 return((struct iovec *)0); 969 } 970 ivp->iov_base = (void *)A(buf); 971 ivp->iov_len = (__kernel_size_t)len; 972 iov32++; 973 ivp++; 974 } 975 return(iov); 976} 977 978asmlinkage long 979sys32_readv(int fd, struct iovec32 *vector, u32 count) 980{ 981 struct iovec iovstack[UIO_FASTIOV]; 982 struct iovec *iov; 983 int ret; 984 mm_segment_t old_fs = get_fs(); 985 986 if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE)) == (struct iovec *)0) 987 return -EFAULT; 988 set_fs(KERNEL_DS); 989 ret = sys_readv(fd, iov, count); 990 set_fs(old_fs); 991 if (iov != iovstack) 992 kfree(iov); 993 return ret; 994} 995 996asmlinkage long 997sys32_writev(int fd, struct iovec32 *vector, u32 count) 998{ 999 struct iovec iovstack[UIO_FASTIOV]; 1000 struct iovec *iov; 1001 int ret; 1002 mm_segment_t old_fs = get_fs(); 1003 1004 if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ)) == (struct iovec *)0) 1005 return -EFAULT; 1006 set_fs(KERNEL_DS); 1007 ret = sys_writev(fd, iov, count); 1008 set_fs(old_fs); 1009 if (iov != iovstack) 1010 kfree(iov); 1011 return ret; 1012} 1013 1014#define RLIM_INFINITY32 0xffffffff 1015#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) 1016 1017struct rlimit32 { 1018 int rlim_cur; 1019 int rlim_max; 1020}; 1021 1022extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim); 1023 1024asmlinkage long 1025sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim) 1026{ 1027 struct rlimit r; 1028 int ret; 1029 mm_segment_t old_fs; 1030 1031 old_fs = get_fs(); 1032 set_fs(KERNEL_DS); 1033 ret = sys_getrlimit(resource, &r); 1034 set_fs(old_fs); 1035 if (!ret) { 1036 if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) || 1037 __put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur) || 1038 __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max)) 1039 ret = -EFAULT; 1040 } 1041 return ret; 1042} 1043 1044extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim); 1045 1046asmlinkage long 1047sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim) 1048{ 1049 struct rlimit r; 1050 int ret; 1051 mm_segment_t old_fs; 1052 1053 old_fs = get_fs(); 1054 set_fs(KERNEL_DS); 1055 ret = sys_old_getrlimit(resource, &r); 1056 set_fs(old_fs); 1057 if (!ret) { 1058 if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) || 1059 __put_user(r.rlim_cur, &rlim->rlim_cur) || 1060 __put_user(r.rlim_max, &rlim->rlim_max)) 1061 ret = -EFAULT; 1062 } 1063 return ret; 1064} 1065 1066extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim); 1067 1068asmlinkage long 1069sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim) 1070{ 1071 struct rlimit r; 1072 int ret; 1073 mm_segment_t old_fs = get_fs (); 1074 1075 if (resource >= RLIM_NLIMITS) return -EINVAL; 1076 if (verify_area(VERIFY_READ, rlim, sizeof(struct rlimit32)) || 1077 __get_user (r.rlim_cur, &rlim->rlim_cur) || 1078 __get_user (r.rlim_max, &rlim->rlim_max)) 1079 return -EFAULT; 1080 if (r.rlim_cur == RLIM_INFINITY32) 1081 r.rlim_cur = RLIM_INFINITY; 1082 if (r.rlim_max == RLIM_INFINITY32) 1083 r.rlim_max = RLIM_INFINITY; 1084 set_fs (KERNEL_DS); 1085 ret = sys_setrlimit(resource, &r); 1086 set_fs (old_fs); 1087 return ret; 1088} 1089 1090/* 1091 * sys_time() can be implemented in user-level using 1092 * sys_gettimeofday(). IA64 did this but i386 Linux did not 1093 * so we have to implement this system call here. 1094 */ 1095asmlinkage long sys32_time(int * tloc) 1096{ 1097 int i; 1098 1099 /* SMP: This is fairly trivial. We grab CURRENT_TIME and 1100 stuff it to user space. No side effects */ 1101 i = CURRENT_TIME; 1102 if (tloc) { 1103 if (put_user(i,tloc)) 1104 i = -EFAULT; 1105 } 1106 return i; 1107} 1108 1109struct rusage32 { 1110 struct timeval32 ru_utime; 1111 struct timeval32 ru_stime; 1112 int ru_maxrss; 1113 int ru_ixrss; 1114 int ru_idrss; 1115 int ru_isrss; 1116 int ru_minflt; 1117 int ru_majflt; 1118 int ru_nswap; 1119 int ru_inblock; 1120 int ru_oublock; 1121 int ru_msgsnd; 1122 int ru_msgrcv; 1123 int ru_nsignals; 1124 int ru_nvcsw; 1125 int ru_nivcsw; 1126}; 1127 1128static int 1129put_rusage (struct rusage32 *ru, struct rusage *r) 1130{ 1131 if (verify_area(VERIFY_WRITE, ru, sizeof(struct rusage32)) || 1132 __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) || 1133 __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) || 1134 __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) || 1135 __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) || 1136 __put_user (r->ru_maxrss, &ru->ru_maxrss) || 1137 __put_user (r->ru_ixrss, &ru->ru_ixrss) || 1138 __put_user (r->ru_idrss, &ru->ru_idrss) || 1139 __put_user (r->ru_isrss, &ru->ru_isrss) || 1140 __put_user (r->ru_minflt, &ru->ru_minflt) || 1141 __put_user (r->ru_majflt, &ru->ru_majflt) || 1142 __put_user (r->ru_nswap, &ru->ru_nswap) || 1143 __put_user (r->ru_inblock, &ru->ru_inblock) || 1144 __put_user (r->ru_oublock, &ru->ru_oublock) || 1145 __put_user (r->ru_msgsnd, &ru->ru_msgsnd) || 1146 __put_user (r->ru_msgrcv, &ru->ru_msgrcv) || 1147 __put_user (r->ru_nsignals, &ru->ru_nsignals) || 1148 __put_user (r->ru_nvcsw, &ru->ru_nvcsw) || 1149 __put_user (r->ru_nivcsw, &ru->ru_nivcsw)) 1150 return -EFAULT; 1151 return 0; 1152} 1153 1154extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, 1155 int options, struct rusage * ru); 1156 1157asmlinkage long 1158sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, 1159 struct rusage32 *ru) 1160{ 1161 if (!ru) 1162 return sys_wait4(pid, stat_addr, options, NULL); 1163 else { 1164 struct rusage r; 1165 int ret; 1166 unsigned int status; 1167 mm_segment_t old_fs = get_fs(); 1168 1169 set_fs (KERNEL_DS); 1170 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r); 1171 set_fs (old_fs); 1172 if (put_rusage (ru, &r)) return -EFAULT; 1173 if (stat_addr && put_user (status, stat_addr)) 1174 return -EFAULT; 1175 return ret; 1176 } 1177} 1178 1179asmlinkage long 1180sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options) 1181{ 1182 return sys32_wait4(pid, stat_addr, options, NULL); 1183} 1184 1185 1186extern asmlinkage long 1187sys_getrusage(int who, struct rusage *ru); 1188 1189asmlinkage long 1190sys32_getrusage(int who, struct rusage32 *ru) 1191{ 1192 struct rusage r; 1193 int ret; 1194 mm_segment_t old_fs = get_fs(); 1195 1196 set_fs (KERNEL_DS); 1197 ret = sys_getrusage(who, &r); 1198 set_fs (old_fs); 1199 if (put_rusage (ru, &r)) return -EFAULT; 1200 return ret; 1201} 1202 1203struct tms32 { 1204 __kernel_clock_t32 tms_utime; 1205 __kernel_clock_t32 tms_stime; 1206 __kernel_clock_t32 tms_cutime; 1207 __kernel_clock_t32 tms_cstime; 1208}; 1209 1210extern int sys_times(struct tms *); 1211 1212asmlinkage long 1213sys32_times(struct tms32 *tbuf) 1214{ 1215 struct tms t; 1216 long ret; 1217 mm_segment_t old_fs = get_fs (); 1218 1219 set_fs (KERNEL_DS); 1220 ret = sys_times(tbuf ? &t : NULL); 1221 set_fs (old_fs); 1222 if (tbuf) { 1223 if (verify_area(VERIFY_WRITE, tbuf, sizeof(struct tms32)) || 1224 __put_user (t.tms_utime, &tbuf->tms_utime) || 1225 __put_user (t.tms_stime, &tbuf->tms_stime) || 1226 __put_user (t.tms_cutime, &tbuf->tms_cutime) || 1227 __put_user (t.tms_cstime, &tbuf->tms_cstime)) 1228 return -EFAULT; 1229 } 1230 return ret; 1231} 1232 1233 1234static inline int get_flock(struct flock *kfl, struct flock32 *ufl) 1235{ 1236 int err; 1237 1238 err = get_user(kfl->l_type, &ufl->l_type); 1239 err |= __get_user(kfl->l_whence, &ufl->l_whence); 1240 err |= __get_user(kfl->l_start, &ufl->l_start); 1241 err |= __get_user(kfl->l_len, &ufl->l_len); 1242 err |= __get_user(kfl->l_pid, &ufl->l_pid); 1243 return err; 1244} 1245 1246static inline int put_flock(struct flock *kfl, struct flock32 *ufl) 1247{ 1248 int err; 1249 1250 err = __put_user(kfl->l_type, &ufl->l_type); 1251 err |= __put_user(kfl->l_whence, &ufl->l_whence); 1252 err |= __put_user(kfl->l_start, &ufl->l_start); 1253 err |= __put_user(kfl->l_len, &ufl->l_len); 1254 err |= __put_user(kfl->l_pid, &ufl->l_pid); 1255 return err; 1256} 1257 1258extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); 1259asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg); 1260 1261 1262asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) 1263{ 1264 switch (cmd) { 1265 case F_GETLK: 1266 case F_SETLK: 1267 case F_SETLKW: 1268 { 1269 struct flock f; 1270 mm_segment_t old_fs; 1271 long ret; 1272 1273 if (get_flock(&f, (struct flock32 *)arg)) 1274 return -EFAULT; 1275 old_fs = get_fs(); set_fs (KERNEL_DS); 1276 ret = sys_fcntl(fd, cmd, (unsigned long)&f); 1277 set_fs (old_fs); 1278 if (ret) return ret; 1279 if (put_flock(&f, (struct flock32 *)arg)) 1280 return -EFAULT; 1281 return 0; 1282 } 1283 case F_GETLK64: 1284 case F_SETLK64: 1285 case F_SETLKW64: 1286 return sys32_fcntl64(fd,cmd,arg); 1287 1288 default: 1289 return sys_fcntl(fd, cmd, (unsigned long)arg); 1290 } 1291} 1292 1293static inline int get_flock64(struct ia32_flock64 *fl32, struct flock *fl64) 1294{ 1295 if (access_ok(fl32, sizeof(struct ia32_flock64), VERIFY_WRITE)) { 1296 int ret = __get_user(fl64->l_type, &fl32->l_type); 1297 ret |= __get_user(fl64->l_whence, &fl32->l_whence); 1298 ret |= __get_user(fl64->l_start, &fl32->l_start); 1299 ret |= __get_user(fl64->l_len, &fl32->l_len); 1300 ret |= __get_user(fl64->l_pid, &fl32->l_pid); 1301 return ret; 1302 } 1303 return -EFAULT; 1304} 1305 1306static inline int put_flock64(struct ia32_flock64 *fl32, struct flock *fl64) 1307{ 1308 if (access_ok(fl32, sizeof(struct ia32_flock64), VERIFY_WRITE)) { 1309 int ret = __put_user(fl64->l_type, &fl32->l_type); 1310 ret |= __put_user(fl64->l_whence, &fl32->l_whence); 1311 ret |= __put_user(fl64->l_start, &fl32->l_start); 1312 ret |= __put_user(fl64->l_len, &fl32->l_len); 1313 ret |= __put_user(fl64->l_pid, &fl32->l_pid); 1314 return ret; 1315 } 1316 return -EFAULT; 1317} 1318 1319asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) 1320{ 1321 struct flock fl64; 1322 mm_segment_t oldfs = get_fs(); 1323 int ret = 0; 1324 int oldcmd = cmd; 1325 unsigned long oldarg = arg; 1326 1327 switch (cmd) { 1328 case F_GETLK64: 1329 cmd = F_GETLK; 1330 goto cnv; 1331 case F_SETLK64: 1332 cmd = F_SETLK; 1333 goto cnv; 1334 case F_SETLKW64: 1335 cmd = F_SETLKW; 1336 cnv: 1337 ret = get_flock64((struct ia32_flock64 *)arg, &fl64); 1338 arg = (unsigned long)&fl64; 1339 set_fs(KERNEL_DS); 1340 break; 1341 case F_GETLK: 1342 case F_SETLK: 1343 case F_SETLKW: 1344 return sys32_fcntl(fd,cmd,arg); 1345 } 1346 if (!ret) 1347 ret = sys_fcntl(fd, cmd, arg); 1348 set_fs(oldfs); 1349 if (oldcmd == F_GETLK64 && !ret) 1350 ret = put_flock64((struct ia32_flock64 *)oldarg, &fl64); 1351 return ret; 1352} 1353 1354int sys32_ni_syscall(int call) 1355{ 1356 printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call, 1357 current->comm); 1358 return -ENOSYS; 1359} 1360 1361/* 32-bit timeval and related flotsam. */ 1362 1363extern asmlinkage long sys_utime(char * filename, struct utimbuf * times); 1364 1365struct utimbuf32 { 1366 __kernel_time_t32 actime, modtime; 1367}; 1368 1369asmlinkage long 1370sys32_utime(char * filename, struct utimbuf32 *times) 1371{ 1372 struct utimbuf t; 1373 mm_segment_t old_fs; 1374 int ret; 1375 char *filenam; 1376 1377 if (!times) 1378 return sys_utime(filename, NULL); 1379 if (verify_area(VERIFY_READ, times, sizeof(struct utimbuf32)) || 1380 __get_user (t.actime, ×->actime) || 1381 __get_user (t.modtime, ×->modtime)) 1382 return -EFAULT; 1383 filenam = getname (filename); 1384 ret = PTR_ERR(filenam); 1385 if (!IS_ERR(filenam)) { 1386 old_fs = get_fs(); 1387 set_fs (KERNEL_DS); 1388 ret = sys_utime(filenam, &t); 1389 set_fs (old_fs); 1390 putname(filenam); 1391 } 1392 return ret; 1393} 1394 1395extern asmlinkage long sys_sysfs(int option, unsigned long arg1, 1396 unsigned long arg2); 1397 1398asmlinkage long 1399sys32_sysfs(int option, u32 arg1, u32 arg2) 1400{ 1401 return sys_sysfs(option, arg1, arg2); 1402} 1403 1404extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type, 1405 unsigned long new_flags, void *data); 1406 1407static char *badfs[] = { 1408 "smbfs", "ncpfs", NULL 1409}; 1410 1411static int checktype(char *user_type) 1412{ 1413 int err = 0; 1414 char **s,*kernel_type = getname(user_type); 1415 if (!kernel_type || IS_ERR(kernel_type)) 1416 return -EFAULT; 1417 for (s = badfs; *s; ++s) 1418 if (!strcmp(kernel_type, *s)) { 1419 printk(KERN_ERR "mount32: unsupported fs `%s' -- use 64bit mount\n", *s); 1420 err = -EINVAL; 1421 break; 1422 } 1423 putname(user_type); 1424 return err; 1425} 1426 1427asmlinkage long 1428sys32_mount(char *dev_name, char *dir_name, char *type, 1429 unsigned long new_flags, u32 data) 1430{ 1431 int err; 1432 if(!capable(CAP_SYS_ADMIN)) 1433 return -EPERM; 1434 err = checktype(type); 1435 if (err) 1436 return err; 1437 return sys_mount(dev_name, dir_name, type, new_flags, (void *)AA(data)); 1438} 1439 1440struct sysinfo32 { 1441 s32 uptime; 1442 u32 loads[3]; 1443 u32 totalram; 1444 u32 freeram; 1445 u32 sharedram; 1446 u32 bufferram; 1447 u32 totalswap; 1448 u32 freeswap; 1449 unsigned short procs; 1450 char _f[22]; 1451}; 1452 1453extern asmlinkage long sys_sysinfo(struct sysinfo *info); 1454 1455asmlinkage long 1456sys32_sysinfo(struct sysinfo32 *info) 1457{ 1458 struct sysinfo s; 1459 int ret; 1460 mm_segment_t old_fs = get_fs (); 1461 1462 set_fs (KERNEL_DS); 1463 ret = sys_sysinfo(&s); 1464 set_fs (old_fs); 1465 if (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) || 1466 __put_user (s.uptime, &info->uptime) || 1467 __put_user (s.loads[0], &info->loads[0]) || 1468 __put_user (s.loads[1], &info->loads[1]) || 1469 __put_user (s.loads[2], &info->loads[2]) || 1470 __put_user (s.totalram, &info->totalram) || 1471 __put_user (s.freeram, &info->freeram) || 1472 __put_user (s.sharedram, &info->sharedram) || 1473 __put_user (s.bufferram, &info->bufferram) || 1474 __put_user (s.totalswap, &info->totalswap) || 1475 __put_user (s.freeswap, &info->freeswap) || 1476 __put_user (s.procs, &info->procs)) 1477 return -EFAULT; 1478 return 0; 1479} 1480 1481extern asmlinkage long sys_sched_rr_get_interval(pid_t pid, 1482 struct timespec *interval); 1483 1484asmlinkage long 1485sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval) 1486{ 1487 struct timespec t; 1488 int ret; 1489 mm_segment_t old_fs = get_fs (); 1490 1491 set_fs (KERNEL_DS); 1492 ret = sys_sched_rr_get_interval(pid, &t); 1493 set_fs (old_fs); 1494 if (verify_area(VERIFY_WRITE, interval, sizeof(struct timespec32)) || 1495 __put_user (t.tv_sec, &interval->tv_sec) || 1496 __put_user (t.tv_nsec, &interval->tv_nsec)) 1497 return -EFAULT; 1498 return ret; 1499} 1500 1501extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set, 1502 old_sigset_t *oset); 1503 1504asmlinkage long 1505sys32_sigprocmask(int how, old_sigset32_t *set, old_sigset32_t *oset) 1506{ 1507 old_sigset_t s; 1508 int ret; 1509 mm_segment_t old_fs = get_fs(); 1510 1511 if (set && get_user (s, set)) return -EFAULT; 1512 set_fs (KERNEL_DS); 1513 ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); 1514 set_fs (old_fs); 1515 if (ret) return ret; 1516 if (oset && put_user (s, oset)) return -EFAULT; 1517 return 0; 1518} 1519 1520extern asmlinkage long sys_sigpending(old_sigset_t *set); 1521 1522asmlinkage long 1523sys32_sigpending(old_sigset32_t *set) 1524{ 1525 old_sigset_t s; 1526 int ret; 1527 mm_segment_t old_fs = get_fs(); 1528 1529 set_fs (KERNEL_DS); 1530 ret = sys_sigpending(&s); 1531 set_fs (old_fs); 1532 if (put_user (s, set)) return -EFAULT; 1533 return ret; 1534} 1535 1536extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize); 1537 1538asmlinkage long 1539sys32_rt_sigpending(sigset32_t *set, __kernel_size_t32 sigsetsize) 1540{ 1541 sigset_t s; 1542 sigset32_t s32; 1543 int ret; 1544 mm_segment_t old_fs = get_fs(); 1545 1546 set_fs (KERNEL_DS); 1547 ret = sys_rt_sigpending(&s, sigsetsize); 1548 set_fs (old_fs); 1549 if (!ret) { 1550 switch (_NSIG_WORDS) { 1551 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; 1552 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; 1553 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; 1554 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; 1555 } 1556 if (copy_to_user (set, &s32, sizeof(sigset32_t))) 1557 return -EFAULT; 1558 } 1559 return ret; 1560} 1561 1562siginfo_t32 * 1563siginfo64to32(siginfo_t32 *d, siginfo_t *s) 1564{ 1565 memset (d, 0, sizeof(siginfo_t32)); 1566 d->si_signo = s->si_signo; 1567 d->si_errno = s->si_errno; 1568 d->si_code = s->si_code; 1569 if (s->si_signo >= SIGRTMIN) { 1570 d->si_pid = s->si_pid; 1571 d->si_uid = s->si_uid; 1572 d->si_int = s->si_int; 1573 } else switch (s->si_signo) { 1574 case SIGCHLD: 1575 d->si_pid = s->si_pid; 1576 d->si_status = s->si_status; 1577 d->si_utime = s->si_utime; 1578 d->si_stime = s->si_stime; 1579 break; 1580 case SIGSEGV: 1581 case SIGBUS: 1582 case SIGFPE: 1583 case SIGILL: 1584 d->si_addr = (long)(s->si_addr); 1585// d->si_trapno = s->si_trapno; 1586 break; 1587 case SIGPOLL: 1588 d->si_band = s->si_band; 1589 d->si_fd = s->si_fd; 1590 break; 1591 default: 1592 d->si_pid = s->si_pid; 1593 d->si_uid = s->si_uid; 1594 break; 1595 } 1596 return d; 1597} 1598 1599siginfo_t * 1600siginfo32to64(siginfo_t *d, siginfo_t32 *s) 1601{ 1602 d->si_signo = s->si_signo; 1603 d->si_errno = s->si_errno; 1604 d->si_code = s->si_code; 1605 if (s->si_signo >= SIGRTMIN) { 1606 d->si_pid = s->si_pid; 1607 d->si_uid = s->si_uid; 1608 d->si_int = s->si_int; 1609 } else switch (s->si_signo) { 1610 case SIGCHLD: 1611 d->si_pid = s->si_pid; 1612 d->si_status = s->si_status; 1613 d->si_utime = s->si_utime; 1614 d->si_stime = s->si_stime; 1615 break; 1616 case SIGSEGV: 1617 case SIGBUS: 1618 case SIGFPE: 1619 case SIGILL: 1620 d->si_addr = (void *)A(s->si_addr); 1621// d->si_trapno = s->si_trapno; 1622 break; 1623 case SIGPOLL: 1624 d->si_band = s->si_band; 1625 d->si_fd = s->si_fd; 1626 break; 1627 default: 1628 d->si_pid = s->si_pid; 1629 d->si_uid = s->si_uid; 1630 break; 1631 } 1632 return d; 1633} 1634 1635extern asmlinkage long 1636sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo, 1637 const struct timespec *uts, size_t sigsetsize); 1638 1639asmlinkage long 1640sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, 1641 struct timespec32 *uts, __kernel_size_t32 sigsetsize) 1642{ 1643 sigset_t s; 1644 sigset32_t s32; 1645 struct timespec t; 1646 int ret; 1647 mm_segment_t old_fs = get_fs(); 1648 siginfo_t info; 1649 siginfo_t32 info32; 1650 1651 if (copy_from_user (&s32, uthese, sizeof(sigset32_t))) 1652 return -EFAULT; 1653 switch (_NSIG_WORDS) { 1654 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); 1655 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); 1656 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); 1657 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); 1658 } 1659 if (uts) { 1660 if (verify_area(VERIFY_READ, uts, sizeof(struct timespec32)) || 1661 __get_user (t.tv_sec, &uts->tv_sec) || 1662 __get_user (t.tv_nsec, &uts->tv_nsec)) 1663 return -EFAULT; 1664 } 1665 set_fs (KERNEL_DS); 1666 ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize); 1667 set_fs (old_fs); 1668 if (ret >= 0 && uinfo) { 1669 if (copy_to_user (uinfo, siginfo64to32(&info32, &info), 1670 sizeof(siginfo_t32))) 1671 return -EFAULT; 1672 } 1673 return ret; 1674} 1675 1676extern asmlinkage long 1677sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo); 1678 1679asmlinkage long 1680sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo) 1681{ 1682 siginfo_t info; 1683 siginfo_t32 info32; 1684 int ret; 1685 mm_segment_t old_fs = get_fs(); 1686 1687 if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32))) 1688 return -EFAULT; 1689 siginfo32to64(&info, &info32); 1690 set_fs (KERNEL_DS); 1691 ret = sys_rt_sigqueueinfo(pid, sig, &info); 1692 set_fs (old_fs); 1693 return ret; 1694} 1695 1696extern void check_pending(int signum); 1697 1698asmlinkage long sys_utimes(char *, struct timeval *); 1699 1700asmlinkage long 1701sys32_utimes(char *filename, struct timeval32 *tvs) 1702{ 1703 char *kfilename; 1704 struct timeval ktvs[2]; 1705 mm_segment_t old_fs; 1706 int ret; 1707 1708 kfilename = getname(filename); 1709 ret = PTR_ERR(kfilename); 1710 if (!IS_ERR(kfilename)) { 1711 if (tvs) { 1712 if (get_tv32(&ktvs[0], tvs) || 1713 get_tv32(&ktvs[1], 1+tvs)) 1714 return -EFAULT; 1715 } 1716 1717 old_fs = get_fs(); 1718 set_fs(KERNEL_DS); 1719 ret = sys_utimes(kfilename, &ktvs[0]); 1720 set_fs(old_fs); 1721 1722 putname(kfilename); 1723 } 1724 return ret; 1725} 1726 1727/* These are here just in case some old ia32 binary calls it. */ 1728asmlinkage long 1729sys32_pause(void) 1730{ 1731 current->state = TASK_INTERRUPTIBLE; 1732 schedule(); 1733 return -ERESTARTNOHAND; 1734} 1735 1736 1737struct sysctl_ia32 { 1738 unsigned int name; 1739 int nlen; 1740 unsigned int oldval; 1741 unsigned int oldlenp; 1742 unsigned int newval; 1743 unsigned int newlen; 1744 unsigned int __unused[4]; 1745}; 1746 1747 1748asmlinkage long 1749sys32_sysctl(struct sysctl_ia32 *args32) 1750{ 1751#ifndef CONFIG_SYSCTL 1752 return -ENOSYS; 1753#else 1754 struct sysctl_ia32 a32; 1755 mm_segment_t old_fs = get_fs (); 1756 void *oldvalp, *newvalp; 1757 size_t oldlen; 1758 int *namep; 1759 long ret; 1760 extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, 1761 void *newval, size_t newlen); 1762 1763 1764 if (copy_from_user(&a32, args32, sizeof (a32))) 1765 return -EFAULT; 1766 1767 /* 1768 * We need to pre-validate these because we have to disable address checking 1769 * before calling do_sysctl() because of OLDLEN but we can't run the risk of the 1770 * user specifying bad addresses here. Well, since we're dealing with 32 bit 1771 * addresses, we KNOW that access_ok() will always succeed, so this is an 1772 * expensive NOP, but so what... 1773 */ 1774 namep = (int *) A(a32.name); 1775 oldvalp = (void *) A(a32.oldval); 1776 newvalp = (void *) A(a32.newval); 1777 1778 if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp))) 1779 || !access_ok(VERIFY_WRITE, namep, 0) 1780 || !access_ok(VERIFY_WRITE, oldvalp, 0) 1781 || !access_ok(VERIFY_WRITE, newvalp, 0)) 1782 return -EFAULT; 1783 1784 set_fs(KERNEL_DS); 1785 lock_kernel(); 1786 ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen); 1787 unlock_kernel(); 1788 set_fs(old_fs); 1789 1790 if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp))) 1791 return -EFAULT; 1792 1793 return ret; 1794#endif 1795} 1796 1797extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf, 1798 size_t count, loff_t pos); 1799 1800extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf, 1801 size_t count, loff_t pos); 1802 1803typedef __kernel_ssize_t32 ssize_t32; 1804 1805 1806/* warning: next two assume little endian */ 1807asmlinkage ssize_t32 1808sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count, 1809 u32 poslo, u32 poshi) 1810{ 1811 return sys_pread(fd, ubuf, count, 1812 ((loff_t)AA(poshi) << 32) | AA(poslo)); 1813} 1814 1815asmlinkage ssize_t32 1816sys32_pwrite(unsigned int fd, char *ubuf, __kernel_size_t32 count, 1817 u32 poslo, u32 poshi) 1818{ 1819 return sys_pwrite(fd, ubuf, count, 1820 ((loff_t)AA(poshi) << 32) | AA(poslo)); 1821} 1822 1823 1824extern asmlinkage long sys_personality(unsigned long); 1825 1826asmlinkage long 1827sys32_personality(unsigned long personality) 1828{ 1829 int ret; 1830 if (personality(current->personality) == PER_LINUX32 && 1831 personality == PER_LINUX) 1832 personality = PER_LINUX32; 1833 ret = sys_personality(personality); 1834 if (ret == PER_LINUX32) 1835 ret = PER_LINUX; 1836 return ret; 1837} 1838 1839extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, 1840 size_t count); 1841 1842asmlinkage long 1843sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count) 1844{ 1845 mm_segment_t old_fs = get_fs(); 1846 int ret; 1847 off_t of; 1848 1849 if (offset && get_user(of, offset)) 1850 return -EFAULT; 1851 1852 set_fs(KERNEL_DS); 1853 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); 1854 set_fs(old_fs); 1855 1856 if (!ret && offset && put_user(of, offset)) 1857 return -EFAULT; 1858 1859 return ret; 1860} 1861 1862/* Handle adjtimex compatability. */ 1863 1864struct timex32 { 1865 u32 modes; 1866 s32 offset, freq, maxerror, esterror; 1867 s32 status, constant, precision, tolerance; 1868 struct timeval32 time; 1869 s32 tick; 1870 s32 ppsfreq, jitter, shift, stabil; 1871 s32 jitcnt, calcnt, errcnt, stbcnt; 1872 s32 :32; s32 :32; s32 :32; s32 :32; 1873 s32 :32; s32 :32; s32 :32; s32 :32; 1874 s32 :32; s32 :32; s32 :32; s32 :32; 1875}; 1876 1877extern int do_adjtimex(struct timex *); 1878 1879asmlinkage long 1880sys32_adjtimex(struct timex32 *utp) 1881{ 1882 struct timex txc; 1883 int ret; 1884 1885 memset(&txc, 0, sizeof(struct timex)); 1886 1887 if(verify_area(VERIFY_READ, utp, sizeof(struct timex32)) || 1888 __get_user(txc.modes, &utp->modes) || 1889 __get_user(txc.offset, &utp->offset) || 1890 __get_user(txc.freq, &utp->freq) || 1891 __get_user(txc.maxerror, &utp->maxerror) || 1892 __get_user(txc.esterror, &utp->esterror) || 1893 __get_user(txc.status, &utp->status) || 1894 __get_user(txc.constant, &utp->constant) || 1895 __get_user(txc.precision, &utp->precision) || 1896 __get_user(txc.tolerance, &utp->tolerance) || 1897 __get_user(txc.time.tv_sec, &utp->time.tv_sec) || 1898 __get_user(txc.time.tv_usec, &utp->time.tv_usec) || 1899 __get_user(txc.tick, &utp->tick) || 1900 __get_user(txc.ppsfreq, &utp->ppsfreq) || 1901 __get_user(txc.jitter, &utp->jitter) || 1902 __get_user(txc.shift, &utp->shift) || 1903 __get_user(txc.stabil, &utp->stabil) || 1904 __get_user(txc.jitcnt, &utp->jitcnt) || 1905 __get_user(txc.calcnt, &utp->calcnt) || 1906 __get_user(txc.errcnt, &utp->errcnt) || 1907 __get_user(txc.stbcnt, &utp->stbcnt)) 1908 return -EFAULT; 1909 1910 ret = do_adjtimex(&txc); 1911 1912 if(verify_area(VERIFY_WRITE, utp, sizeof(struct timex32)) || 1913 __put_user(txc.modes, &utp->modes) || 1914 __put_user(txc.offset, &utp->offset) || 1915 __put_user(txc.freq, &utp->freq) || 1916 __put_user(txc.maxerror, &utp->maxerror) || 1917 __put_user(txc.esterror, &utp->esterror) || 1918 __put_user(txc.status, &utp->status) || 1919 __put_user(txc.constant, &utp->constant) || 1920 __put_user(txc.precision, &utp->precision) || 1921 __put_user(txc.tolerance, &utp->tolerance) || 1922 __put_user(txc.time.tv_sec, &utp->time.tv_sec) || 1923 __put_user(txc.time.tv_usec, &utp->time.tv_usec) || 1924 __put_user(txc.tick, &utp->tick) || 1925 __put_user(txc.ppsfreq, &utp->ppsfreq) || 1926 __put_user(txc.jitter, &utp->jitter) || 1927 __put_user(txc.shift, &utp->shift) || 1928 __put_user(txc.stabil, &utp->stabil) || 1929 __put_user(txc.jitcnt, &utp->jitcnt) || 1930 __put_user(txc.calcnt, &utp->calcnt) || 1931 __put_user(txc.errcnt, &utp->errcnt) || 1932 __put_user(txc.stbcnt, &utp->stbcnt)) 1933 ret = -EFAULT; 1934 1935 return ret; 1936} 1937 1938 1939/* common code for old and new mmaps */ 1940static inline long do_mmap2( 1941 unsigned long addr, unsigned long len, 1942 unsigned long prot, unsigned long flags, 1943 unsigned long fd, unsigned long pgoff) 1944{ 1945 int error = -EBADF; 1946 struct file * file = NULL; 1947 1948 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 1949 if (!(flags & MAP_ANONYMOUS)) { 1950 file = fget(fd); 1951 if (!file) 1952 goto out; 1953 } 1954 1955 down_write(¤t->mm->mmap_sem); 1956 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); 1957 up_write(¤t->mm->mmap_sem); 1958 1959 if (file) 1960 fput(file); 1961out: 1962 return error; 1963} 1964 1965asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, 1966 unsigned long prot, unsigned long flags, 1967 unsigned long fd, unsigned long pgoff) 1968{ 1969 return do_mmap2(addr, len, prot, flags, fd, pgoff); 1970} 1971 1972 1973asmlinkage long sys32_olduname(struct oldold_utsname * name) 1974{ 1975 int error; 1976 1977 if (!name) 1978 return -EFAULT; 1979 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) 1980 return -EFAULT; 1981 1982 down_read(&uts_sem); 1983 1984 error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); 1985 __put_user(0,name->sysname+__OLD_UTS_LEN); 1986 __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); 1987 __put_user(0,name->nodename+__OLD_UTS_LEN); 1988 __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); 1989 __put_user(0,name->release+__OLD_UTS_LEN); 1990 __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); 1991 __put_user(0,name->version+__OLD_UTS_LEN); 1992 { 1993 char *arch = (personality(current->personality) == PER_LINUX32) 1994 ? "i686" : "x86_64"; 1995 1996 __copy_to_user(&name->machine,arch,strlen(arch)+1); 1997 } 1998 1999 up_read(&uts_sem); 2000 2001 error = error ? -EFAULT : 0; 2002 2003 return error; 2004} 2005 2006asmlinkage long sys32_uname(struct old_utsname * name) 2007{ 2008 int err; 2009 down_read(&uts_sem); 2010 err=copy_to_user(name, &system_utsname, sizeof (*name)); 2011 up_read(&uts_sem); 2012 if (personality(current->personality) == PER_LINUX32) 2013 err = copy_to_user(name->machine, "i686", 5); 2014 return err?-EFAULT:0; 2015} 2016 2017extern int sys_ustat(dev_t, struct ustat *); 2018 2019int sys32_ustat(dev_t dev, struct ustat32 *u32p) 2020{ 2021 struct ustat u; 2022 mm_segment_t seg; 2023 int ret; 2024 2025 seg = get_fs(); 2026 set_fs(KERNEL_DS); 2027 ret = sys_ustat(dev,&u); 2028 set_fs(seg); 2029 if (ret >= 0) { 2030 if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || 2031 __put_user((__u32) u.f_tfree, &u32p->f_tfree) || 2032 __put_user((__u32) u.f_tinode, &u32p->f_tfree) || 2033 __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) || 2034 __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack))) 2035 ret = -EFAULT; 2036 } 2037 return ret; 2038} 2039 2040static int nargs(u32 src, char **dst) 2041{ 2042 int cnt; 2043 u32 val; 2044 2045 cnt = 0; 2046 do { 2047 int ret = get_user(val, (__u32 *)(u64)src); 2048 if (ret) 2049 return ret; 2050 if (dst) 2051 dst[cnt] = (char *)(u64)val; 2052 cnt++; 2053 src += 4; 2054 if (cnt >= (MAX_ARG_PAGES*PAGE_SIZE)/sizeof(void*)) 2055 return -E2BIG; 2056 } while(val); 2057 if (dst) 2058 dst[cnt-1] = 0; 2059 return cnt; 2060} 2061 2062int sys32_execve(char *name, u32 argv, u32 envp, struct pt_regs regs) 2063{ 2064 mm_segment_t oldseg; 2065 char **buf; 2066 int na,ne; 2067 int ret; 2068 unsigned sz; 2069 2070 na = nargs(argv, NULL); 2071 if (na < 0) 2072 return -EFAULT; 2073 ne = nargs(envp, NULL); 2074 if (ne < 0) 2075 return -EFAULT; 2076 2077 sz = (na+ne)*sizeof(void *); 2078 if (sz > PAGE_SIZE) 2079 buf = vmalloc(sz); 2080 else 2081 buf = kmalloc(sz, GFP_KERNEL); 2082 if (!buf) 2083 return -ENOMEM; 2084 2085 ret = nargs(argv, buf); 2086 if (ret < 0) 2087 goto free; 2088 2089 ret = nargs(envp, buf + na); 2090 if (ret < 0) 2091 goto free; 2092 2093 name = getname(name); 2094 ret = PTR_ERR(name); 2095 if (IS_ERR(name)) 2096 goto free; 2097 2098 oldseg = get_fs(); 2099 set_fs(KERNEL_DS); 2100 ret = do_execve(name, buf, buf+na, ®s); 2101 set_fs(oldseg); 2102 2103 if (ret == 0) 2104 current->ptrace &= ~PT_DTRACE; 2105 2106 putname(name); 2107 2108free: 2109 if (sz > PAGE_SIZE) 2110 vfree(buf); 2111 else 2112 kfree(buf); 2113 return ret; 2114} 2115 2116asmlinkage int sys32_fork(struct pt_regs regs) 2117{ 2118 return do_fork(SIGCHLD, regs.rsp, ®s, 0); 2119} 2120 2121asmlinkage int sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs) 2122{ 2123 if (!newsp) 2124 newsp = regs.rsp; 2125 return do_fork(clone_flags, newsp, ®s, 0); 2126} 2127 2128/* 2129 * This is trivial, and on the face of it looks like it 2130 * could equally well be done in user mode. 2131 * 2132 * Not so, for quite unobvious reasons - register pressure. 2133 * In user mode vfork() cannot have a stack frame, and if 2134 * done by calling the "clone()" system call directly, you 2135 * do not have enough call-clobbered registers to hold all 2136 * the information you need. 2137 */ 2138asmlinkage int sys32_vfork(struct pt_regs regs) 2139{ 2140 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, ®s, 0); 2141} 2142 2143/* 2144 * Some system calls that need sign extended arguments. This could be done by a generic wrapper. 2145 */ 2146 2147extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin); 2148 2149int sys32_lseek (unsigned int fd, int offset, unsigned int whence) 2150{ 2151 return sys_lseek(fd, offset, whence); 2152} 2153 2154extern int sys_kill(pid_t pid, int sig); 2155 2156int sys32_kill(int pid, int sig) 2157{ 2158 return sys_kill(pid, sig); 2159} 2160 2161 2162#if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE) 2163/* Stuff for NFS server syscalls... */ 2164struct nfsctl_svc32 { 2165 u16 svc32_port; 2166 s32 svc32_nthreads; 2167}; 2168 2169struct nfsctl_client32 { 2170 s8 cl32_ident[NFSCLNT_IDMAX+1]; 2171 s32 cl32_naddr; 2172 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX]; 2173 s32 cl32_fhkeytype; 2174 s32 cl32_fhkeylen; 2175 u8 cl32_fhkey[NFSCLNT_KEYMAX]; 2176}; 2177 2178struct nfsctl_export32 { 2179 s8 ex32_client[NFSCLNT_IDMAX+1]; 2180 s8 ex32_path[NFS_MAXPATHLEN+1]; 2181 __kernel_dev_t32 ex32_dev; 2182 __kernel_ino_t32 ex32_ino; 2183 s32 ex32_flags; 2184 __kernel_uid_t32 ex32_anon_uid; 2185 __kernel_gid_t32 ex32_anon_gid; 2186}; 2187 2188struct nfsctl_uidmap32 { 2189 u32 ug32_ident; /* char * */ 2190 __kernel_uid_t32 ug32_uidbase; 2191 s32 ug32_uidlen; 2192 u32 ug32_udimap; /* uid_t * */ 2193 __kernel_uid_t32 ug32_gidbase; 2194 s32 ug32_gidlen; 2195 u32 ug32_gdimap; /* gid_t * */ 2196}; 2197 2198struct nfsctl_fhparm32 { 2199 struct sockaddr gf32_addr; 2200 __kernel_dev_t32 gf32_dev; 2201 __kernel_ino_t32 gf32_ino; 2202 s32 gf32_version; 2203}; 2204 2205struct nfsctl_fdparm32 { 2206 struct sockaddr gd32_addr; 2207 s8 gd32_path[NFS_MAXPATHLEN+1]; 2208 s32 gd32_version; 2209}; 2210 2211struct nfsctl_fsparm32 { 2212 struct sockaddr gd32_addr; 2213 s8 gd32_path[NFS_MAXPATHLEN+1]; 2214 s32 gd32_maxlen; 2215}; 2216 2217struct nfsctl_arg32 { 2218 s32 ca32_version; /* safeguard */ 2219 union { 2220 struct nfsctl_svc32 u32_svc; 2221 struct nfsctl_client32 u32_client; 2222 struct nfsctl_export32 u32_export; 2223 struct nfsctl_uidmap32 u32_umap; 2224 struct nfsctl_fhparm32 u32_getfh; 2225 struct nfsctl_fdparm32 u32_getfd; 2226 struct nfsctl_fsparm32 u32_getfs; 2227 } u; 2228#define ca32_svc u.u32_svc 2229#define ca32_client u.u32_client 2230#define ca32_export u.u32_export 2231#define ca32_umap u.u32_umap 2232#define ca32_getfh u.u32_getfh 2233#define ca32_getfd u.u32_getfd 2234#define ca32_getfs u.u32_getfs 2235#define ca32_authd u.u32_authd 2236}; 2237 2238union nfsctl_res32 { 2239 __u8 cr32_getfh[NFS_FHSIZE]; 2240 struct knfsd_fh cr32_getfs; 2241}; 2242 2243static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32) 2244{ 2245 int err; 2246 2247 err = get_user(karg->ca_version, &arg32->ca32_version); 2248 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port); 2249 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads); 2250 return err; 2251} 2252 2253static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32) 2254{ 2255 int err; 2256 2257 err = get_user(karg->ca_version, &arg32->ca32_version); 2258 err |= copy_from_user(&karg->ca_client.cl_ident[0], 2259 &arg32->ca32_client.cl32_ident[0], 2260 NFSCLNT_IDMAX); 2261 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr); 2262 err |= copy_from_user(&karg->ca_client.cl_addrlist[0], 2263 &arg32->ca32_client.cl32_addrlist[0], 2264 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX)); 2265 err |= __get_user(karg->ca_client.cl_fhkeytype, 2266 &arg32->ca32_client.cl32_fhkeytype); 2267 err |= __get_user(karg->ca_client.cl_fhkeylen, 2268 &arg32->ca32_client.cl32_fhkeylen); 2269 err |= copy_from_user(&karg->ca_client.cl_fhkey[0], 2270 &arg32->ca32_client.cl32_fhkey[0], 2271 NFSCLNT_KEYMAX); 2272 return err; 2273} 2274 2275static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32) 2276{ 2277 int err; 2278 2279 err = get_user(karg->ca_version, &arg32->ca32_version); 2280 err |= copy_from_user(&karg->ca_export.ex_client[0], 2281 &arg32->ca32_export.ex32_client[0], 2282 NFSCLNT_IDMAX); 2283 err |= copy_from_user(&karg->ca_export.ex_path[0], 2284 &arg32->ca32_export.ex32_path[0], 2285 NFS_MAXPATHLEN); 2286 err |= __get_user(karg->ca_export.ex_dev, 2287 &arg32->ca32_export.ex32_dev); 2288 err |= __get_user(karg->ca_export.ex_ino, 2289 &arg32->ca32_export.ex32_ino); 2290 err |= __get_user(karg->ca_export.ex_flags, 2291 &arg32->ca32_export.ex32_flags); 2292 err |= __get_user(karg->ca_export.ex_anon_uid, 2293 &arg32->ca32_export.ex32_anon_uid); 2294 err |= __get_user(karg->ca_export.ex_anon_gid, 2295 &arg32->ca32_export.ex32_anon_gid); 2296 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid); 2297 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid); 2298 return err; 2299} 2300 2301static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32) 2302{ 2303 u32 uaddr; 2304 int i; 2305 int err; 2306 2307 memset(karg, 0, sizeof(*karg)); 2308 if(get_user(karg->ca_version, &arg32->ca32_version)) 2309 return -EFAULT; 2310 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER); 2311 if(!karg->ca_umap.ug_ident) 2312 return -ENOMEM; 2313 err = get_user(uaddr, &arg32->ca32_umap.ug32_ident); 2314 if(strncpy_from_user(karg->ca_umap.ug_ident, 2315 (char *)A(uaddr), PAGE_SIZE) <= 0) 2316 return -EFAULT; 2317 err |= __get_user(karg->ca_umap.ug_uidbase, 2318 &arg32->ca32_umap.ug32_uidbase); 2319 err |= __get_user(karg->ca_umap.ug_uidlen, 2320 &arg32->ca32_umap.ug32_uidlen); 2321 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap); 2322 if (err) 2323 return -EFAULT; 2324 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen), 2325 GFP_USER); 2326 if(!karg->ca_umap.ug_udimap) 2327 return -ENOMEM; 2328 for(i = 0; i < karg->ca_umap.ug_uidlen; i++) 2329 err |= __get_user(karg->ca_umap.ug_udimap[i], 2330 &(((__kernel_uid_t32 *)A(uaddr))[i])); 2331 err |= __get_user(karg->ca_umap.ug_gidbase, 2332 &arg32->ca32_umap.ug32_gidbase); 2333 err |= __get_user(karg->ca_umap.ug_uidlen, 2334 &arg32->ca32_umap.ug32_gidlen); 2335 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap); 2336 if (err) 2337 return -EFAULT; 2338 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen), 2339 GFP_USER); 2340 if(!karg->ca_umap.ug_gdimap) 2341 return -ENOMEM; 2342 for(i = 0; i < karg->ca_umap.ug_gidlen; i++) 2343 err |= __get_user(karg->ca_umap.ug_gdimap[i], 2344 &(((__kernel_gid_t32 *)A(uaddr))[i])); 2345 2346 return err; 2347} 2348 2349static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32) 2350{ 2351 int err; 2352 2353 err = get_user(karg->ca_version, &arg32->ca32_version); 2354 err |= copy_from_user(&karg->ca_getfh.gf_addr, 2355 &arg32->ca32_getfh.gf32_addr, 2356 (sizeof(struct sockaddr))); 2357 err |= __get_user(karg->ca_getfh.gf_dev, 2358 &arg32->ca32_getfh.gf32_dev); 2359 err |= __get_user(karg->ca_getfh.gf_ino, 2360 &arg32->ca32_getfh.gf32_ino); 2361 err |= __get_user(karg->ca_getfh.gf_version, 2362 &arg32->ca32_getfh.gf32_version); 2363 return err; 2364} 2365 2366static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32) 2367{ 2368 int err; 2369 2370 err = get_user(karg->ca_version, &arg32->ca32_version); 2371 err |= copy_from_user(&karg->ca_getfd.gd_addr, 2372 &arg32->ca32_getfd.gd32_addr, 2373 (sizeof(struct sockaddr))); 2374 err |= copy_from_user(&karg->ca_getfd.gd_path, 2375 &arg32->ca32_getfd.gd32_path, 2376 (NFS_MAXPATHLEN+1)); 2377 err |= get_user(karg->ca_getfd.gd_version, 2378 &arg32->ca32_getfd.gd32_version); 2379 return err; 2380} 2381 2382static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32) 2383{ 2384 int err; 2385 2386 err = get_user(karg->ca_version, &arg32->ca32_version); 2387 err |= copy_from_user(&karg->ca_getfs.gd_addr, 2388 &arg32->ca32_getfs.gd32_addr, 2389 (sizeof(struct sockaddr))); 2390 err |= copy_from_user(&karg->ca_getfs.gd_path, 2391 &arg32->ca32_getfs.gd32_path, 2392 (NFS_MAXPATHLEN+1)); 2393 err |= get_user(karg->ca_getfs.gd_maxlen, 2394 &arg32->ca32_getfs.gd32_maxlen); 2395 return err; 2396} 2397 2398/* This really doesn't need translations, we are only passing 2399 * back a union which contains opaque nfs file handle data. 2400 */ 2401static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32) 2402{ 2403 return copy_to_user(res32, kres, sizeof(*res32)); 2404} 2405 2406int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32) 2407{ 2408 struct nfsctl_arg *karg = NULL; 2409 union nfsctl_res *kres = NULL; 2410 mm_segment_t oldfs; 2411 int err; 2412 2413 karg = kmalloc(sizeof(*karg), GFP_USER); 2414 if(!karg) 2415 return -ENOMEM; 2416 if(res32) { 2417 kres = kmalloc(sizeof(*kres), GFP_USER); 2418 if(!kres) { 2419 kfree(karg); 2420 return -ENOMEM; 2421 } 2422 } 2423 switch(cmd) { 2424 case NFSCTL_SVC: 2425 err = nfs_svc32_trans(karg, arg32); 2426 break; 2427 case NFSCTL_ADDCLIENT: 2428 err = nfs_clnt32_trans(karg, arg32); 2429 break; 2430 case NFSCTL_DELCLIENT: 2431 err = nfs_clnt32_trans(karg, arg32); 2432 break; 2433 case NFSCTL_EXPORT: 2434 case NFSCTL_UNEXPORT: 2435 err = nfs_exp32_trans(karg, arg32); 2436 break; 2437 /* This one is unimplemented, be we're ready for it. */ 2438 case NFSCTL_UGIDUPDATE: 2439 err = nfs_uud32_trans(karg, arg32); 2440 break; 2441 case NFSCTL_GETFH: 2442 err = nfs_getfh32_trans(karg, arg32); 2443 break; 2444 case NFSCTL_GETFD: 2445 err = nfs_getfd32_trans(karg, arg32); 2446 break; 2447 case NFSCTL_GETFS: 2448 err = nfs_getfs32_trans(karg, arg32); 2449 break; 2450 default: 2451 err = -EINVAL; 2452 break; 2453 } 2454 if(err) 2455 goto done; 2456 oldfs = get_fs(); 2457 set_fs(KERNEL_DS); 2458 err = sys_nfsservctl(cmd, karg, kres); 2459 set_fs(oldfs); 2460 2461 if (err) 2462 goto done; 2463 2464 if((cmd == NFSCTL_GETFH) || 2465 (cmd == NFSCTL_GETFD) || 2466 (cmd == NFSCTL_GETFS)) 2467 err = nfs_getfh32_res_trans(kres, res32); 2468 2469done: 2470 if(karg) { 2471 if(cmd == NFSCTL_UGIDUPDATE) { 2472 if(karg->ca_umap.ug_ident) 2473 kfree(karg->ca_umap.ug_ident); 2474 if(karg->ca_umap.ug_udimap) 2475 kfree(karg->ca_umap.ug_udimap); 2476 if(karg->ca_umap.ug_gdimap) 2477 kfree(karg->ca_umap.ug_gdimap); 2478 } 2479 kfree(karg); 2480 } 2481 if(kres) 2482 kfree(kres); 2483 return err; 2484} 2485#else /* !NFSD */ 2486extern asmlinkage long sys_ni_syscall(void); 2487int asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2) 2488{ 2489 return sys_ni_syscall(); 2490} 2491#endif 2492 2493int sys32_module_warning(void) 2494{ 2495 static long warn_time = -(60*HZ); 2496 if (time_before(warn_time + 60*HZ,jiffies) && strcmp(current->comm,"klogd")) { 2497 printk(KERN_INFO "%s: 32bit modutils not supported on 64bit kernel\n", 2498 current->comm); 2499 warn_time = jiffies; 2500 } 2501 return -ENOSYS ; 2502} 2503 2504struct exec_domain ia32_exec_domain = { 2505 name: "linux/x86", 2506 pers_low: PER_LINUX32, 2507 pers_high: PER_LINUX32, 2508}; 2509 2510static int __init ia32_init (void) 2511{ 2512 printk("IA32 emulation $Id: sys_ia32.c,v 1.1.1.1 2008/10/15 03:26:20 james26_jang Exp $\n"); 2513 ia32_exec_domain.signal_map = default_exec_domain.signal_map; 2514 ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; 2515 register_exec_domain(&ia32_exec_domain); 2516 return 0; 2517} 2518 2519__initcall(ia32_init); 2520