[LWN Logo]

Date:         Thu, 18 May 2000 20:29:09 +0100
From: Chris Evans <chris@FERRET.LMH.OX.AC.UK>
Subject:      Nasty XFree Xserver DoS
To: BUGTRAQ@SECURITYFOCUS.COM

Hi,

Here's a very interesting DoS which I discovered against
XFree86-3.3.5. I've had confirmation it also affects 3.3.6 and 4.0 (with a
small difference, see below)

SUMMARY
=======

Remote users can, by sending a malformed packet to port 6000 TCP, cause a
victim X server to freeze for a couple of minutes. During the freeze, the
mouse does not move, the screen does not update in any way. Worse, the
keyboard is unresponsive, INCLUDING console-switch and kill-server key
combinations. For many users, the machine might as well have crashed and a
full reboot via "the Big Red Button" will be performed.

The precise duration of the freeze is dependent upon processor speed. I've
got a P2-350 and my Xserver freezes for 3min 15s. If that's not long
enough, queuing multiple DoS packets can extend that almost indefinitely.

During the freeze, the X server consumes 100% CPU. If you can get a shell
on the afflicted machine, the X server can be sent a signal to restore
sanity, but getting a shell is not an options for users with one machine
and no serial console :-)

As noted, XFree4.0 is also vulnerable but with a slight
difference. Everything freezes as above, apart from the mouse. This is no
use for recovery because the keyboard is still hosed! I suspect the mouse
handling is simply in its own thread, to give the impression of a
smoother, more perfomant X server.

Not all builds of the X server are vulnerable. To be vulnerable, you need
to build with "#define XCSECURITY". All vendors I've spoken to thus far
build with this however.
Quick check: strings /path/to/XF86_SVGA | grep "XC-QUERY-SECURITY-1"

NOTES
=====

The fact that an X server will tend to listen via TCP on port 6000 is a
large risk (the Xserver runs as root with full hardware permissions
enabled). However it is also an oft overlooked risk. People who carefully
disable all their daemons for security purposes, often overlook the fact
that X behaves as a server.

Any distributions with an installation class of "dialup user" or similar,
should really consider starting X with "-nolisten tcp" for these users.

Any bored security organisations could do worse than put some time into
investigating the security of port 6000 of commercial X servers. This
includes things like Exceed for Windows as well as e.g. Sun's X
server. There is broad potential for worse than DoS here...

DISCUSSION OF CODE FLAW
=======================

Well, the summary is that this is YET another example of signed/unsigned
issues. By seeding a loop with a value of -1, we can cause the X server to
perform 4 billion iterations of a loop.

Observe xc/programs/Xserver/os/secauth.c, AuthCheckSitePolicy():

// dataP is user supplied data from the network
char        *policy = *dataP;
int         nPolicies;
...
// Oh dear, we can set nPolicies to -1
nPolicies = *policy++;
while (nPolicies) {
// Do some stuff in a loop
...
  nPolicies--;
}

So, the counter "nPolicies", if seeded with -1, will decrement towards
about minus 2 billion, then wrap to become positive 2 billion, and head
towards its final destination of 0.

Note that to ensure the loop isn't broken out of by various sanity checks,
requires a little (but not much) imagination.

Also note that there is a theoretical chance that the loop may terminate
prematurely with a SIGSEGV, but I haven't observed this (not that I've
tried).

EXPLOIT
=======

Go home...


The END??
=========

No, more X related joy at a future time..

Cheers
Chris