Commit 482928d59db668b8d82a48717f78986d8cea72e9

Authored by Al Viro
1 parent 628ff7c1d8

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

... ... @@ -85,4 +85,11 @@
85 85 * super.c
86 86 */
87 87 extern int do_remount_sb(struct super_block *, int, void *, int);
  88 +
  89 +/*
  90 + * open.c
  91 + */
  92 +struct nameidata;
  93 +extern struct file *nameidata_to_filp(struct nameidata *);
  94 +extern void release_open_intent(struct nameidata *);
... ... @@ -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));
... ... @@ -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