From bf5ffb5fd8558bd799791834def431c0cee5a11f Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 31 Jan 2011 16:32:46 +0100 Subject: Fix cleanup in case of failed mount In case of failure to add to /etc/mtab use same mountpoint for cleanup as for mounting. Reported by Marc Deslauriers --- util/fusermount.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'util') diff --git a/util/fusermount.c b/util/fusermount.c index 588d1bf..b367c40 100644 --- a/util/fusermount.c +++ b/util/fusermount.c @@ -1000,7 +1000,7 @@ static int check_version(const char *dev) } static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd, - int *mountpoint_fd) + int *mountpoint_fd, int *isdir) { int res; const char *mnt = *mntp; @@ -1018,6 +1018,7 @@ static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd, return 0; if (S_ISDIR(stbuf->st_mode)) { + *isdir = 1; *currdir_fd = open(".", O_RDONLY); if (*currdir_fd == -1) { fprintf(stderr, @@ -1025,10 +1026,16 @@ static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd, progname, strerror(errno)); return -1; } - res = chdir(mnt); + *mountpoint_fd = open(mnt, O_RDONLY); + if (*mountpoint_fd == -1) { + fprintf(stderr, "%s: failed to open %s: %s\n", + progname, mnt, strerror(errno)); + return -1; + } + res = fchdir(*mountpoint_fd); if (res == -1) { fprintf(stderr, - "%s: failed to chdir to mountpoint: %s\n", + "%s: failed to fchdir to mountpoint: %s\n", progname, strerror(errno)); return -1; } @@ -1154,6 +1161,7 @@ static int mount_fuse(const char *mnt, const char *opts) const char *real_mnt = mnt; int currdir_fd = -1; int mountpoint_fd = -1; + int isdir = 0; fd = open_fuse_device(&dev); if (fd == -1) @@ -1174,7 +1182,7 @@ static int mount_fuse(const char *mnt, const char *opts) res = check_version(dev); if (res != -1) { res = check_perm(&real_mnt, &stbuf, &currdir_fd, - &mountpoint_fd); + &mountpoint_fd, &isdir); restore_privs(); if (res != -1) res = do_mount(real_mnt, &type, stbuf.st_mode & S_IFMT, @@ -1188,22 +1196,37 @@ static int mount_fuse(const char *mnt, const char *opts) close(currdir_fd); } if (mountpoint_fd != -1) - close(mountpoint_fd); + fcntl(mountpoint_fd, F_SETFD, FD_CLOEXEC); if (res == -1) { close(fd); + if (mountpoint_fd != -1) + close(mountpoint_fd); return -1; } if (geteuid() == 0) { res = add_mount(source, mnt, type, mnt_opts); if (res == -1) { - umount2(mnt, UMOUNT_DETACH); /* lazy umount */ + if (isdir && mountpoint_fd != -1) { + res = fchdir(mountpoint_fd); + if (res == -1) { + close(mountpoint_fd); + close(fd); + return -1; + } + } + umount2(real_mnt, UMOUNT_DETACH); /* lazy umount */ + if (mountpoint_fd != -1) + close(mountpoint_fd); close(fd); return -1; } } + if (mountpoint_fd != -1) + close(mountpoint_fd); + free(source); free(type); free(mnt_opts); -- cgit v1.2.3