1 /* 2 * linux/fs/read_write.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 */ 6 7 #include <linux/slab.h> 8 #include <linux/stat.h> 9 #include <linux/fcntl.h> 10 #include <linux/file.h> 11 #include <linux/uio.h> 12 #include <linux/smp_lock.h> 13 #include <linux/dnotify.h> 14 #include <linux/security.h> 15 #include <linux/module.h> 16 #include <linux/syscalls.h> 17 18 #include <asm/uaccess.h> 19 #include <asm/unistd.h> 20 21 struct file_operations generic_ro_fops = { 22 .llseek = generic_file_llseek, 23 .read = generic_file_read, 24 .mmap = generic_file_readonly_mmap, 25 .sendfile = generic_file_sendfile, 26 }; 27 28 EXPORT_SYMBOL(generic_ro_fops); 29 30 loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) 31 { 32 long long retval; 33 struct inode *inode = file->f_mapping->host; 34 35 down(&inode->i_sem); 36 switch (origin) { 37 case 2: 38 offset += inode->i_size; 39 break; 40 case 1: 41 offset += file->f_pos; 42 } 43 retval = -EINVAL; 44 if (offset>=0 && offset<=inode->i_sb->s_maxbytes) { 45 if (offset != file->f_pos) { 46 file->f_pos = offset; 47 file->f_version = 0; 48 } 49 retval = offset; 50 } 51 up(&inode->i_sem); 52 return retval; 53 } 54 55 EXPORT_SYMBOL(generic_file_llseek); 56 57 loff_t remote_llseek(struct file *file, loff_t offset, int origin) 58 { 59 long long retval; 60 61 lock_kernel(); 62 switch (origin) { 63 case 2: 64 offset += i_size_read(file->f_dentry->d_inode); 65 break; 66 case 1: 67 offset += file->f_pos; 68 } 69 retval = -EINVAL; 70 if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) { 71 if (offset != file->f_pos) { 72 file->f_pos = offset; 73 file->f_version = 0; 74 } 75 retval = offset; 76 } 77 unlock_kernel(); 78 return retval; 79 } 80 EXPORT_SYMBOL(remote_llseek); 81 82 loff_t no_llseek(struct file *file, loff_t offset, int origin) 83 { 84 return -ESPIPE; 85 } 86 EXPORT_SYMBOL(no_llseek); 87 88 loff_t default_llseek(struct file *file, loff_t offset, int origin) 89 { 90 long long retval; 91 92 lock_kernel(); 93 switch (origin) { 94 case 2: 95 offset += i_size_read(file->f_dentry->d_inode); 96 break; 97 case 1: 98 offset += file->f_pos; 99 } 100 retval = -EINVAL; 101 if (offset >= 0) { 102 if (offset != file->f_pos) { 103 file->f_pos = offset; 104 file->f_version = 0; 105 } 106 retval = offset; 107 } 108 unlock_kernel(); 109 return retval; 110 } 111 EXPORT_SYMBOL(default_llseek); 112 113 loff_t vfs_llseek(struct file *file, loff_t offset, int origin) 114 { 115 loff_t (*fn)(struct file *, loff_t, int); 116 117 fn = no_llseek; 118 if (file->f_mode & FMODE_LSEEK) { 119 fn = default_llseek; 120 if (file->f_op && file->f_op->llseek) 121 fn = file->f_op->llseek; 122 } 123 return fn(file, offset, origin); 124 } 125 EXPORT_SYMBOL(vfs_llseek); 126 127 asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) 128 { 129 off_t retval; 130 struct file * file; 131 int fput_needed; 132 133 retval = -EBADF; 134 file = fget_light(fd, &fput_needed); 135 if (!file) 136 goto bad; 137 138 retval = -EINVAL; 139 if (origin <= 2) { 140 loff_t res = vfs_llseek(file, offset, origin); 141 retval = res; 142 if (res != (loff_t)retval) 143 retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ 144 } 145 fput_light(file, fput_needed); 146 bad: 147 return retval; 148 } 149 150 #ifdef __ARCH_WANT_SYS_LLSEEK 151 asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, 152 unsigned long offset_low, loff_t __user * result, 153 unsigned int origin) 154 { 155 int retval; 156 struct file * file; 157 loff_t offset; 158 int fput_needed; 159 160 retval = -EBADF; 161 file = fget_light(fd, &fput_needed); 162 if (!file) 163 goto bad; 164 165 retval = -EINVAL; 166 if (origin > 2) 167 goto out_putf; 168 169 offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low, 170 origin); 171 172 retval = (int)offset; 173 if (offset >= 0) { 174 retval = -EFAULT; 175 if (!copy_to_user(result, &offset, sizeof(offset))) 176 retval = 0; 177 } 178 out_putf: 179 fput_light(file, fput_needed); 180 bad: 181 return retval; 182 } 183 #endif 184 185 186 int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) 187 { 188 struct inode *inode; 189 loff_t pos; 190 191 if (unlikely(count > file->f_maxcount)) 192 goto Einval; 193 pos = *ppos; 194 if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) 195 goto Einval; 196 197 inode = file->f_dentry->d_inode; 198 if (inode->i_flock && MANDATORY_LOCK(inode)) 199 return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); 200 return 0; 201 202 Einval: 203 return -EINVAL; 204 } 205 206 ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) 207 { 208 struct kiocb kiocb; 209 ssize_t ret; 210 211 init_sync_kiocb(&kiocb, filp); 212 kiocb.ki_pos = *ppos; 213 ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos); 214 if (-EIOCBQUEUED == ret) 215 ret = wait_on_sync_kiocb(&kiocb); 216 *ppos = kiocb.ki_pos; 217 return ret; 218 } 219 220 EXPORT_SYMBOL(do_sync_read); 221 222 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) 223 { 224 ssize_t ret; 225 226 if (!(file->f_mode & FMODE_READ)) 227 return -EBADF; 228 if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read)) 229 return -EINVAL; 230 if (unlikely(!access_ok(VERIFY_WRITE, buf, count))) 231 return -EFAULT; 232 233 ret = rw_verify_area(READ, file, pos, count); 234 if (!ret) { 235 ret = security_file_permission (file, MAY_READ); 236 if (!ret) { 237 if (file->f_op->read) 238 ret = file->f_op->read(file, buf, count, pos); 239 else 240 ret = do_sync_read(file, buf, count, pos); 241 if (ret > 0) { 242 dnotify_parent(file->f_dentry, DN_ACCESS); 243 current->rchar += ret; 244 } 245 current->syscr++; 246 } 247 } 248 249 return ret; 250 } 251 252 EXPORT_SYMBOL(vfs_read); 253 254 ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) 255 { 256 struct kiocb kiocb; 257 ssize_t ret; 258 259 init_sync_kiocb(&kiocb, filp); 260 kiocb.ki_pos = *ppos; 261 ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos); 262 if (-EIOCBQUEUED == ret) 263 ret = wait_on_sync_kiocb(&kiocb); 264 *ppos = kiocb.ki_pos; 265 return ret; 266 } 267 268 EXPORT_SYMBOL(do_sync_write); 269 270 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) 271 { 272 ssize_t ret; 273 274 if (!(file->f_mode & FMODE_WRITE)) 275 return -EBADF; 276 if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) 277 return -EINVAL; 278 if (unlikely(!access_ok(VERIFY_READ, buf, count))) 279 return -EFAULT; 280 281 ret = rw_verify_area(WRITE, file, pos, count); 282 if (!ret) { 283 ret = security_file_permission (file, MAY_WRITE); 284 if (!ret) { 285 if (file->f_op->write) 286 ret = file->f_op->write(file, buf, count, pos); 287 else 288 ret = do_sync_write(file, buf, count, pos); 289 if (ret > 0) { 290 dnotify_parent(file->f_dentry, DN_MODIFY); 291 current->wchar += ret; 292 } 293 current->syscw++; 294 } 295 } 296 297 return ret; 298 } 299 300 EXPORT_SYMBOL(vfs_write); 301 302 static inline loff_t file_pos_read(struct file *file) 303 { 304 return file->f_pos; 305 } 306 307 static inline void file_pos_write(struct file *file, loff_t pos) 308 { 309 file->f_pos = pos; 310 } 311 312 asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count) 313 { 314 struct file *file; 315 ssize_t ret = -EBADF; 316 int fput_needed; 317 318 file = fget_light(fd, &fput_needed); 319 if (file) { 320 loff_t pos = file_pos_read(file); 321 ret = vfs_read(file, buf, count, &pos); 322 file_pos_write(file, pos); 323 fput_light(file, fput_needed); 324 } 325 326 return ret; 327 } 328 EXPORT_SYMBOL_GPL(sys_read); 329 330 asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count) 331 { 332 struct file *file; 333 ssize_t ret = -EBADF; 334 int fput_needed; 335 336 file = fget_light(fd, &fput_needed); 337 if (file) { 338 loff_t pos = file_pos_read(file); 339 ret = vfs_write(file, buf, count, &pos); 340 file_pos_write(file, pos); 341 fput_light(file, fput_needed); 342 } 343 344 return ret; 345 } 346 347 asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf, 348 size_t count, loff_t pos) 349 { 350 struct file *file; 351 ssize_t ret = -EBADF; 352 int fput_needed; 353 354 if (pos < 0) 355 return -EINVAL; 356 357 file = fget_light(fd, &fput_needed); 358 if (file) { 359 ret = -ESPIPE; 360 if (file->f_mode & FMODE_PREAD) 361 ret = vfs_read(file, buf, count, &pos); 362 fput_light(file, fput_needed); 363 } 364 365 return ret; 366 } 367 368 asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf, 369 size_t count, loff_t pos) 370 { 371 struct file *file; 372 ssize_t ret = -EBADF; 373 int fput_needed; 374 375 if (pos < 0) 376 return -EINVAL; 377 378 file = fget_light(fd, &fput_needed); 379 if (file) { 380 ret = -ESPIPE; 381 if (file->f_mode & FMODE_PWRITE) 382 ret = vfs_write(file, buf, count, &pos); 383 fput_light(file, fput_needed); 384 } 385 386 return ret; 387 } 388 389 /* 390 * Reduce an iovec's length in-place. Return the resulting number of segments 391 */ 392 unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) 393 { 394 unsigned long seg = 0; 395 size_t len = 0; 396 397 while (seg < nr_segs) { 398 seg++; 399 if (len + iov->iov_len >= to) { 400 iov->iov_len = to - len; 401 break; 402 } 403 len += iov->iov_len; 404 iov++; 405 } 406 return seg; 407 } 408 409 EXPORT_SYMBOL(iov_shorten); 410 411 /* A write operation does a read from user space and vice versa */ 412 #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) 413 414 static ssize_t do_readv_writev(int type, struct file *file, 415 const struct iovec __user * uvector, 416 unsigned long nr_segs, loff_t *pos) 417 { 418 typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); 419 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *); 420 421 size_t tot_len; 422 struct iovec iovstack[UIO_FASTIOV]; 423 struct iovec *iov=iovstack, *vector; 424 ssize_t ret; 425 int seg; 426 io_fn_t fn; 427 iov_fn_t fnv; 428 429 /* 430 * SuS says "The readv() function *may* fail if the iovcnt argument 431 * was less than or equal to 0, or greater than {IOV_MAX}. Linux has 432 * traditionally returned zero for zero segments, so... 433 */ 434 ret = 0; 435 if (nr_segs == 0) 436 goto out; 437 438 /* 439 * First get the "struct iovec" from user memory and 440 * verify all the pointers 441 */ 442 ret = -EINVAL; 443 if ((nr_segs > UIO_MAXIOV) || (nr_segs <= 0)) 444 goto out; 445 if (!file->f_op) 446 goto out; 447 if (nr_segs > UIO_FASTIOV) { 448 ret = -ENOMEM; 449 iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); 450 if (!iov) 451 goto out; 452 } 453 ret = -EFAULT; 454 if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) 455 goto out; 456 457 /* 458 * Single unix specification: 459 * We should -EINVAL if an element length is not >= 0 and fitting an 460 * ssize_t. The total length is fitting an ssize_t 461 * 462 * Be careful here because iov_len is a size_t not an ssize_t 463 */ 464 tot_len = 0; 465 ret = -EINVAL; 466 for (seg = 0; seg < nr_segs; seg++) { 467 void __user *buf = iov[seg].iov_base; 468 ssize_t len = (ssize_t)iov[seg].iov_len; 469 470 if (unlikely(!access_ok(vrfy_dir(type), buf, len))) 471 goto Efault; 472 if (len < 0) /* size_t not fitting an ssize_t .. */ 473 goto out; 474 tot_len += len; 475 if ((ssize_t)tot_len < 0) /* maths overflow on the ssize_t */ 476 goto out; 477 } 478 if (tot_len == 0) { 479 ret = 0; 480 goto out; 481 } 482 483 ret = rw_verify_area(type, file, pos, tot_len); 484 if (ret) 485 goto out; 486 487 fnv = NULL; 488 if (type == READ) { 489 fn = file->f_op->read; 490 fnv = file->f_op->readv; 491 } else { 492 fn = (io_fn_t)file->f_op->write; 493 fnv = file->f_op->writev; 494 } 495 if (fnv) { 496 ret = fnv(file, iov, nr_segs, pos); 497 goto out; 498 } 499 500 /* Do it by hand, with file-ops */ 501 ret = 0; 502 vector = iov; 503 while (nr_segs > 0) { 504 void __user * base; 505 size_t len; 506 ssize_t nr; 507 508 base = vector->iov_base; 509 len = vector->iov_len; 510 vector++; 511 nr_segs--; 512 513 nr = fn(file, base, len, pos); 514 515 if (nr < 0) { 516 if (!ret) ret = nr; 517 break; 518 } 519 ret += nr; 520 if (nr != len) 521 break; 522 } 523 out: 524 if (iov != iovstack) 525 kfree(iov); 526 if ((ret + (type == READ)) > 0) 527 dnotify_parent(file->f_dentry, 528 (type == READ) ? DN_ACCESS : DN_MODIFY); 529 return ret; 530 Efault: 531 ret = -EFAULT; 532 goto out; 533 } 534 535 ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, 536 unsigned long vlen, loff_t *pos) 537 { 538 if (!(file->f_mode & FMODE_READ)) 539 return -EBADF; 540 if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) 541 return -EINVAL; 542 543 return do_readv_writev(READ, file, vec, vlen, pos); 544 } 545 546 EXPORT_SYMBOL(vfs_readv); 547 548 ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, 549 unsigned long vlen, loff_t *pos) 550 { 551 if (!(file->f_mode & FMODE_WRITE)) 552 return -EBADF; 553 if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) 554 return -EINVAL; 555 556 return do_readv_writev(WRITE, file, vec, vlen, pos); 557 } 558 559 EXPORT_SYMBOL(vfs_writev); 560 561 asmlinkage ssize_t 562 sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) 563 { 564 struct file *file; 565 ssize_t ret = -EBADF; 566 int fput_needed; 567 568 file = fget_light(fd, &fput_needed); 569 if (file) { 570 loff_t pos = file_pos_read(file); 571 ret = vfs_readv(file, vec, vlen, &pos); 572 file_pos_write(file, pos); 573 fput_light(file, fput_needed); 574 } 575 576 if (ret > 0) 577 current->rchar += ret; 578 current->syscr++; 579 return ret; 580 } 581 582 asmlinkage ssize_t 583 sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) 584 { 585 struct file *file; 586 ssize_t ret = -EBADF; 587 int fput_needed; 588 589 file = fget_light(fd, &fput_needed); 590 if (file) { 591 loff_t pos = file_pos_read(file); 592 ret = vfs_writev(file, vec, vlen, &pos); 593 file_pos_write(file, pos); 594 fput_light(file, fput_needed); 595 } 596 597 if (ret > 0) 598 current->wchar += ret; 599 current->syscw++; 600 return ret; 601 } 602 603 static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, 604 size_t count, loff_t max) 605 { 606 struct file * in_file, * out_file; 607 struct inode * in_inode, * out_inode; 608 loff_t pos; 609 ssize_t retval; 610 int fput_needed_in, fput_needed_out; 611 612 /* 613 * Get input file, and verify that it is ok.. 614 */ 615 retval = -EBADF; 616 in_file = fget_light(in_fd, &fput_needed_in); 617 if (!in_file) 618 goto out; 619 if (!(in_file->f_mode & FMODE_READ)) 620 goto fput_in; 621 retval = -EINVAL; 622 in_inode = in_file->f_dentry->d_inode; 623 if (!in_inode) 624 goto fput_in; 625 if (!in_file->f_op || !in_file->f_op->sendfile) 626 goto fput_in; 627 retval = -ESPIPE; 628 if (!ppos) 629 ppos = &in_file->f_pos; 630 else 631 if (!(in_file->f_mode & FMODE_PREAD)) 632 goto fput_in; 633 retval = rw_verify_area(READ, in_file, ppos, count); 634 if (retval) 635 goto fput_in; 636 637 retval = security_file_permission (in_file, MAY_READ); 638 if (retval) 639 goto fput_in; 640 641 /* 642 * Get output file, and verify that it is ok.. 643 */ 644 retval = -EBADF; 645 out_file = fget_light(out_fd, &fput_needed_out); 646 if (!out_file) 647 goto fput_in; 648 if (!(out_file->f_mode & FMODE_WRITE)) 649 goto fput_out; 650 retval = -EINVAL; 651 if (!out_file->f_op || !out_file->f_op->sendpage) 652 goto fput_out; 653 out_inode = out_file->f_dentry->d_inode; 654 retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); 655 if (retval) 656 goto fput_out; 657 658 retval = security_file_permission (out_file, MAY_WRITE); 659 if (retval) 660 goto fput_out; 661 662 if (!max) 663 max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); 664 665 pos = *ppos; 666 retval = -EINVAL; 667 if (unlikely(pos < 0)) 668 goto fput_out; 669 if (unlikely(pos + count > max)) { 670 retval = -EOVERFLOW; 671 if (pos >= max) 672 goto fput_out; 673 count = max - pos; 674 } 675 676 retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); 677 678 if (retval > 0) { 679 current->rchar += retval; 680 current->wchar += retval; 681 } 682 current->syscr++; 683 current->syscw++; 684 685 if (*ppos > max) 686 retval = -EOVERFLOW; 687 688 fput_out: 689 fput_light(out_file, fput_needed_out); 690 fput_in: 691 fput_light(in_file, fput_needed_in); 692 out: 693 return retval; 694 } 695 696 asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t __user *offset, size_t count) 697 { 698 loff_t pos; 699 off_t off; 700 ssize_t ret; 701 702 if (offset) { 703 if (unlikely(get_user(off, offset))) 704 return -EFAULT; 705 pos = off; 706 ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS); 707 if (unlikely(put_user(pos, offset))) 708 return -EFAULT; 709 return ret; 710 } 711 712 return do_sendfile(out_fd, in_fd, NULL, count, 0); 713 } 714 715 asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t __user *offset, size_t count) 716 { 717 loff_t pos; 718 ssize_t ret; 719 720 if (offset) { 721 if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t)))) 722 return -EFAULT; 723 ret = do_sendfile(out_fd, in_fd, &pos, count, 0); 724 if (unlikely(put_user(pos, offset))) 725 return -EFAULT; 726 return ret; 727 } 728 729 return do_sendfile(out_fd, in_fd, NULL, count, 0); 730 } 731