aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2010-01-26 18:20:13 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2010-01-26 18:20:13 +0000
commit8b3a0c74a15e237eb4b7053774600f0ce3fff403 (patch)
tree9de3b1b3a5110c94449bc794565bd1aedb1e4c86 /lib
parentd29bc735ad9d10ca2d71e772d432983c8618fb26 (diff)
* Fix race if two "fusermount -u" instances are run in parallel.
Reported by Dan Rosenberg * Make sure that the path to be unmounted doesn't refer to a symlink
Diffstat (limited to 'lib')
-rw-r--r--lib/mount.c2
-rw-r--r--lib/mount_util.c31
-rw-r--r--lib/mount_util.h3
3 files changed, 20 insertions, 16 deletions
diff --git a/lib/mount.c b/lib/mount.c
index 941644f..c3b16a4 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -290,7 +290,7 @@ void fuse_kern_unmount(const char *mountpoint, int fd)
}
if (geteuid() == 0) {
- fuse_mnt_umount("fuse", mountpoint, 1);
+ fuse_mnt_umount("fuse", mountpoint, mountpoint, 1);
return;
}
diff --git a/lib/mount_util.c b/lib/mount_util.c
index 3b6e771..e18e7a4 100644
--- a/lib/mount_util.c
+++ b/lib/mount_util.c
@@ -184,13 +184,13 @@ int fuse_mnt_add_mount(const char *progname, const char *fsname,
return res;
}
-static int exec_umount(const char *progname, const char *mnt, int lazy,
- int legacy)
+static int exec_umount(const char *progname, const char *rel_mnt, int lazy)
{
int res;
int status;
sigset_t blockmask;
sigset_t oldmask;
+ int legacy = 0;
sigemptyset(&blockmask);
sigaddset(&blockmask, SIGCHLD);
@@ -200,6 +200,7 @@ static int exec_umount(const char *progname, const char *mnt, int lazy,
return -1;
}
+retry_umount:
res = fork();
if (res == -1) {
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
@@ -219,11 +220,11 @@ static int exec_umount(const char *progname, const char *mnt, int lazy,
sigprocmask(SIG_SETMASK, &oldmask, NULL);
setuid(geteuid());
if (legacy) {
- execl("/bin/umount", "/bin/umount", "-i", mnt,
+ execl("/bin/umount", "/bin/umount", "-i", rel_mnt,
lazy ? "-l" : NULL, NULL);
} else {
execl("/bin/umount", "/bin/umount", "--no-canonicalize",
- "-i", mnt, lazy ? "-l" : NULL, NULL);
+ "-i", rel_mnt, lazy ? "-l" : NULL, NULL);
}
fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
progname, strerror(errno));
@@ -233,8 +234,13 @@ static int exec_umount(const char *progname, const char *mnt, int lazy,
if (res == -1)
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
- if (status != 0)
+ if (status != 0) {
+ if (!legacy) {
+ legacy = 1;
+ goto retry_umount;
+ }
res = -1;
+ }
out_restore:
sigprocmask(SIG_SETMASK, &oldmask, NULL);
@@ -242,23 +248,20 @@ static int exec_umount(const char *progname, const char *mnt, int lazy,
}
-int fuse_mnt_umount(const char *progname, const char *mnt, int lazy)
+int fuse_mnt_umount(const char *progname, const char *abs_mnt,
+ const char *rel_mnt, int lazy)
{
int res;
- if (!mtab_needs_update(mnt)) {
- res = umount2(mnt, lazy ? 2 : 0);
+ if (!mtab_needs_update(abs_mnt)) {
+ res = umount2(rel_mnt, lazy ? 2 : 0);
if (res == -1)
fprintf(stderr, "%s: failed to unmount %s: %s\n",
- progname, mnt, strerror(errno));
+ progname, abs_mnt, strerror(errno));
return res;
}
- res = exec_umount(progname, mnt, lazy, 0);
- if (res == -1)
- res = exec_umount(progname, mnt, lazy, 1);
-
- return res;
+ return exec_umount(progname, rel_mnt, lazy);
}
char *fuse_mnt_resolve_path(const char *progname, const char *orig)
diff --git a/lib/mount_util.h b/lib/mount_util.h
index cf54d9d..f392f99 100644
--- a/lib/mount_util.h
+++ b/lib/mount_util.h
@@ -10,7 +10,8 @@
int fuse_mnt_add_mount(const char *progname, const char *fsname,
const char *mnt, const char *type, const char *opts);
-int fuse_mnt_umount(const char *progname, const char *mnt, int lazy);
+int fuse_mnt_umount(const char *progname, const char *abs_mnt,
+ const char *rel_mnt, int lazy);
char *fuse_mnt_resolve_path(const char *progname, const char *orig);
int fuse_mnt_check_empty(const char *progname, const char *mnt,
mode_t rootmode, off_t rootsize);