diff --git a/cmd/sharefs/fuse.go b/cmd/sharefs/fuse.go index bbbc144..9a0a014 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 969bfa5..666feb5 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 cccc181..3548667 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} '';