Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Date: Wed, 13 Sep 2017 16:04:19 +1000
From: Dave Chinner <david@...morbit.com>
To: oss-security@...ts.openwall.com
Cc: sandeen@...deen.net, darrick.wong@...cle.com, rwareing@...com
Subject: CVE-2017-14340: Linux kernel: xfs: unprivileged user kernel oops


Summary
-------

XFS mishandles a user settable inode flag in kernels prior to
4.14-rc1 which can cause a local denial of service via a kernel
oops.


Description
-----------

Richard Wareing recently discovered that if the XFS kernel code is
compiled with CONFIG_XFS_RT=y, the code mishandles
FS_XFLAG_RTINHERIT and FS_XFLAG_REALTIME flags when the filesystem
does not have a realtime device configured. When an fsync/fdatasync
operation is run on an inode configured this way, we attempt to
flush the cache of the non-existent realtime device and the kernel
will oops.

While a user cannot set the FS_XFLAG_REALTIME directly on such a
filesystem, we fail to prevent them from setting the
FS_XFLAG_RTINHERIT on directories.  Hence files can inherit the
problematic FS_XFLAG_REALTIME flag from their parent directory at
create time. Setting the FS_XFLAG_RTINHERIT flag does not require
special privileges, so any user with permission to write to a
directory can set it.

Details of the oops signature and the trivial reproducer can be
found in the commit message for the fix below.


Scope of vulnerable filesystems
-------------------------------

This vulnerability was introduced in late 2005 by commit
f538d4da8d52 ("[XFS] write barrier support"). Hence XFS filesystems
on all kernels since 2.6.16 are vulnerable except for:

	* Kernels that are compiled with CONFIG_XFS_RT=n are
	  not vulnerable.

	* XFS filesystems with actual realtime devices are not
	  not vulnerable.


How to recognise a vulnerable system
------------------------------------

1. Search the boot log for the XFS initialisation message. If this
message contains the world "realtime" then the kernel is vulnerable
to the issue:

CONFIG_XFS_RT=y (vulnerable):

# dmesg |grep "XFS with"
[    1.625711] SGI XFS with ACLs, security attributes, realtime, debug enabled

CONFIG_XFS_RT=n (not vulnerable):

# dmesg |grep "XFS with"
[    1.625711] SGI XFS with ACLs, security attributes, debug enabled


2. If you have a vulnerable kernel, check each XFS filesystems to
see if they use a realtime device.

This filesystem is not vulnerable as it has a realtime device
configured:

# xfs_info /mnt |grep ^realtime
realtime =/dev/ram0              extsz=4096   blocks=2048000, rtextents=2048000

This filesystem is vulnerable if the kernel is vulnerable as it does
not have a realtime device:

# xfs_info /mnt |grep ^realtime
realtime =none                   extsz=4096   blocks=0, rtextents=0


Mitigation
----------

Fixed upstream in 4.14-rc1, commit below.

Backports to supported stable upstream kernels is already underway,
so fixes will roll out with the next stable kernel releases.

Recompile the kernel with CONFIG_XFS_RT=n. This is recommended for
users who cannot wait for upstream or distro kernel updates, cannot
backport the fix themselves and do not use realtime devices.


Upstream commit
---------------

commit b31ff3cdf540110da4572e3e29bd172087af65cc
Author: Richard Wareing <rwareing@...com>
Date:   Wed Sep 13 09:09:35 2017 +1000

    xfs: XFS_IS_REALTIME_INODE() should be false if no rt device present
    
    If using a kernel with CONFIG_XFS_RT=y and we set the RHINHERIT flag on
    a directory in a filesystem that does not have a realtime device and
    create a new file in that directory, it gets marked as a real time file.
    When data is written and a fsync is issued, the filesystem attempts to
    flush a non-existent rt device during the fsync process.
    
    This results in a crash dereferencing a null buftarg pointer in
    xfs_blkdev_issue_flush():
    
      BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
      IP: xfs_blkdev_issue_flush+0xd/0x20
      .....
      Call Trace:
        xfs_file_fsync+0x188/0x1c0
        vfs_fsync_range+0x3b/0xa0
        do_fsync+0x3d/0x70
        SyS_fsync+0x10/0x20
        do_syscall_64+0x4d/0xb0
        entry_SYSCALL64_slow_path+0x25/0x25
    
    Setting RT inode flags does not require special privileges so any
    unprivileged user can cause this oops to occur.  To reproduce, confirm
    kernel is compiled with CONFIG_XFS_RT=y and run:
    
      # mkfs.xfs -f /dev/pmem0
      # mount /dev/pmem0 /mnt/test
      # mkdir /mnt/test/foo
      # xfs_io -c 'chattr +t' /mnt/test/foo
      # xfs_io -f -c 'pwrite 0 5m' -c fsync /mnt/test/foo/bar
    
    Or just run xfstests with MKFS_OPTIONS="-d rtinherit=1" and wait.
    
    Kernels built with CONFIG_XFS_RT=n are not exposed to this bug.
    
    Fixes: f538d4da8d52 ("[XFS] write barrier support")
    Cc: <stable@...r.kernel.org>
    Signed-off-by: Richard Wareing <rwareing@...com>
    Signed-off-by: Dave Chinner <david@...morbit.com>
    Signed-off-by: Linus Torvalds <torvalds@...ux-foundation.org>


Timeline:

2017.09.04 - Discussion on xfs@...r.kernel.org (public list) hinted
	     at crash bug in realtime device support
2017.09.09 - Bug found and reported to XFS maintainers
2017.09.12 - Bug reported to security@...nel.org
2017.09.13 - Fix committed to kernel
2017.09.13 - Announcement to oss-security


-Dave.
-- 
Dave Chinner
david@...morbit.com

Download attachment "signature.asc" of type "application/pgp-signature" (820 bytes)

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.