fusermount allows unmount any filesystem

Bug #670622 reported by Paul Szabo on 2010-11-03
260
This bug affects 1 person
Affects Status Importance Assigned to Milestone
fuse (Debian)
Fix Released
Unknown
fuse (Fedora)
Fix Released
Low
fuse (Suse)
Fix Released
Medium
fuse (Ubuntu)
Medium
Unassigned

Bug Description

Binary package hint: fuse-utils

As reported on a public mailing list, fusermount in Ubuntu allows
unprivileged users to unmount anything. For details, please see:

http://lists.grok.org.uk/pipermail/full-disclosure/2010-November/077247.html
http://bugs.debian.org/602333

Cheers,

Paul Szabo <email address hidden> http://www.maths.usyd.edu.au/u/psz/
School of Mathematics and Statistics University of Sydney Australia

Paul Szabo (psz-maths) on 2010-11-03
visibility: private → public

Your friendly security team received the following report via oss-security.
Please respond ASAP.
The issue is public.

------------------------------------------------------------------------------
Date: Thu, 04 Nov 2010 15:45:33 -0400
From: Marc Deslauriers <email address hidden>
Subject: [oss-security] CVE request: fuse

Hello,

There is an issue with FUSE that lets unprivileged users unmount
arbitrary locations via a symlink attack. This is a different issue than
CVE-2009-3297 and CVE-2010-0789.

Ref.:

http://seclists.org/fulldisclosure/2010/Nov/15
http://www.halfdog.net/Security/FuseTimerace/

Thanks,

Marc.

--
Marc Deslauriers
Ubuntu Security Engineer | http://www.ubuntu.com/
Canonical Ltd. | http://www.canonical.com/

Affected distributions with fuse < 2.8.2 *OR* util-linux < 2.17. This means everything except 11.3 and Factory:

11.1
11.2
sle10-sp3
sle11
sle11-moblin20
sle11-sp1

Relevant fuse commits:

  4c3d9b1957 "Use '--no-canonicalize' option of mount(8)..."
  0197ce4041 "Using --no-canonicalize with umount(8) conflicts with..."

and util-linux commits:

  45fc569a75 "mount: add --no-canonicalize option"
  be9adec40f "mount: disable --no-canonicalize for non-root users"

It was reported [1],[2] that the fusermount tool was vulnerable to a race condition between mounting a user filesystem and updating mtab using the standard mount command. If a user were able to win the race, the real mount entry and the mtab entry would differ, making the fuse-mounted filesystem not unmountable by an unprivileged user. Crafted mtab entries can then be used to trick fusermount into believing that a certain part of the filesystem is a user-space filesystem, and will unmount what should be a privileged filesystem (as demonstrated by unmounting /proc).

According to the SUSE bug report [3], this would affect fuse versions before 2.8.2 or util-linux before 2.17, and notes the following commits that correct the problem:

Relevant fuse commits:

  4c3d9b1957 "Use '--no-canonicalize' option of mount(8)..."
  0197ce4041 "Using --no-canonicalize with umount(8) conflicts with..."

and util-linux commits:

  45fc569a75 "mount: add --no-canonicalize option"
  be9adec40f "mount: disable --no-canonicalize for non-root users"

[1] http://www.halfdog.net/Security/FuseTimerace/
[2] http://seclists.org/fulldisclosure/2010/Nov/15
[3] https://bugzilla.novell.com/show_bug.cgi?id=651598

P5->P4 mass change

Created an attachment (id=399921)
fuse fix

Looking deeper, the above is not entirely correct. Fuse versions 2.7.* and 2.8.* are all affected. The fix needs "--no-canonicalize" and "--fake" options in umount(8), which is present in util-linux-ng >= 2.18.

The following commits need backporting to earlier versions of util-linux-ng:

  45fc569a75 mount: add --no-canonicalize option
  be9adec40f mount: disable --no-canonicalize for non-root users
  387ade2a24 umount: add --no-canonicalize
  97a3cef4f1 umount: add --fake option to umount(8)
  1cf4c20b19 mount: don't canonicalize "spec" with --no-canonicalize option

