diff options
author | Matthias Görgens <matthias.goergens@gmail.com> | 2023-04-12 15:39:32 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-12 08:39:32 +0100 |
commit | 7297044ada625da583211f0a574410cddb4f7d8d (patch) | |
tree | fa4a6fa67325614526f06fb9eae6c1d039eb64a6 /util/fusermount.c | |
parent | 681a0c1178fa93017a363a901d0348710582e90b (diff) | |
download | fuse-7297044ada625da583211f0a574410cddb4f7d8d.tar.gz |
Fuse mount: make auto_unmount compatible with suid/dev mount options (#762)
* Fuse mount: make auto_unmount compatible with suid/dev mount options
> When you run as root, fuse normally does not call fusermount but uses
> the mount system call directly. When you specify auto_unmount, it goes
> through fusermount instead. However, fusermount is a setuid binary that
> is normally called by regular users, so it cannot in general accept suid
> or dev options.
In this patch, we split up how fuse mounts as root when `auto_unmount`
is specified.
First, we mount using system calls directly, then we reach out to
fusermount to set up auto_unmount only (with no actual mounting done in
fusermount).
Fixes: #148
Diffstat (limited to 'util/fusermount.c')
-rw-r--r-- | util/fusermount.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/util/fusermount.c b/util/fusermount.c index 32d3fbd..034383e 100644 --- a/util/fusermount.c +++ b/util/fusermount.c @@ -1356,9 +1356,13 @@ int main(int argc, char *argv[]) int cfd; const char *opts = ""; const char *type = NULL; + int setup_auto_unmount_only = 0; static const struct option long_opts[] = { {"unmount", no_argument, NULL, 'u'}, + // Note: auto-unmount deliberately does not have a short version. + // It's meant for internal use by mount.c's setup_auto_unmount. + {"auto-unmount", no_argument, NULL, 'U'}, {"lazy", no_argument, NULL, 'z'}, {"quiet", no_argument, NULL, 'q'}, {"help", no_argument, NULL, 'h'}, @@ -1390,7 +1394,11 @@ int main(int argc, char *argv[]) case 'u': unmount = 1; break; - + case 'U': + unmount = 1; + auto_unmount = 1; + setup_auto_unmount_only = 1; + break; case 'z': lazy = 1; break; @@ -1434,7 +1442,7 @@ int main(int argc, char *argv[]) exit(1); umask(033); - if (unmount) + if (!setup_auto_unmount_only && unmount) goto do_unmount; commfd = getenv(FUSE_COMMFD_ENV); @@ -1444,11 +1452,15 @@ int main(int argc, char *argv[]) goto err_out; } + cfd = atoi(commfd); + + if (setup_auto_unmount_only) + goto wait_for_auto_unmount; + fd = mount_fuse(mnt, opts, &type); if (fd == -1) goto err_out; - cfd = atoi(commfd); res = send_fd(cfd, fd); if (res == -1) goto err_out; @@ -1459,6 +1471,7 @@ int main(int argc, char *argv[]) return 0; } +wait_for_auto_unmount: /* Become a daemon and wait for the parent to exit or die. ie For the control socket to get closed. btw We don't want to use daemon() function here because |