diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2005-09-09 16:10:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 17:03:46 -0400 |
commit | 87729a5514e855ce2c71e3e33833a106b8caf2ae (patch) | |
tree | dd2e7a9fd96b2dd3ebc3951fef2d682e83aa6bb4 /fs/fuse/inode.c | |
parent | db50b96c0f28a21c5a4a19ecaba12d0972aab06a (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/inode.c')
-rw-r--r-- | fs/fuse/inode.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 0b75c73386e9..c8e54c0658f1 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -31,6 +31,7 @@ struct fuse_mount_data { | |||
31 | int fd; | 31 | int fd; |
32 | unsigned rootmode; | 32 | unsigned rootmode; |
33 | unsigned user_id; | 33 | unsigned user_id; |
34 | unsigned group_id; | ||
34 | unsigned flags; | 35 | unsigned flags; |
35 | unsigned max_read; | 36 | unsigned max_read; |
36 | }; | 37 | }; |
@@ -199,6 +200,7 @@ static void fuse_put_super(struct super_block *sb) | |||
199 | spin_lock(&fuse_lock); | 200 | spin_lock(&fuse_lock); |
200 | fc->mounted = 0; | 201 | fc->mounted = 0; |
201 | fc->user_id = 0; | 202 | fc->user_id = 0; |
203 | fc->group_id = 0; | ||
202 | fc->flags = 0; | 204 | fc->flags = 0; |
203 | /* Flush all readers on this fs */ | 205 | /* Flush all readers on this fs */ |
204 | wake_up_all(&fc->waitq); | 206 | wake_up_all(&fc->waitq); |
@@ -248,6 +250,7 @@ enum { | |||
248 | OPT_FD, | 250 | OPT_FD, |
249 | OPT_ROOTMODE, | 251 | OPT_ROOTMODE, |
250 | OPT_USER_ID, | 252 | OPT_USER_ID, |
253 | OPT_GROUP_ID, | ||
251 | OPT_DEFAULT_PERMISSIONS, | 254 | OPT_DEFAULT_PERMISSIONS, |
252 | OPT_ALLOW_OTHER, | 255 | OPT_ALLOW_OTHER, |
253 | OPT_KERNEL_CACHE, | 256 | OPT_KERNEL_CACHE, |
@@ -259,6 +262,7 @@ static match_table_t tokens = { | |||
259 | {OPT_FD, "fd=%u"}, | 262 | {OPT_FD, "fd=%u"}, |
260 | {OPT_ROOTMODE, "rootmode=%o"}, | 263 | {OPT_ROOTMODE, "rootmode=%o"}, |
261 | {OPT_USER_ID, "user_id=%u"}, | 264 | {OPT_USER_ID, "user_id=%u"}, |
265 | {OPT_GROUP_ID, "group_id=%u"}, | ||
262 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, | 266 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, |
263 | {OPT_ALLOW_OTHER, "allow_other"}, | 267 | {OPT_ALLOW_OTHER, "allow_other"}, |
264 | {OPT_KERNEL_CACHE, "kernel_cache"}, | 268 | {OPT_KERNEL_CACHE, "kernel_cache"}, |
@@ -300,6 +304,12 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) | |||
300 | d->user_id = value; | 304 | d->user_id = value; |
301 | break; | 305 | break; |
302 | 306 | ||
307 | case OPT_GROUP_ID: | ||
308 | if (match_int(&args[0], &value)) | ||
309 | return 0; | ||
310 | d->group_id = value; | ||
311 | break; | ||
312 | |||
303 | case OPT_DEFAULT_PERMISSIONS: | 313 | case OPT_DEFAULT_PERMISSIONS: |
304 | d->flags |= FUSE_DEFAULT_PERMISSIONS; | 314 | d->flags |= FUSE_DEFAULT_PERMISSIONS; |
305 | break; | 315 | break; |
@@ -333,6 +343,7 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
333 | struct fuse_conn *fc = get_fuse_conn_super(mnt->mnt_sb); | 343 | struct fuse_conn *fc = get_fuse_conn_super(mnt->mnt_sb); |
334 | 344 | ||
335 | seq_printf(m, ",user_id=%u", fc->user_id); | 345 | seq_printf(m, ",user_id=%u", fc->user_id); |
346 | seq_printf(m, ",group_id=%u", fc->group_id); | ||
336 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) | 347 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) |
337 | seq_puts(m, ",default_permissions"); | 348 | seq_puts(m, ",default_permissions"); |
338 | if (fc->flags & FUSE_ALLOW_OTHER) | 349 | if (fc->flags & FUSE_ALLOW_OTHER) |
@@ -465,6 +476,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
465 | 476 | ||
466 | fc->flags = d.flags; | 477 | fc->flags = d.flags; |
467 | fc->user_id = d.user_id; | 478 | fc->user_id = d.user_id; |
479 | fc->group_id = d.group_id; | ||
468 | fc->max_read = d.max_read; | 480 | fc->max_read = d.max_read; |
469 | if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages) | 481 | if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages) |
470 | fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE; | 482 | fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE; |