XScreenSaver versus XLock:
History and Technical Comparison
by Jamie Zawinski
In the late 1980s, Patrick Naughton wrote a program called XLock; when run, it would take over an X display until you typed your password to unlock it. While locking the screen, it would run your choice of several built-in graphics demos.
But XLock had a number of limitations. The first and most obvious is that it was a screen locker only, not a screen saver: it would always prompt for a password, and you always had to invoke it explicitly. There was no way to tell it to activate when your terminal was idle and draw pretty pictures, then go away without prompting for a password. It also had some other limitations, which I'll cover in a moment.
But the main point is, it wasn't a screensaver at all, and I wanted one. So in 1991, I wrote the first version of XScreenSaver, and released it to the world.
As I was developing XScreenSaver, and releasing new versions every few months, XLock languished. In 1994, David Bagley adopted XLock, renamed it XLockmore, and continued development on it.
XScreenSaver is superior to XLock/XLockmore in a number of ways.
XScreenSaver is both a screen saver and a screen locker. XLockmore is only a locker. Although XLockmore can be configured to not require a password, it still doesn't have the ability to turn on when the machine is idle; for that you have to use an external program that launches and kills it. That's just hokey.
XScreenSaver also has the feature that you can configure it to activate as a screensaver after a little while; and only after a longer while, start locking the screen. That kind of behavior isn't possible in a program that's only a locker.
XLock is a monolithic executable: all of its display modes are hardcoded in to the program.
XScreenSaver uses a client-server model: the ``xscreensaver'' program is a daemon that runs in the background. This daemon does only a few simple things: it knows how to detect idleness, and how to lock the screen.
All eye-candy activity is handled by other programs: the daemon simply launches them, lets them run for a while, then kills them and starts another.
The contract between the daemon and the graphics demos is simple: any program that draws on the root window can be used as a display mode, without having to recompile (or even restart!) XScreenSaver.
This means that the display modes don't have to be written specifically for XScreenSaver: any program that can draw on the root window fits the XScreenSaver framework, regardless of when it was written, what language it was written in, or what programming style its author used. With XLock, each graphics mode has to follow a very particular and idiosyncratic API, and to add a new mode, or change an existing one, the whole program has to be recompiled. With XScreenSaver, it's possible to download and install third-party screensavers without having to compile anything; with XLock, it's an all-or-nothing affair.
Some of the display modes that come with XScreenSaver are actually shell scripts. That sort of thing isn't possible with a monolithic executable.
For a screen locker, that is, a piece of security software, XLock has a remarkably flawed security model.
Secure coding requires you to minimize the amount of code running in security-critical areas. XScreenSaver accomplishes this by having the program that locks the screen (the ``xscreensaver'' daemon) be small, self-contained, and auditable. The display modes, which comprise the vast majority of the code, are held at arm's length and are not trusted. Their proper operation is not necessary for security to be ensured.
In XLock, all the display modes run in the same process that is locking the screen. This means that if any of those programs has a bug, all of XLock will crash. When XLock crashes, your screen unlocks. And obviously, a lock that can spontaneously unlock itself is not a very good lock...
So if any of the graphics modes, as they are picking random numbers and bouncing pixels around the screen, happen to overrun an array, or corrupt memory, or divide by zero, XLock will unlock. Even worse, if the program leaks memory, it will eventually run out of memory and crash when malloc() fails. Which might take a while: you might only find that your screen magically unlocks after a three-day weekend.
The advantage of the XScreenSaver model is that crashes and memory leaks in the graphics modes are not fatal: they do not result in the screen unlocking! Since the display modes run in sub-processes, the presence of a bug in one of them might result in that display mode exiting: which will leave the screen locked. The ``xscreensaver'' daemon will note that a graphics mode is no longer running, and will start another, while leaving the screen securely locked all the time.
Also, since the display modes are not all running in the same process, any memory leaks they might contain are not cumulative: if an XLock mode only leaks a little bit, it might take many days for it to reach the level where it exhausts memory and unlocks the screen; but it's still wasteful, as all those leaks add up. With XScreenSaver, when the display mode changes, the process is restarted. So even if there is a small leak in one of the display modes, you'll never notice, because those leaks don't compound each other: every time the mode changes, the slate is wiped clean.
Of course, effort has been made in both XLock and XScreenSaver to ensure that the display modes do not crash, and do not have memory leaks. But in XLock, any oversight is critical to the security of the whole system; while in XScreenSaver, it just doesn't really make a difference.
On some systems, only programs which are running as root can
check passwords. Therefore, on such systems, a screen locker needs
to be a setuid- To be sure it was safe to make XLock be setuid-root, one would
have to be certain that all of the display modes were
bug-free. Because if even one of the display modes can be coaxed
into overflowing a buffer (for example, by feeding it bogus data
through command-line options, or through the X resource database),
then that display mode could be coaxed into running a shell. This
would be a way for an unprivileged user to gain root access on the
With XScreenSaver, this class of exploit is not possible,
because the display modes are never run as root: only the small
``xscreensaver'' daemon itself is setuid. And it even disavows its
root privileges just after startup, before X is initialized, and
long before any display mode is launched.
To be sure it was safe to make XLock be setuid-root, one would have to be certain that all of the display modes were bug-free. Because if even one of the display modes can be coaxed into overflowing a buffer (for example, by feeding it bogus data through command-line options, or through the X resource database), then that display mode could be coaxed into running a shell. This would be a way for an unprivileged user to gain root access on the system.
With XScreenSaver, this class of exploit is not possible, because the display modes are never run as root: only the small ``xscreensaver'' daemon itself is setuid. And it even disavows its root privileges just after startup, before X is initialized, and long before any display mode is launched.
It is safe for XScreenSaver to be made a setuid-root program. The reason for this is that the amount of code that actually runs as root is very small and self-contained.
Obviously one needs to be very careful about what programs one allows out of the security sandbox; a conscientious sysadmin would want to examine such a program very carefully before installing it. It is possible (and relatively easy) to do this with XScreenSaver, because the daemon that runs as root is small, and is linked against the bare minimum number of external libraries.
With XLock, as mentioned above, one would have to audit every line in every display mode, because the whole thing runs privileged and in the same process. One weak link is all it takes.
There are both GTK+ and Motif versions of the xscreensaver-demo program, which contain a simple and intuitive interface for configuring XScreenSaver, including trying out the display modes, and customizing which ones should be used. This program communicates with the running ``xscreensaver'' daemon, and so changes take effect immediately.
The XScreenSaver configurator also works as a page in the GNOME Control Center: the ``Screensaver Preferences'' section of the Control Center controls XScreenSaver.
XLock contains a configuration/testing UI, but it's very unsophisticated, and really pretty ugly.
XLock can run the same display mode on all monitors connected to the system, but only XScreenSaver can run different display modes on each monitor. XScreenSaver also understands XFree86's ``virtual desktops'', and will always run the demos in full-screen mode in such a way that they exactly fill up the glass; as opposed to running them at the size of the desktop, meaning you might only see some middle portion of each display mode.
In addition to the fact that the XScreenSaver package includes more display modes than are built in to XLockmore, there are also dozens of stand-alone programs that are not packaged with XScreenSaver that can be used as XScreenSaver display modes.
And it's also possible for XScreenSaver to run XLock itself as one of its display modes. The reverse is not possible, since all display modes must be hardcoded in to the XLock binary.
In summary: XLock is an insecure dinosaur, topheavy and dangerous. XScreenSaver is the way to go! Download it now!