I have significantly refactored the XScreenSaver daemon, the component of the XScreenSaver suite that provides screen locking on X11 systems.
These changes greatly reduce the amount of code running in the "critical" section: the part of the code where a crash would cause the screen to unlock. That critical section is now only around 1,800 lines of code, a reduction of roughly 87%.
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. -- Antoine de Saint-Exupery
My approach with XScreenSaver, as I've written about extensively, has always been to minimize the amount of code in the critical section: to link with as few libraries as possible, and to sandbox as much of the rest as possible in separate processes. This approach has worked out very well; XScreenSaver has had an excellent security track record over these last three decades. Not perfect, but pretty damned good. Especially as compared to its putative "competition".
But, it still contains quite a lot of code, and keeping up with new operating system features like hot-swapping of monitors, new ways of detecting user activity and so on, has caused more and more code to creep into it. Remember that XScreenSaver predates not only HDMI, but USB! I wrote the first version on a 1-bit monochrome display.
So I stepped back and took a fresh look at the whole thing from the perspective of, "what needs to be here?" In addition, dropping support for X11 systems more than fifteen years old -- an eminently reasonable thing to do -- allowed me to simplify the flow of control a lot.
The new design looks like this:
- The daemon. Links with Xlib and nothing else.
- Requires the XInput2 extension, standard since X11R7 in 2005.
- Handles grabs, idle detection, and client messages.
- Maps no windows.
- Launched by xscreensaver to blank the screen.
- Launches the screenhacks as sub-processes.
- Handles monitor reconfiguration, fading, visuals, etc.
- If it crashes, the desktop will momentarily be visible, but the keyboard and mouse will remain grabbed and the screen will remain locked.
- Launched by xscreensaver to authenticate the user.
- Draws the unlock dialog, and talks to PAM.
- Exit code indicates success or failure, so if it crashes, that has the same behavior as "incorrect password".
The old XScreenSaver daemon contained 14.5k lines of code in a single executable. The new one contains 12.5k lines across three different executables -- a 14% reduction overall. But as I said earlier, the critical section -- the process whose crash will result in an unlock -- now contains only 1.8k lines -- an 87% reduction. This is great not just because it reduces the attack surface, but also because it's easier to understand and audit.
This release went through a fair amount of alpha and beta testing, but as always, email me if you can make it break.
Though this release was primarily focused on X11, there are some improvements to the other platforms as well, most notably that both macOS and iOS have a cycling "random mode" now.