From: Darrick J. Wong <djwong@xxxxxxxxxx> By default, fuse doesn't allow processes with a uid/gid that don't match those of the server process to access the fuse mount, it doesn't allow suid files or devices, and it relies on the fuse server to perform permissions checking. This is a secure default for very untrusted filesystems, but it's possible that we might actually want to allow general access to an ext4 filesystem as part of containerizing the ext4 metadata parsing. In other words, we want the kernel access control behavior. Add an "kernel" mount option that moves most of the access permissions interpretation back into the kernel, and logs mount/unmount/error messages to dmesg. Right now this is mostly useful for fstests, so we leave it off by default. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- misc/fuse2fs.1.in | 9 +++++++++ misc/fuse2fs.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/misc/fuse2fs.1.in b/misc/fuse2fs.1.in index 1a0c9d54f5893a..517c67ff719911 100644 --- a/misc/fuse2fs.1.in +++ b/misc/fuse2fs.1.in @@ -53,6 +53,15 @@ .SS "fuse2fs options:" .TP \fB-o\fR fuse2fs_debug enable fuse2fs debugging +.TP +.BR -o kernel +Behave more like the kernel ext4 driver in the following ways: +Allows processes owned by other users to access the filesystem. +Uses the kernel's permissions checking logic instead of fuse2fs's. +Enables setuid and device files. +Note that these options can still be overridden (e.g. +.I nosuid +) later. .SS "FUSE options:" .TP \fB-d -o\fR debug diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index f499231dd04c94..d56d51207d1f25 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -52,6 +52,7 @@ #endif #include "../version.h" +#include "uuid/uuid.h" #ifdef ENABLE_NLS #include <libintl.h> @@ -156,6 +157,7 @@ struct fuse2fs { int fakeroot; int alloc_all_blocks; int norecovery; + int kernel; unsigned long offset; unsigned int next_generation; }; @@ -556,6 +558,13 @@ static void op_destroy(void *p EXT2FS_ATTR((unused))) if (err) translate_error(fs, 0, err); } + + if (ff->kernel) { + char uuid[UUID_STR_SIZE]; + + uuid_unparse(fs->super->s_uuid, uuid); + log_printf(ff, "%s %s.\n", _("unmounting filesystem"), uuid); + } } static void *op_init(struct fuse_conn_info *conn @@ -589,6 +598,13 @@ static void *op_init(struct fuse_conn_info *conn } if (ff->debug) cfg->debug = 1; + + if (ff->kernel) { + char uuid[UUID_STR_SIZE]; + + uuid_unparse(fs->super->s_uuid, uuid); + log_printf(ff, "%s %s.\n", _("mounted filesystem"), uuid); + } return ff; } @@ -3506,6 +3522,7 @@ static struct fuse_opt fuse2fs_opts[] = { FUSE2FS_OPT("no_default_opts", no_default_opts, 1), FUSE2FS_OPT("norecovery", norecovery, 1), FUSE2FS_OPT("offset=%lu", offset, 0), + FUSE2FS_OPT("kernel", kernel, 1), FUSE_OPT_KEY("acl", FUSE2FS_IGNORED), FUSE_OPT_KEY("user_xattr", FUSE2FS_IGNORED), @@ -3551,6 +3568,8 @@ static int fuse2fs_opt_proc(void *data, const char *arg, " -o offset=<bytes> similar to mount -o offset=<bytes>, mount the partition starting at <bytes>\n" " -o norecovery don't replay the journal\n" " -o fuse2fs_debug enable fuse2fs debugging\n" + " -o kernel run this as if it were the kernel, which sets:\n" + " allow_others,default_permissions,suid,dev\n" "\n", outargs->argv[0]); if (key == FUSE2FS_HELPFULL) { @@ -3636,6 +3655,13 @@ int main(int argc, char *argv[]) } stderr = fp; stdout = fp; + } else if (fctx.kernel) { + /* in kernel mode, try to log errors to the kernel log */ + FILE *fp = fopen("/dev/ttyprintk", "a"); + if (fp) { + stderr = fp; + stdout = fp; + } } /* Will we allow users to allocate every last block? */ @@ -3762,6 +3788,10 @@ int main(int argc, char *argv[]) #endif } + if (fctx.kernel) + fuse_opt_insert_arg(&args, 1, + "-oallow_other,default_permissions,suid,dev"); + if (fctx.debug) { int i;