Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.9 1771 lines 45 kB view raw
1/* 2 * linux/fs/compat.c 3 * 4 * Kernel compatibililty routines for e.g. 32 bit syscall support 5 * on 64 bit kernels. 6 * 7 * Copyright (C) 2002 Stephen Rothwell, IBM Corporation 8 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) 9 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) 10 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs 11 * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz) 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License version 2 as 15 * published by the Free Software Foundation. 16 */ 17 18#include <linux/stddef.h> 19#include <linux/kernel.h> 20#include <linux/linkage.h> 21#include <linux/compat.h> 22#include <linux/errno.h> 23#include <linux/time.h> 24#include <linux/fs.h> 25#include <linux/fcntl.h> 26#include <linux/namei.h> 27#include <linux/file.h> 28#include <linux/fdtable.h> 29#include <linux/vfs.h> 30#include <linux/ioctl.h> 31#include <linux/init.h> 32#include <linux/ncp_mount.h> 33#include <linux/nfs4_mount.h> 34#include <linux/syscalls.h> 35#include <linux/ctype.h> 36#include <linux/dirent.h> 37#include <linux/fsnotify.h> 38#include <linux/highuid.h> 39#include <linux/personality.h> 40#include <linux/rwsem.h> 41#include <linux/tsacct_kern.h> 42#include <linux/security.h> 43#include <linux/highmem.h> 44#include <linux/signal.h> 45#include <linux/poll.h> 46#include <linux/mm.h> 47#include <linux/eventpoll.h> 48#include <linux/fs_struct.h> 49#include <linux/slab.h> 50#include <linux/pagemap.h> 51 52#include <asm/uaccess.h> 53#include <asm/mmu_context.h> 54#include <asm/ioctls.h> 55#include "internal.h" 56 57int compat_log = 1; 58 59int compat_printk(const char *fmt, ...) 60{ 61 va_list ap; 62 int ret; 63 if (!compat_log) 64 return 0; 65 va_start(ap, fmt); 66 ret = vprintk(fmt, ap); 67 va_end(ap); 68 return ret; 69} 70 71#include "read_write.h" 72 73/* 74 * Not all architectures have sys_utime, so implement this in terms 75 * of sys_utimes. 76 */ 77asmlinkage long compat_sys_utime(const char __user *filename, 78 struct compat_utimbuf __user *t) 79{ 80 struct timespec tv[2]; 81 82 if (t) { 83 if (get_user(tv[0].tv_sec, &t->actime) || 84 get_user(tv[1].tv_sec, &t->modtime)) 85 return -EFAULT; 86 tv[0].tv_nsec = 0; 87 tv[1].tv_nsec = 0; 88 } 89 return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0); 90} 91 92asmlinkage long compat_sys_utimensat(unsigned int dfd, const char __user *filename, struct compat_timespec __user *t, int flags) 93{ 94 struct timespec tv[2]; 95 96 if (t) { 97 if (get_compat_timespec(&tv[0], &t[0]) || 98 get_compat_timespec(&tv[1], &t[1])) 99 return -EFAULT; 100 101 if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) 102 return 0; 103 } 104 return do_utimes(dfd, filename, t ? tv : NULL, flags); 105} 106 107asmlinkage long compat_sys_futimesat(unsigned int dfd, const char __user *filename, struct compat_timeval __user *t) 108{ 109 struct timespec tv[2]; 110 111 if (t) { 112 if (get_user(tv[0].tv_sec, &t[0].tv_sec) || 113 get_user(tv[0].tv_nsec, &t[0].tv_usec) || 114 get_user(tv[1].tv_sec, &t[1].tv_sec) || 115 get_user(tv[1].tv_nsec, &t[1].tv_usec)) 116 return -EFAULT; 117 if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 || 118 tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0) 119 return -EINVAL; 120 tv[0].tv_nsec *= 1000; 121 tv[1].tv_nsec *= 1000; 122 } 123 return do_utimes(dfd, filename, t ? tv : NULL, 0); 124} 125 126asmlinkage long compat_sys_utimes(const char __user *filename, struct compat_timeval __user *t) 127{ 128 return compat_sys_futimesat(AT_FDCWD, filename, t); 129} 130 131static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) 132{ 133 struct compat_stat tmp; 134 135 if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) 136 return -EOVERFLOW; 137 138 memset(&tmp, 0, sizeof(tmp)); 139 tmp.st_dev = old_encode_dev(stat->dev); 140 tmp.st_ino = stat->ino; 141 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) 142 return -EOVERFLOW; 143 tmp.st_mode = stat->mode; 144 tmp.st_nlink = stat->nlink; 145 if (tmp.st_nlink != stat->nlink) 146 return -EOVERFLOW; 147 SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid)); 148 SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid)); 149 tmp.st_rdev = old_encode_dev(stat->rdev); 150 if ((u64) stat->size > MAX_NON_LFS) 151 return -EOVERFLOW; 152 tmp.st_size = stat->size; 153 tmp.st_atime = stat->atime.tv_sec; 154 tmp.st_atime_nsec = stat->atime.tv_nsec; 155 tmp.st_mtime = stat->mtime.tv_sec; 156 tmp.st_mtime_nsec = stat->mtime.tv_nsec; 157 tmp.st_ctime = stat->ctime.tv_sec; 158 tmp.st_ctime_nsec = stat->ctime.tv_nsec; 159 tmp.st_blocks = stat->blocks; 160 tmp.st_blksize = stat->blksize; 161 return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0; 162} 163 164asmlinkage long compat_sys_newstat(const char __user * filename, 165 struct compat_stat __user *statbuf) 166{ 167 struct kstat stat; 168 int error; 169 170 error = vfs_stat(filename, &stat); 171 if (error) 172 return error; 173 return cp_compat_stat(&stat, statbuf); 174} 175 176asmlinkage long compat_sys_newlstat(const char __user * filename, 177 struct compat_stat __user *statbuf) 178{ 179 struct kstat stat; 180 int error; 181 182 error = vfs_lstat(filename, &stat); 183 if (error) 184 return error; 185 return cp_compat_stat(&stat, statbuf); 186} 187 188#ifndef __ARCH_WANT_STAT64 189asmlinkage long compat_sys_newfstatat(unsigned int dfd, 190 const char __user *filename, 191 struct compat_stat __user *statbuf, int flag) 192{ 193 struct kstat stat; 194 int error; 195 196 error = vfs_fstatat(dfd, filename, &stat, flag); 197 if (error) 198 return error; 199 return cp_compat_stat(&stat, statbuf); 200} 201#endif 202 203asmlinkage long compat_sys_newfstat(unsigned int fd, 204 struct compat_stat __user * statbuf) 205{ 206 struct kstat stat; 207 int error = vfs_fstat(fd, &stat); 208 209 if (!error) 210 error = cp_compat_stat(&stat, statbuf); 211 return error; 212} 213 214static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *kbuf) 215{ 216 217 if (sizeof ubuf->f_blocks == 4) { 218 if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail | 219 kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL) 220 return -EOVERFLOW; 221 /* f_files and f_ffree may be -1; it's okay 222 * to stuff that into 32 bits */ 223 if (kbuf->f_files != 0xffffffffffffffffULL 224 && (kbuf->f_files & 0xffffffff00000000ULL)) 225 return -EOVERFLOW; 226 if (kbuf->f_ffree != 0xffffffffffffffffULL 227 && (kbuf->f_ffree & 0xffffffff00000000ULL)) 228 return -EOVERFLOW; 229 } 230 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || 231 __put_user(kbuf->f_type, &ubuf->f_type) || 232 __put_user(kbuf->f_bsize, &ubuf->f_bsize) || 233 __put_user(kbuf->f_blocks, &ubuf->f_blocks) || 234 __put_user(kbuf->f_bfree, &ubuf->f_bfree) || 235 __put_user(kbuf->f_bavail, &ubuf->f_bavail) || 236 __put_user(kbuf->f_files, &ubuf->f_files) || 237 __put_user(kbuf->f_ffree, &ubuf->f_ffree) || 238 __put_user(kbuf->f_namelen, &ubuf->f_namelen) || 239 __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 240 __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || 241 __put_user(kbuf->f_frsize, &ubuf->f_frsize) || 242 __put_user(kbuf->f_flags, &ubuf->f_flags) || 243 __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare))) 244 return -EFAULT; 245 return 0; 246} 247 248/* 249 * The following statfs calls are copies of code from fs/statfs.c and 250 * should be checked against those from time to time 251 */ 252asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_statfs __user *buf) 253{ 254 struct kstatfs tmp; 255 int error = user_statfs(pathname, &tmp); 256 if (!error) 257 error = put_compat_statfs(buf, &tmp); 258 return error; 259} 260 261asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user *buf) 262{ 263 struct kstatfs tmp; 264 int error = fd_statfs(fd, &tmp); 265 if (!error) 266 error = put_compat_statfs(buf, &tmp); 267 return error; 268} 269 270static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf) 271{ 272 if (sizeof ubuf->f_blocks == 4) { 273 if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail | 274 kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL) 275 return -EOVERFLOW; 276 /* f_files and f_ffree may be -1; it's okay 277 * to stuff that into 32 bits */ 278 if (kbuf->f_files != 0xffffffffffffffffULL 279 && (kbuf->f_files & 0xffffffff00000000ULL)) 280 return -EOVERFLOW; 281 if (kbuf->f_ffree != 0xffffffffffffffffULL 282 && (kbuf->f_ffree & 0xffffffff00000000ULL)) 283 return -EOVERFLOW; 284 } 285 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || 286 __put_user(kbuf->f_type, &ubuf->f_type) || 287 __put_user(kbuf->f_bsize, &ubuf->f_bsize) || 288 __put_user(kbuf->f_blocks, &ubuf->f_blocks) || 289 __put_user(kbuf->f_bfree, &ubuf->f_bfree) || 290 __put_user(kbuf->f_bavail, &ubuf->f_bavail) || 291 __put_user(kbuf->f_files, &ubuf->f_files) || 292 __put_user(kbuf->f_ffree, &ubuf->f_ffree) || 293 __put_user(kbuf->f_namelen, &ubuf->f_namelen) || 294 __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 295 __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || 296 __put_user(kbuf->f_frsize, &ubuf->f_frsize) || 297 __put_user(kbuf->f_flags, &ubuf->f_flags) || 298 __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare))) 299 return -EFAULT; 300 return 0; 301} 302 303asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t sz, struct compat_statfs64 __user *buf) 304{ 305 struct kstatfs tmp; 306 int error; 307 308 if (sz != sizeof(*buf)) 309 return -EINVAL; 310 311 error = user_statfs(pathname, &tmp); 312 if (!error) 313 error = put_compat_statfs64(buf, &tmp); 314 return error; 315} 316 317asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct compat_statfs64 __user *buf) 318{ 319 struct kstatfs tmp; 320 int error; 321 322 if (sz != sizeof(*buf)) 323 return -EINVAL; 324 325 error = fd_statfs(fd, &tmp); 326 if (!error) 327 error = put_compat_statfs64(buf, &tmp); 328 return error; 329} 330 331/* 332 * This is a copy of sys_ustat, just dealing with a structure layout. 333 * Given how simple this syscall is that apporach is more maintainable 334 * than the various conversion hacks. 335 */ 336asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u) 337{ 338 struct compat_ustat tmp; 339 struct kstatfs sbuf; 340 int err = vfs_ustat(new_decode_dev(dev), &sbuf); 341 if (err) 342 return err; 343 344 memset(&tmp, 0, sizeof(struct compat_ustat)); 345 tmp.f_tfree = sbuf.f_bfree; 346 tmp.f_tinode = sbuf.f_ffree; 347 if (copy_to_user(u, &tmp, sizeof(struct compat_ustat))) 348 return -EFAULT; 349 return 0; 350} 351 352static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) 353{ 354 if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || 355 __get_user(kfl->l_type, &ufl->l_type) || 356 __get_user(kfl->l_whence, &ufl->l_whence) || 357 __get_user(kfl->l_start, &ufl->l_start) || 358 __get_user(kfl->l_len, &ufl->l_len) || 359 __get_user(kfl->l_pid, &ufl->l_pid)) 360 return -EFAULT; 361 return 0; 362} 363 364static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) 365{ 366 if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) || 367 __put_user(kfl->l_type, &ufl->l_type) || 368 __put_user(kfl->l_whence, &ufl->l_whence) || 369 __put_user(kfl->l_start, &ufl->l_start) || 370 __put_user(kfl->l_len, &ufl->l_len) || 371 __put_user(kfl->l_pid, &ufl->l_pid)) 372 return -EFAULT; 373 return 0; 374} 375 376#ifndef HAVE_ARCH_GET_COMPAT_FLOCK64 377static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) 378{ 379 if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || 380 __get_user(kfl->l_type, &ufl->l_type) || 381 __get_user(kfl->l_whence, &ufl->l_whence) || 382 __get_user(kfl->l_start, &ufl->l_start) || 383 __get_user(kfl->l_len, &ufl->l_len) || 384 __get_user(kfl->l_pid, &ufl->l_pid)) 385 return -EFAULT; 386 return 0; 387} 388#endif 389 390#ifndef HAVE_ARCH_PUT_COMPAT_FLOCK64 391static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) 392{ 393 if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) || 394 __put_user(kfl->l_type, &ufl->l_type) || 395 __put_user(kfl->l_whence, &ufl->l_whence) || 396 __put_user(kfl->l_start, &ufl->l_start) || 397 __put_user(kfl->l_len, &ufl->l_len) || 398 __put_user(kfl->l_pid, &ufl->l_pid)) 399 return -EFAULT; 400 return 0; 401} 402#endif 403 404asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, 405 unsigned long arg) 406{ 407 mm_segment_t old_fs; 408 struct flock f; 409 long ret; 410 411 switch (cmd) { 412 case F_GETLK: 413 case F_SETLK: 414 case F_SETLKW: 415 ret = get_compat_flock(&f, compat_ptr(arg)); 416 if (ret != 0) 417 break; 418 old_fs = get_fs(); 419 set_fs(KERNEL_DS); 420 ret = sys_fcntl(fd, cmd, (unsigned long)&f); 421 set_fs(old_fs); 422 if (cmd == F_GETLK && ret == 0) { 423 /* GETLK was successful and we need to return the data... 424 * but it needs to fit in the compat structure. 425 * l_start shouldn't be too big, unless the original 426 * start + end is greater than COMPAT_OFF_T_MAX, in which 427 * case the app was asking for trouble, so we return 428 * -EOVERFLOW in that case. 429 * l_len could be too big, in which case we just truncate it, 430 * and only allow the app to see that part of the conflicting 431 * lock that might make sense to it anyway 432 */ 433 434 if (f.l_start > COMPAT_OFF_T_MAX) 435 ret = -EOVERFLOW; 436 if (f.l_len > COMPAT_OFF_T_MAX) 437 f.l_len = COMPAT_OFF_T_MAX; 438 if (ret == 0) 439 ret = put_compat_flock(&f, compat_ptr(arg)); 440 } 441 break; 442 443 case F_GETLK64: 444 case F_SETLK64: 445 case F_SETLKW64: 446 ret = get_compat_flock64(&f, compat_ptr(arg)); 447 if (ret != 0) 448 break; 449 old_fs = get_fs(); 450 set_fs(KERNEL_DS); 451 ret = sys_fcntl(fd, (cmd == F_GETLK64) ? F_GETLK : 452 ((cmd == F_SETLK64) ? F_SETLK : F_SETLKW), 453 (unsigned long)&f); 454 set_fs(old_fs); 455 if (cmd == F_GETLK64 && ret == 0) { 456 /* need to return lock information - see above for commentary */ 457 if (f.l_start > COMPAT_LOFF_T_MAX) 458 ret = -EOVERFLOW; 459 if (f.l_len > COMPAT_LOFF_T_MAX) 460 f.l_len = COMPAT_LOFF_T_MAX; 461 if (ret == 0) 462 ret = put_compat_flock64(&f, compat_ptr(arg)); 463 } 464 break; 465 466 default: 467 ret = sys_fcntl(fd, cmd, arg); 468 break; 469 } 470 return ret; 471} 472 473asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, 474 unsigned long arg) 475{ 476 if ((cmd == F_GETLK64) || (cmd == F_SETLK64) || (cmd == F_SETLKW64)) 477 return -EINVAL; 478 return compat_sys_fcntl64(fd, cmd, arg); 479} 480 481asmlinkage long 482compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p) 483{ 484 long ret; 485 aio_context_t ctx64; 486 487 mm_segment_t oldfs = get_fs(); 488 if (unlikely(get_user(ctx64, ctx32p))) 489 return -EFAULT; 490 491 set_fs(KERNEL_DS); 492 /* The __user pointer cast is valid because of the set_fs() */ 493 ret = sys_io_setup(nr_reqs, (aio_context_t __user *) &ctx64); 494 set_fs(oldfs); 495 /* truncating is ok because it's a user address */ 496 if (!ret) 497 ret = put_user((u32) ctx64, ctx32p); 498 return ret; 499} 500 501asmlinkage long 502compat_sys_io_getevents(aio_context_t ctx_id, 503 unsigned long min_nr, 504 unsigned long nr, 505 struct io_event __user *events, 506 struct compat_timespec __user *timeout) 507{ 508 long ret; 509 struct timespec t; 510 struct timespec __user *ut = NULL; 511 512 ret = -EFAULT; 513 if (unlikely(!access_ok(VERIFY_WRITE, events, 514 nr * sizeof(struct io_event)))) 515 goto out; 516 if (timeout) { 517 if (get_compat_timespec(&t, timeout)) 518 goto out; 519 520 ut = compat_alloc_user_space(sizeof(*ut)); 521 if (copy_to_user(ut, &t, sizeof(t)) ) 522 goto out; 523 } 524 ret = sys_io_getevents(ctx_id, min_nr, nr, events, ut); 525out: 526 return ret; 527} 528 529/* A write operation does a read from user space and vice versa */ 530#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) 531 532ssize_t compat_rw_copy_check_uvector(int type, 533 const struct compat_iovec __user *uvector, unsigned long nr_segs, 534 unsigned long fast_segs, struct iovec *fast_pointer, 535 struct iovec **ret_pointer) 536{ 537 compat_ssize_t tot_len; 538 struct iovec *iov = *ret_pointer = fast_pointer; 539 ssize_t ret = 0; 540 int seg; 541 542 /* 543 * SuS says "The readv() function *may* fail if the iovcnt argument 544 * was less than or equal to 0, or greater than {IOV_MAX}. Linux has 545 * traditionally returned zero for zero segments, so... 546 */ 547 if (nr_segs == 0) 548 goto out; 549 550 ret = -EINVAL; 551 if (nr_segs > UIO_MAXIOV || nr_segs < 0) 552 goto out; 553 if (nr_segs > fast_segs) { 554 ret = -ENOMEM; 555 iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); 556 if (iov == NULL) 557 goto out; 558 } 559 *ret_pointer = iov; 560 561 ret = -EFAULT; 562 if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector))) 563 goto out; 564 565 /* 566 * Single unix specification: 567 * We should -EINVAL if an element length is not >= 0 and fitting an 568 * ssize_t. 569 * 570 * In Linux, the total length is limited to MAX_RW_COUNT, there is 571 * no overflow possibility. 572 */ 573 tot_len = 0; 574 ret = -EINVAL; 575 for (seg = 0; seg < nr_segs; seg++) { 576 compat_uptr_t buf; 577 compat_ssize_t len; 578 579 if (__get_user(len, &uvector->iov_len) || 580 __get_user(buf, &uvector->iov_base)) { 581 ret = -EFAULT; 582 goto out; 583 } 584 if (len < 0) /* size_t not fitting in compat_ssize_t .. */ 585 goto out; 586 if (type >= 0 && 587 !access_ok(vrfy_dir(type), compat_ptr(buf), len)) { 588 ret = -EFAULT; 589 goto out; 590 } 591 if (len > MAX_RW_COUNT - tot_len) 592 len = MAX_RW_COUNT - tot_len; 593 tot_len += len; 594 iov->iov_base = compat_ptr(buf); 595 iov->iov_len = (compat_size_t) len; 596 uvector++; 597 iov++; 598 } 599 ret = tot_len; 600 601out: 602 return ret; 603} 604 605static inline long 606copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64) 607{ 608 compat_uptr_t uptr; 609 int i; 610 611 for (i = 0; i < nr; ++i) { 612 if (get_user(uptr, ptr32 + i)) 613 return -EFAULT; 614 if (put_user(compat_ptr(uptr), ptr64 + i)) 615 return -EFAULT; 616 } 617 return 0; 618} 619 620#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *)) 621 622asmlinkage long 623compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 __user *iocb) 624{ 625 struct iocb __user * __user *iocb64; 626 long ret; 627 628 if (unlikely(nr < 0)) 629 return -EINVAL; 630 631 if (nr > MAX_AIO_SUBMITS) 632 nr = MAX_AIO_SUBMITS; 633 634 iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64)); 635 ret = copy_iocb(nr, iocb, iocb64); 636 if (!ret) 637 ret = do_io_submit(ctx_id, nr, iocb64, 1); 638 return ret; 639} 640 641struct compat_ncp_mount_data { 642 compat_int_t version; 643 compat_uint_t ncp_fd; 644 __compat_uid_t mounted_uid; 645 compat_pid_t wdog_pid; 646 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; 647 compat_uint_t time_out; 648 compat_uint_t retry_count; 649 compat_uint_t flags; 650 __compat_uid_t uid; 651 __compat_gid_t gid; 652 compat_mode_t file_mode; 653 compat_mode_t dir_mode; 654}; 655 656struct compat_ncp_mount_data_v4 { 657 compat_int_t version; 658 compat_ulong_t flags; 659 compat_ulong_t mounted_uid; 660 compat_long_t wdog_pid; 661 compat_uint_t ncp_fd; 662 compat_uint_t time_out; 663 compat_uint_t retry_count; 664 compat_ulong_t uid; 665 compat_ulong_t gid; 666 compat_ulong_t file_mode; 667 compat_ulong_t dir_mode; 668}; 669 670static void *do_ncp_super_data_conv(void *raw_data) 671{ 672 int version = *(unsigned int *)raw_data; 673 674 if (version == 3) { 675 struct compat_ncp_mount_data *c_n = raw_data; 676 struct ncp_mount_data *n = raw_data; 677 678 n->dir_mode = c_n->dir_mode; 679 n->file_mode = c_n->file_mode; 680 n->gid = c_n->gid; 681 n->uid = c_n->uid; 682 memmove (n->mounted_vol, c_n->mounted_vol, (sizeof (c_n->mounted_vol) + 3 * sizeof (unsigned int))); 683 n->wdog_pid = c_n->wdog_pid; 684 n->mounted_uid = c_n->mounted_uid; 685 } else if (version == 4) { 686 struct compat_ncp_mount_data_v4 *c_n = raw_data; 687 struct ncp_mount_data_v4 *n = raw_data; 688 689 n->dir_mode = c_n->dir_mode; 690 n->file_mode = c_n->file_mode; 691 n->gid = c_n->gid; 692 n->uid = c_n->uid; 693 n->retry_count = c_n->retry_count; 694 n->time_out = c_n->time_out; 695 n->ncp_fd = c_n->ncp_fd; 696 n->wdog_pid = c_n->wdog_pid; 697 n->mounted_uid = c_n->mounted_uid; 698 n->flags = c_n->flags; 699 } else if (version != 5) { 700 return NULL; 701 } 702 703 return raw_data; 704} 705 706 707struct compat_nfs_string { 708 compat_uint_t len; 709 compat_uptr_t data; 710}; 711 712static inline void compat_nfs_string(struct nfs_string *dst, 713 struct compat_nfs_string *src) 714{ 715 dst->data = compat_ptr(src->data); 716 dst->len = src->len; 717} 718 719struct compat_nfs4_mount_data_v1 { 720 compat_int_t version; 721 compat_int_t flags; 722 compat_int_t rsize; 723 compat_int_t wsize; 724 compat_int_t timeo; 725 compat_int_t retrans; 726 compat_int_t acregmin; 727 compat_int_t acregmax; 728 compat_int_t acdirmin; 729 compat_int_t acdirmax; 730 struct compat_nfs_string client_addr; 731 struct compat_nfs_string mnt_path; 732 struct compat_nfs_string hostname; 733 compat_uint_t host_addrlen; 734 compat_uptr_t host_addr; 735 compat_int_t proto; 736 compat_int_t auth_flavourlen; 737 compat_uptr_t auth_flavours; 738}; 739 740static int do_nfs4_super_data_conv(void *raw_data) 741{ 742 int version = *(compat_uint_t *) raw_data; 743 744 if (version == 1) { 745 struct compat_nfs4_mount_data_v1 *raw = raw_data; 746 struct nfs4_mount_data *real = raw_data; 747 748 /* copy the fields backwards */ 749 real->auth_flavours = compat_ptr(raw->auth_flavours); 750 real->auth_flavourlen = raw->auth_flavourlen; 751 real->proto = raw->proto; 752 real->host_addr = compat_ptr(raw->host_addr); 753 real->host_addrlen = raw->host_addrlen; 754 compat_nfs_string(&real->hostname, &raw->hostname); 755 compat_nfs_string(&real->mnt_path, &raw->mnt_path); 756 compat_nfs_string(&real->client_addr, &raw->client_addr); 757 real->acdirmax = raw->acdirmax; 758 real->acdirmin = raw->acdirmin; 759 real->acregmax = raw->acregmax; 760 real->acregmin = raw->acregmin; 761 real->retrans = raw->retrans; 762 real->timeo = raw->timeo; 763 real->wsize = raw->wsize; 764 real->rsize = raw->rsize; 765 real->flags = raw->flags; 766 real->version = raw->version; 767 } 768 769 return 0; 770} 771 772#define NCPFS_NAME "ncpfs" 773#define NFS4_NAME "nfs4" 774 775asmlinkage long compat_sys_mount(const char __user * dev_name, 776 const char __user * dir_name, 777 const char __user * type, unsigned long flags, 778 const void __user * data) 779{ 780 char *kernel_type; 781 unsigned long data_page; 782 char *kernel_dev; 783 struct filename *dir; 784 int retval; 785 786 retval = copy_mount_string(type, &kernel_type); 787 if (retval < 0) 788 goto out; 789 790 dir = getname(dir_name); 791 retval = PTR_ERR(dir); 792 if (IS_ERR(dir)) 793 goto out1; 794 795 retval = copy_mount_string(dev_name, &kernel_dev); 796 if (retval < 0) 797 goto out2; 798 799 retval = copy_mount_options(data, &data_page); 800 if (retval < 0) 801 goto out3; 802 803 retval = -EINVAL; 804 805 if (kernel_type && data_page) { 806 if (!strcmp(kernel_type, NCPFS_NAME)) { 807 do_ncp_super_data_conv((void *)data_page); 808 } else if (!strcmp(kernel_type, NFS4_NAME)) { 809 if (do_nfs4_super_data_conv((void *) data_page)) 810 goto out4; 811 } 812 } 813 814 retval = do_mount(kernel_dev, dir->name, kernel_type, 815 flags, (void*)data_page); 816 817 out4: 818 free_page(data_page); 819 out3: 820 kfree(kernel_dev); 821 out2: 822 putname(dir); 823 out1: 824 kfree(kernel_type); 825 out: 826 return retval; 827} 828 829struct compat_old_linux_dirent { 830 compat_ulong_t d_ino; 831 compat_ulong_t d_offset; 832 unsigned short d_namlen; 833 char d_name[1]; 834}; 835 836struct compat_readdir_callback { 837 struct compat_old_linux_dirent __user *dirent; 838 int result; 839}; 840 841static int compat_fillonedir(void *__buf, const char *name, int namlen, 842 loff_t offset, u64 ino, unsigned int d_type) 843{ 844 struct compat_readdir_callback *buf = __buf; 845 struct compat_old_linux_dirent __user *dirent; 846 compat_ulong_t d_ino; 847 848 if (buf->result) 849 return -EINVAL; 850 d_ino = ino; 851 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 852 buf->result = -EOVERFLOW; 853 return -EOVERFLOW; 854 } 855 buf->result++; 856 dirent = buf->dirent; 857 if (!access_ok(VERIFY_WRITE, dirent, 858 (unsigned long)(dirent->d_name + namlen + 1) - 859 (unsigned long)dirent)) 860 goto efault; 861 if ( __put_user(d_ino, &dirent->d_ino) || 862 __put_user(offset, &dirent->d_offset) || 863 __put_user(namlen, &dirent->d_namlen) || 864 __copy_to_user(dirent->d_name, name, namlen) || 865 __put_user(0, dirent->d_name + namlen)) 866 goto efault; 867 return 0; 868efault: 869 buf->result = -EFAULT; 870 return -EFAULT; 871} 872 873asmlinkage long compat_sys_old_readdir(unsigned int fd, 874 struct compat_old_linux_dirent __user *dirent, unsigned int count) 875{ 876 int error; 877 struct fd f = fdget(fd); 878 struct compat_readdir_callback buf; 879 880 if (!f.file) 881 return -EBADF; 882 883 buf.result = 0; 884 buf.dirent = dirent; 885 886 error = vfs_readdir(f.file, compat_fillonedir, &buf); 887 if (buf.result) 888 error = buf.result; 889 890 fdput(f); 891 return error; 892} 893 894struct compat_linux_dirent { 895 compat_ulong_t d_ino; 896 compat_ulong_t d_off; 897 unsigned short d_reclen; 898 char d_name[1]; 899}; 900 901struct compat_getdents_callback { 902 struct compat_linux_dirent __user *current_dir; 903 struct compat_linux_dirent __user *previous; 904 int count; 905 int error; 906}; 907 908static int compat_filldir(void *__buf, const char *name, int namlen, 909 loff_t offset, u64 ino, unsigned int d_type) 910{ 911 struct compat_linux_dirent __user * dirent; 912 struct compat_getdents_callback *buf = __buf; 913 compat_ulong_t d_ino; 914 int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) + 915 namlen + 2, sizeof(compat_long_t)); 916 917 buf->error = -EINVAL; /* only used if we fail.. */ 918 if (reclen > buf->count) 919 return -EINVAL; 920 d_ino = ino; 921 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 922 buf->error = -EOVERFLOW; 923 return -EOVERFLOW; 924 } 925 dirent = buf->previous; 926 if (dirent) { 927 if (__put_user(offset, &dirent->d_off)) 928 goto efault; 929 } 930 dirent = buf->current_dir; 931 if (__put_user(d_ino, &dirent->d_ino)) 932 goto efault; 933 if (__put_user(reclen, &dirent->d_reclen)) 934 goto efault; 935 if (copy_to_user(dirent->d_name, name, namlen)) 936 goto efault; 937 if (__put_user(0, dirent->d_name + namlen)) 938 goto efault; 939 if (__put_user(d_type, (char __user *) dirent + reclen - 1)) 940 goto efault; 941 buf->previous = dirent; 942 dirent = (void __user *)dirent + reclen; 943 buf->current_dir = dirent; 944 buf->count -= reclen; 945 return 0; 946efault: 947 buf->error = -EFAULT; 948 return -EFAULT; 949} 950 951asmlinkage long compat_sys_getdents(unsigned int fd, 952 struct compat_linux_dirent __user *dirent, unsigned int count) 953{ 954 struct fd f; 955 struct compat_linux_dirent __user * lastdirent; 956 struct compat_getdents_callback buf; 957 int error; 958 959 if (!access_ok(VERIFY_WRITE, dirent, count)) 960 return -EFAULT; 961 962 f = fdget(fd); 963 if (!f.file) 964 return -EBADF; 965 966 buf.current_dir = dirent; 967 buf.previous = NULL; 968 buf.count = count; 969 buf.error = 0; 970 971 error = vfs_readdir(f.file, compat_filldir, &buf); 972 if (error >= 0) 973 error = buf.error; 974 lastdirent = buf.previous; 975 if (lastdirent) { 976 if (put_user(f.file->f_pos, &lastdirent->d_off)) 977 error = -EFAULT; 978 else 979 error = count - buf.count; 980 } 981 fdput(f); 982 return error; 983} 984 985#ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64 986 987struct compat_getdents_callback64 { 988 struct linux_dirent64 __user *current_dir; 989 struct linux_dirent64 __user *previous; 990 int count; 991 int error; 992}; 993 994static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset, 995 u64 ino, unsigned int d_type) 996{ 997 struct linux_dirent64 __user *dirent; 998 struct compat_getdents_callback64 *buf = __buf; 999 int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1, 1000 sizeof(u64)); 1001 u64 off; 1002 1003 buf->error = -EINVAL; /* only used if we fail.. */ 1004 if (reclen > buf->count) 1005 return -EINVAL; 1006 dirent = buf->previous; 1007 1008 if (dirent) { 1009 if (__put_user_unaligned(offset, &dirent->d_off)) 1010 goto efault; 1011 } 1012 dirent = buf->current_dir; 1013 if (__put_user_unaligned(ino, &dirent->d_ino)) 1014 goto efault; 1015 off = 0; 1016 if (__put_user_unaligned(off, &dirent->d_off)) 1017 goto efault; 1018 if (__put_user(reclen, &dirent->d_reclen)) 1019 goto efault; 1020 if (__put_user(d_type, &dirent->d_type)) 1021 goto efault; 1022 if (copy_to_user(dirent->d_name, name, namlen)) 1023 goto efault; 1024 if (__put_user(0, dirent->d_name + namlen)) 1025 goto efault; 1026 buf->previous = dirent; 1027 dirent = (void __user *)dirent + reclen; 1028 buf->current_dir = dirent; 1029 buf->count -= reclen; 1030 return 0; 1031efault: 1032 buf->error = -EFAULT; 1033 return -EFAULT; 1034} 1035 1036asmlinkage long compat_sys_getdents64(unsigned int fd, 1037 struct linux_dirent64 __user * dirent, unsigned int count) 1038{ 1039 struct fd f; 1040 struct linux_dirent64 __user * lastdirent; 1041 struct compat_getdents_callback64 buf; 1042 int error; 1043 1044 if (!access_ok(VERIFY_WRITE, dirent, count)) 1045 return -EFAULT; 1046 1047 f = fdget(fd); 1048 if (!f.file) 1049 return -EBADF; 1050 1051 buf.current_dir = dirent; 1052 buf.previous = NULL; 1053 buf.count = count; 1054 buf.error = 0; 1055 1056 error = vfs_readdir(f.file, compat_filldir64, &buf); 1057 if (error >= 0) 1058 error = buf.error; 1059 lastdirent = buf.previous; 1060 if (lastdirent) { 1061 typeof(lastdirent->d_off) d_off = f.file->f_pos; 1062 if (__put_user_unaligned(d_off, &lastdirent->d_off)) 1063 error = -EFAULT; 1064 else 1065 error = count - buf.count; 1066 } 1067 fdput(f); 1068 return error; 1069} 1070#endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ 1071 1072static ssize_t compat_do_readv_writev(int type, struct file *file, 1073 const struct compat_iovec __user *uvector, 1074 unsigned long nr_segs, loff_t *pos) 1075{ 1076 compat_ssize_t tot_len; 1077 struct iovec iovstack[UIO_FASTIOV]; 1078 struct iovec *iov = iovstack; 1079 ssize_t ret; 1080 io_fn_t fn; 1081 iov_fn_t fnv; 1082 1083 ret = -EINVAL; 1084 if (!file->f_op) 1085 goto out; 1086 1087 ret = compat_rw_copy_check_uvector(type, uvector, nr_segs, 1088 UIO_FASTIOV, iovstack, &iov); 1089 if (ret <= 0) 1090 goto out; 1091 1092 tot_len = ret; 1093 ret = rw_verify_area(type, file, pos, tot_len); 1094 if (ret < 0) 1095 goto out; 1096 1097 fnv = NULL; 1098 if (type == READ) { 1099 fn = file->f_op->read; 1100 fnv = file->f_op->aio_read; 1101 } else { 1102 fn = (io_fn_t)file->f_op->write; 1103 fnv = file->f_op->aio_write; 1104 } 1105 1106 if (fnv) 1107 ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, 1108 pos, fnv); 1109 else 1110 ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); 1111 1112out: 1113 if (iov != iovstack) 1114 kfree(iov); 1115 if ((ret + (type == READ)) > 0) { 1116 if (type == READ) 1117 fsnotify_access(file); 1118 else 1119 fsnotify_modify(file); 1120 } 1121 return ret; 1122} 1123 1124static size_t compat_readv(struct file *file, 1125 const struct compat_iovec __user *vec, 1126 unsigned long vlen, loff_t *pos) 1127{ 1128 ssize_t ret = -EBADF; 1129 1130 if (!(file->f_mode & FMODE_READ)) 1131 goto out; 1132 1133 ret = -EINVAL; 1134 if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) 1135 goto out; 1136 1137 ret = compat_do_readv_writev(READ, file, vec, vlen, pos); 1138 1139out: 1140 if (ret > 0) 1141 add_rchar(current, ret); 1142 inc_syscr(current); 1143 return ret; 1144} 1145 1146asmlinkage ssize_t 1147compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, 1148 unsigned long vlen) 1149{ 1150 struct fd f = fdget(fd); 1151 ssize_t ret; 1152 loff_t pos; 1153 1154 if (!f.file) 1155 return -EBADF; 1156 pos = f.file->f_pos; 1157 ret = compat_readv(f.file, vec, vlen, &pos); 1158 f.file->f_pos = pos; 1159 fdput(f); 1160 return ret; 1161} 1162 1163asmlinkage ssize_t 1164compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec, 1165 unsigned long vlen, loff_t pos) 1166{ 1167 struct fd f; 1168 ssize_t ret; 1169 1170 if (pos < 0) 1171 return -EINVAL; 1172 f = fdget(fd); 1173 if (!f.file) 1174 return -EBADF; 1175 ret = -ESPIPE; 1176 if (f.file->f_mode & FMODE_PREAD) 1177 ret = compat_readv(f.file, vec, vlen, &pos); 1178 fdput(f); 1179 return ret; 1180} 1181 1182asmlinkage ssize_t 1183compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec, 1184 unsigned long vlen, u32 pos_low, u32 pos_high) 1185{ 1186 loff_t pos = ((loff_t)pos_high << 32) | pos_low; 1187 return compat_sys_preadv64(fd, vec, vlen, pos); 1188} 1189 1190static size_t compat_writev(struct file *file, 1191 const struct compat_iovec __user *vec, 1192 unsigned long vlen, loff_t *pos) 1193{ 1194 ssize_t ret = -EBADF; 1195 1196 if (!(file->f_mode & FMODE_WRITE)) 1197 goto out; 1198 1199 ret = -EINVAL; 1200 if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) 1201 goto out; 1202 1203 ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos); 1204 1205out: 1206 if (ret > 0) 1207 add_wchar(current, ret); 1208 inc_syscw(current); 1209 return ret; 1210} 1211 1212asmlinkage ssize_t 1213compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, 1214 unsigned long vlen) 1215{ 1216 struct fd f = fdget(fd); 1217 ssize_t ret; 1218 loff_t pos; 1219 1220 if (!f.file) 1221 return -EBADF; 1222 pos = f.file->f_pos; 1223 ret = compat_writev(f.file, vec, vlen, &pos); 1224 f.file->f_pos = pos; 1225 fdput(f); 1226 return ret; 1227} 1228 1229asmlinkage ssize_t 1230compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec, 1231 unsigned long vlen, loff_t pos) 1232{ 1233 struct fd f; 1234 ssize_t ret; 1235 1236 if (pos < 0) 1237 return -EINVAL; 1238 f = fdget(fd); 1239 if (!f.file) 1240 return -EBADF; 1241 ret = -ESPIPE; 1242 if (f.file->f_mode & FMODE_PWRITE) 1243 ret = compat_writev(f.file, vec, vlen, &pos); 1244 fdput(f); 1245 return ret; 1246} 1247 1248asmlinkage ssize_t 1249compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec, 1250 unsigned long vlen, u32 pos_low, u32 pos_high) 1251{ 1252 loff_t pos = ((loff_t)pos_high << 32) | pos_low; 1253 return compat_sys_pwritev64(fd, vec, vlen, pos); 1254} 1255 1256asmlinkage long 1257compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32, 1258 unsigned int nr_segs, unsigned int flags) 1259{ 1260 unsigned i; 1261 struct iovec __user *iov; 1262 if (nr_segs > UIO_MAXIOV) 1263 return -EINVAL; 1264 iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec)); 1265 for (i = 0; i < nr_segs; i++) { 1266 struct compat_iovec v; 1267 if (get_user(v.iov_base, &iov32[i].iov_base) || 1268 get_user(v.iov_len, &iov32[i].iov_len) || 1269 put_user(compat_ptr(v.iov_base), &iov[i].iov_base) || 1270 put_user(v.iov_len, &iov[i].iov_len)) 1271 return -EFAULT; 1272 } 1273 return sys_vmsplice(fd, iov, nr_segs, flags); 1274} 1275 1276/* 1277 * Exactly like fs/open.c:sys_open(), except that it doesn't set the 1278 * O_LARGEFILE flag. 1279 */ 1280COMPAT_SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode) 1281{ 1282 return do_sys_open(AT_FDCWD, filename, flags, mode); 1283} 1284 1285/* 1286 * Exactly like fs/open.c:sys_openat(), except that it doesn't set the 1287 * O_LARGEFILE flag. 1288 */ 1289COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode) 1290{ 1291 return do_sys_open(dfd, filename, flags, mode); 1292} 1293 1294#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) 1295 1296static int poll_select_copy_remaining(struct timespec *end_time, void __user *p, 1297 int timeval, int ret) 1298{ 1299 struct timespec ts; 1300 1301 if (!p) 1302 return ret; 1303 1304 if (current->personality & STICKY_TIMEOUTS) 1305 goto sticky; 1306 1307 /* No update for zero timeout */ 1308 if (!end_time->tv_sec && !end_time->tv_nsec) 1309 return ret; 1310 1311 ktime_get_ts(&ts); 1312 ts = timespec_sub(*end_time, ts); 1313 if (ts.tv_sec < 0) 1314 ts.tv_sec = ts.tv_nsec = 0; 1315 1316 if (timeval) { 1317 struct compat_timeval rtv; 1318 1319 rtv.tv_sec = ts.tv_sec; 1320 rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC; 1321 1322 if (!copy_to_user(p, &rtv, sizeof(rtv))) 1323 return ret; 1324 } else { 1325 struct compat_timespec rts; 1326 1327 rts.tv_sec = ts.tv_sec; 1328 rts.tv_nsec = ts.tv_nsec; 1329 1330 if (!copy_to_user(p, &rts, sizeof(rts))) 1331 return ret; 1332 } 1333 /* 1334 * If an application puts its timeval in read-only memory, we 1335 * don't want the Linux-specific update to the timeval to 1336 * cause a fault after the select has completed 1337 * successfully. However, because we're not updating the 1338 * timeval, we can't restart the system call. 1339 */ 1340 1341sticky: 1342 if (ret == -ERESTARTNOHAND) 1343 ret = -EINTR; 1344 return ret; 1345} 1346 1347/* 1348 * Ooo, nasty. We need here to frob 32-bit unsigned longs to 1349 * 64-bit unsigned longs. 1350 */ 1351static 1352int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1353 unsigned long *fdset) 1354{ 1355 nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); 1356 if (ufdset) { 1357 unsigned long odd; 1358 1359 if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t))) 1360 return -EFAULT; 1361 1362 odd = nr & 1UL; 1363 nr &= ~1UL; 1364 while (nr) { 1365 unsigned long h, l; 1366 if (__get_user(l, ufdset) || __get_user(h, ufdset+1)) 1367 return -EFAULT; 1368 ufdset += 2; 1369 *fdset++ = h << 32 | l; 1370 nr -= 2; 1371 } 1372 if (odd && __get_user(*fdset, ufdset)) 1373 return -EFAULT; 1374 } else { 1375 /* Tricky, must clear full unsigned long in the 1376 * kernel fdset at the end, this makes sure that 1377 * actually happens. 1378 */ 1379 memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t)); 1380 } 1381 return 0; 1382} 1383 1384static 1385int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1386 unsigned long *fdset) 1387{ 1388 unsigned long odd; 1389 nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); 1390 1391 if (!ufdset) 1392 return 0; 1393 1394 odd = nr & 1UL; 1395 nr &= ~1UL; 1396 while (nr) { 1397 unsigned long h, l; 1398 l = *fdset++; 1399 h = l >> 32; 1400 if (__put_user(l, ufdset) || __put_user(h, ufdset+1)) 1401 return -EFAULT; 1402 ufdset += 2; 1403 nr -= 2; 1404 } 1405 if (odd && __put_user(*fdset, ufdset)) 1406 return -EFAULT; 1407 return 0; 1408} 1409 1410 1411/* 1412 * This is a virtual copy of sys_select from fs/select.c and probably 1413 * should be compared to it from time to time 1414 */ 1415 1416/* 1417 * We can actually return ERESTARTSYS instead of EINTR, but I'd 1418 * like to be certain this leads to no problems. So I return 1419 * EINTR just for safety. 1420 * 1421 * Update: ERESTARTSYS breaks at least the xview clock binary, so 1422 * I'm trying ERESTARTNOHAND which restart only when you want to. 1423 */ 1424int compat_core_sys_select(int n, compat_ulong_t __user *inp, 1425 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1426 struct timespec *end_time) 1427{ 1428 fd_set_bits fds; 1429 void *bits; 1430 int size, max_fds, ret = -EINVAL; 1431 struct fdtable *fdt; 1432 long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; 1433 1434 if (n < 0) 1435 goto out_nofds; 1436 1437 /* max_fds can increase, so grab it once to avoid race */ 1438 rcu_read_lock(); 1439 fdt = files_fdtable(current->files); 1440 max_fds = fdt->max_fds; 1441 rcu_read_unlock(); 1442 if (n > max_fds) 1443 n = max_fds; 1444 1445 /* 1446 * We need 6 bitmaps (in/out/ex for both incoming and outgoing), 1447 * since we used fdset we need to allocate memory in units of 1448 * long-words. 1449 */ 1450 size = FDS_BYTES(n); 1451 bits = stack_fds; 1452 if (size > sizeof(stack_fds) / 6) { 1453 bits = kmalloc(6 * size, GFP_KERNEL); 1454 ret = -ENOMEM; 1455 if (!bits) 1456 goto out_nofds; 1457 } 1458 fds.in = (unsigned long *) bits; 1459 fds.out = (unsigned long *) (bits + size); 1460 fds.ex = (unsigned long *) (bits + 2*size); 1461 fds.res_in = (unsigned long *) (bits + 3*size); 1462 fds.res_out = (unsigned long *) (bits + 4*size); 1463 fds.res_ex = (unsigned long *) (bits + 5*size); 1464 1465 if ((ret = compat_get_fd_set(n, inp, fds.in)) || 1466 (ret = compat_get_fd_set(n, outp, fds.out)) || 1467 (ret = compat_get_fd_set(n, exp, fds.ex))) 1468 goto out; 1469 zero_fd_set(n, fds.res_in); 1470 zero_fd_set(n, fds.res_out); 1471 zero_fd_set(n, fds.res_ex); 1472 1473 ret = do_select(n, &fds, end_time); 1474 1475 if (ret < 0) 1476 goto out; 1477 if (!ret) { 1478 ret = -ERESTARTNOHAND; 1479 if (signal_pending(current)) 1480 goto out; 1481 ret = 0; 1482 } 1483 1484 if (compat_set_fd_set(n, inp, fds.res_in) || 1485 compat_set_fd_set(n, outp, fds.res_out) || 1486 compat_set_fd_set(n, exp, fds.res_ex)) 1487 ret = -EFAULT; 1488out: 1489 if (bits != stack_fds) 1490 kfree(bits); 1491out_nofds: 1492 return ret; 1493} 1494 1495asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, 1496 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1497 struct compat_timeval __user *tvp) 1498{ 1499 struct timespec end_time, *to = NULL; 1500 struct compat_timeval tv; 1501 int ret; 1502 1503 if (tvp) { 1504 if (copy_from_user(&tv, tvp, sizeof(tv))) 1505 return -EFAULT; 1506 1507 to = &end_time; 1508 if (poll_select_set_timeout(to, 1509 tv.tv_sec + (tv.tv_usec / USEC_PER_SEC), 1510 (tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC)) 1511 return -EINVAL; 1512 } 1513 1514 ret = compat_core_sys_select(n, inp, outp, exp, to); 1515 ret = poll_select_copy_remaining(&end_time, tvp, 1, ret); 1516 1517 return ret; 1518} 1519 1520struct compat_sel_arg_struct { 1521 compat_ulong_t n; 1522 compat_uptr_t inp; 1523 compat_uptr_t outp; 1524 compat_uptr_t exp; 1525 compat_uptr_t tvp; 1526}; 1527 1528asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg) 1529{ 1530 struct compat_sel_arg_struct a; 1531 1532 if (copy_from_user(&a, arg, sizeof(a))) 1533 return -EFAULT; 1534 return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp), 1535 compat_ptr(a.exp), compat_ptr(a.tvp)); 1536} 1537 1538static long do_compat_pselect(int n, compat_ulong_t __user *inp, 1539 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1540 struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, 1541 compat_size_t sigsetsize) 1542{ 1543 compat_sigset_t ss32; 1544 sigset_t ksigmask, sigsaved; 1545 struct compat_timespec ts; 1546 struct timespec end_time, *to = NULL; 1547 int ret; 1548 1549 if (tsp) { 1550 if (copy_from_user(&ts, tsp, sizeof(ts))) 1551 return -EFAULT; 1552 1553 to = &end_time; 1554 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) 1555 return -EINVAL; 1556 } 1557 1558 if (sigmask) { 1559 if (sigsetsize != sizeof(compat_sigset_t)) 1560 return -EINVAL; 1561 if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1562 return -EFAULT; 1563 sigset_from_compat(&ksigmask, &ss32); 1564 1565 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1566 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1567 } 1568 1569 ret = compat_core_sys_select(n, inp, outp, exp, to); 1570 ret = poll_select_copy_remaining(&end_time, tsp, 0, ret); 1571 1572 if (ret == -ERESTARTNOHAND) { 1573 /* 1574 * Don't restore the signal mask yet. Let do_signal() deliver 1575 * the signal on the way back to userspace, before the signal 1576 * mask is restored. 1577 */ 1578 if (sigmask) { 1579 memcpy(&current->saved_sigmask, &sigsaved, 1580 sizeof(sigsaved)); 1581 set_restore_sigmask(); 1582 } 1583 } else if (sigmask) 1584 sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1585 1586 return ret; 1587} 1588 1589asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp, 1590 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1591 struct compat_timespec __user *tsp, void __user *sig) 1592{ 1593 compat_size_t sigsetsize = 0; 1594 compat_uptr_t up = 0; 1595 1596 if (sig) { 1597 if (!access_ok(VERIFY_READ, sig, 1598 sizeof(compat_uptr_t)+sizeof(compat_size_t)) || 1599 __get_user(up, (compat_uptr_t __user *)sig) || 1600 __get_user(sigsetsize, 1601 (compat_size_t __user *)(sig+sizeof(up)))) 1602 return -EFAULT; 1603 } 1604 return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up), 1605 sigsetsize); 1606} 1607 1608asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, 1609 unsigned int nfds, struct compat_timespec __user *tsp, 1610 const compat_sigset_t __user *sigmask, compat_size_t sigsetsize) 1611{ 1612 compat_sigset_t ss32; 1613 sigset_t ksigmask, sigsaved; 1614 struct compat_timespec ts; 1615 struct timespec end_time, *to = NULL; 1616 int ret; 1617 1618 if (tsp) { 1619 if (copy_from_user(&ts, tsp, sizeof(ts))) 1620 return -EFAULT; 1621 1622 to = &end_time; 1623 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) 1624 return -EINVAL; 1625 } 1626 1627 if (sigmask) { 1628 if (sigsetsize != sizeof(compat_sigset_t)) 1629 return -EINVAL; 1630 if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1631 return -EFAULT; 1632 sigset_from_compat(&ksigmask, &ss32); 1633 1634 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1635 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1636 } 1637 1638 ret = do_sys_poll(ufds, nfds, to); 1639 1640 /* We can restart this syscall, usually */ 1641 if (ret == -EINTR) { 1642 /* 1643 * Don't restore the signal mask yet. Let do_signal() deliver 1644 * the signal on the way back to userspace, before the signal 1645 * mask is restored. 1646 */ 1647 if (sigmask) { 1648 memcpy(&current->saved_sigmask, &sigsaved, 1649 sizeof(sigsaved)); 1650 set_restore_sigmask(); 1651 } 1652 ret = -ERESTARTNOHAND; 1653 } else if (sigmask) 1654 sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1655 1656 ret = poll_select_copy_remaining(&end_time, tsp, 0, ret); 1657 1658 return ret; 1659} 1660 1661#ifdef CONFIG_EPOLL 1662 1663asmlinkage long compat_sys_epoll_pwait(int epfd, 1664 struct compat_epoll_event __user *events, 1665 int maxevents, int timeout, 1666 const compat_sigset_t __user *sigmask, 1667 compat_size_t sigsetsize) 1668{ 1669 long err; 1670 compat_sigset_t csigmask; 1671 sigset_t ksigmask, sigsaved; 1672 1673 /* 1674 * If the caller wants a certain signal mask to be set during the wait, 1675 * we apply it here. 1676 */ 1677 if (sigmask) { 1678 if (sigsetsize != sizeof(compat_sigset_t)) 1679 return -EINVAL; 1680 if (copy_from_user(&csigmask, sigmask, sizeof(csigmask))) 1681 return -EFAULT; 1682 sigset_from_compat(&ksigmask, &csigmask); 1683 sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); 1684 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1685 } 1686 1687 err = sys_epoll_wait(epfd, events, maxevents, timeout); 1688 1689 /* 1690 * If we changed the signal mask, we need to restore the original one. 1691 * In case we've got a signal while waiting, we do not restore the 1692 * signal mask yet, and we allow do_signal() to deliver the signal on 1693 * the way back to userspace, before the signal mask is restored. 1694 */ 1695 if (sigmask) { 1696 if (err == -EINTR) { 1697 memcpy(&current->saved_sigmask, &sigsaved, 1698 sizeof(sigsaved)); 1699 set_restore_sigmask(); 1700 } else 1701 sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1702 } 1703 1704 return err; 1705} 1706 1707#endif /* CONFIG_EPOLL */ 1708 1709#ifdef CONFIG_SIGNALFD 1710 1711asmlinkage long compat_sys_signalfd4(int ufd, 1712 const compat_sigset_t __user *sigmask, 1713 compat_size_t sigsetsize, int flags) 1714{ 1715 compat_sigset_t ss32; 1716 sigset_t tmp; 1717 sigset_t __user *ksigmask; 1718 1719 if (sigsetsize != sizeof(compat_sigset_t)) 1720 return -EINVAL; 1721 if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1722 return -EFAULT; 1723 sigset_from_compat(&tmp, &ss32); 1724 ksigmask = compat_alloc_user_space(sizeof(sigset_t)); 1725 if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t))) 1726 return -EFAULT; 1727 1728 return sys_signalfd4(ufd, ksigmask, sizeof(sigset_t), flags); 1729} 1730 1731asmlinkage long compat_sys_signalfd(int ufd, 1732 const compat_sigset_t __user *sigmask, 1733 compat_size_t sigsetsize) 1734{ 1735 return compat_sys_signalfd4(ufd, sigmask, sigsetsize, 0); 1736} 1737#endif /* CONFIG_SIGNALFD */ 1738 1739#ifdef CONFIG_FHANDLE 1740/* 1741 * Exactly like fs/open.c:sys_open_by_handle_at(), except that it 1742 * doesn't set the O_LARGEFILE flag. 1743 */ 1744COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd, 1745 struct file_handle __user *, handle, int, flags) 1746{ 1747 return do_handle_open(mountdirfd, handle, flags); 1748} 1749#endif 1750 1751#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE 1752asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, 1753 compat_off_t __user *offset, compat_size_t count) 1754{ 1755 loff_t pos; 1756 off_t off; 1757 ssize_t ret; 1758 1759 if (offset) { 1760 if (unlikely(get_user(off, offset))) 1761 return -EFAULT; 1762 pos = off; 1763 ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS); 1764 if (unlikely(put_user(pos, offset))) 1765 return -EFAULT; 1766 return ret; 1767 } 1768 1769 return do_sendfile(out_fd, in_fd, NULL, count, 0); 1770} 1771#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */