aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2010-04-26 15:29:08 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2010-04-26 15:29:08 +0000
commit754c488d9805be4861388d4733440a36fe6468bc (patch)
tree44b713605e0859870de1cde3a4f1ac5890172261
parent83eadc2fa34bd09121a7a8e779fffe485df3db57 (diff)
* Fix checking for symlinks in umount from /tmp. Reported by Al
Viro * Fix umounting if /tmp is a symlink. Reported by Franco Broi
-rw-r--r--ChangeLog11
-rw-r--r--configure.in2
-rw-r--r--lib/Makefile.am2
-rw-r--r--util/fusermount.c46
4 files changed, 45 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 47232ad..f7616fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-04-26 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Released 2.8.4
+
+2010-04-26 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Fix checking for symlinks in umount from /tmp. Reported by Al
+ Viro
+
+ * Fix umounting if /tmp is a symlink. Reported by Franco Broi
+
2010-02-18 Miklos Szeredi <miklos@szeredi.hu>
* Fix definition of FUSE_OPT_END for C++. Reported by Tim
diff --git a/configure.in b/configure.in
index 0d939ad..1664204 100644
--- a/configure.in
+++ b/configure.in
@@ -1,4 +1,4 @@
-AC_INIT(fuse, 2.8.3)
+AC_INIT(fuse, 2.8.4)
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d5ef33b..7b19fc2 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -35,7 +35,7 @@ libfuse_la_SOURCES = \
$(iconv_source) \
$(mount_source)
-libfuse_la_LDFLAGS = @libfuse_libs@ -version-number 2:8:3 \
+libfuse_la_LDFLAGS = @libfuse_libs@ -version-number 2:8:4 \
-Wl,--version-script,$(srcdir)/fuse_versionscript
libulockmgr_la_SOURCES = ulockmgr.c
diff --git a/util/fusermount.c b/util/fusermount.c
index 6123c66..ae779d3 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -41,8 +41,8 @@
#ifndef MS_REC
#define MS_REC 16384
#endif
-#ifndef MS_SLAVE
-#define MS_SLAVE (1<<19)
+#ifndef MS_PRIVATE
+#define MS_PRIVATE (1<<18)
#endif
static const char *progname;
@@ -200,15 +200,16 @@ static int may_unmount(const char *mnt, int quiet)
* killed for any reason, mounts are automatically cleaned up.
*
* First make sure nothing is propagated back into the parent
- * namespace by marking all mounts "slave".
+ * namespace by marking all mounts "private".
*
* Then bind mount parent onto a stable base where the user can't move
- * it around. Use "/tmp", since it will almost certainly exist, but
- * anything similar would do as well.
+ * it around.
*
* Finally check /proc/mounts for an entry matching the requested
* mountpoint. If it's found then we are OK, and the user can't move
- * it around within the parent directory as rename() will return EBUSY.
+ * it around within the parent directory as rename() will return
+ * EBUSY. Be careful to ignore any mounts that existed before the
+ * bind.
*/
static int check_is_mount_child(void *p)
{
@@ -220,21 +221,27 @@ static int check_is_mount_child(void *p)
int found;
FILE *fp;
struct mntent *entp;
+ int count;
- res = mount("", "/", "", MS_SLAVE | MS_REC, NULL);
+ res = mount("", "/", "", MS_PRIVATE | MS_REC, NULL);
if (res == -1) {
- fprintf(stderr, "%s: failed to mark mounts slave: %s\n",
+ fprintf(stderr, "%s: failed to mark mounts private: %s\n",
progname, strerror(errno));
return 1;
}
- res = mount(".", "/tmp", "", MS_BIND | MS_REC, NULL);
- if (res == -1) {
- fprintf(stderr, "%s: failed to bind parent to /tmp: %s\n",
- progname, strerror(errno));
+ fp = setmntent(procmounts, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "%s: failed to open %s: %s\n", progname,
+ procmounts, strerror(errno));
return 1;
}
+ count = 0;
+ while ((entp = getmntent(fp)) != NULL)
+ count++;
+ endmntent(fp);
+
fp = setmntent(procmounts, "r");
if (fp == NULL) {
fprintf(stderr, "%s: failed to open %s: %s\n", progname,
@@ -242,10 +249,21 @@ static int check_is_mount_child(void *p)
return 1;
}
+ res = mount(".", "/", "", MS_BIND | MS_REC, NULL);
+ if (res == -1) {
+ fprintf(stderr, "%s: failed to bind parent to /: %s\n",
+ progname, strerror(errno));
+ return 1;
+ }
+
found = 0;
while ((entp = getmntent(fp)) != NULL) {
- if (strncmp(entp->mnt_dir, "/tmp/", 5) == 0 &&
- strcmp(entp->mnt_dir + 5, last) == 0) {
+ if (count > 0) {
+ count--;
+ continue;
+ }
+ if (entp->mnt_dir[0] == '/' &&
+ strcmp(entp->mnt_dir + 1, last) == 0) {
found = 1;
break;
}