aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cmd/sharefs/fuse.go25
-rw-r--r--cmd/sharefs/test/test.py9
-rw-r--r--nixos.nix7
3 files changed, 36 insertions, 5 deletions
diff --git a/cmd/sharefs/fuse.go b/cmd/sharefs/fuse.go
index bbbc1446..9a0a0149 100644
--- a/cmd/sharefs/fuse.go
+++ b/cmd/sharefs/fuse.go
@@ -53,6 +53,9 @@ type (
// Whether sharefs_init failed.
initFailed bool
+ // Whether to create source directory as root.
+ mkdir bool
+
// Open file descriptor to fuse.
Fuse int
@@ -157,6 +160,9 @@ func parseOpts(args *fuseArgs, setup *setupState, log *log.Logger) (ok bool) {
// Pathname to writable source directory.
source *C.char
+ // Whether to create source directory as root.
+ mkdir C.int
+
// Decimal string representation of uid to set when running as root.
setuid *C.char
// Decimal string representation of gid to set when running as root.
@@ -169,6 +175,7 @@ func parseOpts(args *fuseArgs, setup *setupState, log *log.Logger) (ok bool) {
if C.fuse_opt_parse(args, unsafe.Pointer(&unsafeOpts), &[]C.struct_fuse_opt{
{templ: C.CString("source=%s"), offset: C.ulong(unsafe.Offsetof(unsafeOpts.source)), value: 0},
+ {templ: C.CString("mkdir"), offset: C.ulong(unsafe.Offsetof(unsafeOpts.mkdir)), value: 1},
{templ: C.CString("setuid=%s"), offset: C.ulong(unsafe.Offsetof(unsafeOpts.setuid)), value: 0},
{templ: C.CString("setgid=%s"), offset: C.ulong(unsafe.Offsetof(unsafeOpts.setgid)), value: 0},
@@ -223,6 +230,7 @@ func parseOpts(args *fuseArgs, setup *setupState, log *log.Logger) (ok bool) {
} else {
setup.Source = a
}
+ setup.mkdir = unsafeOpts.mkdir != 0
if unsafeOpts.setuid == nil {
setup.Setuid = -1
@@ -339,6 +347,9 @@ func _main(s ...string) (exitCode int) {
} else if setup.Fuse < 3 && (setup.Setuid > 0 || setup.Setgid > 0) {
log.Println("setuid and setgid has no effect when not starting as root")
return 1
+ } else if setup.mkdir {
+ log.Println("mkdir has no effect when not starting as root")
+ return 1
}
op := C.struct_fuse_operations{
@@ -387,6 +398,20 @@ func _main(s ...string) (exitCode int) {
log.Println("setuid and setgid must not be 0")
return 5
}
+
+ if setup.mkdir {
+ if err := os.MkdirAll(setup.Source.String(), 0700); err != nil {
+ if !errors.Is(err, os.ErrExist) {
+ log.Println(err)
+ return 5
+ }
+ // skip setup for existing source directory
+ } else if err = os.Chown(setup.Source.String(), setup.Setuid, setup.Setgid); err != nil {
+ log.Println(err)
+ return 5
+ }
+ }
+
if err := syscall.Setresgid(setup.Setgid, setup.Setgid, setup.Setgid); err != nil {
log.Printf("cannot set gid: %v", err)
return 5
diff --git a/cmd/sharefs/test/test.py b/cmd/sharefs/test/test.py
index 969bfa56..666feb5a 100644
--- a/cmd/sharefs/test/test.py
+++ b/cmd/sharefs/test/test.py
@@ -27,6 +27,7 @@ check_bad_opts_output("setgid=-1", "sharefs: invalid value for option setgid\n")
check_bad_opts_output("setuid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
check_bad_opts_output("setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
check_bad_opts_output("setuid=1023,setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
+check_bad_opts_output("mkdir", "sharefs: mkdir has no effect when not starting as root\n")
# Starting as root without setuid/setgid:
check_bad_opts_output("allow_other", "sharefs: setuid and setgid must not be 0\n", privileged=True)
@@ -37,6 +38,14 @@ check_bad_opts_output("setgid=1023", "sharefs: setuid and setgid must not be 0\n
machine.fail("umount /mnt")
machine.succeed("rmdir /mnt")
+# Unprivileged mount/unmount:
+machine.succeed("sudo -u alice -i mkdir /home/alice/{sdcard,persistent}")
+machine.succeed("sudo -u alice -i /etc/sharefs -o source=/home/alice/persistent /home/alice/sdcard")
+machine.succeed("sudo -u alice -i touch /home/alice/sdcard/check")
+machine.succeed("sudo -u alice -i umount /home/alice/sdcard")
+machine.succeed("sudo -u alice -i rm /home/alice/persistent/check")
+machine.succeed("sudo -u alice -i rmdir /home/alice/{sdcard,persistent}")
+
# Benchmark sharefs:
machine.succeed("fs_mark -v -d /sdcard/fs_mark -l /tmp/fs_log.txt")
machine.copy_from_vm("/tmp/fs_log.txt", "")
diff --git a/nixos.nix b/nixos.nix
index cccc1810..35486679 100644
--- a/nixos.nix
+++ b/nixos.nix
@@ -73,11 +73,7 @@ in
NoNewPrivileges = true;
};
script = ''
- ${pkgs.coreutils}/bin/install \
- -dm0700 \
- -o ${cfg.sharefs.user} \
- -g ${cfg.sharefs.group} \
- ${cfg.sharefs.source} ${cfg.sharefs.name}
+ ${pkgs.coreutils}/bin/install -dm0 ${cfg.sharefs.name}
exec ${cfg.package}/libexec/sharefs -f \
-o ${
@@ -91,6 +87,7 @@ in
"setuid=$(id -u ${cfg.sharefs.user})"
"setgid=$(id -g ${cfg.sharefs.group})"
"source=${cfg.sharefs.source}"
+ "mkdir"
]
} ${cfg.sharefs.name}
'';