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.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index f127625543b4..65da6e1b6de5 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -411,17 +411,45 @@ int fuse_do_getattr(struct inode *inode)
411 return err; 411 return err;
412} 412}
413 413
414/*
415 * Calling into a user-controlled filesystem gives the filesystem
416 * daemon ptrace-like capabilities over the requester process. This
417 * means, that the filesystem daemon is able to record the exact
418 * filesystem operations performed, and can also control the behavior
419 * of the requester process in otherwise impossible ways. For example
420 * it can delay the operation for arbitrary length of time allowing
421 * DoS against the requester.
422 *
423 * For this reason only those processes can call into the filesystem,
424 * for which the owner of the mount has ptrace privilege. This
425 * excludes processes started by other users, suid or sgid processes.
426 */
427static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
428{
429 if (fc->flags & FUSE_ALLOW_OTHER)
430 return 1;
431
432 if (task->euid == fc->user_id &&
433 task->suid == fc->user_id &&
434 task->uid == fc->user_id &&
435 task->egid == fc->group_id &&
436 task->sgid == fc->group_id &&
437 task->gid == fc->group_id)
438 return 1;
439
440 return 0;
441}
442
414static int fuse_revalidate(struct dentry *entry) 443static int fuse_revalidate(struct dentry *entry)
415{ 444{
416 struct inode *inode = entry->d_inode; 445 struct inode *inode = entry->d_inode;
417 struct fuse_inode *fi = get_fuse_inode(inode); 446 struct fuse_inode *fi = get_fuse_inode(inode);
418 struct fuse_conn *fc = get_fuse_conn(inode); 447 struct fuse_conn *fc = get_fuse_conn(inode);
419 448
420 if (get_node_id(inode) == FUSE_ROOT_ID) { 449 if (!fuse_allow_task(fc, current))
421 if (!(fc->flags & FUSE_ALLOW_OTHER) && 450 return -EACCES;
422 current->fsuid != fc->user_id) 451 if (get_node_id(inode) != FUSE_ROOT_ID &&
423 return -EACCES; 452 time_before_eq(jiffies, fi->i_time))
424 } else if (time_before_eq(jiffies, fi->i_time))
425 return 0; 453 return 0;
426 454
427 return fuse_do_getattr(inode); 455 return fuse_do_getattr(inode);
@@ -431,7 +459,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
431{ 459{
432 struct fuse_conn *fc = get_fuse_conn(inode); 460 struct fuse_conn *fc = get_fuse_conn(inode);
433 461
434 if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->user_id) 462 if (!fuse_allow_task(fc, current))
435 return -EACCES; 463 return -EACCES;
436 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 464 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
437 int err = generic_permission(inode, mask, NULL); 465 int err = generic_permission(inode, mask, NULL);