* Fix checking for symlinks in umount from /tmp. Reported by Al

Viro
* Fix umounting if /tmp is a symlink.  Reported by Franco Broi
* Fix stack alignment for clone()
This commit is contained in:
Miklos Szeredi 2010-04-26 15:34:56 +00:00
parent c6cc2b46a6
commit 7140585ba7
5 changed files with 57 additions and 25 deletions

View File

@ -1,3 +1,18 @@
2010-04-26 Miklos Szeredi <miklos@szeredi.hu>
* Released 2.7.6
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-03 Miklos Szeredi <miklos@szeredi.hu>
* Fix stack alignment for clone()
2010-01-26 Miklos Szeredi <miklos@szeredi.hu>
* Released 2.7.5

View File

@ -1,4 +1,4 @@
AC_INIT(fuse, 2.7.5)
AC_INIT(fuse, 2.7.6)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(include/config.h)

View File

@ -1,4 +1,4 @@
AC_INIT(fuse-kernel, 2.7.5)
AC_INIT(fuse-kernel, 2.7.6)
AC_CONFIG_HEADERS([config.h])
AC_PROG_INSTALL

View File

@ -34,7 +34,7 @@ libfuse_la_SOURCES = \
$(iconv_source) \
$(mount_source)
libfuse_la_LDFLAGS = @libfuse_libs@ -version-number 2:7:5 \
libfuse_la_LDFLAGS = @libfuse_libs@ -version-number 2:7:6 \
-Wl,--version-script,$(srcdir)/fuse_versionscript
libulockmgr_la_SOURCES = ulockmgr.c

View File

@ -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,17 +221,11 @@ 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",
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",
fprintf(stderr, "%s: failed to mark mounts private: %s\n",
progname, strerror(errno));
return 1;
}
@ -242,10 +237,33 @@ static int check_is_mount_child(void *p)
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,
procmounts, strerror(errno));
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;
}
@ -262,9 +280,8 @@ static int check_is_mount_child(void *p)
static pid_t clone_newns(void *a)
{
long long buf[16384];
size_t stacksize = sizeof(buf) / 2;
char *stack = ((char *) buf) + stacksize;
char buf[131072];
char *stack = buf + (sizeof(buf) / 2 - ((size_t) buf & 15));
#ifdef __ia64__
extern int __clone2(int (*fn)(void *),
@ -272,8 +289,8 @@ static pid_t clone_newns(void *a)
int flags, void *arg, pid_t *ptid,
void *tls, pid_t *ctid);
return __clone2(check_is_mount_child, stack, stacksize, CLONE_NEWNS, a,
NULL, NULL, NULL);
return __clone2(check_is_mount_child, stack, sizeof(buf) / 2,
CLONE_NEWNS, a, NULL, NULL, NULL);
#else
return clone(check_is_mount_child, stack, CLONE_NEWNS, a);
#endif