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.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 8adc1eed164b..0950455914dd 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -418,7 +418,8 @@ static int fuse_revalidate(struct dentry *entry)
418 struct fuse_conn *fc = get_fuse_conn(inode); 418 struct fuse_conn *fc = get_fuse_conn(inode);
419 419
420 if (get_node_id(inode) == FUSE_ROOT_ID) { 420 if (get_node_id(inode) == FUSE_ROOT_ID) {
421 if (current->fsuid != fc->user_id) 421 if (!(fc->flags & FUSE_ALLOW_OTHER) &&
422 current->fsuid != fc->user_id)
422 return -EACCES; 423 return -EACCES;
423 } else if (time_before_eq(jiffies, fi->i_time)) 424 } else if (time_before_eq(jiffies, fi->i_time))
424 return 0; 425 return 0;
@@ -430,9 +431,31 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
430{ 431{
431 struct fuse_conn *fc = get_fuse_conn(inode); 432 struct fuse_conn *fc = get_fuse_conn(inode);
432 433
433 if (current->fsuid != fc->user_id) 434 if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->user_id)
434 return -EACCES; 435 return -EACCES;
435 else { 436 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
437 int err = generic_permission(inode, mask, NULL);
438
439 /* If permission is denied, try to refresh file
440 attributes. This is also needed, because the root
441 node will at first have no permissions */
442 if (err == -EACCES) {
443 err = fuse_do_getattr(inode);
444 if (!err)
445 err = generic_permission(inode, mask, NULL);
446 }
447
448 /* FIXME: Need some mechanism to revoke permissions:
449 currently if the filesystem suddenly changes the
450 file mode, we will not be informed about it, and
451 continue to allow access to the file/directory.
452
453 This is actually not so grave, since the user can
454 simply keep access to the file/directory anyway by
455 keeping it open... */
456
457 return err;
458 } else {
436 int mode = inode->i_mode; 459 int mode = inode->i_mode;
437 if ((mask & MAY_WRITE) && IS_RDONLY(inode) && 460 if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
438 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) 461 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
@@ -636,6 +659,12 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
636 int err; 659 int err;
637 int is_truncate = 0; 660 int is_truncate = 0;
638 661
662 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
663 err = inode_change_ok(inode, attr);
664 if (err)
665 return err;
666 }
667
639 if (attr->ia_valid & ATTR_SIZE) { 668 if (attr->ia_valid & ATTR_SIZE) {
640 unsigned long limit; 669 unsigned long limit;
641 is_truncate = 1; 670 is_truncate = 1;