aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c152
1 files changed, 132 insertions, 20 deletions
diff --git a/fs/open.c b/fs/open.c
index e52389e1f05b..b52cf013ffa1 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -233,6 +233,14 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
233 233
234 if (!(file->f_mode & FMODE_WRITE)) 234 if (!(file->f_mode & FMODE_WRITE))
235 return -EBADF; 235 return -EBADF;
236
237 /* It's not possible punch hole on append only file */
238 if (mode & FALLOC_FL_PUNCH_HOLE && IS_APPEND(inode))
239 return -EPERM;
240
241 if (IS_IMMUTABLE(inode))
242 return -EPERM;
243
236 /* 244 /*
237 * Revalidate the write permissions, in case security policy has 245 * Revalidate the write permissions, in case security policy has
238 * changed since the files were opened. 246 * changed since the files were opened.
@@ -565,13 +573,15 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
565{ 573{
566 struct path path; 574 struct path path;
567 int error = -EINVAL; 575 int error = -EINVAL;
568 int follow; 576 int lookup_flags;
569 577
570 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) 578 if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
571 goto out; 579 goto out;
572 580
573 follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; 581 lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
574 error = user_path_at(dfd, filename, follow, &path); 582 if (flag & AT_EMPTY_PATH)
583 lookup_flags |= LOOKUP_EMPTY;
584 error = user_path_at(dfd, filename, lookup_flags, &path);
575 if (error) 585 if (error)
576 goto out; 586 goto out;
577 error = mnt_want_write(path.mnt); 587 error = mnt_want_write(path.mnt);
@@ -661,11 +671,16 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
661 int (*open)(struct inode *, struct file *), 671 int (*open)(struct inode *, struct file *),
662 const struct cred *cred) 672 const struct cred *cred)
663{ 673{
674 static const struct file_operations empty_fops = {};
664 struct inode *inode; 675 struct inode *inode;
665 int error; 676 int error;
666 677
667 f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | 678 f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
668 FMODE_PREAD | FMODE_PWRITE; 679 FMODE_PREAD | FMODE_PWRITE;
680
681 if (unlikely(f->f_flags & O_PATH))
682 f->f_mode = FMODE_PATH;
683
669 inode = dentry->d_inode; 684 inode = dentry->d_inode;
670 if (f->f_mode & FMODE_WRITE) { 685 if (f->f_mode & FMODE_WRITE) {
671 error = __get_file_write_access(inode, mnt); 686 error = __get_file_write_access(inode, mnt);
@@ -679,9 +694,15 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
679 f->f_path.dentry = dentry; 694 f->f_path.dentry = dentry;
680 f->f_path.mnt = mnt; 695 f->f_path.mnt = mnt;
681 f->f_pos = 0; 696 f->f_pos = 0;
682 f->f_op = fops_get(inode->i_fop);
683 file_sb_list_add(f, inode->i_sb); 697 file_sb_list_add(f, inode->i_sb);
684 698
699 if (unlikely(f->f_mode & FMODE_PATH)) {
700 f->f_op = &empty_fops;
701 return f;
702 }
703
704 f->f_op = fops_get(inode->i_fop);
705
685 error = security_dentry_open(f, cred); 706 error = security_dentry_open(f, cred);
686 if (error) 707 if (error)
687 goto cleanup_all; 708 goto cleanup_all;
@@ -693,7 +714,8 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
693 if (error) 714 if (error)
694 goto cleanup_all; 715 goto cleanup_all;
695 } 716 }
696 ima_counts_get(f); 717 if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
718 i_readcount_inc(inode);
697 719
698 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 720 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
699 721
@@ -790,6 +812,8 @@ struct file *nameidata_to_filp(struct nameidata *nd)
790 812
791 /* Pick up the filp from the open intent */ 813 /* Pick up the filp from the open intent */
792 filp = nd->intent.open.file; 814 filp = nd->intent.open.file;
815 nd->intent.open.file = NULL;
816
793 /* Has the filesystem initialised the file for us? */ 817 /* Has the filesystem initialised the file for us? */
794 if (filp->f_path.dentry == NULL) { 818 if (filp->f_path.dentry == NULL) {
795 path_get(&nd->path); 819 path_get(&nd->path);
@@ -811,17 +835,8 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
811 835
812 validate_creds(cred); 836 validate_creds(cred);
813 837
814 /* 838 /* We must always pass in a valid mount pointer. */
815 * We must always pass in a valid mount pointer. Historically 839 BUG_ON(!mnt);
816 * callers got away with not passing it, but we must enforce this at
817 * the earliest possible point now to avoid strange problems deep in the
818 * filesystem stack.
819 */
820 if (!mnt) {
821 printk(KERN_WARNING "%s called with NULL vfsmount\n", __func__);
822 dump_stack();
823 return ERR_PTR(-EINVAL);
824 }
825 840
826 error = -ENFILE; 841 error = -ENFILE;
827 f = get_empty_filp(); 842 f = get_empty_filp();
@@ -880,15 +895,110 @@ void fd_install(unsigned int fd, struct file *file)
880 895
881EXPORT_SYMBOL(fd_install); 896EXPORT_SYMBOL(fd_install);
882 897
898static inline int build_open_flags(int flags, int mode, struct open_flags *op)
899{
900 int lookup_flags = 0;
901 int acc_mode;
902
903 if (!(flags & O_CREAT))
904 mode = 0;
905 op->mode = mode;
906
907 /* Must never be set by userspace */
908 flags &= ~FMODE_NONOTIFY;
909
910 /*
911 * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
912 * check for O_DSYNC if the need any syncing at all we enforce it's
913 * always set instead of having to deal with possibly weird behaviour
914 * for malicious applications setting only __O_SYNC.
915 */
916 if (flags & __O_SYNC)
917 flags |= O_DSYNC;
918
919 /*
920 * If we have O_PATH in the open flag. Then we
921 * cannot have anything other than the below set of flags
922 */
923 if (flags & O_PATH) {
924 flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH;
925 acc_mode = 0;
926 } else {
927 acc_mode = MAY_OPEN | ACC_MODE(flags);
928 }
929
930 op->open_flag = flags;
931
932 /* O_TRUNC implies we need access checks for write permissions */
933 if (flags & O_TRUNC)
934 acc_mode |= MAY_WRITE;
935
936 /* Allow the LSM permission hook to distinguish append
937 access from general write access. */
938 if (flags & O_APPEND)
939 acc_mode |= MAY_APPEND;
940
941 op->acc_mode = acc_mode;
942
943 op->intent = flags & O_PATH ? 0 : LOOKUP_OPEN;
944
945 if (flags & O_CREAT) {
946 op->intent |= LOOKUP_CREATE;
947 if (flags & O_EXCL)
948 op->intent |= LOOKUP_EXCL;
949 }
950
951 if (flags & O_DIRECTORY)
952 lookup_flags |= LOOKUP_DIRECTORY;
953 if (!(flags & O_NOFOLLOW))
954 lookup_flags |= LOOKUP_FOLLOW;
955 return lookup_flags;
956}
957
958/**
959 * filp_open - open file and return file pointer
960 *
961 * @filename: path to open
962 * @flags: open flags as per the open(2) second argument
963 * @mode: mode for the new file if O_CREAT is set, else ignored
964 *
965 * This is the helper to open a file from kernelspace if you really
966 * have to. But in generally you should not do this, so please move
967 * along, nothing to see here..
968 */
969struct file *filp_open(const char *filename, int flags, int mode)
970{
971 struct open_flags op;
972 int lookup = build_open_flags(flags, mode, &op);
973 return do_filp_open(AT_FDCWD, filename, &op, lookup);
974}
975EXPORT_SYMBOL(filp_open);
976
977struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
978 const char *filename, int flags)
979{
980 struct open_flags op;
981 int lookup = build_open_flags(flags, 0, &op);
982 if (flags & O_CREAT)
983 return ERR_PTR(-EINVAL);
984 if (!filename && (flags & O_DIRECTORY))
985 if (!dentry->d_inode->i_op->lookup)
986 return ERR_PTR(-ENOTDIR);
987 return do_file_open_root(dentry, mnt, filename, &op, lookup);
988}
989EXPORT_SYMBOL(file_open_root);
990
883long do_sys_open(int dfd, const char __user *filename, int flags, int mode) 991long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
884{ 992{
993 struct open_flags op;
994 int lookup = build_open_flags(flags, mode, &op);
885 char *tmp = getname(filename); 995 char *tmp = getname(filename);
886 int fd = PTR_ERR(tmp); 996 int fd = PTR_ERR(tmp);
887 997
888 if (!IS_ERR(tmp)) { 998 if (!IS_ERR(tmp)) {
889 fd = get_unused_fd_flags(flags); 999 fd = get_unused_fd_flags(flags);
890 if (fd >= 0) { 1000 if (fd >= 0) {
891 struct file *f = do_filp_open(dfd, tmp, flags, mode, 0); 1001 struct file *f = do_filp_open(dfd, tmp, &op, lookup);
892 if (IS_ERR(f)) { 1002 if (IS_ERR(f)) {
893 put_unused_fd(fd); 1003 put_unused_fd(fd);
894 fd = PTR_ERR(f); 1004 fd = PTR_ERR(f);
@@ -958,8 +1068,10 @@ int filp_close(struct file *filp, fl_owner_t id)
958 if (filp->f_op && filp->f_op->flush) 1068 if (filp->f_op && filp->f_op->flush)
959 retval = filp->f_op->flush(filp, id); 1069 retval = filp->f_op->flush(filp, id);
960 1070
961 dnotify_flush(filp, id); 1071 if (likely(!(filp->f_mode & FMODE_PATH))) {
962 locks_remove_posix(filp, id); 1072 dnotify_flush(filp, id);
1073 locks_remove_posix(filp, id);
1074 }
963 fput(filp); 1075 fput(filp);
964 return retval; 1076 return retval;
965} 1077}