From aac476f2effeff013bd0a14a9dad208e462d59e5 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Jun 08 2010 05:07:55 +0000 Subject: Ver. 2.8.4 --- diff --git a/.cvsignore b/.cvsignore index 898ee47..e8288b3 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -fuse-2.8.1.tar.gz +fuse-2.8.4.tar.gz diff --git a/fuse-CVE-2009-3297.patch b/fuse-CVE-2009-3297.patch deleted file mode 100644 index 44e3a32..0000000 --- a/fuse-CVE-2009-3297.patch +++ /dev/null @@ -1,497 +0,0 @@ ---- - lib/mount.c | 2 - lib/mount_util.c | 11 - - lib/mount_util.h | 3 - util/fusermount.c | 376 ++++++++++++++++++++++++++++++++++++++++++++++-------- - 4 files changed, 330 insertions(+), 62 deletions(-) - -Index: util/fusermount.c -=================================================================== ---- util/fusermount.c.orig 2009-07-02 14:48:53.000000000 +0200 -+++ util/fusermount.c 2010-01-21 21:19:12.218633360 +0100 -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #define FUSE_COMMFD_ENV "_FUSE_COMMFD" - -@@ -37,6 +38,12 @@ - #ifndef MS_DIRSYNC - #define MS_DIRSYNC 128 - #endif -+#ifndef MS_REC -+#define MS_REC 16384 -+#endif -+#ifndef MS_SLAVE -+#define MS_SLAVE (1<<19) -+#endif - - static const char *progname; - -@@ -74,77 +81,336 @@ static void restore_privs(void) - } - - #ifndef IGNORE_MTAB -+/* -+ * Make sure that /etc/mtab is checked and updated atomically -+ */ -+static int lock_umount(void) -+{ -+ const char *mtab_lock = _PATH_MOUNTED ".fuselock"; -+ int mtablock; -+ int res; -+ struct stat mtab_stat; -+ -+ /* /etc/mtab could be a symlink to /proc/mounts */ -+ if (lstat(_PATH_MOUNTED, &mtab_stat) == 0 && S_ISLNK(mtab_stat.st_mode)) -+ return -1; -+ -+ mtablock = open(mtab_lock, O_RDWR | O_CREAT, 0600); -+ if (mtablock == -1) { -+ fprintf(stderr, "%s: unable to open fuse lock file: %s\n", -+ progname, strerror(errno)); -+ return -1; -+ } -+ res = lockf(mtablock, F_LOCK, 0); -+ if (res < 0) { -+ fprintf(stderr, "%s: error getting lock: %s\n", progname, -+ strerror(errno)); -+ close(mtablock); -+ return -1; -+ } -+ -+ return mtablock; -+} -+ -+static void unlock_umount(int mtablock) -+{ -+ lockf(mtablock, F_ULOCK, 0); -+ close(mtablock); -+} -+ - static int add_mount(const char *source, const char *mnt, const char *type, - const char *opts) - { - return fuse_mnt_add_mount(progname, source, mnt, type, opts); - } - --static int unmount_fuse(const char *mnt, int quiet, int lazy) -+static int may_unmount(const char *mnt, int quiet) - { -- if (getuid() != 0) { -- struct mntent *entp; -- FILE *fp; -- const char *user = NULL; -- char uidstr[32]; -- unsigned uidlen = 0; -- int found; -- const char *mtab = _PATH_MOUNTED; -+ struct mntent *entp; -+ FILE *fp; -+ const char *user = NULL; -+ char uidstr[32]; -+ unsigned uidlen = 0; -+ int found; -+ const char *mtab = _PATH_MOUNTED; - -- user = get_user_name(); -- if (user == NULL) -- return -1; -+ user = get_user_name(); -+ if (user == NULL) -+ return -1; - -- fp = setmntent(mtab, "r"); -- if (fp == NULL) { -- fprintf(stderr, -- "%s: failed to open %s: %s\n", progname, mtab, -- strerror(errno)); -- return -1; -- } -+ fp = setmntent(mtab, "r"); -+ if (fp == NULL) { -+ fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab, -+ strerror(errno)); -+ return -1; -+ } - -- uidlen = sprintf(uidstr, "%u", getuid()); -+ uidlen = sprintf(uidstr, "%u", getuid()); - -- found = 0; -- while ((entp = getmntent(fp)) != NULL) { -- if (!found && strcmp(entp->mnt_dir, mnt) == 0 && -- (strcmp(entp->mnt_type, "fuse") == 0 || -- strcmp(entp->mnt_type, "fuseblk") == 0 || -- strncmp(entp->mnt_type, "fuse.", 5) == 0 || -- strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) { -- char *p = strstr(entp->mnt_opts, "user="); -- if (p && -- (p == entp->mnt_opts || *(p-1) == ',') && -- strcmp(p + 5, user) == 0) { -- found = 1; -- break; -- } -- /* /etc/mtab is a link pointing to -- /proc/mounts: */ -- else if ((p = -- strstr(entp->mnt_opts, "user_id=")) && -- (p == entp->mnt_opts || -- *(p-1) == ',') && -- strncmp(p + 8, uidstr, uidlen) == 0 && -- (*(p+8+uidlen) == ',' || -- *(p+8+uidlen) == '\0')) { -- found = 1; -- break; -- } -+ found = 0; -+ while ((entp = getmntent(fp)) != NULL) { -+ if (!found && strcmp(entp->mnt_dir, mnt) == 0 && -+ (strcmp(entp->mnt_type, "fuse") == 0 || -+ strcmp(entp->mnt_type, "fuseblk") == 0 || -+ strncmp(entp->mnt_type, "fuse.", 5) == 0 || -+ strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) { -+ char *p = strstr(entp->mnt_opts, "user="); -+ if (p && -+ (p == entp->mnt_opts || *(p-1) == ',') && -+ strcmp(p + 5, user) == 0) { -+ found = 1; -+ break; -+ } -+ /* /etc/mtab is a link pointing to -+ /proc/mounts: */ -+ else if ((p = -+ strstr(entp->mnt_opts, "user_id=")) && -+ (p == entp->mnt_opts || -+ *(p-1) == ',') && -+ strncmp(p + 8, uidstr, uidlen) == 0 && -+ (*(p+8+uidlen) == ',' || -+ *(p+8+uidlen) == '\0')) { -+ found = 1; -+ break; - } - } -- endmntent(fp); -+ } -+ endmntent(fp); - -- if (!found) { -- if (!quiet) -- fprintf(stderr, -- "%s: entry for %s not found in %s\n", -- progname, mnt, mtab); -- return -1; -+ if (!found) { -+ if (!quiet) -+ fprintf(stderr, -+ "%s: entry for %s not found in %s\n", -+ progname, mnt, mtab); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Check whether the file specified in "fusermount -u" is really a -+ * mountpoint and not a symlink. This is necessary otherwise the user -+ * could move the mountpoint away and replace it with a symlink -+ * pointing to an arbitrary mount, thereby tricking fusermount into -+ * unmounting that (umount(2) will follow symlinks). -+ * -+ * This is the child process running in a separate mount namespace, so -+ * we don't mess with the global namespace and if the process is -+ * 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". -+ * -+ * 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. -+ * -+ * 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. -+ */ -+static int check_is_mount_child(void *p) -+{ -+ const char **a = p; -+ const char *last = a[0]; -+ const char *mnt = a[1]; -+ int res; -+ const char *procmounts = "/proc/mounts"; -+ int found; -+ FILE *fp; -+ struct mntent *entp; -+ -+ res = mount("", "/", "", MS_SLAVE | 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", -+ progname, strerror(errno)); -+ return 1; -+ } -+ -+ fp = setmntent(procmounts, "r"); -+ if (fp == NULL) { -+ fprintf(stderr, "%s: failed to open %s: %s\n", progname, -+ procmounts, 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) { -+ found = 1; -+ break; - } - } -+ endmntent(fp); -+ -+ if (!found) { -+ fprintf(stderr, "%s: %s not mounted\n", progname, mnt); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static pid_t clone_newns(void *a) -+{ -+ long long buf[16384]; -+ size_t stacksize = sizeof(buf) / 2; -+ char *stack = ((char *) buf) + stacksize; -+ -+#ifdef __ia64__ -+ extern int __clone2(int (*fn)(void *), -+ void *child_stack_base, size_t stack_size, -+ 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); -+#else -+ return clone(check_is_mount_child, stack, CLONE_NEWNS, a); -+#endif -+} -+ -+static int check_is_mount(const char *last, const char *mnt) -+{ -+ pid_t pid, p; -+ int status; -+ const char *a[2] = { last, mnt }; -+ -+ pid = clone_newns((void *) a); -+ if (pid == (pid_t) -1) { -+ fprintf(stderr, "%s: failed to clone namespace: %s\n", -+ progname, strerror(errno)); -+ return -1; -+ } -+ p = waitpid(pid, &status, __WCLONE); -+ if (p == (pid_t) -1) { -+ fprintf(stderr, "%s: waitpid failed: %s\n", -+ progname, strerror(errno)); -+ return -1; -+ } -+ if (!WIFEXITED(status)) { -+ fprintf(stderr, "%s: child terminated abnormally (status %i)\n", -+ progname, status); -+ return -1; -+ } -+ if (WEXITSTATUS(status) != 0) -+ return -1; -+ -+ return 0; -+} -+ -+static int chdir_to_parent(char *copy, const char **lastp, int *currdir_fd) -+{ -+ char *tmp; -+ const char *parent; -+ char buf[65536]; -+ int res; -+ -+ tmp = strrchr(copy, '/'); -+ if (tmp == NULL || tmp[1] == '\0') { -+ fprintf(stderr, "%s: internal error: invalid abs path: <%s>\n", -+ progname, copy); -+ return -1; -+ } -+ if (tmp != copy) { -+ *tmp = '\0'; -+ parent = copy; -+ *lastp = tmp + 1; -+ } else if (tmp[1] != '\0') { -+ *lastp = tmp + 1; -+ parent = "/"; -+ } else { -+ *lastp = "."; -+ 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", -+ progname, parent, strerror(errno)); -+ return -1; -+ } -+ -+ if (getcwd(buf, sizeof(buf)) == NULL) { -+ fprintf(stderr, "%s: failed to obtain current directory: %s\n", -+ progname, strerror(errno)); -+ return -1; -+ } -+ if (strcmp(buf, parent) != 0) { -+ fprintf(stderr, "%s: mountpoint moved (%s -> %s)\n", progname, -+ parent, buf); -+ return -1; -+ -+ } -+ -+ return 0; -+} -+ -+static int unmount_fuse_locked(const char *mnt, int quiet, int lazy) -+{ -+ int currdir_fd = -1; -+ char *copy; -+ const char *last; -+ int res; -+ -+ if (getuid() != 0) { -+ res = may_unmount(mnt, quiet); -+ if (res == -1) -+ return -1; -+ } -+ -+ copy = strdup(mnt); -+ if (copy == NULL) { -+ fprintf(stderr, "%s: failed to allocate memory\n", progname); -+ return -1; -+ } -+ -+ res = chdir_to_parent(copy, &last, &currdir_fd); -+ if (res == -1) -+ goto out; -+ -+ res = check_is_mount(last, mnt); -+ if (res == -1) -+ goto out; -+ -+ res = fuse_mnt_umount(progname, mnt, last, lazy); -+ -+out: -+ free(copy); -+ if (currdir_fd != -1) { -+ fchdir(currdir_fd); -+ close(currdir_fd); -+ } -+ -+ return res; -+} -+ -+static int unmount_fuse(const char *mnt, int quiet, int lazy) -+{ -+ int res; -+ int mtablock = lock_umount(); -+ -+ res = unmount_fuse_locked(mnt, quiet, lazy); -+ unlock_umount(mtablock); - -- return fuse_mnt_umount(progname, mnt, lazy); -+ return res; - } - - static int count_fuse_fs(void) -@@ -186,7 +452,7 @@ static int add_mount(const char *source, - - static int unmount_fuse(const char *mnt, int quiet, int lazy) - { -- return fuse_mnt_umount(progname, mnt, lazy); -+ return fuse_mnt_umount(progname, mnt, mnt, lazy); - } - #endif /* IGNORE_MTAB */ - -Index: lib/mount.c -=================================================================== ---- lib/mount.c.orig 2009-01-28 10:46:45.000000000 +0100 -+++ lib/mount.c 2010-01-21 21:19:12.218633360 +0100 -@@ -290,7 +290,7 @@ void fuse_kern_unmount(const char *mount - } - - if (geteuid() == 0) { -- fuse_mnt_umount("fuse", mountpoint, 1); -+ fuse_mnt_umount("fuse", mountpoint, mountpoint, 1); - return; - } - -Index: lib/mount_util.c -=================================================================== ---- lib/mount_util.c.orig 2008-07-10 21:35:39.000000000 +0200 -+++ lib/mount_util.c 2010-01-21 21:19:12.219633417 +0100 -@@ -119,18 +119,19 @@ int fuse_mnt_add_mount(const char *progn - return res; - } - --int fuse_mnt_umount(const char *progname, const char *mnt, int lazy) -+int fuse_mnt_umount(const char *progname, const char *abs_mnt, -+ const char *rel_mnt, int lazy) - { - int res; - int status; - sigset_t blockmask; - sigset_t oldmask; - -- if (!mtab_needs_update(mnt)) { -- res = umount2(mnt, lazy ? 2 : 0); -+ if (!mtab_needs_update(abs_mnt)) { -+ res = umount2(rel_mnt, lazy ? 2 : 0); - if (res == -1) - fprintf(stderr, "%s: failed to unmount %s: %s\n", -- progname, mnt, strerror(errno)); -+ progname, abs_mnt, strerror(errno)); - return res; - } - -@@ -150,7 +151,7 @@ int fuse_mnt_umount(const char *progname - if (res == 0) { - sigprocmask(SIG_SETMASK, &oldmask, NULL); - setuid(geteuid()); -- execl("/bin/umount", "/bin/umount", "-i", mnt, -+ execl("/bin/umount", "/bin/umount", "-i", rel_mnt, - lazy ? "-l" : NULL, NULL); - fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", - progname, strerror(errno)); -Index: lib/mount_util.h -=================================================================== ---- lib/mount_util.h.orig 2007-12-12 13:58:00.000000000 +0100 -+++ lib/mount_util.h 2010-01-21 21:19:12.219633417 +0100 -@@ -10,7 +10,8 @@ - - int fuse_mnt_add_mount(const char *progname, const char *fsname, - const char *mnt, const char *type, const char *opts); --int fuse_mnt_umount(const char *progname, const char *mnt, int lazy); -+int fuse_mnt_umount(const char *progname, const char *abs_mnt, -+ const char *rel_mnt, int lazy); - char *fuse_mnt_resolve_path(const char *progname, const char *orig); - int fuse_mnt_check_empty(const char *progname, const char *mnt, - mode_t rootmode, off_t rootsize); - diff --git a/fuse.spec b/fuse.spec index e83a7e5..c814381 100644 --- a/fuse.spec +++ b/fuse.spec @@ -1,6 +1,6 @@ Name: fuse -Version: 2.8.1 -Release: 4%{?dist} +Version: 2.8.4 +Release: 1%{?dist} Summary: File System in Userspace (FUSE) utilities Group: System Environment/Base @@ -10,7 +10,6 @@ Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar. Patch0: fuse-udev_rules.patch Patch1: fuse-openfix.patch -Patch2: fuse-CVE-2009-3297.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: kernel >= 2.6.14 Requires: which @@ -53,7 +52,6 @@ pgk-config) to develop FUSE based applications/filesystems. sed -i 's|mknod|echo Disabled: mknod |g' util/Makefile.in %patch0 -p0 -b .patch0 %patch1 -p0 -b .patch1 -%patch2 -p0 -b .CVE-2009-3297 %build # Can't pass --disable-static here, or else the utils don't build @@ -127,6 +125,10 @@ fi %{_includedir}/fuse %changelog +* Tue Jun 8 2010 Peter Lemenkov 2.8.4-1 +- Ver. 2.8.4 +- CVE-2009-3297 patch dropped (merged upstream) + * Tue Jan 26 2010 Peter Lemenkov 2.8.1-4 - Fixed CVE-2009-3297 (rhbz #558833) diff --git a/import.log b/import.log index 2b10dd7..aece503 100644 --- a/import.log +++ b/import.log @@ -5,3 +5,4 @@ fuse-2_8_0-1_fc11:HEAD:fuse-2.8.0-1.fc11.src.rpm:1253089638 fuse-2_8_1-1_fc11:HEAD:fuse-2.8.1-1.fc11.src.rpm:1254129320 fuse-2_8_1-3_fc12:HEAD:fuse-2.8.1-3.fc12.src.rpm:1258657884 fuse-2_8_1-4_fc12:HEAD:fuse-2.8.1-4.fc12.src.rpm:1264522586 +fuse-2_8_4-1_fc12:HEAD:fuse-2.8.4-1.fc12.src.rpm:1275973606 diff --git a/sources b/sources index f353d8e..f14ccf6 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -0e3505ce90155983f1bc995eb2cf6fa7 fuse-2.8.1.tar.gz +a26ec54e410bb826a387947b10c0fd2c fuse-2.8.4.tar.gz