aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r--fs/fuse/dir.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 8ea4ea13ec5f..d1acab931330 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -695,6 +695,20 @@ static int fuse_do_getattr(struct inode *inode)
695} 695}
696 696
697/* 697/*
698 * Check if attributes are still valid, and if not send a GETATTR
699 * request to refresh them.
700 */
701static int fuse_refresh_attributes(struct inode *inode)
702{
703 struct fuse_inode *fi = get_fuse_inode(inode);
704
705 if (fi->i_time < get_jiffies_64())
706 return fuse_do_getattr(inode);
707 else
708 return 0;
709}
710
711/*
698 * Calling into a user-controlled filesystem gives the filesystem 712 * Calling into a user-controlled filesystem gives the filesystem
699 * daemon ptrace-like capabilities over the requester process. This 713 * daemon ptrace-like capabilities over the requester process. This
700 * means, that the filesystem daemon is able to record the exact 714 * means, that the filesystem daemon is able to record the exact
@@ -770,7 +784,6 @@ static int fuse_access(struct inode *inode, int mask)
770static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) 784static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
771{ 785{
772 struct fuse_conn *fc = get_fuse_conn(inode); 786 struct fuse_conn *fc = get_fuse_conn(inode);
773 struct fuse_inode *fi = get_fuse_inode(inode);
774 bool refreshed = false; 787 bool refreshed = false;
775 int err = 0; 788 int err = 0;
776 789
@@ -778,12 +791,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
778 return -EACCES; 791 return -EACCES;
779 792
780 /* 793 /*
781 * If attributes are needed, but are stale, refresh them 794 * If attributes are needed, refresh them before proceeding
782 * before proceeding
783 */ 795 */
784 if (((fc->flags & FUSE_DEFAULT_PERMISSIONS) || (mask & MAY_EXEC)) && 796 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
785 fi->i_time < get_jiffies_64()) { 797 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
786 err = fuse_do_getattr(inode); 798 err = fuse_refresh_attributes(inode);
787 if (err) 799 if (err)
788 return err; 800 return err;
789 801
@@ -806,14 +818,17 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
806 exist. So if permissions are revoked this won't be 818 exist. So if permissions are revoked this won't be
807 noticed immediately, only after the attribute 819 noticed immediately, only after the attribute
808 timeout has expired */ 820 timeout has expired */
809 821 } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) {
810 } else { 822 err = fuse_access(inode, mask);
811 int mode = inode->i_mode; 823 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
812 if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) 824 if (!(inode->i_mode & S_IXUGO)) {
813 return -EACCES; 825 if (refreshed)
814 826 return -EACCES;
815 if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) 827
816 return fuse_access(inode, mask); 828 err = fuse_do_getattr(inode);
829 if (!err && !(inode->i_mode & S_IXUGO))
830 return -EACCES;
831 }
817 } 832 }
818 return err; 833 return err;
819} 834}
@@ -1046,14 +1061,12 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1046 struct inode *inode = entry->d_inode; 1061 struct inode *inode = entry->d_inode;
1047 struct fuse_inode *fi = get_fuse_inode(inode); 1062 struct fuse_inode *fi = get_fuse_inode(inode);
1048 struct fuse_conn *fc = get_fuse_conn(inode); 1063 struct fuse_conn *fc = get_fuse_conn(inode);
1049 int err = 0; 1064 int err;
1050 1065
1051 if (!fuse_allow_task(fc, current)) 1066 if (!fuse_allow_task(fc, current))
1052 return -EACCES; 1067 return -EACCES;
1053 1068
1054 if (fi->i_time < get_jiffies_64()) 1069 err = fuse_refresh_attributes(inode);
1055 err = fuse_do_getattr(inode);
1056
1057 if (!err) { 1070 if (!err) {
1058 generic_fillattr(inode, stat); 1071 generic_fillattr(inode, stat);
1059 stat->mode = fi->orig_i_mode; 1072 stat->mode = fi->orig_i_mode;