From 3181e6495b0a1670b593011e7c21a558949f44b5 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 16 Mar 2015 13:27:14 +1100 Subject: [PATCH 1/4] Be explicit about ownership info for memfs. --- samples/memfs/fs.go | 21 +++++++-------------- samples/memfs/memfs_test.go | 2 +- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/samples/memfs/fs.go b/samples/memfs/fs.go index 68489d4..a37784f 100644 --- a/samples/memfs/fs.go +++ b/samples/memfs/fs.go @@ -60,8 +60,11 @@ type memFS struct { freeInodes []fuse.InodeID // GUARDED_BY(mu) } -// Create a file system that stores data and metadata in memory. +// Create a file system that stores data and metadata in memory. The supplied +// UID/GID pair will own the root inode. func NewMemFS( + uid uint32, + gid uint32, clock timeutil.Clock) fuse.FileSystem { // Set up the basic struct. fs := &memFS{ @@ -69,10 +72,11 @@ func NewMemFS( inodes: make([]*inode, fuse.RootInodeID+1), } - // Set up the root inode. Its ownership information will later be modified in - // Init. + // Set up the root inode. rootAttrs := fuse.InodeAttributes{ Mode: 0700 | os.ModeDir, + Uid: uid, + Gid: gid, } fs.inodes[fuse.RootInodeID] = newInode(clock, rootAttrs) @@ -196,17 +200,6 @@ func (fs *memFS) Init( req *fuse.InitRequest) (resp *fuse.InitResponse, err error) { resp = &fuse.InitResponse{} - fs.mu.RLock() - defer fs.mu.RUnlock() - - // Update the root inode's ownership information to match the credentials of - // the mounting process. - root := fs.getInodeForModifyingOrDie(fuse.RootInodeID) - defer root.mu.Unlock() - - root.attributes.Uid = req.Header.Uid - root.attributes.Gid = req.Header.Gid - return } diff --git a/samples/memfs/memfs_test.go b/samples/memfs/memfs_test.go index 73cdda8..6b68f7e 100644 --- a/samples/memfs/memfs_test.go +++ b/samples/memfs/memfs_test.go @@ -111,7 +111,7 @@ func (t *MemFSTest) SetUp(ti *TestInfo) { } // Mount a file system. - fs := memfs.NewMemFS(&t.clock) + fs := memfs.NewMemFS(currentUid(), currentGid(), &t.clock) if t.mfs, err = fuse.Mount(mountPoint, fs); err != nil { panic("Mount: " + err.Error()) } From e31cb17e9c6dae10864486434c0911ca248b7a56 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 16 Mar 2015 13:40:04 +1100 Subject: [PATCH 2/4] Added some comments about default_permissions. --- file_system.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/file_system.go b/file_system.go index d8fd3ac..5d50c71 100644 --- a/file_system.go +++ b/file_system.go @@ -258,6 +258,27 @@ func init() { // http://goo.gl/tvYyQt). type InodeAttributes struct { Size uint64 + + // The mode of the inode. This is exposed to the user in e.g. the result of + // fstat(2). + // + // The permissions bits of the mode are not necessarily respected by the FUSE + // kernel layer unless the file system is mounted with the + // 'default_permissions' option (cf. http://goo.gl/1LxOop). + // + // For example, in the case of mkdir: + // + // * (http://goo.gl/JkdxDI) sys_mkdirat calls inode_permission. + // + // * (...) inode_permission eventually calls do_inode_permission. + // + // * (http://goo.gl/aGCsmZ) calls i_op->permission, which is + // fuse_permission (cf. http://goo.gl/VZ9beH). + // + // * (http://goo.gl/5kqUKO) fuse_permission doesn't do anything at all for + // several code paths if FUSE_DEFAULT_PERMISSIONS is unset. In contrast, + // if that flag *is* set, then it calls generic_permission. + // Mode os.FileMode // Time information. See `man 2 stat` for full details. From bc460087541a6bce20d15f2417dc1260a7478df6 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 16 Mar 2015 13:41:01 +1100 Subject: [PATCH 3/4] Mount memfs with the default_permissions option. This is necessary on Linux to make MemFSTest.Mkdir_PermissionDenied pass, for the reasons outlined in commit e31cb17. I don't quite understand why it doesn't come up on OS X. --- samples/memfs/memfs_test.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/samples/memfs/memfs_test.go b/samples/memfs/memfs_test.go index 6b68f7e..e332107 100644 --- a/samples/memfs/memfs_test.go +++ b/samples/memfs/memfs_test.go @@ -27,6 +27,7 @@ import ( "testing" "time" + bazilfuse "bazil.org/fuse" "github.com/jacobsa/fuse" "github.com/jacobsa/fuse/fusetesting" "github.com/jacobsa/fuse/samples/memfs" @@ -112,7 +113,13 @@ func (t *MemFSTest) SetUp(ti *TestInfo) { // Mount a file system. fs := memfs.NewMemFS(currentUid(), currentGid(), &t.clock) - if t.mfs, err = fuse.Mount(mountPoint, fs); err != nil { + + t.mfs, err = fuse.Mount( + mountPoint, + fs, + bazilfuse.DefaultPermissions()) + + if err != nil { panic("Mount: " + err.Error()) } From 27c8c0df9c02fa66b36c714e2d2853077bad7804 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 16 Mar 2015 13:44:18 +1100 Subject: [PATCH 4/4] Added a public note about default_permissions. --- samples/memfs/fs.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/samples/memfs/fs.go b/samples/memfs/fs.go index a37784f..b260cb4 100644 --- a/samples/memfs/fs.go +++ b/samples/memfs/fs.go @@ -60,8 +60,11 @@ type memFS struct { freeInodes []fuse.InodeID // GUARDED_BY(mu) } -// Create a file system that stores data and metadata in memory. The supplied -// UID/GID pair will own the root inode. +// Create a file system that stores data and metadata in memory. +// +// The supplied UID/GID pair will own the root inode. This file system does no +// permissions checking, and should therefore be mounted with the +// default_permissions option. func NewMemFS( uid uint32, gid uint32,