aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <mszeredi@suse.cz>2011-01-31 16:32:46 +0100
committerGravatar Miklos Szeredi <mszeredi@suse.cz>2011-01-31 16:32:46 +0100
commitbf5ffb5fd8558bd799791834def431c0cee5a11f (patch)
treef5dc07af7dad5b841181a77eef3d3dfa2063a200 /util
parentc958643e37a52364c5d8059ccd1cadb7be1cb259 (diff)
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
Diffstat (limited to 'util')
-rw-r--r--util/fusermount.c35
1 files changed, 29 insertions, 6 deletions
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);