Graphical user interfaces environments are complex things, these days. It can take thousands, even millions, of lines of code to write the software for a basic GUI environment. Consider a rich desktop environment on Ubuntu, for instance — arguably the most popular Linux distribution. The X Window System, in the form of X.Org, is around two million lines of code. The GNOME desktop environment, installed atop X.Org, adds another thirteen million on top of that, give or take. Adding Compiz Fusion to that would hardly have any effect on the overall complexity of the software projects used to construct your GUI environment; it’s only about two hundred thousand lines of code.
Fifteen million lines of code is a lot, of course. Using X.Org is no trivial thing, in terms of how big a commitment to the total complexity of software installed on your computer. It’s also a rough necessity, if you want a modern GUI environment running on your Unix-like system. Of course, at the other extreme from high weight desktop environments like GNOME are things like dwm, which boasts fewer than 2000 lines of C — but you still need the X Window System to run it, making the total something like 13 million and two thousand.
All of this starts to look like small potatoes next to some other GUI environments, however. Certain commercial OSes have even bigger, more complex projects tied to their GUI environments, such as the Aqua environment for Apple MacOS X or Aero Glass for MS Windows Vista. It isn’t so easy to provide estimates of project size for these, because in each case the software is closed source, and its source code is jealously guarded by its respective corporate vendor, but the source for such GUI environments can be reasonably expected to run in the tens of millions of lines of code.
Complexity, unfortunately, is the enemy of security. Every time you increase the complexity of a system, you increase the opportunity for something to go wrong in its design. The more lines of code in your system, the more opportunities there are to introduce bugs when developing the system; the more bugs there are, the more opportunities you have for bugs that introduce security vulnerabilities. As phrased in the Source lines of code article at Wikipedia, under the SLOC and relation to security faults heading:
A number of experts have claimed a relationship between the number of lines of code in a program and the number of bugs that it contains. This relationship is not simple, since the number of errors per line of code varies greatly according to the language used, the type of quality assurance processes, and level of testing, but it does appear to exist. More importantly, the number of bugs in a program has been directly related to the number of security faults that are likely to be found in the program.
This has had a number of important implications for system security and these can be seen reflected in operating system design. Firstly, more complex systems are likely to be more insecure simply due to the greater number of lines of code needed to develop them. For this reason, security focused systems such as OpenBSD grow much more slowly than other systems such as Windows and Linux. A second idea, taken up in both OpenBSD and many Linux variants, is that separating code into different sections which run with different security environments (with or without special privileges, for example) ensures that the most security critical segments are small and carefully audited.
Bugs are not the sole source of software security vulnerabilities, however. Conscious architectural design decisions can also lead to security issues. Introducing a bug in the form of a buffer overrun can produce an arbitrary code execution vulnerability, but so can a decision to allow shell scripts “owned” by the administrative user to be executed SUID when they’re world-writable. That’s why Unix systems usually disallow execution of shell scripts that are SUID root.
Enno Boland, one of the contributing developers at suckless.org (the guys who develop the aforementioned wmii), suggests that the X Window System is poorly designed, and I tend to agree. Oh, I know creating and maintaining the underlying framework for an entire modern GUI environment is not an easy task, and I’m sure that at this point in my life I’m not competent to do a better job than the X.Org project, but that doesn’t change the fact that there are some poor design decisions at work there, and that it appears to lack the kind of engineering discipline one might desire from a project of such widespread impact.
The X Window System, like the Aqua and Aero Glass GUI environments, tries to do too many things within one unified package. This creates significant complexity, which in turn masks security issues and other bugs as well as creating ample opportunity for poor architectural decisions to creep in. It does do at least one thing right that most other modern GUI systems don’t, however; it separates concerns between the underlying windowing system and the actual interface components in the form of a window manager. This helps to keep each segment simpler by reducing coupling, providing stable APIs, and offering the opportunity to minimize the complexity of the window manager component separately from the windowing system component itself. X.Org is still about thirteen million lines of code, though.
The suck less philosophy, suckless.org’s approach to programming excellence, has this to say about secure development:
Code complexity is the mother of bloated, hard to use, and totally inconsistent software. With complex code, problems are solved in suboptimal ways, valuable resources are endlessly tied up, performance slows to a halt, and vulnerabilities become a commonplace. The only solution is to scrap the entire project and rewrite it from scratch.
Such sentiments are expressed about software projects such as Microsoft Windows all the time. Unix and Linux users, especially, seem fond of the notion that the only way to fix problems endemic to MS Windows is to scrap the entire code base and start over. Early reports from the Windows 7 project seemed to indicate that was happening to some extent, but it is beginning to look like that was an erroneous picture of what is going on. It’s easy to understand why Microsoft would resist such a drastic measure: after all, the full benefits of a complete rewrite are lost if you only make the same mistakes the second time that you did the first, and if you don’t make the same mistakes with a complete rewrite of something like MS Windows, you break all backward compatibility and end up with something that, if you were to be perfectly honest about it, couldn’t even be called “Windows”.
The suggestion that perhaps the X Window System should get the same treatment people recommend for MS Windows is far more rare. In fact, even in Enno Boland’s public complaint about the “(un)-unixy” design of the X Window System, I don’t see any explicit call for a complete rewrite and replacement of a windowing system framework for Unix. In the long run, however, that may be exactly what we need if we want to drastically improve the security of the average Unix-like system desktop.