aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2016-10-01 01:32:32 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-10-01 01:32:32 -0400
commit5e2b8828ff3d79aca8c3a1730652758753205b61 (patch)
tree258c57cbd536f70eb5ca270c46075cedc944f8e6 /fs/fuse
parent703c73629f93464ce210f5ad92d0c1fb95bfbadf (diff)
fuse: invalidate dir dentry after chmod
Without "default_permissions" the userspace filesystem's lookup operation needs to perform the check for search permission on the directory. If directory does not allow search for everyone (this is quite rare) then userspace filesystem has to set entry timeout to zero to make sure permissions are always performed. Changing the mode bits of the directory should also invalidate the (previously cached) dentry to make sure the next lookup will have a chance of updating the timeout, if needed. Reported-by: Jean-Pierre André <jean-pierre.andre@wanadoo.fr> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Cc: <stable@vger.kernel.org>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dir.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 7490db141dd9..3d3afa7ea57c 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1703,14 +1703,22 @@ error:
1703static int fuse_setattr(struct dentry *entry, struct iattr *attr) 1703static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1704{ 1704{
1705 struct inode *inode = d_inode(entry); 1705 struct inode *inode = d_inode(entry);
1706 int ret;
1706 1707
1707 if (!fuse_allow_current_process(get_fuse_conn(inode))) 1708 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1708 return -EACCES; 1709 return -EACCES;
1709 1710
1710 if (attr->ia_valid & ATTR_FILE) 1711 if (attr->ia_valid & ATTR_FILE)
1711 return fuse_do_setattr(inode, attr, attr->ia_file); 1712 ret = fuse_do_setattr(inode, attr, attr->ia_file);
1712 else 1713 else
1713 return fuse_do_setattr(inode, attr, NULL); 1714 ret = fuse_do_setattr(inode, attr, NULL);
1715
1716 if (!ret) {
1717 /* Directory mode changed, may need to revalidate access */
1718 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
1719 fuse_invalidate_entry_cache(entry);
1720 }
1721 return ret;
1714} 1722}
1715 1723
1716static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, 1724static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,