Skip to content

Commit cbd3a2a

Browse files
author
Miklos Szeredi
committed
fusermount: only allow mount and umount if util-linux suppports --no-canonicalize
Remove "legacy" util-linux support as missing --no-canonicalize cannot be worked around in fuse.
1 parent 1e7607f commit cbd3a2a

4 files changed

Lines changed: 36 additions & 212 deletions

File tree

ChangeLog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
* fusermount: chdir to / before performing mount/umount
77

8+
* fusermount: only allow mount and umount if util-linux supports
9+
--no-canonicalize
10+
811
2010-12-16 Miklos Szeredi <[email protected]>
912

1013
* Highlevel lib: allow hash tables to shrink

configure.in

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ AC_ARG_ENABLE(example,
3333
[ --enable-example Compile with examples ])
3434
AC_ARG_ENABLE(mtab,
3535
[ --disable-mtab Disable and ignore usage of /etc/mtab ])
36-
AC_ARG_ENABLE(legacy-umount,
37-
[ --disable-legacy-umount If umount(8) is util-linux-ng >= 2.18 ])
3836

3937
AC_ARG_WITH(pkgconfigdir,
4038
[ --with-pkgconfigdir=DIR pkgconfig file in DIR @<:@LIBDIR/pkgconfig@:>@],
@@ -57,10 +55,6 @@ if test "$enable_mtab" = "no"; then
5755
AC_DEFINE(IGNORE_MTAB, 1, [Don't update /etc/mtab])
5856
fi
5957

60-
if test "$enable_legacy_umount" != "no"; then
61-
AC_DEFINE(LEGACY_UMOUNT, 1, [Enable legacy umount support])
62-
fi
63-
6458
AC_CHECK_FUNCS([fork setxattr fdatasync])
6559
AC_CHECK_MEMBERS([struct stat.st_atim])
6660
AC_CHECK_MEMBERS([struct stat.st_atimespec])

lib/mount_util.c

Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -73,70 +73,6 @@ static int mtab_needs_update(const char *mnt)
7373
}
7474
#endif /* __NetBSD__ */
7575

76-
static int add_mount_legacy(const char *progname, const char *fsname,
77-
const char *mnt, const char *type, const char *opts)
78-
{
79-
int res;
80-
int status;
81-
sigset_t blockmask;
82-
sigset_t oldmask;
83-
84-
sigemptyset(&blockmask);
85-
sigaddset(&blockmask, SIGCHLD);
86-
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
87-
if (res == -1) {
88-
fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno));
89-
return -1;
90-
}
91-
92-
res = fork();
93-
if (res == -1) {
94-
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
95-
goto out_restore;
96-
}
97-
if (res == 0) {
98-
char templ[] = "/tmp/fusermountXXXXXX";
99-
char *tmp;
100-
101-
sigprocmask(SIG_SETMASK, &oldmask, NULL);
102-
setuid(geteuid());
103-
104-
/*
105-
* hide in a directory, where mount isn't able to resolve
106-
* fsname as a valid path
107-
*/
108-
tmp = mkdtemp(templ);
109-
if (!tmp) {
110-
fprintf(stderr,
111-
"%s: failed to create temporary directory\n",
112-
progname);
113-
exit(1);
114-
}
115-
if (chdir(tmp)) {
116-
fprintf(stderr, "%s: failed to chdir to %s: %s\n",
117-
progname, tmp, strerror(errno));
118-
exit(1);
119-
}
120-
rmdir(tmp);
121-
execl("/bin/mount", "/bin/mount", "-i", "-f", "-t", type,
122-
"-o", opts, fsname, mnt, NULL);
123-
fprintf(stderr, "%s: failed to execute /bin/mount: %s\n",
124-
progname, strerror(errno));
125-
exit(1);
126-
}
127-
res = waitpid(res, &status, 0);
128-
if (res == -1)
129-
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
130-
131-
if (status != 0)
132-
res = -1;
133-
134-
out_restore:
135-
sigprocmask(SIG_SETMASK, &oldmask, NULL);
136-
137-
return res;
138-
}
139-
14076
static int add_mount(const char *progname, const char *fsname,
14177
const char *mnt, const char *type, const char *opts)
14278
{
@@ -191,16 +127,10 @@ static int add_mount(const char *progname, const char *fsname,
191127
int fuse_mnt_add_mount(const char *progname, const char *fsname,
192128
const char *mnt, const char *type, const char *opts)
193129
{
194-
int res;
195-
196130
if (!mtab_needs_update(mnt))
197131
return 0;
198132

199-
res = add_mount(progname, fsname, mnt, type, opts);
200-
if (res == -1)
201-
res = add_mount_legacy(progname, fsname, mnt, type, opts);
202-
203-
return res;
133+
return add_mount(progname, fsname, mnt, type, opts);
204134
}
205135

206136
static int exec_umount(const char *progname, const char *rel_mnt, int lazy)

util/fusermount.c

Lines changed: 32 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -382,54 +382,6 @@ static int chdir_to_parent(char *copy, const char **lastp)
382382
return 0;
383383
}
384384

385-
static int unmount_fuse_legacy(const char *mnt, int lazy)
386-
{
387-
char *copy;
388-
const char *last;
389-
int res;
390-
391-
copy = strdup(mnt);
392-
if (copy == NULL) {
393-
fprintf(stderr, "%s: failed to allocate memory\n", progname);
394-
return -1;
395-
}
396-
397-
res = chdir_to_parent(copy, &last);
398-
if (res == -1)
399-
goto out;
400-
401-
res = check_is_mount(last, mnt);
402-
if (res == -1)
403-
goto out;
404-
405-
res = fuse_mnt_umount(progname, mnt, last, lazy);
406-
407-
out:
408-
free(copy);
409-
410-
return res;
411-
}
412-
413-
static int unmount_fuse_nofollow(const char *mnt, int quiet, int lazy)
414-
{
415-
int res;
416-
int umount_flags = UMOUNT_NOFOLLOW;
417-
418-
if (lazy)
419-
umount_flags |= UMOUNT_DETACH;
420-
421-
res = umount2(mnt, umount_flags);
422-
if (res == -1) {
423-
if (!quiet) {
424-
fprintf(stderr, "%s: failed to unmount %s: %s\n",
425-
progname, mnt, strerror(errno));
426-
}
427-
return -1;
428-
}
429-
430-
return fuse_mnt_remove_mount(progname, mnt);
431-
}
432-
433385
/* Check whether the kernel supports UMOUNT_NOFOLLOW flag */
434386
static int umount_nofollow_support(void)
435387
{
@@ -444,104 +396,49 @@ static int umount_nofollow_support(void)
444396
return 1;
445397
}
446398

447-
#ifdef LEGACY_UMOUNT
448-
/* Check if umount(8) supports "--fake" and "--no-canonicalize" options */
449-
static int umount_fake_support(void)
450-
{
451-
int res;
452-
int status;
453-
sigset_t blockmask;
454-
sigset_t oldmask;
455-
int pip[2];
456-
char buf[1024];
457-
char *s;
458-
unsigned majver;
459-
unsigned minver;
460-
int supported = 0;
461-
int pid;
462-
463-
res = pipe(pip);
464-
if (res == -1)
465-
return 0;
466-
467-
sigemptyset(&blockmask);
468-
sigaddset(&blockmask, SIGCHLD);
469-
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
470-
if (res == -1)
471-
goto out_close;
472-
473-
pid = fork();
474-
if (pid == -1)
475-
goto out_restore;
476-
477-
if (pid == 0) {
478-
int nullfd;
479-
480-
close(pip[0]);
481-
dup2(pip[1], 1);
482-
if (pip[1] != 1)
483-
close(pip[1]);
484-
nullfd = open("/dev/null", O_WRONLY);
485-
dup2(nullfd, 2);
486-
sigprocmask(SIG_SETMASK, &oldmask, NULL);
487-
setuid(getuid());
488-
execl("/bin/umount", "/bin/umount", "--version", NULL);
489-
exit(1);
490-
}
491-
res = read(pip[0], buf, sizeof(buf));
492-
if (res == -1 || res == sizeof(buf))
493-
buf[0] = '\0';
494-
else
495-
buf[res] = '\0';
496-
497-
res = waitpid(pid, &status, 0);
498-
if (res == -1 || status != 0)
499-
goto out_restore;
500-
501-
s = strstr(buf, "util-linux-ng ");
502-
if (s == NULL)
503-
goto out_restore;
504-
505-
s += 14;
506-
if (sscanf(s, "%u.%u", &majver, &minver) < 2)
507-
goto out_restore;
508-
509-
if (majver < 2 || (majver == 2 && minver < 18))
510-
goto out_restore;
511-
512-
supported = 1;
513-
514-
out_restore:
515-
sigprocmask(SIG_SETMASK, &oldmask, NULL);
516-
out_close:
517-
close(pip[0]);
518-
close(pip[1]);
519-
520-
return supported;
521-
}
522-
#else
523-
static int umount_fake_support(void)
524-
{
525-
return 1;
526-
}
527-
#endif
528-
529399
static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
530400
{
531401
int res;
402+
char *copy;
403+
const char *last;
404+
int umount_flags = lazy ? UMOUNT_DETACH : 0;
532405

533406
if (getuid() != 0) {
534407
res = may_unmount(mnt, quiet);
535408
if (res == -1)
536409
return -1;
537410
}
538411

539-
if (umount_nofollow_support() && umount_fake_support())
540-
res = unmount_fuse_nofollow(mnt, quiet, lazy);
541-
else
542-
res = unmount_fuse_legacy(mnt, lazy);
412+
copy = strdup(mnt);
413+
if (copy == NULL) {
414+
fprintf(stderr, "%s: failed to allocate memory\n", progname);
415+
return -1;
416+
}
543417

544-
return res;
418+
res = chdir_to_parent(copy, &last);
419+
if (res == -1)
420+
goto out;
421+
422+
if (umount_nofollow_support()) {
423+
umount_flags |= UMOUNT_NOFOLLOW;
424+
} else {
425+
res = check_is_mount(last, mnt);
426+
if (res == -1)
427+
goto out;
428+
}
429+
430+
res = umount2(last, umount_flags);
431+
if (res == -1 && !quiet) {
432+
fprintf(stderr, "%s: failed to unmount %s: %s\n",
433+
progname, mnt, strerror(errno));
434+
}
435+
436+
out:
437+
chdir("/");
438+
if (res == -1)
439+
return -1;
440+
441+
return fuse_mnt_remove_mount(progname, mnt);
545442
}
546443

547444
static int unmount_fuse(const char *mnt, int quiet, int lazy)

0 commit comments

Comments
 (0)