mirror of
https://github.com/libfuse/libfuse.git
synced 2024-11-26 21:54:30 +08:00
* Use '--no-canonicalize' option of mount(8) (available in
util-linux-ng version 2.17 or greater) to avoid calling readling(2) on the newly mounted filesystem before the mount procedure is finished. This has caused a deadlock if audit was enabled in the kernel. Also use '--no-canonicalize' for umount to avoid touching the mounted filesystem.
This commit is contained in:
parent
e61b775a5a
commit
4c3d9b1957
@ -1,3 +1,12 @@
|
||||
2009-12-17 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
* Use '--no-canonicalize' option of mount(8) (available in
|
||||
util-linux-ng version 2.17 or greater) to avoid calling
|
||||
readling(2) on the newly mounted filesystem before the mount
|
||||
procedure is finished. This has caused a deadlock if "audit" was
|
||||
enabled in the kernel. Also use '--no-canonicalize' for umount to
|
||||
avoid touching the mounted filesystem.
|
||||
|
||||
2009-09-11 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
* Released 2.8.1
|
||||
|
125
lib/mount_util.c
125
lib/mount_util.c
@ -13,6 +13,7 @@
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <mntent.h>
|
||||
#include <sys/stat.h>
|
||||
@ -53,17 +54,14 @@ static int mtab_needs_update(const char *mnt)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fuse_mnt_add_mount(const char *progname, const char *fsname,
|
||||
const char *mnt, const char *type, const char *opts)
|
||||
static int add_mount_legacy(const char *progname, const char *fsname,
|
||||
const char *mnt, const char *type, const char *opts)
|
||||
{
|
||||
int res;
|
||||
int status;
|
||||
sigset_t blockmask;
|
||||
sigset_t oldmask;
|
||||
|
||||
if (!mtab_needs_update(mnt))
|
||||
return 0;
|
||||
|
||||
sigemptyset(&blockmask);
|
||||
sigaddset(&blockmask, SIGCHLD);
|
||||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
|
||||
@ -116,24 +114,18 @@ int fuse_mnt_add_mount(const char *progname, const char *fsname,
|
||||
|
||||
out_restore:
|
||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int fuse_mnt_umount(const char *progname, const char *mnt, int lazy)
|
||||
static int add_mount(const char *progname, const char *fsname,
|
||||
const char *mnt, const char *type, const char *opts)
|
||||
{
|
||||
int res;
|
||||
int status;
|
||||
sigset_t blockmask;
|
||||
sigset_t oldmask;
|
||||
|
||||
if (!mtab_needs_update(mnt)) {
|
||||
res = umount2(mnt, lazy ? 2 : 0);
|
||||
if (res == -1)
|
||||
fprintf(stderr, "%s: failed to unmount %s: %s\n",
|
||||
progname, mnt, strerror(errno));
|
||||
return res;
|
||||
}
|
||||
|
||||
sigemptyset(&blockmask);
|
||||
sigaddset(&blockmask, SIGCHLD);
|
||||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
|
||||
@ -148,10 +140,91 @@ int fuse_mnt_umount(const char *progname, const char *mnt, int lazy)
|
||||
goto out_restore;
|
||||
}
|
||||
if (res == 0) {
|
||||
/*
|
||||
* Hide output, because old versions don't support
|
||||
* --no-canonicalize
|
||||
*/
|
||||
int fd = open("/dev/null", O_RDONLY);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
|
||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
setuid(geteuid());
|
||||
execl("/bin/umount", "/bin/umount", "-i", mnt,
|
||||
lazy ? "-l" : NULL, NULL);
|
||||
execl("/bin/mount", "/bin/mount", "--no-canonicalize", "-i",
|
||||
"-f", "-t", type, "-o", opts, fsname, mnt, NULL);
|
||||
fprintf(stderr, "%s: failed to execute /bin/mount: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
res = waitpid(res, &status, 0);
|
||||
if (res == -1)
|
||||
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
|
||||
|
||||
if (status != 0)
|
||||
res = -1;
|
||||
|
||||
out_restore:
|
||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int fuse_mnt_add_mount(const char *progname, const char *fsname,
|
||||
const char *mnt, const char *type, const char *opts)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (!mtab_needs_update(mnt))
|
||||
return 0;
|
||||
|
||||
res = add_mount(progname, fsname, mnt, type, opts);
|
||||
if (res == -1)
|
||||
res = add_mount_legacy(progname, fsname, mnt, type, opts);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int exec_umount(const char *progname, const char *mnt, int lazy,
|
||||
int legacy)
|
||||
{
|
||||
int res;
|
||||
int status;
|
||||
sigset_t blockmask;
|
||||
sigset_t oldmask;
|
||||
|
||||
sigemptyset(&blockmask);
|
||||
sigaddset(&blockmask, SIGCHLD);
|
||||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
|
||||
if (res == -1) {
|
||||
fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = fork();
|
||||
if (res == -1) {
|
||||
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
|
||||
goto out_restore;
|
||||
}
|
||||
if (res == 0) {
|
||||
/*
|
||||
* Hide output, because old versions don't support
|
||||
* --no-canonicalize
|
||||
*/
|
||||
if (!legacy) {
|
||||
int fd = open("/dev/null", O_RDONLY);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
}
|
||||
|
||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
setuid(geteuid());
|
||||
if (legacy) {
|
||||
execl("/bin/umount", "/bin/umount", "-i", mnt,
|
||||
lazy ? "-l" : NULL, NULL);
|
||||
} else {
|
||||
execl("/bin/umount", "/bin/umount", "--no-canonicalize",
|
||||
"-i", mnt, lazy ? "-l" : NULL, NULL);
|
||||
}
|
||||
fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
@ -166,6 +239,26 @@ int fuse_mnt_umount(const char *progname, const char *mnt, int lazy)
|
||||
out_restore:
|
||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
int fuse_mnt_umount(const char *progname, const char *mnt, int lazy)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (!mtab_needs_update(mnt)) {
|
||||
res = umount2(mnt, lazy ? 2 : 0);
|
||||
if (res == -1)
|
||||
fprintf(stderr, "%s: failed to unmount %s: %s\n",
|
||||
progname, mnt, strerror(errno));
|
||||
return res;
|
||||
}
|
||||
|
||||
res = exec_umount(progname, mnt, lazy, 0);
|
||||
if (res == -1)
|
||||
res = exec_umount(progname, mnt, lazy, 1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
char *fuse_mnt_resolve_path(const char *progname, const char *orig)
|
||||
|
Loading…
Reference in New Issue
Block a user