Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.10-rc8 1395 lines 36 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/fs_struct.h> 48#include <linux/slab.h> 49#include <linux/pagemap.h> 50#include <linux/aio.h> 51 52#include <linux/uaccess.h> 53#include <asm/mmu_context.h> 54#include <asm/ioctls.h> 55#include "internal.h" 56 57/* 58 * Not all architectures have sys_utime, so implement this in terms 59 * of sys_utimes. 60 */ 61COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename, 62 struct compat_utimbuf __user *, t) 63{ 64 struct timespec tv[2]; 65 66 if (t) { 67 if (get_user(tv[0].tv_sec, &t->actime) || 68 get_user(tv[1].tv_sec, &t->modtime)) 69 return -EFAULT; 70 tv[0].tv_nsec = 0; 71 tv[1].tv_nsec = 0; 72 } 73 return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0); 74} 75 76COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags) 77{ 78 struct timespec tv[2]; 79 80 if (t) { 81 if (compat_get_timespec(&tv[0], &t[0]) || 82 compat_get_timespec(&tv[1], &t[1])) 83 return -EFAULT; 84 85 if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) 86 return 0; 87 } 88 return do_utimes(dfd, filename, t ? tv : NULL, flags); 89} 90 91COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t) 92{ 93 struct timespec tv[2]; 94 95 if (t) { 96 if (get_user(tv[0].tv_sec, &t[0].tv_sec) || 97 get_user(tv[0].tv_nsec, &t[0].tv_usec) || 98 get_user(tv[1].tv_sec, &t[1].tv_sec) || 99 get_user(tv[1].tv_nsec, &t[1].tv_usec)) 100 return -EFAULT; 101 if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 || 102 tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0) 103 return -EINVAL; 104 tv[0].tv_nsec *= 1000; 105 tv[1].tv_nsec *= 1000; 106 } 107 return do_utimes(dfd, filename, t ? tv : NULL, 0); 108} 109 110COMPAT_SYSCALL_DEFINE2(utimes, const char __user *, filename, struct compat_timeval __user *, t) 111{ 112 return compat_sys_futimesat(AT_FDCWD, filename, t); 113} 114 115static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) 116{ 117 struct compat_stat tmp; 118 119 if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) 120 return -EOVERFLOW; 121 122 memset(&tmp, 0, sizeof(tmp)); 123 tmp.st_dev = old_encode_dev(stat->dev); 124 tmp.st_ino = stat->ino; 125 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) 126 return -EOVERFLOW; 127 tmp.st_mode = stat->mode; 128 tmp.st_nlink = stat->nlink; 129 if (tmp.st_nlink != stat->nlink) 130 return -EOVERFLOW; 131 SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid)); 132 SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid)); 133 tmp.st_rdev = old_encode_dev(stat->rdev); 134 if ((u64) stat->size > MAX_NON_LFS) 135 return -EOVERFLOW; 136 tmp.st_size = stat->size; 137 tmp.st_atime = stat->atime.tv_sec; 138 tmp.st_atime_nsec = stat->atime.tv_nsec; 139 tmp.st_mtime = stat->mtime.tv_sec; 140 tmp.st_mtime_nsec = stat->mtime.tv_nsec; 141 tmp.st_ctime = stat->ctime.tv_sec; 142 tmp.st_ctime_nsec = stat->ctime.tv_nsec; 143 tmp.st_blocks = stat->blocks; 144 tmp.st_blksize = stat->blksize; 145 return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0; 146} 147 148COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename, 149 struct compat_stat __user *, statbuf) 150{ 151 struct kstat stat; 152 int error; 153 154 error = vfs_stat(filename, &stat); 155 if (error) 156 return error; 157 return cp_compat_stat(&stat, statbuf); 158} 159 160COMPAT_SYSCALL_DEFINE2(newlstat, const char __user *, filename, 161 struct compat_stat __user *, statbuf) 162{ 163 struct kstat stat; 164 int error; 165 166 error = vfs_lstat(filename, &stat); 167 if (error) 168 return error; 169 return cp_compat_stat(&stat, statbuf); 170} 171 172#ifndef __ARCH_WANT_STAT64 173COMPAT_SYSCALL_DEFINE4(newfstatat, unsigned int, dfd, 174 const char __user *, filename, 175 struct compat_stat __user *, statbuf, int, flag) 176{ 177 struct kstat stat; 178 int error; 179 180 error = vfs_fstatat(dfd, filename, &stat, flag); 181 if (error) 182 return error; 183 return cp_compat_stat(&stat, statbuf); 184} 185#endif 186 187COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd, 188 struct compat_stat __user *, statbuf) 189{ 190 struct kstat stat; 191 int error = vfs_fstat(fd, &stat); 192 193 if (!error) 194 error = cp_compat_stat(&stat, statbuf); 195 return error; 196} 197 198static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *kbuf) 199{ 200 201 if (sizeof ubuf->f_blocks == 4) { 202 if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail | 203 kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL) 204 return -EOVERFLOW; 205 /* f_files and f_ffree may be -1; it's okay 206 * to stuff that into 32 bits */ 207 if (kbuf->f_files != 0xffffffffffffffffULL 208 && (kbuf->f_files & 0xffffffff00000000ULL)) 209 return -EOVERFLOW; 210 if (kbuf->f_ffree != 0xffffffffffffffffULL 211 && (kbuf->f_ffree & 0xffffffff00000000ULL)) 212 return -EOVERFLOW; 213 } 214 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || 215 __put_user(kbuf->f_type, &ubuf->f_type) || 216 __put_user(kbuf->f_bsize, &ubuf->f_bsize) || 217 __put_user(kbuf->f_blocks, &ubuf->f_blocks) || 218 __put_user(kbuf->f_bfree, &ubuf->f_bfree) || 219 __put_user(kbuf->f_bavail, &ubuf->f_bavail) || 220 __put_user(kbuf->f_files, &ubuf->f_files) || 221 __put_user(kbuf->f_ffree, &ubuf->f_ffree) || 222 __put_user(kbuf->f_namelen, &ubuf->f_namelen) || 223 __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 224 __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || 225 __put_user(kbuf->f_frsize, &ubuf->f_frsize) || 226 __put_user(kbuf->f_flags, &ubuf->f_flags) || 227 __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare))) 228 return -EFAULT; 229 return 0; 230} 231 232/* 233 * The following statfs calls are copies of code from fs/statfs.c and 234 * should be checked against those from time to time 235 */ 236COMPAT_SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct compat_statfs __user *, buf) 237{ 238 struct kstatfs tmp; 239 int error = user_statfs(pathname, &tmp); 240 if (!error) 241 error = put_compat_statfs(buf, &tmp); 242 return error; 243} 244 245COMPAT_SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct compat_statfs __user *, buf) 246{ 247 struct kstatfs tmp; 248 int error = fd_statfs(fd, &tmp); 249 if (!error) 250 error = put_compat_statfs(buf, &tmp); 251 return error; 252} 253 254static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf) 255{ 256 if (sizeof(ubuf->f_bsize) == 4) { 257 if ((kbuf->f_type | kbuf->f_bsize | kbuf->f_namelen | 258 kbuf->f_frsize | kbuf->f_flags) & 0xffffffff00000000ULL) 259 return -EOVERFLOW; 260 /* f_files and f_ffree may be -1; it's okay 261 * to stuff that into 32 bits */ 262 if (kbuf->f_files != 0xffffffffffffffffULL 263 && (kbuf->f_files & 0xffffffff00000000ULL)) 264 return -EOVERFLOW; 265 if (kbuf->f_ffree != 0xffffffffffffffffULL 266 && (kbuf->f_ffree & 0xffffffff00000000ULL)) 267 return -EOVERFLOW; 268 } 269 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || 270 __put_user(kbuf->f_type, &ubuf->f_type) || 271 __put_user(kbuf->f_bsize, &ubuf->f_bsize) || 272 __put_user(kbuf->f_blocks, &ubuf->f_blocks) || 273 __put_user(kbuf->f_bfree, &ubuf->f_bfree) || 274 __put_user(kbuf->f_bavail, &ubuf->f_bavail) || 275 __put_user(kbuf->f_files, &ubuf->f_files) || 276 __put_user(kbuf->f_ffree, &ubuf->f_ffree) || 277 __put_user(kbuf->f_namelen, &ubuf->f_namelen) || 278 __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 279 __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || 280 __put_user(kbuf->f_frsize, &ubuf->f_frsize) || 281 __put_user(kbuf->f_flags, &ubuf->f_flags) || 282 __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare))) 283 return -EFAULT; 284 return 0; 285} 286 287COMPAT_SYSCALL_DEFINE3(statfs64, const char __user *, pathname, compat_size_t, sz, struct compat_statfs64 __user *, buf) 288{ 289 struct kstatfs tmp; 290 int error; 291 292 if (sz != sizeof(*buf)) 293 return -EINVAL; 294 295 error = user_statfs(pathname, &tmp); 296 if (!error) 297 error = put_compat_statfs64(buf, &tmp); 298 return error; 299} 300 301COMPAT_SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, compat_size_t, sz, struct compat_statfs64 __user *, buf) 302{ 303 struct kstatfs tmp; 304 int error; 305 306 if (sz != sizeof(*buf)) 307 return -EINVAL; 308 309 error = fd_statfs(fd, &tmp); 310 if (!error) 311 error = put_compat_statfs64(buf, &tmp); 312 return error; 313} 314 315/* 316 * This is a copy of sys_ustat, just dealing with a structure layout. 317 * Given how simple this syscall is that apporach is more maintainable 318 * than the various conversion hacks. 319 */ 320COMPAT_SYSCALL_DEFINE2(ustat, unsigned, dev, struct compat_ustat __user *, u) 321{ 322 struct compat_ustat tmp; 323 struct kstatfs sbuf; 324 int err = vfs_ustat(new_decode_dev(dev), &sbuf); 325 if (err) 326 return err; 327 328 memset(&tmp, 0, sizeof(struct compat_ustat)); 329 tmp.f_tfree = sbuf.f_bfree; 330 tmp.f_tinode = sbuf.f_ffree; 331 if (copy_to_user(u, &tmp, sizeof(struct compat_ustat))) 332 return -EFAULT; 333 return 0; 334} 335 336static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) 337{ 338 if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || 339 __get_user(kfl->l_type, &ufl->l_type) || 340 __get_user(kfl->l_whence, &ufl->l_whence) || 341 __get_user(kfl->l_start, &ufl->l_start) || 342 __get_user(kfl->l_len, &ufl->l_len) || 343 __get_user(kfl->l_pid, &ufl->l_pid)) 344 return -EFAULT; 345 return 0; 346} 347 348static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) 349{ 350 if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) || 351 __put_user(kfl->l_type, &ufl->l_type) || 352 __put_user(kfl->l_whence, &ufl->l_whence) || 353 __put_user(kfl->l_start, &ufl->l_start) || 354 __put_user(kfl->l_len, &ufl->l_len) || 355 __put_user(kfl->l_pid, &ufl->l_pid)) 356 return -EFAULT; 357 return 0; 358} 359 360#ifndef HAVE_ARCH_GET_COMPAT_FLOCK64 361static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) 362{ 363 if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || 364 __get_user(kfl->l_type, &ufl->l_type) || 365 __get_user(kfl->l_whence, &ufl->l_whence) || 366 __get_user(kfl->l_start, &ufl->l_start) || 367 __get_user(kfl->l_len, &ufl->l_len) || 368 __get_user(kfl->l_pid, &ufl->l_pid)) 369 return -EFAULT; 370 return 0; 371} 372#endif 373 374#ifndef HAVE_ARCH_PUT_COMPAT_FLOCK64 375static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) 376{ 377 if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) || 378 __put_user(kfl->l_type, &ufl->l_type) || 379 __put_user(kfl->l_whence, &ufl->l_whence) || 380 __put_user(kfl->l_start, &ufl->l_start) || 381 __put_user(kfl->l_len, &ufl->l_len) || 382 __put_user(kfl->l_pid, &ufl->l_pid)) 383 return -EFAULT; 384 return 0; 385} 386#endif 387 388static unsigned int 389convert_fcntl_cmd(unsigned int cmd) 390{ 391 switch (cmd) { 392 case F_GETLK64: 393 return F_GETLK; 394 case F_SETLK64: 395 return F_SETLK; 396 case F_SETLKW64: 397 return F_SETLKW; 398 } 399 400 return cmd; 401} 402 403COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, 404 compat_ulong_t, arg) 405{ 406 mm_segment_t old_fs; 407 struct flock f; 408 long ret; 409 unsigned int conv_cmd; 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 case F_OFD_GETLK: 447 case F_OFD_SETLK: 448 case F_OFD_SETLKW: 449 ret = get_compat_flock64(&f, compat_ptr(arg)); 450 if (ret != 0) 451 break; 452 old_fs = get_fs(); 453 set_fs(KERNEL_DS); 454 conv_cmd = convert_fcntl_cmd(cmd); 455 ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f); 456 set_fs(old_fs); 457 if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) { 458 /* need to return lock information - see above for commentary */ 459 if (f.l_start > COMPAT_LOFF_T_MAX) 460 ret = -EOVERFLOW; 461 if (f.l_len > COMPAT_LOFF_T_MAX) 462 f.l_len = COMPAT_LOFF_T_MAX; 463 if (ret == 0) 464 ret = put_compat_flock64(&f, compat_ptr(arg)); 465 } 466 break; 467 468 default: 469 ret = sys_fcntl(fd, cmd, arg); 470 break; 471 } 472 return ret; 473} 474 475COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, 476 compat_ulong_t, arg) 477{ 478 switch (cmd) { 479 case F_GETLK64: 480 case F_SETLK64: 481 case F_SETLKW64: 482 case F_OFD_GETLK: 483 case F_OFD_SETLK: 484 case F_OFD_SETLKW: 485 return -EINVAL; 486 } 487 return compat_sys_fcntl64(fd, cmd, arg); 488} 489 490/* A write operation does a read from user space and vice versa */ 491#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) 492 493ssize_t compat_rw_copy_check_uvector(int type, 494 const struct compat_iovec __user *uvector, unsigned long nr_segs, 495 unsigned long fast_segs, struct iovec *fast_pointer, 496 struct iovec **ret_pointer) 497{ 498 compat_ssize_t tot_len; 499 struct iovec *iov = *ret_pointer = fast_pointer; 500 ssize_t ret = 0; 501 int seg; 502 503 /* 504 * SuS says "The readv() function *may* fail if the iovcnt argument 505 * was less than or equal to 0, or greater than {IOV_MAX}. Linux has 506 * traditionally returned zero for zero segments, so... 507 */ 508 if (nr_segs == 0) 509 goto out; 510 511 ret = -EINVAL; 512 if (nr_segs > UIO_MAXIOV) 513 goto out; 514 if (nr_segs > fast_segs) { 515 ret = -ENOMEM; 516 iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); 517 if (iov == NULL) 518 goto out; 519 } 520 *ret_pointer = iov; 521 522 ret = -EFAULT; 523 if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector))) 524 goto out; 525 526 /* 527 * Single unix specification: 528 * We should -EINVAL if an element length is not >= 0 and fitting an 529 * ssize_t. 530 * 531 * In Linux, the total length is limited to MAX_RW_COUNT, there is 532 * no overflow possibility. 533 */ 534 tot_len = 0; 535 ret = -EINVAL; 536 for (seg = 0; seg < nr_segs; seg++) { 537 compat_uptr_t buf; 538 compat_ssize_t len; 539 540 if (__get_user(len, &uvector->iov_len) || 541 __get_user(buf, &uvector->iov_base)) { 542 ret = -EFAULT; 543 goto out; 544 } 545 if (len < 0) /* size_t not fitting in compat_ssize_t .. */ 546 goto out; 547 if (type >= 0 && 548 !access_ok(vrfy_dir(type), compat_ptr(buf), len)) { 549 ret = -EFAULT; 550 goto out; 551 } 552 if (len > MAX_RW_COUNT - tot_len) 553 len = MAX_RW_COUNT - tot_len; 554 tot_len += len; 555 iov->iov_base = compat_ptr(buf); 556 iov->iov_len = (compat_size_t) len; 557 uvector++; 558 iov++; 559 } 560 ret = tot_len; 561 562out: 563 return ret; 564} 565 566struct compat_ncp_mount_data { 567 compat_int_t version; 568 compat_uint_t ncp_fd; 569 __compat_uid_t mounted_uid; 570 compat_pid_t wdog_pid; 571 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; 572 compat_uint_t time_out; 573 compat_uint_t retry_count; 574 compat_uint_t flags; 575 __compat_uid_t uid; 576 __compat_gid_t gid; 577 compat_mode_t file_mode; 578 compat_mode_t dir_mode; 579}; 580 581struct compat_ncp_mount_data_v4 { 582 compat_int_t version; 583 compat_ulong_t flags; 584 compat_ulong_t mounted_uid; 585 compat_long_t wdog_pid; 586 compat_uint_t ncp_fd; 587 compat_uint_t time_out; 588 compat_uint_t retry_count; 589 compat_ulong_t uid; 590 compat_ulong_t gid; 591 compat_ulong_t file_mode; 592 compat_ulong_t dir_mode; 593}; 594 595static void *do_ncp_super_data_conv(void *raw_data) 596{ 597 int version = *(unsigned int *)raw_data; 598 599 if (version == 3) { 600 struct compat_ncp_mount_data *c_n = raw_data; 601 struct ncp_mount_data *n = raw_data; 602 603 n->dir_mode = c_n->dir_mode; 604 n->file_mode = c_n->file_mode; 605 n->gid = c_n->gid; 606 n->uid = c_n->uid; 607 memmove (n->mounted_vol, c_n->mounted_vol, (sizeof (c_n->mounted_vol) + 3 * sizeof (unsigned int))); 608 n->wdog_pid = c_n->wdog_pid; 609 n->mounted_uid = c_n->mounted_uid; 610 } else if (version == 4) { 611 struct compat_ncp_mount_data_v4 *c_n = raw_data; 612 struct ncp_mount_data_v4 *n = raw_data; 613 614 n->dir_mode = c_n->dir_mode; 615 n->file_mode = c_n->file_mode; 616 n->gid = c_n->gid; 617 n->uid = c_n->uid; 618 n->retry_count = c_n->retry_count; 619 n->time_out = c_n->time_out; 620 n->ncp_fd = c_n->ncp_fd; 621 n->wdog_pid = c_n->wdog_pid; 622 n->mounted_uid = c_n->mounted_uid; 623 n->flags = c_n->flags; 624 } else if (version != 5) { 625 return NULL; 626 } 627 628 return raw_data; 629} 630 631 632struct compat_nfs_string { 633 compat_uint_t len; 634 compat_uptr_t data; 635}; 636 637static inline void compat_nfs_string(struct nfs_string *dst, 638 struct compat_nfs_string *src) 639{ 640 dst->data = compat_ptr(src->data); 641 dst->len = src->len; 642} 643 644struct compat_nfs4_mount_data_v1 { 645 compat_int_t version; 646 compat_int_t flags; 647 compat_int_t rsize; 648 compat_int_t wsize; 649 compat_int_t timeo; 650 compat_int_t retrans; 651 compat_int_t acregmin; 652 compat_int_t acregmax; 653 compat_int_t acdirmin; 654 compat_int_t acdirmax; 655 struct compat_nfs_string client_addr; 656 struct compat_nfs_string mnt_path; 657 struct compat_nfs_string hostname; 658 compat_uint_t host_addrlen; 659 compat_uptr_t host_addr; 660 compat_int_t proto; 661 compat_int_t auth_flavourlen; 662 compat_uptr_t auth_flavours; 663}; 664 665static int do_nfs4_super_data_conv(void *raw_data) 666{ 667 int version = *(compat_uint_t *) raw_data; 668 669 if (version == 1) { 670 struct compat_nfs4_mount_data_v1 *raw = raw_data; 671 struct nfs4_mount_data *real = raw_data; 672 673 /* copy the fields backwards */ 674 real->auth_flavours = compat_ptr(raw->auth_flavours); 675 real->auth_flavourlen = raw->auth_flavourlen; 676 real->proto = raw->proto; 677 real->host_addr = compat_ptr(raw->host_addr); 678 real->host_addrlen = raw->host_addrlen; 679 compat_nfs_string(&real->hostname, &raw->hostname); 680 compat_nfs_string(&real->mnt_path, &raw->mnt_path); 681 compat_nfs_string(&real->client_addr, &raw->client_addr); 682 real->acdirmax = raw->acdirmax; 683 real->acdirmin = raw->acdirmin; 684 real->acregmax = raw->acregmax; 685 real->acregmin = raw->acregmin; 686 real->retrans = raw->retrans; 687 real->timeo = raw->timeo; 688 real->wsize = raw->wsize; 689 real->rsize = raw->rsize; 690 real->flags = raw->flags; 691 real->version = raw->version; 692 } 693 694 return 0; 695} 696 697#define NCPFS_NAME "ncpfs" 698#define NFS4_NAME "nfs4" 699 700COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, 701 const char __user *, dir_name, 702 const char __user *, type, compat_ulong_t, flags, 703 const void __user *, data) 704{ 705 char *kernel_type; 706 void *options; 707 char *kernel_dev; 708 int retval; 709 710 kernel_type = copy_mount_string(type); 711 retval = PTR_ERR(kernel_type); 712 if (IS_ERR(kernel_type)) 713 goto out; 714 715 kernel_dev = copy_mount_string(dev_name); 716 retval = PTR_ERR(kernel_dev); 717 if (IS_ERR(kernel_dev)) 718 goto out1; 719 720 options = copy_mount_options(data); 721 retval = PTR_ERR(options); 722 if (IS_ERR(options)) 723 goto out2; 724 725 if (kernel_type && options) { 726 if (!strcmp(kernel_type, NCPFS_NAME)) { 727 do_ncp_super_data_conv(options); 728 } else if (!strcmp(kernel_type, NFS4_NAME)) { 729 retval = -EINVAL; 730 if (do_nfs4_super_data_conv(options)) 731 goto out3; 732 } 733 } 734 735 retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options); 736 737 out3: 738 kfree(options); 739 out2: 740 kfree(kernel_dev); 741 out1: 742 kfree(kernel_type); 743 out: 744 return retval; 745} 746 747struct compat_old_linux_dirent { 748 compat_ulong_t d_ino; 749 compat_ulong_t d_offset; 750 unsigned short d_namlen; 751 char d_name[1]; 752}; 753 754struct compat_readdir_callback { 755 struct dir_context ctx; 756 struct compat_old_linux_dirent __user *dirent; 757 int result; 758}; 759 760static int compat_fillonedir(struct dir_context *ctx, const char *name, 761 int namlen, loff_t offset, u64 ino, 762 unsigned int d_type) 763{ 764 struct compat_readdir_callback *buf = 765 container_of(ctx, struct compat_readdir_callback, ctx); 766 struct compat_old_linux_dirent __user *dirent; 767 compat_ulong_t d_ino; 768 769 if (buf->result) 770 return -EINVAL; 771 d_ino = ino; 772 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 773 buf->result = -EOVERFLOW; 774 return -EOVERFLOW; 775 } 776 buf->result++; 777 dirent = buf->dirent; 778 if (!access_ok(VERIFY_WRITE, dirent, 779 (unsigned long)(dirent->d_name + namlen + 1) - 780 (unsigned long)dirent)) 781 goto efault; 782 if ( __put_user(d_ino, &dirent->d_ino) || 783 __put_user(offset, &dirent->d_offset) || 784 __put_user(namlen, &dirent->d_namlen) || 785 __copy_to_user(dirent->d_name, name, namlen) || 786 __put_user(0, dirent->d_name + namlen)) 787 goto efault; 788 return 0; 789efault: 790 buf->result = -EFAULT; 791 return -EFAULT; 792} 793 794COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd, 795 struct compat_old_linux_dirent __user *, dirent, unsigned int, count) 796{ 797 int error; 798 struct fd f = fdget_pos(fd); 799 struct compat_readdir_callback buf = { 800 .ctx.actor = compat_fillonedir, 801 .dirent = dirent 802 }; 803 804 if (!f.file) 805 return -EBADF; 806 807 error = iterate_dir(f.file, &buf.ctx); 808 if (buf.result) 809 error = buf.result; 810 811 fdput_pos(f); 812 return error; 813} 814 815struct compat_linux_dirent { 816 compat_ulong_t d_ino; 817 compat_ulong_t d_off; 818 unsigned short d_reclen; 819 char d_name[1]; 820}; 821 822struct compat_getdents_callback { 823 struct dir_context ctx; 824 struct compat_linux_dirent __user *current_dir; 825 struct compat_linux_dirent __user *previous; 826 int count; 827 int error; 828}; 829 830static int compat_filldir(struct dir_context *ctx, const char *name, int namlen, 831 loff_t offset, u64 ino, unsigned int d_type) 832{ 833 struct compat_linux_dirent __user * dirent; 834 struct compat_getdents_callback *buf = 835 container_of(ctx, struct compat_getdents_callback, ctx); 836 compat_ulong_t d_ino; 837 int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) + 838 namlen + 2, sizeof(compat_long_t)); 839 840 buf->error = -EINVAL; /* only used if we fail.. */ 841 if (reclen > buf->count) 842 return -EINVAL; 843 d_ino = ino; 844 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 845 buf->error = -EOVERFLOW; 846 return -EOVERFLOW; 847 } 848 dirent = buf->previous; 849 if (dirent) { 850 if (signal_pending(current)) 851 return -EINTR; 852 if (__put_user(offset, &dirent->d_off)) 853 goto efault; 854 } 855 dirent = buf->current_dir; 856 if (__put_user(d_ino, &dirent->d_ino)) 857 goto efault; 858 if (__put_user(reclen, &dirent->d_reclen)) 859 goto efault; 860 if (copy_to_user(dirent->d_name, name, namlen)) 861 goto efault; 862 if (__put_user(0, dirent->d_name + namlen)) 863 goto efault; 864 if (__put_user(d_type, (char __user *) dirent + reclen - 1)) 865 goto efault; 866 buf->previous = dirent; 867 dirent = (void __user *)dirent + reclen; 868 buf->current_dir = dirent; 869 buf->count -= reclen; 870 return 0; 871efault: 872 buf->error = -EFAULT; 873 return -EFAULT; 874} 875 876COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd, 877 struct compat_linux_dirent __user *, dirent, unsigned int, count) 878{ 879 struct fd f; 880 struct compat_linux_dirent __user * lastdirent; 881 struct compat_getdents_callback buf = { 882 .ctx.actor = compat_filldir, 883 .current_dir = dirent, 884 .count = count 885 }; 886 int error; 887 888 if (!access_ok(VERIFY_WRITE, dirent, count)) 889 return -EFAULT; 890 891 f = fdget_pos(fd); 892 if (!f.file) 893 return -EBADF; 894 895 error = iterate_dir(f.file, &buf.ctx); 896 if (error >= 0) 897 error = buf.error; 898 lastdirent = buf.previous; 899 if (lastdirent) { 900 if (put_user(buf.ctx.pos, &lastdirent->d_off)) 901 error = -EFAULT; 902 else 903 error = count - buf.count; 904 } 905 fdput_pos(f); 906 return error; 907} 908 909#ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64 910 911struct compat_getdents_callback64 { 912 struct dir_context ctx; 913 struct linux_dirent64 __user *current_dir; 914 struct linux_dirent64 __user *previous; 915 int count; 916 int error; 917}; 918 919static int compat_filldir64(struct dir_context *ctx, const char *name, 920 int namlen, loff_t offset, u64 ino, 921 unsigned int d_type) 922{ 923 struct linux_dirent64 __user *dirent; 924 struct compat_getdents_callback64 *buf = 925 container_of(ctx, struct compat_getdents_callback64, ctx); 926 int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1, 927 sizeof(u64)); 928 u64 off; 929 930 buf->error = -EINVAL; /* only used if we fail.. */ 931 if (reclen > buf->count) 932 return -EINVAL; 933 dirent = buf->previous; 934 935 if (dirent) { 936 if (signal_pending(current)) 937 return -EINTR; 938 if (__put_user_unaligned(offset, &dirent->d_off)) 939 goto efault; 940 } 941 dirent = buf->current_dir; 942 if (__put_user_unaligned(ino, &dirent->d_ino)) 943 goto efault; 944 off = 0; 945 if (__put_user_unaligned(off, &dirent->d_off)) 946 goto efault; 947 if (__put_user(reclen, &dirent->d_reclen)) 948 goto efault; 949 if (__put_user(d_type, &dirent->d_type)) 950 goto efault; 951 if (copy_to_user(dirent->d_name, name, namlen)) 952 goto efault; 953 if (__put_user(0, dirent->d_name + namlen)) 954 goto efault; 955 buf->previous = dirent; 956 dirent = (void __user *)dirent + reclen; 957 buf->current_dir = dirent; 958 buf->count -= reclen; 959 return 0; 960efault: 961 buf->error = -EFAULT; 962 return -EFAULT; 963} 964 965COMPAT_SYSCALL_DEFINE3(getdents64, unsigned int, fd, 966 struct linux_dirent64 __user *, dirent, unsigned int, count) 967{ 968 struct fd f; 969 struct linux_dirent64 __user * lastdirent; 970 struct compat_getdents_callback64 buf = { 971 .ctx.actor = compat_filldir64, 972 .current_dir = dirent, 973 .count = count 974 }; 975 int error; 976 977 if (!access_ok(VERIFY_WRITE, dirent, count)) 978 return -EFAULT; 979 980 f = fdget_pos(fd); 981 if (!f.file) 982 return -EBADF; 983 984 error = iterate_dir(f.file, &buf.ctx); 985 if (error >= 0) 986 error = buf.error; 987 lastdirent = buf.previous; 988 if (lastdirent) { 989 typeof(lastdirent->d_off) d_off = buf.ctx.pos; 990 if (__put_user_unaligned(d_off, &lastdirent->d_off)) 991 error = -EFAULT; 992 else 993 error = count - buf.count; 994 } 995 fdput_pos(f); 996 return error; 997} 998#endif /* __ARCH_WANT_COMPAT_SYS_GETDENTS64 */ 999 1000/* 1001 * Exactly like fs/open.c:sys_open(), except that it doesn't set the 1002 * O_LARGEFILE flag. 1003 */ 1004COMPAT_SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode) 1005{ 1006 return do_sys_open(AT_FDCWD, filename, flags, mode); 1007} 1008 1009/* 1010 * Exactly like fs/open.c:sys_openat(), except that it doesn't set the 1011 * O_LARGEFILE flag. 1012 */ 1013COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode) 1014{ 1015 return do_sys_open(dfd, filename, flags, mode); 1016} 1017 1018#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) 1019 1020static int poll_select_copy_remaining(struct timespec *end_time, void __user *p, 1021 int timeval, int ret) 1022{ 1023 struct timespec ts; 1024 1025 if (!p) 1026 return ret; 1027 1028 if (current->personality & STICKY_TIMEOUTS) 1029 goto sticky; 1030 1031 /* No update for zero timeout */ 1032 if (!end_time->tv_sec && !end_time->tv_nsec) 1033 return ret; 1034 1035 ktime_get_ts(&ts); 1036 ts = timespec_sub(*end_time, ts); 1037 if (ts.tv_sec < 0) 1038 ts.tv_sec = ts.tv_nsec = 0; 1039 1040 if (timeval) { 1041 struct compat_timeval rtv; 1042 1043 rtv.tv_sec = ts.tv_sec; 1044 rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC; 1045 1046 if (!copy_to_user(p, &rtv, sizeof(rtv))) 1047 return ret; 1048 } else { 1049 struct compat_timespec rts; 1050 1051 rts.tv_sec = ts.tv_sec; 1052 rts.tv_nsec = ts.tv_nsec; 1053 1054 if (!copy_to_user(p, &rts, sizeof(rts))) 1055 return ret; 1056 } 1057 /* 1058 * If an application puts its timeval in read-only memory, we 1059 * don't want the Linux-specific update to the timeval to 1060 * cause a fault after the select has completed 1061 * successfully. However, because we're not updating the 1062 * timeval, we can't restart the system call. 1063 */ 1064 1065sticky: 1066 if (ret == -ERESTARTNOHAND) 1067 ret = -EINTR; 1068 return ret; 1069} 1070 1071/* 1072 * Ooo, nasty. We need here to frob 32-bit unsigned longs to 1073 * 64-bit unsigned longs. 1074 */ 1075static 1076int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1077 unsigned long *fdset) 1078{ 1079 nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); 1080 if (ufdset) { 1081 unsigned long odd; 1082 1083 if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t))) 1084 return -EFAULT; 1085 1086 odd = nr & 1UL; 1087 nr &= ~1UL; 1088 while (nr) { 1089 unsigned long h, l; 1090 if (__get_user(l, ufdset) || __get_user(h, ufdset+1)) 1091 return -EFAULT; 1092 ufdset += 2; 1093 *fdset++ = h << 32 | l; 1094 nr -= 2; 1095 } 1096 if (odd && __get_user(*fdset, ufdset)) 1097 return -EFAULT; 1098 } else { 1099 /* Tricky, must clear full unsigned long in the 1100 * kernel fdset at the end, this makes sure that 1101 * actually happens. 1102 */ 1103 memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t)); 1104 } 1105 return 0; 1106} 1107 1108static 1109int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1110 unsigned long *fdset) 1111{ 1112 unsigned long odd; 1113 nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); 1114 1115 if (!ufdset) 1116 return 0; 1117 1118 odd = nr & 1UL; 1119 nr &= ~1UL; 1120 while (nr) { 1121 unsigned long h, l; 1122 l = *fdset++; 1123 h = l >> 32; 1124 if (__put_user(l, ufdset) || __put_user(h, ufdset+1)) 1125 return -EFAULT; 1126 ufdset += 2; 1127 nr -= 2; 1128 } 1129 if (odd && __put_user(*fdset, ufdset)) 1130 return -EFAULT; 1131 return 0; 1132} 1133 1134 1135/* 1136 * This is a virtual copy of sys_select from fs/select.c and probably 1137 * should be compared to it from time to time 1138 */ 1139 1140/* 1141 * We can actually return ERESTARTSYS instead of EINTR, but I'd 1142 * like to be certain this leads to no problems. So I return 1143 * EINTR just for safety. 1144 * 1145 * Update: ERESTARTSYS breaks at least the xview clock binary, so 1146 * I'm trying ERESTARTNOHAND which restart only when you want to. 1147 */ 1148int compat_core_sys_select(int n, compat_ulong_t __user *inp, 1149 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1150 struct timespec *end_time) 1151{ 1152 fd_set_bits fds; 1153 void *bits; 1154 int size, max_fds, ret = -EINVAL; 1155 struct fdtable *fdt; 1156 long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; 1157 1158 if (n < 0) 1159 goto out_nofds; 1160 1161 /* max_fds can increase, so grab it once to avoid race */ 1162 rcu_read_lock(); 1163 fdt = files_fdtable(current->files); 1164 max_fds = fdt->max_fds; 1165 rcu_read_unlock(); 1166 if (n > max_fds) 1167 n = max_fds; 1168 1169 /* 1170 * We need 6 bitmaps (in/out/ex for both incoming and outgoing), 1171 * since we used fdset we need to allocate memory in units of 1172 * long-words. 1173 */ 1174 size = FDS_BYTES(n); 1175 bits = stack_fds; 1176 if (size > sizeof(stack_fds) / 6) { 1177 bits = kmalloc(6 * size, GFP_KERNEL); 1178 ret = -ENOMEM; 1179 if (!bits) 1180 goto out_nofds; 1181 } 1182 fds.in = (unsigned long *) bits; 1183 fds.out = (unsigned long *) (bits + size); 1184 fds.ex = (unsigned long *) (bits + 2*size); 1185 fds.res_in = (unsigned long *) (bits + 3*size); 1186 fds.res_out = (unsigned long *) (bits + 4*size); 1187 fds.res_ex = (unsigned long *) (bits + 5*size); 1188 1189 if ((ret = compat_get_fd_set(n, inp, fds.in)) || 1190 (ret = compat_get_fd_set(n, outp, fds.out)) || 1191 (ret = compat_get_fd_set(n, exp, fds.ex))) 1192 goto out; 1193 zero_fd_set(n, fds.res_in); 1194 zero_fd_set(n, fds.res_out); 1195 zero_fd_set(n, fds.res_ex); 1196 1197 ret = do_select(n, &fds, end_time); 1198 1199 if (ret < 0) 1200 goto out; 1201 if (!ret) { 1202 ret = -ERESTARTNOHAND; 1203 if (signal_pending(current)) 1204 goto out; 1205 ret = 0; 1206 } 1207 1208 if (compat_set_fd_set(n, inp, fds.res_in) || 1209 compat_set_fd_set(n, outp, fds.res_out) || 1210 compat_set_fd_set(n, exp, fds.res_ex)) 1211 ret = -EFAULT; 1212out: 1213 if (bits != stack_fds) 1214 kfree(bits); 1215out_nofds: 1216 return ret; 1217} 1218 1219COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, 1220 compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, 1221 struct compat_timeval __user *, tvp) 1222{ 1223 struct timespec end_time, *to = NULL; 1224 struct compat_timeval tv; 1225 int ret; 1226 1227 if (tvp) { 1228 if (copy_from_user(&tv, tvp, sizeof(tv))) 1229 return -EFAULT; 1230 1231 to = &end_time; 1232 if (poll_select_set_timeout(to, 1233 tv.tv_sec + (tv.tv_usec / USEC_PER_SEC), 1234 (tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC)) 1235 return -EINVAL; 1236 } 1237 1238 ret = compat_core_sys_select(n, inp, outp, exp, to); 1239 ret = poll_select_copy_remaining(&end_time, tvp, 1, ret); 1240 1241 return ret; 1242} 1243 1244struct compat_sel_arg_struct { 1245 compat_ulong_t n; 1246 compat_uptr_t inp; 1247 compat_uptr_t outp; 1248 compat_uptr_t exp; 1249 compat_uptr_t tvp; 1250}; 1251 1252COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg) 1253{ 1254 struct compat_sel_arg_struct a; 1255 1256 if (copy_from_user(&a, arg, sizeof(a))) 1257 return -EFAULT; 1258 return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp), 1259 compat_ptr(a.exp), compat_ptr(a.tvp)); 1260} 1261 1262static long do_compat_pselect(int n, compat_ulong_t __user *inp, 1263 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1264 struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, 1265 compat_size_t sigsetsize) 1266{ 1267 compat_sigset_t ss32; 1268 sigset_t ksigmask, sigsaved; 1269 struct compat_timespec ts; 1270 struct timespec end_time, *to = NULL; 1271 int ret; 1272 1273 if (tsp) { 1274 if (copy_from_user(&ts, tsp, sizeof(ts))) 1275 return -EFAULT; 1276 1277 to = &end_time; 1278 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) 1279 return -EINVAL; 1280 } 1281 1282 if (sigmask) { 1283 if (sigsetsize != sizeof(compat_sigset_t)) 1284 return -EINVAL; 1285 if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1286 return -EFAULT; 1287 sigset_from_compat(&ksigmask, &ss32); 1288 1289 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1290 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1291 } 1292 1293 ret = compat_core_sys_select(n, inp, outp, exp, to); 1294 ret = poll_select_copy_remaining(&end_time, tsp, 0, ret); 1295 1296 if (ret == -ERESTARTNOHAND) { 1297 /* 1298 * Don't restore the signal mask yet. Let do_signal() deliver 1299 * the signal on the way back to userspace, before the signal 1300 * mask is restored. 1301 */ 1302 if (sigmask) { 1303 memcpy(&current->saved_sigmask, &sigsaved, 1304 sizeof(sigsaved)); 1305 set_restore_sigmask(); 1306 } 1307 } else if (sigmask) 1308 sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1309 1310 return ret; 1311} 1312 1313COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp, 1314 compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, 1315 struct compat_timespec __user *, tsp, void __user *, sig) 1316{ 1317 compat_size_t sigsetsize = 0; 1318 compat_uptr_t up = 0; 1319 1320 if (sig) { 1321 if (!access_ok(VERIFY_READ, sig, 1322 sizeof(compat_uptr_t)+sizeof(compat_size_t)) || 1323 __get_user(up, (compat_uptr_t __user *)sig) || 1324 __get_user(sigsetsize, 1325 (compat_size_t __user *)(sig+sizeof(up)))) 1326 return -EFAULT; 1327 } 1328 return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up), 1329 sigsetsize); 1330} 1331 1332COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, 1333 unsigned int, nfds, struct compat_timespec __user *, tsp, 1334 const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) 1335{ 1336 compat_sigset_t ss32; 1337 sigset_t ksigmask, sigsaved; 1338 struct compat_timespec ts; 1339 struct timespec end_time, *to = NULL; 1340 int ret; 1341 1342 if (tsp) { 1343 if (copy_from_user(&ts, tsp, sizeof(ts))) 1344 return -EFAULT; 1345 1346 to = &end_time; 1347 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) 1348 return -EINVAL; 1349 } 1350 1351 if (sigmask) { 1352 if (sigsetsize != sizeof(compat_sigset_t)) 1353 return -EINVAL; 1354 if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1355 return -EFAULT; 1356 sigset_from_compat(&ksigmask, &ss32); 1357 1358 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1359 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1360 } 1361 1362 ret = do_sys_poll(ufds, nfds, to); 1363 1364 /* We can restart this syscall, usually */ 1365 if (ret == -EINTR) { 1366 /* 1367 * Don't restore the signal mask yet. Let do_signal() deliver 1368 * the signal on the way back to userspace, before the signal 1369 * mask is restored. 1370 */ 1371 if (sigmask) { 1372 memcpy(&current->saved_sigmask, &sigsaved, 1373 sizeof(sigsaved)); 1374 set_restore_sigmask(); 1375 } 1376 ret = -ERESTARTNOHAND; 1377 } else if (sigmask) 1378 sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1379 1380 ret = poll_select_copy_remaining(&end_time, tsp, 0, ret); 1381 1382 return ret; 1383} 1384 1385#ifdef CONFIG_FHANDLE 1386/* 1387 * Exactly like fs/open.c:sys_open_by_handle_at(), except that it 1388 * doesn't set the O_LARGEFILE flag. 1389 */ 1390COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd, 1391 struct file_handle __user *, handle, int, flags) 1392{ 1393 return do_handle_open(mountdirfd, handle, flags); 1394} 1395#endif