summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/fuse-lib/mount-common.c22
-rw-r--r--contrib/fuse-lib/mount.c1
-rw-r--r--contrib/fuse-util/fusermount.c87
3 files changed, 62 insertions, 48 deletions
diff --git a/contrib/fuse-lib/mount-common.c b/contrib/fuse-lib/mount-common.c
index 7411e56..fd6cce4 100644
--- a/contrib/fuse-lib/mount-common.c
+++ b/contrib/fuse-lib/mount-common.c
@@ -20,10 +20,11 @@
* - there are some other minor things
*
* For changes that were made later and syncs with upstream,
- * see the commit log.
+ * see the commit log and per-function comments.
*/
#ifndef __NetBSD__
+/* FUSE: cherry-picked bd99f9cf */
static int
mtab_needs_update (const char *mnt)
{
@@ -47,11 +48,22 @@ mtab_needs_update (const char *mnt)
if (errno == ENOENT)
return 0;
} else {
+ uid_t ruid;
+ int err;
+
if (S_ISLNK (stbuf.st_mode))
return 0;
+ ruid = getuid ();
+ if (ruid != 0)
+ setreuid (0, -1);
+
res = access (_PATH_MOUNTED, W_OK);
- if (res == -1 && errno == EROFS)
+ err = (res == -1) ? errno : 0;
+ if (ruid != 0)
+ setreuid (ruid, -1);
+
+ if (err == EROFS)
return 0;
}
@@ -61,6 +73,7 @@ mtab_needs_update (const char *mnt)
#define mtab_needs_update(x) 1
#endif /* __NetBSD__ */
+/* FUSE: called add_mount_legacy(); R.I.P. as of cbd3a2a8 */
int
fuse_mnt_add_mount (const char *progname, const char *fsname,
const char *mnt, const char *type, const char *opts)
@@ -194,6 +207,11 @@ fuse_mnt_resolve_path (const char *progname, const char *orig)
return dst;
}
+/* FUSE: to support some changes that were reverted since
+ * then, it was split in two (fuse_mnt_umount() and
+ * exec_umount()); however the actual code is same as here
+ * since 0197ce40
+ */
int
fuse_mnt_umount (const char *progname, const char *abs_mnt,
const char *rel_mnt, int lazy)
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c
index 8787064..f02a835 100644
--- a/contrib/fuse-lib/mount.c
+++ b/contrib/fuse-lib/mount.c
@@ -18,6 +18,7 @@
#define FUSE_DEVFD_ENV "_FUSE_DEVFD"
+/* FUSE: function is called fuse_kern_unmount() */
void
gf_fuse_unmount (const char *mountpoint, int fd)
{
diff --git a/contrib/fuse-util/fusermount.c b/contrib/fuse-util/fusermount.c
index 4e7e4f9..9a89525 100644
--- a/contrib/fuse-util/fusermount.c
+++ b/contrib/fuse-util/fusermount.c
@@ -116,8 +116,16 @@ static int lock_umount(void)
static void unlock_umount(int mtablock)
{
- lockf(mtablock, F_ULOCK, 0);
- close(mtablock);
+ if (mtablock >= 0) {
+ int res;
+
+ res = lockf(mtablock, F_ULOCK, 0);
+ if (res < 0) {
+ fprintf(stderr, "%s: error releasing lock: %s\n",
+ progname, strerror(errno));
+ }
+ close(mtablock);
+ }
}
static int add_mount(const char *source, const char *mnt, const char *type,
@@ -240,7 +248,7 @@ static int check_is_mount_child(void *p)
}
count = 0;
- while ((entp = getmntent(fp)) != NULL)
+ while (getmntent(fp) != NULL)
count++;
endmntent(fp);
@@ -327,7 +335,7 @@ static int check_is_mount(const char *last, const char *mnt)
return 0;
}
-static int chdir_to_parent(char *copy, const char **lastp, int *currdir_fd)
+static int chdir_to_parent(char *copy, const char **lastp)
{
char *tmp;
const char *parent;
@@ -352,14 +360,6 @@ static int chdir_to_parent(char *copy, const char **lastp, int *currdir_fd)
parent = "/";
}
- *currdir_fd = open(".", O_RDONLY);
- if (*currdir_fd == -1) {
- fprintf(stderr,
- "%s: failed to open current directory: %s\n",
- progname, strerror(errno));
- return -1;
- }
-
res = chdir(parent);
if (res == -1) {
fprintf(stderr, "%s: failed to chdir to %s: %s\n",
@@ -384,7 +384,6 @@ static int chdir_to_parent(char *copy, const char **lastp, int *currdir_fd)
static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
{
- int currdir_fd = -1;
char *copy;
const char *last;
int res;
@@ -401,7 +400,7 @@ static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
return -1;
}
- res = chdir_to_parent(copy, &last, &currdir_fd);
+ res = chdir_to_parent(copy, &last);
if (res == -1)
goto out;
@@ -413,10 +412,6 @@ static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
out:
free(copy);
- if (currdir_fd != -1) {
- fchdir(currdir_fd);
- close(currdir_fd);
- }
return res;
}
@@ -825,15 +820,14 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode,
fprintf(stderr, "%s: mount failed: %s\n", progname,
strerror(errno_save));
goto err;
- } else {
- *sourcep = source;
- *typep = type;
- *mnt_optsp = mnt_opts;
}
+ *sourcep = source;
+ *typep = type;
+ *mnt_optsp = mnt_opts;
free(fsname);
free(optbuf);
- return res;
+ return 0;
err:
free(fsname);
@@ -876,8 +870,7 @@ static int check_version(const char *dev)
return 0;
}
-static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd,
- int *mountpoint_fd)
+static int check_perm(const char **mntp, struct stat *stbuf, int *mountpoint_fd)
{
int res;
const char *mnt = *mntp;
@@ -895,13 +888,6 @@ static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd,
return 0;
if (S_ISDIR(stbuf->st_mode)) {
- *currdir_fd = open(".", O_RDONLY);
- if (*currdir_fd == -1) {
- fprintf(stderr,
- "%s: failed to open current directory: %s\n",
- progname, strerror(errno));
- return -1;
- }
res = chdir(mnt);
if (res == -1) {
fprintf(stderr,
@@ -1057,7 +1043,6 @@ static int mount_fuse(const char *mnt, const char *opts, char *devfd)
char *source = NULL;
char *mnt_opts = NULL;
const char *real_mnt = mnt;
- int currdir_fd = -1;
int mountpoint_fd = -1;
fd = devfd ? check_fuse_device(devfd, &dev) : open_fuse_device(&dev);
@@ -1071,15 +1056,13 @@ static int mount_fuse(const char *mnt, const char *opts, char *devfd)
int mount_count = count_fuse_fs();
if (mount_count >= mount_max) {
fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in /etc/fuse.conf\n", progname);
- close(fd);
- return -1;
+ goto fail_close_fd;
}
}
res = check_version(dev);
if (res != -1) {
- res = check_perm(&real_mnt, &stbuf, &currdir_fd,
- &mountpoint_fd);
+ res = check_perm(&real_mnt, &stbuf, &mountpoint_fd);
restore_privs();
if (res != -1)
res = do_mount(real_mnt, &type, stbuf.st_mode & S_IFMT,
@@ -1088,33 +1071,38 @@ static int mount_fuse(const char *mnt, const char *opts, char *devfd)
} else
restore_privs();
- if (currdir_fd != -1) {
- fchdir(currdir_fd);
- close(currdir_fd);
- }
if (mountpoint_fd != -1)
close(mountpoint_fd);
+ if (res == -1)
+ goto fail_close_fd;
+
+ res = chdir("/");
if (res == -1) {
- close(fd);
- return -1;
+ fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
+ goto fail_close_fd;
}
if (geteuid() == 0) {
res = add_mount(source, mnt, type, mnt_opts);
if (res == -1) {
- umount2(mnt, 2); /* lazy umount */
- close(fd);
- return -1;
+ /* Can't clean up mount in a non-racy way */
+ goto fail_close_fd;
}
}
+out_free:
free(source);
free(type);
free(mnt_opts);
free(dev);
return fd;
+
+fail_close_fd:
+ close(fd);
+ fd = -1;
+ goto out_free;
}
static int send_fd(int sock_fd, int fd)
@@ -1253,6 +1241,13 @@ int main(int argc, char *argv[])
drop_privs();
mnt = fuse_mnt_resolve_path(progname, origmnt);
+ if (mnt != NULL) {
+ res = chdir("/");
+ if (res == -1) {
+ fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
+ exit(1);
+ }
+ }
restore_privs();
if (mnt == NULL)
exit(1);