And a similar race exists during mount, so --no-canonicalize is needed in mount(8) too (covered by the commits listed above).

Fuse versions <2.8.2 need to have these commits backported:

  4c3d9b1957 "Use '--no-canonicalize' option of mount(8)..."
  0197ce4041 "Using --no-canonicalize with umount(8) conflicts with..."

Changed in fuse (Ubuntu):
status: New → Confirmed
importance: Undecided → Medium

In addition to the --no-canonicalize option, the --fake option is also required in umount, which is present in 2.18:

http://git.kernel.org/?p=utils/util-linux-ng/util-linux-ng.git;a=commitdiff;h=97a3cef4f1

Another relevant util-linux-ng commit is:

http://git.kernel.org/?p=utils/util-linux-ng/util-linux-ng.git;a=commitdiff;h=1cf4c20b19 ("spec" still canonicalized)

The above two would be required for util-linux-ng in RHEL6. All of the commits would be required for util-linux in RHEL5.

Fedora 14 has the required util-linux-ng version, but needs the fuse fixes backported. SUSE has a patch to fuse to make it use --no-canonicalize and --fake which should fix the issue:

https://bugzilla.novell.com/attachment.cgi?id=399921

Unfortunately, I've been using RHEL6 to test and with the above patches (to fuse and util-linux-ng) and the proof of concept still works. So I don't think these patches are sufficient to correct the problem, although I'm not sure what is missing.

