Thoughts on Ten Years of qmail Security
Thomas Ptacek | November 2nd, 2007 | Filed Under: Defenses, Uncategorized
Ahh, qmail. What is it about Daniel J. Bernstein’s full-featured Sendmail replacement that we can’t shut up about? Oh yeah, maybe it’s the nine years that have gone by since its last major release in 1998 which saw not one exploitable vulnerability. qmail is one of the top 5 Internet mail servers. Not one other project of similar standing shares this track record. It’s actually kind of spooky.
So, we’ve written about qmail before. And, if Georgi Guninski reads our blog, our qmail writing could conceivably cost me $500. What excuse can we make to keep talking about it?
How about a just-published retrospective on qmail and software security by DJB himself?
DJB isn’t really talking about qmail; he’s using it to illustrate lessons learned about software security. Here’s an example: three answers for eliminating security vulnerabilities from software:
Eliminate bugs from code. As Theo said, “we assume all bugs are vulnerabilities”. Kill bugs, close vulnerabilities. How do we kill bugs? Engineering has wrestled with that for decades. Some answers: formalized software engineering. Automated QA and coverage testing. Unit testing. Code review. Up-front security design.
It works. qmail won by replacing 80’s era C library interfaces with new libraries that made it hard to write incorrect code. Microsoft won by beating the living crap out of their code and release schedule with security-focused QA.
Eliminate code. More code? More potential bugs. Minimizing code footprint reduces exposure to bugs. “Complexity is the enemy of security”. How do we eliminate code? Bernstein’s best answer is reuse: expend effort so your programs exploits your platform, instead of reinventing the wheel.
It works. qmail won by taking advantage of somewhat obscure Unix features like programmable resource limits. The major enterprise web stacks like J2EE and .NET allow web apps to eliminate code by building on well-tested session, database, and templating libraries.
Eliminate trusted code. If you have to spend lines of code to deliver a feature, at least keep the code out of the line of fire. How do we minimize trusted code? Bernstein grapples with this question, arriving at two answers: use the operating system to compartmentalize code, so that vulnerabilities can’t do real damage, and run sensitive code in interpreters, trading speed for security.
It works. Minimizing trusted code (or what consultants would call “the attack surface”) in qmail is the signature architectural trait of qmail. But you get the impression that Bernstein is least satisfied with qmail’s execution here. At the same time, it’s impossible to miss the wins other projects see with this approach: the vast majority of deployed enterprise software is innoculated against memory corruption vulnerabilities because they’re run in high-level languages like C# and Java.
Bernstein has a few grenades to toss. I disagree with his take on “least privilege”; revoking program rights to operating system resources like files and sockets isn’t a distraction. Yes, there’s a (subtle) difference between sandboxing a broken chunk of code and designing it properly to begin with; and yes, it’s true that access control schemes are plagued with “game-over-equivalence” problems (“you can read everyone’s mail, but at least you didn’t get root”). But I found his argument mushy, seeming to contradict his second “minimize the TCB” strategy, and Saltzer’s principals still seem vital to me.
There’s a conspiracy theory among those who have audited qmail’s idiosyncratic codebase that Bernstein didn’t actually write it in C, but rather in a language he compiled down to C. Here he in on the subject:
When I wrote qmail I rejected many languages as being much more painful than C for the end user to compile and use. I was inexplicably blind to the possibility of writing code in a better language and then using an automated translator to convert the code into C as a distribution language.
Of course, now that he’s spending his time writing compiler backends, maybe the new plan is to ship the entire language stack along with his applications.
Bernstein had the benefit of hindsight with buffer overflows, but had to weather integer vulnerabilities along with everyone else. qmail fared remarkably well (the only known integer overflow in qmail isn’t exploitable on any real deployment). The jury’s still out on what the next major bug class will be (our money has been on uninitialized stack variables). We may eke out a few more qmail bugs over the next 10 years. But relying on it seems like a safe bet.


Add New Comment
Viewing 32 Comments
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Add New Comment
Trackbacks