aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dir.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-09-09 16:10:34 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 17:03:46 -0400
commit87729a5514e855ce2c71e3e33833a106b8caf2ae (patch)
treedd2e7a9fd96b2dd3ebc3951fef2d682e83aa6bb4 /fs/fuse/dir.c
parentdb50b96c0f28a21c5a4a19ecaba12d0972aab06a (diff)
[PATCH] FUSE: tighten check for processes allowed access
This patch tightens the check for allowing processes to access non-privileged mounts. The rational is that the filesystem implementation can control the behavior or get otherwise unavailable information of the filesystem user. If the filesystem user process has the same uid, gid, and is not suid or sgid application, then access is safe. Otherwise access is not allowed unless the "allow_other" mount option is given (for which policy is controlled by the userspace mount utility). Thanks to everyone linux-fsdevel, especially Martin Mares who helped uncover problems with the previous approach. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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);