Tom, would have a chance to look at this and see if perhaps something is missing? FWIW, I cannot reproduce this on F14. Despite there being no group-restrictions on fuse (not sure why that's the case), I get the following error:

sh Test.sh
Using target call count 8
Move triggered at count 8
fusermount: user has no write access to mountpoint /proc
fusermount: could not determine username

(although sometimes that first fusermount error shows:

fusermount: user has no write access to mountpoint /home/vdanen/tmp/CVE-2010-3879/tmp/proc

which is the user-mounted directory).

By contrast, fuse-2.8.5-2.fc13 and util-linux-ng-2.17.2-8.fc13 allow me to reproduce this on F13. The same fuse version is on both, but F14 has (a newer) util-linux-ng-2.18-4.5.fc14.

After rebuilding util-linux-ng-2.18-4.5 on Fedora 13, I am still able to reproduce the problem.

Then I realized there was an issue with my F14 testing vm, so after rebooting it, I can indeed reproduce this on F14 (seems something was mucked with sssd which is why I was seeing those permissions errors).

Patched fuse on F14 and still reproduces (using the SUSE patch). So it's either not sufficient or something is still missing from util-linux-ng (on F14, the 1cf4c20b19 patch is missing; rebuilt with just that patch (on 2.18-4.5) and can still reproduce).

So it looks like there is more required than any of these patches to resolve this.

Updated "util-linux" and "fuse" packages have been submitted to the following projects:

SUSE:SLE-10-SP3:Update:Test
SUSE:SLE-10-SP4:Update:Test
SUSE:SLE-11:Update:Test
SUSE:SLE-11-SP1:Update:Test
SUSE:Factory:Head
openSUSE:11.2:Update:Test
openSUSE:11.3:Update:Test

In all 14 submitrequests.

Reassigning to security team for further processing.

Thanks a lot. (Note: It is still filed as "planned update" and will therefore be released later.)

CVE-2010-3879: CVSS v2 Base Score: 3.6 (moderate) (AV:L/AC:L/Au:N/C:N/I:P/A:P): unknown (unknown)

submitting it for SLE10 SP4

The SWAMPID for this issue is 37926.
This issue was rated as low.
Please submit fixed packages until 2011-01-19.
When done, please reassign the bug to <email address hidden>.
Patchinfo will be handled by security team.

there is a conflicting util-linux submission on sle11sp1 from Petr (sr#9153). Could you please merge and resubmit?

(In reply to comment #11)
> there is a conflicting util-linux submission on sle11sp1 from Petr (sr#9153).
> Could you please merge and resubmit?

submitted a merged request: sr#9881.

Launchpad Janitor (janitor) wrote :

This bug was fixed in the package fuse - 2.7.2-1ubuntu2.2

---------------
fuse (2.7.2-1ubuntu2.2) hardy-security; urgency=low

  * SECURITY UPDATE: arbitrary unprivileged unmount (LP: #670622)
    - debian/patches/CVE-2010-3879.dpatch: backported numerous fuse fixes
      from git tree to fix security issues.
      - Block SIGCHLD when executing mount and umount
      - Use "--no-canonicalize' option of mount(8)
      - Fix race if two "fusermount -u" instances are run in parallel
      - Make sure the path to be unmounted doesn't refer to a symlink
      - Use umount --fake to update /etc/mtab
    - debian/patches/200-fix_mount_symlink_handling: removed, changes are
      in the new patch.
    - debian/control: make libfuse2 depend on version of mount that
      contains backported --fake support.
    - CVE-2010-3879
 -- Marc Deslauriers <email address hidden> Thu, 09 Dec 2010 16:27:05 -0500

Changed in fuse (Ubuntu):
status: Confirmed → Fix Released
Changed in fuse (Suse):
importance: Unknown → Medium
status: Unknown → In Progress
Changed in fuse (Debian):
status: Unknown → New

This has stalled for quite a bit. Has any developer/owner of fuse been able to take a look into this to see what is going on?

Ubuntu has released advisories to correct this:

http://www.ubuntu.com/usn/usn-1045-1 (fuse)
http://www.ubuntu.com/usn/usn-1045-2 (mount)

But I can still reproduce the issue on 10.04 LTS (although it doesn't like the Makefile too much):

user@ubuntu:~/CVE-2010-3879$ make
[[ -x DirModifyInotify ]] && rm -f DirModifyInotify || :
/bin/sh: [[: not found
[[ -x FuseMinimal ]] && rm -f FuseMinimal || :
/bin/sh: [[: not found
[[ -L tmp ]] && rm -f tmp || :
/bin/sh: [[: not found
[[ -d tmp-moved ]] && rm -rf tmp-moved || :
/bin/sh: [[: not found
[[ -d tmp-moved ]] && sudo umount tmp-moved/proc && rm -rf tmp-moved || :
/bin/sh: [[: not found
gcc -o DirModifyInotify DirModifyInotify.c
gcc -D_FILE_OFFSET_BITS=64 -lfuse -Wall FuseMinimal.c -o FuseMinimal
ps ax | grep init | grep -v grep
    1 ? Ss 0:01 /sbin/init
sh Test.sh
Using target call count 8
Move triggered at count 8
Cannot find /proc/version - is /proc mounted?
make: *** [test] Error 1
user@ubuntu:~/CVE-2010-3879$ dpkg -l mount libfuse2
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Description
+++-==============-==============-============================================
ii libfuse2 2.8.1-1.1ubunt Filesystem in USErspace library
ii mount 2.17.2-0ubuntu Tools for mounting and manipulating filesyst

Those are the packages that are supposed to fix the flaw.

I noticed they had released updates to fix it and figured I'd make sure before going through the work of extracting their patches (which they backported from upstream by the looks of things). It still takes a bit of persistance, but it works.

No one else has released updates for this. At this point I think we're going to defer it because we don't have a working fix (I'm not even sure if upstream does either at this point) and, for RHEL at least, you need to be in the fuse group to do anything with this.

Does anyone know why Fedora does not have the same policy (of the user having to be in the fuse group in order to use the tools)?

fuse-2.8.5-2.fc14 (fuse): /bin/fusermount (4755,*root,root)
fuse-2.8.1-4.fc13 (fuse): /bin/fusermount (4755,*root,root)
fuse-2.7.4-8.el5 (fuse): /bin/fusermount (4750,*root,fuse)
fuse-2.8.3-1.el6 (fuse): /bin/fusermount (4750,*root,fuse)

Created attachment 475647
Ubuntu patch for fuse-2.7.2

Created attachment 475653
modified test script

Output from Ubuntu using a modified test case (requires the original reproducer). You do have to run it twice to get /proc properly umounted.

user@ubuntu:~/CVE-2010-3879$ cat /etc/issue.net
Ubuntu 10.04.1 LTS
user@ubuntu:~/CVE-2010-3879$ sh test.sh
pre-run, make sure ps is working
user 2031 0.0 0.0 1832 536 pts/0 S+ 12:53 0:00 sh test.sh
user 2032 0.0 0.1 2716 1068 pts/0 R+ 12:53 0:00 ps aux
user 2033 0.0 0.0 3260 660 pts/0 S+ 12:53 0:00 tail -3
DirModifyInotify: no process found
FuseMinimal: no process found
gcc -o DirModifyInotify DirModifyInotify.c
gcc -D_FILE_OFFSET_BITS=64 -lfuse -Wall FuseMinimal.c -o FuseMinimal
Using target call count 8
Move triggered at count 8
fusermount: entry for /proc not found in /etc/mtab
post-run, is ps still working?
user 2054 0.0 0.0 18732 676 ? Ssl 12:53 0:00 ../../FuseMinimal .
user 2061 0.0 0.1 2716 1068 pts/0 R+ 12:53 0:00 ps aux
user 2062 0.0 0.0 3260 664 pts/0 S+ 12:53 0:00 tail -3
user@ubuntu:~/CVE-2010-3879$ sh test.sh
pre-run, make sure ps is working
user 2063 0.0 0.0 1832 536 pts/0 S+ 12:53 0:00 sh test.sh
user 2064 0.0 0.1 2716 1068 pts/0 R+ 12:53 0:00 ps aux
user 2065 0.0 0.0 3260 664 pts/0 S+ 12:53 0:00 tail -3
rm: cannot remove `tmp-moved/proc': Transport endpoint is not connected
[sudo] password for user:
Using target call count 8
Move triggered at count 8
post-run, is ps still working?
Cannot find /proc/version - is /proc mounted?
user@ubuntu:~/CVE-2010-3879$ ps
Cannot find /proc/version - is /proc mounted?

I have updated util-linux-ng in Fedora 14, util-linux-ng-2.18-4.8.fc14

Created fuse tracking bugs for this issue

Affects: fedora-all [bug 673253]

Created util-linux-ng tracking bugs for this issue

Affects: fedora-all [bug 673254]

I'm not sure fuse is on the approved component list for 6.1, so this will still have to wait until 6.2. Also this probably needs to depend on the kernel component as well (which is bz673177).

I've just installed util-linux-ng-2.18-4.8.fc14 from koji in my F14/x86_64 VM and did a git clone of the fuse git repository and built an rpm from it to install in the VM.

So with the util-linux-ng that gives us the options we need, and upstream's latest code for fuse, I can still reproduce this, so it is not fixed upstream.

I found in the fuse upstream commit eba226948b44d5a303a10908d440e808eaf0bae6 that the code checks for "util-linux-ng 2.18" in the "mount --version" output (yeah, there is hardcoded package name and version).

It means that this code will be useless on systems where we backport patches (RHEL6 with util-linux 2.17) or in distributions where is already the latest upstream without the "-ng" suffix (Fedora >= 15).

I'll send an e-mail to Miklos.

Wouldn't we use the --disable-legacy-umount option to configure to get around that?

Please wait with releasing an update until fixes are submitted for the new issue reported in bug 668820.

And let's also include bnc#667215 from the "planned update" list please.

More CVE names have been assigned to this issue. Since we would need to fix them all to get a comprehensive fix, I'm noting them all here as opposed to filing new bugs.

Marc Deslauriers summarized the following on oss-security (http://seclists.org/oss-sec/2011/q1/173):

CVE-2011-0541:

http://fuse.git.sourceforge.net/git/gitweb.cgi?p=fuse/fuse;a=commit;h=bf5ffb5fd8558bd799791834def431c0cee5a11f

Fuse tries to mount a directory without resolving symlinks, and then tries to update mtab. If it couldn't update mtab, it would unmount the directory while resolving symlinks this time, resulting in a different directory being unmounted.

CVE-2011-0542:

http://fuse.git.sourceforge.net/git/gitweb.cgi?p=fuse/fuse;a=commit;h=1e7607ff89c65b005f69e27aeb1649d624099873

This prevents local users from changing the location of the current directory from under fuse using a timing attack.

CVE-2011-0543:

http://fuse.git.sourceforge.net/git/gitweb.cgi?p=fuse/fuse;a=commit;h=cbd3a2a84068aae6e3fe32939d88470d712dbf47

Fuse uses the --no-canonicalize mount option to prevent a symlink attack on the mount point written to mtab. For backwards compatibility reasons, it would fallback to using mount in an insecure way. This fallback could get triggered by a user when an entry already existed in mtab.

All three of these issues allowed local users to trick fuse into unmounting arbitrary directories.

We should now have enough information to get this fully corrected in Fedora.

Created attachment 486670
patch to correct the flaw in fuse on Fedora 14 (v2.8.5)

Current fuse 2.8.5-5.fc14 still fails. I've taken the three upstream commits, merged them, and added the missing bits to make them complete and I've tested it with the original exploit and the new test that showed the failures on Ubuntu, running them 20 times in a row, without being able to umount /proc. I believe that this patch will solve the problem, or at least get us closer (it does work for me, but I've not tested it any way other than using these tests to make sure it was no longer possible to unmount /proc).

% # first run after a fresh boot
% sh new-test.sh
pre-run, make sure ps is working
vdanen 2233 0.0 0.1 106204 1184 pts/0 S+ 13:01 0:00 sh new-test.sh
vdanen 2234 0.0 0.1 110156 1104 pts/0 R+ 13:01 0:00 ps aux
vdanen 2235 0.0 0.0 101016 604 pts/0 S+ 13:01 0:00 tail -3
DirModifyInotify: no process found
FuseMinimal: no process found
gcc -o DirModifyInotify DirModifyInotify.c
gcc -D_FILE_OFFSET_BITS=64 -lfuse -Wall FuseMinimal.c -o FuseMinimal
Using target call count 8
Move triggered at count 8
fusermount: entry for /proc not found in /etc/mtab
post-run, is ps still working?
vdanen 2257 0.0 0.0 234524 488 ? Ssl 13:01 0:00 ../../FuseMinimal .
vdanen 2265 0.0 0.1 110152 1104 pts/0 R+ 13:01 0:00 ps aux
vdanen 2266 0.0 0.0 101016 608 pts/0 S+ 13:01 0:00 tail -3
% # second run
% sh new-test.sh
pre-run, make sure ps is working
vdanen 2267 0.0 0.1 106204 1180 pts/0 S+ 13:01 0:00 sh new-test.sh
vdanen 2268 0.0 0.1 110152 1104 pts/0 R+ 13:01 0:00 ps aux
vdanen 2269 0.0 0.0 101016 604 pts/0 S+ 13:01 0:00 tail -3
rm: cannot remove `tmp-moved/proc': Is a directory
Using target call count 8
Move triggered at count 8
fusermount: user has no write access to mountpoint /proc
fusermount: entry for /proc not found in /etc/mtab
post-run, is ps still working?
vdanen 2281 0.0 0.0 4128 280 pts/0 S+ 13:01 0:00 ./DirModifyInotify --Watch tmp/proc --Watch /etc/mtab --WatchCount 8 --MovePath tmp --LinkTarget /
vdanen 2289 1.0 0.1 110156 1108 pts/0 R+ 13:01 0:00 ps aux
vdanen 2290 0.0 0.0 101016 608 pts/0 S+ 13:01 0:00 tail -3

Hello Vincent and sorry for the hiatus - I was extremely busy last several months. I'll review your patch and apply it very soon.

Created attachment 486688
patch to correct the flaw in fuse on RHEL6 (v2.8.3)

This patch works for RHEL6, but requires a fixed util-linux-ng.

(In reply to comment #41)
> Hello Vincent and sorry for the hiatus - I was extremely busy last several
> months. I'll review your patch and apply it very soon.

Thanks, Peter. That would be great. My back-porting skills are ok, but I'd like to make sure that nothing got broken in the process. It does solve the problem itself, I'm just hoping there are no other regressions. A review would be very much appreciated.

Update released for: fuse, fuse-debuginfo, fuse-debugsource, fuse-devel, libblkid-devel, libblkid-devel-32bit, libblkid1, libblkid1-32bit, libblkid1-x86, libfuse2, libuuid-devel, libuuid-devel-32bit, libuuid1, libuuid1-32bit, libuuid1-x86, util-linux, util-linux-debuginfo, util-linux-debugsource, util-linux-lang, uuid-runtime
Products:
SLE-DEBUGINFO 11-SP1 (i386, ia64, ppc64, s390x, x86_64)
SLE-DESKTOP 11-SP1 (i386, x86_64)
SLE-SDK 11-SP1 (i386, ia64, ppc64, s390x, x86_64)
SLE-SERVER 11-SP1 (i386, ia64, ppc64, s390x, x86_64)
SLES4VMWARE 11-SP1 (i386, x86_64)

On Red Hat Enterprise Linux this is a low impact issue due to the fuse group requirement. The appropriate CVSSv2 score for Red Hat Enterprise Linux is 2.6/AV:L/AC:H/Au:N/C:N/I:P/A:P (AC:H due to an administrator needing to add someone to the fuse group).

On Fedora it is different, because there are no group restrictions in place. On Fedora, this is a moderate impact issue (3.6/AV:L/AC:L/Au:N/C:N/I:P/A:P).

Update released for: fuse, fuse-debuginfo, fuse-debugsource, fuse-devel, fuse-devel-static, libblkid-devel, libblkid1, libblkid1-debuginfo, libfuse2, libfuse2-debuginfo, libuuid-devel, libuuid1, libuuid1-debuginfo, util-linux, util-linux-debuginfo, util-linux-debugsource, util-linux-lang, uuidd, uuidd-debuginfo
Products:
openSUSE 11.2 (debug, i586, x86_64)

Update released for: fuse, fuse-debuginfo, fuse-debugsource, fuse-devel, fuse-devel-static, libblkid-devel, libblkid1, libblkid1-debuginfo, libfuse2, libfuse2-debuginfo, libuuid-devel, libuuid1, libuuid1-debuginfo, util-linux, util-linux-debuginfo, util-linux-debugsource, util-linux-lang, uuidd, uuidd-debuginfo
Products:
openSUSE 11.3 (debug, i586, x86_64)

released

Update released for: fuse, fuse-debuginfo, fuse-devel, libfuse2, util-linux, util-linux-debuginfo
Products:
SLE-DEBUGINFO 10-SP3 (i386, ia64, ppc, s390x, x86_64)
SLE-DESKTOP 10-SP3 (i386, x86_64)
SLE-SAP-APL 10-SP3 (x86_64)
SLE-SDK 10-SP3 (i386, ia64, ppc, s390x, x86_64)
SLE-SERVER 10-SP3 (i386, ia64, ppc, s390x, x86_64)

Update released for: fuse, fuse-debuginfo, fuse-devel, libfuse2
Products:
SLE-DESKTOP 10-SP4 (i386, x86_64)
SLE-SDK 10-SP4 (i386, ia64, ppc, s390x, x86_64)

Changed in fuse (Suse):
status: In Progress → Fix Released

This issue has been addressed in following products:

  Red Hat Enterprise Linux 6

Via RHSA-2011:1083 https://rhn.redhat.com/errata/RHSA-2011-1083.html

Statement:

The Red Hat Security Response Team has rated this issue as having low security impact. On Red Hat Enterprise Linux 5 and 6, a user must be a member of the 'fuse' group in order to use FUSE. Due to the risks associated with fixing this bug on Red Hat Enterprise Linux 5, and because of the group restrictions in place, we currently have no plans to fix this flaw in Red Hat Enterprise Linux 5.

Changed in fuse (Debian):
status: New → Fix Released
Changed in fuse (Fedora):
importance: Unknown → Low
status: Unknown → Fix Released
To post a comment you must log in.
This report contains Public Security information  Edit
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.