Loading fs/fuse/dir.c +22 −8 Original line number Diff line number Diff line Loading @@ -970,6 +970,14 @@ static int fuse_access(struct inode *inode, int mask) return err; } static int fuse_perm_getattr(struct inode *inode, int flags) { if (flags & IPERM_FLAG_RCU) return -ECHILD; return fuse_do_getattr(inode, NULL, NULL); } /* * Check permission. The two basic access models of FUSE are: * Loading @@ -989,9 +997,6 @@ static int fuse_permission(struct inode *inode, int mask, unsigned int flags) bool refreshed = false; int err = 0; if (flags & IPERM_FLAG_RCU) return -ECHILD; if (!fuse_allow_task(fc, current)) return -EACCES; Loading @@ -1000,10 +1005,16 @@ static int fuse_permission(struct inode *inode, int mask, unsigned int flags) */ if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { err = fuse_update_attributes(inode, NULL, NULL, &refreshed); struct fuse_inode *fi = get_fuse_inode(inode); if (fi->i_time < get_jiffies_64()) { refreshed = true; err = fuse_perm_getattr(inode, flags); if (err) return err; } } if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { err = generic_permission(inode, mask, flags, NULL); Loading @@ -1012,7 +1023,7 @@ static int fuse_permission(struct inode *inode, int mask, unsigned int flags) attributes. This is also needed, because the root node will at first have no permissions */ if (err == -EACCES && !refreshed) { err = fuse_do_getattr(inode, NULL, NULL); err = fuse_perm_getattr(inode, flags); if (!err) err = generic_permission(inode, mask, flags, NULL); Loading @@ -1023,13 +1034,16 @@ static int fuse_permission(struct inode *inode, int mask, unsigned int flags) noticed immediately, only after the attribute timeout has expired */ } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { if (flags & IPERM_FLAG_RCU) return -ECHILD; err = fuse_access(inode, mask); } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { if (!(inode->i_mode & S_IXUGO)) { if (refreshed) return -EACCES; err = fuse_do_getattr(inode, NULL, NULL); err = fuse_perm_getattr(inode, flags); if (!err && !(inode->i_mode & S_IXUGO)) return -EACCES; } Loading Loading
fs/fuse/dir.c +22 −8 Original line number Diff line number Diff line Loading @@ -970,6 +970,14 @@ static int fuse_access(struct inode *inode, int mask) return err; } static int fuse_perm_getattr(struct inode *inode, int flags) { if (flags & IPERM_FLAG_RCU) return -ECHILD; return fuse_do_getattr(inode, NULL, NULL); } /* * Check permission. The two basic access models of FUSE are: * Loading @@ -989,9 +997,6 @@ static int fuse_permission(struct inode *inode, int mask, unsigned int flags) bool refreshed = false; int err = 0; if (flags & IPERM_FLAG_RCU) return -ECHILD; if (!fuse_allow_task(fc, current)) return -EACCES; Loading @@ -1000,10 +1005,16 @@ static int fuse_permission(struct inode *inode, int mask, unsigned int flags) */ if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { err = fuse_update_attributes(inode, NULL, NULL, &refreshed); struct fuse_inode *fi = get_fuse_inode(inode); if (fi->i_time < get_jiffies_64()) { refreshed = true; err = fuse_perm_getattr(inode, flags); if (err) return err; } } if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { err = generic_permission(inode, mask, flags, NULL); Loading @@ -1012,7 +1023,7 @@ static int fuse_permission(struct inode *inode, int mask, unsigned int flags) attributes. This is also needed, because the root node will at first have no permissions */ if (err == -EACCES && !refreshed) { err = fuse_do_getattr(inode, NULL, NULL); err = fuse_perm_getattr(inode, flags); if (!err) err = generic_permission(inode, mask, flags, NULL); Loading @@ -1023,13 +1034,16 @@ static int fuse_permission(struct inode *inode, int mask, unsigned int flags) noticed immediately, only after the attribute timeout has expired */ } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { if (flags & IPERM_FLAG_RCU) return -ECHILD; err = fuse_access(inode, mask); } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { if (!(inode->i_mode & S_IXUGO)) { if (refreshed) return -EACCES; err = fuse_do_getattr(inode, NULL, NULL); err = fuse_perm_getattr(inode, flags); if (!err && !(inode->i_mode & S_IXUGO)) return -EACCES; } Loading