Commit 482928d59db668b8d82a48717f78986d8cea72e9
1 parent
628ff7c1d8
Exists in
master
and in
7 other branches
Fix f_flags/f_mode in case of lookup_instantiate_filp() from open(pathname, 3)
Just set f_flags when shoving struct file into nameidata; don't postpone that until __dentry_open(). do_filp_open() has correct value; lookup_instantiate_filp() doesn't - we lose the difference between O_RDWR and 3 by that point. We still set .intent.open.flags, so no fs code needs to be changed. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 4 changed files with 17 additions and 11 deletions Side-by-side Diff
fs/internal.h
fs/namei.c
... | ... | @@ -1640,6 +1640,7 @@ |
1640 | 1640 | if (filp == NULL) |
1641 | 1641 | return ERR_PTR(-ENFILE); |
1642 | 1642 | nd.intent.open.file = filp; |
1643 | + filp->f_flags = open_flag; | |
1643 | 1644 | nd.intent.open.flags = flag; |
1644 | 1645 | nd.intent.open.create_mode = 0; |
1645 | 1646 | error = do_path_lookup(dfd, pathname, |
... | ... | @@ -1685,6 +1686,7 @@ |
1685 | 1686 | if (filp == NULL) |
1686 | 1687 | goto exit_parent; |
1687 | 1688 | nd.intent.open.file = filp; |
1689 | + filp->f_flags = open_flag; | |
1688 | 1690 | nd.intent.open.flags = flag; |
1689 | 1691 | nd.intent.open.create_mode = mode; |
1690 | 1692 | dir = nd.path.dentry; |
... | ... | @@ -1725,7 +1727,7 @@ |
1725 | 1727 | mnt_drop_write(nd.path.mnt); |
1726 | 1728 | goto exit; |
1727 | 1729 | } |
1728 | - filp = nameidata_to_filp(&nd, open_flag); | |
1730 | + filp = nameidata_to_filp(&nd); | |
1729 | 1731 | mnt_drop_write(nd.path.mnt); |
1730 | 1732 | if (nd.root.mnt) |
1731 | 1733 | path_put(&nd.root); |
... | ... | @@ -1789,7 +1791,7 @@ |
1789 | 1791 | mnt_drop_write(nd.path.mnt); |
1790 | 1792 | goto exit; |
1791 | 1793 | } |
1792 | - filp = nameidata_to_filp(&nd, open_flag); | |
1794 | + filp = nameidata_to_filp(&nd); | |
1793 | 1795 | if (!IS_ERR(filp)) { |
1794 | 1796 | error = ima_path_check(&filp->f_path, filp->f_mode & |
1795 | 1797 | (MAY_READ | MAY_WRITE | MAY_EXEC)); |
fs/open.c
... | ... | @@ -821,15 +821,14 @@ |
821 | 821 | } |
822 | 822 | |
823 | 823 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, |
824 | - int flags, struct file *f, | |
824 | + struct file *f, | |
825 | 825 | int (*open)(struct inode *, struct file *), |
826 | 826 | const struct cred *cred) |
827 | 827 | { |
828 | 828 | struct inode *inode; |
829 | 829 | int error; |
830 | 830 | |
831 | - f->f_flags = flags; | |
832 | - f->f_mode = (__force fmode_t)((flags+1) & O_ACCMODE) | FMODE_LSEEK | | |
831 | + f->f_mode = (__force fmode_t)((f->f_flags+1) & O_ACCMODE) | FMODE_LSEEK | | |
833 | 832 | FMODE_PREAD | FMODE_PWRITE; |
834 | 833 | inode = dentry->d_inode; |
835 | 834 | if (f->f_mode & FMODE_WRITE) { |
... | ... | @@ -930,7 +929,6 @@ |
930 | 929 | if (IS_ERR(dentry)) |
931 | 930 | goto out_err; |
932 | 931 | nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), |
933 | - nd->intent.open.flags - 1, | |
934 | 932 | nd->intent.open.file, |
935 | 933 | open, cred); |
936 | 934 | out: |
... | ... | @@ -949,7 +947,7 @@ |
949 | 947 | * |
950 | 948 | * Note that this function destroys the original nameidata |
951 | 949 | */ |
952 | -struct file *nameidata_to_filp(struct nameidata *nd, int flags) | |
950 | +struct file *nameidata_to_filp(struct nameidata *nd) | |
953 | 951 | { |
954 | 952 | const struct cred *cred = current_cred(); |
955 | 953 | struct file *filp; |
... | ... | @@ -958,7 +956,7 @@ |
958 | 956 | filp = nd->intent.open.file; |
959 | 957 | /* Has the filesystem initialised the file for us? */ |
960 | 958 | if (filp->f_path.dentry == NULL) |
961 | - filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, | |
959 | + filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, | |
962 | 960 | NULL, cred); |
963 | 961 | else |
964 | 962 | path_put(&nd->path); |
... | ... | @@ -997,7 +995,8 @@ |
997 | 995 | return ERR_PTR(error); |
998 | 996 | } |
999 | 997 | |
1000 | - return __dentry_open(dentry, mnt, flags, f, NULL, cred); | |
998 | + f->f_flags = flags; | |
999 | + return __dentry_open(dentry, mnt, f, NULL, cred); | |
1001 | 1000 | } |
1002 | 1001 | EXPORT_SYMBOL(dentry_open); |
1003 | 1002 |
include/linux/namei.h
... | ... | @@ -72,8 +72,6 @@ |
72 | 72 | |
73 | 73 | extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, |
74 | 74 | int (*open)(struct inode *, struct file *)); |
75 | -extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); | |
76 | -extern void release_open_intent(struct nameidata *); | |
77 | 75 | |
78 | 76 | extern struct dentry *lookup_one_len(const char *, struct dentry *, int); |
79 | 77 |